diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp index 06b00c089..fd5e34c4a 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp @@ -1,11 +1,15 @@ #include "deck_preview_deck_tags_display_widget.h" +#include "../../../../../dialogs/dlg_convert_deck_to_cod_format.h" +#include "../../../../../settings/cache_settings.h" #include "../../../../tabs/tab_deck_editor.h" #include "../../general/layout_containers/flow_widget.h" #include "deck_preview_tag_addition_widget.h" +#include "deck_preview_tag_dialog.h" #include "deck_preview_tag_display_widget.h" #include "deck_preview_widget.h" +#include #include #include @@ -40,7 +44,11 @@ void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList) for (const QString &tag : deckList->getTags()) { flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); } - flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, this, tr("Edit tags ..."))); + + auto tagAdditionWidget = new DeckPreviewTagAdditionWidget(this, tr("Edit tags ...")); + connect(tagAdditionWidget, &DeckPreviewTagAdditionWidget::tagClicked, this, + &DeckPreviewDeckTagsDisplayWidget::openTagEditDlg); + flowWidget->addWidget(tagAdditionWidget); } void DeckPreviewDeckTagsDisplayWidget::refreshTags() @@ -50,5 +58,107 @@ void DeckPreviewDeckTagsDisplayWidget::refreshTags() for (const QString &tag : tags) { flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); } - flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, this, tr("Edit tags ..."))); + flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, tr("Edit tags ..."))); +} + +/** + * Gets the filepath of all files (no directories) in target directory and all subdirectories + */ +static QStringList getAllFiles(const QString &filePath) +{ + QStringList allFiles; + + // QDirIterator with QDir::Files ensures only files are listed (no directories) + QDirIterator it(filePath, QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); + + while (it.hasNext()) { + allFiles << it.next(); // Add each file path to the list + } + + return allFiles; +} + +void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg() +{ + if (qobject_cast(parentWidget())) { + auto *deckPreviewWidget = qobject_cast(parentWidget()); + QStringList knownTags = deckPreviewWidget->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags(); + QStringList activeTags = deckList->getTags(); + + bool canAddTags = true; + + if (DeckLoader::getFormatFromName(deckPreviewWidget->filePath) != DeckLoader::CockatriceFormat) { + canAddTags = false; + // Retrieve saved preference if the prompt is disabled + if (!SettingsCache::instance().getVisualDeckStoragePromptForConversion()) { + if (SettingsCache::instance().getVisualDeckStorageAlwaysConvert()) { + deckPreviewWidget->deckLoader->convertToCockatriceFormat(deckPreviewWidget->filePath); + deckPreviewWidget->filePath = deckPreviewWidget->deckLoader->getLastFileName(); + deckPreviewWidget->refreshBannerCardText(); + canAddTags = true; + } + } else { + // Show the dialog to the user + DialogConvertDeckToCodFormat conversionDialog(parentWidget()); + if (conversionDialog.exec() == QDialog::Accepted) { + deckPreviewWidget->deckLoader->convertToCockatriceFormat(deckPreviewWidget->filePath); + deckPreviewWidget->filePath = deckPreviewWidget->deckLoader->getLastFileName(); + deckPreviewWidget->refreshBannerCardText(); + canAddTags = true; + + if (conversionDialog.dontAskAgain()) { + SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked); + SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Checked); + } + } else { + SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Unchecked); + + if (conversionDialog.dontAskAgain()) { + SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked); + } else { + SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Checked); + } + } + } + } + + if (canAddTags) { + DeckPreviewTagDialog dialog(knownTags, activeTags); + if (dialog.exec() == QDialog::Accepted) { + QStringList updatedTags = dialog.getActiveTags(); + deckList->setTags(updatedTags); + deckPreviewWidget->deckLoader->saveToFile(deckPreviewWidget->filePath, DeckLoader::CockatriceFormat); + } + } + } else if (parentWidget()) { + // If we're the child of a TabDeckEditor, we are buried under a ton of childWidgets in the DeckInfoDock. + QWidget *currentParent = parentWidget(); + while (currentParent) { + if (qobject_cast(currentParent)) { + break; + } + currentParent = currentParent->parentWidget(); + } + if (qobject_cast(currentParent)) { + auto *deckEditor = qobject_cast(currentParent); + QStringList knownTags; + QStringList allFiles = getAllFiles(SettingsCache::instance().getDeckPath()); + auto *loader = new DeckLoader(); + for (const QString &file : allFiles) { + loader->loadFromFile(file, DeckLoader::getFormatFromName(file), false); + QStringList tags = loader->getTags(); + knownTags.append(tags); + knownTags.removeDuplicates(); + } + + QStringList activeTags = deckList->getTags(); + + DeckPreviewTagDialog dialog(knownTags, activeTags); + if (dialog.exec() == QDialog::Accepted) { + QStringList updatedTags = dialog.getActiveTags(); + deckList->setTags(updatedTags); + deckEditor->setModified(true); + } + } + } } \ No newline at end of file diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h index 4e821f796..344f6119e 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h @@ -1,7 +1,6 @@ #ifndef DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H #define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H -#include "../../../../../deck/deck_loader.h" #include "../../../../tabs/tab_deck_editor.h" #include "deck_preview_widget.h" @@ -18,5 +17,8 @@ public: void refreshTags(); DeckList *deckList; FlowWidget *flowWidget; + +public slots: + void openTagEditDlg(); }; #endif // DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp index 831bb00dd..fb1f99879 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp @@ -1,20 +1,16 @@ #include "deck_preview_tag_addition_widget.h" -#include "../../../../../dialogs/dlg_convert_deck_to_cod_format.h" #include "../../../../../settings/cache_settings.h" #include "deck_preview_tag_dialog.h" -#include #include #include #include #include #include -DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(QWidget *_parent, - DeckPreviewDeckTagsDisplayWidget *_tagsDisplayWidget, - QString _tagName) - : QWidget(_parent), tagsDisplayWidget(_tagsDisplayWidget), tagName_(std::move(_tagName)) +DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(QWidget *_parent, QString _tagName) + : QWidget(_parent), tagName_(std::move(_tagName)) { // Create layout auto *layout = new QHBoxLayout(this); @@ -36,110 +32,12 @@ QSize DeckPreviewTagAdditionWidget::sizeHint() const return {width, height}; } -static QStringList getAllFiles(const QString &filePath, bool recursive) -{ - QStringList allFiles; - - // QDirIterator with QDir::Files ensures only files are listed (no directories) - auto flags = - recursive ? QDirIterator::Subdirectories | QDirIterator::FollowSymlinks : QDirIterator::NoIteratorFlags; - QDirIterator it(filePath, QDir::Files, flags); - - while (it.hasNext()) { - allFiles << it.next(); // Add each file path to the list - } - - return allFiles; -} - void DeckPreviewTagAdditionWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { emit tagClicked(); } QWidget::mousePressEvent(event); - - if (qobject_cast(tagsDisplayWidget->parentWidget())) { - auto *deckPreviewWidget = qobject_cast(tagsDisplayWidget->parentWidget()); - QStringList knownTags = deckPreviewWidget->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags(); - QStringList activeTags = tagsDisplayWidget->deckList->getTags(); - - bool canAddTags = true; - - if (DeckLoader::getFormatFromName(deckPreviewWidget->filePath) != DeckLoader::CockatriceFormat) { - canAddTags = false; - // Retrieve saved preference if the prompt is disabled - if (!SettingsCache::instance().getVisualDeckStoragePromptForConversion()) { - if (SettingsCache::instance().getVisualDeckStorageAlwaysConvert()) { - deckPreviewWidget->deckLoader->convertToCockatriceFormat(deckPreviewWidget->filePath); - deckPreviewWidget->filePath = deckPreviewWidget->deckLoader->getLastFileName(); - deckPreviewWidget->refreshBannerCardText(); - canAddTags = true; - } - } else { - // Show the dialog to the user - DialogConvertDeckToCodFormat conversionDialog(parentWidget()); - if (conversionDialog.exec() == QDialog::Accepted) { - deckPreviewWidget->deckLoader->convertToCockatriceFormat(deckPreviewWidget->filePath); - deckPreviewWidget->filePath = deckPreviewWidget->deckLoader->getLastFileName(); - deckPreviewWidget->refreshBannerCardText(); - canAddTags = true; - - if (conversionDialog.dontAskAgain()) { - SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked); - SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Checked); - } - } else { - SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Unchecked); - - if (conversionDialog.dontAskAgain()) { - SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked); - } else { - SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Checked); - } - } - } - } - - if (canAddTags) { - DeckPreviewTagDialog dialog(knownTags, activeTags); - if (dialog.exec() == QDialog::Accepted) { - QStringList updatedTags = dialog.getActiveTags(); - tagsDisplayWidget->deckList->setTags(updatedTags); - deckPreviewWidget->deckLoader->saveToFile(deckPreviewWidget->filePath, DeckLoader::CockatriceFormat); - } - } - } else if (tagsDisplayWidget->parentWidget()) { - // If we're the child of a TabDeckEditor, we are buried under a ton of childWidgets in the DeckInfoDock. - QWidget *currentParent = tagsDisplayWidget->parentWidget(); - while (currentParent) { - if (qobject_cast(currentParent)) { - break; - } - currentParent = currentParent->parentWidget(); - } - if (qobject_cast(currentParent)) { - auto *deckEditor = qobject_cast(currentParent); - QStringList knownTags; - QStringList allFiles = getAllFiles(SettingsCache::instance().getDeckPath(), true); - auto *loader = new DeckLoader(); - for (const QString &file : allFiles) { - loader->loadFromFile(file, DeckLoader::getFormatFromName(file), false); - QStringList tags = loader->getTags(); - knownTags.append(tags); - knownTags.removeDuplicates(); - } - - QStringList activeTags = tagsDisplayWidget->deckList->getTags(); - - DeckPreviewTagDialog dialog(knownTags, activeTags); - if (dialog.exec() == QDialog::Accepted) { - QStringList updatedTags = dialog.getActiveTags(); - tagsDisplayWidget->deckList->setTags(updatedTags); - deckEditor->setModified(true); - } - } - } } void DeckPreviewTagAdditionWidget::paintEvent(QPaintEvent *event) diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h index 4d288c95a..bdf4a0103 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h @@ -12,9 +12,7 @@ class DeckPreviewTagAdditionWidget : public QWidget Q_OBJECT public: - explicit DeckPreviewTagAdditionWidget(QWidget *_parent, - DeckPreviewDeckTagsDisplayWidget *_tagsDisplayWidget, - QString _tagName); + explicit DeckPreviewTagAdditionWidget(QWidget *_parent, QString _tagName); [[nodiscard]] QSize sizeHint() const override; signals: @@ -26,7 +24,6 @@ protected: void paintEvent(QPaintEvent *event) override; private: - DeckPreviewDeckTagsDisplayWidget *tagsDisplayWidget; QString tagName_; }; diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp index 27555c860..ca1e00a87 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp @@ -287,10 +287,14 @@ static void saveDeckToClipboard(DeckLoader *deckLoader, bool addComments, bool a QMenu *DeckPreviewWidget::createRightClickMenu() { auto *menu = new QMenu(this); + menu->setAttribute(Qt::WA_DeleteOnClose); connect(menu->addAction(tr("Open in deck editor")), &QAction::triggered, this, [this] { emit openDeckEditor(deckLoader); }); + connect(menu->addAction(tr("Edit Tags")), &QAction::triggered, deckTagsDisplayWidget, + &DeckPreviewDeckTagsDisplayWidget::openTagEditDlg); + menu->addSeparator(); auto saveToClipboardMenu = menu->addMenu(tr("Save Deck to Clipboard"));