A DeckLoader is not a DeckList. (#6306)

* A DeckLoader is not a DeckList.

Took 2 hours 39 minutes

* Explicitly initialize base class in copy constructor?

Took 3 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2025-11-12 02:16:44 +01:00 committed by GitHub
parent 4c431e98a6
commit 8e88749078
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 163 additions and 139 deletions

View file

@ -24,13 +24,13 @@ class ArchidektJsonParser : public IJsonDeckParser
public: public:
DeckLoader *parse(const QJsonObject &obj) override DeckLoader *parse(const QJsonObject &obj) override
{ {
DeckLoader *list = new DeckLoader(); DeckLoader *loader = new DeckLoader(nullptr);
QString deckName = obj.value("name").toString(); QString deckName = obj.value("name").toString();
QString deckDescription = obj.value("description").toString(); QString deckDescription = obj.value("description").toString();
list->setName(deckName); loader->getDeckList()->setName(deckName);
list->setComments(deckDescription); loader->getDeckList()->setComments(deckDescription);
QString outputText; QString outputText;
QTextStream outStream(&outputText); QTextStream outStream(&outputText);
@ -47,10 +47,10 @@ public:
outStream << quantity << ' ' << cardName << " (" << setName << ") " << collectorNumber << '\n'; outStream << quantity << ' ' << cardName << " (" << setName << ") " << collectorNumber << '\n';
} }
list->loadFromStream_Plain(outStream, false); loader->getDeckList()->loadFromStream_Plain(outStream, false);
list->resolveSetNameAndNumberToProviderID(); loader->resolveSetNameAndNumberToProviderID();
return list; return loader;
} }
}; };
@ -59,13 +59,13 @@ class MoxfieldJsonParser : public IJsonDeckParser
public: public:
DeckLoader *parse(const QJsonObject &obj) override DeckLoader *parse(const QJsonObject &obj) override
{ {
DeckLoader *list = new DeckLoader(); DeckLoader *loader = new DeckLoader(nullptr);
QString deckName = obj.value("name").toString(); QString deckName = obj.value("name").toString();
QString deckDescription = obj.value("description").toString(); QString deckDescription = obj.value("description").toString();
list->setName(deckName); loader->getDeckList()->setName(deckName);
list->setComments(deckDescription); loader->getDeckList()->setComments(deckDescription);
QString outputText; QString outputText;
QTextStream outStream(&outputText); QTextStream outStream(&outputText);
@ -94,8 +94,8 @@ public:
outStream << quantity << ' ' << cardName << " (" << setName << ") " << collectorNumber << '\n'; outStream << quantity << ' ' << cardName << " (" << setName << ") " << collectorNumber << '\n';
} }
list->loadFromStream_Plain(outStream, false); loader->getDeckList()->loadFromStream_Plain(outStream, false);
list->resolveSetNameAndNumberToProviderID(); loader->resolveSetNameAndNumberToProviderID();
QJsonObject commandersObj = obj.value("commanders").toObject(); QJsonObject commandersObj = obj.value("commanders").toObject();
if (!commandersObj.isEmpty()) { if (!commandersObj.isEmpty()) {
@ -106,12 +106,12 @@ public:
QString collectorNumber = cardData.value("cn").toString(); QString collectorNumber = cardData.value("cn").toString();
QString providerId = cardData.value("scryfall_id").toString(); QString providerId = cardData.value("scryfall_id").toString();
list->setBannerCard({commanderName, providerId}); loader->getDeckList()->setBannerCard({commanderName, providerId});
list->addCard(commanderName, DECK_ZONE_MAIN, -1, setName, collectorNumber, providerId); loader->getDeckList()->addCard(commanderName, DECK_ZONE_MAIN, -1, setName, collectorNumber, providerId);
} }
} }
return list; return loader;
} }
}; };

View file

@ -117,7 +117,7 @@ static void setupParserRules()
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) -> bool { return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) -> bool {
int count = 0; int count = 0;
deck->deckLoader->forEachCard([&](InnerDecklistNode *, const DecklistCardNode *node) { deck->deckLoader->getDeckList()->forEachCard([&](InnerDecklistNode *, const DecklistCardNode *node) {
auto cardInfoPtr = CardDatabaseManager::query()->getCardInfo(node->getName()); auto cardInfoPtr = CardDatabaseManager::query()->getCardInfo(node->getName());
if (!cardInfoPtr.isNull() && cardFilter.check(cardInfoPtr)) { if (!cardInfoPtr.isNull() && cardFilter.check(cardInfoPtr)) {
count += node->getNumber(); count += node->getNumber();
@ -136,7 +136,7 @@ static void setupParserRules()
search["DeckNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter { search["DeckNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
auto name = std::any_cast<QString>(sv[0]); auto name = std::any_cast<QString>(sv[0]);
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) { return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
return deck->deckLoader->getName().contains(name, Qt::CaseInsensitive); return deck->deckLoader->getDeckList()->getName().contains(name, Qt::CaseInsensitive);
}; };
}; };

View file

@ -264,7 +264,7 @@ void DeckViewContainer::loadLocalDeck()
void DeckViewContainer::loadDeckFromFile(const QString &filePath) void DeckViewContainer::loadDeckFromFile(const QString &filePath)
{ {
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(filePath); DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(filePath);
DeckLoader deck; DeckLoader deck(this);
bool success = deck.loadFromFile(filePath, fmt, true); bool success = deck.loadFromFile(filePath, fmt, true);
@ -276,9 +276,9 @@ void DeckViewContainer::loadDeckFromFile(const QString &filePath)
loadDeckFromDeckLoader(&deck); loadDeckFromDeckLoader(&deck);
} }
void DeckViewContainer::loadDeckFromDeckLoader(const DeckLoader *deck) void DeckViewContainer::loadDeckFromDeckLoader(DeckLoader *deck)
{ {
QString deckString = deck->writeToString_Native(); QString deckString = deck->getDeckList()->writeToString_Native();
if (deckString.length() > MAX_FILE_LENGTH) { if (deckString.length() > MAX_FILE_LENGTH) {
QMessageBox::critical(this, tr("Error"), tr("Deck is greater than maximum file size.")); QMessageBox::critical(this, tr("Error"), tr("Deck is greater than maximum file size."));
@ -331,8 +331,9 @@ void DeckViewContainer::loadFromWebsite()
void DeckViewContainer::deckSelectFinished(const Response &r) void DeckViewContainer::deckSelectFinished(const Response &r)
{ {
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext); const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
DeckLoader newDeck(QString::fromStdString(resp.deck())); DeckLoader newDeck(this, new DeckList(QString::fromStdString(resp.deck())));
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(newDeck.getCardRefList())); CardPictureLoader::cacheCardPixmaps(
CardDatabaseManager::query()->getCards(newDeck.getDeckList()->getCardRefList()));
setDeck(newDeck); setDeck(newDeck);
switchToDeckLoadedView(); switchToDeckLoadedView();
} }
@ -413,8 +414,8 @@ void DeckViewContainer::setSideboardLocked(bool locked)
deckView->resetSideboardPlan(); deckView->resetSideboardPlan();
} }
void DeckViewContainer::setDeck(const DeckLoader &deck) void DeckViewContainer::setDeck(DeckLoader &deck)
{ {
deckView->setDeck(deck); deckView->setDeck(*deck.getDeckList());
switchToDeckLoadedView(); switchToDeckLoadedView();
} }

View file

@ -85,12 +85,12 @@ public:
void setReadyStart(bool ready); void setReadyStart(bool ready);
void readyAndUpdate(); void readyAndUpdate();
void setSideboardLocked(bool locked); void setSideboardLocked(bool locked);
void setDeck(const DeckLoader &deck); void setDeck(DeckLoader &deck);
void setVisualDeckStorageExists(bool exists); void setVisualDeckStorageExists(bool exists);
public slots: public slots:
void loadDeckFromFile(const QString &filePath); void loadDeckFromFile(const QString &filePath);
void loadDeckFromDeckLoader(const DeckLoader *deck); void loadDeckFromDeckLoader(DeckLoader *deck);
}; };
#endif // DECK_VIEW_CONTAINER_H #endif // DECK_VIEW_CONTAINER_H

View file

@ -62,7 +62,8 @@ void UtilityMenu::populatePredefinedTokensMenu()
return; return;
} }
InnerDecklistNode *tokenZone = dynamic_cast<InnerDecklistNode *>(_deck->getRoot()->findChild(DECK_ZONE_TOKENS)); InnerDecklistNode *tokenZone =
dynamic_cast<InnerDecklistNode *>(_deck->getDeckList()->getRoot()->findChild(DECK_ZONE_TOKENS));
if (tokenZone) { if (tokenZone) {
if (!tokenZone->empty()) if (!tokenZone->empty())

View file

@ -66,7 +66,7 @@ class Player : public QObject
Q_OBJECT Q_OBJECT
signals: signals:
void openDeckEditor(const DeckLoader *deck); void openDeckEditor(DeckLoader *deck);
void deckChanged(); void deckChanged();
void newCardAdded(AbstractCardItem *card); void newCardAdded(AbstractCardItem *card);
void rearrangeCounters(); void rearrangeCounters();

View file

@ -25,26 +25,27 @@ const QStringList DeckLoader::ACCEPTED_FILE_EXTENSIONS = {"*.cod", "*.dec", "*.d
const QStringList DeckLoader::FILE_NAME_FILTERS = { const QStringList DeckLoader::FILE_NAME_FILTERS = {
tr("Common deck formats (%1)").arg(ACCEPTED_FILE_EXTENSIONS.join(" ")), tr("All files (*.*)")}; tr("Common deck formats (%1)").arg(ACCEPTED_FILE_EXTENSIONS.join(" ")), tr("All files (*.*)")};
DeckLoader::DeckLoader() : DeckList(), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1) DeckLoader::DeckLoader(QObject *parent)
: QObject(parent), deckList(new DeckList()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
{ {
} }
DeckLoader::DeckLoader(const QString &nativeString) DeckLoader::DeckLoader(QObject *parent, DeckList *_deckList)
: DeckList(nativeString), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1) : QObject(parent), deckList(_deckList), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
{
}
DeckLoader::DeckLoader(const DeckList &other)
: DeckList(other), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
{ {
} }
DeckLoader::DeckLoader(const DeckLoader &other) DeckLoader::DeckLoader(const DeckLoader &other)
: DeckList(other), lastFileName(other.lastFileName), lastFileFormat(other.lastFileFormat), : QObject(), deckList(other.deckList), lastFileName(other.lastFileName), lastFileFormat(other.lastFileFormat),
lastRemoteDeckId(other.lastRemoteDeckId) lastRemoteDeckId(other.lastRemoteDeckId)
{ {
} }
void DeckLoader::setDeckList(DeckList *_deckList)
{
deckList = _deckList;
}
bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest) bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest)
{ {
QFile file(fileName); QFile file(fileName);
@ -55,15 +56,15 @@ bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool user
bool result = false; bool result = false;
switch (fmt) { switch (fmt) {
case PlainTextFormat: case PlainTextFormat:
result = loadFromFile_Plain(&file); result = deckList->loadFromFile_Plain(&file);
break; break;
case CockatriceFormat: { case CockatriceFormat: {
result = loadFromFile_Native(&file); result = deckList->loadFromFile_Native(&file);
qCInfo(DeckLoaderLog) << "Loaded from" << fileName << "-" << result; qCInfo(DeckLoaderLog) << "Loaded from" << fileName << "-" << result;
if (!result) { if (!result) {
qCInfo(DeckLoaderLog) << "Retrying as plain format"; qCInfo(DeckLoaderLog) << "Retrying as plain format";
file.seek(0); file.seek(0);
result = loadFromFile_Plain(&file); result = deckList->loadFromFile_Plain(&file);
fmt = PlainTextFormat; fmt = PlainTextFormat;
} }
break; break;
@ -115,13 +116,13 @@ bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool
switch (fmt) { switch (fmt) {
case PlainTextFormat: case PlainTextFormat:
return loadFromFile_Plain(&file); return deckList->loadFromFile_Plain(&file);
case CockatriceFormat: { case CockatriceFormat: {
bool result = false; bool result = false;
result = loadFromFile_Native(&file); result = deckList->loadFromFile_Native(&file);
if (!result) { if (!result) {
file.seek(0); file.seek(0);
return loadFromFile_Plain(&file); return deckList->loadFromFile_Plain(&file);
} }
return result; return result;
} }
@ -137,7 +138,7 @@ bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool
bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId) bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
{ {
bool result = loadFromString_Native(nativeString); bool result = deckList->loadFromString_Native(nativeString);
if (result) { if (result) {
lastFileName = QString(); lastFileName = QString();
lastFileFormat = CockatriceFormat; lastFileFormat = CockatriceFormat;
@ -158,10 +159,10 @@ bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
bool result = false; bool result = false;
switch (fmt) { switch (fmt) {
case PlainTextFormat: case PlainTextFormat:
result = saveToFile_Plain(&file); result = deckList->saveToFile_Plain(&file);
break; break;
case CockatriceFormat: case CockatriceFormat:
result = saveToFile_Native(&file); result = deckList->saveToFile_Native(&file);
break; break;
} }
@ -198,11 +199,11 @@ bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, FileFormat f
// Perform file modifications // Perform file modifications
switch (fmt) { switch (fmt) {
case PlainTextFormat: case PlainTextFormat:
result = saveToFile_Plain(&file); result = deckList->saveToFile_Plain(&file);
break; break;
case CockatriceFormat: case CockatriceFormat:
setLastLoadedTimestamp(QDateTime::currentDateTime().toString()); deckList->setLastLoadedTimestamp(QDateTime::currentDateTime().toString());
result = saveToFile_Native(&file); result = deckList->saveToFile_Native(&file);
break; break;
} }
@ -301,7 +302,7 @@ QString DeckLoader::exportDeckToDecklist(DecklistWebsite website)
}; };
// call our struct function for each card in the deck // call our struct function for each card in the deck
forEachCard(formatDeckListForExport); deckList->forEachCard(formatDeckListForExport);
// Remove the extra return at the end of the last cards // Remove the extra return at the end of the last cards
mainBoardCards.chop(3); mainBoardCards.chop(3);
sideBoardCards.chop(3); sideBoardCards.chop(3);
@ -349,7 +350,7 @@ void DeckLoader::setProviderIdToPreferredPrinting()
SetProviderIdToPreferred setProviderIdToPreferred; SetProviderIdToPreferred setProviderIdToPreferred;
// Call the forEachCard method for each card in the deck // Call the forEachCard method for each card in the deck
forEachCard(setProviderIdToPreferred); deckList->forEachCard(setProviderIdToPreferred);
} }
/** /**
@ -370,7 +371,7 @@ void DeckLoader::resolveSetNameAndNumberToProviderID()
card->setCardProviderId(providerId); card->setCardProviderId(providerId);
}; };
forEachCard(setProviderId); deckList->forEachCard(setProviderId);
} }
// This struct is here to support the forEachCard function call, defined in decklist. // This struct is here to support the forEachCard function call, defined in decklist.
@ -405,7 +406,7 @@ void DeckLoader::clearSetNamesAndNumbers()
card->setCardProviderId(nullptr); card->setCardProviderId(nullptr);
}; };
forEachCard(clearSetNameAndNumber); deckList->forEachCard(clearSetNameAndNumber);
} }
DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName) DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName)
@ -432,8 +433,8 @@ bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments, bool add
} }
// loop zones // loop zones
for (int i = 0; i < getRoot()->size(); i++) { for (int i = 0; i < deckList->getRoot()->size(); i++) {
const auto *zoneNode = dynamic_cast<InnerDecklistNode *>(getRoot()->at(i)); const auto *zoneNode = dynamic_cast<InnerDecklistNode *>(deckList->getRoot()->at(i));
saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber); saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber);
@ -446,12 +447,12 @@ bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments, bool add
void DeckLoader::saveToStream_DeckHeader(QTextStream &out) const void DeckLoader::saveToStream_DeckHeader(QTextStream &out) const
{ {
if (!getName().isEmpty()) { if (!deckList->getName().isEmpty()) {
out << "// " << getName() << "\n\n"; out << "// " << deckList->getName() << "\n\n";
} }
if (!getComments().isEmpty()) { if (!deckList->getComments().isEmpty()) {
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r")); QStringList commentRows = deckList->getComments().split(QRegularExpression("\n|\r\n|\r"));
for (const QString &row : commentRows) { for (const QString &row : commentRows) {
out << "// " << row << "\n"; out << "// " << row << "\n";
} }
@ -558,7 +559,7 @@ bool DeckLoader::convertToCockatriceFormat(QString fileName)
switch (getFormatFromName(fileName)) { switch (getFormatFromName(fileName)) {
case PlainTextFormat: case PlainTextFormat:
// Save in Cockatrice's native format // Save in Cockatrice's native format
result = saveToFile_Native(&file); result = deckList->saveToFile_Native(&file);
break; break;
case CockatriceFormat: case CockatriceFormat:
qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed."; qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed.";
@ -685,19 +686,19 @@ void DeckLoader::printDeckList(QPrinter *printer)
headerCharFormat.setFontWeight(QFont::Bold); headerCharFormat.setFontWeight(QFont::Bold);
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
cursor.insertText(getName()); cursor.insertText(deckList->getName());
headerCharFormat.setFontPointSize(12); headerCharFormat.setFontPointSize(12);
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
cursor.insertText(getComments()); cursor.insertText(deckList->getComments());
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
for (int i = 0; i < getRoot()->size(); i++) { for (int i = 0; i < deckList->getRoot()->size(); i++) {
cursor.insertHtml("<br><img src=theme:hr.jpg>"); cursor.insertHtml("<br><img src=theme:hr.jpg>");
// cursor.insertHtml("<hr>"); // cursor.insertHtml("<hr>");
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
printDeckListNode(&cursor, dynamic_cast<InnerDecklistNode *>(getRoot()->at(i))); printDeckListNode(&cursor, dynamic_cast<InnerDecklistNode *>(deckList->getRoot()->at(i)));
} }
doc.print(printer); doc.print(printer);

View file

@ -14,7 +14,7 @@
inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader") inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader")
class DeckLoader : public DeckList class DeckLoader : public QObject
{ {
Q_OBJECT Q_OBJECT
signals: signals:
@ -52,14 +52,15 @@ public:
}; };
private: private:
DeckList *deckList;
QString lastFileName; QString lastFileName;
FileFormat lastFileFormat; FileFormat lastFileFormat;
int lastRemoteDeckId; int lastRemoteDeckId;
public: public:
DeckLoader(); DeckLoader(QObject *parent);
explicit DeckLoader(const QString &nativeString); DeckLoader(QObject *parent, DeckList *_deckList);
explicit DeckLoader(const DeckList &other); void setDeckList(DeckList *_deckList);
DeckLoader(const DeckLoader &other); DeckLoader(const DeckLoader &other);
const QString &getLastFileName() const const QString &getLastFileName() const
{ {
@ -102,6 +103,11 @@ public:
bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true) const; bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true) const;
bool convertToCockatriceFormat(QString fileName); bool convertToCockatriceFormat(QString fileName);
DeckList *getDeckList()
{
return deckList;
}
private: private:
void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node); void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node);
@ -116,8 +122,8 @@ protected:
QList<DecklistCardNode *> cards, QList<DecklistCardNode *> cards,
bool addComments = true, bool addComments = true,
bool addSetNameAndNumber = true) const; bool addSetNameAndNumber = true) const;
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override; [[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName);
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override; [[nodiscard]] QString getCompleteCardName(const QString &cardName) const;
}; };
#endif #endif

View file

@ -32,6 +32,8 @@ void DeckEditorDeckDockWidget::createDeckDock()
deckModel->setObjectName("deckModel"); deckModel->setObjectName("deckModel");
connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash); connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash);
deckLoader = new DeckLoader(this, deckModel->getDeckList());
DeckListStyleProxy *proxy = new DeckListStyleProxy(this); DeckListStyleProxy *proxy = new DeckListStyleProxy(this);
proxy->setSourceModel(deckModel); proxy->setSourceModel(deckModel);
@ -373,10 +375,9 @@ void DeckEditorDeckDockWidget::syncBannerCardComboBoxSelectionWithDeck()
void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck) void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
{ {
deckLoader = _deck; deckLoader = _deck;
deckModel->setDeckList(deckLoader->getDeckList());
deckModel->setDeckList(_deck); connect(deckLoader, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree);
connect(_deck, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree); connect(deckLoader->getDeckList(), &DeckList::deckHashChanged, deckModel, &DeckListModel::deckHashChanged);
connect(_deck, &DeckLoader::deckHashChanged, deckModel, &DeckListModel::deckHashChanged);
nameEdit->setText(deckModel->getDeckList()->getName()); nameEdit->setText(deckModel->getDeckList()->getName());
commentsEdit->setText(deckModel->getDeckList()->getComments()); commentsEdit->setText(deckModel->getDeckList()->getComments());
@ -398,6 +399,11 @@ DeckLoader *DeckEditorDeckDockWidget::getDeckLoader()
return deckLoader; return deckLoader;
} }
DeckList *DeckEditorDeckDockWidget::getDeckList()
{
return deckModel->getDeckList();
}
/** /**
* Resets the tab to the state for a blank new tab. * Resets the tab to the state for a blank new tab.
*/ */

View file

@ -52,6 +52,7 @@ public slots:
void updateBannerCardComboBox(); void updateBannerCardComboBox();
void setDeck(DeckLoader *_deck); void setDeck(DeckLoader *_deck);
DeckLoader *getDeckLoader(); DeckLoader *getDeckLoader();
DeckList *getDeckList();
void actIncrement(); void actIncrement();
bool swapCard(const QModelIndex &idx); bool swapCard(const QModelIndex &idx);
void actDecrementCard(const ExactCard &card, QString zoneName); void actDecrementCard(const ExactCard &card, QString zoneName);

View file

@ -75,12 +75,12 @@ bool AbstractDlgDeckTextEdit::loadIntoDeck(DeckLoader *deckLoader) const
QString buffer = contentsEdit->toPlainText(); QString buffer = contentsEdit->toPlainText();
if (buffer.contains("<cockatrice_deck version=\"1\">")) { if (buffer.contains("<cockatrice_deck version=\"1\">")) {
return deckLoader->loadFromString_Native(buffer); return deckLoader->getDeckList()->loadFromString_Native(buffer);
} }
QTextStream stream(&buffer); QTextStream stream(&buffer);
if (deckLoader->loadFromStream_Plain(stream, true)) { if (deckLoader->getDeckList()->loadFromStream_Plain(stream, true)) {
if (loadSetNameAndNumberCheckBox->isChecked()) { if (loadSetNameAndNumberCheckBox->isChecked()) {
deckLoader->resolveSetNameAndNumberToProviderID(); deckLoader->resolveSetNameAndNumberToProviderID();
} else { } else {
@ -121,8 +121,7 @@ void DlgLoadDeckFromClipboard::actRefresh()
void DlgLoadDeckFromClipboard::actOK() void DlgLoadDeckFromClipboard::actOK()
{ {
deckList = new DeckLoader; deckList = new DeckLoader(this);
deckList->setParent(this);
if (loadIntoDeck(deckList)) { if (loadIntoDeck(deckList)) {
accept(); accept();

View file

@ -95,9 +95,9 @@ void DlgLoadDeckFromWebsite::accept()
} }
// Parse the plain text deck here // Parse the plain text deck here
DeckLoader *loader = new DeckLoader(); DeckLoader *loader = new DeckLoader(this);
QTextStream stream(&deckText); QTextStream stream(&deckText);
loader->loadFromStream_Plain(stream, false); loader->getDeckList()->loadFromStream_Plain(stream, false);
loader->resolveSetNameAndNumberToProviderID(); loader->resolveSetNameAndNumberToProviderID();
deck = loader; deck = loader;

View file

@ -19,7 +19,7 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
layout = new QGridLayout(this); layout = new QGridLayout(this);
backgroundSourceCard = new CardInfoPictureArtCropWidget(this); backgroundSourceCard = new CardInfoPictureArtCropWidget(this);
backgroundSourceDeck = new DeckLoader(); backgroundSourceDeck = new DeckLoader(this);
backgroundSourceDeck->loadFromFile(SettingsCache::instance().getDeckPath() + "background.cod", backgroundSourceDeck->loadFromFile(SettingsCache::instance().getDeckPath() + "background.cod",
DeckLoader::CockatriceFormat, false); DeckLoader::CockatriceFormat, false);
@ -94,7 +94,7 @@ void HomeWidget::updateRandomCard()
newCard.getCardPtr()->getProperty("layout") != "normal"); newCard.getCardPtr()->getProperty("layout") != "normal");
break; break;
case BackgroundSources::DeckFileArt: case BackgroundSources::DeckFileArt:
QList<CardRef> cardRefs = backgroundSourceDeck->getCardRefList(); QList<CardRef> cardRefs = backgroundSourceDeck->getDeckList()->getCardRefList();
ExactCard oldCard = backgroundSourceCard->getCard(); ExactCard oldCard = backgroundSourceCard->getCard();
if (!cardRefs.empty()) { if (!cardRefs.empty()) {

View file

@ -209,7 +209,7 @@ void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck) void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
{ {
deckDockWidget->setDeck(_deck); deckDockWidget->setDeck(_deck);
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckLoader()->getCardRefList())); CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
setModified(false); setModified(false);
aDeckDockVisible->setChecked(true); aDeckDockVisible->setChecked(true);
@ -222,6 +222,12 @@ DeckLoader *AbstractTabDeckEditor::getDeckLoader() const
return deckDockWidget->getDeckLoader(); return deckDockWidget->getDeckLoader();
} }
/** @brief Returns the currently loaded deck list. */
DeckList *AbstractTabDeckEditor::getDeckList() const
{
return deckDockWidget->getDeckList();
}
/** /**
* @brief Sets the modified state of the tab. * @brief Sets the modified state of the tab.
* @param _modified True if tab is modified, false otherwise. * @param _modified True if tab is modified, false otherwise.
@ -238,7 +244,7 @@ void AbstractTabDeckEditor::setModified(bool _modified)
bool AbstractTabDeckEditor::isBlankNewDeck() const bool AbstractTabDeckEditor::isBlankNewDeck() const
{ {
DeckLoader *deck = deckDockWidget->getDeckLoader(); DeckLoader *deck = deckDockWidget->getDeckLoader();
return !modified && deck->isBlankDeck() && deck->hasNotBeenLoaded(); return !modified && deck->getDeckList()->isBlankDeck() && deck->hasNotBeenLoaded();
} }
/** @brief Creates a new deck. Handles opening in new tab if needed. */ /** @brief Creates a new deck. Handles opening in new tab if needed. */
@ -354,7 +360,7 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
{ {
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName); DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
auto *l = new DeckLoader; auto *l = new DeckLoader(this);
if (l->loadFromFile(fileName, fmt, true)) { if (l->loadFromFile(fileName, fmt, true)) {
if (deckOpenLocation == NEW_TAB) { if (deckOpenLocation == NEW_TAB) {
emit openDeckEditor(l); emit openDeckEditor(l);
@ -379,7 +385,7 @@ bool AbstractTabDeckEditor::actSaveDeck()
{ {
DeckLoader *const deck = getDeckLoader(); DeckLoader *const deck = getDeckLoader();
if (deck->getLastRemoteDeckId() != -1) { if (deck->getLastRemoteDeckId() != -1) {
QString deckString = deck->writeToString_Native(); QString deckString = deck->getDeckList()->writeToString_Native();
if (deckString.length() > MAX_FILE_LENGTH) { if (deckString.length() > MAX_FILE_LENGTH) {
QMessageBox::critical(this, tr("Error"), tr("Could not save remote deck")); QMessageBox::critical(this, tr("Error"), tr("Could not save remote deck"));
return false; return false;
@ -418,7 +424,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setDefaultSuffix("cod"); dialog.setDefaultSuffix("cod");
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS); dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
dialog.selectFile(getDeckLoader()->getName().trimmed()); dialog.selectFile(getDeckList()->getName().trimmed());
if (!dialog.exec()) if (!dialog.exec())
return false; return false;
@ -600,14 +606,14 @@ void AbstractTabDeckEditor::actExportDeckDecklistXyz()
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats() void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
{ {
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this); auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
interface->analyzeDeck(getDeckLoader()); interface->analyzeDeck(getDeckList());
} }
/** @brief Analyzes the deck using TappedOut. */ /** @brief Analyzes the deck using TappedOut. */
void AbstractTabDeckEditor::actAnalyzeDeckTappedout() void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
{ {
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this); auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
interface->analyzeDeck(getDeckLoader()); interface->analyzeDeck(getDeckList());
} }
/** @brief Applies a new filter tree to the database display. */ /** @brief Applies a new filter tree to the database display. */

View file

@ -116,9 +116,12 @@ public:
*/ */
void openDeck(DeckLoader *deck); void openDeck(DeckLoader *deck);
/** @brief Returns the currently active deck. */ /** @brief Returns the currently active deck loader. */
DeckLoader *getDeckLoader() const; DeckLoader *getDeckLoader() const;
/** @brief Returns the currently active deck list. */
DeckList *getDeckList() const;
/** @brief Sets the modified state of the tab. /** @brief Sets the modified state of the tab.
* @param _windowModified Whether the tab is modified. * @param _windowModified Whether the tab is modified.
*/ */
@ -178,7 +181,7 @@ public slots:
signals: signals:
/** @brief Emitted when a deck should be opened in a new editor tab. */ /** @brief Emitted when a deck should be opened in a new editor tab. */
void openDeckEditor(const DeckLoader *deckLoader); void openDeckEditor(DeckLoader *deckLoader);
/** @brief Emitted before the tab is closed. */ /** @brief Emitted before the tab is closed. */
void deckEditorClosing(AbstractTabDeckEditor *tab); void deckEditorClosing(AbstractTabDeckEditor *tab);

View file

@ -15,10 +15,10 @@ void EdhrecDeckApiResponse::fromJson(const QJsonArray &json)
deckList += cardlistValue.toString() + "\n"; deckList += cardlistValue.toString() + "\n";
} }
deckLoader = new DeckLoader(); deckLoader = new DeckLoader(nullptr);
QTextStream stream(&deckList); QTextStream stream(&deckList);
deckLoader->loadFromStream_Plain(stream, true); deckLoader->getDeckList()->loadFromStream_Plain(stream, true);
} }
void EdhrecDeckApiResponse::debugPrint() const void EdhrecDeckApiResponse::debugPrint() const

View file

@ -242,7 +242,7 @@ void TabDeckStorage::actOpenLocalDeck()
continue; continue;
QString filePath = localDirModel->filePath(curLeft); QString filePath = localDirModel->filePath(curLeft);
DeckLoader deckLoader; DeckLoader deckLoader(this);
if (!deckLoader.loadFromFile(filePath, DeckLoader::CockatriceFormat, true)) if (!deckLoader.loadFromFile(filePath, DeckLoader::CockatriceFormat, true))
continue; continue;
@ -308,13 +308,13 @@ void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPa
QFile deckFile(filePath); QFile deckFile(filePath);
QFileInfo deckFileInfo(deckFile); QFileInfo deckFileInfo(deckFile);
DeckLoader deck; DeckLoader deck(this);
if (!deck.loadFromFile(filePath, DeckLoader::CockatriceFormat)) { if (!deck.loadFromFile(filePath, DeckLoader::CockatriceFormat)) {
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file")); QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
return; return;
} }
if (deck.getName().isEmpty()) { if (deck.getDeckList()->getName().isEmpty()) {
bool ok; bool ok;
QString deckName = QString deckName =
getTextWithMax(this, tr("Enter deck name"), tr("This decklist does not have a name.\nPlease enter a name:"), getTextWithMax(this, tr("Enter deck name"), tr("This decklist does not have a name.\nPlease enter a name:"),
@ -323,12 +323,12 @@ void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPa
return; return;
if (deckName.isEmpty()) if (deckName.isEmpty())
deckName = tr("Unnamed deck"); deckName = tr("Unnamed deck");
deck.setName(deckName); deck.getDeckList()->setName(deckName);
} else { } else {
deck.setName(deck.getName().left(MAX_NAME_LENGTH)); deck.getDeckList()->setName(deck.getDeckList()->getName().left(MAX_NAME_LENGTH));
} }
QString deckString = deck.writeToString_Native(); QString deckString = deck.getDeckList()->writeToString_Native();
if (deckString.length() > MAX_FILE_LENGTH) { if (deckString.length() > MAX_FILE_LENGTH) {
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file")); QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
return; return;
@ -433,7 +433,7 @@ void TabDeckStorage::openRemoteDeckFinished(const Response &r, const CommandCont
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext); const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
const Command_DeckDownload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDownload::ext); const Command_DeckDownload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDownload::ext);
DeckLoader loader; DeckLoader loader(this);
if (!loader.loadFromRemote(QString::fromStdString(resp.deck()), cmd.deck_id())) if (!loader.loadFromRemote(QString::fromStdString(resp.deck()), cmd.deck_id()))
return; return;
@ -493,7 +493,7 @@ void TabDeckStorage::downloadFinished(const Response &r,
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext); const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
QString filePath = extraData.toString(); QString filePath = extraData.toString();
DeckLoader deck(QString::fromStdString(resp.deck())); DeckLoader deck(this, new DeckList(QString::fromStdString(resp.deck())));
deck.saveToFile(filePath, DeckLoader::CockatriceFormat); deck.saveToFile(filePath, DeckLoader::CockatriceFormat);
} }

View file

@ -87,7 +87,7 @@ public:
return tr("Deck Storage"); return tr("Deck Storage");
} }
signals: signals:
void openDeckEditor(const DeckLoader *deckLoader); void openDeckEditor(DeckLoader *deckLoader);
}; };
#endif #endif

View file

@ -754,8 +754,9 @@ void TabGame::loadDeckForLocalPlayer(Player *localPlayer, int playerId, ServerIn
{ {
TabbedDeckViewContainer *deckViewContainer = deckViewContainers.value(playerId); TabbedDeckViewContainer *deckViewContainer = deckViewContainers.value(playerId);
if (playerInfo.has_deck_list()) { if (playerInfo.has_deck_list()) {
DeckLoader newDeck(QString::fromStdString(playerInfo.deck_list())); DeckLoader newDeck(this, new DeckList(QString::fromStdString(playerInfo.deck_list())));
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(newDeck.getCardRefList())); CardPictureLoader::cacheCardPixmaps(
CardDatabaseManager::query()->getCards(newDeck.getDeckList()->getCardRefList()));
deckViewContainer->playerDeckView->setDeck(newDeck); deckViewContainer->playerDeckView->setDeck(newDeck);
localPlayer->setDeck(newDeck); localPlayer->setDeck(newDeck);
} }

View file

@ -121,7 +121,7 @@ signals:
void containerProcessingStarted(const GameEventContext &context); void containerProcessingStarted(const GameEventContext &context);
void containerProcessingDone(); void containerProcessingDone();
void openMessageDialog(const QString &userName, bool focus); void openMessageDialog(const QString &userName, bool focus);
void openDeckEditor(const DeckLoader *deck); void openDeckEditor(DeckLoader *deck);
void notIdle(); void notIdle();
void phaseChanged(int phase); void phaseChanged(int phase);

View file

@ -843,7 +843,7 @@ void TabSupervisor::talkLeft(TabMessage *tab)
* Creates either a classic or visual deck editor tab depending on settings * Creates either a classic or visual deck editor tab depending on settings
* @param deckToOpen The deck to open in the tab. Creates a copy of the DeckLoader instance. * @param deckToOpen The deck to open in the tab. Creates a copy of the DeckLoader instance.
*/ */
void TabSupervisor::openDeckInNewTab(const DeckLoader *deckToOpen) void TabSupervisor::openDeckInNewTab(DeckLoader *deckToOpen)
{ {
int type = SettingsCache::instance().getDefaultDeckEditorType(); int type = SettingsCache::instance().getDefaultDeckEditorType();
switch (type) { switch (type) {
@ -865,11 +865,11 @@ void TabSupervisor::openDeckInNewTab(const DeckLoader *deckToOpen)
* Creates a new deck editor tab * Creates a new deck editor tab
* @param deckToOpen The deck to open in the tab. Creates a copy of the DeckLoader instance. * @param deckToOpen The deck to open in the tab. Creates a copy of the DeckLoader instance.
*/ */
TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen) TabDeckEditor *TabSupervisor::addDeckEditorTab(DeckLoader *deckToOpen)
{ {
auto *tab = new TabDeckEditor(this); auto *tab = new TabDeckEditor(this);
if (deckToOpen) if (deckToOpen)
tab->openDeck(new DeckLoader(*deckToOpen)); tab->openDeck(new DeckLoader(this, deckToOpen->getDeckList()));
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed); connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
myAddTab(tab); myAddTab(tab);
@ -878,11 +878,11 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
return tab; return tab;
} }
TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(const DeckLoader *deckToOpen) TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(DeckLoader *deckToOpen)
{ {
auto *tab = new TabDeckEditorVisual(this); auto *tab = new TabDeckEditorVisual(this);
if (deckToOpen) if (deckToOpen)
tab->openDeck(new DeckLoader(*deckToOpen)); tab->openDeck(new DeckLoader(this, deckToOpen->getDeckList()));
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed); connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addVisualDeckEditorTab); connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addVisualDeckEditorTab);
myAddTab(tab); myAddTab(tab);

View file

@ -169,9 +169,9 @@ signals:
void showWindowIfHidden(); void showWindowIfHidden();
public slots: public slots:
void openDeckInNewTab(const DeckLoader *deckToOpen); void openDeckInNewTab(DeckLoader *deckToOpen);
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen); TabDeckEditor *addDeckEditorTab(DeckLoader *deckToOpen);
TabDeckEditorVisual *addVisualDeckEditorTab(const DeckLoader *deckToOpen); TabDeckEditorVisual *addVisualDeckEditorTab(DeckLoader *deckToOpen);
TabVisualDatabaseDisplay *addVisualDatabaseDisplayTab(); TabVisualDatabaseDisplay *addVisualDatabaseDisplayTab();
TabEdhRecMain *addEdhrecMainTab(); TabEdhRecMain *addEdhrecMainTab();
TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false); TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false);

View file

@ -27,7 +27,7 @@ TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath) void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath)
{ {
DeckLoader deckLoader; DeckLoader deckLoader(this);
if (!deckLoader.loadFromFile(filePath, DeckLoader::getFormatFromName(filePath), true)) { if (!deckLoader.loadFromFile(filePath, DeckLoader::getFormatFromName(filePath), true)) {
QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(filePath)); QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(filePath));
return; return;

View file

@ -39,7 +39,7 @@ public slots:
void actOpenLocalDeck(const QString &filePath); void actOpenLocalDeck(const QString &filePath);
signals: signals:
void openDeckEditor(const DeckLoader *deckLoader); void openDeckEditor(DeckLoader *deckLoader);
private: private:
VisualDeckStorageWidget *visualDeckStorageWidget; VisualDeckStorageWidget *visualDeckStorageWidget;

View file

@ -91,7 +91,7 @@ void VisualDatabaseDisplayNameFilterWidget::actLoadFromClipboard()
if (!dlg.exec()) if (!dlg.exec())
return; return;
QStringList cardsInClipboard = dlg.getDeckList()->getCardList(); QStringList cardsInClipboard = dlg.getDeckList()->getDeckList()->getCardList();
for (QString cardName : cardsInClipboard) { for (QString cardName : cardsInClipboard) {
createNameFilter(cardName); createNameFilter(cardName);
} }

View file

@ -167,10 +167,10 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg()
auto *deckEditor = qobject_cast<AbstractTabDeckEditor *>(currentParent); auto *deckEditor = qobject_cast<AbstractTabDeckEditor *>(currentParent);
QStringList knownTags; QStringList knownTags;
QStringList allFiles = getAllFiles(SettingsCache::instance().getDeckPath()); QStringList allFiles = getAllFiles(SettingsCache::instance().getDeckPath());
DeckLoader loader; DeckLoader loader(this);
for (const QString &file : allFiles) { for (const QString &file : allFiles) {
loader.loadFromFile(file, DeckLoader::getFormatFromName(file), false); loader.loadFromFile(file, DeckLoader::getFormatFromName(file), false);
QStringList tags = loader.getTags(); QStringList tags = loader.getDeckList()->getTags();
knownTags.append(tags); knownTags.append(tags);
knownTags.removeDuplicates(); knownTags.removeDuplicates();
} }

View file

@ -25,8 +25,7 @@ DeckPreviewWidget::DeckPreviewWidget(QWidget *_parent,
layout = new QVBoxLayout(this); layout = new QVBoxLayout(this);
setLayout(layout); setLayout(layout);
deckLoader = new DeckLoader(); deckLoader = new DeckLoader(this);
deckLoader->setParent(this);
connect(deckLoader, &DeckLoader::loadFinished, this, &DeckPreviewWidget::initializeUi); connect(deckLoader, &DeckLoader::loadFinished, this, &DeckPreviewWidget::initializeUi);
/* TODO: We shouldn't update the tags on *every* deck load, since it's kinda expensive. We should instead count how /* TODO: We shouldn't update the tags on *every* deck load, since it's kinda expensive. We should instead count how
many deck loads have finished already and if we've loaded all decks and THEN load all the tags at once. */ many deck loads have finished already and if we've loaded all decks and THEN load all the tags at once. */
@ -74,23 +73,23 @@ void DeckPreviewWidget::initializeUi(const bool deckLoadSuccess)
if (!deckLoadSuccess) { if (!deckLoadSuccess) {
return; return;
} }
auto bannerCard = deckLoader->getBannerCard().name.isEmpty() auto bannerCard = deckLoader->getDeckList()->getBannerCard().name.isEmpty()
? ExactCard() ? ExactCard()
: CardDatabaseManager::query()->getCard(deckLoader->getBannerCard()); : CardDatabaseManager::query()->getCard(deckLoader->getDeckList()->getBannerCard());
bannerCardDisplayWidget->setCard(bannerCard); bannerCardDisplayWidget->setCard(bannerCard);
bannerCardDisplayWidget->setFontSize(24); bannerCardDisplayWidget->setFontSize(24);
setFilePath(deckLoader->getLastFileName()); setFilePath(deckLoader->getLastFileName());
colorIdentityWidget = new ColorIdentityWidget(this, getColorIdentity()); colorIdentityWidget = new ColorIdentityWidget(this, getColorIdentity());
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader); deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader->getDeckList());
bannerCardLabel = new QLabel(this); bannerCardLabel = new QLabel(this);
bannerCardLabel->setObjectName("bannerCardLabel"); bannerCardLabel->setObjectName("bannerCardLabel");
bannerCardComboBox = new QComboBox(this); bannerCardComboBox = new QComboBox(this);
bannerCardComboBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); bannerCardComboBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
bannerCardComboBox->setObjectName("bannerCardComboBox"); bannerCardComboBox->setObjectName("bannerCardComboBox");
bannerCardComboBox->setCurrentText(deckLoader->getBannerCard().name); bannerCardComboBox->setCurrentText(deckLoader->getDeckList()->getBannerCard().name);
bannerCardComboBox->installEventFilter(new NoScrollFilter()); bannerCardComboBox->installEventFilter(new NoScrollFilter());
connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DeckPreviewWidget::setBannerCard); &DeckPreviewWidget::setBannerCard);
@ -152,7 +151,7 @@ void DeckPreviewWidget::updateTagsVisibility(bool visible)
QString DeckPreviewWidget::getColorIdentity() QString DeckPreviewWidget::getColorIdentity()
{ {
QStringList cardList = deckLoader->getCardList(); QStringList cardList = deckLoader->getDeckList()->getCardList();
if (cardList.isEmpty()) { if (cardList.isEmpty()) {
return {}; return {};
} }
@ -186,8 +185,8 @@ QString DeckPreviewWidget::getColorIdentity()
*/ */
QString DeckPreviewWidget::getDisplayName() const QString DeckPreviewWidget::getDisplayName() const
{ {
return deckLoader->getName().isEmpty() ? QFileInfo(deckLoader->getLastFileName()).fileName() return deckLoader->getDeckList()->getName().isEmpty() ? QFileInfo(deckLoader->getLastFileName()).fileName()
: deckLoader->getName(); : deckLoader->getDeckList()->getName();
} }
void DeckPreviewWidget::setFilePath(const QString &_filePath) void DeckPreviewWidget::setFilePath(const QString &_filePath)
@ -233,7 +232,7 @@ void DeckPreviewWidget::updateBannerCardComboBox()
// Prepare the new items with deduplication // Prepare the new items with deduplication
QSet<QPair<QString, QString>> bannerCardSet; QSet<QPair<QString, QString>> bannerCardSet;
InnerDecklistNode *listRoot = deckLoader->getRoot(); InnerDecklistNode *listRoot = deckLoader->getDeckList()->getRoot();
for (auto i : *listRoot) { for (auto i : *listRoot) {
auto *currentZone = dynamic_cast<InnerDecklistNode *>(i); auto *currentZone = dynamic_cast<InnerDecklistNode *>(i);
for (auto j : *currentZone) { for (auto j : *currentZone) {
@ -273,7 +272,7 @@ void DeckPreviewWidget::updateBannerCardComboBox()
bannerCardComboBox->setCurrentIndex(restoredIndex); bannerCardComboBox->setCurrentIndex(restoredIndex);
} else { } else {
// Add a placeholder "-" and set it as the current selection // Add a placeholder "-" and set it as the current selection
int bannerIndex = bannerCardComboBox->findText(deckLoader->getBannerCard().name); int bannerIndex = bannerCardComboBox->findText(deckLoader->getDeckList()->getBannerCard().name);
if (bannerIndex != -1) { if (bannerIndex != -1) {
bannerCardComboBox->setCurrentIndex(bannerIndex); bannerCardComboBox->setCurrentIndex(bannerIndex);
} else { } else {
@ -291,7 +290,7 @@ void DeckPreviewWidget::setBannerCard(int /* changedIndex */)
{ {
auto [name, id] = bannerCardComboBox->currentData().value<QPair<QString, QString>>(); auto [name, id] = bannerCardComboBox->currentData().value<QPair<QString, QString>>();
CardRef cardRef = {name, id}; CardRef cardRef = {name, id};
deckLoader->setBannerCard(cardRef); deckLoader->getDeckList()->setBannerCard(cardRef);
deckLoader->saveToFile(filePath, DeckLoader::getFormatFromName(filePath)); deckLoader->saveToFile(filePath, DeckLoader::getFormatFromName(filePath));
bannerCardDisplayWidget->setCard(CardDatabaseManager::query()->getCard(cardRef)); bannerCardDisplayWidget->setCard(CardDatabaseManager::query()->getCard(cardRef));
} }
@ -374,7 +373,7 @@ void DeckPreviewWidget::addSetBannerCardMenu(QMenu *menu)
void DeckPreviewWidget::actRenameDeck() void DeckPreviewWidget::actRenameDeck()
{ {
// read input // read input
const QString oldName = deckLoader->getName(); const QString oldName = deckLoader->getDeckList()->getName();
bool ok; bool ok;
QString newName = QInputDialog::getText(this, "Rename deck", tr("New name:"), QLineEdit::Normal, oldName, &ok); QString newName = QInputDialog::getText(this, "Rename deck", tr("New name:"), QLineEdit::Normal, oldName, &ok);
@ -383,7 +382,7 @@ void DeckPreviewWidget::actRenameDeck()
} }
// write change // write change
deckLoader->setName(newName); deckLoader->getDeckList()->setName(newName);
deckLoader->saveToFile(filePath, DeckLoader::getFormatFromName(filePath)); deckLoader->saveToFile(filePath, DeckLoader::getFormatFromName(filePath));
// update VDS // update VDS

View file

@ -51,7 +51,7 @@ public:
signals: signals:
void deckLoadRequested(const QString &filePath); void deckLoadRequested(const QString &filePath);
void openDeckEditor(const DeckLoader *deck); void openDeckEditor(DeckLoader *deck);
public slots: public slots:
void setFilePath(const QString &filePath); void setFilePath(const QString &filePath);

View file

@ -210,7 +210,7 @@ QStringList VisualDeckStorageFolderDisplayWidget::gatherAllTagsFromFlowWidget()
// Iterate through all DeckPreviewWidgets // Iterate through all DeckPreviewWidgets
for (DeckPreviewWidget *display : flowWidget->findChildren<DeckPreviewWidget *>()) { for (DeckPreviewWidget *display : flowWidget->findChildren<DeckPreviewWidget *>()) {
// Get tags from each DeckPreviewWidget // Get tags from each DeckPreviewWidget
QStringList tags = display->deckLoader->getTags(); QStringList tags = display->deckLoader->getDeckList()->getTags();
// Add tags to the list while avoiding duplicates // Add tags to the list while avoiding duplicates
allTags.append(tags); allTags.append(tags);

View file

@ -93,14 +93,14 @@ QList<DeckPreviewWidget *> VisualDeckStorageSortWidget::filterFiles(QList<DeckPr
switch (sortOrder) { switch (sortOrder) {
case ByName: case ByName:
return widget1->deckLoader->getName() < widget2->deckLoader->getName(); return widget1->deckLoader->getDeckList()->getName() < widget2->deckLoader->getDeckList()->getName();
case Alphabetical: case Alphabetical:
return QString::localeAwareCompare(info1.fileName(), info2.fileName()) <= 0; return QString::localeAwareCompare(info1.fileName(), info2.fileName()) <= 0;
case ByLastModified: case ByLastModified:
return info1.lastModified() > info2.lastModified(); return info1.lastModified() > info2.lastModified();
case ByLastLoaded: { case ByLastLoaded: {
QDateTime time1 = QDateTime::fromString(widget1->deckLoader->getLastLoadedTimestamp()); QDateTime time1 = QDateTime::fromString(widget1->deckLoader->getDeckList()->getLastLoadedTimestamp());
QDateTime time2 = QDateTime::fromString(widget2->deckLoader->getLastLoadedTimestamp()); QDateTime time2 = QDateTime::fromString(widget2->deckLoader->getDeckList()->getLastLoadedTimestamp());
return time1 > time2; return time1 > time2;
} }
} }

View file

@ -59,7 +59,7 @@ void VisualDeckStorageTagFilterWidget::filterDecksBySelectedTags(const QList<Dec
} }
for (DeckPreviewWidget *deckPreview : deckPreviews) { for (DeckPreviewWidget *deckPreview : deckPreviews) {
QStringList deckTags = deckPreview->deckLoader->getTags(); QStringList deckTags = deckPreview->deckLoader->getDeckList()->getTags();
bool hasAllSelected = std::all_of(selectedTags.begin(), selectedTags.end(), bool hasAllSelected = std::all_of(selectedTags.begin(), selectedTags.end(),
[&deckTags](const QString &tag) { return deckTags.contains(tag); }); [&deckTags](const QString &tag) { return deckTags.contains(tag); });
@ -155,7 +155,7 @@ QSet<QString> VisualDeckStorageTagFilterWidget::gatherAllTags() const
for (DeckPreviewWidget *widget : deckWidgets) { for (DeckPreviewWidget *widget : deckWidgets) {
if (widget->checkVisibility()) { if (widget->checkVisibility()) {
for (const QString &tag : widget->deckLoader->getTags()) { for (const QString &tag : widget->deckLoader->getDeckList()->getTags()) {
allTags.insert(tag); allTags.insert(tag);
} }
} }

View file

@ -57,7 +57,7 @@ public slots:
signals: signals:
void bannerCardsRefreshed(); void bannerCardsRefreshed();
void deckLoadRequested(const QString &filePath); void deckLoadRequested(const QString &filePath);
void openDeckEditor(const DeckLoader *deck); void openDeckEditor(DeckLoader *deck);
private: private:
QVBoxLayout *layout; QVBoxLayout *layout;