mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-27 00:53:55 -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 "abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
#include "../../../client/settings/cache_settings.h"
|
#include "../../../client/settings/cache_settings.h"
|
||||||
|
|
@ -40,6 +49,11 @@
|
||||||
#include <libcockatrice/protocol/pending_command.h>
|
#include <libcockatrice/protocol/pending_command.h>
|
||||||
#include <libcockatrice/utility/trice_limits.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)
|
AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||||
{
|
{
|
||||||
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||||
|
|
@ -53,10 +67,13 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
||||||
printingSelectorDockWidget->setHidden(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference());
|
printingSelectorDockWidget->setHidden(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Connect deck signals to this tab
|
||||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckChanged, this, &AbstractTabDeckEditor::onDeckChanged);
|
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckChanged, this, &AbstractTabDeckEditor::onDeckChanged);
|
||||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckModified, this, &AbstractTabDeckEditor::onDeckModified);
|
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckModified, this, &AbstractTabDeckEditor::onDeckModified);
|
||||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::cardChanged, this, &AbstractTabDeckEditor::updateCard);
|
connect(deckDockWidget, &DeckEditorDeckDockWidget::cardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||||
connect(this, &AbstractTabDeckEditor::decrementCard, deckDockWidget, &DeckEditorDeckDockWidget::actDecrementCard);
|
connect(this, &AbstractTabDeckEditor::decrementCard, deckDockWidget, &DeckEditorDeckDockWidget::actDecrementCard);
|
||||||
|
|
||||||
|
// Connect database display signals to this tab
|
||||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
||||||
&AbstractTabDeckEditor::updateCard);
|
&AbstractTabDeckEditor::updateCard);
|
||||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, this,
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, this,
|
||||||
|
|
@ -68,69 +85,97 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
||||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, this,
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, this,
|
||||||
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
||||||
|
|
||||||
|
// Connect filter signals
|
||||||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||||
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||||
|
|
||||||
|
// Connect shortcut changes
|
||||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
&AbstractTabDeckEditor::refreshShortcuts);
|
&AbstractTabDeckEditor::refreshShortcuts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates the card info dock and printing selector.
|
||||||
|
* @param card The card to display.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::updateCard(const ExactCard &card)
|
void AbstractTabDeckEditor::updateCard(const ExactCard &card)
|
||||||
{
|
{
|
||||||
cardInfoDockWidget->updateCard(card);
|
cardInfoDockWidget->updateCard(card);
|
||||||
printingSelectorDockWidget->printingSelector->setCard(card.getCardPtr(), DECK_ZONE_MAIN);
|
printingSelectorDockWidget->printingSelector->setCard(card.getCardPtr(), DECK_ZONE_MAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Placeholder: called when the deck changes. */
|
||||||
void AbstractTabDeckEditor::onDeckChanged()
|
void AbstractTabDeckEditor::onDeckChanged()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the tab as modified and updates the save menu status.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::onDeckModified()
|
void AbstractTabDeckEditor::onDeckModified()
|
||||||
{
|
{
|
||||||
setModified(!isBlankNewDeck());
|
setModified(!isBlankNewDeck());
|
||||||
deckMenu->setSaveStatus(!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)
|
void AbstractTabDeckEditor::addCardHelper(const ExactCard &card, QString zoneName)
|
||||||
{
|
{
|
||||||
if (!card)
|
if (!card)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (card.getInfo().getIsToken())
|
if (card.getInfo().getIsToken())
|
||||||
zoneName = DECK_ZONE_TOKENS;
|
zoneName = DECK_ZONE_TOKENS;
|
||||||
|
|
||||||
QModelIndex newCardIndex = deckDockWidget->deckModel->addCard(card, zoneName);
|
QModelIndex newCardIndex = deckDockWidget->deckModel->addCard(card, zoneName);
|
||||||
// recursiveExpand(newCardIndex);
|
|
||||||
deckDockWidget->deckView->clearSelection();
|
deckDockWidget->deckView->clearSelection();
|
||||||
deckDockWidget->deckView->setCurrentIndex(newCardIndex);
|
deckDockWidget->deckView->setCurrentIndex(newCardIndex);
|
||||||
setModified(true);
|
setModified(true);
|
||||||
|
|
||||||
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
|
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)
|
void AbstractTabDeckEditor::actAddCard(const ExactCard &card)
|
||||||
{
|
{
|
||||||
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
||||||
actAddCardToSideboard(card);
|
actAddCardToSideboard(card);
|
||||||
else
|
else
|
||||||
addCardHelper(card, DECK_ZONE_MAIN);
|
addCardHelper(card, DECK_ZONE_MAIN);
|
||||||
|
|
||||||
deckMenu->setSaveStatus(true);
|
deckMenu->setSaveStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Adds a card to the sideboard explicitly. */
|
||||||
void AbstractTabDeckEditor::actAddCardToSideboard(const ExactCard &card)
|
void AbstractTabDeckEditor::actAddCardToSideboard(const ExactCard &card)
|
||||||
{
|
{
|
||||||
addCardHelper(card, DECK_ZONE_SIDE);
|
addCardHelper(card, DECK_ZONE_SIDE);
|
||||||
deckMenu->setSaveStatus(true);
|
deckMenu->setSaveStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Decrements a card from the main deck. */
|
||||||
void AbstractTabDeckEditor::actDecrementCard(const ExactCard &card)
|
void AbstractTabDeckEditor::actDecrementCard(const ExactCard &card)
|
||||||
{
|
{
|
||||||
emit decrementCard(card, DECK_ZONE_MAIN);
|
emit decrementCard(card, DECK_ZONE_MAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Decrements a card from the sideboard. */
|
||||||
void AbstractTabDeckEditor::actDecrementCardFromSideboard(const ExactCard &card)
|
void AbstractTabDeckEditor::actDecrementCardFromSideboard(const ExactCard &card)
|
||||||
{
|
{
|
||||||
emit decrementCard(card, DECK_ZONE_SIDE);
|
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)
|
void AbstractTabDeckEditor::actSwapCard(const ExactCard &card, const QString &zoneName)
|
||||||
{
|
{
|
||||||
QString providerId = card.getPrinting().getUuid();
|
QString providerId = card.getPrinting().getUuid();
|
||||||
|
|
@ -145,8 +190,8 @@ void AbstractTabDeckEditor::actSwapCard(const ExactCard &card, const QString &zo
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the deck in this tab.
|
* @brief Opens a deck in this tab.
|
||||||
* @param deck The deck. Takes ownership of the object
|
* @param deck DeckLoader object (takes ownership).
|
||||||
*/
|
*/
|
||||||
void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
|
void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
|
||||||
{
|
{
|
||||||
|
|
@ -158,8 +203,8 @@ void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the currently active deck for this tab
|
* @brief Sets the currently active deck.
|
||||||
* @param _deck The deck. Takes ownership of the object
|
* @param _deck DeckLoader object.
|
||||||
*/
|
*/
|
||||||
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
||||||
{
|
{
|
||||||
|
|
@ -167,16 +212,20 @@ void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
||||||
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
|
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
|
||||||
setModified(false);
|
setModified(false);
|
||||||
|
|
||||||
// If they load a deck, make the deck list appear
|
|
||||||
aDeckDockVisible->setChecked(true);
|
aDeckDockVisible->setChecked(true);
|
||||||
deckDockWidget->setVisible(aDeckDockVisible->isChecked());
|
deckDockWidget->setVisible(aDeckDockVisible->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Returns the currently loaded deck. */
|
||||||
DeckLoader *AbstractTabDeckEditor::getDeckList() const
|
DeckLoader *AbstractTabDeckEditor::getDeckList() const
|
||||||
{
|
{
|
||||||
return deckDockWidget->getDeckList();
|
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)
|
void AbstractTabDeckEditor::setModified(bool _modified)
|
||||||
{
|
{
|
||||||
modified = _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
|
bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||||
{
|
{
|
||||||
|
|
@ -192,13 +241,12 @@ bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||||
return !modified && deck->isBlankDeck() && deck->hasNotBeenLoaded();
|
return !modified && deck->isBlankDeck() && deck->hasNotBeenLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Creates a new deck. Handles opening in new tab if needed. */
|
||||||
void AbstractTabDeckEditor::actNewDeck()
|
void AbstractTabDeckEditor::actNewDeck()
|
||||||
{
|
{
|
||||||
auto deckOpenLocation = confirmOpen(false);
|
auto deckOpenLocation = confirmOpen(false);
|
||||||
|
if (deckOpenLocation == CANCELLED)
|
||||||
if (deckOpenLocation == CANCELLED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (deckOpenLocation == NEW_TAB) {
|
if (deckOpenLocation == NEW_TAB) {
|
||||||
emit openDeckEditor(nullptr);
|
emit openDeckEditor(nullptr);
|
||||||
|
|
@ -208,6 +256,7 @@ void AbstractTabDeckEditor::actNewDeck()
|
||||||
cleanDeckAndResetModified();
|
cleanDeckAndResetModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Clears the current deck and resets modified flag. */
|
||||||
void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
||||||
{
|
{
|
||||||
deckMenu->setSaveStatus(false);
|
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
|
* @brief Displays the save confirmation dialog before loading a deck.
|
||||||
* account the `openDeckInNewTab` settting.
|
* @param openInSameTabIfBlank Open in same tab if current tab is blank.
|
||||||
*
|
* @return DeckOpenLocation enum indicating where to open the deck.
|
||||||
* @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
|
|
||||||
*/
|
*/
|
||||||
AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const bool openInSameTabIfBlank)
|
AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const bool openInSameTabIfBlank)
|
||||||
{
|
{
|
||||||
// handle `openDeckInNewTab` setting
|
|
||||||
if (SettingsCache::instance().getOpenDeckInNewTab()) {
|
if (SettingsCache::instance().getOpenDeckInNewTab()) {
|
||||||
if (openInSameTabIfBlank && isBlankNewDeck()) {
|
if (openInSameTabIfBlank && isBlankNewDeck())
|
||||||
return SAME_TAB;
|
return SAME_TAB;
|
||||||
} else {
|
else
|
||||||
return NEW_TAB;
|
return NEW_TAB;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// early return if deck is unmodified
|
if (!modified)
|
||||||
if (!modified) {
|
|
||||||
return SAME_TAB;
|
return SAME_TAB;
|
||||||
}
|
|
||||||
|
|
||||||
// do the save confirmation dialogue
|
|
||||||
tabSupervisor->setCurrentWidget(this);
|
tabSupervisor->setCurrentWidget(this);
|
||||||
|
|
||||||
QMessageBox *msgBox = createSaveConfirmationWindow();
|
QMessageBox *msgBox = createSaveConfirmationWindow();
|
||||||
QPushButton *newTabButton = msgBox->addButton(tr("Open in new tab"), QMessageBox::ApplyRole);
|
QPushButton *newTabButton = msgBox->addButton(tr("Open in new tab"), QMessageBox::ApplyRole);
|
||||||
|
|
||||||
int ret = msgBox->exec();
|
int ret = msgBox->exec();
|
||||||
|
|
||||||
// `exec()` returns an opaque value if a non-standard button was clicked.
|
if (msgBox->clickedButton() == newTabButton)
|
||||||
// Directly check if newTabButton was clicked before switching over the standard buttons.
|
|
||||||
if (msgBox->clickedButton() == newTabButton) {
|
|
||||||
return NEW_TAB;
|
return NEW_TAB;
|
||||||
}
|
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case QMessageBox::Save:
|
case QMessageBox::Save:
|
||||||
|
|
@ -265,9 +300,8 @@ AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates the base save confirmation dialogue box.
|
* @brief Creates the base save confirmation dialog.
|
||||||
*
|
* @return Pointer to a QMessageBox.
|
||||||
* @returns A QMessageBox that can be further modified
|
|
||||||
*/
|
*/
|
||||||
QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
||||||
{
|
{
|
||||||
|
|
@ -279,13 +313,15 @@ QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
||||||
return msgBox;
|
return msgBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads a deck from file using a dialog.
|
||||||
|
* Displays a save confirmation if needed.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::actLoadDeck()
|
void AbstractTabDeckEditor::actLoadDeck()
|
||||||
{
|
{
|
||||||
auto deckOpenLocation = confirmOpen();
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
if (deckOpenLocation == CANCELLED)
|
||||||
if (deckOpenLocation == CANCELLED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
DlgLoadDeck dialog(this);
|
DlgLoadDeck dialog(this);
|
||||||
if (!dialog.exec())
|
if (!dialog.exec())
|
||||||
|
|
@ -296,21 +332,23 @@ void AbstractTabDeckEditor::actLoadDeck()
|
||||||
deckDockWidget->updateBannerCardComboBox();
|
deckDockWidget->updateBannerCardComboBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opens a recently used deck file.
|
||||||
|
* @param fileName Path to the deck file.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::actOpenRecent(const QString &fileName)
|
void AbstractTabDeckEditor::actOpenRecent(const QString &fileName)
|
||||||
{
|
{
|
||||||
auto deckOpenLocation = confirmOpen();
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
if (deckOpenLocation == CANCELLED)
|
||||||
if (deckOpenLocation == CANCELLED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
openDeckFromFile(fileName, deckOpenLocation);
|
openDeckFromFile(fileName, deckOpenLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually opens the deck from file
|
* @brief Actually opens a deck from file.
|
||||||
* @param fileName The path of the deck to open
|
* @param fileName Path to the deck file.
|
||||||
* @param deckOpenLocation Which tab to open the deck
|
* @param deckOpenLocation Where to open the deck (same or new tab).
|
||||||
*/
|
*/
|
||||||
void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation)
|
void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation)
|
||||||
{
|
{
|
||||||
|
|
@ -332,6 +370,11 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
|
||||||
deckMenu->setSaveStatus(true);
|
deckMenu->setSaveStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves the current deck.
|
||||||
|
* If remote deck, sends upload command.
|
||||||
|
* @return True if save succeeded, false otherwise.
|
||||||
|
*/
|
||||||
bool AbstractTabDeckEditor::actSaveDeck()
|
bool AbstractTabDeckEditor::actSaveDeck()
|
||||||
{
|
{
|
||||||
DeckLoader *const deck = getDeckList();
|
DeckLoader *const deck = getDeckList();
|
||||||
|
|
@ -357,12 +400,17 @@ bool AbstractTabDeckEditor::actSaveDeck()
|
||||||
setModified(false);
|
setModified(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox::critical(
|
QMessageBox::critical(
|
||||||
this, tr("Error"),
|
this, tr("Error"),
|
||||||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves the deck to a user-selected file.
|
||||||
|
* @return True if save succeeded.
|
||||||
|
*/
|
||||||
bool AbstractTabDeckEditor::actSaveDeckAs()
|
bool AbstractTabDeckEditor::actSaveDeckAs()
|
||||||
{
|
{
|
||||||
QFileDialog dialog(this, tr("Save deck"));
|
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."));
|
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setModified(false);
|
setModified(false);
|
||||||
|
|
||||||
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback for remote deck save completion.
|
||||||
|
* @param response Server response.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
||||||
{
|
{
|
||||||
if (response.response_code() != Response::RespOk)
|
if (response.response_code() != Response::RespOk)
|
||||||
|
|
@ -399,13 +450,15 @@ void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
||||||
setModified(false);
|
setModified(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads a deck from clipboard.
|
||||||
|
* Displays confirmation if the tab is modified.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
||||||
{
|
{
|
||||||
auto deckOpenLocation = confirmOpen();
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
if (deckOpenLocation == CANCELLED)
|
||||||
if (deckOpenLocation == CANCELLED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
DlgLoadDeckFromClipboard dlg(this);
|
DlgLoadDeckFromClipboard dlg(this);
|
||||||
if (!dlg.exec())
|
if (!dlg.exec())
|
||||||
|
|
@ -421,6 +474,10 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
||||||
deckMenu->setSaveStatus(true);
|
deckMenu->setSaveStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opens the deck editor to edit clipboard contents.
|
||||||
|
* @param annotated If true, edits with annotations.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
||||||
{
|
{
|
||||||
DlgEditDeckInClipboard dlg(*getDeckList(), annotated, this);
|
DlgEditDeckInClipboard dlg(*getDeckList(), annotated, this);
|
||||||
|
|
@ -429,40 +486,46 @@ void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
||||||
|
|
||||||
setDeck(dlg.getDeckList());
|
setDeck(dlg.getDeckList());
|
||||||
setModified(true);
|
setModified(true);
|
||||||
|
|
||||||
deckMenu->setSaveStatus(true);
|
deckMenu->setSaveStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Slot for editing deck in clipboard with annotations. */
|
||||||
void AbstractTabDeckEditor::actEditDeckInClipboard()
|
void AbstractTabDeckEditor::actEditDeckInClipboard()
|
||||||
{
|
{
|
||||||
editDeckInClipboard(true);
|
editDeckInClipboard(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Slot for editing deck in clipboard without annotations. */
|
||||||
void AbstractTabDeckEditor::actEditDeckInClipboardRaw()
|
void AbstractTabDeckEditor::actEditDeckInClipboardRaw()
|
||||||
{
|
{
|
||||||
editDeckInClipboard(false);
|
editDeckInClipboard(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard with set info and annotation. */
|
||||||
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
||||||
{
|
{
|
||||||
getDeckList()->saveToClipboard(true, true);
|
getDeckList()->saveToClipboard(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard with annotation, without set info. */
|
||||||
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo()
|
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo()
|
||||||
{
|
{
|
||||||
getDeckList()->saveToClipboard(true, false);
|
getDeckList()->saveToClipboard(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard without annotations, with set info. */
|
||||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
||||||
{
|
{
|
||||||
getDeckList()->saveToClipboard(false, true);
|
getDeckList()->saveToClipboard(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard without annotations or set info. */
|
||||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
||||||
{
|
{
|
||||||
getDeckList()->saveToClipboard(false, false);
|
getDeckList()->saveToClipboard(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Prints the deck using a QPrintPreviewDialog. */
|
||||||
void AbstractTabDeckEditor::actPrintDeck()
|
void AbstractTabDeckEditor::actPrintDeck()
|
||||||
{
|
{
|
||||||
auto *dlg = new QPrintPreviewDialog(this);
|
auto *dlg = new QPrintPreviewDialog(this);
|
||||||
|
|
@ -470,13 +533,14 @@ void AbstractTabDeckEditor::actPrintDeck()
|
||||||
dlg->exec();
|
dlg->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads a deck from a website.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
||||||
{
|
{
|
||||||
auto deckOpenLocation = confirmOpen();
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
if (deckOpenLocation == CANCELLED)
|
||||||
if (deckOpenLocation == CANCELLED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
DlgLoadDeckFromWebsite dlg(this);
|
DlgLoadDeckFromWebsite dlg(this);
|
||||||
if (!dlg.exec())
|
if (!dlg.exec())
|
||||||
|
|
@ -492,18 +556,21 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
||||||
deckMenu->setSaveStatus(true);
|
deckMenu->setSaveStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Exports the deck to a decklist website.
|
||||||
|
* @param website Website to export to.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
|
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
|
||||||
{
|
{
|
||||||
// check if deck is not null
|
|
||||||
if (DeckLoader *const deck = getDeckList()) {
|
if (DeckLoader *const deck = getDeckList()) {
|
||||||
// Get the decklist url string from the deck loader class.
|
|
||||||
QString decklistUrlString = deck->exportDeckToDecklist(website);
|
QString decklistUrlString = deck->exportDeckToDecklist(website);
|
||||||
// Check to make sure the string isn't empty.
|
// 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.
|
// 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"));
|
QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode the string recieved from the model to make sure all characters are encoded.
|
// Encode the string recieved from the model to make sure all characters are encoded.
|
||||||
// first we put it into a qurl object
|
// first we put it into a qurl object
|
||||||
QUrl decklistUrl = QUrl(decklistUrlString);
|
QUrl decklistUrl = QUrl(decklistUrlString);
|
||||||
|
|
@ -517,48 +584,54 @@ void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @brief Exports deck to www.decklist.org. */
|
||||||
* Exports the deck to www.decklist.org (the old website)
|
|
||||||
*/
|
|
||||||
void AbstractTabDeckEditor::actExportDeckDecklist()
|
void AbstractTabDeckEditor::actExportDeckDecklist()
|
||||||
{
|
{
|
||||||
exportToDecklistWebsite(DeckLoader::DecklistOrg);
|
exportToDecklistWebsite(DeckLoader::DecklistOrg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @brief Exports deck to www.decklist.xyz. */
|
||||||
* Exports the deck to www.decklist.xyz (the new website)
|
|
||||||
*/
|
|
||||||
void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
||||||
{
|
{
|
||||||
exportToDecklistWebsite(DeckLoader::DecklistXyz);
|
exportToDecklistWebsite(DeckLoader::DecklistXyz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Analyzes the deck using DeckStats. */
|
||||||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||||
{
|
{
|
||||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||||
this); // it deletes itself when done
|
|
||||||
interface->analyzeDeck(getDeckList());
|
interface->analyzeDeck(getDeckList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Analyzes the deck using TappedOut. */
|
||||||
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||||
{
|
{
|
||||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||||
this); // it deletes itself when done
|
|
||||||
interface->analyzeDeck(getDeckList());
|
interface->analyzeDeck(getDeckList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Applies a new filter tree to the database display. */
|
||||||
void AbstractTabDeckEditor::filterTreeChanged(FilterTree *filterTree)
|
void AbstractTabDeckEditor::filterTreeChanged(FilterTree *filterTree)
|
||||||
{
|
{
|
||||||
databaseDisplayDockWidget->setFilterTree(filterTree);
|
databaseDisplayDockWidget->setFilterTree(filterTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handles the close event of the tab.
|
||||||
|
* @param event Close event.
|
||||||
|
*/
|
||||||
void AbstractTabDeckEditor::closeEvent(QCloseEvent *event)
|
void AbstractTabDeckEditor::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
emit deckEditorClosing(this);
|
emit deckEditorClosing(this);
|
||||||
event->accept();
|
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)
|
bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||||
{
|
{
|
||||||
if (e->type() == QEvent::Close) {
|
if (e->type() == QEvent::Close) {
|
||||||
|
|
@ -576,6 +649,7 @@ bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||||
aPrintingSelectorDockFloating->setEnabled(false);
|
aPrintingSelectorDockFloating->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o == this && e->type() == QEvent::Hide) {
|
if (o == this && e->type() == QEvent::Hide) {
|
||||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||||
layouts.setDeckEditorLayoutState(saveState());
|
layouts.setDeckEditorLayoutState(saveState());
|
||||||
|
|
@ -585,9 +659,11 @@ bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||||
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||||
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Shows a confirmation dialog before closing. */
|
||||||
bool AbstractTabDeckEditor::confirmClose()
|
bool AbstractTabDeckEditor::confirmClose()
|
||||||
{
|
{
|
||||||
if (modified) {
|
if (modified) {
|
||||||
|
|
@ -601,11 +677,10 @@ bool AbstractTabDeckEditor::confirmClose()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Handles close requests from outside (tab manager). */
|
||||||
bool AbstractTabDeckEditor::closeRequest()
|
bool AbstractTabDeckEditor::closeRequest()
|
||||||
{
|
{
|
||||||
if (!confirmClose()) {
|
if (!confirmClose())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return close();
|
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
|
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||||
#define TAB_GENERIC_DECK_EDITOR_H
|
#define TAB_GENERIC_DECK_EDITOR_H
|
||||||
|
|
||||||
|
|
@ -40,6 +47,45 @@ class QDockWidget;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QAction;
|
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
|
class AbstractTabDeckEditor : public Tab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -47,68 +93,150 @@ class AbstractTabDeckEditor : public Tab
|
||||||
friend class DeckEditorMenu;
|
friend class DeckEditorMenu;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs an AbstractTabDeckEditor.
|
||||||
|
* @param _tabSupervisor Pointer to the TabSupervisor managing this tab.
|
||||||
|
*/
|
||||||
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||||
|
|
||||||
// UI and Navigation
|
/** @brief Creates the menus for this tab. Pure virtual. */
|
||||||
virtual void createMenus() = 0;
|
virtual void createMenus() = 0;
|
||||||
|
|
||||||
|
/** @brief Returns the display text for the tab. */
|
||||||
[[nodiscard]] virtual QString getTabText() const override = 0;
|
[[nodiscard]] virtual QString getTabText() const override = 0;
|
||||||
|
|
||||||
|
/** @brief Confirms whether the tab can be safely closed. */
|
||||||
bool confirmClose();
|
bool confirmClose();
|
||||||
|
|
||||||
|
/** @brief Retranslates the UI text. Pure virtual. */
|
||||||
virtual void retranslateUi() override = 0;
|
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);
|
void openDeck(DeckLoader *deck);
|
||||||
|
|
||||||
|
/** @brief Returns the currently active deck. */
|
||||||
DeckLoader *getDeckList() const;
|
DeckLoader *getDeckList() const;
|
||||||
|
|
||||||
|
/** @brief Sets the modified state of the tab.
|
||||||
|
* @param _windowModified Whether the tab is modified.
|
||||||
|
*/
|
||||||
void setModified(bool _windowModified);
|
void setModified(bool _windowModified);
|
||||||
|
|
||||||
// UI Elements
|
// UI Elements
|
||||||
DeckEditorMenu *deckMenu;
|
DeckEditorMenu *deckMenu; ///< Menu for deck operations
|
||||||
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget;
|
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget; ///< Database dock
|
||||||
DeckEditorCardInfoDockWidget *cardInfoDockWidget;
|
DeckEditorCardInfoDockWidget *cardInfoDockWidget; ///< Card info dock
|
||||||
DeckEditorDeckDockWidget *deckDockWidget;
|
DeckEditorDeckDockWidget *deckDockWidget; ///< Deck dock
|
||||||
DeckEditorFilterDockWidget *filterDockWidget;
|
DeckEditorFilterDockWidget *filterDockWidget; ///< Filter dock
|
||||||
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget; ///< Printing selector dock
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
/** @brief Called when the deck changes. */
|
||||||
virtual void onDeckChanged();
|
virtual void onDeckChanged();
|
||||||
|
|
||||||
|
/** @brief Called when the deck is modified. */
|
||||||
virtual void onDeckModified();
|
virtual void onDeckModified();
|
||||||
|
|
||||||
|
/** @brief Updates the card info panel.
|
||||||
|
* @param card The card to display.
|
||||||
|
*/
|
||||||
void updateCard(const ExactCard &card);
|
void updateCard(const ExactCard &card);
|
||||||
|
|
||||||
|
/** @brief Adds a card to the main deck or sideboard based on Ctrl key. */
|
||||||
void actAddCard(const ExactCard &card);
|
void actAddCard(const ExactCard &card);
|
||||||
|
|
||||||
|
/** @brief Adds a card to the sideboard explicitly. */
|
||||||
void actAddCardToSideboard(const ExactCard &card);
|
void actAddCardToSideboard(const ExactCard &card);
|
||||||
|
|
||||||
|
/** @brief Decrements a card from the main deck. */
|
||||||
void actDecrementCard(const ExactCard &card);
|
void actDecrementCard(const ExactCard &card);
|
||||||
|
|
||||||
|
/** @brief Decrements a card from the sideboard. */
|
||||||
void actDecrementCardFromSideboard(const ExactCard &card);
|
void actDecrementCardFromSideboard(const ExactCard &card);
|
||||||
|
|
||||||
|
/** @brief Opens a recently opened deck file. */
|
||||||
void actOpenRecent(const QString &fileName);
|
void actOpenRecent(const QString &fileName);
|
||||||
|
|
||||||
|
/** @brief Called when the filter tree changes. */
|
||||||
void filterTreeChanged(FilterTree *filterTree);
|
void filterTreeChanged(FilterTree *filterTree);
|
||||||
|
|
||||||
|
/** @brief Requests closing the tab. */
|
||||||
bool closeRequest() override;
|
bool closeRequest() override;
|
||||||
|
|
||||||
|
/** @brief Shows the printing selector dock. Pure virtual. */
|
||||||
virtual void showPrintingSelector() = 0;
|
virtual void showPrintingSelector() = 0;
|
||||||
|
|
||||||
|
/** @brief Slot for when a dock's top-level state changes. Pure virtual. */
|
||||||
virtual void dockTopLevelChanged(bool topLevel) = 0;
|
virtual void dockTopLevelChanged(bool topLevel) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
/** @brief Emitted when a deck should be opened in a new editor tab. */
|
||||||
void openDeckEditor(const DeckLoader *deckLoader);
|
void openDeckEditor(const DeckLoader *deckLoader);
|
||||||
|
|
||||||
|
/** @brief Emitted before the tab is closed. */
|
||||||
void deckEditorClosing(AbstractTabDeckEditor *tab);
|
void deckEditorClosing(AbstractTabDeckEditor *tab);
|
||||||
|
|
||||||
|
/** @brief Emitted when a card should be decremented. */
|
||||||
void decrementCard(const ExactCard &card, QString zoneName);
|
void decrementCard(const ExactCard &card, QString zoneName);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
// Deck Operations
|
/** @brief Starts a new deck in this tab. */
|
||||||
virtual void actNewDeck();
|
virtual void actNewDeck();
|
||||||
|
|
||||||
|
/** @brief Cleans the current deck and resets the modified state. */
|
||||||
void cleanDeckAndResetModified();
|
void cleanDeckAndResetModified();
|
||||||
|
|
||||||
|
/** @brief Loads a deck from file. */
|
||||||
virtual void actLoadDeck();
|
virtual void actLoadDeck();
|
||||||
|
|
||||||
|
/** @brief Saves the current deck. */
|
||||||
bool actSaveDeck();
|
bool actSaveDeck();
|
||||||
|
|
||||||
|
/** @brief Saves the current deck under a new name. */
|
||||||
virtual bool actSaveDeckAs();
|
virtual bool actSaveDeckAs();
|
||||||
|
|
||||||
|
/** @brief Loads a deck from the clipboard. */
|
||||||
virtual void actLoadDeckFromClipboard();
|
virtual void actLoadDeckFromClipboard();
|
||||||
|
|
||||||
|
/** @brief Opens a deck editor for clipboard contents. */
|
||||||
void actEditDeckInClipboard();
|
void actEditDeckInClipboard();
|
||||||
|
|
||||||
|
/** @brief Opens a raw clipboard deck editor. */
|
||||||
void actEditDeckInClipboardRaw();
|
void actEditDeckInClipboardRaw();
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard with full info. */
|
||||||
void actSaveDeckToClipboard();
|
void actSaveDeckToClipboard();
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard without set info. */
|
||||||
void actSaveDeckToClipboardNoSetInfo();
|
void actSaveDeckToClipboardNoSetInfo();
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard in raw format. */
|
||||||
void actSaveDeckToClipboardRaw();
|
void actSaveDeckToClipboardRaw();
|
||||||
|
|
||||||
|
/** @brief Saves deck to clipboard in raw format without set info. */
|
||||||
void actSaveDeckToClipboardRawNoSetInfo();
|
void actSaveDeckToClipboardRawNoSetInfo();
|
||||||
|
|
||||||
|
/** @brief Prints the deck using a preview dialog. */
|
||||||
void actPrintDeck();
|
void actPrintDeck();
|
||||||
|
|
||||||
|
/** @brief Loads a deck from an online website. */
|
||||||
void actLoadDeckFromWebsite();
|
void actLoadDeckFromWebsite();
|
||||||
|
|
||||||
|
/** @brief Exports the deck to decklist.org. */
|
||||||
void actExportDeckDecklist();
|
void actExportDeckDecklist();
|
||||||
|
|
||||||
|
/** @brief Exports the deck to decklist.xyz. */
|
||||||
void actExportDeckDecklistXyz();
|
void actExportDeckDecklistXyz();
|
||||||
|
|
||||||
|
/** @brief Analyzes the deck using deckstats.net. */
|
||||||
void actAnalyzeDeckDeckstats();
|
void actAnalyzeDeckDeckstats();
|
||||||
|
|
||||||
|
/** @brief Analyzes the deck using tappedout.net. */
|
||||||
void actAnalyzeDeckTappedout();
|
void actAnalyzeDeckTappedout();
|
||||||
|
|
||||||
// Remote Save
|
/** @brief Callback when a remote deck save finishes. */
|
||||||
void saveDeckRemoteFinished(const Response &r);
|
void saveDeckRemoteFinished(const Response &r);
|
||||||
|
|
||||||
// UI Layout Management
|
// UI Layout Management
|
||||||
|
|
@ -117,34 +245,62 @@ protected slots:
|
||||||
virtual void freeDocksSize() = 0;
|
virtual void freeDocksSize() = 0;
|
||||||
virtual void refreshShortcuts() = 0;
|
virtual void refreshShortcuts() = 0;
|
||||||
|
|
||||||
|
/** @brief Handles dock close events. */
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
|
/** @brief Event filter for dock state changes. */
|
||||||
bool eventFilter(QObject *o, QEvent *e) override;
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
|
|
||||||
|
/** @brief Slot triggered when a dock visibility changes. Pure virtual. */
|
||||||
virtual void dockVisibleTriggered() = 0;
|
virtual void dockVisibleTriggered() = 0;
|
||||||
|
|
||||||
|
/** @brief Slot triggered when a dock floating state changes. Pure virtual. */
|
||||||
virtual void dockFloatingTriggered() = 0;
|
virtual void dockFloatingTriggered() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/** @brief Sets the deck for this tab.
|
||||||
|
* @param _deck The deck object.
|
||||||
|
*/
|
||||||
virtual void setDeck(DeckLoader *_deck);
|
virtual void setDeck(DeckLoader *_deck);
|
||||||
|
|
||||||
|
/** @brief Helper for editing decks from the clipboard. */
|
||||||
void editDeckInClipboard(bool annotated);
|
void editDeckInClipboard(bool annotated);
|
||||||
|
|
||||||
|
/** @brief Helper for exporting decks to websites.
|
||||||
|
* @param website Target website.
|
||||||
|
*/
|
||||||
void exportToDecklistWebsite(DeckLoader::DecklistWebsite website);
|
void exportToDecklistWebsite(DeckLoader::DecklistWebsite website);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/** @brief Enum describing deck open locations */
|
||||||
* @brief Enum for selecting deck open location
|
|
||||||
*/
|
|
||||||
enum DeckOpenLocation
|
enum DeckOpenLocation
|
||||||
{
|
{
|
||||||
CANCELLED,
|
CANCELLED, ///< Operation cancelled
|
||||||
SAME_TAB,
|
SAME_TAB, ///< Open deck in the same tab
|
||||||
NEW_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);
|
DeckOpenLocation confirmOpen(bool openInSameTabIfBlank = true);
|
||||||
|
|
||||||
|
/** @brief Creates a save confirmation message box.
|
||||||
|
* @return Pointer to a QMessageBox.
|
||||||
|
*/
|
||||||
QMessageBox *createSaveConfirmationWindow();
|
QMessageBox *createSaveConfirmationWindow();
|
||||||
|
|
||||||
|
/** @brief Returns true if the tab is a blank newly created deck. */
|
||||||
bool isBlankNewDeck() const;
|
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);
|
void addCardHelper(const ExactCard &card, QString zoneName);
|
||||||
|
|
||||||
|
/** @brief Swaps a card in the deck view. */
|
||||||
void actSwapCard(const ExactCard &card, const QString &zoneName);
|
void actSwapCard(const ExactCard &card, const QString &zoneName);
|
||||||
|
|
||||||
|
/** @brief Opens a deck from a file. */
|
||||||
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
||||||
|
|
||||||
// UI Menu Elements
|
// UI Menu Elements
|
||||||
|
|
@ -154,7 +310,7 @@ protected:
|
||||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
||||||
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false; ///< Whether the deck/tab has unsaved changes
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TAB_GENERIC_DECK_EDITOR_H
|
#endif // TAB_GENERIC_DECK_EDITOR_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue