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;
43 Qt::SortOrder sortOrder;
45 ColumnSort additionalSortForColumn(
int column)
const
47 for (
const ColumnSort &sort : additionalSortColumns)
49 if (sort.columnId() == column)
55 bool removeAdditionalColumnSorting(
int column)
57 ColumnSort sort = additionalSortForColumn(column);
60 additionalSortColumns.removeAll(sort);
70 : QSortFilterProxyModel(serverListHandler)
72 d->mainSortColumn = -1;
73 d->parentHandler = serverListHandler;
76 ServerListProxyModel::~ServerListProxyModel()
80 void ServerListProxyModel::addAdditionalColumnSorting(
int column, Qt::SortOrder order)
82 if (d->mainSortColumn == column)
87 if (d->mainSortColumn >= 0)
89 d->removeAdditionalColumnSorting(column);
90 d->additionalSortColumns <<
ColumnSort(column, order);
91 emit additionalSortColumnsChanged();
95 d->mainSortColumn = column;
98 sort(d->mainSortColumn, d->sortOrder);
101 const QList<ColumnSort> &ServerListProxyModel::additionalSortColumns()
const
103 return d->additionalSortColumns;
106 void ServerListProxyModel::clearAdditionalSorting()
108 if (!d->additionalSortColumns.isEmpty())
110 d->additionalSortColumns.clear();
111 emit additionalSortColumnsChanged();
115 #define RET_COMPARE(a, b) \
125 int ServerListProxyModel::compareColumnSortData(QVariant &var1, QVariant &var2,
int column)
const
127 using namespace ServerListColumnId;
129 if (!(var1.isValid() || !var2.isValid()))
141 RET_COMPARE(var1.toUInt(), var2.toUInt());
145 RET_COMPARE(var1.toInt(), var2.toInt());
153 RET_COMPARE(var1.toString(), var2.toString());
162 Q_UNUSED(sourceParent);
163 ServerPtr s = serverFromList(sourceRow);
167 const QString &nameFilter = d->filterInfo.serverName;
168 if (!nameFilter.isEmpty())
170 if (!s->name().contains(nameFilter, Qt::CaseInsensitive))
174 if (!d->filterInfo.bEnabled)
177 if (!d->filterInfo.addresses.matches(s->address()))
182 if (d->filterInfo.bShowOnlyValid)
186 && !d->filterInfo.bShowNotRespondingServers)
191 && !d->filterInfo.bShowTooSoonServers)
196 && !d->filterInfo.bShowBannedServers)
209 if (!d->filterInfo.bShowEmpty && s->isEmpty())
212 if (!d->filterInfo.bShowFull && s->isFull())
215 if (d->filterInfo.maxPing > 0 && d->filterInfo.maxPing < s->ping())
218 if (d->filterInfo.lockedServers == Doomseeker::ShowOnly && !s->isLockedAnywhere())
220 else if (d->filterInfo.lockedServers == Doomseeker::ShowNone && s->isLockedAnywhere())
223 if (d->filterInfo.testingServers == Doomseeker::ShowOnly && !s->isTestingServer())
225 else if (d->filterInfo.testingServers == Doomseeker::ShowNone && s->isTestingServer())
228 if (!d->filterInfo.gameModes.isEmpty())
230 if (!d->filterInfo.gameModes.contains(s->gameMode().name(), Qt::CaseInsensitive))
234 if (d->filterInfo.gameModesExcluded.contains(s->gameMode().name(), Qt::CaseInsensitive))
237 if (!d->filterInfo.wads.isEmpty())
239 bool bWadFound =
false;
243 for (
const QString &filteredWad : d->filterInfo.wads)
245 if (s->anyWadnameContains(filteredWad))
256 if (!d->filterInfo.wadsExcluded.isEmpty())
258 for (
const QString &filteredWad : d->filterInfo.wadsExcluded)
260 if (s->anyWadnameContains(filteredWad))
271 return d->filterInfo;
274 bool ServerListProxyModel::isAnyColumnSortedAdditionally()
const
276 return !d->additionalSortColumns.isEmpty();
279 bool ServerListProxyModel::isSortingAdditionallyByColumn(
int column)
const
281 return d->additionalSortForColumn(column).isValid();
284 bool ServerListProxyModel::lessThan(
const QModelIndex &left,
const QModelIndex &right)
const
286 if (!d->parentHandler->getMainWindow()->isEffectivelyActiveWindow())
291 ServerPtr s1 = serverFromList(left);
292 ServerPtr s2 = serverFromList(right);
294 if (s1 !=
nullptr && s2 !=
nullptr)
296 if (s1->isCustom() && !s2->isCustom())
297 return d->sortOrder == Qt::AscendingOrder;
298 else if (!s1->isCustom() && s2->isCustom())
299 return d->sortOrder == Qt::DescendingOrder;
301 if (s1->isLan() && !s2->isLan())
302 return d->sortOrder == Qt::AscendingOrder;
303 else if (!s1->isLan() && s2->isLan())
304 return d->sortOrder == Qt::DescendingOrder;
310 if (sg1 != sg2 && sg1 != 0 && sg2 != 0)
313 return d->sortOrder == Qt::AscendingOrder;
315 return d->sortOrder == Qt::DescendingOrder;
318 if (d->filterInfo.bPopulatedServersOnTop)
322 int numPlayers1 = sourceModel()->data(left.sibling(left.row(),
323 ServerListColumnId::IDPlayers), sortRole()).toInt();
324 int numPlayers2 = sourceModel()->data(right.sibling(right.row(),
325 ServerListColumnId::IDPlayers), sortRole()).toInt();
326 if (numPlayers1 > 0 && numPlayers2 == 0)
327 return d->sortOrder == Qt::AscendingOrder;
328 else if (numPlayers1 == 0 && numPlayers2 > 0)
329 return d->sortOrder == Qt::DescendingOrder;
332 QVariant leftVar = sourceModel()->data(left, sortRole());
333 QVariant rightVar = sourceModel()->data(right, sortRole());
334 int comparison = compareColumnSortData(leftVar, rightVar, left.column());
337 for (
const ColumnSort &additionalSort : d->additionalSortColumns)
339 QModelIndex additionalLeft = left.sibling(left.row(), additionalSort.columnId());
340 QModelIndex additionalRight = right.sibling(right.row(), additionalSort.columnId());
341 leftVar = sourceModel()->data(additionalLeft, sortRole());
342 rightVar = sourceModel()->data(additionalRight, sortRole());
343 comparison = compareColumnSortData(leftVar, rightVar, additionalSort.columnId());
346 if (additionalSort.order() == Qt::DescendingOrder)
352 return comparison < 0;
355 void ServerListProxyModel::removeAdditionalColumnSorting(
int column)
357 bool anythingRemoved = d->removeAdditionalColumnSorting(column);
358 if (d->mainSortColumn > 0)
359 sort(d->mainSortColumn, d->sortOrder);
361 emit additionalSortColumnsChanged();
366 d->filterInfo = filterInfo;
370 ServerPtr ServerListProxyModel::serverFromList(
const QModelIndex &index)
const
372 return serverFromList(index.row());
375 ServerPtr ServerListProxyModel::serverFromList(
int row)
const
378 return model->serverFromList(row);
381 void ServerListProxyModel::setAdditionalSortColumns(
const QList<ColumnSort> &columns)
383 d->additionalSortColumns = columns;
384 emit additionalSortColumnsChanged();
387 void ServerListProxyModel::sortServers(
int column, Qt::SortOrder order)
389 d->mainSortColumn = column;
390 d->sortOrder = order;
391 if (d->removeAdditionalColumnSorting(column))
392 emit additionalSortColumnsChanged();
396 ColumnSort::ColumnSort()
399 order_ = Qt::AscendingOrder;
402 ColumnSort::ColumnSort(
int columnId, Qt::SortOrder order)
404 columnId_ = columnId;
408 int ColumnSort::columnId()
const
413 ColumnSort ColumnSort::deserializeQVariant(
const QVariant &v)
415 QVariantMap map = v.toMap();
417 static_cast<Qt::SortOrder>(map[
"order"].toInt())
421 bool ColumnSort::isValid()
const
423 return columnId() >= 0;
426 Qt::SortOrder ColumnSort::order()
const
431 bool ColumnSort::operator==(
const ColumnSort &other)
const
433 return order() == other.order() && columnId() == other.columnId();
436 QVariant ColumnSort::serializeQVariant()
const
439 map[
"columnId"] = columnId();
440 map[
"order"] = order();