[DeckList] Move metadata into struct (#6380)

* [DeckList] Move metadata into struct

* wipe metadata if preserveMetadata is false
This commit is contained in:
RickyRister
2025-11-30 04:09:09 -08:00
committed by GitHub
parent d57bec8ec6
commit 3ff2df2796
3 changed files with 76 additions and 44 deletions

View File

@@ -77,6 +77,11 @@ void SideboardPlan::write(QXmlStreamWriter *xml)
xml->writeEndElement(); xml->writeEndElement();
} }
bool DeckList::Metadata::isEmpty() const
{
return name.isEmpty() && comments.isEmpty() && bannerCard.isEmpty() && tags.isEmpty();
}
DeckList::DeckList() DeckList::DeckList()
{ {
root = new InnerDecklistNode; root = new InnerDecklistNode;
@@ -122,20 +127,20 @@ bool DeckList::readElement(QXmlStreamReader *xml)
const QString childName = xml->name().toString(); const QString childName = xml->name().toString();
if (xml->isStartElement()) { if (xml->isStartElement()) {
if (childName == "lastLoadedTimestamp") { if (childName == "lastLoadedTimestamp") {
lastLoadedTimestamp = xml->readElementText(); metadata.lastLoadedTimestamp = xml->readElementText();
} else if (childName == "deckname") { } else if (childName == "deckname") {
name = xml->readElementText(); metadata.name = xml->readElementText();
} else if (childName == "comments") { } else if (childName == "comments") {
comments = xml->readElementText(); metadata.comments = xml->readElementText();
} else if (childName == "bannerCard") { } else if (childName == "bannerCard") {
QString providerId = xml->attributes().value("providerId").toString(); QString providerId = xml->attributes().value("providerId").toString();
QString cardName = xml->readElementText(); QString cardName = xml->readElementText();
bannerCard = {cardName, providerId}; metadata.bannerCard = {cardName, providerId};
} else if (childName == "tags") { } else if (childName == "tags") {
tags.clear(); // Clear existing tags metadata.tags.clear(); // Clear existing tags
while (xml->readNextStartElement()) { while (xml->readNextStartElement()) {
if (xml->name().toString() == "tag") { if (xml->name().toString() == "tag") {
tags.append(xml->readElementText()); metadata.tags.append(xml->readElementText());
} }
} }
} else if (childName == "zone") { } else if (childName == "zone") {
@@ -155,24 +160,30 @@ bool DeckList::readElement(QXmlStreamReader *xml)
return true; return true;
} }
void writeMetadata(QXmlStreamWriter *xml, const DeckList::Metadata &metadata)
{
xml->writeTextElement("lastLoadedTimestamp", metadata.lastLoadedTimestamp);
xml->writeTextElement("deckname", metadata.name);
xml->writeStartElement("bannerCard");
xml->writeAttribute("providerId", metadata.bannerCard.providerId);
xml->writeCharacters(metadata.bannerCard.name);
xml->writeEndElement();
xml->writeTextElement("comments", metadata.comments);
// Write tags
xml->writeStartElement("tags");
for (const QString &tag : metadata.tags) {
xml->writeTextElement("tag", tag);
}
xml->writeEndElement();
}
void DeckList::write(QXmlStreamWriter *xml) const void DeckList::write(QXmlStreamWriter *xml) const
{ {
xml->writeStartElement("cockatrice_deck"); xml->writeStartElement("cockatrice_deck");
xml->writeAttribute("version", "1"); xml->writeAttribute("version", "1");
xml->writeTextElement("lastLoadedTimestamp", lastLoadedTimestamp);
xml->writeTextElement("deckname", name);
xml->writeStartElement("bannerCard");
xml->writeAttribute("providerId", bannerCard.providerId);
xml->writeCharacters(bannerCard.name);
xml->writeEndElement();
xml->writeTextElement("comments", comments);
// Write tags writeMetadata(xml, metadata);
xml->writeStartElement("tags");
for (const QString &tag : tags) {
xml->writeTextElement("tag", tag);
}
xml->writeEndElement();
// Write zones // Write zones
for (int i = 0; i < root->size(); i++) { for (int i = 0; i < root->size(); i++) {
@@ -329,7 +340,7 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
const auto &current = inputs.at(index++); const auto &current = inputs.at(index++);
if (!current.contains(reEmpty)) { if (!current.contains(reEmpty)) {
match = reComment.match(current); match = reComment.match(current);
name = match.captured(); metadata.name = match.captured();
break; break;
} }
} }
@@ -337,10 +348,10 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
const auto &current = inputs.at(index++); const auto &current = inputs.at(index++);
if (!current.contains(reEmpty)) { if (!current.contains(reEmpty)) {
match = reComment.match(current); match = reComment.match(current);
comments += match.captured() + '\n'; metadata.comments += match.captured() + '\n';
} }
} }
comments.chop(1); metadata.comments.chop(1);
// Discard empty lines // Discard empty lines
while (index < max_line && inputs.at(index).contains(reEmpty)) { while (index < max_line && inputs.at(index).contains(reEmpty)) {
@@ -504,9 +515,7 @@ void DeckList::cleanList(bool preserveMetadata)
{ {
root->clearTree(); root->clearTree();
if (!preserveMetadata) { if (!preserveMetadata) {
setName(); metadata = {};
setComments();
setTags();
} }
refreshDeckHash(); refreshDeckHash();
} }

View File

@@ -126,12 +126,24 @@ public:
class DeckList : public QObject class DeckList : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
struct Metadata
{
QString name; ///< User-defined deck name.
QString comments; ///< Free-form comments or notes.
CardRef bannerCard; ///< Optional representative card for the deck.
QStringList tags; ///< User-defined tags for deck classification.
QString lastLoadedTimestamp; ///< Timestamp string of last load.
/**
* @brief Checks if all values (except for lastLoadedTimestamp) in the metadata is empty.
*/
bool isEmpty() const;
};
private: private:
QString name; ///< User-defined deck name. Metadata metadata; ///< Deck metadata that is stored in the deck file
QString comments; ///< Free-form comments or notes.
CardRef bannerCard; ///< Optional representative card for the deck.
QString lastLoadedTimestamp; ///< Timestamp string of last load.
QStringList tags; ///< User-defined tags for deck classification.
QMap<QString, SideboardPlan *> sideboardPlans; ///< Named sideboard plans. QMap<QString, SideboardPlan *> sideboardPlans; ///< Named sideboard plans.
InnerDecklistNode *root; ///< Root of the deck tree (zones + cards). InnerDecklistNode *root; ///< Root of the deck tree (zones + cards).
@@ -181,34 +193,34 @@ public slots:
///@{ ///@{
void setName(const QString &_name = QString()) void setName(const QString &_name = QString())
{ {
name = _name; metadata.name = _name;
} }
void setComments(const QString &_comments = QString()) void setComments(const QString &_comments = QString())
{ {
comments = _comments; metadata.comments = _comments;
} }
void setTags(const QStringList &_tags = QStringList()) void setTags(const QStringList &_tags = QStringList())
{ {
tags = _tags; metadata.tags = _tags;
emit deckTagsChanged(); emit deckTagsChanged();
} }
void addTag(const QString &_tag) void addTag(const QString &_tag)
{ {
tags.append(_tag); metadata.tags.append(_tag);
emit deckTagsChanged(); emit deckTagsChanged();
} }
void clearTags() void clearTags()
{ {
tags.clear(); metadata.tags.clear();
emit deckTagsChanged(); emit deckTagsChanged();
} }
void setBannerCard(const CardRef &_bannerCard = {}) void setBannerCard(const CardRef &_bannerCard = {})
{ {
bannerCard = _bannerCard; metadata.bannerCard = _bannerCard;
} }
void setLastLoadedTimestamp(const QString &_lastLoadedTimestamp = QString()) void setLastLoadedTimestamp(const QString &_lastLoadedTimestamp = QString())
{ {
lastLoadedTimestamp = _lastLoadedTimestamp; metadata.lastLoadedTimestamp = _lastLoadedTimestamp;
} }
///@} ///@}
@@ -223,32 +235,38 @@ public:
~DeckList() override; ~DeckList() override;
/// @name Metadata getters /// @name Metadata getters
/// The individual metadata getters still exist for backwards compatibility.
/// TODO: Figure out when we can remove them.
///@{ ///@{
const Metadata &getMetadata() const
{
return metadata;
}
QString getName() const QString getName() const
{ {
return name; return metadata.name;
} }
QString getComments() const QString getComments() const
{ {
return comments; return metadata.comments;
} }
QStringList getTags() const QStringList getTags() const
{ {
return tags; return metadata.tags;
} }
CardRef getBannerCard() const CardRef getBannerCard() const
{ {
return bannerCard; return metadata.bannerCard;
} }
QString getLastLoadedTimestamp() const QString getLastLoadedTimestamp() const
{ {
return lastLoadedTimestamp; return metadata.lastLoadedTimestamp;
} }
///@} ///@}
bool isBlankDeck() const bool isBlankDeck() const
{ {
return name.isEmpty() && comments.isEmpty() && getCardList().isEmpty(); return metadata.isEmpty() && getCardList().isEmpty();
} }
/// @name Sideboard plans /// @name Sideboard plans
@@ -286,7 +304,7 @@ public:
void cleanList(bool preserveMetadata = false); void cleanList(bool preserveMetadata = false);
bool isEmpty() const bool isEmpty() const
{ {
return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); return root->isEmpty() && metadata.isEmpty() && sideboardPlans.isEmpty();
} }
QStringList getCardList() const; QStringList getCardList() const;
QList<CardRef> getCardRefList() const; QList<CardRef> getCardRefList() const;

View File

@@ -19,6 +19,11 @@ struct CardRef
{ {
return name == other.name && providerId == other.providerId; return name == other.name && providerId == other.providerId;
} }
bool isEmpty() const
{
return name.isEmpty() && providerId.isEmpty();
}
}; };
#endif // CARD_REF_H #endif // CARD_REF_H