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);
110 for (
const QString &file : qmFiles) {
111 QString langCode = file;
112 langCode.remove(
"wpanda_");
113 langCode.remove(
".qm");
115 if (!langCode.isEmpty() && QResource(QStringLiteral(
":/i18n/") + file).isValid()) {
116 languages << langCode;
125 static const QStringList kKnownLanguages = {
126 "ar",
"bg",
"bn",
"cs",
"da",
"de",
"el",
"es",
"et",
"fa",
"fi",
"fr",
127 "he",
"hi",
"hr",
"hu",
"id",
"it",
"ja",
"ko",
"lt",
"lv",
"ms",
"nb",
128 "nl",
"pl",
"pt",
"pt_BR",
"ro",
"ru",
"sk",
"sv",
"th",
"tr",
"uk",
129 "vi",
"zh_Hans",
"zh_Hant"
132 for (
const QString &langCode : kKnownLanguages) {
133 if (QResource(QStringLiteral(
":/i18n/wpanda_%1.qm").arg(langCode)).isValid()) {
134 languages << langCode;
140 languages.removeDuplicates();
147 QLocale locale(langCode);
149 if (langCode ==
"pt_BR") {
150 locale = QLocale(QLocale::Portuguese, QLocale::Brazil);
153 QString name = locale.nativeLanguageName();
155 if (langCode.contains(
'_')) {
156 const QString country = locale.nativeTerritoryName();
157 if (!country.isEmpty() && country != name) {
158 name += QString(
" (%1)").arg(country);
162 if (name.isEmpty()) {
164 static const QMap<QString, QString> kFallbacks = {
170 name = kFallbacks.value(langCode, langCode);
173 if (!name.isEmpty() && name.at(0).isLetter()) {
174 name[0] = name.at(0).toUpper();
183 static const QMap<QString, QString> kFlags = {
184 {
"ar",
":/Interface/Locale/arabic.svg"},
185 {
"bg",
":/Interface/Locale/bulgarian.svg"},
186 {
"bn",
":/Interface/Locale/bangladesh.svg"},
187 {
"cs",
":/Interface/Locale/czech.svg"},
188 {
"da",
":/Interface/Locale/danish.svg"},
189 {
"de",
":/Interface/Locale/german.svg"},
190 {
"el",
":/Interface/Locale/greek.svg"},
191 {
"en",
":/Interface/Locale/usa.svg"},
192 {
"es",
":/Interface/Locale/spanish.svg"},
193 {
"et",
":/Interface/Locale/estonian.svg"},
194 {
"fa",
":/Interface/Locale/iranian.svg"},
195 {
"fi",
":/Interface/Locale/finnish.svg"},
196 {
"fr",
":/Interface/Locale/french.svg"},
197 {
"he",
":/Interface/Locale/hebrew.svg"},
198 {
"hi",
":/Interface/Locale/hindi.svg"},
199 {
"hr",
":/Interface/Locale/croatian.svg"},
200 {
"hu",
":/Interface/Locale/hungarian.svg"},
201 {
"id",
":/Interface/Locale/indonesian.svg"},
202 {
"it",
":/Interface/Locale/italian.svg"},
203 {
"ja",
":/Interface/Locale/japanese.svg"},
204 {
"ko",
":/Interface/Locale/korean.svg"},
205 {
"lt",
":/Interface/Locale/lithuanian.svg"},
206 {
"lv",
":/Interface/Locale/latvian.svg"},
207 {
"ms",
":/Interface/Locale/malaysian.svg"},
208 {
"nb",
":/Interface/Locale/norwegian.svg"},
209 {
"nl",
":/Interface/Locale/dutch.svg"},
210 {
"pl",
":/Interface/Locale/polish.svg"},
211 {
"pt",
":/Interface/Locale/portuguese.svg"},
212 {
"pt_BR",
":/Interface/Locale/brasil.svg"},
213 {
"ro",
":/Interface/Locale/romanian.svg"},
214 {
"ru",
":/Interface/Locale/russian.svg"},
215 {
"sk",
":/Interface/Locale/slovak.svg"},
216 {
"sv",
":/Interface/Locale/swedish.svg"},
217 {
"th",
":/Interface/Locale/thai.svg"},
218 {
"tr",
":/Interface/Locale/turkish.svg"},
219 {
"uk",
":/Interface/Locale/ukrainian.svg"},
220 {
"vi",
":/Interface/Locale/vietnamese.svg"},
221 {
"zh_Hans",
":/Interface/Locale/chinese.svg"},
222 {
"zh_Hant",
":/Interface/Locale/chinese_traditional.svg"},
225 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)