[DeckList] Refactor: Create class to RAII underlying tree (#6412)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, 11) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, 13) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, skip, 12) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Fedora, RPM, 43) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Fedora, RPM, skip, 42) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Servatrice_Debian, DEB, yes, skip, 11) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, 24.04) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, skip, 22.04) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (yes, Arch, skip) (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (Windows10-installer, true, Visual Studio 17 2022, x64, 1, Windows, -Win10, win64_msvc2019_64, qtimageformats qtmultimedia qt… (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (Windows7-installer, true, Visual Studio 17 2022, x64, 1, Windows, -Win7, win64_msvc2019_64, 5.15.*, windows-2022, 7, Release) (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (false, Ninja, macOS, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*, macos-15, Apple, 15, Debug, 1, 16.4) (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (macOS13_Intel-package, false, Ninja, 1, macOS, 13, -macOS13_Intel, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*… (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (macOS14-package, false, Ninja, 1, macOS, -macOS14, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*, macos-14, Appl… (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (macOS15-package, false, Ninja, 1, macOS, -macOS15, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*, macos-15, Appl… (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run

* [DeckList] Create class to RAII underlying tree

* Update usages

* fixes after rebase

* update docs
This commit is contained in:
RickyRister 2025-12-14 15:56:58 -08:00 committed by GitHub
parent 589e9a15a6
commit b29909bdbe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 325 additions and 168 deletions

View File

@ -27,6 +27,8 @@ add_library(
libcockatrice/deck_list/tree/inner_deck_list_node.cpp
libcockatrice/deck_list/deck_list.cpp
libcockatrice/deck_list/deck_list_history_manager.cpp
libcockatrice/deck_list/deck_list_node_tree.cpp
libcockatrice/deck_list/deck_list_node_tree.h
)
add_dependencies(libcockatrice_deck_list libcockatrice_protocol)

View File

@ -83,26 +83,23 @@ bool DeckList::Metadata::isEmpty() const
}
DeckList::DeckList()
{
root = new InnerDecklistNode;
}
DeckList::DeckList(const DeckList &other)
: metadata(other.metadata), sideboardPlans(other.sideboardPlans), root(new InnerDecklistNode(other.getRoot())),
cachedDeckHash(other.cachedDeckHash)
{
}
DeckList::DeckList(const QString &nativeString)
{
root = new InnerDecklistNode;
loadFromString_Native(nativeString);
}
DeckList::DeckList(const Metadata &metadata,
const DecklistNodeTree &tree,
const QMap<QString, SideboardPlan *> &sideboardPlans)
: metadata(metadata), sideboardPlans(sideboardPlans), tree(tree)
{
}
DeckList::~DeckList()
{
delete root;
QMapIterator<QString, SideboardPlan *> i(sideboardPlans);
while (i.hasNext())
delete i.next().value();
@ -152,8 +149,7 @@ bool DeckList::readElement(QXmlStreamReader *xml)
}
}
} else if (childName == "zone") {
InnerDecklistNode *newZone = getZoneObjFromName(xml->attributes().value("name").toString());
newZone->readElement(xml);
tree.readZoneElement(xml);
} else if (childName == "sideboard_plan") {
SideboardPlan *newSideboardPlan = new SideboardPlan;
if (newSideboardPlan->readElement(xml)) {
@ -195,9 +191,7 @@ void DeckList::write(QXmlStreamWriter *xml) const
writeMetadata(xml, metadata);
// Write zones
for (int i = 0; i < root->size(); i++) {
root->at(i)->writeElement(xml);
}
tree.write(xml);
// Write sideboard plans
QMapIterator<QString, SideboardPlan *> i(sideboardPlans);
@ -456,25 +450,13 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
QString zoneName = sideboard ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
// make new entry in decklist
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), -1, setCode, collectorNumber);
tree.addCard(cardName, amount, zoneName, -1, setCode, collectorNumber);
}
refreshDeckHash();
return true;
}
InnerDecklistNode *DeckList::getZoneObjFromName(const QString &zoneName)
{
for (int i = 0; i < root->size(); i++) {
auto *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
if (node->getName() == zoneName) {
return node;
}
}
return new InnerDecklistNode(zoneName, root);
}
bool DeckList::loadFromFile_Plain(QIODevice *device)
{
QTextStream in(device);
@ -519,7 +501,7 @@ QString DeckList::writeToString_Plain(bool prefixSideboardCards, bool slashTappe
*/
void DeckList::cleanList(bool preserveMetadata)
{
root->clearTree();
tree.clear();
if (!preserveMetadata) {
metadata = {};
}
@ -528,7 +510,7 @@ void DeckList::cleanList(bool preserveMetadata)
QStringList DeckList::getCardList() const
{
auto nodes = getCardNodes();
auto nodes = tree.getCardNodes();
QStringList result;
std::transform(nodes.cbegin(), nodes.cend(), std::back_inserter(result), [](auto node) { return node->getName(); });
@ -538,7 +520,7 @@ QStringList DeckList::getCardList() const
QList<CardRef> DeckList::getCardRefList() const
{
auto nodes = getCardNodes();
auto nodes = tree.getCardNodes();
QList<CardRef> result;
std::transform(nodes.cbegin(), nodes.cend(), std::back_inserter(result),
@ -547,42 +529,19 @@ QList<CardRef> DeckList::getCardRefList() const
return result;
}
QList<const DecklistCardNode *> DeckList::getCardNodes(const QStringList &restrictToZones) const
QList<const DecklistCardNode *> DeckList::getCardNodes(const QSet<QString> &restrictToZones) const
{
QList<const DecklistCardNode *> result;
auto zoneNodes = getZoneNodes();
for (auto *zoneNode : zoneNodes) {
if (!restrictToZones.isEmpty() && !restrictToZones.contains(zoneNode->getName())) {
continue;
}
for (auto *cardNode : *zoneNode) {
auto *cardCardNode = dynamic_cast<DecklistCardNode *>(cardNode);
if (cardCardNode != nullptr) {
result.append(cardCardNode);
}
}
}
return result;
return tree.getCardNodes(restrictToZones);
}
QList<const InnerDecklistNode *> DeckList::getZoneNodes() const
{
QList<const InnerDecklistNode *> zones;
for (auto *node : *root) {
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(node);
if (!currentZone)
continue;
zones.append(currentZone);
}
return zones;
return tree.getZoneNodes();
}
int DeckList::getSideboardSize() const
{
auto cards = getCardNodes({DECK_ZONE_SIDE});
auto cards = tree.getCardNodes({DECK_ZONE_SIDE});
int size = 0;
for (auto card : cards) {
@ -594,93 +553,18 @@ int DeckList::getSideboardSize() const
DecklistCardNode *DeckList::addCard(const QString &cardName,
const QString &zoneName,
const int position,
int position,
const QString &cardSetName,
const QString &cardSetCollectorNumber,
const QString &cardProviderId,
const bool formatLegal)
bool formatLegal)
{
auto *zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));
if (zoneNode == nullptr) {
zoneNode = new InnerDecklistNode(zoneName, root);
}
auto *node = new DecklistCardNode(cardName, 1, zoneNode, position, cardSetName, cardSetCollectorNumber,
cardProviderId, formatLegal);
auto node =
tree.addCard(cardName, 1, zoneName, position, cardSetName, cardSetCollectorNumber, cardProviderId, formatLegal);
refreshDeckHash();
return node;
}
bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode)
{
if (node == root) {
return true;
}
bool updateHash = false;
if (rootNode == nullptr) {
rootNode = root;
updateHash = true;
}
int index = rootNode->indexOf(node);
if (index != -1) {
delete rootNode->takeAt(index);
if (rootNode->empty()) {
deleteNode(rootNode, rootNode->getParent());
}
if (updateHash) {
refreshDeckHash();
}
return true;
}
for (int i = 0; i < rootNode->size(); i++) {
auto *inner = dynamic_cast<InnerDecklistNode *>(rootNode->at(i));
if (inner) {
if (deleteNode(node, inner)) {
if (updateHash) {
refreshDeckHash();
}
return true;
}
}
}
return false;
}
static QString computeDeckHash(const DeckList &deckList)
{
auto mainDeckNodes = deckList.getCardNodes({DECK_ZONE_MAIN});
auto sideDeckNodes = deckList.getCardNodes({DECK_ZONE_SIDE});
static auto nodesToCardList = [](const QList<const DecklistCardNode *> &nodes, const QString &prefix = {}) {
QStringList result;
for (auto node : nodes) {
for (int i = 0; i < node->getNumber(); ++i) {
result.append(prefix + node->getName().toLower());
}
}
return result;
};
QStringList cardList = nodesToCardList(mainDeckNodes) + nodesToCardList(sideDeckNodes, "SB:");
cardList.sort();
QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1);
quint64 number = (((quint64)(unsigned char)deckHashArray[0]) << 32) +
(((quint64)(unsigned char)deckHashArray[1]) << 24) +
(((quint64)(unsigned char)deckHashArray[2] << 16)) +
(((quint64)(unsigned char)deckHashArray[3]) << 8) + (quint64)(unsigned char)deckHashArray[4];
return QString::number(number, 32).rightJustified(8, '0');
}
/**
* Gets the deck hash.
* The hash is computed on the first call to this method, and is cached until the decklist is modified.
@ -693,7 +577,7 @@ QString DeckList::getDeckHash() const
return cachedDeckHash;
}
cachedDeckHash = computeDeckHash(*this);
cachedDeckHash = tree.computeDeckHash();
return cachedDeckHash;
}
@ -710,15 +594,7 @@ void DeckList::refreshDeckHash()
*/
void DeckList::forEachCard(const std::function<void(InnerDecklistNode *, DecklistCardNode *)> &func) const
{
// Support for this is only possible if the internal structure
// doesn't get more complicated.
for (int i = 0; i < root->size(); i++) {
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
for (int j = 0; j < node->size(); j++) {
DecklistCardNode *card = dynamic_cast<DecklistCardNode *>(node->at(j));
func(node, card);
}
}
tree.forEachCard(func);
}
DeckListMemento DeckList::createMemento(const QString &reason) const

View File

@ -11,6 +11,7 @@
#define DECKLIST_H
#include "deck_list_memento.h"
#include "deck_list_node_tree.h"
#include "tree/inner_deck_list_node.h"
#include <QMap>
@ -107,14 +108,14 @@ public:
* - Provide hashing for deck identity (deck hash).
*
* ### Ownership:
* - Owns the root `InnerDecklistNode` tree.
* - Owns the `DecklistNodeTree`.
* - Owns `SideboardPlan` instances stored in `sideboardPlans`.
*
* ### Example workflow:
* ```
* DeckList deck;
* deck.setName("Mono Red Aggro");
* deck.addCard("Lightning Bolt", "main", -1);
* deck.addCard("Lightning Bolt", "main");
* deck.addTag("Aggro");
* deck.saveToFile_Native(device);
* ```
@ -140,7 +141,7 @@ public:
private:
Metadata metadata; ///< Deck metadata that is stored in the deck file
QMap<QString, SideboardPlan *> sideboardPlans; ///< Named sideboard plans.
InnerDecklistNode *root; ///< Root of the deck tree (zones + cards).
DecklistNodeTree tree; ///< The deck tree (zones + cards).
/**
* @brief Cached deck hash, recalculated lazily.
@ -148,9 +149,6 @@ private:
*/
mutable QString cachedDeckHash;
// Helpers for traversing the tree
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
public:
/// @name Metadata setters
///@{
@ -190,12 +188,24 @@ public:
/// @brief Construct an empty deck.
explicit DeckList();
/// @brief Copy constructor (deep copies the node tree)
DeckList(const DeckList &other);
/// @brief Construct from a serialized native-format string.
explicit DeckList(const QString &nativeString);
/// @brief Construct from components
DeckList(const Metadata &metadata,
const DecklistNodeTree &tree,
const QMap<QString, SideboardPlan *> &sideboardPlans = {});
virtual ~DeckList();
/**
* @brief Gets a pointer to the underlying node tree.
* Note: DO NOT call this method unless the object needs to have access to the underlying model.
* For now, only the DeckListModel should be calling this.
*/
DecklistNodeTree *getTree()
{
return &tree;
}
/// @name Metadata getters
/// The individual metadata getters still exist for backwards compatibility.
///@{
@ -270,25 +280,21 @@ public:
void cleanList(bool preserveMetadata = false);
bool isEmpty() const
{
return root->isEmpty() && metadata.isEmpty() && sideboardPlans.isEmpty();
return tree.isEmpty() && metadata.isEmpty() && sideboardPlans.isEmpty();
}
QStringList getCardList() const;
QList<CardRef> getCardRefList() const;
QList<const DecklistCardNode *> getCardNodes(const QStringList &restrictToZones = QStringList()) const;
QList<const DecklistCardNode *> getCardNodes(const QSet<QString> &restrictToZones = {}) const;
QList<const InnerDecklistNode *> getZoneNodes() const;
int getSideboardSize() const;
InnerDecklistNode *getRoot() const
{
return root;
}
DecklistCardNode *addCard(const QString &cardName,
const QString &zoneName,
int position,
int position = -1,
const QString &cardSetName = QString(),
const QString &cardSetCollectorNumber = QString(),
const QString &cardProviderId = QString(),
const bool formatLegal = true);
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
///@}
/// @name Deck identity

View File

@ -0,0 +1,186 @@
#include "deck_list_node_tree.h"
#include "tree/deck_list_card_node.h"
#include <QCryptographicHash>
#include <QSet>
DecklistNodeTree::DecklistNodeTree() : root(new InnerDecklistNode())
{
}
DecklistNodeTree::DecklistNodeTree(const DecklistNodeTree &other) : root(new InnerDecklistNode(other.root))
{
}
DecklistNodeTree &DecklistNodeTree::operator=(const DecklistNodeTree &other)
{
if (this != &other) {
delete root;
root = new InnerDecklistNode(other.root);
}
return *this;
}
DecklistNodeTree::~DecklistNodeTree()
{
delete root;
}
bool DecklistNodeTree::isEmpty() const
{
return root->isEmpty();
}
void DecklistNodeTree::clear()
{
root->clearTree();
}
QList<const DecklistCardNode *> DecklistNodeTree::getCardNodes(const QSet<QString> &restrictToZones) const
{
QList<const DecklistCardNode *> result;
for (auto *zoneNode : getZoneNodes()) {
if (!restrictToZones.isEmpty() && !restrictToZones.contains(zoneNode->getName())) {
continue;
}
for (auto *cardNode : *zoneNode) {
auto *cardCardNode = dynamic_cast<DecklistCardNode *>(cardNode);
if (cardCardNode) {
result.append(cardCardNode);
}
}
}
return result;
}
QList<const InnerDecklistNode *> DecklistNodeTree::getZoneNodes() const
{
QList<const InnerDecklistNode *> zones;
for (auto *node : *root) {
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(node);
if (!currentZone)
continue;
zones.append(currentZone);
}
return zones;
}
QString DecklistNodeTree::computeDeckHash() const
{
auto mainDeckNodes = getCardNodes({DECK_ZONE_MAIN});
auto sideDeckNodes = getCardNodes({DECK_ZONE_SIDE});
static auto nodesToCardList = [](const QList<const DecklistCardNode *> &nodes, const QString &prefix = {}) {
QStringList result;
for (auto node : nodes) {
for (int i = 0; i < node->getNumber(); ++i) {
result.append(prefix + node->getName().toLower());
}
}
return result;
};
QStringList cardList = nodesToCardList(mainDeckNodes) + nodesToCardList(sideDeckNodes, "SB:");
cardList.sort();
QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1);
quint64 number = (((quint64)(unsigned char)deckHashArray[0]) << 32) +
(((quint64)(unsigned char)deckHashArray[1]) << 24) +
(((quint64)(unsigned char)deckHashArray[2] << 16)) +
(((quint64)(unsigned char)deckHashArray[3]) << 8) + (quint64)(unsigned char)deckHashArray[4];
return QString::number(number, 32).rightJustified(8, '0');
}
void DecklistNodeTree::write(QXmlStreamWriter *xml) const
{
for (int i = 0; i < root->size(); i++) {
root->at(i)->writeElement(xml);
}
}
void DecklistNodeTree::readZoneElement(QXmlStreamReader *xml)
{
QString zoneName = xml->attributes().value("name").toString();
InnerDecklistNode *newZone = getZoneObjFromName(zoneName);
newZone->readElement(xml);
}
DecklistCardNode *DecklistNodeTree::addCard(const QString &cardName,
int amount,
const QString &zoneName,
int position,
const QString &cardSetName,
const QString &cardSetCollectorNumber,
const QString &cardProviderId,
const bool formatLegal)
{
auto *zoneNode = getZoneObjFromName(zoneName);
auto *node = new DecklistCardNode(cardName, amount, zoneNode, position, cardSetName, cardSetCollectorNumber,
cardProviderId, formatLegal);
return node;
}
bool DecklistNodeTree::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode)
{
if (node == root) {
return true;
}
if (rootNode == nullptr) {
rootNode = root;
}
int index = rootNode->indexOf(node);
if (index != -1) {
delete rootNode->takeAt(index);
if (rootNode->empty()) {
deleteNode(rootNode, rootNode->getParent());
}
return true;
}
for (int i = 0; i < rootNode->size(); i++) {
auto *inner = dynamic_cast<InnerDecklistNode *>(rootNode->at(i));
if (inner) {
if (deleteNode(node, inner)) {
return true;
}
}
}
return false;
}
void DecklistNodeTree::forEachCard(const std::function<void(InnerDecklistNode *, DecklistCardNode *)> &func) const
{
// Support for this is only possible if the internal structure
// doesn't get more complicated.
for (int i = 0; i < root->size(); i++) {
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
for (int j = 0; j < node->size(); j++) {
DecklistCardNode *card = dynamic_cast<DecklistCardNode *>(node->at(j));
func(node, card);
}
}
}
/**
* Gets the InnerDecklistNode that is the root node for the given zone, creating a new node if it doesn't exist.
*/
InnerDecklistNode *DecklistNodeTree::getZoneObjFromName(const QString &zoneName) const
{
for (int i = 0; i < root->size(); i++) {
auto *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
if (node->getName() == zoneName) {
return node;
}
}
return new InnerDecklistNode(zoneName, root);
}

