--- /dev/null
+#!/bin/bash
+
+function isDOSFile
+{
+ local FILENAME="$1"
+ file "$FILENAME" | grep -q "CRLF line terminators"
+}
+
+if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# Find files with DOS line endings
+FOUND=0
+for FILE in $(exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq) ; do
+ isDOSFile "$FILE"
+ if (( $? == 0 ))
+ then
+ echo "\"$FILE\" has DOS line endings" >&2
+ FOUND=1
+ fi
+done
+
+exit $FOUND
--- /dev/null
+#!/bin/bash
+
+find src -type f -name "*.cpp" | xargs dos2unix $1 >/dev/null
+find src -type f -name "*.h" | xargs dos2unix $1 >/dev/null
+find src -type f -name "*.py" | xargs dos2unix $1 >/dev/null
\ No newline at end of file
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-/*\r
- * Config_Common.cpp\r
- *\r
- * Created on: Apr 17, 2014\r
- * Author: sbh\r
- */\r
-\r
-#include "Config_Common.h"\r
-#include <Config_Keywords.h>\r
-\r
-#include <libxml/parser.h>\r
-#include <libxml/tree.h>\r
-\r
-#include <sstream> // for stringstream\r
-\r
-#include <string>\r
-#include <algorithm> // for std::transform\r
-#include <vector>\r
-\r
-bool isElementNode(xmlNodePtr theNode)\r
-{\r
- if (!theNode)\r
- return false;\r
- return theNode->type == XML_ELEMENT_NODE;\r
-}\r
-\r
-bool isNode(xmlNodePtr theNode, const char* theNodeName, ...)\r
-{\r
- const xmlChar* aName = theNode->name;\r
- if (!aName || !isElementNode(theNode)) {\r
- return false;\r
- }\r
- if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {\r
- return true;\r
- }\r
- va_list args; // define argument list variable\r
- va_start(args, theNodeName); // init list; point to last defined argument\r
- while (true) {\r
- char *anArg = va_arg (args, char*); // get next argument\r
- if (anArg == NULL)\r
- break;\r
- if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {\r
- va_end(args); // cleanup the system stack\r
- return true;\r
- }\r
- }\r
- va_end(args); // cleanup the system stack\r
- return false;\r
-}\r
-\r
-bool isAttributeNode(xmlNodePtr theNode)\r
-{\r
- if(!isElementNode(theNode))\r
- return false;\r
- // it's parent is "feature" or "source" or page ("case" or "box")\r
- if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE, \r
- WDG_GROUP, WDG_OPTIONALBOX,\r
- WDG_TOOLBOX_BOX, WDG_SWITCH_CASE, NULL))\r
- return false;\r
-\r
- //it should not be a "source" or a "validator" node\r
- bool isLogical = isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NODE_SELFILTER, NULL);\r
- // here must be only widgets not connected to attributes\r
- bool isPagedContainer = isNode(theNode, WDG_TOOLBOX_BOX,\r
- WDG_GROUP,\r
- WDG_SWITCH_CASE, NULL);\r
- return !isLogical && !isPagedContainer;\r
-}\r
-\r
-bool isWidgetNode(xmlNodePtr theNode)\r
-{\r
- if(!isElementNode(theNode))\r
- return false;\r
- // it's parent is "feature" or "source" or a page ("box", "case")\r
- if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE, WDG_GROUP, WDG_OPTIONALBOX,\r
- WDG_TOOLBOX_BOX, WDG_SWITCH_CASE, NULL))\r
- return false;\r
-\r
- //it should not be a "source" or a "validator" node\r
- return !isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NODE_SELFILTER, NULL);\r
-}\r
-\r
-// widget api?\r
-bool isCaseNode(xmlNodePtr theNode)\r
-{\r
- if(!isElementNode(theNode))\r
- return false;\r
-\r
- return isNode(theNode, WDG_OPTIONALBOX, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL);\r
-}\r
-\r
-bool hasChild(xmlNodePtr theNode)\r
-{\r
- xmlNodePtr aNode = theNode->children;\r
- for (; aNode; aNode = aNode->next) {\r
- if (isElementNode(theNode)) {\r
- return true;\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-bool hasParent(xmlNodePtr theNode)\r
-{\r
- xmlNodePtr aNode = theNode->parent;\r
- if (!aNode) {\r
- return false;\r
- }\r
- for (; aNode; aNode = aNode->next) {\r
- if (isElementNode(theNode)) {\r
- return true;\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...)\r
-{\r
- if (!hasParent(theNode)) {\r
- return false; // have no parents at all\r
- }\r
- xmlNodePtr aNode = theNode->parent;\r
- const xmlChar* aName = aNode->name;\r
- if (!aName || !isElementNode(aNode)) {\r
- return false;\r
- }\r
- if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {\r
- return true;\r
- }\r
- va_list args; // define argument list variable\r
- va_start(args, theNodeName); // init list; point to last defined argument\r
- while (true) {\r
- char *anArg = va_arg (args, char*); // get next argument\r
- if (anArg == NULL)\r
- break;\r
- if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {\r
- va_end(args); // cleanup the system stack\r
- return true;\r
- }\r
- }\r
- va_end(args); // cleanup the system stack\r
- return false;\r
-}\r
-\r
-xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const std::vector<const char*>& theNodeNames)\r
-{\r
- if (!hasParent(theNode)) {\r
- return 0; // have no parents at all\r
- }\r
- xmlNodePtr aNode = theNode->parent;\r
- const xmlChar* aName = aNode->name;\r
- if (!aName || !isElementNode(aNode)) {\r
- return 0;\r
- }\r
- for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) {\r
- if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex]))\r
- return aNode;\r
- }\r
- return hasParentRecursive(aNode, theNodeNames);\r
-}\r
-\r
-xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...)\r
-{\r
- std::vector<const char*> aNodeNames;\r
- va_list args; // define argument list variable\r
- va_start(args, theNodeName); // init list; point to last defined argument\r
- aNodeNames.push_back(theNodeName);\r
- while (true) {\r
- char *anArg = va_arg (args, char*); // get next argument\r
- if (anArg == NULL)\r
- break;\r
- aNodeNames.push_back(anArg);\r
- }\r
- va_end(args); // cleanup the system stack\r
- return hasParentRecursive(theNode, aNodeNames);\r
-}\r
-\r
-bool getParametersInfo(xmlNodePtr theNode, std::string& outPropertyId,\r
- std::list<std::string>& outValidatorParameters)\r
-{\r
- //Property id:\r
- char* anIdProp = (char*) xmlGetProp(theNode, BAD_CAST _ID);\r
- if (!anIdProp || anIdProp[0] == 0) {\r
- return false;\r
- }\r
- outPropertyId = std::string(anIdProp);\r
-\r
- //Property parameters:\r
- char* aParamProp = (char*) xmlGetProp(theNode, BAD_CAST _PARAMETERS);\r
- if (aParamProp && aParamProp[0] != 0) {\r
- std::string aPropString = std::string(aParamProp);\r
- std::stringstream aPropStringStream(aPropString);\r
- char COMMA_DELIM = ',';\r
- std::string aParameter;\r
- while (std::getline(aPropStringStream, aParameter, ',')) {\r
- outValidatorParameters.push_back(aParameter);\r
- }\r
- }\r
- return true;\r
-}\r
-\r
-std::string library(const std::string& theLibName)\r
-{\r
- if(theLibName.empty())\r
- return std::string();\r
- std::string aLibName = theLibName;\r
-#ifndef WIN32\r
- static std::string aLibExt( ".so" );\r
- if (aLibName.size() < 3 || aLibName.substr(0, 3) !="lib") {\r
- aLibName = "lib" + aLibName;\r
- }\r
-#else\r
- static std::string aLibExt(".dll");\r
-#endif\r
- std::string anExt = aLibName.substr(aLibName.size() - 4);\r
- if (anExt != aLibExt)\r
- aLibName += aLibExt;\r
-\r
- return aLibName;\r
-}\r
-\r
-bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }\r
-\r
-std::string getProperty(xmlNodePtr theNode, const char* thePropName)\r
-{\r
- std::string result = "";\r
- xmlChar* aPropChars = xmlGetProp(theNode, BAD_CAST thePropName);\r
- if (!aPropChars || aPropChars[0] == 0)\r
- return result;\r
- result = std::string((char*)aPropChars);\r
- xmlFree(aPropChars);\r
-\r
- std::string::iterator new_end = std::unique(result.begin(), result.end(), BothAreSpaces);\r
- result.erase(new_end, result.end()); \r
-\r
- return result;\r
-}\r
-\r
-std::string getContent(xmlNodePtr theNode)\r
-{\r
- std::string result = "";\r
- xmlChar* aContent = xmlNodeGetContent(theNode);\r
- if (!aContent || aContent[0] == 0)\r
- return result;\r
- result = std::string((char*)aContent);\r
- xmlFree(aContent);\r
- return result;\r
-}\r
-\r
-std::string getNormalizedProperty(xmlNodePtr theNode, const char* thePropName)\r
-{\r
- return normalize(getProperty(theNode, thePropName));\r
-}\r
-\r
-bool getBooleanAttribute(xmlNodePtr theNode, const char* theAttributeName, bool theDefault)\r
-{\r
- std::string prop = normalize(getProperty(theNode, theAttributeName));\r
- bool result = theDefault;\r
- if (prop == "true" || prop == "1") {\r
- result = true;\r
- } else if (prop == "false" || prop == "0") {\r
- result = false;\r
- }\r
- return result;\r
-}\r
-\r
-CONFIG_EXPORT std::string normalize(const char* theString)\r
-{\r
- if (!theString)\r
- return std::string();\r
- return normalize(std::string(theString));\r
-}\r
-\r
-CONFIG_EXPORT std::string normalize(const std::string& theString)\r
-{\r
- std::string result = theString;\r
- std::transform(result.begin(), result.end(), result.begin(), ::tolower);\r
- return result;\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * Config_Common.cpp
+ *
+ * Created on: Apr 17, 2014
+ * Author: sbh
+ */
+
+#include "Config_Common.h"
+#include <Config_Keywords.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <sstream> // for stringstream
+
+#include <string>
+#include <algorithm> // for std::transform
+#include <vector>
+
+bool isElementNode(xmlNodePtr theNode)
+{
+ if (!theNode)
+ return false;
+ return theNode->type == XML_ELEMENT_NODE;
+}
+
+bool isNode(xmlNodePtr theNode, const char* theNodeName, ...)
+{
+ const xmlChar* aName = theNode->name;
+ if (!aName || !isElementNode(theNode)) {
+ return false;
+ }
+ if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
+ return true;
+ }
+ va_list args; // define argument list variable
+ va_start(args, theNodeName); // init list; point to last defined argument
+ while (true) {
+ char *anArg = va_arg (args, char*); // get next argument
+ if (anArg == NULL)
+ break;
+ if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
+ va_end(args); // cleanup the system stack
+ return true;
+ }
+ }
+ va_end(args); // cleanup the system stack
+ return false;
+}
+
+bool isAttributeNode(xmlNodePtr theNode)
+{
+ if(!isElementNode(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_OPTIONALBOX,
+ 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);
+ // here must be only widgets not connected to attributes
+ bool isPagedContainer = isNode(theNode, WDG_TOOLBOX_BOX,
+ WDG_GROUP,
+ WDG_SWITCH_CASE, NULL);
+ return !isLogical && !isPagedContainer;
+}
+
+bool isWidgetNode(xmlNodePtr theNode)
+{
+ if(!isElementNode(theNode))
+ return false;
+ // it's parent is "feature" or "source" or a page ("box", "case")
+ if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE, WDG_GROUP, WDG_OPTIONALBOX,
+ WDG_TOOLBOX_BOX, WDG_SWITCH_CASE, NULL))
+ return false;
+
+ //it should not be a "source" or a "validator" node
+ return !isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NODE_SELFILTER, NULL);
+}
+
+// widget api?
+bool isCaseNode(xmlNodePtr theNode)
+{
+ if(!isElementNode(theNode))
+ return false;
+
+ return isNode(theNode, WDG_OPTIONALBOX, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL);
+}
+
+bool hasChild(xmlNodePtr theNode)
+{
+ xmlNodePtr aNode = theNode->children;
+ for (; aNode; aNode = aNode->next) {
+ if (isElementNode(theNode)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool hasParent(xmlNodePtr theNode)
+{
+ xmlNodePtr aNode = theNode->parent;
+ if (!aNode) {
+ return false;
+ }
+ for (; aNode; aNode = aNode->next) {
+ if (isElementNode(theNode)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...)
+{
+ 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;
+ }
+ if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
+ return true;
+ }
+ va_list args; // define argument list variable
+ va_start(args, theNodeName); // init list; point to last defined argument
+ while (true) {
+ char *anArg = va_arg (args, char*); // get next argument
+ if (anArg == NULL)
+ break;
+ if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
+ va_end(args); // cleanup the system stack
+ return true;
+ }
+ }
+ va_end(args); // cleanup the system stack
+ return false;
+}
+
+xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const std::vector<const char*>& theNodeNames)
+{
+ if (!hasParent(theNode)) {
+ return 0; // have no parents at all
+ }
+ xmlNodePtr aNode = theNode->parent;
+ const xmlChar* aName = aNode->name;
+ if (!aName || !isElementNode(aNode)) {
+ return 0;
+ }
+ for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) {
+ if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex]))
+ return aNode;
+ }
+ return hasParentRecursive(aNode, theNodeNames);
+}
+
+xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...)
+{
+ std::vector<const char*> 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<std::string>& outValidatorParameters)
+{
+ //Property id:
+ char* anIdProp = (char*) xmlGetProp(theNode, BAD_CAST _ID);
+ if (!anIdProp || anIdProp[0] == 0) {
+ return false;
+ }
+ outPropertyId = std::string(anIdProp);
+
+ //Property parameters:
+ char* aParamProp = (char*) xmlGetProp(theNode, BAD_CAST _PARAMETERS);
+ if (aParamProp && aParamProp[0] != 0) {
+ std::string aPropString = std::string(aParamProp);
+ std::stringstream aPropStringStream(aPropString);
+ char COMMA_DELIM = ',';
+ std::string aParameter;
+ while (std::getline(aPropStringStream, aParameter, ',')) {
+ outValidatorParameters.push_back(aParameter);
+ }
+ }
+ return true;
+}
+
+std::string library(const std::string& theLibName)
+{
+ if(theLibName.empty())
+ return std::string();
+ std::string aLibName = theLibName;
+#ifndef WIN32
+ static std::string aLibExt( ".so" );
+ if (aLibName.size() < 3 || aLibName.substr(0, 3) !="lib") {
+ aLibName = "lib" + aLibName;
+ }
+#else
+ static std::string aLibExt(".dll");
+#endif
+ std::string anExt = aLibName.substr(aLibName.size() - 4);
+ if (anExt != aLibExt)
+ aLibName += aLibExt;
+
+ return aLibName;
+}
+
+bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
+
+std::string getProperty(xmlNodePtr theNode, const char* thePropName)
+{
+ std::string result = "";
+ xmlChar* aPropChars = xmlGetProp(theNode, BAD_CAST thePropName);
+ if (!aPropChars || aPropChars[0] == 0)
+ return result;
+ result = std::string((char*)aPropChars);
+ xmlFree(aPropChars);
+
+ std::string::iterator new_end = std::unique(result.begin(), result.end(), BothAreSpaces);
+ result.erase(new_end, result.end());
+
+ return result;
+}
+
+std::string getContent(xmlNodePtr theNode)
+{
+ std::string result = "";
+ xmlChar* aContent = xmlNodeGetContent(theNode);
+ if (!aContent || aContent[0] == 0)
+ return result;
+ result = std::string((char*)aContent);
+ xmlFree(aContent);
+ return result;
+}
+
+std::string getNormalizedProperty(xmlNodePtr theNode, const char* thePropName)
+{
+ return normalize(getProperty(theNode, thePropName));
+}
+
+bool getBooleanAttribute(xmlNodePtr theNode, const char* theAttributeName, bool theDefault)
+{
+ std::string prop = normalize(getProperty(theNode, theAttributeName));
+ bool result = theDefault;
+ if (prop == "true" || prop == "1") {
+ result = true;
+ } else if (prop == "false" || prop == "0") {
+ result = false;
+ }
+ return result;
+}
+
+CONFIG_EXPORT std::string normalize(const char* theString)
+{
+ if (!theString)
+ return std::string();
+ return normalize(std::string(theString));
+}
+
+CONFIG_EXPORT std::string normalize(const std::string& theString)
+{
+ std::string result = theString;
+ std::transform(result.begin(), result.end(), result.begin(), ::tolower);
+ return result;
+}
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-#ifndef CONFIG_MESSAGE_H\r
-#define CONFIG_MESSAGE_H\r
-\r
-#include <Config_def.h>\r
-#include <Events_Message.h>\r
-\r
-#include <string>\r
-\r
-/*!\r
- * \class Config_FeatureMessage\r
- * \ingroup Config\r
- * \brief Class to pass a feature entry extracted from xml file.\r
- * Example of the feature entry:\r
- * \code\r
- * <feature id="Part" text="New part" tooltip="Creates a new part" icon=":pictures/part_ico.png"/>\r
- * \endcode\r
- */\r
-class Config_FeatureMessage : public Events_Message\r
-{\r
- std::string myId; ///<Feature unique id\r
- std::string myText; ///<Represents action's text\r
- std::string myTooltip; ///<Represents action's tooltip\r
- std::string myIcon; ///<Represents action's icon\r
- std::string myKeysequence; ///<Represents action's key sequence\r
-\r
- std::string myGroupId; ///<Id of feature's group\r
- std::string myWorkbenchId; ///<Id of feature's workbench\r
- std::string myDocumentKind; ///< kind of the document of the workbench (all documents if empty)\r
- std::string myPluginLibrary; ///<Name of feature's library\r
-\r
- bool myUseInput; ///<Action is being checked until user commit the operation\r
- bool myInternal; ///<Internal feature without GUI representation\r
- bool myModal; ///<True if the feature has to be represented by modal dialog box\r
- bool myIsAutoPreview; ///< Preview computation is performed automatically\r
-\r
- std::string myNestedFeatures; ///<Space separated list of child features\r
- std::string myActionsWhenNested; ///<Space separated list of actions\r
-\r
- public:\r
- /// Event ID that feature is loaded in workbench (GUI)\r
- inline static const char* GUI_EVENT()\r
- {\r
- static const char * MY_GUI_EVENT_ID("WorkshopFeatureLoaded");\r
- return MY_GUI_EVENT_ID;\r
- }\r
- /// Event ID that feature is loaded in workbench (Model)\r
- inline static const char* MODEL_EVENT()\r
- {\r
- static const char * MY_MODEL_EVENT_ID("ModelFeatureLoaded");\r
- return MY_MODEL_EVENT_ID;\r
- }\r
-\r
- /// Constructs Config_FeatureMessage\r
- CONFIG_EXPORT Config_FeatureMessage(const Events_ID theId, const void* theParent = 0);\r
- /// Deletes Config_FeatureMessage\r
- CONFIG_EXPORT virtual ~Config_FeatureMessage();\r
-\r
- //Auto-generated getters/setters\r
- /// Feature's Id\r
- CONFIG_EXPORT const std::string& id() const;\r
- /// Feature's Icon\r
- CONFIG_EXPORT const std::string& icon() const;\r
- /// Feature's shortcut\r
- CONFIG_EXPORT const std::string& keysequence() const;\r
- /// Feature's text\r
- CONFIG_EXPORT const std::string& text() const;\r
- /// Feature's tooltip\r
- CONFIG_EXPORT const std::string& tooltip() const;\r
- /// Id of Feature's Group\r
- CONFIG_EXPORT const std::string& groupId() const;\r
- /// Id of Feature's Workbench\r
- CONFIG_EXPORT const std::string& workbenchId() const;\r
- /// Kind of a document which contains the feature\r
- CONFIG_EXPORT const std::string& documentKind() const;\r
- /// Name of a library which contains the feature\r
- CONFIG_EXPORT const std::string& pluginLibrary() const;\r
- /// Space separated list of nested features\r
- CONFIG_EXPORT const std::string& nestedFeatures() const;\r
- /// Space separated list of actions\r
- CONFIG_EXPORT const std::string& actionsWhenNested() const;\r
- /// If false - feature has no Property panel representation\r
- CONFIG_EXPORT bool isUseInput() const;\r
- /// If true - feature will not be added into the workbench\r
- CONFIG_EXPORT bool isInternal() const;\r
- /// If true - the feature will be represented by modal dialog box GUI\r
- CONFIG_EXPORT bool isModal() const;\r
-\r
- /// If true - preview of the feature is done by any modification of the feature attributes\r
- CONFIG_EXPORT bool isAutoPreview() const;\r
-\r
- ///Set feature's Id\r
- CONFIG_EXPORT void setId(const std::string& id);\r
- ///Set feature's Icon\r
- CONFIG_EXPORT void setIcon(const std::string& icon);\r
- ///Set feature's shortcut\r
- CONFIG_EXPORT void setKeysequence(const std::string& keysequence);\r
- ///Set feature's text\r
- CONFIG_EXPORT void setText(const std::string& text);\r
- ///Set feature's tooltip\r
- CONFIG_EXPORT void setTooltip(const std::string& tooltip);\r
- ///Set id of Feature's Group\r
- CONFIG_EXPORT void setGroupId(const std::string& groupId);\r
- ///Set id of Feature's Workbench\r
- CONFIG_EXPORT void setWorkbenchId(const std::string& workbenchId);\r
- ///Set kind of a document which contains the feature\r
- CONFIG_EXPORT void setDocumentKind(const std::string& documentKind);\r
- ///Set name of a library which contains the feature\r
- CONFIG_EXPORT void setPluginLibrary(const std::string& thePluginLibrary);\r
- ///Set space separated list of nested features\r
- CONFIG_EXPORT void setNestedFeatures(const std::string& theNestedFeatures);\r
- ///Set space separated list of nested features\r
- CONFIG_EXPORT void setActionsWhenNested(const std::string& theActions);\r
- ///Set use input state; If false - feature has no Property panel representation\r
- CONFIG_EXPORT void setUseInput(bool isUseInput);\r
- ///Set internal state; If true - feature will not be added into the workbench\r
- CONFIG_EXPORT void setInternal(bool isInternal);\r
- ///Set auto preview state; If true - preview of the feature is computed automatically\r
- CONFIG_EXPORT void setAutoPreview(bool isAutoPreview);\r
- ///Set modality state; If true - the feature will be represented by modal dialog box GUI\r
- CONFIG_EXPORT void setModal(bool isModal);\r
-};\r
-\r
-#endif // CONFIG_MESSAGE_H\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#ifndef CONFIG_MESSAGE_H
+#define CONFIG_MESSAGE_H
+
+#include <Config_def.h>
+#include <Events_Message.h>
+
+#include <string>
+
+/*!
+ * \class Config_FeatureMessage
+ * \ingroup Config
+ * \brief Class to pass a feature entry extracted from xml file.
+ * Example of the feature entry:
+ * \code
+ * <feature id="Part" text="New part" tooltip="Creates a new part" icon=":pictures/part_ico.png"/>
+ * \endcode
+ */
+class Config_FeatureMessage : public Events_Message
+{
+ std::string myId; ///<Feature unique id
+ std::string myText; ///<Represents action's text
+ std::string myTooltip; ///<Represents action's tooltip
+ std::string myIcon; ///<Represents action's icon
+ std::string myKeysequence; ///<Represents action's key sequence
+
+ std::string myGroupId; ///<Id of feature's group
+ std::string myWorkbenchId; ///<Id of feature's workbench
+ std::string myDocumentKind; ///< kind of the document of the workbench (all documents if empty)
+ std::string myPluginLibrary; ///<Name of feature's library
+
+ bool myUseInput; ///<Action is being checked until user commit the operation
+ bool myInternal; ///<Internal feature without GUI representation
+ bool myModal; ///<True if the feature has to be represented by modal dialog box
+ bool myIsAutoPreview; ///< Preview computation is performed automatically
+
+ std::string myNestedFeatures; ///<Space separated list of child features
+ std::string myActionsWhenNested; ///<Space separated list of actions
+
+ public:
+ /// Event ID that feature is loaded in workbench (GUI)
+ inline static const char* GUI_EVENT()
+ {
+ static const char * MY_GUI_EVENT_ID("WorkshopFeatureLoaded");
+ return MY_GUI_EVENT_ID;
+ }
+ /// Event ID that feature is loaded in workbench (Model)
+ inline static const char* MODEL_EVENT()
+ {
+ static const char * MY_MODEL_EVENT_ID("ModelFeatureLoaded");
+ return MY_MODEL_EVENT_ID;
+ }
+
+ /// Constructs Config_FeatureMessage
+ CONFIG_EXPORT Config_FeatureMessage(const Events_ID theId, const void* theParent = 0);
+ /// Deletes Config_FeatureMessage
+ CONFIG_EXPORT virtual ~Config_FeatureMessage();
+
+ //Auto-generated getters/setters
+ /// Feature's Id
+ CONFIG_EXPORT const std::string& id() const;
+ /// Feature's Icon
+ CONFIG_EXPORT const std::string& icon() const;
+ /// Feature's shortcut
+ CONFIG_EXPORT const std::string& keysequence() const;
+ /// Feature's text
+ CONFIG_EXPORT const std::string& text() const;
+ /// Feature's tooltip
+ CONFIG_EXPORT const std::string& tooltip() const;
+ /// Id of Feature's Group
+ CONFIG_EXPORT const std::string& groupId() const;
+ /// Id of Feature's Workbench
+ CONFIG_EXPORT const std::string& workbenchId() const;
+ /// Kind of a document which contains the feature
+ CONFIG_EXPORT const std::string& documentKind() const;
+ /// Name of a library which contains the feature
+ CONFIG_EXPORT const std::string& pluginLibrary() const;
+ /// Space separated list of nested features
+ CONFIG_EXPORT const std::string& nestedFeatures() const;
+ /// Space separated list of actions
+ CONFIG_EXPORT const std::string& actionsWhenNested() const;
+ /// If false - feature has no Property panel representation
+ CONFIG_EXPORT bool isUseInput() const;
+ /// If true - feature will not be added into the workbench
+ CONFIG_EXPORT bool isInternal() const;
+ /// If true - the feature will be represented by modal dialog box GUI
+ CONFIG_EXPORT bool isModal() const;
+
+ /// If true - preview of the feature is done by any modification of the feature attributes
+ CONFIG_EXPORT bool isAutoPreview() const;
+
+ ///Set feature's Id
+ CONFIG_EXPORT void setId(const std::string& id);
+ ///Set feature's Icon
+ CONFIG_EXPORT void setIcon(const std::string& icon);
+ ///Set feature's shortcut
+ CONFIG_EXPORT void setKeysequence(const std::string& keysequence);
+ ///Set feature's text
+ CONFIG_EXPORT void setText(const std::string& text);
+ ///Set feature's tooltip
+ CONFIG_EXPORT void setTooltip(const std::string& tooltip);
+ ///Set id of Feature's Group
+ CONFIG_EXPORT void setGroupId(const std::string& groupId);
+ ///Set id of Feature's Workbench
+ CONFIG_EXPORT void setWorkbenchId(const std::string& workbenchId);
+ ///Set kind of a document which contains the feature
+ CONFIG_EXPORT void setDocumentKind(const std::string& documentKind);
+ ///Set name of a library which contains the feature
+ CONFIG_EXPORT void setPluginLibrary(const std::string& thePluginLibrary);
+ ///Set space separated list of nested features
+ CONFIG_EXPORT void setNestedFeatures(const std::string& theNestedFeatures);
+ ///Set space separated list of nested features
+ CONFIG_EXPORT void setActionsWhenNested(const std::string& theActions);
+ ///Set use input state; If false - feature has no Property panel representation
+ CONFIG_EXPORT void setUseInput(bool isUseInput);
+ ///Set internal state; If true - feature will not be added into the workbench
+ CONFIG_EXPORT void setInternal(bool isInternal);
+ ///Set auto preview state; If true - preview of the feature is computed automatically
+ CONFIG_EXPORT void setAutoPreview(bool isAutoPreview);
+ ///Set modality state; If true - the feature will be represented by modal dialog box GUI
+ CONFIG_EXPORT void setModal(bool isModal);
+};
+
+#endif // CONFIG_MESSAGE_H
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-/*\r
- * Config_Keywords.h\r
- *\r
- * Created on: Apr 2, 2014\r
- * Author: sbh\r
- */\r
-\r
-#ifndef CONFIG_KEYWORDS_H_\r
-#define CONFIG_KEYWORDS_H_\r
-\r
-/*\r
- * Hardcoded xml entities of plugin-*.xml\r
- */\r
-const static char* NODE_WORKBENCH = "workbench";\r
-const static char* NODE_GROUP = "group";\r
-const static char* NODE_FEATURE = "feature";\r
-const static char* NODE_SOURCE = "source";\r
-const static char* NODE_VALIDATOR = "validator";\r
-const static char* NODE_SELFILTER = "selection_filter";\r
-const static char* NODE_XMLPARENT = "libxml_parent";\r
-\r
-// Property panels\r
-const static char* PROPERTY_PANEL_ID = "property_panel_id";\r
-\r
-// Widgets\r
-const static char* WDG_INFO = "label";\r
-const static char* WDG_DOUBLEVALUE = "doublevalue";\r
-const static char* WDG_INTEGERVALUE = "integervalue";\r
-const static char* WDG_BOOLVALUE = "boolvalue";\r
-const static char* WDG_STRINGVALUE = "stringvalue";\r
-const static char* WDG_MULTISELECTOR = "multi_selector";\r
-const static char* WDG_SHAPE_SELECTOR = "shape_selector";\r
-const static char* WDG_FEATURE_SELECTOR = "feature_selector";\r
-const static char* WDG_CONCEALED_OBJECTS_VIEW = "concealed_objects_view";\r
-const static char* WDG_CHOICE = "choice";\r
-const static char* WDG_DOUBLEVALUE_EDITOR = "doublevalue_editor";\r
-const static char* WDG_FILE_SELECTOR= "file_selector";\r
-const static char* WDG_EXPR_EDITOR = "expr_editor";\r
-const static char* WDG_PLACE_HOLDER = "placeholder";\r
-const static char* WDG_ACTION = "action";\r
-\r
-// Containers\r
-const static char* WDG_GROUP = "groupbox";\r
-const static char* WDG_OPTIONALBOX = "optionalbox";\r
-const static char* WDG_TOOLBOX = "toolbox";\r
-const static char* WDG_TOOLBOX_BOX = "box";\r
-const static char* WDG_SWITCH = "switch";\r
-const static char* WDG_SWITCH_CASE = "case";\r
-// Common properties (xml attributes of nodes)\r
-const static char* _ID = "id";\r
-// NODE_WORKBENCH properties\r
-const static char* WORKBENCH_DOC = "document";\r
-// NODE_SOURCE properties\r
-const static char* SOURCE_FILE = "path";\r
-// NODE_FEATURE properties\r
-const static char* FEATURE_TOOLTIP = "tooltip";\r
-const static char* FEATURE_ICON = "icon";\r
-const static char* FEATURE_TEXT = "title";\r
-const static char* FEATURE_KEYSEQUENCE = "keysequence";\r
-const static char* FEATURE_NESTED = "nested";\r
-const static char* FEATURE_WHEN_NESTED = "when_nested";\r
-const static char* FEATURE_WHEN_NESTED_ACCEPT = "accept";\r
-const static char* FEATURE_WHEN_NESTED_ABORT = "abort";\r
-const static char* FEATURE_DOC = WORKBENCH_DOC;\r
-const static char* FEATURE_MODAL = "modal";\r
-const static char* FEATURE_AUTO_PREVIEW = "auto_preview";\r
-// NODE_VALIDATOR properties, NODE_SELFILTER properties\r
-const static char* _PARAMETERS = "parameters";\r
-\r
-// Widget (attribute) properties\r
-const static char* ATTR_TOOLTIP = FEATURE_TOOLTIP;\r
-const static char* ATTR_ICON = FEATURE_ICON;\r
-const static char* ATTR_LABEL = "label";\r
-const static char* ATTR_STYLE_SHEET = "styleSheet";\r
-const static char* ATTR_DEFAULT = "default";\r
-const static char* ATTR_INTERNAL = "internal";\r
-const static char* ATTR_OBLIGATORY = "obligatory";\r
-const static char* ATTR_CONCEALMENT = "concealment";\r
-const static char* ATTR_USE_RESET = "use_reset";\r
-const static char* ATTR_GREED = "greed";\r
-\r
-// WDG_INFO properties\r
-const static char* INFO_WDG_TEXT = FEATURE_TEXT;\r
-const static char* INFO_WDG_TOOLTIP = FEATURE_TOOLTIP;\r
-// WDG_DOUBLEVALUE properties:\r
-const static char* DOUBLE_WDG_MIN = "min";\r
-const static char* DOUBLE_WDG_MAX = "max";\r
-const static char* DOUBLE_WDG_STEP = "step";\r
-const static char* DOUBLE_WDG_DEFAULT_COMPUTED = "computed";\r
-const static char* DOUBLE_WDG_ACCEPT_EXPRESSIONS = "accept_expressions";\r
-const static char* DOUBLE_WDG_ENABLE_VALUE = "enable_value";\r
-\r
-const static char* DOUBLE_WDG_ENABLE_VALUE_BY_PREFERENCES = "enable_by_preferences";\r
-\r
-// WDG_TOOLBOX/WDG_SWITCH properties\r
-const static char* CONTAINER_PAGE_NAME = "title";\r
-const static char* CONTAINER_PAGE_ICON = "icon";\r
-\r
-/*\r
- * Hardcoded xml entities of plugins.xml\r
- */\r
-\r
-const static char* PLUGIN_FILE = "plugins.xml";\r
-const static char* NODE_PLUGIN = "plugin";\r
-const static char* NODE_PLUGINS = "plugins";\r
-\r
-const static char* PLUGINS_MODULE = "module";\r
-const static char* PLUGIN_CONFIG = "configuration";\r
-const static char* PLUGIN_LIBRARY = "library";\r
-const static char* PLUGIN_SCRIPT = "script";\r
-const static char* PLUGIN_DEPENDENCY = "dependency";\r
-\r
-/*\r
- * Hardcoded xml entities of dataModel.xml\r
- */\r
-const static char* DATAMODEL_FILE = "dataModel.xml";\r
-const static char* NODE_FOLDER = "folder";\r
-const static char* FOLDER_NAME = "name";\r
-const static char* GROUP_TYPE = "group_type";\r
-const static char* ROOT_DOCUMENT = "root_document";\r
-const static char* SUB_DOCUMENT = "sub_document";\r
-const static char* NODE_ICON = "icon";\r
-const static char* SHOW_EMPTY = "show_empty";\r
-const static char* LINK_ITEM = "from_result";\r
-const static char* FOLDER_FEATURES = "folder_features";\r
-\r
-#endif /* CONFIG_KEYWORDS_H_ */\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * Config_Keywords.h
+ *
+ * Created on: Apr 2, 2014
+ * Author: sbh
+ */
+
+#ifndef CONFIG_KEYWORDS_H_
+#define CONFIG_KEYWORDS_H_
+
+/*
+ * Hardcoded xml entities of plugin-*.xml
+ */
+const static char* NODE_WORKBENCH = "workbench";
+const static char* NODE_GROUP = "group";
+const static char* NODE_FEATURE = "feature";
+const static char* NODE_SOURCE = "source";
+const static char* NODE_VALIDATOR = "validator";
+const static char* NODE_SELFILTER = "selection_filter";
+const static char* NODE_XMLPARENT = "libxml_parent";
+
+// Property panels
+const static char* PROPERTY_PANEL_ID = "property_panel_id";
+
+// Widgets
+const static char* WDG_INFO = "label";
+const static char* WDG_DOUBLEVALUE = "doublevalue";
+const static char* WDG_INTEGERVALUE = "integervalue";
+const static char* WDG_BOOLVALUE = "boolvalue";
+const static char* WDG_STRINGVALUE = "stringvalue";
+const static char* WDG_MULTISELECTOR = "multi_selector";
+const static char* WDG_SHAPE_SELECTOR = "shape_selector";
+const static char* WDG_FEATURE_SELECTOR = "feature_selector";
+const static char* WDG_CONCEALED_OBJECTS_VIEW = "concealed_objects_view";
+const static char* WDG_CHOICE = "choice";
+const static char* WDG_DOUBLEVALUE_EDITOR = "doublevalue_editor";
+const static char* WDG_FILE_SELECTOR= "file_selector";
+const static char* WDG_EXPR_EDITOR = "expr_editor";
+const static char* WDG_PLACE_HOLDER = "placeholder";
+const static char* WDG_ACTION = "action";
+
+// Containers
+const static char* WDG_GROUP = "groupbox";
+const static char* WDG_OPTIONALBOX = "optionalbox";
+const static char* WDG_TOOLBOX = "toolbox";
+const static char* WDG_TOOLBOX_BOX = "box";
+const static char* WDG_SWITCH = "switch";
+const static char* WDG_SWITCH_CASE = "case";
+// Common properties (xml attributes of nodes)
+const static char* _ID = "id";
+// NODE_WORKBENCH properties
+const static char* WORKBENCH_DOC = "document";
+// NODE_SOURCE properties
+const static char* SOURCE_FILE = "path";
+// NODE_FEATURE properties
+const static char* FEATURE_TOOLTIP = "tooltip";
+const static char* FEATURE_ICON = "icon";
+const static char* FEATURE_TEXT = "title";
+const static char* FEATURE_KEYSEQUENCE = "keysequence";
+const static char* FEATURE_NESTED = "nested";
+const static char* FEATURE_WHEN_NESTED = "when_nested";
+const static char* FEATURE_WHEN_NESTED_ACCEPT = "accept";
+const static char* FEATURE_WHEN_NESTED_ABORT = "abort";
+const static char* FEATURE_DOC = WORKBENCH_DOC;
+const static char* FEATURE_MODAL = "modal";
+const static char* FEATURE_AUTO_PREVIEW = "auto_preview";
+// NODE_VALIDATOR properties, NODE_SELFILTER properties
+const static char* _PARAMETERS = "parameters";
+
+// Widget (attribute) properties
+const static char* ATTR_TOOLTIP = FEATURE_TOOLTIP;
+const static char* ATTR_ICON = FEATURE_ICON;
+const static char* ATTR_LABEL = "label";
+const static char* ATTR_STYLE_SHEET = "styleSheet";
+const static char* ATTR_DEFAULT = "default";
+const static char* ATTR_INTERNAL = "internal";
+const static char* ATTR_OBLIGATORY = "obligatory";
+const static char* ATTR_CONCEALMENT = "concealment";
+const static char* ATTR_USE_RESET = "use_reset";
+const static char* ATTR_GREED = "greed";
+
+// WDG_INFO properties
+const static char* INFO_WDG_TEXT = FEATURE_TEXT;
+const static char* INFO_WDG_TOOLTIP = FEATURE_TOOLTIP;
+// WDG_DOUBLEVALUE properties:
+const static char* DOUBLE_WDG_MIN = "min";
+const static char* DOUBLE_WDG_MAX = "max";
+const static char* DOUBLE_WDG_STEP = "step";
+const static char* DOUBLE_WDG_DEFAULT_COMPUTED = "computed";
+const static char* DOUBLE_WDG_ACCEPT_EXPRESSIONS = "accept_expressions";
+const static char* DOUBLE_WDG_ENABLE_VALUE = "enable_value";
+
+const static char* DOUBLE_WDG_ENABLE_VALUE_BY_PREFERENCES = "enable_by_preferences";
+
+// WDG_TOOLBOX/WDG_SWITCH properties
+const static char* CONTAINER_PAGE_NAME = "title";
+const static char* CONTAINER_PAGE_ICON = "icon";
+
+/*
+ * Hardcoded xml entities of plugins.xml
+ */
+
+const static char* PLUGIN_FILE = "plugins.xml";
+const static char* NODE_PLUGIN = "plugin";
+const static char* NODE_PLUGINS = "plugins";
+
+const static char* PLUGINS_MODULE = "module";
+const static char* PLUGIN_CONFIG = "configuration";
+const static char* PLUGIN_LIBRARY = "library";
+const static char* PLUGIN_SCRIPT = "script";
+const static char* PLUGIN_DEPENDENCY = "dependency";
+
+/*
+ * Hardcoded xml entities of dataModel.xml
+ */
+const static char* DATAMODEL_FILE = "dataModel.xml";
+const static char* NODE_FOLDER = "folder";
+const static char* FOLDER_NAME = "name";
+const static char* GROUP_TYPE = "group_type";
+const static char* ROOT_DOCUMENT = "root_document";
+const static char* SUB_DOCUMENT = "sub_document";
+const static char* NODE_ICON = "icon";
+const static char* SHOW_EMPTY = "show_empty";
+const static char* LINK_ITEM = "from_result";
+const static char* FOLDER_FEATURES = "folder_features";
+
+#endif /* CONFIG_KEYWORDS_H_ */
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-#ifndef CONFIG_H\r
-#define CONFIG_H\r
-\r
-#if defined CONFIG_EXPORTS\r
-#if defined WIN32\r
-#define CONFIG_EXPORT __declspec( dllexport )\r
-#else\r
-#define CONFIG_EXPORT\r
-#endif\r
-#else\r
-#if defined WIN32\r
-#define CONFIG_EXPORT __declspec( dllimport )\r
-#else\r
-#define CONFIG_EXPORT\r
-#endif\r
-#endif\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#if defined CONFIG_EXPORTS
+#if defined WIN32
+#define CONFIG_EXPORT __declspec( dllexport )
+#else
+#define CONFIG_EXPORT
+#endif
+#else
+#if defined WIN32
+#define CONFIG_EXPORT __declspec( dllimport )
+#else
+#define CONFIG_EXPORT
+#endif
+#endif
+
#endif //CONFIG_H\r
\ No newline at end of file
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->\r
-\r
-#include <FeaturesPlugin_Plugin.h>\r
-\r
-#include <FeaturesPlugin_Boolean.h>\r
-#include <FeaturesPlugin_Extrusion.h>\r
-#include <FeaturesPlugin_ExtrusionCut.h>\r
-#include <FeaturesPlugin_ExtrusionFuse.h>\r
-#include <FeaturesPlugin_Group.h>\r
-#include <FeaturesPlugin_Intersection.h>\r
-#include <FeaturesPlugin_Translation.h>\r
-#include <FeaturesPlugin_Partition.h>\r
-#include <FeaturesPlugin_Pipe.h>\r
-#include <FeaturesPlugin_Placement.h>\r
-#include <FeaturesPlugin_Recover.h>\r
-#include <FeaturesPlugin_RemoveSubShapes.h>\r
-#include <FeaturesPlugin_Revolution.h>\r
-#include <FeaturesPlugin_RevolutionCut.h>\r
-#include <FeaturesPlugin_RevolutionFuse.h>\r
-#include <FeaturesPlugin_Rotation.h>\r
-#include <FeaturesPlugin_Union.h>\r
-#include <FeaturesPlugin_ValidatorTransform.h>\r
-#include <FeaturesPlugin_Validators.h>\r
-\r
-#include <ModelAPI_Session.h>\r
-\r
-#include <string>\r
-\r
-#include <memory>\r
-\r
-using namespace std;\r
-\r
-// the only created instance of this plugin\r
-static FeaturesPlugin_Plugin* MY_FEATURES_INSTANCE = new FeaturesPlugin_Plugin();\r
-\r
-FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()\r
-{\r
- SessionPtr aMgr = ModelAPI_Session::get();\r
- ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorTransform",\r
- new FeaturesPlugin_ValidatorTransform);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorCompositeLauncher",\r
- new FeaturesPlugin_ValidatorCompositeLauncher);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorBaseForGeneration",\r
- new FeaturesPlugin_ValidatorBaseForGeneration);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorPipeLocations",\r
- new FeaturesPlugin_ValidatorPipeLocations);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionDir",\r
- new FeaturesPlugin_ValidatorExtrusionDir);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanSelection",\r
- new FeaturesPlugin_ValidatorBooleanSelection);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorPartitionSelection",\r
- new FeaturesPlugin_ValidatorPartitionSelection);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorRemoveSubShapesSelection",\r
- new FeaturesPlugin_ValidatorRemoveSubShapesSelection);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorRemoveSubShapesResult",\r
- new FeaturesPlugin_ValidatorRemoveSubShapesResult);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorPipePath",\r
- new FeaturesPlugin_ValidatorPipePath);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorUnionSelection",\r
- new FeaturesPlugin_ValidatorUnionSelection);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorUnionArguments",\r
- new FeaturesPlugin_ValidatorUnionArguments);\r
- aFactory->registerValidator("FeaturesPlugin_ValidatorConcealedResult",\r
- new FeaturesPlugin_ValidatorConcealedResult);\r
-\r
- // register this plugin\r
- ModelAPI_Session::get()->registerPlugin(this);\r
-}\r
-\r
-FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)\r
-{\r
- if (theFeatureID == FeaturesPlugin_Extrusion::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Extrusion);\r
- } else if (theFeatureID == FeaturesPlugin_Revolution::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Revolution);\r
- } else if (theFeatureID == FeaturesPlugin_Rotation::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Rotation);\r
- } else if (theFeatureID == FeaturesPlugin_Translation::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Translation);\r
- } else if (theFeatureID == FeaturesPlugin_Boolean::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Boolean);\r
- } else if (theFeatureID == FeaturesPlugin_Group::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Group);\r
- } else if (theFeatureID == FeaturesPlugin_Intersection::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Intersection);\r
- } else if (theFeatureID == FeaturesPlugin_Partition::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Partition);\r
- } else if (theFeatureID == FeaturesPlugin_Pipe::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Pipe);\r
- } else if (theFeatureID == FeaturesPlugin_Placement::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Placement);\r
- } else if (theFeatureID == FeaturesPlugin_Recover::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Recover);\r
- } else if (theFeatureID == FeaturesPlugin_ExtrusionCut::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_ExtrusionCut);\r
- } else if (theFeatureID == FeaturesPlugin_ExtrusionFuse::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_ExtrusionFuse);\r
- } else if (theFeatureID == FeaturesPlugin_RevolutionCut::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_RevolutionCut);\r
- } else if (theFeatureID == FeaturesPlugin_RevolutionFuse::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_RevolutionFuse);\r
- } else if (theFeatureID == FeaturesPlugin_RemoveSubShapes::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_RemoveSubShapes);\r
- } else if (theFeatureID == FeaturesPlugin_Union::ID()) {\r
- return FeaturePtr(new FeaturesPlugin_Union);\r
- }\r
-\r
- // feature of such kind is not found\r
- return FeaturePtr();\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+#include <FeaturesPlugin_Plugin.h>
+
+#include <FeaturesPlugin_Boolean.h>
+#include <FeaturesPlugin_Extrusion.h>
+#include <FeaturesPlugin_ExtrusionCut.h>
+#include <FeaturesPlugin_ExtrusionFuse.h>
+#include <FeaturesPlugin_Group.h>
+#include <FeaturesPlugin_Intersection.h>
+#include <FeaturesPlugin_Translation.h>
+#include <FeaturesPlugin_Partition.h>
+#include <FeaturesPlugin_Pipe.h>
+#include <FeaturesPlugin_Placement.h>
+#include <FeaturesPlugin_Recover.h>
+#include <FeaturesPlugin_RemoveSubShapes.h>
+#include <FeaturesPlugin_Revolution.h>
+#include <FeaturesPlugin_RevolutionCut.h>
+#include <FeaturesPlugin_RevolutionFuse.h>
+#include <FeaturesPlugin_Rotation.h>
+#include <FeaturesPlugin_Union.h>
+#include <FeaturesPlugin_ValidatorTransform.h>
+#include <FeaturesPlugin_Validators.h>
+
+#include <ModelAPI_Session.h>
+
+#include <string>
+
+#include <memory>
+
+using namespace std;
+
+// the only created instance of this plugin
+static FeaturesPlugin_Plugin* MY_FEATURES_INSTANCE = new FeaturesPlugin_Plugin();
+
+FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
+{
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+ aFactory->registerValidator("FeaturesPlugin_ValidatorTransform",
+ new FeaturesPlugin_ValidatorTransform);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorCompositeLauncher",
+ new FeaturesPlugin_ValidatorCompositeLauncher);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorBaseForGeneration",
+ new FeaturesPlugin_ValidatorBaseForGeneration);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorPipeLocations",
+ new FeaturesPlugin_ValidatorPipeLocations);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionDir",
+ new FeaturesPlugin_ValidatorExtrusionDir);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanSelection",
+ new FeaturesPlugin_ValidatorBooleanSelection);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorPartitionSelection",
+ new FeaturesPlugin_ValidatorPartitionSelection);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorRemoveSubShapesSelection",
+ new FeaturesPlugin_ValidatorRemoveSubShapesSelection);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorRemoveSubShapesResult",
+ new FeaturesPlugin_ValidatorRemoveSubShapesResult);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorPipePath",
+ new FeaturesPlugin_ValidatorPipePath);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorUnionSelection",
+ new FeaturesPlugin_ValidatorUnionSelection);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorUnionArguments",
+ new FeaturesPlugin_ValidatorUnionArguments);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorConcealedResult",
+ new FeaturesPlugin_ValidatorConcealedResult);
+
+ // register this plugin
+ ModelAPI_Session::get()->registerPlugin(this);
+}
+
+FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
+{
+ if (theFeatureID == FeaturesPlugin_Extrusion::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Extrusion);
+ } else if (theFeatureID == FeaturesPlugin_Revolution::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Revolution);
+ } else if (theFeatureID == FeaturesPlugin_Rotation::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Rotation);
+ } else if (theFeatureID == FeaturesPlugin_Translation::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Translation);
+ } else if (theFeatureID == FeaturesPlugin_Boolean::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Boolean);
+ } else if (theFeatureID == FeaturesPlugin_Group::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Group);
+ } else if (theFeatureID == FeaturesPlugin_Intersection::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Intersection);
+ } else if (theFeatureID == FeaturesPlugin_Partition::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Partition);
+ } else if (theFeatureID == FeaturesPlugin_Pipe::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Pipe);
+ } else if (theFeatureID == FeaturesPlugin_Placement::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Placement);
+ } else if (theFeatureID == FeaturesPlugin_Recover::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Recover);
+ } else if (theFeatureID == FeaturesPlugin_ExtrusionCut::ID()) {
+ return FeaturePtr(new FeaturesPlugin_ExtrusionCut);
+ } else if (theFeatureID == FeaturesPlugin_ExtrusionFuse::ID()) {
+ return FeaturePtr(new FeaturesPlugin_ExtrusionFuse);
+ } else if (theFeatureID == FeaturesPlugin_RevolutionCut::ID()) {
+ return FeaturePtr(new FeaturesPlugin_RevolutionCut);
+ } else if (theFeatureID == FeaturesPlugin_RevolutionFuse::ID()) {
+ return FeaturePtr(new FeaturesPlugin_RevolutionFuse);
+ } else if (theFeatureID == FeaturesPlugin_RemoveSubShapes::ID()) {
+ return FeaturePtr(new FeaturesPlugin_RemoveSubShapes);
+ } else if (theFeatureID == FeaturesPlugin_Union::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Union);
+ }
+
+ // feature of such kind is not found
+ return FeaturePtr();
+}
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->\r
-\r
-// File: FeaturesPlugin_Validators.cpp\r
-// Created: 22 March 2016\r
-// Author: Dmitry Bobylev\r
-\r
-#include "FeaturesPlugin_Validators.h"\r
-\r
-#include "FeaturesPlugin_Union.h"\r
-\r
-#include <Events_InfoMessage.h>\r
-\r
-#include <ModelAPI_Attribute.h>\r
-#include <ModelAPI_AttributeInteger.h>\r
-#include <ModelAPI_AttributeSelectionList.h>\r
-#include <ModelAPI_AttributeString.h>\r
-#include <ModelAPI_AttributeReference.h>\r
-#include <ModelAPI_AttributeRefList.h>\r
-#include <ModelAPI_Feature.h>\r
-#include <ModelAPI_ResultCompSolid.h>\r
-#include <ModelAPI_ResultConstruction.h>\r
-#include <ModelAPI_Tools.h>\r
-\r
-#include <GeomValidators_BodyShapes.h>\r
-#include <GeomValidators_FeatureKind.h>\r
-#include <GeomValidators_ShapeType.h>\r
-\r
-#include <GeomAPI_DataMapOfShapeShape.h>\r
-#include <GeomAPI_Lin.h>\r
-#include <GeomAPI_PlanarEdges.h>\r
-#include <GeomAPI_ShapeExplorer.h>\r
-#include <GeomAPI_ShapeIterator.h>\r
-\r
-#include <GeomAlgoAPI_CompoundBuilder.h>\r
-#include <GeomAlgoAPI_ShapeBuilder.h>\r
-#include <GeomAlgoAPI_ShapeTools.h>\r
-#include <GeomAlgoAPI_WireBuilder.h>\r
-\r
-#define _USE_MATH_DEFINES\r
-#include <math.h>\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- AttributeSelectionPtr aPathAttrSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);\r
- if(!aPathAttrSelection.get()) {\r
- theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";\r
- return false;\r
- }\r
-\r
- GeomShapePtr aPathShape = aPathAttrSelection->value();\r
- ResultPtr aContext = aPathAttrSelection->context();\r
- if(!aContext.get()) {\r
- theError = "Error: Empty context.";\r
- return false;\r
- }\r
- GeomShapePtr aContextShape = aContext->shape();\r
- if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE && !aPathShape->isEqual(aContextShape)) {\r
- theError = "Error: Local selection of wires not allowed.";\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- static const std::string aCreationMethodID = "creation_method";\r
- static const std::string aBaseObjectsID = "base_objects";\r
- static const std::string aLocationsID = "locations_objects";\r
-\r
- if(theFeature->getKind() != "Pipe") {\r
- theError = "Error: Feature \"%1\" does not supported by this validator.";\r
- theError.arg(theFeature->getKind());\r
- return false;\r
- }\r
-\r
- AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);\r
- if(!aCreationMethodAttr.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(aCreationMethodID);\r
- return false;\r
- }\r
-\r
- if(aCreationMethodAttr->value() != "locations") {\r
- return true;\r
- }\r
-\r
- AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);\r
- if(!aBaseObjectsSelectionList.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(aBaseObjectsID);\r
- return false;\r
- }\r
-\r
- AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);\r
- if(!aLocationsSelectionList.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(aBaseObjectsID);\r
- return false;\r
- }\r
-\r
- if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {\r
- theError = "Error: Number of locations should be the same as base objects.";\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)\r
-{\r
- return false;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- if(theArguments.empty()) {\r
- theError = "Error: Validator parameters is empty.";\r
- return false;\r
- }\r
-\r
- // Checking attribute.\r
- if(!isValidAttribute(theAttribute, theArguments, theError)) {\r
- if(theError.empty()) {\r
- theError = "Error: Attribute contains unacceptable shape.";\r
- }\r
- return false;\r
- }\r
-\r
- std::set<ResultConstructionPtr> aSelectedSketches;\r
- std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;\r
- GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;\r
- std::string anAttributeType = theAttribute->attributeType();\r
- if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {\r
- AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {\r
- AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);\r
- ResultPtr aContext = aSelectionAttr->context();\r
- if(!aContext.get()) {\r
- theError = "Error: Empty context.";\r
- return false;\r
- }\r
-\r
- ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);\r
- if(!aResultConstruction.get()) {\r
- // It is not a result construction. If shape is compound check that it contains only faces and edges.\r
- GeomShapePtr aShape = aSelectionAttr->value();\r
- if(!aShape.get()) {\r
- aShape = aContext->shape();\r
- }\r
-\r
- if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {\r
- for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {\r
- GeomShapePtr aSubShape = anIt.current();\r
- if(aSubShape->shapeType() != GeomAPI_Shape::EDGE\r
- && aSubShape->shapeType() != GeomAPI_Shape::FACE) {\r
- theError = "Error: Compound should contain only faces and edges.";\r
- return false;\r
- }\r
- }\r
- }\r
-\r
- continue;\r
- }\r
-\r
- GeomShapePtr aShape = aSelectionAttr->value();\r
- GeomShapePtr aContextShape = aResultConstruction->shape();\r
- if(!aShape.get()) {\r
- // Whole sketch selected.\r
- if(aSelectedSketchesFromObjects.find(aResultConstruction) != aSelectedSketchesFromObjects.cend()) {\r
- theError = "Error: Object from this sketch is already selected. Sketch is not allowed for selection.";\r
- return false;\r
- }\r
-\r
- aSelectedSketches.insert(aResultConstruction);\r
- } else {\r
- // Object from sketch selected.\r
- if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) {\r
- theError = "Error: Whole sketch with this object is already selected. Don't allow to select this object.";\r
- return false;\r
- }\r
-\r
- for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {\r
- GeomShapePtr aWire = anExp.current();\r
- if(aWire->orientation() != GeomAPI_Shape::FORWARD) {\r
- theError = "Error: Wire with wrong orientation selected.";\r
- return false;\r
- }\r
-\r
- if(aSelectedWiresFromObjects.isBound(aWire)) {\r
- theError = "Error: Objects with such wire already selected. Don't allow to select this object.";\r
- return false;\r
- }\r
-\r
- aSelectedWiresFromObjects.bind(aWire, aWire);\r
- aSelectedSketchesFromObjects.insert(aResultConstruction);\r
- }\r
- }\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- if(!theAttribute.get()) {\r
- theError = "Error: Empty attribute.";\r
- return false;\r
- }\r
-\r
- std::string anAttributeType = theAttribute->attributeType();\r
- if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {\r
- AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {\r
- // If at least one attribute is invalid, the result is false.\r
- if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {\r
- return false;\r
- }\r
- }\r
- } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {\r
- // Getting context.\r
- AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);\r
- ResultPtr aContext = anAttr->context();\r
- if(!aContext.get()) {\r
- theError = "Error: Attribute have empty context.";\r
- return false;\r
- }\r
-\r
- GeomShapePtr aShape = anAttr->value();\r
- GeomShapePtr aContextShape = aContext->shape();\r
- if(!aShape.get()) {\r
- aShape = aContextShape;\r
- }\r
- if(!aShape.get()) {\r
- theError = "Error: Empty shape selected";\r
- return false;\r
- }\r
-\r
- ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);\r
- if(aConstruction.get()) {\r
- // Construciotn selected. Check that is is not infinite.\r
- if(aConstruction->isInfinite()) {\r
- theError = "Error: Infinite constructions is not allowed as base.";\r
- return false;\r
- }\r
-\r
- if(aShape->isEqual(aContextShape)) {\r
- // Whole construction selected. Check that it have faces.\r
- if(aConstruction->facesNum() > 0) {\r
- return true;\r
- }\r
- } else {\r
- // Shape on construction selected. Check that it is a face or wire.\r
- if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
- }\r
-\r
- if(!aShape->isEqual(aContextShape)) {\r
- // Local selection on body does not allowed.\r
- theError = "Error: Selected shape is in the local selection. Only global selection is allowed.";\r
- return false;\r
- }\r
-\r
- // Check that object is a shape with allowed type.\r
- GeomValidators_ShapeType aShapeTypeValidator;\r
- if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {\r
- theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, whole sketch(if it has at least one face), and whole objects with shape types: %1";\r
- std::string anArgumentString;\r
- for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {\r
- if (!anArgumentString.empty())\r
- anArgumentString += ", ";\r
- anArgumentString += *anIt;\r
- }\r
- theError.arg(anArgumentString);\r
- return false;\r
- }\r
-\r
- } else {\r
- theError = "Error: Attribute \"%1\" does not supported by this validator.";\r
- theError.arg(anAttributeType);\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {\r
- theError = "Error: The attribute with the %1 type is not processed";\r
- theError.arg(theAttribute->attributeType());\r
- return false;\r
- }\r
- if (theArguments.size() != 2) {\r
- theError = "Error: Wrong parameters in XML definition for %1 type";\r
- theError.arg(theAttribute->attributeType());\r
- return false;\r
- }\r
- // first argument is for the base attribute, second - for skipping feature kind\r
- std::list<std::string>::const_iterator anIt = theArguments.begin();\r
- std::string aBaseAttributeId = *anIt;\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());\r
- AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);\r
- if (!aBaseAttribute.get()) {\r
- theError = "Wrong parameters in XML definition for %1 type";\r
- theError.arg(theAttribute->attributeType());\r
- return false;\r
- }\r
- if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,\r
- // this validator is not necessary anymore\r
- return true;\r
-\r
- anIt++;\r
- std::string aFeatureAttributeKind = *anIt;\r
- GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();\r
- // check whether the selection is on the sketch\r
- std::list<std::string> anArguments;\r
- anArguments.push_back(aFeatureAttributeKind);\r
-\r
- bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);\r
- bool aPlanarFace = false;\r
- // check if selection has Face selected\r
- GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();\r
- anArguments.clear();\r
- anArguments.push_back("face");\r
- aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);\r
-\r
- bool aValid = !aFeatureKind && aPlanarFace;\r
- return aValid;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorExtrusionDir::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- if(theArguments.size() != 2) {\r
- theError = "Error: Validator should be used with 2 parameters for extrusion.";\r
- return false;\r
- }\r
-\r
- std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();\r
-\r
- AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);\r
- ++anArgsIt;\r
-\r
- GeomShapePtr aDirShape;\r
- AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);\r
- if(aSelAttr.get()) {\r
- aDirShape = aSelAttr->value();\r
- if(!aDirShape.get()) {\r
- ResultPtr aContext = aSelAttr->context();\r
- if(aContext.get()) {\r
- aDirShape = aContext->shape();\r
- }\r
- }\r
- }\r
-\r
- if(!aDirShape.get()) {\r
- // Check that dir can be empty.\r
- if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {\r
- theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" can not be used with default value. Select direction for extrusion.";\r
- theError.arg(*anArgsIt);\r
- return false;\r
- } else {\r
- return true;\r
- }\r
- }\r
-\r
- std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));\r
-\r
- // If faces selected check that direction not parallel with them.\r
- AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);\r
- for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {\r
- AttributeSelectionPtr anAttr = aListAttr->value(anIndex);\r
- GeomShapePtr aShapeInList = anAttr->value();\r
- if(!aShapeInList.get()) {\r
- aShapeInList = anAttr->context()->shape();\r
- }\r
- bool isParallel = true;\r
- if(aShapeInList->shapeType() == GeomAPI_Shape::FACE || aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {\r
- for(GeomAPI_ShapeExplorer anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {\r
- std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));\r
- isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);\r
- if(isParallel) {\r
- break;\r
- }\r
- }\r
- } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {\r
- std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);\r
- if(aPlanarEdges.get()) {\r
- std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();\r
- if(aDirEdge->isLine()) {\r
- std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();\r
- isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;\r
- } else {\r
- isParallel = false;\r
- }\r
- } else {\r
- isParallel = false;\r
- }\r
- } else {\r
- isParallel = false;\r
- }\r
- if(isParallel) {\r
- theError = "Error: Direction is parallel to one of the selected face or face on selected shell.";\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature, std::string theAttribute)\r
-{\r
- return false;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,\r
- Events_InfoMessage& theError) const\r
-{\r
- if(!theAttribute.get()) {\r
- return true;\r
- }\r
-\r
- std::string anAttributeType = theAttribute->attributeType();\r
- if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {\r
- AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {\r
- // If at least one attribute is invalid, the result is false.\r
- if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {\r
- return false;\r
- }\r
- }\r
- } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {\r
- // Getting context.\r
- AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);\r
- ResultPtr aContext = anAttr->context();\r
- if(!aContext.get()) {\r
- return false;\r
- }\r
-\r
- GeomShapePtr aShape = anAttr->value();\r
- GeomShapePtr aContextShape = aContext->shape();\r
- if(!aShape.get()) {\r
- aShape = aContextShape;\r
- }\r
- if(!aShape.get()) {\r
- return false;\r
- }\r
-\r
- if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||\r
- aShape->shapeType() == GeomAPI_Shape::EDGE ||\r
- !aShape->isPlanar()) {\r
- return false;\r
- }\r
- } else {\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- if(!anAttrSelectionList.get()) {\r
- theError = "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";\r
- return false;\r
- }\r
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());\r
- int anOperationType = aFeature->integer("bool_type")->value();\r
-\r
- for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {\r
- AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);\r
- if(!anAttrSelection.get()) {\r
- theError = "Error: Empty attribute selection.";\r
- return false;\r
- }\r
- ResultPtr aContext = anAttrSelection->context();\r
- if(!aContext.get()) {\r
- theError = "Error: Empty selection context.";\r
- return false;\r
- }\r
- ResultConstructionPtr aResultConstruction =\r
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);\r
- if(aResultConstruction.get()) {\r
- theError = "Error: Result construction not allowed for selection.";\r
- return false;\r
- }\r
- std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();\r
- GeomShapePtr aContextShape = aContext->shape();\r
- if(!aShape.get()) {\r
- aShape = aContextShape;\r
- }\r
- if(!aShape.get()) {\r
- theError = "Error: Empty shape.";\r
- return false;\r
- }\r
- if(!aShape->isEqual(aContextShape)) {\r
- theError = "Error: Local selection not allowed.";\r
- return false;\r
- }\r
-\r
- int aShapeType = aShape->shapeType();\r
- if(anOperationType == 1) {\r
- // Fuse operation. Allow to select edges, faces and solids.\r
- if(aShapeType != GeomAPI_Shape::EDGE &&\r
- aShapeType != GeomAPI_Shape::FACE &&\r
- aShapeType != GeomAPI_Shape::SOLID &&\r
- aShapeType != GeomAPI_Shape::COMPSOLID &&\r
- aShapeType != GeomAPI_Shape::COMPOUND) {\r
- theError = "Error: Selected shape has the wrong type.";\r
- return false;\r
- }\r
- } else {\r
- if(aShapeType != GeomAPI_Shape::SOLID &&\r
- aShapeType != GeomAPI_Shape::COMPSOLID &&\r
- aShapeType != GeomAPI_Shape::COMPOUND) {\r
- theError = "Error: Selected shape has the wrong type.";\r
- return false;\r
- }\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- if(!anAttrSelectionList.get()) {\r
- theError = "Error: This validator can only work with selection list in \"Partition\" feature.";\r
- return false;\r
- }\r
-\r
- for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {\r
- AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);\r
-\r
- //GeomValidators_BodyShapes aBodyValidator;\r
- //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {\r
- // continue;\r
- //}\r
-\r
- GeomValidators_FeatureKind aFeatureKindValidator;\r
- if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {\r
- continue;\r
- }\r
-\r
- ResultPtr aContext = aSelectAttr->context();\r
- ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);\r
- if(aResultConstruction.get()) {\r
- theError = "Error: Only body shapes and construction planes are allowed for selection.";\r
- return false;\r
- }\r
-\r
- ResultCompSolidPtr aResultCompsolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);\r
- if(aResultCompsolid.get()) {\r
- continue;\r
- }\r
-\r
- theError = "Error: Only body shapes and construction planes are allowed for selection.";\r
- return false;\r
- }\r
-\r
- theError = "";\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- AttributeSelectionListPtr aSubShapesAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- if(!aSubShapesAttrList.get()) {\r
- theError = "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";\r
- return false;\r
- }\r
-\r
- static const std::string aBaseShapeID = "base_shape";\r
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());\r
- AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);\r
-\r
- if(!aShapeAttrSelection.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(aBaseShapeID);\r
- return false;\r
- }\r
-\r
- GeomShapePtr aBaseShape = aShapeAttrSelection->value();\r
- ResultPtr aContext = aShapeAttrSelection->context();\r
- if(!aContext.get()) {\r
- theError = "Error: Empty context.";\r
- return false;\r
- }\r
- if(!aBaseShape.get()) {\r
- aBaseShape = aContext->shape();\r
- }\r
- if(!aBaseShape.get()) {\r
- theError = "Error: Empty base shape.";\r
- return false;\r
- }\r
-\r
- for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {\r
- bool isSameFound = false;\r
- AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);\r
- GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();\r
- for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {\r
- if(anIt.current()->isEqual(aShapeToAdd)) {\r
- isSameFound = true;\r
- break;\r
- }\r
- }\r
- if(!isSameFound) {\r
- theError = "Error: Only sub-shapes of selected shape is allowed for selection.";\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- static const std::string aBaseShapeID = "base_shape";\r
- static const std::string aSubShapesID = "subshapes";\r
-\r
- if(theFeature->getKind() != "Remove_SubShapes") {\r
- theError = "Error: Feature \"%1\" does not supported by this validator.";\r
- theError.arg(theFeature->getKind());\r
- return false;\r
- }\r
-\r
- AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);\r
- if(!aShapeAttrSelection.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(aBaseShapeID);\r
- return false;\r
- }\r
-\r
- AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);\r
- if(!aSubShapesAttrList.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(aSubShapesID);\r
- return false;\r
- }\r
-\r
- // Copy base shape.\r
- GeomShapePtr aBaseShape = aShapeAttrSelection->value();\r
- if(!aBaseShape.get()) {\r
- theError = "Error: Base shape is empty.";\r
- return false;\r
- }\r
- GeomShapePtr aResultShape = aBaseShape->emptyCopied();\r
-\r
- // Copy sub-shapes from list to new shape.\r
- for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {\r
- AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);\r
- GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();\r
- GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);\r
- }\r
-\r
- // Check new shape.\r
- if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {\r
- theError = "Error: Resulting shape is not valid.";\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,\r
- std::string theAttribute)\r
-{\r
- return false;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- AttributeSelectionListPtr aBaseObjectsAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);\r
- if(!aBaseObjectsAttrList.get()) {\r
- theError = "Error: This validator can only work with selection list in \"%1\" feature.";\r
- theError.arg(FeaturesPlugin_Union::ID());\r
- return false;\r
- }\r
-\r
- for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {\r
- bool isSameFound = false;\r
- AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);\r
- ResultCompSolidPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());\r
- if(!aResult.get()) {\r
- continue;\r
- }\r
- if(aResult->numberOfSubs() > 0) {\r
- theError = "Error: Whole compsolids not allowed for selection.";\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorUnionArguments::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- // Check feature kind.\r
- if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {\r
- theError = "Error: This validator supports only \"%1\" feature.";\r
- theError.arg(FeaturesPlugin_Union::ID());\r
- return false;\r
- }\r
-\r
- // Get base objects attribute list.\r
- AttributeSelectionListPtr aBaseObejctsAttrList = theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());\r
- if(!aBaseObejctsAttrList.get()) {\r
- theError = "Error: Could not get \"%1\" attribute.";\r
- theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());\r
- return false;\r
- }\r
-\r
- // Get all shapes.\r
- ListOfShape aBaseShapesList;\r
- for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {\r
- AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);\r
- GeomShapePtr aShape = anAttrSelectionInList->value();\r
- aBaseShapesList.push_back(aShape);\r
- }\r
-\r
- // Make componud and find connected.\r
- GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);\r
- ListOfShape aCombined, aFree;\r
- GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);\r
-\r
- if(aFree.size() > 0 || aCombined.size() > 1) {\r
- theError = "Error: Not all shapes have shared topology.";\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-//==================================================================================================\r
-bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,\r
- std::string theAttribute)\r
-{\r
- return false;\r
-}\r
-\r
-bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const\r
-{\r
- if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {\r
- theError = "Error: The attribute with the %1 type is not processed";\r
- theError.arg(theAttribute->attributeType());\r
- return false;\r
- }\r
-\r
- AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>\r
- (theAttribute);\r
- ObjectPtr aRefObject = aRefAttribute->value();\r
- if (!aRefObject.get()) {\r
- theError = "Error: Empty feature.";\r
- return false;\r
- }\r
-\r
- FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);\r
- if (!aRefFeature.get()) {\r
- theError = "Error: Empty feature.";\r
- return false;\r
- }\r
- std::list<std::shared_ptr<ModelAPI_Result> > aResults;\r
- ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);\r
-\r
- size_t aConcealedResults = aResults.size();\r
- if (!aConcealedResults && !theArguments.empty()) {\r
- // find if these results are touched by the feature in another attribute\r
- std::list<std::string>::const_iterator anIt = theArguments.begin();\r
- std::string aRecoveredList = *anIt;\r
- if (!aRecoveredList.empty()) {\r
- std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =\r
- theAttribute->owner()->data()->reflist(aRecoveredList);\r
- if (aParameterList.get())\r
- aConcealedResults = aParameterList->size();\r
- }\r
- }\r
-\r
- if (aConcealedResults == 0)\r
- theError = "Error: No concealed results.";\r
-\r
- return theError.empty();\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: FeaturesPlugin_Validators.cpp
+// Created: 22 March 2016
+// Author: Dmitry Bobylev
+
+#include "FeaturesPlugin_Validators.h"
+
+#include "FeaturesPlugin_Union.h"
+
+#include <Events_InfoMessage.h>
+
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomValidators_BodyShapes.h>
+#include <GeomValidators_FeatureKind.h>
+#include <GeomValidators_ShapeType.h>
+
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_WireBuilder.h>
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionPtr aPathAttrSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ if(!aPathAttrSelection.get()) {
+ theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
+ return false;
+ }
+
+ GeomShapePtr aPathShape = aPathAttrSelection->value();
+ ResultPtr aContext = aPathAttrSelection->context();
+ if(!aContext.get()) {
+ theError = "Error: Empty context.";
+ return false;
+ }
+ GeomShapePtr aContextShape = aContext->shape();
+ if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE && !aPathShape->isEqual(aContextShape)) {
+ theError = "Error: Local selection of wires not allowed.";
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ static const std::string aCreationMethodID = "creation_method";
+ static const std::string aBaseObjectsID = "base_objects";
+ static const std::string aLocationsID = "locations_objects";
+
+ if(theFeature->getKind() != "Pipe") {
+ theError = "Error: Feature \"%1\" does not supported by this validator.";
+ theError.arg(theFeature->getKind());
+ return false;
+ }
+
+ AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
+ if(!aCreationMethodAttr.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aCreationMethodID);
+ return false;
+ }
+
+ if(aCreationMethodAttr->value() != "locations") {
+ return true;
+ }
+
+ AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
+ if(!aBaseObjectsSelectionList.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aBaseObjectsID);
+ return false;
+ }
+
+ AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
+ if(!aLocationsSelectionList.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aBaseObjectsID);
+ return false;
+ }
+
+ if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
+ theError = "Error: Number of locations should be the same as base objects.";
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
+{
+ return false;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if(theArguments.empty()) {
+ theError = "Error: Validator parameters is empty.";
+ return false;
+ }
+
+ // Checking attribute.
+ if(!isValidAttribute(theAttribute, theArguments, theError)) {
+ if(theError.empty()) {
+ theError = "Error: Attribute contains unacceptable shape.";
+ }
+ return false;
+ }
+
+ std::set<ResultConstructionPtr> aSelectedSketches;
+ std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
+ GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
+ std::string anAttributeType = theAttribute->attributeType();
+ if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+ AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+ AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
+ ResultPtr aContext = aSelectionAttr->context();
+ if(!aContext.get()) {
+ theError = "Error: Empty context.";
+ return false;
+ }
+
+ ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+ if(!aResultConstruction.get()) {
+ // It is not a result construction. If shape is compound check that it contains only faces and edges.
+ GeomShapePtr aShape = aSelectionAttr->value();
+ if(!aShape.get()) {
+ aShape = aContext->shape();
+ }
+
+ if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+ for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
+ GeomShapePtr aSubShape = anIt.current();
+ if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
+ && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
+ theError = "Error: Compound should contain only faces and edges.";
+ return false;
+ }
+ }
+ }
+
+ continue;
+ }
+
+ GeomShapePtr aShape = aSelectionAttr->value();
+ GeomShapePtr aContextShape = aResultConstruction->shape();
+ if(!aShape.get()) {
+ // Whole sketch selected.
+ if(aSelectedSketchesFromObjects.find(aResultConstruction) != aSelectedSketchesFromObjects.cend()) {
+ theError = "Error: Object from this sketch is already selected. Sketch is not allowed for selection.";
+ return false;
+ }
+
+ aSelectedSketches.insert(aResultConstruction);
+ } else {
+ // Object from sketch selected.
+ if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) {
+ theError = "Error: Whole sketch with this object is already selected. Don't allow to select this object.";
+ return false;
+ }
+
+ for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
+ GeomShapePtr aWire = anExp.current();
+ if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
+ theError = "Error: Wire with wrong orientation selected.";
+ return false;
+ }
+
+ if(aSelectedWiresFromObjects.isBound(aWire)) {
+ theError = "Error: Objects with such wire already selected. Don't allow to select this object.";
+ return false;
+ }
+
+ aSelectedWiresFromObjects.bind(aWire, aWire);
+ aSelectedSketchesFromObjects.insert(aResultConstruction);
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if(!theAttribute.get()) {
+ theError = "Error: Empty attribute.";
+ return false;
+ }
+
+ std::string anAttributeType = theAttribute->attributeType();
+ if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+ AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+ // If at least one attribute is invalid, the result is false.
+ if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
+ return false;
+ }
+ }
+ } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
+ // Getting context.
+ AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ ResultPtr aContext = anAttr->context();
+ if(!aContext.get()) {
+ theError = "Error: Attribute have empty context.";
+ return false;
+ }
+
+ GeomShapePtr aShape = anAttr->value();
+ GeomShapePtr aContextShape = aContext->shape();
+ if(!aShape.get()) {
+ aShape = aContextShape;
+ }
+ if(!aShape.get()) {
+ theError = "Error: Empty shape selected";
+ return false;
+ }
+
+ ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+ if(aConstruction.get()) {
+ // Construciotn selected. Check that is is not infinite.
+ if(aConstruction->isInfinite()) {
+ theError = "Error: Infinite constructions is not allowed as base.";
+ return false;
+ }
+
+ if(aShape->isEqual(aContextShape)) {
+ // Whole construction selected. Check that it have faces.
+ if(aConstruction->facesNum() > 0) {
+ return true;
+ }
+ } else {
+ // Shape on construction selected. Check that it is a face or wire.
+ if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ if(!aShape->isEqual(aContextShape)) {
+ // Local selection on body does not allowed.
+ theError = "Error: Selected shape is in the local selection. Only global selection is allowed.";
+ return false;
+ }
+
+ // Check that object is a shape with allowed type.
+ GeomValidators_ShapeType aShapeTypeValidator;
+ if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
+ theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, whole sketch(if it has at least one face), and whole objects with shape types: %1";
+ std::string anArgumentString;
+ for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
+ if (!anArgumentString.empty())
+ anArgumentString += ", ";
+ anArgumentString += *anIt;
+ }
+ theError.arg(anArgumentString);
+ return false;
+ }
+
+ } else {
+ theError = "Error: Attribute \"%1\" does not supported by this validator.";
+ theError.arg(anAttributeType);
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
+ theError = "Error: The attribute with the %1 type is not processed";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ if (theArguments.size() != 2) {
+ theError = "Error: Wrong parameters in XML definition for %1 type";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ // first argument is for the base attribute, second - for skipping feature kind
+ std::list<std::string>::const_iterator anIt = theArguments.begin();
+ std::string aBaseAttributeId = *anIt;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+ AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
+ if (!aBaseAttribute.get()) {
+ theError = "Wrong parameters in XML definition for %1 type";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
+ // this validator is not necessary anymore
+ return true;
+
+ anIt++;
+ std::string aFeatureAttributeKind = *anIt;
+ GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
+ // check whether the selection is on the sketch
+ std::list<std::string> anArguments;
+ anArguments.push_back(aFeatureAttributeKind);
+
+ bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
+ bool aPlanarFace = false;
+ // check if selection has Face selected
+ GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
+ anArguments.clear();
+ anArguments.push_back("face");
+ aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
+
+ bool aValid = !aFeatureKind && aPlanarFace;
+ return aValid;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorExtrusionDir::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if(theArguments.size() != 2) {
+ theError = "Error: Validator should be used with 2 parameters for extrusion.";
+ return false;
+ }
+
+ std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
+
+ AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
+ ++anArgsIt;
+
+ GeomShapePtr aDirShape;
+ AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
+ if(aSelAttr.get()) {
+ aDirShape = aSelAttr->value();
+ if(!aDirShape.get()) {
+ ResultPtr aContext = aSelAttr->context();
+ if(aContext.get()) {
+ aDirShape = aContext->shape();
+ }
+ }
+ }
+
+ if(!aDirShape.get()) {
+ // Check that dir can be empty.
+ if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
+ theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" can not be used with default value. Select direction for extrusion.";
+ theError.arg(*anArgsIt);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
+
+ // If faces selected check that direction not parallel with them.
+ AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
+ for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+ AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
+ GeomShapePtr aShapeInList = anAttr->value();
+ if(!aShapeInList.get()) {
+ aShapeInList = anAttr->context()->shape();
+ }
+ bool isParallel = true;
+ if(aShapeInList->shapeType() == GeomAPI_Shape::FACE || aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
+ for(GeomAPI_ShapeExplorer anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
+ std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
+ isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
+ if(isParallel) {
+ break;
+ }
+ }
+ } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
+ std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
+ if(aPlanarEdges.get()) {
+ std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
+ if(aDirEdge->isLine()) {
+ std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
+ isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
+ } else {
+ isParallel = false;
+ }
+ } else {
+ isParallel = false;
+ }
+ } else {
+ isParallel = false;
+ }
+ if(isParallel) {
+ theError = "Error: Direction is parallel to one of the selected face or face on selected shell.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature, std::string theAttribute)
+{
+ return false;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
+ Events_InfoMessage& theError) const
+{
+ if(!theAttribute.get()) {
+ return true;
+ }
+
+ std::string anAttributeType = theAttribute->attributeType();
+ if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+ AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+ // If at least one attribute is invalid, the result is false.
+ if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
+ return false;
+ }
+ }
+ } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
+ // Getting context.
+ AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ ResultPtr aContext = anAttr->context();
+ if(!aContext.get()) {
+ return false;
+ }
+
+ GeomShapePtr aShape = anAttr->value();
+ GeomShapePtr aContextShape = aContext->shape();
+ if(!aShape.get()) {
+ aShape = aContextShape;
+ }
+ if(!aShape.get()) {
+ return false;
+ }
+
+ if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
+ aShape->shapeType() == GeomAPI_Shape::EDGE ||
+ !aShape->isPlanar()) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!anAttrSelectionList.get()) {
+ theError = "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
+ return false;
+ }
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ int anOperationType = aFeature->integer("bool_type")->value();
+
+ for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+ if(!anAttrSelection.get()) {
+ theError = "Error: Empty attribute selection.";
+ return false;
+ }
+ ResultPtr aContext = anAttrSelection->context();
+ if(!aContext.get()) {
+ theError = "Error: Empty selection context.";
+ return false;
+ }
+ ResultConstructionPtr aResultConstruction =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+ if(aResultConstruction.get()) {
+ theError = "Error: Result construction not allowed for selection.";
+ return false;
+ }
+ std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+ GeomShapePtr aContextShape = aContext->shape();
+ if(!aShape.get()) {
+ aShape = aContextShape;
+ }
+ if(!aShape.get()) {
+ theError = "Error: Empty shape.";
+ return false;
+ }
+ if(!aShape->isEqual(aContextShape)) {
+ theError = "Error: Local selection not allowed.";
+ return false;
+ }
+
+ int aShapeType = aShape->shapeType();
+ if(anOperationType == 1) {
+ // Fuse operation. Allow to select edges, faces and solids.
+ if(aShapeType != GeomAPI_Shape::EDGE &&
+ aShapeType != GeomAPI_Shape::FACE &&
+ aShapeType != GeomAPI_Shape::SOLID &&
+ aShapeType != GeomAPI_Shape::COMPSOLID &&
+ aShapeType != GeomAPI_Shape::COMPOUND) {
+ theError = "Error: Selected shape has the wrong type.";
+ return false;
+ }
+ } else {
+ if(aShapeType != GeomAPI_Shape::SOLID &&
+ aShapeType != GeomAPI_Shape::COMPSOLID &&
+ aShapeType != GeomAPI_Shape::COMPOUND) {
+ theError = "Error: Selected shape has the wrong type.";
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!anAttrSelectionList.get()) {
+ theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
+ return false;
+ }
+
+ for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
+
+ //GeomValidators_BodyShapes aBodyValidator;
+ //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
+ // continue;
+ //}
+
+ GeomValidators_FeatureKind aFeatureKindValidator;
+ if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
+ continue;
+ }
+
+ ResultPtr aContext = aSelectAttr->context();
+ ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+ if(aResultConstruction.get()) {
+ theError = "Error: Only body shapes and construction planes are allowed for selection.";
+ return false;
+ }
+
+ ResultCompSolidPtr aResultCompsolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
+ if(aResultCompsolid.get()) {
+ continue;
+ }
+
+ theError = "Error: Only body shapes and construction planes are allowed for selection.";
+ return false;
+ }
+
+ theError = "";
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr aSubShapesAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!aSubShapesAttrList.get()) {
+ theError = "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
+ return false;
+ }
+
+ static const std::string aBaseShapeID = "base_shape";
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
+
+ if(!aShapeAttrSelection.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aBaseShapeID);
+ return false;
+ }
+
+ GeomShapePtr aBaseShape = aShapeAttrSelection->value();
+ ResultPtr aContext = aShapeAttrSelection->context();
+ if(!aContext.get()) {
+ theError = "Error: Empty context.";
+ return false;
+ }
+ if(!aBaseShape.get()) {
+ aBaseShape = aContext->shape();
+ }
+ if(!aBaseShape.get()) {
+ theError = "Error: Empty base shape.";
+ return false;
+ }
+
+ for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
+ bool isSameFound = false;
+ AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
+ GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
+ for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+ if(anIt.current()->isEqual(aShapeToAdd)) {
+ isSameFound = true;
+ break;
+ }
+ }
+ if(!isSameFound) {
+ theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ static const std::string aBaseShapeID = "base_shape";
+ static const std::string aSubShapesID = "subshapes";
+
+ if(theFeature->getKind() != "Remove_SubShapes") {
+ theError = "Error: Feature \"%1\" does not supported by this validator.";
+ theError.arg(theFeature->getKind());
+ return false;
+ }
+
+ AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
+ if(!aShapeAttrSelection.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aBaseShapeID);
+ return false;
+ }
+
+ AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
+ if(!aSubShapesAttrList.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aSubShapesID);
+ return false;
+ }
+
+ // Copy base shape.
+ GeomShapePtr aBaseShape = aShapeAttrSelection->value();
+ if(!aBaseShape.get()) {
+ theError = "Error: Base shape is empty.";
+ return false;
+ }
+ GeomShapePtr aResultShape = aBaseShape->emptyCopied();
+
+ // Copy sub-shapes from list to new shape.
+ for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
+ GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
+ GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
+ }
+
+ // Check new shape.
+ if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
+ theError = "Error: Resulting shape is not valid.";
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
+ std::string theAttribute)
+{
+ return false;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr aBaseObjectsAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!aBaseObjectsAttrList.get()) {
+ theError = "Error: This validator can only work with selection list in \"%1\" feature.";
+ theError.arg(FeaturesPlugin_Union::ID());
+ return false;
+ }
+
+ for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
+ bool isSameFound = false;
+ AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
+ ResultCompSolidPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
+ if(!aResult.get()) {
+ continue;
+ }
+ if(aResult->numberOfSubs() > 0) {
+ theError = "Error: Whole compsolids not allowed for selection.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorUnionArguments::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ // Check feature kind.
+ if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
+ theError = "Error: This validator supports only \"%1\" feature.";
+ theError.arg(FeaturesPlugin_Union::ID());
+ return false;
+ }
+
+ // Get base objects attribute list.
+ AttributeSelectionListPtr aBaseObejctsAttrList = theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
+ if(!aBaseObejctsAttrList.get()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
+ return false;
+ }
+
+ // Get all shapes.
+ ListOfShape aBaseShapesList;
+ for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
+ GeomShapePtr aShape = anAttrSelectionInList->value();
+ aBaseShapesList.push_back(aShape);
+ }
+
+ // Make componud and find connected.
+ GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
+ ListOfShape aCombined, aFree;
+ GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
+
+ if(aFree.size() > 0 || aCombined.size() > 1) {
+ theError = "Error: Not all shapes have shared topology.";
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
+ std::string theAttribute)
+{
+ return false;
+}
+
+bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
+ theError = "Error: The attribute with the %1 type is not processed";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+
+ AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
+ (theAttribute);
+ ObjectPtr aRefObject = aRefAttribute->value();
+ if (!aRefObject.get()) {
+ theError = "Error: Empty feature.";
+ return false;
+ }
+
+ FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
+ if (!aRefFeature.get()) {
+ theError = "Error: Empty feature.";
+ return false;
+ }
+ std::list<std::shared_ptr<ModelAPI_Result> > aResults;
+ ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
+
+ size_t aConcealedResults = aResults.size();
+ if (!aConcealedResults && !theArguments.empty()) {
+ // find if these results are touched by the feature in another attribute
+ std::list<std::string>::const_iterator anIt = theArguments.begin();
+ std::string aRecoveredList = *anIt;
+ if (!aRecoveredList.empty()) {
+ std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
+ theAttribute->owner()->data()->reflist(aRecoveredList);
+ if (aParameterList.get())
+ aConcealedResults = aParameterList->size();
+ }
+ }
+
+ if (aConcealedResults == 0)
+ theError = "Error: No concealed results.";
+
+ return theError.empty();
+}
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->\r
-\r
-// File: FeaturesPlugin_Validators.h\r
-// Created: 22 March 2016\r
-// Author: Dmitry Bobylev\r
-\r
-#ifndef FeaturesPlugin_Validators_H_\r
-#define FeaturesPlugin_Validators_H_\r
-\r
-#include <ModelAPI_AttributeValidator.h>\r
-#include <ModelAPI_FeatureValidator.h>\r
-\r
-/// \class FeaturesPlugin_ValidatorPipePath\r
-/// \ingroup Validators\r
-/// \brief A validator for selection pipe path.\r
-class FeaturesPlugin_ValidatorPipePath: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- //! \return True if the attribute is valid.\r
- //! \param[in] theAttribute the checked attribute.\r
- //! \param[in] theArguments arguments of the attribute.\r
- //! \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorPipeLocations\r
-/// \ingroup Validators\r
-/// \brief Validator for the pipe locations.\r
-class FeaturesPlugin_ValidatorPipeLocations: public ModelAPI_FeatureValidator\r
-{\r
- public:\r
- //! \return true if number of selected locations the same as number of selected bases, or empty.\r
- //! \param theFeature the checked feature\r
- //! \param theArguments arguments of the feature (not used)\r
- //! \param theError error message\r
- virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-\r
- /// Returns true if the attribute in feature is not obligatory for the feature execution\r
- virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorBaseForGeneration\r
-/// \ingroup Validators\r
-/// \brief A validator for selection base for generation. Allows to select faces on sketch,\r
-/// whole sketch(if it has at least one face), and following objects: vertex, edge, wire, face.\r
-class FeaturesPlugin_ValidatorBaseForGeneration: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- //! \return true if attribute has selection type listed in the parameter arguments.\r
- //! \param[in] theAttribute the checked attribute.\r
- //! \param[in] theArguments arguments of the attribute.\r
- //! \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-\r
-private:\r
- bool isValidAttribute(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorCompositeLauncher\r
-/// \ingroup Validators\r
-/// \brief A validator for selection at composite feature start\r
-class FeaturesPlugin_ValidatorCompositeLauncher: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- //! \return true if attribute has selection type listed in the parameter arguments.\r
- //! \param[in] theAttribute the checked attribute.\r
- //! \param[in] theArguments arguments of the attribute.\r
- //! \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorExtrusionDir\r
-/// \ingroup Validators\r
-/// \brief A validator for extrusion direction attribute. Allows it to be empty if base objects are\r
-/// planar and do not contain vertices and edges.\r
-class FeaturesPlugin_ValidatorExtrusionDir: public ModelAPI_FeatureValidator\r
-{\r
-public:\r
- //! \return true if attribute listed in the parameter arguments are planar.\r
- //! \param[in] theFeature the checked feature.\r
- //! \param[in] theArguments arguments of the attribute.\r
- //! \param[out] theError error message.\r
- virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-\r
- /// \return true if the attribute in feature is not obligatory for the feature execution\r
- virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);\r
-\r
-private:\r
- bool isShapesCanBeEmpty(const AttributePtr& theAttribute,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorBooleanSelection\r
-/// \ingroup Validators\r
-/// \brief Validates selection for boolean operation.\r
-class FeaturesPlugin_ValidatorBooleanSelection: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- /// \return True if the attribute is valid. It checks whether the selection\r
- /// is acceptable for boolean operation.\r
- /// \param[in] theAttribute an attribute to check.\r
- /// \param[in] theArguments a filter parameters.\r
- /// \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorPartitionSelection\r
-/// \ingroup Validators\r
-/// \brief Validates selection for partition.\r
-class FeaturesPlugin_ValidatorPartitionSelection: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- /// \return True if the attribute is valid. It checks whether the selection\r
- /// is acceptable for operation.\r
- /// \param[in] theAttribute an attribute to check.\r
- /// \param[in] theArguments a filter parameters.\r
- /// \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorRemoveSubShapesSelection\r
-/// \ingroup Validators\r
-/// \brief Validates selection for "Remove Sub-Shapes" feature.\r
-class FeaturesPlugin_ValidatorRemoveSubShapesSelection: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- /// \return True if the attribute is valid. It checks whether the selection\r
- /// is acceptable for operation.\r
- /// \param[in] theAttribute an attribute to check.\r
- /// \param[in] theArguments a filter parameters.\r
- /// \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorRemoveSubShapesResult\r
-/// \ingroup Validators\r
-/// \brief Validator for the Remove Sub-Shapes feature.\r
-class FeaturesPlugin_ValidatorRemoveSubShapesResult: public ModelAPI_FeatureValidator\r
-{\r
- public:\r
- //! \return true if result is valid shape.\r
- //! \param theFeature the checked feature\r
- //! \param theArguments arguments of the feature (not used)\r
- //! \param theError error message\r
- virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-\r
- /// \return true if the attribute in feature is not obligatory for the feature execution\r
- virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorUnionSelection\r
-/// \ingroup Validators\r
-/// \brief Validates selection for "Union" feature.\r
-class FeaturesPlugin_ValidatorUnionSelection: public ModelAPI_AttributeValidator\r
-{\r
-public:\r
- /// \return True if the attribute is valid. It checks whether the selection\r
- /// is acceptable for operation.\r
- /// \param[in] theAttribute an attribute to check.\r
- /// \param[in] theArguments a filter parameters.\r
- /// \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorUnionArguments\r
-/// \ingroup Validators\r
-/// \brief Validator for the "Union" feature.\r
-class FeaturesPlugin_ValidatorUnionArguments: public ModelAPI_FeatureValidator\r
-{\r
- public:\r
- //! \return true if result is valid shape.\r
- //! \param theFeature the checked feature\r
- //! \param theArguments arguments of the feature (not used)\r
- //! \param theError error message\r
- virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-\r
- /// \return true if the attribute in feature is not obligatory for the feature execution\r
- virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);\r
-};\r
-\r
-/// \class FeaturesPlugin_ValidatorConcealedResult\r
-/// \ingroup Validators\r
-/// \brief Validator for the "Recover" feature.\r
-class FeaturesPlugin_ValidatorConcealedResult: public ModelAPI_AttributeValidator\r
-{\r
- public:\r
- //! \return True if the attribute is valid.\r
- //! \param[in] theAttribute the checked attribute.\r
- //! \param[in] theArguments arguments of the attribute.\r
- //! \param[out] theError error message.\r
- virtual bool isValid(const AttributePtr& theAttribute,\r
- const std::list<std::string>& theArguments,\r
- Events_InfoMessage& theError) const;\r
-};\r
-\r
-#endif\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: FeaturesPlugin_Validators.h
+// Created: 22 March 2016
+// Author: Dmitry Bobylev
+
+#ifndef FeaturesPlugin_Validators_H_
+#define FeaturesPlugin_Validators_H_
+
+#include <ModelAPI_AttributeValidator.h>
+#include <ModelAPI_FeatureValidator.h>
+
+/// \class FeaturesPlugin_ValidatorPipePath
+/// \ingroup Validators
+/// \brief A validator for selection pipe path.
+class FeaturesPlugin_ValidatorPipePath: public ModelAPI_AttributeValidator
+{
+public:
+ //! \return True if the attribute is valid.
+ //! \param[in] theAttribute the checked attribute.
+ //! \param[in] theArguments arguments of the attribute.
+ //! \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorPipeLocations
+/// \ingroup Validators
+/// \brief Validator for the pipe locations.
+class FeaturesPlugin_ValidatorPipeLocations: public ModelAPI_FeatureValidator
+{
+ public:
+ //! \return true if number of selected locations the same as number of selected bases, or empty.
+ //! \param theFeature the checked feature
+ //! \param theArguments arguments of the feature (not used)
+ //! \param theError error message
+ virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+ /// Returns true if the attribute in feature is not obligatory for the feature execution
+ virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+};
+
+/// \class FeaturesPlugin_ValidatorBaseForGeneration
+/// \ingroup Validators
+/// \brief A validator for selection base for generation. Allows to select faces on sketch,
+/// whole sketch(if it has at least one face), and following objects: vertex, edge, wire, face.
+class FeaturesPlugin_ValidatorBaseForGeneration: public ModelAPI_AttributeValidator
+{
+public:
+ //! \return true if attribute has selection type listed in the parameter arguments.
+ //! \param[in] theAttribute the checked attribute.
+ //! \param[in] theArguments arguments of the attribute.
+ //! \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+private:
+ bool isValidAttribute(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorCompositeLauncher
+/// \ingroup Validators
+/// \brief A validator for selection at composite feature start
+class FeaturesPlugin_ValidatorCompositeLauncher: public ModelAPI_AttributeValidator
+{
+public:
+ //! \return true if attribute has selection type listed in the parameter arguments.
+ //! \param[in] theAttribute the checked attribute.
+ //! \param[in] theArguments arguments of the attribute.
+ //! \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorExtrusionDir
+/// \ingroup Validators
+/// \brief A validator for extrusion direction attribute. Allows it to be empty if base objects are
+/// planar and do not contain vertices and edges.
+class FeaturesPlugin_ValidatorExtrusionDir: public ModelAPI_FeatureValidator
+{
+public:
+ //! \return true if attribute listed in the parameter arguments are planar.
+ //! \param[in] theFeature the checked feature.
+ //! \param[in] theArguments arguments of the attribute.
+ //! \param[out] theError error message.
+ virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+ /// \return true if the attribute in feature is not obligatory for the feature execution
+ virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+
+private:
+ bool isShapesCanBeEmpty(const AttributePtr& theAttribute,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorBooleanSelection
+/// \ingroup Validators
+/// \brief Validates selection for boolean operation.
+class FeaturesPlugin_ValidatorBooleanSelection: public ModelAPI_AttributeValidator
+{
+public:
+ /// \return True if the attribute is valid. It checks whether the selection
+ /// is acceptable for boolean operation.
+ /// \param[in] theAttribute an attribute to check.
+ /// \param[in] theArguments a filter parameters.
+ /// \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorPartitionSelection
+/// \ingroup Validators
+/// \brief Validates selection for partition.
+class FeaturesPlugin_ValidatorPartitionSelection: public ModelAPI_AttributeValidator
+{
+public:
+ /// \return True if the attribute is valid. It checks whether the selection
+ /// is acceptable for operation.
+ /// \param[in] theAttribute an attribute to check.
+ /// \param[in] theArguments a filter parameters.
+ /// \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorRemoveSubShapesSelection
+/// \ingroup Validators
+/// \brief Validates selection for "Remove Sub-Shapes" feature.
+class FeaturesPlugin_ValidatorRemoveSubShapesSelection: public ModelAPI_AttributeValidator
+{
+public:
+ /// \return True if the attribute is valid. It checks whether the selection
+ /// is acceptable for operation.
+ /// \param[in] theAttribute an attribute to check.
+ /// \param[in] theArguments a filter parameters.
+ /// \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorRemoveSubShapesResult
+/// \ingroup Validators
+/// \brief Validator for the Remove Sub-Shapes feature.
+class FeaturesPlugin_ValidatorRemoveSubShapesResult: public ModelAPI_FeatureValidator
+{
+ public:
+ //! \return true if result is valid shape.
+ //! \param theFeature the checked feature
+ //! \param theArguments arguments of the feature (not used)
+ //! \param theError error message
+ virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+ /// \return true if the attribute in feature is not obligatory for the feature execution
+ virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+};
+
+/// \class FeaturesPlugin_ValidatorUnionSelection
+/// \ingroup Validators
+/// \brief Validates selection for "Union" feature.
+class FeaturesPlugin_ValidatorUnionSelection: public ModelAPI_AttributeValidator
+{
+public:
+ /// \return True if the attribute is valid. It checks whether the selection
+ /// is acceptable for operation.
+ /// \param[in] theAttribute an attribute to check.
+ /// \param[in] theArguments a filter parameters.
+ /// \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+/// \class FeaturesPlugin_ValidatorUnionArguments
+/// \ingroup Validators
+/// \brief Validator for the "Union" feature.
+class FeaturesPlugin_ValidatorUnionArguments: public ModelAPI_FeatureValidator
+{
+ public:
+ //! \return true if result is valid shape.
+ //! \param theFeature the checked feature
+ //! \param theArguments arguments of the feature (not used)
+ //! \param theError error message
+ virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+ /// \return true if the attribute in feature is not obligatory for the feature execution
+ virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+};
+
+/// \class FeaturesPlugin_ValidatorConcealedResult
+/// \ingroup Validators
+/// \brief Validator for the "Recover" feature.
+class FeaturesPlugin_ValidatorConcealedResult: public ModelAPI_AttributeValidator
+{
+ public:
+ //! \return True if the attribute is valid.
+ //! \param[in] theAttribute the checked attribute.
+ //! \param[in] theArguments arguments of the attribute.
+ //! \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+#endif
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModelAPI_Tools.cpp\r
-// Created: 06 Aug 2014\r
-// Author: Vitaly Smetannikov\r
-\r
-#include "ModelAPI_Tools.h"\r
-#include <ModelAPI_Session.h>\r
-#include <ModelAPI_Document.h>\r
-#include <ModelAPI_Object.h>\r
-#include <ModelAPI_AttributeDouble.h>\r
-#include <ModelAPI_ResultParameter.h>\r
-#include <ModelAPI_ResultPart.h>\r
-#include <ModelAPI_AttributeDocRef.h>\r
-#include <ModelAPI_Validator.h>\r
-#include <list>\r
-#include <map>\r
-#include <iostream>\r
-\r
-#include <Events_Loop.h>\r
-#include <ModelAPI_Events.h>\r
-\r
-#define RECURSE_TOP_LEVEL 50\r
-\r
-//#define DEBUG_REMOVE_FEATURES\r
-//#define DEBUG_REMOVE_FEATURES_RECURSE\r
-//#define DEBUG_CYCLING_1550\r
-\r
-#ifdef DEBUG_REMOVE_FEATURES_RECURSE\r
-#include <sstream>\r
-std::string getFeatureInfo(FeaturePtr theFeature)\r
-{\r
- if (!theFeature.get())\r
- return "";\r
- //std::ostringstream aPtrStr;\r
- //aPtrStr << "[" << theFeature.get() << "] ";\r
- std::string aFeatureInfo = /*aPtrStr.str() + */theFeature->name();\r
- CompositeFeaturePtr aComposite = ModelAPI_Tools::compositeOwner(theFeature);\r
- if (aComposite.get()) {\r
- aFeatureInfo = aFeatureInfo + "[in " + aComposite->name() + "]";\r
- }\r
- return aFeatureInfo;\r
-}\r
-#endif\r
-\r
-#ifdef DEBUG_REMOVE_FEATURES\r
-void printMapInfo(const std::map<FeaturePtr, std::set<FeaturePtr> >& theMainList,\r
- const std::string& thePrefix)\r
-{\r
- std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = theMainList.begin(),\r
- aMainLast = theMainList.end();\r
- std::string anInfo;\r
- for (; aMainIt != aMainLast; aMainIt++) {\r
- FeaturePtr aMainListFeature = aMainIt->first;\r
- std::set<FeaturePtr> aMainRefList = aMainIt->second;\r
- std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(), aLast = aMainRefList.end();\r
- std::string aRefsInfo;\r
- for (; anIt != aLast; anIt++) {\r
- aRefsInfo += (*anIt)->name().c_str();\r
- if (anIt != aLast)\r
- aRefsInfo += ", ";\r
- }\r
- if (!aRefsInfo.empty()) {\r
- anInfo = anInfo + aMainListFeature->name().c_str() + ": " + aRefsInfo + "\n";\r
- }\r
- }\r
- std::cout << thePrefix.c_str() << " [feature: references to]: \n" << anInfo.c_str() << std::endl;\r
-}\r
-\r
-void printListInfo(const std::set<FeaturePtr>& theMainList,\r
- const std::string& thePrefix)\r
-{\r
- std::set<FeaturePtr>::const_iterator aMainIt = theMainList.begin(),\r
- aMainLast = theMainList.end();\r
- std::string anInfo;\r
- for (; aMainIt != aMainLast; aMainIt++) {\r
- FeaturePtr aRefFeature = *aMainIt;\r
- anInfo += aRefFeature->name().c_str();\r
- if (aMainIt != aMainLast)\r
- anInfo += ", ";\r
- }\r
- std::cout << thePrefix.c_str() << ": " << anInfo.c_str() << std::endl;\r
-}\r
-#endif\r
-\r
-namespace ModelAPI_Tools {\r
-\r
-std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)\r
-{\r
- return theResult->shape();\r
-}\r
-\r
-void shapesOfType(const FeaturePtr& theFeature,\r
- const GeomAPI_Shape::ShapeType& theType,\r
- std::set<GeomShapePtr>& theShapes)\r
-{\r
- std::list<ResultPtr> aResults = theFeature->results();\r
- std::list<ResultPtr>::const_iterator aRIter = aResults.cbegin();\r
- for (; aRIter != aResults.cend(); aRIter++) {\r
- ResultPtr aResult = *aRIter;\r
- GeomShapePtr aShape = aResult->shape();\r
- if (aShape.get() && aShape->shapeType() == theType)\r
- theShapes.insert(aShape);\r
- }\r
-}\r
-\r
-const char* toString(ModelAPI_ExecState theExecState) \r
-{\r
-#define TO_STRING(__NAME__) case __NAME__: return #__NAME__;\r
- switch (theExecState) {\r
- TO_STRING(ModelAPI_StateDone)\r
- TO_STRING(ModelAPI_StateMustBeUpdated)\r
- TO_STRING(ModelAPI_StateExecFailed)\r
- TO_STRING(ModelAPI_StateInvalidArgument)\r
- TO_STRING(ModelAPI_StateNothing)\r
- default: return "Unknown ExecState.";\r
- }\r
-#undef TO_STRING\r
-}\r
-\r
-std::string getFeatureError(const FeaturePtr& theFeature)\r
-{\r
- std::string anError;\r
- if (!theFeature.get() || !theFeature->data()->isValid() || theFeature->isAction())\r
- return anError;\r
-\r
- // to be removed later, this error should be got from the feature\r
- if (theFeature->data()->execState() == ModelAPI_StateDone ||\r
- theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)\r
- return anError;\r
-\r
- // set error indication\r
- anError = theFeature->error();\r
- if (anError.empty()) {\r
- bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone\r
- || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated );\r
- if (!isDone) {\r
- anError = toString(theFeature->data()->execState());\r
- // If the feature is Composite and error is StateInvalidArgument,\r
- // error text should include error of first invalid sub-feature. Otherwise\r
- // it is not clear what is the reason of the invalid argument.\r
- if (theFeature->data()->execState() == ModelAPI_StateInvalidArgument) {\r
- CompositeFeaturePtr aComposite =\r
- std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);\r
- if (aComposite) {\r
- for (int i = 0, aSize = aComposite->numberOfSubs(); i < aSize; i++) {\r
- FeaturePtr aSubFeature = aComposite->subFeature(i);\r
- std::string aSubFeatureError = getFeatureError(aSubFeature);\r
- if (!aSubFeatureError.empty()) {\r
- anError = anError + " in " + aSubFeature->getKind() + ".\n" + aSubFeatureError;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- return anError;\r
-}\r
-\r
-ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup, const std::string& theName)\r
-{\r
- for (int anIndex = 0; anIndex < theDocument->size(theGroup); ++anIndex) {\r
- ObjectPtr anObject = theDocument->object(theGroup, anIndex);\r
- if (anObject->data()->name() == theName)\r
- return anObject;\r
- }\r
- // not found\r
- return ObjectPtr();\r
-}\r
-\r
-bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher,\r
- const std::string& theName, double& outValue, ResultParameterPtr& theParam)\r
-{\r
- ObjectPtr aParamObj = objectByName(theDocument, ModelAPI_ResultParameter::group(), theName);\r
- theParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);\r
- if (!theParam.get())\r
- return false;\r
- // avoid usage of parameters created later than the initial parameter\r
- if (theSearcher.get() && theDocument->isLater(theDocument->feature(theParam), theSearcher))\r
- return false;\r
- AttributeDoublePtr aValueAttribute = theParam->data()->real(ModelAPI_ResultParameter::VALUE());\r
- outValue = aValueAttribute->value();\r
- return true;\r
-}\r
-\r
-bool findVariable(FeaturePtr theSearcher, const std::string& theName, double& outValue, ResultParameterPtr& theParam,\r
- const DocumentPtr& theDocument)\r
-{\r
- SessionPtr aSession = ModelAPI_Session::get();\r
- std::list<DocumentPtr> aDocList;\r
- DocumentPtr aDocument = theDocument.get() ? theDocument : aSession->activeDocument();\r
- if (findVariable(aDocument, theSearcher, theName, outValue, theParam))\r
- return true;\r
- DocumentPtr aRootDocument = aSession->moduleDocument();\r
- if (aDocument != aRootDocument) {\r
- // any parameters in PartSet is okindependently on the Part position (issu #1504)\r
- if (findVariable(aRootDocument, FeaturePtr(), theName, outValue, theParam))\r
- return true;\r
- }\r
- return false;\r
-}\r
-\r
-ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub)\r
-{\r
- if (theMain != theSub) { // to optimize and avoid of crash on partset document close (don't touch the sub-document structure)\r
- for (int a = theMain->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) {\r
- ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(\r
- theMain->object(ModelAPI_ResultPart::group(), a));\r
- if (aPart && aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value() == theSub) {\r
- return aPart;\r
- }\r
- }\r
- }\r
- return ResultPtr();\r
-}\r
-\r
-FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub)\r
-{\r
- if (theMain != theSub) { // to optimize and avoid of crash on partset document close (don't touch the sub-document structure)\r
- for (int a = theMain->size(ModelAPI_Feature::group()) - 1; a >= 0; a--) {\r
- FeaturePtr aPartFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(\r
- theMain->object(ModelAPI_Feature::group(), a));\r
- if (aPartFeat.get()) {\r
- const std::list<std::shared_ptr<ModelAPI_Result> >& aResList = aPartFeat->results();\r
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResList.begin();\r
- for(; aRes != aResList.end(); aRes++) {\r
- ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes);\r
- if (aPart.get()) {\r
- if (aPart->isActivated() && aPart->partDoc() == theSub)\r
- return aPartFeat;\r
- } else break; // if the first is not Part, others are also not\r
- }\r
- }\r
- }\r
- }\r
- return FeaturePtr();\r
-}\r
-\r
-CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature)\r
-{\r
- if (theFeature.get() && theFeature->data()->isValid()) {\r
- const std::set<std::shared_ptr<ModelAPI_Attribute> >& aRefs = theFeature->data()->refsToMe();\r
- std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aRefIter = aRefs.begin();\r
- for(; aRefIter != aRefs.end(); aRefIter++) {\r
- CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>\r
- ((*aRefIter)->owner());\r
- if (aComp.get() && aComp->data()->isValid() && aComp->isSub(theFeature))\r
- return aComp;\r
- }\r
- }\r
- return CompositeFeaturePtr(); // not found\r
-}\r
-\r
-ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub)\r
-{\r
- ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theSub);\r
- if (aBody.get()) {\r
- FeaturePtr aFeatureOwner = aBody->document()->feature(aBody);\r
- if (aFeatureOwner.get()) {\r
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter = \r
- aFeatureOwner->results().cbegin();\r
- for(; aResIter != aFeatureOwner->results().cend(); aResIter++) {\r
- ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aResIter);\r
- if (aComp && aComp->isSub(aBody))\r
- return aComp;\r
- }\r
- }\r
- }\r
- return ResultCompSolidPtr(); // not found\r
-}\r
-\r
-bool hasSubResults(const ResultPtr& theResult)\r
-{\r
- ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theResult);\r
- return aCompSolid.get() && aCompSolid->numberOfSubs() > 0;\r
-}\r
-\r
-void allResults(const FeaturePtr& theFeature, std::list<ResultPtr>& theResults)\r
-{\r
- if (!theFeature.get()) // safety: for empty feature no results\r
- return;\r
- const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();\r
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();\r
- for (; aRIter != aResults.cend(); aRIter++) {\r
- theResults.push_back(*aRIter);\r
- // iterate sub-bodies of compsolid\r
- ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aRIter);\r
- if (aComp.get()) {\r
- int aNumSub = aComp->numberOfSubs();\r
- for(int a = 0; a < aNumSub; a++) {\r
- theResults.push_back(aComp->subResult(a));\r
- }\r
- }\r
- }\r
-}\r
-\r
-//******************************************************************\r
-bool allDocumentsActivated(std::string& theNotActivatedNames)\r
-{\r
- theNotActivatedNames = "";\r
- bool anAllPartActivated = true;\r
-\r
- DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();\r
- int aSize = aRootDoc->size(ModelAPI_ResultPart::group());\r
- for (int i = 0; i < aSize; i++) {\r
- ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), i);\r
- ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);\r
- if (!aPart->isActivated()) {\r
- anAllPartActivated = false;\r
- if (!theNotActivatedNames.empty())\r
- theNotActivatedNames += ", ";\r
- theNotActivatedNames += aObject->data()->name().c_str();\r
- }\r
- }\r
- return anAllPartActivated;\r
-}\r
-\r
-bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,\r
- const bool theFlushRedisplay,\r
- const bool theUseComposite,\r
- const bool theUseRecursion)\r
-{\r
-#ifdef DEBUG_REMOVE_FEATURES\r
- printListInfo(theFeatures, "selection: ");\r
-#endif\r
-\r
- std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;\r
- ModelAPI_Tools::findAllReferences(theFeatures, aReferences, theUseComposite, theUseRecursion);\r
-#ifdef DEBUG_REMOVE_FEATURES\r
- printMapInfo(aReferences, "allDependencies: ");\r
-#endif\r
-\r
- std::set<FeaturePtr> aFeaturesRefsTo;\r
- ModelAPI_Tools::findRefsToFeatures(theFeatures, aReferences, aFeaturesRefsTo);\r
-#ifdef DEBUG_REMOVE_FEATURES\r
- printListInfo(aFeaturesRefsTo, "references: ");\r
-#endif\r
-\r
- std::set<FeaturePtr> aFeatures = theFeatures;\r
- if (!aFeaturesRefsTo.empty())\r
- aFeatures.insert(aFeaturesRefsTo.begin(), aFeaturesRefsTo.end());\r
-#ifdef DEBUG_REMOVE_FEATURES\r
- printListInfo(aFeatures, "removeFeatures: ");\r
-#endif\r
-\r
- return ModelAPI_Tools::removeFeatures(aFeatures, false);\r
-}\r
-\r
-bool removeFeatures(const std::set<FeaturePtr>& theFeatures,\r
- const bool theFlushRedisplay)\r
-{\r
- bool isDone = false;\r
- std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),\r
- aLast = theFeatures.end();\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aFeature = *anIt;\r
- if (aFeature.get()) {\r
- DocumentPtr aDoc = aFeature->document();\r
- // flush REDISPLAY signal after remove feature\r
- aDoc->removeFeature(aFeature);\r
- isDone = true;\r
- }\r
- }\r
- if (isDone && theFlushRedisplay) {\r
- // the redisplay signal should be flushed in order to erase the feature presentation in the viewer\r
- // if should be done after removeFeature() of document\r
- Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));\r
- }\r
- return true;\r
-}\r
-\r
-// Fills the references list by all references of the feature from the references map.\r
-// This is a recusive method to find references by next found feature in the map of references.\r
-// \param theFeature a feature to find references\r
-// \param theReferencesMap a map of references\r
-// \param theReferences an out container of references\r
-void addRefsToFeature(const FeaturePtr& theFeature,\r
- const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferencesMap,\r
- std::map<FeaturePtr, std::set<FeaturePtr> >& theProcessedReferences,\r
- int theRecLevel,\r
- std::set<FeaturePtr>& theReferences)\r
-{\r
- if (theRecLevel > RECURSE_TOP_LEVEL)\r
- return;\r
- theRecLevel++;\r
-\r
- // if the feature is already processed, get the ready references from the map\r
- if (theProcessedReferences.find(theFeature) != theProcessedReferences.end()) {\r
- std::set<FeaturePtr> aReferences = theProcessedReferences.at(theFeature);\r
- theReferences.insert(aReferences.begin(), aReferences.end());\r
- return;\r
- }\r
-\r
- if (theReferencesMap.find(theFeature) == theReferencesMap.end())\r
- return; // this feature is not in the selection list, so exists without references to it\r
- std::set<FeaturePtr> aMainReferences = theReferencesMap.at(theFeature);\r
-\r
- std::set<FeaturePtr>::const_iterator anIt = aMainReferences.begin(),\r
- aLast = aMainReferences.end();\r
-#ifdef DEBUG_REMOVE_FEATURES_RECURSE\r
- std::string aSpacing;\r
- for (int i = 0; i < theRecLevel; i++)\r
- aSpacing.append(" ");\r
-#endif\r
-\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aRefFeature = *anIt;\r
-#ifdef DEBUG_REMOVE_FEATURES_RECURSE\r
- std::cout << aSpacing << " Ref: " << getFeatureInfo(aRefFeature) << std::endl;\r
-#endif\r
- if (theReferences.find(aRefFeature) == theReferences.end())\r
- theReferences.insert(aRefFeature);\r
- addRefsToFeature(aRefFeature, theReferencesMap, theProcessedReferences, theRecLevel, theReferences);\r
- }\r
-}\r
-\r
-// For each feature from the feature list it searches references to the feature and append them\r
-// to the references map. This is a recusive method.\r
-// \param theFeature a feature to find references\r
-// \param theReferencesMap a map of references\r
-// \param theReferences an out container of references\r
-void findReferences(const std::set<FeaturePtr>& theFeatures,\r
- std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,\r
- const bool theUseComposite, const bool theUseRecursion, int theRecLevel)\r
-{\r
- if (theRecLevel > RECURSE_TOP_LEVEL)\r
- return;\r
- theRecLevel++;\r
- std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),\r
- aLast = theFeatures.end();\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aFeature = *anIt;\r
- if (aFeature.get() && theReferences.find(aFeature) == theReferences.end()) {\r
- DocumentPtr aSelFeatureDoc = aFeature->document();\r
- std::set<FeaturePtr> aSelRefFeatures;\r
- aSelFeatureDoc->refsToFeature(aFeature, aSelRefFeatures, false/*do not emit signals*/);\r
- if (theUseComposite) { // do not filter selection\r
- theReferences[aFeature] = aSelRefFeatures;\r
- }\r
- else { // filter references to skip composition features of the current feature\r
- std::set<FeaturePtr> aFilteredFeatures;\r
- std::set<FeaturePtr>::const_iterator anIt = aSelRefFeatures.begin(),\r
- aLast = aSelRefFeatures.end();\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aCFeature = *anIt;\r
- CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCFeature);\r
- if (aComposite.get() && aComposite->isSub(aFeature))\r
- continue; /// composite of the current feature should be skipped\r
- aFilteredFeatures.insert(aCFeature);\r
- }\r
- theReferences[aFeature] = aFilteredFeatures;\r
- }\r
- if (theUseRecursion) {\r
-#ifdef DEBUG_CYCLING_1550\r
- findReferences(aSelRefFeatures, theReferences, theUseComposite, theUseRecursion, theRecLevel);\r
-#else\r
- findReferences(theReferences[aFeature], theReferences, theUseComposite, theUseRecursion,\r
- theRecLevel);\r
-#endif\r
- }\r
- }\r
- }\r
-}\r
-\r
-void findAllReferences(const std::set<FeaturePtr>& theFeatures,\r
- std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,\r
- const bool theUseComposite,\r
- const bool theUseRecursion)\r
-{\r
- // For dependencies, find main_list:\r
- // sk_1(ext_1, vertex_1)\r
- // ext_1(bool_1, sk_3)\r
- // vertex_1()\r
- // sk_2(ext_2)\r
- // ext_2(bool_2)\r
- // sk_3()\r
- // Information: bool_1 is not selected, ext_2(bool_2) exists\r
- // find all referenced features\r
- std::map<FeaturePtr, std::set<FeaturePtr> > aMainList;\r
- int aRecLevel = 0;\r
- findReferences(theFeatures, aMainList, theUseComposite, theUseRecursion, aRecLevel);\r
-\r
-#ifdef DEBUG_REMOVE_FEATURES\r
- printMapInfo(aMainList, "firstDependencies");\r
-#endif\r
- // find all dependencies for each object:\r
- // sk_1(ext_1, vertex_1) + (sk_3, bool_1)\r
- // ext_1(bool_1, sk_3)\r
- // vertex_1()\r
- // sk_2(ext_2) + (bool_1)\r
- // ext_2(bool_1)\r
- // sk_3()\r
- std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aMainList.begin(),\r
- aMainLast = aMainList.end();\r
- for (; aMainIt != aMainLast; aMainIt++) {\r
- FeaturePtr aMainListFeature = aMainIt->first;\r
-\r
- //std::string aName = aMainListFeature->name();\r
- std::set<FeaturePtr> aMainRefList = aMainIt->second;\r
-\r
-#ifdef DEBUG_REMOVE_FEATURES_RECURSE\r
- char aBuf[50];\r
- int n = sprintf(aBuf, "%d", aMainRefList.size());\r
- std::string aSize(aBuf);\r
- std::cout << "_findAllReferences for the Feature: " << getFeatureInfo(aMainListFeature)\r
- << ", references size = " << aSize << std::endl;\r
-#endif\r
- std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(),\r
- aLast = aMainRefList.end();\r
- std::set<FeaturePtr> aResultRefList;\r
- aResultRefList.insert(aMainRefList.begin(), aMainRefList.end());\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aFeature = *anIt;\r
- int aRecLevel = 0;\r
-#ifdef DEBUG_REMOVE_FEATURES_RECURSE\r
- std::cout << " Ref: " << getFeatureInfo(aFeature) << std::endl;\r
-#endif\r
- aRecLevel++;\r
- addRefsToFeature(aFeature, aMainList, theReferences, aRecLevel, aResultRefList/*aMainRefList*/);\r
- }\r
- theReferences[aMainListFeature] = aResultRefList;\r
- }\r
-#ifdef DEBUG_REMOVE_FEATURES_RECURSE\r
- std::cout << std::endl;\r
-#endif\r
-\r
-#ifdef DEBUG_REMOVE_FEATURES\r
- printMapInfo(theReferences, "allDependencies");\r
-#endif\r
-}\r
-\r
-void findRefsToFeatures(const std::set<FeaturePtr>& theFeatures,\r
- const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,\r
- std::set<FeaturePtr>& theFeaturesRefsTo)\r
-{\r
- std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),\r
- aLast = theFeatures.end();\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aFeature = *anIt;\r
- if (theReferences.find(aFeature) == theReferences.end())\r
- continue;\r
- std::set<FeaturePtr> aRefList = theReferences.at(aFeature);\r
- std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();\r
- for (; aRefIt != aRefLast; aRefIt++) {\r
- FeaturePtr aRefFeature = *aRefIt;\r
- CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aRefFeature);\r
- if (aComposite.get() && aComposite->isSub(aFeature))\r
- continue; /// composite of the current feature should not be removed\r
-\r
- if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected\r
- theFeaturesRefsTo.find(aRefFeature) == theFeaturesRefsTo.end()) // it is not added\r
- theFeaturesRefsTo.insert(aRefFeature);\r
- }\r
- }\r
-}\r
-\r
-void getConcealedResults(const FeaturePtr& theFeature,\r
- std::list<std::shared_ptr<ModelAPI_Result> >& theResults)\r
-{\r
- SessionPtr aSession = ModelAPI_Session::get();\r
-\r
- std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;\r
- theFeature->data()->referencesToObjects(aRefs);\r
- std::list<std::pair<std::string, std::list<ObjectPtr> > >::const_iterator\r
- anIt = aRefs.begin(), aLast = aRefs.end();\r
- std::set<ResultPtr> alreadyThere; // to avoid duplications\r
- for (; anIt != aLast; anIt++) {\r
- if (!aSession->validators()->isConcealed(theFeature->getKind(), anIt->first))\r
- continue; // use only concealed attributes\r
- std::list<ObjectPtr> anObjects = (*anIt).second;\r
- std::list<ObjectPtr>::const_iterator anOIt = anObjects.begin(), anOLast = anObjects.end();\r
- for (; anOIt != anOLast; anOIt++) {\r
- ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(*anOIt);\r
- if (aResult && aResult->isConcealed()) {\r
- if (alreadyThere.find(aResult) == alreadyThere.end()) // issue 1712, avoid duplicates\r
- alreadyThere.insert(aResult);\r
- else continue;\r
- theResults.push_back(aResult);\r
- }\r
- }\r
- }\r
-}\r
-\r
-} // namespace ModelAPI_Tools\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModelAPI_Tools.cpp
+// Created: 06 Aug 2014
+// Author: Vitaly Smetannikov
+
+#include "ModelAPI_Tools.h"
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Object.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_Validator.h>
+#include <list>
+#include <map>
+#include <iostream>
+
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+
+#define RECURSE_TOP_LEVEL 50
+
+//#define DEBUG_REMOVE_FEATURES
+//#define DEBUG_REMOVE_FEATURES_RECURSE
+//#define DEBUG_CYCLING_1550
+
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+#include <sstream>
+std::string getFeatureInfo(FeaturePtr theFeature)
+{
+ if (!theFeature.get())
+ return "";
+ //std::ostringstream aPtrStr;
+ //aPtrStr << "[" << theFeature.get() << "] ";
+ std::string aFeatureInfo = /*aPtrStr.str() + */theFeature->name();
+ CompositeFeaturePtr aComposite = ModelAPI_Tools::compositeOwner(theFeature);
+ if (aComposite.get()) {
+ aFeatureInfo = aFeatureInfo + "[in " + aComposite->name() + "]";
+ }
+ return aFeatureInfo;
+}
+#endif
+
+#ifdef DEBUG_REMOVE_FEATURES
+void printMapInfo(const std::map<FeaturePtr, std::set<FeaturePtr> >& theMainList,
+ const std::string& thePrefix)
+{
+ std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = theMainList.begin(),
+ aMainLast = theMainList.end();
+ std::string anInfo;
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aMainListFeature = aMainIt->first;
+ std::set<FeaturePtr> aMainRefList = aMainIt->second;
+ std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(), aLast = aMainRefList.end();
+ std::string aRefsInfo;
+ for (; anIt != aLast; anIt++) {
+ aRefsInfo += (*anIt)->name().c_str();
+ if (anIt != aLast)
+ aRefsInfo += ", ";
+ }
+ if (!aRefsInfo.empty()) {
+ anInfo = anInfo + aMainListFeature->name().c_str() + ": " + aRefsInfo + "\n";
+ }
+ }
+ std::cout << thePrefix.c_str() << " [feature: references to]: \n" << anInfo.c_str() << std::endl;
+}
+
+void printListInfo(const std::set<FeaturePtr>& theMainList,
+ const std::string& thePrefix)
+{
+ std::set<FeaturePtr>::const_iterator aMainIt = theMainList.begin(),
+ aMainLast = theMainList.end();
+ std::string anInfo;
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aRefFeature = *aMainIt;
+ anInfo += aRefFeature->name().c_str();
+ if (aMainIt != aMainLast)
+ anInfo += ", ";
+ }
+ std::cout << thePrefix.c_str() << ": " << anInfo.c_str() << std::endl;
+}
+#endif
+
+namespace ModelAPI_Tools {
+
+std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)
+{
+ return theResult->shape();
+}
+
+void shapesOfType(const FeaturePtr& theFeature,
+ const GeomAPI_Shape::ShapeType& theType,
+ std::set<GeomShapePtr>& theShapes)
+{
+ std::list<ResultPtr> aResults = theFeature->results();
+ std::list<ResultPtr>::const_iterator aRIter = aResults.cbegin();
+ for (; aRIter != aResults.cend(); aRIter++) {
+ ResultPtr aResult = *aRIter;
+ GeomShapePtr aShape = aResult->shape();
+ if (aShape.get() && aShape->shapeType() == theType)
+ theShapes.insert(aShape);
+ }
+}
+
+const char* toString(ModelAPI_ExecState theExecState)
+{
+#define TO_STRING(__NAME__) case __NAME__: return #__NAME__;
+ switch (theExecState) {
+ TO_STRING(ModelAPI_StateDone)
+ TO_STRING(ModelAPI_StateMustBeUpdated)
+ TO_STRING(ModelAPI_StateExecFailed)
+ TO_STRING(ModelAPI_StateInvalidArgument)
+ TO_STRING(ModelAPI_StateNothing)
+ default: return "Unknown ExecState.";
+ }
+#undef TO_STRING
+}
+
+std::string getFeatureError(const FeaturePtr& theFeature)
+{
+ std::string anError;
+ if (!theFeature.get() || !theFeature->data()->isValid() || theFeature->isAction())
+ return anError;
+
+ // to be removed later, this error should be got from the feature
+ if (theFeature->data()->execState() == ModelAPI_StateDone ||
+ theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
+ return anError;
+
+ // set error indication
+ anError = theFeature->error();
+ if (anError.empty()) {
+ bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone
+ || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
+ if (!isDone) {
+ anError = toString(theFeature->data()->execState());
+ // If the feature is Composite and error is StateInvalidArgument,
+ // error text should include error of first invalid sub-feature. Otherwise
+ // it is not clear what is the reason of the invalid argument.
+ if (theFeature->data()->execState() == ModelAPI_StateInvalidArgument) {
+ CompositeFeaturePtr aComposite =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
+ if (aComposite) {
+ for (int i = 0, aSize = aComposite->numberOfSubs(); i < aSize; i++) {
+ FeaturePtr aSubFeature = aComposite->subFeature(i);
+ std::string aSubFeatureError = getFeatureError(aSubFeature);
+ if (!aSubFeatureError.empty()) {
+ anError = anError + " in " + aSubFeature->getKind() + ".\n" + aSubFeatureError;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return anError;
+}
+
+ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup, const std::string& theName)
+{
+ for (int anIndex = 0; anIndex < theDocument->size(theGroup); ++anIndex) {
+ ObjectPtr anObject = theDocument->object(theGroup, anIndex);
+ if (anObject->data()->name() == theName)
+ return anObject;
+ }
+ // not found
+ return ObjectPtr();
+}
+
+bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher,
+ const std::string& theName, double& outValue, ResultParameterPtr& theParam)
+{
+ ObjectPtr aParamObj = objectByName(theDocument, ModelAPI_ResultParameter::group(), theName);
+ theParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+ if (!theParam.get())
+ return false;
+ // avoid usage of parameters created later than the initial parameter
+ if (theSearcher.get() && theDocument->isLater(theDocument->feature(theParam), theSearcher))
+ return false;
+ AttributeDoublePtr aValueAttribute = theParam->data()->real(ModelAPI_ResultParameter::VALUE());
+ outValue = aValueAttribute->value();
+ return true;
+}
+
+bool findVariable(FeaturePtr theSearcher, const std::string& theName, double& outValue, ResultParameterPtr& theParam,
+ const DocumentPtr& theDocument)
+{
+ SessionPtr aSession = ModelAPI_Session::get();
+ std::list<DocumentPtr> aDocList;
+ DocumentPtr aDocument = theDocument.get() ? theDocument : aSession->activeDocument();
+ if (findVariable(aDocument, theSearcher, theName, outValue, theParam))
+ return true;
+ DocumentPtr aRootDocument = aSession->moduleDocument();
+ if (aDocument != aRootDocument) {
+ // any parameters in PartSet is okindependently on the Part position (issu #1504)
+ if (findVariable(aRootDocument, FeaturePtr(), theName, outValue, theParam))
+ return true;
+ }
+ return false;
+}
+
+ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub)
+{
+ if (theMain != theSub) { // to optimize and avoid of crash on partset document close (don't touch the sub-document structure)
+ for (int a = theMain->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) {
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(
+ theMain->object(ModelAPI_ResultPart::group(), a));
+ if (aPart && aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value() == theSub) {
+ return aPart;
+ }
+ }
+ }
+ return ResultPtr();
+}
+
+FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub)
+{
+ if (theMain != theSub) { // to optimize and avoid of crash on partset document close (don't touch the sub-document structure)
+ for (int a = theMain->size(ModelAPI_Feature::group()) - 1; a >= 0; a--) {
+ FeaturePtr aPartFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(
+ theMain->object(ModelAPI_Feature::group(), a));
+ if (aPartFeat.get()) {
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResList = aPartFeat->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResList.begin();
+ for(; aRes != aResList.end(); aRes++) {
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes);
+ if (aPart.get()) {
+ if (aPart->isActivated() && aPart->partDoc() == theSub)
+ return aPartFeat;
+ } else break; // if the first is not Part, others are also not
+ }
+ }
+ }
+ }
+ return FeaturePtr();
+}
+
+CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature)
+{
+ if (theFeature.get() && theFeature->data()->isValid()) {
+ const std::set<std::shared_ptr<ModelAPI_Attribute> >& aRefs = theFeature->data()->refsToMe();
+ std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aRefIter = aRefs.begin();
+ for(; aRefIter != aRefs.end(); aRefIter++) {
+ CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>
+ ((*aRefIter)->owner());
+ if (aComp.get() && aComp->data()->isValid() && aComp->isSub(theFeature))
+ return aComp;
+ }
+ }
+ return CompositeFeaturePtr(); // not found
+}
+
+ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub)
+{
+ ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theSub);
+ if (aBody.get()) {
+ FeaturePtr aFeatureOwner = aBody->document()->feature(aBody);
+ if (aFeatureOwner.get()) {
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter =
+ aFeatureOwner->results().cbegin();
+ for(; aResIter != aFeatureOwner->results().cend(); aResIter++) {
+ ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aResIter);
+ if (aComp && aComp->isSub(aBody))
+ return aComp;
+ }
+ }
+ }
+ return ResultCompSolidPtr(); // not found
+}
+
+bool hasSubResults(const ResultPtr& theResult)
+{
+ ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theResult);
+ return aCompSolid.get() && aCompSolid->numberOfSubs() > 0;
+}
+
+void allResults(const FeaturePtr& theFeature, std::list<ResultPtr>& theResults)
+{
+ if (!theFeature.get()) // safety: for empty feature no results
+ return;
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
+ for (; aRIter != aResults.cend(); aRIter++) {
+ theResults.push_back(*aRIter);
+ // iterate sub-bodies of compsolid
+ ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aRIter);
+ if (aComp.get()) {
+ int aNumSub = aComp->numberOfSubs();
+ for(int a = 0; a < aNumSub; a++) {
+ theResults.push_back(aComp->subResult(a));
+ }
+ }
+ }
+}
+
+//******************************************************************
+bool allDocumentsActivated(std::string& theNotActivatedNames)
+{
+ theNotActivatedNames = "";
+ bool anAllPartActivated = true;
+
+ DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+ int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+ for (int i = 0; i < aSize; i++) {
+ ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), i);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
+ if (!aPart->isActivated()) {
+ anAllPartActivated = false;
+ if (!theNotActivatedNames.empty())
+ theNotActivatedNames += ", ";
+ theNotActivatedNames += aObject->data()->name().c_str();
+ }
+ }
+ return anAllPartActivated;
+}
+
+bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay,
+ const bool theUseComposite,
+ const bool theUseRecursion)
+{
+#ifdef DEBUG_REMOVE_FEATURES
+ printListInfo(theFeatures, "selection: ");
+#endif
+
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ ModelAPI_Tools::findAllReferences(theFeatures, aReferences, theUseComposite, theUseRecursion);
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(aReferences, "allDependencies: ");
+#endif
+
+ std::set<FeaturePtr> aFeaturesRefsTo;
+ ModelAPI_Tools::findRefsToFeatures(theFeatures, aReferences, aFeaturesRefsTo);
+#ifdef DEBUG_REMOVE_FEATURES
+ printListInfo(aFeaturesRefsTo, "references: ");
+#endif
+
+ std::set<FeaturePtr> aFeatures = theFeatures;
+ if (!aFeaturesRefsTo.empty())
+ aFeatures.insert(aFeaturesRefsTo.begin(), aFeaturesRefsTo.end());
+#ifdef DEBUG_REMOVE_FEATURES
+ printListInfo(aFeatures, "removeFeatures: ");
+#endif
+
+ return ModelAPI_Tools::removeFeatures(aFeatures, false);
+}
+
+bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay)
+{
+ bool isDone = false;
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (aFeature.get()) {
+ DocumentPtr aDoc = aFeature->document();
+ // flush REDISPLAY signal after remove feature
+ aDoc->removeFeature(aFeature);
+ isDone = true;
+ }
+ }
+ if (isDone && theFlushRedisplay) {
+ // the redisplay signal should be flushed in order to erase the feature presentation in the viewer
+ // if should be done after removeFeature() of document
+ Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ }
+ return true;
+}
+
+// Fills the references list by all references of the feature from the references map.
+// This is a recusive method to find references by next found feature in the map of references.
+// \param theFeature a feature to find references
+// \param theReferencesMap a map of references
+// \param theReferences an out container of references
+void addRefsToFeature(const FeaturePtr& theFeature,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferencesMap,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theProcessedReferences,
+ int theRecLevel,
+ std::set<FeaturePtr>& theReferences)
+{
+ if (theRecLevel > RECURSE_TOP_LEVEL)
+ return;
+ theRecLevel++;
+
+ // if the feature is already processed, get the ready references from the map
+ if (theProcessedReferences.find(theFeature) != theProcessedReferences.end()) {
+ std::set<FeaturePtr> aReferences = theProcessedReferences.at(theFeature);
+ theReferences.insert(aReferences.begin(), aReferences.end());
+ return;
+ }
+
+ if (theReferencesMap.find(theFeature) == theReferencesMap.end())
+ return; // this feature is not in the selection list, so exists without references to it
+ std::set<FeaturePtr> aMainReferences = theReferencesMap.at(theFeature);
+
+ std::set<FeaturePtr>::const_iterator anIt = aMainReferences.begin(),
+ aLast = aMainReferences.end();
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ std::string aSpacing;
+ for (int i = 0; i < theRecLevel; i++)
+ aSpacing.append(" ");
+#endif
+
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aRefFeature = *anIt;
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ std::cout << aSpacing << " Ref: " << getFeatureInfo(aRefFeature) << std::endl;
+#endif
+ if (theReferences.find(aRefFeature) == theReferences.end())
+ theReferences.insert(aRefFeature);
+ addRefsToFeature(aRefFeature, theReferencesMap, theProcessedReferences, theRecLevel, theReferences);
+ }
+}
+
+// For each feature from the feature list it searches references to the feature and append them
+// to the references map. This is a recusive method.
+// \param theFeature a feature to find references
+// \param theReferencesMap a map of references
+// \param theReferences an out container of references
+void findReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite, const bool theUseRecursion, int theRecLevel)
+{
+ if (theRecLevel > RECURSE_TOP_LEVEL)
+ return;
+ theRecLevel++;
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (aFeature.get() && theReferences.find(aFeature) == theReferences.end()) {
+ DocumentPtr aSelFeatureDoc = aFeature->document();
+ std::set<FeaturePtr> aSelRefFeatures;
+ aSelFeatureDoc->refsToFeature(aFeature, aSelRefFeatures, false/*do not emit signals*/);
+ if (theUseComposite) { // do not filter selection
+ theReferences[aFeature] = aSelRefFeatures;
+ }
+ else { // filter references to skip composition features of the current feature
+ std::set<FeaturePtr> aFilteredFeatures;
+ std::set<FeaturePtr>::const_iterator anIt = aSelRefFeatures.begin(),
+ aLast = aSelRefFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aCFeature = *anIt;
+ CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCFeature);
+ if (aComposite.get() && aComposite->isSub(aFeature))
+ continue; /// composite of the current feature should be skipped
+ aFilteredFeatures.insert(aCFeature);
+ }
+ theReferences[aFeature] = aFilteredFeatures;
+ }
+ if (theUseRecursion) {
+#ifdef DEBUG_CYCLING_1550
+ findReferences(aSelRefFeatures, theReferences, theUseComposite, theUseRecursion, theRecLevel);
+#else
+ findReferences(theReferences[aFeature], theReferences, theUseComposite, theUseRecursion,
+ theRecLevel);
+#endif
+ }
+ }
+ }
+}
+
+void findAllReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite,
+ const bool theUseRecursion)
+{
+ // For dependencies, find main_list:
+ // sk_1(ext_1, vertex_1)
+ // ext_1(bool_1, sk_3)
+ // vertex_1()
+ // sk_2(ext_2)
+ // ext_2(bool_2)
+ // sk_3()
+ // Information: bool_1 is not selected, ext_2(bool_2) exists
+ // find all referenced features
+ std::map<FeaturePtr, std::set<FeaturePtr> > aMainList;
+ int aRecLevel = 0;
+ findReferences(theFeatures, aMainList, theUseComposite, theUseRecursion, aRecLevel);
+
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(aMainList, "firstDependencies");
+#endif
+ // find all dependencies for each object:
+ // sk_1(ext_1, vertex_1) + (sk_3, bool_1)
+ // ext_1(bool_1, sk_3)
+ // vertex_1()
+ // sk_2(ext_2) + (bool_1)
+ // ext_2(bool_1)
+ // sk_3()
+ std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aMainList.begin(),
+ aMainLast = aMainList.end();
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aMainListFeature = aMainIt->first;
+
+ //std::string aName = aMainListFeature->name();
+ std::set<FeaturePtr> aMainRefList = aMainIt->second;
+
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ char aBuf[50];
+ int n = sprintf(aBuf, "%d", aMainRefList.size());
+ std::string aSize(aBuf);
+ std::cout << "_findAllReferences for the Feature: " << getFeatureInfo(aMainListFeature)
+ << ", references size = " << aSize << std::endl;
+#endif
+ std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(),
+ aLast = aMainRefList.end();
+ std::set<FeaturePtr> aResultRefList;
+ aResultRefList.insert(aMainRefList.begin(), aMainRefList.end());
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ int aRecLevel = 0;
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ std::cout << " Ref: " << getFeatureInfo(aFeature) << std::endl;
+#endif
+ aRecLevel++;
+ addRefsToFeature(aFeature, aMainList, theReferences, aRecLevel, aResultRefList/*aMainRefList*/);
+ }
+ theReferences[aMainListFeature] = aResultRefList;
+ }
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ std::cout << std::endl;
+#endif
+
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(theReferences, "allDependencies");
+#endif
+}
+
+void findRefsToFeatures(const std::set<FeaturePtr>& theFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ std::set<FeaturePtr>& theFeaturesRefsTo)
+{
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (theReferences.find(aFeature) == theReferences.end())
+ continue;
+ std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
+ std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
+ for (; aRefIt != aRefLast; aRefIt++) {
+ FeaturePtr aRefFeature = *aRefIt;
+ CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aRefFeature);
+ if (aComposite.get() && aComposite->isSub(aFeature))
+ continue; /// composite of the current feature should not be removed
+
+ if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
+ theFeaturesRefsTo.find(aRefFeature) == theFeaturesRefsTo.end()) // it is not added
+ theFeaturesRefsTo.insert(aRefFeature);
+ }
+ }
+}
+
+void getConcealedResults(const FeaturePtr& theFeature,
+ std::list<std::shared_ptr<ModelAPI_Result> >& theResults)
+{
+ SessionPtr aSession = ModelAPI_Session::get();
+
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+ theFeature->data()->referencesToObjects(aRefs);
+ std::list<std::pair<std::string, std::list<ObjectPtr> > >::const_iterator
+ anIt = aRefs.begin(), aLast = aRefs.end();
+ std::set<ResultPtr> alreadyThere; // to avoid duplications
+ for (; anIt != aLast; anIt++) {
+ if (!aSession->validators()->isConcealed(theFeature->getKind(), anIt->first))
+ continue; // use only concealed attributes
+ std::list<ObjectPtr> anObjects = (*anIt).second;
+ std::list<ObjectPtr>::const_iterator anOIt = anObjects.begin(), anOLast = anObjects.end();
+ for (; anOIt != anOLast; anOIt++) {
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(*anOIt);
+ if (aResult && aResult->isConcealed()) {
+ if (alreadyThere.find(aResult) == alreadyThere.end()) // issue 1712, avoid duplicates
+ alreadyThere.insert(aResult);
+ else continue;
+ theResults.push_back(aResult);
+ }
+ }
+ }
+}
+
+} // namespace ModelAPI_Tools
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModelAPI_Tools.h\r
-// Created: 06 Aug 2014\r
-// Author: Vitaly Smetannikov\r
-\r
-#ifndef ModelAPI_Tools_HeaderFile\r
-#define ModelAPI_Tools_HeaderFile\r
-\r
-#include "ModelAPI.h"\r
-\r
-#include <ModelAPI_CompositeFeature.h>\r
-#include <ModelAPI_Document.h>\r
-#include <ModelAPI_Feature.h>\r
-#include <ModelAPI_Result.h>\r
-#include <ModelAPI_ResultParameter.h>\r
-#include <ModelAPI_ResultCompSolid.h>\r
-\r
-#include <GeomAPI_Shape.h>\r
-\r
-#include <vector>\r
-#include <map>\r
-#include <set>\r
-\r
-namespace ModelAPI_Tools {\r
-/// Returns shape from the given Result object\r
-MODELAPI_EXPORT std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult);\r
-\r
-/// Creates a container of shape of the feature results satisfied the given shape type\r
-/// \param theFeature a source feature\r
-/// \param theType shape type\r
-/// \param an output container for shapes\r
-MODELAPI_EXPORT void shapesOfType(const FeaturePtr& theFeature,\r
- const GeomAPI_Shape::ShapeType& theType,\r
- std::set<GeomShapePtr>& theShapes);\r
-\r
-/*! Returns the feature error generated according to feature error and exec state\r
- * \param theFeature a feature\r
- * \return error value or empty string\r
- */\r
-MODELAPI_EXPORT std::string getFeatureError(const FeaturePtr& theFeature);\r
-\r
-/*!\r
- * Searches for variable with name \param theName in \param theDocument. \r
- * If found, set it value in the \param outValue and returns true.\r
- * theSearcher must be located later in the history than the found variable.\r
- */\r
-MODELAPI_EXPORT bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher,\r
- const std::string& theName, double& outValue, ResultParameterPtr& theParam);\r
-\r
-/*!\r
- * Searches for variable with name \param theName in the active document (Part), when\r
- * in the root document (PartSet). If found, set it value in the \param outValue\r
- * and returns true. If \param theDocument is empty active document is used.\r
- * theSearcher must be located later in the history than the found variable.\r
- */\r
-MODELAPI_EXPORT bool findVariable(FeaturePtr theSearcher, const std::string& theName,\r
- double& outValue, ResultParameterPtr& theParam,\r
- const DocumentPtr& theDocument = DocumentPtr());\r
-\r
-/*!\r
- * Searches for Part result that contains the reference to the given document.\r
- * The result must be presented in the tree.\r
- * \param theMain document that contains the searched feature\r
- * \param theSub document that is searched, the resulting feature references to it\r
- * \returns null if not found\r
- */\r
-MODELAPI_EXPORT ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub);\r
-\r
-/*!\r
- * Searches for Part the feature that contains in result the reference to the given document.\r
- * The result may be disabled.\r
- * \param theMain document that contains the searched feature\r
- * \param theSub document that is searched, the resulting feature references to it\r
- * \returns null if not found\r
- */\r
-MODELAPI_EXPORT FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub);\r
-\r
-/*!\r
- * Returns the composite feature - parent of this feature.\r
- * \param theFeature the sub-element of composite\r
- * \returns null if it is not sub-element of composite\r
- */\r
-MODELAPI_EXPORT CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature);\r
-\r
-/*!\r
- * Returns the compsolid result - parent of this result.\r
- * \param theSub the sub-element of comp-solid\r
- * \returns null if it is not sub-element of composite\r
- */\r
-MODELAPI_EXPORT ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub);\r
-\r
-/*!\r
-* Returns true if the result contains a not empty list of sub results. It processes result compsolid.\r
-* \param theResult a result object\r
-* \returns boolean value\r
-*/\r
-MODELAPI_EXPORT bool hasSubResults(const ResultPtr& theResult);\r
-\r
-/*!\r
-* Adds the results of the given feature to theResults list: including disabled and sub-results\r
-*/\r
-MODELAPI_EXPORT void allResults(const FeaturePtr& theFeature, std::list<ResultPtr>& theResults);\r
-\r
-/*!\r
- Returns true if there are no parts in the document, which are not activated\r
- \param theNotActivatedNames out string which contains not activated names\r
- \return a boolean value\r
- */\r
-MODELAPI_EXPORT bool allDocumentsActivated(std::string& theNotActivatedNames);\r
-\r
-\r
-/*! Removes features from the document\r
-* \param theFeatures a list of features to be removed\r
-* \param theFlushRedisplay a boolean value if the redisplay signal should be flushed\r
-* \return true if at least one feature is removed\r
-*/\r
-MODELAPI_EXPORT bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,\r
- const bool theFlushRedisplay = false,\r
- const bool theUseComposite = false,\r
- const bool theUseRecursion = true);\r
-\r
-/*! Removes features from the document\r
-* \param theFeatures a list of features to be removed\r
-* \param theFlushRedisplay a boolean value if the redisplay signal should be flushed\r
-* \return true if at least one feature is removed\r
-*/\r
-MODELAPI_EXPORT bool removeFeatures(const std::set<FeaturePtr>& theFeatures,\r
- const bool theFlushRedisplay);\r
-\r
-/*! Build a map of references for the given set of features\r
-* \param theFeatures a list of features\r
-* \param theReferences a map of all references to the features\r
-* \param theUseComposite state if the composite features of the reference should be in the map\r
-* \param theUseRecursion state if references for features out of the sources feature\r
- list are put into the result container. E.g. if theFeatures contains "Sketch_2", map will\r
- contain references to this feature also.\r
-*/\r
-MODELAPI_EXPORT void findAllReferences(const std::set<FeaturePtr>& theFeatures,\r
- std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,\r
- const bool theUseComposite = true,\r
- const bool theUseRecursion = true);\r
-\r
-/*! In the map of references find all features referenced to the source feature\r
-* \param theFeatures a list of features to find references\r
-* \param theReferences a map of all references to the features\r
-* \param theFeaturesRefsTo an out list of referenced features\r
-*/\r
-MODELAPI_EXPORT void findRefsToFeatures(const std::set<FeaturePtr>& aFeatures,\r
- const std::map<FeaturePtr, std::set<FeaturePtr> >& aReferences,\r
- std::set<FeaturePtr>& aFeaturesRefsTo);\r
-\r
-/*! Finds referenced of the feature to objects and collects concealed results.\r
-* \param theFeatures a model feature\r
-* \param theResults container for concealed results. It has no duplications\r
-*/\r
-MODELAPI_EXPORT void getConcealedResults(const FeaturePtr& theFeature,\r
- std::list<std::shared_ptr<ModelAPI_Result> >& theResults);\r
-}\r
-\r
-#endif\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModelAPI_Tools.h
+// Created: 06 Aug 2014
+// Author: Vitaly Smetannikov
+
+#ifndef ModelAPI_Tools_HeaderFile
+#define ModelAPI_Tools_HeaderFile
+
+#include "ModelAPI.h"
+
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Result.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_ResultCompSolid.h>
+
+#include <GeomAPI_Shape.h>
+
+#include <vector>
+#include <map>
+#include <set>
+
+namespace ModelAPI_Tools {
+/// Returns shape from the given Result object
+MODELAPI_EXPORT std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult);
+
+/// Creates a container of shape of the feature results satisfied the given shape type
+/// \param theFeature a source feature
+/// \param theType shape type
+/// \param an output container for shapes
+MODELAPI_EXPORT void shapesOfType(const FeaturePtr& theFeature,
+ const GeomAPI_Shape::ShapeType& theType,
+ std::set<GeomShapePtr>& theShapes);
+
+/*! Returns the feature error generated according to feature error and exec state
+ * \param theFeature a feature
+ * \return error value or empty string
+ */
+MODELAPI_EXPORT std::string getFeatureError(const FeaturePtr& theFeature);
+
+/*!
+ * Searches for variable with name \param theName in \param theDocument.
+ * If found, set it value in the \param outValue and returns true.
+ * theSearcher must be located later in the history than the found variable.
+ */
+MODELAPI_EXPORT bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher,
+ const std::string& theName, double& outValue, ResultParameterPtr& theParam);
+
+/*!
+ * Searches for variable with name \param theName in the active document (Part), when
+ * in the root document (PartSet). If found, set it value in the \param outValue
+ * and returns true. If \param theDocument is empty active document is used.
+ * theSearcher must be located later in the history than the found variable.
+ */
+MODELAPI_EXPORT bool findVariable(FeaturePtr theSearcher, const std::string& theName,
+ double& outValue, ResultParameterPtr& theParam,
+ const DocumentPtr& theDocument = DocumentPtr());
+
+/*!
+ * Searches for Part result that contains the reference to the given document.
+ * The result must be presented in the tree.
+ * \param theMain document that contains the searched feature
+ * \param theSub document that is searched, the resulting feature references to it
+ * \returns null if not found
+ */
+MODELAPI_EXPORT ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub);
+
+/*!
+ * Searches for Part the feature that contains in result the reference to the given document.
+ * The result may be disabled.
+ * \param theMain document that contains the searched feature
+ * \param theSub document that is searched, the resulting feature references to it
+ * \returns null if not found
+ */
+MODELAPI_EXPORT FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub);
+
+/*!
+ * Returns the composite feature - parent of this feature.
+ * \param theFeature the sub-element of composite
+ * \returns null if it is not sub-element of composite
+ */
+MODELAPI_EXPORT CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature);
+
+/*!
+ * Returns the compsolid result - parent of this result.
+ * \param theSub the sub-element of comp-solid
+ * \returns null if it is not sub-element of composite
+ */
+MODELAPI_EXPORT ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub);
+
+/*!
+* Returns true if the result contains a not empty list of sub results. It processes result compsolid.
+* \param theResult a result object
+* \returns boolean value
+*/
+MODELAPI_EXPORT bool hasSubResults(const ResultPtr& theResult);
+
+/*!
+* Adds the results of the given feature to theResults list: including disabled and sub-results
+*/
+MODELAPI_EXPORT void allResults(const FeaturePtr& theFeature, std::list<ResultPtr>& theResults);
+
+/*!
+ Returns true if there are no parts in the document, which are not activated
+ \param theNotActivatedNames out string which contains not activated names
+ \return a boolean value
+ */
+MODELAPI_EXPORT bool allDocumentsActivated(std::string& theNotActivatedNames);
+
+
+/*! Removes features from the document
+* \param theFeatures a list of features to be removed
+* \param theFlushRedisplay a boolean value if the redisplay signal should be flushed
+* \return true if at least one feature is removed
+*/
+MODELAPI_EXPORT bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay = false,
+ const bool theUseComposite = false,
+ const bool theUseRecursion = true);
+
+/*! Removes features from the document
+* \param theFeatures a list of features to be removed
+* \param theFlushRedisplay a boolean value if the redisplay signal should be flushed
+* \return true if at least one feature is removed
+*/
+MODELAPI_EXPORT bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay);
+
+/*! Build a map of references for the given set of features
+* \param theFeatures a list of features
+* \param theReferences a map of all references to the features
+* \param theUseComposite state if the composite features of the reference should be in the map
+* \param theUseRecursion state if references for features out of the sources feature
+ list are put into the result container. E.g. if theFeatures contains "Sketch_2", map will
+ contain references to this feature also.
+*/
+MODELAPI_EXPORT void findAllReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite = true,
+ const bool theUseRecursion = true);
+
+/*! In the map of references find all features referenced to the source feature
+* \param theFeatures a list of features to find references
+* \param theReferences a map of all references to the features
+* \param theFeaturesRefsTo an out list of referenced features
+*/
+MODELAPI_EXPORT void findRefsToFeatures(const std::set<FeaturePtr>& aFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& aReferences,
+ std::set<FeaturePtr>& aFeaturesRefsTo);
+
+/*! Finds referenced of the feature to objects and collects concealed results.
+* \param theFeatures a model feature
+* \param theResults container for concealed results. It has no duplications
+*/
+MODELAPI_EXPORT void getConcealedResults(const FeaturePtr& theFeature,
+ std::list<std::shared_ptr<ModelAPI_Result> >& theResults);
+}
+
+#endif
-from ModelAPI import *\r
-aSession = ModelAPI_Session.get()\r
-aDoc = aSession.moduleDocument()\r
-assert(not aSession.canUndo())\r
-assert(not aSession.canRedo())\r
-\r
-aSession.startOperation()\r
-aFeature = aDoc.addFeature("Point")\r
-# Since validators are introduced we have to initialize all\r
-# the feature's attributes\r
-# aFeature.string("creation_method").setValue("by_xyz")\r
-aFeature.real("x").setValue(1.)\r
-aFeature.real("y").setValue(-1.)\r
-aFeature.real("z").setValue(0.)\r
-aFeatureName = aFeature.name()\r
-# "2" is because Origin is the first point\r
-assert(aFeatureName == "Point_2")\r
-\r
-aFeature.execute()\r
-aSession.finishOperation()\r
-\r
-assert(aDoc.size("Construction") == 8)\r
-assert(aSession.canUndo())\r
-assert(not aSession.canRedo())\r
-\r
-aSession.undo()\r
-assert(aDoc.size("Construction") == 7)\r
-assert(not aSession.canUndo())\r
-assert(aSession.canRedo())\r
-\r
-aSession.redo()\r
-assert(aDoc.size("Construction") == 8)\r
-assert(aSession.canUndo())\r
-assert(not aSession.canRedo())\r
-\r
-import model\r
-assert(model.checkPythonDump())\r
+from ModelAPI import *
+aSession = ModelAPI_Session.get()
+aDoc = aSession.moduleDocument()
+assert(not aSession.canUndo())
+assert(not aSession.canRedo())
+
+aSession.startOperation()
+aFeature = aDoc.addFeature("Point")
+# Since validators are introduced we have to initialize all
+# the feature's attributes
+# aFeature.string("creation_method").setValue("by_xyz")
+aFeature.real("x").setValue(1.)
+aFeature.real("y").setValue(-1.)
+aFeature.real("z").setValue(0.)
+aFeatureName = aFeature.name()
+# "2" is because Origin is the first point
+assert(aFeatureName == "Point_2")
+
+aFeature.execute()
+aSession.finishOperation()
+
+assert(aDoc.size("Construction") == 8)
+assert(aSession.canUndo())
+assert(not aSession.canRedo())
+
+aSession.undo()
+assert(aDoc.size("Construction") == 7)
+assert(not aSession.canUndo())
+assert(aSession.canRedo())
+
+aSession.redo()
+assert(aDoc.size("Construction") == 8)
+assert(aSession.canUndo())
+assert(not aSession.canRedo())
+
+import model
+assert(model.checkPythonDump())
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-#ifndef MODULEBASE_H\r
-#define MODULEBASE_H\r
-\r
-#if defined MODULEBASE_EXPORTS\r
-#if defined WIN32\r
-#define MODULEBASE_EXPORT __declspec( dllexport )\r
-#else\r
-#define MODULEBASE_EXPORT\r
-#endif\r
-#else\r
-#if defined WIN32\r
-#define MODULEBASE_EXPORT __declspec( dllimport )\r
-#else\r
-#define MODULEBASE_EXPORT\r
-#endif\r
-#endif\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#ifndef MODULEBASE_H
+#define MODULEBASE_H
+
+#if defined MODULEBASE_EXPORTS
+#if defined WIN32
+#define MODULEBASE_EXPORT __declspec( dllexport )
+#else
+#define MODULEBASE_EXPORT
+#endif
+#else
+#if defined WIN32
+#define MODULEBASE_EXPORT __declspec( dllimport )
+#else
+#define MODULEBASE_EXPORT
+#endif
+#endif
+
#endif //MODULEBASE_H\r
\ No newline at end of file
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_FilterValidated.cpp\r
-// Created: 17 Mar 2015\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#include "ModuleBase_FilterValidated.h"\r
-#include "ModuleBase_IWorkshop.h"\r
-#include "ModuleBase_IViewer.h"\r
-\r
-#include <ModuleBase_IModule.h>\r
-#include <ModuleBase_IPropertyPanel.h>\r
-#include <ModuleBase_ISelection.h>\r
-#include <ModuleBase_Operation.h>\r
-#include <ModuleBase_WidgetValidated.h>\r
-#include <ModuleBase_WidgetValidator.h>\r
-#include <ModuleBase_ViewerPrs.h>\r
-#include <ModuleBase_Tools.h>\r
-\r
-IMPLEMENT_STANDARD_HANDLE(ModuleBase_FilterValidated, SelectMgr_Filter);\r
-IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_FilterValidated, SelectMgr_Filter);\r
-\r
-Standard_Boolean ModuleBase_FilterValidated::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const\r
-{\r
- bool aValid = true;\r
- ModuleBase_Operation* anOperation = myWorkshop->module()->currentOperation();\r
- if (anOperation) {\r
- ModuleBase_IViewer* aViewer = myWorkshop->viewer();\r
- Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();\r
-\r
- ModuleBase_Tools::selectionInfo(aContext, "ModuleBase_FilterValidated::IsOk");\r
-\r
- ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();\r
- ModuleBase_ModelWidget* aCurrentWidget = aPanel->preselectionWidget();\r
- if (!aCurrentWidget)\r
- aCurrentWidget = myWorkshop->module()->activeWidget();\r
- if (aCurrentWidget) {\r
- ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs());\r
- myWorkshop->selection()->fillPresentation(aPrs, theOwner);\r
- ModuleBase_WidgetValidated* aWidgetValidated = dynamic_cast<ModuleBase_WidgetValidated*>\r
- (aCurrentWidget);\r
- if (aWidgetValidated)\r
- aValid = !aWidgetValidated || aWidgetValidated->isValidSelection(aPrs);\r
- else{\r
- ModuleBase_WidgetValidator* aWidgetValidator = aCurrentWidget->widgetValidator();\r
- if (aWidgetValidator)\r
- aValid = aWidgetValidator->isValidSelection(aPrs);\r
- }\r
- }\r
- }\r
-\r
-#ifdef DEBUG_FILTERS\r
- qDebug(QString("ModuleBase_FilterValidated::IsOk = %1").arg(aValid).toStdString().c_str());\r
-#endif\r
- return aValid;\r
-}\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_FilterValidated.cpp
+// Created: 17 Mar 2015
+// Author: Natalia ERMOLAEVA
+
+#include "ModuleBase_FilterValidated.h"
+#include "ModuleBase_IWorkshop.h"
+#include "ModuleBase_IViewer.h"
+
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ISelection.h>
+#include <ModuleBase_Operation.h>
+#include <ModuleBase_WidgetValidated.h>
+#include <ModuleBase_WidgetValidator.h>
+#include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_Tools.h>
+
+IMPLEMENT_STANDARD_HANDLE(ModuleBase_FilterValidated, SelectMgr_Filter);
+IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_FilterValidated, SelectMgr_Filter);
+
+Standard_Boolean ModuleBase_FilterValidated::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const
+{
+ bool aValid = true;
+ ModuleBase_Operation* anOperation = myWorkshop->module()->currentOperation();
+ if (anOperation) {
+ ModuleBase_IViewer* aViewer = myWorkshop->viewer();
+ Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+
+ ModuleBase_Tools::selectionInfo(aContext, "ModuleBase_FilterValidated::IsOk");
+
+ ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+ ModuleBase_ModelWidget* aCurrentWidget = aPanel->preselectionWidget();
+ if (!aCurrentWidget)
+ aCurrentWidget = myWorkshop->module()->activeWidget();
+ if (aCurrentWidget) {
+ ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs());
+ myWorkshop->selection()->fillPresentation(aPrs, theOwner);
+ ModuleBase_WidgetValidated* aWidgetValidated = dynamic_cast<ModuleBase_WidgetValidated*>
+ (aCurrentWidget);
+ if (aWidgetValidated)
+ aValid = !aWidgetValidated || aWidgetValidated->isValidSelection(aPrs);
+ else{
+ ModuleBase_WidgetValidator* aWidgetValidator = aCurrentWidget->widgetValidator();
+ if (aWidgetValidator)
+ aValid = aWidgetValidator->isValidSelection(aPrs);
+ }
+ }
+ }
+
+#ifdef DEBUG_FILTERS
+ qDebug(QString("ModuleBase_FilterValidated::IsOk = %1").arg(aValid).toStdString().c_str());
+#endif
+ return aValid;
+}
+
- // Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-#ifndef ModuleBase_IModule_H\r
-#define ModuleBase_IModule_H\r
-\r
-#include "ModuleBase.h"\r
-#include "ModuleBase_IWorkshop.h"\r
-\r
-#include <ModelAPI_Feature.h>\r
-#include <ModelAPI_Attribute.h>\r
-\r
-#include <GeomAPI_Shape.h>\r
-#include <GeomAPI_ICustomPrs.h>\r
-\r
-#include <QString>\r
-#include <QObject>\r
-#include <QMap>\r
-#include <QList>\r
-\r
-#include <string>\r
-#include <vector>\r
-#include <map>\r
-\r
-class QAction;\r
-class QMouseEvent;\r
-class QKeyEvent;\r
-class QMenu;\r
-class Config_WidgetAPI;\r
-class ModuleBase_ModelWidget;\r
-class ModuleBase_Operation;\r
-class ModuleBase_IWorkshop;\r
-class ModelAPI_Result;\r
-\r
-class Handle_AIS_InteractiveObject;\r
-\r
-/**\r
- * \ingroup GUI\r
- * Interface to a module\r
- */\r
-class MODULEBASE_EXPORT ModuleBase_IModule : public QObject\r
-{\r
- Q_OBJECT\r
- public:\r
- /// enumeration to know which objects should be customized\r
- enum ModuleBase_CustomizeFlag {\r
- CustomizeArguments = 0, /// references of other objects referenced to the current feature\r
- CustomizeResults, /// results of the current feature\r
- CustomizeHighlightedObjects /// highlighted objects of the active widget\r
- };\r
-\r
- /// Constructor\r
- /// \param theParent instance of workshop interface\r
- ModuleBase_IModule(ModuleBase_IWorkshop* theParent);\r
-\r
- virtual ~ModuleBase_IModule() {}\r
-\r
- /// Add default selection filters of the module to the current viewer\r
- virtual void activateSelectionFilters() {};\r
-\r
- /// Remove default selection filters of the module from the current viewer\r
- virtual void deactivateSelectionFilters() {};\r
-\r
- /// Stores the current selection\r
- virtual void storeSelection() {};\r
-\r
- /// Restores the current selection\r
- virtual void restoreSelection() {};\r
-\r
- /// Reads description of features from XML file \r
- virtual void createFeatures();\r
-\r
- /// Called on creation of menu item in desktop\r
- virtual void actionCreated(QAction*);\r
-\r
- /// Launching of a edit operation on the feature \r
- /// \param theFeature feature for editing\r
- virtual void editFeature(FeaturePtr theFeature);\r
-\r
- /// Returns true if the operation can be committed. Result in default implementation is true.\r
- /// \return boolean value\r
- virtual bool canCommitOperation() const { return true; }\r
-\r
- /// Creates an operation and send it to loop\r
- /// \param theCmdId the operation name\r
- virtual void launchOperation(const QString& theCmdId);\r
-\r
- /// Executes feature as a modal dialog box\r
- /// \param theCmdId the operation name\r
- virtual void launchModal(const QString& theCmdId);\r
-\r
- /// Realizes some functionality by an operation start\r
- /// \param theOperation a started operation\r
- virtual void operationStarted(ModuleBase_Operation* theOperation) {}\r
-\r
- /// Realizes some functionality by an operation resume\r
- /// By default it emits operationResumed signal\r
- /// \param theOperation a resumed operation\r
- virtual void operationResumed(ModuleBase_Operation* theOperation);\r
-\r
- /// Realizes some functionality by an operation stop\r
- virtual void operationStopped(ModuleBase_Operation* theOperation) {}\r
-\r
- /// Realizes some functionality by an operation commit\r
- virtual void operationCommitted(ModuleBase_Operation* theOperation) {}\r
-\r
- /// Realizes some functionality by an operation abort\r
- virtual void operationAborted(ModuleBase_Operation* theOperation) {}\r
-\r
- /// Realizes some functionality by an operation start\r
- virtual ModuleBase_Operation* currentOperation() const = 0;\r
-\r
- /// Add menu items for viewer into the actions map\r
- /// \param theStdActions a map of standard actions\r
- /// \param theParent a parent widget\r
- /// \param theMenuActions map of action/menu for the desirable index in the viewer menu\r
- /// \return true if items are added and there is no necessity to provide standard menu\r
- virtual bool addViewerMenu(const QMap<QString, QAction*>& theStdActions,\r
- QWidget* theParent,\r
- QMap<int, QAction*>& theMenuActions) const\r
- { return false; }\r
-\r
- /// Add menu items for object browser into the given menu\r
- /// \param theMenu a popup menu to be shown in the object browser\r
- virtual void addObjectBrowserMenu(QMenu* theMenu) const {};\r
-\r
- /// Creates custom widgets for property panel\r
- /// \param theType a type of widget\r
- /// \param theParent the parent object\r
- /// \param theWidgetApi the widget configuration. The attribute of the model widget is obtained from\r
- virtual ModuleBase_ModelWidget* createWidgetByType(const std::string& theType, QWidget* theParent,\r
- Config_WidgetAPI* theWidgetApi)\r
- {\r
- return 0;\r
- }\r
-\r
- /// Returns the active widget, by default it is the property panel active widget\r
- virtual ModuleBase_ModelWidget* activeWidget() const = 0;\r
-\r
- /// Returns current workshop\r
- ModuleBase_IWorkshop* workshop() const { return myWorkshop; }\r
-\r
- /// Call back forlast tuning of property panel before operation performance\r
- /// It is called as on clearing of property panel as on filling with new widgets\r
- virtual void propertyPanelDefined(ModuleBase_Operation* theOperation) {}\r
-\r
- /// Have an opportunity to create widgets for the current operation instead of standard creation in workshop\r
- /// \param theOperation a started operation\r
- /// \param theWidgets a list of created widgets\r
- /// \return boolean result, false by default\r
- virtual bool createWidgets(ModuleBase_Operation* theOperation,\r
- QList<ModuleBase_ModelWidget*>& theWidgets) const { return false; }\r
-\r
- //! Returns True if there are available Undos and there is not an active operation\r
- virtual bool canUndo() const;\r
-\r
- //! Returns True if there are available Redos and there is not an active operation\r
- virtual bool canRedo() const;\r
-\r
- /// Returns true if the action can be applyed to the object\r
- /// \param theObject a checked object\r
- /// \param theActionId an identifier of action, to be found in the menu manager like "DELETE_CMD"\r
- /// \return the a boolean result\r
- virtual bool canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const = 0;\r
-\r
- /// Returns True if the current operation can be committed. By default it is true.\r
- /// \return a boolean value\r
- //virtual bool canCommitOperation() const;\r
-\r
- /// Returns whether the object can be erased. The default realization returns true.\r
- /// \param theObject a model object\r
- virtual bool canEraseObject(const ObjectPtr& theObject) const;\r
-\r
- /// Returns whether the object can be displayed. The default realization returns true.\r
- /// \param theObject a model object\r
- virtual bool canDisplayObject(const ObjectPtr& theObject) const;\r
-\r
- /// Make some functionality after the objects are hidden in viewer\r
- /// \param theObjects a list of hidden objects\r
- //virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects) {};\r
-\r
- /// Returns true if selection for the object can be activate.\r
- /// By default a result or feature of the current operation can not be activated\r
- /// \param theObject a model object\r
- virtual bool canActivateSelection(const ObjectPtr& theObject) const;\r
-\r
- /// Reacts to the delete action in module\r
- /// \returns true if the action is processed\r
- virtual bool deleteObjects() { return false; };\r
-\r
- /// Performs functionality on closing document\r
- virtual void closeDocument() = 0;\r
-\r
- /// Clears specific presentations in the viewer\r
- virtual void clearViewer() = 0;\r
-\r
- /// Returns a list of modes, where the AIS objects should be activated\r
- /// \param theModes a list of modes\r
- virtual void activeSelectionModes(QIntList& theModes) {}\r
-\r
- /// Appends specific selection modes for the module to the list of types\r
- /// \param theTypes a selection modes to be extended\r
- virtual void customSubShapesSelectionModes(QIntList& theTypes) {}\r
-\r
- /// Return true if the custom presentation is activated\r
- /// \param theFlag a flag of level of customization, which means that only part of sub-elements\r
- /// \return boolean value\r
- virtual bool isCustomPrsActivated(const ModuleBase_CustomizeFlag& theFlag) const { return false; };\r
-\r
- /// Activate custom presentation for the object. Default realization is empty.\r
- /// \param theFeature a feature instance\r
- /// \param theFlag a flag of level of customization, which means that only part of sub-elements\r
- /// \param theUpdateViewer the parameter whether the viewer should be update immediately\r
- virtual void activateCustomPrs(const FeaturePtr& theFeature,\r
- const ModuleBase_CustomizeFlag& theFlag,\r
- const bool theUpdateViewer) {}\r
-\r
- /// Deactivate custom presentation for the object. Default realization is empty.\r
- /// \param theFlag a flag of level of customization, which means that only part of sub-elements\r
- /// \param theUpdateViewer the parameter whether the viewer should be update immediately\r
- virtual void deactivateCustomPrs(const ModuleBase_CustomizeFlag& theFlag,\r
- const bool theUpdateViewer) {}\r
-\r
- /// Modifies the given presentation in the custom way.\r
- virtual bool customisePresentation(std::shared_ptr<ModelAPI_Result> theResult, AISObjectPtr thePrs,\r
- GeomCustomPrsPtr theCustomPrs) { return false; };\r
-\r
- /// Update the object presentable properties such as color, lines width and other\r
- /// If the object is result with the color attribute value set, it is used,\r
- /// otherwise the customize is applyed to the object's feature if it is a custom prs\r
- /// \param theObject an object instance\r
- /// \param theFlag a flag of level of customization, which means that only part of sub-elements\r
- /// should be updated(e.g. only highlighted elements)\r
- /// \param theUpdateViewer the parameter whether the viewer should be update immediately\r
- /// \returns true if the object is modified\r
- virtual bool customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag,\r
- const bool theUpdateViewer);\r
-\r
- /// This method is called on object browser creation for customization of module specific features\r
- /// \param theObjectBrowser a pinter on Object Browser widget\r
- virtual void customizeObjectBrowser(QWidget* theObjectBrowser) {}\r
-\r
- /// Creates a new operation\r
- /// \param theCmdId the operation name\r
- virtual ModuleBase_Operation* createOperation(const std::string& theCmdId);\r
-\r
- /// Create specific for the module presentation\r
- /// \param theResult an object for presentation\r
- /// \return created presentation or NULL(default value)\r
- virtual Handle_AIS_InteractiveObject createPresentation(\r
- const std::shared_ptr<ModelAPI_Result>& theResult);\r
-\r
- //! Returns data object by AIS\r
- virtual ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const = 0;\r
-\r
- //! Returns true if the presentation can be shown in shading mode\r
- //! \param theAIS presentation to be checked\r
- //! \return boolean value\r
- virtual bool canBeShaded(Handle(AIS_InteractiveObject) theAIS) const;\r
-\r
- /// Update state of pop-up menu items in object browser\r
- /// \param theStdActions - a map of standard actions\r
- virtual void updateObjectBrowserMenu(const QMap<QString, QAction*>& theStdActions) {}\r
-\r
- /// Update state of pop-up menu items in viewer\r
- /// \param theStdActions - a map of standard actions\r
- virtual void updateViewerMenu(const QMap<QString, QAction*>& theStdActions) {}\r
-\r
- /// Returns true if the action should be always enabled\r
- /// \param theActionId an action index: Accept or Accept All\r
- /// \return boolean value\r
- virtual bool isActionEnableStateFixed(const int theActionId) const { return false; }\r
-\r
- //! Returns the feature error if the current state of the feature in the module is not correct\r
- //! If the feature is correct, it returns an empty value\r
- //! \return string value\r
- virtual QString getFeatureError(const FeaturePtr& theFeature);\r
-\r
- /// Returns list of granted operation indices\r
- virtual void grantedOperationIds(ModuleBase_Operation* theOperation, QStringList& theIds) const;\r
-\r
- /// Connects or disconnects to the value changed signal of the property panel widgets\r
- /// \param theWidget a property contol widget\r
- /// \param isToConnect a boolean value whether connect or disconnect\r
- virtual void connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect) {};\r
-\r
- /// Validates the operation to change the "Apply" button state.\r
- /// \param thePreviousState the previous state of the widget\r
- virtual void widgetStateChanged(int thePreviousState) {};\r
-\r
- /// Returns true if the event is processed.\r
- /// \param thePreviousAttributeID an index of the previous active attribute\r
- virtual bool processEnter(const std::string& thePreviousAttributeID) { return false; };\r
-\r
- /// Performs some GUI actions before an operation transaction is stopped\r
- /// Default realization is empty\r
- virtual void beforeOperationStopped(ModuleBase_Operation* theOperation) {};\r
-\r
- /// Finds a shape by attribute if it is possible\r
- /// \param theAttribute an attribute\r
- /// \return a geom shape\r
- virtual GeomShapePtr findShape(const AttributePtr& theAttribute) = 0;\r
-\r
- /// Finds an attribute by geom shape if it is possible\r
- /// \param theObject an object of the attribute\r
- /// \param theGeomShape a geom shape\r
- /// \return theAttribute\r
- virtual AttributePtr findAttribute(const ObjectPtr& theObject,\r
- const GeomShapePtr& theGeomShape) = 0;\r
-\r
- /// Returns XML information by the feature index\r
- /// \param theFeatureId a feature id\r
- /// \param theXmlCfg XML configuration\r
- /// \param theDescription feature description\r
- void getXMLRepresentation(const std::string& theFeatureId, std::string& theXmlCfg,\r
- std::string& theDescription);\r
-\r
-signals:\r
- /// Signal which is emitted when operation is launched\r
- void operationLaunched();\r
-\r
- /// Segnal emitted when an operation is resumed\r
- /// \param theOp a resumed operation\r
- void resumed(ModuleBase_Operation* theOp);\r
-\r
-public slots:\r
- /// Called on call of command corresponded to a feature\r
- virtual void onFeatureTriggered();\r
-\r
- /// Slot called on object display\r
- /// \param theObject a data object\r
- /// \param theAIS a presentation object\r
- virtual void onObjectDisplayed(ObjectPtr theObject, AISObjectPtr theAIS) {}\r
-\r
- /// Slot called on before object erase\r
- /// \param theObject a data object\r
- /// \param theAIS a presentation object\r
- virtual void onBeforeObjectErase(ObjectPtr theObject, AISObjectPtr theAIS) {}\r
-\r
-protected slots:\r
- /// Called on selection changed event\r
- virtual void onSelectionChanged() {}\r
-\r
-protected:\r
- /// Register validators for this module\r
- virtual void registerValidators() {}\r
-\r
- /// Register selection filters for this module\r
- virtual void registerFilters() {}\r
-\r
- /// Register properties of this module\r
- virtual void registerProperties() {}\r
-\r
- /// Returns new instance of operation object (used in createOperation for customization)\r
- virtual ModuleBase_Operation* getNewOperation(const std::string& theFeatureId);\r
-\r
-protected:\r
- /// Reference to workshop\r
- ModuleBase_IWorkshop* myWorkshop;\r
-\r
- /// Map of features in XML\r
- std::map<std::string, std::string> myFeaturesInFiles;\r
-};\r
-\r
-\r
-\r
-//! This function must return a new module instance.\r
-extern "C" {\r
-typedef ModuleBase_IModule* (*CREATE_FUNC)(ModuleBase_IWorkshop*);\r
-}\r
-\r
-#define CREATE_MODULE "createModule"\r
-\r
-#endif //ModuleBase_IModule\r
+ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#ifndef ModuleBase_IModule_H
+#define ModuleBase_IModule_H
+
+#include "ModuleBase.h"
+#include "ModuleBase_IWorkshop.h"
+
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Attribute.h>
+
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_ICustomPrs.h>
+
+#include <QString>
+#include <QObject>
+#include <QMap>
+#include <QList>
+
+#include <string>
+#include <vector>
+#include <map>
+
+class QAction;
+class QMouseEvent;
+class QKeyEvent;
+class QMenu;
+class Config_WidgetAPI;
+class ModuleBase_ModelWidget;
+class ModuleBase_Operation;
+class ModuleBase_IWorkshop;
+class ModelAPI_Result;
+
+class Handle_AIS_InteractiveObject;
+
+/**
+ * \ingroup GUI
+ * Interface to a module
+ */
+class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
+{
+ Q_OBJECT
+ public:
+ /// enumeration to know which objects should be customized
+ enum ModuleBase_CustomizeFlag {
+ CustomizeArguments = 0, /// references of other objects referenced to the current feature
+ CustomizeResults, /// results of the current feature
+ CustomizeHighlightedObjects /// highlighted objects of the active widget
+ };
+
+ /// Constructor
+ /// \param theParent instance of workshop interface
+ ModuleBase_IModule(ModuleBase_IWorkshop* theParent);
+
+ virtual ~ModuleBase_IModule() {}
+
+ /// Add default selection filters of the module to the current viewer
+ virtual void activateSelectionFilters() {};
+
+ /// Remove default selection filters of the module from the current viewer
+ virtual void deactivateSelectionFilters() {};
+
+ /// Stores the current selection
+ virtual void storeSelection() {};
+
+ /// Restores the current selection
+ virtual void restoreSelection() {};
+
+ /// Reads description of features from XML file
+ virtual void createFeatures();
+
+ /// Called on creation of menu item in desktop
+ virtual void actionCreated(QAction*);
+
+ /// Launching of a edit operation on the feature
+ /// \param theFeature feature for editing
+ virtual void editFeature(FeaturePtr theFeature);
+
+ /// Returns true if the operation can be committed. Result in default implementation is true.
+ /// \return boolean value
+ virtual bool canCommitOperation() const { return true; }
+
+ /// Creates an operation and send it to loop
+ /// \param theCmdId the operation name
+ virtual void launchOperation(const QString& theCmdId);
+
+ /// Executes feature as a modal dialog box
+ /// \param theCmdId the operation name
+ virtual void launchModal(const QString& theCmdId);
+
+ /// Realizes some functionality by an operation start
+ /// \param theOperation a started operation
+ virtual void operationStarted(ModuleBase_Operation* theOperation) {}
+
+ /// Realizes some functionality by an operation resume
+ /// By default it emits operationResumed signal
+ /// \param theOperation a resumed operation
+ virtual void operationResumed(ModuleBase_Operation* theOperation);
+
+ /// Realizes some functionality by an operation stop
+ virtual void operationStopped(ModuleBase_Operation* theOperation) {}
+
+ /// Realizes some functionality by an operation commit
+ virtual void operationCommitted(ModuleBase_Operation* theOperation) {}
+
+ /// Realizes some functionality by an operation abort
+ virtual void operationAborted(ModuleBase_Operation* theOperation) {}
+
+ /// Realizes some functionality by an operation start
+ virtual ModuleBase_Operation* currentOperation() const = 0;
+
+ /// Add menu items for viewer into the actions map
+ /// \param theStdActions a map of standard actions
+ /// \param theParent a parent widget
+ /// \param theMenuActions map of action/menu for the desirable index in the viewer menu
+ /// \return true if items are added and there is no necessity to provide standard menu
+ virtual bool addViewerMenu(const QMap<QString, QAction*>& theStdActions,
+ QWidget* theParent,
+ QMap<int, QAction*>& theMenuActions) const
+ { return false; }
+
+ /// Add menu items for object browser into the given menu
+ /// \param theMenu a popup menu to be shown in the object browser
+ virtual void addObjectBrowserMenu(QMenu* theMenu) const {};
+
+ /// Creates custom widgets for property panel
+ /// \param theType a type of widget
+ /// \param theParent the parent object
+ /// \param theWidgetApi the widget configuration. The attribute of the model widget is obtained from
+ virtual ModuleBase_ModelWidget* createWidgetByType(const std::string& theType, QWidget* theParent,
+ Config_WidgetAPI* theWidgetApi)
+ {
+ return 0;
+ }
+
+ /// Returns the active widget, by default it is the property panel active widget
+ virtual ModuleBase_ModelWidget* activeWidget() const = 0;
+
+ /// Returns current workshop
+ ModuleBase_IWorkshop* workshop() const { return myWorkshop; }
+
+ /// Call back forlast tuning of property panel before operation performance
+ /// It is called as on clearing of property panel as on filling with new widgets
+ virtual void propertyPanelDefined(ModuleBase_Operation* theOperation) {}
+
+ /// Have an opportunity to create widgets for the current operation instead of standard creation in workshop
+ /// \param theOperation a started operation
+ /// \param theWidgets a list of created widgets
+ /// \return boolean result, false by default
+ virtual bool createWidgets(ModuleBase_Operation* theOperation,
+ QList<ModuleBase_ModelWidget*>& theWidgets) const { return false; }
+
+ //! Returns True if there are available Undos and there is not an active operation
+ virtual bool canUndo() const;
+
+ //! Returns True if there are available Redos and there is not an active operation
+ virtual bool canRedo() const;
+
+ /// Returns true if the action can be applyed to the object
+ /// \param theObject a checked object
+ /// \param theActionId an identifier of action, to be found in the menu manager like "DELETE_CMD"
+ /// \return the a boolean result
+ virtual bool canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const = 0;
+
+ /// Returns True if the current operation can be committed. By default it is true.
+ /// \return a boolean value
+ //virtual bool canCommitOperation() const;
+
+ /// Returns whether the object can be erased. The default realization returns true.
+ /// \param theObject a model object
+ virtual bool canEraseObject(const ObjectPtr& theObject) const;
+
+ /// Returns whether the object can be displayed. The default realization returns true.
+ /// \param theObject a model object
+ virtual bool canDisplayObject(const ObjectPtr& theObject) const;
+
+ /// Make some functionality after the objects are hidden in viewer
+ /// \param theObjects a list of hidden objects
+ //virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects) {};
+
+ /// Returns true if selection for the object can be activate.
+ /// By default a result or feature of the current operation can not be activated
+ /// \param theObject a model object
+ virtual bool canActivateSelection(const ObjectPtr& theObject) const;
+
+ /// Reacts to the delete action in module
+ /// \returns true if the action is processed
+ virtual bool deleteObjects() { return false; };
+
+ /// Performs functionality on closing document
+ virtual void closeDocument() = 0;
+
+ /// Clears specific presentations in the viewer
+ virtual void clearViewer() = 0;
+
+ /// Returns a list of modes, where the AIS objects should be activated
+ /// \param theModes a list of modes
+ virtual void activeSelectionModes(QIntList& theModes) {}
+
+ /// Appends specific selection modes for the module to the list of types
+ /// \param theTypes a selection modes to be extended
+ virtual void customSubShapesSelectionModes(QIntList& theTypes) {}
+
+ /// Return true if the custom presentation is activated
+ /// \param theFlag a flag of level of customization, which means that only part of sub-elements
+ /// \return boolean value
+ virtual bool isCustomPrsActivated(const ModuleBase_CustomizeFlag& theFlag) const { return false; };
+
+ /// Activate custom presentation for the object. Default realization is empty.
+ /// \param theFeature a feature instance
+ /// \param theFlag a flag of level of customization, which means that only part of sub-elements
+ /// \param theUpdateViewer the parameter whether the viewer should be update immediately
+ virtual void activateCustomPrs(const FeaturePtr& theFeature,
+ const ModuleBase_CustomizeFlag& theFlag,
+ const bool theUpdateViewer) {}
+
+ /// Deactivate custom presentation for the object. Default realization is empty.
+ /// \param theFlag a flag of level of customization, which means that only part of sub-elements
+ /// \param theUpdateViewer the parameter whether the viewer should be update immediately
+ virtual void deactivateCustomPrs(const ModuleBase_CustomizeFlag& theFlag,
+ const bool theUpdateViewer) {}
+
+ /// Modifies the given presentation in the custom way.
+ virtual bool customisePresentation(std::shared_ptr<ModelAPI_Result> theResult, AISObjectPtr thePrs,
+ GeomCustomPrsPtr theCustomPrs) { return false; };
+
+ /// Update the object presentable properties such as color, lines width and other
+ /// If the object is result with the color attribute value set, it is used,
+ /// otherwise the customize is applyed to the object's feature if it is a custom prs
+ /// \param theObject an object instance
+ /// \param theFlag a flag of level of customization, which means that only part of sub-elements
+ /// should be updated(e.g. only highlighted elements)
+ /// \param theUpdateViewer the parameter whether the viewer should be update immediately
+ /// \returns true if the object is modified
+ virtual bool customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag,
+ const bool theUpdateViewer);
+
+ /// This method is called on object browser creation for customization of module specific features
+ /// \param theObjectBrowser a pinter on Object Browser widget
+ virtual void customizeObjectBrowser(QWidget* theObjectBrowser) {}
+
+ /// Creates a new operation
+ /// \param theCmdId the operation name
+ virtual ModuleBase_Operation* createOperation(const std::string& theCmdId);
+
+ /// Create specific for the module presentation
+ /// \param theResult an object for presentation
+ /// \return created presentation or NULL(default value)
+ virtual Handle_AIS_InteractiveObject createPresentation(
+ const std::shared_ptr<ModelAPI_Result>& theResult);
+
+ //! Returns data object by AIS
+ virtual ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const = 0;
+
+ //! Returns true if the presentation can be shown in shading mode
+ //! \param theAIS presentation to be checked
+ //! \return boolean value
+ virtual bool canBeShaded(Handle(AIS_InteractiveObject) theAIS) const;
+
+ /// Update state of pop-up menu items in object browser
+ /// \param theStdActions - a map of standard actions
+ virtual void updateObjectBrowserMenu(const QMap<QString, QAction*>& theStdActions) {}
+
+ /// Update state of pop-up menu items in viewer
+ /// \param theStdActions - a map of standard actions
+ virtual void updateViewerMenu(const QMap<QString, QAction*>& theStdActions) {}
+
+ /// Returns true if the action should be always enabled
+ /// \param theActionId an action index: Accept or Accept All
+ /// \return boolean value
+ virtual bool isActionEnableStateFixed(const int theActionId) const { return false; }
+
+ //! Returns the feature error if the current state of the feature in the module is not correct
+ //! If the feature is correct, it returns an empty value
+ //! \return string value
+ virtual QString getFeatureError(const FeaturePtr& theFeature);
+
+ /// Returns list of granted operation indices
+ virtual void grantedOperationIds(ModuleBase_Operation* theOperation, QStringList& theIds) const;
+
+ /// Connects or disconnects to the value changed signal of the property panel widgets
+ /// \param theWidget a property contol widget
+ /// \param isToConnect a boolean value whether connect or disconnect
+ virtual void connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect) {};
+
+ /// Validates the operation to change the "Apply" button state.
+ /// \param thePreviousState the previous state of the widget
+ virtual void widgetStateChanged(int thePreviousState) {};
+
+ /// Returns true if the event is processed.
+ /// \param thePreviousAttributeID an index of the previous active attribute
+ virtual bool processEnter(const std::string& thePreviousAttributeID) { return false; };
+
+ /// Performs some GUI actions before an operation transaction is stopped
+ /// Default realization is empty
+ virtual void beforeOperationStopped(ModuleBase_Operation* theOperation) {};
+
+ /// Finds a shape by attribute if it is possible
+ /// \param theAttribute an attribute
+ /// \return a geom shape
+ virtual GeomShapePtr findShape(const AttributePtr& theAttribute) = 0;
+
+ /// Finds an attribute by geom shape if it is possible
+ /// \param theObject an object of the attribute
+ /// \param theGeomShape a geom shape
+ /// \return theAttribute
+ virtual AttributePtr findAttribute(const ObjectPtr& theObject,
+ const GeomShapePtr& theGeomShape) = 0;
+
+ /// Returns XML information by the feature index
+ /// \param theFeatureId a feature id
+ /// \param theXmlCfg XML configuration
+ /// \param theDescription feature description
+ void getXMLRepresentation(const std::string& theFeatureId, std::string& theXmlCfg,
+ std::string& theDescription);
+
+signals:
+ /// Signal which is emitted when operation is launched
+ void operationLaunched();
+
+ /// Segnal emitted when an operation is resumed
+ /// \param theOp a resumed operation
+ void resumed(ModuleBase_Operation* theOp);
+
+public slots:
+ /// Called on call of command corresponded to a feature
+ virtual void onFeatureTriggered();
+
+ /// Slot called on object display
+ /// \param theObject a data object
+ /// \param theAIS a presentation object
+ virtual void onObjectDisplayed(ObjectPtr theObject, AISObjectPtr theAIS) {}
+
+ /// Slot called on before object erase
+ /// \param theObject a data object
+ /// \param theAIS a presentation object
+ virtual void onBeforeObjectErase(ObjectPtr theObject, AISObjectPtr theAIS) {}
+
+protected slots:
+ /// Called on selection changed event
+ virtual void onSelectionChanged() {}
+
+protected:
+ /// Register validators for this module
+ virtual void registerValidators() {}
+
+ /// Register selection filters for this module
+ virtual void registerFilters() {}
+
+ /// Register properties of this module
+ virtual void registerProperties() {}
+
+ /// Returns new instance of operation object (used in createOperation for customization)
+ virtual ModuleBase_Operation* getNewOperation(const std::string& theFeatureId);
+
+protected:
+ /// Reference to workshop
+ ModuleBase_IWorkshop* myWorkshop;
+
+ /// Map of features in XML
+ std::map<std::string, std::string> myFeaturesInFiles;
+};
+
+
+
+//! This function must return a new module instance.
+extern "C" {
+typedef ModuleBase_IModule* (*CREATE_FUNC)(ModuleBase_IWorkshop*);
+}
+
+#define CREATE_MODULE "createModule"
+
+#endif //ModuleBase_IModule
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_ModelWidget.cpp\r
-// Created: 25 Apr 2014\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#include "ModuleBase_ModelWidget.h"\r
-#include "ModuleBase_ViewerPrs.h"\r
-#include "ModuleBase_Tools.h"\r
-#include "ModuleBase_WidgetValidator.h"\r
-\r
-#include <Events_InfoMessage.h>\r
-\r
-#include <ModelAPI_Data.h>\r
-#include <ModelAPI_Attribute.h>\r
-#include <ModelAPI_Events.h>\r
-#include <ModelAPI_Session.h>\r
-#include <ModelAPI_Validator.h>\r
-\r
-#include <Config_Keywords.h>\r
-#include <Config_WidgetAPI.h>\r
-#include <Config_Translator.h>\r
-#include <Config_PropManager.h>\r
-\r
-#include <Events_Loop.h>\r
-\r
-#include <QEvent>\r
-#include <QLabel>\r
-#include <QFocusEvent>\r
-#include <QTextCodec>\r
-\r
-//#define DEBUG_VALUE_STATE\r
-\r
-//#define DEBUG_WIDGET_INSTANCE\r
-//#define DEBUG_ENABLE_SKETCH_INPUT_FIELDS\r
-\r
-ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,\r
- const Config_WidgetAPI* theData)\r
- : QWidget(theParent),\r
- myIsEditing(false),\r
- myState(Stored),\r
- myIsValueStateBlocked(false),\r
- myFlushUpdateBlocked(false),\r
- myWidgetValidator(0)\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::ModuleBase_ModelWidget");\r
-#endif\r
-\r
- myIsInternal = theData->getBooleanAttribute(ATTR_INTERNAL, false);\r
-\r
- myDefaultValue = theData->getProperty(ATTR_DEFAULT);\r
- myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);\r
- myIsComputedDefault = theData->getProperty(ATTR_DEFAULT) == DOUBLE_WDG_DEFAULT_COMPUTED;\r
- myAttributeID = theData ? theData->widgetId() : "";\r
- myIsObligatory = theData->getBooleanAttribute(ATTR_OBLIGATORY, true);\r
-\r
- myIsValueEnabled = On; // not defined or "true"\r
- std::string anEnableValue = theData->getProperty(DOUBLE_WDG_ENABLE_VALUE);\r
- if (anEnableValue == "false")\r
- myIsValueEnabled = Off;\r
- if (anEnableValue == DOUBLE_WDG_ENABLE_VALUE_BY_PREFERENCES)\r
- myIsValueEnabled = DefinedInPreferences;\r
-\r
- connect(this, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));\r
- connect(this, SIGNAL(valuesModified()), this, SLOT(onWidgetValuesModified()));\r
-}\r
-\r
-ModuleBase_ModelWidget::~ModuleBase_ModelWidget()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::~ModuleBase_ModelWidget");\r
-#endif\r
-}\r
-\r
-bool ModuleBase_ModelWidget::reset()\r
-{\r
- bool aResult = resetCustom();\r
- if (aResult)\r
- setValueState(Reset);\r
-\r
- return aResult;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const\r
-{\r
- return theObject->data()->attribute(attributeID())->isInitialized();\r
-}\r
-\r
-bool ModuleBase_ModelWidget::isValueEnabled() const\r
-{\r
- bool anEnabled = true;\r
- if (myIsValueEnabled == DefinedInPreferences) {\r
-#ifdef DEBUG_ENABLE_SKETCH_INPUT_FIELDS\r
- bool aCanDisable = false;\r
-#else\r
- bool aCanDisable = true;//Config_PropManager::boolean(SKETCH_TAB_NAME, "disable_input_fields", "true");\r
-#endif\r
- if (aCanDisable)\r
- anEnabled = false;\r
- }\r
- else if (myIsValueEnabled == Off)\r
- anEnabled = false;\r
- return anEnabled;\r
-}\r
-\r
-void ModuleBase_ModelWidget::processValueState()\r
-{\r
- if (myState == ModifiedInPP || myState == ModifiedInViewer)\r
- storeValue();\r
-}\r
-\r
-QString ModuleBase_ModelWidget::getValueStateError() const\r
-{\r
- QString anError = "";\r
-\r
- ModuleBase_ModelWidget::ValueState aState = getValueState();\r
- if (aState != ModuleBase_ModelWidget::Stored) {\r
- AttributePtr anAttr = feature()->attribute(attributeID());\r
- if (anAttr.get()) {\r
- QString anAttributeName = anAttr->id().c_str();\r
- switch (aState) {\r
- case ModuleBase_ModelWidget::ModifiedInViewer:\r
- anError = "Attribute \"" + anAttributeName +\r
- "\" is locked by modification value in the viewer.";\r
- break;\r
- case ModuleBase_ModelWidget::Reset:\r
- anError = "Attribute \"" + anAttributeName + "\" is not initialized.";\r
- break;\r
- case ModuleBase_ModelWidget::ModifiedInPP: // Apply should be enabled in this mode\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- return anError;\r
-}\r
-\r
-QString ModuleBase_ModelWidget::getError(const bool theValueStateChecked) const\r
-{\r
- QString anError;\r
-\r
- if (!feature().get())\r
- return anError;\r
-\r
- std::string anAttributeID = attributeID();\r
- AttributePtr anAttribute = feature()->attribute(anAttributeID);\r
- if (!anAttribute.get())\r
- return anError;\r
-\r
- std::string aValidatorID;\r
- Events_InfoMessage anErrorMsg;\r
-\r
- static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();\r
- if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {\r
- if (anErrorMsg.empty())\r
- anErrorMsg = "unknown error.";\r
- anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg.messageString();\r
- }\r
-\r
- if (!anErrorMsg.empty()) {\r
- std::string aStr = Config_Translator::translate(anErrorMsg);\r
- std::string aCodec = Config_Translator::codec(anErrorMsg.context());\r
- anError = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());\r
- }\r
-\r
- if (anError.isEmpty() && theValueStateChecked)\r
- anError = getValueStateError();\r
-\r
- anError = translateString(anError);\r
- return anError;\r
-}\r
-\r
-\r
-QString ModuleBase_ModelWidget::translateString(const QString& theMsg) const\r
-{\r
- if (!theMsg.isEmpty()) {\r
- std::string aContext = feature()->getKind();\r
- std::string aStr = Config_Translator::translate(aContext, theMsg.toStdString().c_str());\r
- std::string aCodec = Config_Translator::codec(aContext);\r
- return QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());\r
- }\r
- return theMsg;\r
-}\r
-\r
-\r
-void ModuleBase_ModelWidget::enableFocusProcessing()\r
-{\r
- QList<QWidget*> aMyControls = getControls();\r
- foreach(QWidget* eachControl, aMyControls) {\r
- eachControl->setFocusPolicy(Qt::StrongFocus);\r
- eachControl->installEventFilter(this);\r
- }\r
-}\r
-\r
-void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)\r
-{\r
- QList<QWidget*> aWidgetList = getControls();\r
- foreach(QWidget* aWidget, aWidgetList) {\r
- QLabel* aLabel = qobject_cast<QLabel*>(aWidget);\r
- // We won't set the effect to QLabels - it looks ugly\r
- if(aLabel) continue;\r
- // If effect is the installed on a different widget, setGraphicsEffect() will\r
- // remove the effect from the widget and install it on this widget.\r
- // That's why we create a new effect for each widget\r
- ModuleBase_Tools::setShadowEffect(aWidget, isHighlighted);\r
- }\r
-}\r
-\r
-void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue,\r
- const bool isUpdateFlushed)\r
-{\r
- /// it is possible to give this flag as parameter in storeValue/storeCustomValue\r
- /// after debug, it may be corrected\r
- myFlushUpdateBlocked = !isUpdateFlushed;\r
- myFeature = theFeature;\r
- if (theToStoreValue) {\r
- /// it is possible that the attribute is filled before the operation is started,\r
- /// e.g. by reentrant operation case some attributes are filled by values of\r
- /// feature of previous operation, we should not lost them here\r
- if (!theFeature->data()->attribute(attributeID())->isInitialized())\r
- storeValue();\r
- }\r
- myFlushUpdateBlocked = false;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::focusTo()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::focusTo");\r
-#endif\r
- QList<QWidget*> aControls = getControls();\r
- QList<QWidget*>::const_iterator anIt = aControls.begin(), aLast = aControls.end();\r
- bool isFocusAccepted = false;\r
- for (; anIt != aLast && !isFocusAccepted; anIt++) {\r
- QWidget* aWidget = *anIt;\r
- if (aWidget && aWidget->focusPolicy() != Qt::NoFocus) {\r
- ModuleBase_Tools::setFocus(aWidget, "ModuleBase_ModelWidget::focusTo()");\r
- isFocusAccepted = true;\r
- }\r
- }\r
- return isFocusAccepted;\r
-}\r
-\r
-void ModuleBase_ModelWidget::activate()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::activate");\r
-#endif\r
- // the control value is stored to the mode by the focus in on the widget\r
- // we need the value is initialized in order to enable the apply button in the property panel.\r
- // It should happens in the creation mode only because all fields are filled in the edition mode\r
- if (!isEditingMode()) {\r
- AttributePtr anAttribute = myFeature->data()->attribute(myAttributeID);\r
- if (anAttribute.get() != NULL && !anAttribute->isInitialized())\r
- initializeValueByActivate();\r
- }\r
-\r
- if (myWidgetValidator)\r
- myWidgetValidator->activateFilters(true);\r
-\r
- activateCustom();\r
-}\r
-\r
-void ModuleBase_ModelWidget::deactivate()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::deactivate");\r
-#endif\r
- myIsValueStateBlocked = false;\r
- myState = Stored;\r
- if (myWidgetValidator)\r
- myWidgetValidator->activateFilters(false);\r
-}\r
-\r
-void ModuleBase_ModelWidget::initializeValueByActivate()\r
-{\r
- if (isComputedDefault()) {\r
- if (myFeature->compute(myAttributeID)) {\r
- restoreValue();\r
- }\r
- }\r
- else {\r
- storeValue();\r
- }\r
-}\r
-\r
-QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)\r
-{\r
- QWidget* aControl = 0;\r
-\r
- QList<QWidget*> aControls = getControls();\r
- int aSize = aControls.size();\r
-\r
- if (isFirst) {\r
- for (int i = 0; i < aSize && !aControl; i++) {\r
- if (aControls[i]->focusPolicy() != Qt::NoFocus)\r
- aControl = aControls[i];\r
- }\r
- }\r
- else {\r
- for (int i = aSize - 1; i >= 0 && !aControl; i--) {\r
- if (aControls[i]->focusPolicy() != Qt::NoFocus)\r
- aControl = aControls[i];\r
- }\r
- }\r
- return aControl;\r
-}\r
-\r
-void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)\r
-{\r
- myDefaultValue = theValue;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::storeValue()\r
-{\r
- setValueState(Stored);\r
-\r
- emit beforeValuesChanged();\r
- bool isDone = storeValueCustom();\r
- emit afterValuesChanged();\r
-\r
- return isDone;\r
-}\r
-#ifdef DEBUG_VALUE_STATE\r
-std::string getDebugInfo(const ModuleBase_ModelWidget::ValueState& theState)\r
-{\r
- std::string anInfo;\r
- switch (theState) {\r
- case ModuleBase_ModelWidget::Stored: anInfo = "Stored "; break;\r
- case ModuleBase_ModelWidget::ModifiedInPP: anInfo = "ModifiedInPP "; break;\r
- case ModuleBase_ModelWidget::ModifiedInViewer: anInfo = "ModifiedInViewer"; break;\r
- case ModuleBase_ModelWidget::Reset: anInfo = "Reset "; break;\r
- default: break;\r
- }\r
- return anInfo;\r
-}\r
-\r
-#endif\r
-ModuleBase_ModelWidget::ValueState ModuleBase_ModelWidget::setValueState\r
- (const ModuleBase_ModelWidget::ValueState& theState)\r
-{\r
- ValueState aState = myState;\r
-\r
- if (myState != theState && !myIsValueStateBlocked) {\r
-#ifdef DEBUG_VALUE_STATE\r
- qDebug(QString("setValueState: previous state = %1,\t new state = %2")\r
- .arg(getDebugInfo(myState).c_str())\r
- .arg(getDebugInfo(theState).c_str()).toStdString().c_str());\r
-#endif\r
- myState = theState;\r
- emit valueStateChanged(aState);\r
- }\r
- return aState;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::blockValueState(const bool theBlocked)\r
-{\r
- bool isBlocked = myIsValueStateBlocked;\r
- myIsValueStateBlocked = theBlocked;\r
- return isBlocked;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::restoreValue()\r
-{\r
- emit beforeValuesRestored();\r
- bool isDone = restoreValueCustom();\r
- emit afterValuesRestored();\r
-\r
- return isDone;\r
-}\r
-\r
-void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)\r
-{\r
- if (!myFlushUpdateBlocked) {\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::updateObject");\r
-#endif\r
- ModuleBase_Tools::flushUpdated(theObject);\r
- emit objectUpdated();\r
- }\r
-}\r
-\r
-void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)\r
-{\r
- //blockUpdateViewer(true);\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::moveObject");\r
-#endif\r
-\r
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);\r
- ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);\r
- Events_Loop::loop()->flush(anEvent);\r
-\r
- //blockUpdateViewer(false);\r
-}\r
-\r
-bool ModuleBase_ModelWidget::processEnter()\r
-{\r
- return false;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::processDelete()\r
-{\r
- // we consider that model objects eats delete key in order to\r
- // do nothing by for example symbol delete in line edit or spin box\r
- return true;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)\r
-{\r
- QWidget* aWidget = qobject_cast<QWidget*>(theObject);\r
- if (theEvent->type() == QEvent::FocusIn) {\r
- #ifdef _DEBUG\r
- // The following two lines are for debugging purpose only\r
- QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);\r
- bool isWinFocus = aFocusEvent->reason() == Qt::ActiveWindowFocusReason;\r
- #endif\r
- if (getControls().contains(aWidget)) {\r
- emit focusInWidget(this);\r
- }\r
- }\r
- else if (theEvent->type() == QEvent::FocusOut) {\r
- QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);\r
-\r
- Qt::FocusReason aReason = aFocusEvent->reason();\r
- bool aMouseOrKey = aReason == Qt::MouseFocusReason ||\r
- aReason == Qt::TabFocusReason ||\r
- aReason == Qt::BacktabFocusReason ||\r
- aReason == Qt::OtherFocusReason; // to process widget->setFocus()\r
- if (aMouseOrKey && getControls().contains(aWidget)) {\r
- if (getValueState() == ModifiedInPP) {\r
- storeValue();\r
- }\r
- }\r
- }\r
- // pass the event on to the parent class\r
-\r
- return QObject::eventFilter(theObject, theEvent);\r
-}\r
-\r
-//**************************************************************\r
-void ModuleBase_ModelWidget::onWidgetValuesChanged()\r
-{\r
- storeValue();\r
-}\r
-\r
-//**************************************************************\r
-void ModuleBase_ModelWidget::onWidgetValuesModified()\r
-{\r
- setValueState(ModifiedInPP);\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_ModelWidget.cpp
+// Created: 25 Apr 2014
+// Author: Natalia ERMOLAEVA
+
+#include "ModuleBase_ModelWidget.h"
+#include "ModuleBase_ViewerPrs.h"
+#include "ModuleBase_Tools.h"
+#include "ModuleBase_WidgetValidator.h"
+
+#include <Events_InfoMessage.h>
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <Config_Keywords.h>
+#include <Config_WidgetAPI.h>
+#include <Config_Translator.h>
+#include <Config_PropManager.h>
+
+#include <Events_Loop.h>
+
+#include <QEvent>
+#include <QLabel>
+#include <QFocusEvent>
+#include <QTextCodec>
+
+//#define DEBUG_VALUE_STATE
+
+//#define DEBUG_WIDGET_INSTANCE
+//#define DEBUG_ENABLE_SKETCH_INPUT_FIELDS
+
+ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,
+ const Config_WidgetAPI* theData)
+ : QWidget(theParent),
+ myIsEditing(false),
+ myState(Stored),
+ myIsValueStateBlocked(false),
+ myFlushUpdateBlocked(false),
+ myWidgetValidator(0)
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::ModuleBase_ModelWidget");
+#endif
+
+ myIsInternal = theData->getBooleanAttribute(ATTR_INTERNAL, false);
+
+ myDefaultValue = theData->getProperty(ATTR_DEFAULT);
+ myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);
+ myIsComputedDefault = theData->getProperty(ATTR_DEFAULT) == DOUBLE_WDG_DEFAULT_COMPUTED;
+ myAttributeID = theData ? theData->widgetId() : "";
+ myIsObligatory = theData->getBooleanAttribute(ATTR_OBLIGATORY, true);
+
+ myIsValueEnabled = On; // not defined or "true"
+ std::string anEnableValue = theData->getProperty(DOUBLE_WDG_ENABLE_VALUE);
+ if (anEnableValue == "false")
+ myIsValueEnabled = Off;
+ if (anEnableValue == DOUBLE_WDG_ENABLE_VALUE_BY_PREFERENCES)
+ myIsValueEnabled = DefinedInPreferences;
+
+ connect(this, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));
+ connect(this, SIGNAL(valuesModified()), this, SLOT(onWidgetValuesModified()));
+}
+
+ModuleBase_ModelWidget::~ModuleBase_ModelWidget()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::~ModuleBase_ModelWidget");
+#endif
+}
+
+bool ModuleBase_ModelWidget::reset()
+{
+ bool aResult = resetCustom();
+ if (aResult)
+ setValueState(Reset);
+
+ return aResult;
+}
+
+bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const
+{
+ return theObject->data()->attribute(attributeID())->isInitialized();
+}
+
+bool ModuleBase_ModelWidget::isValueEnabled() const
+{
+ bool anEnabled = true;
+ if (myIsValueEnabled == DefinedInPreferences) {
+#ifdef DEBUG_ENABLE_SKETCH_INPUT_FIELDS
+ bool aCanDisable = false;
+#else
+ bool aCanDisable = true;//Config_PropManager::boolean(SKETCH_TAB_NAME, "disable_input_fields", "true");
+#endif
+ if (aCanDisable)
+ anEnabled = false;
+ }
+ else if (myIsValueEnabled == Off)
+ anEnabled = false;
+ return anEnabled;
+}
+
+void ModuleBase_ModelWidget::processValueState()
+{
+ if (myState == ModifiedInPP || myState == ModifiedInViewer)
+ storeValue();
+}
+
+QString ModuleBase_ModelWidget::getValueStateError() const
+{
+ QString anError = "";
+
+ ModuleBase_ModelWidget::ValueState aState = getValueState();
+ if (aState != ModuleBase_ModelWidget::Stored) {
+ AttributePtr anAttr = feature()->attribute(attributeID());
+ if (anAttr.get()) {
+ QString anAttributeName = anAttr->id().c_str();
+ switch (aState) {
+ case ModuleBase_ModelWidget::ModifiedInViewer:
+ anError = "Attribute \"" + anAttributeName +
+ "\" is locked by modification value in the viewer.";
+ break;
+ case ModuleBase_ModelWidget::Reset:
+ anError = "Attribute \"" + anAttributeName + "\" is not initialized.";
+ break;
+ case ModuleBase_ModelWidget::ModifiedInPP: // Apply should be enabled in this mode
+ default:
+ break;
+ }
+ }
+ }
+ return anError;
+}
+
+QString ModuleBase_ModelWidget::getError(const bool theValueStateChecked) const
+{
+ QString anError;
+
+ if (!feature().get())
+ return anError;
+
+ std::string anAttributeID = attributeID();
+ AttributePtr anAttribute = feature()->attribute(anAttributeID);
+ if (!anAttribute.get())
+ return anError;
+
+ std::string aValidatorID;
+ Events_InfoMessage anErrorMsg;
+
+ static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+ if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {
+ if (anErrorMsg.empty())
+ anErrorMsg = "unknown error.";
+ anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg.messageString();
+ }
+
+ if (!anErrorMsg.empty()) {
+ std::string aStr = Config_Translator::translate(anErrorMsg);
+ std::string aCodec = Config_Translator::codec(anErrorMsg.context());
+ anError = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
+ }
+
+ if (anError.isEmpty() && theValueStateChecked)
+ anError = getValueStateError();
+
+ anError = translateString(anError);
+ return anError;
+}
+
+
+QString ModuleBase_ModelWidget::translateString(const QString& theMsg) const
+{
+ if (!theMsg.isEmpty()) {
+ std::string aContext = feature()->getKind();
+ std::string aStr = Config_Translator::translate(aContext, theMsg.toStdString().c_str());
+ std::string aCodec = Config_Translator::codec(aContext);
+ return QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
+ }
+ return theMsg;
+}
+
+
+void ModuleBase_ModelWidget::enableFocusProcessing()
+{
+ QList<QWidget*> aMyControls = getControls();
+ foreach(QWidget* eachControl, aMyControls) {
+ eachControl->setFocusPolicy(Qt::StrongFocus);
+ eachControl->installEventFilter(this);
+ }
+}
+
+void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)
+{
+ QList<QWidget*> aWidgetList = getControls();
+ foreach(QWidget* aWidget, aWidgetList) {
+ QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
+ // We won't set the effect to QLabels - it looks ugly
+ if(aLabel) continue;
+ // If effect is the installed on a different widget, setGraphicsEffect() will
+ // remove the effect from the widget and install it on this widget.
+ // That's why we create a new effect for each widget
+ ModuleBase_Tools::setShadowEffect(aWidget, isHighlighted);
+ }
+}
+
+void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue,
+ const bool isUpdateFlushed)
+{
+ /// it is possible to give this flag as parameter in storeValue/storeCustomValue
+ /// after debug, it may be corrected
+ myFlushUpdateBlocked = !isUpdateFlushed;
+ myFeature = theFeature;
+ if (theToStoreValue) {
+ /// it is possible that the attribute is filled before the operation is started,
+ /// e.g. by reentrant operation case some attributes are filled by values of
+ /// feature of previous operation, we should not lost them here
+ if (!theFeature->data()->attribute(attributeID())->isInitialized())
+ storeValue();
+ }
+ myFlushUpdateBlocked = false;
+}
+
+bool ModuleBase_ModelWidget::focusTo()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::focusTo");
+#endif
+ QList<QWidget*> aControls = getControls();
+ QList<QWidget*>::const_iterator anIt = aControls.begin(), aLast = aControls.end();
+ bool isFocusAccepted = false;
+ for (; anIt != aLast && !isFocusAccepted; anIt++) {
+ QWidget* aWidget = *anIt;
+ if (aWidget && aWidget->focusPolicy() != Qt::NoFocus) {
+ ModuleBase_Tools::setFocus(aWidget, "ModuleBase_ModelWidget::focusTo()");
+ isFocusAccepted = true;
+ }
+ }
+ return isFocusAccepted;
+}
+
+void ModuleBase_ModelWidget::activate()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::activate");
+#endif
+ // the control value is stored to the mode by the focus in on the widget
+ // we need the value is initialized in order to enable the apply button in the property panel.
+ // It should happens in the creation mode only because all fields are filled in the edition mode
+ if (!isEditingMode()) {
+ AttributePtr anAttribute = myFeature->data()->attribute(myAttributeID);
+ if (anAttribute.get() != NULL && !anAttribute->isInitialized())
+ initializeValueByActivate();
+ }
+
+ if (myWidgetValidator)
+ myWidgetValidator->activateFilters(true);
+
+ activateCustom();
+}
+
+void ModuleBase_ModelWidget::deactivate()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::deactivate");
+#endif
+ myIsValueStateBlocked = false;
+ myState = Stored;
+ if (myWidgetValidator)
+ myWidgetValidator->activateFilters(false);
+}
+
+void ModuleBase_ModelWidget::initializeValueByActivate()
+{
+ if (isComputedDefault()) {
+ if (myFeature->compute(myAttributeID)) {
+ restoreValue();
+ }
+ }
+ else {
+ storeValue();
+ }
+}
+
+QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)
+{
+ QWidget* aControl = 0;
+
+ QList<QWidget*> aControls = getControls();
+ int aSize = aControls.size();
+
+ if (isFirst) {
+ for (int i = 0; i < aSize && !aControl; i++) {
+ if (aControls[i]->focusPolicy() != Qt::NoFocus)
+ aControl = aControls[i];
+ }
+ }
+ else {
+ for (int i = aSize - 1; i >= 0 && !aControl; i--) {
+ if (aControls[i]->focusPolicy() != Qt::NoFocus)
+ aControl = aControls[i];
+ }
+ }
+ return aControl;
+}
+
+void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)
+{
+ myDefaultValue = theValue;
+}
+
+bool ModuleBase_ModelWidget::storeValue()
+{
+ setValueState(Stored);
+
+ emit beforeValuesChanged();
+ bool isDone = storeValueCustom();
+ emit afterValuesChanged();
+
+ return isDone;
+}
+#ifdef DEBUG_VALUE_STATE
+std::string getDebugInfo(const ModuleBase_ModelWidget::ValueState& theState)
+{
+ std::string anInfo;
+ switch (theState) {
+ case ModuleBase_ModelWidget::Stored: anInfo = "Stored "; break;
+ case ModuleBase_ModelWidget::ModifiedInPP: anInfo = "ModifiedInPP "; break;
+ case ModuleBase_ModelWidget::ModifiedInViewer: anInfo = "ModifiedInViewer"; break;
+ case ModuleBase_ModelWidget::Reset: anInfo = "Reset "; break;
+ default: break;
+ }
+ return anInfo;
+}
+
+#endif
+ModuleBase_ModelWidget::ValueState ModuleBase_ModelWidget::setValueState
+ (const ModuleBase_ModelWidget::ValueState& theState)
+{
+ ValueState aState = myState;
+
+ if (myState != theState && !myIsValueStateBlocked) {
+#ifdef DEBUG_VALUE_STATE
+ qDebug(QString("setValueState: previous state = %1,\t new state = %2")
+ .arg(getDebugInfo(myState).c_str())
+ .arg(getDebugInfo(theState).c_str()).toStdString().c_str());
+#endif
+ myState = theState;
+ emit valueStateChanged(aState);
+ }
+ return aState;
+}
+
+bool ModuleBase_ModelWidget::blockValueState(const bool theBlocked)
+{
+ bool isBlocked = myIsValueStateBlocked;
+ myIsValueStateBlocked = theBlocked;
+ return isBlocked;
+}
+
+bool ModuleBase_ModelWidget::restoreValue()
+{
+ emit beforeValuesRestored();
+ bool isDone = restoreValueCustom();
+ emit afterValuesRestored();
+
+ return isDone;
+}
+
+void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)
+{
+ if (!myFlushUpdateBlocked) {
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::updateObject");
+#endif
+ ModuleBase_Tools::flushUpdated(theObject);
+ emit objectUpdated();
+ }
+}
+
+void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)
+{
+ //blockUpdateViewer(true);
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::moveObject");
+#endif
+
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
+ ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);
+ Events_Loop::loop()->flush(anEvent);
+
+ //blockUpdateViewer(false);
+}
+
+bool ModuleBase_ModelWidget::processEnter()
+{
+ return false;
+}
+
+bool ModuleBase_ModelWidget::processDelete()
+{
+ // we consider that model objects eats delete key in order to
+ // do nothing by for example symbol delete in line edit or spin box
+ return true;
+}
+
+bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
+{
+ QWidget* aWidget = qobject_cast<QWidget*>(theObject);
+ if (theEvent->type() == QEvent::FocusIn) {
+ #ifdef _DEBUG
+ // The following two lines are for debugging purpose only
+ QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);
+ bool isWinFocus = aFocusEvent->reason() == Qt::ActiveWindowFocusReason;
+ #endif
+ if (getControls().contains(aWidget)) {
+ emit focusInWidget(this);
+ }
+ }
+ else if (theEvent->type() == QEvent::FocusOut) {
+ QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);
+
+ Qt::FocusReason aReason = aFocusEvent->reason();
+ bool aMouseOrKey = aReason == Qt::MouseFocusReason ||
+ aReason == Qt::TabFocusReason ||
+ aReason == Qt::BacktabFocusReason ||
+ aReason == Qt::OtherFocusReason; // to process widget->setFocus()
+ if (aMouseOrKey && getControls().contains(aWidget)) {
+ if (getValueState() == ModifiedInPP) {
+ storeValue();
+ }
+ }
+ }
+ // pass the event on to the parent class
+
+ return QObject::eventFilter(theObject, theEvent);
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::onWidgetValuesChanged()
+{
+ storeValue();
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::onWidgetValuesModified()
+{
+ setValueState(ModifiedInPP);
+}
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-/*\r
- * ModuleBase_OperationDescription.h\r
- *\r
- * Created on: Apr 2, 2014\r
- * Author: sbh\r
- */\r
-\r
-#ifndef MODULEBASE_OPERATIONDESCRIPTION_H\r
-#define MODULEBASE_OPERATIONDESCRIPTION_H\r
-\r
-#include <ModuleBase.h>\r
-#include <ModuleBase_Operation.h>\r
-\r
-#include <QObject>\r
-#include <QString>\r
-#include <QList>\r
-\r
-#include <memory>\r
-\r
-//class ModuleBase_ModelWidget;\r
-\r
-/*!\r
- * \class ModuleBase_OperationDescription\r
- * \ingroup GUI\r
- * Description of operation from XML\r
- */\r
-class MODULEBASE_EXPORT ModuleBase_OperationDescription\r
-{\r
- public:\r
- /// Constructor\r
- /// \param theId - the operation identifier\r
- ModuleBase_OperationDescription(const QString& theId = "");\r
- /// Destructor\r
- virtual ~ModuleBase_OperationDescription();\r
-\r
- /// Unique name of the operation\r
- /// \return string name of the operation.\r
- const QString& operationId() const;\r
-\r
- /// Returns a short description of operation (will be\r
- /// inserted in title of property panel)\r
- const QString& description() const;\r
-\r
- /// Sets a short description of operation (will be\r
- /// inserted in title of property panel)\r
- void setDescription(const QString& theDescription);\r
-\r
- /// Returns XML representation of the operation's widget.\r
- /// \return XML QString\r
- const QString& xmlRepresentation() const;\r
-\r
- /// Sets XML representation of the operation's widget.\r
- /// \param theXMLRepresentation - XML QString\r
- void setXmlRepresentation(const QString& theXMLRepresentation);\r
-\r
- /// Returns true if there are no model widgets\r
- /// \return the boolean value\r
- bool hasXmlRepresentation() const;\r
-\r
- private:\r
- //!< Next fields could be extracted into a subclass;\r
- /// the operation identifier\r
- QString myOperationId; \r
-\r
- /// the short description of the opertaion\r
- QString myDescription; \r
-\r
- /// the xml definition\r
- QString myXmlRepresentation; \r
-};\r
-\r
-#endif //ModuleBase_OperationDescription_H\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_OperationDescription.h
+ *
+ * Created on: Apr 2, 2014
+ * Author: sbh
+ */
+
+#ifndef MODULEBASE_OPERATIONDESCRIPTION_H
+#define MODULEBASE_OPERATIONDESCRIPTION_H
+
+#include <ModuleBase.h>
+#include <ModuleBase_Operation.h>
+
+#include <QObject>
+#include <QString>
+#include <QList>
+
+#include <memory>
+
+//class ModuleBase_ModelWidget;
+
+/*!
+ * \class ModuleBase_OperationDescription
+ * \ingroup GUI
+ * Description of operation from XML
+ */
+class MODULEBASE_EXPORT ModuleBase_OperationDescription
+{
+ public:
+ /// Constructor
+ /// \param theId - the operation identifier
+ ModuleBase_OperationDescription(const QString& theId = "");
+ /// Destructor
+ virtual ~ModuleBase_OperationDescription();
+
+ /// Unique name of the operation
+ /// \return string name of the operation.
+ const QString& operationId() const;
+
+ /// Returns a short description of operation (will be
+ /// inserted in title of property panel)
+ const QString& description() const;
+
+ /// Sets a short description of operation (will be
+ /// inserted in title of property panel)
+ void setDescription(const QString& theDescription);
+
+ /// Returns XML representation of the operation's widget.
+ /// \return XML QString
+ const QString& xmlRepresentation() const;
+
+ /// Sets XML representation of the operation's widget.
+ /// \param theXMLRepresentation - XML QString
+ void setXmlRepresentation(const QString& theXMLRepresentation);
+
+ /// Returns true if there are no model widgets
+ /// \return the boolean value
+ bool hasXmlRepresentation() const;
+
+ private:
+ //!< Next fields could be extracted into a subclass;
+ /// the operation identifier
+ QString myOperationId;
+
+ /// the short description of the opertaion
+ QString myDescription;
+
+ /// the xml definition
+ QString myXmlRepresentation;
+};
+
+#endif //ModuleBase_OperationDescription_H
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_WidgetConcealedObjects.cpp\r
-// Created: 29 Jul 2016\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#include <ModuleBase_WidgetConcealedObjects.h>\r
-#include <ModuleBase_Tools.h>\r
-\r
-#include <ModelAPI_Result.h>\r
-#include <ModelAPI_AttributeReference.h>\r
-#include <ModelAPI_AttributeRefList.h>\r
-#include <ModelAPI_Session.h>\r
-#include <ModelAPI_Validator.h>\r
-#include <ModelAPI_Tools.h>\r
-\r
-#include <Config_WidgetAPI.h>\r
-\r
-#include <QGridLayout>\r
-\r
-#include <QWidget>\r
-#include <QTableWidget>\r
-#include <QHeaderView>\r
-#include <QToolButton>\r
-\r
-const int DEFAULT_NAME_COLUMN_WIDTH = 200;\r
-\r
-ModuleBase_WidgetConcealedObjects::ModuleBase_WidgetConcealedObjects(QWidget* theParent,\r
- const Config_WidgetAPI* theData)\r
-: ModuleBase_ModelWidget(theParent, theData)\r
-{\r
- myBaseShapeAttribute = theData->getProperty("base_shape_attribute");\r
- QGridLayout* aMainLay = new QGridLayout(this);\r
- ModuleBase_Tools::adjustMargins(aMainLay);\r
-\r
- myView = new QTableWidget(this);\r
- aMainLay->addWidget(myView);\r
-\r
- myView->setColumnCount(2);\r
- myView->horizontalHeader()->setVisible(false);\r
- myView->verticalHeader()->setVisible(false);\r
-}\r
-\r
-ModuleBase_WidgetConcealedObjects::~ModuleBase_WidgetConcealedObjects()\r
-{\r
-}\r
-\r
-bool ModuleBase_WidgetConcealedObjects::storeValueCustom()\r
-{\r
- if(!myFeature)\r
- return false;\r
- DataPtr aData = myFeature->data();\r
- AttributeRefListPtr anAttributeList = aData->reflist(attributeID());\r
- anAttributeList->clear();\r
- int aSize1 = anAttributeList->size(false);\r
- for (int i = 0, aSize = myView->rowCount(); i < aSize; i++) {\r
- QToolButton* aButton = dynamic_cast<QToolButton*>(myView->cellWidget(i, 0));;\r
- if (aButton->isChecked())\r
- anAttributeList->append(myConcealedResults[i]);\r
- }\r
- int aSize = anAttributeList->size(false);\r
- return true;\r
-}\r
-\r
-bool ModuleBase_WidgetConcealedObjects::restoreValueCustom()\r
-{\r
- FeaturePtr aBaseFeature;\r
- ObjectPtr anObject;\r
- if (myFeature) {\r
- anObject = ModuleBase_Tools::getObject(myFeature->attribute(myBaseShapeAttribute));\r
- if (anObject.get() != NULL)\r
- aBaseFeature = ModelAPI_Feature::feature(anObject);\r
- }\r
- if (myBaseFeature != aBaseFeature) {\r
- myView->setRowCount(0);\r
- myConcealedResults.clear();\r
- myBaseFeature = aBaseFeature;\r
- if (myBaseFeature.get()) {\r
- std::list<std::shared_ptr<ModelAPI_Result> > aResults;\r
- ModelAPI_Tools::getConcealedResults(myBaseFeature, aResults);\r
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator anIt = aResults.begin(),\r
- aLast = aResults.end();\r
- for (; anIt != aLast; anIt++) {\r
- ResultPtr aResult = *anIt;\r
-\r
- int aRowId = myView->rowCount();\r
- addViewRow(aResult);\r
- myConcealedResults[aRowId] = aResult;\r
- }\r
- }\r
- }\r
- \r
- DataPtr aData = myFeature->data();\r
- AttributeRefListPtr anAttributeList = aData->reflist(attributeID());\r
- int aSize = anAttributeList->size();\r
- for (int i = 0, aSize = myView->rowCount(); i < aSize; i++) {\r
- ResultPtr aResult = myConcealedResults[i];\r
- QToolButton* aButton = dynamic_cast<QToolButton*>(myView->cellWidget(i, 0));\r
- bool isChecked = anAttributeList->isInList(aResult);\r
-\r
- bool aBlocked = aButton->blockSignals(true);\r
- aButton->setChecked(isChecked);\r
- this->updateItemIcon(aButton);\r
- aButton->blockSignals(aBlocked);\r
- }\r
- return true;\r
-}\r
-\r
-QList<QWidget*> ModuleBase_WidgetConcealedObjects::getControls() const\r
-{\r
- QList<QWidget*> result;\r
- result << myView;\r
- return result;\r
-}\r
-\r
-void ModuleBase_WidgetConcealedObjects::addViewRow(const std::shared_ptr<ModelAPI_Result>& theResult)\r
-{\r
- int anId = myView->rowCount();\r
- myView->setRowCount(anId+1);\r
-\r
- QToolButton* aVisibilityBtn = new QToolButton(this);\r
- connect(aVisibilityBtn, SIGNAL(toggled(bool)), this, SLOT(onItemToggled(bool)));\r
- aVisibilityBtn->setCheckable(true);\r
- aVisibilityBtn->setChecked(false);\r
- updateItemIcon(aVisibilityBtn);\r
-\r
- myView->setCellWidget(anId, 0, aVisibilityBtn);\r
- myView->setItem(anId, 1, new QTableWidgetItem(theResult->data()->name().c_str()));\r
-\r
- if (anId == 1) {\r
- myView->setColumnWidth(0, myView->verticalHeader()->defaultSectionSize());\r
- myView->setColumnWidth(1, DEFAULT_NAME_COLUMN_WIDTH);\r
- }\r
-}\r
-\r
-void ModuleBase_WidgetConcealedObjects::onItemToggled(bool theState)\r
-{\r
- emit valuesChanged();\r
- updateObject(myFeature);\r
-}\r
-\r
-void ModuleBase_WidgetConcealedObjects::updateItemIcon(QToolButton* theButton)\r
-{\r
- bool isChecked = theButton->isChecked();\r
- theButton->setIcon(isChecked ? QIcon(":icons/concealed_on.png")\r
- : QIcon(":icons/concealed_off.png"));\r
- theButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_WidgetConcealedObjects.cpp
+// Created: 29 Jul 2016
+// Author: Natalia ERMOLAEVA
+
+#include <ModuleBase_WidgetConcealedObjects.h>
+#include <ModuleBase_Tools.h>
+
+#include <ModelAPI_Result.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_Tools.h>
+
+#include <Config_WidgetAPI.h>
+
+#include <QGridLayout>
+
+#include <QWidget>
+#include <QTableWidget>
+#include <QHeaderView>
+#include <QToolButton>
+
+const int DEFAULT_NAME_COLUMN_WIDTH = 200;
+
+ModuleBase_WidgetConcealedObjects::ModuleBase_WidgetConcealedObjects(QWidget* theParent,
+ const Config_WidgetAPI* theData)
+: ModuleBase_ModelWidget(theParent, theData)
+{
+ myBaseShapeAttribute = theData->getProperty("base_shape_attribute");
+ QGridLayout* aMainLay = new QGridLayout(this);
+ ModuleBase_Tools::adjustMargins(aMainLay);
+
+ myView = new QTableWidget(this);
+ aMainLay->addWidget(myView);
+
+ myView->setColumnCount(2);
+ myView->horizontalHeader()->setVisible(false);
+ myView->verticalHeader()->setVisible(false);
+}
+
+ModuleBase_WidgetConcealedObjects::~ModuleBase_WidgetConcealedObjects()
+{
+}
+
+bool ModuleBase_WidgetConcealedObjects::storeValueCustom()
+{
+ if(!myFeature)
+ return false;
+ DataPtr aData = myFeature->data();
+ AttributeRefListPtr anAttributeList = aData->reflist(attributeID());
+ anAttributeList->clear();
+ int aSize1 = anAttributeList->size(false);
+ for (int i = 0, aSize = myView->rowCount(); i < aSize; i++) {
+ QToolButton* aButton = dynamic_cast<QToolButton*>(myView->cellWidget(i, 0));;
+ if (aButton->isChecked())
+ anAttributeList->append(myConcealedResults[i]);
+ }
+ int aSize = anAttributeList->size(false);
+ return true;
+}
+
+bool ModuleBase_WidgetConcealedObjects::restoreValueCustom()
+{
+ FeaturePtr aBaseFeature;
+ ObjectPtr anObject;
+ if (myFeature) {
+ anObject = ModuleBase_Tools::getObject(myFeature->attribute(myBaseShapeAttribute));
+ if (anObject.get() != NULL)
+ aBaseFeature = ModelAPI_Feature::feature(anObject);
+ }
+ if (myBaseFeature != aBaseFeature) {
+ myView->setRowCount(0);
+ myConcealedResults.clear();
+ myBaseFeature = aBaseFeature;
+ if (myBaseFeature.get()) {
+ std::list<std::shared_ptr<ModelAPI_Result> > aResults;
+ ModelAPI_Tools::getConcealedResults(myBaseFeature, aResults);
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator anIt = aResults.begin(),
+ aLast = aResults.end();
+ for (; anIt != aLast; anIt++) {
+ ResultPtr aResult = *anIt;
+
+ int aRowId = myView->rowCount();
+ addViewRow(aResult);
+ myConcealedResults[aRowId] = aResult;
+ }
+ }
+ }
+
+ DataPtr aData = myFeature->data();
+ AttributeRefListPtr anAttributeList = aData->reflist(attributeID());
+ int aSize = anAttributeList->size();
+ for (int i = 0, aSize = myView->rowCount(); i < aSize; i++) {
+ ResultPtr aResult = myConcealedResults[i];
+ QToolButton* aButton = dynamic_cast<QToolButton*>(myView->cellWidget(i, 0));
+ bool isChecked = anAttributeList->isInList(aResult);
+
+ bool aBlocked = aButton->blockSignals(true);
+ aButton->setChecked(isChecked);
+ this->updateItemIcon(aButton);
+ aButton->blockSignals(aBlocked);
+ }
+ return true;
+}
+
+QList<QWidget*> ModuleBase_WidgetConcealedObjects::getControls() const
+{
+ QList<QWidget*> result;
+ result << myView;
+ return result;
+}
+
+void ModuleBase_WidgetConcealedObjects::addViewRow(const std::shared_ptr<ModelAPI_Result>& theResult)
+{
+ int anId = myView->rowCount();
+ myView->setRowCount(anId+1);
+
+ QToolButton* aVisibilityBtn = new QToolButton(this);
+ connect(aVisibilityBtn, SIGNAL(toggled(bool)), this, SLOT(onItemToggled(bool)));
+ aVisibilityBtn->setCheckable(true);
+ aVisibilityBtn->setChecked(false);
+ updateItemIcon(aVisibilityBtn);
+
+ myView->setCellWidget(anId, 0, aVisibilityBtn);
+ myView->setItem(anId, 1, new QTableWidgetItem(theResult->data()->name().c_str()));
+
+ if (anId == 1) {
+ myView->setColumnWidth(0, myView->verticalHeader()->defaultSectionSize());
+ myView->setColumnWidth(1, DEFAULT_NAME_COLUMN_WIDTH);
+ }
+}
+
+void ModuleBase_WidgetConcealedObjects::onItemToggled(bool theState)
+{
+ emit valuesChanged();
+ updateObject(myFeature);
+}
+
+void ModuleBase_WidgetConcealedObjects::updateItemIcon(QToolButton* theButton)
+{
+ bool isChecked = theButton->isChecked();
+ theButton->setIcon(isChecked ? QIcon(":icons/concealed_on.png")
+ : QIcon(":icons/concealed_off.png"));
+ theButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+}
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_WidgetConcealedObjects.h\r
-// Created: 29 Jul 2016\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#ifndef MODULEBASE_WIDGETCONCEALEDOBJECTS_H_\r
-#define MODULEBASE_WIDGETCONCEALEDOBJECTS_H_\r
-\r
-#include <ModuleBase.h>\r
-#include <ModuleBase_ModelWidget.h>\r
-\r
-#include <string>\r
-#include <map>\r
-#include <memory>\r
-\r
-class ModelAPI_Object;\r
-\r
-class QWidget;\r
-class QTableWidget;\r
-class QToolButton;\r
-\r
-/**\r
-* \ingroup GUI\r
-* Implementation of model widget for table of concealed objects.\r
-*/\r
-class MODULEBASE_EXPORT ModuleBase_WidgetConcealedObjects : public ModuleBase_ModelWidget\r
-{\r
- Q_OBJECT\r
- public:\r
- /// Constructor\r
- /// \param theParent the parent object\r
- /// \param theData the widget configuration.\r
- ModuleBase_WidgetConcealedObjects(QWidget* theParent,\r
- const Config_WidgetAPI* theData);\r
- virtual ~ModuleBase_WidgetConcealedObjects();\r
-\r
- /// Redefinition of virtual method\r
- virtual QList<QWidget*> getControls() const;\r
-\r
- /// The widget can not accept focus\r
- virtual bool canAcceptFocus() const { return false; };\r
-\r
-protected:\r
- /// Saves the internal parameters to the given feature\r
- /// \return True in success\r
- virtual bool storeValueCustom();\r
-\r
- /// Redefinition of virtual method\r
- virtual bool restoreValueCustom();\r
-\r
-private:\r
- /// Creates a row in view\r
- /// \param theResult a result for the row\r
- void addViewRow(const std::shared_ptr<ModelAPI_Result>& theResult);\r
-\r
-private slots:\r
- /// Processes the display button click in the view.\r
- /// \param theState a new state\r
- void onItemToggled(bool theState);\r
-\r
-private:\r
- /// Updates icon of button\r
- /// \param theButton a button of the table\r
- void updateItemIcon(QToolButton* theButton);\r
-\r
-private:\r
- std::string myBaseShapeAttribute; ///< attribute of the base object\r
- QTableWidget* myView; ///< table view of visibility states\r
-\r
- std::shared_ptr<ModelAPI_Feature> myBaseFeature; ///< backup of feature of filling the table view\r
- /// backup of visualized in the view concealed objects, stored to avoid table rebuild by restore\r
- std::map<int, std::shared_ptr<ModelAPI_Result> > myConcealedResults;\r
-};\r
-\r
-#endif /* MODULEBASE_WIDGETCONCEALEDOBJECTS_H_ */\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_WidgetConcealedObjects.h
+// Created: 29 Jul 2016
+// Author: Natalia ERMOLAEVA
+
+#ifndef MODULEBASE_WIDGETCONCEALEDOBJECTS_H_
+#define MODULEBASE_WIDGETCONCEALEDOBJECTS_H_
+
+#include <ModuleBase.h>
+#include <ModuleBase_ModelWidget.h>
+
+#include <string>
+#include <map>
+#include <memory>
+
+class ModelAPI_Object;
+
+class QWidget;
+class QTableWidget;
+class QToolButton;
+
+/**
+* \ingroup GUI
+* Implementation of model widget for table of concealed objects.
+*/
+class MODULEBASE_EXPORT ModuleBase_WidgetConcealedObjects : public ModuleBase_ModelWidget
+{
+ Q_OBJECT
+ public:
+ /// Constructor
+ /// \param theParent the parent object
+ /// \param theData the widget configuration.
+ ModuleBase_WidgetConcealedObjects(QWidget* theParent,
+ const Config_WidgetAPI* theData);
+ virtual ~ModuleBase_WidgetConcealedObjects();
+
+ /// Redefinition of virtual method
+ virtual QList<QWidget*> getControls() const;
+
+ /// The widget can not accept focus
+ virtual bool canAcceptFocus() const { return false; };
+
+protected:
+ /// Saves the internal parameters to the given feature
+ /// \return True in success
+ virtual bool storeValueCustom();
+
+ /// Redefinition of virtual method
+ virtual bool restoreValueCustom();
+
+private:
+ /// Creates a row in view
+ /// \param theResult a result for the row
+ void addViewRow(const std::shared_ptr<ModelAPI_Result>& theResult);
+
+private slots:
+ /// Processes the display button click in the view.
+ /// \param theState a new state
+ void onItemToggled(bool theState);
+
+private:
+ /// Updates icon of button
+ /// \param theButton a button of the table
+ void updateItemIcon(QToolButton* theButton);
+
+private:
+ std::string myBaseShapeAttribute; ///< attribute of the base object
+ QTableWidget* myView; ///< table view of visibility states
+
+ std::shared_ptr<ModelAPI_Feature> myBaseFeature; ///< backup of feature of filling the table view
+ /// backup of visualized in the view concealed objects, stored to avoid table rebuild by restore
+ std::map<int, std::shared_ptr<ModelAPI_Result> > myConcealedResults;
+};
+
+#endif /* MODULEBASE_WIDGETCONCEALEDOBJECTS_H_ */
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-/*\r
- * ModuleBase_WidgetFactory.cpp\r
- *\r
- * Created on: Apr 3, 2014\r
- * Author: sbh\r
- */\r
-\r
-#include <ModuleBase_WidgetFactory.h>\r
-#include <ModuleBase_IconFactory.h>\r
-\r
-#include <ModuleBase_Operation.h>\r
-#include <ModuleBase_OperationDescription.h>\r
-#include <ModuleBase_WidgetEditor.h>\r
-#include <ModuleBase_WidgetSwitch.h>\r
-#include <ModuleBase_WidgetShapeSelector.h>\r
-#include <ModuleBase_WidgetFeatureSelector.h>\r
-#include <ModuleBase_WidgetDoubleValue.h>\r
-#include <ModuleBase_WidgetIntValue.h>\r
-#include <ModuleBase_WidgetBoolValue.h>\r
-#include <ModuleBase_WidgetFileSelector.h>\r
-#include <ModuleBase_WidgetChoice.h>\r
-#include <ModuleBase_IWorkshop.h>\r
-#include <ModuleBase_IModule.h>\r
-#include <ModuleBase_Tools.h>\r
-#include <ModuleBase_WidgetLineEdit.h>\r
-#include <ModuleBase_WidgetMultiSelector.h>\r
-#include <ModuleBase_WidgetConcealedObjects.h>\r
-#include <ModuleBase_WidgetLabel.h>\r
-#include <ModuleBase_WidgetToolbox.h>\r
-#include <ModuleBase_PageBase.h>\r
-#include <ModuleBase_PageGroupBox.h>\r
-#include <ModuleBase_WidgetOptionalBox.h>\r
-#include <ModuleBase_PageWidget.h>\r
-#include <ModuleBase_WidgetExprEditor.h>\r
-#include <ModuleBase_WidgetCreatorFactory.h>\r
-#include <ModuleBase_WidgetAction.h>\r
-\r
-#include <ModelAPI_Validator.h>\r
-#include <ModelAPI_Session.h>\r
-\r
-#include <Config_Keywords.h>\r
-#include <Config_WidgetAPI.h>\r
-\r
-#include <QWidget>\r
-#include <QHBoxLayout>\r
-#include <QGridLayout>\r
-#include <QSpinBox>\r
-#include <QMetaProperty>\r
-#include <QLabel>\r
-#include <QPixmap>\r
-#include <QGroupBox>\r
-#include <QToolBox>\r
-\r
-#ifdef _DEBUG\r
-#include <QDebug>\r
-#endif\r
-\r
-#include <cfloat>\r
-#include <climits>\r
-\r
-ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(const std::string& theXmlRepresentation,\r
- ModuleBase_IWorkshop* theWorkshop)\r
- : myWorkshop(theWorkshop)\r
-{\r
- myWidgetApi = new Config_WidgetAPI(theXmlRepresentation);\r
-}\r
-\r
-ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()\r
-{\r
- delete myWidgetApi;\r
-}\r
-\r
-void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage, bool alignToTop)\r
-{\r
- std::string aWType = myWidgetApi->widgetType();\r
- if (aWType == NODE_FEATURE) {\r
- // if XML definition of the feature contains the next key, the widgets should not be created,\r
- // but a specific panel should be made. However, to provide persistent of the panel values,\r
- // we need to get into the panel the feature of the operation. As a result this panel should\r
- // be created after the feature creating(create operation). The method setPanel() of this\r
- // class is used for this. Here, we just return to avoid the widgets creation.\r
- std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);\r
- if (!aPanelName.empty())\r
- return;\r
- }\r
-\r
- if (!myWidgetApi->toChildWidget())\r
- return;\r
-\r
- do { //Iterate over each node\r
- std::string aWdgType = myWidgetApi->widgetType();\r
- // Create PageGroup TODO: extract\r
- if (myWidgetApi->isGroupBoxWidget() ||\r
- ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {\r
-\r
- //if current widget is groupbox (container) process it's children recursively\r
- ModuleBase_PageBase* aPage = createPageByType(aWdgType, thePage->pageWidget());\r
-\r
- createWidget(aPage);\r
- thePage->addPageWidget(aPage);\r
- } else {\r
- // Create a ModelWidget\r
- ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, thePage->pageWidget());\r
- if (aWidget) {\r
- if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {\r
- thePage->addModelWidget(aWidget);\r
- } else {\r
- aWidget->setVisible(false);\r
- }\r
- }\r
- // Create PagedContainer TODO: extract\r
- if (myWidgetApi->isPagedWidget()) {\r
- //If current widget is toolbox or switch-casebox then fetch all\r
- //it's pages recursively and setup into the widget.\r
- if (myWidgetApi->toChildWidget()) {\r
- do {\r
- QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));\r
- QString aCaseId = qs(myWidgetApi->getProperty(_ID));\r
- ModuleBase_PageBase* aPage = new ModuleBase_PageWidget(aWidget);\r
- createWidget(aPage);\r
- if (aWdgType == WDG_SWITCH || aWdgType == WDG_TOOLBOX) {\r
- ModuleBase_PagedContainer* aContainer = qobject_cast<ModuleBase_PagedContainer*>(aWidget);\r
-\r
- QString anIconPath = qs( myWidgetApi->getProperty( CONTAINER_PAGE_ICON ) );\r
- QPixmap anIcon = ModuleBase_IconFactory::loadPixmap( anIconPath );\r
- aContainer->addPage( aPage, aPageName, aCaseId, anIcon );\r
- }\r
- } while (myWidgetApi->toNextWidget());\r
- }\r
- }\r
- }\r
- } while (myWidgetApi->toNextWidget());\r
-\r
- if (alignToTop)\r
- thePage->alignToTop();\r
-}\r
-\r
-void ModuleBase_WidgetFactory::createPanel(ModuleBase_PageBase* thePage,\r
- const FeaturePtr& theFeature)\r
-{\r
- std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);\r
- if (!aPanelName.empty() && ModuleBase_WidgetCreatorFactory::get()->hasPanelWidget(aPanelName)) {\r
- QWidget* aPanel = ModuleBase_WidgetCreatorFactory::get()->createPanelByType(aPanelName,\r
- thePage->pageWidget(), theFeature);\r
- thePage->addWidget(aPanel);\r
- thePage->alignToTop();\r
- }\r
-}\r
-\r
-void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage,\r
- const std::string& theWidgetId)\r
-{\r
- bool aFound = false;\r
- moveToWidgetId(theWidgetId, aFound);\r
- if (aFound) {\r
- std::string aWdgType = myWidgetApi->widgetType();\r
-\r
- // Create a ModelWidget\r
- ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, thePage->pageWidget());\r
- if (aWidget) {\r
- if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {\r
- thePage->addModelWidget(aWidget);\r
- }\r
- else {\r
- aWidget->setVisible(false);\r
- }\r
- }\r
- }\r
- thePage->alignToTop();\r
-}\r
-\r
-void ModuleBase_WidgetFactory::getAttributeTitle(const std::string& theAttributeId,\r
- std::string& theTitle)\r
-{\r
- bool aFound = false;\r
- moveToWidgetId(theAttributeId, aFound);\r
- if (aFound) {\r
- theTitle = QString::fromStdString(myWidgetApi->widgetLabel()).toStdString().c_str();\r
- if (theTitle.empty())\r
- theTitle = QString::fromStdString(myWidgetApi->getProperty(CONTAINER_PAGE_NAME)).toStdString().c_str();\r
- }\r
-}\r
-\r
-void ModuleBase_WidgetFactory::getGreedAttribute(std::string& theAttributeId)\r
-{\r
- if (!theAttributeId.empty())\r
- return;\r
-\r
- if (!myWidgetApi->toChildWidget())\r
- return;\r
-\r
- do { //Iterate over each node\r
- std::string aWdgType = myWidgetApi->widgetType();\r
- // Find title under PageGroup\r
- if (myWidgetApi->isGroupBoxWidget() ||\r
- ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {\r
- getGreedAttribute(theAttributeId);\r
- }\r
- else {\r
- // Find title here\r
- std::string anAttributeId = myWidgetApi->widgetId();\r
- if (myWidgetApi->getBooleanAttribute(ATTR_GREED, false))\r
- theAttributeId = anAttributeId;\r
- if (theAttributeId.empty() && myWidgetApi->isPagedWidget()) {\r
- //If current widget is toolbox or switch-casebox then fetch all\r
- //it's pages recursively and setup into the widget.\r
- if (myWidgetApi->toChildWidget()) {\r
- do {\r
- getGreedAttribute(theAttributeId);\r
- } while (theAttributeId.empty() && myWidgetApi->toNextWidget());\r
- }\r
- }\r
- }\r
- } while (theAttributeId.empty() && myWidgetApi->toNextWidget());\r
-}\r
-\r
-void ModuleBase_WidgetFactory::moveToWidgetId(const std::string& theWidgetId, bool& theFound)\r
-{\r
- if (theFound)\r
- return;\r
-\r
- if (!myWidgetApi->toChildWidget())\r
- return;\r
-\r
- do { //Iterate over each node\r
- std::string aWdgType = myWidgetApi->widgetType();\r
- // Find title under PageGroup\r
- if (myWidgetApi->isGroupBoxWidget() ||\r
- ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {\r
- moveToWidgetId(theWidgetId, theFound);\r
- }\r
- else {\r
- // Find title here\r
- std::string anAttributeId = myWidgetApi->widgetId();\r
- theFound = anAttributeId == theWidgetId;\r
- if (!theFound && myWidgetApi->isPagedWidget()) {\r
- //If current widget is toolbox or switch-casebox then fetch all\r
- //it's pages recursively and setup into the widget.\r
- if (myWidgetApi->toChildWidget()) {\r
- do {\r
- moveToWidgetId(theWidgetId, theFound);\r
- } while (!theFound && myWidgetApi->toNextWidget());\r
- }\r
- }\r
- }\r
- } while (!theFound && myWidgetApi->toNextWidget());\r
-}\r
-\r
-ModuleBase_PageBase* ModuleBase_WidgetFactory::createPageByType(const std::string& theType,\r
- QWidget* theParent)\r
-{\r
- ModuleBase_PageBase* aResult = NULL;\r
-\r
- if (theType == WDG_GROUP) {\r
- QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));\r
- ModuleBase_PageGroupBox* aPage = new ModuleBase_PageGroupBox(theParent);\r
- aPage->setTitle(aGroupName);\r
- aResult = aPage;\r
- }\r
- else if (theType == WDG_OPTIONALBOX) {\r
- ModuleBase_WidgetOptionalBox* aPage = new ModuleBase_WidgetOptionalBox(theParent,\r
- myWidgetApi);\r
- aResult = aPage;\r
- }\r
- if (!aResult)\r
- aResult = ModuleBase_WidgetCreatorFactory::get()->createPageByType(theType, theParent,\r
- myWidgetApi);\r
-\r
- ModuleBase_ModelWidget* aWidget = dynamic_cast<ModuleBase_ModelWidget*>(aResult);\r
- if (aWidget)\r
- myModelWidgets.append(aWidget);\r
-\r
- return aResult;\r
-}\r
-\r
-ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType,\r
- QWidget* theParent)\r
-{\r
- ModuleBase_ModelWidget* result = NULL;\r
-\r
- if (theType == WDG_INFO) {\r
- result = new ModuleBase_WidgetLabel(theParent, myWidgetApi);\r
- } else if (theType == WDG_DOUBLEVALUE) {\r
- result = new ModuleBase_WidgetDoubleValue(theParent, myWidgetApi);\r
- } else if (theType == WDG_INTEGERVALUE) {\r
- result = new ModuleBase_WidgetIntValue(theParent, myWidgetApi);\r
- } else if (theType == WDG_SHAPE_SELECTOR) {\r
- result = new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi);\r
- } else if (theType == WDG_FEATURE_SELECTOR) {\r
- result = new ModuleBase_WidgetFeatureSelector(theParent, myWorkshop, myWidgetApi);\r
- } else if (theType == WDG_BOOLVALUE) {\r
- result = new ModuleBase_WidgetBoolValue(theParent, myWidgetApi);\r
- //} else if (theType == WDG_DOUBLEVALUE_EDITOR) {\r
- // result = new ModuleBase_WidgetEditor(theParent, myWidgetApi);\r
- } else if (theType == WDG_FILE_SELECTOR) {\r
- result = new ModuleBase_WidgetFileSelector(theParent, myWidgetApi);\r
- } else if (theType == WDG_CHOICE) {\r
- result = new ModuleBase_WidgetChoice(theParent, myWidgetApi);\r
- } else if (theType == WDG_STRINGVALUE) {\r
- std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );\r
- result = new ModuleBase_WidgetLineEdit( theParent, myWidgetApi, aPlaceHolder );\r
- } else if (theType == WDG_EXPR_EDITOR) {\r
- std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );\r
- result = new ModuleBase_WidgetExprEditor( theParent, myWidgetApi, aPlaceHolder );\r
- } else if (theType == WDG_MULTISELECTOR) {\r
- result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi);\r
- } else if (theType == WDG_CONCEALED_OBJECTS_VIEW) {\r
- result = new ModuleBase_WidgetConcealedObjects(theParent, myWidgetApi);\r
- } else if (theType == WDG_TOOLBOX) {\r
- result = new ModuleBase_WidgetToolbox(theParent, myWidgetApi);\r
- } else if (theType == WDG_SWITCH) {\r
- result = new ModuleBase_WidgetSwitch(theParent, myWidgetApi);\r
- } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE ||\r
- theType == NODE_VALIDATOR) {\r
- // Do nothing for "box" and "case"\r
- result = NULL;\r
- } else if (theType == WDG_ACTION) {\r
- result = new ModuleBase_WidgetAction(theParent, myWidgetApi);\r
- } else {\r
- result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi);\r
- if (!result)\r
- result = ModuleBase_WidgetCreatorFactory::get()->createWidgetByType(theType, theParent,\r
- myWidgetApi, myWorkshop);\r
- #ifdef _DEBUG\r
- if (!result) {\r
- qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type %s", theType.c_str());\r
- }\r
- #endif\r
- }\r
- if (result)\r
- myModelWidgets.append(result);\r
- return result;\r
-}\r
-\r
-QString ModuleBase_WidgetFactory::qs(const std::string& theStdString)\r
-{\r
- return QString::fromStdString(theStdString);\r
-}\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_WidgetFactory.cpp
+ *
+ * Created on: Apr 3, 2014
+ * Author: sbh
+ */
+
+#include <ModuleBase_WidgetFactory.h>
+#include <ModuleBase_IconFactory.h>
+
+#include <ModuleBase_Operation.h>
+#include <ModuleBase_OperationDescription.h>
+#include <ModuleBase_WidgetEditor.h>
+#include <ModuleBase_WidgetSwitch.h>
+#include <ModuleBase_WidgetShapeSelector.h>
+#include <ModuleBase_WidgetFeatureSelector.h>
+#include <ModuleBase_WidgetDoubleValue.h>
+#include <ModuleBase_WidgetIntValue.h>
+#include <ModuleBase_WidgetBoolValue.h>
+#include <ModuleBase_WidgetFileSelector.h>
+#include <ModuleBase_WidgetChoice.h>
+#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_WidgetLineEdit.h>
+#include <ModuleBase_WidgetMultiSelector.h>
+#include <ModuleBase_WidgetConcealedObjects.h>
+#include <ModuleBase_WidgetLabel.h>
+#include <ModuleBase_WidgetToolbox.h>
+#include <ModuleBase_PageBase.h>
+#include <ModuleBase_PageGroupBox.h>
+#include <ModuleBase_WidgetOptionalBox.h>
+#include <ModuleBase_PageWidget.h>
+#include <ModuleBase_WidgetExprEditor.h>
+#include <ModuleBase_WidgetCreatorFactory.h>
+#include <ModuleBase_WidgetAction.h>
+
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_Session.h>
+
+#include <Config_Keywords.h>
+#include <Config_WidgetAPI.h>
+
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QGridLayout>
+#include <QSpinBox>
+#include <QMetaProperty>
+#include <QLabel>
+#include <QPixmap>
+#include <QGroupBox>
+#include <QToolBox>
+
+#ifdef _DEBUG
+#include <QDebug>
+#endif
+
+#include <cfloat>
+#include <climits>
+
+ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(const std::string& theXmlRepresentation,
+ ModuleBase_IWorkshop* theWorkshop)
+ : myWorkshop(theWorkshop)
+{
+ myWidgetApi = new Config_WidgetAPI(theXmlRepresentation);
+}
+
+ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()
+{
+ delete myWidgetApi;
+}
+
+void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage, bool alignToTop)
+{
+ std::string aWType = myWidgetApi->widgetType();
+ if (aWType == NODE_FEATURE) {
+ // if XML definition of the feature contains the next key, the widgets should not be created,
+ // but a specific panel should be made. However, to provide persistent of the panel values,
+ // we need to get into the panel the feature of the operation. As a result this panel should
+ // be created after the feature creating(create operation). The method setPanel() of this
+ // class is used for this. Here, we just return to avoid the widgets creation.
+ std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
+ if (!aPanelName.empty())
+ return;
+ }
+
+ if (!myWidgetApi->toChildWidget())
+ return;
+
+ do { //Iterate over each node
+ std::string aWdgType = myWidgetApi->widgetType();
+ // Create PageGroup TODO: extract
+ if (myWidgetApi->isGroupBoxWidget() ||
+ ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {
+
+ //if current widget is groupbox (container) process it's children recursively
+ ModuleBase_PageBase* aPage = createPageByType(aWdgType, thePage->pageWidget());
+
+ createWidget(aPage);
+ thePage->addPageWidget(aPage);
+ } else {
+ // Create a ModelWidget
+ ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, thePage->pageWidget());
+ if (aWidget) {
+ if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {
+ thePage->addModelWidget(aWidget);
+ } else {
+ aWidget->setVisible(false);
+ }
+ }
+ // Create PagedContainer TODO: extract
+ if (myWidgetApi->isPagedWidget()) {
+ //If current widget is toolbox or switch-casebox then fetch all
+ //it's pages recursively and setup into the widget.
+ if (myWidgetApi->toChildWidget()) {
+ do {
+ QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
+ QString aCaseId = qs(myWidgetApi->getProperty(_ID));
+ ModuleBase_PageBase* aPage = new ModuleBase_PageWidget(aWidget);
+ createWidget(aPage);
+ if (aWdgType == WDG_SWITCH || aWdgType == WDG_TOOLBOX) {
+ ModuleBase_PagedContainer* aContainer = qobject_cast<ModuleBase_PagedContainer*>(aWidget);
+
+ QString anIconPath = qs( myWidgetApi->getProperty( CONTAINER_PAGE_ICON ) );
+ QPixmap anIcon = ModuleBase_IconFactory::loadPixmap( anIconPath );
+ aContainer->addPage( aPage, aPageName, aCaseId, anIcon );
+ }
+ } while (myWidgetApi->toNextWidget());
+ }
+ }
+ }
+ } while (myWidgetApi->toNextWidget());
+
+ if (alignToTop)
+ thePage->alignToTop();
+}
+
+void ModuleBase_WidgetFactory::createPanel(ModuleBase_PageBase* thePage,
+ const FeaturePtr& theFeature)
+{
+ std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
+ if (!aPanelName.empty() && ModuleBase_WidgetCreatorFactory::get()->hasPanelWidget(aPanelName)) {
+ QWidget* aPanel = ModuleBase_WidgetCreatorFactory::get()->createPanelByType(aPanelName,
+ thePage->pageWidget(), theFeature);
+ thePage->addWidget(aPanel);
+ thePage->alignToTop();
+ }
+}
+
+void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage,
+ const std::string& theWidgetId)
+{
+ bool aFound = false;
+ moveToWidgetId(theWidgetId, aFound);
+ if (aFound) {
+ std::string aWdgType = myWidgetApi->widgetType();
+
+ // Create a ModelWidget
+ ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, thePage->pageWidget());
+ if (aWidget) {
+ if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {
+ thePage->addModelWidget(aWidget);
+ }
+ else {
+ aWidget->setVisible(false);
+ }
+ }
+ }
+ thePage->alignToTop();
+}
+
+void ModuleBase_WidgetFactory::getAttributeTitle(const std::string& theAttributeId,
+ std::string& theTitle)
+{
+ bool aFound = false;
+ moveToWidgetId(theAttributeId, aFound);
+ if (aFound) {
+ theTitle = QString::fromStdString(myWidgetApi->widgetLabel()).toStdString().c_str();
+ if (theTitle.empty())
+ theTitle = QString::fromStdString(myWidgetApi->getProperty(CONTAINER_PAGE_NAME)).toStdString().c_str();
+ }
+}
+
+void ModuleBase_WidgetFactory::getGreedAttribute(std::string& theAttributeId)
+{
+ if (!theAttributeId.empty())
+ return;
+
+ if (!myWidgetApi->toChildWidget())
+ return;
+
+ do { //Iterate over each node
+ std::string aWdgType = myWidgetApi->widgetType();
+ // Find title under PageGroup
+ if (myWidgetApi->isGroupBoxWidget() ||
+ ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {
+ getGreedAttribute(theAttributeId);
+ }
+ else {
+ // Find title here
+ std::string anAttributeId = myWidgetApi->widgetId();
+ if (myWidgetApi->getBooleanAttribute(ATTR_GREED, false))
+ theAttributeId = anAttributeId;
+ if (theAttributeId.empty() && myWidgetApi->isPagedWidget()) {
+ //If current widget is toolbox or switch-casebox then fetch all
+ //it's pages recursively and setup into the widget.
+ if (myWidgetApi->toChildWidget()) {
+ do {
+ getGreedAttribute(theAttributeId);
+ } while (theAttributeId.empty() && myWidgetApi->toNextWidget());
+ }
+ }
+ }
+ } while (theAttributeId.empty() && myWidgetApi->toNextWidget());
+}
+
+void ModuleBase_WidgetFactory::moveToWidgetId(const std::string& theWidgetId, bool& theFound)
+{
+ if (theFound)
+ return;
+
+ if (!myWidgetApi->toChildWidget())
+ return;
+
+ do { //Iterate over each node
+ std::string aWdgType = myWidgetApi->widgetType();
+ // Find title under PageGroup
+ if (myWidgetApi->isGroupBoxWidget() ||
+ ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {
+ moveToWidgetId(theWidgetId, theFound);
+ }
+ else {
+ // Find title here
+ std::string anAttributeId = myWidgetApi->widgetId();
+ theFound = anAttributeId == theWidgetId;
+ if (!theFound && myWidgetApi->isPagedWidget()) {
+ //If current widget is toolbox or switch-casebox then fetch all
+ //it's pages recursively and setup into the widget.
+ if (myWidgetApi->toChildWidget()) {
+ do {
+ moveToWidgetId(theWidgetId, theFound);
+ } while (!theFound && myWidgetApi->toNextWidget());
+ }
+ }
+ }
+ } while (!theFound && myWidgetApi->toNextWidget());
+}
+
+ModuleBase_PageBase* ModuleBase_WidgetFactory::createPageByType(const std::string& theType,
+ QWidget* theParent)
+{
+ ModuleBase_PageBase* aResult = NULL;
+
+ if (theType == WDG_GROUP) {
+ QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
+ ModuleBase_PageGroupBox* aPage = new ModuleBase_PageGroupBox(theParent);
+ aPage->setTitle(aGroupName);
+ aResult = aPage;
+ }
+ else if (theType == WDG_OPTIONALBOX) {
+ ModuleBase_WidgetOptionalBox* aPage = new ModuleBase_WidgetOptionalBox(theParent,
+ myWidgetApi);
+ aResult = aPage;
+ }
+ if (!aResult)
+ aResult = ModuleBase_WidgetCreatorFactory::get()->createPageByType(theType, theParent,
+ myWidgetApi);
+
+ ModuleBase_ModelWidget* aWidget = dynamic_cast<ModuleBase_ModelWidget*>(aResult);
+ if (aWidget)
+ myModelWidgets.append(aWidget);
+
+ return aResult;
+}
+
+ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType,
+ QWidget* theParent)
+{
+ ModuleBase_ModelWidget* result = NULL;
+
+ if (theType == WDG_INFO) {
+ result = new ModuleBase_WidgetLabel(theParent, myWidgetApi);
+ } else if (theType == WDG_DOUBLEVALUE) {
+ result = new ModuleBase_WidgetDoubleValue(theParent, myWidgetApi);
+ } else if (theType == WDG_INTEGERVALUE) {
+ result = new ModuleBase_WidgetIntValue(theParent, myWidgetApi);
+ } else if (theType == WDG_SHAPE_SELECTOR) {
+ result = new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi);
+ } else if (theType == WDG_FEATURE_SELECTOR) {
+ result = new ModuleBase_WidgetFeatureSelector(theParent, myWorkshop, myWidgetApi);
+ } else if (theType == WDG_BOOLVALUE) {
+ result = new ModuleBase_WidgetBoolValue(theParent, myWidgetApi);
+ //} else if (theType == WDG_DOUBLEVALUE_EDITOR) {
+ // result = new ModuleBase_WidgetEditor(theParent, myWidgetApi);
+ } else if (theType == WDG_FILE_SELECTOR) {
+ result = new ModuleBase_WidgetFileSelector(theParent, myWidgetApi);
+ } else if (theType == WDG_CHOICE) {
+ result = new ModuleBase_WidgetChoice(theParent, myWidgetApi);
+ } else if (theType == WDG_STRINGVALUE) {
+ std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
+ result = new ModuleBase_WidgetLineEdit( theParent, myWidgetApi, aPlaceHolder );
+ } else if (theType == WDG_EXPR_EDITOR) {
+ std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
+ result = new ModuleBase_WidgetExprEditor( theParent, myWidgetApi, aPlaceHolder );
+ } else if (theType == WDG_MULTISELECTOR) {
+ result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi);
+ } else if (theType == WDG_CONCEALED_OBJECTS_VIEW) {
+ result = new ModuleBase_WidgetConcealedObjects(theParent, myWidgetApi);
+ } else if (theType == WDG_TOOLBOX) {
+ result = new ModuleBase_WidgetToolbox(theParent, myWidgetApi);
+ } else if (theType == WDG_SWITCH) {
+ result = new ModuleBase_WidgetSwitch(theParent, myWidgetApi);
+ } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE ||
+ theType == NODE_VALIDATOR) {
+ // Do nothing for "box" and "case"
+ result = NULL;
+ } else if (theType == WDG_ACTION) {
+ result = new ModuleBase_WidgetAction(theParent, myWidgetApi);
+ } else {
+ result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi);
+ if (!result)
+ result = ModuleBase_WidgetCreatorFactory::get()->createWidgetByType(theType, theParent,
+ myWidgetApi, myWorkshop);
+ #ifdef _DEBUG
+ if (!result) {
+ qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type %s", theType.c_str());
+ }
+ #endif
+ }
+ if (result)
+ myModelWidgets.append(result);
+ return result;
+}
+
+QString ModuleBase_WidgetFactory::qs(const std::string& theStdString)
+{
+ return QString::fromStdString(theStdString);
+}
+
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_WidgetFeatureSelector.cpp\r
-// Created: 5 Sep 2016\r
-// Author: Natalia Ermolaeva\r
-\r
-#include <ModuleBase_WidgetFeatureSelector.h>\r
-\r
-#include <ModuleBase_Definitions.h>\r
-#include <ModuleBase_ISelection.h>\r
-#include <ModuleBase_IWorkshop.h>\r
-#include <ModuleBase_IViewer.h>\r
-#include <ModuleBase_Tools.h>\r
-#include <ModuleBase_FilterFactory.h>\r
-#include <ModuleBase_Filter.h>\r
-#include <ModuleBase_IModule.h>\r
-#include <ModuleBase_ViewerPrs.h>\r
-#include <ModuleBase_IconFactory.h>\r
-#include <ModuleBase_ResultPrs.h>\r
-\r
-#include <Config_WidgetAPI.h>\r
-#include <Events_Loop.h>\r
-#include <Events_Message.h>\r
-#include <GeomAPI_Interface.h>\r
-#include <GeomAPI_Shape.h>\r
-\r
-#include <ModelAPI_Data.h>\r
-#include <ModelAPI_Document.h>\r
-#include <ModelAPI_Events.h>\r
-#include <ModelAPI_Feature.h>\r
-#include <ModelAPI_Result.h>\r
-#include <ModelAPI_Session.h>\r
-\r
-#include <Config_WidgetAPI.h>\r
-\r
-#include <GeomAPI_Shape.h>\r
-\r
-#include <QWidget>\r
-#include <QLayout>\r
-#include <QLabel>\r
-#include <QLineEdit>\r
-#include <QToolButton>\r
-#include <QString>\r
-#include <QEvent>\r
-#include <QApplication>\r
-#include <QFormLayout>\r
-\r
-#include <memory>\r
-\r
-#include <list>\r
-#include <string>\r
-\r
-\r
-ModuleBase_WidgetFeatureSelector::ModuleBase_WidgetFeatureSelector(QWidget* theParent,\r
- ModuleBase_IWorkshop* theWorkshop,\r
- const Config_WidgetAPI* theData)\r
-: ModuleBase_WidgetValidated(theParent, theWorkshop, theData)\r
-{\r
- QFormLayout* aLayout = new QFormLayout(this);\r
- ModuleBase_Tools::adjustMargins(aLayout);\r
-\r
- QString aLabelText = QString::fromStdString(theData->widgetLabel());\r
- QString aLabelIcon = QString::fromStdString(theData->widgetIcon());\r
- myLabel = new QLabel(aLabelText, this);\r
- if (!aLabelIcon.isEmpty())\r
- myLabel->setPixmap(ModuleBase_IconFactory::loadPixmap(aLabelIcon));\r
-\r
-\r
- QString aToolTip = QString::fromStdString(theData->widgetTooltip());\r
- myTextLine = new QLineEdit(this);\r
- QString anObjName = QString::fromStdString(attributeID());\r
- myTextLine->setObjectName(anObjName);\r
- myTextLine->setReadOnly(true);\r
- myTextLine->setToolTip(aToolTip);\r
- myTextLine->installEventFilter(this);\r
-\r
- aLayout->addRow(myLabel, myTextLine);\r
- myLabel->setToolTip(aToolTip);\r
-}\r
-\r
-//********************************************************************\r
-ModuleBase_WidgetFeatureSelector::~ModuleBase_WidgetFeatureSelector()\r
-{\r
-}\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_WidgetFeatureSelector.cpp
+// Created: 5 Sep 2016
+// Author: Natalia Ermolaeva
+
+#include <ModuleBase_WidgetFeatureSelector.h>
+
+#include <ModuleBase_Definitions.h>
+#include <ModuleBase_ISelection.h>
+#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_IViewer.h>
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_FilterFactory.h>
+#include <ModuleBase_Filter.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_IconFactory.h>
+#include <ModuleBase_ResultPrs.h>
+
+#include <Config_WidgetAPI.h>
+#include <Events_Loop.h>
+#include <Events_Message.h>
+#include <GeomAPI_Interface.h>
+#include <GeomAPI_Shape.h>
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Result.h>
+#include <ModelAPI_Session.h>
+
+#include <Config_WidgetAPI.h>
+
+#include <GeomAPI_Shape.h>
+
+#include <QWidget>
+#include <QLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QToolButton>
+#include <QString>
+#include <QEvent>
+#include <QApplication>
+#include <QFormLayout>
+
+#include <memory>
+
+#include <list>
+#include <string>
+
+
+ModuleBase_WidgetFeatureSelector::ModuleBase_WidgetFeatureSelector(QWidget* theParent,
+ ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData)
+: ModuleBase_WidgetValidated(theParent, theWorkshop, theData)
+{
+ QFormLayout* aLayout = new QFormLayout(this);
+ ModuleBase_Tools::adjustMargins(aLayout);
+
+ QString aLabelText = QString::fromStdString(theData->widgetLabel());
+ QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
+ myLabel = new QLabel(aLabelText, this);
+ if (!aLabelIcon.isEmpty())
+ myLabel->setPixmap(ModuleBase_IconFactory::loadPixmap(aLabelIcon));
+
+
+ QString aToolTip = QString::fromStdString(theData->widgetTooltip());
+ myTextLine = new QLineEdit(this);
+ QString anObjName = QString::fromStdString(attributeID());
+ myTextLine->setObjectName(anObjName);
+ myTextLine->setReadOnly(true);
+ myTextLine->setToolTip(aToolTip);
+ myTextLine->installEventFilter(this);
+
+ aLayout->addRow(myLabel, myTextLine);
+ myLabel->setToolTip(aToolTip);
+}
+
+//********************************************************************
+ModuleBase_WidgetFeatureSelector::~ModuleBase_WidgetFeatureSelector()
+{
+}
+
//********************************************************************
bool ModuleBase_WidgetFeatureSelector::setSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
{
{
ModuleBase_ModelWidget::deactivate();
disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- activateFilters(false);\r
+ activateFilters(false);
myWorkshop->deactivateSubShapesSelection();
-}\r
-\r
+}
+
//********************************************************************
void ModuleBase_WidgetFeatureSelector::activateCustom()
{
connect(myWorkshop, SIGNAL(selectionChanged()), this,
SLOT(onSelectionChanged()), Qt::UniqueConnection);
- activateFilters(true);\r
+ activateFilters(true);
QIntList aShapeTypes;
aShapeTypes.push_back(ModuleBase_ResultPrs::Sel_Result);
//static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
//ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent);
}
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetFeatureSelector::storeValueCustom()\r
-{\r
- // the value is stored on the selection changed signal processing \r
- return true;\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetFeatureSelector::setSelection(QList<ModuleBase_ViewerPrsPtr>& theValues,\r
- const bool theToValidate)\r
-{\r
- if (theValues.empty()) {\r
- // In order to make reselection possible, set empty object and shape should be done\r
- setSelectionCustom(std::shared_ptr<ModuleBase_ViewerPrs>(new ModuleBase_ViewerPrs(\r
- ObjectPtr(), GeomShapePtr(), NULL)));\r
- return false;\r
- }\r
- // it removes the processed value from the parameters list\r
- ModuleBase_ViewerPrsPtr aValue = theValues.takeFirst();\r
- bool isDone = false;\r
-\r
- if (!theToValidate || isValidSelection(aValue))\r
- isDone = setSelectionCustom(aValue);\r
-\r
- return isDone;\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetFeatureSelector::restoreValueCustom()\r
-{\r
- bool isBlocked = this->blockSignals(true);\r
- updateSelectionName();\r
- this->blockSignals(isBlocked);\r
-\r
- return true;\r
-}\r
-\r
-//********************************************************************\r
-QList<QWidget*> ModuleBase_WidgetFeatureSelector::getControls() const\r
-{\r
- QList<QWidget*> aControls;\r
- aControls.append(myTextLine);\r
- return aControls;\r
-}\r
-\r
-void ModuleBase_WidgetFeatureSelector::updateFocus()\r
-{\r
- emit focusOutWidget(this);\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetFeatureSelector::updateSelectionName()\r
-{\r
- DataPtr aData = myFeature->data();\r
- if (!aData->isValid())\r
- return;\r
-\r
- ObjectPtr anObject = ModuleBase_Tools::getObject(myFeature->attribute(attributeID()));\r
- if (anObject.get() != NULL) {\r
- std::string aName = anObject->data()->name();\r
- myTextLine->setText(QString::fromStdString(aName));\r
- } else {\r
- myTextLine->clear();\r
- }\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetFeatureSelector::isValidInFilters(const ModuleBase_ViewerPrsPtr& thePrs)\r
-{\r
- bool aValid = false;\r
-\r
- ObjectPtr anObject = thePrs->object();\r
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);\r
- aValid = aFeature.get();\r
- if (!aValid) {\r
- ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);\r
- aValid = aResult.get() && aResult->shape() == thePrs->shape();\r
- }\r
-\r
- return aValid;\r
-}\r
-\r
-//********************************************************************\r
+
+//********************************************************************
+bool ModuleBase_WidgetFeatureSelector::storeValueCustom()
+{
+ // the value is stored on the selection changed signal processing
+ return true;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetFeatureSelector::setSelection(QList<ModuleBase_ViewerPrsPtr>& theValues,
+ const bool theToValidate)
+{
+ if (theValues.empty()) {
+ // In order to make reselection possible, set empty object and shape should be done
+ setSelectionCustom(std::shared_ptr<ModuleBase_ViewerPrs>(new ModuleBase_ViewerPrs(
+ ObjectPtr(), GeomShapePtr(), NULL)));
+ return false;
+ }
+ // it removes the processed value from the parameters list
+ ModuleBase_ViewerPrsPtr aValue = theValues.takeFirst();
+ bool isDone = false;
+
+ if (!theToValidate || isValidSelection(aValue))
+ isDone = setSelectionCustom(aValue);
+
+ return isDone;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetFeatureSelector::restoreValueCustom()
+{
+ bool isBlocked = this->blockSignals(true);
+ updateSelectionName();
+ this->blockSignals(isBlocked);
+
+ return true;
+}
+
+//********************************************************************
+QList<QWidget*> ModuleBase_WidgetFeatureSelector::getControls() const
+{
+ QList<QWidget*> aControls;
+ aControls.append(myTextLine);
+ return aControls;
+}
+
+void ModuleBase_WidgetFeatureSelector::updateFocus()
+{
+ emit focusOutWidget(this);
+}
+
+//********************************************************************
+void ModuleBase_WidgetFeatureSelector::updateSelectionName()
+{
+ DataPtr aData = myFeature->data();
+ if (!aData->isValid())
+ return;
+
+ ObjectPtr anObject = ModuleBase_Tools::getObject(myFeature->attribute(attributeID()));
+ if (anObject.get() != NULL) {
+ std::string aName = anObject->data()->name();
+ myTextLine->setText(QString::fromStdString(aName));
+ } else {
+ myTextLine->clear();
+ }
+}
+
+//********************************************************************
+bool ModuleBase_WidgetFeatureSelector::isValidInFilters(const ModuleBase_ViewerPrsPtr& thePrs)
+{
+ bool aValid = false;
+
+ ObjectPtr anObject = thePrs->object();
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+ aValid = aFeature.get();
+ if (!aValid) {
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ aValid = aResult.get() && aResult->shape() == thePrs->shape();
+ }
+
+ return aValid;
+}
+
+//********************************************************************
void ModuleBase_WidgetFeatureSelector::onSelectionChanged()
{
- QList<ModuleBase_ViewerPrsPtr> aSelected = myWorkshop->selection()->getSelected(\r
- ModuleBase_ISelection::AllControls);\r
+ QList<ModuleBase_ViewerPrsPtr> aSelected = myWorkshop->selection()->getSelected(
+ ModuleBase_ISelection::AllControls);
bool isDone = setSelection(aSelected, true/*false*/);
updateOnSelectionChanged(isDone);
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_WidgetFeatureSelector.h\r
-// Created: 5 Sep 2016\r
-// Author: Natalia Ermolaeva\r
-\r
-#ifndef ModuleBase_WidgetFeatureSelector_H\r
-#define ModuleBase_WidgetFeatureSelector_H\r
-\r
-#include "ModuleBase.h"\r
-#include "ModuleBase_WidgetSelector.h"\r
-\r
-class Config_WidgetAPI;\r
-class QWidget;\r
-class QLabel;\r
-class QLineEdit;\r
-\r
-/**\r
-* \ingroup GUI\r
-* Implementation of widget for feature selection.\r
-* This type of widget can be defined in XML file with 'feature_selector' keyword.\r
-* For example:\r
-* \code\r
-* <feature_selector id="main_object" \r
-* label="Main object" \r
-* tooltip="Select an object solid"\r
-* />\r
-* \endcode\r
-* It can use following parameters:\r
-* - id - name of object attribute\r
-* - label - content of widget's label\r
-* - tooltip - the witget's tooltip text\r
-*/\r
-class MODULEBASE_EXPORT ModuleBase_WidgetFeatureSelector : public ModuleBase_WidgetValidated\r
-{\r
-Q_OBJECT\r
- public:\r
-\r
- /// Constructor\r
- /// \param theParent the parent object\r
- /// \param theWorkshop instance of workshop interface\r
- /// \param theData the widget configuation. The attribute of the model widget is obtained from\r
- ModuleBase_WidgetFeatureSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,\r
- const Config_WidgetAPI* theData);\r
-\r
- virtual ~ModuleBase_WidgetFeatureSelector();\r
-\r
- /// Set the given wrapped value to the current widget\r
- /// This value should be processed in the widget according to the needs\r
- /// The method is called by the current operation to process the operation preselection.\r
- /// It is redefined to check the value validity and if it is, fill the attribute with by value\r
- /// \param theValues the wrapped selection values\r
- /// \param theToValidate a flag on validation of the values\r
- virtual bool setSelection(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues,\r
- const bool theToValidate);\r
-\r
- /// Returns list of widget controls\r
- /// \return a control list\r
- virtual QList<QWidget*> getControls() const;\r
-\r
- /// Fills the attribute with the value of the selected owner\r
- /// \param thePrs a selected owner\r
- virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);\r
-\r
- /// The method called when widget is deactivated\r
- virtual void deactivate();\r
-\r
-protected:\r
- /// The method called when widget is activated\r
- virtual void activateCustom();\r
-\r
- /// Saves the internal parameters to the given feature\r
- /// \return True in success\r
- virtual bool storeValueCustom();\r
-\r
- virtual bool restoreValueCustom();\r
-\r
- /// Computes and updates name of selected object in the widget\r
- virtual void updateSelectionName();\r
-\r
- // Update focus after the attribute value change\r
- virtual void updateFocus();\r
-\r
- /// Checks whether all active viewer filters validate the presentation\r
- /// \param thePrs a selected presentation in the view\r
- /// \return a boolean value\r
- virtual bool isValidInFilters(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);\r
-\r
- /// Emits model changed info, updates the current control by selection change\r
- /// \param theDone a state whether the selection is set\r
- virtual void updateOnSelectionChanged(const bool theDone);\r
-\r
-protected slots:\r
- /// Called on selection changed event\r
- virtual void onSelectionChanged();\r
-\r
- //----------- Class members -------------\r
-protected:\r
- /// Label of the widget\r
- QLabel* myLabel;\r
-\r
- /// Input control of the widget\r
- QLineEdit* myTextLine;\r
-};\r
-\r
-#endif\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_WidgetFeatureSelector.h
+// Created: 5 Sep 2016
+// Author: Natalia Ermolaeva
+
+#ifndef ModuleBase_WidgetFeatureSelector_H
+#define ModuleBase_WidgetFeatureSelector_H
+
+#include "ModuleBase.h"
+#include "ModuleBase_WidgetSelector.h"
+
+class Config_WidgetAPI;
+class QWidget;
+class QLabel;
+class QLineEdit;
+
+/**
+* \ingroup GUI
+* Implementation of widget for feature selection.
+* This type of widget can be defined in XML file with 'feature_selector' keyword.
+* For example:
+* \code
+* <feature_selector id="main_object"
+* label="Main object"
+* tooltip="Select an object solid"
+* />
+* \endcode
+* It can use following parameters:
+* - id - name of object attribute
+* - label - content of widget's label
+* - tooltip - the witget's tooltip text
+*/
+class MODULEBASE_EXPORT ModuleBase_WidgetFeatureSelector : public ModuleBase_WidgetValidated
+{
+Q_OBJECT
+ public:
+
+ /// Constructor
+ /// \param theParent the parent object
+ /// \param theWorkshop instance of workshop interface
+ /// \param theData the widget configuation. The attribute of the model widget is obtained from
+ ModuleBase_WidgetFeatureSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData);
+
+ virtual ~ModuleBase_WidgetFeatureSelector();
+
+ /// Set the given wrapped value to the current widget
+ /// This value should be processed in the widget according to the needs
+ /// The method is called by the current operation to process the operation preselection.
+ /// It is redefined to check the value validity and if it is, fill the attribute with by value
+ /// \param theValues the wrapped selection values
+ /// \param theToValidate a flag on validation of the values
+ virtual bool setSelection(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues,
+ const bool theToValidate);
+
+ /// Returns list of widget controls
+ /// \return a control list
+ virtual QList<QWidget*> getControls() const;
+
+ /// Fills the attribute with the value of the selected owner
+ /// \param thePrs a selected owner
+ virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+ /// The method called when widget is deactivated
+ virtual void deactivate();
+
+protected:
+ /// The method called when widget is activated
+ virtual void activateCustom();
+
+ /// Saves the internal parameters to the given feature
+ /// \return True in success
+ virtual bool storeValueCustom();
+
+ virtual bool restoreValueCustom();
+
+ /// Computes and updates name of selected object in the widget
+ virtual void updateSelectionName();
+
+ // Update focus after the attribute value change
+ virtual void updateFocus();
+
+ /// Checks whether all active viewer filters validate the presentation
+ /// \param thePrs a selected presentation in the view
+ /// \return a boolean value
+ virtual bool isValidInFilters(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+ /// Emits model changed info, updates the current control by selection change
+ /// \param theDone a state whether the selection is set
+ virtual void updateOnSelectionChanged(const bool theDone);
+
+protected slots:
+ /// Called on selection changed event
+ virtual void onSelectionChanged();
+
+ //----------- Class members -------------
+protected:
+ /// Label of the widget
+ QLabel* myLabel;
+
+ /// Input control of the widget
+ QLineEdit* myTextLine;
+};
+
+#endif
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_WidgetSelector.h\r
-// Created: 19 June 2015\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#ifndef ModuleBase_WidgetSelector_H\r
-#define ModuleBase_WidgetSelector_H\r
-\r
-#include "ModuleBase.h"\r
-#include "ModuleBase_WidgetValidated.h"\r
-#include "ModuleBase_Definitions.h"\r
-\r
-#include <ModelAPI_Object.h>\r
-#include <ModelAPI_Attribute.h>\r
-#include <GeomAPI_Shape.h>\r
-\r
-class Config_WidgetAPI;\r
-class QWidget;\r
-class ModuleBase_IWorkshop;\r
-class ModuleBase_ViewerPrs;\r
-class ModelAPI_Result;\r
-\r
-/**\r
-* \ingroup GUI\r
-* Implementation of widget for selection.\r
-* This abstract interface is designed to be used for shape/multi shape selector widgets.\r
-*/\r
-class MODULEBASE_EXPORT ModuleBase_WidgetSelector : public ModuleBase_WidgetValidated\r
-{\r
-Q_OBJECT\r
- public:\r
-\r
- /// Constructor\r
- /// \param theParent the parent object\r
- /// \param theWorkshop instance of workshop interface\r
- /// \param theData the widget configuation. The attribute of the model widget is obtained from\r
- ModuleBase_WidgetSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,\r
- const Config_WidgetAPI* theData);\r
-\r
- virtual ~ModuleBase_WidgetSelector();\r
-\r
- /// Defines if it is supposed that the widget should interact with the viewer.\r
- virtual bool isViewerSelector() { return true; }\r
-\r
- /// Activate or deactivate selection and selection filters\r
- /// \return true if the selection filter of the widget is activated in viewer context\r
- virtual bool activateSelectionAndFilters(bool toActivate);\r
-\r
- /// Checks the widget validity. By default, it returns true.\r
- /// \param thePrs a selected presentation in the view\r
- /// \return a boolean value\r
- virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);\r
-\r
- /// Fills the attribute with the value of the selected owner\r
- /// \param thePrs a selected owner\r
- virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);\r
-\r
- /// The methiod called when widget is deactivated\r
- virtual void deactivate();\r
-\r
- /// Return the attribute values wrapped in a list of viewer presentations\r
- /// \return a list of viewer presentations, which contains an attribute result and\r
- /// a shape. If the attribute do not uses the shape, it is empty\r
- virtual QList<std::shared_ptr<ModuleBase_ViewerPrs>> getAttributeSelection() const;\r
-\r
-protected slots:\r
- /// Slot which is called on selection event\r
- virtual void onSelectionChanged();\r
-\r
-protected:\r
- /// Emits model changed info, updates the current control by selection change\r
- /// \param theDone a state whether the selection is set\r
- virtual void updateOnSelectionChanged(const bool theDone);\r
-\r
- /// Update focus after the attribute value change\r
- // NDS: has body is temporary\r
- virtual void updateFocus() {};\r
-\r
- /// Retunrs a list of possible shape types\r
- /// \return a list of shapes\r
- QIntList getShapeTypes() const;\r
-\r
- /// Retunrs a list of possible shape types\r
- /// \return a list of shapes\r
- virtual QIntList shapeTypes() const = 0;\r
-\r
- /// Computes and updates name of selected object in the widget\r
- // NDS: has body is temporary\r
- virtual void updateSelectionName() {};\r
-\r
- /// The methiod called when widget is activated\r
- virtual void activateCustom();\r
-\r
- /// Returns true if selected shape corresponds to requested shape types.\r
- /// If the widget type of shapes contains the faces item, the result is converted\r
- /// to construction result and the method returns true if there is at least one face\r
- /// in the construction.\r
- /// \param theShape a shape\r
- /// \param theResult a selected result\r
- bool acceptSubShape(const GeomShapePtr& theShape,\r
- const std::shared_ptr<ModelAPI_Result>& theResult) const;\r
-\r
- /// Return an object and geom shape by the viewer presentation\r
- /// \param thePrs a selection\r
- /// \param theObject an output object\r
- /// \param theShape a shape of the selection\r
- virtual void getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs,\r
- ObjectPtr& theObject,\r
- GeomShapePtr& theShape);\r
-\r
- //----------- Class members -------------\r
- /// Returns a name in the next form: attribute_feature_name/attribute_id\r
- /// \param theAttribute a model attribute\r
- /// \param theWorkshop a workshop class instance\r
- /// \return string value\r
- static std::string generateName(const AttributePtr& theAttribute,\r
- ModuleBase_IWorkshop* theWorkshop);\r
-};\r
-\r
-#endif\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_WidgetSelector.h
+// Created: 19 June 2015
+// Author: Natalia ERMOLAEVA
+
+#ifndef ModuleBase_WidgetSelector_H
+#define ModuleBase_WidgetSelector_H
+
+#include "ModuleBase.h"
+#include "ModuleBase_WidgetValidated.h"
+#include "ModuleBase_Definitions.h"
+
+#include <ModelAPI_Object.h>
+#include <ModelAPI_Attribute.h>
+#include <GeomAPI_Shape.h>
+
+class Config_WidgetAPI;
+class QWidget;
+class ModuleBase_IWorkshop;
+class ModuleBase_ViewerPrs;
+class ModelAPI_Result;
+
+/**
+* \ingroup GUI
+* Implementation of widget for selection.
+* This abstract interface is designed to be used for shape/multi shape selector widgets.
+*/
+class MODULEBASE_EXPORT ModuleBase_WidgetSelector : public ModuleBase_WidgetValidated
+{
+Q_OBJECT
+ public:
+
+ /// Constructor
+ /// \param theParent the parent object
+ /// \param theWorkshop instance of workshop interface
+ /// \param theData the widget configuation. The attribute of the model widget is obtained from
+ ModuleBase_WidgetSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData);
+
+ virtual ~ModuleBase_WidgetSelector();
+
+ /// Defines if it is supposed that the widget should interact with the viewer.
+ virtual bool isViewerSelector() { return true; }
+
+ /// Activate or deactivate selection and selection filters
+ /// \return true if the selection filter of the widget is activated in viewer context
+ virtual bool activateSelectionAndFilters(bool toActivate);
+
+ /// Checks the widget validity. By default, it returns true.
+ /// \param thePrs a selected presentation in the view
+ /// \return a boolean value
+ virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+ /// Fills the attribute with the value of the selected owner
+ /// \param thePrs a selected owner
+ virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+ /// The methiod called when widget is deactivated
+ virtual void deactivate();
+
+ /// Return the attribute values wrapped in a list of viewer presentations
+ /// \return a list of viewer presentations, which contains an attribute result and
+ /// a shape. If the attribute do not uses the shape, it is empty
+ virtual QList<std::shared_ptr<ModuleBase_ViewerPrs>> getAttributeSelection() const;
+
+protected slots:
+ /// Slot which is called on selection event
+ virtual void onSelectionChanged();
+
+protected:
+ /// Emits model changed info, updates the current control by selection change
+ /// \param theDone a state whether the selection is set
+ virtual void updateOnSelectionChanged(const bool theDone);
+
+ /// Update focus after the attribute value change
+ // NDS: has body is temporary
+ virtual void updateFocus() {};
+
+ /// Retunrs a list of possible shape types
+ /// \return a list of shapes
+ QIntList getShapeTypes() const;
+
+ /// Retunrs a list of possible shape types
+ /// \return a list of shapes
+ virtual QIntList shapeTypes() const = 0;
+
+ /// Computes and updates name of selected object in the widget
+ // NDS: has body is temporary
+ virtual void updateSelectionName() {};
+
+ /// The methiod called when widget is activated
+ virtual void activateCustom();
+
+ /// Returns true if selected shape corresponds to requested shape types.
+ /// If the widget type of shapes contains the faces item, the result is converted
+ /// to construction result and the method returns true if there is at least one face
+ /// in the construction.
+ /// \param theShape a shape
+ /// \param theResult a selected result
+ bool acceptSubShape(const GeomShapePtr& theShape,
+ const std::shared_ptr<ModelAPI_Result>& theResult) const;
+
+ /// Return an object and geom shape by the viewer presentation
+ /// \param thePrs a selection
+ /// \param theObject an output object
+ /// \param theShape a shape of the selection
+ virtual void getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs,
+ ObjectPtr& theObject,
+ GeomShapePtr& theShape);
+
+ //----------- Class members -------------
+ /// Returns a name in the next form: attribute_feature_name/attribute_id
+ /// \param theAttribute a model attribute
+ /// \param theWorkshop a workshop class instance
+ /// \return string value
+ static std::string generateName(const AttributePtr& theAttribute,
+ ModuleBase_IWorkshop* theWorkshop);
+};
+
+#endif
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-#include <ModuleBase_WidgetValidated.h>\r
-#include <ModuleBase_FilterFactory.h>\r
-#include <ModuleBase_IViewer.h>\r
-#include <ModuleBase_ISelection.h>\r
-#include <ModuleBase_WidgetSelectorStore.h>\r
-#include <ModuleBase_ViewerPrs.h>\r
-\r
-#include <Events_InfoMessage.h>\r
-\r
-#include <ModelAPI_Session.h>\r
-#include <ModelAPI_Validator.h>\r
-#include <ModelAPI_AttributeValidator.h>\r
-#include <ModelAPI_Events.h>\r
-#include <ModelAPI_ResultCompSolid.h>\r
-#include <ModelAPI_Tools.h>\r
-\r
-#include <SelectMgr_ListIteratorOfListOfFilter.hxx>\r
-#include <SelectMgr_EntityOwner.hxx>\r
-#include <StdSelect_BRepOwner.hxx>\r
-\r
-#include <Events_Loop.h>\r
-\r
-#include <QWidget>\r
-\r
-//#define DEBUG_VALID_STATE\r
-\r
-ModuleBase_WidgetValidated::ModuleBase_WidgetValidated(QWidget* theParent,\r
- ModuleBase_IWorkshop* theWorkshop,\r
- const Config_WidgetAPI* theData)\r
-: ModuleBase_ModelWidget(theParent, theData),\r
- myWorkshop(theWorkshop), myIsInValidate(false)\r
-{\r
- myAttributeStore = new ModuleBase_WidgetSelectorStore();\r
-}\r
-\r
-ModuleBase_WidgetValidated::~ModuleBase_WidgetValidated()\r
-{\r
- delete myAttributeStore;\r
-}\r
-\r
-//********************************************************************\r
-ObjectPtr ModuleBase_WidgetValidated::findPresentedObject(const AISObjectPtr& theAIS) const\r
-{\r
- return myPresentedObject;\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::clearValidatedCash()\r
-{\r
-#ifdef DEBUG_VALID_STATE\r
- qDebug("clearValidatedCash");\r
-#endif\r
- myValidPrs.Clear();\r
- myInvalidPrs.Clear();\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::storeAttributeValue(const AttributePtr& theAttribute)\r
-{\r
- myIsInValidate = true;\r
- myAttributeStore->storeAttributeValue(theAttribute, myWorkshop);\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::restoreAttributeValue(const AttributePtr& theAttribute,\r
- const bool theValid)\r
-{\r
- myIsInValidate = false;\r
- myAttributeStore->restoreAttributeValue(theAttribute, myWorkshop);\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetValidated::isValidInFilters(const ModuleBase_ViewerPrsPtr& thePrs)\r
-{\r
- bool aValid = true;\r
- Handle(SelectMgr_EntityOwner) anOwner = thePrs->owner();\r
-\r
- // if an owner is null, the selection happens in the Object browser.\r
- // creates a selection owner on the base of object shape and the object AIS object\r
- if (anOwner.IsNull() && thePrs->owner().IsNull() && thePrs->object().get()) {\r
- ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);\r
- GeomShapePtr aShape = aResult.get() ? aResult->shape() : GeomShapePtr();\r
- // some results have no shape, e.g. the parameter one. So, they should not be validated\r
- if (aShape.get()) {\r
- const TopoDS_Shape aTDShape = aShape->impl<TopoDS_Shape>();\r
- Handle(AIS_InteractiveObject) anIO = myWorkshop->selection()->getIO(thePrs);\r
- anOwner = new StdSelect_BRepOwner(aTDShape, anIO);\r
- myPresentedObject = aResult;\r
- }\r
- else\r
- aValid = false; // only results with a shape can be filtered\r
- }\r
- // checks the owner by the AIS context activated filters\r
- if (!anOwner.IsNull()) {\r
- // the widget validator filter should be active, but during check by preselection\r
- // it is not yet activated, so we need to activate/deactivate it manually\r
- bool isActivated = isFilterActivated();\r
- if (!isActivated)\r
- activateFilters(true);\r
-\r
- Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();\r
- if (!aContext.IsNull()) {\r
- const SelectMgr_ListOfFilter& aFilters = aContext->Filters();\r
- SelectMgr_ListIteratorOfListOfFilter anIt(aFilters);\r
- for (; anIt.More() && aValid; anIt.Next()) {\r
- Handle(SelectMgr_Filter) aFilter = anIt.Value();\r
- aValid = aFilter->IsOk(anOwner);\r
- }\r
- }\r
- if (!isActivated)\r
- activateFilters(false);\r
- }\r
-\r
- // removes created owner\r
- if (!anOwner.IsNull() && anOwner != thePrs->owner()) {\r
- anOwner.Nullify();\r
- myPresentedObject = ObjectPtr();\r
- }\r
- return aValid;\r
-}\r
-\r
-//********************************************************************\r
-AttributePtr ModuleBase_WidgetValidated::attribute() const\r
-{\r
- return myFeature->attribute(attributeID());\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetValidated::isValidSelection(const ModuleBase_ViewerPrsPtr& theValue)\r
-{\r
- bool aValid = false;\r
- if (getValidState(theValue, aValid)) {\r
- return aValid;\r
- }\r
- aValid = isValidSelectionCustom(theValue);\r
- if (aValid)\r
- aValid = isValidSelectionForAttribute(theValue, attribute());\r
-\r
- storeValidState(theValue, aValid);\r
- return aValid;\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetValidated::isValidSelectionForAttribute(const ModuleBase_ViewerPrsPtr& theValue,\r
- const AttributePtr& theAttribute)\r
-{\r
- bool aValid = false;\r
-\r
- // stores the current values of the widget attribute\r
- bool isFlushesActived, isAttributeSetInitializedBlocked;\r
-\r
- blockAttribute(theAttribute, true, isFlushesActived, isAttributeSetInitializedBlocked);\r
-\r
- storeAttributeValue(theAttribute);\r
-\r
- // saves the owner value to the widget attribute\r
- aValid = setSelectionCustom(theValue);\r
- if (aValid)\r
- // checks the attribute validity\r
- aValid = isValidAttribute(theAttribute);\r
-\r
- // restores the current values of the widget attribute\r
- restoreAttributeValue(theAttribute, aValid);\r
-\r
- blockAttribute(theAttribute, false, isFlushesActived, isAttributeSetInitializedBlocked);\r
- /// NDS: The following rows are commented for issue #1452 (to be removed after debug)\r
- /// This is not correct to perform it here because it might cause update selection and\r
- /// the selection mechanizm will be circled: use the scenario of the bug with preselected point.\r
- // In particular case the results are deleted and called as redisplayed inside of this\r
- // highlight-selection, to they must be flushed as soon as possible.\r
- // Example: selection of group-vertices subshapes with shift pressend on body. Without\r
- // these 4 lines below the application crashes because of left presentations on\r
- // removed results still in the viewer.\r
- /*static Events_ID aDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);\r
- static Events_ID aRedispEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);\r
- Events_Loop::loop()->flush(aDeletedEvent);\r
- Events_Loop::loop()->flush(aRedispEvent);\r
- */\r
- return aValid;\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetValidated::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)\r
-{\r
- return true;\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetValidated::isValidAttribute(const AttributePtr& theAttribute) const\r
-{\r
- SessionPtr aMgr = ModelAPI_Session::get();\r
- ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();\r
- std::string aValidatorID;\r
- Events_InfoMessage anError;\r
- return aFactory->validate(theAttribute, aValidatorID, anError);\r
-}\r
-\r
-bool ModuleBase_WidgetValidated::isFilterActivated() const\r
-{\r
- bool isActivated = false;\r
-\r
- Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();\r
- ModuleBase_IViewer* aViewer = myWorkshop->viewer();\r
-\r
- return aViewer->hasSelectionFilter(aSelFilter);\r
-}\r
-\r
-bool ModuleBase_WidgetValidated::activateFilters(const bool toActivate)\r
-{\r
- ModuleBase_IViewer* aViewer = myWorkshop->viewer();\r
-\r
- Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();\r
- bool aHasSelectionFilter = aViewer->hasSelectionFilter(aSelFilter);\r
-\r
- if (toActivate)\r
- aViewer->addSelectionFilter(aSelFilter);\r
- else {\r
- aViewer->removeSelectionFilter(aSelFilter);\r
- clearValidatedCash();\r
- }\r
-\r
- return aHasSelectionFilter;\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::blockAttribute(const AttributePtr& theAttribute,\r
- const bool& theToBlock,\r
- bool& isFlushesActived,\r
- bool& isAttributeSetInitializedBlocked)\r
-{\r
- Events_Loop* aLoop = Events_Loop::loop();\r
- DataPtr aData = myFeature->data();\r
- if (theToBlock) {\r
- // blocks the flush signals to avoid the temporary objects visualization in the viewer\r
- // they should not be shown in order to do not lose highlight by erasing them\r
- isFlushesActived = aLoop->activateFlushes(false);\r
-\r
- aData->blockSendAttributeUpdated(true);\r
- isAttributeSetInitializedBlocked = theAttribute->blockSetInitialized(true);\r
- }\r
- else {\r
- aData->blockSendAttributeUpdated(false, false);\r
- theAttribute->blockSetInitialized(isAttributeSetInitializedBlocked);\r
- aLoop->activateFlushes(isFlushesActived);\r
- }\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::storeValidState(const ModuleBase_ViewerPrsPtr& theValue, const bool theValid)\r
-{\r
- GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr();\r
- if (aShape.get()) {\r
- if (theValid) {\r
- const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();\r
- bool aValidPrsContains = myValidPrs.IsBound(aTDShape) &&\r
- theValue.get()->isEqual(myValidPrs.Find(aTDShape).get());\r
- if (!aValidPrsContains) {\r
- #ifdef LIST_OF_VALID_PRS\r
- myValidPrs.append(theValue);\r
- #else\r
- myValidPrs.Bind(aTDShape, theValue);\r
- #endif\r
- // the commented code will be useful when the valid state of the presentation\r
- // will be changable between activate/deactivate. Currently it does not happen.\r
- //if (anInvalidPrs)\r
- // myInvalidPrs.removeOne(theValue);\r
- }\r
- }\r
- else { // !theValid\r
- if (aShape.get()) {\r
- const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();\r
- bool anIValidPrsContains = myInvalidPrs.IsBound(aTDShape) &&\r
- theValue.get()->isEqual(myInvalidPrs.Find(aTDShape).get());\r
- if (!anIValidPrsContains) {\r
- #ifdef LIST_OF_VALID_PRS\r
- myInvalidPrs.append(theValue);\r
- #else\r
- myInvalidPrs.Bind(aTDShape, theValue);\r
- #endif\r
- //if (!aValidPrs)\r
- // myValidPrs.removeOne(theValue);\r
- }\r
- }\r
- }\r
- }\r
- #ifdef DEBUG_VALID_STATE\r
- qDebug(QString("storeValidState: myValidPrs.size() = %1, myInvalidPrs.size() = %2").arg(myValidPrs.count())\r
- .arg(myInvalidPrs.count()).toStdString().c_str());\r
- #endif\r
-}\r
-\r
-//********************************************************************\r
-bool ModuleBase_WidgetValidated::getValidState(const ModuleBase_ViewerPrsPtr& theValue, bool& theValid)\r
-{\r
- if (!theValue.get())\r
- return false;\r
-\r
-#ifdef LIST_OF_VALID_PRS\r
- bool aValidPrsContains = myValidPrs.contains(theValue);\r
- bool anInvalidPrsContains = myInvalidPrs.contains(theValue);\r
-#else\r
- GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr();\r
- if (!aShape.get())\r
- return false;\r
-\r
- const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();\r
- bool aValidPrsContains = myValidPrs.IsBound(aTDShape) &&\r
- theValue.get()->isEqual(myValidPrs.Find(aTDShape).get());\r
-\r
- bool anInvalidPrsContains = myInvalidPrs.IsBound(aTDShape) &&\r
- theValue.get()->isEqual(myInvalidPrs.Find(aTDShape).get());\r
- /*\r
- bool aValidPrsContains = false, anInvalidPrsContains = false;\r
- GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr();\r
- if (aShape.get()) {\r
- aValidPrsContains = myValidPrs.contains(aShape);\r
- anInvalidPrsContains = myInvalidPrs.contains(aShape);\r
-\r
- if (aValidPrsContains)\r
- aValidPrsContains = theValue == myValidPrs[aShape];\r
- else\r
- anInvalidPrsContains = theValue == myInvalidPrs[aShape];*/\r
-#endif\r
-\r
- if (aValidPrsContains)\r
- theValid = true;\r
- else if (anInvalidPrsContains)\r
- theValid = false;\r
-\r
- return aValidPrsContains || anInvalidPrsContains;\r
-}\r
-\r
-//********************************************************************\r
-QList<ModuleBase_ViewerPrsPtr> ModuleBase_WidgetValidated::getFilteredSelected()\r
-{\r
- QList<ModuleBase_ViewerPrsPtr> aSelected = myWorkshop->selection()->getSelected(\r
- ModuleBase_ISelection::Viewer);\r
-\r
- QList<ModuleBase_ViewerPrsPtr> anOBSelected = myWorkshop->selection()->getSelected(\r
- ModuleBase_ISelection::Browser);\r
- // filter the OB presentations\r
- filterPresentations(anOBSelected);\r
- if (!anOBSelected.isEmpty())\r
- ModuleBase_ISelection::appendSelected(anOBSelected, aSelected);\r
-\r
- filterCompSolids(aSelected);\r
-\r
- return aSelected;\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::filterPresentations(QList<ModuleBase_ViewerPrsPtr>& theValues)\r
-{\r
- QList<ModuleBase_ViewerPrsPtr> aValidatedValues;\r
-\r
- QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theValues.begin(), aLast = theValues.end();\r
- bool isDone = false;\r
- for (; anIt != aLast; anIt++) {\r
- if (isValidInFilters(*anIt))\r
- aValidatedValues.append(*anIt);\r
- }\r
- if (aValidatedValues.size() != theValues.size()) {\r
- theValues.clear();\r
- theValues = aValidatedValues;\r
- }\r
-}\r
-\r
-//********************************************************************\r
-void ModuleBase_WidgetValidated::filterCompSolids(QList<ModuleBase_ViewerPrsPtr>& theValues)\r
-{\r
- std::set<ResultCompSolidPtr> aCompSolids;\r
- QList<ModuleBase_ViewerPrsPtr> aValidatedValues;\r
-\r
- // Collect compsolids.\r
- QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theValues.begin(), aLast = theValues.end();\r
- for (; anIt != aLast; anIt++) {\r
- const ModuleBase_ViewerPrsPtr& aViewerPrs = *anIt;\r
- ObjectPtr anObject = aViewerPrs->object();\r
- ResultCompSolidPtr aResultCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anObject);\r
- if(aResultCompSolid.get()) {\r
- aCompSolids.insert(aResultCompSolid);\r
- }\r
- }\r
-\r
- // Filter sub-solids of compsolids.\r
- anIt = theValues.begin();\r
- for (; anIt != aLast; anIt++) {\r
- const ModuleBase_ViewerPrsPtr& aViewerPrs = *anIt;\r
- ObjectPtr anObject = aViewerPrs->object();\r
- ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);\r
- ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aResult);\r
- if(aResCompSolidPtr.get() && (aCompSolids.find(aResCompSolidPtr) != aCompSolids.end())) {\r
- // Skip sub-solid of compsolid.\r
- continue;\r
- } else {\r
- aValidatedValues.append(*anIt);\r
- }\r
- }\r
-\r
- if (aValidatedValues.size() != theValues.size()) {\r
- theValues.clear();\r
- theValues = aValidatedValues;\r
- }\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#include <ModuleBase_WidgetValidated.h>
+#include <ModuleBase_FilterFactory.h>
+#include <ModuleBase_IViewer.h>
+#include <ModuleBase_ISelection.h>
+#include <ModuleBase_WidgetSelectorStore.h>
+#include <ModuleBase_ViewerPrs.h>
+
+#include <Events_InfoMessage.h>
+
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_AttributeValidator.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_Tools.h>
+
+#include <SelectMgr_ListIteratorOfListOfFilter.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <StdSelect_BRepOwner.hxx>
+
+#include <Events_Loop.h>
+
+#include <QWidget>
+
+//#define DEBUG_VALID_STATE
+
+ModuleBase_WidgetValidated::ModuleBase_WidgetValidated(QWidget* theParent,
+ ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData)
+: ModuleBase_ModelWidget(theParent, theData),
+ myWorkshop(theWorkshop), myIsInValidate(false)
+{
+ myAttributeStore = new ModuleBase_WidgetSelectorStore();
+}
+
+ModuleBase_WidgetValidated::~ModuleBase_WidgetValidated()
+{
+ delete myAttributeStore;
+}
+
+//********************************************************************
+ObjectPtr ModuleBase_WidgetValidated::findPresentedObject(const AISObjectPtr& theAIS) const
+{
+ return myPresentedObject;
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::clearValidatedCash()
+{
+#ifdef DEBUG_VALID_STATE
+ qDebug("clearValidatedCash");
+#endif
+ myValidPrs.Clear();
+ myInvalidPrs.Clear();
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::storeAttributeValue(const AttributePtr& theAttribute)
+{
+ myIsInValidate = true;
+ myAttributeStore->storeAttributeValue(theAttribute, myWorkshop);
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::restoreAttributeValue(const AttributePtr& theAttribute,
+ const bool theValid)
+{
+ myIsInValidate = false;
+ myAttributeStore->restoreAttributeValue(theAttribute, myWorkshop);
+}
+
+//********************************************************************
+bool ModuleBase_WidgetValidated::isValidInFilters(const ModuleBase_ViewerPrsPtr& thePrs)
+{
+ bool aValid = true;
+ Handle(SelectMgr_EntityOwner) anOwner = thePrs->owner();
+
+ // if an owner is null, the selection happens in the Object browser.
+ // creates a selection owner on the base of object shape and the object AIS object
+ if (anOwner.IsNull() && thePrs->owner().IsNull() && thePrs->object().get()) {
+ ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
+ GeomShapePtr aShape = aResult.get() ? aResult->shape() : GeomShapePtr();
+ // some results have no shape, e.g. the parameter one. So, they should not be validated
+ if (aShape.get()) {
+ const TopoDS_Shape aTDShape = aShape->impl<TopoDS_Shape>();
+ Handle(AIS_InteractiveObject) anIO = myWorkshop->selection()->getIO(thePrs);
+ anOwner = new StdSelect_BRepOwner(aTDShape, anIO);
+ myPresentedObject = aResult;
+ }
+ else
+ aValid = false; // only results with a shape can be filtered
+ }
+ // checks the owner by the AIS context activated filters
+ if (!anOwner.IsNull()) {
+ // the widget validator filter should be active, but during check by preselection
+ // it is not yet activated, so we need to activate/deactivate it manually
+ bool isActivated = isFilterActivated();
+ if (!isActivated)
+ activateFilters(true);
+
+ Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
+ if (!aContext.IsNull()) {
+ const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
+ SelectMgr_ListIteratorOfListOfFilter anIt(aFilters);
+ for (; anIt.More() && aValid; anIt.Next()) {
+ Handle(SelectMgr_Filter) aFilter = anIt.Value();
+ aValid = aFilter->IsOk(anOwner);
+ }
+ }
+ if (!isActivated)
+ activateFilters(false);
+ }
+
+ // removes created owner
+ if (!anOwner.IsNull() && anOwner != thePrs->owner()) {
+ anOwner.Nullify();
+ myPresentedObject = ObjectPtr();
+ }
+ return aValid;
+}
+
+//********************************************************************
+AttributePtr ModuleBase_WidgetValidated::attribute() const
+{
+ return myFeature->attribute(attributeID());
+}
+
+//********************************************************************
+bool ModuleBase_WidgetValidated::isValidSelection(const ModuleBase_ViewerPrsPtr& theValue)
+{
+ bool aValid = false;
+ if (getValidState(theValue, aValid)) {
+ return aValid;
+ }
+ aValid = isValidSelectionCustom(theValue);
+ if (aValid)
+ aValid = isValidSelectionForAttribute(theValue, attribute());
+
+ storeValidState(theValue, aValid);
+ return aValid;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetValidated::isValidSelectionForAttribute(const ModuleBase_ViewerPrsPtr& theValue,
+ const AttributePtr& theAttribute)
+{
+ bool aValid = false;
+
+ // stores the current values of the widget attribute
+ bool isFlushesActived, isAttributeSetInitializedBlocked;
+
+ blockAttribute(theAttribute, true, isFlushesActived, isAttributeSetInitializedBlocked);
+
+ storeAttributeValue(theAttribute);
+
+ // saves the owner value to the widget attribute
+ aValid = setSelectionCustom(theValue);
+ if (aValid)
+ // checks the attribute validity
+ aValid = isValidAttribute(theAttribute);
+
+ // restores the current values of the widget attribute
+ restoreAttributeValue(theAttribute, aValid);
+
+ blockAttribute(theAttribute, false, isFlushesActived, isAttributeSetInitializedBlocked);
+ /// NDS: The following rows are commented for issue #1452 (to be removed after debug)
+ /// This is not correct to perform it here because it might cause update selection and
+ /// the selection mechanizm will be circled: use the scenario of the bug with preselected point.
+ // In particular case the results are deleted and called as redisplayed inside of this
+ // highlight-selection, to they must be flushed as soon as possible.
+ // Example: selection of group-vertices subshapes with shift pressend on body. Without
+ // these 4 lines below the application crashes because of left presentations on
+ // removed results still in the viewer.
+ /*static Events_ID aDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+ static Events_ID aRedispEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ Events_Loop::loop()->flush(aDeletedEvent);
+ Events_Loop::loop()->flush(aRedispEvent);
+ */
+ return aValid;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetValidated::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
+{
+ return true;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetValidated::isValidAttribute(const AttributePtr& theAttribute) const
+{
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+ std::string aValidatorID;
+ Events_InfoMessage anError;
+ return aFactory->validate(theAttribute, aValidatorID, anError);
+}
+
+bool ModuleBase_WidgetValidated::isFilterActivated() const
+{
+ bool isActivated = false;
+
+ Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();
+ ModuleBase_IViewer* aViewer = myWorkshop->viewer();
+
+ return aViewer->hasSelectionFilter(aSelFilter);
+}
+
+bool ModuleBase_WidgetValidated::activateFilters(const bool toActivate)
+{
+ ModuleBase_IViewer* aViewer = myWorkshop->viewer();
+
+ Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();
+ bool aHasSelectionFilter = aViewer->hasSelectionFilter(aSelFilter);
+
+ if (toActivate)
+ aViewer->addSelectionFilter(aSelFilter);
+ else {
+ aViewer->removeSelectionFilter(aSelFilter);
+ clearValidatedCash();
+ }
+
+ return aHasSelectionFilter;
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::blockAttribute(const AttributePtr& theAttribute,
+ const bool& theToBlock,
+ bool& isFlushesActived,
+ bool& isAttributeSetInitializedBlocked)
+{
+ Events_Loop* aLoop = Events_Loop::loop();
+ DataPtr aData = myFeature->data();
+ if (theToBlock) {
+ // blocks the flush signals to avoid the temporary objects visualization in the viewer
+ // they should not be shown in order to do not lose highlight by erasing them
+ isFlushesActived = aLoop->activateFlushes(false);
+
+ aData->blockSendAttributeUpdated(true);
+ isAttributeSetInitializedBlocked = theAttribute->blockSetInitialized(true);
+ }
+ else {
+ aData->blockSendAttributeUpdated(false, false);
+ theAttribute->blockSetInitialized(isAttributeSetInitializedBlocked);
+ aLoop->activateFlushes(isFlushesActived);
+ }
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::storeValidState(const ModuleBase_ViewerPrsPtr& theValue, const bool theValid)
+{
+ GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr();
+ if (aShape.get()) {
+ if (theValid) {
+ const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
+ bool aValidPrsContains = myValidPrs.IsBound(aTDShape) &&
+ theValue.get()->isEqual(myValidPrs.Find(aTDShape).get());
+ if (!aValidPrsContains) {
+ #ifdef LIST_OF_VALID_PRS
+ myValidPrs.append(theValue);
+ #else
+ myValidPrs.Bind(aTDShape, theValue);
+ #endif
+ // the commented code will be useful when the valid state of the presentation
+ // will be changable between activate/deactivate. Currently it does not happen.
+ //if (anInvalidPrs)
+ // myInvalidPrs.removeOne(theValue);
+ }
+ }
+ else { // !theValid
+ if (aShape.get()) {
+ const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
+ bool anIValidPrsContains = myInvalidPrs.IsBound(aTDShape) &&
+ theValue.get()->isEqual(myInvalidPrs.Find(aTDShape).get());
+ if (!anIValidPrsContains) {
+ #ifdef LIST_OF_VALID_PRS
+ myInvalidPrs.append(theValue);
+ #else
+ myInvalidPrs.Bind(aTDShape, theValue);
+ #endif
+ //if (!aValidPrs)
+ // myValidPrs.removeOne(theValue);
+ }
+ }
+ }
+ }
+ #ifdef DEBUG_VALID_STATE
+ qDebug(QString("storeValidState: myValidPrs.size() = %1, myInvalidPrs.size() = %2").arg(myValidPrs.count())
+ .arg(myInvalidPrs.count()).toStdString().c_str());
+ #endif
+}
+
+//********************************************************************
+bool ModuleBase_WidgetValidated::getValidState(const ModuleBase_ViewerPrsPtr& theValue, bool& theValid)
+{
+ if (!theValue.get())
+ return false;
+
+#ifdef LIST_OF_VALID_PRS
+ bool aValidPrsContains = myValidPrs.contains(theValue);
+ bool anInvalidPrsContains = myInvalidPrs.contains(theValue);
+#else
+ GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr();
+ if (!aShape.get())
+ return false;
+
+ const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
+ bool aValidPrsContains = myValidPrs.IsBound(aTDShape) &&
+ theValue.get()->isEqual(myValidPrs.Find(aTDShape).get());
+
+ bool anInvalidPrsContains = myInvalidPrs.IsBound(aTDShape) &&
+ theValue.get()->isEqual(myInvalidPrs.Find(aTDShape).get());
+ /*
+ bool aValidPrsContains = false, anInvalidPrsContains = false;
+ GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr();
+ if (aShape.get()) {
+ aValidPrsContains = myValidPrs.contains(aShape);
+ anInvalidPrsContains = myInvalidPrs.contains(aShape);
+
+ if (aValidPrsContains)
+ aValidPrsContains = theValue == myValidPrs[aShape];
+ else
+ anInvalidPrsContains = theValue == myInvalidPrs[aShape];*/
+#endif
+
+ if (aValidPrsContains)
+ theValid = true;
+ else if (anInvalidPrsContains)
+ theValid = false;
+
+ return aValidPrsContains || anInvalidPrsContains;
+}
+
+//********************************************************************
+QList<ModuleBase_ViewerPrsPtr> ModuleBase_WidgetValidated::getFilteredSelected()
+{
+ QList<ModuleBase_ViewerPrsPtr> aSelected = myWorkshop->selection()->getSelected(
+ ModuleBase_ISelection::Viewer);
+
+ QList<ModuleBase_ViewerPrsPtr> anOBSelected = myWorkshop->selection()->getSelected(
+ ModuleBase_ISelection::Browser);
+ // filter the OB presentations
+ filterPresentations(anOBSelected);
+ if (!anOBSelected.isEmpty())
+ ModuleBase_ISelection::appendSelected(anOBSelected, aSelected);
+
+ filterCompSolids(aSelected);
+
+ return aSelected;
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::filterPresentations(QList<ModuleBase_ViewerPrsPtr>& theValues)
+{
+ QList<ModuleBase_ViewerPrsPtr> aValidatedValues;
+
+ QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theValues.begin(), aLast = theValues.end();
+ bool isDone = false;
+ for (; anIt != aLast; anIt++) {
+ if (isValidInFilters(*anIt))
+ aValidatedValues.append(*anIt);
+ }
+ if (aValidatedValues.size() != theValues.size()) {
+ theValues.clear();
+ theValues = aValidatedValues;
+ }
+}
+
+//********************************************************************
+void ModuleBase_WidgetValidated::filterCompSolids(QList<ModuleBase_ViewerPrsPtr>& theValues)
+{
+ std::set<ResultCompSolidPtr> aCompSolids;
+ QList<ModuleBase_ViewerPrsPtr> aValidatedValues;
+
+ // Collect compsolids.
+ QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theValues.begin(), aLast = theValues.end();
+ for (; anIt != aLast; anIt++) {
+ const ModuleBase_ViewerPrsPtr& aViewerPrs = *anIt;
+ ObjectPtr anObject = aViewerPrs->object();
+ ResultCompSolidPtr aResultCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anObject);
+ if(aResultCompSolid.get()) {
+ aCompSolids.insert(aResultCompSolid);
+ }
+ }
+
+ // Filter sub-solids of compsolids.
+ anIt = theValues.begin();
+ for (; anIt != aLast; anIt++) {
+ const ModuleBase_ViewerPrsPtr& aViewerPrs = *anIt;
+ ObjectPtr anObject = aViewerPrs->object();
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aResult);
+ if(aResCompSolidPtr.get() && (aCompSolids.find(aResCompSolidPtr) != aCompSolids.end())) {
+ // Skip sub-solid of compsolid.
+ continue;
+ } else {
+ aValidatedValues.append(*anIt);
+ }
+ }
+
+ if (aValidatedValues.size() != theValues.size()) {
+ theValues.clear();
+ theValues = aValidatedValues;
+ }
+}
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_WidgetValidated.h\r
-// Created: 12 Mar 2015\r
-// Author: Natalia ERMOLAEVA\r
-\r
-\r
-#ifndef MODULEBASE_WIDGETVALIDATED_H_\r
-#define MODULEBASE_WIDGETVALIDATED_H_\r
-\r
-#include <ModuleBase.h>\r
-#include <ModuleBase_ModelWidget.h>\r
-\r
-#include <GeomAPI_Shape.h>\r
-#include <GeomAPI_AISObject.h>\r
-#include <ModelAPI_Object.h>\r
-#include <ModelAPI_Attribute.h>\r
-\r
-#include <SelectMgr_ListOfFilter.hxx>\r
-#include <NCollection_DataMap.hxx>\r
-#include <TopoDS_Shape.hxx>\r
-\r
-#include <QList>\r
-#include <QMap>\r
-\r
-class QWidget;\r
-class ModuleBase_IWorkshop;\r
-class ModuleBase_ISelection;\r
-class ModuleBase_WidgetSelectorStore;\r
-class ModelAPI_Validator;\r
-class Config_WidgetAPI;\r
-class Handle_SelectMgr_EntityOwner;\r
-\r
-//#define LIST_OF_VALID_PRS\r
-\r
-/**\r
-* \ingroup GUI\r
-* Implementation of widget with validators and filters processing.\r
-*/\r
-class MODULEBASE_EXPORT ModuleBase_WidgetValidated : public ModuleBase_ModelWidget\r
-{\r
- Q_OBJECT\r
- public:\r
- /// Constructor\r
- /// \param theParent the parent object\r
- /// \param theWorkshop a reference to workshop\r
- /// \param theData the widget configuation. The attribute of the model widget is obtained from\r
- ModuleBase_WidgetValidated(QWidget* theParent,\r
- ModuleBase_IWorkshop* theWorkshop,\r
- const Config_WidgetAPI* theData);\r
- virtual ~ModuleBase_WidgetValidated();\r
-\r
- /// Checks all widget validator if the owner is valid. Firstly it checks custom widget validating,\r
- /// next, the attribute's validating. It trying on the give selection to current attribute by\r
- /// setting the value inside and calling validators. After this, the previous attribute value is\r
- /// restored.The valid/invalid value is cashed.\r
- /// \param theValue a selected presentation in the view\r
- /// \return a boolean value\r
- virtual bool isValidSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue);\r
-\r
- //! Returns data object by AIS\r
- ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const;\r
-\r
- //! Clear all validated cash in the widget\r
- void clearValidatedCash();\r
-\r
- /// Returns true if the workshop validator filter has been already activated\r
- /// \return boolean value\r
- bool isFilterActivated() const;\r
-\r
-protected:\r
- /// Checks whether all active viewer filters validate the presentation\r
- /// \param thePrs a selected presentation in the view\r
- /// \return a boolean value\r
- virtual bool isValidInFilters(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);\r
-\r
- /// Checks all attribute validators returns valid. It tries on the given selection\r
- /// to current attribute by setting the value inside and calling validators. After this,\r
- /// the previous attribute value is restored.The valid/invalid value is cashed.\r
- /// \param theValue a selected presentation in the view\r
- /// \param theAttribute the attribute\r
- /// \return a boolean value\r
- bool isValidSelectionForAttribute(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue,\r
- const AttributePtr& theAttribute);\r
-\r
- /// Retunrs attribute, which should be validated. In default implementation,\r
- /// this is an attribute of ID\r
- /// \return an attribute\r
- virtual AttributePtr attribute() const;\r
-\r
- /// Creates a backup of the current values of the attribute\r
- /// It should be realized in the specific widget because of different\r
- /// parameters of the current attribute\r
- /// \param theAttribute an attribute to be stored\r
- virtual void storeAttributeValue(const AttributePtr& theAttribute);\r
-\r
- /// Creates a backup of the current values of the attribute\r
- /// It should be realized in the specific widget because of different\r
- /// parameters of the current attribute\r
- /// \param theAttribute an attribute to be restored\r
- /// \param theValid a boolean flag, if restore happens for valid parameters\r
- virtual void restoreAttributeValue(const AttributePtr& theAttribute, const bool theValid);\r
-\r
- /// Checks the widget validity. By default, it returns true.\r
- /// \param thePrs a selected presentation in the view\r
- /// \return a boolean value\r
- virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);\r
-\r
- /// Fills the attribute with the value of the selected owner\r
- /// \param thePrs a selected owner\r
- virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs) = 0;\r
-\r
- /// Returns a list of selected presentations in the viewer and object browser\r
- /// The presentations from the object browser are filtered by the AIS context filters\r
- /// \return a list of presentations\r
- QList<std::shared_ptr<ModuleBase_ViewerPrs>> getFilteredSelected();\r
-\r
- /// It obtains selection filters from the workshop and activates them in the active viewer\r
- /// \param toActivate a flag about activation or deactivation the filters\r
- /// \return true if the selection filter of the widget is activated in viewer context\r
- bool activateFilters(const bool toActivate);\r
-\r
- /// Block the model flush of update and intialization of attribute\r
- /// \param theAttribute an attribute of blocking\r
- /// \param theToBlock flag whether the model is blocked or unblocked\r
- /// \param isFlushesActived out value if model is blocked, in value if model is unblocked\r
- /// to be used to restore flush state when unblocked\r
- /// \param isAttributeSetInitializedBlocked out value if model is blocked\r
- /// in value if model is unblocked to be used to restore previous state when unblocked\r
- virtual void blockAttribute(const AttributePtr& theAttribute, const bool& theToBlock,\r
- bool& isFlushesActived, bool& isAttributeSetInitializedBlocked);\r
-\r
-private:\r
- /// Checks the current attibute in all attribute validators\r
- /// \param theAttribute an attribute to be validated\r
- /// \return true if all validators return that the attribute is valid\r
- bool isValidAttribute(const AttributePtr& theAttribute) const;\r
-\r
-protected:\r
- /// Gets the validity state of the presentation in an internal map. Returns true if the valid state of value is stored\r
- /// \param theValue a viewer presentation\r
- /// \param theValid a valid state\r
- bool getValidState(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue, bool& theValid);\r
-\r
- /// Store the validity state of the presentation in an internal map\r
- /// \param theValue a viewer presentation\r
- /// \param theValid a valid state\r
- void storeValidState(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue, const bool theValid);\r
-\r
-private:\r
- /// Applies AIS context filters to the parameter list. The not approved presentations are\r
- /// removed from the parameters.\r
- /// \param theValues a list of presentations.\r
- void filterPresentations(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues);\r
-\r
- /// Remove subshapes of compsolids if whole compsolid is present.\r
- /// \param theValues a list of presentations.\r
- void filterCompSolids(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues);\r
-\r
-protected:\r
- /// Reference to workshop\r
- ModuleBase_IWorkshop* myWorkshop;\r
- /// The widget is in validation mode: store is performed, restore is not\r
- bool myIsInValidate;\r
-\r
-private:\r
- ObjectPtr myPresentedObject; /// back up of the filtered object\r
-#ifdef LIST_OF_VALID_PRS\r
- QList<std::shared_ptr<ModuleBase_ViewerPrs>> myValidPrs; /// cash of valid selection presentations\r
- QList<std::shared_ptr<ModuleBase_ViewerPrs>> myInvalidPrs; /// cash of invalid selection presentations\r
-#else\r
- // assume that one presentation selection presentation corresponds only one shape\r
- NCollection_DataMap<TopoDS_Shape, std::shared_ptr<ModuleBase_ViewerPrs> > myValidPrs;\r
- NCollection_DataMap<TopoDS_Shape, std::shared_ptr<ModuleBase_ViewerPrs> > myInvalidPrs;\r
-#endif\r
-\r
- /// store to backup parameters of the model\r
- ModuleBase_WidgetSelectorStore* myAttributeStore;\r
-};\r
-\r
-#endif /* MODULEBASE_WIDGETVALIDATED_H_ */\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModuleBase_WidgetValidated.h
+// Created: 12 Mar 2015
+// Author: Natalia ERMOLAEVA
+
+
+#ifndef MODULEBASE_WIDGETVALIDATED_H_
+#define MODULEBASE_WIDGETVALIDATED_H_
+
+#include <ModuleBase.h>
+#include <ModuleBase_ModelWidget.h>
+
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_AISObject.h>
+#include <ModelAPI_Object.h>
+#include <ModelAPI_Attribute.h>
+
+#include <SelectMgr_ListOfFilter.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <QList>
+#include <QMap>
+
+class QWidget;
+class ModuleBase_IWorkshop;
+class ModuleBase_ISelection;
+class ModuleBase_WidgetSelectorStore;
+class ModelAPI_Validator;
+class Config_WidgetAPI;
+class Handle_SelectMgr_EntityOwner;
+
+//#define LIST_OF_VALID_PRS
+
+/**
+* \ingroup GUI
+* Implementation of widget with validators and filters processing.
+*/
+class MODULEBASE_EXPORT ModuleBase_WidgetValidated : public ModuleBase_ModelWidget
+{
+ Q_OBJECT
+ public:
+ /// Constructor
+ /// \param theParent the parent object
+ /// \param theWorkshop a reference to workshop
+ /// \param theData the widget configuation. The attribute of the model widget is obtained from
+ ModuleBase_WidgetValidated(QWidget* theParent,
+ ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData);
+ virtual ~ModuleBase_WidgetValidated();
+
+ /// Checks all widget validator if the owner is valid. Firstly it checks custom widget validating,
+ /// next, the attribute's validating. It trying on the give selection to current attribute by
+ /// setting the value inside and calling validators. After this, the previous attribute value is
+ /// restored.The valid/invalid value is cashed.
+ /// \param theValue a selected presentation in the view
+ /// \return a boolean value
+ virtual bool isValidSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue);
+
+ //! Returns data object by AIS
+ ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const;
+
+ //! Clear all validated cash in the widget
+ void clearValidatedCash();
+
+ /// Returns true if the workshop validator filter has been already activated
+ /// \return boolean value
+ bool isFilterActivated() const;
+
+protected:
+ /// Checks whether all active viewer filters validate the presentation
+ /// \param thePrs a selected presentation in the view
+ /// \return a boolean value
+ virtual bool isValidInFilters(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+ /// Checks all attribute validators returns valid. It tries on the given selection
+ /// to current attribute by setting the value inside and calling validators. After this,
+ /// the previous attribute value is restored.The valid/invalid value is cashed.
+ /// \param theValue a selected presentation in the view
+ /// \param theAttribute the attribute
+ /// \return a boolean value
+ bool isValidSelectionForAttribute(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue,
+ const AttributePtr& theAttribute);
+
+ /// Retunrs attribute, which should be validated. In default implementation,
+ /// this is an attribute of ID
+ /// \return an attribute
+ virtual AttributePtr attribute() const;
+
+ /// Creates a backup of the current values of the attribute
+ /// It should be realized in the specific widget because of different
+ /// parameters of the current attribute
+ /// \param theAttribute an attribute to be stored
+ virtual void storeAttributeValue(const AttributePtr& theAttribute);
+
+ /// Creates a backup of the current values of the attribute
+ /// It should be realized in the specific widget because of different
+ /// parameters of the current attribute
+ /// \param theAttribute an attribute to be restored
+ /// \param theValid a boolean flag, if restore happens for valid parameters
+ virtual void restoreAttributeValue(const AttributePtr& theAttribute, const bool theValid);
+
+ /// Checks the widget validity. By default, it returns true.
+ /// \param thePrs a selected presentation in the view
+ /// \return a boolean value
+ virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+ /// Fills the attribute with the value of the selected owner
+ /// \param thePrs a selected owner
+ virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs) = 0;
+
+ /// Returns a list of selected presentations in the viewer and object browser
+ /// The presentations from the object browser are filtered by the AIS context filters
+ /// \return a list of presentations
+ QList<std::shared_ptr<ModuleBase_ViewerPrs>> getFilteredSelected();
+
+ /// It obtains selection filters from the workshop and activates them in the active viewer
+ /// \param toActivate a flag about activation or deactivation the filters
+ /// \return true if the selection filter of the widget is activated in viewer context
+ bool activateFilters(const bool toActivate);
+
+ /// Block the model flush of update and intialization of attribute
+ /// \param theAttribute an attribute of blocking
+ /// \param theToBlock flag whether the model is blocked or unblocked
+ /// \param isFlushesActived out value if model is blocked, in value if model is unblocked
+ /// to be used to restore flush state when unblocked
+ /// \param isAttributeSetInitializedBlocked out value if model is blocked
+ /// in value if model is unblocked to be used to restore previous state when unblocked
+ virtual void blockAttribute(const AttributePtr& theAttribute, const bool& theToBlock,
+ bool& isFlushesActived, bool& isAttributeSetInitializedBlocked);
+
+private:
+ /// Checks the current attibute in all attribute validators
+ /// \param theAttribute an attribute to be validated
+ /// \return true if all validators return that the attribute is valid
+ bool isValidAttribute(const AttributePtr& theAttribute) const;
+
+protected:
+ /// Gets the validity state of the presentation in an internal map. Returns true if the valid state of value is stored
+ /// \param theValue a viewer presentation
+ /// \param theValid a valid state
+ bool getValidState(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue, bool& theValid);
+
+ /// Store the validity state of the presentation in an internal map
+ /// \param theValue a viewer presentation
+ /// \param theValid a valid state
+ void storeValidState(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue, const bool theValid);
+
+private:
+ /// Applies AIS context filters to the parameter list. The not approved presentations are
+ /// removed from the parameters.
+ /// \param theValues a list of presentations.
+ void filterPresentations(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues);
+
+ /// Remove subshapes of compsolids if whole compsolid is present.
+ /// \param theValues a list of presentations.
+ void filterCompSolids(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues);
+
+protected:
+ /// Reference to workshop
+ ModuleBase_IWorkshop* myWorkshop;
+ /// The widget is in validation mode: store is performed, restore is not
+ bool myIsInValidate;
+
+private:
+ ObjectPtr myPresentedObject; /// back up of the filtered object
+#ifdef LIST_OF_VALID_PRS
+ QList<std::shared_ptr<ModuleBase_ViewerPrs>> myValidPrs; /// cash of valid selection presentations
+ QList<std::shared_ptr<ModuleBase_ViewerPrs>> myInvalidPrs; /// cash of invalid selection presentations
+#else
+ // assume that one presentation selection presentation corresponds only one shape
+ NCollection_DataMap<TopoDS_Shape, std::shared_ptr<ModuleBase_ViewerPrs> > myValidPrs;
+ NCollection_DataMap<TopoDS_Shape, std::shared_ptr<ModuleBase_ViewerPrs> > myInvalidPrs;
+#endif
+
+ /// store to backup parameters of the model
+ ModuleBase_WidgetSelectorStore* myAttributeStore;
+};
+
+#endif /* MODULEBASE_WIDGETVALIDATED_H_ */
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-#ifndef PARTSET_H\r
-#define PARTSET_H\r
-\r
-#if defined PARTSET_EXPORTS\r
-#if defined WIN32\r
-#define PARTSET_EXPORT __declspec( dllexport )\r
-#else\r
-#define PARTSET_EXPORT\r
-#endif\r
-#else\r
-#if defined WIN32\r
-#define PARTSET_EXPORT __declspec( dllimport )\r
-#else\r
-#define PARTSET_EXPORT\r
-#endif\r
-#endif\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#ifndef PARTSET_H
+#define PARTSET_H
+
+#if defined PARTSET_EXPORTS
+#if defined WIN32
+#define PARTSET_EXPORT __declspec( dllexport )
+#else
+#define PARTSET_EXPORT
+#endif
+#else
+#if defined WIN32
+#define PARTSET_EXPORT __declspec( dllimport )
+#else
+#define PARTSET_EXPORT
+#endif
+#endif
+
#endif //PARTSET_H\r
\ No newline at end of file
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: PartSet_SketcherMgr.cpp\r
-// Created: 19 Dec 2014\r
-// Author: Vitaly SMETANNIKOV\r
-\r
-#include "PartSet_SketcherMgr.h"\r
-#include "PartSet_SketcherReetntrantMgr.h"\r
-#include "PartSet_Module.h"\r
-#include "PartSet_MouseProcessor.h"\r
-#include "PartSet_Tools.h"\r
-#include "PartSet_WidgetSketchLabel.h"\r
-#include "PartSet_WidgetEditor.h"\r
-#include "PartSet_ResultSketchPrs.h"\r
-\r
-#include <XGUI_ModuleConnector.h>\r
-#include <XGUI_Displayer.h>\r
-#include <XGUI_Workshop.h>\r
-#include <XGUI_ContextMenuMgr.h>\r
-#include <XGUI_Selection.h>\r
-#include <XGUI_SelectionMgr.h>\r
-#include <XGUI_ModuleConnector.h>\r
-#include <XGUI_PropertyPanel.h>\r
-#include <XGUI_ViewerProxy.h>\r
-#include <XGUI_OperationMgr.h>\r
-#include <XGUI_ErrorMgr.h>\r
-#include <XGUI_Tools.h>\r
-\r
-#include <ModuleBase_IPropertyPanel.h>\r
-#include <ModuleBase_ISelection.h>\r
-#include <ModuleBase_IViewer.h>\r
-#include <ModuleBase_IWorkshop.h>\r
-#include <ModuleBase_IViewWindow.h>\r
-#include <ModuleBase_ModelWidget.h>\r
-#include <ModuleBase_Operation.h>\r
-#include <ModuleBase_OperationFeature.h>\r
-#include <ModuleBase_Operation.h>\r
-#include <ModuleBase_WidgetEditor.h>\r
-#include <ModuleBase_ViewerPrs.h>\r
-#include <ModuleBase_Tools.h>\r
-#include <ModuleBase_ResultPrs.h>\r
-\r
-#include <GeomDataAPI_Point2D.h>\r
-\r
-#include <Events_Loop.h>\r
-\r
-#include <SketchPlugin_Line.h>\r
-#include <SketchPlugin_Sketch.h>\r
-#include <SketchPlugin_Point.h>\r
-#include <SketchPlugin_Arc.h>\r
-#include <SketchPlugin_Circle.h>\r
-#include <SketchPlugin_ConstraintLength.h>\r
-#include <SketchPlugin_ConstraintDistance.h>\r
-#include <SketchPlugin_ConstraintParallel.h>\r
-#include <SketchPlugin_ConstraintPerpendicular.h>\r
-#include <SketchPlugin_ConstraintRadius.h>\r
-#include <SketchPlugin_ConstraintRigid.h>\r
-#include <SketchPlugin_ConstraintHorizontal.h>\r
-#include <SketchPlugin_ConstraintVertical.h>\r
-#include <SketchPlugin_ConstraintEqual.h>\r
-#include <SketchPlugin_ConstraintTangent.h>\r
-#include <SketchPlugin_ConstraintCoincidence.h>\r
-#include <SketchPlugin_ConstraintFillet.h>\r
-#include <SketchPlugin_ConstraintMirror.h>\r
-#include <SketchPlugin_ConstraintAngle.h>\r
-#include <SketchPlugin_ConstraintCollinear.h>\r
-#include <SketchPlugin_ConstraintMiddle.h>\r
-#include <SketchPlugin_MultiRotation.h>\r
-#include <SketchPlugin_MultiTranslation.h>\r
-#include <SketchPlugin_IntersectionPoint.h>\r
-\r
-#include <SketcherPrs_Tools.h>\r
-\r
-#include <SelectMgr_IndexedMapOfOwner.hxx>\r
-#include <StdSelect_BRepOwner.hxx>\r
-\r
-//#include <AIS_DimensionSelectionMode.hxx>\r
-#include <AIS_Shape.hxx>\r
-#include <AIS_Dimension.hxx>\r
-\r
-#include <ModelAPI_Events.h>\r
-#include <ModelAPI_Session.h>\r
-#include <ModelAPI_AttributeString.h>\r
-\r
-#include <ModelAPI_Validator.h>\r
-#include <ModelAPI_Tools.h>\r
-\r
-#include <QMouseEvent>\r
-#include <QApplication>\r
-#include <QCursor>\r
-#include <QMessageBox>\r
-#include <QMainWindow>\r
-\r
-//#define DEBUG_DO_NOT_BY_ENTER\r
-//#define DEBUG_SKETCHER_ENTITIES\r
-//#define DEBUG_SKETCH_ENTITIES_ON_MOVE\r
-\r
-//#define DEBUG_CURSOR\r
-\r
-/// Fills attribute and result lists by the selected owner. In case if the attribute is found,\r
-/// by the owner shape, it is put to the list. Otherwise if type of owner shape is edge, put the function\r
-/// result as is to the list of results.\r
-/// \param theOwner a viewer selected owner\r
-/// \param theFeature a feature, where the attribute is searched\r
-/// \param theSketch a current sketch\r
-/// \param theSelectedAttribute an output list of attributes\r
-/// \param theSelectedResults an output list of edge results\r
-void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,\r
- const FeaturePtr& theFeature, const FeaturePtr& theSketch,\r
- const ResultPtr& theResult,\r
- std::set<AttributePtr>& aSelectedAttributes,\r
- std::set<ResultPtr>& aSelectedResults)\r
-{\r
- Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner);\r
- if (aBRepOwner.IsNull())\r
- return;\r
- Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(\r
- aBRepOwner->Selectable());\r
- if (aBRepOwner->HasShape()) {\r
- const TopoDS_Shape& aShape = aBRepOwner->Shape();\r
- TopAbs_ShapeEnum aShapeType = aShape.ShapeType();\r
- if (aShapeType == TopAbs_VERTEX) {\r
- AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature,\r
- aShape, theSketch);\r
- if (aPntAttr.get() != NULL)\r
- aSelectedAttributes.insert(aPntAttr);\r
- }\r
- else if (aShapeType == TopAbs_EDGE &&\r
- aSelectedResults.find(theResult) == aSelectedResults.end()) {\r
- aSelectedResults.insert(theResult);\r
- }\r
- }\r
-}\r
-\r
-PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)\r
- : QObject(theModule), myModule(theModule), myIsDragging(false), myDragDone(false),\r
- myIsMouseOverWindow(false),\r
- myIsMouseOverViewProcessed(true), myPreviousUpdateViewerEnabled(true),\r
- myIsPopupMenuActive(false)\r
-{\r
- ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();\r
- ModuleBase_IViewer* aViewer = anIWorkshop->viewer();\r
-\r
- myPreviousDrawModeEnabled = true;//aViewer->isSelectionEnabled();\r
-\r
- connect(aViewer, SIGNAL(mousePress(ModuleBase_IViewWindow*, QMouseEvent*)),\r
- this, SLOT(onMousePressed(ModuleBase_IViewWindow*, QMouseEvent*)));\r
-\r
- connect(aViewer, SIGNAL(mouseRelease(ModuleBase_IViewWindow*, QMouseEvent*)),\r
- this, SLOT(onMouseReleased(ModuleBase_IViewWindow*, QMouseEvent*)));\r
-\r
- connect(aViewer, SIGNAL(mouseMove(ModuleBase_IViewWindow*, QMouseEvent*)),\r
- this, SLOT(onMouseMoved(ModuleBase_IViewWindow*, QMouseEvent*)));\r
-\r
- connect(aViewer, SIGNAL(mouseDoubleClick(ModuleBase_IViewWindow*, QMouseEvent*)),\r
- this, SLOT(onMouseDoubleClick(ModuleBase_IViewWindow*, QMouseEvent*)));\r
-\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);\r
- XGUI_Workshop* aWorkshop = aConnector->workshop();\r
- connect(aWorkshop, SIGNAL(applicationStarted()), this, SLOT(onApplicationStarted()));\r
-\r
- myIsConstraintsShown[PartSet_Tools::Geometrical] = true;\r
- myIsConstraintsShown[PartSet_Tools::Dimensional] = true;\r
- myIsConstraintsShown[PartSet_Tools::Expressions] = false;\r
-}\r
-\r
-PartSet_SketcherMgr::~PartSet_SketcherMgr()\r
-{\r
- if (!myPlaneFilter.IsNull())\r
- myPlaneFilter.Nullify();\r
-}\r
-\r
-void PartSet_SketcherMgr::onEnterViewPort()\r
-{\r
- // 1. if the mouse over window, update the next flag. Do not perform update visibility of\r
- // created feature because it should be done in onMouseMove(). Some widgets watch\r
- // the mouse move and use the cursor position to update own values. If the presentaion is\r
- // redisplayed before this update, the feature presentation jumps from reset value to current.\r
- myIsMouseOverWindow = true;\r
-\r
- #ifdef DEBUG_DO_NOT_BY_ENTER\r
- return;\r
- #endif\r
-\r
- if (canChangeCursor(getCurrentOperation())) {\r
- QCursor* aCurrentCursor = QApplication::overrideCursor();\r
- if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {\r
- QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));\r
-#ifdef DEBUG_CURSOR\r
- qDebug("onEnterViewPort() : Qt::CrossCursor");\r
-#endif\r
- }\r
- }\r
-\r
- if (!isNestedCreateOperation(getCurrentOperation(), activeSketch()))\r
- return;\r
-\r
- operationMgr()->onValidateOperation();\r
-\r
- // we need change displayed state of the current operation feature\r
- // if the feature is presentable, e.g. distance construction. It has no results, so workshop does\r
- // not accept a signal about the result created. Nothing is shown until mouse is moved out/in view\r
- // port. If the isDisplayed flag is true, the presentable feature is displayed as soon as the\r
- // presentation becomes valid and redisplay happens\r
- //ModuleBase_Operation* aOperation = getCurrentOperation();\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- if (aFeature.get() && aFeature->data()->isValid()) {\r
- visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature), false);\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::onLeaveViewPort()\r
-{\r
- myIsMouseOverViewProcessed = false;\r
- myIsMouseOverWindow = false;\r
-\r
- #ifdef DEBUG_DO_NOT_BY_ENTER\r
- return;\r
- #endif\r
-\r
- if (canChangeCursor(getCurrentOperation())) {\r
- QApplication::restoreOverrideCursor();\r
-#ifdef DEBUG_CURSOR\r
- qDebug("onLeaveViewPort() : None");\r
-#endif\r
- }\r
-\r
- if (!isNestedCreateOperation(getCurrentOperation(), activeSketch()))\r
- return;\r
-\r
- // the method should be performed if the popup menu is called,\r
- // the reset of the current widget should not happen\r
- if (myIsPopupMenuActive)\r
- return;\r
-\r
- // it is important to validate operation here only if sketch entity create operation is active\r
- // because at this operation we reacts to the mouse leave/enter view port\r
- operationMgr()->onValidateOperation();\r
-\r
- // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
- XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();\r
- // disable the viewer update in order to avoid visualization of redisplayed feature in viewer\r
- // obtained after reset value\r
- bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false);\r
- ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();\r
- if (anActiveWidget)\r
- anActiveWidget->reset();\r
-\r
- // hides the presentation of the current operation feature\r
- // the feature is to be erased here, but it is correct to call canDisplayObject because\r
- // there can be additional check (e.g. editor widget in distance constraint)\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));\r
- }\r
- // we should update viewer after the presentation are hidden in the viewer\r
- // otherwise the reset presentation(line) appears in the viewer(by quick move from viewer to PP)\r
- aDisplayer->enableUpdateViewer(isEnableUpdateViewer);\r
-}\r
-\r
-void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()\r
-{\r
- if (!isNestedEditOperation(getCurrentOperation(), myModule->sketchMgr()->activeSketch()) ||\r
- myModule->sketchReentranceMgr()->isInternalEditActive())\r
- return;\r
- // it is necessary to save current selection in order to restore it after the values are modifed\r
- storeSelection();\r
-\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
- XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();\r
- myPreviousUpdateViewerEnabled = aDisplayer->enableUpdateViewer(false);\r
-}\r
-\r
-void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()\r
-{\r
- if (!isNestedEditOperation(getCurrentOperation(), myModule->sketchMgr()->activeSketch()) ||\r
- myModule->sketchReentranceMgr()->isInternalEditActive()) {\r
- myModule->sketchReentranceMgr()->updateInternalEditActiveState();\r
- return;\r
- }\r
- // it is necessary to restore current selection in order to restore it after the values are modified\r
- restoreSelection();\r
- myCurrentSelection.clear();\r
-\r
- // 3. the flag to disable the update viewer should be set in order to avoid blinking in the \r
- // viewer happens by deselect/select the modified objects. The flag should be restored after\r
- // the selection processing. The update viewer should be also called.\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
- XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();\r
- aDisplayer->enableUpdateViewer(myPreviousUpdateViewerEnabled);\r
- aDisplayer->updateViewer();\r
-\r
-\r
-}\r
-\r
-void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)\r
-{\r
- if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent))\r
- return;\r
-\r
- //get2dPoint(theWnd, theEvent, myClickedPoint);\r
-\r
- if (!(theEvent->buttons() & Qt::LeftButton))\r
- return;\r
-\r
- // Clear dragging mode\r
- myIsDragging = false;\r
-\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- ModuleBase_IViewer* aViewer = aWorkshop->viewer();\r
- if (!aViewer->canDragByMouse())\r
- return;\r
-\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (!aFOperation)\r
- return;\r
-\r
- if (aFOperation->isEditOperation()) {\r
- // If the current widget is a selector, do nothing, it processes the mouse press\r
- ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();\r
- if(anActiveWidget && anActiveWidget->isViewerSelector()) {\r
- return;\r
- }\r
- }\r
-\r
- // Use only for sketch operations\r
- if (myCurrentSketch) {\r
- if (!PartSet_Tools::sketchPlane(myCurrentSketch))\r
- return;\r
-\r
- bool isSketcher = isSketchOperation(aFOperation);\r
- bool isSketchOpe = isNestedSketchOperation(aFOperation);\r
-\r
- // Avoid non-sketch operations\r
- if ((!isSketchOpe) && (!isSketcher))\r
- return;\r
-\r
- bool isEditing = aFOperation->isEditOperation();\r
-\r
- // Ignore creation sketch operation\r
- if ((!isSketcher) && (!isEditing))\r
- return;\r
-\r
- Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();\r
- // Remember highlighted objects for editing\r
- ModuleBase_ISelection* aSelect = aWorkshop->selection();\r
-\r
- bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);\r
- storeSelection(!aHasShift);\r
-\r
- if (myCurrentSelection.empty()) {\r
- if (isSketchOpe && (!isSketcher))\r
- // commit previous operation\r
- if (!aFOperation->commit())\r
- aFOperation->abort();\r
- return;\r
- }\r
- // Init flyout point for radius rotation\r
- FeaturePtr aFeature = myCurrentSelection.begin().key();\r
-\r
- get2dPoint(theWnd, theEvent, myCurrentPoint);\r
- if (isSketcher) {\r
- myIsDragging = true;\r
- myDragDone = false;\r
-\r
- myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);\r
- // selection should be restored before edit operation start to process the\r
- // selected entities, e.g. selection of point(attribute on a line) should edit the point\r
- restoreSelection();\r
- launchEditing();\r
- if (aFeature.get() != NULL) {\r
- std::shared_ptr<SketchPlugin_Feature> aSPFeature = \r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);\r
- if (aSPFeature.get() && \r
- (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() ||\r
- aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) {\r
- DataPtr aData = aSPFeature->data();\r
- AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());\r
- std::shared_ptr<GeomDataAPI_Point2D> aFPAttr = \r
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aAttr);\r
- aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY);\r
- }\r
- }\r
- } else if (isSketchOpe && isEditing) {\r
- // If selected another object commit current result\r
- aFOperation->commit();\r
-\r
- myIsDragging = true;\r
- myDragDone = false;\r
-\r
- myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);\r
- // selection should be restored before edit operation start to process the\r
- // selected entities, e.g. selection of point(attribute on a line) should edit the point\r
- restoreSelection();\r
- launchEditing();\r
- if (aFeature.get() != NULL) {\r
- std::shared_ptr<SketchPlugin_Feature> aSPFeature = \r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);\r
- if (aSPFeature.get() && \r
- (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() ||\r
- aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) {\r
- DataPtr aData = aSPFeature->data();\r
- AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());\r
- std::shared_ptr<GeomDataAPI_Point2D> aFPAttr = \r
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aAttr);\r
- aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY);\r
- }\r
- }\r
- restoreSelection();\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)\r
-{\r
- if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent))\r
- return;\r
-\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- ModuleBase_IViewer* aViewer = aWorkshop->viewer();\r
- if (!aViewer->canDragByMouse())\r
- return;\r
- ModuleBase_Operation* aOp = getCurrentOperation();\r
- if (aOp) {\r
- if (isNestedSketchOperation(aOp)) {\r
- // Only for sketcher operations\r
- if (myIsDragging) {\r
- if (myDragDone) {\r
- myCurrentSelection.clear();\r
- }\r
- }\r
- }\r
- }\r
-\r
- aWorkshop->viewer()->enableDrawMode(myPreviousDrawModeEnabled);\r
- myIsDragging = false;\r
-\r
- ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();\r
- PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);\r
- if (aProcessor)\r
- aProcessor->mouseReleased(theWnd, theEvent);\r
-}\r
-\r
-void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)\r
-{\r
-#ifdef DEBUG_SKETCH_ENTITIES_ON_MOVE\r
- CompositeFeaturePtr aSketch = activeSketch();\r
- if (aSketch.get()) {\r
- std::cout << "mouse move SKETCH FEATURES [" << aSketch->numberOfSubs() << "]:" << std::endl;\r
- QStringList anInfo;\r
- for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) {\r
- //std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl;\r
- anInfo.append(ModuleBase_Tools::objectInfo(aSketch->subFeature(i)));\r
- }\r
- QString anInfoStr = anInfo.join("\n");\r
- qDebug(QString("%1").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str());\r
- }\r
-#endif\r
-\r
- if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent))\r
- return;\r
-\r
- if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) {\r
- // 1. perform the widget mouse move functionality and display the presentation\r
- // the mouse move should be processed in the widget, if it can in order to visualize correct\r
- // presentation. These widgets correct the feature attribute according to the mouse position\r
- ModuleBase_ModelWidget* anActiveWidget = myModule->activeWidget();\r
- PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);\r
- if (aProcessor)\r
- aProcessor->mouseMoved(theWnd, theEvent);\r
- if (!myIsMouseOverViewProcessed) {\r
- myIsMouseOverViewProcessed = true;\r
-\r
- // the feature is to be erased here, but it is correct to call canDisplayObject because\r
- // there can be additional check (e.g. editor widget in distance constraint)\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));\r
- }\r
- }\r
- }\r
- //myClickedPoint.clear();\r
-\r
- if (myIsDragging) {\r
- // 1. the current selection is saved in the mouse press method in order to restore it after moving\r
- // 2. the enable selection in the viewer should be temporary switched off in order to ignore\r
- // mouse press signal in the viewer(it call Select for AIS context and the dragged objects are\r
- // deselected). This flag should be restored in the slot, processed the mouse release signal.\r
-\r
- ModuleBase_Operation* aCurrentOperation = getCurrentOperation();\r
- if (!aCurrentOperation)\r
- return;\r
- if (isSketchOperation(aCurrentOperation))\r
- return; // No edit operation activated\r
-\r
- Handle(V3d_View) aView = theWnd->v3dView();\r
- gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);\r
- Point aMousePnt;\r
- get2dPoint(theWnd, theEvent, aMousePnt);\r
- double dX = aMousePnt.myCurX - myCurrentPoint.myCurX;\r
- double dY = aMousePnt.myCurY - myCurrentPoint.myCurY;\r
-\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
- XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();\r
- // 3. the flag to disable the update viewer should be set in order to avoid blinking in the \r
- // viewer happens by deselect/select the modified objects. The flag should be restored after\r
- // the selection processing. The update viewer should be also called.\r
- bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false);\r
-\r
- static Events_ID aMoveEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);\r
- //static Events_ID aUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);\r
- FeatureToSelectionMap::const_iterator anIt = myCurrentSelection.begin(),\r
- aLast = myCurrentSelection.end();\r
- // 4. the features and attributes modification(move)\r
- bool isModified = false;\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aFeature = anIt.key();\r
-\r
- std::set<AttributePtr> anAttributes = anIt.value().first;\r
- // Process selection by attribute: the priority to the attribute\r
- if (!anAttributes.empty()) {\r
- std::set<AttributePtr>::const_iterator anAttIt = anAttributes.begin(),\r
- anAttLast = anAttributes.end();\r
- for (; anAttIt != anAttLast; anAttIt++) {\r
- AttributePtr anAttr = *anAttIt;\r
- if (anAttr.get() == NULL)\r
- continue;\r
- std::string aAttrId = anAttr->id();\r
- DataPtr aData = aFeature->data();\r
- if (aData->isValid()) {\r
- std::shared_ptr<GeomDataAPI_Point2D> aPoint = \r
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(aAttrId));\r
- if (aPoint.get() != NULL) {\r
- bool isImmutable = aPoint->setImmutable(true);\r
- aPoint->move(dX, dY);\r
- isModified = true;\r
- ModelAPI_EventCreator::get()->sendUpdated(aFeature, aMoveEvent);\r
- aPoint->setImmutable(isImmutable);\r
- }\r
- }\r
- }\r
- } else {\r
- // Process selection by feature\r
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =\r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);\r
- if (aSketchFeature) {\r
- aSketchFeature->move(dX, dY);\r
- isModified = true;\r
- ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, aMoveEvent);\r
- }\r
- }\r
- }\r
- // the modified state of the current operation should be updated if there are features, which\r
- // were changed here\r
- if (isModified) {\r
- aCurrentOperation->onValuesChanged();\r
- }\r
- Events_Loop::loop()->flush(aMoveEvent); // up all move events - to be processed in the solver\r
- //Events_Loop::loop()->flush(aUpdateEvent); // up update events - to redisplay presentations\r
-\r
- // 5. it is necessary to save current selection in order to restore it after the features moving\r
- restoreSelection();\r
- // 6. restore the update viewer flag and call this update\r
- aDisplayer->enableUpdateViewer(isEnableUpdateViewer);\r
- aDisplayer->updateViewer();\r
-\r
- myDragDone = true;\r
- myCurrentPoint = aMousePnt;\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation && aFOperation->isEditOperation()) {\r
- std::string aId = aFOperation->id().toStdString();\r
- if (isDistanceOperation(aFOperation))\r
- {\r
- // Activate dimension value editing on double click\r
- ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();\r
- QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();\r
- // Find corresponded widget to activate value editing\r
- foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {\r
- if (aWgt->attributeID() == SketchPlugin_Constraint::VALUE() ||\r
- aWgt->attributeID() == SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()) {\r
- PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);\r
- if (anEditor)\r
- anEditor->showPopupEditor();\r
- return;\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::onApplicationStarted()\r
-{\r
- ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);\r
- XGUI_Workshop* aWorkshop = aConnector->workshop();\r
- PartSet_SketcherReetntrantMgr* aReentranceMgr = myModule->sketchReentranceMgr();\r
-\r
- XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel();\r
- if (aPropertyPanel) {\r
- //connect(aPropertyPanel, SIGNAL(beforeWidgetActivated(ModuleBase_ModelWidget*)),\r
- // this, SLOT(onBeforeWidgetActivated(ModuleBase_ModelWidget*)));\r
-\r
- connect(aPropertyPanel, SIGNAL(noMoreWidgets(const std::string&)),\r
- aReentranceMgr, SLOT(onNoMoreWidgets(const std::string&)));\r
- connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),\r
- aReentranceMgr, SLOT(onWidgetActivated()));\r
- }\r
-\r
- XGUI_ViewerProxy* aViewerProxy = aWorkshop->viewer();\r
- connect(aViewerProxy, SIGNAL(enterViewPort()), this, SLOT(onEnterViewPort()));\r
- connect(aViewerProxy, SIGNAL(leaveViewPort()), this, SLOT(onLeaveViewPort()));\r
-\r
- XGUI_ContextMenuMgr* aContextMenuMgr = aWorkshop->contextMenuMgr();\r
- connect(aContextMenuMgr, SIGNAL(beforeContextMenu()), this, SLOT(onBeforeContextMenu()));\r
- connect(aContextMenuMgr, SIGNAL(afterContextMenu()), this, SLOT(onAfterContextMenu()));\r
-}\r
-\r
-//void PartSet_SketcherMgr::onBeforeWidgetActivated(ModuleBase_ModelWidget* theWidget)\r
-//{\r
- //if (!myClickedPoint.myIsInitialized)\r
- // return;\r
-\r
- //ModuleBase_Operation* aOperation = getCurrentOperation();\r
- // the distance constraint feature should not use the clickedd point\r
- // this is workaround in order to don't throw down the flyout point value,\r
- // set by execute() method of these type of features\r
- //if (isDistanceOperation(aOperation))\r
- // return;\r
-\r
- //PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast<PartSet_WidgetPoint2D*>(theWidget);\r
- //if (aPnt2dWgt) {\r
- // aPnt2dWgt->setPoint(myClickedPoint.myCurX, myClickedPoint.myCurY);\r
- //}\r
-//}\r
-\r
-void PartSet_SketcherMgr::onBeforeContextMenu()\r
-{\r
- myIsPopupMenuActive = true;\r
-}\r
-\r
-void PartSet_SketcherMgr::onAfterContextMenu()\r
-{\r
- myIsPopupMenuActive = false;\r
-}\r
-\r
-void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent, \r
- Point& thePoint)\r
-{\r
- Handle(V3d_View) aView = theWnd->v3dView();\r
- gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);\r
- double aX, anY;\r
- PartSet_Tools::convertTo2D(aPoint, myCurrentSketch, aView, aX, anY);\r
- thePoint.setValue(aX, anY);\r
-}\r
-\r
-void PartSet_SketcherMgr::launchEditing()\r
-{\r
- if (!myCurrentSelection.empty()) {\r
- FeaturePtr aFeature = myCurrentSelection.begin().key();\r
- std::shared_ptr<SketchPlugin_Feature> aSPFeature = \r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);\r
- if (aSPFeature && (!aSPFeature->isExternal())) {\r
- myModule->editFeature(aSPFeature);\r
- }\r
- }\r
-}\r
-\r
-bool PartSet_SketcherMgr::sketchSolverError()\r
-{\r
- bool anError = false;\r
- CompositeFeaturePtr aSketch = activeSketch();\r
- if (aSketch.get()) {\r
- AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());\r
- anError = !aAttributeString->value().empty();\r
- }\r
- return anError;\r
-}\r
-\r
-QString PartSet_SketcherMgr::getFeatureError(const FeaturePtr& theFeature)\r
-{\r
- std::string anError = "";\r
- if (!theFeature.get() || !theFeature->data()->isValid())\r
- return anError.c_str();\r
-\r
- CompositeFeaturePtr aSketch = activeSketch();\r
- if (aSketch.get() && aSketch == theFeature) {\r
- AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());\r
- anError = aAttributeString->value();\r
- ModuleBase_Tools::translate(aSketch->getKind(), anError);\r
- }\r
- return anError.c_str();\r
-}\r
-\r
-void PartSet_SketcherMgr::clearClickedFlags()\r
-{\r
- //myClickedPoint.clear();\r
- myCurrentPoint.clear();\r
-}\r
-\r
-const QStringList& PartSet_SketcherMgr::replicationsIdList()\r
-{\r
- static QStringList aReplicationIds;\r
- if (aReplicationIds.size() == 0) {\r
- aReplicationIds << SketchPlugin_ConstraintMirror::ID().c_str();\r
- aReplicationIds << SketchPlugin_MultiRotation::ID().c_str();\r
- aReplicationIds << SketchPlugin_MultiTranslation::ID().c_str();\r
- }\r
- return aReplicationIds;\r
-}\r
-\r
-const QStringList& PartSet_SketcherMgr::constraintsIdList()\r
-{\r
- static QStringList aConstraintIds;\r
- if (aConstraintIds.size() == 0) {\r
- aConstraintIds << SketchPlugin_ConstraintLength::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintDistance::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintRigid::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintRadius::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintPerpendicular::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintParallel::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintHorizontal::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintVertical::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintEqual::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintTangent::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintCoincidence::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintAngle::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintCollinear::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintMiddle::ID().c_str();\r
- aConstraintIds << SketchPlugin_ConstraintMirror::ID().c_str();\r
- aConstraintIds << SketchPlugin_MultiTranslation::ID().c_str();\r
- aConstraintIds << SketchPlugin_MultiRotation::ID().c_str();\r
- }\r
- return aConstraintIds;\r
-}\r
-\r
-void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes)\r
-{\r
- theModes.clear();\r
-\r
- theModes.append(SketcherPrs_Tools::Sel_Dimension_Text);\r
- theModes.append(SketcherPrs_Tools::Sel_Dimension_Line);\r
- theModes.append(SketcherPrs_Tools::Sel_Constraint);\r
- theModes.append(TopAbs_VERTEX);\r
- theModes.append(TopAbs_EDGE);\r
-}\r
-\r
-Handle(AIS_InteractiveObject) PartSet_SketcherMgr::createPresentation(const ResultPtr& theResult)\r
-{\r
- Handle(AIS_InteractiveObject) aPrs;\r
-\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(theResult);\r
- if (aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID()) {\r
- aPrs = new PartSet_ResultSketchPrs(theResult);\r
- }\r
- return aPrs;\r
-}\r
-\r
-bool PartSet_SketcherMgr::isSketchOperation(ModuleBase_Operation* theOperation)\r
-{\r
- return theOperation && theOperation->id().toStdString() == SketchPlugin_Sketch::ID();\r
-}\r
-\r
-bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOperation) const\r
-{\r
- bool aNestedSketch = false;\r
-\r
- FeaturePtr anActiveSketch = activeSketch();\r
- if (anActiveSketch.get() && theOperation) {\r
- ModuleBase_Operation* aSketchOperation = operationMgr()->findOperation(\r
- anActiveSketch->getKind().c_str());\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (theOperation);\r
- if (aSketchOperation && aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- if (aFeature.get()) {\r
- QStringList aGrantedOpIds = aSketchOperation->grantedOperationIds();\r
- aNestedSketch = aGrantedOpIds.contains(aFeature->getKind().c_str());\r
- }\r
- }\r
- }\r
- return aNestedSketch;\r
-}\r
-\r
-bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation,\r
- const CompositeFeaturePtr& theSketch) const\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (theOperation);\r
- return aFOperation && !aFOperation->isEditOperation() &&\r
- isNestedSketchOperation(aFOperation);\r
-}\r
-\r
-bool PartSet_SketcherMgr::isNestedEditOperation(ModuleBase_Operation* theOperation,\r
- const CompositeFeaturePtr& theSketch) const\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (theOperation);\r
- return aFOperation && aFOperation->isEditOperation() &&\r
- isNestedSketchOperation(aFOperation);\r
-}\r
-\r
-bool PartSet_SketcherMgr::isEntity(const std::string& theId)\r
-{\r
- return (theId == SketchPlugin_Line::ID()) ||\r
- (theId == SketchPlugin_Point::ID()) ||\r
- (theId == SketchPlugin_Arc::ID()) ||\r
- (theId == SketchPlugin_Circle::ID());\r
-}\r
-\r
-bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation)\r
-{\r
- std::string anId = theOperation ? theOperation->id().toStdString() : "";\r
-\r
- return isDistanceKind(anId);\r
-}\r
-\r
-bool PartSet_SketcherMgr::isDistanceKind(std::string& theKind)\r
-{\r
- return (theKind == SketchPlugin_ConstraintLength::ID()) ||\r
- (theKind == SketchPlugin_ConstraintDistance::ID()) ||\r
- (theKind == SketchPlugin_ConstraintRadius::ID()) ||\r
- (theKind == SketchPlugin_ConstraintAngle::ID());\r
-}\r
-\r
-void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (!aFOperation)\r
- return;\r
-\r
- myModule->onViewTransformed();\r
-\r
- // Display all sketcher sub-Objects\r
- myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());\r
-\r
- // Hide sketcher result\r
- std::list<ResultPtr> aResults = myCurrentSketch->results();\r
- std::list<ResultPtr>::const_iterator aIt;\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {\r
- (*aIt)->setDisplayed(false);\r
- }\r
- myCurrentSketch->setDisplayed(false);\r
-\r
- // Remove invalid sketch entities\r
- std::set<FeaturePtr> anInvalidFeatures;\r
- ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();\r
- for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {\r
- FeaturePtr aFeature = myCurrentSketch->subFeature(i);\r
- if (aFeature.get()) {\r
- if (!aFactory->validate(aFeature))\r
- anInvalidFeatures.insert(aFeature);\r
- }\r
- }\r
- if (!anInvalidFeatures.empty()) {\r
- std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;\r
- ModelAPI_Tools::findAllReferences(anInvalidFeatures, aReferences, false);\r
-\r
- std::set<FeaturePtr>::const_iterator anIt = anInvalidFeatures.begin(),\r
- aLast = anInvalidFeatures.end();\r
- // separate features to references to parameter features and references to others\r
- QStringList anInvalidFeatureNames;\r
- for (; anIt != aLast; anIt++) {\r
- FeaturePtr aFeature = *anIt;\r
- if (aFeature.get())\r
- anInvalidFeatureNames.append(aFeature->name().c_str());\r
- }\r
- std::string aPrefixInfo = QString("Invalid features of the sketch will be deleted: %1.\n\n").\r
- arg(anInvalidFeatureNames.join(", ")).toStdString().c_str();\r
- std::set<FeaturePtr> aFeatureRefsToDelete;\r
- if (ModuleBase_Tools::askToDelete(anInvalidFeatures, aReferences, aConnector->desktop(),\r
- aFeatureRefsToDelete, aPrefixInfo)) {\r
- if (!aFeatureRefsToDelete.empty())\r
- anInvalidFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());\r
- ModelAPI_Tools::removeFeatures(anInvalidFeatures, true);\r
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));\r
- // TODO: call the next method in the XGUI_OperationMgr::onOperationStarted().\r
- workshop()->errorMgr()->updateAcceptAllAction(myCurrentSketch);\r
- }\r
- }\r
-\r
- // Display sketcher objects\r
- QStringList anInfo;\r
- for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {\r
- FeaturePtr aFeature = myCurrentSketch->subFeature(i);\r
-#ifdef DEBUG_SKETCHER_ENTITIES\r
- anInfo.append(ModuleBase_Tools::objectInfo(aFeature));\r
-#endif\r
- std::list<ResultPtr> aResults = aFeature->results();\r
- std::list<ResultPtr>::const_iterator aIt;\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {\r
- (*aIt)->setDisplayed(true);\r
- }\r
- aFeature->setDisplayed(true);\r
- }\r
-#ifdef DEBUG_SKETCHER_ENTITIES\r
- QString anInfoStr = anInfo.join(";\t");\r
- qDebug(QString("startSketch: %1, %2").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str());\r
-#endif\r
-\r
- if(myCirclePointFilter.IsNull()) {\r
- myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop());\r
- }\r
-\r
- myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter);\r
-\r
- if (myPlaneFilter.IsNull()) \r
- myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();\r
-\r
- myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);\r
- bool aHasPlane = false;\r
- std::shared_ptr<GeomAPI_Pln> aPln;\r
- aPln = PartSet_Tools::sketchPlane(myCurrentSketch);\r
- myPlaneFilter->setPlane(aPln);\r
-\r
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));\r
- // all displayed objects should be activated in current selection modes according to switched\r
- // plane filter\r
- if (aPln.get())\r
- aConnector->activateModuleSelectionModes();\r
-}\r
-\r
-void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)\r
-{\r
- myIsMouseOverWindow = false;\r
- myIsConstraintsShown[PartSet_Tools::Geometrical] = true;\r
- myIsConstraintsShown[PartSet_Tools::Dimensional] = true;\r
- myIsConstraintsShown[PartSet_Tools::Expressions] = false;\r
-\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());\r
-\r
- DataPtr aData = myCurrentSketch->data();\r
- if (!aData->isValid()) {\r
- XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();\r
- // The sketch was aborted\r
- myCurrentSketch = CompositeFeaturePtr();\r
- // TODO: move this outside of if-else\r
- myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);\r
- myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);\r
-\r
- // Erase all sketcher objects\r
- QObjectPtrList aObjects = aDisplayer->displayedObjects();\r
- foreach (ObjectPtr aObj, aObjects) {\r
- DataPtr aObjData = aObj->data();\r
- if (!aObjData->isValid())\r
- aObj->setDisplayed(false);\r
- }\r
- }\r
- else {\r
- // Hide all sketcher sub-Objects\r
- for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {\r
- FeaturePtr aFeature = myCurrentSketch->subFeature(i);\r
- std::list<ResultPtr> aResults = aFeature->results();\r
- std::list<ResultPtr>::const_iterator aIt;\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {\r
- (*aIt)->setDisplayed(false);\r
- }\r
- aFeature->setDisplayed(false);\r
- }\r
- // Display sketcher result\r
- std::list<ResultPtr> aResults = myCurrentSketch->results();\r
- std::list<ResultPtr>::const_iterator aIt;\r
- Events_Loop* aLoop = Events_Loop::loop();\r
- static Events_ID aDispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);\r
-\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (theOperation);\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {\r
- if (!aFOperation->isDisplayedOnStart(*aIt)) {\r
- (*aIt)->setDisplayed(true);\r
- // this display event is needed because sketch already may have "displayed" state,\r
- // but not displayed while it is still active (issue 613, abort of existing sketch)\r
- ModelAPI_EventCreator::get()->sendUpdated(*aIt, aDispEvent);\r
- }\r
- }\r
- if (!aFOperation->isDisplayedOnStart(myCurrentSketch))\r
- myCurrentSketch->setDisplayed(true);\r
- \r
- myCurrentSketch = CompositeFeaturePtr();\r
-\r
- myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);\r
- myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);\r
-\r
- Events_Loop::loop()->flush(aDispEvent);\r
- }\r
- // restore the module selection modes, which were changed on startSketch\r
- aConnector->activateModuleSelectionModes();\r
-}\r
-\r
-void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)\r
-{\r
- if (canChangeCursor(theOperation) && myIsMouseOverWindow) {\r
- QCursor* aCurrentCursor = QApplication::overrideCursor();\r
- if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {\r
- QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));\r
-#ifdef DEBUG_CURSOR\r
- qDebug("startNestedSketch() : Qt::CrossCursor");\r
-#endif\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)\r
-{\r
- myIsMouseOverViewProcessed = true;\r
- operationMgr()->onValidateOperation();\r
- // when sketch nested operation is stopped the cursor should be restored unconditionally\r
- //if (canChangeCursor(theOperation)) {\r
- QApplication::restoreOverrideCursor();\r
-#ifdef DEBUG_CURSOR\r
- qDebug("stopNestedSketch() : None");\r
-#endif\r
- //}\r
- /// improvement to deselect automatically all eventual selected objects, when\r
- // returning to the neutral point of the Sketcher\r
- workshop()->selector()->clearSelection();\r
-}\r
-\r
-void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)\r
-{\r
- if (isNestedCreateOperation(theOperation, activeSketch())) {\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (theOperation);\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- // it is necessary to check the the feature data validity because\r
- // some kind of features are removed by an operation commit(the macro state of a feature)\r
- if (aFeature.get() && aFeature->data()->isValid()) {\r
- visualizeFeature(aFeature, aFOperation->isEditOperation(), true);\r
- }\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate)\r
-{\r
- if (toActivate)\r
- myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);\r
- else\r
- myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);\r
-}\r
-\r
-bool PartSet_SketcherMgr::operationActivatedByPreselection()\r
-{\r
- bool isOperationStopped = false;\r
- ModuleBase_Operation* anOperation = getCurrentOperation();\r
- if(anOperation && isNestedSketchOperation(anOperation)) {\r
- // Set final definitions if they are necessary\r
- //propertyPanelDefined(aOperation);\r
- /// Commit sketcher operations automatically\r
- /// distance operation are able to show popup editor to modify the distance value\r
- /// after entering the value, the operation should be committed/aborted(by Esc key)\r
- bool aCanCommitOperation = true;\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (anOperation);\r
- if (aFOperation && PartSet_SketcherMgr::isDistanceOperation(aFOperation)) {\r
- bool aValueAccepted = setDistanceValueByPreselection(anOperation, myModule->workshop(),\r
- aCanCommitOperation);\r
- if (!aValueAccepted)\r
- return isOperationStopped;\r
- }\r
-\r
- if (aCanCommitOperation)\r
- isOperationStopped = anOperation->commit();\r
- else {\r
- anOperation->abort();\r
- isOperationStopped = true;\r
- }\r
- }\r
- return isOperationStopped;\r
-}\r
-\r
-bool PartSet_SketcherMgr::canUndo() const\r
-{\r
- return isNestedCreateOperation(getCurrentOperation(), activeSketch());\r
-}\r
-\r
-bool PartSet_SketcherMgr::canRedo() const\r
-{\r
- return isNestedCreateOperation(getCurrentOperation(), activeSketch());\r
-}\r
-\r
-bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const\r
-{\r
- bool aCanErase = true;\r
- // when the sketch operation is active, results of sketch sub-feature can not be hidden\r
- if (myCurrentSketch.get()) {\r
- return !isObjectOfSketch(theObject);\r
- }\r
- return aCanErase;\r
-}\r
-\r
-bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const\r
-{\r
- bool aCanDisplay = true;\r
-\r
- bool aHasActiveSketch = activeSketch().get() != NULL;\r
- if (aHasActiveSketch) {\r
- // 1. the sketch feature should not be displayed during the sketch active operation\r
- // it is hidden by a sketch operation start and shown by a sketch stop, just the sketch \r
- // nested features can be visualized\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);\r
- if (aFeature.get() != NULL && aFeature == activeSketch()) {\r
- aCanDisplay = false;\r
- }\r
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =\r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);\r
- /// some sketch entities should be never shown, e.g. projection feature\r
- if (aSketchFeature.get())\r
- aCanDisplay = aSketchFeature->canBeDisplayed();\r
- }\r
- else { // there are no an active sketch\r
- // 2. sketch sub-features should not be visualized if the sketch operation is not active\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);\r
- if (aFeature.get() != NULL) {\r
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =\r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);\r
- if (aSketchFeature.get()) {\r
- aCanDisplay = false;\r
- }\r
- }\r
- }\r
-\r
- // 3. the method should not filter the objects, which are not related to the current operation.\r
- // The object is filtered just if it is a current operation feature or this feature result\r
- if (aCanDisplay) {\r
- bool isObjectFound = false;\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- if (aFeature.get()) {\r
- std::list<ResultPtr> aResults = aFeature->results();\r
- if (theObject == aFeature)\r
- isObjectFound = true;\r
- else {\r
- std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLast = aResults.end();\r
- for (; anIt != aLast && !isObjectFound; anIt++) {\r
- isObjectFound = *anIt == theObject;\r
- }\r
- }\r
- }\r
- }\r
- if (isObjectFound) {\r
- // 4. For created nested feature operation do not display the created feature if\r
- // the mouse curstor leaves the OCC window.\r
- // The correction cases, which ignores this condition:\r
- // a. the property panel values modification\r
- // b. the popup menu activated\r
- // c. widget editor control\r
- #ifndef DEBUG_DO_NOT_BY_ENTER\r
- if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) {\r
- ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();\r
- ModuleBase_WidgetEditor* anEditorWdg = anActiveWidget ? dynamic_cast<ModuleBase_WidgetEditor*>(anActiveWidget) : 0;\r
- // the active widget editor should not influence here. The presentation should be visible always\r
- // when this widget is active.\r
- if (!anEditorWdg && !myIsPopupMenuActive) {\r
- // during a nested create operation, the feature is redisplayed only if the mouse over view\r
- // of there was a value modified in the property panel after the mouse left the view\r
- aCanDisplay = canDisplayCurrentCreatedFeature();\r
- }\r
- }\r
- #endif\r
- }\r
- }\r
-\r
- // checks the sketcher constraints visibility according to active sketch check box states\r
- if (aCanDisplay) {\r
- bool aProcessed = false;\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);\r
- if (aFeature.get()) {\r
- bool aConstraintDisplayed = canDisplayConstraint(aFeature, PartSet_Tools::Any, aProcessed);\r
- if (aProcessed)\r
- aCanDisplay = aConstraintDisplayed;\r
- }\r
- }\r
-\r
- return aCanDisplay;\r
-}\r
-\r
-bool PartSet_SketcherMgr::canDisplayConstraint(const FeaturePtr& theFeature,\r
- const PartSet_Tools::ConstraintVisibleState& theState,\r
- bool& isProcessed) const\r
-{\r
- bool aSwitchedOn = true;\r
-\r
- const QStringList& aConstrIds = constraintsIdList();\r
-\r
- std::string aKind = theFeature->getKind();\r
- if (aConstrIds.contains(QString(aKind.c_str()))) {\r
- bool isTypedConstraint = false;\r
-\r
- switch (theState) {\r
- case PartSet_Tools::Dimensional: {\r
- bool isDistance = isDistanceKind(aKind);\r
- if (isDistance) {\r
- isProcessed = true;\r
- aSwitchedOn = myIsConstraintsShown[theState];\r
- }\r
- }\r
- break;\r
- case PartSet_Tools::Geometrical: {\r
- bool isGeometrical = !isDistanceKind(aKind);\r
- if (isGeometrical) {\r
- isProcessed = true;\r
- aSwitchedOn = myIsConstraintsShown[theState];\r
- }\r
- }\r
- break;\r
- case PartSet_Tools::Any: {\r
- isProcessed = true;\r
- bool isDistance = isDistanceKind(aKind);\r
- if (isDistance)\r
- aSwitchedOn = myIsConstraintsShown[PartSet_Tools::Dimensional];\r
- else\r
- aSwitchedOn = myIsConstraintsShown[PartSet_Tools::Geometrical];\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- return aSwitchedOn;\r
-}\r
-\r
-/*void PartSet_SketcherMgr::processHiddenObject(const std::list<ObjectPtr>& theObjects)\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation && myCurrentSketch.get()) {\r
- // find results of the current operation\r
- // these results should not be proposed to be deleted\r
- FeaturePtr anOperationFeature = aFOperation->feature();\r
- std::list<ResultPtr> anOperationResultList = anOperationFeature->results();\r
- std::set<ResultPtr> anOperationResults;\r
- std::list<ResultPtr>::const_iterator aRIt = anOperationResultList.begin(),\r
- aRLast = anOperationResultList.end();\r
- for (; aRIt != aRLast; aRIt++)\r
- anOperationResults.insert(*aRIt);\r
-\r
- std::set<FeaturePtr> anObjectsToBeDeleted;\r
- QStringList anObjectsToBeDeletedNames;\r
- std::list<ObjectPtr>::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();\r
- for (; anIt != aLast; anIt++) {\r
- ObjectPtr anObject = *anIt;\r
- bool aCanErase = true;\r
- // when the sketch operation is active, results of sketch sub-feature can not be hidden\r
- ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);\r
- // the result is found between current feature results\r
- if (anOperationResults.find(aResult) != anOperationResults.end())\r
- continue;\r
-\r
- if (aResult.get()) {\r
- // Display sketcher objects\r
- for (int i = 0; i < myCurrentSketch->numberOfSubs() && aCanErase; i++) {\r
- FeaturePtr aFeature = myCurrentSketch->subFeature(i);\r
- std::list<ResultPtr> aResults = aFeature->results();\r
- std::list<ResultPtr>::const_iterator anIt;\r
- for (anIt = aResults.begin(); anIt != aResults.end() && aCanErase; ++anIt) {\r
- aCanErase = *anIt != aResult;\r
- }\r
- }\r
- }\r
- if (!aCanErase) {\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);\r
- if (aFeature.get() && anObjectsToBeDeleted.find(aFeature) == anObjectsToBeDeleted.end()) {\r
- anObjectsToBeDeleted.insert(aFeature);\r
- anObjectsToBeDeletedNames.append(aFeature->name().c_str());\r
- }\r
- }\r
- }\r
- if (!anObjectsToBeDeleted.empty()) {\r
- QString aFeatureNames = anObjectsToBeDeletedNames.join(", ");\r
- QString aMessage = tr("The following features have incorrect presentation and \\r
-will be hidden: %1. Would you like to delete them?")\r
- .arg(aFeatureNames);\r
- int anAnswer = QMessageBox::question(qApp->activeWindow(), tr("Features hide"),\r
- aMessage, QMessageBox::Ok | QMessageBox::Cancel,\r
- QMessageBox::Cancel);\r
- if (anAnswer == QMessageBox::Ok) {\r
- QObjectPtrList anObjects;\r
- std::set<FeaturePtr>::const_iterator anIt = anObjectsToBeDeleted.begin(),\r
- aLast = anObjectsToBeDeleted.end();\r
- for (; anIt != aLast; anIt++)\r
- anObjects.append(*anIt);\r
- SessionPtr aMgr = ModelAPI_Session::get();\r
- DocumentPtr aDoc = aMgr->activeDocument();\r
- bool aIsOp = aMgr->isOperation();\r
- if (!aIsOp)\r
- aMgr->startOperation();\r
- workshop()->deleteFeatures(anObjects);\r
- //static Events_ID aDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);\r
- //static Events_ID aRedispEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);\r
- //Events_Loop::loop()->flush(aDeletedEvent);\r
- //Events_Loop::loop()->flush(aRedispEvent);\r
-\r
- if (!aIsOp)\r
- aMgr->finishOperation();\r
- }\r
- }\r
- }\r
-}*/\r
-\r
-bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const\r
-{\r
- bool aCanDisplay = myIsMouseOverWindow;\r
- if (!aCanDisplay) {\r
- ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();\r
- if (anActiveWidget)\r
- aCanDisplay = anActiveWidget->getValueState() == ModuleBase_ModelWidget::Stored;\r
- }\r
- return aCanDisplay;\r
-}\r
-\r
-bool PartSet_SketcherMgr::canChangeCursor(ModuleBase_Operation* theOperation) const\r
-{\r
- return isNestedCreateOperation(theOperation, activeSketch()) ||\r
- myModule->sketchReentranceMgr()->isInternalEditActive();\r
-}\r
-\r
-const QMap<PartSet_Tools::ConstraintVisibleState, bool>& PartSet_SketcherMgr::showConstraintStates()\r
-{\r
- return myIsConstraintsShown;\r
-}\r
-\r
-bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const\r
-{\r
- bool isFoundObject = false;\r
-\r
- FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject);\r
- if (anObjectFeature.get()) {\r
- int aSize = myCurrentSketch->numberOfSubs();\r
- for (int i = 0; i < myCurrentSketch->numberOfSubs() && !isFoundObject; i++) {\r
- FeaturePtr aCurrentFeature = myCurrentSketch->subFeature(i);\r
- isFoundObject = myCurrentSketch->subFeature(i) == anObjectFeature;\r
- }\r
- }\r
- return isFoundObject;\r
-}\r
-\r
-void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePln)\r
-{\r
- if (myPlaneFilter.IsNull()) \r
- myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();\r
-\r
- myPlaneFilter->setPlane(thePln);\r
-}\r
-\r
-bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation,\r
- ModuleBase_IWorkshop* theWorkshop,\r
- bool& theCanCommitOperation)\r
-{\r
- bool isValueAccepted = false;\r
- theCanCommitOperation = false;\r
-\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (theOperation);\r
- FeaturePtr aFeature = aFOperation->feature();\r
- // editor is shown only if all attribute references are filled by preseletion\r
- bool anAllRefAttrInitialized = true;\r
-\r
- std::list<AttributePtr> aRefAttrs = aFeature->data()->attributes(\r
- ModelAPI_AttributeRefAttr::typeId());\r
- std::list<AttributePtr>::const_iterator anIt = aRefAttrs.begin(), aLast = aRefAttrs.end();\r
- for (; anIt != aLast && anAllRefAttrInitialized; anIt++) {\r
- anAllRefAttrInitialized = (*anIt)->isInitialized();\r
- }\r
- if (anAllRefAttrInitialized) {\r
- // Activate dimension value editing on double click\r
- ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();\r
- QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();\r
- // Find corresponded widget to activate value editing\r
- foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {\r
- if (aWgt->attributeID() == "ConstraintValue") {\r
- // the featue should be displayed in order to find the AIS text position,\r
- // the place where the editor will be shown\r
- aFeature->setDisplayed(true);\r
- /// the execute is necessary to perform in the feature compute for flyout position\r
- aFeature->execute();\r
-\r
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));\r
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));\r
-\r
- PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);\r
- if (anEditor) {\r
- int aX = 0, anY = 0;\r
-\r
- XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(theWorkshop);\r
- XGUI_Displayer* aDisplayer = aWorkshop->displayer();\r
- AISObjectPtr anAIS = aDisplayer->getAISObject(aFeature);\r
- Handle(AIS_InteractiveObject) anAISIO;\r
- if (anAIS.get() != NULL) {\r
- anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();\r
- }\r
- if (anAIS.get() != NULL) {\r
- Handle(AIS_InteractiveObject) anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();\r
-\r
- if (!anAISIO.IsNull()) {\r
- Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAISIO);\r
- if (!aDim.IsNull()) {\r
- gp_Pnt aPosition = aDim->GetTextPosition();\r
-\r
- ModuleBase_IViewer* aViewer = aWorkshop->viewer();\r
- Handle(V3d_View) aView = aViewer->activeView();\r
- int aCX, aCY;\r
- aView->Convert(aPosition.X(), aPosition.Y(), aPosition.Z(), aCX, aCY);\r
-\r
- QWidget* aViewPort = aViewer->activeViewPort();\r
- QPoint aGlPoint = aViewPort->mapToGlobal(QPoint(aCX, aCY));\r
- aX = aGlPoint.x();\r
- anY = aGlPoint.y();\r
- }\r
- }\r
- anEditor->setCursorPosition(aX, anY);\r
- isValueAccepted = anEditor->showPopupEditor(false);\r
- theCanCommitOperation = true;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- return isValueAccepted;\r
-}\r
-\r
-void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,\r
- const FeaturePtr& theSketch,\r
- ModuleBase_IWorkshop* theWorkshop,\r
- const FeatureToSelectionMap& theSelection,\r
- SelectMgr_IndexedMapOfOwner& theOwnersToSelect)\r
-{\r
- if (theFeature.get() == NULL)\r
- return;\r
-\r
- FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature);\r
- std::set<AttributePtr> aSelectedAttributes = anIt.value().first;\r
- std::set<ResultPtr> aSelectedResults = anIt.value().second;\r
-\r
- ModuleBase_IViewer* aViewer = theWorkshop->viewer();\r
-\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);\r
- XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();\r
-\r
- // 1. found the feature's owners. Check the AIS objects of the constructions\r
- AISObjectPtr aAISObj = aDisplayer->getAISObject(theFeature);\r
- if (aAISObj.get() != NULL && aSelectedAttributes.empty() && aSelectedResults.empty()) {\r
- Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();\r
-\r
- SelectMgr_IndexedMapOfOwner aSelectedOwners;\r
- aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners);\r
- for (Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++) {\r
- Handle(SelectMgr_EntityOwner) anOwner = aSelectedOwners(i);\r
- if (!anOwner.IsNull())\r
- theOwnersToSelect.Add(anOwner);\r
- }\r
- }\r
-\r
- // 2. found the feature results's owners\r
- std::list<ResultPtr> aResults = theFeature->results();\r
- std::list<ResultPtr>::const_iterator aIt;\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)\r
- {\r
- ResultPtr aResult = *aIt;\r
- AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult);\r
- if (aAISObj.get() == NULL)\r
- continue; \r
- Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();\r
-\r
- SelectMgr_IndexedMapOfOwner aSelectedOwners; \r
- aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners);\r
- for ( Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++ ) {\r
- Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(aSelectedOwners(i));\r
- if ( anOwner.IsNull() || !anOwner->HasShape() )\r
- continue;\r
- const TopoDS_Shape& aShape = anOwner->Shape();\r
- TopAbs_ShapeEnum aShapeType = aShape.ShapeType();\r
- if (aShapeType == TopAbs_VERTEX) {\r
- AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch);\r
- if (aPntAttr.get() != NULL &&\r
- aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) {\r
- theOwnersToSelect.Add(anOwner);\r
- }\r
- }\r
- else if (aShapeType == TopAbs_EDGE) {\r
- bool aFound = aSelectedResults.find(aResult) != aSelectedResults.end();\r
- if (aSelectedResults.find(aResult) != aSelectedResults.end() &&\r
- theOwnersToSelect.FindIndex(anOwner) <= 0)\r
- theOwnersToSelect.Add(anOwner);\r
- }\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect)\r
-{\r
- if (isToConnect) {\r
- connect(theWidget, SIGNAL(beforeValuesChanged()),\r
- this, SLOT(onBeforeValuesChangedInPropertyPanel()));\r
- connect(theWidget, SIGNAL(afterValuesChanged()),\r
- this, SLOT(onAfterValuesChangedInPropertyPanel()));\r
- }\r
- else {\r
- disconnect(theWidget, SIGNAL(beforeValuesChanged()),\r
- this, SLOT(onBeforeValuesChangedInPropertyPanel()));\r
- disconnect(theWidget, SIGNAL(afterValuesChanged()),\r
- this, SLOT(onAfterValuesChangedInPropertyPanel()));\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState)\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation) {\r
- if (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||\r
- isNestedSketchOperation(aFOperation) &&\r
- thePreviousState == ModuleBase_ModelWidget::ModifiedInPP) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));\r
- }\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject)\r
-{\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (getCurrentOperation());\r
- if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||\r
- isNestedSketchOperation(aFOperation)))\r
- SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]);\r
-\r
- // update entities selection priorities\r
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);\r
- if (aFeature.get() && PartSet_SketcherMgr::isEntity(aFeature->getKind())) {\r
- // update priority for feature\r
- updateSelectionPriority(aFeature, aFeature);\r
- // update priority for results of the feature\r
- std::list<ResultPtr> aResults = aFeature->results();\r
- std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLastIt = aResults.end();\r
- for (; anIt != aLastIt; anIt++)\r
- updateSelectionPriority(*anIt, aFeature);\r
- }\r
-}\r
-\r
-ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const\r
-{\r
- return myModule->workshop()->currentOperation();\r
-}\r
-\r
-//**************************************************************\r
-ModuleBase_ModelWidget* PartSet_SketcherMgr::getActiveWidget() const\r
-{\r
- ModuleBase_ModelWidget* aWidget = 0;\r
- ModuleBase_Operation* anOperation = getCurrentOperation();\r
- if (anOperation) {\r
- ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();\r
- if (aPanel)\r
- aWidget = aPanel->activeWidget();\r
- }\r
- return aWidget;\r
-}\r
-\r
-void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature,\r
- const bool isEditOperation,\r
- const bool isToDisplay,\r
- const bool isFlushRedisplay)\r
-{\r
- #ifdef DEBUG_DO_NOT_BY_ENTER\r
- return;\r
- #endif\r
-\r
- if (isEditOperation || !theFeature.get())\r
- return;\r
-\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
-\r
- // 1. change visibility of the object itself, here the presentable object is processed,\r
- // e.g. constraints features\r
- //FeaturePtr aFeature = aFOperation->feature();\r
- std::list<ResultPtr> aResults = theFeature->results();\r
- if (isToDisplay)\r
- theFeature->setDisplayed(true);\r
- else\r
- theFeature->setDisplayed(false);\r
-\r
- // change visibility of the object results, e.g. non-constraint features\r
- std::list<ResultPtr>::const_iterator aIt;\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {\r
- if (isToDisplay) {\r
- (*aIt)->setDisplayed(true);\r
- }\r
- else {\r
- (*aIt)->setDisplayed(false);\r
- }\r
- }\r
- if (isFlushRedisplay)\r
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));\r
-}\r
-\r
-void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)\r
-{\r
- if (!myCurrentSketch.get())\r
- return;\r
-\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- ModuleBase_ISelection* aSelect = aWorkshop->selection();\r
- QList<ModuleBase_ViewerPrsPtr> aStoredPrs = aSelect->getHighlighted();\r
-\r
- QList<FeaturePtr> aFeatureList;\r
- if (!theHighlightedOnly) {\r
- QList<ModuleBase_ViewerPrsPtr> aSelected = aSelect->getSelected(\r
- ModuleBase_ISelection::AllControls);\r
- aStoredPrs.append(aSelected);\r
- }\r
-\r
- // 1. it is necessary to save current selection in order to restore it after the features moving\r
- myCurrentSelection.clear();\r
-\r
- QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = aStoredPrs.begin(), aLast = aStoredPrs.end();\r
-\r
- CompositeFeaturePtr aSketch = activeSketch();\r
- for (; anIt != aLast; anIt++) {\r
- ModuleBase_ViewerPrsPtr aPrs = *anIt;\r
- ObjectPtr anObject = aPrs->object();\r
- if (!anObject.get())\r
- continue;\r
-\r
- ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);\r
- FeaturePtr aFeature;\r
- if (aResult.get())\r
- aFeature = ModelAPI_Feature::feature(aResult);\r
- else\r
- aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);\r
-\r
-\r
- std::set<AttributePtr> aSelectedAttributes;\r
- std::set<ResultPtr> aSelectedResults;\r
- if (myCurrentSelection.find(aFeature) != myCurrentSelection.end()) {\r
- std::pair<std::set<AttributePtr>, std::set<ResultPtr> > aPair = myCurrentSelection.find(aFeature).value();\r
- aSelectedAttributes = aPair.first;\r
- aSelectedResults = aPair.second;\r
- }\r
-\r
- Handle(SelectMgr_EntityOwner) anOwner = aPrs->owner();\r
- if (aResult.get()) {\r
- getAttributesOrResults(anOwner, aFeature, aSketch, aResult,\r
- aSelectedAttributes, aSelectedResults);\r
- }\r
- else {\r
- std::list<ResultPtr> aResults = aFeature->results();\r
- std::list<ResultPtr>::const_iterator aIt;\r
- for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {\r
- ResultPtr aResult = *aIt;\r
- getAttributesOrResults(anOwner, aFeature, aSketch, aResult,\r
- aSelectedAttributes, aSelectedResults);\r
- }\r
- }\r
- myCurrentSelection[aFeature] = std::make_pair(aSelectedAttributes, aSelectedResults);\r
- }\r
- //qDebug(QString(" storeSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());\r
-}\r
-\r
-void PartSet_SketcherMgr::restoreSelection()\r
-{\r
- if (!myCurrentSketch.get())\r
- return;\r
-\r
- //qDebug(QString("restoreSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
- FeatureToSelectionMap::const_iterator aSIt = myCurrentSelection.begin(),\r
- aSLast = myCurrentSelection.end();\r
- SelectMgr_IndexedMapOfOwner anOwnersToSelect;\r
- for (; aSIt != aSLast; aSIt++) {\r
- anOwnersToSelect.Clear();\r
- getSelectionOwners(aSIt.key(), myCurrentSketch, aWorkshop, myCurrentSelection,\r
- anOwnersToSelect);\r
- aConnector->workshop()->selector()->setSelectedOwners(anOwnersToSelect, false);\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::onShowConstraintsToggle(int theType, bool theState)\r
-{\r
- PartSet_Tools::ConstraintVisibleState aType = (PartSet_Tools::ConstraintVisibleState)theType;\r
-\r
- updateBySketchParameters(aType, theState);\r
-}\r
-\r
-void PartSet_SketcherMgr::updateBySketchParameters(\r
- const PartSet_Tools::ConstraintVisibleState& theType,\r
- bool theState)\r
-{\r
- if (myCurrentSketch.get() == NULL)\r
- return;\r
-\r
- bool aPrevState = myIsConstraintsShown[theType];\r
- myIsConstraintsShown[theType] = theState;\r
-\r
- switch (theType) {\r
- case PartSet_Tools::Geometrical:\r
- case PartSet_Tools::Dimensional: {\r
- if (aPrevState != theState) {\r
- ModuleBase_IWorkshop* aWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);\r
- for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {\r
- FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);\r
- bool aProcessed = false;\r
- bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, theType, aProcessed);\r
- if (aProcessed)\r
- aSubFeature->setDisplayed(aConstraintDisplayed);\r
- }\r
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));\r
- }\r
- }\r
- break;\r
- case PartSet_Tools::Expressions: {\r
- if (aPrevState != theState) {\r
- /// call all sketch features redisplay, the expression state will be corrected in customize\r
- /// of distance presentation\r
- Events_ID anEventId = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);\r
- PartSet_Tools::sendSubFeaturesEvent(myCurrentSketch, anEventId);\r
- }\r
- }\r
- break;\r
- }\r
-}\r
-\r
-void PartSet_SketcherMgr::updateSelectionPriority(ObjectPtr theObject,\r
- FeaturePtr theFeature)\r
-{\r
- if (!theObject.get() || !theFeature.get())\r
- return;\r
-\r
- AISObjectPtr anAIS = workshop()->displayer()->getAISObject(theObject);\r
- Handle(AIS_InteractiveObject) anAISIO;\r
- if (anAIS.get() != NULL) {\r
- anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();\r
- }\r
-\r
- if (!anAISIO.IsNull()) { // the presentation for the object is visualized\r
- int anAdditionalPriority = 0;\r
- // current feature\r
- std::shared_ptr<SketchPlugin_Feature> aSPFeature =\r
- std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);\r
- if (aSPFeature.get() != NULL) {\r
- // 1. Vertices\r
- // 2. Simple segments\r
- // 3. External objects (violet color)\r
- // 4. Auxiliary segments (dotted)\r
- // StdSelect_BRepSelectionTool::Load uses priority calculating:\r
- // Standard_Integer aPriority = (thePriority == -1) ? GetStandardPriority (theShape, theType) : thePriority;\r
- // Priority of Vertex is 8, edge(segment) is 7.\r
- // It might be not corrected as provides the condition above.\r
- bool isExternal = aSPFeature->isExternal();\r
- bool isAuxiliary = PartSet_Tools::isAuxiliarySketchEntity(aSPFeature);\r
- // current feature\r
- if (!isExternal && !isAuxiliary)\r
- anAdditionalPriority = 30;\r
- // external feature\r
- if (isExternal)\r
- anAdditionalPriority = 20;\r
- // auxiliary feature\r
- if (isAuxiliary) {\r
- anAdditionalPriority = 10; /// auxiliary objects should have less priority that\r
- // edges/vertices of local selection on not-sketch objects\r
- }\r
- Handle(ModuleBase_ResultPrs) aResult = Handle(ModuleBase_ResultPrs)::DownCast(anAISIO);\r
- if (!aResult.IsNull()) {\r
- aResult->setAdditionalSelectionPriority(anAdditionalPriority);\r
- }\r
- }\r
- }\r
-}\r
-\r
-XGUI_Workshop* PartSet_SketcherMgr::workshop() const\r
-{\r
- ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();\r
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);\r
- return aConnector->workshop();\r
-}\r
-\r
-XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const\r
-{\r
- return workshop()->operationMgr();\r
-}\r
-\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: PartSet_SketcherMgr.cpp
+// Created: 19 Dec 2014
+// Author: Vitaly SMETANNIKOV
+
+#include "PartSet_SketcherMgr.h"
+#include "PartSet_SketcherReetntrantMgr.h"
+#include "PartSet_Module.h"
+#include "PartSet_MouseProcessor.h"
+#include "PartSet_Tools.h"
+#include "PartSet_WidgetSketchLabel.h"
+#include "PartSet_WidgetEditor.h"
+#include "PartSet_ResultSketchPrs.h"
+
+#include <XGUI_ModuleConnector.h>
+#include <XGUI_Displayer.h>
+#include <XGUI_Workshop.h>
+#include <XGUI_ContextMenuMgr.h>
+#include <XGUI_Selection.h>
+#include <XGUI_SelectionMgr.h>
+#include <XGUI_ModuleConnector.h>
+#include <XGUI_PropertyPanel.h>
+#include <XGUI_ViewerProxy.h>
+#include <XGUI_OperationMgr.h>
+#include <XGUI_ErrorMgr.h>
+#include <XGUI_Tools.h>
+
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ISelection.h>
+#include <ModuleBase_IViewer.h>
+#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_IViewWindow.h>
+#include <ModuleBase_ModelWidget.h>
+#include <ModuleBase_Operation.h>
+#include <ModuleBase_OperationFeature.h>
+#include <ModuleBase_Operation.h>
+#include <ModuleBase_WidgetEditor.h>
+#include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_ResultPrs.h>
+
+#include <GeomDataAPI_Point2D.h>
+
+#include <Events_Loop.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+#include <SketchPlugin_Point.h>
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Circle.h>
+#include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintParallel.h>
+#include <SketchPlugin_ConstraintPerpendicular.h>
+#include <SketchPlugin_ConstraintRadius.h>
+#include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_ConstraintHorizontal.h>
+#include <SketchPlugin_ConstraintVertical.h>
+#include <SketchPlugin_ConstraintEqual.h>
+#include <SketchPlugin_ConstraintTangent.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintFillet.h>
+#include <SketchPlugin_ConstraintMirror.h>
+#include <SketchPlugin_ConstraintAngle.h>
+#include <SketchPlugin_ConstraintCollinear.h>
+#include <SketchPlugin_ConstraintMiddle.h>
+#include <SketchPlugin_MultiRotation.h>
+#include <SketchPlugin_MultiTranslation.h>
+#include <SketchPlugin_IntersectionPoint.h>
+
+#include <SketcherPrs_Tools.h>
+
+#include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <StdSelect_BRepOwner.hxx>
+
+//#include <AIS_DimensionSelectionMode.hxx>
+#include <AIS_Shape.hxx>
+#include <AIS_Dimension.hxx>
+
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_AttributeString.h>
+
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_Tools.h>
+
+#include <QMouseEvent>
+#include <QApplication>
+#include <QCursor>
+#include <QMessageBox>
+#include <QMainWindow>
+
+//#define DEBUG_DO_NOT_BY_ENTER
+//#define DEBUG_SKETCHER_ENTITIES
+//#define DEBUG_SKETCH_ENTITIES_ON_MOVE
+
+//#define DEBUG_CURSOR
+
+/// Fills attribute and result lists by the selected owner. In case if the attribute is found,
+/// by the owner shape, it is put to the list. Otherwise if type of owner shape is edge, put the function
+/// result as is to the list of results.
+/// \param theOwner a viewer selected owner
+/// \param theFeature a feature, where the attribute is searched
+/// \param theSketch a current sketch
+/// \param theSelectedAttribute an output list of attributes
+/// \param theSelectedResults an output list of edge results
+void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,
+ const FeaturePtr& theFeature, const FeaturePtr& theSketch,
+ const ResultPtr& theResult,
+ std::set<AttributePtr>& aSelectedAttributes,
+ std::set<ResultPtr>& aSelectedResults)
+{
+ Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner);
+ if (aBRepOwner.IsNull())
+ return;
+ Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(
+ aBRepOwner->Selectable());
+ if (aBRepOwner->HasShape()) {
+ const TopoDS_Shape& aShape = aBRepOwner->Shape();
+ TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+ if (aShapeType == TopAbs_VERTEX) {
+ AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature,
+ aShape, theSketch);
+ if (aPntAttr.get() != NULL)
+ aSelectedAttributes.insert(aPntAttr);
+ }
+ else if (aShapeType == TopAbs_EDGE &&
+ aSelectedResults.find(theResult) == aSelectedResults.end()) {
+ aSelectedResults.insert(theResult);
+ }
+ }
+}
+
+PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
+ : QObject(theModule), myModule(theModule), myIsDragging(false), myDragDone(false),
+ myIsMouseOverWindow(false),
+ myIsMouseOverViewProcessed(true), myPreviousUpdateViewerEnabled(true),
+ myIsPopupMenuActive(false)
+{
+ ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
+ ModuleBase_IViewer* aViewer = anIWorkshop->viewer();
+
+ myPreviousDrawModeEnabled = true;//aViewer->isSelectionEnabled();
+
+ connect(aViewer, SIGNAL(mousePress(ModuleBase_IViewWindow*, QMouseEvent*)),
+ this, SLOT(onMousePressed(ModuleBase_IViewWindow*, QMouseEvent*)));
+
+ connect(aViewer, SIGNAL(mouseRelease(ModuleBase_IViewWindow*, QMouseEvent*)),
+ this, SLOT(onMouseReleased(ModuleBase_IViewWindow*, QMouseEvent*)));
+
+ connect(aViewer, SIGNAL(mouseMove(ModuleBase_IViewWindow*, QMouseEvent*)),
+ this, SLOT(onMouseMoved(ModuleBase_IViewWindow*, QMouseEvent*)));
+
+ connect(aViewer, SIGNAL(mouseDoubleClick(ModuleBase_IViewWindow*, QMouseEvent*)),
+ this, SLOT(onMouseDoubleClick(ModuleBase_IViewWindow*, QMouseEvent*)));
+
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
+ XGUI_Workshop* aWorkshop = aConnector->workshop();
+ connect(aWorkshop, SIGNAL(applicationStarted()), this, SLOT(onApplicationStarted()));
+
+ myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
+ myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
+ myIsConstraintsShown[PartSet_Tools::Expressions] = false;
+}
+
+PartSet_SketcherMgr::~PartSet_SketcherMgr()
+{
+ if (!myPlaneFilter.IsNull())
+ myPlaneFilter.Nullify();
+}
+
+void PartSet_SketcherMgr::onEnterViewPort()
+{
+ // 1. if the mouse over window, update the next flag. Do not perform update visibility of
+ // created feature because it should be done in onMouseMove(). Some widgets watch
+ // the mouse move and use the cursor position to update own values. If the presentaion is
+ // redisplayed before this update, the feature presentation jumps from reset value to current.
+ myIsMouseOverWindow = true;
+
+ #ifdef DEBUG_DO_NOT_BY_ENTER
+ return;
+ #endif
+
+ if (canChangeCursor(getCurrentOperation())) {
+ QCursor* aCurrentCursor = QApplication::overrideCursor();
+ if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
+ QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
+#ifdef DEBUG_CURSOR
+ qDebug("onEnterViewPort() : Qt::CrossCursor");
+#endif
+ }
+ }
+
+ if (!isNestedCreateOperation(getCurrentOperation(), activeSketch()))
+ return;
+
+ operationMgr()->onValidateOperation();
+
+ // we need change displayed state of the current operation feature
+ // if the feature is presentable, e.g. distance construction. It has no results, so workshop does
+ // not accept a signal about the result created. Nothing is shown until mouse is moved out/in view
+ // port. If the isDisplayed flag is true, the presentable feature is displayed as soon as the
+ // presentation becomes valid and redisplay happens
+ //ModuleBase_Operation* aOperation = getCurrentOperation();
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ if (aFeature.get() && aFeature->data()->isValid()) {
+ visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature), false);
+ }
+ }
+}
+
+void PartSet_SketcherMgr::onLeaveViewPort()
+{
+ myIsMouseOverViewProcessed = false;
+ myIsMouseOverWindow = false;
+
+ #ifdef DEBUG_DO_NOT_BY_ENTER
+ return;
+ #endif
+
+ if (canChangeCursor(getCurrentOperation())) {
+ QApplication::restoreOverrideCursor();
+#ifdef DEBUG_CURSOR
+ qDebug("onLeaveViewPort() : None");
+#endif
+ }
+
+ if (!isNestedCreateOperation(getCurrentOperation(), activeSketch()))
+ return;
+
+ // the method should be performed if the popup menu is called,
+ // the reset of the current widget should not happen
+ if (myIsPopupMenuActive)
+ return;
+
+ // it is important to validate operation here only if sketch entity create operation is active
+ // because at this operation we reacts to the mouse leave/enter view port
+ operationMgr()->onValidateOperation();
+
+ // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+ XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+ // disable the viewer update in order to avoid visualization of redisplayed feature in viewer
+ // obtained after reset value
+ bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false);
+ ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+ if (anActiveWidget)
+ anActiveWidget->reset();
+
+ // hides the presentation of the current operation feature
+ // the feature is to be erased here, but it is correct to call canDisplayObject because
+ // there can be additional check (e.g. editor widget in distance constraint)
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
+ }
+ // we should update viewer after the presentation are hidden in the viewer
+ // otherwise the reset presentation(line) appears in the viewer(by quick move from viewer to PP)
+ aDisplayer->enableUpdateViewer(isEnableUpdateViewer);
+}
+
+void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
+{
+ if (!isNestedEditOperation(getCurrentOperation(), myModule->sketchMgr()->activeSketch()) ||
+ myModule->sketchReentranceMgr()->isInternalEditActive())
+ return;
+ // it is necessary to save current selection in order to restore it after the values are modifed
+ storeSelection();
+
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+ XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+ myPreviousUpdateViewerEnabled = aDisplayer->enableUpdateViewer(false);
+}
+
+void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
+{
+ if (!isNestedEditOperation(getCurrentOperation(), myModule->sketchMgr()->activeSketch()) ||
+ myModule->sketchReentranceMgr()->isInternalEditActive()) {
+ myModule->sketchReentranceMgr()->updateInternalEditActiveState();
+ return;
+ }
+ // it is necessary to restore current selection in order to restore it after the values are modified
+ restoreSelection();
+ myCurrentSelection.clear();
+
+ // 3. the flag to disable the update viewer should be set in order to avoid blinking in the
+ // viewer happens by deselect/select the modified objects. The flag should be restored after
+ // the selection processing. The update viewer should be also called.
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+ XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+ aDisplayer->enableUpdateViewer(myPreviousUpdateViewerEnabled);
+ aDisplayer->updateViewer();
+
+
+}
+
+void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
+{
+ if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent))
+ return;
+
+ //get2dPoint(theWnd, theEvent, myClickedPoint);
+
+ if (!(theEvent->buttons() & Qt::LeftButton))
+ return;
+
+ // Clear dragging mode
+ myIsDragging = false;
+
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ ModuleBase_IViewer* aViewer = aWorkshop->viewer();
+ if (!aViewer->canDragByMouse())
+ return;
+
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (!aFOperation)
+ return;
+
+ if (aFOperation->isEditOperation()) {
+ // If the current widget is a selector, do nothing, it processes the mouse press
+ ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+ if(anActiveWidget && anActiveWidget->isViewerSelector()) {
+ return;
+ }
+ }
+
+ // Use only for sketch operations
+ if (myCurrentSketch) {
+ if (!PartSet_Tools::sketchPlane(myCurrentSketch))
+ return;
+
+ bool isSketcher = isSketchOperation(aFOperation);
+ bool isSketchOpe = isNestedSketchOperation(aFOperation);
+
+ // Avoid non-sketch operations
+ if ((!isSketchOpe) && (!isSketcher))
+ return;
+
+ bool isEditing = aFOperation->isEditOperation();
+
+ // Ignore creation sketch operation
+ if ((!isSketcher) && (!isEditing))
+ return;
+
+ Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+ // Remember highlighted objects for editing
+ ModuleBase_ISelection* aSelect = aWorkshop->selection();
+
+ bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
+ storeSelection(!aHasShift);
+
+ if (myCurrentSelection.empty()) {
+ if (isSketchOpe && (!isSketcher))
+ // commit previous operation
+ if (!aFOperation->commit())
+ aFOperation->abort();
+ return;
+ }
+ // Init flyout point for radius rotation
+ FeaturePtr aFeature = myCurrentSelection.begin().key();
+
+ get2dPoint(theWnd, theEvent, myCurrentPoint);
+ if (isSketcher) {
+ myIsDragging = true;
+ myDragDone = false;
+
+ myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
+ // selection should be restored before edit operation start to process the
+ // selected entities, e.g. selection of point(attribute on a line) should edit the point
+ restoreSelection();
+ launchEditing();
+ if (aFeature.get() != NULL) {
+ std::shared_ptr<SketchPlugin_Feature> aSPFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ if (aSPFeature.get() &&
+ (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() ||
+ aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) {
+ DataPtr aData = aSPFeature->data();
+ AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());
+ std::shared_ptr<GeomDataAPI_Point2D> aFPAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aAttr);
+ aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY);
+ }
+ }
+ } else if (isSketchOpe && isEditing) {
+ // If selected another object commit current result
+ aFOperation->commit();
+
+ myIsDragging = true;
+ myDragDone = false;
+
+ myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
+ // selection should be restored before edit operation start to process the
+ // selected entities, e.g. selection of point(attribute on a line) should edit the point
+ restoreSelection();
+ launchEditing();
+ if (aFeature.get() != NULL) {
+ std::shared_ptr<SketchPlugin_Feature> aSPFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ if (aSPFeature.get() &&
+ (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() ||
+ aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) {
+ DataPtr aData = aSPFeature->data();
+ AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());
+ std::shared_ptr<GeomDataAPI_Point2D> aFPAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aAttr);
+ aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY);
+ }
+ }
+ restoreSelection();
+ }
+ }
+}
+
+void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
+{
+ if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent))
+ return;
+
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ ModuleBase_IViewer* aViewer = aWorkshop->viewer();
+ if (!aViewer->canDragByMouse())
+ return;
+ ModuleBase_Operation* aOp = getCurrentOperation();
+ if (aOp) {
+ if (isNestedSketchOperation(aOp)) {
+ // Only for sketcher operations
+ if (myIsDragging) {
+ if (myDragDone) {
+ myCurrentSelection.clear();
+ }
+ }
+ }
+ }
+
+ aWorkshop->viewer()->enableDrawMode(myPreviousDrawModeEnabled);
+ myIsDragging = false;
+
+ ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+ PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);
+ if (aProcessor)
+ aProcessor->mouseReleased(theWnd, theEvent);
+}
+
+void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
+{
+#ifdef DEBUG_SKETCH_ENTITIES_ON_MOVE
+ CompositeFeaturePtr aSketch = activeSketch();
+ if (aSketch.get()) {
+ std::cout << "mouse move SKETCH FEATURES [" << aSketch->numberOfSubs() << "]:" << std::endl;
+ QStringList anInfo;
+ for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) {
+ //std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl;
+ anInfo.append(ModuleBase_Tools::objectInfo(aSketch->subFeature(i)));
+ }
+ QString anInfoStr = anInfo.join("\n");
+ qDebug(QString("%1").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str());
+ }
+#endif
+
+ if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent))
+ return;
+
+ if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) {
+ // 1. perform the widget mouse move functionality and display the presentation
+ // the mouse move should be processed in the widget, if it can in order to visualize correct
+ // presentation. These widgets correct the feature attribute according to the mouse position
+ ModuleBase_ModelWidget* anActiveWidget = myModule->activeWidget();
+ PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);
+ if (aProcessor)
+ aProcessor->mouseMoved(theWnd, theEvent);
+ if (!myIsMouseOverViewProcessed) {
+ myIsMouseOverViewProcessed = true;
+
+ // the feature is to be erased here, but it is correct to call canDisplayObject because
+ // there can be additional check (e.g. editor widget in distance constraint)
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
+ }
+ }
+ }
+ //myClickedPoint.clear();
+
+ if (myIsDragging) {
+ // 1. the current selection is saved in the mouse press method in order to restore it after moving
+ // 2. the enable selection in the viewer should be temporary switched off in order to ignore
+ // mouse press signal in the viewer(it call Select for AIS context and the dragged objects are
+ // deselected). This flag should be restored in the slot, processed the mouse release signal.
+
+ ModuleBase_Operation* aCurrentOperation = getCurrentOperation();
+ if (!aCurrentOperation)
+ return;
+ if (isSketchOperation(aCurrentOperation))
+ return; // No edit operation activated
+
+ Handle(V3d_View) aView = theWnd->v3dView();
+ gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);
+ Point aMousePnt;
+ get2dPoint(theWnd, theEvent, aMousePnt);
+ double dX = aMousePnt.myCurX - myCurrentPoint.myCurX;
+ double dY = aMousePnt.myCurY - myCurrentPoint.myCurY;
+
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+ XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+ // 3. the flag to disable the update viewer should be set in order to avoid blinking in the
+ // viewer happens by deselect/select the modified objects. The flag should be restored after
+ // the selection processing. The update viewer should be also called.
+ bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false);
+
+ static Events_ID aMoveEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
+ //static Events_ID aUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+ FeatureToSelectionMap::const_iterator anIt = myCurrentSelection.begin(),
+ aLast = myCurrentSelection.end();
+ // 4. the features and attributes modification(move)
+ bool isModified = false;
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = anIt.key();
+
+ std::set<AttributePtr> anAttributes = anIt.value().first;
+ // Process selection by attribute: the priority to the attribute
+ if (!anAttributes.empty()) {
+ std::set<AttributePtr>::const_iterator anAttIt = anAttributes.begin(),
+ anAttLast = anAttributes.end();
+ for (; anAttIt != anAttLast; anAttIt++) {
+ AttributePtr anAttr = *anAttIt;
+ if (anAttr.get() == NULL)
+ continue;
+ std::string aAttrId = anAttr->id();
+ DataPtr aData = aFeature->data();
+ if (aData->isValid()) {
+ std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(aAttrId));
+ if (aPoint.get() != NULL) {
+ bool isImmutable = aPoint->setImmutable(true);
+ aPoint->move(dX, dY);
+ isModified = true;
+ ModelAPI_EventCreator::get()->sendUpdated(aFeature, aMoveEvent);
+ aPoint->setImmutable(isImmutable);
+ }
+ }
+ }
+ } else {
+ // Process selection by feature
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ if (aSketchFeature) {
+ aSketchFeature->move(dX, dY);
+ isModified = true;
+ ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, aMoveEvent);
+ }
+ }
+ }
+ // the modified state of the current operation should be updated if there are features, which
+ // were changed here
+ if (isModified) {
+ aCurrentOperation->onValuesChanged();
+ }
+ Events_Loop::loop()->flush(aMoveEvent); // up all move events - to be processed in the solver
+ //Events_Loop::loop()->flush(aUpdateEvent); // up update events - to redisplay presentations
+
+ // 5. it is necessary to save current selection in order to restore it after the features moving
+ restoreSelection();
+ // 6. restore the update viewer flag and call this update
+ aDisplayer->enableUpdateViewer(isEnableUpdateViewer);
+ aDisplayer->updateViewer();
+
+ myDragDone = true;
+ myCurrentPoint = aMousePnt;
+ }
+}
+
+void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation && aFOperation->isEditOperation()) {
+ std::string aId = aFOperation->id().toStdString();
+ if (isDistanceOperation(aFOperation))
+ {
+ // Activate dimension value editing on double click
+ ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
+ QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
+ // Find corresponded widget to activate value editing
+ foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
+ if (aWgt->attributeID() == SketchPlugin_Constraint::VALUE() ||
+ aWgt->attributeID() == SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()) {
+ PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
+ if (anEditor)
+ anEditor->showPopupEditor();
+ return;
+ }
+ }
+ }
+ }
+}
+
+void PartSet_SketcherMgr::onApplicationStarted()
+{
+ ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
+ XGUI_Workshop* aWorkshop = aConnector->workshop();
+ PartSet_SketcherReetntrantMgr* aReentranceMgr = myModule->sketchReentranceMgr();
+
+ XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel();
+ if (aPropertyPanel) {
+ //connect(aPropertyPanel, SIGNAL(beforeWidgetActivated(ModuleBase_ModelWidget*)),
+ // this, SLOT(onBeforeWidgetActivated(ModuleBase_ModelWidget*)));
+
+ connect(aPropertyPanel, SIGNAL(noMoreWidgets(const std::string&)),
+ aReentranceMgr, SLOT(onNoMoreWidgets(const std::string&)));
+ connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),
+ aReentranceMgr, SLOT(onWidgetActivated()));
+ }
+
+ XGUI_ViewerProxy* aViewerProxy = aWorkshop->viewer();
+ connect(aViewerProxy, SIGNAL(enterViewPort()), this, SLOT(onEnterViewPort()));
+ connect(aViewerProxy, SIGNAL(leaveViewPort()), this, SLOT(onLeaveViewPort()));
+
+ XGUI_ContextMenuMgr* aContextMenuMgr = aWorkshop->contextMenuMgr();
+ connect(aContextMenuMgr, SIGNAL(beforeContextMenu()), this, SLOT(onBeforeContextMenu()));
+ connect(aContextMenuMgr, SIGNAL(afterContextMenu()), this, SLOT(onAfterContextMenu()));
+}
+
+//void PartSet_SketcherMgr::onBeforeWidgetActivated(ModuleBase_ModelWidget* theWidget)
+//{
+ //if (!myClickedPoint.myIsInitialized)
+ // return;
+
+ //ModuleBase_Operation* aOperation = getCurrentOperation();
+ // the distance constraint feature should not use the clickedd point
+ // this is workaround in order to don't throw down the flyout point value,
+ // set by execute() method of these type of features
+ //if (isDistanceOperation(aOperation))
+ // return;
+
+ //PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast<PartSet_WidgetPoint2D*>(theWidget);
+ //if (aPnt2dWgt) {
+ // aPnt2dWgt->setPoint(myClickedPoint.myCurX, myClickedPoint.myCurY);
+ //}
+//}
+
+void PartSet_SketcherMgr::onBeforeContextMenu()
+{
+ myIsPopupMenuActive = true;
+}
+
+void PartSet_SketcherMgr::onAfterContextMenu()
+{
+ myIsPopupMenuActive = false;
+}
+
+void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent,
+ Point& thePoint)
+{
+ Handle(V3d_View) aView = theWnd->v3dView();
+ gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);
+ double aX, anY;
+ PartSet_Tools::convertTo2D(aPoint, myCurrentSketch, aView, aX, anY);
+ thePoint.setValue(aX, anY);
+}
+
+void PartSet_SketcherMgr::launchEditing()
+{
+ if (!myCurrentSelection.empty()) {
+ FeaturePtr aFeature = myCurrentSelection.begin().key();
+ std::shared_ptr<SketchPlugin_Feature> aSPFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ if (aSPFeature && (!aSPFeature->isExternal())) {
+ myModule->editFeature(aSPFeature);
+ }
+ }
+}
+
+bool PartSet_SketcherMgr::sketchSolverError()
+{
+ bool anError = false;
+ CompositeFeaturePtr aSketch = activeSketch();
+ if (aSketch.get()) {
+ AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());
+ anError = !aAttributeString->value().empty();
+ }
+ return anError;
+}
+
+QString PartSet_SketcherMgr::getFeatureError(const FeaturePtr& theFeature)
+{
+ std::string anError = "";
+ if (!theFeature.get() || !theFeature->data()->isValid())
+ return anError.c_str();
+
+ CompositeFeaturePtr aSketch = activeSketch();
+ if (aSketch.get() && aSketch == theFeature) {
+ AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());
+ anError = aAttributeString->value();
+ ModuleBase_Tools::translate(aSketch->getKind(), anError);
+ }
+ return anError.c_str();
+}
+
+void PartSet_SketcherMgr::clearClickedFlags()
+{
+ //myClickedPoint.clear();
+ myCurrentPoint.clear();
+}
+
+const QStringList& PartSet_SketcherMgr::replicationsIdList()
+{
+ static QStringList aReplicationIds;
+ if (aReplicationIds.size() == 0) {
+ aReplicationIds << SketchPlugin_ConstraintMirror::ID().c_str();
+ aReplicationIds << SketchPlugin_MultiRotation::ID().c_str();
+ aReplicationIds << SketchPlugin_MultiTranslation::ID().c_str();
+ }
+ return aReplicationIds;
+}
+
+const QStringList& PartSet_SketcherMgr::constraintsIdList()
+{
+ static QStringList aConstraintIds;
+ if (aConstraintIds.size() == 0) {
+ aConstraintIds << SketchPlugin_ConstraintLength::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintDistance::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintRigid::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintRadius::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintPerpendicular::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintParallel::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintHorizontal::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintVertical::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintEqual::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintTangent::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintCoincidence::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintAngle::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintCollinear::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintMiddle::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintMirror::ID().c_str();
+ aConstraintIds << SketchPlugin_MultiTranslation::ID().c_str();
+ aConstraintIds << SketchPlugin_MultiRotation::ID().c_str();
+ }
+ return aConstraintIds;
+}
+
+void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes)
+{
+ theModes.clear();
+
+ theModes.append(SketcherPrs_Tools::Sel_Dimension_Text);
+ theModes.append(SketcherPrs_Tools::Sel_Dimension_Line);
+ theModes.append(SketcherPrs_Tools::Sel_Constraint);
+ theModes.append(TopAbs_VERTEX);
+ theModes.append(TopAbs_EDGE);
+}
+
+Handle(AIS_InteractiveObject) PartSet_SketcherMgr::createPresentation(const ResultPtr& theResult)
+{
+ Handle(AIS_InteractiveObject) aPrs;
+
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theResult);
+ if (aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID()) {
+ aPrs = new PartSet_ResultSketchPrs(theResult);
+ }
+ return aPrs;
+}
+
+bool PartSet_SketcherMgr::isSketchOperation(ModuleBase_Operation* theOperation)
+{
+ return theOperation && theOperation->id().toStdString() == SketchPlugin_Sketch::ID();
+}
+
+bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOperation) const
+{
+ bool aNestedSketch = false;
+
+ FeaturePtr anActiveSketch = activeSketch();
+ if (anActiveSketch.get() && theOperation) {
+ ModuleBase_Operation* aSketchOperation = operationMgr()->findOperation(
+ anActiveSketch->getKind().c_str());
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ if (aSketchOperation && aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ if (aFeature.get()) {
+ QStringList aGrantedOpIds = aSketchOperation->grantedOperationIds();
+ aNestedSketch = aGrantedOpIds.contains(aFeature->getKind().c_str());
+ }
+ }
+ }
+ return aNestedSketch;
+}
+
+bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation,
+ const CompositeFeaturePtr& theSketch) const
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ return aFOperation && !aFOperation->isEditOperation() &&
+ isNestedSketchOperation(aFOperation);
+}
+
+bool PartSet_SketcherMgr::isNestedEditOperation(ModuleBase_Operation* theOperation,
+ const CompositeFeaturePtr& theSketch) const
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ return aFOperation && aFOperation->isEditOperation() &&
+ isNestedSketchOperation(aFOperation);
+}
+
+bool PartSet_SketcherMgr::isEntity(const std::string& theId)
+{
+ return (theId == SketchPlugin_Line::ID()) ||
+ (theId == SketchPlugin_Point::ID()) ||
+ (theId == SketchPlugin_Arc::ID()) ||
+ (theId == SketchPlugin_Circle::ID());
+}
+
+bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation)
+{
+ std::string anId = theOperation ? theOperation->id().toStdString() : "";
+
+ return isDistanceKind(anId);
+}
+
+bool PartSet_SketcherMgr::isDistanceKind(std::string& theKind)
+{
+ return (theKind == SketchPlugin_ConstraintLength::ID()) ||
+ (theKind == SketchPlugin_ConstraintDistance::ID()) ||
+ (theKind == SketchPlugin_ConstraintRadius::ID()) ||
+ (theKind == SketchPlugin_ConstraintAngle::ID());
+}
+
+void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (!aFOperation)
+ return;
+
+ myModule->onViewTransformed();
+
+ // Display all sketcher sub-Objects
+ myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
+
+ // Hide sketcher result
+ std::list<ResultPtr> aResults = myCurrentSketch->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+ (*aIt)->setDisplayed(false);
+ }
+ myCurrentSketch->setDisplayed(false);
+
+ // Remove invalid sketch entities
+ std::set<FeaturePtr> anInvalidFeatures;
+ ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
+ for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+ FeaturePtr aFeature = myCurrentSketch->subFeature(i);
+ if (aFeature.get()) {
+ if (!aFactory->validate(aFeature))
+ anInvalidFeatures.insert(aFeature);
+ }
+ }
+ if (!anInvalidFeatures.empty()) {
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ ModelAPI_Tools::findAllReferences(anInvalidFeatures, aReferences, false);
+
+ std::set<FeaturePtr>::const_iterator anIt = anInvalidFeatures.begin(),
+ aLast = anInvalidFeatures.end();
+ // separate features to references to parameter features and references to others
+ QStringList anInvalidFeatureNames;
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (aFeature.get())
+ anInvalidFeatureNames.append(aFeature->name().c_str());
+ }
+ std::string aPrefixInfo = QString("Invalid features of the sketch will be deleted: %1.\n\n").
+ arg(anInvalidFeatureNames.join(", ")).toStdString().c_str();
+ std::set<FeaturePtr> aFeatureRefsToDelete;
+ if (ModuleBase_Tools::askToDelete(anInvalidFeatures, aReferences, aConnector->desktop(),
+ aFeatureRefsToDelete, aPrefixInfo)) {
+ if (!aFeatureRefsToDelete.empty())
+ anInvalidFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
+ ModelAPI_Tools::removeFeatures(anInvalidFeatures, true);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+ // TODO: call the next method in the XGUI_OperationMgr::onOperationStarted().
+ workshop()->errorMgr()->updateAcceptAllAction(myCurrentSketch);
+ }
+ }
+
+ // Display sketcher objects
+ QStringList anInfo;
+ for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+ FeaturePtr aFeature = myCurrentSketch->subFeature(i);
+#ifdef DEBUG_SKETCHER_ENTITIES
+ anInfo.append(ModuleBase_Tools::objectInfo(aFeature));
+#endif
+ std::list<ResultPtr> aResults = aFeature->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+ (*aIt)->setDisplayed(true);
+ }
+ aFeature->setDisplayed(true);
+ }
+#ifdef DEBUG_SKETCHER_ENTITIES
+ QString anInfoStr = anInfo.join(";\t");
+ qDebug(QString("startSketch: %1, %2").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str());
+#endif
+
+ if(myCirclePointFilter.IsNull()) {
+ myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop());
+ }
+
+ myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter);
+
+ if (myPlaneFilter.IsNull())
+ myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
+
+ myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
+ bool aHasPlane = false;
+ std::shared_ptr<GeomAPI_Pln> aPln;
+ aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
+ myPlaneFilter->setPlane(aPln);
+
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ // all displayed objects should be activated in current selection modes according to switched
+ // plane filter
+ if (aPln.get())
+ aConnector->activateModuleSelectionModes();
+}
+
+void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
+{
+ myIsMouseOverWindow = false;
+ myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
+ myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
+ myIsConstraintsShown[PartSet_Tools::Expressions] = false;
+
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
+
+ DataPtr aData = myCurrentSketch->data();
+ if (!aData->isValid()) {
+ XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+ // The sketch was aborted
+ myCurrentSketch = CompositeFeaturePtr();
+ // TODO: move this outside of if-else
+ myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
+ myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
+
+ // Erase all sketcher objects
+ QObjectPtrList aObjects = aDisplayer->displayedObjects();
+ foreach (ObjectPtr aObj, aObjects) {
+ DataPtr aObjData = aObj->data();
+ if (!aObjData->isValid())
+ aObj->setDisplayed(false);
+ }
+ }
+ else {
+ // Hide all sketcher sub-Objects
+ for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+ FeaturePtr aFeature = myCurrentSketch->subFeature(i);
+ std::list<ResultPtr> aResults = aFeature->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+ (*aIt)->setDisplayed(false);
+ }
+ aFeature->setDisplayed(false);
+ }
+ // Display sketcher result
+ std::list<ResultPtr> aResults = myCurrentSketch->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID aDispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+ if (!aFOperation->isDisplayedOnStart(*aIt)) {
+ (*aIt)->setDisplayed(true);
+ // this display event is needed because sketch already may have "displayed" state,
+ // but not displayed while it is still active (issue 613, abort of existing sketch)
+ ModelAPI_EventCreator::get()->sendUpdated(*aIt, aDispEvent);
+ }
+ }
+ if (!aFOperation->isDisplayedOnStart(myCurrentSketch))
+ myCurrentSketch->setDisplayed(true);
+
+ myCurrentSketch = CompositeFeaturePtr();
+
+ myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
+ myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
+
+ Events_Loop::loop()->flush(aDispEvent);
+ }
+ // restore the module selection modes, which were changed on startSketch
+ aConnector->activateModuleSelectionModes();
+}
+
+void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
+{
+ if (canChangeCursor(theOperation) && myIsMouseOverWindow) {
+ QCursor* aCurrentCursor = QApplication::overrideCursor();
+ if (!aCurrentCursor || aCurrentCursor->shape() != Qt::CrossCursor) {
+ QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
+#ifdef DEBUG_CURSOR
+ qDebug("startNestedSketch() : Qt::CrossCursor");
+#endif
+ }
+ }
+}
+
+void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
+{
+ myIsMouseOverViewProcessed = true;
+ operationMgr()->onValidateOperation();
+ // when sketch nested operation is stopped the cursor should be restored unconditionally
+ //if (canChangeCursor(theOperation)) {
+ QApplication::restoreOverrideCursor();
+#ifdef DEBUG_CURSOR
+ qDebug("stopNestedSketch() : None");
+#endif
+ //}
+ /// improvement to deselect automatically all eventual selected objects, when
+ // returning to the neutral point of the Sketcher
+ workshop()->selector()->clearSelection();
+}
+
+void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
+{
+ if (isNestedCreateOperation(theOperation, activeSketch())) {
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ // it is necessary to check the the feature data validity because
+ // some kind of features are removed by an operation commit(the macro state of a feature)
+ if (aFeature.get() && aFeature->data()->isValid()) {
+ visualizeFeature(aFeature, aFOperation->isEditOperation(), true);
+ }
+ }
+ }
+}
+
+void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate)
+{
+ if (toActivate)
+ myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
+ else
+ myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
+}
+
+bool PartSet_SketcherMgr::operationActivatedByPreselection()
+{
+ bool isOperationStopped = false;
+ ModuleBase_Operation* anOperation = getCurrentOperation();
+ if(anOperation && isNestedSketchOperation(anOperation)) {
+ // Set final definitions if they are necessary
+ //propertyPanelDefined(aOperation);
+ /// Commit sketcher operations automatically
+ /// distance operation are able to show popup editor to modify the distance value
+ /// after entering the value, the operation should be committed/aborted(by Esc key)
+ bool aCanCommitOperation = true;
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (anOperation);
+ if (aFOperation && PartSet_SketcherMgr::isDistanceOperation(aFOperation)) {
+ bool aValueAccepted = setDistanceValueByPreselection(anOperation, myModule->workshop(),
+ aCanCommitOperation);
+ if (!aValueAccepted)
+ return isOperationStopped;
+ }
+
+ if (aCanCommitOperation)
+ isOperationStopped = anOperation->commit();
+ else {
+ anOperation->abort();
+ isOperationStopped = true;
+ }
+ }
+ return isOperationStopped;
+}
+
+bool PartSet_SketcherMgr::canUndo() const
+{
+ return isNestedCreateOperation(getCurrentOperation(), activeSketch());
+}
+
+bool PartSet_SketcherMgr::canRedo() const
+{
+ return isNestedCreateOperation(getCurrentOperation(), activeSketch());
+}
+
+bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const
+{
+ bool aCanErase = true;
+ // when the sketch operation is active, results of sketch sub-feature can not be hidden
+ if (myCurrentSketch.get()) {
+ return !isObjectOfSketch(theObject);
+ }
+ return aCanErase;
+}
+
+bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
+{
+ bool aCanDisplay = true;
+
+ bool aHasActiveSketch = activeSketch().get() != NULL;
+ if (aHasActiveSketch) {
+ // 1. the sketch feature should not be displayed during the sketch active operation
+ // it is hidden by a sketch operation start and shown by a sketch stop, just the sketch
+ // nested features can be visualized
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature.get() != NULL && aFeature == activeSketch()) {
+ aCanDisplay = false;
+ }
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ /// some sketch entities should be never shown, e.g. projection feature
+ if (aSketchFeature.get())
+ aCanDisplay = aSketchFeature->canBeDisplayed();
+ }
+ else { // there are no an active sketch
+ // 2. sketch sub-features should not be visualized if the sketch operation is not active
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature.get() != NULL) {
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ if (aSketchFeature.get()) {
+ aCanDisplay = false;
+ }
+ }
+ }
+
+ // 3. the method should not filter the objects, which are not related to the current operation.
+ // The object is filtered just if it is a current operation feature or this feature result
+ if (aCanDisplay) {
+ bool isObjectFound = false;
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ if (aFeature.get()) {
+ std::list<ResultPtr> aResults = aFeature->results();
+ if (theObject == aFeature)
+ isObjectFound = true;
+ else {
+ std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLast = aResults.end();
+ for (; anIt != aLast && !isObjectFound; anIt++) {
+ isObjectFound = *anIt == theObject;
+ }
+ }
+ }
+ }
+ if (isObjectFound) {
+ // 4. For created nested feature operation do not display the created feature if
+ // the mouse curstor leaves the OCC window.
+ // The correction cases, which ignores this condition:
+ // a. the property panel values modification
+ // b. the popup menu activated
+ // c. widget editor control
+ #ifndef DEBUG_DO_NOT_BY_ENTER
+ if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) {
+ ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+ ModuleBase_WidgetEditor* anEditorWdg = anActiveWidget ? dynamic_cast<ModuleBase_WidgetEditor*>(anActiveWidget) : 0;
+ // the active widget editor should not influence here. The presentation should be visible always
+ // when this widget is active.
+ if (!anEditorWdg && !myIsPopupMenuActive) {
+ // during a nested create operation, the feature is redisplayed only if the mouse over view
+ // of there was a value modified in the property panel after the mouse left the view
+ aCanDisplay = canDisplayCurrentCreatedFeature();
+ }
+ }
+ #endif
+ }
+ }
+
+ // checks the sketcher constraints visibility according to active sketch check box states
+ if (aCanDisplay) {
+ bool aProcessed = false;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature.get()) {
+ bool aConstraintDisplayed = canDisplayConstraint(aFeature, PartSet_Tools::Any, aProcessed);
+ if (aProcessed)
+ aCanDisplay = aConstraintDisplayed;
+ }
+ }
+
+ return aCanDisplay;
+}
+
+bool PartSet_SketcherMgr::canDisplayConstraint(const FeaturePtr& theFeature,
+ const PartSet_Tools::ConstraintVisibleState& theState,
+ bool& isProcessed) const
+{
+ bool aSwitchedOn = true;
+
+ const QStringList& aConstrIds = constraintsIdList();
+
+ std::string aKind = theFeature->getKind();
+ if (aConstrIds.contains(QString(aKind.c_str()))) {
+ bool isTypedConstraint = false;
+
+ switch (theState) {
+ case PartSet_Tools::Dimensional: {
+ bool isDistance = isDistanceKind(aKind);
+ if (isDistance) {
+ isProcessed = true;
+ aSwitchedOn = myIsConstraintsShown[theState];
+ }
+ }
+ break;
+ case PartSet_Tools::Geometrical: {
+ bool isGeometrical = !isDistanceKind(aKind);
+ if (isGeometrical) {
+ isProcessed = true;
+ aSwitchedOn = myIsConstraintsShown[theState];
+ }
+ }
+ break;
+ case PartSet_Tools::Any: {
+ isProcessed = true;
+ bool isDistance = isDistanceKind(aKind);
+ if (isDistance)
+ aSwitchedOn = myIsConstraintsShown[PartSet_Tools::Dimensional];
+ else
+ aSwitchedOn = myIsConstraintsShown[PartSet_Tools::Geometrical];
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return aSwitchedOn;
+}
+
+/*void PartSet_SketcherMgr::processHiddenObject(const std::list<ObjectPtr>& theObjects)
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation && myCurrentSketch.get()) {
+ // find results of the current operation
+ // these results should not be proposed to be deleted
+ FeaturePtr anOperationFeature = aFOperation->feature();
+ std::list<ResultPtr> anOperationResultList = anOperationFeature->results();
+ std::set<ResultPtr> anOperationResults;
+ std::list<ResultPtr>::const_iterator aRIt = anOperationResultList.begin(),
+ aRLast = anOperationResultList.end();
+ for (; aRIt != aRLast; aRIt++)
+ anOperationResults.insert(*aRIt);
+
+ std::set<FeaturePtr> anObjectsToBeDeleted;
+ QStringList anObjectsToBeDeletedNames;
+ std::list<ObjectPtr>::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
+ for (; anIt != aLast; anIt++) {
+ ObjectPtr anObject = *anIt;
+ bool aCanErase = true;
+ // when the sketch operation is active, results of sketch sub-feature can not be hidden
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ // the result is found between current feature results
+ if (anOperationResults.find(aResult) != anOperationResults.end())
+ continue;
+
+ if (aResult.get()) {
+ // Display sketcher objects
+ for (int i = 0; i < myCurrentSketch->numberOfSubs() && aCanErase; i++) {
+ FeaturePtr aFeature = myCurrentSketch->subFeature(i);
+ std::list<ResultPtr> aResults = aFeature->results();
+ std::list<ResultPtr>::const_iterator anIt;
+ for (anIt = aResults.begin(); anIt != aResults.end() && aCanErase; ++anIt) {
+ aCanErase = *anIt != aResult;
+ }
+ }
+ }
+ if (!aCanErase) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ if (aFeature.get() && anObjectsToBeDeleted.find(aFeature) == anObjectsToBeDeleted.end()) {
+ anObjectsToBeDeleted.insert(aFeature);
+ anObjectsToBeDeletedNames.append(aFeature->name().c_str());
+ }
+ }
+ }
+ if (!anObjectsToBeDeleted.empty()) {
+ QString aFeatureNames = anObjectsToBeDeletedNames.join(", ");
+ QString aMessage = tr("The following features have incorrect presentation and \
+will be hidden: %1. Would you like to delete them?")
+ .arg(aFeatureNames);
+ int anAnswer = QMessageBox::question(qApp->activeWindow(), tr("Features hide"),
+ aMessage, QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+ if (anAnswer == QMessageBox::Ok) {
+ QObjectPtrList anObjects;
+ std::set<FeaturePtr>::const_iterator anIt = anObjectsToBeDeleted.begin(),
+ aLast = anObjectsToBeDeleted.end();
+ for (; anIt != aLast; anIt++)
+ anObjects.append(*anIt);
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ bool aIsOp = aMgr->isOperation();
+ if (!aIsOp)
+ aMgr->startOperation();
+ workshop()->deleteFeatures(anObjects);
+ //static Events_ID aDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+ //static Events_ID aRedispEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ //Events_Loop::loop()->flush(aDeletedEvent);
+ //Events_Loop::loop()->flush(aRedispEvent);
+
+ if (!aIsOp)
+ aMgr->finishOperation();
+ }
+ }
+ }
+}*/
+
+bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const
+{
+ bool aCanDisplay = myIsMouseOverWindow;
+ if (!aCanDisplay) {
+ ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
+ if (anActiveWidget)
+ aCanDisplay = anActiveWidget->getValueState() == ModuleBase_ModelWidget::Stored;
+ }
+ return aCanDisplay;
+}
+
+bool PartSet_SketcherMgr::canChangeCursor(ModuleBase_Operation* theOperation) const
+{
+ return isNestedCreateOperation(theOperation, activeSketch()) ||
+ myModule->sketchReentranceMgr()->isInternalEditActive();
+}
+
+const QMap<PartSet_Tools::ConstraintVisibleState, bool>& PartSet_SketcherMgr::showConstraintStates()
+{
+ return myIsConstraintsShown;
+}
+
+bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const
+{
+ bool isFoundObject = false;
+
+ FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject);
+ if (anObjectFeature.get()) {
+ int aSize = myCurrentSketch->numberOfSubs();
+ for (int i = 0; i < myCurrentSketch->numberOfSubs() && !isFoundObject; i++) {
+ FeaturePtr aCurrentFeature = myCurrentSketch->subFeature(i);
+ isFoundObject = myCurrentSketch->subFeature(i) == anObjectFeature;
+ }
+ }
+ return isFoundObject;
+}
+
+void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePln)
+{
+ if (myPlaneFilter.IsNull())
+ myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
+
+ myPlaneFilter->setPlane(thePln);
+}
+
+bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation,
+ ModuleBase_IWorkshop* theWorkshop,
+ bool& theCanCommitOperation)
+{
+ bool isValueAccepted = false;
+ theCanCommitOperation = false;
+
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ FeaturePtr aFeature = aFOperation->feature();
+ // editor is shown only if all attribute references are filled by preseletion
+ bool anAllRefAttrInitialized = true;
+
+ std::list<AttributePtr> aRefAttrs = aFeature->data()->attributes(
+ ModelAPI_AttributeRefAttr::typeId());
+ std::list<AttributePtr>::const_iterator anIt = aRefAttrs.begin(), aLast = aRefAttrs.end();
+ for (; anIt != aLast && anAllRefAttrInitialized; anIt++) {
+ anAllRefAttrInitialized = (*anIt)->isInitialized();
+ }
+ if (anAllRefAttrInitialized) {
+ // Activate dimension value editing on double click
+ ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
+ QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
+ // Find corresponded widget to activate value editing
+ foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
+ if (aWgt->attributeID() == "ConstraintValue") {
+ // the featue should be displayed in order to find the AIS text position,
+ // the place where the editor will be shown
+ aFeature->setDisplayed(true);
+ /// the execute is necessary to perform in the feature compute for flyout position
+ aFeature->execute();
+
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+
+ PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
+ if (anEditor) {
+ int aX = 0, anY = 0;
+
+ XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(theWorkshop);
+ XGUI_Displayer* aDisplayer = aWorkshop->displayer();
+ AISObjectPtr anAIS = aDisplayer->getAISObject(aFeature);
+ Handle(AIS_InteractiveObject) anAISIO;
+ if (anAIS.get() != NULL) {
+ anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+ }
+ if (anAIS.get() != NULL) {
+ Handle(AIS_InteractiveObject) anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+
+ if (!anAISIO.IsNull()) {
+ Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAISIO);
+ if (!aDim.IsNull()) {
+ gp_Pnt aPosition = aDim->GetTextPosition();
+
+ ModuleBase_IViewer* aViewer = aWorkshop->viewer();
+ Handle(V3d_View) aView = aViewer->activeView();
+ int aCX, aCY;
+ aView->Convert(aPosition.X(), aPosition.Y(), aPosition.Z(), aCX, aCY);
+
+ QWidget* aViewPort = aViewer->activeViewPort();
+ QPoint aGlPoint = aViewPort->mapToGlobal(QPoint(aCX, aCY));
+ aX = aGlPoint.x();
+ anY = aGlPoint.y();
+ }
+ }
+ anEditor->setCursorPosition(aX, anY);
+ isValueAccepted = anEditor->showPopupEditor(false);
+ theCanCommitOperation = true;
+ }
+ }
+ }
+ }
+ }
+ return isValueAccepted;
+}
+
+void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
+ const FeaturePtr& theSketch,
+ ModuleBase_IWorkshop* theWorkshop,
+ const FeatureToSelectionMap& theSelection,
+ SelectMgr_IndexedMapOfOwner& theOwnersToSelect)
+{
+ if (theFeature.get() == NULL)
+ return;
+
+ FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature);
+ std::set<AttributePtr> aSelectedAttributes = anIt.value().first;
+ std::set<ResultPtr> aSelectedResults = anIt.value().second;
+
+ ModuleBase_IViewer* aViewer = theWorkshop->viewer();
+
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
+ XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+
+ // 1. found the feature's owners. Check the AIS objects of the constructions
+ AISObjectPtr aAISObj = aDisplayer->getAISObject(theFeature);
+ if (aAISObj.get() != NULL && aSelectedAttributes.empty() && aSelectedResults.empty()) {
+ Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+
+ SelectMgr_IndexedMapOfOwner aSelectedOwners;
+ aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners);
+ for (Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++) {
+ Handle(SelectMgr_EntityOwner) anOwner = aSelectedOwners(i);
+ if (!anOwner.IsNull())
+ theOwnersToSelect.Add(anOwner);
+ }
+ }
+
+ // 2. found the feature results's owners
+ std::list<ResultPtr> aResults = theFeature->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
+ {
+ ResultPtr aResult = *aIt;
+ AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult);
+ if (aAISObj.get() == NULL)
+ continue;
+ Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+
+ SelectMgr_IndexedMapOfOwner aSelectedOwners;
+ aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners);
+ for ( Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++ ) {
+ Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(aSelectedOwners(i));
+ if ( anOwner.IsNull() || !anOwner->HasShape() )
+ continue;
+ const TopoDS_Shape& aShape = anOwner->Shape();
+ TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+ if (aShapeType == TopAbs_VERTEX) {
+ AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch);
+ if (aPntAttr.get() != NULL &&
+ aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) {
+ theOwnersToSelect.Add(anOwner);
+ }
+ }
+ else if (aShapeType == TopAbs_EDGE) {
+ bool aFound = aSelectedResults.find(aResult) != aSelectedResults.end();
+ if (aSelectedResults.find(aResult) != aSelectedResults.end() &&
+ theOwnersToSelect.FindIndex(anOwner) <= 0)
+ theOwnersToSelect.Add(anOwner);
+ }
+ }
+ }
+}
+
+void PartSet_SketcherMgr::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect)
+{
+ if (isToConnect) {
+ connect(theWidget, SIGNAL(beforeValuesChanged()),
+ this, SLOT(onBeforeValuesChangedInPropertyPanel()));
+ connect(theWidget, SIGNAL(afterValuesChanged()),
+ this, SLOT(onAfterValuesChangedInPropertyPanel()));
+ }
+ else {
+ disconnect(theWidget, SIGNAL(beforeValuesChanged()),
+ this, SLOT(onBeforeValuesChangedInPropertyPanel()));
+ disconnect(theWidget, SIGNAL(afterValuesChanged()),
+ this, SLOT(onAfterValuesChangedInPropertyPanel()));
+ }
+}
+
+void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState)
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation) {
+ if (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||
+ isNestedSketchOperation(aFOperation) &&
+ thePreviousState == ModuleBase_ModelWidget::ModifiedInPP) {
+ FeaturePtr aFeature = aFOperation->feature();
+ visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature));
+ }
+ }
+}
+
+void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject)
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (getCurrentOperation());
+ if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||
+ isNestedSketchOperation(aFOperation)))
+ SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]);
+
+ // update entities selection priorities
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature.get() && PartSet_SketcherMgr::isEntity(aFeature->getKind())) {
+ // update priority for feature
+ updateSelectionPriority(aFeature, aFeature);
+ // update priority for results of the feature
+ std::list<ResultPtr> aResults = aFeature->results();
+ std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLastIt = aResults.end();
+ for (; anIt != aLastIt; anIt++)
+ updateSelectionPriority(*anIt, aFeature);
+ }
+}
+
+ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const
+{
+ return myModule->workshop()->currentOperation();
+}
+
+//**************************************************************
+ModuleBase_ModelWidget* PartSet_SketcherMgr::getActiveWidget() const
+{
+ ModuleBase_ModelWidget* aWidget = 0;
+ ModuleBase_Operation* anOperation = getCurrentOperation();
+ if (anOperation) {
+ ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+ if (aPanel)
+ aWidget = aPanel->activeWidget();
+ }
+ return aWidget;
+}
+
+void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature,
+ const bool isEditOperation,
+ const bool isToDisplay,
+ const bool isFlushRedisplay)
+{
+ #ifdef DEBUG_DO_NOT_BY_ENTER
+ return;
+ #endif
+
+ if (isEditOperation || !theFeature.get())
+ return;
+
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+
+ // 1. change visibility of the object itself, here the presentable object is processed,
+ // e.g. constraints features
+ //FeaturePtr aFeature = aFOperation->feature();
+ std::list<ResultPtr> aResults = theFeature->results();
+ if (isToDisplay)
+ theFeature->setDisplayed(true);
+ else
+ theFeature->setDisplayed(false);
+
+ // change visibility of the object results, e.g. non-constraint features
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+ if (isToDisplay) {
+ (*aIt)->setDisplayed(true);
+ }
+ else {
+ (*aIt)->setDisplayed(false);
+ }
+ }
+ if (isFlushRedisplay)
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+}
+
+void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
+{
+ if (!myCurrentSketch.get())
+ return;
+
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ ModuleBase_ISelection* aSelect = aWorkshop->selection();
+ QList<ModuleBase_ViewerPrsPtr> aStoredPrs = aSelect->getHighlighted();
+
+ QList<FeaturePtr> aFeatureList;
+ if (!theHighlightedOnly) {
+ QList<ModuleBase_ViewerPrsPtr> aSelected = aSelect->getSelected(
+ ModuleBase_ISelection::AllControls);
+ aStoredPrs.append(aSelected);
+ }
+
+ // 1. it is necessary to save current selection in order to restore it after the features moving
+ myCurrentSelection.clear();
+
+ QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = aStoredPrs.begin(), aLast = aStoredPrs.end();
+
+ CompositeFeaturePtr aSketch = activeSketch();
+ for (; anIt != aLast; anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = *anIt;
+ ObjectPtr anObject = aPrs->object();
+ if (!anObject.get())
+ continue;
+
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ FeaturePtr aFeature;
+ if (aResult.get())
+ aFeature = ModelAPI_Feature::feature(aResult);
+ else
+ aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+
+
+ std::set<AttributePtr> aSelectedAttributes;
+ std::set<ResultPtr> aSelectedResults;
+ if (myCurrentSelection.find(aFeature) != myCurrentSelection.end()) {
+ std::pair<std::set<AttributePtr>, std::set<ResultPtr> > aPair = myCurrentSelection.find(aFeature).value();
+ aSelectedAttributes = aPair.first;
+ aSelectedResults = aPair.second;
+ }
+
+ Handle(SelectMgr_EntityOwner) anOwner = aPrs->owner();
+ if (aResult.get()) {
+ getAttributesOrResults(anOwner, aFeature, aSketch, aResult,
+ aSelectedAttributes, aSelectedResults);
+ }
+ else {
+ std::list<ResultPtr> aResults = aFeature->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+ ResultPtr aResult = *aIt;
+ getAttributesOrResults(anOwner, aFeature, aSketch, aResult,
+ aSelectedAttributes, aSelectedResults);
+ }
+ }
+ myCurrentSelection[aFeature] = std::make_pair(aSelectedAttributes, aSelectedResults);
+ }
+ //qDebug(QString(" storeSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());
+}
+
+void PartSet_SketcherMgr::restoreSelection()
+{
+ if (!myCurrentSketch.get())
+ return;
+
+ //qDebug(QString("restoreSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+ FeatureToSelectionMap::const_iterator aSIt = myCurrentSelection.begin(),
+ aSLast = myCurrentSelection.end();
+ SelectMgr_IndexedMapOfOwner anOwnersToSelect;
+ for (; aSIt != aSLast; aSIt++) {
+ anOwnersToSelect.Clear();
+ getSelectionOwners(aSIt.key(), myCurrentSketch, aWorkshop, myCurrentSelection,
+ anOwnersToSelect);
+ aConnector->workshop()->selector()->setSelectedOwners(anOwnersToSelect, false);
+ }
+}
+
+void PartSet_SketcherMgr::onShowConstraintsToggle(int theType, bool theState)
+{
+ PartSet_Tools::ConstraintVisibleState aType = (PartSet_Tools::ConstraintVisibleState)theType;
+
+ updateBySketchParameters(aType, theState);
+}
+
+void PartSet_SketcherMgr::updateBySketchParameters(
+ const PartSet_Tools::ConstraintVisibleState& theType,
+ bool theState)
+{
+ if (myCurrentSketch.get() == NULL)
+ return;
+
+ bool aPrevState = myIsConstraintsShown[theType];
+ myIsConstraintsShown[theType] = theState;
+
+ switch (theType) {
+ case PartSet_Tools::Geometrical:
+ case PartSet_Tools::Dimensional: {
+ if (aPrevState != theState) {
+ ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+ for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+ FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);
+ bool aProcessed = false;
+ bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, theType, aProcessed);
+ if (aProcessed)
+ aSubFeature->setDisplayed(aConstraintDisplayed);
+ }
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ }
+ }
+ break;
+ case PartSet_Tools::Expressions: {
+ if (aPrevState != theState) {
+ /// call all sketch features redisplay, the expression state will be corrected in customize
+ /// of distance presentation
+ Events_ID anEventId = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ PartSet_Tools::sendSubFeaturesEvent(myCurrentSketch, anEventId);
+ }
+ }
+ break;
+ }
+}
+
+void PartSet_SketcherMgr::updateSelectionPriority(ObjectPtr theObject,
+ FeaturePtr theFeature)
+{
+ if (!theObject.get() || !theFeature.get())
+ return;
+
+ AISObjectPtr anAIS = workshop()->displayer()->getAISObject(theObject);
+ Handle(AIS_InteractiveObject) anAISIO;
+ if (anAIS.get() != NULL) {
+ anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+ }
+
+ if (!anAISIO.IsNull()) { // the presentation for the object is visualized
+ int anAdditionalPriority = 0;
+ // current feature
+ std::shared_ptr<SketchPlugin_Feature> aSPFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
+ if (aSPFeature.get() != NULL) {
+ // 1. Vertices
+ // 2. Simple segments
+ // 3. External objects (violet color)
+ // 4. Auxiliary segments (dotted)
+ // StdSelect_BRepSelectionTool::Load uses priority calculating:
+ // Standard_Integer aPriority = (thePriority == -1) ? GetStandardPriority (theShape, theType) : thePriority;
+ // Priority of Vertex is 8, edge(segment) is 7.
+ // It might be not corrected as provides the condition above.
+ bool isExternal = aSPFeature->isExternal();
+ bool isAuxiliary = PartSet_Tools::isAuxiliarySketchEntity(aSPFeature);
+ // current feature
+ if (!isExternal && !isAuxiliary)
+ anAdditionalPriority = 30;
+ // external feature
+ if (isExternal)
+ anAdditionalPriority = 20;
+ // auxiliary feature
+ if (isAuxiliary) {
+ anAdditionalPriority = 10; /// auxiliary objects should have less priority that
+ // edges/vertices of local selection on not-sketch objects
+ }
+ Handle(ModuleBase_ResultPrs) aResult = Handle(ModuleBase_ResultPrs)::DownCast(anAISIO);
+ if (!aResult.IsNull()) {
+ aResult->setAdditionalSelectionPriority(anAdditionalPriority);
+ }
+ }
+ }
+}
+
+XGUI_Workshop* PartSet_SketcherMgr::workshop() const
+{
+ ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
+ return aConnector->workshop();
+}
+
+XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const
+{
+ return workshop()->operationMgr();
+}
+
/// before restarting of operation we need to clear selection, as it may take part in
/// new feature creation, e.g. tangent arc. But it is not necessary as it was processed
/// by mouse release when the operation was restarted.
- workshop()->selector()->clearSelection();\r
+ workshop()->selector()->clearSelection();
myPreviousFeature = aFOperation->feature();
restartOperation();
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->\r
-\r
-// File: XGUI_OperationMgr.cpp\r
-// Created: 20 Apr 2014\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#include "XGUI_OperationMgr.h"\r
-#include "XGUI_ModuleConnector.h"\r
-#include "XGUI_Workshop.h"\r
-#include "XGUI_ErrorMgr.h"\r
-#include "XGUI_Tools.h"\r
-#include "XGUI_ObjectsBrowser.h"\r
-#include "XGUI_ContextMenuMgr.h"\r
-\r
-#include <ModuleBase_IPropertyPanel.h>\r
-#include <ModuleBase_ModelWidget.h>\r
-#include "ModuleBase_Operation.h"\r
-#include "ModuleBase_IWorkshop.h"\r
-#include "ModuleBase_IModule.h"\r
-#include <ModuleBase_IViewer.h>\r
-#include "ModuleBase_OperationDescription.h"\r
-#include "ModuleBase_OperationFeature.h"\r
-#include "ModuleBase_Tools.h"\r
-\r
-#include "ModelAPI_CompositeFeature.h"\r
-#include "ModelAPI_Session.h"\r
-\r
-#include <XGUI_PropertyPanel.h>\r
-#include <QToolButton>\r
-#include <QLineEdit>\r
-\r
-#include <QMessageBox>\r
-#include <QApplication>\r
-#include <QKeyEvent>\r
-\r
-//#define DEBUG_CURRENT_FEATURE\r
-\r
-/// Processes "Delete" key event of application. This key is used by several application actions.\r
-/// There is a logical order of the actions processing. So the key can not be set for actions\r
-/// as a shortcut. The class listens the key event and call operation manager processor.\r
-class XGUI_ShortCutListener : public QObject\r
-{\r
-public:\r
- /// Constructor\r
- /// \param theParent the parent to be deleted when the parent is deleted\r
- /// \param theOperationMgr the class to perform deletion\r
- XGUI_ShortCutListener(QObject* theParent, XGUI_OperationMgr* theOperationMgr)\r
- : QObject(theParent), myOperationMgr(theOperationMgr)\r
- {\r
- qApp->installEventFilter(this);\r
- }\r
- ~XGUI_ShortCutListener() {}\r
-\r
- /// Switch on short cut listener\r
- void setActive(const bool theIsActive) { myIsActive = theIsActive; }\r
-\r
- /// Redefinition of virtual function to process Delete key release\r
- virtual bool eventFilter(QObject *theObject, QEvent *theEvent)\r
- {\r
- bool isAccepted = false;\r
- if (myIsActive && theEvent->type() == QEvent::KeyRelease) {\r
- QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);\r
- if(aKeyEvent) {\r
- switch (aKeyEvent->key()) {\r
- case Qt::Key_Delete: {\r
- isAccepted = myOperationMgr->onProcessDelete(theObject);\r
- }\r
- }\r
- }\r
- }\r
- if (!isAccepted)\r
- isAccepted = QObject::eventFilter(theObject, theEvent);\r
- return isAccepted;\r
- }\r
-\r
-private:\r
- XGUI_OperationMgr* myOperationMgr; /// processor for key event\r
- bool myIsActive; /// boolean state whether the event filter perform own signal processing\r
-};\r
-\r
-XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent,\r
- ModuleBase_IWorkshop* theWorkshop)\r
-: QObject(theParent), myWorkshop(theWorkshop)\r
-{\r
- /// we need to install filter to the application in order to react to 'Delete' key button\r
- /// this key can not be a short cut for a corresponded action because we need to set\r
- /// the actions priority\r
- myShortCutListener = new XGUI_ShortCutListener(theParent, this);\r
-}\r
-\r
-XGUI_OperationMgr::~XGUI_OperationMgr()\r
-{\r
-}\r
-\r
-void XGUI_OperationMgr::activate()\r
-{\r
- myShortCutListener->setActive(true);\r
-}\r
-\r
-void XGUI_OperationMgr::deactivate()\r
-{\r
- myShortCutListener->setActive(false);\r
-}\r
-\r
-ModuleBase_Operation* XGUI_OperationMgr::currentOperation() const\r
-{\r
- return myOperations.count() > 0 ? myOperations.last() : 0;\r
-}\r
-\r
-bool XGUI_OperationMgr::isCurrentOperation(ModuleBase_Operation* theOperation)\r
-{\r
- if(!hasOperation())\r
- return false;\r
- return currentOperation() == theOperation;\r
-}\r
-\r
-bool XGUI_OperationMgr::hasOperation() const\r
-{\r
- return !myOperations.isEmpty() && (myOperations.last() != NULL);\r
-}\r
-\r
-bool XGUI_OperationMgr::hasOperation(const QString& theId) const\r
-{\r
- foreach(ModuleBase_Operation* aOp, myOperations) {\r
- if (aOp->id() == theId)\r
- return true;\r
- }\r
- return false;\r
-}\r
-\r
-ModuleBase_Operation* XGUI_OperationMgr::findOperation(const QString& theId) const\r
-{\r
- QList<ModuleBase_Operation*>::const_iterator anIt = myOperations.end();\r
- while (anIt != myOperations.begin()) {\r
- --anIt;\r
- ModuleBase_Operation* anOperation = *anIt;\r
- if (anOperation->id() == theId)\r
- return anOperation;\r
- }\r
- return 0;\r
-}\r
-\r
-\r
-int XGUI_OperationMgr::operationsCount() const\r
-{\r
- return myOperations.count();\r
-}\r
-\r
-QStringList XGUI_OperationMgr::operationList() const\r
-{\r
- QStringList result;\r
- foreach(ModuleBase_Operation* eachOperation, myOperations) {\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(eachOperation);\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- if(aFeature) {\r
- result << QString::fromStdString(aFeature->getKind());\r
- }\r
- }\r
- }\r
- return result;\r
-}\r
-\r
-ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation* theOperation) const\r
-{\r
- int idx = myOperations.lastIndexOf(theOperation);\r
- if(idx == -1 || idx == 0) {\r
- return NULL;\r
- }\r
- return myOperations.at(idx - 1);\r
-}\r
-\r
-bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)\r
-{\r
- bool isAccepted = false;\r
- if (theEvent->type() == QEvent::KeyRelease) {\r
- QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);\r
- if(aKeyEvent)\r
- isAccepted = onKeyReleased(theObject, aKeyEvent);\r
- }\r
- if (!isAccepted)\r
- isAccepted = QObject::eventFilter(theObject, theEvent);\r
-\r
- return isAccepted;\r
-}\r
-\r
-bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)\r
-{\r
- if (hasOperation())\r
- currentOperation()->postpone();\r
- myOperations.append(theOperation);\r
-\r
- connect(theOperation, SIGNAL(beforeStarted()), SLOT(onBeforeOperationStarted()));\r
- connect(theOperation, SIGNAL(beforeAborted()), SLOT(onBeforeOperationAborted()));\r
- connect(theOperation, SIGNAL(beforeCommitted()), SLOT(onBeforeOperationCommitted()));\r
-\r
- connect(theOperation, SIGNAL(started()), SLOT(onOperationStarted()));\r
- connect(theOperation, SIGNAL(aborted()), SLOT(onOperationAborted()));\r
- connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted()));\r
-\r
- connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped()));\r
- connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed()));\r
-\r
- bool isStarted = theOperation->start();\r
- if (isStarted)\r
- onValidateOperation();\r
- return isStarted;\r
-}\r
-\r
-bool XGUI_OperationMgr::abortAllOperations()\r
-{\r
- bool aResult = true;\r
- if(!hasOperation())\r
- return aResult;\r
-\r
- if (operationsCount() == 1) {\r
- ModuleBase_Operation* aCurrentOperation = currentOperation();\r
- if (canStopOperation(aCurrentOperation)) {\r
- abortOperation(aCurrentOperation);\r
- }\r
- else\r
- aResult = false;\r
- }\r
- else {\r
- aResult = QMessageBox::question(qApp->activeWindow(),\r
- tr("Abort operation"),\r
- tr("All active operations will be aborted."),\r
- QMessageBox::Ok | QMessageBox::Cancel,\r
- QMessageBox::Cancel) == QMessageBox::Ok;\r
- while(aResult && hasOperation()) {\r
- abortOperation(currentOperation());\r
- }\r
- }\r
- return aResult;\r
-}\r
-\r
-bool XGUI_OperationMgr::commitAllOperations()\r
-{\r
- bool isCompositeCommitted = false, anOperationProcessed = false;\r
- while (hasOperation()) {\r
- ModuleBase_Operation* anOperation = currentOperation();\r
- if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {\r
- anOperationProcessed = onCommitOperation();\r
- } else {\r
- abortOperation(anOperation);\r
- anOperationProcessed = true;\r
- }\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (anOperation);\r
- if (aFOperation) {\r
- FeaturePtr aFeature = aFOperation->feature();\r
- CompositeFeaturePtr aComposite = \r
- std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);\r
- isCompositeCommitted = aComposite.get();\r
- if (isCompositeCommitted)\r
- break;\r
- }\r
- // not processed[committed] operation might be used in composite feature,\r
- // so the while will be stopped by the previous check.\r
- // this code is not necessary, but logically should be done when the processing will not\r
- // be done for not composite feature by some reasons\r
- if (!anOperationProcessed)\r
- break;\r
- }\r
- return true;\r
-}\r
-\r
-void XGUI_OperationMgr::onValidateOperation()\r
-{\r
- if (!hasOperation())\r
- return;\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>\r
- (currentOperation());\r
- if(aFOperation && aFOperation->feature().get())\r
- XGUI_Tools::workshop(myWorkshop)->errorMgr()->updateActions(aFOperation->feature());\r
-}\r
-\r
-void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperation)\r
-{\r
- XGUI_ErrorMgr* anErrorMgr = XGUI_Tools::workshop(myWorkshop)->errorMgr();\r
- if (theOperation) {\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);\r
- if (aFOperation)\r
- anErrorMgr->updateAcceptAllAction(aFOperation->feature());\r
- }\r
- else {\r
- foreach(ModuleBase_Operation* anOperation, myOperations) {\r
- if (anOperation)\r
- updateApplyOfOperations(anOperation);\r
- }\r
- }\r
- // Apply button of the current operation should also be updated\r
- onValidateOperation();\r
-}\r
-\r
-bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)\r
-{\r
- //in case of nested (sketch) operation no confirmation needed\r
- if (isGrantedOperation(theOperation->id()))\r
- return true;\r
- if (theOperation && theOperation->isModified()) {\r
- QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());\r
- int anAnswer = QMessageBox::question(qApp->activeWindow(),\r
- tr("Abort operation"),\r
- aMessage,\r
- QMessageBox::Ok | QMessageBox::Cancel,\r
- QMessageBox::Cancel);\r
- return anAnswer == QMessageBox::Ok;\r
- }\r
- return true;\r
-}\r
-\r
-bool XGUI_OperationMgr::commitOperation()\r
-{\r
- //if (hasOperation() && currentOperation()->isValid()) {\r
- // onCommitOperation();\r
- // return true;\r
- //}\r
- //return false;\r
- return onCommitOperation();\r
-}\r
-\r
-void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)\r
-{\r
- theOperation->resume();\r
-}\r
-\r
-bool XGUI_OperationMgr::isGrantedOperation(const QString& theId)\r
-{\r
- bool isGranted = false;\r
-\r
- QListIterator<ModuleBase_Operation*> anIt(myOperations);\r
- anIt.toBack();\r
- ModuleBase_Operation* aPreviousOperation = 0;\r
- while (anIt.hasPrevious() && !isGranted) {\r
- ModuleBase_Operation* anOp = anIt.previous();\r
- if (anOp)\r
- isGranted = anOp->isGranted(theId);\r
- }\r
- return isGranted;\r
-}\r
-\r
-void XGUI_OperationMgr::setCurrentFeature(const FeaturePtr& theFeature)\r
-{\r
- SessionPtr aMgr = ModelAPI_Session::get();\r
- DocumentPtr aDoc = aMgr->activeDocument();\r
- bool aIsOp = aMgr->isOperation();\r
- if (!aIsOp)\r
- aMgr->startOperation(QString("Set current feature: %1").arg(theFeature->getKind().c_str()).toStdString());\r
- aDoc->setCurrentFeature(theFeature, false);\r
- if (!aIsOp)\r
- aMgr->finishOperation();\r
-}\r
-\r
-bool XGUI_OperationMgr::canStartOperation(const QString& theId)\r
-{\r
- bool aCanStart = true;\r
- ModuleBase_Operation* aCurrentOp = currentOperation();\r
- if (aCurrentOp) {\r
- bool aGranted = aCurrentOp->isGranted(theId);\r
- // the started operation is granted for the current one,\r
- // e.g. current - Sketch, started - Line\r
- if (aGranted) {\r
- aCanStart = true;\r
- }\r
- else {\r
- if (!isGrantedOperation(theId)) {\r
- // the operation is not granted in the current list of operations\r
- // e.g. Edit Parameter when Sketch, Line in Sketch is active.\r
- aCanStart = abortAllOperations();\r
- }\r
- else if (canStopOperation(aCurrentOp)) {\r
- // the started operation is granted in the parrent operation,\r
- // e.g. current - Line in Sketch, started Circle \r
- stopOperation(aCurrentOp);\r
- } else {\r
- aCanStart = false;\r
- }\r
- }\r
- }\r
- return aCanStart;\r
-}\r
-\r
-void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation)\r
-{\r
- if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && theOperation->isModified())\r
- theOperation->commit();\r
- else\r
- abortOperation(theOperation);\r
-}\r
-\r
-void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)\r
-{\r
- ModuleBase_Operation* aCurrentOperation = currentOperation();\r
- if (theOperation == aCurrentOperation)\r
- theOperation->abort();\r
- else {\r
- // it is possible to trigger upper operation(e.g. sketch, current is sketch line)\r
- // all operation from the current to triggered should also be aborted\r
- // operations over the parameter one are not aborted(e.g. extrusion cut, sketch abort)\r
- while(hasOperation()) {\r
- ModuleBase_Operation* aCurrentOperation = currentOperation();\r
- aCurrentOperation->abort();\r
- if(theOperation == aCurrentOperation)\r
- break;\r
- }\r
- }\r
-}\r
-\r
-bool XGUI_OperationMgr::onCommitOperation()\r
-{\r
- bool isCommitted = false;\r
- ModuleBase_Operation* anOperation = currentOperation();\r
- if (anOperation && myWorkshop->module()->canCommitOperation())\r
- isCommitted = anOperation->commit();\r
- return isCommitted;\r
-}\r
-\r
-void XGUI_OperationMgr::onAbortOperation()\r
-{\r
- ModuleBase_Operation* aCurrentOperation = currentOperation();\r
- if (aCurrentOperation && canStopOperation(aCurrentOperation)) {\r
- abortOperation(aCurrentOperation);\r
- }\r
-}\r
-\r
-void XGUI_OperationMgr::onBeforeOperationStarted()\r
-{\r
- ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- if (!aCurrentOperation)\r
- return;\r
-\r
- /// Set current feature and remeber old current feature\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);\r
- if (aFOperation) {\r
- SessionPtr aMgr = ModelAPI_Session::get();\r
- DocumentPtr aDoc = aMgr->activeDocument();\r
- // the parameter of current feature should be false, we should use all feature, not only visible\r
- // in order to correctly save the previous feature of the nested operation, where the\r
- // features can be not visible in the tree. The problem case is Edit sketch entitity(line)\r
- // in the Sketch, created in ExtrusionCut operation. The entity disappears by commit.\r
- // When sketch entity operation started, the sketch should be cashed here as the current.\r
- // Otherwise(the flag is true), the ExtrusionCut is cashed, when commit happens, the sketch\r
- // is disabled, sketch entity is disabled as extrusion cut is created earliest then sketch.\r
- // As a result the sketch disappears from the viewer. However after commit it is displayed back.\r
- aFOperation->setPreviousCurrentFeature(aDoc->currentFeature(false));\r
-\r
-#ifdef DEBUG_CURRENT_FEATURE\r
- FeaturePtr aFeature = aFOperation->feature();\r
- QString aKind = aFeature ? aFeature->getKind().c_str() : "";\r
- qDebug(QString("onBeforeOperationStarted(), edit operation = %1, feature = %2")\r
- .arg(aFOperation->isEditOperation())\r
- .arg(ModuleBase_Tools::objectInfo(aFeature)).toStdString().c_str());\r
-\r
- qDebug(QString("\tdocument->currentFeature(false) = %1").arg(\r
- ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());\r
-#endif\r
-\r
- if (aFOperation->isEditOperation()) {// it should be performed by the feature edit only\r
- // in create operation, the current feature is changed by addFeature()\r
- aDoc->setCurrentFeature(aFOperation->feature(), false);\r
- // this is the only place where flushes must be called after setCurrentFeature for the current\r
- // moment: after this the opertion is not finished, so, the ObjectBrowser state may be corrupted\r
- // (issue #1457)\r
- static Events_Loop* aLoop = Events_Loop::loop();\r
- static Events_ID aCreateEvent = aLoop->eventByName(EVENT_OBJECT_CREATED);\r
- aLoop->flush(aCreateEvent);\r
- static Events_ID aDeleteEvent = aLoop->eventByName(EVENT_OBJECT_DELETED);\r
- aLoop->flush(aDeleteEvent);\r
- }\r
-\r
-#ifdef DEBUG_CURRENT_FEATURE\r
- qDebug("\tdocument->setCurrentFeature");\r
- qDebug(QString("\tdocument->currentFeature(false) = %1").arg(\r
- ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());\r
-#endif\r
- }\r
-}\r
-\r
-void XGUI_OperationMgr::onOperationStarted()\r
-{\r
- ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- updateApplyOfOperations(aSenderOperation);\r
- XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);\r
- aWorkshop->operationStarted(aSenderOperation);\r
-}\r
-\r
-void XGUI_OperationMgr::onBeforeOperationAborted()\r
-{\r
- onBeforeOperationCommitted();\r
-}\r
-\r
-void XGUI_OperationMgr::onOperationAborted()\r
-{\r
- ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- emit operationAborted(aSenderOperation);\r
-}\r
-\r
-void XGUI_OperationMgr::onBeforeOperationCommitted()\r
-{\r
- ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- if (!aCurrentOperation)\r
- return;\r
-\r
- /// Restore the previous current feature\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);\r
- if (aFOperation) {\r
-#ifdef DEBUG_CURRENT_FEATURE\r
- QString aKind = aFOperation->feature()->getKind().c_str();\r
- qDebug(QString("onBeforeOperationCommitted(), edit operation = %1, feature = %2")\r
- .arg(aFOperation->isEditOperation())\r
- .arg(ModuleBase_Tools::objectInfo(aFOperation->feature())).toStdString().c_str());\r
-\r
- qDebug(QString("\tdocument->currentFeature(false) = %1").arg(\r
- ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());\r
-#endif\r
-\r
- if (aFOperation->isEditOperation()) {\r
- /// Restore the previous current feature\r
- setCurrentFeature(aFOperation->previousCurrentFeature());\r
- }\r
- else { // create operation\r
- // the Top created feature should stays the current. In nested operations, like Line in the Sketch or\r
- // Sketch in ExtrusionCut, a previous feature should be restored on commit. It is performed here\r
- // in order to perform it in the current transaction without opening a new one.\r
- if (myOperations.front() != aFOperation)\r
- setCurrentFeature(aFOperation->previousCurrentFeature());\r
- }\r
-#ifdef DEBUG_CURRENT_FEATURE\r
- qDebug("\tdocument->setCurrentFeature");\r
- qDebug(QString("\tdocument->currentFeature(false) = %1").arg(\r
- ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());\r
-#endif\r
- ModuleBase_IModule* aModule = myWorkshop->module();\r
- if (aModule)\r
- aModule->beforeOperationStopped(aFOperation);\r
- }\r
-}\r
-\r
-void XGUI_OperationMgr::onOperationCommitted()\r
-{\r
- // apply state for all features from the stack of operations should be updated\r
- updateApplyOfOperations();\r
-\r
- ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- emit operationCommitted(aSenderOperation);\r
-}\r
-\r
-void XGUI_OperationMgr::onOperationResumed()\r
-{\r
- ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- emit operationResumed(aSenderOperation);\r
-}\r
-\r
-void XGUI_OperationMgr::onOperationStopped()\r
-{\r
- ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());\r
- ModuleBase_Operation* aCurrentOperation = currentOperation();\r
- if (!aSenderOperation || !aCurrentOperation || aSenderOperation != aCurrentOperation)\r
- return;\r
-\r
- myOperations.removeAll(aCurrentOperation);\r
- aCurrentOperation->deleteLater();\r
-\r
- emit operationStopped(aCurrentOperation);\r
-\r
- // get last operation which can be resumed\r
- ModuleBase_Operation* aResultOp = 0;\r
- QListIterator<ModuleBase_Operation*> anIt(myOperations);\r
- anIt.toBack();\r
- while (anIt.hasPrevious()) {\r
- ModuleBase_Operation* anOp = anIt.previous();\r
- if (anOp) {\r
- aResultOp = anOp;\r
- break;\r
- }\r
- }\r
- if (aResultOp) {\r
- bool isModified = aCurrentOperation->isModified();\r
- aResultOp->setIsModified(aResultOp->isModified() || isModified);\r
- resumeOperation(aResultOp);\r
- onValidateOperation();\r
- }\r
-}\r
-\r
-bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent)\r
-{\r
- // Let the manager decide what to do with the given key combination.\r
- ModuleBase_Operation* anOperation = currentOperation();\r
- bool isAccepted = false;\r
- switch (theEvent->key()) {\r
- case Qt::Key_Return:\r
- case Qt::Key_Enter: {\r
- isAccepted = onProcessEnter(theObject);\r
- }\r
- break;\r
- case Qt::Key_N:\r
- case Qt::Key_P: {\r
- bool noModifiers = (theEvent->modifiers() == Qt::NoModifier);\r
- if (noModifiers) {\r
- ModuleBase_IViewer* aViewer = myWorkshop->viewer();\r
- Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();\r
- if (!aContext.IsNull()) {\r
- Handle(V3d_View) aView = aViewer->activeView();\r
- if ((theEvent->key() == Qt::Key_N))\r
- aContext->HilightNextDetected(aView);\r
- else if ((theEvent->key() == Qt::Key_P))\r
- aContext->HilightPreviousDetected(aView);\r
- }\r
- }\r
- }\r
- break;\r
- break;\r
- default:\r
- isAccepted = false;\r
- break;\r
- }\r
- //if(anOperation) {\r
- // anOperation->keyReleased(theEvent->key());\r
- //}\r
- return isAccepted;\r
-}\r
-\r
-bool XGUI_OperationMgr::onProcessEnter(QObject* theObject)\r
-{\r
- bool isAccepted = false;\r
- ModuleBase_Operation* aOperation = currentOperation();\r
- // to avoid enter processing when operation has not been started yet\r
- if (!aOperation)\r
- return isAccepted;\r
- ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();\r
- // only property panel enter is processed in order to do not process enter in application dialogs\r
- bool isPPChild = isChildObject(theObject, aPanel);\r
- if (!isPPChild)\r
- return isAccepted;\r
-\r
- ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();\r
- bool isAborted = false;\r
- if (!anActiveWgt) {\r
- QWidget* aFocusWidget = aPanel->focusWidget();\r
- QToolButton* aCancelBtn = dynamic_cast<XGUI_PropertyPanel*>(aPanel)->findButton(PROP_PANEL_CANCEL);\r
- if (aFocusWidget && aCancelBtn && aFocusWidget == aCancelBtn) {\r
- abortOperation(aOperation);\r
- isAccepted = true;\r
- isAborted = true;\r
- }\r
- }\r
- if (!isAborted) {\r
- isAccepted = anActiveWgt && anActiveWgt->processEnter();\r
- if (!isAccepted) {\r
- isAccepted = myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");\r
- if (!isAccepted) {\r
- /// functionality is similar to Apply click\r
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());\r
- if (!aFOperation || myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) {\r
- // key released is emitted to apply the current value to the model if it was modified in PP\r
- emit keyEnterReleased();\r
- commitOperation();\r
- isAccepted = true;\r
- }\r
- else\r
- isAccepted = false;\r
- }\r
- }\r
- }\r
- return isAccepted;\r
-}\r
-\r
-bool editorControl(QObject* theObject)\r
-{\r
- QLineEdit* aLineEdit = dynamic_cast<QLineEdit*>(theObject);\r
- return aLineEdit;\r
-}\r
-\r
-bool XGUI_OperationMgr::onProcessDelete(QObject* theObject)\r
-{\r
- bool isAccepted = false;\r
- ModuleBase_Operation* aOperation = currentOperation();\r
- ModuleBase_ModelWidget* anActiveWgt = 0;\r
- // firstly the widget should process Delete action\r
- ModuleBase_IPropertyPanel* aPanel;\r
- bool isPPChildObject = false;\r
- if (aOperation) {\r
- aPanel = aOperation->propertyPanel();\r
- if (aPanel) {\r
- isPPChildObject = isChildObject(theObject, aPanel);\r
- // process delete in active widget only if delete sender is child of property panel\r
- // it is necessary for the case when OB is shown, user perform selection and click Delete\r
- if (isPPChildObject) {\r
- anActiveWgt = aPanel->activeWidget();\r
- if (anActiveWgt) {\r
- isAccepted = anActiveWgt->processDelete();\r
- }\r
- }\r
- }\r
- }\r
- if (!isAccepted) {\r
- // after widget, object browser and viewer should process delete\r
- /// other widgets such as line edit controls should not lead to\r
- /// processing delete by workshop\r
- XGUI_ObjectsBrowser* aBrowser = XGUI_Tools::workshop(myWorkshop)->objectBrowser();\r
- QWidget* aViewPort = myWorkshop->viewer()->activeViewPort();\r
- bool isToDeleteObject = false;\r
- XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);\r
- XGUI_ContextMenuMgr* aContextMenuMgr = aWorkshop->contextMenuMgr();\r
- if (theObject == aBrowser->treeView()) {\r
- aContextMenuMgr->updateObjectBrowserMenu();\r
- isToDeleteObject = aContextMenuMgr->action("DELETE_CMD")->isEnabled();\r
- }\r
- else if (isChildObject(theObject, aViewPort)) {\r
- aContextMenuMgr->updateViewerMenu();\r
- isToDeleteObject = aContextMenuMgr->action("DELETE_CMD")->isEnabled();\r
- }\r
- else if (isPPChildObject) {\r
- // property panel child object is processed to process delete performed on Apply button of PP\r
- isToDeleteObject = true;\r
- }\r
- else if (editorControl(theObject)) {\r
- isToDeleteObject = false; /// Line Edit of Rename operation in ObjectBrowser\r
- isAccepted = true;\r
- }\r
-\r
- if (isToDeleteObject) {\r
- aWorkshop->deleteObjects();\r
- isAccepted = true;\r
- }\r
- }\r
-\r
- return isAccepted;\r
-}\r
-\r
-bool XGUI_OperationMgr::isChildObject(const QObject* theObject, const QObject* theParent)\r
-{\r
- bool isPPChild = false;\r
- if (theParent && theObject) {\r
- QObject* aParent = (QObject*)theObject;\r
- while (aParent ) {\r
- isPPChild = aParent == theParent;\r
- if (isPPChild)\r
- break;\r
- aParent = aParent->parent();\r
- }\r
- }\r
- return isPPChild;\r
-}\r
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: XGUI_OperationMgr.cpp
+// Created: 20 Apr 2014
+// Author: Natalia ERMOLAEVA
+
+#include "XGUI_OperationMgr.h"
+#include "XGUI_ModuleConnector.h"
+#include "XGUI_Workshop.h"
+#include "XGUI_ErrorMgr.h"
+#include "XGUI_Tools.h"
+#include "XGUI_ObjectsBrowser.h"
+#include "XGUI_ContextMenuMgr.h"
+
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ModelWidget.h>
+#include "ModuleBase_Operation.h"
+#include "ModuleBase_IWorkshop.h"
+#include "ModuleBase_IModule.h"
+#include <ModuleBase_IViewer.h>
+#include "ModuleBase_OperationDescription.h"
+#include "ModuleBase_OperationFeature.h"
+#include "ModuleBase_Tools.h"
+
+#include "ModelAPI_CompositeFeature.h"
+#include "ModelAPI_Session.h"
+
+#include <XGUI_PropertyPanel.h>
+#include <QToolButton>
+#include <QLineEdit>
+
+#include <QMessageBox>
+#include <QApplication>
+#include <QKeyEvent>
+
+//#define DEBUG_CURRENT_FEATURE
+
+/// Processes "Delete" key event of application. This key is used by several application actions.
+/// There is a logical order of the actions processing. So the key can not be set for actions
+/// as a shortcut. The class listens the key event and call operation manager processor.
+class XGUI_ShortCutListener : public QObject
+{
+public:
+ /// Constructor
+ /// \param theParent the parent to be deleted when the parent is deleted
+ /// \param theOperationMgr the class to perform deletion
+ XGUI_ShortCutListener(QObject* theParent, XGUI_OperationMgr* theOperationMgr)
+ : QObject(theParent), myOperationMgr(theOperationMgr)
+ {
+ qApp->installEventFilter(this);
+ }
+ ~XGUI_ShortCutListener() {}
+
+ /// Switch on short cut listener
+ void setActive(const bool theIsActive) { myIsActive = theIsActive; }
+
+ /// Redefinition of virtual function to process Delete key release
+ virtual bool eventFilter(QObject *theObject, QEvent *theEvent)
+ {
+ bool isAccepted = false;
+ if (myIsActive && theEvent->type() == QEvent::KeyRelease) {
+ QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
+ if(aKeyEvent) {
+ switch (aKeyEvent->key()) {
+ case Qt::Key_Delete: {
+ isAccepted = myOperationMgr->onProcessDelete(theObject);
+ }
+ }
+ }
+ }
+ if (!isAccepted)
+ isAccepted = QObject::eventFilter(theObject, theEvent);
+ return isAccepted;
+ }
+
+private:
+ XGUI_OperationMgr* myOperationMgr; /// processor for key event
+ bool myIsActive; /// boolean state whether the event filter perform own signal processing
+};
+
+XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent,
+ ModuleBase_IWorkshop* theWorkshop)
+: QObject(theParent), myWorkshop(theWorkshop)
+{
+ /// we need to install filter to the application in order to react to 'Delete' key button
+ /// this key can not be a short cut for a corresponded action because we need to set
+ /// the actions priority
+ myShortCutListener = new XGUI_ShortCutListener(theParent, this);
+}
+
+XGUI_OperationMgr::~XGUI_OperationMgr()
+{
+}
+
+void XGUI_OperationMgr::activate()
+{
+ myShortCutListener->setActive(true);
+}
+
+void XGUI_OperationMgr::deactivate()
+{
+ myShortCutListener->setActive(false);
+}
+
+ModuleBase_Operation* XGUI_OperationMgr::currentOperation() const
+{
+ return myOperations.count() > 0 ? myOperations.last() : 0;
+}
+
+bool XGUI_OperationMgr::isCurrentOperation(ModuleBase_Operation* theOperation)
+{
+ if(!hasOperation())
+ return false;
+ return currentOperation() == theOperation;
+}
+
+bool XGUI_OperationMgr::hasOperation() const
+{
+ return !myOperations.isEmpty() && (myOperations.last() != NULL);
+}
+
+bool XGUI_OperationMgr::hasOperation(const QString& theId) const
+{
+ foreach(ModuleBase_Operation* aOp, myOperations) {
+ if (aOp->id() == theId)
+ return true;
+ }
+ return false;
+}
+
+ModuleBase_Operation* XGUI_OperationMgr::findOperation(const QString& theId) const
+{
+ QList<ModuleBase_Operation*>::const_iterator anIt = myOperations.end();
+ while (anIt != myOperations.begin()) {
+ --anIt;
+ ModuleBase_Operation* anOperation = *anIt;
+ if (anOperation->id() == theId)
+ return anOperation;
+ }
+ return 0;
+}
+
+
+int XGUI_OperationMgr::operationsCount() const
+{
+ return myOperations.count();
+}
+
+QStringList XGUI_OperationMgr::operationList() const
+{
+ QStringList result;
+ foreach(ModuleBase_Operation* eachOperation, myOperations) {
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(eachOperation);
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ if(aFeature) {
+ result << QString::fromStdString(aFeature->getKind());
+ }
+ }
+ }
+ return result;
+}
+
+ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation* theOperation) const
+{
+ int idx = myOperations.lastIndexOf(theOperation);
+ if(idx == -1 || idx == 0) {
+ return NULL;
+ }
+ return myOperations.at(idx - 1);
+}
+
+bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
+{
+ bool isAccepted = false;
+ if (theEvent->type() == QEvent::KeyRelease) {
+ QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
+ if(aKeyEvent)
+ isAccepted = onKeyReleased(theObject, aKeyEvent);
+ }
+ if (!isAccepted)
+ isAccepted = QObject::eventFilter(theObject, theEvent);
+
+ return isAccepted;
+}
+
+bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
+{
+ if (hasOperation())
+ currentOperation()->postpone();
+ myOperations.append(theOperation);
+
+ connect(theOperation, SIGNAL(beforeStarted()), SLOT(onBeforeOperationStarted()));
+ connect(theOperation, SIGNAL(beforeAborted()), SLOT(onBeforeOperationAborted()));
+ connect(theOperation, SIGNAL(beforeCommitted()), SLOT(onBeforeOperationCommitted()));
+
+ connect(theOperation, SIGNAL(started()), SLOT(onOperationStarted()));
+ connect(theOperation, SIGNAL(aborted()), SLOT(onOperationAborted()));
+ connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted()));
+
+ connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped()));
+ connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed()));
+
+ bool isStarted = theOperation->start();
+ if (isStarted)
+ onValidateOperation();
+ return isStarted;
+}
+
+bool XGUI_OperationMgr::abortAllOperations()
+{
+ bool aResult = true;
+ if(!hasOperation())
+ return aResult;
+
+ if (operationsCount() == 1) {
+ ModuleBase_Operation* aCurrentOperation = currentOperation();
+ if (canStopOperation(aCurrentOperation)) {
+ abortOperation(aCurrentOperation);
+ }
+ else
+ aResult = false;
+ }
+ else {
+ aResult = QMessageBox::question(qApp->activeWindow(),
+ tr("Abort operation"),
+ tr("All active operations will be aborted."),
+ QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel) == QMessageBox::Ok;
+ while(aResult && hasOperation()) {
+ abortOperation(currentOperation());
+ }
+ }
+ return aResult;
+}
+
+bool XGUI_OperationMgr::commitAllOperations()
+{
+ bool isCompositeCommitted = false, anOperationProcessed = false;
+ while (hasOperation()) {
+ ModuleBase_Operation* anOperation = currentOperation();
+ if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {
+ anOperationProcessed = onCommitOperation();
+ } else {
+ abortOperation(anOperation);
+ anOperationProcessed = true;
+ }
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (anOperation);
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ CompositeFeaturePtr aComposite =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+ isCompositeCommitted = aComposite.get();
+ if (isCompositeCommitted)
+ break;
+ }
+ // not processed[committed] operation might be used in composite feature,
+ // so the while will be stopped by the previous check.
+ // this code is not necessary, but logically should be done when the processing will not
+ // be done for not composite feature by some reasons
+ if (!anOperationProcessed)
+ break;
+ }
+ return true;
+}
+
+void XGUI_OperationMgr::onValidateOperation()
+{
+ if (!hasOperation())
+ return;
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (currentOperation());
+ if(aFOperation && aFOperation->feature().get())
+ XGUI_Tools::workshop(myWorkshop)->errorMgr()->updateActions(aFOperation->feature());
+}
+
+void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperation)
+{
+ XGUI_ErrorMgr* anErrorMgr = XGUI_Tools::workshop(myWorkshop)->errorMgr();
+ if (theOperation) {
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+ if (aFOperation)
+ anErrorMgr->updateAcceptAllAction(aFOperation->feature());
+ }
+ else {
+ foreach(ModuleBase_Operation* anOperation, myOperations) {
+ if (anOperation)
+ updateApplyOfOperations(anOperation);
+ }
+ }
+ // Apply button of the current operation should also be updated
+ onValidateOperation();
+}
+
+bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
+{
+ //in case of nested (sketch) operation no confirmation needed
+ if (isGrantedOperation(theOperation->id()))
+ return true;
+ if (theOperation && theOperation->isModified()) {
+ QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
+ int anAnswer = QMessageBox::question(qApp->activeWindow(),
+ tr("Abort operation"),
+ aMessage,
+ QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+ return anAnswer == QMessageBox::Ok;
+ }
+ return true;
+}
+
+bool XGUI_OperationMgr::commitOperation()
+{
+ //if (hasOperation() && currentOperation()->isValid()) {
+ // onCommitOperation();
+ // return true;
+ //}
+ //return false;
+ return onCommitOperation();
+}
+
+void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
+{
+ theOperation->resume();
+}
+
+bool XGUI_OperationMgr::isGrantedOperation(const QString& theId)
+{
+ bool isGranted = false;
+
+ QListIterator<ModuleBase_Operation*> anIt(myOperations);
+ anIt.toBack();
+ ModuleBase_Operation* aPreviousOperation = 0;
+ while (anIt.hasPrevious() && !isGranted) {
+ ModuleBase_Operation* anOp = anIt.previous();
+ if (anOp)
+ isGranted = anOp->isGranted(theId);
+ }
+ return isGranted;
+}
+
+void XGUI_OperationMgr::setCurrentFeature(const FeaturePtr& theFeature)
+{
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ bool aIsOp = aMgr->isOperation();
+ if (!aIsOp)
+ aMgr->startOperation(QString("Set current feature: %1").arg(theFeature->getKind().c_str()).toStdString());
+ aDoc->setCurrentFeature(theFeature, false);
+ if (!aIsOp)
+ aMgr->finishOperation();
+}
+
+bool XGUI_OperationMgr::canStartOperation(const QString& theId)
+{
+ bool aCanStart = true;
+ ModuleBase_Operation* aCurrentOp = currentOperation();
+ if (aCurrentOp) {
+ bool aGranted = aCurrentOp->isGranted(theId);
+ // the started operation is granted for the current one,
+ // e.g. current - Sketch, started - Line
+ if (aGranted) {
+ aCanStart = true;
+ }
+ else {
+ if (!isGrantedOperation(theId)) {
+ // the operation is not granted in the current list of operations
+ // e.g. Edit Parameter when Sketch, Line in Sketch is active.
+ aCanStart = abortAllOperations();
+ }
+ else if (canStopOperation(aCurrentOp)) {
+ // the started operation is granted in the parrent operation,
+ // e.g. current - Line in Sketch, started Circle
+ stopOperation(aCurrentOp);
+ } else {
+ aCanStart = false;
+ }
+ }
+ }
+ return aCanStart;
+}
+
+void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation)
+{
+ if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && theOperation->isModified())
+ theOperation->commit();
+ else
+ abortOperation(theOperation);
+}
+
+void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)
+{
+ ModuleBase_Operation* aCurrentOperation = currentOperation();
+ if (theOperation == aCurrentOperation)
+ theOperation->abort();
+ else {
+ // it is possible to trigger upper operation(e.g. sketch, current is sketch line)
+ // all operation from the current to triggered should also be aborted
+ // operations over the parameter one are not aborted(e.g. extrusion cut, sketch abort)
+ while(hasOperation()) {
+ ModuleBase_Operation* aCurrentOperation = currentOperation();
+ aCurrentOperation->abort();
+ if(theOperation == aCurrentOperation)
+ break;
+ }
+ }
+}
+
+bool XGUI_OperationMgr::onCommitOperation()
+{
+ bool isCommitted = false;
+ ModuleBase_Operation* anOperation = currentOperation();
+ if (anOperation && myWorkshop->module()->canCommitOperation())
+ isCommitted = anOperation->commit();
+ return isCommitted;
+}
+
+void XGUI_OperationMgr::onAbortOperation()
+{
+ ModuleBase_Operation* aCurrentOperation = currentOperation();
+ if (aCurrentOperation && canStopOperation(aCurrentOperation)) {
+ abortOperation(aCurrentOperation);
+ }
+}
+
+void XGUI_OperationMgr::onBeforeOperationStarted()
+{
+ ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ if (!aCurrentOperation)
+ return;
+
+ /// Set current feature and remeber old current feature
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);
+ if (aFOperation) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ // the parameter of current feature should be false, we should use all feature, not only visible
+ // in order to correctly save the previous feature of the nested operation, where the
+ // features can be not visible in the tree. The problem case is Edit sketch entitity(line)
+ // in the Sketch, created in ExtrusionCut operation. The entity disappears by commit.
+ // When sketch entity operation started, the sketch should be cashed here as the current.
+ // Otherwise(the flag is true), the ExtrusionCut is cashed, when commit happens, the sketch
+ // is disabled, sketch entity is disabled as extrusion cut is created earliest then sketch.
+ // As a result the sketch disappears from the viewer. However after commit it is displayed back.
+ aFOperation->setPreviousCurrentFeature(aDoc->currentFeature(false));
+
+#ifdef DEBUG_CURRENT_FEATURE
+ FeaturePtr aFeature = aFOperation->feature();
+ QString aKind = aFeature ? aFeature->getKind().c_str() : "";
+ qDebug(QString("onBeforeOperationStarted(), edit operation = %1, feature = %2")
+ .arg(aFOperation->isEditOperation())
+ .arg(ModuleBase_Tools::objectInfo(aFeature)).toStdString().c_str());
+
+ qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
+ ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
+#endif
+
+ if (aFOperation->isEditOperation()) {// it should be performed by the feature edit only
+ // in create operation, the current feature is changed by addFeature()
+ aDoc->setCurrentFeature(aFOperation->feature(), false);
+ // this is the only place where flushes must be called after setCurrentFeature for the current
+ // moment: after this the opertion is not finished, so, the ObjectBrowser state may be corrupted
+ // (issue #1457)
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID aCreateEvent = aLoop->eventByName(EVENT_OBJECT_CREATED);
+ aLoop->flush(aCreateEvent);
+ static Events_ID aDeleteEvent = aLoop->eventByName(EVENT_OBJECT_DELETED);
+ aLoop->flush(aDeleteEvent);
+ }
+
+#ifdef DEBUG_CURRENT_FEATURE
+ qDebug("\tdocument->setCurrentFeature");
+ qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
+ ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
+#endif
+ }
+}
+
+void XGUI_OperationMgr::onOperationStarted()
+{
+ ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ updateApplyOfOperations(aSenderOperation);
+ XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
+ aWorkshop->operationStarted(aSenderOperation);
+}
+
+void XGUI_OperationMgr::onBeforeOperationAborted()
+{
+ onBeforeOperationCommitted();
+}
+
+void XGUI_OperationMgr::onOperationAborted()
+{
+ ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ emit operationAborted(aSenderOperation);
+}
+
+void XGUI_OperationMgr::onBeforeOperationCommitted()
+{
+ ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ if (!aCurrentOperation)
+ return;
+
+ /// Restore the previous current feature
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);
+ if (aFOperation) {
+#ifdef DEBUG_CURRENT_FEATURE
+ QString aKind = aFOperation->feature()->getKind().c_str();
+ qDebug(QString("onBeforeOperationCommitted(), edit operation = %1, feature = %2")
+ .arg(aFOperation->isEditOperation())
+ .arg(ModuleBase_Tools::objectInfo(aFOperation->feature())).toStdString().c_str());
+
+ qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
+ ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
+#endif
+
+ if (aFOperation->isEditOperation()) {
+ /// Restore the previous current feature
+ setCurrentFeature(aFOperation->previousCurrentFeature());
+ }
+ else { // create operation
+ // the Top created feature should stays the current. In nested operations, like Line in the Sketch or
+ // Sketch in ExtrusionCut, a previous feature should be restored on commit. It is performed here
+ // in order to perform it in the current transaction without opening a new one.
+ if (myOperations.front() != aFOperation)
+ setCurrentFeature(aFOperation->previousCurrentFeature());
+ }
+#ifdef DEBUG_CURRENT_FEATURE
+ qDebug("\tdocument->setCurrentFeature");
+ qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
+ ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
+#endif
+ ModuleBase_IModule* aModule = myWorkshop->module();
+ if (aModule)
+ aModule->beforeOperationStopped(aFOperation);
+ }
+}
+
+void XGUI_OperationMgr::onOperationCommitted()
+{
+ // apply state for all features from the stack of operations should be updated
+ updateApplyOfOperations();
+
+ ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ emit operationCommitted(aSenderOperation);
+}
+
+void XGUI_OperationMgr::onOperationResumed()
+{
+ ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ emit operationResumed(aSenderOperation);
+}
+
+void XGUI_OperationMgr::onOperationStopped()
+{
+ ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ ModuleBase_Operation* aCurrentOperation = currentOperation();
+ if (!aSenderOperation || !aCurrentOperation || aSenderOperation != aCurrentOperation)
+ return;
+
+ myOperations.removeAll(aCurrentOperation);
+ aCurrentOperation->deleteLater();
+
+ emit operationStopped(aCurrentOperation);
+
+ // get last operation which can be resumed
+ ModuleBase_Operation* aResultOp = 0;
+ QListIterator<ModuleBase_Operation*> anIt(myOperations);
+ anIt.toBack();
+ while (anIt.hasPrevious()) {
+ ModuleBase_Operation* anOp = anIt.previous();
+ if (anOp) {
+ aResultOp = anOp;
+ break;
+ }
+ }
+ if (aResultOp) {
+ bool isModified = aCurrentOperation->isModified();
+ aResultOp->setIsModified(aResultOp->isModified() || isModified);
+ resumeOperation(aResultOp);
+ onValidateOperation();
+ }
+}
+
+bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent)
+{
+ // Let the manager decide what to do with the given key combination.
+ ModuleBase_Operation* anOperation = currentOperation();
+ bool isAccepted = false;
+ switch (theEvent->key()) {
+ case Qt::Key_Return:
+ case Qt::Key_Enter: {
+ isAccepted = onProcessEnter(theObject);
+ }
+ break;
+ case Qt::Key_N:
+ case Qt::Key_P: {
+ bool noModifiers = (theEvent->modifiers() == Qt::NoModifier);
+ if (noModifiers) {
+ ModuleBase_IViewer* aViewer = myWorkshop->viewer();
+ Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+ if (!aContext.IsNull()) {
+ Handle(V3d_View) aView = aViewer->activeView();
+ if ((theEvent->key() == Qt::Key_N))
+ aContext->HilightNextDetected(aView);
+ else if ((theEvent->key() == Qt::Key_P))
+ aContext->HilightPreviousDetected(aView);
+ }
+ }
+ }
+ break;
+ break;
+ default:
+ isAccepted = false;
+ break;
+ }
+ //if(anOperation) {
+ // anOperation->keyReleased(theEvent->key());
+ //}
+ return isAccepted;
+}
+
+bool XGUI_OperationMgr::onProcessEnter(QObject* theObject)
+{
+ bool isAccepted = false;
+ ModuleBase_Operation* aOperation = currentOperation();
+ // to avoid enter processing when operation has not been started yet
+ if (!aOperation)
+ return isAccepted;
+ ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+ // only property panel enter is processed in order to do not process enter in application dialogs
+ bool isPPChild = isChildObject(theObject, aPanel);
+ if (!isPPChild)
+ return isAccepted;
+
+ ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
+ bool isAborted = false;
+ if (!anActiveWgt) {
+ QWidget* aFocusWidget = aPanel->focusWidget();
+ QToolButton* aCancelBtn = dynamic_cast<XGUI_PropertyPanel*>(aPanel)->findButton(PROP_PANEL_CANCEL);
+ if (aFocusWidget && aCancelBtn && aFocusWidget == aCancelBtn) {
+ abortOperation(aOperation);
+ isAccepted = true;
+ isAborted = true;
+ }
+ }
+ if (!isAborted) {
+ isAccepted = anActiveWgt && anActiveWgt->processEnter();
+ if (!isAccepted) {
+ isAccepted = myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");
+ if (!isAccepted) {
+ /// functionality is similar to Apply click
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());
+ if (!aFOperation || myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) {
+ // key released is emitted to apply the current value to the model if it was modified in PP
+ emit keyEnterReleased();
+ commitOperation();
+ isAccepted = true;
+ }
+ else
+ isAccepted = false;
+ }
+ }
+ }
+ return isAccepted;
+}
+
+bool editorControl(QObject* theObject)
+{
+ QLineEdit* aLineEdit = dynamic_cast<QLineEdit*>(theObject);
+ return aLineEdit;
+}
+
+bool XGUI_OperationMgr::onProcessDelete(QObject* theObject)
+{
+ bool isAccepted = false;
+ ModuleBase_Operation* aOperation = currentOperation();
+ ModuleBase_ModelWidget* anActiveWgt = 0;
+ // firstly the widget should process Delete action
+ ModuleBase_IPropertyPanel* aPanel;
+ bool isPPChildObject = false;
+ if (aOperation) {
+ aPanel = aOperation->propertyPanel();
+ if (aPanel) {
+ isPPChildObject = isChildObject(theObject, aPanel);
+ // process delete in active widget only if delete sender is child of property panel
+ // it is necessary for the case when OB is shown, user perform selection and click Delete
+ if (isPPChildObject) {
+ anActiveWgt = aPanel->activeWidget();
+ if (anActiveWgt) {
+ isAccepted = anActiveWgt->processDelete();
+ }
+ }
+ }
+ }
+ if (!isAccepted) {
+ // after widget, object browser and viewer should process delete
+ /// other widgets such as line edit controls should not lead to
+ /// processing delete by workshop
+ XGUI_ObjectsBrowser* aBrowser = XGUI_Tools::workshop(myWorkshop)->objectBrowser();
+ QWidget* aViewPort = myWorkshop->viewer()->activeViewPort();
+ bool isToDeleteObject = false;
+ XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
+ XGUI_ContextMenuMgr* aContextMenuMgr = aWorkshop->contextMenuMgr();
+ if (theObject == aBrowser->treeView()) {
+ aContextMenuMgr->updateObjectBrowserMenu();
+ isToDeleteObject = aContextMenuMgr->action("DELETE_CMD")->isEnabled();
+ }
+ else if (isChildObject(theObject, aViewPort)) {
+ aContextMenuMgr->updateViewerMenu();
+ isToDeleteObject = aContextMenuMgr->action("DELETE_CMD")->isEnabled();
+ }
+ else if (isPPChildObject) {
+ // property panel child object is processed to process delete performed on Apply button of PP
+ isToDeleteObject = true;
+ }
+ else if (editorControl(theObject)) {
+ isToDeleteObject = false; /// Line Edit of Rename operation in ObjectBrowser
+ isAccepted = true;
+ }
+
+ if (isToDeleteObject) {
+ aWorkshop->deleteObjects();
+ isAccepted = true;
+ }
+ }
+
+ return isAccepted;
+}
+
+bool XGUI_OperationMgr::isChildObject(const QObject* theObject, const QObject* theParent)
+{
+ bool isPPChild = false;
+ if (theParent && theObject) {
+ QObject* aParent = (QObject*)theObject;
+ while (aParent ) {
+ isPPChild = aParent == theParent;
+ if (isPPChild)
+ break;
+ aParent = aParent->parent();
+ }
+ }
+ return isPPChild;
+}