Salome HOME
Merge branch 'master' of salome:modules/shaper
authorVitaly SMETANNIKOV <vsv@squeezex2.nnov.opencascade.com>
Tue, 1 Nov 2016 15:28:24 +0000 (18:28 +0300)
committerVitaly SMETANNIKOV <vsv@squeezex2.nnov.opencascade.com>
Tue, 1 Nov 2016 15:28:24 +0000 (18:28 +0300)
29 files changed:
findDOSfiles.sh [new file with mode: 0755]
fixDOSfiles.sh [new file with mode: 0755]
src/Config/Config_Common.cpp
src/Config/Config_FeatureMessage.h
src/Config/Config_Keywords.h
src/Config/Config_def.h
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/ModelAPI/Test/TestUndoRedo.py
src/ModuleBase/ModuleBase.h
src/ModuleBase/ModuleBase_FilterValidated.cpp
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_ModelWidget.cpp
src/ModuleBase/ModuleBase_OperationDescription.h
src/ModuleBase/ModuleBase_WidgetConcealedObjects.cpp
src/ModuleBase/ModuleBase_WidgetConcealedObjects.h
src/ModuleBase/ModuleBase_WidgetFactory.cpp
src/ModuleBase/ModuleBase_WidgetFeatureSelector.cpp
src/ModuleBase/ModuleBase_WidgetFeatureSelector.h
src/ModuleBase/ModuleBase_WidgetSelector.h
src/ModuleBase/ModuleBase_WidgetValidated.cpp
src/ModuleBase/ModuleBase_WidgetValidated.h
src/PartSet/PartSet.h
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherReetntrantMgr.cpp
src/XGUI/XGUI_OperationMgr.cpp

diff --git a/findDOSfiles.sh b/findDOSfiles.sh
new file mode 100755 (executable)
index 0000000..dca626b
--- /dev/null
@@ -0,0 +1,27 @@
+#!/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
diff --git a/fixDOSfiles.sh b/fixDOSfiles.sh
new file mode 100755 (executable)
index 0000000..d6ac884
--- /dev/null
@@ -0,0 +1,5 @@
+#!/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
index 4184449f734a218ffedc8502dea8429d2b5a0a57..46a3f3ce1d8301422dbff62227a2cd4d3bf0ef23 100644 (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;
+}
index d2f75851360615285d3e5f9ab05171c6134258db..f82a249b5078cde292139f8bb7b9689e17397e18 100644 (file)
-// 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
index 3b8de46934afe57ec8b15d880189c178b14ed8ab..a99495114dbbe0fc85b3752f2f67d1009cb305c0 100644 (file)
-// 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_ */
index 6d0f73d9507075f949d040e48566675179804619..d572bbfd6e10e1dfd63fda44ae7a9f6d457a7ab9 100644 (file)
@@ -1,20 +1,20 @@
-// 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
index 8d05e895fee00cfdff07290363e31be772454ee1..c4049c0e25dd22ac3ace535c54f5041f7c1e9a50 100644 (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();
+}
index b682efc1c0b4a5504f6e115aeb1dbe83a1c66868..c29889567e38dae4b9a1c995b69f021b60f81966 100644 (file)
-// 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();
+}
index 223519b773c818af13b6df3c67ede67bd06a743e..d01605463efc0bd9577bc6c719b7660513927863 100644 (file)
-// 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
index 36fd94b663b4d93de166a2a712ad3c7d5ede97d2..ee9de24e129e5140d0e996d7ae456f0b0c48692c 100755 (executable)
-// 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
index 4d1c7a65f7cb2d0fa7d6395b8115befe64e0b0c7..d9c685d6e715b0ce16391a9707f2b4f9ad0c51fd 100755 (executable)
-// 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
index 3981f30d4f257df0c4604ce52f1cdb38ceefd727..db93001c300bb10faea43ccd67bf01ddff7d658f 100644 (file)
@@ -1,37 +1,37 @@
-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())
index 6152b63ec36517f13dbcacef993d583383912be2..436de02dd04df9391cdec8efdbee192c587cd7bc 100644 (file)
@@ -1,20 +1,20 @@
-// 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
index b9238538ca255e64caf0b974931386af72d6b942..097eb60cb82d4e7dc7acd52169c3ade72c17f5bd 100644 (file)
@@ -1,57 +1,57 @@
-// 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;
+}
+
index 75cd6e62aea767d8aea70b9a7f9e0746788ed713..41a37c0b47a50ac5c4c7e4d62744ac9553883c78 100755 (executable)
- // 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
index 97abfaec8f59e3438c820ac4e3a8a345fa9382e7..66d1c8c96daca4ad89f36bc567d7ed64348dd5ef 100644 (file)
-// 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);
+}
index 7de7c3288dac0b3e69684bdd98ba6d3702df7b49..3fdc27b1d32f95254e013d9cfd0053daf5a0119e 100644 (file)
@@ -1,74 +1,74 @@
-// 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
index 2e772162929e4a6bbfe9af5db63e60d1cec51526..0e5f4d9e6e939acb2590eab668109f83fc16dabc 100644 (file)
-// 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);
+}
index 5a42a775c5c465eaa0e231277f86684bdb08cac9..9cd8f092afa17768c1c596f1fcb8065e3ef4f805 100644 (file)
@@ -1,76 +1,76 @@
-// 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_ */
index c0045ec1da324153e01be47d221c1636d766195e..2812d171432748d29d7bd937528573983302288e 100644 (file)
-// 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);
+}
+
index 74da1b3af54c2d36eaad54e170b7c8be3adfa1e2..a181d9e0c4d54d9bc34b94bb9e08491b12ad2d89 100644 (file)
@@ -1,88 +1,88 @@
-// 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)
 {
@@ -101,17 +101,17 @@ void ModuleBase_WidgetFeatureSelector::deactivate()
 {
   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);
@@ -122,94 +122,94 @@ void ModuleBase_WidgetFeatureSelector::activateCustom()
   //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);
index 7e1538b19f09fc9b7d08677f477b834810d2ce68..3489a336a0fc618274cd6b7b30b9e81ddba928aa 100644 (file)
-// 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
index 11f3e474c6edf4d8b59dc12f797d193d49c20a06..3a309beb06e5fbc9850a8d083abdf859ce40c776 100755 (executable)
-// 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
index 8a3705523e62f4a036170366392f852db9836c37..daecef19f35de242812527ed9bbc41ff5ed22cdf 100644 (file)
-// 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;
+  }
+}
index 31b7b59a0982b9de0ff8221bc98e7aae7c370db7..427ecf169d63547f6e0a3f226e4db00f0875d973 100644 (file)
-// 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_ */
index e39f0e728555904a966bc7b5d78a48769878783c..fa6e6647c43a34eb6b75a486b27122499923aa4d 100644 (file)
@@ -1,20 +1,20 @@
-// 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
index 5d607f93c7dffb2dbb7ad57fdec62b78ae55aeeb..5d5a26e5b02220e96eb5c7bc8ffbb5bf3f26496c 100755 (executable)
-// 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();
+}
+
index 4cfcf167d8f49f9726c1ca2cb94d447d257c2013..5bc007456d2a4c577573406ff582b592adc27ca5 100755 (executable)
@@ -161,7 +161,7 @@ bool PartSet_SketcherReetntrantMgr::processMouseMoved(ModuleBase_IViewWindow* th
         /// 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();
index 4db8401dc3b4ea9c4106890222233bcbc6cde8cc..9eed3307496e8315865b87c16057776ce6668459 100644 (file)
-// 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;
+}