Salome HOME
Fix for the issue #937 and crashes:
[modules/shaper.git] / src / Model / Model_Document.cpp
index d91389b3ed623237139ce6b4dd9d66c416143502..d85fb7b292b9abcbdddf464d43ece287587726ac 100644 (file)
@@ -34,6 +34,7 @@
 #include <TDF_AttributeDelta.hxx>
 #include <TDF_AttributeDeltaList.hxx>
 #include <TDF_ListIteratorOfAttributeDeltaList.hxx>
+#include <TDF_ListIteratorOfLabelList.hxx>
 
 #include <climits>
 #ifndef WIN32
@@ -67,6 +68,8 @@ Model_Document::Model_Document(const std::string theID, const std::string theKin
   // in transaction for nesting correct working
   myDoc->NewCommand();
   TDataStd_Integer::Set(myDoc->Main().Father(), 0);
+  // this to avoid creation of integer attribute outside the transaction after undo
+  transactionID();
   myDoc->CommitCommand();
 }
 
@@ -277,6 +280,7 @@ void Model_Document::close(const bool theForever)
 
   // close all only if it is really asked, otherwise it can be undoed/redoed
   if (theForever) {
+    // flush everything to avoid messages with bad objects
     delete myObjs;
     myObjs = 0;
     if (myDoc->CanClose() == CDM_CCS_OK)
@@ -395,7 +399,11 @@ static void modifiedLabels(const Handle(TDocStd_Document)& theDoc, TDF_LabelList
     aDelta = theDoc->GetRedos().First();
   else 
     aDelta = theDoc->GetUndos().Last();
-  aDelta->Labels(theDelta);
+  TDF_LabelList aDeltaList;
+  aDelta->Labels(aDeltaList); // it clears list, so, use new one and then append to the result
+  for(TDF_ListIteratorOfLabelList aListIter(aDeltaList); aListIter.More(); aListIter.Next()) {
+    theDelta.Append(aListIter.Value());
+  }
   // add also label of the modified attributes
   const TDF_AttributeDeltaList& anAttrs = aDelta->AttributeDeltas();
   for (TDF_ListIteratorOfAttributeDeltaList anAttr(anAttrs); anAttr.More(); anAttr.Next()) {
@@ -507,7 +515,7 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
       subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize);
     }
   }
-  // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
+  // after undo of all sub-documents to avoid updates on not-modified data (issue 370)
   if (theSynchronize) {
     myObjs->synchronizeFeatures(aDeltaLabels, true, isRoot());
     // update the current features status
@@ -610,7 +618,24 @@ FeaturePtr Model_Document::addFeature(std::string theID, const bool theMakeCurre
     aDocToAdd = this;
   }
   if (aFeature) {
-    aDocToAdd->myObjs->addFeature(aFeature, aDocToAdd->currentFeature(false));
+    // searching for feature after which must be added the next feature: this is the current feature
+    // but also all sub-features of this feature
+    FeaturePtr aCurrent = aDocToAdd->currentFeature(false);
+    bool isModified = true;
+    for(CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCurrent);
+        aComp.get() && isModified; 
+        aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCurrent)) {
+      isModified =  false;
+      int aSubs = aComp->numberOfSubs(false);
+      for(int a = 0; a < aSubs; a++) {
+        FeaturePtr aSub = aComp->subFeature(a, false);
+        if (myObjs->isLater(aSub, aCurrent)) {
+          isModified =  true;
+          aCurrent = aSub;
+        }
+      }
+    }
+    aDocToAdd->myObjs->addFeature(aFeature, aCurrent);
     if (!aFeature->isAction()) {  // do not add action to the data model
       if (theMakeCurrent)  // after all this feature stays in the document, so make it current
         aDocToAdd->setCurrentFeature(aFeature, false);
@@ -637,6 +662,8 @@ void Model_Document::removeFeature(FeaturePtr theFeature)
 void Model_Document::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis)
 {
   myObjs->moveFeature(theMoved, theAfterThis);
+  if (theAfterThis == currentFeature(true))
+    setCurrentFeature(theMoved, true);
 }
 
 void Model_Document::updateHistory(const std::shared_ptr<ModelAPI_Object> theObject)