Allow editing tags in the DeckEditor.

This commit is contained in:
Lukas Brübach 2025-02-11 12:16:47 +01:00
parent eeffdb5e68
commit 2bf6ef959e
6 changed files with 128 additions and 51 deletions

View file

@ -113,6 +113,8 @@ void TabDeckEditor::createDeckDock()
connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&TabDeckEditor::setBannerCard); &TabDeckEditor::setBannerCard);
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckModel->getDeckList());
aIncrement = new QAction(QString(), this); aIncrement = new QAction(QString(), this);
aIncrement->setIcon(QPixmap("theme:icons/increment")); aIncrement->setIcon(QPixmap("theme:icons/increment"));
connect(aIncrement, SIGNAL(triggered()), this, SLOT(actIncrement())); connect(aIncrement, SIGNAL(triggered()), this, SLOT(actIncrement()));
@ -148,6 +150,8 @@ void TabDeckEditor::createDeckDock()
upperLayout->addWidget(bannerCardLabel, 2, 0); upperLayout->addWidget(bannerCardLabel, 2, 0);
upperLayout->addWidget(bannerCardComboBox, 2, 1); upperLayout->addWidget(bannerCardComboBox, 2, 1);
upperLayout->addWidget(deckTagsDisplayWidget, 3, 1);
hashLabel1 = new QLabel(); hashLabel1 = new QLabel();
hashLabel1->setObjectName("hashLabel1"); hashLabel1->setObjectName("hashLabel1");
auto *hashSizePolicy = new QSizePolicy(); auto *hashSizePolicy = new QSizePolicy();
@ -1608,6 +1612,8 @@ void TabDeckEditor::setDeck(DeckLoader *_deck)
deckView->expandAll(); deckView->expandAll();
setModified(false); setModified(false);
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
// If they load a deck, make the deck list appear // If they load a deck, make the deck list appear
aDeckDockVisible->setChecked(true); aDeckDockVisible->setChecked(true);
deckDock->setVisible(aDeckDockVisible->isChecked()); deckDock->setVisible(aDeckDockVisible->isChecked());

View file

@ -5,6 +5,7 @@
#include "../../game/cards/card_database.h" #include "../../game/cards/card_database.h"
#include "../game_logic/key_signals.h" #include "../game_logic/key_signals.h"
#include "../ui/widgets/printing_selector/printing_selector.h" #include "../ui/widgets/printing_selector/printing_selector.h"
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
#include "tab.h" #include "tab.h"
#include <QAbstractItemModel> #include <QAbstractItemModel>
@ -19,6 +20,7 @@ class CardInfoFrameWidget;
class QTextEdit; class QTextEdit;
class QLabel; class QLabel;
class DeckLoader; class DeckLoader;
class DeckPreviewDeckTagsDisplayWidget;
class Response; class Response;
class FilterTreeModel; class FilterTreeModel;
class FilterBuilder; class FilterBuilder;
@ -136,6 +138,7 @@ private:
QTextEdit *commentsEdit; QTextEdit *commentsEdit;
QLabel *bannerCardLabel; QLabel *bannerCardLabel;
QComboBox *bannerCardComboBox; QComboBox *bannerCardComboBox;
DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
QLabel *hashLabel1; QLabel *hashLabel1;
LineEditUnfocusable *hashLabel; LineEditUnfocusable *hashLabel;
FilterTreeModel *filterModel; FilterTreeModel *filterModel;

View file

@ -1,5 +1,6 @@
#include "deck_preview_deck_tags_display_widget.h" #include "deck_preview_deck_tags_display_widget.h"
#include "../../../../tabs/tab_deck_editor.h"
#include "../../general/layout_containers/flow_widget.h" #include "../../general/layout_containers/flow_widget.h"
#include "deck_preview_tag_addition_widget.h" #include "deck_preview_tag_addition_widget.h"
#include "deck_preview_tag_display_widget.h" #include "deck_preview_tag_display_widget.h"
@ -8,8 +9,8 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLabel> #include <QLabel>
DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(DeckPreviewWidget *_parent, DeckLoader *_deckLoader) DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList)
: QWidget(_parent), parent(_parent), deckLoader(_deckLoader) : QWidget(_parent), deckList(_deckList)
{ {
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
@ -21,21 +22,33 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(DeckPreviewWi
setFixedHeight(100); setFixedHeight(100);
connect(deckLoader, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded); flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
for (const QString &tag : this->deckLoader->getTags()) {
if (deckList) {
connectDeckList(deckList);
}
layout->addWidget(flowWidget);
}
void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList)
{
flowWidget->clearLayout();
deckList = _deckList;
connect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
for (const QString &tag : deckList->getTags()) {
flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag));
} }
flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, tr("Edit tags ..."))); flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, this, tr("Edit tags ...")));
layout->addWidget(flowWidget);
} }
void DeckPreviewDeckTagsDisplayWidget::refreshTags() void DeckPreviewDeckTagsDisplayWidget::refreshTags()
{ {
flowWidget->clearLayout(); flowWidget->clearLayout();
for (const QString &tag : this->deckLoader->getTags()) { QStringList tags = deckList->getTags();
for (const QString &tag : tags) {
flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag));
} }
flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, tr("Edit tags ..."))); flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, this, tr("Edit tags ...")));
} }

View file

