12#include <QFontDatabase>
19static void loadAllFonts()
21 static const QStringList kFontPaths = {
22 ":/Fonts/NotoSansArabic-Regular.ttf",
23 ":/Fonts/NotoSansBengali-Regular.ttf",
24 ":/Fonts/NotoSansDevanagari-Regular.ttf",
25 ":/Fonts/NotoSansHebrew-Regular.ttf",
26 ":/Fonts/NotoSansKR-Regular.ttf",
27 ":/Fonts/NotoSansSC-Regular.ttf",
28 ":/Fonts/NotoSansThai-Regular.ttf",
31 for (
const auto &path : kFontPaths) {
32 if (QFontDatabase::addApplicationFont(path) == -1) {
33 qWarning() <<
"Failed to load WASM font:" << path;
56 if (language.isEmpty()) {
67 m_translator =
nullptr;
69 if (language ==
"en") {
80 const QString qmFile = QStringLiteral(
":/i18n/wpanda_%1.qm").arg(language);
82 if (QResource(qmFile).isValid()) {
83 m_translator =
new QTranslator(
this);
86 qWarning() <<
"Failed to load translation for" << language <<
", falling back to English";
88 m_translator =
nullptr;
99 QStringList languages = {
"en"};
102 QDir translationsDir(QStringLiteral(
":/i18n"));
103 if (translationsDir.exists()) {
104 const QStringList qmFiles = translationsDir.entryList({
"wpanda_*.qm"}, QDir::Files);
106 for (
const QString &file : qmFiles) {
107 QString langCode = file;
108 langCode.remove(
"wpanda_");
109 langCode.remove(
".qm");
111 if (!langCode.isEmpty() && QResource(QStringLiteral(
":/i18n/") + file).isValid()) {
112 languages << langCode;
117 static const QStringList kKnownLanguages = {
118 "ar",
"bg",
"bn",
"cs",
"da",
"de",
"el",
"es",
"et",
"fa",
"fi",
"fr",
119 "he",
"hi",
"hr",
"hu",
"id",
"it",
"ja",
"ko",
"lt",
"lv",
"ms",
"nb",
120 "nl",
"pl",
"pt",
"pt_BR",
"ro",
"ru",
"sk",
"sv",
"th",
"tr",
"uk",
121 "vi",
"zh_Hans",
"zh_Hant"
124 for (
const QString &langCode : kKnownLanguages) {
125 if (QResource(QStringLiteral(
":/i18n/wpanda_%1.qm").arg(langCode)).isValid()) {
126 languages << langCode;
131 languages.removeDuplicates();
138 QLocale locale(langCode);
140 if (langCode ==
"pt_BR") {
141 locale = QLocale(QLocale::Portuguese, QLocale::Brazil);
144 QString name = locale.nativeLanguageName();
146 if (langCode.contains(
'_')) {
147 const QString country = locale.nativeTerritoryName();
148 if (!country.isEmpty() && country != name) {
149 name += QString(
" (%1)").arg(country);
153 if (name.isEmpty()) {
155 static const QMap<QString, QString> kFallbacks = {
161 name = kFallbacks.value(langCode, langCode);
164 if (!name.isEmpty() && name.at(0).isLetter()) {
165 name[0] = name.at(0).toUpper();
174 static const QMap<QString, QString> kFlags = {
175 {
"ar",
":/Interface/Locale/arabic.svg"},
176 {
"bg",
":/Interface/Locale/bulgarian.svg"},
177 {
"bn",
":/Interface/Locale/bangladesh.svg"},
178 {
"cs",
":/Interface/Locale/czech.svg"},
179 {
"da",
":/Interface/Locale/danish.svg"},
180 {
"de",
":/Interface/Locale/german.svg"},
181 {
"el",
":/Interface/Locale/greek.svg"},
182 {
"en",
":/Interface/Locale/usa.svg"},
183 {
"es",
":/Interface/Locale/spanish.svg"},
184 {
"et",
":/Interface/Locale/estonian.svg"},
185 {
"fa",
":/Interface/Locale/iranian.svg"},
186 {
"fi",
":/Interface/Locale/finnish.svg"},
187 {
"fr",
":/Interface/Locale/french.svg"},
188 {
"he",
":/Interface/Locale/hebrew.svg"},
189 {
"hi",
":/Interface/Locale/hindi.svg"},
190 {
"hr",
":/Interface/Locale/croatian.svg"},
191 {
"hu",
":/Interface/Locale/hungarian.svg"},
192 {
"id",
":/Interface/Locale/indonesian.svg"},
193 {
"it",
":/Interface/Locale/italian.svg"},
194 {
"ja",
":/Interface/Locale/japanese.svg"},
195 {
"ko",
":/Interface/Locale/korean.svg"},
196 {
"lt",
":/Interface/Locale/lithuanian.svg"},
197 {
"lv",
":/Interface/Locale/latvian.svg"},
198 {
"ms",
":/Interface/Locale/malaysian.svg"},
199 {
"nb",
":/Interface/Locale/norwegian.svg"},
200 {
"nl",
":/Interface/Locale/dutch.svg"},
201 {
"pl",
":/Interface/Locale/polish.svg"},
202 {
"pt",
":/Interface/Locale/portuguese.svg"},
203 {
"pt_BR",
":/Interface/Locale/brasil.svg"},
204 {
"ro",
":/Interface/Locale/romanian.svg"},
205 {
"ru",
":/Interface/Locale/russian.svg"},
206 {
"sk",
":/Interface/Locale/slovak.svg"},
207 {
"sv",
":/Interface/Locale/swedish.svg"},
208 {
"th",
":/Interface/Locale/thai.svg"},
209 {
"tr",
":/Interface/Locale/turkish.svg"},
210 {
"uk",
":/Interface/Locale/ukrainian.svg"},
211 {
"vi",
":/Interface/Locale/vietnamese.svg"},
212 {
"zh_Hans",
":/Interface/Locale/chinese.svg"},
213 {
"zh_Hant",
":/Interface/Locale/chinese_traditional.svg"},
216 return kFlags.value(langCode,
":/Interface/Locale/default.svg");
Custom QApplication subclass with exception handling and main-window access.
LanguageManager: Qt translation loading and language metadata.
Typed wrappers around QSettings for all application preferences.
static Application * instance()
Returns the application instance cast to Application*.
void loadTranslation(const QString &language)
Loads and installs the Qt translation for language.
LanguageManager(QObject *parent=nullptr)
void translationChanged()
Emitted after a translation has been successfully loaded (or reset to English).
QString flagIcon(const QString &langCode) const
Returns the flag icon resource path for langCode.
QStringList availableLanguages() const
Returns all available translation language codes, sorted, with "en" first.
~LanguageManager() override
QString displayName(const QString &langCode) const
Returns the native display name for langCode (e.g. "Deutsch" for "de").
static void setLanguage(const QString &lang)