From 80165c28a9751d09f0f54767188d94d189704b46 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Fri, 17 Jan 2025 03:38:01 +0100 Subject: [PATCH] Add options to include/exclude set name and collector number during clipboard import/export. (#5482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add options to include/exclude set name and collector number during clipboard import/export. * Missing parentheses in action label. * Revert the silliest lint in the world. --------- Co-authored-by: Lukas BrĂ¼bach --- .../src/client/tabs/tab_deck_editor.cpp | 32 ++++++++++ cockatrice/src/client/tabs/tab_deck_editor.h | 5 +- cockatrice/src/deck/deck_loader.cpp | 59 +++++++++++++++---- cockatrice/src/deck/deck_loader.h | 11 +++- .../dialogs/dlg_load_deck_from_clipboard.cpp | 16 ++++- .../dialogs/dlg_load_deck_from_clipboard.h | 2 + 6 files changed, 108 insertions(+), 17 deletions(-) diff --git a/cockatrice/src/client/tabs/tab_deck_editor.cpp b/cockatrice/src/client/tabs/tab_deck_editor.cpp index 3c0db84a0..f9e73356d 100644 --- a/cockatrice/src/client/tabs/tab_deck_editor.cpp +++ b/cockatrice/src/client/tabs/tab_deck_editor.cpp @@ -337,9 +337,17 @@ void TabDeckEditor::createMenus() aSaveDeckToClipboard = new QAction(QString(), this); connect(aSaveDeckToClipboard, SIGNAL(triggered()), this, SLOT(actSaveDeckToClipboard())); + aSaveDeckToClipboardNoSetNameAndNumber = new QAction(QString(), this); + connect(aSaveDeckToClipboardNoSetNameAndNumber, SIGNAL(triggered()), this, + SLOT(actSaveDeckToClipboardNoSetNameAndNumber())); + aSaveDeckToClipboardRaw = new QAction(QString(), this); connect(aSaveDeckToClipboardRaw, SIGNAL(triggered()), this, SLOT(actSaveDeckToClipboardRaw())); + aSaveDeckToClipboardRawNoSetNameAndNumber = new QAction(QString(), this); + connect(aSaveDeckToClipboardRawNoSetNameAndNumber, SIGNAL(triggered()), this, + SLOT(actSaveDeckToClipboardRawNoSetNameAndNumber())); + aPrintDeck = new QAction(QString(), this); connect(aPrintDeck, SIGNAL(triggered()), this, SLOT(actPrintDeck())); @@ -370,7 +378,9 @@ void TabDeckEditor::createMenus() saveDeckToClipboardMenu = new QMenu(this); saveDeckToClipboardMenu->addAction(aSaveDeckToClipboard); + saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardNoSetNameAndNumber); saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardRaw); + saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardRawNoSetNameAndNumber); deckMenu = new QMenu(this); deckMenu->addAction(aNewDeck); @@ -741,7 +751,9 @@ void TabDeckEditor::retranslateUi() saveDeckToClipboardMenu->setTitle(tr("Save deck to clipboard")); aSaveDeckToClipboard->setText(tr("Annotated")); + aSaveDeckToClipboardNoSetNameAndNumber->setText(tr("Annotated (No set name or number)")); aSaveDeckToClipboardRaw->setText(tr("Not Annotated")); + aSaveDeckToClipboardRawNoSetNameAndNumber->setText(tr("Not Annotated (No set name or number)")); aPrintDeck->setText(tr("&Print deck...")); @@ -1172,6 +1184,15 @@ void TabDeckEditor::actSaveDeckToClipboard() QApplication::clipboard()->setText(buffer, QClipboard::Selection); } +void TabDeckEditor::actSaveDeckToClipboardNoSetNameAndNumber() +{ + QString buffer; + QTextStream stream(&buffer); + deckModel->getDeckList()->saveToStream_Plain(stream, true, false); + QApplication::clipboard()->setText(buffer, QClipboard::Clipboard); + QApplication::clipboard()->setText(buffer, QClipboard::Selection); +} + void TabDeckEditor::actSaveDeckToClipboardRaw() { QString buffer; @@ -1181,6 +1202,15 @@ void TabDeckEditor::actSaveDeckToClipboardRaw() QApplication::clipboard()->setText(buffer, QClipboard::Selection); } +void TabDeckEditor::actSaveDeckToClipboardRawNoSetNameAndNumber() +{ + QString buffer; + QTextStream stream(&buffer); + deckModel->getDeckList()->saveToStream_Plain(stream, false, false); + QApplication::clipboard()->setText(buffer, QClipboard::Clipboard); + QApplication::clipboard()->setText(buffer, QClipboard::Selection); +} + void TabDeckEditor::actPrintDeck() { auto *dlg = new QPrintPreviewDialog(this); @@ -1723,7 +1753,9 @@ void TabDeckEditor::setSaveStatus(bool newStatus) aSaveDeck->setEnabled(newStatus); aSaveDeckAs->setEnabled(newStatus); aSaveDeckToClipboard->setEnabled(newStatus); + aSaveDeckToClipboardNoSetNameAndNumber->setEnabled(newStatus); aSaveDeckToClipboardRaw->setEnabled(newStatus); + aSaveDeckToClipboardRawNoSetNameAndNumber->setEnabled(newStatus); saveDeckToClipboardMenu->setEnabled(newStatus); aPrintDeck->setEnabled(newStatus); analyzeDeckMenu->setEnabled(newStatus); diff --git a/cockatrice/src/client/tabs/tab_deck_editor.h b/cockatrice/src/client/tabs/tab_deck_editor.h index 0a11b3c8c..6a5d320a4 100644 --- a/cockatrice/src/client/tabs/tab_deck_editor.h +++ b/cockatrice/src/client/tabs/tab_deck_editor.h @@ -56,7 +56,9 @@ private slots: bool actSaveDeckAs(); void actLoadDeckFromClipboard(); void actSaveDeckToClipboard(); + void actSaveDeckToClipboardNoSetNameAndNumber(); void actSaveDeckToClipboardRaw(); + void actSaveDeckToClipboardRawNoSetNameAndNumber(); void actPrintDeck(); void actExportDeckDecklist(); void actAnalyzeDeckDeckstats(); @@ -145,7 +147,8 @@ private: QMenu *deckMenu, *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *printingSelectorDockMenu, *analyzeDeckMenu, *saveDeckToClipboardMenu, *loadRecentDeckMenu; QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard, - *aSaveDeckToClipboard, *aSaveDeckToClipboardRaw, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats, + *aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetNameAndNumber, *aSaveDeckToClipboardRaw, + *aSaveDeckToClipboardRawNoSetNameAndNumber, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose; QAction *aClearFilterAll, *aClearFilterOne; QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement, *aSwapCard; diff --git a/cockatrice/src/deck/deck_loader.cpp b/cockatrice/src/deck/deck_loader.cpp index 0543020a4..c738b6aa8 100644 --- a/cockatrice/src/deck/deck_loader.cpp +++ b/cockatrice/src/deck/deck_loader.cpp @@ -328,6 +328,37 @@ void DeckLoader::resolveSetNameAndNumberToProviderID() forEachCard(setProviderId); } +// This struct is here to support the forEachCard function call, defined in decklist. +// It requires a function to be called for each card, and it will set the providerId. +struct ClearSetNameAndNumber +{ + // Main operator for struct, allowing the foreachcard to work. + ClearSetNameAndNumber() + { + } + + void operator()(const InnerDecklistNode *node, DecklistCardNode *card) const + { + Q_UNUSED(node); + // Set the providerId on the card + card->setCardSetShortName(nullptr); + card->setCardCollectorNumber(nullptr); + } +}; + +/** + * This function iterates through each card in the decklist and sets the providerId + * on each card based on its set name and collector number. + */ +void DeckLoader::clearSetNamesAndNumbers() +{ + // Set up the struct to call. + ClearSetNameAndNumber clearSetNameAndNumber; + + // Call the forEachCard method for each card in the deck + forEachCard(clearSetNameAndNumber); +} + DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName) { if (fileName.endsWith(".cod", Qt::CaseInsensitive)) { @@ -336,7 +367,7 @@ DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName) return PlainTextFormat; } -bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments) +bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments, bool addSetNameAndNumber) { if (addComments) { saveToStream_DeckHeader(out); @@ -346,7 +377,7 @@ bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments) for (int i = 0; i < getRoot()->size(); i++) { const auto *zoneNode = dynamic_cast(getRoot()->at(i)); - saveToStream_DeckZone(out, zoneNode, addComments); + saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber); // end of zone out << "\n"; @@ -370,7 +401,10 @@ void DeckLoader::saveToStream_DeckHeader(QTextStream &out) } } -void DeckLoader::saveToStream_DeckZone(QTextStream &out, const InnerDecklistNode *zoneNode, bool addComments) +void DeckLoader::saveToStream_DeckZone(QTextStream &out, + const InnerDecklistNode *zoneNode, + bool addComments, + bool addSetNameAndNumber) { // group cards by card type and count the subtotals QMultiMap cardsByType; @@ -406,7 +440,7 @@ void DeckLoader::saveToStream_DeckZone(QTextStream &out, const InnerDecklistNode QList cards = cardsByType.values(cardType); - saveToStream_DeckZoneCards(out, zoneNode, cards, addComments); + saveToStream_DeckZoneCards(out, zoneNode, cards, addComments, addSetNameAndNumber); if (addComments) { out << "\n"; @@ -417,7 +451,8 @@ void DeckLoader::saveToStream_DeckZone(QTextStream &out, const InnerDecklistNode void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out, const InnerDecklistNode *zoneNode, QList cards, - bool addComments) + bool addComments, + bool addSetNameAndNumber) { // QMultiMap sorts values in reverse order for (int i = cards.size() - 1; i >= 0; --i) { @@ -433,12 +468,14 @@ void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out, if (!card->getName().isNull() && !card->getName().isEmpty()) { out << " " << card->getName(); } - if (!card->getCardSetShortName().isNull() && !card->getCardSetShortName().isEmpty()) { - out << " " - << "(" << card->getCardSetShortName() << ")"; - } - if (!card->getCardCollectorNumber().isNull()) { - out << " " << card->getCardCollectorNumber(); + if (addSetNameAndNumber) { + if (!card->getCardSetShortName().isNull() && !card->getCardSetShortName().isEmpty()) { + out << " " + << "(" << card->getCardSetShortName() << ")"; + } + if (!card->getCardCollectorNumber().isNull()) { + out << " " << card->getCardCollectorNumber(); + } } out << "\n"; } diff --git a/cockatrice/src/deck/deck_loader.h b/cockatrice/src/deck/deck_loader.h index 6d2631d33..0e9dfa374 100644 --- a/cockatrice/src/deck/deck_loader.h +++ b/cockatrice/src/deck/deck_loader.h @@ -45,6 +45,7 @@ public: return lastRemoteDeckId; } + void clearSetNamesAndNumbers(); static FileFormat getFormatFromName(const QString &fileName); bool loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest = false); @@ -57,15 +58,19 @@ public: void resolveSetNameAndNumberToProviderID(); // overload - bool saveToStream_Plain(QTextStream &out, bool addComments = true); + bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true); protected: void saveToStream_DeckHeader(QTextStream &out); - void saveToStream_DeckZone(QTextStream &out, const InnerDecklistNode *zoneNode, bool addComments = true); + void saveToStream_DeckZone(QTextStream &out, + const InnerDecklistNode *zoneNode, + bool addComments = true, + bool addSetNameAndNumber = true); void saveToStream_DeckZoneCards(QTextStream &out, const InnerDecklistNode *zoneNode, QList cards, - bool addComments = true); + bool addComments = true, + bool addSetNameAndNumber = true); [[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override; [[nodiscard]] QString getCompleteCardName(const QString &cardName) const override; }; diff --git a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp index 4077a8456..e5e5b5951 100644 --- a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp +++ b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp @@ -4,6 +4,7 @@ #include "../settings/cache_settings.h" #include +#include #include #include #include @@ -24,9 +25,16 @@ DlgLoadDeckFromClipboard::DlgLoadDeckFromClipboard(QWidget *parent) : QDialog(pa connect(buttonBox, SIGNAL(accepted()), this, SLOT(actOK())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + loadSetNameAndNumberCheckBox = new QCheckBox(tr("Parse Set Name and Number (if available)")); + loadSetNameAndNumberCheckBox->setChecked(true); + + auto *buttonLayout = new QHBoxLayout; + buttonLayout->addWidget(loadSetNameAndNumberCheckBox); + buttonLayout->addWidget(buttonBox); + auto *mainLayout = new QVBoxLayout; mainLayout->addWidget(contentsEdit); - mainLayout->addWidget(buttonBox); + mainLayout->addLayout(buttonLayout); setLayout(mainLayout); @@ -65,7 +73,11 @@ void DlgLoadDeckFromClipboard::actOK() } } else if (deckLoader->loadFromStream_Plain(stream)) { deckList = deckLoader; - deckList->resolveSetNameAndNumberToProviderID(); + if (loadSetNameAndNumberCheckBox->isChecked()) { + deckList->resolveSetNameAndNumberToProviderID(); + } else { + deckList->clearSetNamesAndNumbers(); + } accept(); } else { QMessageBox::critical(this, tr("Error"), tr("Invalid deck list.")); diff --git a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h index 56c75f707..337f8c7d3 100644 --- a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h +++ b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h @@ -1,6 +1,7 @@ #ifndef DLG_LOAD_DECK_FROM_CLIPBOARD_H #define DLG_LOAD_DECK_FROM_CLIPBOARD_H +#include #include class DeckLoader; @@ -19,6 +20,7 @@ private: DeckLoader *deckList; QPlainTextEdit *contentsEdit; QPushButton *refreshButton; + QCheckBox *loadSetNameAndNumberCheckBox; public: explicit DlgLoadDeckFromClipboard(QWidget *parent = nullptr);