From 93ab9f969183e2642708a395f68d5373343811bd Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Sun, 16 Nov 2014 21:12:14 -0800 Subject: [PATCH 1/9] Add 'Start time' column to game list --- CMakeLists.txt | 4 +- cockatrice/src/carddatabase.cpp | 2 +- cockatrice/src/gameselector.cpp | 11 ++-- cockatrice/src/gamesmodel.cpp | 110 ++++++++++++++++++++++++-------- cockatrice/src/gamesmodel.h | 18 +++++- 5 files changed, 109 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cf8857a..350fb149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,9 +79,9 @@ ELSEIF (CMAKE_COMPILER_IS_GNUCXX) include(CheckCXXCompilerFlag) set(CMAKE_CXX_FLAGS_RELEASE "-s -O2") - set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -pedantic -Werror") + set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -pedantic") - set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Winline -Wno-long-long -Wno-error=extra -Wno-error=unused-parameter -Wno-inline -Wno-error=delete-non-virtual-dtor -Wno-error=sign-compare -Wno-error=reorder -Wno-error=missing-declarations) + set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Winline -Wno-long-long -Wno-inline) FOREACH(FLAG ${ADDITIONAL_DEBUG_FLAGS}) CHECK_CXX_COMPILER_FLAG("${FLAG}" CXX_HAS_WARNING_${FLAG}) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index f34a0725..5336b5b3 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -225,7 +225,7 @@ QString PictureLoader::getPicUrl() } // if a card has a muid, use the default url; if not, use the fallback - int muid = set ? muid = card->getMuId(set->getShortName()) : 0; + int muid = set ? card->getMuId(set->getShortName()) : 0; if(muid) picUrl = picDownloadHq ? settingsCache->getPicUrlHq() : settingsCache->getPicUrl(); else diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index 25bf2ebd..f858a129 100644 --- a/cockatrice/src/gameselector.cpp +++ b/cockatrice/src/gameselector.cpp @@ -27,16 +27,17 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup gameListProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); gameListView->setModel(gameListProxyModel); gameListView->setSortingEnabled(true); + gameListView->sortByColumn(gameListModel->startTimeColIndex(), Qt::AscendingOrder); gameListView->setAlternatingRowColors(true); gameListView->setRootIsDecorated(true); if (_room) - gameListView->header()->hideSection(1); + gameListView->header()->hideSection(gameListModel->roomColIndex()); else gameListProxyModel->setUnavailableGamesVisible(true); #if QT_VERSION < 0x050000 - gameListView->header()->setResizeMode(1, QHeaderView::ResizeToContents); + gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents); #else - gameListView->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + gameListView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); #endif filterButton = new QPushButton; filterButton->setIcon(QIcon(":/resources/icon_search.svg")); @@ -53,7 +54,7 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup createButton = 0; joinButton = new QPushButton; spectateButton = new QPushButton; - + QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addWidget(filterButton); buttonLayout->addWidget(clearFilterButton); @@ -63,7 +64,7 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup buttonLayout->addWidget(joinButton); buttonLayout->addWidget(spectateButton); buttonLayout->setAlignment(Qt::AlignTop); - + QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(gameListView); mainLayout->addLayout(buttonLayout); diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index df0ec880..17900834 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -1,6 +1,52 @@ #include "gamesmodel.h" #include "pb/serverinfo_game.pb.h" #include +#include +#include + +namespace { + const unsigned SECS_PER_HALF_MIN = 30; + const unsigned SECS_PER_MIN = 60; + const unsigned SECS_PER_HALF_HOUR = 1600; // 60 * 30 + const unsigned SECS_PER_HOUR = 3600; // 60 * 60 + const unsigned SECS_PER_DAY = 86400; // 60 * 60 * 24 + + /** + * Pretty print an integer number of seconds ago. Accurate to only one unit, + * rounded. + * + * For example... + * 0-59 seconds will return "X seconds ago" + * 1-59 minutes will return "X minutes ago"; 90 seconds will return "2 minutes ago" + * 1-23 hours will return "X hours ago"; 90 minutes will return "2 hours ago" + * 24+ hours will return "1+ days ago", because it seems unlikely that we care about + * an accurate timestamp of day old games. + */ + std::string prettyPrintSecsAgo(uint32_t secs) { + std::ostringstream str_stream; + + if (secs < SECS_PER_MIN) { + str_stream << secs; + str_stream << "s ago"; + } else if (secs < SECS_PER_HOUR) { + uint32_t mins = secs / SECS_PER_MIN; + if (secs % SECS_PER_MIN >= SECS_PER_HALF_MIN) + mins++; + str_stream << mins; + str_stream << "m ago"; + } else if (secs < SECS_PER_DAY) { + uint32_t hours = secs / SECS_PER_HOUR; + if (secs % SECS_PER_HOUR >= SECS_PER_HALF_HOUR) + hours++; + str_stream << hours; + str_stream << "h ago"; + } else { + str_stream << "a long time ago"; + } + + return str_stream.str(); + } +} GamesModel::GamesModel(const QMap &_rooms, const QMap &_gameTypes, QObject *parent) : QAbstractTableModel(parent), rooms(_rooms), gameTypes(_gameTypes) @@ -13,25 +59,36 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const return QVariant(); if (role == Qt::UserRole) return index.row(); - if (role != Qt::DisplayRole) + if (role != Qt::DisplayRole && role != SORT_ROLE) return QVariant(); if ((index.row() >= gameList.size()) || (index.column() >= columnCount())) return QVariant(); - + const ServerInfo_Game &g = gameList[index.row()]; switch (index.column()) { - case 0: return QString::fromStdString(g.description()); - case 1: return rooms.value(g.room_id()); - case 2: return QString::fromStdString(g.creator_info().name()); - case 3: { + case 0: return rooms.value(g.room_id()); + case 1: { + uint32_t now = time(NULL); + uint32_t then = g.start_time(); + int secs = now - then; + + switch (role) { + case Qt::DisplayRole: return QString::fromStdString(prettyPrintSecsAgo(secs)); + case SORT_ROLE: return QVariant(secs); + default: return QVariant(); // Shouldn't ever be reached. + } + } + case 2: return QString::fromStdString(g.description()); + case 3: return QString::fromStdString(g.creator_info().name()); + case 4: { 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))); return result.join(", "); } - case 4: return g.with_password() ? ((g.spectators_need_password() || !g.spectators_allowed()) ? tr("yes") : tr("yes, free for spectators")) : tr("no"); - case 5: { + case 5: return g.with_password() ? ((g.spectators_need_password() || !g.spectators_allowed()) ? tr("yes") : tr("yes, free for spectators")) : tr("no"); + case 6: { QStringList result; if (g.only_buddies()) result.append(tr("buddies only")); @@ -39,8 +96,8 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const result.append(tr("reg. users only")); return result.join(", "); } - case 6: return QString("%1/%2").arg(g.player_count()).arg(g.max_players()); - case 7: return g.spectators_allowed() ? QVariant(g.spectators_count()) : QVariant(tr("not allowed")); + case 7: return QString("%1/%2").arg(g.player_count()).arg(g.max_players()); + case 8: return g.spectators_allowed() ? QVariant(g.spectators_count()) : QVariant(tr("not allowed")); default: return QVariant(); } } @@ -50,14 +107,15 @@ QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int ro if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal)) return QVariant(); switch (section) { - case 0: return tr("Description"); - case 1: return tr("Room"); - case 2: return tr("Creator"); - case 3: return tr("Game type"); - case 4: return tr("Password"); - case 5: return tr("Restrictions"); - case 6: return tr("Players"); - case 7: return tr("Spectators"); + case 0: return tr("Room"); + case 1: return tr("Start time"); + case 2: return tr("Description"); + case 3: return tr("Creator"); + case 4: return tr("Game type"); + case 5: return tr("Password"); + case 6: return tr("Restrictions"); + case 7: return tr("Players"); + case 8: return tr("Spectators"); default: return QVariant(); } } @@ -70,7 +128,7 @@ const ServerInfo_Game &GamesModel::getGame(int row) void GamesModel::updateGameList(const ServerInfo_Game &game) { - for (int i = 0; i < gameList.size(); i++) + for (int i = 0; i < gameList.size(); i++) { if (gameList[i].game_id() == game.game_id()) { if (game.closed()) { beginRemoveRows(QModelIndex(), i, i); @@ -78,10 +136,11 @@ void GamesModel::updateGameList(const ServerInfo_Game &game) endRemoveRows(); } else { gameList[i].MergeFrom(game); - emit dataChanged(index(i, 0), index(i, 7)); + emit dataChanged(index(i, 0), index(i, NUM_COLS-1)); } return; } + } if (game.player_count() <= 0) return; beginInsertRows(QModelIndex(), gameList.size(), gameList.size()); @@ -97,6 +156,7 @@ GamesProxyModel::GamesProxyModel(QObject *parent, ServerInfo_User *_ownUser) maxPlayersFilterMin(-1), maxPlayersFilterMax(-1) { + setSortRole(GamesModel::SORT_ROLE); setDynamicSortFilter(true); } @@ -146,7 +206,7 @@ void GamesProxyModel::resetFilterParameters() gameTypeFilter.clear(); maxPlayersFilterMin = -1; maxPlayersFilterMax = -1; - + invalidateFilter(); } @@ -155,7 +215,7 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourc GamesModel *model = qobject_cast(sourceModel()); if (!model) return false; - + const ServerInfo_Game &game = model->getGame(sourceRow); if (!unavailableGamesVisible) { if (game.player_count() == game.max_players()) @@ -174,17 +234,17 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourc if (!creatorNameFilter.isEmpty()) if (!QString::fromStdString(game.creator_info().name()).contains(creatorNameFilter, Qt::CaseInsensitive)) return false; - + QSet gameTypes; for (int i = 0; i < game.game_types_size(); ++i) gameTypes.insert(game.game_types(i)); if (!gameTypeFilter.isEmpty() && gameTypes.intersect(gameTypeFilter).isEmpty()) return false; - + if ((maxPlayersFilterMin != -1) && ((int)game.max_players() < maxPlayersFilterMin)) return false; if ((maxPlayersFilterMax != -1) && ((int)game.max_players() > maxPlayersFilterMax)) return false; - + return true; } diff --git a/cockatrice/src/gamesmodel.h b/cockatrice/src/gamesmodel.h index aeb37e95..85432cf1 100644 --- a/cockatrice/src/gamesmodel.h +++ b/cockatrice/src/gamesmodel.h @@ -16,15 +16,27 @@ private: QList gameList; QMap rooms; QMap gameTypes; + + static const int NUM_COLS = 9; public: + static const int SORT_ROLE = Qt::UserRole+1; + GamesModel(const QMap &_rooms, const QMap &_gameTypes, QObject *parent = 0); int rowCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : gameList.size(); } - int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 8; } + int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return NUM_COLS; } QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - + const ServerInfo_Game &getGame(int row); + + /** + * Update game list with a (possibly new) game. + */ void updateGameList(const ServerInfo_Game &game); + + int roomColIndex() { return 0; } + int startTimeColIndex() { return 1; } + const QMap &getGameTypes() { return gameTypes; } }; @@ -39,7 +51,7 @@ private: int maxPlayersFilterMin, maxPlayersFilterMax; public: GamesProxyModel(QObject *parent = 0, ServerInfo_User *_ownUser = 0); - + bool getUnavailableGamesVisible() const { return unavailableGamesVisible; } void setUnavailableGamesVisible(bool _unavailableGamesVisible); bool getPasswordProtectedGamesVisible() const { return passwordProtectedGamesVisible; } From 4972d227d9c16e97c22310294faed17e747f09c6 Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Mon, 17 Nov 2014 10:19:34 -0800 Subject: [PATCH 2/9] Add back -Werror, etc. on debug build --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 350fb149..4cf8857a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,9 +79,9 @@ ELSEIF (CMAKE_COMPILER_IS_GNUCXX) include(CheckCXXCompilerFlag) set(CMAKE_CXX_FLAGS_RELEASE "-s -O2") - set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -pedantic") + set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -pedantic -Werror") - set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Winline -Wno-long-long -Wno-inline) + set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Winline -Wno-long-long -Wno-error=extra -Wno-error=unused-parameter -Wno-inline -Wno-error=delete-non-virtual-dtor -Wno-error=sign-compare -Wno-error=reorder -Wno-error=missing-declarations) FOREACH(FLAG ${ADDITIONAL_DEBUG_FLAGS}) CHECK_CXX_COMPILER_FLAG("${FLAG}" CXX_HAS_WARNING_${FLAG}) From a3dc403f75e0007c456c45d9eb7fe9bea226e326 Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Mon, 17 Nov 2014 10:28:15 -0800 Subject: [PATCH 3/9] Translate, change 'Start time' to 'Game created', add debug log --- cockatrice/src/gamesmodel.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 17900834..da177fbe 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -1,5 +1,6 @@ #include "gamesmodel.h" #include "pb/serverinfo_game.pb.h" +#include #include #include #include @@ -12,7 +13,7 @@ namespace { const unsigned SECS_PER_DAY = 86400; // 60 * 60 * 24 /** - * Pretty print an integer number of seconds ago. Accurate to only one unit, + * Pretty print an integer number of seconds ago. Accurate to only one unit, * rounded. * * For example... @@ -34,17 +35,17 @@ namespace { mins++; str_stream << mins; str_stream << "m ago"; - } else if (secs < SECS_PER_DAY) { + } else if (secs < SECS_PER_HOUR * 5) { uint32_t hours = secs / SECS_PER_HOUR; if (secs % SECS_PER_HOUR >= SECS_PER_HALF_HOUR) hours++; str_stream << hours; - str_stream << "h ago"; + str_stream << "hr ago"; } else { - str_stream << "a long time ago"; + str_stream << "5+ hours ago"; } - return str_stream.str(); + return tr(str_stream.str()); } } @@ -75,7 +76,10 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const switch (role) { case Qt::DisplayRole: return QString::fromStdString(prettyPrintSecsAgo(secs)); case SORT_ROLE: return QVariant(secs); - default: return QVariant(); // Shouldn't ever be reached. + default: { + qDebug() << "Returning data for col 1 of games model when role != display, role != sort"; + return QVariant(); // Shouldn't ever be reached. + } } } case 2: return QString::fromStdString(g.description()); @@ -108,7 +112,7 @@ QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int ro return QVariant(); switch (section) { case 0: return tr("Room"); - case 1: return tr("Start time"); + case 1: return tr("Game created"); case 2: return tr("Description"); case 3: return tr("Creator"); case 4: return tr("Game type"); From 7aff20b4ee849281b71ea63c85440a6cb8c2825a Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Mon, 17 Nov 2014 10:35:54 -0800 Subject: [PATCH 4/9] Fix the build --- cockatrice/src/gamesmodel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index da177fbe..95d02c06 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -23,7 +23,7 @@ namespace { * 24+ hours will return "1+ days ago", because it seems unlikely that we care about * an accurate timestamp of day old games. */ - std::string prettyPrintSecsAgo(uint32_t secs) { + QString prettyPrintSecsAgo(uint32_t secs) { std::ostringstream str_stream; if (secs < SECS_PER_MIN) { @@ -45,7 +45,7 @@ namespace { str_stream << "5+ hours ago"; } - return tr(str_stream.str()); + return QObject::tr(str_stream.str().c_str()); } } @@ -74,7 +74,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const int secs = now - then; switch (role) { - case Qt::DisplayRole: return QString::fromStdString(prettyPrintSecsAgo(secs)); + case Qt::DisplayRole: return prettyPrintSecsAgo(secs); case SORT_ROLE: return QVariant(secs); default: { qDebug() << "Returning data for col 1 of games model when role != display, role != sort"; From da145bdd7b5d53f2f69aa5959af8654f54f3cd00 Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Mon, 17 Nov 2014 10:45:37 -0800 Subject: [PATCH 5/9] fix localization in time strings --- cockatrice/src/gamesmodel.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 95d02c06..3c84ad3b 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -10,7 +10,6 @@ namespace { const unsigned SECS_PER_MIN = 60; const unsigned SECS_PER_HALF_HOUR = 1600; // 60 * 30 const unsigned SECS_PER_HOUR = 3600; // 60 * 60 - const unsigned SECS_PER_DAY = 86400; // 60 * 60 * 24 /** * Pretty print an integer number of seconds ago. Accurate to only one unit, @@ -24,28 +23,22 @@ namespace { * an accurate timestamp of day old games. */ QString prettyPrintSecsAgo(uint32_t secs) { - std::ostringstream str_stream; - if (secs < SECS_PER_MIN) { - str_stream << secs; - str_stream << "s ago"; - } else if (secs < SECS_PER_HOUR) { + return QString::number(secs).append(QObject::tr("s ago")); + } + if (secs < SECS_PER_HOUR) { uint32_t mins = secs / SECS_PER_MIN; if (secs % SECS_PER_MIN >= SECS_PER_HALF_MIN) mins++; - str_stream << mins; - str_stream << "m ago"; - } else if (secs < SECS_PER_HOUR * 5) { + return QString::number(mins).append(QObject::tr("m ago")); + } + if (secs < SECS_PER_HOUR * 5) { uint32_t hours = secs / SECS_PER_HOUR; if (secs % SECS_PER_HOUR >= SECS_PER_HALF_HOUR) hours++; - str_stream << hours; - str_stream << "hr ago"; - } else { - str_stream << "5+ hours ago"; + return QString::number(hours).append(QObject::tr("hr ago")); } - - return QObject::tr(str_stream.str().c_str()); + return QObject::tr("5+ hours ago"); } } From d0969c10c63815eab4c03ab47c5a559ce5ec1025 Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Mon, 17 Nov 2014 20:38:52 -0800 Subject: [PATCH 6/9] Show hours and minutes between 60 and 90 minutes --- cockatrice/src/gamesmodel.cpp | 46 ++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 3c84ad3b..af09ea73 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -6,39 +6,61 @@ #include namespace { - const unsigned SECS_PER_HALF_MIN = 30; const unsigned SECS_PER_MIN = 60; - const unsigned SECS_PER_HALF_HOUR = 1600; // 60 * 30 - const unsigned SECS_PER_HOUR = 3600; // 60 * 60 + const unsigned SECS_PER_HALF_HOUR = 60 * 30; + const unsigned SECS_PER_HOUR = 60 * 60; + const unsigned SECS_PER_90_MINS = 60 * 90; /** * Pretty print an integer number of seconds ago. Accurate to only one unit, - * rounded. + * rounded. As a special case, time between 60 and 90 minutes will display + * both the hours and minutes. * * For example... - * 0-59 seconds will return "X seconds ago" - * 1-59 minutes will return "X minutes ago"; 90 seconds will return "2 minutes ago" - * 1-23 hours will return "X hours ago"; 90 minutes will return "2 hours ago" - * 24+ hours will return "1+ days ago", because it seems unlikely that we care about - * an accurate timestamp of day old games. + * 0-59 seconds will return "Xs ago" + * 1-59 minutes will return "Xm ago"; 90 seconds will return "2m ago" + * 60-90 minutes will return "Xhr Ym ago" + * 91-300 minutes will return "Xhr ago"; 91 minutes will return "2hr ago" + * 300+ minutes will return "5+ hr ago", because it seems unlikely that we + * care about an accurate timestamp of old games. */ QString prettyPrintSecsAgo(uint32_t secs) { if (secs < SECS_PER_MIN) { + //: This will have a number prepended, like "10s ago" return QString::number(secs).append(QObject::tr("s ago")); } if (secs < SECS_PER_HOUR) { uint32_t mins = secs / SECS_PER_MIN; - if (secs % SECS_PER_MIN >= SECS_PER_HALF_MIN) + if (secs % SECS_PER_MIN >= 30) mins++; + //: This will have a number prepended, like "10m ago" return QString::number(mins).append(QObject::tr("m ago")); - } + } + // Here, we want to display both the hours and minutes. + // + // There are two small "corner" cases which could be rectified with + // some more knotty iffy-elsey code: + // Between 1:00:00 and 1:00:29 will display "1hr 0m ago" + // Between 1:29:30 and 1:29:59 will display "1hr 31m ago" + // + // Personally, I prefer to keep the code cleaner, and allow these. + if (secs < SECS_PER_90_MINS) { + uint32_t mins = secs / SECS_PER_MIN - 60; + if (secs % SECS_PER_MIN >= 30) + mins++; + return QObject::tr("1hr ") + .append(QString::number(mins)) + //: This will have a number prepended, like "5m ago" + .append(QObject::tr("m ago")); + } if (secs < SECS_PER_HOUR * 5) { uint32_t hours = secs / SECS_PER_HOUR; if (secs % SECS_PER_HOUR >= SECS_PER_HALF_HOUR) hours++; + //: This will have a number prepended, like "2h ago" return QString::number(hours).append(QObject::tr("hr ago")); } - return QObject::tr("5+ hours ago"); + return QObject::tr("5+ hrs ago"); } } From 0af70883a8bd96deca5f5681d89b14728901fdec Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Mon, 17 Nov 2014 20:57:28 -0800 Subject: [PATCH 7/9] 0s-5m displayed as '<5m ago' --- cockatrice/src/gamesmodel.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index af09ea73..6bf32d35 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -6,28 +6,24 @@ #include namespace { - const unsigned SECS_PER_MIN = 60; - const unsigned SECS_PER_HALF_HOUR = 60 * 30; - const unsigned SECS_PER_HOUR = 60 * 60; - const unsigned SECS_PER_90_MINS = 60 * 90; + const unsigned SECS_PER_MIN = 60; + const unsigned SECS_PER_HOUR = 60 * 60; /** * Pretty print an integer number of seconds ago. Accurate to only one unit, - * rounded. As a special case, time between 60 and 90 minutes will display - * both the hours and minutes. + * rounded; <5 minutes and >5 hours are displayed as such. As a special case, + * time between 60 and 90 minutes will display both the hours and minutes. * * For example... - * 0-59 seconds will return "Xs ago" - * 1-59 minutes will return "Xm ago"; 90 seconds will return "2m ago" + * 0-300 seconds will return "<5m ago" + * 5-59 minutes will return "Xm ago" * 60-90 minutes will return "Xhr Ym ago" - * 91-300 minutes will return "Xhr ago"; 91 minutes will return "2hr ago" - * 300+ minutes will return "5+ hr ago", because it seems unlikely that we - * care about an accurate timestamp of old games. + * 91-300 minutes will return "Xhr ago" + * 300+ minutes will return "5+ hr ago" */ QString prettyPrintSecsAgo(uint32_t secs) { - if (secs < SECS_PER_MIN) { - //: This will have a number prepended, like "10s ago" - return QString::number(secs).append(QObject::tr("s ago")); + if (secs < SECS_PER_MIN * 5) { + return QObject::tr("<5m ago"); } if (secs < SECS_PER_HOUR) { uint32_t mins = secs / SECS_PER_MIN; @@ -44,7 +40,7 @@ namespace { // Between 1:29:30 and 1:29:59 will display "1hr 31m ago" // // Personally, I prefer to keep the code cleaner, and allow these. - if (secs < SECS_PER_90_MINS) { + if (secs < SECS_PER_MIN * 90) { uint32_t mins = secs / SECS_PER_MIN - 60; if (secs % SECS_PER_MIN >= 30) mins++; @@ -55,7 +51,7 @@ namespace { } if (secs < SECS_PER_HOUR * 5) { uint32_t hours = secs / SECS_PER_HOUR; - if (secs % SECS_PER_HOUR >= SECS_PER_HALF_HOUR) + if (secs % SECS_PER_HOUR >= SECS_PER_MIN * 30) hours++; //: This will have a number prepended, like "2h ago" return QString::number(hours).append(QObject::tr("hr ago")); From 03bdbe2c7a58f92c42f6f17aa73623ed28eaea19 Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Sat, 22 Nov 2014 00:08:00 -0800 Subject: [PATCH 8/9] Added '<1m ago' --- cockatrice/src/gamesmodel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 6bf32d35..57c2988f 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -22,6 +22,9 @@ namespace { * 300+ minutes will return "5+ hr ago" */ QString prettyPrintSecsAgo(uint32_t secs) { + if (secs < SECS_PER_MIN) { + return QObject::tr("<1m ago"); + } if (secs < SECS_PER_MIN * 5) { return QObject::tr("<5m ago"); } From cab37b39452eb14cbed3e64a07fc01429d8f4d70 Mon Sep 17 00:00:00 2001 From: Mitchell Rosen Date: Sat, 22 Nov 2014 00:08:47 -0800 Subject: [PATCH 9/9] Capitalize game columns --- cockatrice/src/gamesmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 57c2988f..77e2f7f5 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -126,10 +126,10 @@ QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int ro return QVariant(); switch (section) { case 0: return tr("Room"); - case 1: return tr("Game created"); + case 1: return tr("Game Created"); case 2: return tr("Description"); case 3: return tr("Creator"); - case 4: return tr("Game type"); + case 4: return tr("Game Type"); case 5: return tr("Password"); case 6: return tr("Restrictions"); case 7: return tr("Players");