mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
[Doxygen] abstract_tab_deck_editor (#6286)
* Doxygen abstract_tab_deck_editor Took 15 minutes Took 15 minutes Took 4 seconds * Lint. Took 28 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
757e9f3415
commit
7e6cad974f
2 changed files with 319 additions and 88 deletions
|
|
@ -1,3 +1,12 @@
|
|||
/**
|
||||
* @file abstract_tab_deck_editor.cpp
|
||||
* @brief Implementation of the AbstractTabDeckEditor class.
|
||||
*
|
||||
* Handles deck editor tab UI, deck management, card operations, clipboard
|
||||
* operations, printing, deck export, remote uploads, and interactions with
|
||||
* external services (DeckStats, TappedOut, etc.).
|
||||
*/
|
||||
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
|
|
@ -40,6 +49,11 @@
|
|||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
/**
|
||||
* @brief Constructs the AbstractTabDeckEditor.
|
||||
* Initializes all dock widgets and connects signals/slots.
|
||||
* @param _tabSupervisor The tab supervisor managing this tab.
|
||||
*/
|
||||
AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||
{
|
||||
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||
|
|
@ -53,10 +67,13 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
|||
printingSelectorDockWidget->setHidden(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference());
|
||||
});
|
||||
|
||||
// Connect deck signals to this tab
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckChanged, this, &AbstractTabDeckEditor::onDeckChanged);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckModified, this, &AbstractTabDeckEditor::onDeckModified);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::cardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||
connect(this, &AbstractTabDeckEditor::decrementCard, deckDockWidget, &DeckEditorDeckDockWidget::actDecrementCard);
|
||||
|
||||
// Connect database display signals to this tab
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
||||
&AbstractTabDeckEditor::updateCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, this,
|
||||
|
|
@ -68,69 +85,97 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
|||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, this,
|
||||
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
||||
|
||||
// Connect filter signals
|
||||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||
|
||||
// Connect shortcut changes
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&AbstractTabDeckEditor::refreshShortcuts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the card info dock and printing selector.
|
||||
* @param card The card to display.
|
||||
*/
|
||||
void AbstractTabDeckEditor::updateCard(const ExactCard &card)
|
||||
{
|
||||
cardInfoDockWidget->updateCard(card);
|
||||
printingSelectorDockWidget->printingSelector->setCard(card.getCardPtr(), DECK_ZONE_MAIN);
|
||||
}
|
||||
|
||||
/** @brief Placeholder: called when the deck changes. */
|
||||
void AbstractTabDeckEditor::onDeckChanged()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the tab as modified and updates the save menu status.
|
||||
*/
|
||||
void AbstractTabDeckEditor::onDeckModified()
|
||||
{
|
||||
setModified(!isBlankNewDeck());
|
||||
deckMenu->setSaveStatus(!isBlankNewDeck());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper for adding a card to a deck zone.
|
||||
* @param card Card to add.
|
||||
* @param zoneName Zone to add the card to.
|
||||
*/
|
||||
void AbstractTabDeckEditor::addCardHelper(const ExactCard &card, QString zoneName)
|
||||
{
|
||||
if (!card)
|
||||
return;
|
||||
|
||||
if (card.getInfo().getIsToken())
|
||||
zoneName = DECK_ZONE_TOKENS;
|
||||
|
||||
QModelIndex newCardIndex = deckDockWidget->deckModel->addCard(card, zoneName);
|
||||
// recursiveExpand(newCardIndex);
|
||||
deckDockWidget->deckView->clearSelection();
|
||||
deckDockWidget->deckView->setCurrentIndex(newCardIndex);
|
||||
setModified(true);
|
||||
|
||||
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a card to the main deck or sideboard depending on Ctrl key.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actAddCard(const ExactCard &card)
|
||||
{
|
||||
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
||||
actAddCardToSideboard(card);
|
||||
else
|
||||
addCardHelper(card, DECK_ZONE_MAIN);
|
||||
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
/** @brief Adds a card to the sideboard explicitly. */
|
||||
void AbstractTabDeckEditor::actAddCardToSideboard(const ExactCard &card)
|
||||
{
|
||||
addCardHelper(card, DECK_ZONE_SIDE);
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
/** @brief Decrements a card from the main deck. */
|
||||
void AbstractTabDeckEditor::actDecrementCard(const ExactCard &card)
|
||||
{
|
||||
emit decrementCard(card, DECK_ZONE_MAIN);
|
||||
}
|
||||
|
||||
/** @brief Decrements a card from the sideboard. */
|
||||
void AbstractTabDeckEditor::actDecrementCardFromSideboard(const ExactCard &card)
|
||||
{
|
||||
emit decrementCard(card, DECK_ZONE_SIDE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Swaps a card in a deck zone.
|
||||
* @param card Card to swap.
|
||||
* @param zoneName Zone to swap in.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actSwapCard(const ExactCard &card, const QString &zoneName)
|
||||
{
|
||||
QString providerId = card.getPrinting().getUuid();
|
||||
|
|
@ -145,8 +190,8 @@ void AbstractTabDeckEditor::actSwapCard(const ExactCard &card, const QString &zo
|
|||
}
|
||||
|
||||
/**
|
||||
* Opens the deck in this tab.
|
||||
* @param deck The deck. Takes ownership of the object
|
||||
* @brief Opens a deck in this tab.
|
||||
* @param deck DeckLoader object (takes ownership).
|
||||
*/
|
||||
void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
|
||||
{
|
||||
|
|
@ -158,8 +203,8 @@ void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the currently active deck for this tab
|
||||
* @param _deck The deck. Takes ownership of the object
|
||||
* @brief Sets the currently active deck.
|
||||
* @param _deck DeckLoader object.
|
||||
*/
|
||||
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
||||
{
|
||||
|
|
@ -167,16 +212,20 @@ void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
|||
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
|
||||
setModified(false);
|
||||
|
||||
// If they load a deck, make the deck list appear
|
||||
aDeckDockVisible->setChecked(true);
|
||||
deckDockWidget->setVisible(aDeckDockVisible->isChecked());
|
||||
}
|
||||
|
||||
/** @brief Returns the currently loaded deck. */
|
||||
DeckLoader *AbstractTabDeckEditor::getDeckList() const
|
||||
{
|
||||
return deckDockWidget->getDeckList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the modified state of the tab.
|
||||
* @param _modified True if tab is modified, false otherwise.
|
||||
*/
|
||||
void AbstractTabDeckEditor::setModified(bool _modified)
|
||||
{
|
||||
modified = _modified;
|
||||
|
|
@ -184,7 +233,7 @@ void AbstractTabDeckEditor::setModified(bool _modified)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if this tab is a blank newly opened tab, as if it was just created with the `New Deck` action.
|
||||
* @brief Returns true if the tab is a blank newly created deck.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||
{
|
||||
|
|
@ -192,13 +241,12 @@ bool AbstractTabDeckEditor::isBlankNewDeck() const
|
|||
return !modified && deck->isBlankDeck() && deck->hasNotBeenLoaded();
|
||||
}
|
||||
|
||||
/** @brief Creates a new deck. Handles opening in new tab if needed. */
|
||||
void AbstractTabDeckEditor::actNewDeck()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen(false);
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
if (deckOpenLocation == CANCELLED)
|
||||
return;
|
||||
}
|
||||
|
||||
if (deckOpenLocation == NEW_TAB) {
|
||||
emit openDeckEditor(nullptr);
|
||||
|
|
@ -208,6 +256,7 @@ void AbstractTabDeckEditor::actNewDeck()
|
|||
cleanDeckAndResetModified();
|
||||
}
|
||||
|
||||
/** @brief Clears the current deck and resets modified flag. */
|
||||
void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
||||
{
|
||||
deckMenu->setSaveStatus(false);
|
||||
|
|
@ -216,43 +265,29 @@ void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
|||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @brief Displays the save confirmation dialog before loading a deck.
|
||||
* @param openInSameTabIfBlank Open in same tab if current tab is blank.
|
||||
* @return DeckOpenLocation enum indicating where to open the deck.
|
||||
*/
|
||||
AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const bool openInSameTabIfBlank)
|
||||
{
|
||||
// handle `openDeckInNewTab` setting
|
||||
if (SettingsCache::instance().getOpenDeckInNewTab()) {
|
||||
if (openInSameTabIfBlank && isBlankNewDeck()) {
|
||||
if (openInSameTabIfBlank && isBlankNewDeck())
|
||||
return SAME_TAB;
|
||||
} else {
|
||||
else
|
||||
return NEW_TAB;
|
||||
}
|
||||
}
|
||||
|
||||
// early return if deck is unmodified
|
||||
if (!modified) {
|
||||
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) {
|
||||
if (msgBox->clickedButton() == newTabButton)
|
||||
return NEW_TAB;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case QMessageBox::Save:
|
||||
|
|
@ -265,9 +300,8 @@ AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the base save confirmation dialogue box.
|
||||
*
|
||||
* @returns A QMessageBox that can be further modified
|
||||
* @brief Creates the base save confirmation dialog.
|
||||
* @return Pointer to a QMessageBox.
|
||||
*/
|
||||
QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
||||
{
|
||||
|
|
@ -279,13 +313,15 @@ QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
|||
return msgBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads a deck from file using a dialog.
|
||||
* Displays a save confirmation if needed.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actLoadDeck()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
if (deckOpenLocation == CANCELLED)
|
||||
return;
|
||||
}
|
||||
|
||||
DlgLoadDeck dialog(this);
|
||||
if (!dialog.exec())
|
||||
|
|
@ -296,21 +332,23 @@ void AbstractTabDeckEditor::actLoadDeck()
|
|||
deckDockWidget->updateBannerCardComboBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens a recently used deck file.
|
||||
* @param fileName Path to the deck file.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actOpenRecent(const QString &fileName)
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
if (deckOpenLocation == CANCELLED)
|
||||
return;
|
||||
}
|
||||
|
||||
openDeckFromFile(fileName, deckOpenLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually opens the deck from file
|
||||
* @param fileName The path of the deck to open
|
||||
* @param deckOpenLocation Which tab to open the deck
|
||||
* @brief Actually opens a deck from file.
|
||||
* @param fileName Path to the deck file.
|
||||
* @param deckOpenLocation Where to open the deck (same or new tab).
|
||||
*/
|
||||
void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation)
|
||||
{
|
||||
|
|
@ -332,6 +370,11 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
|
|||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Saves the current deck.
|
||||
* If remote deck, sends upload command.
|
||||
* @return True if save succeeded, false otherwise.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::actSaveDeck()
|
||||
{
|
||||
DeckLoader *const deck = getDeckList();
|
||||
|
|
@ -357,12 +400,17 @@ bool AbstractTabDeckEditor::actSaveDeck()
|
|||
setModified(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Saves the deck to a user-selected file.
|
||||
* @return True if save succeeded.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::actSaveDeckAs()
|
||||
{
|
||||
QFileDialog dialog(this, tr("Save deck"));
|
||||
|
|
@ -384,13 +432,16 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
|||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
|
||||
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback for remote deck save completion.
|
||||
* @param response Server response.
|
||||
*/
|
||||
void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
||||
{
|
||||
if (response.response_code() != Response::RespOk)
|
||||
|
|
@ -399,13 +450,15 @@ void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
|||
setModified(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads a deck from clipboard.
|
||||
* Displays confirmation if the tab is modified.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
if (deckOpenLocation == CANCELLED)
|
||||
return;
|
||||
}
|
||||
|
||||
DlgLoadDeckFromClipboard dlg(this);
|
||||
if (!dlg.exec())
|
||||
|
|
@ -421,6 +474,10 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
|||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens the deck editor to edit clipboard contents.
|
||||
* @param annotated If true, edits with annotations.
|
||||
*/
|
||||
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
||||
{
|
||||
DlgEditDeckInClipboard dlg(*getDeckList(), annotated, this);
|
||||
|
|
@ -429,40 +486,46 @@ void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
|||
|
||||
setDeck(dlg.getDeckList());
|
||||
setModified(true);
|
||||
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
/** @brief Slot for editing deck in clipboard with annotations. */
|
||||
void AbstractTabDeckEditor::actEditDeckInClipboard()
|
||||
{
|
||||
editDeckInClipboard(true);
|
||||
}
|
||||
|
||||
/** @brief Slot for editing deck in clipboard without annotations. */
|
||||
void AbstractTabDeckEditor::actEditDeckInClipboardRaw()
|
||||
{
|
||||
editDeckInClipboard(false);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard with set info and annotation. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
||||
{
|
||||
getDeckList()->saveToClipboard(true, true);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard with annotation, without set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo()
|
||||
{
|
||||
getDeckList()->saveToClipboard(true, false);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard without annotations, with set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
||||
{
|
||||
getDeckList()->saveToClipboard(false, true);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard without annotations or set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
||||
{
|
||||
getDeckList()->saveToClipboard(false, false);
|
||||
}
|
||||
|
||||
/** @brief Prints the deck using a QPrintPreviewDialog. */
|
||||
void AbstractTabDeckEditor::actPrintDeck()
|
||||
{
|
||||
auto *dlg = new QPrintPreviewDialog(this);
|
||||
|
|
@ -470,13 +533,14 @@ void AbstractTabDeckEditor::actPrintDeck()
|
|||
dlg->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads a deck from a website.
|
||||
*/
|
||||
void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
if (deckOpenLocation == CANCELLED)
|
||||
return;
|
||||
}
|
||||
|
||||
DlgLoadDeckFromWebsite dlg(this);
|
||||
if (!dlg.exec())
|
||||
|
|
@ -492,18 +556,21 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
|||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exports the deck to a decklist website.
|
||||
* @param website Website to export to.
|
||||
*/
|
||||
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
// check if deck is not null
|
||||
if (DeckLoader *const deck = getDeckList()) {
|
||||
// Get the decklist url string from the deck loader class.
|
||||
QString decklistUrlString = deck->exportDeckToDecklist(website);
|
||||
// Check to make sure the string isn't empty.
|
||||
if (QString::compare(decklistUrlString, "", Qt::CaseInsensitive) == 0) {
|
||||
if (decklistUrlString.isEmpty()) {
|
||||
// Show an error if the deck is empty, and return.
|
||||
QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Encode the string recieved from the model to make sure all characters are encoded.
|
||||
// first we put it into a qurl object
|
||||
QUrl decklistUrl = QUrl(decklistUrlString);
|
||||
|
|
@ -517,48 +584,54 @@ void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the deck to www.decklist.org (the old website)
|
||||
*/
|
||||
/** @brief Exports deck to www.decklist.org. */
|
||||
void AbstractTabDeckEditor::actExportDeckDecklist()
|
||||
{
|
||||
exportToDecklistWebsite(DeckLoader::DecklistOrg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the deck to www.decklist.xyz (the new website)
|
||||
*/
|
||||
/** @brief Exports deck to www.decklist.xyz. */
|
||||
void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
||||
{
|
||||
exportToDecklistWebsite(DeckLoader::DecklistXyz);
|
||||
}
|
||||
|
||||
/** @brief Analyzes the deck using DeckStats. */
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||
{
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||
this); // it deletes itself when done
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
interface->analyzeDeck(getDeckList());
|
||||
}
|
||||
|
||||
/** @brief Analyzes the deck using TappedOut. */
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||
{
|
||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||
this); // it deletes itself when done
|
||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
interface->analyzeDeck(getDeckList());
|
||||
}
|
||||
|
||||
/** @brief Applies a new filter tree to the database display. */
|
||||
void AbstractTabDeckEditor::filterTreeChanged(FilterTree *filterTree)
|
||||
{
|
||||
databaseDisplayDockWidget->setFilterTree(filterTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the close event of the tab.
|
||||
* @param event Close event.
|
||||
*/
|
||||
void AbstractTabDeckEditor::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
emit deckEditorClosing(this);
|
||||
event->accept();
|
||||
}
|
||||
|
||||
// Method uses to sync docks state with menu items state
|
||||
/**
|
||||
* @brief Event filter for dock visibility and geometry changes.
|
||||
* @param o Object sending the event.
|
||||
* @param e Event.
|
||||
* @return False always.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::Close) {
|
||||
|
|
@ -576,6 +649,7 @@ bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
|||
aPrintingSelectorDockFloating->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (o == this && e->type() == QEvent::Hide) {
|
||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||
layouts.setDeckEditorLayoutState(saveState());
|
||||
|
|
@ -585,9 +659,11 @@ bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
|||
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Shows a confirmation dialog before closing. */
|
||||
bool AbstractTabDeckEditor::confirmClose()
|
||||
{
|
||||
if (modified) {
|
||||
|
|
@ -601,11 +677,10 @@ bool AbstractTabDeckEditor::confirmClose()
|
|||
return true;
|
||||
}
|
||||
|
||||
/** @brief Handles close requests from outside (tab manager). */
|
||||
bool AbstractTabDeckEditor::closeRequest()
|
||||
{
|
||||
if (!confirmClose()) {
|
||||
if (!confirmClose())
|
||||
return false;
|
||||
}
|
||||
|
||||
return close();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
/**
|
||||
* @file abstract_tab_deck_editor.h
|
||||
* @brief Defines the AbstractTabDeckEditor class, which provides a base for
|
||||
* deck editor tabs in the application.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||
#define TAB_GENERIC_DECK_EDITOR_H
|
||||
|
||||
|
|
@ -40,6 +47,45 @@ class QDockWidget;
|
|||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
/**
|
||||
* @class AbstractTabDeckEditor
|
||||
* @ingroup DeckEditorTabs
|
||||
* @brief AbstractTabDeckEditor is the base class for all deck editor tabs.
|
||||
*
|
||||
* **Description:**
|
||||
* AbstractTabDeckEditor is the base class for all deck editor tabs. It provides core functionality such as deck model
|
||||
* management, card addition/removal, and integration with dock widgets and tab supervisors.
|
||||
*
|
||||
* **Purpose:**
|
||||
*
|
||||
* - Acts as the foundation for deck editor tabs (TabDeckEditor and TabDeckEditorVisual).
|
||||
* - Provides basic deck operations like adding, removing, swapping, and decrementing cards.
|
||||
* - Integrates with DeckListModel and CardDatabaseModel to access deck and card data.
|
||||
* - Handles saving, loading, and layout persistence at the tab level.
|
||||
*
|
||||
* **Dock Widgets (typically managed in derived classes):**
|
||||
*
|
||||
* - DeckEditorCardInfoDockWidget — Displays detailed card info.
|
||||
* - DeckEditorDeckDockWidget— Displays mainboard/sideboard cards and zones.
|
||||
* - DeckEditorFilterDockWidget— Provides filtering options for card searches.
|
||||
* - DeckEditorPrintingSelectorDockWidget— Selector for different card printings.
|
||||
* - DeckEditorDatabaseDisplayWidget— Shows card database for adding cards to deck.
|
||||
*
|
||||
* **Key Methods:**
|
||||
*
|
||||
* - actAddCard(const ExactCard &card) — Adds a card to the deck.
|
||||
* - actDecrementCard(const ExactCard &card) — Removes a single instance of a card from the deck.
|
||||
* - actSwapCard(const ExactCard &card, const QString &zone) — Swaps a card between zones.
|
||||
* - actRemoveCard() — Removes the currently selected card from the deck.
|
||||
* - actSaveDeckAs() — Performs a "Save As" action for the deck.
|
||||
* - updateCard(const ExactCard &card) — Updates the currently displayed card info in the dock.
|
||||
* - onDeckModified() — Called when the deck model is changed.
|
||||
*
|
||||
* Provides UI docks for the deck, database, card info, printing selector,
|
||||
* and filters. Supports loading, saving, editing, exporting decks, and
|
||||
* interactions with external services such as DeckStats, TappedOut, and
|
||||
* remote deck uploads.
|
||||
*/
|
||||
class AbstractTabDeckEditor : public Tab
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -47,68 +93,150 @@ class AbstractTabDeckEditor : public Tab
|
|||
friend class DeckEditorMenu;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs an AbstractTabDeckEditor.
|
||||
* @param _tabSupervisor Pointer to the TabSupervisor managing this tab.
|
||||
*/
|
||||
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||
|
||||
// UI and Navigation
|
||||
/** @brief Creates the menus for this tab. Pure virtual. */
|
||||
virtual void createMenus() = 0;
|
||||
|
||||
/** @brief Returns the display text for the tab. */
|
||||
[[nodiscard]] virtual QString getTabText() const override = 0;
|
||||
|
||||
/** @brief Confirms whether the tab can be safely closed. */
|
||||
bool confirmClose();
|
||||
|
||||
/** @brief Retranslates the UI text. Pure virtual. */
|
||||
virtual void retranslateUi() override = 0;
|
||||
|
||||
// Deck Management
|
||||
/** @brief Opens a deck in this tab.
|
||||
* @param deck Pointer to a DeckLoader object.
|
||||
*/
|
||||
void openDeck(DeckLoader *deck);
|
||||
|
||||
/** @brief Returns the currently active deck. */
|
||||
DeckLoader *getDeckList() const;
|
||||
|
||||
/** @brief Sets the modified state of the tab.
|
||||
* @param _windowModified Whether the tab is modified.
|
||||
*/
|
||||
void setModified(bool _windowModified);
|
||||
|
||||
// UI Elements
|
||||
DeckEditorMenu *deckMenu;
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget;
|
||||
DeckEditorCardInfoDockWidget *cardInfoDockWidget;
|
||||
DeckEditorDeckDockWidget *deckDockWidget;
|
||||
DeckEditorFilterDockWidget *filterDockWidget;
|
||||
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
||||
DeckEditorMenu *deckMenu; ///< Menu for deck operations
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget; ///< Database dock
|
||||
DeckEditorCardInfoDockWidget *cardInfoDockWidget; ///< Card info dock
|
||||
DeckEditorDeckDockWidget *deckDockWidget; ///< Deck dock
|
||||
DeckEditorFilterDockWidget *filterDockWidget; ///< Filter dock
|
||||
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget; ///< Printing selector dock
|
||||
|
||||
public slots:
|
||||
/** @brief Called when the deck changes. */
|
||||
virtual void onDeckChanged();
|
||||
|
||||
/** @brief Called when the deck is modified. */
|
||||
virtual void onDeckModified();
|
||||
|
||||
/** @brief Updates the card info panel.
|
||||
* @param card The card to display.
|
||||
*/
|
||||
void updateCard(const ExactCard &card);
|
||||
|
||||
/** @brief Adds a card to the main deck or sideboard based on Ctrl key. */
|
||||
void actAddCard(const ExactCard &card);
|
||||
|
||||
/** @brief Adds a card to the sideboard explicitly. */
|
||||
void actAddCardToSideboard(const ExactCard &card);
|
||||
|
||||
/** @brief Decrements a card from the main deck. */
|
||||
void actDecrementCard(const ExactCard &card);
|
||||
|
||||
/** @brief Decrements a card from the sideboard. */
|
||||
void actDecrementCardFromSideboard(const ExactCard &card);
|
||||
|
||||
/** @brief Opens a recently opened deck file. */
|
||||
void actOpenRecent(const QString &fileName);
|
||||
|
||||
/** @brief Called when the filter tree changes. */
|
||||
void filterTreeChanged(FilterTree *filterTree);
|
||||
|
||||
/** @brief Requests closing the tab. */
|
||||
bool closeRequest() override;
|
||||
|
||||
/** @brief Shows the printing selector dock. Pure virtual. */
|
||||
virtual void showPrintingSelector() = 0;
|
||||
|
||||
/** @brief Slot for when a dock's top-level state changes. Pure virtual. */
|
||||
virtual void dockTopLevelChanged(bool topLevel) = 0;
|
||||
|
||||
signals:
|
||||
/** @brief Emitted when a deck should be opened in a new editor tab. */
|
||||
void openDeckEditor(const DeckLoader *deckLoader);
|
||||
|
||||
/** @brief Emitted before the tab is closed. */
|
||||
void deckEditorClosing(AbstractTabDeckEditor *tab);
|
||||
|
||||
/** @brief Emitted when a card should be decremented. */
|
||||
void decrementCard(const ExactCard &card, QString zoneName);
|
||||
|
||||
protected slots:
|
||||
// Deck Operations
|
||||
/** @brief Starts a new deck in this tab. */
|
||||
virtual void actNewDeck();
|
||||
|
||||
/** @brief Cleans the current deck and resets the modified state. */
|
||||
void cleanDeckAndResetModified();
|
||||
|
||||
/** @brief Loads a deck from file. */
|
||||
virtual void actLoadDeck();
|
||||
|
||||
/** @brief Saves the current deck. */
|
||||
bool actSaveDeck();
|
||||
|
||||
/** @brief Saves the current deck under a new name. */
|
||||
virtual bool actSaveDeckAs();
|
||||
|
||||
/** @brief Loads a deck from the clipboard. */
|
||||
virtual void actLoadDeckFromClipboard();
|
||||
|
||||
/** @brief Opens a deck editor for clipboard contents. */
|
||||
void actEditDeckInClipboard();
|
||||
|
||||
/** @brief Opens a raw clipboard deck editor. */
|
||||
void actEditDeckInClipboardRaw();
|
||||
|
||||
/** @brief Saves deck to clipboard with full info. */
|
||||
void actSaveDeckToClipboard();
|
||||
|
||||
/** @brief Saves deck to clipboard without set info. */
|
||||
void actSaveDeckToClipboardNoSetInfo();
|
||||
|
||||
/** @brief Saves deck to clipboard in raw format. */
|
||||
void actSaveDeckToClipboardRaw();
|
||||
|
||||
/** @brief Saves deck to clipboard in raw format without set info. */
|
||||
void actSaveDeckToClipboardRawNoSetInfo();
|
||||
|
||||
/** @brief Prints the deck using a preview dialog. */
|
||||
void actPrintDeck();
|
||||
|
||||
/** @brief Loads a deck from an online website. */
|
||||
void actLoadDeckFromWebsite();
|
||||
|
||||
/** @brief Exports the deck to decklist.org. */
|
||||
void actExportDeckDecklist();
|
||||
|
||||
/** @brief Exports the deck to decklist.xyz. */
|
||||
void actExportDeckDecklistXyz();
|
||||
|
||||
/** @brief Analyzes the deck using deckstats.net. */
|
||||
void actAnalyzeDeckDeckstats();
|
||||
|
||||
/** @brief Analyzes the deck using tappedout.net. */
|
||||
void actAnalyzeDeckTappedout();
|
||||
|
||||
// Remote Save
|
||||
/** @brief Callback when a remote deck save finishes. */
|
||||
void saveDeckRemoteFinished(const Response &r);
|
||||
|
||||
// UI Layout Management
|
||||
|
|
@ -117,34 +245,62 @@ protected slots:
|
|||
virtual void freeDocksSize() = 0;
|
||||
virtual void refreshShortcuts() = 0;
|
||||
|
||||
/** @brief Handles dock close events. */
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
/** @brief Event filter for dock state changes. */
|
||||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
|
||||
/** @brief Slot triggered when a dock visibility changes. Pure virtual. */
|
||||
virtual void dockVisibleTriggered() = 0;
|
||||
|
||||
/** @brief Slot triggered when a dock floating state changes. Pure virtual. */
|
||||
virtual void dockFloatingTriggered() = 0;
|
||||
|
||||
private:
|
||||
/** @brief Sets the deck for this tab.
|
||||
* @param _deck The deck object.
|
||||
*/
|
||||
virtual void setDeck(DeckLoader *_deck);
|
||||
|
||||
/** @brief Helper for editing decks from the clipboard. */
|
||||
void editDeckInClipboard(bool annotated);
|
||||
|
||||
/** @brief Helper for exporting decks to websites.
|
||||
* @param website Target website.
|
||||
*/
|
||||
void exportToDecklistWebsite(DeckLoader::DecklistWebsite website);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Enum for selecting deck open location
|
||||
*/
|
||||
/** @brief Enum describing deck open locations */
|
||||
enum DeckOpenLocation
|
||||
{
|
||||
CANCELLED,
|
||||
SAME_TAB,
|
||||
NEW_TAB
|
||||
CANCELLED, ///< Operation cancelled
|
||||
SAME_TAB, ///< Open deck in the same tab
|
||||
NEW_TAB ///< Open deck in a new tab
|
||||
};
|
||||
|
||||
/** @brief Confirms deck open action based on settings and modified state.
|
||||
* @param openInSameTabIfBlank Whether to reuse same tab if blank.
|
||||
* @return Selected DeckOpenLocation.
|
||||
*/
|
||||
DeckOpenLocation confirmOpen(bool openInSameTabIfBlank = true);
|
||||
|
||||
/** @brief Creates a save confirmation message box.
|
||||
* @return Pointer to a QMessageBox.
|
||||
*/
|
||||
QMessageBox *createSaveConfirmationWindow();
|
||||
|
||||
/** @brief Returns true if the tab is a blank newly created deck. */
|
||||
bool isBlankNewDeck() const;
|
||||
|
||||
// Helper functions for card actions
|
||||
/** @brief Helper function to add a card to a specific deck zone. */
|
||||
void addCardHelper(const ExactCard &card, QString zoneName);
|
||||
|
||||
/** @brief Swaps a card in the deck view. */
|
||||
void actSwapCard(const ExactCard &card, const QString &zoneName);
|
||||
|
||||
/** @brief Opens a deck from a file. */
|
||||
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
||||
|
||||
// UI Menu Elements
|
||||
|
|
@ -154,7 +310,7 @@ protected:
|
|||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
||||
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||
|
||||
bool modified = false;
|
||||
bool modified = false; ///< Whether the deck/tab has unsaved changes
|
||||
};
|
||||
|
||||
#endif // TAB_GENERIC_DECK_EDITOR_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue