Cockatrice/libcockatrice_card/libcockatrice/card/card_info.h
BruebachL d603a2bb6a
[Tooling] Apply include-what-you-use across the tree (#7396)
* [DeckList] Apply include-what-you-use to libcockatrice_deck_list

* [IWYU] Apply include-what-you-use across the tree

Run one whole-tree IWYU pass over the libcockatrice_* libraries, the
Cockatrice client, Oracle, Servatrice and the test suite, so each
translation unit includes what it uses directly and forward-declares
what it does not need.

IWYU only analyses real translation units, never the moc code CMake
generates from Q_OBJECT headers, so it strips includes that moc output
silently relies on. Where a type is passed by value (or nested in a
QList/QMap) in a signal or slot signature, the generated moc code needs
the complete type; those includes are kept with an explanatory
`// IWYU pragma: keep`. The same holds for Q_DECLARE_METATYPE targets
such as QSqlDatabase.

A handful of includes are added by hand where callers brace-initialize a
const-reference parameter, which also requires the complete type.

Applied as a single commit on purpose: stripping includes from the
libcockatrice_* headers is precisely what breaks the client, test and
server translation units, and the fixes for those live in the same
translation units. Splitting by component would therefore leave
intermediate commits that do not compile.

All 426 modified Q_OBJECT/Q_GADGET headers were verified to be
moc-self-contained by compiling each generated moc_*.cpp standalone;
several built only because of moc include ordering in
mocs_compilation.cpp before the keep-includes were added.

* [Tooling] Emit public Qt headers and fix IWYU fallout CI found

Three problems the local build could not see, all because a green local
build only proves the configuration it was run under.

Private Qt headers. IWYU emitted private, lowercase Qt headers, and
qtypes.h does not exist at all before Qt 6.9, so the Debian 12 and
Ubuntu 24.04 jobs on Qt 6.4.2 failed to compile. The generator only
emitted a mapping when the capital header name mirrored the private one
(QAbstractAnimation for qabstractanimation.h), so qtypes.h, which is
wrapped by QtTypes instead, got no mapping and kept the private
spelling. Map it explicitly to <QtTypes>, which is public since Qt 5 and
provides the same typedefs either way, and rewrite the 100 affected
includes.

Do not generalize this to "prefer any Qt* wrapper". The table is
generated from whichever Qt is installed, and the wrappers are not
equally old: QtLogging only appeared in Qt 6.8 and QtMinMax in 6.5, so
that heuristic trades one breakage for another. Every other lowercase
header still in the tree has shipped publicly since Qt 5, so those are
left alone.

Platform-guarded includes. IWYU only sees the preprocessor configuration
it is handed, so it dropped an include that only the macOS branch of
main.cpp needs, and the macOS jobs failed on an undeclared
UrlSchemeEventFilter. Restore the include. Force-compiling every file
that carries a platform guard under Q_OS_MAC, Q_OS_MACOS and __APPLE__
reports nothing else, so the macOS branches are covered rather than
assumed.

shellcheck. Drop a leftover variable and stop assigning the
include-what-you-use lookup, which was only ever an existence check.

* [Tooling] Map Qt 6.5+ split headers to QtGlobal for Qt 6.4 compatibility

IWYU emitted QtTypes, QtPreprocessorSupport, QtVersionChecks, QtAssert,
QtMinMax, QtClassHelperMacros, QtEnvironmentVariables and QtTranslation.
Qt 6.5 split those declarations out of qglobal.h into separate headers, so
neither the Qt* wrapper nor the q*.h private name exists on the oldest Qt we
support (6.4.2), and Debian 12 / Ubuntu 24.04 fail with "No such file or
directory". qtypes.h is worse still: it only appeared in Qt 6.9.

QtGlobal is the one spelling that works across the whole supported range. It
has been public since Qt 5, defines these declarations itself up to Qt 6.4, and
includes the split headers from Qt 6.5 on, so redirect all eight private
headers to it and collapse the affected includes in the tree.

Curated overrides now take precedence over the name-mirroring rule, which
cannot know about Qt version floors because the mapping is generated from
whatever Qt is installed. That rule was mapping qtversionchecks.h to
<QtVersionChecks> even with an override present, because the override was only
consulted as a fallback. A curated key that matches nothing is now a hard
error rather than a silent fallback, and the redirected headers are no longer
advertised as the home of a symbol.

Verified every Qt include in the tree resolves against the real
qt6-base-dev 6.4.2 package: 15 distinct includes, 0 missing.

* [Tooling] Map QOverload to QtGlobal and drop the QMetaMethodArgument include

Two more headers IWYU emitted do not exist on Qt 6.4.2:

QOverload was split out of qglobal.h in Qt 6.5, so on 6.4.2 it is declared in
qglobal.h directly and the standalone header is a hard error. QtGlobal covers
both, so map qoverload.h to it like the other 6.5+ split headers.

QMetaMethodArgument is never referenced anywhere in the tree. It is a bare
forwarder for qobjectdefs.h that our generator advertised as a class symbol,
which is how IWYU came to add the include at all. The symbol mappings are
generated from header names, so they cannot tell a forwarder that happens to be
capitalised from a real class; removing the unused include is the fix, and the
generic case stays a known limitation of the generator.

Extending the audit to every Q* header (an earlier pass only matched headers
starting with "Qt" or lowercase q*.h, so it missed all of them) against the real
qt6-base-dev, qt6-multimedia-dev, qt6-declarative-dev, qt6-svg-dev and
qt6-websockets-dev 6.4.2 packages: 341 distinct Qt includes, 0 missing.

* [Game] Give moc the complete CardItem type in player_actions.h

player_actions.h forward declares CardItem but passes QList<CardItem *> by
value in actPlay/actPlayFacedown/actHide. moc instantiates the metatype for
those parameters, and on Qt 6.4 that expands to sizeof(CardItem), so Ubuntu
24.04 fails with "invalid application of 'sizeof' to incomplete type
'CardItem'". Newer Qt tolerates the incomplete type, which is why only the
6.4.2 jobs failed.

Include the defining header with an IWYU pragma keep, matching how the other
MOC-required includes in this area are handled.

* [Game] Give moc the complete ServerInfo_Card type

player_logic.h, game_scene.h, view_zone.h and view_zone_widget.h forward
declare ServerInfo_Card but pass QList<const ServerInfo_Card *> through signal
and slot signatures. moc instantiates the metatype for those parameters, which
Qt 6.4 expands to sizeof(ServerInfo_Card), so the connect in game_scene.cpp
fails on Debian 12 and Ubuntu 24.04 with "invalid application of 'sizeof' to
incomplete type 'const ServerInfo_Card'". Newer Qt tolerates it, so only the
6.4.2 jobs failed.

Include the generated protobuf header with an IWYU pragma keep, following the
pattern already used for ServerInfo_Player and ServerInfo_User in
game_event_handler.h.

* [Client] Complete the types Qt 6.4 needs for connect and moc

Qt 6.4 expands QMetaType::fromType on the normalised argument list of a
PMF connect and on moc-generated metatypes, which requires sizeof on every
signal and slot parameter. Newer Qt tolerates forward declarations there,
so only the Debian 12 and Ubuntu 24.04 jobs failed, with
"invalid application of 'sizeof' to incomplete type" for QMouseEvent,
QPrinter and GameReplay.

Replace the forward declarations with the real includes:

- QMouseEvent in the nine widget headers that pass it through signals
- QPrinter in abstract_tab_deck_editor.cpp, for the actPrintDeck lambda
- game_replay.pb.h in tab_replays.h. GameReplay is a protobuf message, so
  the project's game/replay.h only forward declares it and cannot supply
  the complete type.

Found by recompiling all 1918 project TUs against the Debian Qt 6.4.2
headers, which reproduces those two CI jobs locally in one pass.

* [Client] Complete Release and QMenu for Qt 6.4 moc and connect

Continuing the Qt 6.4 complete-type sweep:

- window_main.cpp connects ClientUpdateChecker::finishedCheck to
  MainWindow::checkClientUpdatesFinished, whose Release * parameter made
  moc 6.4 instantiate the metatype. GameReplay turned out to be a protobuf
  message, so Release likewise needed release_channel.h in the three
  headers declaring those signals: window_main.h, dlg_update.h and
  client_update_checker.h.
- moc 6.4 also needs sizeof(QMenu) for the QList<QMenu *> carried by
  TabSupervisor::setMenu and MainWindow::updateTabMenu.

Verified by regenerating moc output with the Debian moc 6.4.2 for all 434
Q_OBJECT/Q_GADGET classes and compiling it, plus recompiling all 1612
source TUs, against the Qt 6.4.2 headers: no remaining failures.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-08 11:13:50 +02:00

556 lines
20 KiB
C++

#ifndef CARD_INFO_H
#define CARD_INFO_H
#include "format/format_legality_rules.h"
#include "lazy_properties_hash.h"
#include "printing/printing_info.h"
#include <QByteArray>
#include <QChar>
#include <QHash>
#include <QList>
#include <QLoggingCategory>
#include <QMap>
#include <QMetaType>
#include <QObject>
#include <QSet>
#include <QSharedPointer>
#include <QString>
#include <QStringList>
#include <qtmetamacros.h>
#include <utility>
inline Q_LOGGING_CATEGORY(CardInfoLog, "card_info");
class CardInfo;
class CardSet;
class CardRelation;
typedef QSharedPointer<CardInfo> CardInfoPtr;
typedef QSharedPointer<CardSet> CardSetPtr;
typedef QSharedPointer<FormatRules> FormatRulesPtr;
typedef QMap<QString, QList<PrintingInfo>> SetToPrintingsMap;
typedef QHash<QString, CardInfoPtr> CardNameMap;
typedef QHash<QString, CardSetPtr> SetNameMap;
typedef QHash<QString, FormatRulesPtr> FormatRulesNameMap;
Q_DECLARE_METATYPE(CardInfoPtr)
/**
* @class CardInfo
* @ingroup Cards
*
* @brief Represents a card and its associated metadata, properties, and relationships.
*
* CardInfo holds both static information (name, text, flags) and dynamic data
* (properties, set memberships, relationships). It also integrates with
* signals/slots, allowing observers to react to property or visual updates.
*
* Each CardInfo may belong to multiple sets through its printings, and can
* be related to other cards through defined relationships.
*/
class CardInfo : public QObject
{
Q_OBJECT
public:
/**
* @class CardInfo::UiAttributes
* @ingroup Cards
*
* @brief Attributes of the card that affect display and game logic.
*/
struct UiAttributes
{
bool cipt = false; ///< Positioning flag used by UI.
bool landscapeOrientation = false; ///< Orientation flag for rendering.
int tableRow = 0; ///< Row index in a table or visual representation.
bool upsideDownArt = false; ///< Whether artwork is flipped for visual purposes.
};
private:
/** @name Private Card Properties
* @anchor PrivateCardProperties
*/
///@{
CardInfoPtr smartThis; ///< Smart pointer to self for safe cross-references.
QString name; ///< Full name of the card.
QString simpleName; ///< Simplified name for fuzzy matching.
QString text; ///< Text description or rules text of the card.
bool isToken; ///< Whether this card is a token or not.
QMap<QString, QString> localizedNames; ///< Localized card names, keyed by language code.
QMap<QString, QString> localizedTexts; ///< Localized rules text, keyed by language code.
LazyPropertiesHash properties; ///< Key-value store of dynamic card properties.
QList<CardRelation *> relatedCards; ///< Forward references to related cards.
QList<CardRelation *> reverseRelatedCards; ///< Cards that refer back to this card.
QList<CardRelation *> reverseRelatedCardsToMe; ///< Cards that consider this card as related.
SetToPrintingsMap setsToPrintings; ///< Mapping from set names to printing variations.
UiAttributes uiAttributes; ///< Attributes that affect display and game logic
QString setsNames; ///< Cached, human-readable list of set names.
QSet<QString> altNames; ///< Cached set of alternate names, used when searching
///@}
public:
/**
* @brief Constructs a CardInfo with full initialization.
*
* @param _name The name of the card.
* @param _text Rules text or description of the card.
* @param _isToken Flag indicating whether the card is a token.
* @param _properties Arbitrary key-value properties.
* @param _relatedCards Forward references to related cards.
* @param _reverseRelatedCards Backward references to related cards.
* @param _sets Map of set names to printing information.
* @param _uiAttributes Attributes that affect display and game logic
* @param _localizedNames Localized card names, keyed by language code.
* @param _localizedTexts Localized rules text, keyed by language code.
*/
explicit CardInfo(const QString &_name,
const QString &_text,
bool _isToken,
const QHash<QString, QString> &_properties,
const QList<CardRelation *> &_relatedCards,
const QList<CardRelation *> &_reverseRelatedCards,
SetToPrintingsMap _sets,
UiAttributes _uiAttributes,
QMap<QString, QString> _localizedNames = {},
QMap<QString, QString> _localizedTexts = {});
/**
* @brief Constructs a CardInfo from a cache snapshot with precomputed derived
* state.
*
* Used by the binary cache reader to skip recomputing @p _simpleName and
* @p _altNames (which otherwise require a Unicode normalization and a full
* printing scan). Properties are supplied as a pre-serialized @p _propertiesBlob
* so the QHash<QString, QString> is not built at load time (it is materialized on first
* query).
*
* @param _name The card name.
* @param _text Rules text or description of the card.
* @param _isToken Token flag.
* @param _propertiesBlob Pre-serialized properties blob (as written by the cache).
* @param _relatedCards Forward relationships.
* @param _reverseRelatedCards Reverse relationships.
* @param _sets Printing information per set.
* @param _uiAttributes Attributes that affect display and game logic.
* @param _simpleName Precomputed simplified name.
* @param _altNames Precomputed alternate names.
* @param _localizedNames Localized card names, keyed by language code.
* @param _localizedTexts Localized rules text, keyed by language code.
*/
explicit CardInfo(const QString &_name,
const QString &_text,
bool _isToken,
const QByteArray &_propertiesBlob,
const QList<CardRelation *> &_relatedCards,
const QList<CardRelation *> &_reverseRelatedCards,
SetToPrintingsMap _sets,
UiAttributes _uiAttributes,
QString _simpleName,
QSet<QString> _altNames,
QMap<QString, QString> _localizedNames = {},
QMap<QString, QString> _localizedTexts = {});
/**
* @brief Copy constructor for CardInfo.
*
* Performs a deep copy of properties, sets, and related card lists.
*
* @param other Another CardInfo to copy.
*/
CardInfo(const CardInfo &other)
: QObject(other.parent()), name(other.name), simpleName(other.simpleName), text(other.text),
isToken(other.isToken), localizedNames(other.localizedNames), localizedTexts(other.localizedTexts),
properties(other.properties), relatedCards(other.relatedCards),
reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe),
setsToPrintings(other.setsToPrintings), uiAttributes(other.uiAttributes), setsNames(other.setsNames),
altNames(other.altNames)
{
}
/**
* @brief Creates a new instance with only the card name.
*
* All other fields are set to defaults.
*
* @param _name The card name.
* @return Shared pointer to the new CardInfo instance.
*/
static CardInfoPtr newInstance(const QString &_name);
/**
* @brief Creates a new instance with full initialization.
*
* @param _name Name of the card.
* @param _text Rules text or description.
* @param _isToken Token flag.
* @param _properties Arbitrary properties.
* @param _relatedCards Forward relationships.
* @param _reverseRelatedCards Reverse relationships.
* @param _sets Printing information per set.
* @param _uiAttributes Attributes that affect display and game logic
* @param _localizedNames Localized card names, keyed by language code.
* @param _localizedTexts Localized rules text, keyed by language code.
* @return Shared pointer to the new CardInfo instance.
*/
static CardInfoPtr newInstance(const QString &_name,
const QString &_text,
bool _isToken,
const QHash<QString, QString> &_properties,
const QList<CardRelation *> &_relatedCards,
const QList<CardRelation *> &_reverseRelatedCards,
SetToPrintingsMap _sets,
UiAttributes _uiAttributes,
QMap<QString, QString> _localizedNames = {},
QMap<QString, QString> _localizedTexts = {});
/**
* @brief Creates a new instance from a cache snapshot with precomputed
* derived state.
*
* @param _name Name of the card.
* @param _text Rules text or description.
* @param _isToken Token flag.
* @param _propertiesBlob Pre-serialized properties blob (as written by the cache).
* @param _relatedCards Forward relationships.
* @param _reverseRelatedCards Reverse relationships.
* @param _sets Printing information per set.
* @param _uiAttributes Attributes that affect display and game logic.
* @param _simpleName Precomputed simplified name.
* @param _altNames Precomputed alternate names.
* @param _appendToSets When true (default), the card is appended to each of
* its CardSets. Pass false when building cards in parallel so the
* (non-thread-safe) set membership is populated in a later
* single-threaded pass.
* @param _localizedNames Localized card names, keyed by language code.
* @param _localizedTexts Localized rules text, keyed by language code.
* @return Shared pointer to the new CardInfo instance.
*/
static CardInfoPtr newInstance(const QString &_name,
const QString &_text,
bool _isToken,
QByteArray _propertiesBlob,
const QList<CardRelation *> &_relatedCards,
const QList<CardRelation *> &_reverseRelatedCards,
SetToPrintingsMap _sets,
UiAttributes _uiAttributes,
QString _simpleName,
QSet<QString> _altNames,
bool _appendToSets = true,
QMap<QString, QString> _localizedNames = {},
QMap<QString, QString> _localizedTexts = {});
/**
* @brief Clones the current CardInfo instance.
*
* Uses the copy constructor and ensures the smart pointer is properly set.
*
* @return Shared pointer to the cloned CardInfo.
*/
[[nodiscard]] CardInfoPtr clone() const
{
auto newCardInfo = CardInfoPtr(new CardInfo(*this));
newCardInfo->setSmartPointer(newCardInfo); // Set the smart pointer for the new instance
return newCardInfo;
}
/**
* @brief Sets the internal smart pointer to self.
*
* Used internally to allow safe cross-references among CardInfo and CardSet.
*
* @param _ptr Shared pointer pointing to this instance.
*/
void setSmartPointer(CardInfoPtr _ptr)
{
smartThis = std::move(_ptr);
}
/** @name Basic Properties Accessors */ //@{
[[nodiscard]] inline const QString &getName() const
{
return name;
}
[[nodiscard]] const QString &getSimpleName() const
{
return simpleName;
}
const QSet<QString> &getAltNames()
{
return altNames;
}
[[nodiscard]] const QString &getText() const
{
return text;
}
void setText(const QString &_text)
{
text = _text;
emit cardInfoChanged(smartThis);
}
/**
* @brief Returns the card name in the given language, falling back to the
* English name when no localization is available.
*
* @param lang Language code (e.g. "de", "ja", "zhs").
* @return The localized name, or the English name as fallback.
*/
[[nodiscard]] const QString &getLocalizedName(const QString &lang) const
{
const auto it = localizedNames.constFind(lang);
return it != localizedNames.constEnd() ? it.value() : name;
}
/**
* @brief Returns the rules text in the given language, falling back to the
* English text when no localization is available.
*
* @param lang Language code (e.g. "de", "ja", "zhs").
* @return The localized text, or the English text as fallback.
*/
[[nodiscard]] const QString &getLocalizedText(const QString &lang) const
{
const auto it = localizedTexts.constFind(lang);
return it != localizedTexts.constEnd() ? it.value() : text;
}
/**
* @brief Returns the localized card names keyed by language code.
*
* Only languages that have an entry are present; there is no English
* fallback in this map.
*/
[[nodiscard]] const QMap<QString, QString> &getLocalizedNames() const
{
return localizedNames;
}
/**
* @brief Returns the localized rules text keyed by language code.
*
* Only languages that have an entry are present; there is no English
* fallback in this map.
*/
[[nodiscard]] const QMap<QString, QString> &getLocalizedTexts() const
{
return localizedTexts;
}
/**
* @brief Sets the card name for the given language.
*
* @param lang Language code.
* @param _localizedName The localized card name.
*/
void setLocalizedName(const QString &lang, const QString &_localizedName)
{
if (localizedNames.value(lang) == _localizedName) {
return;
}
localizedNames.insert(lang, _localizedName);
emit cardInfoChanged(smartThis);
}
/**
* @brief Sets the rules text for the given language.
*
* @param lang Language code.
* @param _localizedText The localized rules text.
*/
void setLocalizedText(const QString &lang, const QString &_localizedText)
{
if (localizedTexts.value(lang) == _localizedText) {
return;
}
localizedTexts.insert(lang, _localizedText);
emit cardInfoChanged(smartThis);
}
/**
* @brief Returns the language codes for which this card has a localized
* name or rules text.
*/
[[nodiscard]] QStringList localizationLanguages() const
{
QStringList languages = localizedNames.keys();
languages.append(localizedTexts.keys());
languages.removeDuplicates();
return languages;
}
[[nodiscard]] bool getIsToken() const
{
return isToken;
}
[[nodiscard]] QStringList getProperties() const
{
return getPropertiesHash().keys();
}
[[nodiscard]] const QHash<QString, QString> &getPropertiesHash() const;
[[nodiscard]] QString getProperty(const QString &propertyName) const
{
return getPropertiesHash().value(propertyName);
}
void setProperty(const QString &_name, const QString &_value);
[[nodiscard]] bool hasProperty(const QString &propertyName) const
{
return getPropertiesHash().contains(propertyName);
}
[[nodiscard]] const SetToPrintingsMap &getSets() const
{
return setsToPrintings;
}
[[nodiscard]] const QString &getSetsNames() const
{
return setsNames;
}
//@}
/** @name Related Cards Accessors */ //@{
[[nodiscard]] const QList<CardRelation *> &getRelatedCards() const
{
return relatedCards;
}
[[nodiscard]] const QList<CardRelation *> &getReverseRelatedCards() const
{
return reverseRelatedCards;
}
[[nodiscard]] const QList<CardRelation *> &getReverseRelatedCards2Me() const
{
return reverseRelatedCardsToMe;
}
[[nodiscard]] QList<CardRelation *> getAllRelatedCards() const
{
QList<CardRelation *> result;
result.append(getRelatedCards());
result.append(getReverseRelatedCards2Me());
return result;
}
void resetReverseRelatedCards2Me();
void addReverseRelatedCards2Me(CardRelation *cardRelation)
{
reverseRelatedCardsToMe.append(cardRelation);
}
//@}
/** @name UI Positioning */ //@{
[[nodiscard]] const UiAttributes &getUiAttributes() const
{
return uiAttributes;
}
//@}
[[nodiscard]] QChar getColorChar() const;
/** @name Legacy/Convenience Property Accessors */ //@{
[[nodiscard]] QString getCardType() const;
void setCardType(const QString &value);
[[nodiscard]] QString getCmc() const;
[[nodiscard]] QString getColors() const;
void setColors(const QString &value);
[[nodiscard]] QString getLoyalty() const;
[[nodiscard]] QString getMainCardType() const;
[[nodiscard]] QString getManaCost() const;
[[nodiscard]] QString getPowTough() const;
void setPowTough(const QString &value);
//@}
/**
* @brief Returns a version of the card name safe for file storage or fuzzy matching.
*
* Removes invalid characters, replaces spacing markers, and normalizes diacritics.
*
* @return Corrected card name as a QString.
*/
[[nodiscard]] QString getCorrectedName() const;
/**
* @brief Gets the card's legality value for the given format.
* The legality prop for a format is stored in the property map under the key "format-<name>"
* @param format The format's name.
* @return The card's legality value for the format. Empty if not found.
*/
[[nodiscard]] QString getLegalityProp(const QString &format) const;
/**
* @brief Checks if the card is legal in the given format.
* A card is considered legal in a format if its properties map contains an entry for "format-<name>", with value
* "legal" or "restricted".
* @param format The format's name. If empty, will always return true.
* @return Whether the card is legal in the given format.
*/
[[nodiscard]] bool isLegalInFormat(const QString &format) const;
/**
* @brief Adds a printing to a specific set.
*
* Updates the mapping and refreshes the cached list of set names.
*
* @param _set The set to which the card should be added.
* @param _info Optional printing information.
*/
void addToSet(const CardSetPtr &_set, const PrintingInfo &_info = PrintingInfo());
/**
* @brief Combines legality properties from a provided map.
*
* Useful for merging format legality flags from multiple sources.
*
* @param props Key-value mapping of format legalities.
*/
void combineLegalities(const QHash<QString, QString> &props);
/**
* @brief Refreshes all cached fields that are calculated from the contained sets and printings.
*
* Typically called after adding or modifying set memberships or printings.
*/
void refreshCachedSets();
/**
* @brief Simplifies a name for fuzzy matching.
*
* Converts to lowercase, removes punctuation/spacing.
*
* @param name Original name string.
* @return Simplified name string.
*/
static QString simplifyName(const QString &name);
private:
/**
* @brief Refreshes the cached, human-readable list of set names.
*
* Typically called after adding or modifying set memberships.
*/
void refreshCachedSetNames();
/**
* @brief Refreshes the cached list of alt names for the card.
*
* Typically called after adding or modifying the contained printings.
*/
void refreshCachedAltNames();
signals:
/**
* @brief Emitted when a pixmap for this card has been updated or finished loading.
*
* @param printing Specific printing for which the pixmap has updated.
*/
void pixmapUpdated(const PrintingInfo &printing);
/**
* @brief Emitted when card properties or state have changed.
*
* @param card Shared pointer to the CardInfo instance that changed.
*/
void cardInfoChanged(CardInfoPtr card);
};
#endif