From 50449158bcb91391d17219dd2d06ef846c2da94f Mon Sep 17 00:00:00 2001 From: "Tom Dewey tom.dewey@raspberrypi.com" Date: Mon, 16 Oct 2023 13:09:34 +0100 Subject: [PATCH 1/5] i18n: Advanced settings -> OS customization Per a request from the Raspberry Pi Communications team, change 'Advanced Settings' and 'Image customization' to read 'OS customization'. This is to avoid amibuguity in the English, where Image_r_ and Image may be conflated when reading at speed. Regrettably, this breaks the existing translations. To prevent confusion, explicitly delete the existing translations - as they're almost certainly not valid with the reworded meaning. --- README.md | 4 ++-- src/OptionsPopup.qml | 6 +++--- src/UseSavedSettingsPopup.qml | 12 ++++++------ src/i18n/rpi-imager_ca.ts | 8 ++++---- src/i18n/rpi-imager_de.ts | 8 ++++---- src/i18n/rpi-imager_en.ts | 4 ++-- src/i18n/rpi-imager_es.ts | 8 ++++---- src/i18n/rpi-imager_fr.ts | 8 ++++---- src/i18n/rpi-imager_it.ts | 8 ++++---- src/i18n/rpi-imager_ja.ts | 8 ++++---- src/i18n/rpi-imager_ko.ts | 8 ++++---- src/i18n/rpi-imager_nl.ts | 8 ++++---- src/i18n/rpi-imager_ru.ts | 8 ++++---- src/i18n/rpi-imager_sk.ts | 8 ++++---- src/i18n/rpi-imager_sl.ts | 8 ++++---- src/i18n/rpi-imager_tr.ts | 4 ++-- src/i18n/rpi-imager_uk.ts | 8 ++++---- src/i18n/rpi-imager_zh.ts | 8 ++++---- 18 files changed, 67 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index cf5d49f..f52184c 100644 --- a/README.md +++ b/README.md @@ -197,8 +197,8 @@ On macOS, disable it by editing the property list for the application: defaults write org.raspberrypi.Imager.plist telemetry -bool NO ``` -### Advanced options +### OS Customization -When using the app, press CTRL + SHIFT + X to reveal the **Advanced options** dialog. +When using the app, press CTRL + SHIFT + X to reveal the **OS Customization** dialog. In here, you can specify several things you would otherwise set in the boot configuration files. For example, you can enable SSH, set the Wi-Fi login, and specify your locale settings for the system image. diff --git a/src/OptionsPopup.qml b/src/OptionsPopup.qml index 568d1cd..db43505 100644 --- a/src/OptionsPopup.qml +++ b/src/OptionsPopup.qml @@ -17,7 +17,7 @@ Window { maximumWidth: width minimumHeight: 125 height: Math.min(750, cl.implicitHeight) - title: qsTr("Advanced options") + title: qsTr("OS Customization") property bool initialized: false property bool hasSavedSettings: false @@ -49,7 +49,7 @@ Window { RowLayout { Label { - text: qsTr("Image customization options") + text: qsTr("OS customization options") } ComboBox { id: comboSaveSettings @@ -539,7 +539,7 @@ Window { /* Lacking an easy cross-platform to fetch keyboard layout from host system, just default to "gb" for people in UK time zone for now, and "us" for everyone else */ - if (tz == "Europe/London") { + if (tz === "Europe/London") { fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("gb") } else { fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("us") diff --git a/src/UseSavedSettingsPopup.qml b/src/UseSavedSettingsPopup.qml index f002763..d17790d 100644 --- a/src/UseSavedSettingsPopup.qml +++ b/src/UseSavedSettingsPopup.qml @@ -70,7 +70,7 @@ Popup { Layout.topMargin: 10 font.family: roboto.name font.bold: true - text: qsTr("Use image customisation?") + text: qsTr("Use OS customization?") } Text { @@ -85,7 +85,7 @@ Popup { Layout.topMargin: 25 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Accessible.name: text.replace(/<\/?[^>]+(>|$)/g, "") - text: qsTr("Would you like to apply image customization settings?") + text: qsTr("Would you like to apply OS customization settings?") } RowLayout { @@ -95,10 +95,10 @@ Popup { id: buttons ImButton { - text: qsTr("NO") + text: qsTr("EDIT SETTINGS") onClicked: { msgpopup.close() - msgpopup.no() + msgpopup.editSettings() } Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff" Material.background: "#c51a4a" @@ -127,10 +127,10 @@ Popup { } ImButton { - text: qsTr("EDIT SETTINGS") + text: qsTr("NO") onClicked: { msgpopup.close() - msgpopup.editSettings() + msgpopup.no() } Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff" Material.background: "#c51a4a" diff --git a/src/i18n/rpi-imager_ca.ts b/src/i18n/rpi-imager_ca.ts index 4239a25..123d79f 100644 --- a/src/i18n/rpi-imager_ca.ts +++ b/src/i18n/rpi-imager_ca.ts @@ -282,13 +282,13 @@ OptionsPopup - Advanced options - Opcions avançades + OS customization + - Image customization options - Opcions de personalització de les imatges + OS customization options + diff --git a/src/i18n/rpi-imager_de.ts b/src/i18n/rpi-imager_de.ts index e252d53..a5f15bd 100644 --- a/src/i18n/rpi-imager_de.ts +++ b/src/i18n/rpi-imager_de.ts @@ -319,13 +319,13 @@ OptionsPopup - Advanced options - Erweiterte Optionen + OS customization + - Image customization options - OS-Modifizierungen + OS customization options + diff --git a/src/i18n/rpi-imager_en.ts b/src/i18n/rpi-imager_en.ts index 0a302ee..16cb85c 100644 --- a/src/i18n/rpi-imager_en.ts +++ b/src/i18n/rpi-imager_en.ts @@ -278,12 +278,12 @@ OptionsPopup - Advanced options + OS customization - Image customization options + OS customization options diff --git a/src/i18n/rpi-imager_es.ts b/src/i18n/rpi-imager_es.ts index 8d35c96..d64b7c6 100644 --- a/src/i18n/rpi-imager_es.ts +++ b/src/i18n/rpi-imager_es.ts @@ -282,13 +282,13 @@ OptionsPopup - Advanced options - Opciones avanzadas + OS customization + - Image customization options - Opciones de personalización de imagen + OS customization options + diff --git a/src/i18n/rpi-imager_fr.ts b/src/i18n/rpi-imager_fr.ts index dabf454..e07417a 100644 --- a/src/i18n/rpi-imager_fr.ts +++ b/src/i18n/rpi-imager_fr.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - Réglages avancés + OS customization + - Image customization options - Options de personnalisation de l'image + OS customization options + diff --git a/src/i18n/rpi-imager_it.ts b/src/i18n/rpi-imager_it.ts index d328c52..67bb9e1 100644 --- a/src/i18n/rpi-imager_it.ts +++ b/src/i18n/rpi-imager_it.ts @@ -319,13 +319,13 @@ Aggiungi sia 'rpi-imager.exe' che 'fat32format.exe' all&apos OptionsPopup - Advanced options - Opzioni avanzate + OS customization + - Image customization options - Opzioni personalizzazione immagine + OS customization options + diff --git a/src/i18n/rpi-imager_ja.ts b/src/i18n/rpi-imager_ja.ts index 0268bda..f689f50 100644 --- a/src/i18n/rpi-imager_ja.ts +++ b/src/i18n/rpi-imager_ja.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - 詳細な設定 + OS customization + - Image customization options - イメージカスタマイズオプション + OS customization options + diff --git a/src/i18n/rpi-imager_ko.ts b/src/i18n/rpi-imager_ko.ts index e1a36f3..d2602e1 100644 --- a/src/i18n/rpi-imager_ko.ts +++ b/src/i18n/rpi-imager_ko.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - 고급 옵션 + OS customization + - Image customization options - 이미지 사용자 정의 옵션 + OS customization options + diff --git a/src/i18n/rpi-imager_nl.ts b/src/i18n/rpi-imager_nl.ts index 0786b63..d2ce1bc 100644 --- a/src/i18n/rpi-imager_nl.ts +++ b/src/i18n/rpi-imager_nl.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - Geavanceerde instellingen + OS customization + - Image customization options - Image instellingen + OS customization options + diff --git a/src/i18n/rpi-imager_ru.ts b/src/i18n/rpi-imager_ru.ts index 8b9062e..e97ac87 100644 --- a/src/i18n/rpi-imager_ru.ts +++ b/src/i18n/rpi-imager_ru.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - Дополнительные параметры + OS customization + - Image customization options - Параметры настройки образа + OS customization options + diff --git a/src/i18n/rpi-imager_sk.ts b/src/i18n/rpi-imager_sk.ts index be70d81..a3578ab 100644 --- a/src/i18n/rpi-imager_sk.ts +++ b/src/i18n/rpi-imager_sk.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - Pokročilé možnosti + OS customization + - Image customization options - Možnosti úprav obrazu + OS customization options + diff --git a/src/i18n/rpi-imager_sl.ts b/src/i18n/rpi-imager_sl.ts index 07965dc..4624545 100644 --- a/src/i18n/rpi-imager_sl.ts +++ b/src/i18n/rpi-imager_sl.ts @@ -318,13 +318,13 @@ OptionsPopup - Advanced options - Napredne možnosti + OS customization + - Image customization options - Uporabi opcije prilagoditve slike diska + OS customization options + diff --git a/src/i18n/rpi-imager_tr.ts b/src/i18n/rpi-imager_tr.ts index 42f9b86..53abf54 100644 --- a/src/i18n/rpi-imager_tr.ts +++ b/src/i18n/rpi-imager_tr.ts @@ -290,12 +290,12 @@ OptionsPopup - Advanced options + OS customization - Image customization options + OS customization options diff --git a/src/i18n/rpi-imager_uk.ts b/src/i18n/rpi-imager_uk.ts index cf8f099..3cdb6cf 100644 --- a/src/i18n/rpi-imager_uk.ts +++ b/src/i18n/rpi-imager_uk.ts @@ -282,13 +282,13 @@ OptionsPopup - Advanced options - Розширені налаштування + OS customization + - Image customization options - Налаштування образу + OS customization options + diff --git a/src/i18n/rpi-imager_zh.ts b/src/i18n/rpi-imager_zh.ts index 3ab8a83..cb83a6a 100644 --- a/src/i18n/rpi-imager_zh.ts +++ b/src/i18n/rpi-imager_zh.ts @@ -306,13 +306,13 @@ OptionsPopup - Advanced options - 高级设置 + OS customization + - Image customization options - 镜像自定义选项 + OS customization options + From ecf992cb62ee0b4c2c52466dbad0fd7c84cb1361 Mon Sep 17 00:00:00 2001 From: "Tom Dewey tom.dewey@raspberrypi.com" Date: Tue, 17 Oct 2023 15:21:49 +0100 Subject: [PATCH 2/5] Rework OS Customization In the new flow, it doesn't make sense to _not_ save the OS customization parameters, so remove the ComboBox. Additionally, our data model was failing to notify the UI of changes to the saved settings state. Due to time constraints, I'm not able to resolve the binding in the 'correct' manner, but I can introduce a makeshift status signalling mechanism to prevent UI inconsistency. --- src/OptionsPopup.qml | 93 +++++++++++++++++++---------------- src/UseSavedSettingsPopup.qml | 18 ++++++- src/imagewriter.cpp | 3 ++ src/main.qml | 6 +++ 4 files changed, 76 insertions(+), 44 deletions(-) diff --git a/src/OptionsPopup.qml b/src/OptionsPopup.qml index db43505..7b41d2a 100644 --- a/src/OptionsPopup.qml +++ b/src/OptionsPopup.qml @@ -29,6 +29,8 @@ Window { property string cloudinitwrite property string cloudinitnetwork + signal saveSettingsSignal(var settings) + ColumnLayout { id: cl spacing: 10 @@ -51,16 +53,6 @@ Window { Label { text: qsTr("OS customization options") } - ComboBox { - id: comboSaveSettings - model: { - [qsTr("for this session only"), - qsTr("to always use")] - } - Layout.minimumWidth: 250 - Layout.maximumHeight: 40 - enabled: !imageWriter.isEmbeddedMode() - } } TabBar { @@ -453,7 +445,6 @@ Window { fieldKeyboardLayout.model = imageWriter.getKeymapLayoutList() if (Object.keys(settings).length) { - comboSaveSettings.currentIndex = 1 hasSavedSettings = true } if ('hostname' in settings) { @@ -807,43 +798,61 @@ Window { function saveSettings() { - if (comboSaveSettings.currentIndex == 1) { - hasSavedSettings = true - var settings = { }; - if (chkHostname.checked && fieldHostname.length) { - settings.hostname = fieldHostname.text - } - if (chkSetUser.checked) { - settings.sshUserName = fieldUserName.text - settings.sshUserPassword = fieldUserPassword.alreadyCrypted ? fieldUserPassword.text : imageWriter.crypt(fieldUserPassword.text) - } + var settings = { }; + if (chkHostname.checked && fieldHostname.length) { + settings.hostname = fieldHostname.text + } + if (chkSetUser.checked) { + settings.sshUserName = fieldUserName.text + settings.sshUserPassword = fieldUserPassword.alreadyCrypted ? fieldUserPassword.text : imageWriter.crypt(fieldUserPassword.text) + } - settings.sshEnabled = chkSSH.checked - if (chkSSH.checked && radioPubKeyAuthentication.checked) { - settings.sshAuthorizedKeys = fieldPublicKey.text + settings.sshEnabled = chkSSH.checked + if (chkSSH.checked && radioPubKeyAuthentication.checked) { + settings.sshAuthorizedKeys = fieldPublicKey.text + } + if (chkWifi.checked) { + settings.wifiSSID = fieldWifiSSID.text + if (chkWifiSSIDHidden.checked) { + settings.wifiSSIDHidden = true } - if (chkWifi.checked) { - settings.wifiSSID = fieldWifiSSID.text - if (chkWifiSSIDHidden.checked) { - settings.wifiSSIDHidden = true - } - settings.wifiPassword = fieldWifiPassword.text.length == 64 ? fieldWifiPassword.text : imageWriter.pbkdf2(fieldWifiPassword.text, fieldWifiSSID.text) - settings.wifiCountry = fieldWifiCountry.editText - } - if (chkLocale.checked) { - settings.timezone = fieldTimezone.editText - settings.keyboardLayout = fieldKeyboardLayout.editText - } - - imageWriter.setSavedCustomizationSettings(settings) - - } else if (hasSavedSettings) { - imageWriter.clearSavedCustomizationSettings() - hasSavedSettings = false + settings.wifiPassword = fieldWifiPassword.text.length == 64 ? fieldWifiPassword.text : imageWriter.pbkdf2(fieldWifiPassword.text, fieldWifiSSID.text) + settings.wifiCountry = fieldWifiCountry.editText + } + if (chkLocale.checked) { + settings.timezone = fieldTimezone.editText + settings.keyboardLayout = fieldKeyboardLayout.editText } imageWriter.setSetting("beep", chkBeep.checked) imageWriter.setSetting("eject", chkEject.checked) imageWriter.setSetting("telemetry", chkTelemtry.checked) + + if (chkHostname.checked || chkSetUser.checked || chkSSH.checked || chkWifi.checked || chkLocale.checked) { + /* OS customization to be applied. */ + hasSavedSettings = true + saveSettingsSignal(settings) + } + } + + function clearCustomizationFields() + { + fieldHostname.clear() + fieldUserName.clear() + fieldUserPassword.clear() + radioPubKeyAuthentication.checked = false + radioPasswordAuthentication.checked = false + fieldPublicKey.clear() + fieldWifiSSID.clear() + fieldWifiCountry.currentIndex = -1 + fieldWifiPassword.clear() + fieldTimezone.currentIndex = -1 + fieldKeyboardLayout.currentIndex = -1 + chkSetUser.checked = false + chkSSH.checked = false + chkLocale.checked = false + chkWifi.checked = false + chkWifiSSIDHidden.checked = false + chkHostname.checked = false } } diff --git a/src/UseSavedSettingsPopup.qml b/src/UseSavedSettingsPopup.qml index d17790d..a6b60d7 100644 --- a/src/UseSavedSettingsPopup.qml +++ b/src/UseSavedSettingsPopup.qml @@ -18,6 +18,8 @@ Popup { padding: 0 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + property bool hasSavedSettings: false + signal yes() signal no() signal noClearSettings() @@ -105,6 +107,7 @@ Popup { } ImButton { + id: noAndClearButton text: qsTr("NO, CLEAR SETTINGS") onClicked: { msgpopup.close() @@ -112,10 +115,11 @@ Popup { } Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff" Material.background: "#c51a4a" - enabled: imageWriter.hasSavedCustomizationSettings() ? true : false + enabled: false } ImButton { + id: yesButton text: qsTr("YES") onClicked: { msgpopup.close() @@ -123,7 +127,7 @@ Popup { } Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff" Material.background: "#c51a4a" - enabled: imageWriter.hasSavedCustomizationSettings() ? true : false + enabled: false } ImButton { @@ -142,6 +146,16 @@ Popup { function openPopup() { open() + if (hasSavedSettings) { + /* HACK: Bizarrely, the button enabled characteristics are not re-evaluated on open. + * So, let's manually _force_ these buttons to be enabled */ + yesButton.enabled = true + noAndClearButton.enabled = true + } else { + yesButton.enabled = false + noAndClearButton.enabled = false + } + // trigger screen reader to speak out message msgpopupbody.forceActiveFocus() } diff --git a/src/imagewriter.cpp b/src/imagewriter.cpp index 5d5b397..2a86281 100644 --- a/src/imagewriter.cpp +++ b/src/imagewriter.cpp @@ -1039,6 +1039,7 @@ void ImageWriter::setSavedCustomizationSettings(const QVariantMap &map) _settings.setValue(key, map.value(key)); } _settings.endGroup(); + _settings.sync(); } QVariantMap ImageWriter::getSavedCustomizationSettings() @@ -1060,10 +1061,12 @@ void ImageWriter::clearSavedCustomizationSettings() _settings.beginGroup("imagecustomization"); _settings.remove(""); _settings.endGroup(); + _settings.sync(); } bool ImageWriter::hasSavedCustomizationSettings() { + _settings.sync(); _settings.beginGroup("imagecustomization"); bool result = !_settings.childKeys().isEmpty(); _settings.endGroup(); diff --git a/src/main.qml b/src/main.qml index a3f6cbd..d755026 100644 --- a/src/main.qml +++ b/src/main.qml @@ -1183,6 +1183,10 @@ ApplicationWindow { OptionsPopup { id: optionspopup + onSaveSettingsSignal: { + imageWriter.setSavedCustomizationSettings(settings) + usesavedsettingspopup.hasSavedSettings = true + } } UseSavedSettingsPopup { @@ -1196,6 +1200,8 @@ ApplicationWindow { confirmwritepopup.askForConfirmation() } onNoClearSettings: { + hasSavedSettings = false + optionspopup.clearCustomizationFields() imageWriter.clearSavedCustomizationSettings() confirmwritepopup.askForConfirmation() } From cd9596d0bddfdbbca4db176563b3f0b45643fdb7 Mon Sep 17 00:00:00 2001 From: "Tom Dewey tom.dewey@raspberrypi.com" Date: Tue, 17 Oct 2023 16:11:23 +0100 Subject: [PATCH 3/5] qml: Remove redundant string This used to be attached to the ComboBox for selecting whether you wanted the customization options to be applied only for this session, or stored for re-use. As we've removed that option, we should also remove the label string. --- src/OptionsPopup.qml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/OptionsPopup.qml b/src/OptionsPopup.qml index 7b41d2a..a60ef1a 100644 --- a/src/OptionsPopup.qml +++ b/src/OptionsPopup.qml @@ -48,13 +48,6 @@ Window { //ScrollBar.vertical.policy: ScrollBar.AlwaysOn ColumnLayout { - - RowLayout { - Label { - text: qsTr("OS customization options") - } - } - TabBar { id: bar Layout.fillWidth: true From 819ffe14f0e84bd08b60362b672db3a1dd632f93 Mon Sep 17 00:00:00 2001 From: "Tom Dewey tom.dewey@raspberrypi.com" Date: Tue, 17 Oct 2023 16:35:28 +0100 Subject: [PATCH 4/5] qml: Use sensible defaults to clear Options --- src/OptionsPopup.qml | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/OptionsPopup.qml b/src/OptionsPopup.qml index a60ef1a..c333098 100644 --- a/src/OptionsPopup.qml +++ b/src/OptionsPopup.qml @@ -830,22 +830,46 @@ Window { function clearCustomizationFields() { - fieldHostname.clear() - fieldUserName.clear() + /* Bind copies of the lists */ + fieldTimezone.model = imageWriter.getTimezoneList() + fieldKeyboardLayout.model = imageWriter.getKeymapLayoutList() + fieldWifiCountry.model = imageWriter.getCountryList() + + fieldHostname.text = "raspberrypi" + fieldUserName.text = imageWriter.getCurrentUser() fieldUserPassword.clear() radioPubKeyAuthentication.checked = false radioPasswordAuthentication.checked = false fieldPublicKey.clear() - fieldWifiSSID.clear() - fieldWifiCountry.currentIndex = -1 - fieldWifiPassword.clear() - fieldTimezone.currentIndex = -1 - fieldKeyboardLayout.currentIndex = -1 + + /* Timezone Settings*/ + fieldTimezone.currentIndex = fieldTimezone.find(imageWriter.getTimezone()) + /* Lacking an easy cross-platform to fetch keyboard layout + from host system, just default to "gb" for people in + UK time zone for now, and "us" for everyone else */ + if (imageWriter.getTimezone() === "Europe/London") { + fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("gb") + } else { + fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("us") + } + chkSetUser.checked = false chkSSH.checked = false chkLocale.checked = false - chkWifi.checked = false chkWifiSSIDHidden.checked = false chkHostname.checked = false + + /* WiFi Settings */ + fieldWifiSSID.text = imageWriter.getSSID() + if (fieldWifiSSID.text.length) { + fieldWifiPassword.text = imageWriter.getPSK() + if (fieldWifiPassword.text.length) { + chkShowPassword.checked = false + if (Qt.platform.os == "osx") { + /* User indicated wifi must be prefilled */ + chkWifi.checked = true + } + } + } } } From 9d51352a6ff36c0e1ed2dd837b673de9a6ad5ee2 Mon Sep 17 00:00:00 2001 From: "Tom Dewey tom.dewey@raspberrypi.com" Date: Wed, 18 Oct 2023 10:13:52 +0100 Subject: [PATCH 5/5] embedded: Fixup patch context --- .../rpi-imager/0001-rpi-imager-change-window-to-popup.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embedded/imager/package/rpi-imager/0001-rpi-imager-change-window-to-popup.patch b/embedded/imager/package/rpi-imager/0001-rpi-imager-change-window-to-popup.patch index 105c6fb..2c6e506 100644 --- a/embedded/imager/package/rpi-imager/0001-rpi-imager-change-window-to-popup.patch +++ b/embedded/imager/package/rpi-imager/0001-rpi-imager-change-window-to-popup.patch @@ -24,6 +24,6 @@ index 568d1cd..9e36607 100644 + function raise() { } + /* */ + - title: qsTr("Advanced options") + title: qsTr("OS Customization") property bool initialized: false