Merge branch 'master' into tooomm-qt5

This commit is contained in:
tooomm 2026-09-06 18:17:21 +02:00
commit 9766c9dcf8
117 changed files with 5448 additions and 1793 deletions

View file

@ -5,6 +5,8 @@
#include <QCryptographicHash>
#include <QSet>
static constexpr int MAX_DECK_SIZE = 1e5;
DecklistNodeTree::DecklistNodeTree() : root(new InnerDecklistNode())
{
}
@ -113,7 +115,7 @@ void DecklistNodeTree::readZoneElement(QXmlStreamReader *xml)
{
QString zoneName = xml->attributes().value("name").toString();
InnerDecklistNode *newZone = getZoneObjFromName(zoneName);
newZone->readElement(xml);
totalCards += newZone->readElement(xml, MAX_DECK_SIZE - totalCards);
}
DecklistCardNode *DecklistNodeTree::addCard(const QString &cardName,
@ -125,6 +127,8 @@ DecklistCardNode *DecklistNodeTree::addCard(const QString &cardName,
const QString &cardProviderId,
const bool formatLegal)
{
amount = qMin(amount, MAX_DECK_SIZE - totalCards);
totalCards += amount;
auto *zoneNode = getZoneObjFromName(zoneName);
auto *node = new DecklistCardNode(cardName, amount, zoneNode, position, cardSetName, cardSetCollectorNumber,
cardProviderId, formatLegal);

View file

@ -10,6 +10,7 @@
class DecklistNodeTree
{
InnerDecklistNode *root; ///< Root of the deck tree (zones + cards).
int totalCards = 0;
public:
/** @brief Constructs an empty DecklistNodeTree. */
@ -114,6 +115,25 @@ public:
*/
QList<const InnerDecklistNode *> getCustomZones(const QString &boardZoneName) const;
/**
* @brief Checks whether a zone name is taken anywhere in the deck.
*
* Covers the standard board names and any top-level or nested custom zone.
* @param zoneName The checked name.
* @return true if the name is reserved or already in use.
*/
bool hasZoneName(const QString &zoneName) const;
/**
* @brief Finds a custom zone anywhere in the deck by name.
*
* Walks the children of every top-level zone, so a zone nested under any
* board (and not just the standard ones) is found.
* @param zoneName The zone name to find.
* @return The matching zone node, or nullptr if none exists.
*/
InnerDecklistNode *findCustomZoneByName(const QString &zoneName) const;
/**
* @brief Applies a function to every card in the deck tree. This can modify the cards.
*
@ -127,8 +147,6 @@ private:
InnerDecklistNode *getZoneObjFromName(const QString &zoneName) const;
InnerDecklistNode *findBoardZone(const QString &boardZoneName) const;
InnerDecklistNode *findOrCreateBoardZone(const QString &boardZoneName);
InnerDecklistNode *findCustomZoneByName(const QString &zoneName) const;
bool hasZoneName(const QString &zoneName) const;
};
#endif // COCKATRICE_DECKLIST_NODE_TREE_H

View file

@ -34,15 +34,15 @@ bool AbstractDecklistCardNode::compareName(AbstractDecklistNode *other) const
}
}
bool AbstractDecklistCardNode::readElement(QXmlStreamReader *xml)
int AbstractDecklistCardNode::readElement(QXmlStreamReader *xml, int /* limit */)
{
while (!xml->atEnd()) {
xml->readNext();
if (xml->isEndElement() && xml->name().toString() == "card") {
return false;
return 0;
}
}
return true;
return 0;
}
void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml)
@ -60,4 +60,4 @@ void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml)
if (!getCardProviderId().isEmpty()) {
xml->writeAttribute("uuid", getCardProviderId());
}
}
}

View file

