diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index 05846bbb7..7b42f69ca 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -25,6 +25,7 @@
resources/icons/pencil.svg
resources/icons/player.svg
resources/icons/ready_start.svg
+ resources/icons/reload.svg
resources/icons/remove_row.svg
resources/icons/scales.svg
resources/icons/search.svg
diff --git a/cockatrice/resources/icons/reload.svg b/cockatrice/resources/icons/reload.svg
new file mode 100644
index 000000000..102995876
--- /dev/null
+++ b/cockatrice/resources/icons/reload.svg
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/cockatrice/src/client/tabs/tab_deck_editor.cpp b/cockatrice/src/client/tabs/tab_deck_editor.cpp
index 8eee22cf5..a2ac824af 100644
--- a/cockatrice/src/client/tabs/tab_deck_editor.cpp
+++ b/cockatrice/src/client/tabs/tab_deck_editor.cpp
@@ -113,6 +113,8 @@ void TabDeckEditor::createDeckDock()
connect(bannerCardComboBox, QOverload::of(&QComboBox::currentIndexChanged), this,
&TabDeckEditor::setBannerCard);
+ deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckModel->getDeckList());
+
aIncrement = new QAction(QString(), this);
aIncrement->setIcon(QPixmap("theme:icons/increment"));
connect(aIncrement, SIGNAL(triggered()), this, SLOT(actIncrement()));
@@ -148,6 +150,8 @@ void TabDeckEditor::createDeckDock()
upperLayout->addWidget(bannerCardLabel, 2, 0);
upperLayout->addWidget(bannerCardComboBox, 2, 1);
+ upperLayout->addWidget(deckTagsDisplayWidget, 3, 1);
+
hashLabel1 = new QLabel();
hashLabel1->setObjectName("hashLabel1");
auto *hashSizePolicy = new QSizePolicy();
@@ -1608,6 +1612,8 @@ void TabDeckEditor::setDeck(DeckLoader *_deck)
deckView->expandAll();
setModified(false);
+ deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
+
// If they load a deck, make the deck list appear
aDeckDockVisible->setChecked(true);
deckDock->setVisible(aDeckDockVisible->isChecked());
diff --git a/cockatrice/src/client/tabs/tab_deck_editor.h b/cockatrice/src/client/tabs/tab_deck_editor.h
index ab0c0883e..9bb696e34 100644
--- a/cockatrice/src/client/tabs/tab_deck_editor.h
+++ b/cockatrice/src/client/tabs/tab_deck_editor.h
@@ -5,6 +5,7 @@
#include "../../game/cards/card_database.h"
#include "../game_logic/key_signals.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
@@ -19,6 +20,7 @@ class CardInfoFrameWidget;
class QTextEdit;
class QLabel;
class DeckLoader;
+class DeckPreviewDeckTagsDisplayWidget;
class Response;
class FilterTreeModel;
class FilterBuilder;
@@ -136,6 +138,7 @@ private:
QTextEdit *commentsEdit;
QLabel *bannerCardLabel;
QComboBox *bannerCardComboBox;
+ DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
QLabel *hashLabel1;
LineEditUnfocusable *hashLabel;
FilterTreeModel *filterModel;
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 7f2dfaab0..06b00c089 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,5 +1,6 @@
#include "deck_preview_deck_tags_display_widget.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_display_widget.h"
@@ -8,8 +9,8 @@
#include
#include
-DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(DeckPreviewWidget *_parent, DeckLoader *_deckLoader)
- : QWidget(_parent), parent(_parent), deckLoader(_deckLoader)
+DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList)
+ : QWidget(_parent), deckList(_deckList)
{
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
@@ -21,21 +22,33 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(DeckPreviewWi
setFixedHeight(100);
- connect(deckLoader, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
-
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 DeckPreviewTagAdditionWidget(this, tr("Edit tags ...")));
- layout->addWidget(flowWidget);
+ flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, this, tr("Edit tags ...")));
}
void DeckPreviewDeckTagsDisplayWidget::refreshTags()
{
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 DeckPreviewTagAdditionWidget(this, tr("Edit tags ...")));
+ flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, this, tr("Edit tags ...")));
}
\ 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 a6a1c8de4..4e821f796 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
@@ -2,6 +2,7 @@
#define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
#include "../../../../../deck/deck_loader.h"
+#include "../../../../tabs/tab_deck_editor.h"
#include "deck_preview_widget.h"
#include
@@ -12,10 +13,10 @@ class DeckPreviewDeckTagsDisplayWidget : public QWidget
Q_OBJECT
public:
- explicit DeckPreviewDeckTagsDisplayWidget(DeckPreviewWidget *_parent, DeckLoader *_deckLoader);
+ explicit DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList);
+ void connectDeckList(DeckList *_deckList);
void refreshTags();
- DeckPreviewWidget *parent;
- DeckLoader *deckLoader;
+ DeckList *deckList;
FlowWidget *flowWidget;
};
#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 16a87bc8d..831bb00dd 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
@@ -4,14 +4,17 @@
#include "../../../../../settings/cache_settings.h"
#include "deck_preview_tag_dialog.h"
+#include
#include
#include
#include
#include
+#include
-DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(DeckPreviewDeckTagsDisplayWidget *_parent,
- const QString &_tagName)
- : QWidget(_parent), parent(_parent), tagName_(_tagName)
+DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(QWidget *_parent,
+ DeckPreviewDeckTagsDisplayWidget *_tagsDisplayWidget,
+ QString _tagName)
+ : QWidget(_parent), tagsDisplayWidget(_tagsDisplayWidget), tagName_(std::move(_tagName))
{
// Create layout
auto *layout = new QHBoxLayout(this);
@@ -30,7 +33,23 @@ QSize DeckPreviewTagAdditionWidget::sizeHint() const
int width = textWidth + 50; // Add extra padding
int height = fm.height() + 10; // Height based on font size + padding
- return QSize(width, height);
+ 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)
@@ -39,52 +58,86 @@ void DeckPreviewTagAdditionWidget::mousePressEvent(QMouseEvent *event)
emit tagClicked();
}
QWidget::mousePressEvent(event);
- QStringList knownTags = parent->parent->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags();
- QStringList activeTags = parent->deckLoader->getTags();
- bool canAddTags = true;
+ if (qobject_cast(tagsDisplayWidget->parentWidget())) {
+ auto *deckPreviewWidget = qobject_cast(tagsDisplayWidget->parentWidget());
+ QStringList knownTags = deckPreviewWidget->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags();
+ QStringList activeTags = tagsDisplayWidget->deckList->getTags();
- if (DeckLoader::getFormatFromName(parent->parent->filePath) != DeckLoader::CockatriceFormat) {
- 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;
+ bool canAddTags = true;
- if (conversionDialog.dontAskAgain()) {
- SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked);
- SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Checked);
+ 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 {
- 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()) {
- SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked);
+ if (conversionDialog.dontAskAgain()) {
+ SettingsCache::instance().setVisualDeckStoragePromptForConversion(Qt::CheckState::Unchecked);
+ SettingsCache::instance().setVisualDeckStorageAlwaysConvert(Qt::CheckState::Checked);
+ }
} 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) {
- DeckPreviewTagDialog dialog(knownTags, activeTags);
- if (dialog.exec() == QDialog::Accepted) {
- QStringList updatedTags = dialog.getActiveTags();
- parent->deckLoader->setTags(updatedTags);
- parent->deckLoader->saveToFile(parent->parent->filePath, DeckLoader::CockatriceFormat);
+ 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);
+ }
}
}
}
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 14d51a556..4d288c95a 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,8 +12,10 @@ class DeckPreviewTagAdditionWidget : public QWidget
Q_OBJECT
public:
- explicit DeckPreviewTagAdditionWidget(DeckPreviewDeckTagsDisplayWidget *_parent, const QString &tagName);
- QSize sizeHint() const override;
+ explicit DeckPreviewTagAdditionWidget(QWidget *_parent,
+ DeckPreviewDeckTagsDisplayWidget *_tagsDisplayWidget,
+ QString _tagName);
+ [[nodiscard]] QSize sizeHint() const override;
signals:
void tagClicked(); // Emitted when the tag is clicked
@@ -24,10 +26,8 @@ protected:
void paintEvent(QPaintEvent *event) override;
private:
- DeckPreviewDeckTagsDisplayWidget *parent;
+ DeckPreviewDeckTagsDisplayWidget *tagsDisplayWidget;
QString tagName_;
- QLabel *tagLabel_;
- QPushButton *closeButton_;
};
#endif // DECK_PREVIEW_TAG_ADDITION_WIDGET_H
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 27519c252..df8ab2641 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
@@ -34,10 +34,26 @@ DeckPreviewWidget::DeckPreviewWidget(QWidget *_parent,
connect(&SettingsCache::instance(), &SettingsCache::visualDeckStorageShowTagsOnDeckPreviewsChanged, this,
&DeckPreviewWidget::updateTagsVisibility);
+ connect(&SettingsCache::instance(), &SettingsCache::visualDeckStorageShowBannerCardComboBoxChanged, this,
+ &DeckPreviewWidget::updateBannerCardComboBoxVisibility);
layout->addWidget(bannerCardDisplayWidget);
}
+void DeckPreviewWidget::retranslateUi()
+{
+ bannerCardLabel->setText(tr("Banner Card"));
+}
+
+void DeckPreviewWidget::resizeEvent(QResizeEvent *event)
+{
+ QWidget::resizeEvent(event);
+ if (bannerCardDisplayWidget == nullptr || bannerCardComboBox == nullptr) {
+ return;
+ }
+ bannerCardComboBox->setMaximumWidth(bannerCardDisplayWidget->width());
+}
+
void DeckPreviewWidget::initializeUi(const bool deckLoadSuccess)
{
if (!deckLoadSuccess) {
@@ -56,10 +72,27 @@ void DeckPreviewWidget::initializeUi(const bool deckLoadSuccess)
colorIdentityWidget = new DeckPreviewColorIdentityWidget(this, getColorIdentity());
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader);
+
+ bannerCardLabel = new QLabel();
+ bannerCardLabel->setObjectName("bannerCardLabel");
+ bannerCardComboBox = new QComboBox(this);
+ bannerCardComboBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ bannerCardComboBox->setObjectName("bannerCardComboBox");
+ bannerCardComboBox->setCurrentText(deckLoader->getBannerCard().first);
+ bannerCardComboBox->installEventFilter(new NoScrollFilter());
+ connect(bannerCardComboBox, QOverload::of(&QComboBox::currentIndexChanged), this,
+ &DeckPreviewWidget::setBannerCard);
+
+ updateBannerCardComboBox();
+ updateBannerCardComboBoxVisibility(SettingsCache::instance().getVisualDeckStorageShowBannerCardComboBox());
updateTagsVisibility(SettingsCache::instance().getVisualDeckStorageShowTagsOnDeckPreviews());
layout->addWidget(colorIdentityWidget);
layout->addWidget(deckTagsDisplayWidget);
+ layout->addWidget(bannerCardLabel);
+ layout->addWidget(bannerCardComboBox);
+
+ retranslateUi();
}
void DeckPreviewWidget::updateVisibility()
@@ -78,9 +111,24 @@ bool DeckPreviewWidget::checkVisibility() const
return true;
}
+void DeckPreviewWidget::updateBannerCardComboBoxVisibility(bool visible)
+{
+ if (bannerCardComboBox == nullptr) {
+ return;
+ }
+
+ if (visible) {
+ bannerCardComboBox->setVisible(true);
+ bannerCardLabel->setVisible(true);
+ } else {
+ bannerCardComboBox->setHidden(true);
+ bannerCardLabel->setHidden(true);
+ }
+}
+
void DeckPreviewWidget::updateTagsVisibility(bool visible)
{
- if (!deckTagsDisplayWidget) {
+ if (deckTagsDisplayWidget == nullptr) {
return;
}
@@ -133,6 +181,81 @@ void DeckPreviewWidget::refreshBannerCardText()
deckLoader->getName().isEmpty() ? QFileInfo(deckLoader->getLastFileName()).fileName() : deckLoader->getName());
}
+void DeckPreviewWidget::updateBannerCardComboBox()
+{
+ // Store the current text of the combo box
+ QString currentText = bannerCardComboBox->currentText();
+
+ // Block signals temporarily
+ bool wasBlocked = bannerCardComboBox->blockSignals(true);
+
+ // Clear the existing items in the combo box
+ bannerCardComboBox->clear();
+
+ // Prepare the new items with deduplication
+ QSet> bannerCardSet;
+ InnerDecklistNode *listRoot = deckLoader->getRoot();
+ for (auto i : *listRoot) {
+ auto *currentZone = dynamic_cast(i);
+ for (auto j : *currentZone) {
+ auto *currentCard = dynamic_cast(j);
+ if (!currentCard)
+ continue;
+
+ for (int k = 0; k < currentCard->getNumber(); ++k) {
+ CardInfoPtr info = CardDatabaseManager::getInstance()->getCardByNameAndProviderId(
+ currentCard->getName(), currentCard->getCardProviderId());
+ if (info) {
+ bannerCardSet.insert(
+ QPair(currentCard->getName(), currentCard->getCardProviderId()));
+ }
+ }
+ }
+ }
+
+ QList> pairList = bannerCardSet.values();
+
+ // Sort QList by the first() element of the QPair
+ std::sort(pairList.begin(), pairList.end(), [](const QPair &a, const QPair &b) {
+ return a.first.toLower() < b.first.toLower();
+ });
+
+ for (const auto &pair : pairList) {
+ QVariantMap dataMap;
+ dataMap["name"] = pair.first;
+ dataMap["uuid"] = pair.second;
+
+ bannerCardComboBox->addItem(pair.first, dataMap);
+ }
+
+ // Try to restore the previous selection by finding the currentText
+ int restoredIndex = bannerCardComboBox->findText(currentText);
+ if (restoredIndex != -1) {
+ bannerCardComboBox->setCurrentIndex(restoredIndex);
+ } else {
+ // Add a placeholder "-" and set it as the current selection
+ int bannerIndex = bannerCardComboBox->findText(deckLoader->getBannerCard().first);
+ if (bannerIndex != -1) {
+ bannerCardComboBox->setCurrentIndex(bannerIndex);
+ } else {
+ bannerCardComboBox->insertItem(0, "-");
+ bannerCardComboBox->setCurrentIndex(0);
+ }
+ }
+
+ // Restore the previous signal blocking state
+ bannerCardComboBox->blockSignals(wasBlocked);
+}
+
+void DeckPreviewWidget::setBannerCard(int /* changedIndex */)
+{
+ QVariantMap itemData = bannerCardComboBox->itemData(bannerCardComboBox->currentIndex()).toMap();
+ deckLoader->setBannerCard(QPair(itemData["name"].toString(), itemData["uuid"].toString()));
+ deckLoader->saveToFile(filePath, DeckLoader::getFormatFromName(filePath));
+ bannerCardDisplayWidget->setCard(CardDatabaseManager::getInstance()->getCardByNameAndProviderId(
+ itemData["name"].toString(), itemData["uuid"].toString()));
+}
+
void DeckPreviewWidget::imageClickedEvent(QMouseEvent *event, DeckPreviewCardPictureWidget *instance)
{
Q_UNUSED(instance);
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h
index af5dd04b7..36228ab6e 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h
@@ -19,15 +19,18 @@ public:
explicit DeckPreviewWidget(QWidget *_parent,
VisualDeckStorageWidget *_visualDeckStorageWidget,
const QString &_filePath);
+ void retranslateUi();
QString getColorIdentity();
VisualDeckStorageWidget *visualDeckStorageWidget;
QVBoxLayout *layout;
QString filePath;
DeckLoader *deckLoader;
- DeckPreviewCardPictureWidget *bannerCardDisplayWidget;
- DeckPreviewColorIdentityWidget *colorIdentityWidget;
- DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
+ DeckPreviewCardPictureWidget *bannerCardDisplayWidget = nullptr;
+ DeckPreviewColorIdentityWidget *colorIdentityWidget = nullptr;
+ DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget = nullptr;
+ QLabel *bannerCardLabel = nullptr;
+ QComboBox *bannerCardComboBox = nullptr;
bool filteredBySearch = false;
bool filteredByColor = false;
bool filteredByTags = false;
@@ -41,11 +44,28 @@ signals:
public slots:
void setFilePath(const QString &filePath);
void refreshBannerCardText();
+ void updateBannerCardComboBox();
+ void setBannerCard(int);
void imageClickedEvent(QMouseEvent *event, DeckPreviewCardPictureWidget *instance);
void imageDoubleClickedEvent(QMouseEvent *event, DeckPreviewCardPictureWidget *instance);
void initializeUi(bool deckLoadSuccess);
void updateVisibility();
+ void updateBannerCardComboBoxVisibility(bool visible);
void updateTagsVisibility(bool visible);
+ void resizeEvent(QResizeEvent *event) override;
+};
+
+class NoScrollFilter : public QObject
+{
+ Q_OBJECT
+protected:
+ bool eventFilter(QObject *obj, QEvent *event) override
+ {
+ if (event->type() == QEvent::Wheel) {
+ return true; // Blocks the event
+ }
+ return QObject::eventFilter(obj, event);
+ }
};
#endif // DECK_PREVIEW_WIDGET_H
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
index 8e43f703e..0e04f1dc6 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
@@ -11,6 +11,7 @@
#include
#include
+#include
#include
#include
@@ -35,6 +36,11 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
sortWidget = new VisualDeckStorageSortWidget(this);
searchWidget = new VisualDeckStorageSearchWidget(this);
+ refreshButton = new QToolButton(this);
+ refreshButton->setIcon(QPixmap("theme:icons/reload"));
+ refreshButton->setFixedSize(32, 32);
+ connect(refreshButton, &QPushButton::clicked, this, &VisualDeckStorageWidget::refreshIfPossible);
+
showFoldersCheckBox = new QCheckBox(this);
showFoldersCheckBox->setChecked(SettingsCache::instance().getVisualDeckStorageShowFolders());
connect(showFoldersCheckBox, &QCheckBox::QT_STATE_CHANGED, this, &VisualDeckStorageWidget::updateShowFolders);
@@ -59,6 +65,12 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
connect(drawUnusedColorIdentitiesCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
&SettingsCache::setVisualDeckStorageDrawUnusedColorIdentities);
+ bannerCardComboBoxVisibilityCheckBox = new QCheckBox(this);
+ bannerCardComboBoxVisibilityCheckBox->setChecked(
+ SettingsCache::instance().getVisualDeckStorageShowBannerCardComboBox());
+ connect(bannerCardComboBoxVisibilityCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
+ &SettingsCache::setVisualDeckStorageShowBannerCardComboBox);
+
// card size slider
cardSizeWidget = new CardSizeWidget(this, nullptr, SettingsCache::instance().getVisualDeckStorageCardSize());
@@ -67,11 +79,13 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
quickSettingsWidget->addSettingsWidget(tagFilterVisibilityCheckBox);
quickSettingsWidget->addSettingsWidget(tagsOnWidgetsVisibilityCheckBox);
quickSettingsWidget->addSettingsWidget(drawUnusedColorIdentitiesCheckBox);
+ quickSettingsWidget->addSettingsWidget(bannerCardComboBoxVisibilityCheckBox);
quickSettingsWidget->addSettingsWidget(cardSizeWidget);
searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget);
searchAndSortLayout->addWidget(sortWidget);
searchAndSortLayout->addWidget(searchWidget);
+ searchAndSortLayout->addWidget(refreshButton);
searchAndSortLayout->addWidget(quickSettingsWidget);
// tag filter box
@@ -104,6 +118,29 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
} else {
scrollArea->setWidget(databaseLoadIndicator);
}
+
+ addRecursiveWatch(watcher, SettingsCache::instance().getDeckPath());
+
+ // Signals for changes
+ connect(&watcher, &QFileSystemWatcher::fileChanged, this, &VisualDeckStorageWidget::refreshIfPossible);
+ connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &VisualDeckStorageWidget::refreshIfPossible);
+}
+
+void VisualDeckStorageWidget::refreshIfPossible()
+{
+ if (scrollArea->widget() != databaseLoadIndicator) {
+ createRootFolderWidget();
+ }
+}
+
+void VisualDeckStorageWidget::addRecursiveWatch(QFileSystemWatcher &watcher, const QString &dirPath)
+{
+ QDir dir(dirPath);
+ watcher.addPath(dirPath); // Watch the root directory
+
+ for (const QFileInfo &entry : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ addRecursiveWatch(watcher, entry.absoluteFilePath());
+ }
}
void VisualDeckStorageWidget::showEvent(QShowEvent *event)
@@ -132,6 +169,7 @@ void VisualDeckStorageWidget::retranslateUi()
tagFilterVisibilityCheckBox->setText(tr("Show Tag Filter"));
tagsOnWidgetsVisibilityCheckBox->setText(tr("Show Tags On Deck Previews"));
drawUnusedColorIdentitiesCheckBox->setText(tr("Draw not contained Color Identities"));
+ bannerCardComboBoxVisibilityCheckBox->setText(tr("Show Banner Card Selection Option"));
}
void VisualDeckStorageWidget::deckPreviewClickedEvent(QMouseEvent *event, DeckPreviewWidget *instance)
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h
index b6ced6375..b2eee6ab4 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h
@@ -14,6 +14,7 @@
#include
#include
+#include
class VisualDeckStorageSearchWidget;
class VisualDeckStorageSortWidget;
@@ -25,6 +26,8 @@ class VisualDeckStorageWidget final : public QWidget
Q_OBJECT
public:
explicit VisualDeckStorageWidget(QWidget *parent);
+ void refreshIfPossible();
+ void addRecursiveWatch(QFileSystemWatcher &watcher, const QString &dirPath);
void retranslateUi();
CardSizeWidget *cardSizeWidget;
@@ -61,13 +64,16 @@ private:
VisualDeckStorageSortWidget *sortWidget;
VisualDeckStorageSearchWidget *searchWidget;
DeckPreviewColorIdentityFilterWidget *deckPreviewColorIdentityFilterWidget;
+ QToolButton *refreshButton;
SettingsButtonWidget *quickSettingsWidget;
QCheckBox *showFoldersCheckBox;
QCheckBox *drawUnusedColorIdentitiesCheckBox;
+ QCheckBox *bannerCardComboBoxVisibilityCheckBox;
QCheckBox *tagFilterVisibilityCheckBox;
QCheckBox *tagsOnWidgetsVisibilityCheckBox;
QScrollArea *scrollArea;
VisualDeckStorageFolderDisplayWidget *folderWidget;
+ QFileSystemWatcher watcher;
};
#endif // VISUAL_DECK_STORAGE_WIDGET_H
diff --git a/cockatrice/src/deck/deck_loader.cpp b/cockatrice/src/deck/deck_loader.cpp
index ed1d8fa71..5249f1bba 100644
--- a/cockatrice/src/deck/deck_loader.cpp
+++ b/cockatrice/src/deck/deck_loader.cpp
@@ -162,6 +162,10 @@ bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
lastFileName = fileName;
lastFileFormat = fmt;
}
+
+ file.flush();
+ file.close();
+
return result;
}
diff --git a/cockatrice/src/settings/cache_settings.cpp b/cockatrice/src/settings/cache_settings.cpp
index c8f2aa737..58e16f24b 100644
--- a/cockatrice/src/settings/cache_settings.cpp
+++ b/cockatrice/src/settings/cache_settings.cpp
@@ -264,6 +264,8 @@ SettingsCache::SettingsCache()
visualDeckStorageSortingOrder = settings->value("interface/visualdeckstoragesortingorder", 0).toInt();
visualDeckStorageShowFolders = settings->value("interface/visualdeckstorageshowfolders", true).toBool();
visualDeckStorageShowTagFilter = settings->value("interface/visualdeckstorageshowtagfilter", true).toBool();
+ visualDeckStorageShowBannerCardComboBox =
+ settings->value("interface/visualdeckstorageshowbannercardcombobox", true).toBool();
visualDeckStorageShowTagsOnDeckPreviews =
settings->value("interface/visualdeckstorageshowtagsondeckpreviews", true).toBool();
visualDeckStorageDrawUnusedColorIdentities =
@@ -670,6 +672,13 @@ void SettingsCache::setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T _showTa
emit visualDeckStorageShowTagFilterChanged(visualDeckStorageShowTagFilter);
}
+void SettingsCache::setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T _showBannerCardComboBox)
+{
+ visualDeckStorageShowBannerCardComboBox = _showBannerCardComboBox;
+ settings->setValue("interface/visualdeckstorageshowbannercardcombobox", visualDeckStorageShowBannerCardComboBox);
+ emit visualDeckStorageShowBannerCardComboBoxChanged(visualDeckStorageShowBannerCardComboBox);
+}
+
void SettingsCache::setVisualDeckStorageShowTagsOnDeckPreviews(QT_STATE_CHANGED_T _showTags)
{
visualDeckStorageShowTagsOnDeckPreviews = _showTags;
diff --git a/cockatrice/src/settings/cache_settings.h b/cockatrice/src/settings/cache_settings.h
index ff89bb9e9..bb23394e0 100644
--- a/cockatrice/src/settings/cache_settings.h
+++ b/cockatrice/src/settings/cache_settings.h
@@ -60,6 +60,7 @@ signals:
void printingSelectorCardSizeChanged();
void printingSelectorNavigationButtonsVisibleChanged();
void visualDeckStorageShowTagFilterChanged(bool _visible);
+ void visualDeckStorageShowBannerCardComboBoxChanged(bool _visible);
void visualDeckStorageShowTagsOnDeckPreviewsChanged(bool _visible);
void visualDeckStorageCardSizeChanged();
void visualDeckStorageDrawUnusedColorIdentitiesChanged(bool _visible);
@@ -129,6 +130,7 @@ private:
bool printingSelectorNavigationButtonsVisible;
int visualDeckStorageSortingOrder;
bool visualDeckStorageShowFolders;
+ bool visualDeckStorageShowBannerCardComboBox;
bool visualDeckStorageShowTagsOnDeckPreviews;
bool visualDeckStorageShowTagFilter;
int visualDeckStorageCardSize;
@@ -412,6 +414,10 @@ public:
{
return visualDeckStorageShowTagFilter;
}
+ bool getVisualDeckStorageShowBannerCardComboBox() const
+ {
+ return visualDeckStorageShowBannerCardComboBox;
+ }
bool getVisualDeckStorageShowTagsOnDeckPreviews() const
{
return visualDeckStorageShowTagsOnDeckPreviews;
@@ -760,6 +766,7 @@ public slots:
void setVisualDeckStorageSortingOrder(int _visualDeckStorageSortingOrder);
void setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T value);
void setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T _showTags);
+ void setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T _showBannerCardComboBox);
void setVisualDeckStorageShowTagsOnDeckPreviews(QT_STATE_CHANGED_T _showTags);
void setVisualDeckStorageCardSize(int _visualDeckStorageCardSize);
void setVisualDeckStorageDrawUnusedColorIdentities(QT_STATE_CHANGED_T _visualDeckStorageDrawUnusedColorIdentities);
diff --git a/common/decklist.cpp b/common/decklist.cpp
index 164ccdfc6..d395accff 100644
--- a/common/decklist.cpp
+++ b/common/decklist.cpp
@@ -369,7 +369,7 @@ DeckList::DeckList()
// TODO: https://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
DeckList::DeckList(const DeckList &other)
: QObject(), name(other.name), comments(other.comments), bannerCard(other.bannerCard), deckHash(other.deckHash),
- lastLoadedTimestamp(other.lastLoadedTimestamp)
+ lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags)
{
root = new InnerDecklistNode(other.getRoot());
@@ -807,6 +807,7 @@ void DeckList::cleanList()
root->clearTree();
setName();
setComments();
+ setTags();
deckHash = QString();
emit deckHashChanged();
}
diff --git a/dbconverter/src/mocks.cpp b/dbconverter/src/mocks.cpp
index 21769a5d4..9a76edf84 100644
--- a/dbconverter/src/mocks.cpp
+++ b/dbconverter/src/mocks.cpp
@@ -208,6 +208,9 @@ void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T /* value
void SettingsCache::setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T /* _showTags */)
{
}
+void SettingsCache::setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T /* _showBannerCardComboBox */)
+{
+}
void SettingsCache::setVisualDeckStorageShowTagsOnDeckPreviews(QT_STATE_CHANGED_T /* _showTags */)
{
}
diff --git a/tests/carddatabase/mocks.cpp b/tests/carddatabase/mocks.cpp
index db813a8f1..0383a81d2 100644
--- a/tests/carddatabase/mocks.cpp
+++ b/tests/carddatabase/mocks.cpp
@@ -212,6 +212,9 @@ void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T /* value
void SettingsCache::setVisualDeckStorageShowTagFilter(QT_STATE_CHANGED_T /* _showTags */)
{
}
+void SettingsCache::setVisualDeckStorageShowBannerCardComboBox(QT_STATE_CHANGED_T /* _showBannerCardComboBox */)
+{
+}
void SettingsCache::setVisualDeckStorageShowTagsOnDeckPreviews(QT_STATE_CHANGED_T /* _showTags */)
{
}