diff --git a/cockatrice/src/dlg_filter_games.cpp b/cockatrice/src/dlg_filter_games.cpp index eb2e8f78..7c33b8b8 100644 --- a/cockatrice/src/dlg_filter_games.cpp +++ b/cockatrice/src/dlg_filter_games.cpp @@ -12,49 +12,37 @@ #include #include -DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, QWidget *parent) +DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, const GamesProxyModel *_gamesProxyModel, QWidget *parent) : QDialog(parent), - allGameTypes(_allGameTypes) + allGameTypes(_allGameTypes), + gamesProxyModel(_gamesProxyModel) { QSettings settings; settings.beginGroup("filter_games"); unavailableGamesVisibleCheckBox = new QCheckBox(tr("Show &unavailable games")); - unavailableGamesVisibleCheckBox->setChecked( - settings.value("unavailable_games_visible", false).toBool() - ); + unavailableGamesVisibleCheckBox->setChecked(gamesProxyModel->getUnavailableGamesVisible()); passwordProtectedGamesVisibleCheckBox = new QCheckBox(tr("Show &password protected games")); - passwordProtectedGamesVisibleCheckBox->setChecked( - settings.value("password_protected_games_visible", false).toBool() - ); - + passwordProtectedGamesVisibleCheckBox->setChecked(gamesProxyModel->getPasswordProtectedGamesVisible()); + gameNameFilterEdit = new QLineEdit; - gameNameFilterEdit->setText( - settings.value("game_name_filter", "").toString() - ); + gameNameFilterEdit->setText(gamesProxyModel->getGameNameFilter()); QLabel *gameNameFilterLabel = new QLabel(tr("Game &description:")); gameNameFilterLabel->setBuddy(gameNameFilterEdit); - + creatorNameFilterEdit = new QLineEdit; - creatorNameFilterEdit->setText( - settings.value("creator_name_filter", "").toString() - ); + creatorNameFilterEdit->setText(gamesProxyModel->getCreatorNameFilter()); QLabel *creatorNameFilterLabel = new QLabel(tr("&Creator name:")); creatorNameFilterLabel->setBuddy(creatorNameFilterEdit); - + QVBoxLayout *gameTypeFilterLayout = new QVBoxLayout; QMapIterator gameTypesIterator(allGameTypes); while (gameTypesIterator.hasNext()) { gameTypesIterator.next(); QCheckBox *temp = new QCheckBox(gameTypesIterator.value()); - temp->setChecked( - settings.value( - "game_type/" + hashGameType(gameTypesIterator.value()), - false - ).toBool() - ); + temp->setChecked(gamesProxyModel->getGameTypeFilter().contains(gameTypesIterator.key())); gameTypeFilterCheckBoxes.insert(gameTypesIterator.key(), temp); gameTypeFilterLayout->addWidget(temp); @@ -65,34 +53,30 @@ DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, QWidget gameTypeFilterGroupBox->setLayout(gameTypeFilterLayout); } else gameTypeFilterGroupBox = 0; - + QLabel *maxPlayersFilterMinLabel = new QLabel(tr("at &least:")); maxPlayersFilterMinSpinBox = new QSpinBox; maxPlayersFilterMinSpinBox->setMinimum(1); maxPlayersFilterMinSpinBox->setMaximum(99); - maxPlayersFilterMinSpinBox->setValue( - settings.value("min_players", 1).toInt() - ); + maxPlayersFilterMinSpinBox->setValue(gamesProxyModel->getMaxPlayersFilterMin()); maxPlayersFilterMinLabel->setBuddy(maxPlayersFilterMinSpinBox); - + QLabel *maxPlayersFilterMaxLabel = new QLabel(tr("at &most:")); maxPlayersFilterMaxSpinBox = new QSpinBox; maxPlayersFilterMaxSpinBox->setMinimum(1); maxPlayersFilterMaxSpinBox->setMaximum(99); - maxPlayersFilterMaxSpinBox->setValue( - settings.value("max_players", 99).toInt() - ); + maxPlayersFilterMaxSpinBox->setValue(gamesProxyModel->getMaxPlayersFilterMax()); maxPlayersFilterMaxLabel->setBuddy(maxPlayersFilterMaxSpinBox); - + QGridLayout *maxPlayersFilterLayout = new QGridLayout; maxPlayersFilterLayout->addWidget(maxPlayersFilterMinLabel, 0, 0); maxPlayersFilterLayout->addWidget(maxPlayersFilterMinSpinBox, 0, 1); maxPlayersFilterLayout->addWidget(maxPlayersFilterMaxLabel, 1, 0); maxPlayersFilterLayout->addWidget(maxPlayersFilterMaxSpinBox, 1, 1); - + QGroupBox *maxPlayersGroupBox = new QGroupBox(tr("Maximum player count")); maxPlayersGroupBox->setLayout(maxPlayersFilterLayout); - + QGridLayout *leftGrid = new QGridLayout; leftGrid->addWidget(gameNameFilterLabel, 0, 0); leftGrid->addWidget(gameNameFilterEdit, 0, 1); @@ -101,66 +85,34 @@ DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, QWidget leftGrid->addWidget(maxPlayersGroupBox, 2, 0, 1, 2); leftGrid->addWidget(unavailableGamesVisibleCheckBox, 3, 0, 1, 2); leftGrid->addWidget(passwordProtectedGamesVisibleCheckBox, 4, 0, 1, 2); - + QVBoxLayout *leftColumn = new QVBoxLayout; leftColumn->addLayout(leftGrid); leftColumn->addStretch(); - + QVBoxLayout *rightColumn = new QVBoxLayout; rightColumn->addWidget(gameTypeFilterGroupBox); - + QHBoxLayout *hbox = new QHBoxLayout; hbox->addLayout(leftColumn); hbox->addLayout(rightColumn); - + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, SIGNAL(accepted()), this, SLOT(actOk())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - + QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(hbox); mainLayout->addWidget(buttonBox); - + setLayout(mainLayout); setWindowTitle(tr("Filter games")); } void DlgFilterGames::actOk() { - QSettings settings; - settings.beginGroup("filter_games"); - settings.setValue( - "unavailable_games_visible", - unavailableGamesVisibleCheckBox->isChecked() - ); - settings.setValue( - "password_protected_games_visible", - passwordProtectedGamesVisibleCheckBox->isChecked() - ); - settings.setValue("game_name_filter", gameNameFilterEdit->text()); - settings.setValue("creator_name_filter", creatorNameFilterEdit->text()); - - QMapIterator gameTypeIterator(allGameTypes); - QMapIterator checkboxIterator(gameTypeFilterCheckBoxes); - while (gameTypeIterator.hasNext()) { - gameTypeIterator.next(); - checkboxIterator.next(); - - settings.setValue( - "game_type/" + hashGameType(gameTypeIterator.value()), - checkboxIterator.value()->isChecked() - ); - } - - settings.setValue("min_players", maxPlayersFilterMinSpinBox->value()); - settings.setValue("max_players", maxPlayersFilterMaxSpinBox->value()); - accept(); } -QString DlgFilterGames::hashGameType(const QString &gameType) const { - return QCryptographicHash::hash(gameType.toUtf8(), QCryptographicHash::Md5).toHex(); -} - bool DlgFilterGames::getUnavailableGamesVisible() const { return unavailableGamesVisibleCheckBox->isChecked(); diff --git a/cockatrice/src/dlg_filter_games.h b/cockatrice/src/dlg_filter_games.h index 2480e642..9374e387 100644 --- a/cockatrice/src/dlg_filter_games.h +++ b/cockatrice/src/dlg_filter_games.h @@ -4,6 +4,7 @@ #include #include #include +#include "gamesmodel.h" class QCheckBox; class QLineEdit; @@ -21,17 +22,13 @@ private: QSpinBox *maxPlayersFilterMaxSpinBox; const QMap &allGameTypes; + const GamesProxyModel *gamesProxyModel; - /* - * The game type might contain special characters, so to use it in - * QSettings we just hash it. - */ - QString hashGameType(const QString &gameType) const; private slots: void actOk(); public: - DlgFilterGames(const QMap &allGameTypes, QWidget *parent = 0); - + DlgFilterGames(const QMap &_allGameTypes, const GamesProxyModel *_gamesProxyModel, QWidget *parent = 0); + bool getUnavailableGamesVisible() const; void setUnavailableGamesVisible(bool _unavailableGamesVisible); bool getPasswordProtectedGamesVisible() const; diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index 4cbfbedb..a04cd694 100644 --- a/cockatrice/src/gameselector.cpp +++ b/cockatrice/src/gameselector.cpp @@ -32,8 +32,12 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup gameListView->setRootIsDecorated(true); if (_room) gameListView->header()->hideSection(gameListModel->roomColIndex()); - else - gameListProxyModel->setUnavailableGamesVisible(true); + + if (room) + gameTypeMap = gameListModel->getGameTypes().value(room->getRoomId()); + + gameListProxyModel->loadFilterParameters(gameTypeMap); + #if QT_VERSION < 0x050000 gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents); #else @@ -44,7 +48,7 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup connect(filterButton, SIGNAL(clicked()), this, SLOT(actSetFilter())); clearFilterButton = new QPushButton; clearFilterButton->setIcon(QIcon(":/resources/icon_clearsearch.svg")); - clearFilterButton->setEnabled(false); + clearFilterButton->setEnabled(true); connect(clearFilterButton, SIGNAL(clicked()), this, SLOT(actClearFilter())); if (room) { @@ -82,29 +86,28 @@ GameSelector::GameSelector(AbstractClient *_client, const TabSupervisor *_tabSup void GameSelector::actSetFilter() { - GameTypeMap gameTypeMap; - if (room) - gameTypeMap = gameListModel->getGameTypes().value(room->getRoomId()); - DlgFilterGames dlg(gameTypeMap, this); - + DlgFilterGames dlg(gameTypeMap, gameListProxyModel, this); + if (!dlg.exec()) return; - + clearFilterButton->setEnabled(true); - + gameListProxyModel->setUnavailableGamesVisible(dlg.getUnavailableGamesVisible()); gameListProxyModel->setPasswordProtectedGamesVisible(dlg.getPasswordProtectedGamesVisible()); gameListProxyModel->setGameNameFilter(dlg.getGameNameFilter()); gameListProxyModel->setCreatorNameFilter(dlg.getCreatorNameFilter()); gameListProxyModel->setGameTypeFilter(dlg.getGameTypeFilter()); gameListProxyModel->setMaxPlayersFilter(dlg.getMaxPlayersFilterMin(), dlg.getMaxPlayersFilterMax()); + gameListProxyModel->saveFilterParameters(gameTypeMap); } void GameSelector::actClearFilter() { clearFilterButton->setEnabled(false); - + gameListProxyModel->resetFilterParameters(); + gameListProxyModel->saveFilterParameters(gameTypeMap); } void GameSelector::actCreate() @@ -136,7 +139,7 @@ void GameSelector::checkResponse(const Response &response) void GameSelector::actJoin() { bool spectator = sender() == spectateButton; - + QModelIndex ind = gameListView->currentIndex(); if (!ind.isValid()) return; @@ -149,19 +152,19 @@ void GameSelector::actJoin() if (!ok) return; } - + Command_JoinGame cmd; cmd.set_game_id(game.game_id()); cmd.set_password(password.toStdString()); cmd.set_spectator(spectator); cmd.set_override_restrictions(overrideRestrictions); - + TabRoom *r = tabSupervisor->getRoomTabs().value(game.room_id()); if (!r) { QMessageBox::critical(this, tr("Error"), tr("Please join the respective room first.")); return; } - + PendingCommand *pend = r->prepareRoomCommand(cmd); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response))); r->sendRoomCommand(pend); diff --git a/cockatrice/src/gameselector.h b/cockatrice/src/gameselector.h index 47a9c395..8e043850 100644 --- a/cockatrice/src/gameselector.h +++ b/cockatrice/src/gameselector.h @@ -34,6 +34,7 @@ private: GamesModel *gameListModel; GamesProxyModel *gameListProxyModel; QPushButton *filterButton, *clearFilterButton, *createButton, *joinButton, *spectateButton; + GameTypeMap gameTypeMap; public: GameSelector(AbstractClient *_client, const TabSupervisor *_tabSupervisor, TabRoom *_room, const QMap &_rooms, const QMap &_gameTypes, QWidget *parent = 0); void retranslateUi(); diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 112b4324..e8e55d44 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace { const unsigned SECS_PER_MIN = 60; @@ -10,7 +12,7 @@ namespace { /** * Pretty print an integer number of seconds ago. Accurate to only one unit, - * rounded; <5 minutes and >5 hours are displayed as such. As a special case, + * 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... @@ -85,7 +87,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const QDateTime then; then.setTime_t(g.start_time()); unsigned int secs = then.secsTo(QDateTime::currentDateTime()); - + switch (role) { case Qt::DisplayRole: return prettyPrintSecsAgo(secs); case SORT_ROLE: return QVariant(secs); @@ -221,12 +223,62 @@ void GamesProxyModel::resetFilterParameters() gameNameFilter = QString(); creatorNameFilter = QString(); gameTypeFilter.clear(); - maxPlayersFilterMin = -1; - maxPlayersFilterMax = -1; + maxPlayersFilterMin = 1; + maxPlayersFilterMax = DEFAULT_MAX_PLAYERS_MAX; invalidateFilter(); } +void GamesProxyModel::loadFilterParameters(const QMap &allGameTypes) +{ + QSettings settings; + settings.beginGroup("filter_games"); + + unavailableGamesVisible = settings.value("unavailable_games_visible", false).toBool(); + passwordProtectedGamesVisible = settings.value("password_protected_games_visible", false).toBool(); + gameNameFilter = settings.value("game_name_filter", "").toString(); + creatorNameFilter = settings.value("creator_name_filter", "").toString(); + maxPlayersFilterMin = settings.value("min_players", 1).toInt(); + maxPlayersFilterMax = settings.value("max_players", DEFAULT_MAX_PLAYERS_MAX).toInt(); + + QMapIterator gameTypesIterator(allGameTypes); + while (gameTypesIterator.hasNext()) { + gameTypesIterator.next(); + if (settings.value("game_type/" + hashGameType(gameTypesIterator.value()), false).toBool()) { + gameTypeFilter.insert(gameTypesIterator.key()); + } + } + + invalidateFilter(); +} + +void GamesProxyModel::saveFilterParameters(const QMap &allGameTypes) +{ + QSettings settings; + settings.beginGroup("filter_games"); + + settings.setValue("unavailable_games_visible", unavailableGamesVisible); + settings.setValue( + "password_protected_games_visible", + passwordProtectedGamesVisible + ); + settings.setValue("game_name_filter", gameNameFilter); + settings.setValue("creator_name_filter", creatorNameFilter); + + QMapIterator gameTypeIterator(allGameTypes); + while (gameTypeIterator.hasNext()) { + gameTypeIterator.next(); + + settings.setValue( + "game_type/" + hashGameType(gameTypeIterator.value()), + gameTypeFilter.contains(gameTypeIterator.key()) + ); + } + + settings.setValue("min_players", maxPlayersFilterMin); + settings.setValue("max_players", maxPlayersFilterMax); +} + bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourceParent*/) const { GamesModel *model = qobject_cast(sourceModel()); @@ -265,3 +317,7 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourc return true; } + +QString GamesProxyModel::hashGameType(const QString &gameType) const { + return QCryptographicHash::hash(gameType.toUtf8(), QCryptographicHash::Md5).toHex(); +} diff --git a/cockatrice/src/gamesmodel.h b/cockatrice/src/gamesmodel.h index 85432cf1..23c7e592 100644 --- a/cockatrice/src/gamesmodel.h +++ b/cockatrice/src/gamesmodel.h @@ -49,6 +49,14 @@ private: QString gameNameFilter, creatorNameFilter; QSet gameTypeFilter; int maxPlayersFilterMin, maxPlayersFilterMax; + + static const int DEFAULT_MAX_PLAYERS_MAX = 99; + + /* + * The game type might contain special characters, so to use it in + * QSettings we just hash it. + */ + QString hashGameType(const QString &gameType) const; public: GamesProxyModel(QObject *parent = 0, ServerInfo_User *_ownUser = 0); @@ -66,6 +74,8 @@ public: int getMaxPlayersFilterMax() const { return maxPlayersFilterMax; } void setMaxPlayersFilter(int _maxPlayersFilterMin, int _maxPlayersFilterMax); void resetFilterParameters(); + void loadFilterParameters(const QMap &allGameTypes); + void saveFilterParameters(const QMap &allGameTypes); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; };