diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-15 12:56:40 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-15 12:56:40 +0200 |
| commit | c9392961aa3554a17ab88bfe3ad4e6b76b9a60bc (patch) | |
| tree | 6e7c4394a6baa774ed5ba2fd3b3fb343f9bf4b57 /src/config.cpp | |
| parent | 5a3f827a01d1902a0dadc5debb4200138d4af885 (diff) | |
| download | qtmaildir-c9392961aa3554a17ab88bfe3ad4e6b76b9a60bc.tar.gz qtmaildir-c9392961aa3554a17ab88bfe3ad4e6b76b9a60bc.zip | |
feat(i18n): add a language key overriding the system locale
The interface language followed the environment and nothing else, so
choosing it meant setting LANG for the whole application. [general]
language overrides it in both directions: it selects Italian on an English
desktop, and en_US forces English on an Italian one.
A short code or a full locale name both work, since Qt resolves "it" to
it_IT when the QLocale is built and QTranslator::load falls back from
qtmaildir_it_IT to qtmaildir_it. "system" is the default written down, so
the default can be expressed rather than only reached by deleting the key.
Validated on the locale NAME rather than on whether a translation loads,
because those are different questions and only one is an error. QLocale
accepts any string and degrades an unrecognised one to C rather than
failing, so `language = itallian` loads no translation and is otherwise
indistinguishable from asking for English on purpose; meanwhile
`language = en_US` legitimately loads nothing, English being the source
language and shipping no .qm. Checking the name separates the typo from
the deliberate choice, and the typo is reported.
The translator is now installed after Config is loaded, since the config
is what chooses it. The cost is that config warnings are generated before
the translator exists and are therefore built in English; retranslating
them would mean re-running load(), and a warning about the config file is
the one string a user can still act on in either language.
Verified against the real loader across six configurations, under both
LANG=en_US and LANG=it_IT: short and full codes select Italian, system and
an absent key follow the environment, en_US forces English whatever the
environment says, and a bad name reports a problem and falls back. Two
mutations checked: dropping the name validation and treating "system" as a
locale name each fail a test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/config.cpp')
| -rw-r--r-- | src/config.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/config.cpp b/src/config.cpp index 266ed39..600c558 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -196,6 +196,30 @@ void Config::load(const QString &path) m_startupAccount = settings.value(QStringLiteral("startup_account")).toString().trimmed(); + // Interface language. "system" is spelled out so the default can be written + // down rather than only expressed by deleting the key. + // + // Validated here rather than left to whether a translation loads, because + // those are different questions and only one of them is an error. QLocale + // accepts anything and degrades an unrecognised name to C, so `language = + // itallian` would load no translation and look exactly like asking for + // English. Meanwhile `language = en_US` legitimately loads nothing, since + // English is the source language and ships no .qm. Checking the NAME + // separates the typo from the deliberate choice. + const QString language = + settings.value(QStringLiteral("language")).toString().trimmed(); + if (!language.isEmpty() + && language.compare(QStringLiteral("system"), Qt::CaseInsensitive) != 0) { + if (QLocale(language).language() == QLocale::C) { + addProblem(tr("Language '%1' is not a locale name; using the " + "system language. Expected something like 'it' or " + "'it_IT'.") + .arg(language)); + } else { + m_language = language; + } + } + const QVariant zoom = settings.value(QStringLiteral("message_zoom")); if (zoom.isValid()) { bool ok = false; |
