diff --git a/src/imagewriter.cpp b/src/imagewriter.cpp index 8457c0b..132b944 100644 --- a/src/imagewriter.cpp +++ b/src/imagewriter.cpp @@ -472,10 +472,11 @@ namespace { } // namespace anonymous -void ImageWriter::setHWFilterList(const QByteArray &json) { +void ImageWriter::setHWFilterList(const QByteArray &json, const bool &inclusive) { + std::lock_guard lock(_deviceListMutationMutex); QJsonDocument json_document = QJsonDocument::fromJson(json); - _deviceFilter = json_document.array(); + _deviceFilterIsInclusive = inclusive; } void ImageWriter::handleNetworkRequestFinished(QNetworkReply *data) { @@ -532,13 +533,62 @@ void ImageWriter::handleNetworkRequestFinished(QNetworkReply *data) { } } +namespace { + QJsonArray filterOsListWithHWTags(QJsonArray incoming_os_list, QJsonArray hw_filter, const bool inclusive, uint8_t count = 0) { + if (count > MAX_SUBITEMS_DEPTH) { + qDebug() << "Aborting insertion of subitems, exceeded maximum configured limit of " << MAX_SUBITEMS_DEPTH << " levels."; + return {}; + } + + QJsonArray returnArray = {}; + + for (auto ositem : incoming_os_list) { + auto ositemObject = ositem.toObject(); + + if (ositemObject.contains("subitems")) { + // Recurse! + ositemObject["subitems"] = filterOsListWithHWTags(ositemObject["subitems"].toArray(), hw_filter, inclusive, count++); + if (ositemObject["subitems"].toArray().count() > 0) { + returnArray += ositemObject; + } + } else { + // Filter this one! + if (ositemObject.contains("devices")) { + auto keep = false; + auto ositem_devices = ositemObject["devices"].toArray(); + + for (auto compat_device : ositem_devices) { + if (hw_filter.contains(compat_device.toString())) { + keep = true; + break; + } + } + + if (keep) { + returnArray.append(ositem); + } + } else { + // No devices tags, so work out if we're exclusive or inclusive filtering! + if (inclusive) { + returnArray.append(ositem); + } + } + } + + //returnArray += ositemObject; + } + + return returnArray; + } +} // namespace anonymous + QByteArray ImageWriter::getFilteredOSlist() { QJsonArray reference_os_list_array = {}; QJsonObject reference_imager_metadata = {}; { std::lock_guard lock(_deviceListMutationMutex); if (!_completeOsList.isEmpty()) { - reference_os_list_array = _completeOsList.object()["os_list"].toArray(); + reference_os_list_array = filterOsListWithHWTags(_completeOsList.object()["os_list"].toArray(), _deviceFilter, _deviceFilterIsInclusive); reference_imager_metadata = _completeOsList.object()["imager"].toObject(); } } diff --git a/src/imagewriter.h b/src/imagewriter.h index 1183c08..54874d8 100644 --- a/src/imagewriter.h +++ b/src/imagewriter.h @@ -86,7 +86,7 @@ public: Q_INVOKABLE void beginOSListFetch(); /** Set the HW filter, for a filtered view of the OS list */ - Q_INVOKABLE void setHWFilterList(const QByteArray &json); + Q_INVOKABLE void setHWFilterList(const QByteArray &json, const bool &inclusive); /* Set custom cache file */ void setCustomCacheFile(const QString &cacheFile, const QByteArray &sha256); @@ -184,6 +184,7 @@ private: QNetworkAccessManager _networkManager; QJsonDocument _completeOsList; QJsonArray _deviceFilter; + bool _deviceFilterIsInclusive; std::mutex _deviceListMutationMutex; protected: diff --git a/src/main.qml b/src/main.qml index c10bb09..3b940c6 100644 --- a/src/main.qml +++ b/src/main.qml @@ -25,20 +25,6 @@ ApplicationWindow { FontLoader {id: robotoLight; source: "fonts/Roboto-Light.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 - - /** 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: { if (progressBar.visible) { close.accepted = false @@ -1267,7 +1253,6 @@ ApplicationWindow { } function onOsListPrepared() { - console.log("OS list updated."); fetchOSlist() } @@ -1457,9 +1442,6 @@ ApplicationWindow { oslist_parsed = o["os_list"] } - if (hwTags != "") { - filterItems(oslist_parsed, JSON.parse(hwTags), hwTagMatchingType) - } checkForRandom(oslist_parsed) /* Flatten subitems to subitems_json */ @@ -1581,28 +1563,21 @@ ApplicationWindow { } function selectHWitem(hwmodel) { - hwTags = hwmodel.tags + /* Default is exclusive matching */ + var inclusive = false 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 + inclusive = true break; } - } else { - /* Default is exclusive exact matching */ - hwTagMatchingType = 0 } + imageWriter.setHWFilterList(hwmodel.tags, inclusive) + /* Reload list */ var oslist_json = imageWriter.getFilteredOSlist(); var o = JSON.parse(oslist_json)