Salome HOME
Fix for issue #319 : remove useless documents on start of the operation (undo/redo...
authormpv <mikhail.ponikarov@opencascade.com>
Wed, 24 Dec 2014 09:29:11 +0000 (12:29 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Wed, 24 Dec 2014 09:29:11 +0000 (12:29 +0300)
src/Model/Model_Application.cpp
src/Model/Model_Application.h
src/Model/Model_AttributeRefAttr.cpp
src/Model/Model_Document.cpp
src/Model/Model_Session.cpp

index 147bb4ac29e2c4450b28c73bafa042215c8c8c18..204cafe1418d99d1e690eb87fe5b6242cc46003a 100644 (file)
@@ -85,6 +85,26 @@ bool Model_Application::isLoadByDemand(std::string theID)
   return myLoadedByDemand.find(theID) != myLoadedByDemand.end();
 }
 
+//=======================================================================
+void Model_Application::removeUselessDocuments(
+  std::list<std::shared_ptr<ModelAPI_Document> > theUsedDocs)
+{
+  std::map<std::string, std::shared_ptr<Model_Document> >::iterator aDoc = myDocs.begin();
+  while(aDoc != myDocs.end()) {
+    bool aFound = false;
+    std::list<std::shared_ptr<ModelAPI_Document> >::iterator aUsed = theUsedDocs.begin();
+    for(; !aFound && aUsed != theUsedDocs.end(); aUsed++) {
+      aFound = aDoc->second == *aUsed;
+    }
+    if (!aFound) { // remove the useless
+      aDoc->second->close();
+      aDoc = myDocs.erase(aDoc);
+    } else {
+      aDoc++;
+    }
+  }
+}
+
 //=======================================================================
 Model_Application::Model_Application()
 {
index aa25bcb4e161c9b6bfa1a389a12dff6942618463..d1156b2844e80a7daacbfd107b9299bfe8d1da73 100644 (file)
@@ -49,6 +49,9 @@ class Model_Application : public TDocStd_Application
   void setLoadByDemand(std::string theID);
   //! Returns true if specified document must be loaded by demand
   bool isLoadByDemand(std::string theID);
+  //! Closes and removes the documents that are not loaded by demand and
+  //! not in the given list
+  void removeUselessDocuments(std::list<std::shared_ptr<ModelAPI_Document> > theUsedDocs);
 
  public:
   // Redefined OCAF methods
index 14e6eb4a18d394929af5d30dc2d89d11f10ac4c6..b6ac116635859ca831369e5011715e601d55fde9 100644 (file)
@@ -31,7 +31,7 @@ void Model_AttributeRefAttr::setAttr(std::shared_ptr<ModelAPI_Attribute> theAttr
 std::shared_ptr<ModelAPI_Attribute> Model_AttributeRefAttr::attr()
 {
   ObjectPtr anObj = object();
-  if (anObj) {
+  if (anObj && anObj->data()) {
     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(anObj->data());
     return aData->attribute(TCollection_AsciiString(myID->Get()).ToCString());
   }
index 60f1634999ac896b092afb9acc82cbb007d15b3e..dfd03fefc57fe9f6d745d56082a4fcff9fdc4a95 100644 (file)
@@ -623,14 +623,16 @@ const std::set<std::string> Model_Document::subDocuments(const bool theActivated
   for (; aLabIter.More(); aLabIter.Next()) {
     TDF_Label aFLabel = aLabIter.Value()->Label();
     FeaturePtr aFeature = feature(aFLabel);
-    const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
-    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
-    for (; aRIter != aResults.cend(); aRIter++) {
-      if ((*aRIter)->groupName() != ModelAPI_ResultPart::group()) continue;
-      if ((*aRIter)->isInHistory()) {
-        ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRIter);
-        if (aPart && (!theActivatedOnly || aPart->isActivated()))
-          aResult.insert(aPart->data()->name());
+    if (aFeature.get()) { // if document is closed the feature may be not in myObjs map
+      const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
+      std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
+      for (; aRIter != aResults.cend(); aRIter++) {
+        if ((*aRIter)->groupName() != ModelAPI_ResultPart::group()) continue;
+        if ((*aRIter)->isInHistory()) {
+          ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRIter);
+          if (aPart && (!theActivatedOnly || aPart->isActivated()))
+            aResult.insert(aPart->data()->name());
+        }
       }
     }
   }
index 88d9f81d47c47720e58b62e8010b83fa365259ef..159b7a2f678b19e60ac6fac4862c1881100dbeca 100644 (file)
@@ -53,6 +53,9 @@ void Model_Session::startOperation()
   static std::shared_ptr<Events_Message> aStartedMsg
     (new Events_Message(Events_Loop::eventByName("StartOperation")));
   Events_Loop::loop()->send(aStartedMsg);
+  // remove all useless documents that has been closed: on start of operation undo/redo is cleared
+  std::list<std::shared_ptr<ModelAPI_Document> > aUsedDocs = allOpenedDocuments();
+  Model_Application::getApplication()->removeUselessDocuments(aUsedDocs);
 }
 
 void Model_Session::finishOperation()