Merge branch 'master' into edit-default-tags

This commit is contained in:
BruebachL 2025-06-13 11:57:37 +02:00 committed by GitHub
commit 297654b053
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 294 additions and 83 deletions

View file

@ -235,6 +235,7 @@ set(cockatrice_SOURCES
src/server/user/user_list_manager.cpp src/server/user/user_list_manager.cpp
src/server/user/user_list_widget.cpp src/server/user/user_list_widget.cpp
src/settings/cache_settings.cpp src/settings/cache_settings.cpp
src/settings/card_counter_settings.cpp
src/settings/card_database_settings.cpp src/settings/card_database_settings.cpp
src/settings/card_override_settings.cpp src/settings/card_override_settings.cpp
src/settings/debug_settings.cpp src/settings/debug_settings.cpp

View file

@ -8,6 +8,20 @@ searches are case insensitive.
<dd>[red deck wins](#red deck wins) <small>(Any deck with a display name containing the words red, deck, and wins)</small></dd> <dd>[red deck wins](#red deck wins) <small>(Any deck with a display name containing the words red, deck, and wins)</small></dd>
<dd>["red deck wins"](#%22red deck wins%22) <small>(Any deck with a display name containing the exact phrase "red deck wins")</small></dd> <dd>["red deck wins"](#%22red deck wins%22) <small>(Any deck with a display name containing the exact phrase "red deck wins")</small></dd>
<dt>Deck <u>N</u>ame:</dt>
<dd>[n:aggro](#n:aggro) <small>(Any deck with a name containing the word aggro)</small></dd>
<dd>[n:red n:deck n:wins](#n:red n:deck n:wins) <small>(Any deck with a name containing the words red, deck, and wins)</small></dd>
<dd>[n:"red deck wins"](#n:%22red deck wins%22) <small>(Any deck with a name containing the exact phrase "red deck wins")</small></dd>
<dt><u>F</u>ile Name:</dt>
<dd>[f:aggro](#f:aggro) <small>(Any deck with a filename containing the word aggro)</small></dd>
<dd>[f:red f:deck f:wins](#f:red f:deck f:wins) <small>(Any deck with a filename containing the words red, deck, and wins)</small></dd>
<dd>[f:"red deck wins"](#f:%22red deck wins%22) <small>(Any deck with a filename containing the exact phrase "red deck wins")</small></dd>
<dt>Relative <u>P</u>ath (starting from the deck folder):</dt>
<dd>[p:aggro](#p:aggro) <small>(Any deck that has "aggro" somewhere in its relative path)</small></dd>
<dd>[p:edh/](#p:edh/) <small>(Any deck with "edh/" in its relative path, A.K.A. decks in the "edh" folder)</small></dd>
<dt>Deck Contents (Uses [card search expressions](#cardSearchSyntaxHelp)):</dt> <dt>Deck Contents (Uses [card search expressions](#cardSearchSyntaxHelp)):</dt>
<dd><a href="#[[plains]]">[[plains]]</a> <small>(Any deck that contains at least one card with "plains" in its name)</small></dd> <dd><a href="#[[plains]]">[[plains]]</a> <small>(Any deck that contains at least one card with "plains" in its name)</small></dd>
<dd><a href="#[[t:legendary]]">[[t:legendary]]</a> <small>(Any deck that contains at least one legendary)</small></dd> <dd><a href="#[[t:legendary]]">[[t:legendary]]</a> <small>(Any deck that contains at least one legendary)</small></dd>

View file

@ -42,14 +42,6 @@ VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidg
connect(showBannerCardComboBoxCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(), connect(showBannerCardComboBoxCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
&SettingsCache::setVisualDeckStorageShowBannerCardComboBox); &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 // draw unused color identities checkbox
drawUnusedColorIdentitiesCheckBox = new QCheckBox(this); drawUnusedColorIdentitiesCheckBox = new QCheckBox(this);
drawUnusedColorIdentitiesCheckBox->setChecked( drawUnusedColorIdentitiesCheckBox->setChecked(
@ -113,7 +105,6 @@ VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidg
this->addSettingsWidget(showTagFilterCheckBox); this->addSettingsWidget(showTagFilterCheckBox);
this->addSettingsWidget(showTagsOnDeckPreviewsCheckBox); this->addSettingsWidget(showTagsOnDeckPreviewsCheckBox);
this->addSettingsWidget(showBannerCardComboBoxCheckBox); this->addSettingsWidget(showBannerCardComboBoxCheckBox);
this->addSettingsWidget(searchFolderNamesCheckBox);
this->addSettingsWidget(drawUnusedColorIdentitiesCheckBox); this->addSettingsWidget(drawUnusedColorIdentitiesCheckBox);
this->addSettingsWidget(unusedColorIdentityOpacityWidget); this->addSettingsWidget(unusedColorIdentityOpacityWidget);
this->addSettingsWidget(deckPreviewTooltipWidget); this->addSettingsWidget(deckPreviewTooltipWidget);
@ -130,7 +121,6 @@ void VisualDeckStorageQuickSettingsWidget::retranslateUi()
showTagFilterCheckBox->setText(tr("Show Tag Filter")); showTagFilterCheckBox->setText(tr("Show Tag Filter"));
showTagsOnDeckPreviewsCheckBox->setText(tr("Show Tags On Deck Previews")); showTagsOnDeckPreviewsCheckBox->setText(tr("Show Tags On Deck Previews"));
showBannerCardComboBoxCheckBox->setText(tr("Show Banner Card Selection Option")); showBannerCardComboBoxCheckBox->setText(tr("Show Banner Card Selection Option"));
searchFolderNamesCheckBox->setText(tr("Include Folder Names in Search"));
drawUnusedColorIdentitiesCheckBox->setText(tr("Draw unused Color Identities")); drawUnusedColorIdentitiesCheckBox->setText(tr("Draw unused Color Identities"));
unusedColorIdentitiesOpacityLabel->setText(tr("Unused Color Identities Opacity")); unusedColorIdentitiesOpacityLabel->setText(tr("Unused Color Identities Opacity"));
unusedColorIdentitiesOpacitySpinBox->setSuffix("%"); unusedColorIdentitiesOpacitySpinBox->setSuffix("%");
@ -165,11 +155,6 @@ bool VisualDeckStorageQuickSettingsWidget::getShowTagsOnDeckPreviews() const
return showTagsOnDeckPreviewsCheckBox->isChecked(); return showTagsOnDeckPreviewsCheckBox->isChecked();
} }
bool VisualDeckStorageQuickSettingsWidget::getSearchFolderNames() const
{
return searchFolderNamesCheckBox->isChecked();
}
int VisualDeckStorageQuickSettingsWidget::getUnusedColorIdentitiesOpacity() const int VisualDeckStorageQuickSettingsWidget::getUnusedColorIdentitiesOpacity() const
{ {
return unusedColorIdentitiesOpacitySpinBox->value(); return unusedColorIdentitiesOpacitySpinBox->value();

View file

@ -23,7 +23,6 @@ class VisualDeckStorageQuickSettingsWidget : public SettingsButtonWidget
QCheckBox *showBannerCardComboBoxCheckBox; QCheckBox *showBannerCardComboBoxCheckBox;
QCheckBox *showTagFilterCheckBox; QCheckBox *showTagFilterCheckBox;
QCheckBox *showTagsOnDeckPreviewsCheckBox; QCheckBox *showTagsOnDeckPreviewsCheckBox;
QCheckBox *searchFolderNamesCheckBox;
QLabel *unusedColorIdentitiesOpacityLabel; QLabel *unusedColorIdentitiesOpacityLabel;
QSpinBox *unusedColorIdentitiesOpacitySpinBox; QSpinBox *unusedColorIdentitiesOpacitySpinBox;
QLabel *deckPreviewTooltipLabel; QLabel *deckPreviewTooltipLabel;
@ -50,7 +49,6 @@ public:
bool getShowBannerCardComboBox() const; bool getShowBannerCardComboBox() const;
bool getShowTagFilter() const; bool getShowTagFilter() const;
bool getShowTagsOnDeckPreviews() const; bool getShowTagsOnDeckPreviews() const;
bool getSearchFolderNames() const;
int getUnusedColorIdentitiesOpacity() const; int getUnusedColorIdentitiesOpacity() const;
TooltipType getDeckPreviewTooltip() const; TooltipType getDeckPreviewTooltip() const;
int getCardSize() const; int getCardSize() const;
@ -61,7 +59,6 @@ signals:
void showBannerCardComboBoxChanged(bool enabled); void showBannerCardComboBoxChanged(bool enabled);
void showTagFilterChanged(bool enabled); void showTagFilterChanged(bool enabled);
void showTagsOnDeckPreviewsChanged(bool enabled); void showTagsOnDeckPreviewsChanged(bool enabled);
void searchFolderNamesChanged(bool enabled);
void unusedColorIdentitiesOpacityChanged(int opacity); void unusedColorIdentitiesOpacityChanged(int opacity);
void deckPreviewTooltipChanged(TooltipType tooltip); void deckPreviewTooltipChanged(TooltipType tooltip);
void cardSizeChanged(int scale); void cardSizeChanged(int scale);

View file

@ -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. * @param filePath The filepath to convert into a relative filepath
* 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
*/ */
static QString getFileSearchName(const QString &filePath, bool includeFolderName) static QString toRelativeFilepath(const QString &filePath)
{ {
QString deckPath = SettingsCache::instance().getDeckPath(); QString deckPath = SettingsCache::instance().getDeckPath();
if (includeFolderName && filePath.startsWith(deckPath)) { if (filePath.startsWith(deckPath)) {
return filePath.mid(deckPath.length()); return filePath.mid(deckPath.length());
} }
@ -71,14 +69,12 @@ static QString getFileSearchName(const QString &filePath, bool includeFolderName
return fileName; return fileName;
} }
void VisualDeckStorageSearchWidget::filterWidgets(QList<DeckPreviewWidget *> widgets, void VisualDeckStorageSearchWidget::filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText)
const QString &searchText,
bool includeFolderName)
{ {
auto filterString = DeckFilterString(searchText); auto filterString = DeckFilterString(searchText);
for (auto widget : widgets) { for (auto widget : widgets) {
QString fileSearchName = getFileSearchName(widget->filePath, includeFolderName); QString relativeFilePath = toRelativeFilepath(widget->filePath);
widget->filteredBySearch = !filterString.check(widget, {fileSearchName}); widget->filteredBySearch = !filterString.check(widget, {relativeFilePath});
} }
} }

View file

@ -16,7 +16,7 @@ class VisualDeckStorageSearchWidget : public QWidget
public: public:
explicit VisualDeckStorageSearchWidget(VisualDeckStorageWidget *parent); explicit VisualDeckStorageSearchWidget(VisualDeckStorageWidget *parent);
QString getSearchText(); QString getSearchText();
void filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText, bool includeFolderName); void filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText);
private: private:
QHBoxLayout *layout; QHBoxLayout *layout;

View file

@ -46,8 +46,6 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
&VisualDeckStorageWidget::updateShowFolders); &VisualDeckStorageWidget::updateShowFolders);
connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::showTagFilterChanged, this, connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::showTagFilterChanged, this,
&VisualDeckStorageWidget::updateTagsVisibility); &VisualDeckStorageWidget::updateTagsVisibility);
connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::searchFolderNamesChanged, this,
&VisualDeckStorageWidget::updateSearchFilter);
searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget); searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget);
searchAndSortLayout->addWidget(sortWidget); searchAndSortLayout->addWidget(sortWidget);
@ -196,8 +194,7 @@ void VisualDeckStorageWidget::updateColorFilter()
void VisualDeckStorageWidget::updateSearchFilter() void VisualDeckStorageWidget::updateSearchFilter()
{ {
if (folderWidget) { if (folderWidget) {
searchWidget->filterWidgets(folderWidget->findChildren<DeckPreviewWidget *>(), searchWidget->getSearchText(), searchWidget->filterWidgets(folderWidget->findChildren<DeckPreviewWidget *>(), searchWidget->getSearchText());
quickSettingsWidget->getSearchFolderNames());
folderWidget->updateVisibility(); folderWidget->updateVisibility();
} }
} }

View file

@ -12,13 +12,17 @@
#include "../game/cards/card_database_manager.h" #include "../game/cards/card_database_manager.h"
#include "../main.h" #include "../main.h"
#include "../settings/cache_settings.h" #include "../settings/cache_settings.h"
#include "../settings/card_counter_settings.h"
#include "../settings/shortcut_treeview.h" #include "../settings/shortcut_treeview.h"
#include "../utility/sequence_edit.h" #include "../utility/sequence_edit.h"
#include <QAbstractButton>
#include <QAbstractListModel>
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
#include <QCheckBox> #include <QCheckBox>
#include <QCloseEvent> #include <QCloseEvent>
#include <QColorDialog>
#include <QComboBox> #include <QComboBox>
#include <QDebug> #include <QDebug>
#include <QDesktopServices> #include <QDesktopServices>
@ -42,7 +46,7 @@
#include <QStackedWidget> #include <QStackedWidget>
#include <QToolBar> #include <QToolBar>
#include <QTranslator> #include <QTranslator>
#include <qabstractbutton.h> #include <QVariant>
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs" #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" #define WIKI_CUSTOM_SHORTCUTS "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts"
@ -442,6 +446,51 @@ AppearanceSettingsPage::AppearanceSettingsPage()
cardsGroupBox = new QGroupBox; cardsGroupBox = new QGroupBox;
cardsGroupBox->setLayout(cardsGrid); 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 // Hand layout
horizontalHandCheckBox.setChecked(settings.getHorizontalHand()); horizontalHandCheckBox.setChecked(settings.getHorizontalHand());
connect(&horizontalHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings, &SettingsCache::setHorizontalHand); connect(&horizontalHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings, &SettingsCache::setHorizontalHand);
@ -489,6 +538,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
mainLayout->addWidget(themeGroupBox); mainLayout->addWidget(themeGroupBox);
mainLayout->addWidget(menuGroupBox); mainLayout->addWidget(menuGroupBox);
mainLayout->addWidget(cardsGroupBox); mainLayout->addWidget(cardsGroupBox);
mainLayout->addWidget(cardCountersGroupBox);
mainLayout->addWidget(handGroupBox); mainLayout->addWidget(handGroupBox);
mainLayout->addWidget(tableGroupBox); mainLayout->addWidget(tableGroupBox);
mainLayout->addStretch(); mainLayout->addStretch();
@ -577,6 +627,13 @@ void AppearanceSettingsPage::retranslateUi()
cardViewExpandedRowsMaxLabel.setText(tr("Maximum expanded height for card view window:")); cardViewExpandedRowsMaxLabel.setText(tr("Maximum expanded height for card view window:"));
cardViewExpandedRowsMaxBox.setSuffix(tr(" rows")); 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")); handGroupBox->setTitle(tr("Hand layout"));
horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)")); horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)"));
leftJustifiedHandCheckBox.setText(tr("Enable left justification")); leftJustifiedHandCheckBox.setText(tr("Enable left justification"));

View file

@ -125,6 +125,8 @@ private:
QGroupBox *cardsGroupBox; QGroupBox *cardsGroupBox;
QGroupBox *handGroupBox; QGroupBox *handGroupBox;
QGroupBox *tableGroupBox; QGroupBox *tableGroupBox;
QGroupBox *cardCountersGroupBox;
QList<QLabel *> cardCounterNames;
QSpinBox minPlayersForMultiColumnLayoutEdit; QSpinBox minPlayersForMultiColumnLayoutEdit;
QSpinBox maxFontSizeForCardsEdit; QSpinBox maxFontSizeForCardsEdit;

View file

@ -2,6 +2,7 @@
#include "../../client/tabs/tab_game.h" #include "../../client/tabs/tab_game.h"
#include "../../settings/cache_settings.h" #include "../../settings/cache_settings.h"
#include "../../settings/card_counter_settings.h"
#include "../cards/card_info.h" #include "../cards/card_info.h"
#include "../game_scene.h" #include "../game_scene.h"
#include "../player/player.h" #include "../player/player.h"
@ -32,6 +33,11 @@ CardItem::CardItem(Player *_owner,
ptMenu = new QMenu; ptMenu = new QMenu;
moveMenu = new QMenu; moveMenu = new QMenu;
connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) {
if (counters.contains(counterId))
update();
});
retranslateUi(); retranslateUi();
} }
@ -84,6 +90,8 @@ void CardItem::retranslateUi()
void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
painter->save(); painter->save();
AbstractCardItem::paint(painter, option, widget); AbstractCardItem::paint(painter, option, widget);
@ -91,8 +99,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QMapIterator<int, int> counterIterator(counters); QMapIterator<int, int> counterIterator(counters);
while (counterIterator.hasNext()) { while (counterIterator.hasNext()) {
counterIterator.next(); counterIterator.next();
QColor _color; QColor _color = cardCounterSettings.color(counterIterator.key());
_color.setHsv(counterIterator.key() * 60, 150, 255);
paintNumberEllipse(counterIterator.value(), 14, _color, i, counters.size(), painter); paintNumberEllipse(counterIterator.value(), 14, _color, i, counters.size(), painter);
++i; ++i;

View file

@ -12,7 +12,7 @@ QueryPartList <- ComplexQueryPart ( ws ("AND" ws)? ComplexQueryPart)* ws*
ComplexQueryPart <- SomewhatComplexQueryPart ws "OR" ws ComplexQueryPart / SomewhatComplexQueryPart ComplexQueryPart <- SomewhatComplexQueryPart ws "OR" ws ComplexQueryPart / SomewhatComplexQueryPart
SomewhatComplexQueryPart <- [(] QueryPartList [)] / QueryPart SomewhatComplexQueryPart <- [(] QueryPartList [)] / QueryPart
QueryPart <- NotQuery / DeckContentQuery / GenericQuery QueryPart <- NotQuery / DeckContentQuery / DeckNameQuery / FileNameQuery / PathQuery / GenericQuery
NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart
@ -20,6 +20,10 @@ DeckContentQuery <- CardSearch NumericExpression?
CardSearch <- '[[' CardFilterString ']]' CardSearch <- '[[' CardFilterString ']]'
CardFilterString <- (!']]'.)* CardFilterString <- (!']]'.)*
DeckNameQuery <- ([Dd] 'eck')? [Nn] 'ame'? [:] String
FileNameQuery <- [Ff] ('ile' 'name'?)? [:] String
PathQuery <- [Pp] 'ath'? [:] String
GenericQuery <- String GenericQuery <- String
NonDoubleQuoteUnlessEscaped <- '\\\"'. / !["]. NonDoubleQuoteUnlessEscaped <- '\\\"'. / !["].
@ -129,6 +133,28 @@ static void setupParserRules()
return QString::fromStdString(std::string(sv.sv())); return QString::fromStdString(std::string(sv.sv()));
}; };
search["DeckNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
auto name = std::any_cast<QString>(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<QString>(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<QString>(sv[0]);
return [=](const DeckPreviewWidget *, const ExtraDeckSearchInfo &info) {
return info.relativeFilePath.contains(name, Qt::CaseInsensitive);
};
};
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter { search["GenericQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
auto name = std::any_cast<QString>(sv[0]); auto name = std::any_cast<QString>(sv[0]);
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) { return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {

View file

@ -17,9 +17,9 @@ inline Q_LOGGING_CATEGORY(DeckFilterStringLog, "deck_filter_string");
struct ExtraDeckSearchInfo 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<bool(const DeckPreviewWidget *, const ExtraDeckSearchInfo &)> DeckFilter; typedef std::function<bool(const DeckPreviewWidget *, const ExtraDeckSearchInfo &)> DeckFilter;

View file

@ -8,6 +8,7 @@
#include "../../dialogs/dlg_roll_dice.h" #include "../../dialogs/dlg_roll_dice.h"
#include "../../main.h" #include "../../main.h"
#include "../../settings/cache_settings.h" #include "../../settings/cache_settings.h"
#include "../../settings/card_counter_settings.h"
#include "../board/arrow_item.h" #include "../board/arrow_item.h"
#include "../board/card_item.h" #include "../board/card_item.h"
#include "../board/card_list.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 = new QMenu(QString());
createPredefinedTokenMenu->setEnabled(false); createPredefinedTokenMenu->setEnabled(false);
mCardCounters = new QMenu;
playerMenu->addSeparator(); playerMenu->addSeparator();
countersMenu = playerMenu->addMenu(QString()); countersMenu = playerMenu->addMenu(QString());
playerMenu->addSeparator(); playerMenu->addSeparator();
@ -461,6 +464,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
mCustomZones = nullptr; mCustomZones = nullptr;
aCreateAnotherToken = nullptr; aCreateAnotherToken = nullptr;
createPredefinedTokenMenu = nullptr; createPredefinedTokenMenu = nullptr;
mCardCounters = nullptr;
} }
aTap = new QAction(this); 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); aPlayFacedown = new QAction(this);
connect(aPlayFacedown, &QAction::triggered, this, &Player::actPlayFacedown); 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); auto *tempAddCounter = new QAction(this);
tempAddCounter->setData(9 + i * 1000); tempAddCounter->setData(9 + i * 1000);
auto *tempRemoveCounter = new QAction(this); auto *tempRemoveCounter = new QAction(this);
@ -892,19 +896,17 @@ void Player::retranslateUi()
aResetPT->setText(tr("Reset p&ower and toughness")); aResetPT->setText(tr("Reset p&ower and toughness"));
aSetAnnotation->setText(tr("&Set annotation...")); aSetAnnotation->setText(tr("&Set annotation..."));
QStringList counterColors; auto &cardCounterSettings = SettingsCache::instance().cardCounters();
counterColors.append(tr("Red"));
counterColors.append(tr("Yellow"));
counterColors.append(tr("Green"));
mCardCounters->setTitle(tr("Ca&rd counters"));
for (int i = 0; i < aAddCounter.size(); ++i) { 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) { 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) { 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")); 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/aCCRed"));
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCYellow")); addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCYellow"));
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCGreen")); 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<QKeySequence> removeCCShortCuts; QList<QKeySequence> removeCCShortCuts;
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCRed")); removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCRed"));
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCYellow")); removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCYellow"));
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCGreen")); 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<QKeySequence> setCCShortCuts; QList<QKeySequence> setCCShortCuts;
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCRed")); setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCRed"));
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCYellow")); setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCYellow"));
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCGreen")); 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)); 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)); 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)); aSetCounter[i]->setShortcut(setCCShortCuts.at(i));
} }
@ -3944,15 +3955,18 @@ void Player::updateCardMenu(const CardItem *card)
cardMenu->addAction(aSelectAll); cardMenu->addAction(aSelectAll);
cardMenu->addAction(aSelectRow); cardMenu->addAction(aSelectRow);
cardMenu->addSeparator();
mCardCounters->clear();
for (int i = 0; i < aAddCounter.size(); ++i) { for (int i = 0; i < aAddCounter.size(); ++i) {
cardMenu->addSeparator(); mCardCounters->addSeparator();
cardMenu->addAction(aAddCounter[i]); mCardCounters->addAction(aAddCounter[i]);
if (card->getCounters().contains(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->addSeparator();
cardMenu->addMenu(mCardCounters);
} else if (card->getZone()->getName() == "stack") { } else if (card->getZone()->getName() == "stack") {
// Card is on the stack // Card is on the stack
if (canModifyCard) { if (canModifyCard) {

View file

@ -253,7 +253,7 @@ public:
private: private:
TabGame *game; TabGame *game;
QMenu *sbMenu, *countersMenu, *sayMenu, *createPredefinedTokenMenu, *mRevealLibrary, *mLendLibrary, *mRevealTopCard, 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, TearOffMenu *moveGraveMenu, *moveRfgMenu, *graveMenu, *moveHandMenu, *handMenu, *libraryMenu, *topLibraryMenu,
*bottomLibraryMenu, *rfgMenu, *playerMenu; *bottomLibraryMenu, *rfgMenu, *playerMenu;
QList<QMenu *> playerLists; QList<QMenu *> playerLists;

View file

@ -6,6 +6,7 @@
#include "../game/phase.h" #include "../game/phase.h"
#include "../game/player/player.h" #include "../game/player/player.h"
#include "../game/zones/card_zone.h" #include "../game/zones/card_zone.h"
#include "../settings/card_counter_settings.h"
#include "pb/context_move_card.pb.h" #include "pb/context_move_card.pb.h"
#include "pb/context_mulligan.pb.h" #include "pb/context_mulligan.pb.h"
#include "pb/serverinfo_user.pb.h" #include "pb/serverinfo_user.pb.h"
@ -613,28 +614,15 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c
QString finalStr; QString finalStr;
int delta = abs(oldValue - value); int delta = abs(oldValue - value);
if (value > oldValue) { 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 { } else {
finalStr = tr("%1 removes %2 %3 from %4 (now %5)."); finalStr = tr("%1 removes %2 \"%3\" counter(s) from %4 (now %5).", "", delta);
}
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:;
} }
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
appendHtmlServerMessage(finalStr.arg(sanitizeHtml(player->getName())) appendHtmlServerMessage(finalStr.arg(sanitizeHtml(player->getName()))
.arg("<font class=\"blue\">" + QString::number(delta) + "</font>") .arg("<font class=\"blue\">" + QString::number(delta) + "</font>")
.arg(colorStr) .arg(cardCounterSettings.displayName(counterId))
.arg(cardLink(std::move(cardName))) .arg(cardLink(std::move(cardName)))
.arg(value)); .arg(value));
} }

View file

@ -1,8 +1,10 @@
#include "cache_settings.h" #include "cache_settings.h"
#include "../client/network/release_channel.h" #include "../client/network/release_channel.h"
#include "card_counter_settings.h"
#include "card_override_settings.h" #include "card_override_settings.h"
#include <QAbstractListModel>
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@ -179,6 +181,8 @@ SettingsCache::SettingsCache()
cardOverrideSettings = new CardOverrideSettings(settingsPath, this); cardOverrideSettings = new CardOverrideSettings(settingsPath, this);
debugSettings = new DebugSettings(settingsPath, this); debugSettings = new DebugSettings(settingsPath, this);
cardCounterSettings = new CardCounterSettings(settingsPath, this);
if (!QFile(settingsPath + "global.ini").exists()) if (!QFile(settingsPath + "global.ini").exists())
translateLegacySettings(); translateLegacySettings();
@ -1439,3 +1443,8 @@ SettingsCache &SettingsCache::instance()
{ {
return *settingsCache; return *settingsCache;
} }
CardCounterSettings &SettingsCache::cardCounters() const
{
return *cardCounterSettings;
}

View file

@ -123,6 +123,7 @@ inline QStringList defaultTags = {
}; };
class QSettings; class QSettings;
class CardCounterSettings;
class SettingsCache : public QObject class SettingsCache : public QObject
{ {
@ -185,6 +186,7 @@ private:
RecentsSettings *recentsSettings; RecentsSettings *recentsSettings;
CardOverrideSettings *cardOverrideSettings; CardOverrideSettings *cardOverrideSettings;
DebugSettings *debugSettings; DebugSettings *debugSettings;
CardCounterSettings *cardCounterSettings;
QByteArray mainWindowGeometry; QByteArray mainWindowGeometry;
QByteArray tokenDialogGeometry; QByteArray tokenDialogGeometry;
@ -870,6 +872,8 @@ public:
{ {
return *debugSettings; return *debugSettings;
} }
CardCounterSettings &cardCounters() const;
bool getIsPortableBuild() const bool getIsPortableBuild() const
{ {
return isPortableBuild; return isPortableBuild;

View file

@ -0,0 +1,56 @@
#include "card_counter_settings.h"
#include <QColor>
#include <QSettings>
#include <QtMath>
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<QColor>() == 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<QColor>();
}
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;
}

View file

@ -0,0 +1,29 @@
#ifndef CARD_COUNTER_SETTINGS_H
#define CARD_COUNTER_SETTINGS_H
#include "settings_manager.h"
#include <QObject>
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

View file

@ -284,31 +284,58 @@ private:
{"DeckViewContainer/forceStartGameButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Force Start"), {"DeckViewContainer/forceStartGameButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Force Start"),
parseSequenceString(""), parseSequenceString(""),
ShortcutGroup::Game_Lobby)}, 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+>"), parseSequenceString("Ctrl+>"),
ShortcutGroup::Card_Counters)}, 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+<"), parseSequenceString("Ctrl+<"),
ShortcutGroup::Card_Counters)}, 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+?"), parseSequenceString("Ctrl+?"),
ShortcutGroup::Card_Counters)}, 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+."), parseSequenceString("Ctrl+."),
ShortcutGroup::Card_Counters)}, 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+,"), parseSequenceString("Ctrl+,"),
ShortcutGroup::Card_Counters)}, 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+/"), parseSequenceString("Ctrl+/"),
ShortcutGroup::Card_Counters)}, 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+."), parseSequenceString("Alt+."),
ShortcutGroup::Card_Counters)}, 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+,"), parseSequenceString("Alt+,"),
ShortcutGroup::Card_Counters)}, 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+/"), parseSequenceString("Alt+/"),
ShortcutGroup::Card_Counters)}, ShortcutGroup::Card_Counters)},
{"Player/aInc", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Life Counter"), {"Player/aInc", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Life Counter"),

View file

@ -56,6 +56,7 @@
<xs:element type="xs:integer" name="tablerow" minOccurs="0" maxOccurs="1" /> <xs:element type="xs:integer" name="tablerow" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:boolean" name="cipt" minOccurs="0" maxOccurs="1" /> <xs:element type="xs:boolean" name="cipt" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:boolean" name="upsidedown" minOccurs="0" maxOccurs="1" /> <xs:element type="xs:boolean" name="upsidedown" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:boolean" name="landscapeOrientation" minOccurs="0" maxOccurs="1" />
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:element name="cockatrice_carddatabase"> <xs:element name="cockatrice_carddatabase">

View file

@ -33,6 +33,7 @@ set(oracle_SOURCES
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp ../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
../cockatrice/src/settings/cache_settings.cpp ../cockatrice/src/settings/cache_settings.cpp
../cockatrice/src/settings/shortcuts_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/card_database_settings.cpp
../cockatrice/src/settings/servers_settings.cpp ../cockatrice/src/settings/servers_settings.cpp
../cockatrice/src/settings/settings_manager.cpp ../cockatrice/src/settings/settings_manager.cpp