From e85f4894297ac328105d332a34e0b200ead7263c Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sat, 18 Oct 2025 22:49:36 +0800 Subject: [PATCH 01/13] feat: Implement language selection feature --- Assets/Translations/en.json | 12 ++++++++++- Assets/settings-default.json | 5 +++-- Commons/I18n.qml | 7 +++++++ Commons/Settings.qml | 1 + Modules/Settings/Tabs/GeneralTab.qml | 31 +++++++++++++++++++++++++++- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index e8ee372b..5c0b9e5d 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -68,6 +68,16 @@ "description": "Increase or decrease the size of the monospaced text." } } + }, + "language": { + "section": { + "label": "Language", + "description": "Choose your preferred language for the application." + }, + "select": { + "label": "Application Language", + "description": "Select the language used in the application's interface." + } } }, "audio": { @@ -1197,7 +1207,7 @@ "scan-again": "Scan again" } }, - + "tooltips": { "refresh": "Refresh", "close": "Close", diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 27f2b735..850fc6f8 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -66,7 +66,8 @@ "animationSpeed": 1, "animationDisabled": false, "compactLockScreen": false, - "lockOnSuspend": true + "lockOnSuspend": true, + "language": "en" }, "location": { "name": "Tokyo", @@ -255,4 +256,4 @@ "battery": { "chargingMode": 0 } -} \ No newline at end of file +} diff --git a/Commons/I18n.qml b/Commons/I18n.qml index 6f49f097..fe2ab0a6 100644 --- a/Commons/I18n.qml +++ b/Commons/I18n.qml @@ -168,6 +168,13 @@ Singleton { } } + // Check for user-defined language setting + if (Settings.data.general.language !== "" && availableLanguages.includes(Settings.data.general.language)) { + Logger.d("I18n", `User-defined language found: "${Settings.data.general.language}"`) + setLanguage(Settings.data.general.language) + return + } + // Detect user's favorite locale - languages for (var i = 0; i < Qt.locale().uiLanguages.length; i++) { const fullUserLang = Qt.locale().uiLanguages[i] diff --git a/Commons/Settings.qml b/Commons/Settings.qml index a0306c13..6799dc8e 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -192,6 +192,7 @@ Singleton { property bool animationDisabled: false property bool compactLockScreen: false property bool lockOnSuspend: true + property string language: "en" } // location diff --git a/Modules/Settings/Tabs/GeneralTab.qml b/Modules/Settings/Tabs/GeneralTab.qml index 0a63a7fd..3bd5de54 100644 --- a/Modules/Settings/Tabs/GeneralTab.qml +++ b/Modules/Settings/Tabs/GeneralTab.qml @@ -190,7 +190,36 @@ ColumnLayout { Layout.bottomMargin: Style.marginXL } - // Lock Screen + // Language selection + ColumnLayout { + spacing: Style.marginL + Layout.fillWidth: true + + NHeader { + label: I18n.tr("settings.general.language.section.label") + description: I18n.tr("settings.general.language.section.description") + } + + NComboBox { + Layout.fillWidth: true + label: I18n.tr("settings.general.language.select.label") + description: I18n.tr("settings.general.language.select.description") + model: I18n.availableLanguages.map(function(langCode) { + return { "key": langCode, "name": langCode } + }) + currentKey: Settings.data.general.language !== "" ? Settings.data.general.language : I18n.langCode + onSelected: key => { + Settings.data.general.language = key + I18n.setLanguage(key) + } + } + } + + NDivider { + Layout.fillWidth: true + Layout.topMargin: Style.marginXL + Layout.bottomMargin: Style.marginXL + } ColumnLayout { spacing: Style.marginL Layout.fillWidth: true From 677cd373aca8979c5019ecd22835f231b49055dc Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sat, 18 Oct 2025 22:52:38 +0800 Subject: [PATCH 02/13] feat(i18n): Add language selection translation for German --- Assets/Translations/de.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index f53299c2..5cffaab1 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -68,6 +68,16 @@ } }, "reset-scaling": "Skalierung zurücksetzen" + }, + "language": { + "section": { + "label": "Sprache", + "description": "Wählen Sie Ihre bevorzugte Sprache für die Anwendung." + }, + "select": { + "label": "Anwendungssprache", + "description": "Wählen Sie die in der Anwendungsoberfläche verwendete Sprache." + } } }, "audio": { From 3e7386b344ea66ff5bcb1b4b9c33bbc0de604f92 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sat, 18 Oct 2025 22:53:48 +0800 Subject: [PATCH 03/13] feat(i18n): Add language selection translation for Spanish --- Assets/Translations/es.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 77bd8612..7df19467 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -68,6 +68,16 @@ } }, "reset-scaling": "Restablecer la escala" + }, + "language": { + "section": { + "label": "Idioma", + "description": "Elige tu idioma preferido para la aplicación." + }, + "select": { + "label": "Idioma de la aplicación", + "description": "Selecciona el idioma utilizado en la interfaz de la aplicación." + } } }, "audio": { From a594a03e584da26a7b6c8a1b5213f12cf450a729 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sat, 18 Oct 2025 22:55:18 +0800 Subject: [PATCH 04/13] feat(i18n): Add language selection translation for French --- Assets/Translations/fr.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index f180575a..a4ab5fe1 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -68,6 +68,16 @@ } }, "reset-scaling": "Réinitialiser l'échelle" + }, + "language": { + "section": { + "label": "Langue", + "description": "Choisissez votre langue préférée pour l'application." + }, + "select": { + "label": "Langue de l'application", + "description": "Sélectionnez la langue utilisée dans l'interface de l'application." + } } }, "audio": { From 57fe2c1a21f8568f70535163528da13b0e379df5 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sat, 18 Oct 2025 22:56:17 +0800 Subject: [PATCH 05/13] feat(i18n): Add language selection translation for Portuguese --- Assets/Translations/pt.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 5e2a5658..16f24122 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -68,6 +68,16 @@ } }, "reset-scaling": "Redefinir escala" + }, + "language": { + "section": { + "label": "Idioma", + "description": "Escolha o seu idioma preferido para a aplicação." + }, + "select": { + "label": "Idioma da aplicação", + "description": "Selecione o idioma usado na interface da aplicação." + } } }, "audio": { From 5cffc848033dae2e7561ac93c3096b7c3036e829 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sat, 18 Oct 2025 22:57:19 +0800 Subject: [PATCH 06/13] feat(i18n): Add language selection translation for Simplified Chinese --- Assets/Translations/zh-CN.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 889266c4..c9532210 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -68,6 +68,16 @@ "description": "增大或减小等宽文本的尺寸" } } + }, + "language": { + "section": { + "label": "语言", + "description": "选择您偏好的应用程序语言。" + }, + "select": { + "label": "应用程序语言", + "description": "选择应用程序界面中使用的语言。" + } } }, "audio": { From 80443bb74ef40f00aefa340f81afeeab679495c1 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:25:03 +0800 Subject: [PATCH 07/13] fix(languge): language defaults to an empty string --- Assets/settings-default.json | 2 +- Commons/Settings.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 850fc6f8..04aaab90 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -67,7 +67,7 @@ "animationDisabled": false, "compactLockScreen": false, "lockOnSuspend": true, - "language": "en" + "language": "" }, "location": { "name": "Tokyo", diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 6799dc8e..937ab041 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -192,7 +192,7 @@ Singleton { property bool animationDisabled: false property bool compactLockScreen: false property bool lockOnSuspend: true - property string language: "en" + property string language: "" } // location From 63bd97e76f952d302dd3b38e3acc06fd8d648ff1 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:29:39 +0800 Subject: [PATCH 08/13] feat(i18n): Implement and refine language selection feature Introduces a language selection option in settings, allowing users to manually choose an application language or revert to automatic system locale detection. This includes UI updates, settings integration, and improved language detection logic. --- Assets/Translations/en.json | 3 +- Commons/I18n.qml | 55 ++++++++++++---------------- Modules/Settings/Tabs/GeneralTab.qml | 14 +++++-- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 5c0b9e5d..783dc34b 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -76,7 +76,8 @@ }, "select": { "label": "Application Language", - "description": "Select the language used in the application's interface." + "description": "Select the language used in the application's interface.", + "auto-detect": "Automatic" } } }, diff --git a/Commons/I18n.qml b/Commons/I18n.qml index fe2ab0a6..4ec5e86f 100644 --- a/Commons/I18n.qml +++ b/Commons/I18n.qml @@ -7,10 +7,11 @@ import qs.Commons Singleton { id: root - property string debugForceLanguage: "" + property bool isLoaded: false property string langCode: "" + property string systemDetectedLangCode: "" property var availableLanguages: [] property var translations: ({}) property var fallbackTranslations: ({}) @@ -158,48 +159,40 @@ Singleton { return } - if (Settings.isDebug && debugForceLanguage !== "") { - Logger.d("I18n", `Debug mode: forcing language to "${debugForceLanguage}"`) - if (availableLanguages.includes(debugForceLanguage)) { - setLanguage(debugForceLanguage) - return - } else { - Logger.w("I18n", `Debug language "${debugForceLanguage}" not available in [${availableLanguages.join(', ')}]`) - } - } + var detectedLang = "" - // Check for user-defined language setting - if (Settings.data.general.language !== "" && availableLanguages.includes(Settings.data.general.language)) { - Logger.d("I18n", `User-defined language found: "${Settings.data.general.language}"`) - setLanguage(Settings.data.general.language) - return - } - - // Detect user's favorite locale - languages + // First, determine the system's preferred language for (var i = 0; i < Qt.locale().uiLanguages.length; i++) { const fullUserLang = Qt.locale().uiLanguages[i] - // Try full code match (such as zh CN, en US) if (availableLanguages.includes(fullUserLang)) { - Logger.d("I18n", `Exact match found: "${fullUserLang}"`) - setLanguage(fullUserLang) - return + detectedLang = fullUserLang + break } - // If full code match fails, try short code matching (such as zh, en) const shortUserLang = fullUserLang.substring(0, 2) if (availableLanguages.includes(shortUserLang)) { - Logger.d("I18n", `Short code match found: "${shortUserLang}" from "${fullUserLang}"`) - setLanguage(shortUserLang) - return + detectedLang = shortUserLang + break } - - Logger.d("I18n", `No match for system language: "${fullUserLang}"`) } - // Fallback to first available language (preferably "en" if available) - const fallbackLang = availableLanguages.includes("en") ? "en" : availableLanguages[0] - setLanguage(fallbackLang) + // If no system language is found among available languages, fallback + if (detectedLang === "") { + detectedLang = availableLanguages.includes("en") ? "en" : availableLanguages[0] + } + + root.systemDetectedLangCode = detectedLang + Logger.d("I18n", `System detected language: "${root.systemDetectedLangCode}"`) + + // Now, apply the language: user-defined, then system-detected + if (Settings.data.general.language !== "" && availableLanguages.includes(Settings.data.general.language)) { + Logger.d("I18n", `User-defined language found: "${Settings.data.general.language}"`) + setLanguage(Settings.data.general.language) + } else { + Logger.d("I18n", `No user-defined language, using system detected: "${root.systemDetectedLangCode}"`) + setLanguage(root.systemDetectedLangCode) + } } // ------------------------------------------- diff --git a/Modules/Settings/Tabs/GeneralTab.qml b/Modules/Settings/Tabs/GeneralTab.qml index 3bd5de54..40b5276d 100644 --- a/Modules/Settings/Tabs/GeneralTab.qml +++ b/Modules/Settings/Tabs/GeneralTab.qml @@ -204,13 +204,19 @@ ColumnLayout { Layout.fillWidth: true label: I18n.tr("settings.general.language.select.label") description: I18n.tr("settings.general.language.select.description") - model: I18n.availableLanguages.map(function(langCode) { + model: [ + { "key": "", "name": I18n.tr("settings.general.language.select.auto-detect") + " (" + I18n.systemDetectedLangCode + ")" } + ].concat(I18n.availableLanguages.map(function(langCode) { return { "key": langCode, "name": langCode } - }) - currentKey: Settings.data.general.language !== "" ? Settings.data.general.language : I18n.langCode + })) + currentKey: Settings.data.general.language onSelected: key => { Settings.data.general.language = key - I18n.setLanguage(key) + if (key === "") { + I18n.detectLanguage() // Re-detect system language if "Automatic" is selected + } else { + I18n.setLanguage(key) // Set specific language + } } } } From 66de0222b098d41e51318cd7e3834a6087fa57cf Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:39:23 +0800 Subject: [PATCH 09/13] feat(i18n): Add German translation for language auto-detect --- Assets/Translations/de.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 5cffaab1..f5bc5c5c 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -76,7 +76,8 @@ }, "select": { "label": "Anwendungssprache", - "description": "Wählen Sie die in der Anwendungsoberfläche verwendete Sprache." + "description": "Wählen Sie die in der Anwendungsoberfläche verwendete Sprache.", + "auto-detect": "Automatisch" } } }, From e5b46c2e2b87844bffe81c3489445820a60b751f Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:40:59 +0800 Subject: [PATCH 10/13] feat(i18n): Add Spanish translation for language auto-detect --- Assets/Translations/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 7df19467..13f4a41e 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -76,7 +76,8 @@ }, "select": { "label": "Idioma de la aplicación", - "description": "Selecciona el idioma utilizado en la interfaz de la aplicación." + "description": "Selecciona el idioma utilizado en la interfaz de la aplicación.", + "auto-detect": "Automático" } } }, From f58391ce809b384301faaa28f736f523be433c47 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:42:03 +0800 Subject: [PATCH 11/13] feat(i18n): Add French translation for language auto-detect --- Assets/Translations/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index a4ab5fe1..53c45c13 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -76,7 +76,8 @@ }, "select": { "label": "Langue de l'application", - "description": "Sélectionnez la langue utilisée dans l'interface de l'application." + "description": "Sélectionnez la langue utilisée dans l'interface de l'application.", + "auto-detect": "Automatique" } } }, From 4474e7366b7278c140a10eef21fff39719435d62 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:43:18 +0800 Subject: [PATCH 12/13] feat(i18n): Add Portuguese translation for language auto-detect --- Assets/Translations/pt.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 16f24122..70f6c643 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -76,7 +76,8 @@ }, "select": { "label": "Idioma da aplicação", - "description": "Selecione o idioma usado na interface da aplicação." + "description": "Selecione o idioma usado na interface da aplicação.", + "auto-detect": "Automático" } } }, From 00d8e18a45007f66e1a94aa214d0d33436e295d3 Mon Sep 17 00:00:00 2001 From: loner <2788892716@qq.com> Date: Sun, 19 Oct 2025 01:45:58 +0800 Subject: [PATCH 13/13] feat(i18n): Add Simplified Chinese translation for language auto-detect --- Assets/Translations/zh-CN.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index c9532210..29ec3c67 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -76,7 +76,8 @@ }, "select": { "label": "应用程序语言", - "description": "选择应用程序界面中使用的语言。" + "description": "选择应用程序界面中使用的语言。", + "auto-detect": "自动检测" } } },