Salome HOME
#1329 arc tangent arc mode problem
[modules/shaper.git] / src / ModelAPI / ModelAPI_Tools.cpp
index 9023cb2d2d89893c4fb9bf343d2fc6ab248571a1..20df8a89d2e5a36255d32f9308de5de5ec237022 100755 (executable)
@@ -22,6 +22,20 @@ std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)
   return theResult->shape();
 }
 
+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;
@@ -38,8 +52,26 @@ std::string getFeatureError(const FeaturePtr& theFeature)
   if (anError.empty()) {
     bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone
                  || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
-    if (!isDone)
-      anError = theFeature->data()->execState();
+    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;
@@ -195,6 +227,28 @@ ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub)
   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()) {