View File

@ -0,0 +1,87 @@
#ifndef COCKATRICE_DECKLIST_NODE_TREE_H
#define COCKATRICE_DECKLIST_NODE_TREE_H
#include "libcockatrice/utility/card_ref.h"
#include "tree/deck_list_card_node.h"
#include "tree/inner_deck_list_node.h"
#include <QSet>
class DecklistNodeTree
{
InnerDecklistNode *root; ///< Root of the deck tree (zones + cards).
public:
/// @brief Constructs an empty DecklistNodeTree
explicit DecklistNodeTree();
/// @brief Copy constructor. Deep copies the tree
explicit DecklistNodeTree(const DecklistNodeTree &other);
/// @brief Copy-assignment operator. Deep copies the tree
DecklistNodeTree &operator=(const DecklistNodeTree &other);
virtual ~DecklistNodeTree();
/**
* @brief Gets a pointer to the underlying root node.
* Note: DO NOT call this method unless the object needs to have access to the underlying model.
* For now, only the DeckListModel should be calling this.
*/
InnerDecklistNode *getRoot() const
{
return root;
}
bool isEmpty() const;
/**
* @brief Deletes all nodes except the root.
*/
void clear();
/**
* Gets all card nodes in the tree
* @param restrictToZones Only get the nodes in these zones
* @return A QList containing all the card nodes in the zone.
*/
QList<const DecklistCardNode *> getCardNodes(const QSet<QString> &restrictToZones = {}) const;
QList<const InnerDecklistNode *> getZoneNodes() const;
/**
* @brief Computes the deck hash
*/
QString computeDeckHash() const;
/**
*@brief Writes the contents of the deck to xml
*/
void write(QXmlStreamWriter *xml) const;
/**
* @brief Reads a "zone" section of the xml to this tree
*/
void readZoneElement(QXmlStreamReader *xml);
DecklistCardNode *addCard(const QString &cardName,
int amount,
const QString &zoneName,
int position,
const QString &cardSetName = QString(),
const QString &cardSetCollectorNumber = QString(),
const QString &cardProviderId = QString(),
const bool formatLegal = true);
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
/**
* @brief Apply a function to every card in the deck tree. This can modify the cards.
*
* @param func Function taking (zone node, card node).
*/
void forEachCard(const std::function<void(InnerDecklistNode *, DecklistCardNode *)> &func) const;
private:
// Helpers for traversing the tree
InnerDecklistNode *getZoneObjFromName(const QString &zoneName) const;
};
#endif // COCKATRICE_DECKLIST_NODE_TREE_H

