diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp index c44012486..37f537249 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp @@ -77,6 +77,11 @@ void SideboardPlan::write(QXmlStreamWriter *xml) xml->writeEndElement(); } +bool DeckList::Metadata::isEmpty() const +{ + return name.isEmpty() && comments.isEmpty() && bannerCard.isEmpty() && tags.isEmpty(); +} + DeckList::DeckList() { root = new InnerDecklistNode; @@ -122,20 +127,20 @@ bool DeckList::readElement(QXmlStreamReader *xml) const QString childName = xml->name().toString(); if (xml->isStartElement()) { if (childName == "lastLoadedTimestamp") { - lastLoadedTimestamp = xml->readElementText(); + metadata.lastLoadedTimestamp = xml->readElementText(); } else if (childName == "deckname") { - name = xml->readElementText(); + metadata.name = xml->readElementText(); } else if (childName == "comments") { - comments = xml->readElementText(); + metadata.comments = xml->readElementText(); } else if (childName == "bannerCard") { QString providerId = xml->attributes().value("providerId").toString(); QString cardName = xml->readElementText(); - bannerCard = {cardName, providerId}; + metadata.bannerCard = {cardName, providerId}; } else if (childName == "tags") { - tags.clear(); // Clear existing tags + metadata.tags.clear(); // Clear existing tags while (xml->readNextStartElement()) { if (xml->name().toString() == "tag") { - tags.append(xml->readElementText()); + metadata.tags.append(xml->readElementText()); } } } else if (childName == "zone") { @@ -155,24 +160,30 @@ bool DeckList::readElement(QXmlStreamReader *xml) 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 { xml->writeStartElement("cockatrice_deck"); 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 - xml->writeStartElement("tags"); - for (const QString &tag : tags) { - xml->writeTextElement("tag", tag); - } - xml->writeEndElement(); + writeMetadata(xml, metadata); // Write zones for (int i = 0; i < root->size(); i++) { @@ -329,7 +340,7 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata) const auto ¤t = inputs.at(index++); if (!current.contains(reEmpty)) { match = reComment.match(current); - name = match.captured(); + metadata.name = match.captured(); break; } } @@ -337,10 +348,10 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata) const auto ¤t = inputs.at(index++); if (!current.contains(reEmpty)) { match = reComment.match(current); - comments += match.captured() + '\n'; + metadata.comments += match.captured() + '\n'; } } - comments.chop(1); + metadata.comments.chop(1); // Discard empty lines while (index < max_line && inputs.at(index).contains(reEmpty)) { @@ -504,9 +515,7 @@ void DeckList::cleanList(bool preserveMetadata) { root->clearTree(); if (!preserveMetadata) { - setName(); - setComments(); - setTags(); + metadata = {}; } refreshDeckHash(); } diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h index cbab9ce5d..5340d69fe 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h @@ -126,12 +126,24 @@ public: class DeckList : public QObject { 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: - QString name; ///< User-defined deck name. - 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. + Metadata metadata; ///< Deck metadata that is stored in the deck file QMap sideboardPlans; ///< Named sideboard plans. InnerDecklistNode *root; ///< Root of the deck tree (zones + cards). @@ -181,34 +193,34 @@ public slots: ///@{ void setName(const QString &_name = QString()) { - name = _name; + metadata.name = _name; } void setComments(const QString &_comments = QString()) { - comments = _comments; + metadata.comments = _comments; } void setTags(const QStringList &_tags = QStringList()) { - tags = _tags; + metadata.tags = _tags; emit deckTagsChanged(); } void addTag(const QString &_tag) { - tags.append(_tag); + metadata.tags.append(_tag); emit deckTagsChanged(); } void clearTags() { - tags.clear(); + metadata.tags.clear(); emit deckTagsChanged(); } void setBannerCard(const CardRef &_bannerCard = {}) { - bannerCard = _bannerCard; + metadata.bannerCard = _bannerCard; } void setLastLoadedTimestamp(const QString &_lastLoadedTimestamp = QString()) { - lastLoadedTimestamp = _lastLoadedTimestamp; + metadata.lastLoadedTimestamp = _lastLoadedTimestamp; } ///@} @@ -223,32 +235,38 @@ public: ~DeckList() override; /// @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 { - return name; + return metadata.name; } QString getComments() const { - return comments; + return metadata.comments; } QStringList getTags() const { - return tags; + return metadata.tags; } CardRef getBannerCard() const { - return bannerCard; + return metadata.bannerCard; } QString getLastLoadedTimestamp() const { - return lastLoadedTimestamp; + return metadata.lastLoadedTimestamp; } ///@} bool isBlankDeck() const { - return name.isEmpty() && comments.isEmpty() && getCardList().isEmpty(); + return metadata.isEmpty() && getCardList().isEmpty(); } /// @name Sideboard plans @@ -286,7 +304,7 @@ public: void cleanList(bool preserveMetadata = false); bool isEmpty() const { - return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); + return root->isEmpty() && metadata.isEmpty() && sideboardPlans.isEmpty(); } QStringList getCardList() const; QList getCardRefList() const; diff --git a/libcockatrice_utility/libcockatrice/utility/card_ref.h b/libcockatrice_utility/libcockatrice/utility/card_ref.h index d29eee0bb..d89fe590b 100644 --- a/libcockatrice_utility/libcockatrice/utility/card_ref.h +++ b/libcockatrice_utility/libcockatrice/utility/card_ref.h @@ -19,6 +19,11 @@ struct CardRef { return name == other.name && providerId == other.providerId; } + + bool isEmpty() const + { + return name.isEmpty() && providerId.isEmpty(); + } }; #endif // CARD_REF_H