mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
Merge pull request #520 from lonerOrz/feature/language-selection
feat: Implement language selection feature
This commit is contained in:
@@ -68,6 +68,17 @@
|
||||
}
|
||||
},
|
||||
"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.",
|
||||
"auto-detect": "Automatisch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
|
||||
@@ -68,6 +68,17 @@
|
||||
"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.",
|
||||
"auto-detect": "Automatic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
@@ -1213,7 +1224,7 @@
|
||||
"scan-again": "Scan again"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"tooltips": {
|
||||
"refresh": "Refresh",
|
||||
"close": "Close",
|
||||
|
||||
@@ -68,6 +68,17 @@
|
||||
}
|
||||
},
|
||||
"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.",
|
||||
"auto-detect": "Automático"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
|
||||
@@ -68,6 +68,17 @@
|
||||
}
|
||||
},
|
||||
"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.",
|
||||
"auto-detect": "Automatique"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
|
||||
@@ -68,6 +68,17 @@
|
||||
}
|
||||
},
|
||||
"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.",
|
||||
"auto-detect": "Automático"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
|
||||
@@ -68,6 +68,17 @@
|
||||
"description": "增大或减小等宽文本的尺寸"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"section": {
|
||||
"label": "语言",
|
||||
"description": "选择您偏好的应用程序语言。"
|
||||
},
|
||||
"select": {
|
||||
"label": "应用程序语言",
|
||||
"description": "选择应用程序界面中使用的语言。",
|
||||
"auto-detect": "自动检测"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
"animationSpeed": 1,
|
||||
"animationDisabled": false,
|
||||
"compactLockScreen": false,
|
||||
"lockOnSuspend": true
|
||||
"lockOnSuspend": true,
|
||||
"language": ""
|
||||
},
|
||||
"location": {
|
||||
"name": "Tokyo",
|
||||
@@ -256,4 +257,4 @@
|
||||
"battery": {
|
||||
"chargingMode": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-24
@@ -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,41 +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 = ""
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
|
||||
@@ -192,6 +192,7 @@ Singleton {
|
||||
property bool animationDisabled: false
|
||||
property bool compactLockScreen: false
|
||||
property bool lockOnSuspend: true
|
||||
property string language: ""
|
||||
}
|
||||
|
||||
// location
|
||||
|
||||
@@ -190,7 +190,42 @@ 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: [
|
||||
{ "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
|
||||
onSelected: key => {
|
||||
Settings.data.general.language = key
|
||||
if (key === "") {
|
||||
I18n.detectLanguage() // Re-detect system language if "Automatic" is selected
|
||||
} else {
|
||||
I18n.setLanguage(key) // Set specific language
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL
|
||||
Layout.bottomMargin: Style.marginXL
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL
|
||||
Layout.fillWidth: true
|
||||
|
||||
Reference in New Issue
Block a user