From 93674b3893caa54bc0aef06903906b10d9c4af81 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Fri, 14 Nov 2025 11:19:00 +0100 Subject: [PATCH 01/14] test implementation to use map style containers for easier interface and connection editor improvments --- .../gtpy_abstractscriptcomponent.cpp | 27 ++++++++++++------- src/module/utilities/gtpy_transfer.cpp | 9 ++++++- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp b/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp index 7ab7005..07f2589 100644 --- a/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp +++ b/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp @@ -41,13 +41,14 @@ setStructContainerValue(GtPropertyStructContainer& con, const QString& argName, { auto entry = std::find_if(con.begin(), con.end(), [&argName](const GtPropertyStructInstance& entry){ +#if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) + return entry.ident() == argName; +#elif GT_VERSION >= GT_VERSION_CHECK(2, 0, 0) return entry.getMemberVal("name") == argName; +#endif }); - if (entry == con.end()) - { - return false; - } + if (entry == con.end()) return false; return entry->setMemberVal("value", value); } @@ -57,13 +58,15 @@ structContainerValue(const GtPropertyStructContainer& con, const QString& argNam { auto entry = std::find_if(con.begin(), con.end(), [&argName](const GtPropertyStructInstance& entry){ +#if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) + return entry.ident() == argName; +#elif GT_VERSION >= GT_VERSION_CHECK(2, 0, 0) return entry.getMemberVal("name") == argName; +#endif + }); - if (entry == con.end()) - { - return {}; - } + if (entry == con.end()) return {}; return entry->getMemberValToVariant("value"); } @@ -93,7 +96,11 @@ GtpyAbstractScriptComponent::GtpyAbstractScriptComponent() : m_replaceTabBySpaces{"replaceTab", "Replace tab by spaces"}, m_tabSize{"tabSize", "Tab size"}, m_script{"script", "Script"} -#if GT_VERSION >= GT_VERSION_CHECK(2, 0, 0) +#if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) + , + m_inputArgs{"input_args", GtPropertyStructContainer::Associative}, + m_outputArgs{"output_args", GtPropertyStructContainer::Associative} +#elif GT_VERSION >= GT_VERSION_CHECK(2, 0, 0) , m_inputArgs{"input_args"}, m_outputArgs{"output_args"} @@ -104,7 +111,9 @@ GtpyAbstractScriptComponent::GtpyAbstractScriptComponent() : auto createStructDef = [](const QString& typeName, gt::PropertyFactoryFunction f){ GtPropertyStructDefinition structDef(typeName); + #if GT_VERSION < GT_VERSION_CHECK(2, 1, 0) structDef.defineMember("name", gt::makeStringProperty()); + #endif // GT_VERSION < GT_VERSION_CHECK(2, 1, 0) structDef.defineMember("value", f); return structDef; }; diff --git a/src/module/utilities/gtpy_transfer.cpp b/src/module/utilities/gtpy_transfer.cpp index 7cf3154..0fad250 100644 --- a/src/module/utilities/gtpy_transfer.cpp +++ b/src/module/utilities/gtpy_transfer.cpp @@ -65,7 +65,11 @@ gtpy::transfer::propStructToPython( for (const auto& instance : container) { +#if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) + auto name = instance.ident(); +#else auto name = instance.getMemberVal("name"); +#endif if (!name.isEmpty()) { @@ -92,8 +96,11 @@ gtpy::transfer::propStructFromPython( for (auto& entry : container) { +#if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) + auto argName = entry.ident(); +#else auto argName = entry.getMemberVal("name"); - +#endif auto iter = dict.find(argName); if (iter != dict.end()) { From 75b70207b225044e5399f050b4be3ac765b6480b Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Fri, 14 Nov 2025 12:58:04 +0100 Subject: [PATCH 02/14] initial file structure for upgrades --- src/module/CMakeLists.txt | 2 ++ src/module/gt_python.cpp | 16 ++++++++++ src/module/gt_python.h | 3 ++ src/module/utilities/gtpy_moduleupgrader.cpp | 20 +++++++++++++ src/module/utilities/gtpy_moduleupgrader.h | 31 ++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 src/module/utilities/gtpy_moduleupgrader.cpp create mode 100644 src/module/utilities/gtpy_moduleupgrader.h diff --git a/src/module/CMakeLists.txt b/src/module/CMakeLists.txt index c24f99a..9f86692 100644 --- a/src/module/CMakeLists.txt +++ b/src/module/CMakeLists.txt @@ -90,6 +90,7 @@ set(HEADERS wizards/gtpy_wizardgeometryitem.h wizards/python_task/gtpy_taskwizardpage.h wizards/script_calculator/gtpy_scriptcalculatorwizardpage.h + utilities/gtpy_moduleupgrader.h ) set(SOURCES @@ -162,6 +163,7 @@ set(SOURCES wizards/gtpy_wizardgeometryitem.cpp wizards/python_task/gtpy_taskwizardpage.cpp wizards/script_calculator/gtpy_scriptcalculatorwizardpage.cpp + utilities/gtpy_moduleupgrader.cpp ) set(MODULE_ID "Python Module (Python ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR})") diff --git a/src/module/gt_python.cpp b/src/module/gt_python.cpp index 4b23cc7..b68dc1a 100644 --- a/src/module/gt_python.cpp +++ b/src/module/gt_python.cpp @@ -55,9 +55,11 @@ #include "gt_accessdataconnection.h" #include "gtpy_scriptcollectionsettings.h" +#include "gtpy_moduleupgrader.h" #include "gt_python.h" + #if GT_VERSION >= 0x010700 GtVersionNumber GtPythonModule::version() @@ -327,6 +329,19 @@ QList GtPythonModule::sharedFunctions() const } #endif +QList +GtPythonModule::upgradeRoutines() const +{ + return + { +#if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) + gt::VersionUpgradeRoutine {GtVersionNumber(2, 0, 0), + >py::module_upgrader::to_2_0_0::run} +#endif + }; +} + + namespace PythonExecution { @@ -350,6 +365,7 @@ parseScriptFile(QFile& file) return out.readAll(); } + int runPythonInterpreter(const QStringList& args) { diff --git a/src/module/gt_python.h b/src/module/gt_python.h index a538bce..b41702e 100644 --- a/src/module/gt_python.h +++ b/src/module/gt_python.h @@ -177,6 +177,9 @@ class GtPythonModule: public QObject, public GtModuleInterface, QList commandLineFunctions() const override; QList sharedFunctions() const override; + + /** We are providing routines to upgrade the datamodel */ + QList upgradeRoutines() const override; #endif private: diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp new file mode 100644 index 0000000..3f46d83 --- /dev/null +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -0,0 +1,20 @@ +/* GTlab - Gas Turbine laboratory + * Source File: gtpy_code.h + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: 2025 German Aerospace Center (DLR) + * + * Created on: 14.11.2025 + * Author: Jens Schmeink (DLR AT-TWK) + */ + +#include "gtpy_moduleupgrader.h" + +#include "gt_logging.h" + +bool +gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, + const QString& targetPath) +{ + gtDebug() << "Do upgrade for file" << targetPath; +} diff --git a/src/module/utilities/gtpy_moduleupgrader.h b/src/module/utilities/gtpy_moduleupgrader.h new file mode 100644 index 0000000..300d76d --- /dev/null +++ b/src/module/utilities/gtpy_moduleupgrader.h @@ -0,0 +1,31 @@ +/* GTlab - Gas Turbine laboratory + * Source File: gtpy_code.h + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: 2025 German Aerospace Center (DLR) + * + * Created on: 14.11.2025 + * Author: Jens Schmeink (DLR AT-TWK) + */ +#ifndef GTPY_MODULEUPGRADER_H +#define GTPY_MODULEUPGRADER_H + +#include + +namespace gtpy { + +namespace module_upgrader { + +namespace to_2_0_0 { + /** + * @brief Performs the upgrade to predign data model 3.0.0 + * + * @return true in case of success + */ + bool run(QDomElement& root, const QString& targetPath); +} // to_2_0_0 +} // module_upgrader +} // gtpy + + +#endif // GTPY_MODULEUPGRADER_H From 29f24f9aaf86d587f02ebcd75c797a4475807240 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Fri, 14 Nov 2025 13:52:13 +0100 Subject: [PATCH 03/14] first version of upgrader --- src/module/utilities/gtpy_moduleupgrader.cpp | 99 +++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index 3f46d83..a69655f 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -12,9 +12,106 @@ #include "gt_logging.h" +namespace { + + void findElementsByClass(const QDomNode& node, + const QStringList& classNames, + QList& results) + { + QDomNode child = node.firstChild(); + while (!child.isNull()) { + + if (child.isElement()) { + QDomElement elem = child.toElement(); + + if (!elem.isNull()) { + QString classValue = elem.attribute("class"); + + if (classNames.contains(classValue)) { + results.append(elem); + // laut deiner Anforderung: + // solche Einträge haben KEINE weiteren relevanten Untereinträge, + // aber wir durchsuchen trotzdem nicht den Baum *innerhalb* dieses Elements: + child = child.nextSibling(); + continue; + } + } + } + + // rekursiv in die nächste Ebene + findElementsByClass(child, classNames, results); + + child = child.nextSibling(); + } + } + + void normalizePropertyContainer(QDomElement container) + { + QDomNode child = container.firstChild(); + + while (!child.isNull()) { + if (child.isElement()) { + QDomElement prop = child.toElement(); + + if (prop.tagName() == "property") { + + // 1. find sub propety "name" + QDomElement nameElem; + QDomNode sub = prop.firstChild(); + + while (!sub.isNull()) + { + if (sub.isElement()) + { + QDomElement e = sub.toElement(); + if (e.attribute("name") == "name") + { + nameElem = e; + break; + } + } + sub = sub.nextSibling(); + } + + if (!nameElem.isNull()) + { + QString newName = nameElem.text().trimmed(); + + // 2. name="UUID" → name="OP" + prop.setAttribute("name", newName); + + // 3. Remove sub property + prop.removeChild(nameElem); + } + } + } + + child = child.nextSibling(); + } + } + +} + bool gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, const QString& targetPath) { - gtDebug() << "Do upgrade for file" << targetPath; + // only do updates for process elements + if (!targetPath.endsWith(".gttask")) return true; + + if (root.isNull()) + { + gtError() << QObject::tr("Invalid .gttask file!"); + return false; + } + + QList calcElements; + findElementsByClass(root, {"GtpyScriptCalculator", "GtpyTask"}, calcElements); + + for (auto e : calcElements) + { + normalizePropertyContainer(e); + } + + return true; } From ce3e163810d638a2fc25923d6565e13b6a52aa4f Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Fri, 14 Nov 2025 14:17:53 +0100 Subject: [PATCH 04/14] add small logging info --- src/module/utilities/gtpy_moduleupgrader.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index a69655f..3ca4fae 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -108,6 +108,10 @@ gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, QList calcElements; findElementsByClass(root, {"GtpyScriptCalculator", "GtpyTask"}, calcElements); + if (calcElements.isEmpty()) return true; + + gtTrace() << QObject::tr("Update task file") << targetPath; + for (auto e : calcElements) { normalizePropertyContainer(e); From 46d7af7311bc10901859470afbfb5f83809a8861 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Fri, 14 Nov 2025 14:48:51 +0100 Subject: [PATCH 05/14] unlock upcoming upgrade routine only for orrect version --- src/module/gt_python.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/module/gt_python.cpp b/src/module/gt_python.cpp index b68dc1a..7a87938 100644 --- a/src/module/gt_python.cpp +++ b/src/module/gt_python.cpp @@ -332,13 +332,20 @@ QList GtPythonModule::sharedFunctions() const QList GtPythonModule::upgradeRoutines() const { - return - { + GtVersionNumber current = const_cast(this)->version(); + + if(current >= GtVersionNumber(2, 0, 0)) + { + return + { #if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) - gt::VersionUpgradeRoutine {GtVersionNumber(2, 0, 0), - >py::module_upgrader::to_2_0_0::run} + gt::VersionUpgradeRoutine {GtVersionNumber(2, 0, 0), + >py::module_upgrader::to_2_0_0::run} #endif - }; + }; + } + + return {}; } From 562a5f49da69351e6cb3f9b37ed74c8c7b492de4 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Mon, 17 Nov 2025 08:43:06 +0100 Subject: [PATCH 06/14] initial code for replacment in connections as well --- src/module/utilities/gtpy_moduleupgrader.cpp | 124 ++++++++++++++----- 1 file changed, 91 insertions(+), 33 deletions(-) diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index 3ca4fae..4e2eb47 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -13,49 +13,54 @@ #include "gt_logging.h" namespace { - + // internal helper void findElementsByClass(const QDomNode& node, - const QStringList& classNames, - QList& results) + const QStringList& classNames, + QList& results) { QDomNode child = node.firstChild(); - while (!child.isNull()) { - - if (child.isElement()) { + while (!child.isNull()) + { + if (child.isElement()) + { QDomElement elem = child.toElement(); + if (!elem.isNull()) + { + QString c = elem.attribute("class"); - if (!elem.isNull()) { - QString classValue = elem.attribute("class"); - - if (classNames.contains(classValue)) { + if (classNames.contains(c)) + { results.append(elem); - // laut deiner Anforderung: - // solche Einträge haben KEINE weiteren relevanten Untereinträge, - // aber wir durchsuchen trotzdem nicht den Baum *innerhalb* dieses Elements: + + // depth is enough child = child.nextSibling(); continue; } } } - // rekursiv in die nächste Ebene findElementsByClass(child, classNames, results); - child = child.nextSibling(); } } - void normalizePropertyContainer(QDomElement container) + void normalizePropertyContainer(QDomElement container, + QMap& replaceMap) { QDomNode child = container.firstChild(); - while (!child.isNull()) { - if (child.isElement()) { + while (!child.isNull()) + { + if (child.isElement()) + { QDomElement prop = child.toElement(); - if (prop.tagName() == "property") { + if (prop.tagName() == "property") + { + + QString oldUUID = prop.attribute("name"); - // 1. find sub propety "name" + // Search for sub element NewName QDomElement nameElem; QDomNode sub = prop.firstChild(); @@ -77,10 +82,13 @@ namespace { { QString newName = nameElem.text().trimmed(); - // 2. name="UUID" → name="OP" + // keep connection info + replaceMap.insert(oldUUID, newName); + + // Replace UUID in name attribute prop.setAttribute("name", newName); - // 3. Remove sub property + // Remove subelement prop.removeChild(nameElem); } } @@ -90,6 +98,66 @@ namespace { } } + void replaceUUIDsInTextNodes(QDomNode node, + const QMap& replaceMap) + { + QDomNode child = node.firstChild(); + + while (!child.isNull()) + { + + if (child.isText()) + { + QString txt = child.nodeValue(); + QString newTxt = txt; + + for (auto it = replaceMap.begin(); it != replaceMap.end(); ++it) + { + newTxt.replace(it.key(), it.value()); + } + + if (newTxt != txt) + child.setNodeValue(newTxt); + } + + replaceUUIDsInTextNodes(child, replaceMap); + child = child.nextSibling(); + } + } + + // Main function: + // root: documentElement() + // classNames: z.B. {"MyCalc", "MyTask"} + void process(QDomElement root, + const QStringList& classNames) + { + QList found; + + // Step 1: Find elements with class=... + findElementsByClass(root, classNames, found); + + // Step 2: Replace UUIDs in input/output_args and build map + QMap replaceMap; + + for (QDomElement& elem : found) + { + QDomElement c = elem.firstChildElement("property-container"); + while (!c.isNull()) { + QString name = c.attribute("name"); + + if (name == "input_args" || + name == "output_args") + { + normalizePropertyContainer(c, replaceMap); + } + + c = c.nextSiblingElement("property-container"); + } + } + + // Step 3: Replace all uuids in the document + replaceUUIDsInTextNodes(root, replaceMap); + } } bool @@ -105,17 +173,7 @@ gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, return false; } - QList calcElements; - findElementsByClass(root, {"GtpyScriptCalculator", "GtpyTask"}, calcElements); - - if (calcElements.isEmpty()) return true; - - gtTrace() << QObject::tr("Update task file") << targetPath; - - for (auto e : calcElements) - { - normalizePropertyContainer(e); - } + process(root, {"GtpyScriptCalculator", "GtpyTask"}); return true; } From a3a679d140d5e9ee0fe7aeee7d5646cf4db0cfcc Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Mon, 17 Nov 2025 14:45:48 +0100 Subject: [PATCH 07/14] some cleanup --- src/module/utilities/gtpy_moduleupgrader.cpp | 86 +++++++++----------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index 4e2eb47..96af640 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -15,8 +15,9 @@ namespace { // internal helper void findElementsByClass(const QDomNode& node, - const QStringList& classNames, - QList& results) + const QStringList& classNames, + QList& results, + bool allowNestedClassElements = false) { QDomNode child = node.firstChild(); while (!child.isNull()) @@ -32,20 +33,23 @@ namespace { { results.append(elem); - // depth is enough - child = child.nextSibling(); - continue; + if (!allowNestedClassElements) + { + child = child.nextSibling(); + continue; + } } } } - findElementsByClass(child, classNames, results); + findElementsByClass(child, classNames, results, allowNestedClassElements); child = child.nextSibling(); } } - void normalizePropertyContainer(QDomElement container, - QMap& replaceMap) + void normalizePropertyContainerId( + QDomElement container, QString const& formerNameKey, + QMap& replaceMap) { QDomNode child = container.firstChild(); @@ -57,10 +61,9 @@ namespace { if (prop.tagName() == "property") { - QString oldUUID = prop.attribute("name"); - // Search for sub element NewName + // Search for sub element NewName QDomElement nameElem; QDomNode sub = prop.firstChild(); @@ -69,7 +72,7 @@ namespace { if (sub.isElement()) { QDomElement e = sub.toElement(); - if (e.attribute("name") == "name") + if (e.attribute("name") == formerNameKey) { nameElem = e; break; @@ -124,40 +127,6 @@ namespace { child = child.nextSibling(); } } - - // Main function: - // root: documentElement() - // classNames: z.B. {"MyCalc", "MyTask"} - void process(QDomElement root, - const QStringList& classNames) - { - QList found; - - // Step 1: Find elements with class=... - findElementsByClass(root, classNames, found); - - // Step 2: Replace UUIDs in input/output_args and build map - QMap replaceMap; - - for (QDomElement& elem : found) - { - QDomElement c = elem.firstChildElement("property-container"); - while (!c.isNull()) { - QString name = c.attribute("name"); - - if (name == "input_args" || - name == "output_args") - { - normalizePropertyContainer(c, replaceMap); - } - - c = c.nextSiblingElement("property-container"); - } - } - - // Step 3: Replace all uuids in the document - replaceUUIDsInTextNodes(root, replaceMap); - } } bool @@ -173,7 +142,32 @@ gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, return false; } - process(root, {"GtpyScriptCalculator", "GtpyTask"}); + QList found; + + // Step 1: Find elements with class=... + findElementsByClass(root, {"GtpyScriptCalculator", "GtpyTask"}, found); + + // Step 2: Replace UUIDs in input/output_args and build map + QMap replaceMap; + + for (QDomElement& elem : found) + { + QDomElement c = elem.firstChildElement("property-container"); + while (!c.isNull()) { + QString name = c.attribute("name"); + + if (name == "input_args" || + name == "output_args") + { + normalizePropertyContainerId(c, "name", replaceMap); + } + + c = c.nextSiblingElement("property-container"); + } + } + + // Step 3: Replace all uuids in the document + replaceUUIDsInTextNodes(root, replaceMap); return true; } From 45bffde94e4cd16a6ad8ded69562986153df8595 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Mon, 17 Nov 2025 15:14:41 +0100 Subject: [PATCH 08/14] small cleanup --- src/module/gt_python.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/module/gt_python.cpp b/src/module/gt_python.cpp index 7a87938..42ec815 100644 --- a/src/module/gt_python.cpp +++ b/src/module/gt_python.cpp @@ -332,20 +332,12 @@ QList GtPythonModule::sharedFunctions() const QList GtPythonModule::upgradeRoutines() const { - GtVersionNumber current = const_cast(this)->version(); - - if(current >= GtVersionNumber(2, 0, 0)) - { - return - { + return { #if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) gt::VersionUpgradeRoutine {GtVersionNumber(2, 0, 0), >py::module_upgrader::to_2_0_0::run} #endif - }; - } - - return {}; + }; } From 196bceb1927f6c9ca9e176593e5e42d0f10fc1e8 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Tue, 18 Nov 2025 09:45:34 +0100 Subject: [PATCH 09/14] update to use root element sawell --- src/module/utilities/gtpy_moduleupgrader.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index 96af640..43a89a8 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -19,6 +19,22 @@ namespace { QList& results, bool allowNestedClassElements = false) { + if (node.isElement()) + { + QDomElement elem = node.toElement(); + if (!elem.isNull()) + { + QString c = elem.attribute("class"); + + if (classNames.contains(c)) + { + results.append(elem); + + if (!allowNestedClassElements) return; + } + } + } + QDomNode child = node.firstChild(); while (!child.isNull()) { From f25bb2836d76ca3cbcfc523061c3ec58efe0d9b8 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Wed, 19 Nov 2025 12:08:11 +0100 Subject: [PATCH 10/14] add relevant python helping functions for access --- src/module/utilities/gtpy_decorator.cpp | 86 ++++++++++++++++++++++++- src/module/utilities/gtpy_decorator.h | 27 +++++++- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/module/utilities/gtpy_decorator.cpp b/src/module/utilities/gtpy_decorator.cpp index 419e769..9de750c 100644 --- a/src/module/utilities/gtpy_decorator.cpp +++ b/src/module/utilities/gtpy_decorator.cpp @@ -1037,6 +1037,59 @@ GtpyDecorator::getPropertyContainerVal(GtObject* obj, QString const& id, return structCon.getMemberValToVariant(memberId); } +QVariant +GtpyDecorator::getPropertyContainerVal (GtObject* obj, + const QString& id, + const QString& entryId, + const QString& memberId) +{ + GtPropertyStructContainer* s = structContainerOfObject(obj, id); + + if (!s) + { + gtError() << __func__ << " -> PropertyStruct container of " + "object not found!"; + return {}; + } + + for (int index = 0; index < s->size(); ++index) + { + if (s->at(index).ident() == entryId) + { + GtPropertyStructInstance& structCon = s->at(index); + + return structCon.getMemberValToVariant(memberId); + } + } + + gtError() << __func__ << tr("-> Cannot get parameter %1 of entry %2" + "in container %3").arg(memberId, entryId, id); + + return {}; +} + +QStringList +GtpyDecorator::getPropertyContainerEntryIds(GtObject* obj, + const QString& containerId) +{ + GtPropertyStructContainer* s = structContainerOfObject(obj, containerId); + + if (!s) + { + gtError() << __func__ << " -> PropertyStruct container of " + "object not found!"; + return {}; + } + + QStringList retVal; + + for (int var = 0; var < s->size(); ++var) + { + retVal << s->at(var).ident(); + } + + return retVal; +} bool GtpyDecorator::setPropertyContainerVal(GtObject* obj, const QString& id, @@ -1059,11 +1112,42 @@ GtpyDecorator::setPropertyContainerVal(GtObject* obj, const QString& id, return false; } - GtPropertyStructInstance& structCon = s->at(index); return structCon.setMemberVal(memberId, val); } + +bool +GtpyDecorator::setPropertyContainerVal(GtObject* obj, const QString& id, + const QString& entryId, + const QString& memberId, + const QVariant& val) +{ + GtPropertyStructContainer* s = structContainerOfObject(obj, id); + + if (!s) + { + gtError() << __func__ << " -> PropertyStruct container of " + "object not found!"; + return false; + } + + for (int index = 0; index < s->size(); ++index) + { + if (s->at(index).ident() == entryId) + { + GtPropertyStructInstance& structCon = s->at(index); + + return structCon.setMemberVal(memberId, val); + } + } + + gtError() << __func__ << tr("-> Cannot set parameter %1 of entry %2" + "in container %3").arg(memberId, entryId, id); + + return false; +} + #endif QList GtpyDecorator::findGtProperties(GtObject* obj) diff --git a/src/module/utilities/gtpy_decorator.h b/src/module/utilities/gtpy_decorator.h index 8014671..8681bb4 100644 --- a/src/module/utilities/gtpy_decorator.h +++ b/src/module/utilities/gtpy_decorator.h @@ -423,13 +423,29 @@ public slots: * @param id of the property struct container * @param index of the element of the items of the container * @param memberId of the property to call - * @return the value as a variant + * @return the value as a variant - empty for invalid inputs * * Example call in python: * task.getPropertyContainerVal("args_input", 0, "name") */ QVariant getPropertyContainerVal (GtObject* obj, const QString& id, - int index, const QString& memberId); + int index, const QString& memberId); + + /** + * Same as above, but uses the ident of the property entry to find it + */ + QVariant getPropertyContainerVal(GtObject* obj, const QString& id, + const QString& entryId, + const QString& memberId); + + /** + * @brief getPropertyContainerEntryIds + * @param obj - object which has the property container + * @param containerId - Id of the property container to evaluate + * @return a ist of all ids of the contained properties + */ + QStringList getPropertyContainerEntryIds(GtObject* obj, + const QString& containerId); /** * @brief setPropertyContainerVal @@ -444,6 +460,13 @@ public slots: */ bool setPropertyContainerVal(GtObject* obj, QString const& id, int index, QString const& memberId, const QVariant& val); + + /** + * Same as above, but uses the ident of the property entry to find it + */ + bool setPropertyContainerVal(GtObject* obj, QString const& id, + const QString& entryId, + QString const& memberId, const QVariant& val); #endif /** * @brief findGtProperties returns all properties of a GtObject From ac526fbb8ca0a5b5bb3ae02d12fc2a0f8c7b6b9a Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Wed, 3 Dec 2025 16:32:42 +0100 Subject: [PATCH 11/14] some cleanup --- src/module/utilities/gtpy_decorator.cpp | 9 +- src/module/utilities/gtpy_moduleupgrader.cpp | 185 ++++++++++--------- 2 files changed, 98 insertions(+), 96 deletions(-) diff --git a/src/module/utilities/gtpy_decorator.cpp b/src/module/utilities/gtpy_decorator.cpp index 9de750c..d2ad488 100644 --- a/src/module/utilities/gtpy_decorator.cpp +++ b/src/module/utilities/gtpy_decorator.cpp @@ -1037,11 +1037,12 @@ GtpyDecorator::getPropertyContainerVal(GtObject* obj, QString const& id, return structCon.getMemberValToVariant(memberId); } + QVariant -GtpyDecorator::getPropertyContainerVal (GtObject* obj, - const QString& id, - const QString& entryId, - const QString& memberId) +GtpyDecorator::getPropertyContainerVal(GtObject* obj, + const QString& id, + const QString& entryId, + const QString& memberId) { GtPropertyStructContainer* s = structContainerOfObject(obj, id); diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index 43a89a8..a7f660c 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -11,139 +11,140 @@ #include "gtpy_moduleupgrader.h" #include "gt_logging.h" +#include "gt_xmlexpr.h" namespace { - // internal helper - void findElementsByClass(const QDomNode& node, - const QStringList& classNames, - QList& results, - bool allowNestedClassElements = false) +// internal helper +void findElementsByClass(const QDomNode& node, + const QStringList& classNames, + QList& results, + bool allowNestedClassElements = false) +{ + if (node.isElement()) { - if (node.isElement()) + QDomElement elem = node.toElement(); + if (!elem.isNull()) { - QDomElement elem = node.toElement(); - if (!elem.isNull()) - { - QString c = elem.attribute("class"); + QString c = elem.attribute(gt::xml::S_CLASS_TAG); - if (classNames.contains(c)) - { - results.append(elem); + if (classNames.contains(c)) + { + results.append(elem); - if (!allowNestedClassElements) return; - } + if (!allowNestedClassElements) return; } } + } - QDomNode child = node.firstChild(); - while (!child.isNull()) + QDomNode child = node.firstChild(); + while (!child.isNull()) + { + if (child.isElement()) { - if (child.isElement()) + QDomElement elem = child.toElement(); + if (!elem.isNull()) { - QDomElement elem = child.toElement(); - if (!elem.isNull()) + QString c = elem.attribute(gt::xml::S_CLASS_TAG); + + if (classNames.contains(c)) { - QString c = elem.attribute("class"); + results.append(elem); - if (classNames.contains(c)) + if (!allowNestedClassElements) { - results.append(elem); - - if (!allowNestedClassElements) - { - child = child.nextSibling(); - continue; - } + child = child.nextSibling(); + continue; } } } - - findElementsByClass(child, classNames, results, allowNestedClassElements); - child = child.nextSibling(); } + + findElementsByClass(child, classNames, results, allowNestedClassElements); + child = child.nextSibling(); } +} - void normalizePropertyContainerId( - QDomElement container, QString const& formerNameKey, - QMap& replaceMap) - { - QDomNode child = container.firstChild(); +void normalizePropertyContainerId( + QDomElement container, QString const& formerNameKey, + QMap& replaceMap) +{ + QDomNode child = container.firstChild(); - while (!child.isNull()) + while (!child.isNull()) + { + if (child.isElement()) { - if (child.isElement()) - { - QDomElement prop = child.toElement(); + QDomElement prop = child.toElement(); - if (prop.tagName() == "property") - { - QString oldUUID = prop.attribute("name"); + if (prop.tagName() == gt::xml::S_PROPERTY_TAG) + { + QString oldUUID = prop.attribute(gt::xml::S_NAME_TAG); - // Search for sub element NewName - QDomElement nameElem; - QDomNode sub = prop.firstChild(); + // Search for sub element NewName + QDomElement nameElem; + QDomNode sub = prop.firstChild(); - while (!sub.isNull()) + while (!sub.isNull()) + { + if (sub.isElement()) { - if (sub.isElement()) + QDomElement e = sub.toElement(); + if (e.attribute(gt::xml::S_NAME_TAG) == formerNameKey) { - QDomElement e = sub.toElement(); - if (e.attribute("name") == formerNameKey) - { - nameElem = e; - break; - } + nameElem = e; + break; } - sub = sub.nextSibling(); } + sub = sub.nextSibling(); + } - if (!nameElem.isNull()) - { - QString newName = nameElem.text().trimmed(); + if (!nameElem.isNull()) + { + QString newName = nameElem.text().trimmed(); - // keep connection info - replaceMap.insert(oldUUID, newName); + // keep connection info + replaceMap.insert(oldUUID, newName); - // Replace UUID in name attribute - prop.setAttribute("name", newName); + // Replace UUID in name attribute + prop.setAttribute(gt::xml::S_NAME_TAG, newName); - // Remove subelement - prop.removeChild(nameElem); - } + // Remove subelement + prop.removeChild(nameElem); } } - - child = child.nextSibling(); } + + child = child.nextSibling(); } +} + +void replaceUUIDsInTextNodes(QDomNode node, + const QMap& replaceMap) +{ + QDomNode child = node.firstChild(); - void replaceUUIDsInTextNodes(QDomNode node, - const QMap& replaceMap) + while (!child.isNull()) { - QDomNode child = node.firstChild(); - while (!child.isNull()) + if (child.isText()) { + QString txt = child.nodeValue(); + QString newTxt = txt; - if (child.isText()) + for (auto it = replaceMap.begin(); it != replaceMap.end(); ++it) { - QString txt = child.nodeValue(); - QString newTxt = txt; - - for (auto it = replaceMap.begin(); it != replaceMap.end(); ++it) - { - newTxt.replace(it.key(), it.value()); - } - - if (newTxt != txt) - child.setNodeValue(newTxt); + newTxt.replace(it.key(), it.value()); } - replaceUUIDsInTextNodes(child, replaceMap); - child = child.nextSibling(); + if (newTxt != txt) + child.setNodeValue(newTxt); } + + replaceUUIDsInTextNodes(child, replaceMap); + child = child.nextSibling(); } } +} bool gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, @@ -168,17 +169,17 @@ gtpy::module_upgrader::to_2_0_0::run(QDomElement& root, for (QDomElement& elem : found) { - QDomElement c = elem.firstChildElement("property-container"); - while (!c.isNull()) { - QString name = c.attribute("name"); + QDomElement c = elem.firstChildElement(gt::xml::S_PROPERTYCONT_TAG); + while (!c.isNull()) + { + QString name = c.attribute(gt::xml::S_NAME_TAG); - if (name == "input_args" || - name == "output_args") + if (name == "input_args" || name == "output_args") { - normalizePropertyContainerId(c, "name", replaceMap); + normalizePropertyContainerId(c, gt::xml::S_NAME_TAG, replaceMap); } - c = c.nextSiblingElement("property-container"); + c = c.nextSiblingElement(gt::xml::S_PROPERTYCONT_TAG); } } From 76c0dfae9eda6f2bec4dffaedd5b6bb321a1da3e Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Thu, 29 Jan 2026 08:43:16 +0100 Subject: [PATCH 12/14] integration of review --- .../gtpy_abstractscriptcomponent.cpp | 4 +- src/module/utilities/gtpy_decorator.cpp | 31 +++--- src/module/utilities/gtpy_decorator.h | 28 +++++- src/module/utilities/gtpy_moduleupgrader.cpp | 98 +++++++++++-------- 4 files changed, 100 insertions(+), 61 deletions(-) diff --git a/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp b/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp index 07f2589..70b8fe0 100644 --- a/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp +++ b/src/module/processcomponents/gtpy_abstractscriptcomponent.cpp @@ -95,13 +95,11 @@ GtpyAbstractScriptComponent::GtpyAbstractScriptComponent() : m_pyThreadId{-1}, m_replaceTabBySpaces{"replaceTab", "Replace tab by spaces"}, m_tabSize{"tabSize", "Tab size"}, - m_script{"script", "Script"} + m_script{"script", "Script"}, #if GT_VERSION >= GT_VERSION_CHECK(2, 1, 0) - , m_inputArgs{"input_args", GtPropertyStructContainer::Associative}, m_outputArgs{"output_args", GtPropertyStructContainer::Associative} #elif GT_VERSION >= GT_VERSION_CHECK(2, 0, 0) - , m_inputArgs{"input_args"}, m_outputArgs{"output_args"} #endif diff --git a/src/module/utilities/gtpy_decorator.cpp b/src/module/utilities/gtpy_decorator.cpp index d2ad488..d30e107 100644 --- a/src/module/utilities/gtpy_decorator.cpp +++ b/src/module/utilities/gtpy_decorator.cpp @@ -1053,14 +1053,11 @@ GtpyDecorator::getPropertyContainerVal(GtObject* obj, return {}; } - for (int index = 0; index < s->size(); ++index) - { - if (s->at(index).ident() == entryId) - { - GtPropertyStructInstance& structCon = s->at(index); + GtPropertyStructContainer::const_iterator it = s->findEntry(entryId); - return structCon.getMemberValToVariant(memberId); - } + if (it != s->end()) + { + return it->getMemberValToVariant(memberId); } gtError() << __func__ << tr("-> Cannot get parameter %1 of entry %2" @@ -1084,10 +1081,11 @@ GtpyDecorator::getPropertyContainerEntryIds(GtObject* obj, QStringList retVal; - for (int var = 0; var < s->size(); ++var) - { - retVal << s->at(var).ident(); - } + std::transform(s->begin(), s->end(), std::back_inserter(retVal), + [](const auto& v) + { + return v.ident(); + }); return retVal; } @@ -1133,14 +1131,11 @@ GtpyDecorator::setPropertyContainerVal(GtObject* obj, const QString& id, return false; } - for (int index = 0; index < s->size(); ++index) - { - if (s->at(index).ident() == entryId) - { - GtPropertyStructInstance& structCon = s->at(index); + GtPropertyStructContainer::iterator it = s->findEntry(entryId); - return structCon.setMemberVal(memberId, val); - } + if (it != s->end()) + { + return it->setMemberVal(memberId, val); } gtError() << __func__ << tr("-> Cannot set parameter %1 of entry %2" diff --git a/src/module/utilities/gtpy_decorator.h b/src/module/utilities/gtpy_decorator.h index 8681bb4..861d63f 100644 --- a/src/module/utilities/gtpy_decorator.h +++ b/src/module/utilities/gtpy_decorator.h @@ -434,12 +434,29 @@ public slots: /** * Same as above, but uses the ident of the property entry to find it */ + + /** + * @brief getPropertyContainerVal + * Find a struct container property and return a value of + * a defined propety + * @param obj - parent object of the struct propety + * @param id of the property struct container + * @param entryId - id of the entry to read the value from. + * In contrast to function above this function does not use the index + * @param memberId of the property to call + * @return the value as a variant - empty for invalid inputs + * + * Example call in python: + * task.getPropertyContainerVal("constraints", "minEta", "value") + */ QVariant getPropertyContainerVal(GtObject* obj, const QString& id, const QString& entryId, const QString& memberId); /** * @brief getPropertyContainerEntryIds + * Returns a list with all property entry ids of a given container element + * The container element is specified by its containerId * @param obj - object which has the property container * @param containerId - Id of the property container to evaluate * @return a ist of all ids of the contained properties @@ -462,7 +479,16 @@ public slots: QString const& memberId, const QVariant& val); /** - * Same as above, but uses the ident of the property entry to find it + * @brief setPropertyContainerVal + * Find a struct container property and sets a value of + * a defined propety + * @param obj - parent object of the struct propety + * @param id of the property struct container + * @param entryId - Id of the container element to modify. Incontrast to the + * function above the elment is determined by id and not by index + * @param memberId of the property to call + * @param val - value to set + * @return true in case of success, else false */ bool setPropertyContainerVal(GtObject* obj, QString const& id, const QString& entryId, diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index a7f660c..43b503c 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -23,17 +23,16 @@ void findElementsByClass(const QDomNode& node, if (node.isElement()) { QDomElement elem = node.toElement(); - if (!elem.isNull()) - { - QString c = elem.attribute(gt::xml::S_CLASS_TAG); - if (classNames.contains(c)) - { - results.append(elem); + QString c = elem.attribute(gt::xml::S_CLASS_TAG); - if (!allowNestedClassElements) return; - } + if (classNames.contains(c)) + { + results.append(elem); + + if (!allowNestedClassElements) return; } + } QDomNode child = node.firstChild(); @@ -64,54 +63,75 @@ void findElementsByClass(const QDomNode& node, } } +/** + * @brief normalizePropertyContainerId + * Important change of the update is the replacement of the names + * of the property elements. + * Therefore a map is used to collect the old and new names of the entries. + * @param container - QDomElement of the container property + * @param formerNameKey - identifier if the property in the old structure + * @param replaceMap - map to collect the required renamings + */ void normalizePropertyContainerId( - QDomElement container, QString const& formerNameKey, + QDomElement const& container, QString const& formerNameKey, QMap& replaceMap) { QDomNode child = container.firstChild(); while (!child.isNull()) { - if (child.isElement()) + if (child.isElement() == false) { - QDomElement prop = child.toElement(); + child = child.nextSibling(); + continue; + } - if (prop.tagName() == gt::xml::S_PROPERTY_TAG) - { - QString oldUUID = prop.attribute(gt::xml::S_NAME_TAG); + QDomElement prop = child.toElement(); - // Search for sub element NewName - QDomElement nameElem; - QDomNode sub = prop.firstChild(); + if (prop.tagName() != gt::xml::S_PROPERTY_TAG) + { + child = child.nextSibling(); + continue; + } + + QString oldUUID = prop.attribute(gt::xml::S_NAME_TAG); - while (!sub.isNull()) + if (oldUUID.isEmpty()) + { + child = child.nextSibling(); + continue; + } + + // Search for sub element NewName + QDomElement nameElem; + QDomNode sub = prop.firstChild(); + + while (!sub.isNull()) + { + QDomElement e = sub.toElement(); + if (!e.isNull() && e.tagName() == gt::xml::S_PROPERTY_TAG) + { + if (e.attribute(gt::xml::S_NAME_TAG) == formerNameKey) { - if (sub.isElement()) - { - QDomElement e = sub.toElement(); - if (e.attribute(gt::xml::S_NAME_TAG) == formerNameKey) - { - nameElem = e; - break; - } - } - sub = sub.nextSibling(); + nameElem = e; + break; } + } + sub = sub.nextSibling(); + } - if (!nameElem.isNull()) - { - QString newName = nameElem.text().trimmed(); + if (!nameElem.isNull()) + { + QString newName = nameElem.text().trimmed(); - // keep connection info - replaceMap.insert(oldUUID, newName); + // keep connection info + replaceMap.insert(oldUUID, newName); - // Replace UUID in name attribute - prop.setAttribute(gt::xml::S_NAME_TAG, newName); + // Replace UUID in name attribute + prop.setAttribute(gt::xml::S_NAME_TAG, newName); - // Remove subelement - prop.removeChild(nameElem); - } - } + // Remove subelement + prop.removeChild(nameElem); } child = child.nextSibling(); From 290d08bb344685084195089a53dae4f7c3df99bb Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Mon, 2 Feb 2026 10:08:53 +0100 Subject: [PATCH 13/14] changes after review feedback --- src/module/utilities/gtpy_decorator.h | 13 ++--- src/module/utilities/gtpy_moduleupgrader.cpp | 58 ++++++++++---------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/module/utilities/gtpy_decorator.h b/src/module/utilities/gtpy_decorator.h index 861d63f..bcb0a04 100644 --- a/src/module/utilities/gtpy_decorator.h +++ b/src/module/utilities/gtpy_decorator.h @@ -424,7 +424,6 @@ public slots: * @param index of the element of the items of the container * @param memberId of the property to call * @return the value as a variant - empty for invalid inputs - * * Example call in python: * task.getPropertyContainerVal("args_input", 0, "name") */ @@ -436,16 +435,14 @@ public slots: */ /** - * @brief getPropertyContainerVal - * Find a struct container property and return a value of + * @brief Find a struct container property and return a value of * a defined propety + * * @param obj - parent object of the struct propety * @param id of the property struct container * @param entryId - id of the entry to read the value from. - * In contrast to function above this function does not use the index * @param memberId of the property to call * @return the value as a variant - empty for invalid inputs - * * Example call in python: * task.getPropertyContainerVal("constraints", "minEta", "value") */ @@ -479,13 +476,11 @@ public slots: QString const& memberId, const QVariant& val); /** - * @brief setPropertyContainerVal - * Find a struct container property and sets a value of + * @brief Find a struct container property and sets a value of * a defined propety * @param obj - parent object of the struct propety * @param id of the property struct container - * @param entryId - Id of the container element to modify. Incontrast to the - * function above the elment is determined by id and not by index + * @param entryId - Id of the container element to modify. * @param memberId of the property to call * @param val - value to set * @return true in case of success, else false diff --git a/src/module/utilities/gtpy_moduleupgrader.cpp b/src/module/utilities/gtpy_moduleupgrader.cpp index 43b503c..e02928e 100644 --- a/src/module/utilities/gtpy_moduleupgrader.cpp +++ b/src/module/utilities/gtpy_moduleupgrader.cpp @@ -14,6 +14,25 @@ #include "gt_xmlexpr.h" namespace { + + +bool handleElement(const QDomNode& node, + const QStringList& classNames, + QList& results, + bool allowNestedClassElements) +{ + QDomElement elem = node.toElement(); + QString c = elem.attribute(gt::xml::S_CLASS_TAG); + + if (classNames.contains(c)) + { + results.append(elem); + return allowNestedClassElements; + } + return true; +} + + // internal helper void findElementsByClass(const QDomNode& node, const QStringList& classNames, @@ -22,17 +41,10 @@ void findElementsByClass(const QDomNode& node, { if (node.isElement()) { - QDomElement elem = node.toElement(); - - QString c = elem.attribute(gt::xml::S_CLASS_TAG); - - if (classNames.contains(c)) + if (!handleElement(node, classNames, results, allowNestedClassElements)) { - results.append(elem); - - if (!allowNestedClassElements) return; + return; } - } QDomNode child = node.firstChild(); @@ -40,21 +52,10 @@ void findElementsByClass(const QDomNode& node, { if (child.isElement()) { - QDomElement elem = child.toElement(); - if (!elem.isNull()) + if (!handleElement(child, classNames, results, allowNestedClassElements)) { - QString c = elem.attribute(gt::xml::S_CLASS_TAG); - - if (classNames.contains(c)) - { - results.append(elem); - - if (!allowNestedClassElements) - { - child = child.nextSibling(); - continue; - } - } + child = child.nextSibling(); + continue; } } @@ -109,13 +110,12 @@ void normalizePropertyContainerId( while (!sub.isNull()) { QDomElement e = sub.toElement(); - if (!e.isNull() && e.tagName() == gt::xml::S_PROPERTY_TAG) + if (!e.isNull() + && e.tagName() == gt::xml::S_PROPERTY_TAG + && e.attribute(gt::xml::S_NAME_TAG) == formerNameKey) { - if (e.attribute(gt::xml::S_NAME_TAG) == formerNameKey) - { - nameElem = e; - break; - } + nameElem = e; + break; } sub = sub.nextSibling(); } From 0b9ed3d086b002fd45d556bb73f3a15c99adf0b2 Mon Sep 17 00:00:00 2001 From: "Schmeink, Jens" Date: Mon, 2 Feb 2026 10:51:28 +0100 Subject: [PATCH 14/14] cleanup of docstring --- src/module/utilities/gtpy_decorator.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/module/utilities/gtpy_decorator.h b/src/module/utilities/gtpy_decorator.h index bcb0a04..8f32162 100644 --- a/src/module/utilities/gtpy_decorator.h +++ b/src/module/utilities/gtpy_decorator.h @@ -430,13 +430,10 @@ public slots: QVariant getPropertyContainerVal (GtObject* obj, const QString& id, int index, const QString& memberId); - /** - * Same as above, but uses the ident of the property entry to find it - */ - /** * @brief Find a struct container property and return a value of - * a defined propety + * a defined property. This function uses the id string of the + * container element. * * @param obj - parent object of the struct propety * @param id of the property struct container