Allow nested subitems

Fixes "Can't assign to existing role 'subitems' of different type"
or hang (depending on Qt version) on using nested subitems.

Keep nested subitems flattenend as json string in memory while not
being used, to simplify dealing with ListElement expectation that
all elements have the same data type, as well as QML/Ecmascript's
memory management.
This commit is contained in:
Floris Bos 2022-01-23 19:30:16 +01:00
parent 10b50d5f8e
commit c17795c48e
2 changed files with 42 additions and 16 deletions

7
debian/changelog vendored
View file

@ -5,12 +5,17 @@ rpi-imager (1.6.3) unstable; urgency=medium
repository. Some heuristics are used with custom images from disk. repository. Some heuristics are used with custom images from disk.
* Advanced settings: add support for cloudinit format * Advanced settings: add support for cloudinit format
* Advanced settings: add support for specifying username * Advanced settings: add support for specifying username
* Advanced settings: allow setting username and password
* Advanced settings: allow hidden wifi SSID
* Advanced settings: allow multi-line authorized_keys
* Retry on GnuTLS Recv errors
* Some fixes to deal better with Linux distributions auto-mounting * Some fixes to deal better with Linux distributions auto-mounting
drives drives
* Add Slovenija translation * Add Slovenija translation
* Adds support for zstd * Adds support for zstd
* Allow nested subitems entries
-- Floris Bos <bos@je-eigen-domein.nl> Thu, 09 Dec 2021 11:13:12 +0100 -- Floris Bos <bos@je-eigen-domein.nl> Sun, 23 Jan 2022 16:39:46 +0100
rpi-imager (1.6.2) unstable; urgency=medium rpi-imager (1.6.2) unstable; urgency=medium

View file

@ -478,7 +478,7 @@ ApplicationWindow {
contains_multiple_files: false contains_multiple_files: false
release_date: "" release_date: ""
subitems_url: "internal://back" subitems_url: "internal://back"
subitems: [] subitems_json: ""
name: qsTr("Back") name: qsTr("Back")
description: qsTr("Go back to main menu") description: qsTr("Go back to main menu")
tooltip: "" tooltip: ""
@ -520,7 +520,7 @@ ApplicationWindow {
contains_multiple_files: false contains_multiple_files: false
release_date: "" release_date: ""
subitems_url: "" subitems_url: ""
subitems: [] subitems_json: ""
name: qsTr("Erase") name: qsTr("Erase")
description: qsTr("Format card as FAT32") description: qsTr("Format card as FAT32")
tooltip: "" tooltip: ""
@ -632,7 +632,7 @@ ApplicationWindow {
Column { Column {
Image { Image {
source: "icons/ic_chevron_right_40px.svg" source: "icons/ic_chevron_right_40px.svg"
visible: (typeof(subitems) == "object" && subitems.count) || (typeof(subitems_url) == "string" && subitems_url != "" && subitems_url != "internal://back") visible: (typeof(subitems_json) == "string" && subitems_json != "") || (typeof(subitems_url) == "string" && subitems_url != "" && subitems_url != "internal://back")
height: parent.parent.parent.height height: parent.parent.parent.height
fillMode: Image.Pad fillMode: Image.Pad
} }
@ -1084,24 +1084,38 @@ ApplicationWindow {
} }
function oslistFromJson(o) { function oslistFromJson(o) {
var oslist = false
var lang_country = Qt.locale().name var lang_country = Qt.locale().name
if ("os_list_"+lang_country in o) { if ("os_list_"+lang_country in o) {
return o["os_list_"+lang_country] oslist = o["os_list_"+lang_country]
} }
if (lang_country.includes("_")) { else if (lang_country.includes("_")) {
var lang = lang_country.substr(0, lang_country.indexOf("_")) var lang = lang_country.substr(0, lang_country.indexOf("_"))
if ("os_list_"+lang in o) { if ("os_list_"+lang in o) {
return o["os_list_"+lang] oslist = o["os_list_"+lang]
} }
} }
if (!"os_list" in o) { if (!oslist) {
onError(qsTr("Error parsing os_list.json")) if (!"os_list" in o) {
return false onError(qsTr("Error parsing os_list.json"))
return false
}
oslist = o["os_list"]
} }
var oslist = o["os_list"]
checkForRandom(oslist) checkForRandom(oslist)
/* Flatten subitems to subitems_json */
for (var i in oslist) {
var entry = oslist[i];
if ("subitems" in entry) {
entry["subitems_json"] = JSON.stringify(entry["subitems"])
delete entry["subitems"]
}
}
return oslist return oslist
} }
@ -1110,8 +1124,8 @@ ApplicationWindow {
for (var i = 0; i < collection.count; i++) { for (var i = 0; i < collection.count; i++) {
var os = collection.get(i) var os = collection.get(i)
if (typeof(os.subitems) !== "undefined") { if (typeof(os.subitems_json) == "string" && os.subitems_json != "") {
selectNamedOS(name, os.subitems) selectNamedOS(name, os.subitems_json)
} }
else if (typeof(os.url) !== "undefined" && name === os.name) { else if (typeof(os.url) !== "undefined" && name === os.name) {
selectOSitem(os, false) selectOSitem(os, false)
@ -1197,12 +1211,19 @@ ApplicationWindow {
function selectOSitem(d, selectFirstSubitem) function selectOSitem(d, selectFirstSubitem)
{ {
if (typeof(d.subitems) == "object" && d.subitems.count) { if (typeof(d.subitems_json) == "string" && d.subitems_json !== "") {
var m = newSublist() var m = newSublist()
var subitems = JSON.parse(d.subitems_json)
for (var i=0; i<d.subitems.count; i++) for (var i in subitems)
{ {
m.append(d.subitems.get(i)) var entry = subitems[i];
if ("subitems" in entry) {
/* Flatten sub-subitems entry */
entry["subitems_json"] = JSON.stringify(entry["subitems"])
delete entry["subitems"]
}
m.append(entry)
} }
osswipeview.itemAt(osswipeview.currentIndex+1).currentIndex = (selectFirstSubitem === true) ? 0 : -1 osswipeview.itemAt(osswipeview.currentIndex+1).currentIndex = (selectFirstSubitem === true) ? 0 : -1