From: nds Date: Thu, 14 Jul 2016 07:22:58 +0000 (+0300) Subject: Issue #1659 New widget for supporting optional inputs : correction for enclosed cases. X-Git-Tag: V_2.5.0~197 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=392e617e3add41f698281c14ce5701cfd9f41e9c;p=modules%2Fshaper.git Issue #1659 New widget for supporting optional inputs : correction for enclosed cases. --- diff --git a/src/Config/Config_AttributeMessage.cpp b/src/Config/Config_AttributeMessage.cpp index 973dd3930..b154d9cbf 100644 --- a/src/Config/Config_AttributeMessage.cpp +++ b/src/Config/Config_AttributeMessage.cpp @@ -9,7 +9,6 @@ Config_AttributeMessage::Config_AttributeMessage(const Events_ID theId, const vo myFeatureId = std::string(); // Feature unique id myIsObligatory = true; myIsConcealment = false; - myCaseId = std::string(); } Config_AttributeMessage::~Config_AttributeMessage() @@ -57,22 +56,12 @@ void Config_AttributeMessage::setObligatory(bool theObligatory) this->myIsObligatory = theObligatory; } -const std::string& Config_AttributeMessage::caseId() const +const std::list >& Config_AttributeMessage::getCases() const { - return myCaseId; + return myCases; } -const std::string& Config_AttributeMessage::switchId() const +void Config_AttributeMessage::setCases(const std::list >& theCases) { - return mySwitchId; -} - -void Config_AttributeMessage::setCaseId(const std::string& theId) -{ - this->myCaseId = theId; -} - -void Config_AttributeMessage::setSwitchId(const std::string& theId) -{ - this->mySwitchId = theId; + myCases = theCases; } diff --git a/src/Config/Config_AttributeMessage.h b/src/Config/Config_AttributeMessage.h index e9ab250ea..d2a8cf705 100644 --- a/src/Config/Config_AttributeMessage.h +++ b/src/Config/Config_AttributeMessage.h @@ -8,6 +8,7 @@ #include #include +#include /*! * \class Config_AttributeMessage @@ -22,10 +23,10 @@ class Config_AttributeMessage : public Events_Message std::string myFeatureId; ///< Attribute's feature's unique id bool myIsObligatory; ///< Required to be set by user, else it's feature is invalid. bool myIsConcealment; ///< If true, conceals features used as input - std::string myCaseId; ///< Attribute's case's id, if it placed inside a paged containers - std::string mySwitchId; ///< Attribute's switch id, if it placed inside a paged containers + ///< a list of pairs, if the attribute is placed inside paged containers: (case, switch) + std::list > myCases; - public: +public: /// Same event as Config_FeatureMessage::MODEL_EVENT() inline static const char* MODEL_EVENT() { @@ -47,10 +48,10 @@ class Config_AttributeMessage : public Events_Message CONFIG_EXPORT bool isObligatory() const; /// Returns true if attribute should conceal input features CONFIG_EXPORT bool isConcealment() const; - /// Returns id of a case which contain the attribute - CONFIG_EXPORT const std::string& caseId() const; - /// Returns id of a switch which contain the attribute - CONFIG_EXPORT const std::string& switchId() const; + /// Returns container of ids of pair of a case and switches + CONFIG_EXPORT const std::list >& getCases() const; + /// Sets ids of pair of a case and switches + CONFIG_EXPORT void setCases(const std::list >& theCases); /// Set attribute's unique id CONFIG_EXPORT void setAttributeId(const std::string& theId); @@ -60,10 +61,6 @@ class Config_AttributeMessage : public Events_Message CONFIG_EXPORT void setConcealment(bool isConcealment); /// Set attribute's obligatory state CONFIG_EXPORT void setObligatory(bool isObligatory); - /// Set attribute's case - CONFIG_EXPORT void setCaseId(const std::string& id); - /// Set attribute's switch - CONFIG_EXPORT void setSwitchId(const std::string& id); }; #endif // ATTRIBUTE_MESSAGE_H diff --git a/src/Config/Config_Common.cpp b/src/Config/Config_Common.cpp index 7d2a3ba87..ac274ada8 100644 --- a/src/Config/Config_Common.cpp +++ b/src/Config/Config_Common.cpp @@ -143,24 +143,24 @@ bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...) return false; } -bool hasParentRecursive(xmlNodePtr theNode, const std::vector& theNodeNames) +xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const std::vector& theNodeNames) { if (!hasParent(theNode)) { - return false; // have no parents at all + return 0; // have no parents at all } xmlNodePtr aNode = theNode->parent; const xmlChar* aName = aNode->name; if (!aName || !isElementNode(aNode)) { - return false; + return 0; } for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) { if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex])) - return true; + return aNode; } return hasParentRecursive(aNode, theNodeNames); } -bool hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...) +xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...) { std::vector aNodeNames; va_list args; // define argument list variable diff --git a/src/Config/Config_Common.h b/src/Config/Config_Common.h index 0998a6b73..eb7cbc9fa 100644 --- a/src/Config/Config_Common.h +++ b/src/Config/Config_Common.h @@ -84,7 +84,7 @@ 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, ...); +CONFIG_EXPORT xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...); /*! diff --git a/src/Config/Config_FeatureReader.cpp b/src/Config/Config_FeatureReader.cpp index 4f3b12cac..4797d9d4a 100644 --- a/src/Config/Config_FeatureReader.cpp +++ b/src/Config/Config_FeatureReader.cpp @@ -71,23 +71,31 @@ void Config_FeatureReader::processNode(xmlNodePtr theNode) aMessage->setAttributeId(anAttributeID); aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true)); aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false)); - if (hasParentRecursive(theNode, WDG_CHECK_GROUP, NULL)) { - const char* kWdgCase = WDG_CHECK_GROUP; - const char* kWdgSwitch = WDG_CHECK_GROUP; - aMessage->setCaseId(restoreAttribute(kWdgCase, _ID)); - aMessage->setSwitchId(restoreAttribute(kWdgSwitch, _ID)); - } - // nested "paged" widgets are not allowed, this issue may be resolved here: - else 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 = hasParentRecursive(theNode, WDG_SWITCH_CASE, NULL) - ? WDG_SWITCH - : WDG_TOOLBOX; - aMessage->setCaseId(restoreAttribute(kWdgCase, _ID)); - aMessage->setSwitchId(restoreAttribute(kWdgSwitch, _ID)); + + std::list > aCases; + xmlNodePtr aCaseNode = hasParentRecursive(theNode, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, WDG_CHECK_GROUP, NULL); + while(aCaseNode) { + std::string aCaseNodeID = getProperty(aCaseNode, _ID); + std::string aSwitchNodeID = ""; + const xmlChar* aName = aCaseNode->name; + xmlNodePtr aSwitchNode; + if (!xmlStrcmp(aName, (const xmlChar *) WDG_SWITCH_CASE)) { + aSwitchNode = hasParentRecursive(aCaseNode, WDG_SWITCH, NULL); + } + else if (!xmlStrcmp(aName, (const xmlChar *) WDG_TOOLBOX_BOX)) { + aSwitchNode = hasParentRecursive(aCaseNode, WDG_TOOLBOX, NULL); + } + if (!xmlStrcmp(aName, (const xmlChar *) WDG_CHECK_GROUP)) { + /// the box is optional, attribute is in case if the optional attribute value is not empty + aSwitchNode = aCaseNode; + } + if (aSwitchNode) + aSwitchNodeID = getProperty(aSwitchNode, _ID); + + aCases.push_back(std::make_pair(aSwitchNodeID, aCaseNodeID)); + aCaseNode = hasParentRecursive(aSwitchNode, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, WDG_CHECK_GROUP, NULL); } + aMessage->setCases(aCases); Events_Loop::loop()->send(aMessage); } // container pages, like "case" or "box" diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 44d24c0fa..ce6a26f9a 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -375,9 +375,9 @@ void Model_Session::processEvent(const std::shared_ptr& theMessa if(aMsgAttr->isConcealment()) { validators()->registerConcealment(aMsgAttr->featureId(), aMsgAttr->attributeId()); } - if (!aMsgAttr->caseId().empty()) { - validators()->registerCase(aMsgAttr->featureId(), aMsgAttr->attributeId(), - aMsgAttr->switchId(), aMsgAttr->caseId()); + const std::list >& aCases = aMsgAttr->getCases(); + if (!aCases.empty()) { + validators()->registerCase(aMsgAttr->featureId(), aMsgAttr->attributeId(), aCases); } } } diff --git a/src/Model/Model_Validator.cpp b/src/Model/Model_Validator.cpp index 1d420229f..ed7ffac93 100644 --- a/src/Model/Model_Validator.cpp +++ b/src/Model/Model_Validator.cpp @@ -314,40 +314,55 @@ bool Model_ValidatorsFactory::isConcealed(std::string theFeature, std::string th } void Model_ValidatorsFactory::registerCase(std::string theFeature, std::string theAttribute, - std::string theSwitchId, std::string theCaseId) + const std::list >& theCases) { - std::map > > > + std::map > > > ::iterator aFindFeature = myCases.find(theFeature); if (aFindFeature == myCases.end()) { - myCases[theFeature] = std::map > >(); + myCases[theFeature] = std::map > >(); aFindFeature = myCases.find(theFeature); } - std::map > >::iterator aFindAttrID = + std::map > >::iterator aFindAttrID = aFindFeature->second.find(theAttribute); + if (aFindAttrID == aFindFeature->second.end()) { aFindFeature->second[theAttribute] = - std::pair >(theSwitchId, std::set()); + std::map >(); aFindAttrID = aFindFeature->second.find(theAttribute); } - aFindAttrID->second.second.insert(theCaseId); + std::list >::const_iterator aCasesIt = theCases.begin(), + aCasesLast = theCases.end(); + std::map > aFindCases = aFindAttrID->second; + for (; aCasesIt != aCasesLast; aCasesIt++) { + std::pair aCasePair = *aCasesIt; + std::string aSwitch = aCasePair.first; + if (aFindAttrID->second.find(aSwitch) == aFindAttrID->second.end()) { + aFindAttrID->second[aSwitch] = std::set(); + } + aFindAttrID->second[aSwitch].insert(aCasePair.second); + } } bool Model_ValidatorsFactory::isCase(FeaturePtr theFeature, std::string theAttribute) { - std::map > > > + bool anInCase = true; + std::map > > > ::iterator aFindFeature = myCases.find(theFeature->getKind()); if (aFindFeature != myCases.end()) { - std::map > >::iterator + std::map > >::iterator aFindAttrID = aFindFeature->second.find(theAttribute); if (aFindAttrID != aFindFeature->second.end()) { - // the the switch-attribute that contains the case value - AttributeStringPtr aSwitch = theFeature->string(aFindAttrID->second.first); - if (aSwitch.get()) { - // the second has the case identifier - return aFindAttrID->second.second.find(aSwitch->value()) != - aFindAttrID->second.second.end(); + std::map >::iterator + aCasesIt = aFindAttrID->second.begin(), aCasesLast = aFindAttrID->second.end(); + for (; aCasesIt != aCasesLast && anInCase; aCasesIt++) { + // the the switch-attribute that contains the case value + AttributeStringPtr aSwitch = theFeature->string(aCasesIt->first); + if (aSwitch.get()) { + // the second has the case identifier + anInCase = aCasesIt->second.find(aSwitch->value()) != aCasesIt->second.end(); + } } } } - return true; // if no additional conditions, this attribute is the case to be validated + return anInCase; // if no additional conditions, this attribute is the case to be validated } diff --git a/src/Model/Model_Validator.h b/src/Model/Model_Validator.h index 2fd016478..87a9b02da 100644 --- a/src/Model/Model_Validator.h +++ b/src/Model/Model_Validator.h @@ -41,7 +41,7 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory /// Map from feature kind to map of attribute IDs to pair // (switchId (ID of the attribute) and case Ids (possible values of the switch attribute)) std::map > > > myCases; + std::map > > > myCases; public: /// Registers the instance of the validator by the ID @@ -94,9 +94,13 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory /// Returns true that it was registered that attribute conceals the referenced result virtual bool isConcealed(std::string theFeature, std::string theAttribute); + /// register the case-attribute (\a myCases set definition) + //virtual void registerCase(std::string theFeature, std::string theAttribute, + // std::string theSwitchId, std::string theCaseId); + /// register the case-attribute (\a myCases set definition) virtual void registerCase(std::string theFeature, std::string theAttribute, - std::string theSwitchId, std::string theCaseId); + const std::list >& theCases); /// Returns true if the attribute must be checked (the case is selected) virtual bool isCase(FeaturePtr theFeature, std::string theAttribute); diff --git a/src/ModelAPI/ModelAPI_Validator.h b/src/ModelAPI/ModelAPI_Validator.h index 7fddb71ac..0557333ba 100644 --- a/src/ModelAPI/ModelAPI_Validator.h +++ b/src/ModelAPI/ModelAPI_Validator.h @@ -103,7 +103,7 @@ class MODELAPI_EXPORT ModelAPI_ValidatorsFactory /// Register the case-attribute: this attribute is checked only if its case is selected virtual void registerCase(std::string theFeature, std::string theAttribute, - std::string theSwitchId, std::string theCaseId) = 0; + const std::list >& theCases) = 0; /// Returns true if the attribute must be checked (the case is selected) virtual bool isCase(FeaturePtr theFeature, std::string theAttribute) = 0; diff --git a/src/ModuleBase/ModuleBase_WidgetCheckGroupBox.cpp b/src/ModuleBase/ModuleBase_WidgetCheckGroupBox.cpp index 05f202306..6ca136d04 100755 --- a/src/ModuleBase/ModuleBase_WidgetCheckGroupBox.cpp +++ b/src/ModuleBase/ModuleBase_WidgetCheckGroupBox.cpp @@ -64,6 +64,9 @@ void ModuleBase_WidgetCheckGroupBox::onPageClicked() { storeValue(); updateControlsVisibility(); + + if (!isEditingMode()) + emit focusOutWidget(this); } void ModuleBase_WidgetCheckGroupBox::addPageStretch()