From 1bc92623dc97059d856af093d00d3d47e27e45b8 Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:24:50 -0800 Subject: [PATCH] add "open in new tab" button to decklist confirmation dialogue (#5183) * refactor to use confirmOpen * implement extra button in confirmation * use brackets in one-liner if statements * refactor save confirmation window into function --- .../src/client/tabs/tab_deck_editor.cpp | 91 ++++++++++++++++--- cockatrice/src/client/tabs/tab_deck_editor.h | 14 +++ 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/cockatrice/src/client/tabs/tab_deck_editor.cpp b/cockatrice/src/client/tabs/tab_deck_editor.cpp index 0c9edbb0b..1e2284186 100644 --- a/cockatrice/src/client/tabs/tab_deck_editor.cpp +++ b/cockatrice/src/client/tabs/tab_deck_editor.cpp @@ -748,9 +748,7 @@ bool TabDeckEditor::confirmClose() { if (modified) { tabSupervisor->setCurrentWidget(this); - QMessageBox::StandardButton ret = QMessageBox::warning( - this, tr("Are you sure?"), tr("The decklist has been modified.\nDo you want to save the changes?"), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + int ret = createSaveConfirmationWindow()->exec(); if (ret == QMessageBox::Save) return actSaveDeck(); else if (ret == QMessageBox::Cancel) @@ -767,13 +765,16 @@ void TabDeckEditor::closeRequest() void TabDeckEditor::actNewDeck() { - if (SettingsCache::instance().getOpenDeckInNewTab()) { - emit openDeckEditor(nullptr); + auto deckOpenLocation = confirmOpen(false); + + if (deckOpenLocation == CANCELLED) { return; } - if (!confirmClose()) + if (deckOpenLocation == NEW_TAB) { + emit openDeckEditor(nullptr); return; + } deckModel->cleanList(); nameEdit->setText(QString()); @@ -785,10 +786,11 @@ void TabDeckEditor::actNewDeck() void TabDeckEditor::actLoadDeck() { - bool openInNewTab = SettingsCache::instance().getOpenDeckInNewTab() && !isBlankNewDeck(); + auto deckOpenLocation = confirmOpen(); - if (!openInNewTab && !confirmClose()) + if (deckOpenLocation == CANCELLED) { return; + } QFileDialog dialog(this, tr("Load deck")); dialog.setDirectory(SettingsCache::instance().getDeckPath()); @@ -801,7 +803,7 @@ void TabDeckEditor::actLoadDeck() auto *l = new DeckLoader; if (l->loadFromFile(fileName, fmt)) { - if (openInNewTab) { + if (deckOpenLocation == NEW_TAB) { emit openDeckEditor(l); } else { setSaveStatus(false); @@ -878,16 +880,17 @@ bool TabDeckEditor::actSaveDeckAs() void TabDeckEditor::actLoadDeckFromClipboard() { - bool openInNewTab = SettingsCache::instance().getOpenDeckInNewTab() && !isBlankNewDeck(); + auto deckOpenLocation = confirmOpen(); - if (!openInNewTab && !confirmClose()) + if (deckOpenLocation == CANCELLED) { return; + } DlgLoadDeckFromClipboard dlg(this); if (!dlg.exec()) return; - if (openInNewTab) { + if (deckOpenLocation == NEW_TAB) { emit openDeckEditor(dlg.getDeckList()); } else { setDeck(dlg.getDeckList()); @@ -987,6 +990,70 @@ void TabDeckEditor::recursiveExpand(const QModelIndex &index) deckView->expand(index); } +/** + * @brief Displays the save confirmation dialogue that is shown before loading a deck, if required. Takes into + * account the `openDeckInNewTab` settting. + * + * @param openInSameTabIfBlank Open the deck in the same tab instead of a new tab if the current tab is completely + * blank. Only relevant when the `openDeckInNewTab` setting is enabled. + * + * @returns An enum that indicates if and where to load the deck + */ +TabDeckEditor::DeckOpenLocation TabDeckEditor::confirmOpen(const bool openInSameTabIfBlank) +{ + // handle `openDeckInNewTab` setting + if (SettingsCache::instance().getOpenDeckInNewTab()) { + if (openInSameTabIfBlank && isBlankNewDeck()) { + return SAME_TAB; + } else { + return NEW_TAB; + } + } + + // early return if deck is unmodified + if (!modified) { + return SAME_TAB; + } + + // do the save confirmation dialogue + tabSupervisor->setCurrentWidget(this); + + QMessageBox *msgBox = createSaveConfirmationWindow(); + QPushButton *newTabButton = msgBox->addButton(tr("Open in new tab"), QMessageBox::ApplyRole); + + int ret = msgBox->exec(); + + // `exec()` returns an opaque value if a non-standard button was clicked. + // Directly check if newTabButton was clicked before switching over the standard buttons. + if (msgBox->clickedButton() == newTabButton) { + return NEW_TAB; + } + + switch (ret) { + case QMessageBox::Save: + return actSaveDeck() ? SAME_TAB : CANCELLED; + case QMessageBox::Discard: + return SAME_TAB; + default: + return CANCELLED; + } +} + +/** + * @brief Creates the base save confirmation dialogue box. + * + * @returns A QMessageBox that can be further modified + */ +QMessageBox *TabDeckEditor::createSaveConfirmationWindow() +{ + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setIcon(QMessageBox::Warning); + msgBox->setWindowTitle(tr("Are you sure?")); + msgBox->setText(tr("The decklist has been modified.\nDo you want to save the changes?")); + msgBox->setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + return msgBox; +} + /** * @brief Returns true if this tab is a blank newly opened tab, as if it was just created with the `New Deck` action. */ diff --git a/cockatrice/src/client/tabs/tab_deck_editor.h b/cockatrice/src/client/tabs/tab_deck_editor.h index b8c45c110..6aff1cc31 100644 --- a/cockatrice/src/client/tabs/tab_deck_editor.h +++ b/cockatrice/src/client/tabs/tab_deck_editor.h @@ -22,6 +22,7 @@ class Response; class FilterTreeModel; class FilterBuilder; class QGroupBox; +class QMessageBox; class QHBoxLayout; class QVBoxLayout; class QPushButton; @@ -100,6 +101,19 @@ private slots: void showSearchSyntaxHelp(); private: + /** + * @brief Which tab to open the new deck in + */ + enum DeckOpenLocation + { + CANCELLED, + SAME_TAB, + NEW_TAB + }; + + DeckOpenLocation confirmOpen(const bool openInSameTabIfBlank = true); + QMessageBox *createSaveConfirmationWindow(); + bool isBlankNewDeck() const; CardInfoPtr currentCardInfo() const; void addCardHelper(QString zoneName);