From 7e08f7df675535ef4d3c5062ff8999cdb5176160 Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Thu, 12 Jun 2025 17:45:01 -0700 Subject: [PATCH 1/4] [VDS] Remove searchFolderName setting (#5970) * [VDS] Remove searchFolderName setting * rename property in ExtraDeckSearchInfo --- ...ual_deck_storage_quick_settings_widget.cpp | 15 -------------- ...isual_deck_storage_quick_settings_widget.h | 3 --- .../visual_deck_storage_search_widget.cpp | 20 ++++++++----------- .../visual_deck_storage_search_widget.h | 2 +- .../visual_deck_storage_widget.cpp | 5 +---- .../src/game/filters/deck_filter_string.h | 4 ++-- cockatrice/src/settings/cache_settings.cpp | 7 ------- cockatrice/src/settings/cache_settings.h | 6 ------ dbconverter/src/mocks.cpp | 3 --- tests/carddatabase/mocks.cpp | 3 --- 10 files changed, 12 insertions(+), 56 deletions(-) diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp index cd085a511..385007c3e 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp @@ -42,14 +42,6 @@ VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidg connect(showBannerCardComboBoxCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(), &SettingsCache::setVisualDeckStorageShowBannerCardComboBox); - // search folder names checkbox - searchFolderNamesCheckBox = new QCheckBox(this); - searchFolderNamesCheckBox->setChecked(SettingsCache::instance().getVisualDeckStorageSearchFolderNames()); - connect(searchFolderNamesCheckBox, &QCheckBox::QT_STATE_CHANGED, this, - &VisualDeckStorageQuickSettingsWidget::searchFolderNamesChanged); - connect(searchFolderNamesCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(), - &SettingsCache::setVisualDeckStorageSearchFolderNames); - // draw unused color identities checkbox drawUnusedColorIdentitiesCheckBox = new QCheckBox(this); drawUnusedColorIdentitiesCheckBox->setChecked( @@ -113,7 +105,6 @@ VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidg this->addSettingsWidget(showTagFilterCheckBox); this->addSettingsWidget(showTagsOnDeckPreviewsCheckBox); this->addSettingsWidget(showBannerCardComboBoxCheckBox); - this->addSettingsWidget(searchFolderNamesCheckBox); this->addSettingsWidget(drawUnusedColorIdentitiesCheckBox); this->addSettingsWidget(unusedColorIdentityOpacityWidget); this->addSettingsWidget(deckPreviewTooltipWidget); @@ -130,7 +121,6 @@ void VisualDeckStorageQuickSettingsWidget::retranslateUi() showTagFilterCheckBox->setText(tr("Show Tag Filter")); showTagsOnDeckPreviewsCheckBox->setText(tr("Show Tags On Deck Previews")); showBannerCardComboBoxCheckBox->setText(tr("Show Banner Card Selection Option")); - searchFolderNamesCheckBox->setText(tr("Include Folder Names in Search")); drawUnusedColorIdentitiesCheckBox->setText(tr("Draw unused Color Identities")); unusedColorIdentitiesOpacityLabel->setText(tr("Unused Color Identities Opacity")); unusedColorIdentitiesOpacitySpinBox->setSuffix("%"); @@ -165,11 +155,6 @@ bool VisualDeckStorageQuickSettingsWidget::getShowTagsOnDeckPreviews() const return showTagsOnDeckPreviewsCheckBox->isChecked(); } -bool VisualDeckStorageQuickSettingsWidget::getSearchFolderNames() const -{ - return searchFolderNamesCheckBox->isChecked(); -} - int VisualDeckStorageQuickSettingsWidget::getUnusedColorIdentitiesOpacity() const { return unusedColorIdentitiesOpacitySpinBox->value(); diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h index d27a9053b..11c1d64e9 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h @@ -23,7 +23,6 @@ class VisualDeckStorageQuickSettingsWidget : public SettingsButtonWidget QCheckBox *showBannerCardComboBoxCheckBox; QCheckBox *showTagFilterCheckBox; QCheckBox *showTagsOnDeckPreviewsCheckBox; - QCheckBox *searchFolderNamesCheckBox; QLabel *unusedColorIdentitiesOpacityLabel; QSpinBox *unusedColorIdentitiesOpacitySpinBox; QLabel *deckPreviewTooltipLabel; @@ -50,7 +49,6 @@ public: bool getShowBannerCardComboBox() const; bool getShowTagFilter() const; bool getShowTagsOnDeckPreviews() const; - bool getSearchFolderNames() const; int getUnusedColorIdentitiesOpacity() const; TooltipType getDeckPreviewTooltip() const; int getCardSize() const; @@ -61,7 +59,6 @@ signals: void showBannerCardComboBoxChanged(bool enabled); void showTagFilterChanged(bool enabled); void showTagsOnDeckPreviewsChanged(bool enabled); - void searchFolderNamesChanged(bool enabled); void unusedColorIdentitiesOpacityChanged(int opacity); void deckPreviewTooltipChanged(TooltipType tooltip); void cardSizeChanged(int scale); diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp index 2998845f1..560e3c6c9 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp @@ -52,17 +52,15 @@ QString VisualDeckStorageSearchWidget::getSearchText() } /** - * Gets the filename used for the search. + * Converts the filepath into a relative filepath starting from the deck folder. + * If the file isn't in the deck folder, then this will just return the filename. * - * if includeFolderName is true, then this returns the relative filepath starting from the deck folder. - * If the file isn't in the deck folder, or includeFolderName is false, then this will just return the filename. - * - * @param filePath The filePath to convert into a search name + * @param filePath The filepath to convert into a relative filepath */ -static QString getFileSearchName(const QString &filePath, bool includeFolderName) +static QString toRelativeFilepath(const QString &filePath) { QString deckPath = SettingsCache::instance().getDeckPath(); - if (includeFolderName && filePath.startsWith(deckPath)) { + if (filePath.startsWith(deckPath)) { return filePath.mid(deckPath.length()); } @@ -71,14 +69,12 @@ static QString getFileSearchName(const QString &filePath, bool includeFolderName return fileName; } -void VisualDeckStorageSearchWidget::filterWidgets(QList widgets, - const QString &searchText, - bool includeFolderName) +void VisualDeckStorageSearchWidget::filterWidgets(QList widgets, const QString &searchText) { auto filterString = DeckFilterString(searchText); for (auto widget : widgets) { - QString fileSearchName = getFileSearchName(widget->filePath, includeFolderName); - widget->filteredBySearch = !filterString.check(widget, {fileSearchName}); + QString relativeFilePath = toRelativeFilepath(widget->filePath); + widget->filteredBySearch = !filterString.check(widget, {relativeFilePath}); } } diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.h index 444ea9a27..e8b91bc5b 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.h +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.h @@ -16,7 +16,7 @@ class VisualDeckStorageSearchWidget : public QWidget public: explicit VisualDeckStorageSearchWidget(VisualDeckStorageWidget *parent); QString getSearchText(); - void filterWidgets(QList widgets, const QString &searchText, bool includeFolderName); + void filterWidgets(QList widgets, const QString &searchText); private: QHBoxLayout *layout; diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp index e82f0c8d6..078b9337f 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp @@ -46,8 +46,6 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare &VisualDeckStorageWidget::updateShowFolders); connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::showTagFilterChanged, this, &VisualDeckStorageWidget::updateTagsVisibility); - connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::searchFolderNamesChanged, this, - &VisualDeckStorageWidget::updateSearchFilter); searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget); searchAndSortLayout->addWidget(sortWidget); @@ -196,8 +194,7 @@ void VisualDeckStorageWidget::updateColorFilter() void VisualDeckStorageWidget::updateSearchFilter() { if (folderWidget) { - searchWidget->filterWidgets(folderWidget->findChildren(), searchWidget->getSearchText(), - quickSettingsWidget->getSearchFolderNames()); + searchWidget->filterWidgets(folderWidget->findChildren(), searchWidget->getSearchText()); folderWidget->updateVisibility(); } } diff --git a/cockatrice/src/game/filters/deck_filter_string.h b/cockatrice/src/game/filters/deck_filter_string.h index dfdb1f1a8..df6eac783 100644 --- a/cockatrice/src/game/filters/deck_filter_string.h +++ b/cockatrice/src/game/filters/deck_filter_string.h @@ -17,9 +17,9 @@ inline Q_LOGGING_CATEGORY(DeckFilterStringLog, "deck_filter_string"); struct ExtraDeckSearchInfo { /** - * The filename used for filtering. Varies based on settings. + * The relative filepath starting from the deck folder */ - QString fileSearchName; + QString relativeFilePath; }; typedef std::function DeckFilter; diff --git a/cockatrice/src/settings/cache_settings.cpp b/cockatrice/src/settings/cache_settings.cpp index acd8cd581..68f7645ce 100644 --- a/cockatrice/src/settings/cache_settings.cpp +++ b/cockatrice/src/settings/cache_settings.cpp @@ -271,7 +271,6 @@ SettingsCache::SettingsCache() visualDeckStorageSortingOrder = settings->value("interface/visualdeckstoragesortingorder", 0).toInt(); visualDeckStorageShowFolders = settings->value("interface/visualdeckstorageshowfolders", true).toBool(); visualDeckStorageShowTagFilter = settings->value("interface/visualdeckstorageshowtagfilter", true).toBool(); - visualDeckStorageSearchFolderNames = settings->value("interface/visualdeckstoragesearchfoldernames", true).toBool(); visualDeckStorageShowBannerCardComboBox = settings->value("interface/visualdeckstorageshowbannercardcombobox", true).toBool(); visualDeckStorageShowTagsOnDeckPreviews = @@ -731,12 +730,6 @@ void SettingsCache::setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T _showTa emit visualDeckStorageShowTagFilterChanged(visualDeckStorageShowTagFilter); } -void SettingsCache::setVisualDeckStorageSearchFolderNames(QT_STATE_CHANGED_T value) -{ - visualDeckStorageSearchFolderNames = value; - settings->setValue("interface/visualdeckstoragesearchfoldernames", visualDeckStorageSearchFolderNames); -} - void SettingsCache::setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T _showBannerCardComboBox) { visualDeckStorageShowBannerCardComboBox = _showBannerCardComboBox; diff --git a/cockatrice/src/settings/cache_settings.h b/cockatrice/src/settings/cache_settings.h index f0861af58..ddf08c578 100644 --- a/cockatrice/src/settings/cache_settings.h +++ b/cockatrice/src/settings/cache_settings.h @@ -146,7 +146,6 @@ private: bool visualDeckStorageShowBannerCardComboBox; bool visualDeckStorageShowTagsOnDeckPreviews; bool visualDeckStorageShowTagFilter; - bool visualDeckStorageSearchFolderNames; int visualDeckStorageCardSize; bool visualDeckStorageDrawUnusedColorIdentities; int visualDeckStorageUnusedColorIdentitiesOpacity; @@ -453,10 +452,6 @@ public: { return visualDeckStorageShowTagFilter; } - bool getVisualDeckStorageSearchFolderNames() const - { - return visualDeckStorageSearchFolderNames; - } bool getVisualDeckStorageShowBannerCardComboBox() const { return visualDeckStorageShowBannerCardComboBox; @@ -851,7 +846,6 @@ public slots: void setVisualDeckStorageSortingOrder(int _visualDeckStorageSortingOrder); void setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T value); void setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T _showTags); - void setVisualDeckStorageSearchFolderNames(QT_STATE_CHANGED_T value); void setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T _showBannerCardComboBox); void setVisualDeckStorageShowTagsOnDeckPreviews(QT_STATE_CHANGED_T _showTags); void setVisualDeckStorageCardSize(int _visualDeckStorageCardSize); diff --git a/dbconverter/src/mocks.cpp b/dbconverter/src/mocks.cpp index acd199759..ad9738a19 100644 --- a/dbconverter/src/mocks.cpp +++ b/dbconverter/src/mocks.cpp @@ -227,9 +227,6 @@ void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T /* value void SettingsCache::setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T /* _showTags */) { } -void SettingsCache::setVisualDeckStorageSearchFolderNames(QT_STATE_CHANGED_T /* value */) -{ -} void SettingsCache::setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T /* _showBannerCardComboBox */) { } diff --git a/tests/carddatabase/mocks.cpp b/tests/carddatabase/mocks.cpp index 8ac925c0b..05d0d2244 100644 --- a/tests/carddatabase/mocks.cpp +++ b/tests/carddatabase/mocks.cpp @@ -231,9 +231,6 @@ void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T /* value void SettingsCache::setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T /* _showTags */) { } -void SettingsCache::setVisualDeckStorageSearchFolderNames(QT_STATE_CHANGED_T /* value */) -{ -} void SettingsCache::setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T /* _showBannerCardComboBox */) { } From 8d0b36d2d4cef1fccde0e6ea3f5db45a19756dac Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:16:35 -0700 Subject: [PATCH 2/4] [VDS] add deck search query options for name, filename, and path (#5975) * implement search expressions * update syntax help --- cockatrice/resources/help/deck_search.md | 14 ++++++++++ .../src/game/filters/deck_filter_string.cpp | 28 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/cockatrice/resources/help/deck_search.md b/cockatrice/resources/help/deck_search.md index e2fa4fe37..95c237b16 100644 --- a/cockatrice/resources/help/deck_search.md +++ b/cockatrice/resources/help/deck_search.md @@ -8,6 +8,20 @@ searches are case insensitive.
[red deck wins](#red deck wins) (Any deck with a display name containing the words red, deck, and wins)
["red deck wins"](#%22red deck wins%22) (Any deck with a display name containing the exact phrase "red deck wins")
+
Deck Name:
+
[n:aggro](#n:aggro) (Any deck with a name containing the word aggro)
+
[n:red n:deck n:wins](#n:red n:deck n:wins) (Any deck with a name containing the words red, deck, and wins)
+
[n:"red deck wins"](#n:%22red deck wins%22) (Any deck with a name containing the exact phrase "red deck wins")
+ +
File Name:
+
[f:aggro](#f:aggro) (Any deck with a filename containing the word aggro)
+
[f:red f:deck f:wins](#f:red f:deck f:wins) (Any deck with a filename containing the words red, deck, and wins)
+
[f:"red deck wins"](#f:%22red deck wins%22) (Any deck with a filename containing the exact phrase "red deck wins")
+ +
Relative Path (starting from the deck folder):
+
[p:aggro](#p:aggro) (Any deck that has "aggro" somewhere in its relative path)
+
[p:edh/](#p:edh/) (Any deck with "edh/" in its relative path, A.K.A. decks in the "edh" folder)
+
Deck Contents (Uses [card search expressions](#cardSearchSyntaxHelp)):
[[plains]] (Any deck that contains at least one card with "plains" in its name)
[[t:legendary]] (Any deck that contains at least one legendary)
diff --git a/cockatrice/src/game/filters/deck_filter_string.cpp b/cockatrice/src/game/filters/deck_filter_string.cpp index 13c39910d..4d493e5f1 100644 --- a/cockatrice/src/game/filters/deck_filter_string.cpp +++ b/cockatrice/src/game/filters/deck_filter_string.cpp @@ -12,7 +12,7 @@ QueryPartList <- ComplexQueryPart ( ws ("AND" ws)? ComplexQueryPart)* ws* ComplexQueryPart <- SomewhatComplexQueryPart ws "OR" ws ComplexQueryPart / SomewhatComplexQueryPart SomewhatComplexQueryPart <- [(] QueryPartList [)] / QueryPart -QueryPart <- NotQuery / DeckContentQuery / GenericQuery +QueryPart <- NotQuery / DeckContentQuery / DeckNameQuery / FileNameQuery / PathQuery / GenericQuery NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart @@ -20,6 +20,10 @@ DeckContentQuery <- CardSearch NumericExpression? CardSearch <- '[[' CardFilterString ']]' CardFilterString <- (!']]'.)* +DeckNameQuery <- ([Dd] 'eck')? [Nn] 'ame'? [:] String +FileNameQuery <- [Ff] ('ile' 'name'?)? [:] String +PathQuery <- [Pp] 'ath'? [:] String + GenericQuery <- String NonDoubleQuoteUnlessEscaped <- '\\\"'. / !["]. @@ -129,6 +133,28 @@ static void setupParserRules() return QString::fromStdString(std::string(sv.sv())); }; + search["DeckNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter { + auto name = std::any_cast(sv[0]); + return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) { + return deck->deckLoader->getName().contains(name, Qt::CaseInsensitive); + }; + }; + + search["FileNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter { + auto name = std::any_cast(sv[0]); + return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) { + auto filename = QFileInfo(deck->filePath).fileName(); + return filename.contains(name, Qt::CaseInsensitive); + }; + }; + + search["PathQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter { + auto name = std::any_cast(sv[0]); + return [=](const DeckPreviewWidget *, const ExtraDeckSearchInfo &info) { + return info.relativeFilePath.contains(name, Qt::CaseInsensitive); + }; + }; + search["GenericQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter { auto name = std::any_cast(sv[0]); return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) { From 0b34d20716e52a909ffec86ebd263e9efef1c4ca Mon Sep 17 00:00:00 2001 From: SlightlyCircuitous <71394296+SlightlyCircuitous@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:53:07 -0400 Subject: [PATCH 3/4] Add "landscapeOrientation" as a valid element (#5966) --- doc/carddatabase_v4/cards.xsd | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/carddatabase_v4/cards.xsd b/doc/carddatabase_v4/cards.xsd index 732a5b5ba..9a879302b 100644 --- a/doc/carddatabase_v4/cards.xsd +++ b/doc/carddatabase_v4/cards.xsd @@ -56,6 +56,7 @@ + From 33946e61bb79452f5fe236a99dafc19cf3571d05 Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Fri, 13 Jun 2025 04:12:46 +0200 Subject: [PATCH 4/4] feat: Configurable colors for card counter (#5882) * feat: Configurable colors for card counter This patch adds support for: - User-defined colors for card counters; - 3 additional types of card counters. The colors used for counters is stored locally and not shared with other users. This is intentional as the feature is likely to be used for improved accessibility. In order to preserve backwards-compatibility, and because I don't have a better idea, counters keep their existing color-based names (Red, Green, Yellow) in menus and in the message log. For consistency, the new counters also get assigned color-based names (Cyan, Purple, Magenta). This choice is a compromise, as allowing user-defined names for counters raises many additional (UI/UX) questions that I don't know how to answer. A good long-term solution would be to include counter names as part of a game definition system and hence would be in scope for #1740. The choice of adding 3 additional types of counters and the Cyan, Purple and Magenta names are not random. The existing code for determining counter colors goes: Red, Green, Yellow, Cyan, Purple, Magenta, Black (unreadable) and thus 6 is the maximum number of counters that existing versions of Cockatrice are able to support. This way, released clients get a degraded experience (cannot interact with the new counters, messages in the server log say "Player X places 1 on Card (now 1)" without specifying 1 of what), but do see the counters properly. Fixes #2020 * Do not use %n * Use SettingsManager * Use qSin instead of sin Fix build failures with old GCC. * Use letters for card counter names * Place card counter actions in separate menu * Remove copy-paste error * include QtMath * Do not color whole settings page * derp --------- Co-authored-by: Zach H --- cockatrice/CMakeLists.txt | 1 + cockatrice/src/dialogs/dlg_settings.cpp | 59 ++++++++++++++++++- cockatrice/src/dialogs/dlg_settings.h | 2 + cockatrice/src/game/board/card_item.cpp | 11 +++- cockatrice/src/game/player/player.cpp | 44 +++++++++----- cockatrice/src/game/player/player.h | 2 +- cockatrice/src/server/message_log_widget.cpp | 22 ++----- cockatrice/src/settings/cache_settings.cpp | 9 +++ cockatrice/src/settings/cache_settings.h | 4 ++ .../src/settings/card_counter_settings.cpp | 56 ++++++++++++++++++ .../src/settings/card_counter_settings.h | 29 +++++++++ cockatrice/src/settings/shortcuts_settings.h | 45 +++++++++++--- oracle/CMakeLists.txt | 1 + 13 files changed, 240 insertions(+), 45 deletions(-) create mode 100644 cockatrice/src/settings/card_counter_settings.cpp create mode 100644 cockatrice/src/settings/card_counter_settings.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 846167d93..ca7912eaf 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -234,6 +234,7 @@ set(cockatrice_SOURCES src/server/user/user_list_manager.cpp src/server/user/user_list_widget.cpp src/settings/cache_settings.cpp + src/settings/card_counter_settings.cpp src/settings/card_database_settings.cpp src/settings/card_override_settings.cpp src/settings/debug_settings.cpp diff --git a/cockatrice/src/dialogs/dlg_settings.cpp b/cockatrice/src/dialogs/dlg_settings.cpp index 63901325f..0b0b86260 100644 --- a/cockatrice/src/dialogs/dlg_settings.cpp +++ b/cockatrice/src/dialogs/dlg_settings.cpp @@ -12,13 +12,17 @@ #include "../game/cards/card_database_manager.h" #include "../main.h" #include "../settings/cache_settings.h" +#include "../settings/card_counter_settings.h" #include "../settings/shortcut_treeview.h" #include "../utility/sequence_edit.h" +#include +#include #include #include #include #include +#include #include #include #include @@ -42,7 +46,7 @@ #include #include #include -#include +#include #define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs" #define WIKI_CUSTOM_SHORTCUTS "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts" @@ -442,6 +446,51 @@ AppearanceSettingsPage::AppearanceSettingsPage() cardsGroupBox = new QGroupBox; cardsGroupBox->setLayout(cardsGrid); + // Card counter colors + + auto *cardCounterColorsLayout = new QGridLayout; + cardCounterColorsLayout->setColumnStretch(1, 1); + cardCounterColorsLayout->setColumnStretch(3, 1); + cardCounterColorsLayout->setColumnStretch(5, 1); + + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); + for (int index = 0; index < 6; ++index) { + auto *pushButton = new QPushButton; + pushButton->setStyleSheet(QString("background-color: %1").arg(cardCounterSettings.color(index).name())); + + connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, pushButton, + [index, pushButton](int changedIndex, const QColor &color) { + if (index == changedIndex) { + pushButton->setStyleSheet(QString("background-color: %1").arg(color.name())); + } + }); + + connect(pushButton, &QPushButton::clicked, this, [index, this]() { + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); + + auto newColor = QColorDialog::getColor(cardCounterSettings.color(index), this); + if (!newColor.isValid()) + return; + + cardCounterSettings.setColor(index, newColor); + }); + + auto *colorName = new QLabel; + cardCounterNames.append(colorName); + + int row = index / 3; + int column = 2 * (index % 3); + + cardCounterColorsLayout->addWidget(pushButton, row, column); + cardCounterColorsLayout->addWidget(colorName, row, column + 1); + } + + auto *cardCountersLayout = new QVBoxLayout; + cardCountersLayout->addLayout(cardCounterColorsLayout, 1); + + cardCountersGroupBox = new QGroupBox; + cardCountersGroupBox->setLayout(cardCountersLayout); + // Hand layout horizontalHandCheckBox.setChecked(settings.getHorizontalHand()); connect(&horizontalHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings, &SettingsCache::setHorizontalHand); @@ -489,6 +538,7 @@ AppearanceSettingsPage::AppearanceSettingsPage() mainLayout->addWidget(themeGroupBox); mainLayout->addWidget(menuGroupBox); mainLayout->addWidget(cardsGroupBox); + mainLayout->addWidget(cardCountersGroupBox); mainLayout->addWidget(handGroupBox); mainLayout->addWidget(tableGroupBox); mainLayout->addStretch(); @@ -577,6 +627,13 @@ void AppearanceSettingsPage::retranslateUi() cardViewExpandedRowsMaxLabel.setText(tr("Maximum expanded height for card view window:")); cardViewExpandedRowsMaxBox.setSuffix(tr(" rows")); + cardCountersGroupBox->setTitle(tr("Card counters")); + + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); + for (int index = 0; index < cardCounterNames.size(); ++index) { + cardCounterNames[index]->setText(tr("Counter %1").arg(cardCounterSettings.displayName(index))); + } + handGroupBox->setTitle(tr("Hand layout")); horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)")); leftJustifiedHandCheckBox.setText(tr("Enable left justification")); diff --git a/cockatrice/src/dialogs/dlg_settings.h b/cockatrice/src/dialogs/dlg_settings.h index 54b2cbcd8..f0b9c62c9 100644 --- a/cockatrice/src/dialogs/dlg_settings.h +++ b/cockatrice/src/dialogs/dlg_settings.h @@ -125,6 +125,8 @@ private: QGroupBox *cardsGroupBox; QGroupBox *handGroupBox; QGroupBox *tableGroupBox; + QGroupBox *cardCountersGroupBox; + QList cardCounterNames; QSpinBox minPlayersForMultiColumnLayoutEdit; QSpinBox maxFontSizeForCardsEdit; diff --git a/cockatrice/src/game/board/card_item.cpp b/cockatrice/src/game/board/card_item.cpp index 55df7a477..f9d702d92 100644 --- a/cockatrice/src/game/board/card_item.cpp +++ b/cockatrice/src/game/board/card_item.cpp @@ -2,6 +2,7 @@ #include "../../client/tabs/tab_game.h" #include "../../settings/cache_settings.h" +#include "../../settings/card_counter_settings.h" #include "../cards/card_info.h" #include "../game_scene.h" #include "../player/player.h" @@ -32,6 +33,11 @@ CardItem::CardItem(Player *_owner, ptMenu = new QMenu; moveMenu = new QMenu; + connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) { + if (counters.contains(counterId)) + update(); + }); + retranslateUi(); } @@ -84,6 +90,8 @@ void CardItem::retranslateUi() void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); + painter->save(); AbstractCardItem::paint(painter, option, widget); @@ -91,8 +99,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QMapIterator counterIterator(counters); while (counterIterator.hasNext()) { counterIterator.next(); - QColor _color; - _color.setHsv(counterIterator.key() * 60, 150, 255); + QColor _color = cardCounterSettings.color(counterIterator.key()); paintNumberEllipse(counterIterator.value(), 14, _color, i, counters.size(), painter); ++i; diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 9fff6b3df..8ce7b0055 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -8,6 +8,7 @@ #include "../../dialogs/dlg_roll_dice.h" #include "../../main.h" #include "../../settings/cache_settings.h" +#include "../../settings/card_counter_settings.h" #include "../board/arrow_item.h" #include "../board/card_item.h" #include "../board/card_list.h" @@ -419,6 +420,8 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T createPredefinedTokenMenu = new QMenu(QString()); createPredefinedTokenMenu->setEnabled(false); + mCardCounters = new QMenu; + playerMenu->addSeparator(); countersMenu = playerMenu->addMenu(QString()); playerMenu->addSeparator(); @@ -461,6 +464,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T mCustomZones = nullptr; aCreateAnotherToken = nullptr; createPredefinedTokenMenu = nullptr; + mCardCounters = nullptr; } aTap = new QAction(this); @@ -538,7 +542,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T aPlayFacedown = new QAction(this); connect(aPlayFacedown, &QAction::triggered, this, &Player::actPlayFacedown); - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 6; ++i) { auto *tempAddCounter = new QAction(this); tempAddCounter->setData(9 + i * 1000); auto *tempRemoveCounter = new QAction(this); @@ -892,19 +896,17 @@ void Player::retranslateUi() aResetPT->setText(tr("Reset p&ower and toughness")); aSetAnnotation->setText(tr("&Set annotation...")); - QStringList counterColors; - counterColors.append(tr("Red")); - counterColors.append(tr("Yellow")); - counterColors.append(tr("Green")); + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); + mCardCounters->setTitle(tr("Ca&rd counters")); for (int i = 0; i < aAddCounter.size(); ++i) { - aAddCounter[i]->setText(tr("&Add counter (%1)").arg(counterColors[i])); + aAddCounter[i]->setText(tr("&Add counter (%1)").arg(cardCounterSettings.displayName(i))); } for (int i = 0; i < aRemoveCounter.size(); ++i) { - aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(counterColors[i])); + aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(cardCounterSettings.displayName(i))); } for (int i = 0; i < aSetCounter.size(); ++i) { - aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(counterColors[i])); + aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(cardCounterSettings.displayName(i))); } aMoveToTopLibrary->setText(tr("&Top of library in random order")); @@ -960,24 +962,33 @@ void Player::setShortcutsActive() addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCRed")); addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCYellow")); addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCGreen")); + addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCCyan")); + addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCPurple")); + addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCMagenta")); QList removeCCShortCuts; removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCRed")); removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCYellow")); removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCGreen")); + removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCCyan")); + removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCPurple")); + removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCMagenta")); QList setCCShortCuts; setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCRed")); setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCYellow")); setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCGreen")); + setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCCyan")); + setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCPurple")); + setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCMagenta")); - for (int i = 0; i < aAddCounter.size(); ++i) { + for (int i = 0; i < addCCShortCuts.size(); ++i) { aAddCounter[i]->setShortcut(addCCShortCuts.at(i)); } - for (int i = 0; i < aRemoveCounter.size(); ++i) { + for (int i = 0; i < removeCCShortCuts.size(); ++i) { aRemoveCounter[i]->setShortcut(removeCCShortCuts.at(i)); } - for (int i = 0; i < aSetCounter.size(); ++i) { + for (int i = 0; i < setCCShortCuts.size(); ++i) { aSetCounter[i]->setShortcut(setCCShortCuts.at(i)); } @@ -3944,15 +3955,18 @@ void Player::updateCardMenu(const CardItem *card) cardMenu->addAction(aSelectAll); cardMenu->addAction(aSelectRow); + cardMenu->addSeparator(); + mCardCounters->clear(); for (int i = 0; i < aAddCounter.size(); ++i) { - cardMenu->addSeparator(); - cardMenu->addAction(aAddCounter[i]); + mCardCounters->addSeparator(); + mCardCounters->addAction(aAddCounter[i]); if (card->getCounters().contains(i)) { - cardMenu->addAction(aRemoveCounter[i]); + mCardCounters->addAction(aRemoveCounter[i]); } - cardMenu->addAction(aSetCounter[i]); + mCardCounters->addAction(aSetCounter[i]); } cardMenu->addSeparator(); + cardMenu->addMenu(mCardCounters); } else if (card->getZone()->getName() == "stack") { // Card is on the stack if (canModifyCard) { diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index d802ef796..9062ac5b4 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -253,7 +253,7 @@ public: private: TabGame *game; QMenu *sbMenu, *countersMenu, *sayMenu, *createPredefinedTokenMenu, *mRevealLibrary, *mLendLibrary, *mRevealTopCard, - *mRevealHand, *mRevealRandomHandCard, *mRevealRandomGraveyardCard, *mCustomZones; + *mRevealHand, *mRevealRandomHandCard, *mRevealRandomGraveyardCard, *mCustomZones, *mCardCounters; TearOffMenu *moveGraveMenu, *moveRfgMenu, *graveMenu, *moveHandMenu, *handMenu, *libraryMenu, *topLibraryMenu, *bottomLibraryMenu, *rfgMenu, *playerMenu; QList playerLists; diff --git a/cockatrice/src/server/message_log_widget.cpp b/cockatrice/src/server/message_log_widget.cpp index a61a7ba2c..ed25801f6 100644 --- a/cockatrice/src/server/message_log_widget.cpp +++ b/cockatrice/src/server/message_log_widget.cpp @@ -6,6 +6,7 @@ #include "../game/phase.h" #include "../game/player/player.h" #include "../game/zones/card_zone.h" +#include "../settings/card_counter_settings.h" #include "pb/context_move_card.pb.h" #include "pb/context_mulligan.pb.h" #include "pb/serverinfo_user.pb.h" @@ -613,28 +614,15 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c QString finalStr; int delta = abs(oldValue - value); if (value > oldValue) { - finalStr = tr("%1 places %2 %3 on %4 (now %5)."); + finalStr = tr("%1 places %2 \"%3\" counter(s) on %4 (now %5).", "", delta); } else { - finalStr = tr("%1 removes %2 %3 from %4 (now %5)."); - } - - QString colorStr; - switch (counterId) { - case 0: - colorStr = tr("red counter(s)", "", delta); - break; - case 1: - colorStr = tr("yellow counter(s)", "", delta); - break; - case 2: - colorStr = tr("green counter(s)", "", delta); - break; - default:; + finalStr = tr("%1 removes %2 \"%3\" counter(s) from %4 (now %5).", "", delta); } + auto &cardCounterSettings = SettingsCache::instance().cardCounters(); appendHtmlServerMessage(finalStr.arg(sanitizeHtml(player->getName())) .arg("" + QString::number(delta) + "") - .arg(colorStr) + .arg(cardCounterSettings.displayName(counterId)) .arg(cardLink(std::move(cardName))) .arg(value)); } diff --git a/cockatrice/src/settings/cache_settings.cpp b/cockatrice/src/settings/cache_settings.cpp index 68f7645ce..65229bee0 100644 --- a/cockatrice/src/settings/cache_settings.cpp +++ b/cockatrice/src/settings/cache_settings.cpp @@ -1,8 +1,10 @@ #include "cache_settings.h" #include "../client/network/release_channel.h" +#include "card_counter_settings.h" #include "card_override_settings.h" +#include #include #include #include @@ -179,6 +181,8 @@ SettingsCache::SettingsCache() cardOverrideSettings = new CardOverrideSettings(settingsPath, this); debugSettings = new DebugSettings(settingsPath, this); + cardCounterSettings = new CardCounterSettings(settingsPath, this); + if (!QFile(settingsPath + "global.ini").exists()) translateLegacySettings(); @@ -1423,3 +1427,8 @@ SettingsCache &SettingsCache::instance() { return *settingsCache; } + +CardCounterSettings &SettingsCache::cardCounters() const +{ + return *cardCounterSettings; +} diff --git a/cockatrice/src/settings/cache_settings.h b/cockatrice/src/settings/cache_settings.h index ddf08c578..d64e74750 100644 --- a/cockatrice/src/settings/cache_settings.h +++ b/cockatrice/src/settings/cache_settings.h @@ -43,6 +43,7 @@ constexpr int NETWORK_CACHE_SIZE_MAX = 1024 * 1024; // 1 TB #define DEFAULT_FONT_SIZE 12 class QSettings; +class CardCounterSettings; class SettingsCache : public QObject { @@ -104,6 +105,7 @@ private: RecentsSettings *recentsSettings; CardOverrideSettings *cardOverrideSettings; DebugSettings *debugSettings; + CardCounterSettings *cardCounterSettings; QByteArray mainWindowGeometry; QByteArray tokenDialogGeometry; @@ -779,6 +781,8 @@ public: { return *debugSettings; } + CardCounterSettings &cardCounters() const; + bool getIsPortableBuild() const { return isPortableBuild; diff --git a/cockatrice/src/settings/card_counter_settings.cpp b/cockatrice/src/settings/card_counter_settings.cpp new file mode 100644 index 000000000..d22eb239f --- /dev/null +++ b/cockatrice/src/settings/card_counter_settings.cpp @@ -0,0 +1,56 @@ +#include "card_counter_settings.h" + +#include +#include +#include + +CardCounterSettings::CardCounterSettings(const QString &settingsPath, QObject *parent) + : SettingsManager(settingsPath + "global.ini", parent) +{ +} + +void CardCounterSettings::setColor(int counterId, const QColor &color) +{ + QString key = QString("cards/counters/%1/color").arg(counterId); + + if (settings.value(key).value() == color) + return; + + settings.setValue(key, color); + emit colorChanged(counterId, color); +} + +QColor CardCounterSettings::color(int counterId) const +{ + QColor defaultColor; + + if (counterId < 6) { + // Preserve legacy colors + defaultColor = QColor::fromHsv(counterId * 60, 150, 255); + } else { + // Future-proof support for more counters with pseudo-random colors + int h = (counterId * 37) % 360; + int s = 128 + 64 * qSin((counterId * 97) * 0.1); // 64-192 + int v = 196 + 32 * qSin((counterId * 101) * 0.07); // 164-228 + + defaultColor = QColor::fromHsv(h, s, v); + } + + return settings.value(QString("cards/counters/%1/color").arg(counterId), defaultColor).value(); +} + +QString CardCounterSettings::displayName(int counterId) const +{ + // Currently, card counters name are fixed to A, B, ..., Z, AA, AB, ... + + auto nChars = 1 + counterId / 26; + QString str; + str.resize(nChars); + + for (auto it = str.rbegin(); it != str.rend(); ++it) { + *it = QChar('A' + (counterId) % 26); + counterId /= 26; + } + + return str; +} diff --git a/cockatrice/src/settings/card_counter_settings.h b/cockatrice/src/settings/card_counter_settings.h new file mode 100644 index 000000000..bb3a9bd57 --- /dev/null +++ b/cockatrice/src/settings/card_counter_settings.h @@ -0,0 +1,29 @@ +#ifndef CARD_COUNTER_SETTINGS_H +#define CARD_COUNTER_SETTINGS_H + +#include "settings_manager.h" + +#include + +class QSettings; +class QColor; + +class CardCounterSettings : public SettingsManager +{ + Q_OBJECT + +public: + CardCounterSettings(const QString &settingsPath, QObject *parent = nullptr); + + QColor color(int counterId) const; + + QString displayName(int counterId) const; + +public slots: + void setColor(int counterId, const QColor &color); + +signals: + void colorChanged(int counterId, const QColor &color); +}; + +#endif // CARD_COUNTER_SETTINGS_H diff --git a/cockatrice/src/settings/shortcuts_settings.h b/cockatrice/src/settings/shortcuts_settings.h index 596781cff..dd8a60b68 100644 --- a/cockatrice/src/settings/shortcuts_settings.h +++ b/cockatrice/src/settings/shortcuts_settings.h @@ -284,31 +284,58 @@ private: {"DeckViewContainer/forceStartGameButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Force Start"), parseSequenceString(""), ShortcutGroup::Game_Lobby)}, - {"Player/aCCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Green Counter"), + {"Player/aCCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (F)"), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aRCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (F)"), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aSCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (F)..."), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aCCPurple", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (E)"), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aRCPurple", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (E)"), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aSCPurple", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (E)..."), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aCCCyan", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter(D)"), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aRCCyan", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (D)"), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aSCCyan", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (D)..."), + parseSequenceString(""), + ShortcutGroup::Card_Counters)}, + {"Player/aCCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (C)"), parseSequenceString("Ctrl+>"), ShortcutGroup::Card_Counters)}, - {"Player/aRCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Green Counter"), + {"Player/aRCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (C)"), parseSequenceString("Ctrl+<"), ShortcutGroup::Card_Counters)}, - {"Player/aSCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Green Counters..."), + {"Player/aSCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (C)..."), parseSequenceString("Ctrl+?"), ShortcutGroup::Card_Counters)}, - {"Player/aCCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Yellow Counter"), + {"Player/aCCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (B)"), parseSequenceString("Ctrl+."), ShortcutGroup::Card_Counters)}, - {"Player/aRCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Yellow Counter"), + {"Player/aRCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (B)"), parseSequenceString("Ctrl+,"), ShortcutGroup::Card_Counters)}, - {"Player/aSCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Yellow Counters..."), + {"Player/aSCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (B)..."), parseSequenceString("Ctrl+/"), ShortcutGroup::Card_Counters)}, - {"Player/aCCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Red Counter"), + {"Player/aCCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (A)"), parseSequenceString("Alt+."), ShortcutGroup::Card_Counters)}, - {"Player/aRCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Red Counter"), + {"Player/aRCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (A)"), parseSequenceString("Alt+,"), ShortcutGroup::Card_Counters)}, - {"Player/aSCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Red Counters..."), + {"Player/aSCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (A)..."), parseSequenceString("Alt+/"), ShortcutGroup::Card_Counters)}, {"Player/aInc", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Life Counter"), diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index ba5dd7284..5015ba234 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -33,6 +33,7 @@ set(oracle_SOURCES ../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp ../cockatrice/src/settings/cache_settings.cpp ../cockatrice/src/settings/shortcuts_settings.cpp + ../cockatrice/src/settings/card_counter_settings.cpp ../cockatrice/src/settings/card_database_settings.cpp ../cockatrice/src/settings/servers_settings.cpp ../cockatrice/src/settings/settings_manager.cpp