From bfedc12fa8d64645f99828b8998da587529247b8 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 11 Nov 2025 11:57:41 +0100 Subject: [PATCH] Deck loader is a gui class. (#6294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Deck loader is a gui class. Took 31 minutes Took 3 minutes * Deck Loader is responsible for printing. Took 8 minutes Took 2 seconds * Style proxy. Took 14 minutes Took 6 minutes Took 1 minute * Don't need to include QBrush anymore. Took 3 minutes Took 7 seconds * Includes for printer. Took 5 minutes * Nuke getDeckList() Took 9 minutes * Adjust to rebase. Took 35 seconds * Lint. Took 3 minutes * Braces for one line return statements. Took 13 minutes Took 50 seconds * Enum for model columns. Took 9 minutes * One more single line if. Took 1 minute * Another style lint on a sunday night Took 5 minutes * Move enum to namespace. Took 3 minutes * Fix a critical blocker. Took 5 minutes * Update docs. Took 3 minutes * Doxygen and namespace enums. Took 2 minutes Took 15 seconds * Adjust to namespace. Took 4 minutes Took 1 minute --------- Co-authored-by: Lukas BrĂ¼bach --- cockatrice/CMakeLists.txt | 2 + .../parsers/interface_json_deck_parser.h | 3 +- .../src/game/deckview/deck_view_container.cpp | 2 +- .../src/game/deckview/deck_view_container.h | 3 +- cockatrice/src/game/player/player_info.h | 2 +- .../interface/deck_loader}/deck_loader.cpp | 99 +++++++ .../src/interface/deck_loader}/deck_loader.h | 12 + .../deck_analytics/mana_base_widget.cpp | 2 +- .../deck_analytics/mana_curve_widget.cpp | 2 +- .../deck_analytics/mana_devotion_widget.cpp | 2 +- .../deck_editor_deck_dock_widget.cpp | 20 +- .../deck_editor_deck_dock_widget.h | 3 +- .../deck_editor/deck_list_style_proxy.cpp | 37 +++ .../deck_editor/deck_list_style_proxy.h | 15 + .../widgets/dialogs/dlg_load_deck.cpp | 3 +- .../dialogs/dlg_load_deck_from_clipboard.cpp | 2 +- .../dialogs/dlg_select_set_for_cards.cpp | 8 +- .../all_zones_card_amount_widget.h | 2 +- .../printing_selector/card_amount_widget.h | 2 +- .../widgets/tabs/abstract_tab_deck_editor.cpp | 32 +- .../widgets/tabs/abstract_tab_deck_editor.h | 2 +- .../average_deck/edhrec_deck_api_response.cpp | 3 +- .../average_deck/edhrec_deck_api_response.h | 3 +- .../widgets/tabs/tab_deck_storage.cpp | 2 +- .../interface/widgets/tabs/tab_supervisor.h | 2 +- .../visual_deck_editor_sample_hand_widget.cpp | 2 +- .../visual_deck_editor_widget.cpp | 2 +- .../deck_preview_deck_tags_display_widget.h | 2 +- .../deck_preview/deck_preview_widget.h | 2 +- .../visual_deck_storage_widget.h | 1 + .../models/deck_list/CMakeLists.txt | 3 +- .../models/deck_list/deck_list_model.cpp | 277 ++++++------------ .../models/deck_list/deck_list_model.h | 85 ++++-- 33 files changed, 384 insertions(+), 255 deletions(-) rename {libcockatrice_models/libcockatrice/models/deck_list => cockatrice/src/interface/deck_loader}/deck_loader.cpp (84%) rename {libcockatrice_models/libcockatrice/models/deck_list => cockatrice/src/interface/deck_loader}/deck_loader.h (91%) create mode 100644 cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp create mode 100644 cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 3ba24b31e..995b55258 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -19,6 +19,7 @@ set(cockatrice_SOURCES src/client/settings/card_counter_settings.cpp src/client/settings/shortcut_treeview.cpp src/client/settings/shortcuts_settings.cpp + src/interface/deck_loader/deck_loader.cpp src/interface/widgets/dialogs/dlg_connect.cpp src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp src/interface/widgets/dialogs/dlg_create_game.cpp @@ -149,6 +150,7 @@ set(cockatrice_SOURCES src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp + src/interface/widgets/deck_editor/deck_list_style_proxy.cpp src/interface/widgets/general/background_sources.cpp src/interface/widgets/general/display/banner_widget.cpp src/interface/widgets/general/display/bar_widget.cpp diff --git a/cockatrice/src/client/network/parsers/interface_json_deck_parser.h b/cockatrice/src/client/network/parsers/interface_json_deck_parser.h index 91915c306..a2bb9e812 100644 --- a/cockatrice/src/client/network/parsers/interface_json_deck_parser.h +++ b/cockatrice/src/client/network/parsers/interface_json_deck_parser.h @@ -6,9 +6,10 @@ #ifndef INTERFACE_JSON_DECK_PARSER_H #define INTERFACE_JSON_DECK_PARSER_H +#include "../../../interface/deck_loader/deck_loader.h" + #include #include -#include class IJsonDeckParser { diff --git a/cockatrice/src/game/deckview/deck_view_container.cpp b/cockatrice/src/game/deckview/deck_view_container.cpp index 6a01467d1..5b74fbe97 100644 --- a/cockatrice/src/game/deckview/deck_view_container.cpp +++ b/cockatrice/src/game/deckview/deck_view_container.cpp @@ -2,6 +2,7 @@ #include "../../client/settings/cache_settings.h" #include "../../interface/card_picture_loader/card_picture_loader.h" +#include "../../interface/deck_loader/deck_loader.h" #include "../../interface/widgets/dialogs/dlg_load_deck.h" #include "../../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h" #include "../../interface/widgets/dialogs/dlg_load_deck_from_website.h" @@ -16,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/cockatrice/src/game/deckview/deck_view_container.h b/cockatrice/src/game/deckview/deck_view_container.h index 7f283527f..df381561b 100644 --- a/cockatrice/src/game/deckview/deck_view_container.h +++ b/cockatrice/src/game/deckview/deck_view_container.h @@ -7,8 +7,9 @@ #ifndef DECK_VIEW_CONTAINER_H #define DECK_VIEW_CONTAINER_H +#include "../../interface/deck_loader/deck_loader.h" + #include -#include class QVBoxLayout; class AbstractCardItem; diff --git a/cockatrice/src/game/player/player_info.h b/cockatrice/src/game/player/player_info.h index 81f3f1487..d60c245e2 100644 --- a/cockatrice/src/game/player/player_info.h +++ b/cockatrice/src/game/player/player_info.h @@ -7,6 +7,7 @@ #ifndef COCKATRICE_PLAYER_INFO_H #define COCKATRICE_PLAYER_INFO_H +#include "../../interface/deck_loader/deck_loader.h" #include "../zones/hand_zone.h" #include "../zones/pile_zone.h" #include "../zones/stack_zone.h" @@ -14,7 +15,6 @@ #include "player_target.h" #include -#include #include class PlayerInfo : public QObject diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_loader.cpp b/cockatrice/src/interface/deck_loader/deck_loader.cpp similarity index 84% rename from libcockatrice_models/libcockatrice/models/deck_list/deck_loader.cpp rename to cockatrice/src/interface/deck_loader/deck_loader.cpp index 95f4d9224..34d30d8ad 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_loader.cpp +++ b/cockatrice/src/interface/deck_loader/deck_loader.cpp @@ -7,8 +7,13 @@ #include #include #include +#include #include #include +#include +#include +#include +#include #include #include #include @@ -603,3 +608,97 @@ QString DeckLoader::getCompleteCardName(const QString &cardName) const return cardName; } + +void DeckLoader::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node) +{ + const int totalColumns = 2; + + if (node->height() == 1) { + QTextBlockFormat blockFormat; + QTextCharFormat charFormat; + charFormat.setFontPointSize(11); + charFormat.setFontWeight(QFont::Bold); + cursor->insertBlock(blockFormat, charFormat); + + QTextTableFormat tableFormat; + tableFormat.setCellPadding(0); + tableFormat.setCellSpacing(0); + tableFormat.setBorder(0); + QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat); + for (int i = 0; i < node->size(); i++) { + auto *card = dynamic_cast(node->at(i)); + + QTextCharFormat cellCharFormat; + cellCharFormat.setFontPointSize(9); + + QTextTableCell cell = table->cellAt(i, 0); + cell.setFormat(cellCharFormat); + QTextCursor cellCursor = cell.firstCursorPosition(); + cellCursor.insertText(QString("%1 ").arg(card->getNumber())); + + cell = table->cellAt(i, 1); + cell.setFormat(cellCharFormat); + cellCursor = cell.firstCursorPosition(); + cellCursor.insertText(card->getName()); + } + } else if (node->height() == 2) { + QTextBlockFormat blockFormat; + QTextCharFormat charFormat; + charFormat.setFontPointSize(14); + charFormat.setFontWeight(QFont::Bold); + + cursor->insertBlock(blockFormat, charFormat); + + QTextTableFormat tableFormat; + tableFormat.setCellPadding(10); + tableFormat.setCellSpacing(0); + tableFormat.setBorder(0); + QVector constraints; + for (int i = 0; i < totalColumns; i++) { + constraints << QTextLength(QTextLength::PercentageLength, 100.0 / totalColumns); + } + tableFormat.setColumnWidthConstraints(constraints); + + QTextTable *table = cursor->insertTable(1, totalColumns, tableFormat); + for (int i = 0; i < node->size(); i++) { + QTextCursor cellCursor = table->cellAt(0, (i * totalColumns) / node->size()).lastCursorPosition(); + printDeckListNode(&cellCursor, dynamic_cast(node->at(i))); + } + } + + cursor->movePosition(QTextCursor::End); +} + +void DeckLoader::printDeckList(QPrinter *printer) +{ + QTextDocument doc; + + QFont font("Serif"); + font.setStyleHint(QFont::Serif); + doc.setDefaultFont(font); + + QTextCursor cursor(&doc); + + QTextBlockFormat headerBlockFormat; + QTextCharFormat headerCharFormat; + headerCharFormat.setFontPointSize(16); + headerCharFormat.setFontWeight(QFont::Bold); + + cursor.insertBlock(headerBlockFormat, headerCharFormat); + cursor.insertText(getName()); + + headerCharFormat.setFontPointSize(12); + cursor.insertBlock(headerBlockFormat, headerCharFormat); + cursor.insertText(getComments()); + cursor.insertBlock(headerBlockFormat, headerCharFormat); + + for (int i = 0; i < getRoot()->size(); i++) { + cursor.insertHtml("
"); + // cursor.insertHtml("
"); + cursor.insertBlock(headerBlockFormat, headerCharFormat); + + printDeckListNode(&cursor, dynamic_cast(getRoot()->at(i))); + } + + doc.print(printer); +} diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_loader.h b/cockatrice/src/interface/deck_loader/deck_loader.h similarity index 91% rename from libcockatrice_models/libcockatrice/models/deck_list/deck_loader.h rename to cockatrice/src/interface/deck_loader/deck_loader.h index f11ded444..a7af3bad9 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_loader.h +++ b/cockatrice/src/interface/deck_loader/deck_loader.h @@ -8,6 +8,8 @@ #define DECK_LOADER_H #include +#include +#include #include inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader") @@ -19,6 +21,13 @@ signals: void deckLoaded(); void loadFinished(bool success); +public slots: + /** + * @brief Prints the decklist to the provided QPrinter. + * @param printer The printer to render the decklist to. + */ + void printDeckList(QPrinter *printer); + public: enum FileFormat { @@ -93,6 +102,9 @@ public: bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true) const; bool convertToCockatriceFormat(QString fileName); +private: + void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node); + protected: void saveToStream_DeckHeader(QTextStream &out) const; void saveToStream_DeckZone(QTextStream &out, diff --git a/cockatrice/src/interface/widgets/deck_analytics/mana_base_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/mana_base_widget.cpp index 29fa3ece8..27079dd52 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/mana_base_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/mana_base_widget.cpp @@ -1,5 +1,6 @@ #include "mana_base_widget.h" +#include "../../deck_loader/deck_loader.h" #include "../general/display/banner_widget.h" #include "../general/display/bar_widget.h" @@ -8,7 +9,6 @@ #include #include #include -#include ManaBaseWidget::ManaBaseWidget(QWidget *parent, DeckListModel *_deckListModel) : QWidget(parent), deckListModel(_deckListModel) diff --git a/cockatrice/src/interface/widgets/deck_analytics/mana_curve_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/mana_curve_widget.cpp index e2067326a..668b3afd5 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/mana_curve_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/mana_curve_widget.cpp @@ -1,13 +1,13 @@ #include "mana_curve_widget.h" #include "../../../main.h" +#include "../../deck_loader/deck_loader.h" #include "../general/display/banner_widget.h" #include "../general/display/bar_widget.h" #include #include #include -#include #include ManaCurveWidget::ManaCurveWidget(QWidget *parent, DeckListModel *_deckListModel) diff --git a/cockatrice/src/interface/widgets/deck_analytics/mana_devotion_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/mana_devotion_widget.cpp index d23d6bfab..4454caef1 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/mana_devotion_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/mana_devotion_widget.cpp @@ -1,6 +1,7 @@ #include "mana_devotion_widget.h" #include "../../../main.h" +#include "../../deck_loader/deck_loader.h" #include "../general/display/banner_widget.h" #include "../general/display/bar_widget.h" @@ -8,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp index 0e6b535bf..fed70f5d6 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp @@ -1,6 +1,8 @@ #include "deck_editor_deck_dock_widget.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/deck_loader.h" +#include "deck_list_style_proxy.h" #include #include @@ -29,9 +31,13 @@ void DeckEditorDeckDockWidget::createDeckDock() deckModel = new DeckListModel(this); deckModel->setObjectName("deckModel"); connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash); + + DeckListStyleProxy *proxy = new DeckListStyleProxy(this); + proxy->setSourceModel(deckModel); + deckView = new QTreeView(); deckView->setObjectName("deckView"); - deckView->setModel(deckModel); + deckView->setModel(proxy); deckView->setUniformRowHeights(true); deckView->setSortingEnabled(true); deckView->sortByColumn(1, Qt::AscendingOrder); @@ -111,8 +117,8 @@ void DeckEditorDeckDockWidget::createDeckDock() activeGroupCriteriaComboBox->addItem(tr("Mana Cost"), DeckListModelGroupCriteria::MANA_COST); activeGroupCriteriaComboBox->addItem(tr("Colors"), DeckListModelGroupCriteria::COLOR); connect(activeGroupCriteriaComboBox, QOverload::of(&QComboBox::currentIndexChanged), [this]() { - deckModel->setActiveGroupCriteria( - static_cast(activeGroupCriteriaComboBox->currentData(Qt::UserRole).toInt())); + deckModel->setActiveGroupCriteria(static_cast( + activeGroupCriteriaComboBox->currentData(Qt::UserRole).toInt())); deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder()); deckView->expandAll(); deckView->expandAll(); @@ -366,7 +372,11 @@ void DeckEditorDeckDockWidget::syncBannerCardComboBoxSelectionWithDeck() */ void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck) { + deckLoader = _deck; + deckModel->setDeckList(_deck); + connect(_deck, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree); + connect(_deck, &DeckLoader::deckHashChanged, deckModel, &DeckListModel::deckHashChanged); nameEdit->setText(deckModel->getDeckList()->getName()); commentsEdit->setText(deckModel->getDeckList()->getComments()); @@ -383,9 +393,9 @@ void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck) emit deckChanged(); } -DeckLoader *DeckEditorDeckDockWidget::getDeckList() +DeckLoader *DeckEditorDeckDockWidget::getDeckLoader() { - return deckModel->getDeckList(); + return deckLoader; } /** diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h index 62810e7eb..3c53d508f 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h @@ -27,6 +27,7 @@ class DeckEditorDeckDockWidget : public QDockWidget Q_OBJECT public: explicit DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent); + DeckLoader *deckLoader; DeckListModel *deckModel; QTreeView *deckView; QComboBox *bannerCardComboBox; @@ -50,7 +51,7 @@ public slots: void cleanDeck(); void updateBannerCardComboBox(); void setDeck(DeckLoader *_deck); - DeckLoader *getDeckList(); + DeckLoader *getDeckLoader(); void actIncrement(); bool swapCard(const QModelIndex &idx); void actDecrementCard(const ExactCard &card, QString zoneName); diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp new file mode 100644 index 000000000..555d4524f --- /dev/null +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp @@ -0,0 +1,37 @@ +#include "deck_list_style_proxy.h" + +#include +#include +#include +#include + +QVariant DeckListStyleProxy::data(const QModelIndex &index, int role) const +{ + QVariant value = QIdentityProxyModel::data(index, role); + + const bool isCard = QIdentityProxyModel::data(index, DeckRoles::IsCardRole).toBool(); + + if (role == Qt::FontRole && !isCard) { + QFont f; + f.setBold(true); + return f; + } + + if (role == Qt::BackgroundRole) { + if (isCard) { + const bool legal = QIdentityProxyModel::data(index, DeckRoles::IsLegalRole).toBool(); + int base = 255 - (index.row() % 2) * 30; + return legal ? QBrush(QColor(base, base, base)) : QBrush(QColor(255, base / 3, base / 3)); + } else { + int depth = QIdentityProxyModel::data(index, DeckRoles::DepthRole).toInt(); + int color = 90 + 60 * depth; + return QBrush(QColor(color, 255, color)); + } + } + + if (role == Qt::ForegroundRole) { + return QBrush(QColor(0, 0, 0)); + } + + return value; +} diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h new file mode 100644 index 000000000..a7e58eb02 --- /dev/null +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h @@ -0,0 +1,15 @@ +#ifndef COCKATRICE_DECK_LIST_STYLE_PROXY_H +#define COCKATRICE_DECK_LIST_STYLE_PROXY_H + +#include + +class DeckListStyleProxy : public QIdentityProxyModel +{ + Q_OBJECT +public: + using QIdentityProxyModel::QIdentityProxyModel; + + QVariant data(const QModelIndex &index, int role) const override; +}; + +#endif // COCKATRICE_DECK_LIST_STYLE_PROXY_H diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp index 4f21d7543..b87800909 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp @@ -1,8 +1,7 @@ #include "dlg_load_deck.h" #include "../../../client/settings/cache_settings.h" - -#include +#include "../../deck_loader/deck_loader.h" DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck")) { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp index cfd99872a..15ee0e21d 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp @@ -1,6 +1,7 @@ #include "dlg_load_deck_from_clipboard.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/deck_loader.h" #include "dlg_settings.h" #include @@ -12,7 +13,6 @@ #include #include #include -#include /** * Creates the main layout and connects the signals that are common to all versions of this window diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp index a2c68410c..31e2f8d14 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp @@ -1,5 +1,6 @@ #include "dlg_select_set_for_cards.h" +#include "../../deck_loader/deck_loader.h" #include "../interface/widgets/cards/card_info_picture_widget.h" #include "../interface/widgets/general/layout_containers/flow_widget.h" #include "dlg_select_set_for_cards.h" @@ -16,7 +17,6 @@ #include #include #include -#include #include #include @@ -162,14 +162,14 @@ void DlgSelectSetForCards::actOK() void DlgSelectSetForCards::actClear() { - model->getDeckList()->clearSetNamesAndNumbers(); + qobject_cast(model->getDeckList())->clearSetNamesAndNumbers(); accept(); } void DlgSelectSetForCards::actSetAllToPreferred() { - model->getDeckList()->clearSetNamesAndNumbers(); - model->getDeckList()->setProviderIdToPreferredPrinting(); + qobject_cast(model->getDeckList())->clearSetNamesAndNumbers(); + qobject_cast(model->getDeckList())->setProviderIdToPreferredPrinting(); accept(); } diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h index b16319da9..bf8ade36a 100644 --- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h @@ -7,12 +7,12 @@ #ifndef ALL_ZONES_CARD_AMOUNT_WIDGET_H #define ALL_ZONES_CARD_AMOUNT_WIDGET_H +#include "../../deck_loader/deck_loader.h" #include "card_amount_widget.h" #include #include #include -#include class AllZonesCardAmountWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h index 8bb3b2ee5..543964a79 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h @@ -9,6 +9,7 @@ #define CARD_AMOUNT_WIDGET_H #include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" +#include "../../deck_loader/deck_loader.h" #include "../general/display/dynamic_font_size_push_button.h" #include @@ -18,7 +19,6 @@ #include #include #include -#include class CardAmountWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp index a5406aa6c..4fbe4a1c1 100644 --- a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp +++ b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp @@ -209,7 +209,7 @@ void AbstractTabDeckEditor::openDeck(DeckLoader *deck) void AbstractTabDeckEditor::setDeck(DeckLoader *_deck) { deckDockWidget->setDeck(_deck); - CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList())); + CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckLoader()->getCardRefList())); setModified(false); aDeckDockVisible->setChecked(true); @@ -217,9 +217,9 @@ void AbstractTabDeckEditor::setDeck(DeckLoader *_deck) } /** @brief Returns the currently loaded deck. */ -DeckLoader *AbstractTabDeckEditor::getDeckList() const +DeckLoader *AbstractTabDeckEditor::getDeckLoader() const { - return deckDockWidget->getDeckList(); + return deckDockWidget->getDeckLoader(); } /** @@ -237,7 +237,7 @@ void AbstractTabDeckEditor::setModified(bool _modified) */ bool AbstractTabDeckEditor::isBlankNewDeck() const { - DeckLoader *deck = getDeckList(); + DeckLoader *deck = deckDockWidget->getDeckLoader(); return !modified && deck->isBlankDeck() && deck->hasNotBeenLoaded(); } @@ -377,7 +377,7 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo */ bool AbstractTabDeckEditor::actSaveDeck() { - DeckLoader *const deck = getDeckList(); + DeckLoader *const deck = getDeckLoader(); if (deck->getLastRemoteDeckId() != -1) { QString deckString = deck->writeToString_Native(); if (deckString.length() > MAX_FILE_LENGTH) { @@ -418,7 +418,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs() dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setDefaultSuffix("cod"); dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS); - dialog.selectFile(getDeckList()->getName().trimmed()); + dialog.selectFile(getDeckLoader()->getName().trimmed()); if (!dialog.exec()) return false; @@ -426,7 +426,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs() QString fileName = dialog.selectedFiles().at(0); DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName); - if (!getDeckList()->saveToFile(fileName, fmt)) { + if (!getDeckLoader()->saveToFile(fileName, fmt)) { QMessageBox::critical( this, tr("Error"), tr("The deck could not be saved.\nPlease check that the directory is writable and try again.")); @@ -480,7 +480,7 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard() */ void AbstractTabDeckEditor::editDeckInClipboard(bool annotated) { - DlgEditDeckInClipboard dlg(*getDeckList(), annotated, this); + DlgEditDeckInClipboard dlg(*getDeckLoader(), annotated, this); if (!dlg.exec()) return; @@ -504,32 +504,32 @@ void AbstractTabDeckEditor::actEditDeckInClipboardRaw() /** @brief Saves deck to clipboard with set info and annotation. */ void AbstractTabDeckEditor::actSaveDeckToClipboard() { - getDeckList()->saveToClipboard(true, true); + getDeckLoader()->saveToClipboard(true, true); } /** @brief Saves deck to clipboard with annotation, without set info. */ void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo() { - getDeckList()->saveToClipboard(true, false); + getDeckLoader()->saveToClipboard(true, false); } /** @brief Saves deck to clipboard without annotations, with set info. */ void AbstractTabDeckEditor::actSaveDeckToClipboardRaw() { - getDeckList()->saveToClipboard(false, true); + getDeckLoader()->saveToClipboard(false, true); } /** @brief Saves deck to clipboard without annotations or set info. */ void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo() { - getDeckList()->saveToClipboard(false, false); + getDeckLoader()->saveToClipboard(false, false); } /** @brief Prints the deck using a QPrintPreviewDialog. */ void AbstractTabDeckEditor::actPrintDeck() { auto *dlg = new QPrintPreviewDialog(this); - connect(dlg, &QPrintPreviewDialog::paintRequested, deckDockWidget->deckModel, &DeckListModel::printDeckList); + connect(dlg, &QPrintPreviewDialog::paintRequested, deckDockWidget->getDeckLoader(), &DeckLoader::printDeckList); dlg->exec(); } @@ -562,7 +562,7 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite() */ void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website) { - if (DeckLoader *const deck = getDeckList()) { + if (DeckLoader *const deck = getDeckLoader()) { QString decklistUrlString = deck->exportDeckToDecklist(website); // Check to make sure the string isn't empty. if (decklistUrlString.isEmpty()) { @@ -600,14 +600,14 @@ void AbstractTabDeckEditor::actExportDeckDecklistXyz() void AbstractTabDeckEditor::actAnalyzeDeckDeckstats() { auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this); - interface->analyzeDeck(getDeckList()); + interface->analyzeDeck(getDeckLoader()); } /** @brief Analyzes the deck using TappedOut. */ void AbstractTabDeckEditor::actAnalyzeDeckTappedout() { auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this); - interface->analyzeDeck(getDeckList()); + interface->analyzeDeck(getDeckLoader()); } /** @brief Applies a new filter tree to the database display. */ diff --git a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h index 26fc78832..3716566d0 100644 --- a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h +++ b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h @@ -117,7 +117,7 @@ public: void openDeck(DeckLoader *deck); /** @brief Returns the currently active deck. */ - DeckLoader *getDeckList() const; + DeckLoader *getDeckLoader() const; /** @brief Sets the modified state of the tab. * @param _windowModified Whether the tab is modified. diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp index d525baafb..acb5308a6 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp @@ -1,11 +1,12 @@ #include "edhrec_deck_api_response.h" +#include "../../../../../../deck_loader/deck_loader.h" + #include #include #include #include #include -#include void EdhrecDeckApiResponse::fromJson(const QJsonArray &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h index 2666789e9..b362819df 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h @@ -7,12 +7,13 @@ #ifndef EDHREC_DECK_API_RESPONSE_H #define EDHREC_DECK_API_RESPONSE_H +#include "../../../../../../deck_loader/deck_loader.h" + #include #include #include #include #include -#include class EdhrecDeckApiResponse { diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp index cf8acec5a..8760c775c 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp @@ -1,6 +1,7 @@ #include "tab_deck_storage.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/deck_loader.h" #include "../interface/widgets/server/remote/remote_decklist_tree_widget.h" #include "../interface/widgets/utility/get_text_with_max.h" @@ -19,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h index fbc7062cc..c620900c4 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h @@ -8,6 +8,7 @@ #ifndef TAB_SUPERVISOR_H #define TAB_SUPERVISOR_H +#include "../../deck_loader/deck_loader.h" #include "../interface/widgets/server/user/user_list_proxy.h" #include "abstract_tab_deck_editor.h" #include "api/edhrec/tab_edhrec.h" @@ -23,7 +24,6 @@ #include #include #include -#include inline Q_LOGGING_CATEGORY(TabSupervisorLog, "tab_supervisor"); diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp index 7e4e2407d..ae9cb10ef 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp @@ -1,10 +1,10 @@ #include "visual_deck_editor_sample_hand_widget.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/deck_loader.h" #include "../cards/card_info_picture_widget.h" #include -#include #include VisualDeckEditorSampleHandWidget::VisualDeckEditorSampleHandWidget(QWidget *parent, DeckListModel *_deckListModel) diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp index d9acfce5d..005efd6db 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp @@ -1,6 +1,7 @@ #include "visual_deck_editor_widget.h" #include "../../../main.h" +#include "../../deck_loader/deck_loader.h" #include "../../layouts/overlap_layout.h" #include "../cards/card_info_picture_with_text_overlay_widget.h" #include "../cards/deck_card_zone_display_widget.h" @@ -22,7 +23,6 @@ #include #include #include -#include #include VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_deckListModel) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h index 5f6059549..4270e38e5 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h @@ -7,10 +7,10 @@ #ifndef DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H #define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H +#include "../../../deck_loader/deck_loader.h" #include "deck_preview_widget.h" #include -#include inline bool confirmOverwriteIfExists(QWidget *parent, const QString &filePath); diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h index 154af3dfc..49bf3335c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h @@ -7,6 +7,7 @@ #ifndef DECK_PREVIEW_WIDGET_H #define DECK_PREVIEW_WIDGET_H +#include "../../../deck_loader/deck_loader.h" #include "../../cards/additional_info/color_identity_widget.h" #include "../../cards/deck_preview_card_picture_widget.h" #include "../visual_deck_storage_widget.h" @@ -18,7 +19,6 @@ #include #include #include -#include class QMenu; class VisualDeckStorageWidget; diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h index f49d2544b..7db6fb0c7 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h @@ -7,6 +7,7 @@ #ifndef VISUAL_DECK_STORAGE_WIDGET_H #define VISUAL_DECK_STORAGE_WIDGET_H +#include "../../deck_loader/deck_loader.h" #include "../cards/card_size_widget.h" #include "../general/layout_containers/flow_widget.h" #include "../quick_settings/settings_button_widget.h" diff --git a/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt b/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt index cadc98cde..ef66feaf2 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt +++ b/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt @@ -2,7 +2,7 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) -set(HEADERS deck_list_model.h deck_list_sort_filter_proxy_model.h deck_loader.h) +set(HEADERS deck_list_model.h deck_list_sort_filter_proxy_model.h) if(Qt6_FOUND) qt6_wrap_cpp(MOC_SOURCES ${HEADERS}) @@ -12,7 +12,6 @@ endif() add_library( libcockatrice_models_deck_list STATIC ${MOC_SOURCES} deck_list_model.cpp deck_list_sort_filter_proxy_model.cpp - deck_loader.cpp ) target_include_directories(libcockatrice_models_deck_list PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp index c34d2115e..52e3b678c 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp @@ -1,24 +1,12 @@ #include "deck_list_model.h" -#include "deck_loader.h" - -#include -#include -#include -#include -#include -#include -#include -#include #include DeckListModel::DeckListModel(QObject *parent) : QAbstractItemModel(parent), lastKnownColumn(1), lastKnownOrder(Qt::AscendingOrder) { - deckList = new DeckLoader; + deckList = new DeckList; deckList->setParent(this); - connect(deckList, &DeckLoader::deckLoaded, this, &DeckListModel::rebuildTree); - connect(deckList, &DeckLoader::deckHashChanged, this, &DeckListModel::deckHashChanged); root = new InnerDecklistNode; } @@ -107,83 +95,96 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const return {}; } - auto *temp = static_cast(index.internalPointer()); - auto *card = dynamic_cast(temp); - if (card == nullptr) { - const auto *node = dynamic_cast(temp); + auto *node = static_cast(index.internalPointer()); + auto *card = dynamic_cast(node); + + // Group node + if (!card) { + const auto *group = dynamic_cast(node); + switch (role) { - case Qt::FontRole: { - QFont f; - f.setBold(true); - return f; - } case Qt::DisplayRole: case Qt::EditRole: { switch (index.column()) { - case 0: - return node->recursiveCount(true); - case 1: { - if (role == Qt::DisplayRole) - return node->getVisibleName(); - return node->getName(); - } - case 2: { - return node->getCardSetShortName(); - } - case 3: { - return node->getCardCollectorNumber(); - } - case 4: { - return node->getCardProviderId(); - } + case DeckListModelColumns::CARD_AMOUNT: + return group->recursiveCount(true); + case DeckListModelColumns::CARD_NAME: + if (role == Qt::DisplayRole) { + return group->getVisibleName(); + } + return group->getName(); + case DeckListModelColumns::CARD_SET: + return group->getCardSetShortName(); + case DeckListModelColumns::CARD_COLLECTOR_NUMBER: + return group->getCardCollectorNumber(); + case DeckListModelColumns::CARD_PROVIDER_ID: + return group->getCardProviderId(); default: return {}; } } - case Qt::UserRole + 1: + case DeckRoles::IsCardRole: return false; - case Qt::BackgroundRole: { - int color = 90 + 60 * node->depth(); - return QBrush(QColor(color, 255, color)); - } - case Qt::ForegroundRole: { - return QBrush(QColor(0, 0, 0)); - } - default: - return {}; - } - } else { - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - switch (index.column()) { - case 0: - return card->getNumber(); - case 1: - return card->getName(); - case 2: - return card->getCardSetShortName(); - case 3: - return card->getCardCollectorNumber(); - case 4: - return card->getCardProviderId(); - default: - return {}; - } - } - case Qt::UserRole + 1: + + case DeckRoles::DepthRole: + return group->depth(); + + // legality does not apply to group nodes + case DeckRoles::IsLegalRole: return true; - case Qt::BackgroundRole: { - int color = 255 - (index.row() % 2) * 30; - return QBrush(QColor(color, color, color)); - } - case Qt::ForegroundRole: { - return QBrush(QColor(0, 0, 0)); - } + default: return {}; } } + + // Card node + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + switch (index.column()) { + case DeckListModelColumns::CARD_AMOUNT: + return card->getNumber(); + case DeckListModelColumns::CARD_NAME: + return card->getName(); + case DeckListModelColumns::CARD_SET: + return card->getCardSetShortName(); + case DeckListModelColumns::CARD_COLLECTOR_NUMBER: + return card->getCardCollectorNumber(); + case DeckListModelColumns::CARD_PROVIDER_ID: + return card->getCardProviderId(); + default: + return {}; + } + + case DeckRoles::IsCardRole: { + return true; + } + + case DeckRoles::DepthRole: { + return card->depth(); + } + + default: { + return {}; + } + } +} + +void DeckListModel::emitBackgroundUpdates(const QModelIndex &parent) +{ + int rows = rowCount(parent); + if (rows == 0) + return; + + QModelIndex topLeft = index(0, 0, parent); + QModelIndex bottomRight = index(rows - 1, columnCount() - 1, parent); + emit dataChanged(topLeft, bottomRight, {Qt::BackgroundRole}); + + for (int r = 0; r < rows; ++r) { + QModelIndex child = index(r, 0, parent); + emitBackgroundUpdates(child); + } } QVariant DeckListModel::headerData(const int section, const Qt::Orientation orientation, const int role) const @@ -197,15 +198,15 @@ QVariant DeckListModel::headerData(const int section, const Qt::Orientation orie } switch (section) { - case 0: + case DeckListModelColumns::CARD_AMOUNT: return tr("Count"); - case 1: + case DeckListModelColumns::CARD_NAME: return tr("Card"); - case 2: + case DeckListModelColumns::CARD_SET: return tr("Set"); - case 3: + case DeckListModelColumns::CARD_COLLECTOR_NUMBER: return tr("Number"); - case 4: + case DeckListModelColumns::CARD_PROVIDER_ID: return tr("Provider ID"); default: return {}; @@ -262,19 +263,19 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con } switch (index.column()) { - case 0: + case DeckListModelColumns::CARD_AMOUNT: node->setNumber(value.toInt()); break; - case 1: + case DeckListModelColumns::CARD_NAME: node->setName(value.toString()); break; - case 2: + case DeckListModelColumns::CARD_SET: node->setCardSetShortName(value.toString()); break; - case 3: + case DeckListModelColumns::CARD_COLLECTOR_NUMBER: node->setCardCollectorNumber(value.toString()); break; - case 4: + case DeckListModelColumns::CARD_PROVIDER_ID: node->setCardProviderId(value.toString()); break; default: @@ -520,7 +521,7 @@ void DeckListModel::sort(int column, Qt::SortOrder order) emit layoutChanged(); } -void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria newCriteria) +void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria::Type newCriteria) { activeGroupCriteria = newCriteria; rebuildTree(); @@ -528,19 +529,17 @@ void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria newCriteri void DeckListModel::cleanList() { - setDeckList(new DeckLoader); + setDeckList(new DeckList); } /** * @param _deck The deck. Takes ownership of the object */ -void DeckListModel::setDeckList(DeckLoader *_deck) +void DeckListModel::setDeckList(DeckList *_deck) { deckList->deleteLater(); deckList = _deck; deckList->setParent(this); - connect(deckList, &DeckLoader::deckLoaded, this, &DeckListModel::rebuildTree); - connect(deckList, &DeckLoader::deckHashChanged, this, &DeckListModel::deckHashChanged); rebuildTree(); } @@ -628,98 +627,4 @@ QList *DeckListModel::getZones() const zones->append(currentZone->getName()); } return zones; -} - -void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node) -{ - const int totalColumns = 2; - - if (node->height() == 1) { - QTextBlockFormat blockFormat; - QTextCharFormat charFormat; - charFormat.setFontPointSize(11); - charFormat.setFontWeight(QFont::Bold); - cursor->insertBlock(blockFormat, charFormat); - - QTextTableFormat tableFormat; - tableFormat.setCellPadding(0); - tableFormat.setCellSpacing(0); - tableFormat.setBorder(0); - QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat); - for (int i = 0; i < node->size(); i++) { - auto *card = dynamic_cast(node->at(i)); - - QTextCharFormat cellCharFormat; - cellCharFormat.setFontPointSize(9); - - QTextTableCell cell = table->cellAt(i, 0); - cell.setFormat(cellCharFormat); - QTextCursor cellCursor = cell.firstCursorPosition(); - cellCursor.insertText(QString("%1 ").arg(card->getNumber())); - - cell = table->cellAt(i, 1); - cell.setFormat(cellCharFormat); - cellCursor = cell.firstCursorPosition(); - cellCursor.insertText(card->getName()); - } - } else if (node->height() == 2) { - QTextBlockFormat blockFormat; - QTextCharFormat charFormat; - charFormat.setFontPointSize(14); - charFormat.setFontWeight(QFont::Bold); - - cursor->insertBlock(blockFormat, charFormat); - - QTextTableFormat tableFormat; - tableFormat.setCellPadding(10); - tableFormat.setCellSpacing(0); - tableFormat.setBorder(0); - QVector constraints; - for (int i = 0; i < totalColumns; i++) { - constraints << QTextLength(QTextLength::PercentageLength, 100.0 / totalColumns); - } - tableFormat.setColumnWidthConstraints(constraints); - - QTextTable *table = cursor->insertTable(1, totalColumns, tableFormat); - for (int i = 0; i < node->size(); i++) { - QTextCursor cellCursor = table->cellAt(0, (i * totalColumns) / node->size()).lastCursorPosition(); - printDeckListNode(&cellCursor, dynamic_cast(node->at(i))); - } - } - - cursor->movePosition(QTextCursor::End); -} - -void DeckListModel::printDeckList(QPrinter *printer) -{ - QTextDocument doc; - - QFont font("Serif"); - font.setStyleHint(QFont::Serif); - doc.setDefaultFont(font); - - QTextCursor cursor(&doc); - - QTextBlockFormat headerBlockFormat; - QTextCharFormat headerCharFormat; - headerCharFormat.setFontPointSize(16); - headerCharFormat.setFontWeight(QFont::Bold); - - cursor.insertBlock(headerBlockFormat, headerCharFormat); - cursor.insertText(deckList->getName()); - - headerCharFormat.setFontPointSize(12); - cursor.insertBlock(headerBlockFormat, headerCharFormat); - cursor.insertText(deckList->getComments()); - cursor.insertBlock(headerBlockFormat, headerCharFormat); - - for (int i = 0; i < root->size(); i++) { - cursor.insertHtml("
"); - // cursor.insertHtml("
"); - cursor.insertBlock(headerBlockFormat, headerCharFormat); - - printDeckListNode(&cursor, dynamic_cast(root->at(i))); - } - - doc.print(printer); -} +} \ No newline at end of file diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h index e169af395..8beabd4ba 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h @@ -8,20 +8,73 @@ #include #include -class DeckLoader; class CardDatabase; class QPrinter; class QTextCursor; /** - * @brief Specifies the criteria used to group cards in the DeckListModel. + * @namespace DeckRoles + * @brief Custom model roles used by the DeckListModel for data retrieval. + * + * These roles extend Qt's item data roles starting at Qt::UserRole. */ -enum DeckListModelGroupCriteria +namespace DeckRoles +{ +/** + * @enum DeckRoles + * @brief Custom data roles for deck-related model items. + * + * These roles are used to retrieve specialized data from the DeckListModel. + */ +enum +{ + IsCardRole = Qt::UserRole + 1, /**< Indicates whether the item represents a card. */ + DepthRole, /**< Depth level within the deck's grouping hierarchy. */ + IsLegalRole /**< Whether the card is legal in the current deck format. */ +}; +} // namespace DeckRoles + +/** + * @namespace DeckListModelColumns + * @brief Column indices for the DeckListModel. + * + * These values map to the columns in the deck list table representation. + */ +namespace DeckListModelColumns +{ +/** + * @enum DeckListModelColumns + * @brief Column identifiers for displaying card information in the deck list. + */ +enum +{ + CARD_AMOUNT = 0, /**< The number of copies of the card. */ + CARD_NAME = 1, /**< The card's name. */ + CARD_SET = 2, /**< The set or expansion the card belongs to. */ + CARD_COLLECTOR_NUMBER = 3, /**< Collector number of the card within the set. */ + CARD_PROVIDER_ID = 4 /**< ID used by the external data provider (e.g., Scryfall). */ +}; +} // namespace DeckListModelColumns + +/** + * @namespace DeckListModelGroupCriteria + * @brief Specifies criteria used to group cards in the DeckListModel. + * + * These values determine how cards are grouped in UI views such as the deck editor. + */ +namespace DeckListModelGroupCriteria +{ +/** + * @enum DeckListModelGroupCriteria + * @brief Available grouping strategies for deck visualization. + */ +enum Type { MAIN_TYPE, /**< Group cards by their main type (e.g., creature, instant). */ - MANA_COST, /**< Group cards by their mana cost. */ + MANA_COST, /**< Group cards by their total mana cost. */ COLOR /**< Group cards by their color identity. */ }; +} // namespace DeckListModelGroupCriteria /** * @class DecklistModelCardNode @@ -119,12 +172,12 @@ public: * * Slots: * - rebuildTree(): rebuilds the model structure from the underlying DeckLoader. - * - printDeckList(): renders the decklist to a QPrinter. */ class DeckListModel : public QAbstractItemModel { Q_OBJECT -private slots: + +public slots: /** * @brief Rebuilds the model tree from the underlying DeckLoader. * @@ -133,13 +186,6 @@ private slots: */ void rebuildTree(); -public slots: - /** - * @brief Prints the decklist to the provided QPrinter. - * @param printer The printer to render the decklist to. - */ - void printDeckList(QPrinter *printer); - signals: /** * @brief Emitted whenever the deck hash changes due to modifications in the model. @@ -170,6 +216,7 @@ public: int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; + void emitBackgroundUpdates(const QModelIndex &parent); QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QModelIndex index(int row, int column, const QModelIndex &parent) const override; QModelIndex parent(const QModelIndex &index) const override; @@ -222,11 +269,11 @@ public: * @brief Removes all cards and resets the model. */ void cleanList(); - DeckLoader *getDeckList() const + DeckList *getDeckList() const { return deckList; } - void setDeckList(DeckLoader *_deck); + void setDeckList(DeckList *_deck); QList getCards() const; QList getCardsForZone(const QString &zoneName) const; @@ -236,12 +283,12 @@ public: * @brief Sets the criteria used to group cards in the model. * @param newCriteria The new grouping criteria. */ - void setActiveGroupCriteria(DeckListModelGroupCriteria newCriteria); + void setActiveGroupCriteria(DeckListModelGroupCriteria::Type newCriteria); private: - DeckLoader *deckList; /**< Pointer to the deck loader providing the underlying data. */ + DeckList *deckList; /**< Pointer to the deck loader providing the underlying data. */ InnerDecklistNode *root; /**< Root node of the model tree. */ - DeckListModelGroupCriteria activeGroupCriteria = DeckListModelGroupCriteria::MAIN_TYPE; + DeckListModelGroupCriteria::Type activeGroupCriteria = DeckListModelGroupCriteria::MAIN_TYPE; int lastKnownColumn; /**< Last column used for sorting. */ Qt::SortOrder lastKnownOrder; /**< Last known sort order. */ @@ -254,8 +301,6 @@ private: void emitRecursiveUpdates(const QModelIndex &index); void sortHelper(InnerDecklistNode *node, Qt::SortOrder order); - void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node); - template T getNode(const QModelIndex &index) const { if (!index.isValid())