(&QComboBox::currentIndexChanged), this,
+ &GeneralSettingsPage::cardLanguageBoxChanged);
+
auto *languageGrid = new QGridLayout;
languageGrid->addWidget(&languageLabel, 0, 0);
languageGrid->addWidget(&languageBox, 0, 1);
- languageGrid->addWidget(&advertiseTranslationPageLabel, 1, 1, Qt::AlignRight);
+ languageGrid->addWidget(&cardLanguageLabel, 1, 0);
+ languageGrid->addWidget(&cardLanguageBox, 1, 1);
+ languageGrid->addWidget(&cardLanguageNoteLabel, 2, 1);
+ languageGrid->addWidget(&advertiseTranslationPageLabel, 3, 1, Qt::AlignRight);
+
+ cardLanguageNoteLabel.setWordWrap(true);
+ cardLanguageNoteLabel.setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
languageGroupBox = new QGroupBox;
languageGroupBox->setLayout(languageGrid);
@@ -412,6 +435,52 @@ void GeneralSettingsPage::languageBoxChanged(int index)
SettingsCache::instance().personal().setLang(languageBox.itemData(index).toString());
}
+void GeneralSettingsPage::cardLanguageBoxChanged(int index)
+{
+ const QString lang = cardLanguageBox.itemData(index).toString();
+ SettingsCache::instance().cardsDisplay().setCardLang(lang);
+
+ // Switching to a non-default language only takes effect after the card
+ // database is re-imported with that language selected; English data is always
+ // present, so switching back to English needs no prompt.
+ if (lang == "en") {
+ return;
+ }
+
+ // The binary cache does not track the language its entries were imported in,
+ // and the downloaded pictures were fetched with English art names, so both are
+ // stale until Oracle re-imports the database in the new language: drop them.
+ QFile::remove(SettingsCache::instance().getCardDatabasePath() + ".cache");
+ CardPictureLoader::clearNetworkCache();
+ CardPictureLoader::clearPixmapCache();
+
+ // Art is resolved by the translated card name for non-English languages, so the
+ // matching Scryfall URL is added to the top of the download list. It stays
+ // visible in the deck editor settings, where it can be removed or reordered.
+ const bool localizedUrlAdded = SettingsCache::instance().downloads().addLocalizedScryfallUrl();
+
+ QString message = tr("The card database only contains English card data. To see cards in %1, "
+ "Oracle must run once with this language selected and re-import the card "
+ "database.
"
+ "The cached database and the downloaded card pictures have been cleared, so a "
+ "re-import is picked up without stale entries.
")
+ .arg(cardLanguageBox.itemText(index));
+ if (localizedUrlAdded) {
+ message += tr("The Scryfall URL that resolves card art by translated name was added to the top of your "
+ "download list. You can remove or reorder it any time.
");
+ }
+ message += tr("Run Oracle now?
");
+
+ const QMessageBox::StandardButton answer = QMessageBox::question(
+ this, tr("Card text & images language changed"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+ // The answer only controls whether Oracle starts right away; the caches stay
+ // cleared so the next import or launch rebuilds them in the new language.
+ if (answer == QMessageBox::Yes) {
+ emit cardDatabaseUpdateRequested();
+ }
+}
+
void GeneralSettingsPage::updateStartupServerControlsVisibility()
{
const int index = startupTabSelector.currentIndex();
@@ -429,6 +498,10 @@ void GeneralSettingsPage::retranslateUi()
languageGroupBox->setTitle(tr("Language settings"));
languageLabel.setText(tr("Language:"));
+ cardLanguageBox.setItemText(0, tr("English"));
+ cardLanguageLabel.setText(tr("Card text & images language:"));
+ cardLanguageNoteLabel.setText(
+ tr("Foreign card names, text and art apply after you update the card database (Oracle)."));
advertiseTranslationPageLabel.setText(
QString("%2").arg(WIKI_TRANSLATION_FAQ).arg(tr("How to help with translations")));
diff --git a/cockatrice/src/interface/widgets/settings_page/general_settings_page.h b/cockatrice/src/interface/widgets/settings_page/general_settings_page.h
index e0c1a47bf..7afba158f 100644
--- a/cockatrice/src/interface/widgets/settings_page/general_settings_page.h
+++ b/cockatrice/src/interface/widgets/settings_page/general_settings_page.h
@@ -23,6 +23,10 @@ public:
static QStringList findQmFiles();
static QString languageName(const QString &lang);
+signals:
+ /// Request to re-import the card database with the newly selected card language
+ void cardDatabaseUpdateRequested();
+
private slots:
void deckPathButtonClicked();
void filtersPathButtonClicked();
@@ -33,6 +37,7 @@ private slots:
void tokenDatabasePathButtonClicked();
void resetAllPathsClicked();
void languageBoxChanged(int index);
+ void cardLanguageBoxChanged(int index);
void updateStartupServerControlsVisibility();
private:
@@ -46,6 +51,10 @@ private:
QComboBox languageBox;
QLabel advertiseTranslationPageLabel;
+ QLabel cardLanguageLabel;
+ QComboBox cardLanguageBox;
+ QLabel cardLanguageNoteLabel;
+
QLabel updateReleaseChannelLabel;
QComboBox updateReleaseChannelBox;
QCheckBox startupUpdateCheckCheckBox;
diff --git a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp
index e4f24ab73..a3b89f8c4 100644
--- a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp
+++ b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp
@@ -1,6 +1,7 @@
#include "messages_settings_page.h"
#include "../../../client/settings/cache_settings.h"
+#include "../../pixel_map_generator.h"
#include "../interface/widgets/utility/get_text_with_max.h"
#include
@@ -59,6 +60,10 @@ MessagesSettingsPage::MessagesSettingsPage()
connect(&roomHistory, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().chat(),
&ChatSettings::setRoomHistory);
+ ignoreAllPrivateMessagesCheckBox.setChecked(SettingsCache::instance().chat().getIgnoreAllPrivateMessages());
+ connect(&ignoreAllPrivateMessagesCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance().chat(),
+ &ChatSettings::setIgnoreAllPrivateMessages);
+
customAlertString = new QLineEdit();
customAlertString->setText(SettingsCache::instance().chat().getHighlightWords());
connect(customAlertString, &QLineEdit::textChanged, &SettingsCache::instance().chat(),
@@ -76,6 +81,7 @@ MessagesSettingsPage::MessagesSettingsPage()
chatGrid->addWidget(&messagePopups, 5, 0);
chatGrid->addWidget(&mentionPopups, 6, 0);
chatGrid->addWidget(&roomHistory, 7, 0);
+ chatGrid->addWidget(&ignoreAllPrivateMessagesCheckBox, 8, 0);
chatGroupBox = new QGroupBox;
chatGroupBox->setLayout(chatGrid);
@@ -102,15 +108,15 @@ MessagesSettingsPage::MessagesSettingsPage()
}
aAdd = new QAction(this);
- aAdd->setIcon(QPixmap("theme:icons/increment"));
+ aAdd->setIcon(themePixmap(QStringLiteral("icons/increment")));
connect(aAdd, &QAction::triggered, this, &MessagesSettingsPage::actAdd);
aEdit = new QAction(this);
- aEdit->setIcon(QPixmap("theme:icons/pencil"));
+ aEdit->setIcon(themePixmap(QStringLiteral("icons/pencil")));
connect(aEdit, &QAction::triggered, this, &MessagesSettingsPage::actEdit);
aRemove = new QAction(this);
- aRemove->setIcon(QPixmap("theme:icons/decrement"));
+ aRemove->setIcon(themePixmap(QStringLiteral("icons/decrement")));
connect(aRemove, &QAction::triggered, this, &MessagesSettingsPage::actRemove);
auto *messageToolBar = new QToolBar;
@@ -256,6 +262,7 @@ void MessagesSettingsPage::retranslateUi()
messagePopups.setText(tr("Enable desktop notifications for private messages"));
mentionPopups.setText(tr("Enable desktop notification for mentions"));
roomHistory.setText(tr("Enable room message history on join"));
+ ignoreAllPrivateMessagesCheckBox.setText(tr("Ignore all private messages"));
hexLabel.setText(tr("(Color is hexadecimal)"));
hexHighlightLabel.setText(tr("(Color is hexadecimal)"));
customAlertStringLabel.setText(tr("Separate words with a space, alphanumeric characters only"));
diff --git a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h
index e98ae0592..436ebbad9 100644
--- a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h
+++ b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h
@@ -40,6 +40,7 @@ private:
QCheckBox messagePopups;
QCheckBox mentionPopups;
QCheckBox roomHistory;
+ QCheckBox ignoreAllPrivateMessagesCheckBox;
QGroupBox *chatGroupBox;
QGroupBox *highlightGroupBox;
QGroupBox *messageGroupBox;
diff --git a/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp
index 1f1867f7c..1277d0e49 100644
--- a/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp
+++ b/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp
@@ -3,6 +3,7 @@
#include "../../../client/settings/cache_settings.h"
#include "../../../client/settings/shortcut_treeview.h"
#include "../../../client/settings/shortcuts_settings.h"
+#include "../../pixel_map_generator.h"
#include "../interface/widgets/utility/custom_line_edit.h"
#include "../interface/widgets/utility/sequence_edit.h"
@@ -47,8 +48,8 @@ ShortcutSettingsPage::ShortcutSettingsPage()
btnResetAll = new QPushButton(this);
btnClearAll = new QPushButton(this);
- btnResetAll->setIcon(QPixmap("theme:icons/update"));
- btnClearAll->setIcon(QPixmap("theme:icons/clearsearch"));
+ btnResetAll->setIcon(themePixmap(QStringLiteral("icons/update")));
+ btnClearAll->setIcon(themePixmap(QStringLiteral("icons/clearsearch")));
// layout
auto *_editLayout = new QGridLayout;
diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp
index 66b68d823..657ef3dbe 100644
--- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp
+++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp
@@ -1,5 +1,6 @@
#include "archidekt_api_response_deck_display_widget.h"
+#include "../../../../../../client/settings/cache_settings.h"
#include "../../../../../deck_loader/card_node_function.h"
#include "../../../../../deck_loader/deck_loader.h"
#include "../../../../cards/card_size_widget.h"
@@ -10,6 +11,7 @@
#include
#include
+#include
ArchidektApiResponseDeckDisplayWidget::ArchidektApiResponseDeckDisplayWidget(QWidget *parent,
ArchidektApiResponseDeck _response,
@@ -120,6 +122,9 @@ ArchidektApiResponseDeckDisplayWidget::ArchidektApiResponseDeckDisplayWidget(QWi
}
model = new DeckListModel(this);
+ model->setDisplayLanguage(SettingsCache::instance().cardsDisplay().getCardLang());
+ connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::cardLangChanged, model,
+ [this](const QString &lang) { model->setDisplayLanguage(lang); });
connect(model, &DeckListModel::modelReset, this, &ArchidektApiResponseDeckDisplayWidget::decklistModelReset);
auto decklist = QSharedPointer(new DeckList);
diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp
index 98b21d0f1..888197f53 100644
--- a/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp
+++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp
@@ -1,6 +1,7 @@
#include "tab_archidekt.h"
#include "../../../../../client/settings/cache_settings.h"
+#include "../../../../pixel_map_generator.h"
#include "../../../cards/additional_info/mana_symbol_widget.h"
#include "../../../utility/completer_utils.h"
#include "../../tab_supervisor.h"
@@ -213,7 +214,7 @@ void TabArchidekt::setupFilterWidgets()
// Format filter (collapsible)
formatButton = new SettingsButtonWidget(secondaryToolbar);
formatButton->setButtonText(tr("Formats"));
- formatButton->setButtonIcon(QPixmap("theme:icons/scale_balanced"));
+ formatButton->setButtonIcon(themePixmap(QStringLiteral("icons/scale_balanced")));
QWidget *formatContainer = new QWidget(secondaryToolbar);
QGridLayout *formatLayout = new QGridLayout(formatContainer);
diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp
index 4f50e38a6..2cbbedfa4 100644
--- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp
+++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp
@@ -1,6 +1,7 @@
#include "commander_bracket_widget.h"
#include "../../../../../client/settings/cache_settings.h"
+#include "../../../../pixel_map_generator.h"
#include "commander_bracket_service.h"
#include
@@ -30,7 +31,7 @@ CommanderBracketWidget::CommanderBracketWidget(QWidget *parent) : QWidget(parent
bracketInfoButton->setEnabled(false);
bracketRefreshButton = new QToolButton(this);
- bracketRefreshButton->setIcon(QPixmap("theme:icons/reload"));
+ bracketRefreshButton->setIcon(themePixmap(QStringLiteral("icons/reload")));
bracketRefreshButton->setAutoRaise(true);
connect(bracketRefreshButton, &QToolButton::clicked, this, &CommanderBracketWidget::requestBracketEstimate);
diff --git a/cockatrice/src/interface/widgets/tabs/tab_account.cpp b/cockatrice/src/interface/widgets/tabs/tab_account.cpp
index 410a48d40..dbcf50966 100644
--- a/cockatrice/src/interface/widgets/tabs/tab_account.cpp
+++ b/cockatrice/src/interface/widgets/tabs/tab_account.cpp
@@ -137,6 +137,11 @@ void TabAccount::retranslateUi()
buddyList->retranslateUi();
ignoreList->retranslateUi();
userInfoBox->retranslateUi();
+
+ buddyList->setToolTip(tr("Buddies are marked with a star in chat, a sound plays when they join or leave the "
+ "server, and they can be invited to buddy-only games."));
+ ignoreList->setToolTip(tr("Ignored users' chat messages are hidden from you, and they cannot send you private "
+ "messages or join your games."));
}
void TabAccount::processListUsersResponse(const Response &response)
diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp
index f9ccd6beb..267491b9a 100644
--- a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp
+++ b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp
@@ -2,6 +2,7 @@
#include "../../../client/settings/cache_settings.h"
#include "../../deck_loader/deck_loader.h"
+#include "../../pixel_map_generator.h"
#include "../deck_share/deck_share_utils.h"
#include "../deck_share/share_bar_widget.h"
#include "../interface/widgets/server/remote/remote_decklist_tree_widget.h"
@@ -19,7 +20,7 @@
#include