diff --git a/cockatrice/cockatrice_en@source.ts b/cockatrice/cockatrice_en@source.ts index be95b2f58..284dd81aa 100644 --- a/cockatrice/cockatrice_en@source.ts +++ b/cockatrice/cockatrice_en@source.ts @@ -131,123 +131,128 @@ Please check that the directory is writable and try again. AppearanceSettingsPage - + Error - + Could not create themes directory at '%1'. - + Theme settings - + Current theme: - + Open themes folder - + Menu settings - + Show keyboard shortcuts in right-click menus - + Card rendering - + Display card names on cards having a picture - + Auto-Rotate cards with sideways layout - + Override all card art with personal set preference (Pre-ProviderID change behavior) [Requires Client restart] - + Bump sets that the deck contains cards from to the top in the printing selector - + Scale cards on mouse over - - Minimum overlap percentage of cards on the stack and in vertical hand - - - - - Maximum initial height for card view window: - - - - - rows - - - - - Maximum expanded height for card view window: + Use rounded card corners - Hand layout + Minimum overlap percentage of cards on the stack and in vertical hand - Display hand horizontally (wastes space) + Maximum initial height for card view window: - Enable left justification - - - - Table grid layout + rows - - Invert vertical coordinate + + Maximum expanded height for card view window: - Minimum player count for multi-column layout: + Hand layout + Display hand horizontally (wastes space) + + + + + Enable left justification + + + + + Table grid layout + + + + + Invert vertical coordinate + + + + + Minimum player count for multi-column layout: + + + + Maximum font size for information displayed on cards: @@ -533,22 +538,22 @@ This is only saved for moderators and cannot be seen by the banned person. CardInfoPictureWidget - + View related cards - + Add card to deck - + Mainboard - + Sideboard @@ -963,166 +968,166 @@ This is only saved for moderators and cannot be seen by the banned person. DeckEditorSettingsPage - - + + Update Spoilers - - + + Success - + Download URLs have been reset. - + Downloaded card pictures have been reset. - + Error - + One or more downloaded card pictures could not be cleared. - + Add URL - - + + URL: - - + + Edit URL - + Network Cache Size: - + Redirect Cache TTL: - + How long cached redirects for urls are valid for. - + Picture Cache Size: - + Add New URL - + Remove URL - + Day(s) - + Updating... - + Choose path - + URL Download Priority - + Spoilers - + Download Spoilers Automatically - + Spoiler Location: - + Last Change - + Spoilers download automatically on launch - + Press the button to manually update without relaunching - + Do not close settings until manual update is complete - + Download card pictures on the fly - + How to add a custom URL - + Delete Downloaded Images - + Reset Download URLs - + On-disk cache for downloaded pictures - + In-memory cache for pictures not currently on screen @@ -2496,12 +2501,12 @@ Your email will be used to verify your account. DlgSettings - + Unknown Error loading card database - + Your card database is invalid. Cockatrice may not function correctly with an invalid database @@ -2512,7 +2517,7 @@ Would you like to change your database location setting? - + Your card database version is too old. This can cause problems loading card information or images @@ -2523,7 +2528,7 @@ Would you like to change your database location setting? - + Your card database did not finish loading Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues with your cards.xml attached @@ -2532,21 +2537,21 @@ Would you like to change your database location setting? - + File Error loading your card database. Would you like to change your database location setting? - + Your card database was loaded but contains no cards. Would you like to change your database location setting? - + Unknown card database load status Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues @@ -2555,59 +2560,59 @@ Would you like to change your database location setting? - - - + + + Error - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + General - + Appearance - + User Interface - + Card Sources - + Chat - + Sound - + Shortcuts @@ -3059,102 +3064,102 @@ You may have to build from source yourself. GeneralSettingsPage - + Reset all paths - + All paths have been reset - - - - - - + + + + + + Choose path - + Personal settings - + Language: - + Paths (editing disabled in portable mode) - + Paths - + How to help with translations - + Decks directory: - + Replays directory: - + Pictures directory: - + Card database: - + Custom database directory: - + Token database: - + Update channel - + Check for client updates on startup - + Notify if a feature supported by the server is missing in my client - + Automatically run Oracle when running a new version of Cockatrice - + Show tips on startup @@ -4554,110 +4559,110 @@ Cockatrice will now reload the card database. MessagesSettingsPage - + Word1 Word2 Word3 - + Add New Message - + Edit Message - + Remove Message - + Add message - - + + Message: - + Edit message - + Chat settings - + Custom alert words - + Enable chat mentions - + Enable mention completer - + In-game message macros - + How to use in-game message macros - + Ignore chat room messages sent by unregistered users - + Ignore private messages sent by unregistered users - - + + Invert text color - + Enable desktop notifications for private messages - + Enable desktop notification for mentions - + Enable room message history on join - - + + (Color is hexadecimal) - + Separate words with a space, alphanumeric characters only @@ -5524,10 +5529,15 @@ Cockatrice will now reload the card database. PrintingSelector - + Display Navigation Buttons + + + <b>Warning:</b> You appear to be using custom card art, which has known bugs when also using the printing selector in this version of Cockatrice. + + PrintingSelectorCardOverlayWidget @@ -5919,53 +5929,53 @@ Cockatrice will now reload the card database. ShortcutSettingsPage - - + + Restore all default shortcuts - + Do you really want to restore all default shortcuts? - + Clear all default shortcuts - + Do you really want to clear all shortcuts? - + Section: - + Action: - + Shortcut: - + How to set custom shortcuts - + Clear all shortcuts - + Search by shortcut name @@ -6019,27 +6029,27 @@ Please check your shortcut settings! SoundSettingsPage - + Enable &sounds - + Current sounds theme: - + Test system sound engine - + Sound settings - + Master volume @@ -7634,102 +7644,102 @@ Please refrain from engaging in this activity or further actions may be taken ag UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + &Clicking plays all selected cards (instead of just the clicked card) - + &Play all nonlands onto the stack (not the battlefield) by default - + Close card view window when last card is removed - + Annotate card text on tokens - + Use tear-off menus, allowing right click menus to persist on screen - + Notifications settings - + Enable notifications in taskbar - + Notify in the taskbar for game events while you are spectating - + Notify in the taskbar when users in your buddy list connect - + Animation settings - + &Tap/untap animation - + Deck editor/storage settings - + Open deck in new tab by default - + Prompt before converting .txt decks to .cod format - + Always convert if not prompted - + Use visual deck storage in game lobby - + Replay settings - + Buffer time for backwards skip via shortcut: diff --git a/cockatrice/src/client/ui/picture_loader/picture_loader.cpp b/cockatrice/src/client/ui/picture_loader/picture_loader.cpp index 7d981aee6..97c382b96 100644 --- a/cockatrice/src/client/ui/picture_loader/picture_loader.cpp +++ b/cockatrice/src/client/ui/picture_loader/picture_loader.cpp @@ -195,3 +195,31 @@ void PictureLoader::picsPathChanged() { QPixmapCache::clear(); } + +bool PictureLoader::hasCustomArt() +{ + auto picsPath = SettingsCache::instance().getPicsPath(); + QDirIterator it(picsPath, QDir::Dirs | QDir::NoDotAndDotDot); + + // Check if there is at least one non-directory file in the pics path, other + // than in the "downloadedPics" subdirectory. + while (it.hasNext()) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) + QFileInfo dir(it.nextFileInfo()); +#else + // nextFileInfo() is only available in Qt 6.3+, for previous versions, we build + // the QFileInfo from a QString which requires more system calls. + QFileInfo dir(it.next()); +#endif + + if (it.fileName() == "downloadedPics") + continue; + + QDirIterator subIt(it.filePath(), QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); + if (subIt.hasNext()) { + return true; + } + } + + return false; +} diff --git a/cockatrice/src/client/ui/picture_loader/picture_loader.h b/cockatrice/src/client/ui/picture_loader/picture_loader.h index 8819bddac..68a9424e4 100644 --- a/cockatrice/src/client/ui/picture_loader/picture_loader.h +++ b/cockatrice/src/client/ui/picture_loader/picture_loader.h @@ -36,6 +36,7 @@ public: static void clearPixmapCache(CardInfoPtr card); static void clearPixmapCache(); static void cacheCardPixmaps(QList cards); + static bool hasCustomArt(); public slots: static void clearNetworkCache(); diff --git a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp index 9d79d1a36..09facc5a7 100644 --- a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp +++ b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp @@ -16,11 +16,14 @@ QStringList PictureLoaderWorker::md5Blacklist = QStringList() << "db0c48db407a90 PictureLoaderWorker::PictureLoaderWorker() : QObject(nullptr), picsPath(SettingsCache::instance().getPicsPath()), customPicsPath(SettingsCache::instance().getCustomPicsPath()), - picDownload(SettingsCache::instance().getPicDownload()), downloadRunning(false), loadQueueRunning(false) + picDownload(SettingsCache::instance().getPicDownload()), downloadRunning(false), loadQueueRunning(false), + overrideAllCardArtWithPersonalPreference(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference()) { connect(this, SIGNAL(startLoadQueue()), this, SLOT(processLoadQueue()), Qt::QueuedConnection); connect(&SettingsCache::instance(), SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged())); connect(&SettingsCache::instance(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged())); + connect(&SettingsCache::instance(), &SettingsCache::overrideAllCardArtWithPersonalPreferenceChanged, this, + &PictureLoaderWorker::setOverrideAllCardArtWithPersonalPreference); networkManager = new QNetworkAccessManager(this); // We need a timeout to ensure requests don't hang indefinitely in case of @@ -83,11 +86,24 @@ void PictureLoaderWorker::processLoadQueue() qCDebug(PictureLoaderWorkerLog).nospace() << "[card: " << cardName << " set: " << setName << "]: Trying to load picture"; - if (CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting( - cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) { - if (cardImageExistsOnDisk(setName, correctedCardName)) { - continue; - } + // FIXME: This is a hack so that to keep old Cockatrice behavior + // (ignoring provider ID) when the "override all card art with personal + // preference" is set. + // + // Figure out a proper way to integrate the two systems at some point. + // + // Note: need to go through a member for + // overrideAllCardArtWithPersonalPreference as reading from the + // SettingsCache instance from the PictureLoaderWorker thread could + // cause race conditions. + // + // XXX: Reading from the CardDatabaseManager instance from the + // PictureLoaderWorker thread might not be safe either + bool searchCustomPics = overrideAllCardArtWithPersonalPreference || + CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting( + cardName, cardBeingLoaded.getCard()->getPixmapCacheKey()); + if (searchCustomPics && cardImageExistsOnDisk(setName, correctedCardName, searchCustomPics)) { + continue; } qCDebug(PictureLoaderWorkerLog).nospace() @@ -100,23 +116,26 @@ void PictureLoaderWorker::processLoadQueue() } } -bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &correctedCardname) +bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &correctedCardname, bool searchCustomPics) { QImage image; QImageReader imgReader; imgReader.setDecideFormatFromContent(true); QList picsPaths = QList(); - QDirIterator it(customPicsPath, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); - // Recursively check all subdirectories of the CUSTOM folder - while (it.hasNext()) { - QString thisPath(it.next()); - QFileInfo thisFileInfo(thisPath); + if (searchCustomPics) { + QDirIterator it(customPicsPath, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); - if (thisFileInfo.isFile() && - (thisFileInfo.fileName() == correctedCardname || thisFileInfo.completeBaseName() == correctedCardname || - thisFileInfo.baseName() == correctedCardname)) { - picsPaths << thisPath; // Card found in the CUSTOM directory, somewhere + // Recursively check all subdirectories of the CUSTOM folder + while (it.hasNext()) { + QString thisPath(it.next()); + QFileInfo thisFileInfo(thisPath); + + if (thisFileInfo.isFile() && + (thisFileInfo.fileName() == correctedCardname || thisFileInfo.completeBaseName() == correctedCardname || + thisFileInfo.baseName() == correctedCardname)) { + picsPaths << thisPath; // Card found in the CUSTOM directory, somewhere + } } } @@ -451,7 +470,12 @@ void PictureLoaderWorker::picsPathChanged() customPicsPath = SettingsCache::instance().getCustomPicsPath(); } +void PictureLoaderWorker::setOverrideAllCardArtWithPersonalPreference(bool _overrideAllCardArtWithPersonalPreference) +{ + overrideAllCardArtWithPersonalPreference = _overrideAllCardArtWithPersonalPreference; +} + void PictureLoaderWorker::clearNetworkCache() { networkManager->cache()->clear(); -} \ No newline at end of file +} diff --git a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h index 823bcd7ec..e85ede8f1 100644 --- a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h +++ b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h @@ -42,8 +42,16 @@ private: PictureToLoad cardBeingLoaded; PictureToLoad cardBeingDownloaded; bool picDownload, downloadRunning, loadQueueRunning; + bool overrideAllCardArtWithPersonalPreference; void startNextPicDownload(); - bool cardImageExistsOnDisk(QString &setName, QString &correctedCardName); + + /** Emit the `imageLoaded` signal and return `true` if a picture is found on + disk, return `false` otherwise. + + If `searchCustomPics` is `true`, the CUSTOM folder is searched for a + matching image first; otherwise, only the set-based folders are used. */ + bool cardImageExistsOnDisk(QString &setName, QString &correctedCardName, bool searchCustomPics); + bool imageIsBlackListed(const QByteArray &); QNetworkReply *makeRequest(const QUrl &url); void cacheRedirect(const QUrl &originalUrl, const QUrl &redirectUrl); @@ -58,6 +66,7 @@ private slots: void picDownloadChanged(); void picsPathChanged(); + void setOverrideAllCardArtWithPersonalPreference(bool _overrideAllCardArtWithPersonalPreference); public slots: void processLoadQueue(); diff --git a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp index c0605fc39..ef3816049 100644 --- a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp +++ b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp @@ -1,12 +1,15 @@ #include "printing_selector.h" #include "../../../../settings/cache_settings.h" +#include "../../picture_loader/picture_loader.h" #include "printing_selector_card_display_widget.h" #include "printing_selector_card_search_widget.h" #include "printing_selector_card_selection_widget.h" #include "printing_selector_card_sorting_widget.h" +#include #include +#include /** * @brief Constructs a PrintingSelector widget to display and manage card printings. @@ -29,6 +32,24 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck layout = new QVBoxLayout(this); setLayout(layout); + if (PictureLoader::hasCustomArt()) { + QFrame *warningFrame = new QFrame(this); + warningFrame->setFrameShape(QFrame::StyledPanel); + + warningLabel = new QLabel(this); + warningLabel->setTextFormat(Qt::RichText); + warningLabel->setWordWrap(true); + + auto *warningLayout = new QVBoxLayout(warningFrame); + warningFrame->setLayout(warningLayout); + + warningLayout->addWidget(warningLabel); + + layout->addWidget(warningFrame); + } else { + warningLabel = nullptr; + } + widgetLoadingBufferTimer = new QTimer(this); flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded); @@ -83,6 +104,12 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck void PrintingSelector::retranslateUi() { navigationCheckBox->setText(tr("Display Navigation Buttons")); + + if (warningLabel) { + warningLabel->setText( + tr("Warning: You appear to be using custom card art, which has known bugs when also " + "using the printing selector in this version of Cockatrice.")); + } } void PrintingSelector::printingsInDeckChanged() diff --git a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h index fd360f37a..ea2e69a5f 100644 --- a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h +++ b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h @@ -46,6 +46,7 @@ private: QWidget *sortAndOptionsContainer; QHBoxLayout *sortAndOptionsLayout; QCheckBox *navigationCheckBox; + QLabel *warningLabel; PrintingSelectorCardSortingWidget *sortToolBar; PrintingSelectorCardSearchWidget *searchBar; FlowWidget *flowWidget; diff --git a/cockatrice/src/settings/cache_settings.cpp b/cockatrice/src/settings/cache_settings.cpp index 87215aefb..5cec81cf7 100644 --- a/cockatrice/src/settings/cache_settings.cpp +++ b/cockatrice/src/settings/cache_settings.cpp @@ -632,7 +632,7 @@ void SettingsCache::setOverrideAllCardArtWithPersonalPreference(QT_STATE_CHANGED { overrideAllCardArtWithPersonalPreference = static_cast(_overrideAllCardArt); settings->setValue("cards/overrideallcardartwithpersonalpreference", overrideAllCardArtWithPersonalPreference); - emit overrideAllCardArtWithPersonalPreferenceChanged(); + emit overrideAllCardArtWithPersonalPreferenceChanged(overrideAllCardArtWithPersonalPreference); } void SettingsCache::setBumpSetsWithCardsInDeckToTop(QT_STATE_CHANGED_T _bumpSetsWithCardsInDeckToTop) diff --git a/cockatrice/src/settings/cache_settings.h b/cockatrice/src/settings/cache_settings.h index c33efad6d..f4c00acdc 100644 --- a/cockatrice/src/settings/cache_settings.h +++ b/cockatrice/src/settings/cache_settings.h @@ -55,7 +55,7 @@ signals: void themeChanged(); void picDownloadChanged(); void displayCardNamesChanged(); - void overrideAllCardArtWithPersonalPreferenceChanged(); + void overrideAllCardArtWithPersonalPreferenceChanged(bool _overrideAllCardArtWithPersonalPreference); void bumpSetsWithCardsInDeckToTopChanged(); void printingSelectorSortOrderChanged(); void printingSelectorCardSizeChanged();