mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-24 10:23:02 -07:00
[Client] Expose custom zone management in the deck editor
Wires the state layer into every editor surface that shows deck zones. - Deck dock: context menu on zones gains New/Rename/Delete/Change board actions, with per-zone submenus for adding cards. - Card database dock and visual database display gain an add-to-zone submenu listing custom zones per board plus a create-zone entry. - All prompt call sites pass validateNewZoneName so duplicates and reserved names are rejected inline before Ok unlocks. - Rename reuses the same dialog in name-only mode, keeping one validation contract for every zone-name entry point. - Change board marks the current board instead of offering a no-op, and the state layer refuses moves onto boards holding a same-named zone from imported decks.
This commit is contained in:
parent
5a18de28be
commit
fc6e1af1df
11 changed files with 258 additions and 0 deletions
|
|
@ -90,6 +90,13 @@ void CardDatabaseView::decrementCard(const QString &zoneName)
|
||||||
emit cardDecremented(currentCardName(), zoneName);
|
emit cardDecremented(currentCardName(), zoneName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CardDatabaseView::setZoneMenuProvider(const std::function<QList<QPair<QString, QStringList>>()> &provider,
|
||||||
|
const std::function<void()> &newZoneHandler)
|
||||||
|
{
|
||||||
|
zoneMenuProvider = provider;
|
||||||
|
this->newZoneHandler = newZoneHandler;
|
||||||
|
}
|
||||||
|
|
||||||
void CardDatabaseView::updateCard(const QModelIndex ¤t, const QModelIndex & /*previous*/)
|
void CardDatabaseView::updateCard(const QModelIndex ¤t, const QModelIndex & /*previous*/)
|
||||||
{
|
{
|
||||||
if (!current.isValid()) {
|
if (!current.isValid()) {
|
||||||
|
|
@ -142,6 +149,40 @@ void CardDatabaseView::openCustomMenu(QPoint point)
|
||||||
[this, card] { emit cardAdded(card->getName(), DECK_ZONE_SIDE); });
|
[this, card] { emit cardAdded(card->getName(), DECK_ZONE_SIDE); });
|
||||||
connect(selectPrinting, &QAction::triggered, this, &CardDatabaseView::selectPrintingClicked);
|
connect(selectPrinting, &QAction::triggered, this, &CardDatabaseView::selectPrintingClicked);
|
||||||
|
|
||||||
|
if (zoneMenuProvider) {
|
||||||
|
QMenu *addToZoneMenu = menu.addMenu(tr("Add to Zone"));
|
||||||
|
for (const QString &boardName :
|
||||||
|
{QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE), QString(DECK_ZONE_MAYBEBOARD)}) {
|
||||||
|
QAction *action = addToZoneMenu->addAction(InnerDecklistNode::visibleNameFromName(boardName));
|
||||||
|
connect(action, &QAction::triggered, this,
|
||||||
|
[this, card, boardName] { emit cardAdded(card->getName(), boardName); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool anyCustomZone = false;
|
||||||
|
const auto zoneBoards = zoneMenuProvider();
|
||||||
|
for (const auto &zoneBoard : zoneBoards) {
|
||||||
|
const QString &boardName = zoneBoard.first;
|
||||||
|
const QStringList &customZones = zoneBoard.second;
|
||||||
|
if (customZones.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anyCustomZone = true;
|
||||||
|
QMenu *boardSubmenu = addToZoneMenu->addMenu(InnerDecklistNode::visibleNameFromName(boardName));
|
||||||
|
for (const QString &zoneName : customZones) {
|
||||||
|
QAction *action = boardSubmenu->addAction(zoneName);
|
||||||
|
connect(action, &QAction::triggered, this,
|
||||||
|
[this, card, zoneName] { emit cardAdded(card->getName(), zoneName); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anyCustomZone) {
|
||||||
|
addToZoneMenu->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction *newZoneAction = addToZoneMenu->addAction(tr("Create &new zone..."));
|
||||||
|
connect(newZoneAction, &QAction::triggered, this, [this] { newZoneHandler(); });
|
||||||
|
}
|
||||||
|
|
||||||
if (canBeCommander(*card)) {
|
if (canBeCommander(*card)) {
|
||||||
QAction *edhRecCommander = menu.addAction(tr("Show on EDHRec (Commander)"));
|
QAction *edhRecCommander = menu.addAction(tr("Show on EDHRec (Commander)"));
|
||||||
connect(edhRecCommander, &QAction::triggered, this, [this, card] { emit edhrecClicked(card, true); });
|
connect(edhRecCommander, &QAction::triggered, this, [this, card] { emit edhrecClicked(card, true); });
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../../key_signals.h"
|
#include "../../key_signals.h"
|
||||||
|
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
#include <functional>
|
||||||
#include <libcockatrice/card/card_info.h>
|
#include <libcockatrice/card/card_info.h>
|
||||||
|
|
||||||
class CardDatabaseModel;
|
class CardDatabaseModel;
|
||||||
|
|
@ -19,6 +20,12 @@ class CardDatabaseView : public QTreeView
|
||||||
KeySignals searchKeySignals;
|
KeySignals searchKeySignals;
|
||||||
CardDatabaseDisplayModel *databaseDisplayModel;
|
CardDatabaseDisplayModel *databaseDisplayModel;
|
||||||
|
|
||||||
|
/// Provides the custom zones available in the current deck, grouped by board zone.
|
||||||
|
/// The list contains (board zone name, custom zone names) pairs for every board.
|
||||||
|
std::function<QList<QPair<QString, QStringList>>()> zoneMenuProvider;
|
||||||
|
/// Handler invoked when the user picks "New zone..." from the add-to-zone menu.
|
||||||
|
std::function<void()> newZoneHandler;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CardDatabaseView(QWidget *parent, CardDatabaseDisplayModel *model);
|
explicit CardDatabaseView(QWidget *parent, CardDatabaseDisplayModel *model);
|
||||||
|
|
||||||
|
|
@ -33,6 +40,16 @@ public:
|
||||||
return &searchKeySignals;
|
return &searchKeySignals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the provider used to populate the "Add to zone" submenu of the context menu.
|
||||||
|
* If no provider is set, the submenu is not shown.
|
||||||
|
*
|
||||||
|
* @param provider Returns the custom zones of the current deck, grouped by board zone
|
||||||
|
* @param newZoneHandler Invoked when the user chooses "New zone..." in the submenu
|
||||||
|
*/
|
||||||
|
void setZoneMenuProvider(const std::function<QList<QPair<QString, QStringList>>()> &provider,
|
||||||
|
const std::function<void()> &newZoneHandler);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void cardChanged(const QString &cardName);
|
void cardChanged(const QString &cardName);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
#include "deck_editor_card_database_dock_widget.h"
|
#include "deck_editor_card_database_dock_widget.h"
|
||||||
|
|
||||||
|
#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h"
|
||||||
|
#include "card_database_view.h"
|
||||||
|
#include "deck_state_manager.h"
|
||||||
|
#include "deck_zone_dialog.h"
|
||||||
|
|
||||||
|
#include <libcockatrice/deck_list/deck_list_node_tree.h>
|
||||||
|
|
||||||
DeckEditorCardDatabaseDockWidget::DeckEditorCardDatabaseDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent)
|
DeckEditorCardDatabaseDockWidget::DeckEditorCardDatabaseDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent)
|
||||||
{
|
{
|
||||||
setObjectName("databaseDisplayDock");
|
setObjectName("databaseDisplayDock");
|
||||||
|
|
@ -15,6 +22,26 @@ void DeckEditorCardDatabaseDockWidget::createDatabaseDisplayDock(AbstractTabDeck
|
||||||
{
|
{
|
||||||
databaseDisplayWidget = new DeckEditorDatabaseDisplayWidget(this, deckEditor->databaseModel);
|
databaseDisplayWidget = new DeckEditorDatabaseDisplayWidget(this, deckEditor->databaseModel);
|
||||||
|
|
||||||
|
databaseDisplayWidget->getDatabaseView()->setZoneMenuProvider(
|
||||||
|
[deckEditor]() -> QList<QPair<QString, QStringList>> {
|
||||||
|
QList<QPair<QString, QStringList>> result;
|
||||||
|
auto *deckListModel = deckEditor->deckStateManager->getModel();
|
||||||
|
for (const QString &boardName :
|
||||||
|
{QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE), QString(DECK_ZONE_MAYBEBOARD)}) {
|
||||||
|
result.append({boardName, deckListModel->getCustomZoneNames(boardName)});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
[this, deckEditor] {
|
||||||
|
QString boardName;
|
||||||
|
const QString zoneName = promptForNewZone(this, {}, &boardName, [deckEditor](const QString &candidate) {
|
||||||
|
return deckEditor->deckStateManager->validateNewZoneName(candidate);
|
||||||
|
});
|
||||||
|
if (!zoneName.isEmpty()) {
|
||||||
|
deckEditor->deckStateManager->createCustomZone(boardName, zoneName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
auto *frame = new QVBoxLayout;
|
auto *frame = new QVBoxLayout;
|
||||||
frame->setObjectName("databaseDisplayFrame");
|
frame->setObjectName("databaseDisplayFrame");
|
||||||
frame->addWidget(databaseDisplayWidget);
|
frame->addWidget(databaseDisplayWidget);
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,18 @@
|
||||||
#include "../tabs/api/commander_spellbook/commander_bracket_widget.h"
|
#include "../tabs/api/commander_spellbook/commander_bracket_widget.h"
|
||||||
#include "deck_list_style_proxy.h"
|
#include "deck_list_style_proxy.h"
|
||||||
#include "deck_state_manager.h"
|
#include "deck_state_manager.h"
|
||||||
|
#include "deck_zone_dialog.h"
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <libcockatrice/card/database/card_database_manager.h>
|
#include <libcockatrice/card/database/card_database_manager.h>
|
||||||
|
#include <libcockatrice/deck_list/deck_list_node_tree.h>
|
||||||
#include <libcockatrice/settings/deck_editor_settings.h>
|
#include <libcockatrice/settings/deck_editor_settings.h>
|
||||||
#include <libcockatrice/settings/interface_settings.h>
|
#include <libcockatrice/settings/interface_settings.h>
|
||||||
#include <libcockatrice/utility/macros.h>
|
#include <libcockatrice/utility/macros.h>
|
||||||
|
|
@ -772,14 +775,142 @@ void DeckEditorDeckDockWidget::offsetCountAtIndex(const QModelIndex &idx, bool i
|
||||||
|
|
||||||
void DeckEditorDeckDockWidget::decklistCustomMenu(QPoint point)
|
void DeckEditorDeckDockWidget::decklistCustomMenu(QPoint point)
|
||||||
{
|
{
|
||||||
|
const QModelIndex sourceIndex = proxy->mapToSource(deckView->indexAt(point));
|
||||||
|
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
|
|
||||||
|
const bool isCustomZoneRow = sourceIndex.isValid() && sourceIndex.data(DeckRoles::IsCustomZoneRole).toBool();
|
||||||
|
const bool isBoardZoneRow = sourceIndex.isValid() && !isCustomZoneRow && !sourceIndex.parent().isValid();
|
||||||
|
const bool isCardRow =
|
||||||
|
sourceIndex.isValid() && !isCustomZoneRow && !isBoardZoneRow && !getModel()->hasChildren(sourceIndex);
|
||||||
|
|
||||||
|
if (isCardRow) {
|
||||||
|
addMoveToZoneMenu(&menu, sourceIndex);
|
||||||
|
menu.addSeparator();
|
||||||
|
} else if (isCustomZoneRow) {
|
||||||
|
const QString zoneName =
|
||||||
|
sourceIndex.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
|
||||||
|
|
||||||
|
QAction *renameAction = menu.addAction(tr("&Rename zone..."));
|
||||||
|
connect(renameAction, &QAction::triggered, this, [this, zoneName] {
|
||||||
|
const QString newName = promptForRename(this, zoneName, [this](const QString &candidate) {
|
||||||
|
return deckStateManager->validateNewZoneName(candidate);
|
||||||
|
});
|
||||||
|
if (!newName.isEmpty() && newName != zoneName) {
|
||||||
|
deckStateManager->renameCustomZone(zoneName, newName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QMenu *boardMenu = menu.addMenu(tr("Change &board"));
|
||||||
|
addChangeBoardMenu(boardMenu, zoneName);
|
||||||
|
|
||||||
|
QAction *deleteAction = menu.addAction(tr("&Delete zone"));
|
||||||
|
deleteAction->setEnabled(!getModel()->hasChildren(sourceIndex));
|
||||||
|
deleteAction->setStatusTip(tr("Move or remove all cards first."));
|
||||||
|
connect(deleteAction, &QAction::triggered, this, [this, zoneName] {
|
||||||
|
const auto result =
|
||||||
|
QMessageBox::warning(this, tr("Delete zone"), tr("Delete the zone \"%1\"?").arg(zoneName),
|
||||||
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
|
if (result == QMessageBox::Yes) {
|
||||||
|
deckStateManager->removeCustomZone(zoneName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addSeparator();
|
||||||
|
} else if (isBoardZoneRow) {
|
||||||
|
const QString boardName =
|
||||||
|
sourceIndex.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
|
||||||
|
// Tokens cannot host custom zones, so only offer the action on real boards.
|
||||||
|
const bool canHostCustomZones =
|
||||||
|
boardName == DECK_ZONE_MAIN || boardName == DECK_ZONE_SIDE || boardName == DECK_ZONE_MAYBEBOARD;
|
||||||
|
if (canHostCustomZones) {
|
||||||
|
addNewZoneAction(&menu, boardName);
|
||||||
|
menu.addSeparator();
|
||||||
|
}
|
||||||
|
} else if (!sourceIndex.isValid()) {
|
||||||
|
addNewZoneAction(&menu);
|
||||||
|
menu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
QAction *selectPrinting = menu.addAction(tr("Select Printing"));
|
QAction *selectPrinting = menu.addAction(tr("Select Printing"));
|
||||||
connect(selectPrinting, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::showPrintingSelector);
|
connect(selectPrinting, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::showPrintingSelector);
|
||||||
|
|
||||||
menu.exec(deckView->mapToGlobal(point));
|
menu.exec(deckView->mapToGlobal(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::addMoveToZoneMenu(QMenu *menu, const QModelIndex &sourceCardIndex)
|
||||||
|
{
|
||||||
|
const auto moveToZone = [this, sourceCardIndex](const QString &targetZoneName) {
|
||||||
|
deckStateManager->moveCardToZone(sourceCardIndex, targetZoneName);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const QString &boardName : {QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE), QString(DECK_ZONE_MAYBEBOARD)}) {
|
||||||
|
QAction *action = menu->addAction(InnerDecklistNode::visibleNameFromName(boardName));
|
||||||
|
connect(action, &QAction::triggered, this, [moveToZone, boardName] { moveToZone(boardName); });
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto tree = deckStateManager->getDeckListShared()->getTree();
|
||||||
|
bool anyCustomZone = false;
|
||||||
|
for (const QString &boardName : {QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE), QString(DECK_ZONE_MAYBEBOARD)}) {
|
||||||
|
QList<const InnerDecklistNode *> customZones = tree->getCustomZones(boardName);
|
||||||
|
if (customZones.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anyCustomZone = true;
|
||||||
|
QMenu *boardSubmenu = menu->addMenu(InnerDecklistNode::visibleNameFromName(boardName));
|
||||||
|
for (const auto *customZone : customZones) {
|
||||||
|
QAction *action = boardSubmenu->addAction(customZone->getName());
|
||||||
|
connect(action, &QAction::triggered, this, [moveToZone, customZone] { moveToZone(customZone->getName()); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anyCustomZone) {
|
||||||
|
menu->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
addNewZoneAction(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::addChangeBoardMenu(QMenu *menu, const QString &zoneName)
|
||||||
|
{
|
||||||
|
const auto tree = deckStateManager->getDeckListShared()->getTree();
|
||||||
|
for (const QString &boardName : {QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE), QString(DECK_ZONE_MAYBEBOARD)}) {
|
||||||
|
QAction *action = menu->addAction(InnerDecklistNode::visibleNameFromName(boardName));
|
||||||
|
|
||||||
|
// The board currently holding the zone is marked instead of offered.
|
||||||
|
// Duplicate names cannot come up through the editor, so this doubles as
|
||||||
|
// the uniqueness guard for imported decks.
|
||||||
|
bool holdsTheZone = false;
|
||||||
|
for (const auto *customZone : tree->getCustomZones(boardName)) {
|
||||||
|
if (customZone->getName() == zoneName) {
|
||||||
|
holdsTheZone = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (holdsTheZone) {
|
||||||
|
action->setCheckable(true);
|
||||||
|
action->setChecked(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(action, &QAction::triggered, this,
|
||||||
|
[this, zoneName, boardName] { deckStateManager->moveCustomZone(zoneName, boardName); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::addNewZoneAction(QMenu *menu, const QString &initialBoardName)
|
||||||
|
{
|
||||||
|
QAction *newZoneAction = menu->addAction(tr("Create &new zone..."));
|
||||||
|
connect(newZoneAction, &QAction::triggered, this, [this, initialBoardName] {
|
||||||
|
QString boardName;
|
||||||
|
const QString zoneName = promptForNewZone(this, initialBoardName, &boardName, [this](const QString &candidate) {
|
||||||
|
return deckStateManager->validateNewZoneName(candidate);
|
||||||
|
});
|
||||||
|
if (!zoneName.isEmpty()) {
|
||||||
|
deckStateManager->createCustomZone(boardName, zoneName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void DeckEditorDeckDockWidget::refreshShortcuts()
|
void DeckEditorDeckDockWidget::refreshShortcuts()
|
||||||
{
|
{
|
||||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QMenu>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
|
@ -102,6 +103,10 @@ private:
|
||||||
[[nodiscard]] QModelIndexList getSelectedCardNodeSourceIndices() const;
|
[[nodiscard]] QModelIndexList getSelectedCardNodeSourceIndices() const;
|
||||||
void offsetCountAtIndex(const QModelIndex &idx, bool isIncrement);
|
void offsetCountAtIndex(const QModelIndex &idx, bool isIncrement);
|
||||||
|
|
||||||
|
void addMoveToZoneMenu(QMenu *menu, const QModelIndex &sourceCardIndex);
|
||||||
|
void addChangeBoardMenu(QMenu *menu, const QString &zoneName);
|
||||||
|
void addNewZoneAction(QMenu *menu, const QString &initialBoardName = {});
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void decklistCustomMenu(QPoint point);
|
void decklistCustomMenu(QPoint point);
|
||||||
void updateCard(QModelIndex, const QModelIndex ¤t);
|
void updateCard(QModelIndex, const QModelIndex ¤t);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../../../../client/settings/shortcuts_settings.h"
|
#include "../../../../client/settings/shortcuts_settings.h"
|
||||||
#include "../../cards/card_info_display_widget.h"
|
#include "../../cards/card_info_display_widget.h"
|
||||||
#include "../../deck_editor/deck_state_manager.h"
|
#include "../../deck_editor/deck_state_manager.h"
|
||||||
|
#include "../../deck_editor/deck_zone_dialog.h"
|
||||||
#include "../../filters/filter_builder.h"
|
#include "../../filters/filter_builder.h"
|
||||||
#include "../../interface/pixel_map_generator.h"
|
#include "../../interface/pixel_map_generator.h"
|
||||||
#include "../../interface/widgets/cards/card_info_frame_widget.h"
|
#include "../../interface/widgets/cards/card_info_frame_widget.h"
|
||||||
|
|
@ -84,6 +85,7 @@ void TabDeckEditorVisual::createCentralFrame()
|
||||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::printingSelectorRequested, this,
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::printingSelectorRequested, this,
|
||||||
&TabDeckEditorVisual::showPrintingSelector);
|
&TabDeckEditorVisual::showPrintingSelector);
|
||||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardInfoRequested, this, &TabDeckEditorVisual::updateCardInfo);
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardInfoRequested, this, &TabDeckEditorVisual::updateCardInfo);
|
||||||
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::newZoneRequested, this, &TabDeckEditorVisual::createNewZone);
|
||||||
|
|
||||||
centralFrame->addWidget(tabContainer);
|
centralFrame->addWidget(tabContainer);
|
||||||
setCentralWidget(centralWidget);
|
setCentralWidget(centralWidget);
|
||||||
|
|
@ -269,6 +271,18 @@ bool TabDeckEditorVisual::actSaveDeckAs()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Prompts for and creates a new custom deck zone. */
|
||||||
|
void TabDeckEditorVisual::createNewZone()
|
||||||
|
{
|
||||||
|
QString boardName;
|
||||||
|
const QString zoneName = promptForNewZone(this, {}, &boardName, [this](const QString &candidate) {
|
||||||
|
return deckStateManager->validateNewZoneName(candidate);
|
||||||
|
});
|
||||||
|
if (!zoneName.isEmpty()) {
|
||||||
|
deckStateManager->createCustomZone(boardName, zoneName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief Refreshes keyboard shortcuts for this tab from settings. */
|
/** @brief Refreshes keyboard shortcuts for this tab from settings. */
|
||||||
void TabDeckEditorVisual::refreshShortcuts()
|
void TabDeckEditorVisual::refreshShortcuts()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,11 @@ public slots:
|
||||||
*/
|
*/
|
||||||
bool actSaveDeckAs() override;
|
bool actSaveDeckAs() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prompts for and creates a new custom deck zone.
|
||||||
|
*/
|
||||||
|
void createNewZone();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Sets the deck for this tab and selects the sub-tab to open on
|
* @brief Sets the deck for this tab and selects the sub-tab to open on
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
|
||||||
&TabDeckEditorVisualTabWidget::printingSelectorRequested);
|
&TabDeckEditorVisualTabWidget::printingSelectorRequested);
|
||||||
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardInfoRequested, this,
|
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardInfoRequested, this,
|
||||||
&TabDeckEditorVisualTabWidget::cardInfoRequested);
|
&TabDeckEditorVisualTabWidget::cardInfoRequested);
|
||||||
|
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::newZoneRequested, this,
|
||||||
|
&TabDeckEditorVisualTabWidget::newZoneRequested);
|
||||||
|
|
||||||
statsAnalyzer = new DeckListStatisticsAnalyzer(this, deckModel);
|
statsAnalyzer = new DeckListStatisticsAnalyzer(this, deckModel);
|
||||||
statsAnalyzer->analyze();
|
statsAnalyzer->analyze();
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,7 @@ signals:
|
||||||
void edhrecRequested(const CardInfoPtr &cardInfo, bool isCommander);
|
void edhrecRequested(const CardInfoPtr &cardInfo, bool isCommander);
|
||||||
void printingSelectorRequested();
|
void printingSelectorRequested();
|
||||||
void cardInfoRequested(const ExactCard &cardName);
|
void cardInfoRequested(const ExactCard &cardName);
|
||||||
|
void newZoneRequested();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout *layout; ///< Layout for tabs and controls.
|
QVBoxLayout *layout; ///< Layout for tabs and controls.
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,20 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
|
||||||
databaseView->setItemDelegate(nullptr);
|
databaseView->setItemDelegate(nullptr);
|
||||||
databaseView->setVisible(false);
|
databaseView->setVisible(false);
|
||||||
|
|
||||||
|
// Without a deck model there is nothing to add cards to, so the zone menu stays hidden.
|
||||||
|
if (deckListModel) {
|
||||||
|
databaseView->setZoneMenuProvider(
|
||||||
|
[this, deckListModel]() -> QList<QPair<QString, QStringList>> {
|
||||||
|
QList<QPair<QString, QStringList>> result;
|
||||||
|
for (const QString &boardName :
|
||||||
|
{QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE), QString(DECK_ZONE_MAYBEBOARD)}) {
|
||||||
|
result.append({boardName, deckListModel->getCustomZoneNames(boardName)});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
[this] { emit newZoneRequested(); });
|
||||||
|
}
|
||||||
|
|
||||||
searchEdit->setTreeView(databaseView);
|
searchEdit->setTreeView(databaseView);
|
||||||
searchEdit->installEventFilter(databaseView->getKeySignals());
|
searchEdit->installEventFilter(databaseView->getKeySignals());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ signals:
|
||||||
void edhrecRequested(const CardInfoPtr &cardInfo, bool isCommander);
|
void edhrecRequested(const CardInfoPtr &cardInfo, bool isCommander);
|
||||||
void printingSelectorRequested();
|
void printingSelectorRequested();
|
||||||
void cardInfoRequested(const ExactCard &cardName);
|
void cardInfoRequested(const ExactCard &cardName);
|
||||||
|
void newZoneRequested();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue