[Refactor] Pass around LoadedDeck instead of DeckLoader (#6422)

This commit is contained in:
RickyRister 2025-12-20 04:39:00 -08:00 committed by GitHub
parent 367507e054
commit d6db21419c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 253 additions and 264 deletions

View file

@ -213,22 +213,22 @@ void AbstractTabDeckEditor::actSwapCard(const ExactCard &card, const QString &zo
/**
* @brief Opens a deck in this tab.
* @param deck DeckLoader object (takes ownership).
* @param deck The deck
*/
void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
void AbstractTabDeckEditor::openDeck(const LoadedDeck &deck)
{
setDeck(deck);
if (!deck->getLastLoadInfo().fileName.isEmpty()) {
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(deck->getLastLoadInfo().fileName);
if (!deck.lastLoadInfo.fileName.isEmpty()) {
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(deck.lastLoadInfo.fileName);
}
}
/**
* @brief Sets the currently active deck.
* @param _deck DeckLoader object.
* @param _deck The deck
*/
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
void AbstractTabDeckEditor::setDeck(const LoadedDeck &_deck)
{
deckDockWidget->setDeck(_deck);
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
@ -265,8 +265,8 @@ void AbstractTabDeckEditor::setModified(bool _modified)
*/
bool AbstractTabDeckEditor::isBlankNewDeck() const
{
DeckLoader *deck = deckDockWidget->getDeckLoader();
return !modified && deck->getDeckList()->isBlankDeck() && deck->hasNotBeenLoaded();
const LoadedDeck &loadedDeck = deckDockWidget->getDeckLoader()->getDeck();
return !modified && loadedDeck.isEmpty();
}
/** @brief Creates a new deck. Handles opening in new tab if needed. */
@ -277,7 +277,7 @@ void AbstractTabDeckEditor::actNewDeck()
return;
if (deckOpenLocation == NEW_TAB) {
emit openDeckEditor(nullptr);
emit openDeckEditor(LoadedDeck());
return;
}
@ -382,17 +382,15 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
{
DeckFileFormat::Format fmt = DeckFileFormat::getFormatFromName(fileName);
auto *l = new DeckLoader(this);
if (l->loadFromFile(fileName, fmt, true)) {
auto l = DeckLoader(this);
if (l.loadFromFile(fileName, fmt, true)) {
if (deckOpenLocation == NEW_TAB) {
emit openDeckEditor(l);
l->deleteLater();
emit openDeckEditor(l.getDeck());
} else {
deckMenu->setSaveStatus(false);
openDeck(l);
openDeck(l.getDeck());
}
} else {
l->deleteLater();
QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(fileName));
}
deckMenu->setSaveStatus(true);
@ -405,16 +403,16 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
*/
bool AbstractTabDeckEditor::actSaveDeck()
{
DeckLoader *const deck = getDeckLoader();
if (deck->getLastLoadInfo().remoteDeckId != LoadedDeck::LoadInfo::NON_REMOTE_ID) {
QString deckString = deck->getDeckList()->writeToString_Native();
const LoadedDeck &loadedDeck = getDeckLoader()->getDeck();
if (loadedDeck.lastLoadInfo.remoteDeckId != LoadedDeck::LoadInfo::NON_REMOTE_ID) {
QString deckString = loadedDeck.deckList.writeToString_Native();
if (deckString.length() > MAX_FILE_LENGTH) {
QMessageBox::critical(this, tr("Error"), tr("Could not save remote deck"));
return false;
}
Command_DeckUpload cmd;
cmd.set_deck_id(static_cast<google::protobuf::uint32>(deck->getLastLoadInfo().remoteDeckId));
cmd.set_deck_id(static_cast<google::protobuf::uint32>(loadedDeck.lastLoadInfo.remoteDeckId));
cmd.set_deck_list(deckString.toStdString());
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
@ -422,9 +420,11 @@ bool AbstractTabDeckEditor::actSaveDeck()
tabSupervisor->getClient()->sendCommand(pend);
return true;
} else if (deck->getLastLoadInfo().fileName.isEmpty())
}
if (loadedDeck.lastLoadInfo.fileName.isEmpty())
return actSaveDeckAs();
else if (deck->saveToFile(deck->getLastLoadInfo().fileName, deck->getLastLoadInfo().fileFormat)) {
if (getDeckLoader()->saveToFile(loadedDeck.lastLoadInfo.fileName, loadedDeck.lastLoadInfo.fileFormat)) {
setModified(false);
return true;
}
@ -493,9 +493,9 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
return;
if (deckOpenLocation == NEW_TAB) {
emit openDeckEditor(dlg.getDeckList());
emit openDeckEditor({.deckList = dlg.getDeckList()});
} else {
setDeck(dlg.getDeckList());
setDeck({.deckList = dlg.getDeckList()});
setModified(true);
}
@ -508,11 +508,11 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
*/
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
{
DlgEditDeckInClipboard dlg(getDeckLoader(), annotated, this);
DlgEditDeckInClipboard dlg(getDeckLoader()->getDeck().deckList, annotated, this);
if (!dlg.exec())
return;
setDeck(dlg.getDeckList());
setDeck({dlg.getDeckList(), getDeckLoader()->getDeck().lastLoadInfo});
setModified(true);
deckMenu->setSaveStatus(true);
}
@ -576,9 +576,9 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
return;
if (deckOpenLocation == NEW_TAB) {
emit openDeckEditor(dlg.getDeck());
emit openDeckEditor({.deckList = dlg.getDeck()});
} else {
setDeck(dlg.getDeck());
setDeck({.deckList = dlg.getDeck()});
setModified(true);
}
@ -591,8 +591,8 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
*/
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
{
if (DeckLoader *const deck = getDeckLoader()) {
QString decklistUrlString = deck->exportDeckToDecklist(getDeckList(), website);
if (DeckList *deckList = getDeckList()) {
QString decklistUrlString = DeckLoader::exportDeckToDecklist(deckList, website);
// Check to make sure the string isn't empty.
if (decklistUrlString.isEmpty()) {
// Show an error if the deck is empty, and return.

View file

@ -114,9 +114,9 @@ public:
virtual void retranslateUi() override = 0;
/** @brief Opens a deck in this tab.
* @param deck Pointer to a DeckLoader object.
* @param deck The deck to open
*/
void openDeck(DeckLoader *deck);
void openDeck(const LoadedDeck &deck);
/** @brief Returns the currently active deck loader. */
DeckLoader *getDeckLoader() const;
@ -198,7 +198,7 @@ public slots:
signals:
/** @brief Emitted when a deck should be opened in a new editor tab. */
void openDeckEditor(DeckLoader *deckLoader);
void openDeckEditor(const LoadedDeck &deck);
/** @brief Emitted before the tab is closed. */
void deckEditorClosing(AbstractTabDeckEditor *tab);
@ -286,7 +286,7 @@ private:
/** @brief Sets the deck for this tab.
* @param _deck The deck object.
*/
virtual void setDeck(DeckLoader *_deck);
virtual void setDeck(const LoadedDeck &_deck);
/** @brief Helper for editing decks from the clipboard. */
void editDeckInClipboard(bool annotated);

View file

@ -90,14 +90,14 @@ void ArchidektApiResponseDeckDisplayWidget::onGroupCriteriaChange(const QString
void ArchidektApiResponseDeckDisplayWidget::actOpenInDeckEditor()
{
auto loader = new DeckLoader(this);
loader->getDeckList()->loadFromString_Native(model->getDeckList()->writeToString_Native());
loader->getDeckList()->setName(response.getDeckName());
loader->getDeckList()->setGameFormat(
DeckList deckList(*model->getDeckList());
deckList.setName(response.getDeckName());
deckList.setGameFormat(
ArchidektFormats::formatToCockatriceName(ArchidektFormats::DeckFormat(response.getDeckFormat() - 1)));
emit openInDeckEditor(loader);
LoadedDeck loadedDeck = {deckList, {}};
emit openInDeckEditor(loadedDeck);
}
void ArchidektApiResponseDeckDisplayWidget::clearAllDisplayWidgets()

View file

@ -31,7 +31,7 @@
*
* ### Signals
* - `requestNavigation(QString url)` triggered when navigation to a deck URL is requested.
* - `openInDeckEditor(DeckLoader *loader)` emitted when the user chooses to open the deck
* - `openInDeckEditor(const LoadedDeck &deck)` emitted when the user chooses to open the deck
* in the deck editor.
*
* ### Features
@ -52,9 +52,9 @@ signals:
/**
* @brief Emitted when the deck should be opened in the deck editor.
* @param loader Initialized DeckLoader containing the deck data.
* @param deck LoadedDeck containing the deck data.
*/
void openInDeckEditor(DeckLoader *loader);
void openInDeckEditor(const LoadedDeck &deck);
public:
/**
@ -75,7 +75,7 @@ public:
void retranslateUi();
/**
* @brief Opens the deck in the deck editor via DeckLoader.
* @brief Opens the deck in the deck editor.
*/
void actOpenInDeckEditor();

View file

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

View file

@ -21,7 +21,7 @@ public:
// Debug method for logging
void debugPrint() const;
DeckLoader *deckLoader;
DeckList deck;
};
#endif // EDHREC_DECK_API_RESPONSE_H

View file

@ -363,7 +363,7 @@ void TabEdhRecMain::processAverageDeckResponse(QJsonObject reply)
{
EdhrecAverageDeckApiResponse deckData;
deckData.fromJson(reply);
tabSupervisor->openDeckInNewTab(deckData.deck.deckLoader);
tabSupervisor->openDeckInNewTab({deckData.deck.deck, {}});
}
void TabEdhRecMain::prettyPrintJson(const QJsonValue &value, int indentLevel)

View file

@ -12,7 +12,6 @@ class CardDatabaseDisplayModel;
class DeckListModel;
class QLabel;
class DeckLoader;
/**
* @class TabDeckEditor

View file

@ -245,7 +245,7 @@ void TabDeckStorage::actOpenLocalDeck()
if (!deckLoader->loadFromFile(filePath, DeckFileFormat::Cockatrice, true))
continue;
emit openDeckEditor(deckLoader);
emit openDeckEditor(deckLoader->getDeck());
}
}
@ -307,13 +307,15 @@ void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPa
QFile deckFile(filePath);
QFileInfo deckFileInfo(deckFile);
DeckLoader deck(this);
if (!deck.loadFromFile(filePath, DeckFileFormat::Cockatrice)) {
DeckLoader deckLoader(this);
if (!deckLoader.loadFromFile(filePath, DeckFileFormat::Cockatrice)) {
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
return;
}
if (deck.getDeckList()->getName().isEmpty()) {
DeckList deck = deckLoader.getDeck().deckList;
if (deck.getName().isEmpty()) {
bool ok;
QString deckName =
getTextWithMax(this, tr("Enter deck name"), tr("This decklist does not have a name.\nPlease enter a name:"),
@ -322,12 +324,12 @@ void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPa
return;
if (deckName.isEmpty())
deckName = tr("Unnamed deck");
deck.getDeckList()->setName(deckName);
deck.setName(deckName);
} else {
deck.getDeckList()->setName(deck.getDeckList()->getName().left(MAX_NAME_LENGTH));
deck.setName(deck.getName().left(MAX_NAME_LENGTH));
}
QString deckString = deck.getDeckList()->writeToString_Native();
QString deckString = deck.writeToString_Native();
if (deckString.length() > MAX_FILE_LENGTH) {
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
return;
@ -436,7 +438,7 @@ void TabDeckStorage::openRemoteDeckFinished(const Response &r, const CommandCont
if (!loader.loadFromRemote(QString::fromStdString(resp.deck()), cmd.deck_id()))
return;
emit openDeckEditor(&loader);
emit openDeckEditor(loader.getDeck());
}
void TabDeckStorage::actDownload()
@ -492,8 +494,12 @@ void TabDeckStorage::downloadFinished(const Response &r,
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
QString filePath = extraData.toString();
DeckLoader deck(this, new DeckList(QString::fromStdString(resp.deck())));
deck.saveToFile(filePath, DeckFileFormat::Cockatrice);
DeckList deckList = DeckList(QString::fromStdString(resp.deck()));
DeckLoader deckLoader(this);
deckLoader.setDeck({deckList, {}});
deckLoader.saveToFile(filePath, DeckFileFormat::Cockatrice);
}
void TabDeckStorage::actNewFolder()

View file

@ -13,6 +13,7 @@
#include <libcockatrice/network/client/abstract/abstract_client.h>
struct LoadedDeck;
class ServerInfo_User;
class AbstractClient;
class QTreeView;
@ -23,7 +24,6 @@ class QTreeWidgetItem;
class QGroupBox;
class CommandContainer;
class Response;
class DeckLoader;
class TabDeckStorage : public Tab
{
@ -87,7 +87,7 @@ public:
return tr("Deck Storage");
}
signals:
void openDeckEditor(DeckLoader *deckLoader);
void openDeckEditor(const LoadedDeck &deck);
};
#endif

View file

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

View file

@ -45,7 +45,6 @@ class ReplayTimelineWidget;
class CardZone;
class AbstractCardItem;
class CardItem;
class DeckLoader;
class QVBoxLayout;
class QHBoxLayout;
class GameReplay;
@ -119,7 +118,7 @@ signals:
void containerProcessingStarted(const GameEventContext &context);
void containerProcessingDone();
void openMessageDialog(const QString &userName, bool focus);
void openDeckEditor(DeckLoader *deck);
void openDeckEditor(const LoadedDeck &deck);
void notIdle();
void phaseChanged(int phase);

View file

@ -133,10 +133,10 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *
// create tabs menu actions
aTabDeckEditor = new QAction(this);
connect(aTabDeckEditor, &QAction::triggered, this, [this] { addDeckEditorTab(nullptr); });
connect(aTabDeckEditor, &QAction::triggered, this, [this] { addDeckEditorTab(LoadedDeck()); });
aTabVisualDeckEditor = new QAction(this);
connect(aTabVisualDeckEditor, &QAction::triggered, this, [this] { addVisualDeckEditorTab(nullptr); });
connect(aTabVisualDeckEditor, &QAction::triggered, this, [this] { addVisualDeckEditorTab(LoadedDeck()); });
aTabEdhRec = new QAction(this);
connect(aTabEdhRec, &QAction::triggered, this, [this] { addEdhrecMainTab(); });
@ -846,9 +846,9 @@ void TabSupervisor::talkLeft(TabMessage *tab)
/**
* Creates a new deck editor tab and loads the deck into it.
* 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.
*/
void TabSupervisor::openDeckInNewTab(DeckLoader *deckToOpen)
void TabSupervisor::openDeckInNewTab(const LoadedDeck &deckToOpen)
{
int type = SettingsCache::instance().getDefaultDeckEditorType();
switch (type) {
@ -868,13 +868,12 @@ void TabSupervisor::openDeckInNewTab(DeckLoader *deckToOpen)
/**
* 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.
*/
TabDeckEditor *TabSupervisor::addDeckEditorTab(DeckLoader *deckToOpen)
TabDeckEditor *TabSupervisor::addDeckEditorTab(const LoadedDeck &deckToOpen)
{
auto *tab = new TabDeckEditor(this);
if (deckToOpen)
tab->openDeck(deckToOpen);
tab->openDeck(deckToOpen);
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
myAddTab(tab);
@ -883,11 +882,10 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(DeckLoader *deckToOpen)
return tab;
}
TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(DeckLoader *deckToOpen)
TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(const LoadedDeck &deckToOpen)
{
auto *tab = new TabDeckEditorVisual(this);
if (deckToOpen)
tab->openDeck(deckToOpen);
tab->openDeck(deckToOpen);
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addVisualDeckEditorTab);
myAddTab(tab);

View file

@ -168,9 +168,9 @@ signals:
void showWindowIfHidden();
public slots:
void openDeckInNewTab(DeckLoader *deckToOpen);
TabDeckEditor *addDeckEditorTab(DeckLoader *deckToOpen);
TabDeckEditorVisual *addVisualDeckEditorTab(DeckLoader *deckToOpen);
void openDeckInNewTab(const LoadedDeck &deckToOpen);
TabDeckEditor *addDeckEditorTab(const LoadedDeck &deckToOpen);
TabDeckEditorVisual *addVisualDeckEditorTab(const LoadedDeck &deckToOpen);
TabVisualDatabaseDisplay *addVisualDatabaseDisplayTab();
TabEdhRecMain *addEdhrecMainTab();
TabArchidekt *addArchidektTab();

View file

@ -24,11 +24,11 @@ TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath)
{
auto deckLoader = new DeckLoader(this);
if (!deckLoader->loadFromFile(filePath, DeckFileFormat::getFormatFromName(filePath), true)) {
auto deckLoader = DeckLoader(this);
if (!deckLoader.loadFromFile(filePath, DeckFileFormat::getFormatFromName(filePath), true)) {
QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(filePath));
return;
}
emit openDeckEditor(deckLoader);
emit openDeckEditor(deckLoader.getDeck());
}

View file

@ -9,9 +9,9 @@
#include "../tab.h"
struct LoadedDeck;
class AbstractClient;
class CommandContainer;
class DeckLoader;
class DeckPreviewWidget;
class QFileSystemModel;
class QGroupBox;
@ -39,7 +39,7 @@ public slots:
void actOpenLocalDeck(const QString &filePath);
signals:
void openDeckEditor(DeckLoader *deckLoader);
void openDeckEditor(const LoadedDeck &deck);
private:
VisualDeckStorageWidget *visualDeckStorageWidget;