qml: Filtering types

Introduce 4 filtering types per device spec:

- "exclusive", which only includes OS' that match one of the specified
  tags, and discards any OS that is untagged.
- "exclusive_prefix", which only includes OS' that prefix-match one of
  the specified tags, discarding any OS that is untagged.
- "inclusive", which discards any OS that doesn't include one of the
  specified tags, but includes untagged images.
- "inclusive_prefix", which discards any OS that doesn't prefix match
  one of the specified tags, but includes untagged images.
This commit is contained in:
Tom Dewey tom.dewey@raspberrypi.com 2023-10-10 11:57:01 +01:00
parent 0f496dc2c9
commit 4fb84ff3e8

View file

@ -25,8 +25,20 @@ ApplicationWindow {
FontLoader {id: robotoLight; source: "fonts/Roboto-Light.ttf"} FontLoader {id: robotoLight; source: "fonts/Roboto-Light.ttf"}
FontLoader {id: robotoBold; source: "fonts/Roboto-Bold.ttf"} FontLoader {id: robotoBold; source: "fonts/Roboto-Bold.ttf"}
/** hw device list storage
*
* To allow us to filter the OS list, we maintain an application-wide record of the selected device
* tags.
*/
property string hwTags property string hwTags
/** 0: Exclusive, must match explicit device names only, no untagged
1: Exclusive by prefix, must match the device name as a prefix, no untagged
2: Inclusive, match explicit device names and untagged
3: Inclusive by prefix, match explicit device names and untagged
*/
property int hwTagMatchingType
onClosing: { onClosing: {
if (progressBar.visible) { if (progressBar.visible) {
close.accepted = false close.accepted = false
@ -474,6 +486,7 @@ ApplicationWindow {
tags: "[]" tags: "[]"
icon: "" icon: ""
description: "" description: ""
matching_type: "exclusive"
} }
} }
currentIndex: -1 currentIndex: -1
@ -1309,7 +1322,7 @@ ApplicationWindow {
} }
} }
function filterItems(list, tags) function filterItems(list, tags, matchingType)
{ {
if (!tags || !tags.length) if (!tags || !tags.length)
return return
@ -1321,24 +1334,67 @@ ApplicationWindow {
if ("devices" in entry && entry["devices"].length) { if ("devices" in entry && entry["devices"].length) {
var foundTag = false var foundTag = false
for (var j in tags) switch(matchingType) {
{ case 0: /* exact matching */
if (entry["devices"].includes(tags[j])) case 2: /* exact matching */
{ for (var j in tags)
foundTag = true {
if (entry["devices"].includes(tags[j]))
{
foundTag = true
break
}
}
/* If there's no match, remove this item from the list. */
if (!foundTag)
{
list.splice(i, 1)
continue
}
break
case 1: /* Exlusive by prefix matching */
case 3: /* Inclusive by prefix matching */
for (var deviceTypePrefix in tags) {
for (var deviceSpec in entry["devices"]) {
if (deviceSpec.startsWith(deviceTypePrefix)) {
foundTag = true
break
}
}
/* Terminate outer loop early if we've already
* decided it's a match
*/
if (foundTag) {
break
}
}
/* If there's no match, remove this item from the list. */
if (!foundTag)
{
list.splice(i, 1)
continue
}
break break
}
} }
} else {
if (!foundTag) /* No device list attached? If we're in an exclusive mode that's bad news indeed. */
{ switch (matchingType) {
list.splice(i, 1) case 0:
continue case 1:
if (!("subitems" in entry)) {
/* If you're not carrying subitems, you're not going in. */
list.splice(i, 1)
}
break
case 2:
case 3:
/* Inclusive filtering. We're keeping this one. */
break;
} }
} }
if ("subitems" in entry) { if ("subitems" in entry) {
filterItems(entry["subitems"], tags) filterItems(entry["subitems"], tags, hwTagMatchingType)
} }
} }
} }
@ -1366,7 +1422,7 @@ ApplicationWindow {
} }
if (hwTags != "") { if (hwTags != "") {
filterItems(oslist, JSON.parse(hwTags)) filterItems(oslist, JSON.parse(hwTags), hwTagMatchingType)
} }
checkForRandom(oslist) checkForRandom(oslist)
@ -1516,6 +1572,28 @@ ApplicationWindow {
function selectHWitem(hwmodel) { function selectHWitem(hwmodel) {
hwTags = hwmodel.tags hwTags = hwmodel.tags
if (hwmodel.matching_type) {
switch (hwmodel.matching_type) {
case "exclusive":
hwTagMatchingType = 0
break;
case "exclusive_prefix":
hwTagMatchingType = 1
break;
case "inclusive":
hwTagMatchingType = 2
break;
case "inclusive_prefix":
hwTagMatchingType = 3
break;
}
} else {
/* Default is exclusive exact matching */
hwTagMatchingType = 0
}
/* Reload list */ /* Reload list */
httpRequest(imageWriter.constantOsListUrl(), function (x) { httpRequest(imageWriter.constantOsListUrl(), function (x) {
var o = JSON.parse(x.responseText) var o = JSON.parse(x.responseText)