TranslationCatalog.h header

#include <ew/core/TranslationCatalog.h>

Namespace ew::core

TranslationCatalog class

class ew::core::TranslationCatalog

Every translation for one locale.

A project holds one catalogue per locale, and they are parallel, not alternative. This is the reason the localization pipeline does not reuse ew::core::document::DocumentVariant: a variant is the writer's "what-if" draft, of which exactly one is active and IS the document's live body, so selecting a locale would rewrite the project and make exporting two languages in one pass impossible. Locales must all exist at once and none of them is the body.

Members

ew::core::localization::TranslationCatalog::TranslationCatalog(QString locale)

Creates an empty catalogue for locale, a BCP-47 tag such as es or pt-BR.

const QString & ew::core::localization::TranslationCatalog::locale() const

The BCP-47 tag this catalogue translates into.

const std::map< StringId, TranslationEntry > & ew::core::localization::TranslationCatalog::entries() const

Every entry, ordered by address so the serialized form is stable and diff-friendly.

const TranslationEntry * ew::core::localization::TranslationCatalog::find(const StringId &id) const

The entry for id, or null when the string has never been translated.

void ew::core::localization::TranslationCatalog::set(const StringId &id, TranslationEntry entry)

Adds or replaces the entry for id.

void ew::core::localization::TranslationCatalog::remove(const StringId &id)

Removes the entry for id; harmless if there is none.

void ew::core::localization::TranslationCatalog::setEntries(std::map< StringId, TranslationEntry > entries)

Replaces every entry at once (used by the loader and by an import).

TranslationStatus ew::core::localization::TranslationCatalog::statusFor(const StringId &id, const QString &currentSourceText) const

What id still needs, given the source text it would be translated from.

currentSourceText is passed in rather than looked up because a catalogue holds translations, not the project – keeping it ignorant of where sources live is what lets the same type serve a document body, an entity property and a category label without knowing the difference between them.

Stale outranks NeedsReview when both apply: a review of text that no longer matches its source is wasted work, so the reviewer needs to hear about the drift first.

TranslationEntry struct

struct ew::core::TranslationEntry

One string's translation, plus what is needed to tell whether it is still true.

Members

QString ew::core::localization::TranslationEntry::text

The translated text.

QString ew::core::localization::TranslationEntry::sourceDigest

A digest of the SOURCE text this translation was made from – the whole point of the entry.

Staleness is a comparison, not a flag: the only way to know a translation has drifted is to hold what it was translated FROM and compare. Storing the source text itself would work and would double the catalogue; a digest answers the same question in fixed size. See sourceDigest().

bool ew::core::localization::TranslationEntry::needsReview = false

Whether a human has been asked to look at this entry. Unlike staleness this is an INTENT, not a fact about the text, so it is stored rather than derived.

Enumerations

enum class TranslationStatus { New, Translated, NeedsReview, Stale }

What a translator or reviewer still owes a given string.

DERIVED, NEVER STORED. There is deliberately no toToken/fromToken pair for this enum and it must not gain one: a stored status would have to be rewritten across the whole catalogue every time the writer touched a source string, and the one that got missed would claim a translation was current when it no longer matched. Ask TranslationCatalog::statusFor instead, which computes the answer from the source in front of it.

Functions

QString ew::core::localization::sourceDigest(const QString &sourceText)

The digest of sourceText, as stored in TranslationEntry::sourceDigest.

SHA-256, hex, in full. A truncated digest would collide eventually, and a collision here does not look like a crash – it silently reports a stale translation as current, which is precisely the failure this whole mechanism exists to prevent.