[DeckList] Disable copy constructor (#6339)

* [DeckList] Disable copy constructor

Took 1 hour 44 minutes

Took 1 minute

# Commit time for manual adjustment:
# Took 28 seconds


Took 33 seconds

* Revert member to pointer.

Took 19 minutes

* Revert pulling up setters/getters now that getDeckList is no longer const.

Took 6 minutes

* Revert more.

Took 2 minutes

* One more fix.

Took 1 minute

* Update cockatrice/src/interface/deck_loader/deck_loader.cpp

Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>
This commit is contained in:
BruebachL
2025-11-20 13:20:09 +01:00
committed by GitHub
parent 9957cb20e2
commit ab5d6db8a2
18 changed files with 49 additions and 69 deletions

View File

@@ -330,7 +330,7 @@ void DeckViewScene::setDeck(const DeckList &_deck)
if (deck) if (deck)
delete deck; delete deck;
deck = new DeckList(_deck); deck = new DeckList(_deck.writeToString_Native());
rebuildTree(); rebuildTree();
applySideboardPlan(deck->getCurrentSideboardPlan()); applySideboardPlan(deck->getCurrentSideboardPlan());
rearrangeItems(); rearrangeItems();

View File

@@ -263,7 +263,8 @@ void Player::deleteCard(CardItem *card)
} }
} }
void Player::setDeck(const DeckLoader &_deck) // TODO: Does a player need a DeckLoader?
void Player::setDeck(DeckLoader &_deck)
{ {
deck = new DeckLoader(this, _deck.getDeckList()); deck = new DeckLoader(this, _deck.getDeckList());

View File

@@ -130,7 +130,7 @@ public:
return playerMenu; return playerMenu;
} }
void setDeck(const DeckLoader &_deck); void setDeck(DeckLoader &_deck);
[[nodiscard]] DeckLoader *getDeck() const [[nodiscard]] DeckLoader *getDeck() const
{ {

View File

@@ -33,13 +33,6 @@ DeckLoader::DeckLoader(QObject *parent)
DeckLoader::DeckLoader(QObject *parent, DeckList *_deckList) DeckLoader::DeckLoader(QObject *parent, DeckList *_deckList)
: QObject(parent), deckList(_deckList), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1) : QObject(parent), deckList(_deckList), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
{ {
deckList->setParent(this);
}
void DeckLoader::setDeckList(DeckList *_deckList)
{
deckList = _deckList;
deckList->setParent(this);
} }
bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest) bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest)
@@ -159,12 +152,14 @@ bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
break; break;
case CockatriceFormat: case CockatriceFormat:
result = deckList->saveToFile_Native(&file); result = deckList->saveToFile_Native(&file);
qCInfo(DeckLoaderLog) << "Saving to " << fileName << "-" << result;
break; break;
} }
if (result) { if (result) {
lastFileName = fileName; lastFileName = fileName;
lastFileFormat = fmt; lastFileFormat = fmt;
qCInfo(DeckLoaderLog) << "Deck was saved -" << result;
} }
file.flush(); file.flush();

View File

@@ -56,8 +56,6 @@ public:
DeckLoader(const DeckLoader &) = delete; DeckLoader(const DeckLoader &) = delete;
DeckLoader &operator=(const DeckLoader &) = delete; DeckLoader &operator=(const DeckLoader &) = delete;
void setDeckList(DeckList *_deckList);
const QString &getLastFileName() const const QString &getLastFileName() const
{ {
return lastFileName; return lastFileName;
@@ -109,7 +107,7 @@ public:
bool convertToCockatriceFormat(QString fileName); bool convertToCockatriceFormat(QString fileName);
DeckList *getDeckList() const DeckList *getDeckList()
{ {
return deckList; return deckList;
} }

View File

@@ -109,7 +109,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
&DeckEditorDeckDockWidget::setBannerCard); &DeckEditorDeckDockWidget::setBannerCard);
bannerCardComboBox->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible()); bannerCardComboBox->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckModel->getDeckList()); deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader);
deckTagsDisplayWidget->setHidden(!SettingsCache::instance().getDeckEditorTagsWidgetVisible()); deckTagsDisplayWidget->setHidden(!SettingsCache::instance().getDeckEditorTagsWidgetVisible());
activeGroupCriteriaLabel = new QLabel(this); activeGroupCriteriaLabel = new QLabel(this);
@@ -382,7 +382,7 @@ void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
deckView->expandAll(); deckView->expandAll();
deckView->expandAll(); deckView->expandAll();
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList()); deckTagsDisplayWidget->connectDeckList();
emit deckChanged(); emit deckChanged();
} }
@@ -412,7 +412,7 @@ void DeckEditorDeckDockWidget::cleanDeck()
emit deckModified(); emit deckModified();
emit deckChanged(); emit deckChanged();
updateBannerCardComboBox(); updateBannerCardComboBox();
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList()); deckTagsDisplayWidget->connectDeckList();
} }
void DeckEditorDeckDockWidget::recursiveExpand(const QModelIndex &index) void DeckEditorDeckDockWidget::recursiveExpand(const QModelIndex &index)

View File

