mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-24 18:33:03 -07:00
[Client] Show localized card names, texts and pictures
Localization wiring now runs end to end: the oracle importer collects
foreignData for the configured language and the client renders it.
- [Oracle] Import localized names and rules texts for the selected cardLang
- single-face cards store their foreignData name and full text
- multi-face (split/adventure/aftermath/prepare) cards collect the joined
name once and join each face's translated text with the same separator
as the English merge; an incomplete translation falls back to English;
the joined text follows the same highest-priority-set policy as the
single-face path and is only collected when localization is enabled
- the wizard switching languages re-imports the card database
- [Client] Display localized card info throughout the client
- card info text/picture widgets and the game board re-render on language
change
- pictures resolve cardLang art through Scryfall's named endpoint using the
localized name, falling back to id-based art when no match exists
- deck editor keeps canonical English names as card identity (EditRole)
while showing localized names (DisplayRole), so decks and wire names
stay stable
- [Card] Add CardLocalization-backed name/text lookup and cards.xml v4
localization elements with a bounded-size translation cache
- [Tests] Cover oracle foreignData import (incl. multi-face joins, priority
and fallback paths), XML v4 localization parsing, deck model localized
display and the language-aware settings default
Existing installations need to re-run Oracle to see translations: localized
data only lands in cards.xml when the Oracle app is started with the
preferred language selected — launch the separate "Oracle" program that
ships with Cockatrice, pick the language in the wizard and let it re-import
the card database.
The client's database cache (cards.xml.cache) is invalidated by the cache
format bump and the source-hash checks, but a cache written before the
re-import can still hold English-only entries (the hash uses file size and
mtime, so a same-size/same-timestamp rewrite may be served as-is); delete
cards.xml.cache and relaunch if no localized names/texts show up after
re-importing.
This commit is contained in:
parent
fd82b140a8
commit
8bb2337117
35 changed files with 1138 additions and 25 deletions
|
|
@ -107,7 +107,8 @@ public:
|
|||
SplitCardPart(const QString &_name,
|
||||
const QString &_text,
|
||||
const QHash<QString, QString> &_properties,
|
||||
const PrintingInfo &_printingInfo);
|
||||
const PrintingInfo &_printingInfo,
|
||||
const QString &_localizedText = QString());
|
||||
inline const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
|
|
@ -116,6 +117,13 @@ public:
|
|||
{
|
||||
return text;
|
||||
}
|
||||
/**
|
||||
* @brief The cardLang rules text of this face's foreignData entry, if any.
|
||||
*/
|
||||
inline const QString &getLocalizedText() const
|
||||
{
|
||||
return localizedText;
|
||||
}
|
||||
inline const QHash<QString, QString> &getProperties() const
|
||||
{
|
||||
return properties;
|
||||
|
|
@ -128,10 +136,18 @@ public:
|
|||
private:
|
||||
QString name;
|
||||
QString text;
|
||||
QString localizedText;
|
||||
QHash<QString, QString> properties;
|
||||
PrintingInfo printingInfo;
|
||||
};
|
||||
|
||||
struct LocalizedCardEntry
|
||||
{
|
||||
QString name;
|
||||
QString text;
|
||||
CardSet::Priority priority = CardSet::PriorityLowest;
|
||||
};
|
||||
|
||||
class OracleImporter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -171,12 +187,53 @@ private:
|
|||
*/
|
||||
QAtomicInt importCancelled;
|
||||
|
||||
/**
|
||||
* The ISO-639 language code whose foreignData is imported; "en" by default.
|
||||
*/
|
||||
QString cardLang = "en";
|
||||
|
||||
/**
|
||||
* Whether cardLang is a supported language other than English, so per-card
|
||||
* foreignData scanning can be skipped entirely when disabled.
|
||||
*/
|
||||
bool localizationEnabled = false;
|
||||
|
||||
/**
|
||||
* Localized name/text collected per imported card key while parsing sets,
|
||||
* applied to the CardInfo objects by applyLocalizedData() once all
|
||||
* printings have been seen so the best-priority one wins.
|
||||
*/
|
||||
QMap<QString, LocalizedCardEntry> localizedEntries;
|
||||
|
||||
/**
|
||||
* cardLang rules text collected for split-card names while parsing sets,
|
||||
* applied by applyLocalizedData(). Kept apart from localizedEntries because
|
||||
* MTGJSON emits each split face as its own card object with the joined name
|
||||
* on every foreignData entry: names and the per-face text join have different
|
||||
* completeness and must not overwrite each other under the same key.
|
||||
*/
|
||||
QMap<QString, LocalizedCardEntry> splitLocalizedTexts;
|
||||
|
||||
CardInfoPtr addCard(QString name,
|
||||
const QString &text,
|
||||
bool isToken,
|
||||
QHash<QString, QString> properties,
|
||||
const QList<CardRelation *> &relatedCards,
|
||||
const PrintingInfo &printingInfo);
|
||||
|
||||
/**
|
||||
* Records the first foreignData entry matching cardLang for the given card
|
||||
* key, keeping the entry from the highest-priority set seen so far.
|
||||
*
|
||||
* Multi-face cards (split, adventure, aftermath, prepare) pass collectText =
|
||||
* false: MTGJSON emits one foreignData entry per face with the same joined
|
||||
* name but only that face's text, so the name is collected here while the
|
||||
* per-face texts are joined during the split-card merge.
|
||||
*/
|
||||
void collectForeignData(const QString &cardKey,
|
||||
const CardSetPtr ¤tSet,
|
||||
const QJsonObject &card,
|
||||
bool collectText = true);
|
||||
signals:
|
||||
void setIndexChanged(int cardsImported, int setIndex, const QString &setName);
|
||||
void dataReadProgress(int bytesRead, int totalBytes);
|
||||
|
|
@ -195,6 +252,15 @@ public:
|
|||
{
|
||||
progressReporting = enabled;
|
||||
}
|
||||
/**
|
||||
* Selects the ISO-639 language code whose foreignData is imported.
|
||||
* English (the default) and unsupported codes disable localization.
|
||||
*/
|
||||
void setCardLang(const QString &lang);
|
||||
const QString &getCardLang() const
|
||||
{
|
||||
return cardLang;
|
||||
}
|
||||
/**
|
||||
* Scans the given JSON document for set metadata. Takes the data by value so
|
||||
* the wizard can hand over its decompressed buffer without copying it.
|
||||
|
|
@ -212,6 +278,12 @@ public:
|
|||
{
|
||||
importCancelled.storeRelease(1);
|
||||
}
|
||||
/**
|
||||
* Applies the collected localized names/texts to the imported cards.
|
||||
* Called automatically at the end of startImport(); exposed separately so
|
||||
* tests can drive it after importing sets directly.
|
||||
*/
|
||||
void applyLocalizedData();
|
||||
bool saveToFile(const QString &fileName, const QString &sourceUrl, const QString &sourceVersion);
|
||||
int importCardsFromSet(const CardSetPtr ¤tSet, const QJsonArray &cardsList);
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue