Salome HOME
Issue #640 It is impossible to remove dimension
[modules/shaper.git] / src / Model / Model_Document.cpp
index 90e577c05d2ef0c610b97dd4c72799dc2b601c1d..2913075901a1c12bf6c05823643c786bb872ffa2 100644 (file)
@@ -171,7 +171,8 @@ bool Model_Document::load(const char* theFileName, DocumentPtr theThis)
     setCurrentFeature(currentFeature(false), false);
     aSession->setCheckTransactions(true);
     aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
-    aSession->setActiveDocument(anApp->getDocument(myID), true);
+    // this is done in Part result "activate", so no needed here. Causes not-blue active part.
+    // aSession->setActiveDocument(anApp->getDocument(myID), true);
   }
   return !isError;
 }
@@ -257,8 +258,11 @@ void Model_Document::close(const bool theForever)
   // close all subs
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
-  for (; aSubIter != aSubs.end(); aSubIter++)
-    subDoc(*aSubIter)->close(theForever);
+  for (; aSubIter != aSubs.end(); aSubIter++) {
+    std::shared_ptr<Model_Document> aSub = subDoc(*aSubIter);
+    if (aSub->myObjs) // if it was not closed before
+      aSub->close(theForever);
+  }
 
   // close for thid document needs no transaction in this document
   std::static_pointer_cast<Model_Session>(Model_Session::get())->setCheckTransactions(false);
@@ -423,9 +427,14 @@ bool Model_Document::canUndo()
   // check other subs contains operation that can be undoed
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
-  for (; aSubIter != aSubs.end(); aSubIter++)
-    if (subDoc(*aSubIter)->canUndo())
-      return true;
+  for (; aSubIter != aSubs.end(); aSubIter++) {
+    std::shared_ptr<Model_Document> aSub = subDoc(*aSubIter);
+    if (aSub->myObjs) {// if it was not closed before
+      if (aSub->canUndo())
+        return true;
+    }
+  }
+
   return false;
 }
 
@@ -444,8 +453,11 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
     // undo for all subs
     const std::set<std::string> aSubs = subDocuments(true);
     std::set<std::string>::iterator aSubIter = aSubs.begin();
-    for (; aSubIter != aSubs.end(); aSubIter++)
+    for (; aSubIter != aSubs.end(); aSubIter++) {
+      if (!subDoc(*aSubIter)->myObjs)
+        continue;
       subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize);
+    }
   }
   // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
   if (theSynchronize) {
@@ -467,9 +479,12 @@ bool Model_Document::canRedo()
   // check other subs contains operation that can be redoed
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
-  for (; aSubIter != aSubs.end(); aSubIter++)
+  for (; aSubIter != aSubs.end(); aSubIter++) {
+    if (!subDoc(*aSubIter)->myObjs)
+      continue;
     if (subDoc(*aSubIter)->canRedo())
       return true;
+  }
   return false;
 }
 
@@ -565,11 +580,6 @@ void Model_Document::refsToFeature(FeaturePtr theFeature,
 
 void Model_Document::removeFeature(FeaturePtr theFeature)
 {
-  // if this feature is current, make the current the previous feature
-  if (theFeature == currentFeature(false)) {
-    FeaturePtr aPrev = myObjs->nextFeature(theFeature, true);
-    setCurrentFeature(aPrev, false);
-  }
   myObjs->removeFeature(theFeature);
 }
 
@@ -632,6 +642,8 @@ int Model_Document::size(const std::string& theGroupID)
 
 std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theVisible)
 {
+  if (!myObjs) // on close document feature destruction it may call this method
+    return std::shared_ptr<ModelAPI_Feature>();
   TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE);
   Handle(TDF_Reference) aRef;
   if (aRefLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
@@ -650,20 +662,14 @@ std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theV
 void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent,
   const bool theVisible)
 {
+  // blocks the flush signals to avoid each objects visualization in the viewer
+  // they should not be shown once after all modifications are performed
+  Events_Loop* aLoop = Events_Loop::loop();
+  bool isActive = aLoop->activateFlushes(false);
+
   TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE);
   CompositeFeaturePtr aMain; // main feature that may nest the new current
   if (theCurrent.get()) {
-    /*
-    if (theVisible) { // make features below which are not in history also enabled: sketch subs
-      FeaturePtr aNext = myObjs->nextFeature(theCurrent);
-      for (; aNext.get(); aNext = myObjs->nextFeature(theCurrent)) {
-        if (aNext->isInHistory()) {
-          break; // next in history is not needed
-        } else { // next not in history is good for making current
-          theCurrent = aNext;
-        }
-      }
-    }*/
     aMain = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theCurrent);
     if (!aMain.get()) {
       // if feature nests into compisite feature, make the composite feature as current
@@ -678,9 +684,25 @@ void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurr
         }
       }
     }
+  }
 
+  if (theVisible) { // make features below which are not in history also enabled: sketch subs
+    FeaturePtr aNext = 
+      theCurrent.get() ? myObjs->nextFeature(theCurrent) : myObjs->firstFeature();
+    for (; aNext.get(); aNext = myObjs->nextFeature(theCurrent)) {
+      if (aNext->isInHistory()) {
+        break; // next in history is not needed
+      } else { // next not in history is good for making current
+        theCurrent = aNext;
+      }
+    }
+  }
+  if (theCurrent.get()) {
     std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theCurrent->data());
-    if (!aData.get()) return; // unknown case
+    if (!aData.get() || !aData->isValid()) {
+      aLoop->activateFlushes(isActive);
+      return;
+    }
     TDF_Label aFeatureLabel = aData->label().Father();
 
     Handle(TDF_Reference) aRef;
@@ -693,8 +715,9 @@ void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurr
     aRefLab.ForgetAttribute(TDF_Reference::GetID());
   }
   // make all features after this feature disabled in reversed order (to remove results without deps)
-  static Events_Loop* aLoop = Events_Loop::loop();
   static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static Events_ID aCreateEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+  static Events_ID aDeleteEvent = aLoop->eventByName(EVENT_OBJECT_DELETED);
 
   bool aPassed = false; // flag that the current object is already passed in cycle
   FeaturePtr anIter = myObjs->lastFeature();
@@ -703,7 +726,9 @@ void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurr
     if (anIter == theCurrent) aPassed = true;
 
     bool aDisabledFlag = !aPassed;
-    if (aMain.get() && aMain->isSub(anIter))
+    if (aMain.get() && aMain->isSub(anIter)) // sub-elements of not-disabled feature are not disabled
+      aDisabledFlag = false;
+    if (anIter->getKind() == "Parameter") // parameters are always out of the history
       aDisabledFlag = false;
     if (anIter->setDisabled(aDisabledFlag)) {
       // state of feature is changed => so feature become updated
@@ -713,7 +738,23 @@ void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurr
       ModelAPI_EventCreator::get()->sendUpdated(anIter, aRedispEvent /*, false*/);
     }
   }
+  // unblock  the flush signals and up them after this
+  aLoop->activateFlushes(isActive);
+
+  aLoop->flush(aCreateEvent);
   aLoop->flush(aRedispEvent);
+  aLoop->flush(aDeleteEvent);
+}
+
+void Model_Document::setCurrentFeatureUp()
+{
+  // on remove just go up for minimum step: highlight external objects in sketch causes 
+  // problems if it is true: here and in "setCurrentFeature"
+  FeaturePtr aCurrent = currentFeature(false);
+  if (aCurrent.get()) { // if not, do nothing because null is the upper
+    FeaturePtr aPrev = myObjs->nextFeature(aCurrent, true);
+    setCurrentFeature(aPrev, false);
+  }
 }
 
 TDF_Label Model_Document::generalLabel() const
@@ -789,3 +830,8 @@ ResultPtr Model_Document::findByName(const std::string theName)
 {
   return myObjs->findByName(theName);
 }
+
+std::list<std::shared_ptr<ModelAPI_Feature> > Model_Document::allFeatures()
+{
+  return myObjs->allFeatures();
+}