Add dropdown for game age filtering (#4092)

* Part 1 for #3067: Basic combo box (dropdown) filtering mechanism for game age.

* Apply suggestions from draft review

# Conflicts:
#	cockatrice/src/gamesmodel.cpp
#	cockatrice/src/gamesmodel.h

* switch to using QTime

* check for games older than a day

* formatting for casts and more unnecessary cosmetic changes

* ebbit1q fixes

Co-authored-by: ebbit1q <ebbit1q@gmail.com>
This commit is contained in:
Kaitlin 2020-09-30 23:46:10 -04:00 committed by GitHub
parent 58d024d067
commit eba9c097f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 46 deletions

View file

@ -23,7 +23,15 @@ enum GameListColumn
SPECTATORS
};
const QString GamesModel::getGameCreatedString(const int secs) const
const bool DEFAULT_UNAVAILABLE_GAMES_VISIBLE = false;
const bool DEFAULT_SHOW_PASSWORD_PROTECTED_GAMES = true;
const bool DEFAULT_SHOW_BUDDIES_ONLY_GAMES = true;
const bool DEFAULT_HIDE_IGNORED_USER_GAMES = false;
const int DEFAULT_MAX_PLAYERS_MIN = 1;
const int DEFAULT_MAX_PLAYERS_MAX = 99;
constexpr QTime DEFAULT_MAX_GAME_AGE = QTime();
const QString GamesModel::getGameCreatedString(const int secs)
{
QString ret;
@ -60,20 +68,23 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
if ((index.row() >= gameList.size()) || (index.column() >= columnCount()))
return QVariant();
const ServerInfo_Game &g = gameList[index.row()];
const ServerInfo_Game &gameentry = gameList[index.row()];
switch (index.column()) {
case ROOM:
return rooms.value(g.room_id());
return rooms.value(gameentry.room_id());
case CREATED: {
QDateTime then;
then.setTime_t(g.start_time());
int secs = then.secsTo(QDateTime::currentDateTime());
switch (role) {
case Qt::DisplayRole:
case Qt::DisplayRole: {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
QDateTime then = QDateTime::fromSecsSinceEpoch(gameentry.start_time(), Qt::UTC);
#else
QDateTime then = QDateTime::fromTime_t(gameentry.start_time(), Qt::UTC);
#endif
int secs = then.secsTo(QDateTime::currentDateTimeUtc());
return getGameCreatedString(secs);
}
case SORT_ROLE:
return QVariant(secs);
return QVariant(-static_cast<qint64>(gameentry.start_time()));
case Qt::TextAlignmentRole:
return Qt::AlignCenter;
default:
@ -84,7 +95,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
switch (role) {
case SORT_ROLE:
case Qt::DisplayRole:
return QString::fromStdString(g.description());
return QString::fromStdString(gameentry.description());
case Qt::TextAlignmentRole:
return Qt::AlignLeft;
default:
@ -94,11 +105,11 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
switch (role) {
case SORT_ROLE:
case Qt::DisplayRole:
return QString::fromStdString(g.creator_info().name());
return QString::fromStdString(gameentry.creator_info().name());
case Qt::DecorationRole: {
QPixmap avatarPixmap = UserLevelPixmapGenerator::generatePixmap(
13, (UserLevelFlags)g.creator_info().user_level(), false,
QString::fromStdString(g.creator_info().privlevel()));
13, (UserLevelFlags)gameentry.creator_info().user_level(), false,
QString::fromStdString(gameentry.creator_info().privlevel()));
return QIcon(avatarPixmap);
}
default:
@ -110,9 +121,9 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
case SORT_ROLE:
case Qt::DisplayRole: {
QStringList result;
GameTypeMap gameTypeMap = gameTypes.value(g.room_id());
for (int i = g.game_types_size() - 1; i >= 0; --i)
result.append(gameTypeMap.value(g.game_types(i)));
GameTypeMap gameTypeMap = gameTypes.value(gameentry.room_id());
for (int i = gameentry.game_types_size() - 1; i >= 0; --i)
result.append(gameTypeMap.value(gameentry.game_types(i)));
return result.join(", ");
}
case Qt::TextAlignmentRole:
@ -125,16 +136,16 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
case SORT_ROLE:
case Qt::DisplayRole: {
QStringList result;
if (g.with_password())
if (gameentry.with_password())
result.append(tr("password"));
if (g.only_buddies())
if (gameentry.only_buddies())
result.append(tr("buddies only"));
if (g.only_registered())
if (gameentry.only_registered())
result.append(tr("reg. users only"));
return result.join(", ");
}
case Qt::DecorationRole: {
return g.with_password() ? QIcon(LockPixmapGenerator::generatePixmap(13)) : QVariant();
return gameentry.with_password() ? QIcon(LockPixmapGenerator::generatePixmap(13)) : QVariant();
case Qt::TextAlignmentRole:
return Qt::AlignLeft;
default:
@ -145,7 +156,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
switch (role) {
case SORT_ROLE:
case Qt::DisplayRole:
return QString("%1/%2").arg(g.player_count()).arg(g.max_players());
return QString("%1/%2").arg(gameentry.player_count()).arg(gameentry.max_players());
case Qt::TextAlignmentRole:
return Qt::AlignCenter;
default:
@ -156,19 +167,19 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
switch (role) {
case SORT_ROLE:
case Qt::DisplayRole: {
if (g.spectators_allowed()) {
if (gameentry.spectators_allowed()) {
QString result;
result.append(QString::number(g.spectators_count()));
result.append(QString::number(gameentry.spectators_count()));
if (g.spectators_can_chat() && g.spectators_omniscient()) {
if (gameentry.spectators_can_chat() && gameentry.spectators_omniscient()) {
result.append(" (")
.append(tr("can chat"))
.append(" & ")
.append(tr("see hands"))
.append(")");
} else if (g.spectators_can_chat()) {
} else if (gameentry.spectators_can_chat()) {
result.append(" (").append(tr("can chat")).append(")");
} else if (g.spectators_omniscient()) {
} else if (gameentry.spectators_omniscient()) {
result.append(" (").append(tr("can see hands")).append(")");
}
@ -314,6 +325,12 @@ void GamesProxyModel::setMaxPlayersFilter(int _maxPlayersFilterMin, int _maxPlay
invalidateFilter();
}
void GamesProxyModel::setMaxGameAge(const QTime &_maxGameAge)
{
maxGameAge = _maxGameAge;
invalidateFilter();
}
int GamesProxyModel::getNumFilteredGames() const
{
GamesModel *model = qobject_cast<GamesModel *>(sourceModel());
@ -340,6 +357,7 @@ void GamesProxyModel::resetFilterParameters()
gameTypeFilter.clear();
maxPlayersFilterMin = DEFAULT_MAX_PLAYERS_MIN;
maxPlayersFilterMax = DEFAULT_MAX_PLAYERS_MAX;
maxGameAge = DEFAULT_MAX_GAME_AGE;
invalidateFilter();
}
@ -351,7 +369,7 @@ bool GamesProxyModel::areFilterParametersSetToDefaults() const
showBuddiesOnlyGames == DEFAULT_SHOW_BUDDIES_ONLY_GAMES &&
hideIgnoredUserGames == DEFAULT_HIDE_IGNORED_USER_GAMES && gameNameFilter.isEmpty() &&
creatorNameFilter.isEmpty() && gameTypeFilter.isEmpty() && maxPlayersFilterMin == DEFAULT_MAX_PLAYERS_MIN &&
maxPlayersFilterMax == DEFAULT_MAX_PLAYERS_MAX;
maxPlayersFilterMax == DEFAULT_MAX_PLAYERS_MAX && maxGameAge == DEFAULT_MAX_GAME_AGE;
}
void GamesProxyModel::loadFilterParameters(const QMap<int, QString> &allGameTypes)
@ -365,6 +383,7 @@ void GamesProxyModel::loadFilterParameters(const QMap<int, QString> &allGameType
creatorNameFilter = gameFilters.getCreatorNameFilter();
maxPlayersFilterMin = gameFilters.getMinPlayers();
maxPlayersFilterMax = gameFilters.getMaxPlayers();
maxGameAge = gameFilters.getMaxGameAge();
QMapIterator<int, QString> gameTypesIterator(allGameTypes);
while (gameTypesIterator.hasNext()) {
@ -396,6 +415,7 @@ void GamesProxyModel::saveFilterParameters(const QMap<int, QString> &allGameType
gameFilters.setMinPlayers(maxPlayersFilterMin);
gameFilters.setMaxPlayers(maxPlayersFilterMax);
gameFilters.setMaxGameAge(maxGameAge);
}
bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sourceParent*/) const
@ -405,6 +425,11 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sour
bool GamesProxyModel::filterAcceptsRow(int sourceRow) const
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
static const QDate epochDate = QDateTime::fromSecsSinceEpoch(0, Qt::UTC).date();
#else
static const QDate epochDate = QDateTime::fromTime_t(0, Qt::UTC).date();
#endif
GamesModel *model = qobject_cast<GamesModel *>(sourceModel());
if (!model)
return false;
@ -442,11 +467,21 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow) const
if (!gameTypeFilter.isEmpty() && gameTypes.intersect(gameTypeFilter).isEmpty())
return false;
if ((int)game.max_players() < maxPlayersFilterMin)
if (game.max_players() < maxPlayersFilterMin)
return false;
if ((int)game.max_players() > maxPlayersFilterMax)
if (game.max_players() > maxPlayersFilterMax)
return false;
if (maxGameAge.isValid()) {
QDateTime now = QDateTime::currentDateTimeUtc();
qint64 signed_start_time = game.start_time(); // cast to 64 bit value to allow signed value
QDateTime total = now.addSecs(-signed_start_time); // a 32 bit value would wrap at 2038-1-19
// games shouldn't have negative ages but we'll not filter them
// because qtime wraps after a day we consider all games older than a day to be too old
if (total.isValid() && total.date() >= epochDate && (total.date() > epochDate || total.time() > maxGameAge)) {
return false;
}
}
return true;
}