[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.
This commit is contained in:
Lukas Brübach 2026-08-30 22:26:41 +02:00
parent f1923e7c13
commit 17ed97be13
3 changed files with 20 additions and 15 deletions

View file

@ -470,20 +470,13 @@ QString DeckStateManager::validateNewZoneName(const QString &zoneName) const
const auto *tree = deckList->getTree(); const auto *tree = deckList->getTree();
// Top-level zones (boards and legacy zones) claim their names too. // Reuse the tree's own uniqueness contract: any top-level zone and any
for (int i = 0; i < tree->getRoot()->size(); i++) { // custom zone on *every* board claims the name (hasZoneName also reserves
if (tree->getRoot()->at(i)->getName() == trimmedZoneName) { // the standard board names, which we already rejected with a dedicated
return tr("A zone with this name already exists."); // 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.");
// 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.");
}
}
} }
return {}; return {};
@ -558,6 +551,7 @@ bool DeckStateManager::modifyTree(const QString &reason, const std::function<boo
historyManager->save(memento); historyManager->save(memento);
deckListModel->rebuildTree(); deckListModel->rebuildTree();
deckList->refreshDeckHash(); deckList->refreshDeckHash();
emit deckListModel->deckHashChanged();
doCardModified(); doCardModified();
} }

View file

@ -50,6 +50,9 @@ DeckZoneDialog::DeckZoneDialog(QWidget *parent,
if (allowBoardSelection) { if (allowBoardSelection) {
layout->addWidget(boardLabel); layout->addWidget(boardLabel);
layout->addWidget(boardCombo); layout->addWidget(boardCombo);
} else {
boardLabel->hide();
boardCombo->hide();
} }
layout->addWidget(buttonBox); layout->addWidget(buttonBox);

View file

@ -115,6 +115,15 @@ public:
*/ */
QList<const InnerDecklistNode *> getCustomZones(const QString &boardZoneName) const; QList<const InnerDecklistNode *> 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. * @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 *findBoardZone(const QString &boardZoneName) const;
InnerDecklistNode *findOrCreateBoardZone(const QString &boardZoneName); InnerDecklistNode *findOrCreateBoardZone(const QString &boardZoneName);
InnerDecklistNode *findCustomZoneByName(const QString &zoneName) const; InnerDecklistNode *findCustomZoneByName(const QString &zoneName) const;
bool hasZoneName(const QString &zoneName) const;
}; };
#endif // COCKATRICE_DECKLIST_NODE_TREE_H #endif // COCKATRICE_DECKLIST_NODE_TREE_H