@ -141,7 +141,7 @@ public:
*
* This supports loading deck files from Cockatrice’s XML format.
*/
bool readElement(QXmlStreamReader *xml) override;
int readElement(QXmlStreamReader *xml, int limit) override;
/**
* @brief Serialize this node’s properties to XML.

View file

@ -183,7 +183,7 @@ public:
* Cockatrice deck XML format.
* @{
*/
virtual bool readElement(QXmlStreamReader *xml) = 0;
virtual int readElement(QXmlStreamReader *xml, int limit) = 0;
virtual void writeElement(QXmlStreamWriter *xml) = 0;
/// @}
};

View file

@ -43,6 +43,13 @@ void InnerDecklistNode::setSortMethod(DeckSortMethod method)
}
}
const QList<QString> &InnerDecklistNode::boardZoneNames()
{
static const QList<QString> names = {QString(DECK_ZONE_MAIN), QString(DECK_ZONE_SIDE),
QString(DECK_ZONE_MAYBEBOARD)};
return names;
}
QString InnerDecklistNode::getVisibleName() const
{
return visibleNameFromName(name);
@ -87,6 +94,9 @@ AbstractDecklistNode *InnerDecklistNode::findCardChildByNameProviderIdAndNumber(
int InnerDecklistNode::height() const
{
if (isEmpty()) {
return 1;
}
return at(0)->height() + 1;
}
@ -141,27 +151,31 @@ bool InnerDecklistNode::compareName(AbstractDecklistNode *other) const
}
}
bool InnerDecklistNode::readElement(QXmlStreamReader *xml)
int InnerDecklistNode::readElement(QXmlStreamReader *xml, int limit)
{
int totalCards = 0;
while (!xml->atEnd()) {
xml->readNext();
const QString childName = xml->name().toString();
if (xml->isStartElement()) {
if (childName == "zone") {
auto *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this);
newZone->readElement(xml);
totalCards += newZone->readElement(xml, limit - totalCards);
} else if (childName == "card") {
auto *newCard = new DecklistCardNode(
xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(),
this, -1, xml->attributes().value("setShortName").toString(),
xml->attributes().value("collectorNumber").toString(), xml->attributes().value("uuid").toString());
newCard->readElement(xml);
int amount = xml->attributes().value("number").toString().toInt();
amount = qMin(amount, limit - totalCards);
auto *newCard = new DecklistCardNode(xml->attributes().value("name").toString(), amount, this, -1,
xml->attributes().value("setShortName").toString(),
xml->attributes().value("collectorNumber").toString(),
xml->attributes().value("uuid").toString());
totalCards += amount;
totalCards += newCard->readElement(xml, limit - totalCards);
}
} else if (xml->isEndElement() && (childName == "zone")) {
return false;
return totalCards;
}
}
return true;
return totalCards;
}
void InnerDecklistNode::writeElement(QXmlStreamWriter *xml)
@ -201,4 +215,4 @@ QVector<QPair<int, int>> InnerDecklistNode::sort(Qt::SortOrder order)
}
return result;
}
}

View file

@ -18,6 +18,9 @@
#include "abstract_deck_list_node.h"
#include <QList>
#include <QString>
/** @brief Constant for the "main" deck zone name. */
#define DECK_ZONE_MAIN "main"
/** @brief Constant for the "sideboard" zone name. */
@ -118,6 +121,13 @@ public:
*/
static QString visibleNameFromName(const QString &_name);
/**
* @brief The standard board zone names, in display order.
*
* @return main, side and maybeboard.
*/
static const QList<QString> &boardZoneNames();
/**
* @brief Get this node’s display-friendly name.
* @return Human-readable name (zone/group name).
@ -216,9 +226,10 @@ public:
/**
* @brief Deserialize this node and its children from XML.
* @param xml Reader positioned at this element.
* @return true if parsing succeeded.
* @param limit The maximum amount of cards to read
* @return the amount of cards found
*/
bool readElement(QXmlStreamReader *xml) override;
int readElement(QXmlStreamReader *xml, int limit) override;
/**
* @brief Serialize this node and its children to XML.