From 48ae7cf0ed778dff9992101ae6913f3075ee16d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Sun, 30 Aug 2026 22:26:41 +0200 Subject: [PATCH] [DeckEditor] Address zone-management review feedback - Expose DecklistNodeTree::hasZoneName and use it in validateNewZoneName so the uniqueness scan covers custom zones on every board, not just the standard ones. - Hide the board selector in the rename dialog path where it is not used. - Emit deckHashChanged after refreshDeckHash so the deck hash label stays current after zone create/rename/move/remove. --- .../deck_editor/deck_state_manager.cpp | 22 +++++++------------ .../widgets/deck_editor/deck_zone_dialog.cpp | 3 +++ .../deck_list/deck_list_node_tree.h | 10 ++++++++- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp index b60685d20..e007e6dd0 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp @@ -470,20 +470,13 @@ QString DeckStateManager::validateNewZoneName(const QString &zoneName) const const auto *tree = deckList->getTree(); - // Top-level zones (boards and legacy zones) claim their names too. - for (int i = 0; i < tree->getRoot()->size(); i++) { - if (tree->getRoot()->at(i)->getName() == trimmedZoneName) { - return tr("A zone with this name already exists."); - } - } - - // Custom zone names are unique across the whole deck. - for (const QString &board : InnerDecklistNode::boardZoneNames()) { - for (const auto *customZone : tree->getCustomZones(board)) { - if (customZone->getName() == trimmedZoneName) { - return tr("A zone with this name already exists."); - } - } + // Reuse the tree's own uniqueness contract: any top-level zone and any + // custom zone on *every* board claims the name (hasZoneName also reserves + // the standard board names, which we already rejected with a dedicated + // message above). Scanning only the standard boards here would miss a + // custom zone an imported deck carries under `tokens`. + if (tree->hasZoneName(trimmedZoneName)) { + return tr("A zone with this name already exists."); } return {}; @@ -558,6 +551,7 @@ bool DeckStateManager::modifyTree(const QString &reason, const std::functionsave(memento); deckListModel->rebuildTree(); deckList->refreshDeckHash(); + emit deckListModel->deckHashChanged(); doCardModified(); } diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp index a14beec0e..9a0be2570 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp @@ -50,6 +50,9 @@ DeckZoneDialog::DeckZoneDialog(QWidget *parent, if (allowBoardSelection) { layout->addWidget(boardLabel); layout->addWidget(boardCombo); + } else { + boardLabel->hide(); + boardCombo->hide(); } layout->addWidget(buttonBox); diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h index af1193f26..3c88d6030 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h @@ -115,6 +115,15 @@ public: */ QList getCustomZones(const QString &boardZoneName) const; + /** + * @brief Checks whether a zone name is taken anywhere in the deck. + * + * Covers the standard board names and any top-level or nested custom zone. + * @param zoneName The checked name. + * @return true if the name is reserved or already in use. + */ + bool hasZoneName(const QString &zoneName) const; + /** * @brief Applies a function to every card in the deck tree. This can modify the cards. * @@ -129,7 +138,6 @@ private: InnerDecklistNode *findBoardZone(const QString &boardZoneName) const; InnerDecklistNode *findOrCreateBoardZone(const QString &boardZoneName); InnerDecklistNode *findCustomZoneByName(const QString &zoneName) const; - bool hasZoneName(const QString &zoneName) const; }; #endif // COCKATRICE_DECKLIST_NODE_TREE_H