View File

@ -41,7 +41,7 @@ void DeckListModel::rebuildTree()
beginResetModel();
root->clearTree();
InnerDecklistNode *listRoot = deckList->getRoot();
InnerDecklistNode *listRoot = deckList->getTree()->getRoot();
for (int i = 0; i < listRoot->size(); i++) {
auto *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
@ -313,7 +313,7 @@ bool DeckListModel::removeRows(int row, int count, const QModelIndex &parent)
for (int i = 0; i < count; i++) {
AbstractDecklistNode *toDelete = node->takeAt(row);
if (auto *temp = dynamic_cast<DecklistModelCardNode *>(toDelete)) {
deckList->deleteNode(temp->getDataNode());
deckList->getTree()->deleteNode(temp->getDataNode());
}
delete toDelete;
}
@ -668,7 +668,7 @@ bool DeckListModel::isCardQuantityLegalForCurrentFormat(const CardInfoPtr cardIn
void DeckListModel::refreshCardFormatLegalities()
{
InnerDecklistNode *listRoot = deckList->getRoot();
InnerDecklistNode *listRoot = deckList->getTree()->getRoot();
for (int i = 0; i < listRoot->size(); i++) {
auto *currentZone = static_cast<InnerDecklistNode *>(listRoot->at(i));

View File

@ -202,7 +202,7 @@ public:
* affects its hash.
*
* Slots:
* - rebuildTree(): rebuilds the model structure from the underlying DeckLoader.
* - rebuildTree(): rebuilds the model structure from the underlying node tree.
*/
class DeckListModel : public QAbstractItemModel
{
@ -210,7 +210,7 @@ class DeckListModel : public QAbstractItemModel
public slots:
/**
* @brief Rebuilds the model tree from the underlying DeckLoader.
* @brief Rebuilds the model tree from the underlying node tree.
*
* This updates all indices and ensures the model reflects the current
* state of the deck.