mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
[TabDeckEditor] Create class to centralize deck state (#6459)
* create new file * use QSharedPointer in DeckListModel * [TabDeckEditor] Create class to centralize deck state * delete method * update docs
This commit is contained in:
parent
0085015ebe
commit
b2dd8eed3f
31 changed files with 933 additions and 577 deletions
|
|
@ -156,6 +156,7 @@ set(cockatrice_SOURCES
|
|||
src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_list_style_proxy.cpp
|
||||
src/interface/widgets/deck_editor/deck_state_manager.cpp
|
||||
src/interface/widgets/general/background_sources.cpp
|
||||
src/interface/widgets/general/display/background_plate_widget.cpp
|
||||
src/interface/widgets/general/display/banner_widget.cpp
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "deck_editor_deck_dock_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "deck_list_style_proxy.h"
|
||||
#include "deck_state_manager.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDockWidget>
|
||||
|
|
@ -38,7 +38,7 @@ static int findRestoreIndex(const CardRef &wanted, const QComboBox *combo)
|
|||
}
|
||||
|
||||
DeckEditorDeckDockWidget::DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent)
|
||||
: QDockWidget(parent), deckEditor(parent)
|
||||
: QDockWidget(parent), deckEditor(parent), deckStateManager(parent->deckStateManager)
|
||||
{
|
||||
setObjectName("deckDock");
|
||||
|
||||
|
|
@ -52,19 +52,19 @@ DeckEditorDeckDockWidget::DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent
|
|||
|
||||
void DeckEditorDeckDockWidget::createDeckDock()
|
||||
{
|
||||
deckModel = new DeckListModel(this);
|
||||
deckModel->setObjectName("deckModel");
|
||||
connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash);
|
||||
|
||||
deckLoader = new DeckLoader(this);
|
||||
connect(getModel(), &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash);
|
||||
|
||||
proxy = new DeckListStyleProxy(this);
|
||||
proxy->setSourceModel(deckModel);
|
||||
proxy->setSourceModel(getModel());
|
||||
|
||||
historyManagerWidget = new DeckListHistoryManagerWidget(deckModel, proxy, deckEditor->getHistoryManager(), this);
|
||||
historyManagerWidget = new DeckListHistoryManagerWidget(deckStateManager, proxy, this);
|
||||
connect(historyManagerWidget, &DeckListHistoryManagerWidget::requestDisplayWidgetSync, this,
|
||||
&DeckEditorDeckDockWidget::syncDisplayWidgetsToModel);
|
||||
|
||||
connect(deckStateManager, &DeckStateManager::focusIndexChanged, this, &DeckEditorDeckDockWidget::setSelectedIndex);
|
||||
connect(deckStateManager, &DeckStateManager::deckReplaced, this,
|
||||
&DeckEditorDeckDockWidget::syncDisplayWidgetsToModel);
|
||||
|
||||
deckView = new QTreeView();
|
||||
deckView->setObjectName("deckView");
|
||||
deckView->setModel(proxy);
|
||||
|
|
@ -97,7 +97,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
nameDebounceTimer = new QTimer(this);
|
||||
nameDebounceTimer->setSingleShot(true);
|
||||
nameDebounceTimer->setInterval(300); // debounce duration in ms
|
||||
connect(nameDebounceTimer, &QTimer::timeout, this, [this]() { updateName(nameEdit->text()); });
|
||||
connect(nameDebounceTimer, &QTimer::timeout, this, &DeckEditorDeckDockWidget::writeName);
|
||||
|
||||
connect(nameEdit, &LineEditUnfocusable::textChanged, this, [this]() {
|
||||
nameDebounceTimer->start(); // restart debounce timer
|
||||
|
|
@ -141,7 +141,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
commentsDebounceTimer = new QTimer(this);
|
||||
commentsDebounceTimer->setSingleShot(true);
|
||||
commentsDebounceTimer->setInterval(400); // longer debounce for multi-line
|
||||
connect(commentsDebounceTimer, &QTimer::timeout, this, [this]() { updateComments(); });
|
||||
connect(commentsDebounceTimer, &QTimer::timeout, this, &DeckEditorDeckDockWidget::writeComments);
|
||||
|
||||
connect(commentsEdit, &QTextEdit::textChanged, this, [this]() {
|
||||
commentsDebounceTimer->start(); // restart debounce timer
|
||||
|
|
@ -152,21 +152,21 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
bannerCardLabel->setText(tr("Banner Card"));
|
||||
bannerCardLabel->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
bannerCardComboBox = new QComboBox(this);
|
||||
connect(deckModel, &DeckListModel::dataChanged, this, [this]() {
|
||||
connect(getModel(), &DeckListModel::dataChanged, this, [this]() {
|
||||
// Delay the update to avoid race conditions
|
||||
QTimer::singleShot(100, this, &DeckEditorDeckDockWidget::updateBannerCardComboBox);
|
||||
});
|
||||
connect(deckModel, &DeckListModel::cardAddedAt, this, &DeckEditorDeckDockWidget::recursiveExpand);
|
||||
connect(deckModel, &DeckListModel::modelReset, this, &DeckEditorDeckDockWidget::expandAll);
|
||||
connect(getModel(), &DeckListModel::cardAddedAt, this, &DeckEditorDeckDockWidget::recursiveExpand);
|
||||
connect(getModel(), &DeckListModel::modelReset, this, &DeckEditorDeckDockWidget::expandAll);
|
||||
|
||||
connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DeckEditorDeckDockWidget::setBannerCard);
|
||||
&DeckEditorDeckDockWidget::writeBannerCard);
|
||||
bannerCardComboBox->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
|
||||
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckModel->getDeckList()->getTags());
|
||||
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, {});
|
||||
deckTagsDisplayWidget->setHidden(!SettingsCache::instance().getDeckEditorTagsWidgetVisible());
|
||||
connect(deckTagsDisplayWidget, &DeckPreviewDeckTagsDisplayWidget::tagsChanged, this,
|
||||
&DeckEditorDeckDockWidget::setTags);
|
||||
connect(deckTagsDisplayWidget, &DeckPreviewDeckTagsDisplayWidget::tagsChanged, deckStateManager,
|
||||
&DeckStateManager::setTags);
|
||||
|
||||
activeGroupCriteriaLabel = new QLabel(this);
|
||||
|
||||
|
|
@ -175,9 +175,9 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
activeGroupCriteriaComboBox->addItem(tr("Mana Cost"), DeckListModelGroupCriteria::MANA_COST);
|
||||
activeGroupCriteriaComboBox->addItem(tr("Colors"), DeckListModelGroupCriteria::COLOR);
|
||||
connect(activeGroupCriteriaComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() {
|
||||
deckModel->setActiveGroupCriteria(static_cast<DeckListModelGroupCriteria::Type>(
|
||||
getModel()->setActiveGroupCriteria(static_cast<DeckListModelGroupCriteria::Type>(
|
||||
activeGroupCriteriaComboBox->currentData(Qt::UserRole).toInt()));
|
||||
deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
getModel()->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
});
|
||||
|
||||
aIncrement = new QAction(QString(), this);
|
||||
|
|
@ -295,9 +295,10 @@ void DeckEditorDeckDockWidget::initializeFormats()
|
|||
formatComboBox->addItem(formatName, formatName); // store the raw key in itemData
|
||||
}
|
||||
|
||||
if (!deckModel->getDeckList()->getGameFormat().isEmpty()) {
|
||||
deckModel->setActiveFormat(deckModel->getDeckList()->getGameFormat());
|
||||
formatComboBox->setCurrentIndex(formatComboBox->findData(deckModel->getDeckList()->getGameFormat()));
|
||||
QString format = deckStateManager->getMetadata().gameFormat;
|
||||
if (!format.isEmpty()) {
|
||||
getModel()->setActiveFormat(format);
|
||||
formatComboBox->setCurrentIndex(formatComboBox->findData(format));
|
||||
} else {
|
||||
// Ensure no selection is visible initially
|
||||
formatComboBox->setCurrentIndex(-1);
|
||||
|
|
@ -306,11 +307,10 @@ void DeckEditorDeckDockWidget::initializeFormats()
|
|||
connect(formatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int index) {
|
||||
if (index >= 0) {
|
||||
QString formatKey = formatComboBox->itemData(index).toString();
|
||||
deckModel->setActiveFormat(formatKey);
|
||||
deckStateManager->setFormat(formatKey);
|
||||
} else {
|
||||
deckModel->setActiveFormat(QString()); // clear format if deselected
|
||||
deckStateManager->setFormat(""); // clear format if deselected
|
||||
}
|
||||
emit deckModified();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -340,43 +340,37 @@ ExactCard DeckEditorDeckDockWidget::getCurrentCard()
|
|||
void DeckEditorDeckDockWidget::updateCard(const QModelIndex /*¤t*/, const QModelIndex & /*previous*/)
|
||||
{
|
||||
if (ExactCard card = getCurrentCard()) {
|
||||
emit cardChanged(card);
|
||||
emit selectedCardChanged(card);
|
||||
}
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateName(const QString &name)
|
||||
/**
|
||||
* @brief Writes the contents of the name textBox to the DeckStateManager
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::writeName()
|
||||
{
|
||||
emit requestDeckHistorySave(
|
||||
QString(tr("Rename deck to \"%1\" from \"%2\"")).arg(name).arg(deckLoader->getDeck().deckList.getName()));
|
||||
deckModel->getDeckList()->setName(name);
|
||||
deckEditor->setModified(name.isEmpty());
|
||||
emit nameChanged();
|
||||
emit deckModified();
|
||||
QString name = nameEdit->text();
|
||||
deckStateManager->setName(name);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateComments()
|
||||
/**
|
||||
* @brief Writes the contents of the comments textBox to the DeckStateManager
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::writeComments()
|
||||
{
|
||||
emit requestDeckHistorySave(tr("Updated comments (was %1 chars, now %2 chars)")
|
||||
.arg(deckLoader->getDeck().deckList.getComments().size())
|
||||
.arg(commentsEdit->toPlainText().size()));
|
||||
|
||||
deckModel->getDeckList()->setComments(commentsEdit->toPlainText());
|
||||
deckEditor->setModified(commentsEdit->toPlainText().isEmpty());
|
||||
emit commentsChanged();
|
||||
emit deckModified();
|
||||
QString comments = commentsEdit->toPlainText();
|
||||
deckStateManager->setComments(comments);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateHash()
|
||||
{
|
||||
hashLabel->setText(deckModel->getDeckList()->getDeckHash());
|
||||
emit hashChanged();
|
||||
emit deckModified();
|
||||
hashLabel->setText(deckStateManager->getDeckHash());
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateBannerCardComboBox()
|
||||
{
|
||||
// Store current banner card identity
|
||||
CardRef wanted = deckModel->getDeckList()->getBannerCard();
|
||||
CardRef wanted = deckStateManager->getMetadata().bannerCard;
|
||||
|
||||
// Block signals temporarily
|
||||
bool wasBlocked = bannerCardComboBox->blockSignals(true);
|
||||
|
|
@ -386,7 +380,7 @@ void DeckEditorDeckDockWidget::updateBannerCardComboBox()
|
|||
|
||||
// Collect unique (name, providerId) pairs
|
||||
QSet<QPair<QString, QString>> bannerCardSet;
|
||||
QList<CardRef> cardsInDeck = deckModel->getCardRefs();
|
||||
QList<CardRef> cardsInDeck = getModel()->getCardRefs();
|
||||
|
||||
for (auto cardRef : cardsInDeck) {
|
||||
if (!CardDatabaseManager::query()->getCard(cardRef)) {
|
||||
|
|
@ -415,7 +409,6 @@ void DeckEditorDeckDockWidget::updateBannerCardComboBox()
|
|||
// Handle results
|
||||
if (restoreIndex != -1) {
|
||||
bannerCardComboBox->setCurrentIndex(restoreIndex);
|
||||
syncDeckListBannerCardWithComboBox();
|
||||
} else {
|
||||
// Add a placeholder "-" and set it as the current selection
|
||||
bannerCardComboBox->insertItem(0, "-");
|
||||
|
|
@ -426,25 +419,14 @@ void DeckEditorDeckDockWidget::updateBannerCardComboBox()
|
|||
bannerCardComboBox->blockSignals(wasBlocked);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::setBannerCard(int /* changedIndex */)
|
||||
/**
|
||||
* @brief Writes the selected bannerCard to the DeckStateManager
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::writeBannerCard(int index)
|
||||
{
|
||||
emit requestDeckHistorySave(tr("Banner card changed"));
|
||||
syncDeckListBannerCardWithComboBox();
|
||||
deckEditor->setModified(true);
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::setTags(const QStringList &tags)
|
||||
{
|
||||
deckModel->getDeckList()->setTags(tags);
|
||||
deckEditor->setModified(true);
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::syncDeckListBannerCardWithComboBox()
|
||||
{
|
||||
auto [name, id] = bannerCardComboBox->currentData().value<QPair<QString, QString>>();
|
||||
deckModel->getDeckList()->setBannerCard({name, id});
|
||||
auto [name, id] = bannerCardComboBox->itemData(index).value<QPair<QString, QString>>();
|
||||
CardRef bannerCard = {name, id};
|
||||
deckStateManager->setBannerCard(bannerCard);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateShowBannerCardComboBox(const bool visible)
|
||||
|
|
@ -460,7 +442,7 @@ void DeckEditorDeckDockWidget::updateShowTagsWidget(const bool visible)
|
|||
|
||||
void DeckEditorDeckDockWidget::syncBannerCardComboBoxSelectionWithDeck()
|
||||
{
|
||||
if (deckModel->getDeckList()->getBannerCard().name == "") {
|
||||
if (deckStateManager->getMetadata().bannerCard.name == "") {
|
||||
if (bannerCardComboBox->findText("-") != -1) {
|
||||
bannerCardComboBox->setCurrentIndex(bannerCardComboBox->findText("-"));
|
||||
} else {
|
||||
|
|
@ -468,36 +450,26 @@ void DeckEditorDeckDockWidget::syncBannerCardComboBoxSelectionWithDeck()
|
|||
bannerCardComboBox->setCurrentIndex(0);
|
||||
}
|
||||
} else {
|
||||
bannerCardComboBox->setCurrentText(deckModel->getDeckList()->getBannerCard().name);
|
||||
bannerCardComboBox->setCurrentText(deckStateManager->getMetadata().bannerCard.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently active deck for this tab
|
||||
* @param _deck The deck.
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::setDeck(const LoadedDeck &_deck)
|
||||
void DeckEditorDeckDockWidget::setSelectedIndex(const QModelIndex &newCardIndex)
|
||||
{
|
||||
deckLoader->setDeck(_deck);
|
||||
deckModel->setDeckList(&deckLoader->getDeck().deckList);
|
||||
connect(deckLoader, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree);
|
||||
|
||||
emit requestDeckHistoryClear();
|
||||
historyManagerWidget->setDeckListModel(deckModel);
|
||||
|
||||
syncDisplayWidgetsToModel();
|
||||
|
||||
emit deckChanged();
|
||||
deckView->clearSelection();
|
||||
deckView->setCurrentIndex(newCardIndex);
|
||||
recursiveExpand(newCardIndex);
|
||||
deckView->setFocus(Qt::FocusReason::MouseFocusReason);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::syncDisplayWidgetsToModel()
|
||||
{
|
||||
nameEdit->blockSignals(true);
|
||||
nameEdit->setText(deckModel->getDeckList()->getName());
|
||||
nameEdit->setText(deckStateManager->getMetadata().name);
|
||||
nameEdit->blockSignals(false);
|
||||
|
||||
commentsEdit->blockSignals(true);
|
||||
commentsEdit->setText(deckModel->getDeckList()->getComments());
|
||||
commentsEdit->setText(deckStateManager->getMetadata().comments);
|
||||
commentsEdit->blockSignals(false);
|
||||
|
||||
bannerCardComboBox->blockSignals(true);
|
||||
|
|
@ -507,44 +479,22 @@ void DeckEditorDeckDockWidget::syncDisplayWidgetsToModel()
|
|||
updateHash();
|
||||
sortDeckModelToDeckView();
|
||||
|
||||
deckTagsDisplayWidget->setTags(deckModel->getDeckList()->getTags());
|
||||
deckTagsDisplayWidget->setTags(deckStateManager->getMetadata().tags);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::sortDeckModelToDeckView()
|
||||
{
|
||||
deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
deckModel->setActiveFormat(deckModel->getDeckList()->getGameFormat());
|
||||
formatComboBox->setCurrentIndex(formatComboBox->findData(deckModel->getDeckList()->getGameFormat()));
|
||||
|
||||
emit deckChanged();
|
||||
}
|
||||
|
||||
DeckLoader *DeckEditorDeckDockWidget::getDeckLoader()
|
||||
{
|
||||
return deckLoader;
|
||||
}
|
||||
|
||||
const DeckList &DeckEditorDeckDockWidget::getDeckList() const
|
||||
{
|
||||
return *deckModel->getDeckList();
|
||||
getModel()->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
getModel()->setActiveFormat(deckStateManager->getMetadata().gameFormat);
|
||||
formatComboBox->setCurrentIndex(formatComboBox->findData(deckStateManager->getMetadata().gameFormat));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the tab to the state for a blank new tab.
|
||||
* @brief Convenience method to get the underlying model instance from the DeckStateManager
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::cleanDeck()
|
||||
DeckListModel *DeckEditorDeckDockWidget::getModel() const
|
||||
{
|
||||
deckModel->cleanList();
|
||||
nameEdit->setText(QString());
|
||||
emit nameChanged();
|
||||
commentsEdit->setText(QString());
|
||||
emit commentsChanged();
|
||||
hashLabel->setText(QString());
|
||||
emit hashChanged();
|
||||
emit deckModified();
|
||||
emit deckChanged();
|
||||
updateBannerCardComboBox();
|
||||
deckTagsDisplayWidget->setTags(deckModel->getDeckList()->getTags());
|
||||
return deckStateManager->getModel();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::selectPrevCard()
|
||||
|
|
@ -635,7 +585,7 @@ QModelIndexList DeckEditorDeckDockWidget::getSelectedCardNodes() const
|
|||
auto selectedRows = deckView->selectionModel()->selectedRows();
|
||||
|
||||
const auto notLeafNode = [this](const QModelIndex &index) {
|
||||
return deckModel->hasChildren(proxy->mapToSource(index));
|
||||
return getModel()->hasChildren(proxy->mapToSource(index));
|
||||
};
|
||||
selectedRows.erase(std::remove_if(selectedRows.begin(), selectedRows.end(), notLeafNode), selectedRows.end());
|
||||
|
||||
|
|
@ -650,21 +600,7 @@ void DeckEditorDeckDockWidget::actAddCard(const ExactCard &card, const QString &
|
|||
}
|
||||
|
||||
QString zoneName = card.getInfo().getIsToken() ? DECK_ZONE_TOKENS : _zoneName;
|
||||
|
||||
emit requestDeckHistorySave(tr("Added (%1): %2 (%3) %4")
|
||||
.arg(zoneName, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
|
||||
card.getPrinting().getProperty("num")));
|
||||
|
||||
QModelIndex newCardIndex = deckModel->addCard(card, zoneName);
|
||||
|
||||
if (!newCardIndex.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
deckView->clearSelection();
|
||||
deckView->setCurrentIndex(newCardIndex);
|
||||
|
||||
emit deckModified();
|
||||
deckStateManager->addCard(card, zoneName);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::actIncrementSelection()
|
||||
|
|
@ -681,12 +617,12 @@ void DeckEditorDeckDockWidget::actSwapCard(const ExactCard &card, const QString
|
|||
QString providerId = card.getPrinting().getUuid();
|
||||
QString collectorNumber = card.getPrinting().getProperty("num");
|
||||
|
||||
QModelIndex foundCard = deckModel->findCard(card.getName(), zoneName, providerId, collectorNumber);
|
||||
QModelIndex foundCard = getModel()->findCard(card.getName(), zoneName, providerId, collectorNumber);
|
||||
if (!foundCard.isValid()) {
|
||||
foundCard = deckModel->findCard(card.getName(), zoneName);
|
||||
foundCard = getModel()->findCard(card.getName(), zoneName);
|
||||
}
|
||||
|
||||
swapCard(foundCard);
|
||||
deckStateManager->swapCardAtIndex(foundCard);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::actSwapSelection()
|
||||
|
|
@ -699,54 +635,15 @@ void DeckEditorDeckDockWidget::actSwapSelection()
|
|||
deckView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
}
|
||||
|
||||
bool isModified = false;
|
||||
for (const auto ¤tIndex : selectedRows) {
|
||||
if (swapCard(currentIndex)) {
|
||||
isModified = true;
|
||||
}
|
||||
deckStateManager->swapCardAtIndex(currentIndex);
|
||||
}
|
||||
|
||||
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
if (isModified) {
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the card at the index between the maindeck and sideboard
|
||||
*
|
||||
* @param currentIndex The index to swap.
|
||||
* @return True if the swap was successful
|
||||
*/
|
||||
bool DeckEditorDeckDockWidget::swapCard(const QModelIndex ¤tIndex)
|
||||
{
|
||||
if (!currentIndex.isValid())
|
||||
return false;
|
||||
const QString cardName = currentIndex.siblingAtColumn(DeckListModelColumns::CARD_NAME).data().toString();
|
||||
const QString cardProviderID =
|
||||
currentIndex.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data().toString();
|
||||
const QModelIndex gparent = currentIndex.parent().parent();
|
||||
|
||||
if (!gparent.isValid())
|
||||
return false;
|
||||
|
||||
const QString zoneName = gparent.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
|
||||
offsetCountAtIndex(currentIndex, false);
|
||||
const QString otherZoneName = zoneName == DECK_ZONE_MAIN ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
|
||||
|
||||
if (ExactCard card = CardDatabaseManager::query()->getCard({cardName, cardProviderID})) {
|
||||
deckModel->addCard(card, otherZoneName);
|
||||
} else {
|
||||
// Third argument (true) says create the card no matter what, even if not in DB
|
||||
deckModel->addPreferredPrintingCard(cardName, otherZoneName, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::actDecrementCard(const ExactCard &card, QString zoneName)
|
||||
{
|
||||
if (!card)
|
||||
|
|
@ -754,17 +651,7 @@ void DeckEditorDeckDockWidget::actDecrementCard(const ExactCard &card, QString z
|
|||
if (card.getInfo().getIsToken())
|
||||
zoneName = DECK_ZONE_TOKENS;
|
||||
|
||||
QString providerId = card.getPrinting().getUuid();
|
||||
QString collectorNumber = card.getPrinting().getProperty("num");
|
||||
|
||||
QModelIndex idx = deckModel->findCard(card.getName(), zoneName, providerId, collectorNumber);
|
||||
if (!idx.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
deckView->clearSelection();
|
||||
deckView->setCurrentIndex(proxy->mapToSource(idx));
|
||||
offsetCountAtIndex(idx, false);
|
||||
deckStateManager->decrementCard(card, zoneName);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::actDecrementSelection()
|
||||
|
|
@ -794,25 +681,11 @@ void DeckEditorDeckDockWidget::actRemoveCard()
|
|||
deckView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
}
|
||||
|
||||
bool isModified = false;
|
||||
for (const auto &index : selectedRows) {
|
||||
if (!index.isValid() || deckModel->hasChildren(index)) {
|
||||
continue;
|
||||
}
|
||||
QModelIndex sourceIndex = proxy->mapToSource(index);
|
||||
QString cardName = sourceIndex.siblingAtColumn(DeckListModelColumns::CARD_NAME).data().toString();
|
||||
|
||||
emit requestDeckHistorySave(QString(tr("Removed \"%1\" (all copies)")).arg(cardName));
|
||||
|
||||
deckModel->removeRow(sourceIndex.row(), sourceIndex.parent());
|
||||
isModified = true;
|
||||
for (const auto &row : selectedRows) {
|
||||
deckStateManager->removeCardAtIndex(row);
|
||||
}
|
||||
|
||||
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
if (isModified) {
|
||||
emit deckModified();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -822,28 +695,17 @@ void DeckEditorDeckDockWidget::actRemoveCard()
|
|||
*/
|
||||
void DeckEditorDeckDockWidget::offsetCountAtIndex(const QModelIndex &idx, bool isIncrement)
|
||||
{
|
||||
if (!idx.isValid() || deckModel->hasChildren(idx)) {
|
||||
if (!idx.isValid() || getModel()->hasChildren(idx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndex sourceIndex = proxy->mapToSource(idx);
|
||||
|
||||
QString cardName = sourceIndex.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
|
||||
QString providerId =
|
||||
sourceIndex.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data(Qt::DisplayRole).toString();
|
||||
|
||||
const auto reason = QString(tr("%1 %2 × \"%3\" (%4)"))
|
||||
.arg(isIncrement ? tr("Added") : tr("Removed"))
|
||||
.arg(1)
|
||||
.arg(cardName)
|
||||
.arg(providerId);
|
||||
|
||||
emit requestDeckHistorySave(reason);
|
||||
|
||||
int offset = isIncrement ? 1 : -1;
|
||||
deckModel->offsetCountAtIndex(sourceIndex, offset);
|
||||
|
||||
emit deckModified();
|
||||
if (isIncrement) {
|
||||
deckStateManager->incrementCountAtIndex(sourceIndex);
|
||||
} else {
|
||||
deckStateManager->decrementCountAtIndex(sourceIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::decklistCustomMenu(QPoint point)
|
||||
|
|
|
|||
|
|
@ -28,22 +28,14 @@ class DeckEditorDeckDockWidget : public QDockWidget
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent);
|
||||
DeckLoader *deckLoader;
|
||||
|
||||
DeckListStyleProxy *proxy;
|
||||
DeckListModel *deckModel;
|
||||
QTreeView *deckView;
|
||||
QComboBox *bannerCardComboBox;
|
||||
void createDeckDock();
|
||||
ExactCard getCurrentCard();
|
||||
void retranslateUi();
|
||||
QString getDeckName()
|
||||
{
|
||||
return nameEdit->text();
|
||||
}
|
||||
QString getSimpleDeckName()
|
||||
{
|
||||
return nameEdit->text().simplified();
|
||||
}
|
||||
|
||||
QComboBox *getGroupByComboBox()
|
||||
{
|
||||
return activeGroupCriteriaComboBox;
|
||||
|
|
@ -55,15 +47,11 @@ public:
|
|||
}
|
||||
|
||||
public slots:
|
||||
void cleanDeck();
|
||||
void selectPrevCard();
|
||||
void selectNextCard();
|
||||
void updateBannerCardComboBox();
|
||||
void setDeck(const LoadedDeck &_deck);
|
||||
void syncDisplayWidgetsToModel();
|
||||
void sortDeckModelToDeckView();
|
||||
DeckLoader *getDeckLoader();
|
||||
const DeckList &getDeckList() const;
|
||||
void actAddCard(const ExactCard &card, const QString &zoneName);
|
||||
void actIncrementSelection();
|
||||
void actDecrementCard(const ExactCard &card, QString zoneName);
|
||||
|
|
@ -74,17 +62,12 @@ public slots:
|
|||
void initializeFormats();
|
||||
|
||||
signals:
|
||||
void nameChanged();
|
||||
void commentsChanged();
|
||||
void hashChanged();
|
||||
void deckChanged();
|
||||
void deckModified();
|
||||
void requestDeckHistorySave(const QString &modificationReason);
|
||||
void requestDeckHistoryClear();
|
||||
void cardChanged(const ExactCard &_card);
|
||||
void selectedCardChanged(const ExactCard &card);
|
||||
|
||||
private:
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
DeckStateManager *deckStateManager;
|
||||
|
||||
DeckListHistoryManagerWidget *historyManagerWidget;
|
||||
KeySignals deckViewKeySignals;
|
||||
QLabel *nameLabel;
|
||||
|
|
@ -107,18 +90,17 @@ private:
|
|||
|
||||
QAction *aRemoveCard, *aIncrement, *aDecrement, *aSwapCard;
|
||||
|
||||
DeckListModel *getModel() const;
|
||||
[[nodiscard]] QModelIndexList getSelectedCardNodes() const;
|
||||
void offsetCountAtIndex(const QModelIndex &idx, bool isIncrement);
|
||||
|
||||
private slots:
|
||||
void decklistCustomMenu(QPoint point);
|
||||
bool swapCard(const QModelIndex ¤tIndex);
|
||||
void updateCard(QModelIndex, const QModelIndex ¤t);
|
||||
void updateName(const QString &name);
|
||||
void updateComments();
|
||||
void setBannerCard(int);
|
||||
void setTags(const QStringList &tags);
|
||||
void syncDeckListBannerCardWithComboBox();
|
||||
void writeName();
|
||||
void writeComments();
|
||||
void writeBannerCard(int);
|
||||
void setSelectedIndex(const QModelIndex &newCardIndex);
|
||||
void updateHash();
|
||||
void refreshShortcuts();
|
||||
void updateShowBannerCardComboBox(bool visible);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#include "deck_list_history_manager_widget.h"
|
||||
|
||||
DeckListHistoryManagerWidget::DeckListHistoryManagerWidget(DeckListModel *_deckListModel,
|
||||
#include "deck_state_manager.h"
|
||||
|
||||
DeckListHistoryManagerWidget::DeckListHistoryManagerWidget(DeckStateManager *_deckStateManager,
|
||||
DeckListStyleProxy *_styleProxy,
|
||||
DeckListHistoryManager *manager,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), deckListModel(_deckListModel), styleProxy(_styleProxy), historyManager(manager)
|
||||
: QWidget(parent), deckStateManager(_deckStateManager), styleProxy(_styleProxy)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
|
||||
|
|
@ -43,8 +44,7 @@ DeckListHistoryManagerWidget::DeckListHistoryManagerWidget(DeckListModel *_deckL
|
|||
|
||||
connect(historyList, &QListWidget::itemClicked, this, &DeckListHistoryManagerWidget::onListClicked);
|
||||
|
||||
connect(historyManager, &DeckListHistoryManager::undoRedoStateChanged, this,
|
||||
&DeckListHistoryManagerWidget::refreshList);
|
||||
connect(deckStateManager, &DeckStateManager::historyChanged, this, &DeckListHistoryManagerWidget::refreshList);
|
||||
|
||||
refreshList();
|
||||
retranslateUi();
|
||||
|
|
@ -58,15 +58,12 @@ void DeckListHistoryManagerWidget::retranslateUi()
|
|||
historyLabel->setText(tr("Click on an entry to revert to that point in the history."));
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::setDeckListModel(DeckListModel *_deckListModel)
|
||||
{
|
||||
deckListModel = _deckListModel;
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::refreshList()
|
||||
{
|
||||
historyList->clear();
|
||||
|
||||
DeckListHistoryManager *historyManager = deckStateManager->getHistoryManager();
|
||||
|
||||
// Fill redo section first (oldest redo at top, newest redo closest to divider)
|
||||
const auto redoStack = historyManager->getRedoStack();
|
||||
for (int i = 0; i < redoStack.size(); ++i) { // iterate forward
|
||||
|
|
@ -98,36 +95,7 @@ void DeckListHistoryManagerWidget::refreshList()
|
|||
redoButton->setEnabled(historyManager->canRedo());
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::doUndo()
|
||||
{
|
||||
if (!historyManager->canUndo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
historyManager->undo(deckListModel->getDeckList());
|
||||
deckListModel->rebuildTree();
|
||||
emit deckListModel->layoutChanged();
|
||||
emit requestDisplayWidgetSync();
|
||||
|
||||
refreshList();
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::doRedo()
|
||||
{
|
||||
if (!historyManager->canRedo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
historyManager->redo(deckListModel->getDeckList());
|
||||
deckListModel->rebuildTree();
|
||||
|
||||
emit deckListModel->layoutChanged();
|
||||
emit requestDisplayWidgetSync();
|
||||
|
||||
refreshList();
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::onListClicked(QListWidgetItem *item)
|
||||
void DeckListHistoryManagerWidget::onListClicked(const QListWidgetItem *item)
|
||||
{
|
||||
// Ignore non-selectable items (like divider)
|
||||
if (!(item->flags() & Qt::ItemIsSelectable)) {
|
||||
|
|
@ -138,23 +106,24 @@ void DeckListHistoryManagerWidget::onListClicked(QListWidgetItem *item)
|
|||
int index = item->data(Qt::UserRole + 1).toInt();
|
||||
|
||||
if (mode == "redo") {
|
||||
const auto redoStack = historyManager->getRedoStack();
|
||||
const auto redoStack = deckStateManager->getHistoryManager()->getRedoStack();
|
||||
int steps = redoStack.size() - index;
|
||||
for (int i = 0; i < steps; ++i) {
|
||||
historyManager->redo(deckListModel->getDeckList());
|
||||
}
|
||||
deckStateManager->redo(steps);
|
||||
} else if (mode == "undo") {
|
||||
const auto undoStack = historyManager->getUndoStack();
|
||||
int steps = undoStack.size() - 1 - index;
|
||||
for (int i = 0; i < steps + 1; ++i) {
|
||||
historyManager->undo(deckListModel->getDeckList());
|
||||
}
|
||||
const auto undoStack = deckStateManager->getHistoryManager()->getUndoStack();
|
||||
int steps = undoStack.size() - index;
|
||||
deckStateManager->undo(steps);
|
||||
}
|
||||
|
||||
deckListModel->rebuildTree();
|
||||
|
||||
emit deckListModel->layoutChanged();
|
||||
emit requestDisplayWidgetSync();
|
||||
|
||||
refreshList();
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::doUndo()
|
||||
{
|
||||
deckStateManager->undo();
|
||||
}
|
||||
|
||||
void DeckListHistoryManagerWidget::doRedo()
|
||||
{
|
||||
deckStateManager->redo();
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
#include <libcockatrice/deck_list/deck_list_history_manager.h>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
|
||||
class DeckStateManager;
|
||||
|
||||
class DeckListHistoryManagerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -25,22 +27,19 @@ public slots:
|
|||
void retranslateUi();
|
||||
|
||||
public:
|
||||
explicit DeckListHistoryManagerWidget(DeckListModel *deckListModel,
|
||||
explicit DeckListHistoryManagerWidget(DeckStateManager *deckStateManager,
|
||||
DeckListStyleProxy *styleProxy,
|
||||
DeckListHistoryManager *manager,
|
||||
QWidget *parent = nullptr);
|
||||
void setDeckListModel(DeckListModel *_deckListModel);
|
||||
|
||||
private slots:
|
||||
void refreshList();
|
||||
void onListClicked(QListWidgetItem *item);
|
||||
void onListClicked(const QListWidgetItem *item);
|
||||
void doUndo();
|
||||
void doRedo();
|
||||
|
||||
private:
|
||||
DeckListModel *deckListModel;
|
||||
DeckStateManager *deckStateManager;
|
||||
DeckListStyleProxy *styleProxy;
|
||||
DeckListHistoryManager *historyManager;
|
||||
|
||||
QHBoxLayout *layout;
|
||||
QAction *aUndo;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,361 @@
|
|||
#include "deck_state_manager.h"
|
||||
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list_history_manager.h>
|
||||
|
||||
DeckStateManager::DeckStateManager(QObject *parent)
|
||||
: QObject(parent), deckList(QSharedPointer<DeckList>(new DeckList)),
|
||||
deckListModel(new DeckListModel(this, deckList)), historyManager(new DeckListHistoryManager(this))
|
||||
{
|
||||
connect(historyManager, &DeckListHistoryManager::undoRedoStateChanged, this, [this] {
|
||||
setModified(true);
|
||||
emit historyChanged();
|
||||
});
|
||||
connect(deckListModel, &DeckListModel::rowsInserted, this, &DeckStateManager::uniqueCardsChanged);
|
||||
connect(deckListModel, &DeckListModel::rowsRemoved, this, &DeckStateManager::uniqueCardsChanged);
|
||||
}
|
||||
|
||||
const DeckList &DeckStateManager::getDeckList() const
|
||||
{
|
||||
return *deckList.get();
|
||||
}
|
||||
|
||||
LoadedDeck DeckStateManager::toLoadedDeck() const
|
||||
{
|
||||
return {getDeckList(), lastLoadInfo};
|
||||
}
|
||||
|
||||
DeckList::Metadata const &DeckStateManager::getMetadata() const
|
||||
{
|
||||
return deckList->getMetadata();
|
||||
}
|
||||
|
||||
QString DeckStateManager::getSimpleDeckName() const
|
||||
{
|
||||
return deckList->getMetadata().name.simplified();
|
||||
}
|
||||
|
||||
QString DeckStateManager::getDeckHash() const
|
||||
{
|
||||
return deckList->getDeckHash();
|
||||
}
|
||||
|
||||
bool DeckStateManager::isModified() const
|
||||
{
|
||||
return modified;
|
||||
}
|
||||
|
||||
void DeckStateManager::setModified(bool state)
|
||||
{
|
||||
if (state == modified) {
|
||||
return;
|
||||
}
|
||||
|
||||
modified = state;
|
||||
emit isModifiedChanged(modified);
|
||||
}
|
||||
|
||||
bool DeckStateManager::isBlankNewDeck() const
|
||||
{
|
||||
return !isModified() && deckList->isBlankDeck();
|
||||
}
|
||||
|
||||
void DeckStateManager::replaceDeck(const LoadedDeck &deck)
|
||||
{
|
||||
lastLoadInfo = deck.lastLoadInfo;
|
||||
deckList = QSharedPointer<DeckList>(new DeckList(deck.deckList));
|
||||
deckListModel->setDeckList(deckList);
|
||||
|
||||
historyManager->clear();
|
||||
|
||||
setModified(false);
|
||||
emit deckReplaced();
|
||||
}
|
||||
|
||||
void DeckStateManager::clearDeck()
|
||||
{
|
||||
replaceDeck(LoadedDeck());
|
||||
}
|
||||
|
||||
bool DeckStateManager::modifyDeck(const QString &reason, const std::function<bool(DeckListModel *)> &operation)
|
||||
{
|
||||
DeckListMemento memento = deckList->createMemento(reason);
|
||||
bool success = operation(deckListModel);
|
||||
|
||||
if (success) {
|
||||
historyManager->save(memento);
|
||||
doCardModified();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
QModelIndex DeckStateManager::modifyDeck(const QString &reason,
|
||||
const std::function<QModelIndex(DeckListModel *)> &operation)
|
||||
{
|
||||
DeckListMemento memento = deckList->createMemento(reason);
|
||||
QModelIndex idx = operation(deckListModel);
|
||||
|
||||
if (idx.isValid()) {
|
||||
historyManager->save(memento);
|
||||
doCardModified();
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void DeckStateManager::setName(const QString &name)
|
||||
{
|
||||
QString previous = deckList->getName();
|
||||
if (previous == name) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestHistorySave(tr("Rename deck to \"%1\" from \"%2\"").arg(name).arg(previous));
|
||||
deckList->setName(name);
|
||||
|
||||
doMetadataModified();
|
||||
}
|
||||
|
||||
void DeckStateManager::setComments(const QString &comments)
|
||||
{
|
||||
QString previous = deckList->getComments();
|
||||
if (previous == comments) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestHistorySave(tr("Updated comments (was %1 chars, now %2 chars)").arg(previous.size()).arg(comments.size()));
|
||||
deckList->setComments(comments);
|
||||
|
||||
doMetadataModified();
|
||||
}
|
||||
|
||||
void DeckStateManager::setBannerCard(const CardRef &bannerCard)
|
||||
{
|
||||
CardRef previous = deckList->getBannerCard();
|
||||
if (previous == bannerCard) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestHistorySave(tr("Set banner card to %1 (%2)").arg(bannerCard.name).arg(bannerCard.providerId));
|
||||
deckList->setBannerCard(bannerCard);
|
||||
|
||||
doMetadataModified();
|
||||
}
|
||||
|
||||
void DeckStateManager::setTags(const QStringList &tags)
|
||||
{
|
||||
QStringList previous = deckList->getTags();
|
||||
if (previous == tags) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestHistorySave(tr("Tags changed"));
|
||||
deckList->setTags(tags);
|
||||
|
||||
doMetadataModified();
|
||||
}
|
||||
|
||||
void DeckStateManager::setFormat(const QString &format)
|
||||
{
|
||||
if (deckList->getMetadata().gameFormat == format) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestHistorySave(tr("Set format to %1").arg(format));
|
||||
deckListModel->setActiveFormat(format);
|
||||
|
||||
doMetadataModified();
|
||||
}
|
||||
|
||||
QModelIndex DeckStateManager::addCard(const ExactCard &card, const QString &zoneName)
|
||||
{
|
||||
if (!card) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString reason = tr("Added (%1): %2 (%3) %4")
|
||||
.arg(zoneName, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
|
||||
card.getPrinting().getProperty("num"));
|
||||
|
||||
QModelIndex idx = modifyDeck(reason, [&card, &zoneName](auto model) { return model->addCard(card, zoneName); });
|
||||
|
||||
if (idx.isValid()) {
|
||||
emit focusIndexChanged(idx);
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
QModelIndex DeckStateManager::decrementCard(const ExactCard &card, const QString &zoneName)
|
||||
{
|
||||
if (!card)
|
||||
return {};
|
||||
|
||||
QString providerId = card.getPrinting().getUuid();
|
||||
QString collectorNumber = card.getPrinting().getProperty("num");
|
||||
|
||||
QModelIndex idx = deckListModel->findCard(card.getName(), zoneName, providerId, collectorNumber);
|
||||
if (!idx.isValid()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool success = offsetCountAtIndex(idx, false);
|
||||
|
||||
if (!success) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (idx.isValid()) {
|
||||
emit focusIndexChanged(idx);
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static bool doSwapCard(DeckListModel *model,
|
||||
const QModelIndex &idx,
|
||||
const QString &cardName,
|
||||
const QString &providerId,
|
||||
const QString &otherZone)
|
||||
{
|
||||
bool success = model->offsetCountAtIndex(idx, -1);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ExactCard card = CardDatabaseManager::query()->getCard({cardName, providerId})) {
|
||||
model->addCard(card, otherZone);
|
||||
} else {
|
||||
// Third argument (true) says create the card no matter what, even if not in DB
|
||||
model->addPreferredPrintingCard(cardName, otherZone, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeckStateManager::swapCardAtIndex(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
QString cardName = idx.siblingAtColumn(DeckListModelColumns::CARD_NAME).data().toString();
|
||||
QString providerId = idx.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data().toString();
|
||||
QModelIndex gparent = idx.parent().parent();
|
||||
|
||||
if (!gparent.isValid())
|
||||
return false;
|
||||
|
||||
QString zoneName = gparent.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
|
||||
QString otherZoneName = zoneName == DECK_ZONE_MAIN ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
|
||||
|
||||
QString reason = tr("Moved to %1 1 × \"%2\" (%3)") //
|
||||
.arg(otherZoneName)
|
||||
.arg(cardName)
|
||||
.arg(providerId);
|
||||
|
||||
return modifyDeck(reason, [&idx, &cardName, &providerId, &otherZoneName](auto model) {
|
||||
return doSwapCard(model, idx, cardName, providerId, otherZoneName);
|
||||
});
|
||||
}
|
||||
|
||||
bool DeckStateManager::removeCardAtIndex(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid() || deckListModel->hasChildren(idx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString cardName = idx.siblingAtColumn(DeckListModelColumns::CARD_NAME).data().toString();
|
||||
|
||||
QString reason = tr("Removed \"%1\" (all copies)").arg(cardName);
|
||||
|
||||
return modifyDeck(reason, [&idx](auto model) { return model->removeRow(idx.row(), idx.parent()); });
|
||||
}
|
||||
|
||||
bool DeckStateManager::incrementCountAtIndex(const QModelIndex &idx)
|
||||
{
|
||||
return offsetCountAtIndex(idx, 1);
|
||||
}
|
||||
|
||||
bool DeckStateManager::decrementCountAtIndex(const QModelIndex &idx)
|
||||
{
|
||||
return offsetCountAtIndex(idx, -1);
|
||||
}
|
||||
|
||||
bool DeckStateManager::offsetCountAtIndex(const QModelIndex &idx, int offset)
|
||||
{
|
||||
if (!idx.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString cardName = idx.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
|
||||
QString providerId = idx.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data(Qt::DisplayRole).toString();
|
||||
|
||||
QString reason = tr("%1 1 × \"%2\" (%3)") //
|
||||
.arg(offset > 0 ? tr("Added") : tr("Removed"))
|
||||
.arg(cardName)
|
||||
.arg(providerId);
|
||||
|
||||
return modifyDeck(reason, [&idx, &offset](auto model) { return model->offsetCountAtIndex(idx, offset); });
|
||||
}
|
||||
|
||||
void DeckStateManager::undo(int steps)
|
||||
{
|
||||
if (!historyManager->canUndo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < steps; i++) {
|
||||
if (!historyManager->canUndo()) {
|
||||
continue;
|
||||
}
|
||||
historyManager->undo(deckList.get());
|
||||
}
|
||||
|
||||
deckListModel->rebuildTree();
|
||||
|
||||
emit deckListModel->layoutChanged();
|
||||
}
|
||||
|
||||
void DeckStateManager::redo(int steps)
|
||||
{
|
||||
if (!historyManager->canRedo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < steps; i++) {
|
||||
if (!historyManager->canRedo()) {
|
||||
continue;
|
||||
}
|
||||
historyManager->redo(deckList.get());
|
||||
}
|
||||
|
||||
deckListModel->rebuildTree();
|
||||
|
||||
emit deckListModel->layoutChanged();
|
||||
}
|
||||
|
||||
void DeckStateManager::requestHistorySave(const QString &reason)
|
||||
{
|
||||
historyManager->save(deckList->createMemento(reason));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles updating state and emitting signals whenever the cards are modified
|
||||
*/
|
||||
void DeckStateManager::doCardModified()
|
||||
{
|
||||
setModified(true);
|
||||
emit cardModified();
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles updating state and emitting signals whenever the metadata is modified
|
||||
*/
|
||||
void DeckStateManager::doMetadataModified()
|
||||
{
|
||||
setModified(true);
|
||||
emit metadataModified();
|
||||
emit deckModified();
|
||||
}
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
#ifndef COCKATRICE_DECK_STATE_MANAGER_H
|
||||
#define COCKATRICE_DECK_STATE_MANAGER_H
|
||||
|
||||
#include "../../deck_loader/loaded_deck.h"
|
||||
#include "deck_list_model.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
|
||||
class DeckListHistoryManager;
|
||||
|
||||
/**
|
||||
* @brief This class centralizes the management of the state of the deck in the deck editor tab.
|
||||
* It is responsible for owning and managing the DeckListModel, underlying DeckList, load info, and edit history.
|
||||
*
|
||||
* Although this class provides getters for the underlying DeckListModel, you should generally refrain from directly
|
||||
* modifying the returned model. Outside modifications to the deck state should be done through @link
|
||||
* DeckStateManager::modifyDeck and the metadata setters.
|
||||
* Those methods ensure that the history is recorded and correct signals are emitted.
|
||||
*/
|
||||
class DeckStateManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
LoadedDeck::LoadInfo lastLoadInfo;
|
||||
QSharedPointer<DeckList> deckList;
|
||||
DeckListModel *deckListModel;
|
||||
DeckListHistoryManager *historyManager;
|
||||
|
||||
bool modified = false;
|
||||
|
||||
public:
|
||||
explicit DeckStateManager(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Gets the underlying HistoryManager.
|
||||
* @return The DeckListHistoryManager instance
|
||||
*/
|
||||
DeckListHistoryManager *getHistoryManager() const
|
||||
{
|
||||
return historyManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the underlying DeckListModel.
|
||||
* You should generally refrain modifying the returned model directly.
|
||||
* However, it's fine (and intended) to perform queries on the returned model.
|
||||
* @return The DeckListModel instance
|
||||
*/
|
||||
DeckListModel *getModel() const
|
||||
{
|
||||
return deckListModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a view of the current deck.
|
||||
*/
|
||||
const DeckList &getDeckList() const;
|
||||
|
||||
/**
|
||||
* @brief Creates a LoadedDeck containing the contents of the current deck and the current LoadInfo.
|
||||
*
|
||||
* @return A new LoadedDeck instance.
|
||||
*/
|
||||
LoadedDeck toLoadedDeck() const;
|
||||
|
||||
/**
|
||||
* @brief Gets a view of the metadata in the DeckList
|
||||
*/
|
||||
DeckList::Metadata const &getMetadata() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the deck's simplified name.
|
||||
*/
|
||||
QString getSimpleDeckName() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the deck hash.
|
||||
*/
|
||||
QString getDeckHash() const;
|
||||
|
||||
/**
|
||||
* @brief Checks if the deck has been modified since it was last saved
|
||||
*/
|
||||
bool isModified() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the new isModified state, emitting a signal if the state changed.
|
||||
* This class will automatically update its isModified state, but you may need to set it manually to handle, for
|
||||
* example, saving.
|
||||
* @param state The state
|
||||
*/
|
||||
void setModified(bool state);
|
||||
|
||||
/**
|
||||
* @brief Checks if the deck state is as if it was a new deck
|
||||
*/
|
||||
bool isBlankNewDeck() const;
|
||||
|
||||
/**
|
||||
* @brief Overwrites the current deck with a new deck, resetting all history
|
||||
* @param deck The new deck.
|
||||
*/
|
||||
void replaceDeck(const LoadedDeck &deck);
|
||||
|
||||
/**
|
||||
* @brief Resets the deck to a blank new deck, resetting all history.
|
||||
*/
|
||||
void clearDeck();
|
||||
|
||||
/**
|
||||
* @brief Sets the lastLoadInfo.
|
||||
* @param loadInfo The lastLoadInfo
|
||||
*/
|
||||
void setLastLoadInfo(const LoadedDeck::LoadInfo &loadInfo)
|
||||
{
|
||||
lastLoadInfo = loadInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Modifies the cards in the deck, in a wrapped operation that is saved to the history.
|
||||
*
|
||||
* The operation is a function that accepts a DeckListModel that it operates upon, and returns a bool.
|
||||
*
|
||||
* This method will pass the underlying DeckListModel into the operation function. The function can call methods on
|
||||
* the model to modify the deck.
|
||||
* The function should return a bool to indicate success/failure.
|
||||
*
|
||||
* If the operation returns true, the state of the deck before the operation is ran is saved to the history, and the
|
||||
* isModified state is updated.
|
||||
* If the operation returns false, the history and isModified state is not updated.
|
||||
*
|
||||
* Note that even if the operation fails, any modifications to the model will already have been made.
|
||||
* It's recommended for the operation to always return true if any modification has already been made to the model,
|
||||
* as not doing that may cause the state to become desynced.
|
||||
*
|
||||
* @param reason The reason to display in the history
|
||||
* @param operation The modification operation.
|
||||
* @return The bool returned from the operation
|
||||
*/
|
||||
bool modifyDeck(const QString &reason, const std::function<bool(DeckListModel *)> &operation);
|
||||
|
||||
/**
|
||||
* @brief Modifies the cards in the deck, in a wrapped operation that is saved to the history.
|
||||
*
|
||||
* The operation is a function that accepts a DeckListModel that it operates upon, and returns a QModelIndex.
|
||||
* If the index is invalid, then the operation is considered to be a failure.
|
||||
*
|
||||
* See the other @link DeckStateManager::modifyDeck for more info about the behavior of this method.
|
||||
*
|
||||
* @param reason The reason to display in the history
|
||||
* @param operation The modification operation.
|
||||
* @return The QModelIndex returned from the operation
|
||||
*/
|
||||
QModelIndex modifyDeck(const QString &reason, const std::function<QModelIndex(DeckListModel *)> &operation);
|
||||
|
||||
/// @name Metadata setters
|
||||
/// @brief These methods set the metadata. Will no-op if the new value is the same as the current value.
|
||||
/// Saves the operation to history if successful.
|
||||
///@{
|
||||
void setName(const QString &name);
|
||||
void setComments(const QString &comments);
|
||||
void setBannerCard(const CardRef &bannerCard);
|
||||
void setTags(const QStringList &tags);
|
||||
void setFormat(const QString &format);
|
||||
///@}
|
||||
|
||||
/**
|
||||
* @brief Adds the given card to the given zone.
|
||||
* Saves the operation to history if successful.
|
||||
*
|
||||
* @param card The card to add
|
||||
* @param zoneName The zone to add the card to
|
||||
* @return The index of the added card
|
||||
*/
|
||||
QModelIndex addCard(const ExactCard &card, const QString &zoneName);
|
||||
|
||||
/**
|
||||
* @brief Removes 1 copy of the given card from the given zone.
|
||||
* Saves the operation to history if successful.
|
||||
*
|
||||
* @param card The card to remove
|
||||
* @param zoneName The zone to remove the card from
|
||||
* @return The index of the removed card. Will be invalid if the last copy was removed.
|
||||
*/
|
||||
QModelIndex decrementCard(const ExactCard &card, const QString &zoneName);
|
||||
|
||||
/**
|
||||
* @brief Swaps one copy of the card at the given index between the maindeck and sideboard.
|
||||
* No-ops if index is invalid or not a card node.
|
||||
* Saves the operation to history if successful.
|
||||
*
|
||||
* @param idx The model index
|
||||
* @return Whether the operation was successfully performed
|
||||
*/
|
||||
bool swapCardAtIndex(const QModelIndex &idx);
|
||||
|
||||
/**
|
||||
* @brief Removes all copies of the card at the given index.
|
||||
* No-ops if index is invalid or not a card node.
|
||||
* Saves the operation to history if successful.
|
||||
*
|
||||
* @param idx The model index
|
||||
* @return Whether the operation was successfully performed
|
||||
*/
|
||||
bool removeCardAtIndex(const QModelIndex &idx);
|
||||
|
||||
/**
|
||||
* @brief Increments the number of copies of the card at the given index by 1.
|
||||
* No-ops if index is invalid or not a card node.
|
||||
* Saves the operation to history if successful.
|
||||
*
|
||||
* @param idx The model index
|
||||
* @return Whether the operation was successfully performed
|
||||
*/
|
||||
bool incrementCountAtIndex(const QModelIndex &idx);
|
||||
|
||||
/**
|
||||
* @brief Decrements the number of copies of the card at the given index by 1.
|
||||
* No-ops if index is invalid or not a card node.
|
||||
* Saves the operation to history if successful.
|
||||
*
|
||||
* @param idx The model index
|
||||
* @return Whether the operation was successfully performed
|
||||
*/
|
||||
bool decrementCountAtIndex(const QModelIndex &idx);
|
||||
|
||||
/**
|
||||
* Undoes n steps of the history, setting the decklist state and updating the current step in the historyManager.
|
||||
* @param steps Number of steps to undo.
|
||||
*/
|
||||
void undo(int steps = 1);
|
||||
|
||||
/**
|
||||
* Redoes n steps of the history, setting the decklist state and updating the current step in the historyManager.
|
||||
* @param steps Number of steps to redo.
|
||||
*/
|
||||
void redo(int steps = 1);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Saves the current decklist state to history.
|
||||
* @param reason The reason that is shown in the history.
|
||||
*/
|
||||
void requestHistorySave(const QString &reason);
|
||||
|
||||
private:
|
||||
bool offsetCountAtIndex(const QModelIndex &idx, int offset);
|
||||
void doCardModified();
|
||||
void doMetadataModified();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* A modification has been made to the cards in the deck
|
||||
*/
|
||||
void cardModified();
|
||||
|
||||
/**
|
||||
* A card that wasn't previously in the deck was added to the deck, or the last copy of a card was removed from the
|
||||
* deck.
|
||||
*/
|
||||
void uniqueCardsChanged();
|
||||
|
||||
/**
|
||||
* A modification has been made to the metadata in the deck
|
||||
*/
|
||||
void metadataModified();
|
||||
|
||||
/**
|
||||
* A modification has been made to the cards or metadata in the deck
|
||||
*/
|
||||
void deckModified();
|
||||
|
||||
/**
|
||||
* The history has been greatly changed and needs to be reloaded.
|
||||
*/
|
||||
void historyChanged();
|
||||
|
||||
/**
|
||||
* The deck has been completely changed.
|
||||
*/
|
||||
void deckReplaced();
|
||||
|
||||
/**
|
||||
* The isModified state of the deck has changed
|
||||
* @param isModified the new state
|
||||
*/
|
||||
void isModifiedChanged(bool isModified);
|
||||
|
||||
/**
|
||||
* The selected card on any views connected to this deck should be changed to this index.
|
||||
* @param index The model index
|
||||
*/
|
||||
void focusIndexChanged(QModelIndex index);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_DECK_STATE_MANAGER_H
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../../deck_loader/card_node_function.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../deck_editor/deck_state_manager.h"
|
||||
#include "../interface/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../interface/widgets/general/layout_containers/flow_widget.h"
|
||||
|
||||
|
|
@ -21,7 +22,8 @@
|
|||
#include <qdrag.h>
|
||||
#include <qevent.h>
|
||||
|
||||
DlgSelectSetForCards::DlgSelectSetForCards(QWidget *parent, DeckListModel *_model) : QDialog(parent), model(_model)
|
||||
DlgSelectSetForCards::DlgSelectSetForCards(QWidget *parent, DeckStateManager *deckStateManger)
|
||||
: QDialog(parent), deckStateManager(deckStateManger)
|
||||
{
|
||||
setMinimumSize(500, 500);
|
||||
setAcceptDrops(true);
|
||||
|
|
@ -165,36 +167,39 @@ void DlgSelectSetForCards::actOK()
|
|||
|
||||
if (modifiedSetsAndCardsMap.isEmpty()) {
|
||||
accept(); // Nothing to do
|
||||
} else {
|
||||
emit deckAboutToBeModified(tr("Bulk modified printings."));
|
||||
return;
|
||||
}
|
||||
|
||||
for (QString modifiedSet : modifiedSetsAndCardsMap.keys()) {
|
||||
for (QString card : modifiedSetsAndCardsMap.value(modifiedSet)) {
|
||||
swapPrinting(model, modifiedSet, card);
|
||||
auto bulkModify = [&modifiedSetsAndCardsMap](DeckListModel *model) {
|
||||
for (QString modifiedSet : modifiedSetsAndCardsMap.keys()) {
|
||||
for (QString card : modifiedSetsAndCardsMap.value(modifiedSet)) {
|
||||
swapPrinting(model, modifiedSet, card);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
deckStateManager->modifyDeck(tr("Bulk modified printings."), bulkModify);
|
||||
|
||||
if (!modifiedSetsAndCardsMap.isEmpty()) {
|
||||
emit deckModified();
|
||||
}
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::actClear()
|
||||
{
|
||||
emit deckAboutToBeModified(tr("Cleared all printing information."));
|
||||
model->forEachCard(CardNodeFunction::ClearPrintingData());
|
||||
emit deckModified();
|
||||
deckStateManager->modifyDeck(tr("Cleared all printing information."), [](auto model) {
|
||||
model->forEachCard(CardNodeFunction::ClearPrintingData());
|
||||
return true;
|
||||
});
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::actSetAllToPreferred()
|
||||
{
|
||||
emit deckAboutToBeModified(tr("Set all printings to preferred."));
|
||||
model->forEachCard(CardNodeFunction::ClearPrintingData());
|
||||
model->forEachCard(CardNodeFunction::SetProviderIdToPreferred());
|
||||
emit deckModified();
|
||||
deckStateManager->modifyDeck(tr("Set all printings to preferred."), [](auto model) {
|
||||
model->forEachCard(CardNodeFunction::ClearPrintingData());
|
||||
model->forEachCard(CardNodeFunction::SetProviderIdToPreferred());
|
||||
return true;
|
||||
});
|
||||
accept();
|
||||
}
|
||||
|
||||
|
|
@ -227,10 +232,8 @@ void DlgSelectSetForCards::sortSetsByCount()
|
|||
QMap<QString, int> DlgSelectSetForCards::getSetsForCards()
|
||||
{
|
||||
QMap<QString, int> setCounts;
|
||||
if (!model)
|
||||
return setCounts;
|
||||
|
||||
QList<QString> cardNames = model->getCardNames();
|
||||
QList<QString> cardNames = deckStateManager->getModel()->getCardNames();
|
||||
|
||||
for (auto cardName : cardNames) {
|
||||
CardInfoPtr infoPtr = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
|
|
@ -269,7 +272,7 @@ void DlgSelectSetForCards::updateCardLists()
|
|||
}
|
||||
}
|
||||
|
||||
QList<QString> cardNames = model->getCardNames();
|
||||
QList<QString> cardNames = deckStateManager->getModel()->getCardNames();
|
||||
|
||||
for (auto cardName : cardNames) {
|
||||
bool found = false;
|
||||
|
|
@ -351,10 +354,8 @@ void DlgSelectSetForCards::dropEvent(QDropEvent *event)
|
|||
QMap<QString, QStringList> DlgSelectSetForCards::getCardsForSets()
|
||||
{
|
||||
QMap<QString, QStringList> setCards;
|
||||
if (!model)
|
||||
return setCards;
|
||||
|
||||
QList<QString> cardNames = model->getCardNames();
|
||||
QList<QString> cardNames = deckStateManager->getModel()->getCardNames();
|
||||
|
||||
for (auto cardName : cardNames) {
|
||||
CardInfoPtr infoPtr = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
|
||||
class DeckStateManager;
|
||||
class SetEntryWidget; // Forward declaration
|
||||
|
||||
class DlgSelectSetForCards : public QDialog
|
||||
|
|
@ -25,7 +26,7 @@ class DlgSelectSetForCards : public QDialog
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DlgSelectSetForCards(QWidget *parent, DeckListModel *_model);
|
||||
explicit DlgSelectSetForCards(QWidget *parent, DeckStateManager *deckStateManager);
|
||||
void retranslateUi();
|
||||
void sortSetsByCount();
|
||||
QMap<QString, QStringList> getCardsForSets();
|
||||
|
|
@ -37,7 +38,6 @@ public:
|
|||
signals:
|
||||
void widgetOrderChanged();
|
||||
void orderChanged();
|
||||
void deckAboutToBeModified(const QString &reason);
|
||||
void deckModified();
|
||||
|
||||
public slots:
|
||||
|
|
@ -61,7 +61,7 @@ private:
|
|||
QLabel *modifiedCardsLabel;
|
||||
QWidget *listContainer;
|
||||
QListWidget *listWidget;
|
||||
DeckListModel *model;
|
||||
DeckStateManager *deckStateManager;
|
||||
QMap<QString, SetEntryWidget *> setEntries;
|
||||
QPushButton *clearButton;
|
||||
QPushButton *setAllToPreferredButton;
|
||||
|
|
|
|||
|
|
@ -11,16 +11,12 @@
|
|||
* UI elements for managing card counts in both the mainboard and sideboard zones.
|
||||
*
|
||||
* @param parent The parent widget.
|
||||
* @param deckEditor Pointer to the TabDeckEditor.
|
||||
* @param deckModel Pointer to the DeckListModel.
|
||||
* @param deckView Pointer to the QTreeView for the deck display.
|
||||
* @param deckStateManager Pointer to the DeckStateManager
|
||||
* @param cardSizeSlider Pointer to the QSlider used for dynamic font resizing.
|
||||
* @param rootCard The root card for the widget.
|
||||
*/
|
||||
AllZonesCardAmountWidget::AllZonesCardAmountWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &rootCard)
|
||||
: QWidget(parent), cardSizeSlider(cardSizeSlider)
|
||||
|
|
@ -32,11 +28,9 @@ AllZonesCardAmountWidget::AllZonesCardAmountWidget(QWidget *parent,
|
|||
setContentsMargins(5, 5, 5, 5); // Padding around the text
|
||||
|
||||
zoneLabelMainboard = new ShadowBackgroundLabel(this, tr("Mainboard"));
|
||||
buttonBoxMainboard =
|
||||
new CardAmountWidget(this, deckEditor, deckModel, deckView, cardSizeSlider, rootCard, DECK_ZONE_MAIN);
|
||||
buttonBoxMainboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_MAIN);
|
||||
zoneLabelSideboard = new ShadowBackgroundLabel(this, tr("Sideboard"));
|
||||
buttonBoxSideboard =
|
||||
new CardAmountWidget(this, deckEditor, deckModel, deckView, cardSizeSlider, rootCard, DECK_ZONE_SIDE);
|
||||
buttonBoxSideboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_SIDE);
|
||||
|
||||
layout->addWidget(zoneLabelMainboard, 0, Qt::AlignHCenter | Qt::AlignBottom);
|
||||
layout->addWidget(buttonBoxMainboard, 0, Qt::AlignHCenter | Qt::AlignTop);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ class AllZonesCardAmountWidget : public QWidget
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit AllZonesCardAmountWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &rootCard);
|
||||
int getMainboardAmount();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "card_amount_widget.h"
|
||||
|
||||
#include "../deck_editor/deck_state_manager.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
|
|
@ -7,22 +9,17 @@
|
|||
* @brief Constructs a widget for displaying and controlling the card count in a specific zone.
|
||||
*
|
||||
* @param parent The parent widget.
|
||||
* @param deckEditor Pointer to the TabDeckEditor instance.
|
||||
* @param deckModel Pointer to the DeckListModel instance.
|
||||
* @param deckView Pointer to the QTreeView displaying the deck.
|
||||
* @param cardSizeSlider Pointer to the QSlider for adjusting font size.
|
||||
* @param rootCard The root card to manage within the widget.
|
||||
* @param zoneName The zone name (e.g., DECK_ZONE_MAIN or DECK_ZONE_SIDE).
|
||||
*/
|
||||
CardAmountWidget::CardAmountWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &rootCard,
|
||||
const QString &zoneName)
|
||||
: QWidget(parent), deckEditor(deckEditor), deckModel(deckModel), deckView(deckView), cardSizeSlider(cardSizeSlider),
|
||||
rootCard(rootCard), zoneName(zoneName), hovered(false)
|
||||
: QWidget(parent), deckStateManager(deckStateManager), cardSizeSlider(cardSizeSlider), rootCard(rootCard),
|
||||
zoneName(zoneName), hovered(false)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
|
@ -56,15 +53,10 @@ CardAmountWidget::CardAmountWidget(QWidget *parent,
|
|||
layout->addWidget(incrementButton);
|
||||
|
||||
// React to model changes
|
||||
connect(deckModel, &DeckListModel::dataChanged, this, &CardAmountWidget::updateCardCount);
|
||||
connect(deckModel, &QAbstractItemModel::rowsRemoved, this, &CardAmountWidget::updateCardCount);
|
||||
connect(deckStateManager, &DeckStateManager::cardModified, this, &CardAmountWidget::updateCardCount);
|
||||
|
||||
// Connect slider for dynamic font size adjustment
|
||||
connect(cardSizeSlider, &QSlider::valueChanged, this, &CardAmountWidget::adjustFontSize);
|
||||
|
||||
if (deckEditor) {
|
||||
connect(this, &CardAmountWidget::deckModified, deckEditor, &AbstractTabDeckEditor::onDeckHistorySaveRequested);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -168,7 +160,7 @@ static QModelIndex addAndReplacePrintings(DeckListModel *model,
|
|||
void CardAmountWidget::addPrinting(const QString &zone)
|
||||
{
|
||||
// Check if we will need to add extra copies due to replacing copies without providerIds
|
||||
QModelIndex existing = deckModel->findCard(rootCard.getName(), zone);
|
||||
QModelIndex existing = deckStateManager->getModel()->findCard(rootCard.getName(), zone);
|
||||
|
||||
int extraCopies = 0;
|
||||
bool replacingProviderless = false;
|
||||
|
|
@ -192,15 +184,13 @@ void CardAmountWidget::addPrinting(const QString &zone)
|
|||
.arg(rootCard.getPrinting().getUuid())
|
||||
.arg(replacingProviderless ? " (replaced providerless printings)" : "");
|
||||
|
||||
emit deckModified(reason);
|
||||
|
||||
// Add the card and expand the list UI
|
||||
auto newCardIndex = addAndReplacePrintings(deckModel, existing, rootCard, zone, extraCopies, replacingProviderless);
|
||||
QModelIndex newCardIndex = deckStateManager->modifyDeck(reason, [&](auto model) {
|
||||
return addAndReplacePrintings(model, existing, rootCard, zone, extraCopies, replacingProviderless);
|
||||
});
|
||||
|
||||
if (newCardIndex.isValid()) {
|
||||
deckView->setCurrentIndex(newCardIndex);
|
||||
deckView->setFocus(Qt::FocusReason::MouseFocusReason);
|
||||
deckEditor->setModified(true);
|
||||
emit deckStateManager->focusIndexChanged(newCardIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -250,13 +240,11 @@ void CardAmountWidget::decrementCardHelper(const QString &zone)
|
|||
.arg(zone == DECK_ZONE_MAIN ? "mainboard" : "sideboard")
|
||||
.arg(rootCard.getPrinting().getUuid());
|
||||
|
||||
emit deckModified(reason);
|
||||
|
||||
QModelIndex idx = deckModel->findCard(rootCard.getName(), zone, rootCard.getPrinting().getUuid(),
|
||||
deckStateManager->modifyDeck(reason, [this, &zone](auto model) {
|
||||
QModelIndex idx = model->findCard(rootCard.getName(), zone, rootCard.getPrinting().getUuid(),
|
||||
rootCard.getPrinting().getProperty("num"));
|
||||
|
||||
deckModel->offsetCountAtIndex(idx, -1);
|
||||
deckEditor->setModified(true);
|
||||
return model->offsetCountAtIndex(idx, -1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -273,7 +261,7 @@ int CardAmountWidget::countCardsInZone(const QString &deckZone)
|
|||
return 0; // Cards without uuids/providerIds CANNOT match another card, they are undefined for us.
|
||||
}
|
||||
|
||||
QList<ExactCard> cards = deckModel->getCardsForZone(deckZone);
|
||||
QList<ExactCard> cards = deckStateManager->getModel()->getCardsForZone(deckZone);
|
||||
|
||||
return std::count_if(cards.cbegin(), cards.cend(),
|
||||
[&uuid](const ExactCard &card) { return card.getPrinting().getUuid() == uuid; });
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@ signals:
|
|||
|
||||
public:
|
||||
explicit CardAmountWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &rootCard,
|
||||
const QString &zoneName);
|
||||
|
|
@ -44,9 +42,7 @@ protected:
|
|||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private:
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
DeckListModel *deckModel;
|
||||
QTreeView *deckView;
|
||||
DeckStateManager *deckStateManager;
|
||||
QSlider *cardSizeSlider;
|
||||
ExactCard rootCard;
|
||||
QString zoneName;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../interface/card_picture_loader/card_picture_loader.h"
|
||||
#include "../../../interface/widgets/dialogs/dlg_select_set_for_cards.h"
|
||||
#include "../deck_editor/deck_state_manager.h"
|
||||
#include "printing_selector_card_display_widget.h"
|
||||
#include "printing_selector_card_search_widget.h"
|
||||
#include "printing_selector_card_selection_widget.h"
|
||||
|
|
@ -21,12 +22,9 @@
|
|||
*
|
||||
* @param parent The parent widget for the PrintingSelector.
|
||||
* @param deckEditor The TabDeckEditor instance used for managing the deck.
|
||||
* @param deckModel The DeckListModel instance that provides data for the deck's contents.
|
||||
* @param deckView The QTreeView instance used to display the deck and its contents.
|
||||
*/
|
||||
PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deckEditor)
|
||||
: QWidget(parent), deckEditor(_deckEditor), deckModel(deckEditor->deckDockWidget->deckModel),
|
||||
deckView(deckEditor->deckDockWidget->deckView)
|
||||
: QWidget(parent), deckEditor(_deckEditor), deckStateManager(_deckEditor->deckStateManager)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
layout = new QVBoxLayout(this);
|
||||
|
|
@ -74,13 +72,12 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck
|
|||
|
||||
layout->addWidget(flowWidget);
|
||||
|
||||
cardSelectionBar = new PrintingSelectorCardSelectionWidget(this);
|
||||
cardSelectionBar = new PrintingSelectorCardSelectionWidget(this, deckStateManager);
|
||||
cardSelectionBar->setVisible(SettingsCache::instance().getPrintingSelectorNavigationButtonsVisible());
|
||||
layout->addWidget(cardSelectionBar);
|
||||
|
||||
// Connect deck model data change signal to update display
|
||||
connect(deckModel, &DeckListModel::rowsInserted, this, &PrintingSelector::printingsInDeckChanged);
|
||||
connect(deckModel, &DeckListModel::rowsRemoved, this, &PrintingSelector::printingsInDeckChanged);
|
||||
connect(deckStateManager, &DeckStateManager::uniqueCardsChanged, this, &PrintingSelector::printingsInDeckChanged);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
|
@ -152,7 +149,8 @@ void PrintingSelector::getAllSetsForCurrentCard()
|
|||
QList<PrintingInfo> printingsToUse;
|
||||
|
||||
if (SettingsCache::instance().getBumpSetsWithCardsInDeckToTop()) {
|
||||
printingsToUse = sortToolBar->prependPrintingsInDeck(filteredPrintings, selectedCard, deckModel);
|
||||
printingsToUse =
|
||||
sortToolBar->prependPrintingsInDeck(filteredPrintings, selectedCard, deckStateManager->getModel());
|
||||
} else {
|
||||
printingsToUse = filteredPrintings;
|
||||
}
|
||||
|
|
@ -164,7 +162,7 @@ void PrintingSelector::getAllSetsForCurrentCard()
|
|||
connect(widgetLoadingBufferTimer, &QTimer::timeout, this, [=, this]() mutable {
|
||||
for (int i = 0; i < BATCH_SIZE && currentIndex < printingsToUse.size(); ++i, ++currentIndex) {
|
||||
auto card = ExactCard(selectedCard, printingsToUse[currentIndex]);
|
||||
auto *cardDisplayWidget = new PrintingSelectorCardDisplayWidget(this, deckEditor, deckModel, deckView,
|
||||
auto *cardDisplayWidget = new PrintingSelectorCardDisplayWidget(this, deckEditor, deckStateManager,
|
||||
cardSizeWidget->getSlider(), card);
|
||||
flowWidget->addWidget(cardDisplayWidget);
|
||||
cardDisplayWidget->clampSetNameToPicture();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#define BATCH_SIZE 10
|
||||
|
||||
class DeckStateManager;
|
||||
class PrintingSelectorCardSearchWidget;
|
||||
class PrintingSelectorCardSelectionWidget;
|
||||
class PrintingSelectorCardSortingWidget;
|
||||
|
|
@ -35,15 +36,6 @@ public:
|
|||
|
||||
void setCard(const CardInfoPtr &newCard);
|
||||
void getAllSetsForCurrentCard();
|
||||
[[nodiscard]] DeckListModel *getDeckModel() const
|
||||
{
|
||||
return deckModel;
|
||||
}
|
||||
|
||||
[[nodiscard]] AbstractTabDeckEditor *getDeckEditor() const
|
||||
{
|
||||
return deckEditor;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void retranslateUi();
|
||||
|
|
@ -75,8 +67,7 @@ private:
|
|||
CardSizeWidget *cardSizeWidget;
|
||||
PrintingSelectorCardSelectionWidget *cardSelectionBar;
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
DeckListModel *deckModel;
|
||||
QTreeView *deckView;
|
||||
DeckStateManager *deckStateManager;
|
||||
CardInfoPtr selectedCard;
|
||||
QTimer *widgetLoadingBufferTimer;
|
||||
int currentIndex = 0;
|
||||
|
|
|
|||
|
|
@ -18,15 +18,13 @@
|
|||
*
|
||||
* @param parent The parent widget for this display.
|
||||
* @param deckEditor The TabDeckEditor instance for deck management.
|
||||
* @param deckModel The DeckListModel instance providing deck data.
|
||||
* @param deckView The QTreeView instance displaying the deck.
|
||||
* @param deckStateManager The DeckStateManager instance providing deck data.
|
||||
* @param cardSizeSlider The slider controlling the size of the displayed card.
|
||||
* @param rootCard The root card object, representing the card to be displayed.
|
||||
*/
|
||||
PrintingSelectorCardDisplayWidget::PrintingSelectorCardDisplayWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &rootCard)
|
||||
: QWidget(parent)
|
||||
|
|
@ -36,8 +34,7 @@ PrintingSelectorCardDisplayWidget::PrintingSelectorCardDisplayWidget(QWidget *pa
|
|||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
// Create the overlay widget for the card display
|
||||
overlayWidget =
|
||||
new PrintingSelectorCardOverlayWidget(this, deckEditor, deckModel, deckView, cardSizeSlider, rootCard);
|
||||
overlayWidget = new PrintingSelectorCardOverlayWidget(this, deckEditor, deckStateManager, cardSizeSlider, rootCard);
|
||||
connect(overlayWidget, &PrintingSelectorCardOverlayWidget::cardPreferenceChanged, this,
|
||||
[this]() { emit cardPreferenceChanged(); });
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ class PrintingSelectorCardDisplayWidget : public QWidget
|
|||
public:
|
||||
PrintingSelectorCardDisplayWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &rootCard);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,15 +22,13 @@
|
|||
*
|
||||
* @param parent The parent widget for this overlay.
|
||||
* @param _deckEditor The TabDeckEditor instance for deck management.
|
||||
* @param deckModel The DeckListModel instance providing deck data.
|
||||
* @param deckView The QTreeView instance displaying the deck.
|
||||
* @param deckStateManager The DeckStateManager instance providing deck data.
|
||||
* @param cardSizeSlider The slider controlling the size of the card.
|
||||
* @param _rootCard The root card object that contains information about the card.
|
||||
*/
|
||||
PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *_deckEditor,
|
||||
DeckListModel *deckModel,
|
||||
QTreeView *deckView,
|
||||
DeckStateManager *deckStateManager,
|
||||
QSlider *cardSizeSlider,
|
||||
const ExactCard &_rootCard)
|
||||
: QWidget(parent), deckEditor(_deckEditor), rootCard(_rootCard)
|
||||
|
|
@ -58,8 +56,7 @@ PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *pa
|
|||
updatePinBadgeVisibility();
|
||||
|
||||
// Add AllZonesCardAmountWidget
|
||||
allZonesCardAmountWidget =
|
||||
new AllZonesCardAmountWidget(this, deckEditor, deckModel, deckView, cardSizeSlider, _rootCard);
|
||||
allZonesCardAmountWidget = new AllZonesCardAmountWidget(this, deckStateManager, cardSizeSlider, _rootCard);
|
||||
|
||||
allZonesCardAmountWidget->raise(); // Ensure it's on top of the picture
|
||||
// Set initial visibility based on amounts
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ class PrintingSelectorCardOverlayWidget : public QWidget
|
|||
public:
|
||||
explicit PrintingSelectorCardOverlayWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *_deckEditor,
|
||||
DeckListModel *_deckModel,
|
||||
QTreeView *_deckView,
|
||||
DeckStateManager *_deckStateManager,
|
||||
QSlider *_cardSizeSlider,
|
||||
const ExactCard &_rootCard);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@
|
|||
*
|
||||
* @param parent The parent PrintingSelector widget responsible for managing card selection.
|
||||
*/
|
||||
PrintingSelectorCardSelectionWidget::PrintingSelectorCardSelectionWidget(PrintingSelector *parent) : parent(parent)
|
||||
PrintingSelectorCardSelectionWidget::PrintingSelectorCardSelectionWidget(PrintingSelector *parent,
|
||||
DeckStateManager *deckStateManager)
|
||||
: parent(parent), deckStateManager(deckStateManager)
|
||||
{
|
||||
cardSelectionBarLayout = new QHBoxLayout(this);
|
||||
cardSelectionBarLayout->setContentsMargins(9, 0, 9, 0);
|
||||
|
|
@ -48,12 +50,6 @@ void PrintingSelectorCardSelectionWidget::connectSignals()
|
|||
|
||||
void PrintingSelectorCardSelectionWidget::selectSetForCards()
|
||||
{
|
||||
auto *setSelectionDialog = new DlgSelectSetForCards(nullptr, parent->getDeckModel());
|
||||
connect(setSelectionDialog, &DlgSelectSetForCards::deckAboutToBeModified, parent->getDeckEditor(),
|
||||
&AbstractTabDeckEditor::onDeckHistorySaveRequested);
|
||||
connect(setSelectionDialog, &DlgSelectSetForCards::deckModified, parent->getDeckEditor(),
|
||||
&AbstractTabDeckEditor::onDeckModified);
|
||||
if (!setSelectionDialog->exec()) {
|
||||
return;
|
||||
}
|
||||
auto *setSelectionDialog = new DlgSelectSetForCards(nullptr, deckStateManager);
|
||||
setSelectionDialog->exec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class PrintingSelectorCardSelectionWidget : public QWidget
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PrintingSelectorCardSelectionWidget(PrintingSelector *parent);
|
||||
explicit PrintingSelectorCardSelectionWidget(PrintingSelector *parent, DeckStateManager *deckStateManager);
|
||||
|
||||
void connectSignals();
|
||||
|
||||
|
|
@ -27,6 +27,7 @@ public slots:
|
|||
|
||||
private:
|
||||
PrintingSelector *parent;
|
||||
DeckStateManager *deckStateManager;
|
||||
QHBoxLayout *cardSelectionBarLayout;
|
||||
QPushButton *previousCardButton;
|
||||
QPushButton *selectSetForCardsButton;
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ QList<PrintingInfo> PrintingSelectorCardSortingWidget::prependPinnedPrintings(co
|
|||
*/
|
||||
QList<PrintingInfo> PrintingSelectorCardSortingWidget::prependPrintingsInDeck(const QList<PrintingInfo> &printings,
|
||||
const CardInfoPtr &selectedCard,
|
||||
DeckListModel *deckModel)
|
||||
const DeckListModel *deckModel)
|
||||
{
|
||||
if (!selectedCard) {
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public:
|
|||
QList<PrintingInfo> prependPinnedPrintings(const QList<PrintingInfo> &printings, const QString &cardName);
|
||||
QList<PrintingInfo> prependPrintingsInDeck(const QList<PrintingInfo> &printings,
|
||||
const CardInfoPtr &selectedCard,
|
||||
DeckListModel *deckModel);
|
||||
const DeckListModel *deckModel);
|
||||
|
||||
public slots:
|
||||
void updateSortOrder();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../client/network/interfaces/deck_stats_interface.h"
|
||||
#include "../client/network/interfaces/tapped_out_interface.h"
|
||||
#include "../deck_editor/deck_state_manager.h"
|
||||
#include "../interface/card_picture_loader/card_picture_loader.h"
|
||||
#include "../interface/pixel_map_generator.h"
|
||||
#include "../interface/widgets/dialogs/dlg_load_deck.h"
|
||||
|
|
@ -52,7 +53,7 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
|||
{
|
||||
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||
|
||||
historyManager = new DeckListHistoryManager(this);
|
||||
deckStateManager = new DeckStateManager(this);
|
||||
|
||||
databaseDisplayDockWidget = new DeckEditorDatabaseDisplayWidget(this);
|
||||
deckDockWidget = new DeckEditorDeckDockWidget(this);
|
||||
|
|
@ -64,14 +65,8 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
|||
});
|
||||
|
||||
// Connect deck signals to this tab
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckChanged, this, &AbstractTabDeckEditor::onDeckChanged);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckModified, this, &AbstractTabDeckEditor::onDeckModified);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::requestDeckHistorySave, this,
|
||||
&AbstractTabDeckEditor::onDeckHistorySaveRequested);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::requestDeckHistoryClear, this,
|
||||
&AbstractTabDeckEditor::onDeckHistoryClearRequested);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::cardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||
connect(this, &AbstractTabDeckEditor::decrementCard, deckDockWidget, &DeckEditorDeckDockWidget::actDecrementCard);
|
||||
connect(deckStateManager, &DeckStateManager::isModifiedChanged, this, &AbstractTabDeckEditor::onDeckModified);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::selectedCardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||
|
||||
// Connect database display signals to this tab
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
||||
|
|
@ -107,7 +102,6 @@ void AbstractTabDeckEditor::updateCard(const ExactCard &card)
|
|||
/** @brief Placeholder: called when the deck changes. */
|
||||
void AbstractTabDeckEditor::onDeckChanged()
|
||||
{
|
||||
historyManager->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,24 +109,8 @@ void AbstractTabDeckEditor::onDeckChanged()
|
|||
*/
|
||||
void AbstractTabDeckEditor::onDeckModified()
|
||||
{
|
||||
setModified(!isBlankNewDeck());
|
||||
deckMenu->setSaveStatus(!isBlankNewDeck());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the tab as modified and updates the save menu status.
|
||||
*/
|
||||
void AbstractTabDeckEditor::onDeckHistorySaveRequested(const QString &modificationReason)
|
||||
{
|
||||
historyManager->save(deckDockWidget->getDeckList().createMemento(modificationReason));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the tab as modified and updates the save menu status.
|
||||
*/
|
||||
void AbstractTabDeckEditor::onDeckHistoryClearRequested()
|
||||
{
|
||||
historyManager->clear();
|
||||
deckMenu->setSaveStatus(!deckStateManager->isBlankNewDeck());
|
||||
emit tabTextChanged(this, getTabText());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -142,7 +120,7 @@ void AbstractTabDeckEditor::onDeckHistoryClearRequested()
|
|||
*/
|
||||
void AbstractTabDeckEditor::addCardHelper(const ExactCard &card, const QString &zoneName)
|
||||
{
|
||||
deckDockWidget->actAddCard(card, zoneName);
|
||||
deckStateManager->addCard(card, zoneName);
|
||||
|
||||
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
|
||||
}
|
||||
|
|
@ -170,13 +148,13 @@ void AbstractTabDeckEditor::actAddCardToSideboard(const ExactCard &card)
|
|||
/** @brief Decrements a card from the main deck. */
|
||||
void AbstractTabDeckEditor::actDecrementCard(const ExactCard &card)
|
||||
{
|
||||
emit decrementCard(card, DECK_ZONE_MAIN);
|
||||
deckStateManager->decrementCard(card, DECK_ZONE_MAIN);
|
||||
}
|
||||
|
||||
/** @brief Decrements a card from the sideboard. */
|
||||
void AbstractTabDeckEditor::actDecrementCardFromSideboard(const ExactCard &card)
|
||||
{
|
||||
emit decrementCard(card, DECK_ZONE_SIDE);
|
||||
deckStateManager->decrementCard(card, DECK_ZONE_SIDE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,45 +176,13 @@ void AbstractTabDeckEditor::openDeck(const LoadedDeck &deck)
|
|||
*/
|
||||
void AbstractTabDeckEditor::setDeck(const LoadedDeck &_deck)
|
||||
{
|
||||
deckDockWidget->setDeck(_deck);
|
||||
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList().getCardRefList()));
|
||||
setModified(false);
|
||||
deckStateManager->replaceDeck(_deck);
|
||||
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(_deck.deckList.getCardRefList()));
|
||||
|
||||
aDeckDockVisible->setChecked(true);
|
||||
deckDockWidget->setVisible(aDeckDockVisible->isChecked());
|
||||
}
|
||||
|
||||
/** @brief Returns the currently loaded deck. */
|
||||
DeckLoader *AbstractTabDeckEditor::getDeckLoader() const
|
||||
{
|
||||
return deckDockWidget->getDeckLoader();
|
||||
}
|
||||
|
||||
/** @brief Returns the currently loaded deck list. */
|
||||
const DeckList &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;
|
||||
emit tabTextChanged(this, getTabText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the tab is a blank newly created deck.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||
{
|
||||
const LoadedDeck &loadedDeck = deckDockWidget->getDeckLoader()->getDeck();
|
||||
return !modified && loadedDeck.isEmpty();
|
||||
}
|
||||
|
||||
/** @brief Creates a new deck. Handles opening in new tab if needed. */
|
||||
void AbstractTabDeckEditor::actNewDeck()
|
||||
{
|
||||
|
|
@ -255,9 +201,8 @@ void AbstractTabDeckEditor::actNewDeck()
|
|||
/** @brief Clears the current deck and resets modified flag. */
|
||||
void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
||||
{
|
||||
deckStateManager->clearDeck();
|
||||
deckMenu->setSaveStatus(false);
|
||||
deckDockWidget->cleanDeck();
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -268,13 +213,13 @@ void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
|||
AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const bool openInSameTabIfBlank)
|
||||
{
|
||||
if (SettingsCache::instance().getOpenDeckInNewTab()) {
|
||||
if (openInSameTabIfBlank && isBlankNewDeck())
|
||||
if (openInSameTabIfBlank && deckStateManager->isBlankNewDeck())
|
||||
return SAME_TAB;
|
||||
else
|
||||
return NEW_TAB;
|
||||
}
|
||||
|
||||
if (!modified)
|
||||
if (!deckStateManager->isModified())
|
||||
return SAME_TAB;
|
||||
|
||||
tabSupervisor->setCurrentWidget(this);
|
||||
|
|
@ -325,7 +270,6 @@ void AbstractTabDeckEditor::actLoadDeck()
|
|||
|
||||
QString fileName = dialog.selectedFiles().at(0);
|
||||
openDeckFromFile(fileName, deckOpenLocation);
|
||||
deckDockWidget->updateBannerCardComboBox();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -371,7 +315,7 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
|
|||
*/
|
||||
bool AbstractTabDeckEditor::actSaveDeck()
|
||||
{
|
||||
const LoadedDeck &loadedDeck = getDeckLoader()->getDeck();
|
||||
const auto loadedDeck = deckStateManager->toLoadedDeck();
|
||||
if (loadedDeck.lastLoadInfo.remoteDeckId != LoadedDeck::LoadInfo::NON_REMOTE_ID) {
|
||||
QString deckString = loadedDeck.deckList.writeToString_Native();
|
||||
if (deckString.length() > MAX_FILE_LENGTH) {
|
||||
|
|
@ -392,8 +336,10 @@ bool AbstractTabDeckEditor::actSaveDeck()
|
|||
if (loadedDeck.lastLoadInfo.fileName.isEmpty())
|
||||
return actSaveDeckAs();
|
||||
|
||||
if (getDeckLoader()->saveToFile(loadedDeck.lastLoadInfo.fileName, loadedDeck.lastLoadInfo.fileFormat)) {
|
||||
setModified(false);
|
||||
auto deckLoader = DeckLoader(this);
|
||||
deckLoader.setDeck(loadedDeck);
|
||||
if (deckLoader.saveToFile(loadedDeck.lastLoadInfo.fileName, loadedDeck.lastLoadInfo.fileFormat)) {
|
||||
deckStateManager->setModified(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -409,12 +355,14 @@ bool AbstractTabDeckEditor::actSaveDeck()
|
|||
*/
|
||||
bool AbstractTabDeckEditor::actSaveDeckAs()
|
||||
{
|
||||
LoadedDeck loadedDeck = deckStateManager->toLoadedDeck();
|
||||
|
||||
QFileDialog dialog(this, tr("Save deck"));
|
||||
dialog.setDirectory(SettingsCache::instance().getDeckPath());
|
||||
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
dialog.setDefaultSuffix("cod");
|
||||
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
|
||||
dialog.selectFile(getDeckList().getName().trimmed());
|
||||
dialog.selectFile(loadedDeck.deckList.getName().trimmed());
|
||||
|
||||
if (!dialog.exec())
|
||||
return false;
|
||||
|
|
@ -422,14 +370,18 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
|||
QString fileName = dialog.selectedFiles().at(0);
|
||||
DeckFileFormat::Format fmt = DeckFileFormat::getFormatFromName(fileName);
|
||||
|
||||
if (!getDeckLoader()->saveToFile(fileName, fmt)) {
|
||||
DeckLoader deckLoader = DeckLoader(this);
|
||||
deckLoader.setDeck(loadedDeck);
|
||||
if (!deckLoader.saveToFile(fileName, fmt)) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
deckStateManager->setLastLoadInfo({.fileName = fileName, .fileFormat = fmt});
|
||||
|
||||
deckStateManager->setModified(false);
|
||||
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -443,7 +395,7 @@ void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
|||
if (response.response_code() != Response::RespOk)
|
||||
QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved."));
|
||||
else
|
||||
setModified(false);
|
||||
deckStateManager->setModified(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -464,7 +416,7 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
|||
emit openDeckEditor({.deckList = dlg.getDeckList()});
|
||||
} else {
|
||||
setDeck({.deckList = dlg.getDeckList()});
|
||||
setModified(true);
|
||||
deckStateManager->setModified(true);
|
||||
}
|
||||
|
||||
deckMenu->setSaveStatus(true);
|
||||
|
|
@ -476,12 +428,13 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
|||
*/
|
||||
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
||||
{
|
||||
DlgEditDeckInClipboard dlg(getDeckLoader()->getDeck().deckList, annotated, this);
|
||||
LoadedDeck loadedDeck = deckStateManager->toLoadedDeck();
|
||||
DlgEditDeckInClipboard dlg(loadedDeck.deckList, annotated, this);
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
setDeck({dlg.getDeckList(), getDeckLoader()->getDeck().lastLoadInfo});
|
||||
setModified(true);
|
||||
setDeck({dlg.getDeckList(), loadedDeck.lastLoadInfo});
|
||||
deckStateManager->setModified(true);
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
|
|
@ -500,25 +453,25 @@ void AbstractTabDeckEditor::actEditDeckInClipboardRaw()
|
|||
/** @brief Saves deck to clipboard with set info and annotation. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
||||
{
|
||||
DeckLoader::saveToClipboard(getDeckList(), true, true);
|
||||
DeckLoader::saveToClipboard(deckStateManager->getDeckList(), true, true);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard with annotation, without set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo()
|
||||
{
|
||||
DeckLoader::saveToClipboard(getDeckList(), true, false);
|
||||
DeckLoader::saveToClipboard(deckStateManager->getDeckList(), true, false);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard without annotations, with set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
||||
{
|
||||
DeckLoader::saveToClipboard(getDeckList(), false, true);
|
||||
DeckLoader::saveToClipboard(deckStateManager->getDeckList(), false, true);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard without annotations or set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
||||
{
|
||||
DeckLoader::saveToClipboard(getDeckList(), false, false);
|
||||
DeckLoader::saveToClipboard(deckStateManager->getDeckList(), false, false);
|
||||
}
|
||||
|
||||
/** @brief Prints the deck using a QPrintPreviewDialog. */
|
||||
|
|
@ -526,7 +479,7 @@ void AbstractTabDeckEditor::actPrintDeck()
|
|||
{
|
||||
auto *dlg = new QPrintPreviewDialog(this);
|
||||
connect(dlg, &QPrintPreviewDialog::paintRequested, this,
|
||||
[this](QPrinter *printer) { DeckLoader::printDeckList(printer, getDeckList()); });
|
||||
[this](QPrinter *printer) { DeckLoader::printDeckList(printer, deckStateManager->getDeckList()); });
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +500,7 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
|||
emit openDeckEditor({.deckList = dlg.getDeck()});
|
||||
} else {
|
||||
setDeck({.deckList = dlg.getDeck()});
|
||||
setModified(true);
|
||||
deckStateManager->setModified(true);
|
||||
}
|
||||
|
||||
deckMenu->setSaveStatus(true);
|
||||
|
|
@ -559,7 +512,7 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
|||
*/
|
||||
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
QString decklistUrlString = DeckLoader::exportDeckToDecklist(getDeckList(), website);
|
||||
QString decklistUrlString = DeckLoader::exportDeckToDecklist(deckStateManager->getDeckList(), website);
|
||||
// Check to make sure the string isn't empty.
|
||||
if (decklistUrlString.isEmpty()) {
|
||||
// Show an error if the deck is empty, and return.
|
||||
|
|
@ -592,14 +545,14 @@ void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
|||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||
{
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
interface->analyzeDeck(getDeckList());
|
||||
interface->analyzeDeck(deckStateManager->getDeckList());
|
||||
}
|
||||
|
||||
/** @brief Analyzes the deck using TappedOut. */
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||
{
|
||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
interface->analyzeDeck(getDeckList());
|
||||
interface->analyzeDeck(deckStateManager->getDeckList());
|
||||
}
|
||||
|
||||
/** @brief Applies a new filter tree to the database display. */
|
||||
|
|
@ -658,7 +611,7 @@ bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
|||
/** @brief Shows a confirmation dialog before closing. */
|
||||
bool AbstractTabDeckEditor::confirmClose()
|
||||
{
|
||||
if (modified) {
|
||||
if (deckStateManager->isModified()) {
|
||||
tabSupervisor->setCurrentWidget(this);
|
||||
int ret = createSaveConfirmationWindow()->exec();
|
||||
if (ret == QMessageBox::Save)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <libcockatrice/deck_list/deck_list_history_manager.h>
|
||||
|
||||
class DeckStateManager;
|
||||
class CardDatabaseModel;
|
||||
class CardDatabaseDisplayModel;
|
||||
|
||||
|
|
@ -117,30 +118,13 @@ public:
|
|||
*/
|
||||
void openDeck(const LoadedDeck &deck);
|
||||
|
||||
/** @brief Returns the currently active deck loader. */
|
||||
DeckLoader *getDeckLoader() const;
|
||||
|
||||
/** @brief Returns the currently active deck list. */
|
||||
const DeckList &getDeckList() const;
|
||||
|
||||
/** @brief Sets the modified state of the tab.
|
||||
* @param _windowModified Whether the tab is modified.
|
||||
*/
|
||||
void setModified(bool _windowModified);
|
||||
|
||||
DeckEditorDeckDockWidget *getDeckDockWidget() const
|
||||
{
|
||||
return deckDockWidget;
|
||||
}
|
||||
|
||||
DeckListHistoryManager *getHistoryManager() const
|
||||
{
|
||||
return historyManager;
|
||||
}
|
||||
|
||||
DeckListHistoryManager *historyManager;
|
||||
|
||||
// UI Elements
|
||||
DeckStateManager *deckStateManager;
|
||||
DeckEditorMenu *deckMenu; ///< Menu for deck operations
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget; ///< Database dock
|
||||
DeckEditorCardInfoDockWidget *cardInfoDockWidget; ///< Card info dock
|
||||
|
|
@ -155,14 +139,6 @@ public slots:
|
|||
/** @brief Called when the deck is modified. */
|
||||
virtual void onDeckModified();
|
||||
|
||||
/** @brief Called when a widget is about to modify the state of the DeckList.
|
||||
* @param modificationReason The reason for the state modification
|
||||
*/
|
||||
virtual void onDeckHistorySaveRequested(const QString &modificationReason);
|
||||
|
||||
/** @brief Called when a widget would like to clear the history. */
|
||||
virtual void onDeckHistoryClearRequested();
|
||||
|
||||
/** @brief Updates the card info panel.
|
||||
* @param card The card to display.
|
||||
*/
|
||||
|
|
@ -202,9 +178,6 @@ signals:
|
|||
/** @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:
|
||||
/** @brief Starts a new deck in this tab. */
|
||||
virtual void actNewDeck();
|
||||
|
|
@ -315,9 +288,6 @@ protected:
|
|||
*/
|
||||
QMessageBox *createSaveConfirmationWindow();
|
||||
|
||||
/** @brief Returns true if the tab is a blank newly created deck. */
|
||||
bool isBlankNewDeck() const;
|
||||
|
||||
/** @brief Helper function to add a card to a specific deck zone. */
|
||||
void addCardHelper(const ExactCard &card, const QString &zoneName);
|
||||
|
||||
|
|
@ -330,8 +300,6 @@ protected:
|
|||
QAction *aResetLayout;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
||||
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||
|
||||
bool modified = false; ///< Whether the deck/tab has unsaved changes
|
||||
};
|
||||
|
||||
#endif // TAB_GENERIC_DECK_EDITOR_H
|
||||
|
|
|
|||
|
|
@ -68,7 +68,10 @@ ArchidektApiResponseDeckDisplayWidget::ArchidektApiResponseDeckDisplayWidget(QWi
|
|||
|
||||
model = new DeckListModel(this);
|
||||
connect(model, &DeckListModel::modelReset, this, &ArchidektApiResponseDeckDisplayWidget::decklistModelReset);
|
||||
model->getDeckList()->loadFromStream_Plain(deckStream, false);
|
||||
|
||||
auto decklist = QSharedPointer<DeckList>(new DeckList);
|
||||
decklist->loadFromStream_Plain(deckStream, false);
|
||||
model->setDeckList(decklist);
|
||||
|
||||
model->forEachCard(CardNodeFunction::ResolveProviderId());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "tab_deck_editor.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../deck_editor/deck_state_manager.h"
|
||||
#include "../filters/filter_builder.h"
|
||||
#include "../interface/pixel_map_generator.h"
|
||||
#include "../interface/widgets/cards/card_info_frame_widget.h"
|
||||
|
|
@ -114,8 +115,8 @@ void TabDeckEditor::createMenus()
|
|||
*/
|
||||
QString TabDeckEditor::getTabText() const
|
||||
{
|
||||
QString result = tr("Deck: %1").arg(deckDockWidget->getSimpleDeckName());
|
||||
if (modified)
|
||||
QString result = tr("Deck: %1").arg(deckStateManager->getSimpleDeckName());
|
||||
if (deckStateManager->isModified())
|
||||
result.prepend("* ");
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "tab_deck_editor_visual.h"
|
||||
|
||||
#include "../../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_editor/deck_state_manager.h"
|
||||
#include "../../filters/filter_builder.h"
|
||||
#include "../../interface/pixel_map_generator.h"
|
||||
#include "../../interface/widgets/cards/card_info_frame_widget.h"
|
||||
|
|
@ -61,7 +62,7 @@ void TabDeckEditorVisual::createCentralFrame()
|
|||
centralFrame = new QVBoxLayout;
|
||||
centralWidget->setLayout(centralFrame);
|
||||
|
||||
tabContainer = new TabDeckEditorVisualTabWidget(centralWidget, this, deckDockWidget->deckModel,
|
||||
tabContainer = new TabDeckEditorVisualTabWidget(centralWidget, this, deckStateManager->getModel(),
|
||||
databaseDisplayDockWidget->databaseModel,
|
||||
databaseDisplayDockWidget->databaseDisplayModel);
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ void TabDeckEditorVisual::onDeckChanged()
|
|||
AbstractTabDeckEditor::onDeckModified();
|
||||
tabContainer->visualDeckView->constructZoneWidgetsFromDeckListModel();
|
||||
tabContainer->deckAnalytics->refreshDisplays();
|
||||
tabContainer->sampleHandWidget->setDeckModel(deckDockWidget->deckModel);
|
||||
tabContainer->sampleHandWidget->setDeckModel(deckStateManager->getModel());
|
||||
}
|
||||
|
||||
/** @brief Creates menus for deck editing and view options, including dock actions. */
|
||||
|
|
@ -149,8 +150,8 @@ void TabDeckEditorVisual::createMenus()
|
|||
/** @brief Returns the tab text, prepending a mark if the deck has unsaved changes. */
|
||||
QString TabDeckEditorVisual::getTabText() const
|
||||
{
|
||||
QString result = tr("Visual Deck: %1").arg(deckDockWidget->getSimpleDeckName());
|
||||
if (modified)
|
||||
QString result = tr("Visual Deck: %1").arg(deckStateManager->getSimpleDeckName());
|
||||
if (deckStateManager->isModified())
|
||||
result.prepend("* ");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -166,9 +167,9 @@ void TabDeckEditorVisual::changeModelIndexAndCardInfo(const ExactCard &activeCar
|
|||
void TabDeckEditorVisual::changeModelIndexToCard(const ExactCard &activeCard)
|
||||
{
|
||||
QString cardName = activeCard.getName();
|
||||
QModelIndex index = deckDockWidget->deckModel->findCard(cardName, DECK_ZONE_MAIN);
|
||||
QModelIndex index = deckStateManager->getModel()->findCard(cardName, DECK_ZONE_MAIN);
|
||||
if (!index.isValid()) {
|
||||
index = deckDockWidget->deckModel->findCard(cardName, DECK_ZONE_SIDE);
|
||||
index = deckStateManager->getModel()->findCard(cardName, DECK_ZONE_SIDE);
|
||||
}
|
||||
if (!deckDockWidget->getSelectionModel()->hasSelection()) {
|
||||
deckDockWidget->getSelectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
|
|
@ -182,7 +183,7 @@ void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event,
|
|||
auto card = instance->getCard();
|
||||
|
||||
// Get the model index for the card
|
||||
QModelIndex idx = deckDockWidget->deckModel->findCard(card.getName(), zoneName);
|
||||
QModelIndex idx = deckStateManager->getModel()->findCard(card.getName(), zoneName);
|
||||
if (!idx.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -191,8 +192,8 @@ void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event,
|
|||
|
||||
// Double click = swap
|
||||
if (event->type() == QEvent::MouseButtonDblClick && event->button() == Qt::LeftButton) {
|
||||
deckDockWidget->actSwapCard(card, zoneName);
|
||||
idx = deckDockWidget->deckModel->findCard(card.getName(), zoneName);
|
||||
deckStateManager->swapCardAtIndex(idx);
|
||||
idx = deckStateManager->getModel()->findCard(card.getName(), zoneName);
|
||||
sel->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../../../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h"
|
||||
#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h"
|
||||
#include "../deck_editor/deck_state_manager.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
|
|
@ -60,7 +61,7 @@ void VisualDatabaseDisplayNameFilterWidget::retranslateUi()
|
|||
|
||||
void VisualDatabaseDisplayNameFilterWidget::actLoadFromDeck()
|
||||
{
|
||||
DeckListModel *deckListModel = deckEditor->deckDockWidget->deckModel;
|
||||
DeckListModel *deckListModel = deckEditor->deckStateManager->getModel();
|
||||
|
||||
if (!deckListModel)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -5,14 +5,15 @@
|
|||
DeckListModel::DeckListModel(QObject *parent)
|
||||
: QAbstractItemModel(parent), lastKnownColumn(1), lastKnownOrder(Qt::AscendingOrder)
|
||||
{
|
||||
// This class will leak the decklist object. We cannot safely delete it in the dtor because the deckList field is a
|
||||
// non-owning pointer and another deckList might have been assigned to it.
|
||||
// `DeckListModel::cleanList` also leaks for the same reason.
|
||||
// TODO: fix the leak
|
||||
deckList = new DeckList;
|
||||
deckList = QSharedPointer<DeckList>(new DeckList());
|
||||
root = new InnerDecklistNode;
|
||||
}
|
||||
|
||||
DeckListModel::DeckListModel(QObject *parent, const QSharedPointer<DeckList> &deckList) : DeckListModel(parent)
|
||||
{
|
||||
setDeckList(deckList);
|
||||
}
|
||||
|
||||
DeckListModel::~DeckListModel()
|
||||
{
|
||||
delete root;
|
||||
|
|
@ -586,13 +587,13 @@ void DeckListModel::setActiveFormat(const QString &_format)
|
|||
|
||||
void DeckListModel::cleanList()
|
||||
{
|
||||
setDeckList(new DeckList);
|
||||
setDeckList(QSharedPointer<DeckList>(new DeckList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _deck The deck.
|
||||
*/
|
||||
void DeckListModel::setDeckList(DeckList *_deck)
|
||||
void DeckListModel::setDeckList(const QSharedPointer<DeckList> &_deck)
|
||||
{
|
||||
if (deckList != _deck) {
|
||||
deckList = _deck;
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ signals:
|
|||
|
||||
public:
|
||||
explicit DeckListModel(QObject *parent = nullptr);
|
||||
explicit DeckListModel(QObject *parent, const QSharedPointer<DeckList> &deckList);
|
||||
~DeckListModel() override;
|
||||
|
||||
/**
|
||||
|
|
@ -314,11 +315,12 @@ public:
|
|||
* @brief Removes all cards and resets the model.
|
||||
*/
|
||||
void cleanList();
|
||||
[[nodiscard]] DeckList *getDeckList() const
|
||||
|
||||
[[nodiscard]] QSharedPointer<DeckList> getDeckList() const
|
||||
{
|
||||
return deckList;
|
||||
}
|
||||
void setDeckList(DeckList *_deck);
|
||||
void setDeckList(const QSharedPointer<DeckList> &_deck);
|
||||
|
||||
/**
|
||||
* @brief Apply a function to every card in the deck tree.
|
||||
|
|
@ -351,8 +353,8 @@ public:
|
|||
[[nodiscard]] QList<QString> getZones() const;
|
||||
|
||||
private:
|
||||
DeckList *deckList; /**< Pointer to the deck loader providing the underlying data. */
|
||||
InnerDecklistNode *root; /**< Root node of the model tree. */
|
||||
QSharedPointer<DeckList> deckList; /**< Pointer to the decklist providing the underlying data. */
|
||||
InnerDecklistNode *root; /**< Root node of the model tree. */
|
||||
DeckListModelGroupCriteria::Type activeGroupCriteria = DeckListModelGroupCriteria::MAIN_TYPE;
|
||||
int lastKnownColumn; /**< Last column used for sorting. */
|
||||
Qt::SortOrder lastKnownOrder; /**< Last known sort order. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue