fix(Settings/LanguageView): do not change language on the fly

disable retranslation, display a confirmation dialog and apply the
language change after app restart

rationale: the way the retranslation works internally is that it force
reevaluation of _all_ QML bindings which:
- might lead to crashes (immediately or later)
- lots of warnings printed to console, some bindings can get broken as a result
- not all UI is correctly retranslated on the fly (we have lots of places
where we assign the text imperatively via JS code), so these wouldn't
appear translated before app restart anyway

Fixes #7823
This commit is contained in:
Lukáš Tinkl 2023-04-27 13:30:15 +02:00 committed by Lukáš Tinkl
parent 8ccd091ebc
commit c548a96a2a
3 changed files with 9 additions and 26 deletions

View File

@ -28,7 +28,7 @@ proc delete*(self: Service) =
proc newService*(events: EventEmitter): Service = proc newService*(events: EventEmitter): Service =
result = Service() result = Service()
result.events = events result.events = events
result.shouldRetranslate = false #not defined(linux) result.shouldRetranslate = false
proc obtainLanguages(dir: string): seq[string] = proc obtainLanguages(dir: string): seq[string] =
let localeRe = re".*qml_(.*).qm" let localeRe = re".*qml_(.*).qm"

View File

@ -39,7 +39,7 @@ SettingsContentBase {
function changeLanguage(key) { function changeLanguage(key) {
languagePicker.newKey = key languagePicker.newKey = key
languagePause.start() Qt.callLater(root.languageStore.changeLanguage, languagePicker.newKey)
} }
ColumnLayout { ColumnLayout {
@ -105,14 +105,6 @@ SettingsContentBase {
return "" return ""
} }
Timer {
id: languagePause
interval: 100
onTriggered: {
// changeLanguage function operation blocks a little bit the UI so getting around it with a small pause (timer) in order to get the desired visual behavior
root.languageStore.changeLanguage(languagePicker.newKey)
}
}
objectName: "languagePicker" objectName: "languagePicker"
inputList: SortFilterProxyModel { inputList: SortFilterProxyModel {
sourceModel: root.languageStore.languageModel sourceModel: root.languageStore.languageModel
@ -154,18 +146,9 @@ SettingsContentBase {
onItemPickerChanged: { onItemPickerChanged: {
if(selected && root.languageStore.currentLanguage !== key) { if(selected && root.languageStore.currentLanguage !== key) {
// IMPORTANT: Workaround to temporary resolve the crash we have when language is changed (`startupModule` is null and some qml bindings are still calling this dead pointer) so, change language will not retranslate root.changeLanguage(key)
// and instead, also on mac and win, the app will quit to apply the new language languageConfirmationDialog.active = true
// TEMPORARY: It should be removed as it is only used in Linux OS but it must be investigated how to change language in execution time, as well, in Linux (will be addressed in another task) languageConfirmationDialog.item.open()
//if (Qt.platform.os === Constants.linux) {
root.changeLanguage(key)
linuxConfirmationDialog.active = true
linuxConfirmationDialog.item.open()
// }
//else {
// root.changeLanguage(key)
//}
} }
} }
} }
@ -206,16 +189,15 @@ SettingsContentBase {
} }
} }
// TEMPORARY: It should be removed as it is only used in Linux OS but it must be investigated how to change language in execution time, as well, in Linux (will be addressed in another task)
Loader { Loader {
id: linuxConfirmationDialog id: languageConfirmationDialog
active: false active: false
sourceComponent: ConfirmationDialog { sourceComponent: ConfirmationDialog {
header.title: qsTr("Change language") header.title: qsTr("Change language")
confirmationText: qsTr("Display language has been changed. You must restart the application for changes to take effect.") confirmationText: qsTr("Display language has been changed. You must restart the application for changes to take effect.")
confirmButtonLabel: qsTr("Close the app now") confirmButtonLabel: qsTr("Close the app now")
onConfirmButtonClicked: { onConfirmButtonClicked: {
linuxConfirmationDialog.active = false languageConfirmationDialog.active = false
Qt.quit() Qt.quit()
} }
} }

View File

@ -439,7 +439,8 @@ void dos_qguiapplication_load_translation(::DosQQmlApplicationEngine *vptr, cons
if (g_translator.load(translationPackage)) { if (g_translator.load(translationPackage)) {
bool success = QGuiApplication::installTranslator(&g_translator); bool success = QGuiApplication::installTranslator(&g_translator);
auto engine = static_cast<QQmlApplicationEngine *>(vptr); auto engine = static_cast<QQmlApplicationEngine *>(vptr);
if (shouldRetranslate) engine->retranslate(); if (engine && success && shouldRetranslate)
engine->retranslate();
} else { } else {
printf("Failed to load translation file %s\n", translationPackage); printf("Failed to load translation file %s\n", translationPackage);
} }