From a27e3138e3e85a8e8ff9085c96aaca2ac8dea812 Mon Sep 17 00:00:00 2001 From: spo Date: Mon, 6 Jul 2015 16:48:14 +0300 Subject: [PATCH] Issue #671 - Removing object used in feature creation with optional parameters. -- Fix: groupbox nested attributes in switch/toolbox nodes. --- src/Config/Config_Common.cpp | 36 +++++++++++++++++++++++++++++ src/Config/Config_Common.h | 6 +++++ src/Config/Config_FeatureReader.cpp | 7 +++--- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/Config/Config_Common.cpp b/src/Config/Config_Common.cpp index a36be0325..bb5ddeed9 100644 --- a/src/Config/Config_Common.cpp +++ b/src/Config/Config_Common.cpp @@ -17,6 +17,7 @@ #include #include // for std::transform +#include bool isElementNode(xmlNodePtr theNode) { @@ -55,12 +56,14 @@ bool isAttributeNode(xmlNodePtr theNode) return false; // it's parent is "feature" or "source" or page ("case" or "box") if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE, + WDG_GROUP, WDG_CHECK_GROUP, WDG_TOOLBOX_BOX, WDG_SWITCH_CASE, NULL)) return false; //it should not be a "source" or a "validator" node bool isLogical = isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NODE_SELFILTER, NULL); bool isPagedContainer = isNode(theNode, WDG_TOOLBOX, WDG_TOOLBOX_BOX, + WDG_GROUP, WDG_CHECK_GROUP, WDG_SWITCH, WDG_SWITCH_CASE, NULL); return !isLogical && !isPagedContainer; } @@ -140,6 +143,39 @@ bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...) return false; } +bool hasParentRecursive(xmlNodePtr theNode, const std::vector& theNodeNames) +{ + if (!hasParent(theNode)) { + return false; // have no parents at all + } + xmlNodePtr aNode = theNode->parent; + const xmlChar* aName = aNode->name; + if (!aName || !isElementNode(aNode)) { + return false; + } + for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) { + if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex])) + return true; + } + return hasParentRecursive(aNode, theNodeNames); +} + +bool hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...) +{ + std::vector aNodeNames; + va_list args; // define argument list variable + va_start(args, theNodeName); // init list; point to last defined argument + aNodeNames.push_back(theNodeName); + while (true) { + char *anArg = va_arg (args, char*); // get next argument + if (anArg == NULL) + break; + aNodeNames.push_back(anArg); + } + va_end(args); // cleanup the system stack + return hasParentRecursive(theNode, aNodeNames); +} + bool getParametersInfo(xmlNodePtr theNode, std::string& outPropertyId, std::list& outValidatorParameters) { diff --git a/src/Config/Config_Common.h b/src/Config/Config_Common.h index 1850f8a7b..52776d764 100644 --- a/src/Config/Config_Common.h +++ b/src/Config/Config_Common.h @@ -81,6 +81,12 @@ CONFIG_EXPORT bool hasParent(xmlNodePtr theNode); */ CONFIG_EXPORT bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...); +/*! + * Checks if the given node has any valid parent in hierarchy with any of the given node names. + */ +CONFIG_EXPORT bool hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...); + + /*! * Returns named property for an id node as std::string and the parameters of the node. */ diff --git a/src/Config/Config_FeatureReader.cpp b/src/Config/Config_FeatureReader.cpp index 2b024061a..8a3b5f19b 100644 --- a/src/Config/Config_FeatureReader.cpp +++ b/src/Config/Config_FeatureReader.cpp @@ -72,11 +72,11 @@ void Config_FeatureReader::processNode(xmlNodePtr theNode) aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true)); aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false)); // nested "paged" widgets are not allowed, this issue may be resolved here: - if (hasParent(theNode, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL)) { - const char* kWdgCase = hasParent(theNode, WDG_SWITCH_CASE, NULL) + if (hasParentRecursive(theNode, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL)) { + const char* kWdgCase = hasParentRecursive(theNode, WDG_SWITCH_CASE, NULL) ? WDG_SWITCH_CASE : WDG_TOOLBOX_BOX; - const char* kWdgSwitch = hasParent(theNode, WDG_SWITCH_CASE, NULL) + const char* kWdgSwitch = hasParentRecursive(theNode, WDG_SWITCH_CASE, NULL) ? WDG_SWITCH : WDG_TOOLBOX; aMessage->setCaseId(restoreAttribute(kWdgCase, _ID)); @@ -106,6 +106,7 @@ bool Config_FeatureReader::processChildren(xmlNodePtr theNode) bool result = isNode(theNode, NODE_WORKBENCH, NODE_GROUP, NULL); if(!result && myIsProcessWidgets) { result = isNode(theNode, NODE_FEATURE, + WDG_GROUP, WDG_CHECK_GROUP, WDG_TOOLBOX, WDG_TOOLBOX_BOX, WDG_SWITCH, WDG_SWITCH_CASE, NULL); } -- 2.39.2