@@ -133,16 +133,16 @@ void DlgLoadDeckFromClipboard::actOK()
/** /**
* Creates the dialog window for the "Edit deck in clipboard" action * Creates the dialog window for the "Edit deck in clipboard" action
* *
* @param deckList The existing deck in the deck editor. Copies the instance * @param _deckLoader The existing deck in the deck editor. Copies the instance
* @param _annotated Whether to add annotations to the text that is loaded from the deck * @param _annotated Whether to add annotations to the text that is loaded from the deck
* @param parent The parent widget * @param parent The parent widget
*/ */
DlgEditDeckInClipboard::DlgEditDeckInClipboard(const DeckLoader &deckList, bool _annotated, QWidget *parent) DlgEditDeckInClipboard::DlgEditDeckInClipboard(DeckLoader *_deckLoader, bool _annotated, QWidget *parent)
: AbstractDlgDeckTextEdit(parent), annotated(_annotated) : AbstractDlgDeckTextEdit(parent), annotated(_annotated)
{ {
setWindowTitle(tr("Edit deck in clipboard")); setWindowTitle(tr("Edit deck in clipboard"));
deckLoader = new DeckLoader(this, deckList.getDeckList()); deckLoader = new DeckLoader(this, _deckLoader->getDeckList());
deckLoader->setParent(this); deckLoader->setParent(this);
DlgEditDeckInClipboard::actRefresh(); DlgEditDeckInClipboard::actRefresh();

View File

@@ -88,7 +88,7 @@ private:
bool annotated; bool annotated;
public: public:
explicit DlgEditDeckInClipboard(const DeckLoader &deckList, bool _annotated, QWidget *parent = nullptr); explicit DlgEditDeckInClipboard(DeckLoader *_deckLoader, bool _annotated, QWidget *parent = nullptr);
[[nodiscard]] DeckLoader *getDeckList() const override [[nodiscard]] DeckLoader *getDeckList() const override
{ {

View File

@@ -486,7 +486,7 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
*/ */
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated) void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
{ {
DlgEditDeckInClipboard dlg(*getDeckLoader(), annotated, this); DlgEditDeckInClipboard dlg(getDeckLoader(), annotated, this);
if (!dlg.exec()) if (!dlg.exec())
return; return;

View File

@@ -242,11 +242,11 @@ void TabDeckStorage::actOpenLocalDeck()
continue; continue;
QString filePath = localDirModel->filePath(curLeft); QString filePath = localDirModel->filePath(curLeft);
DeckLoader deckLoader(this); auto deckLoader = new DeckLoader(this);
if (!deckLoader.loadFromFile(filePath, DeckLoader::CockatriceFormat, true)) if (!deckLoader->loadFromFile(filePath, DeckLoader::CockatriceFormat, true))
continue; continue;
emit openDeckEditor(&deckLoader); emit openDeckEditor(deckLoader);
} }
} }

View File

@@ -869,7 +869,7 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(DeckLoader *deckToOpen)
{ {
auto *tab = new TabDeckEditor(this); auto *tab = new TabDeckEditor(this);
if (deckToOpen) if (deckToOpen)
tab->openDeck(new DeckLoader(this, deckToOpen->getDeckList())); tab->openDeck(deckToOpen);
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);
@@ -882,7 +882,7 @@ TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(DeckLoader *deckToOpe
{ {
auto *tab = new TabDeckEditorVisual(this); auto *tab = new TabDeckEditorVisual(this);
if (deckToOpen) if (deckToOpen)
tab->openDeck(new DeckLoader(this, deckToOpen->getDeckList())); tab->openDeck(deckToOpen);
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

@@ -27,11 +27,11 @@ TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath) void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath)
{ {
DeckLoader deckLoader(this); auto deckLoader = new 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;
} }
emit openDeckEditor(&deckLoader); emit openDeckEditor(deckLoader);
} }

View File

@@ -14,8 +14,8 @@
#include <QLabel> #include <QLabel>
#include <QMessageBox> #include <QMessageBox>
DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList) DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckLoader *_deckLoader)
: QWidget(_parent), deckList(nullptr) : QWidget(_parent), deckLoader(_deckLoader)
{ {
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
@@ -28,21 +28,20 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_par
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded); flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
if (_deckList) { connectDeckList();
connectDeckList(_deckList);
}
layout->addWidget(flowWidget); layout->addWidget(flowWidget);
} }
void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList) void DeckPreviewDeckTagsDisplayWidget::connectDeckList()
{ {
if (deckList) { if (deckLoader) {
disconnect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags); disconnect(deckLoader->getDeckList(), &DeckList::deckTagsChanged, this,
&DeckPreviewDeckTagsDisplayWidget::refreshTags);
} }
deckList = _deckList; connect(deckLoader->getDeckList(), &DeckList::deckTagsChanged, this,
connect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags); &DeckPreviewDeckTagsDisplayWidget::refreshTags);
refreshTags(); refreshTags();
} }
@@ -51,7 +50,7 @@ void DeckPreviewDeckTagsDisplayWidget::refreshTags()
{ {
flowWidget->clearLayout(); flowWidget->clearLayout();
for (const QString &tag : deckList->getTags()) { for (const QString &tag : deckLoader->getDeckList()->getTags()) {
flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag));
} }
@@ -98,7 +97,7 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg()
if (qobject_cast<DeckPreviewWidget *>(parentWidget())) { if (qobject_cast<DeckPreviewWidget *>(parentWidget())) {
auto *deckPreviewWidget = qobject_cast<DeckPreviewWidget *>(parentWidget()); auto *deckPreviewWidget = qobject_cast<DeckPreviewWidget *>(parentWidget());
QStringList knownTags = deckPreviewWidget->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags(); QStringList knownTags = deckPreviewWidget->visualDeckStorageWidget->tagFilterWidget->getAllKnownTags();
QStringList activeTags = deckList->getTags(); QStringList activeTags = deckLoader->getDeckList()->getTags();
bool canAddTags = true; bool canAddTags = true;
@@ -149,7 +148,7 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg()
DeckPreviewTagDialog dialog(knownTags, activeTags); DeckPreviewTagDialog dialog(knownTags, activeTags);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QStringList updatedTags = dialog.getActiveTags(); QStringList updatedTags = dialog.getActiveTags();
deckList->setTags(updatedTags); deckLoader->getDeckList()->setTags(updatedTags);
deckPreviewWidget->deckLoader->saveToFile(deckPreviewWidget->filePath, DeckLoader::CockatriceFormat); deckPreviewWidget->deckLoader->saveToFile(deckPreviewWidget->filePath, DeckLoader::CockatriceFormat);
} }
} }
@@ -175,12 +174,12 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg()
knownTags.removeDuplicates(); knownTags.removeDuplicates();
} }
QStringList activeTags = deckList->getTags(); QStringList activeTags = deckLoader->getDeckList()->getTags();
DeckPreviewTagDialog dialog(knownTags, activeTags); DeckPreviewTagDialog dialog(knownTags, activeTags);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QStringList updatedTags = dialog.getActiveTags(); QStringList updatedTags = dialog.getActiveTags();
deckList->setTags(updatedTags); deckLoader->getDeckList()->setTags(updatedTags);
deckEditor->setModified(true); deckEditor->setModified(true);
} }
} }