@ -2,6 +2,7 @@
#define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H #define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
#include "../../../../../deck/deck_loader.h" #include "../../../../../deck/deck_loader.h"
#include "../../../../tabs/tab_deck_editor.h"
#include "deck_preview_widget.h" #include "deck_preview_widget.h"
#include <QWidget> #include <QWidget>
@ -12,10 +13,10 @@ class DeckPreviewDeckTagsDisplayWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit DeckPreviewDeckTagsDisplayWidget(DeckPreviewWidget *_parent, DeckLoader *_deckLoader); explicit DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList);
void connectDeckList(DeckList *_deckList);
void refreshTags(); void refreshTags();
DeckPreviewWidget *parent; DeckList *deckList;
DeckLoader *deckLoader;
FlowWidget *flowWidget; FlowWidget *flowWidget;
}; };
#endif // DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H #endif // DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H

View file

@ -4,14 +4,16 @@
#include "../../../../../settings/cache_settings.h" #include "../../../../../settings/cache_settings.h"
#include "deck_preview_tag_dialog.h" #include "deck_preview_tag_dialog.h"
#include <QDirIterator>
#include <QFontMetrics> #include <QFontMetrics>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QMouseEvent> #include <QMouseEvent>
#include <QPainter> #include <QPainter>
DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(DeckPreviewDeckTagsDisplayWidget *_parent, DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(QWidget *_parent,
DeckPreviewDeckTagsDisplayWidget *_tagsDisplayWidget,
const QString &_tagName) const QString &_tagName)
: QWidget(_parent), parent(_parent), tagName_(_tagName) : QWidget(_parent), tagsDisplayWidget(_tagsDisplayWidget), tagName_(_tagName)
{ {
// Create layout // Create layout
auto *layout = new QHBoxLayout(this); auto *layout = new QHBoxLayout(this);
@ -33,58 +35,108 @@ QSize DeckPreviewTagAdditionWidget::sizeHint() const
return QSize(width, height); return QSize(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) void DeckPreviewTagAdditionWidget::mousePressEvent(QMouseEvent *event)
{ {
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
emit tagClicked(); emit tagClicked();
} }
QWidget::mousePressEvent(event); QWidget::mousePressEvent(event);
QStringList knownTags = parent->parent->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags();
QStringList activeTags = parent->deckLoader->getTags();
bool canAddTags = true; if (qobject_cast<DeckPreviewWidget *>(tagsDisplayWidget->parentWidget())) {
DeckPreviewWidget *deckPreviewWidget = qobject_cast<DeckPreviewWidget *>(tagsDisplayWidget->parentWidget());
QStringList knownTags = deckPreviewWidget->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags();
QStringList activeTags = tagsDisplayWidget->deckList->getTags();
if (DeckLoader::getFormatFromName(parent->parent->filePath) != DeckLoader::CockatriceFormat) { bool canAddTags = true;
canAddTags = false;
// Retrieve saved preference if the prompt is disabled
if (!SettingsCache::instance().getVisualDeckStoragePromptForConversion()) {
if (SettingsCache::instance().getVisualDeckStorageAlwaysConvert()) {
parent->deckLoader->convertToCockatriceFormat(parent->parent->filePath);
parent->parent->filePath = parent->deckLoader->getLastFileName();
parent->parent->refreshBannerCardText();
canAddTags = true;
}
} else {
// Show the dialog to the user
DialogConvertDeckToCodFormat conversionDialog(parent);
if (conversionDialog.exec() == QDialog::Accepted) {
parent->deckLoader->convertToCockatriceFormat(parent->parent->filePath);
parent->parent->filePath = parent->deckLoader->getLastFileName();
parent->parent->refreshBannerCardText();
canAddTags = true;
if (conversionDialog.dontAskAgain()) { if (DeckLoader::getFormatFromName(deckPreviewWidget->filePath) != DeckLoader::CockatriceFormat) {
SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked); canAddTags = false;
SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Checked); // 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 { } else {
SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Unchecked); // 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()) { if (conversionDialog.dontAskAgain()) {
SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked); SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked);
SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Checked);
}
} else { } else {
SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Checked); SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Unchecked);
if (conversionDialog.dontAskAgain()) {
SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked);
} else {
SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Checked);
}
} }
} }
} }
}
if (canAddTags) { if (canAddTags) {
DeckPreviewTagDialog dialog(knownTags, activeTags); DeckPreviewTagDialog dialog(knownTags, activeTags);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QStringList updatedTags = dialog.getActiveTags(); QStringList updatedTags = dialog.getActiveTags();
parent->deckLoader->setTags(updatedTags); tagsDisplayWidget->deckList->setTags(updatedTags);
parent->deckLoader->saveToFile(parent->parent->filePath, DeckLoader::CockatriceFormat); 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<TabDeckEditor *>(currentParent)) {
break;
}
currentParent = currentParent->parentWidget();
}
if (qobject_cast<TabDeckEditor *>(currentParent)) {
TabDeckEditor *deckEditor = qobject_cast<TabDeckEditor *>(currentParent);
QStringList knownTags;
QStringList allFiles = getAllFiles(SettingsCache::instance().getDeckPath(), true);
DeckLoader *loader = new DeckLoader();
for (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);
}
} }
} }
} }

View file

@ -12,7 +12,9 @@ class DeckPreviewTagAdditionWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit DeckPreviewTagAdditionWidget(DeckPreviewDeckTagsDisplayWidget *_parent, const QString &tagName); explicit DeckPreviewTagAdditionWidget(QWidget *_parent,
DeckPreviewDeckTagsDisplayWidget *_tagsDisplayWidget,
const QString &_tagName);
QSize sizeHint() const override; QSize sizeHint() const override;
signals: signals:
@ -24,7 +26,7 @@ protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
private: private:
DeckPreviewDeckTagsDisplayWidget *parent; DeckPreviewDeckTagsDisplayWidget *tagsDisplayWidget;
QString tagName_; QString tagName_;
QLabel *tagLabel_; QLabel *tagLabel_;
QPushButton *closeButton_; QPushButton *closeButton_;