23 #include "serverlistproxymodel.h"
25 #include "gui/entity/serverlistfilterinfo.h"
26 #include "gui/mainwindow.h"
27 #include "gui/models/serverlistcolumn.h"
28 #include "gui/models/serverlistmodel.h"
29 #include "gui/serverlist.h"
30 #include "serverapi/playerslist.h"
31 #include "serverapi/server.h"
36 DClass<ServerListProxyModel>
39 QList<ColumnSort> additionalSortColumns;
40 bool groupServersWithPlayersAtTop;
44 Qt::SortOrder sortOrder;
46 ColumnSort additionalSortForColumn(
int column)
const
48 for (
const ColumnSort &sort : additionalSortColumns)
50 if (sort.columnId() == column)
56 bool removeAdditionalColumnSorting(
int column)
58 ColumnSort sort = additionalSortForColumn(column);
61 additionalSortColumns.removeAll(sort);
71 : QSortFilterProxyModel(serverListHandler)
73 d->groupServersWithPlayersAtTop =
true;
74 d->mainSortColumn = -1;
75 d->parentHandler = serverListHandler;
78 ServerListProxyModel::~ServerListProxyModel()
82 void ServerListProxyModel::addAdditionalColumnSorting(
int column, Qt::SortOrder order)
84 if (d->mainSortColumn == column)
89 if (d->mainSortColumn >= 0)
91 d->removeAdditionalColumnSorting(column);
92 d->additionalSortColumns <<
ColumnSort(column, order);
93 emit additionalSortColumnsChanged();
97 d->mainSortColumn = column;
100 sort(d->mainSortColumn, d->sortOrder);
103 const QList<ColumnSort> &ServerListProxyModel::additionalSortColumns()
const
105 return d->additionalSortColumns;
108 void ServerListProxyModel::clearAdditionalSorting()
110 if (!d->additionalSortColumns.isEmpty())
112 d->additionalSortColumns.clear();
113 emit additionalSortColumnsChanged();
117 #define RET_COMPARE(a, b) \
127 int ServerListProxyModel::compareColumnSortData(QVariant &var1, QVariant &var2,
int column)
const
129 using namespace ServerListColumnId;
131 if (!(var1.isValid() || !var2.isValid()))
143 RET_COMPARE(var1.toUInt(), var2.toUInt());
147 RET_COMPARE(var1.toInt(), var2.toInt());
155 RET_COMPARE(var1.toString(), var2.toString());
164 Q_UNUSED(sourceParent);
165 ServerPtr s = serverFromList(sourceRow);
169 const QString &nameFilter = d->filterInfo.serverName;
170 if (!nameFilter.isEmpty())
172 if (!s->name().contains(nameFilter, Qt::CaseInsensitive))
176 if (!d->filterInfo.bEnabled)
181 if (d->filterInfo.bShowOnlyValid)
192 if (!d->filterInfo.bShowEmpty && s->isEmpty())
195 if (!d->filterInfo.bShowFull && s->isFull())
198 if (d->filterInfo.maxPing > 0 && d->filterInfo.maxPing < s->ping())
201 if (d->filterInfo.testingServers == Doomseeker::ShowOnly && !s->isTestingServer())
203 else if (d->filterInfo.testingServers == Doomseeker::ShowNone && s->isTestingServer())
206 if (!d->filterInfo.gameModes.isEmpty())
208 if (!d->filterInfo.gameModes.contains(s->gameMode().name(), Qt::CaseInsensitive))
212 if (d->filterInfo.gameModesExcluded.contains(s->gameMode().name(), Qt::CaseInsensitive))
215 if (!d->filterInfo.wads.isEmpty())
217 bool bWadFound =
false;
221 for (
const QString &filteredWad : d->filterInfo.wads)
223 if (s->anyWadnameContains(filteredWad))
234 if (!d->filterInfo.wadsExcluded.isEmpty())
236 for (
const QString &filteredWad : d->filterInfo.wadsExcluded)
238 if (s->anyWadnameContains(filteredWad))
249 return d->filterInfo;
252 bool ServerListProxyModel::isAnyColumnSortedAdditionally()
const
254 return !d->additionalSortColumns.isEmpty();
257 bool ServerListProxyModel::isSortingAdditionallyByColumn(
int column)
const
259 return d->additionalSortForColumn(column).isValid();
262 bool ServerListProxyModel::lessThan(
const QModelIndex &left,
const QModelIndex &right)
const
264 if (!d->parentHandler->getMainWindow()->isEffectivelyActiveWindow())
269 ServerPtr s1 = serverFromList(left);
270 ServerPtr s2 = serverFromList(right);
272 if (s1 !=
nullptr && s2 !=
nullptr)
274 if (s1->isCustom() && !s2->isCustom())
275 return d->sortOrder == Qt::AscendingOrder;
276 else if (!s1->isCustom() && s2->isCustom())
277 return d->sortOrder == Qt::DescendingOrder;
279 if (s1->isLan() && !s2->isLan())
280 return d->sortOrder == Qt::AscendingOrder;
281 else if (!s1->isLan() && s2->isLan())
282 return d->sortOrder == Qt::DescendingOrder;
288 if (sg1 != sg2 && sg1 != 0 && sg2 != 0)
291 return d->sortOrder == Qt::AscendingOrder;
293 return d->sortOrder == Qt::DescendingOrder;
296 if (d->groupServersWithPlayersAtTop)
300 int numPlayers1 = sourceModel()->data(left.sibling(left.row(),
301 ServerListColumnId::IDPlayers), sortRole()).toInt();
302 int numPlayers2 = sourceModel()->data(right.sibling(right.row(),
303 ServerListColumnId::IDPlayers), sortRole()).toInt();
304 if (numPlayers1 > 0 && numPlayers2 == 0)
305 return d->sortOrder == Qt::AscendingOrder;
306 else if (numPlayers1 == 0 && numPlayers2 > 0)
307 return d->sortOrder == Qt::DescendingOrder;
310 QVariant leftVar = sourceModel()->data(left, sortRole());
311 QVariant rightVar = sourceModel()->data(right, sortRole());
312 int comparison = compareColumnSortData(leftVar, rightVar, left.column());
315 for (
const ColumnSort &additionalSort : d->additionalSortColumns)
317 QModelIndex additionalLeft = left.sibling(left.row(), additionalSort.columnId());
318 QModelIndex additionalRight = right.sibling(right.row(), additionalSort.columnId());
319 leftVar = sourceModel()->data(additionalLeft, sortRole());
320 rightVar = sourceModel()->data(additionalRight, sortRole());
321 comparison = compareColumnSortData(leftVar, rightVar, additionalSort.columnId());
324 if (additionalSort.order() == Qt::DescendingOrder)
330 return comparison < 0;
333 void ServerListProxyModel::removeAdditionalColumnSorting(
int column)
335 bool anythingRemoved = d->removeAdditionalColumnSorting(column);
336 if (d->mainSortColumn > 0)
337 sort(d->mainSortColumn, d->sortOrder);
339 emit additionalSortColumnsChanged();
344 d->filterInfo = filterInfo;
348 void ServerListProxyModel::setGroupServersWithPlayersAtTop(
bool b)
350 d->groupServersWithPlayersAtTop = b;
354 ServerPtr ServerListProxyModel::serverFromList(
const QModelIndex &index)
const
356 return serverFromList(index.row());
359 ServerPtr ServerListProxyModel::serverFromList(
int row)
const
362 return model->serverFromList(row);
365 void ServerListProxyModel::setAdditionalSortColumns(
const QList<ColumnSort> &columns)
367 d->additionalSortColumns = columns;
368 emit additionalSortColumnsChanged();
371 void ServerListProxyModel::sortServers(
int column, Qt::SortOrder order)
373 d->mainSortColumn = column;
374 d->sortOrder = order;
375 if (d->removeAdditionalColumnSorting(column))
376 emit additionalSortColumnsChanged();
380 ColumnSort::ColumnSort()
383 order_ = Qt::AscendingOrder;
386 ColumnSort::ColumnSort(
int columnId, Qt::SortOrder order)
388 columnId_ = columnId;
392 int ColumnSort::columnId()
const
397 ColumnSort ColumnSort::deserializeQVariant(
const QVariant &v)
399 QVariantMap map = v.toMap();
401 static_cast<Qt::SortOrder>(map[
"order"].toInt())
405 bool ColumnSort::isValid()
const
407 return columnId() >= 0;
410 Qt::SortOrder ColumnSort::order()
const
415 bool ColumnSort::operator==(
const ColumnSort &other)
const
417 return order() == other.order() && columnId() == other.columnId();
420 QVariant ColumnSort::serializeQVariant()
const
423 map[
"columnId"] = columnId();
424 map[
"order"] = order();