View File

@@ -20,10 +20,10 @@ class DeckPreviewDeckTagsDisplayWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList); explicit DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckLoader *_deckLoader);
void connectDeckList(DeckList *_deckList); void connectDeckList();
void refreshTags(); void refreshTags();
DeckList *deckList; DeckLoader *deckLoader;
FlowWidget *flowWidget; FlowWidget *flowWidget;
public slots: public slots:

View File

@@ -82,7 +82,7 @@ void DeckPreviewWidget::initializeUi(const bool deckLoadSuccess)
setFilePath(deckLoader->getLastFileName()); setFilePath(deckLoader->getLastFileName());
colorIdentityWidget = new ColorIdentityWidget(this, getColorIdentity()); colorIdentityWidget = new ColorIdentityWidget(this, getColorIdentity());
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader->getDeckList()); deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader);
bannerCardLabel = new QLabel(this); bannerCardLabel = new QLabel(this);
bannerCardLabel->setObjectName("bannerCardLabel"); bannerCardLabel->setObjectName("bannerCardLabel");

View File

@@ -80,20 +80,6 @@ DeckList::DeckList()
root = new InnerDecklistNode; root = new InnerDecklistNode;
} }
// TODO: https://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
DeckList::DeckList(const DeckList &other)
: QObject(), name(other.name), comments(other.comments), bannerCard(other.bannerCard),
lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags), cachedDeckHash(other.cachedDeckHash)
{
root = new InnerDecklistNode(other.getRoot());
QMapIterator<QString, SideboardPlan *> spIterator(other.getSideboardPlans());
while (spIterator.hasNext()) {
spIterator.next();
sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList()));
}
}
DeckList::DeckList(const QString &nativeString) DeckList::DeckList(const QString &nativeString)
{ {
root = new InnerDecklistNode; root = new InnerDecklistNode;

View File

@@ -215,8 +215,9 @@ public slots:
public: public:
/// @brief Construct an empty deck. /// @brief Construct an empty deck.
explicit DeckList(); explicit DeckList();
/// @brief Deep-copy constructor. /// @brief Delete copy constructor.
DeckList(const DeckList &other); DeckList(const DeckList &) = delete;
DeckList &operator=(const DeckList &) = delete;
/// @brief Construct from a serialized native-format string. /// @brief Construct from a serialized native-format string.
explicit DeckList(const QString &nativeString); explicit DeckList(const QString &nativeString);
~DeckList() override; ~DeckList() override;

View File

@@ -533,14 +533,14 @@ void DeckListModel::cleanList()
} }
/** /**
* @param _deck The deck. Takes ownership of the object * @param _deck The deck.
*/ */
void DeckListModel::setDeckList(DeckList *_deck) void DeckListModel::setDeckList(DeckList *_deck)
{ {
deckList->deleteLater(); if (deckList != _deck) {
deckList = _deck; deckList = _deck;
deckList->setParent(this); rebuildTree();
rebuildTree(); }
} }
QList<ExactCard> DeckListModel::getCards() const QList<ExactCard> DeckListModel::getCards() const