Salome HOME
Issue #3044: Undo list contains empty string for Load python script
[modules/shaper.git] / src / Model / Model_Session.cpp
index 16f55677b2dc611a97f2c905fe3cf7b942295e4a..4ccc8f1b748e2dc99faacb3563819636f067ebaf 100644 (file)
@@ -26,6 +26,7 @@
 #include <Model_Application.h>
 #include <Model_Events.h>
 #include <Model_Validator.h>
+#include <Model_FiltersFactory.h>
 #include <ModelAPI_Events.h>
 #include <Events_Loop.h>
 #include <Events_InfoMessage.h>
@@ -79,7 +80,7 @@ void Model_Session::closeAll()
 
 void Model_Session::startOperation(const std::string& theId, const bool theAttachedToNested)
 {
-  myOperationAttachedToNext = theAttachedToNested;
+  myOperationAttachedToNext.push_back(theAttachedToNested);
   ROOT_DOC->startOperation();
   ROOT_DOC->operationId(theId);
   static std::shared_ptr<Events_Message> aStartedMsg
@@ -97,9 +98,13 @@ void Model_Session::finishOperation()
 {
   setCheckTransactions(false);
   ROOT_DOC->finishOperation();
-  if (myOperationAttachedToNext) { // twice, with nested
-    ROOT_DOC->finishOperation();
-    myOperationAttachedToNext = false;
+  if (!myOperationAttachedToNext.empty()) {
+    while (myOperationAttachedToNext.back()) {
+      // with nested, the first transaction can not be attached
+      ROOT_DOC->finishOperation();
+      myOperationAttachedToNext.pop_back();
+    }
+    myOperationAttachedToNext.pop_back();
   }
   setCheckTransactions(true);
 }
@@ -108,9 +113,13 @@ void Model_Session::abortOperation()
 {
   setCheckTransactions(false);
   ROOT_DOC->abortOperation();
-  if (myOperationAttachedToNext) { // twice, with nested
-    ROOT_DOC->abortOperation();
-    myOperationAttachedToNext = false;
+  if (!myOperationAttachedToNext.empty()) {
+    while (myOperationAttachedToNext.back()) {
+      // with nested, the first transaction can not be attached
+      ROOT_DOC->abortOperation();
+      myOperationAttachedToNext.pop_back();
+    }
+    myOperationAttachedToNext.pop_back();
   }
   setCheckTransactions(true);
   // here the update mechanism may work after abort, so, suppress the warnings about
@@ -134,6 +143,11 @@ bool Model_Session::isModified()
   return ROOT_DOC->isModified();
 }
 
+void Model_Session::clearUndos()
+{
+  ROOT_DOC->clearUndos();
+}
+
 bool Model_Session::canUndo()
 {
   return ROOT_DOC->canUndo();
@@ -426,7 +440,6 @@ Model_Session::Model_Session()
 {
   myPluginsInfoLoaded = false;
   myCheckTransactions = true;
-  myOperationAttachedToNext = false;
   ModelAPI_Session::setSession(std::shared_ptr<ModelAPI_Session>(this));
   // register the configuration reading listener
   Events_Loop* aLoop = Events_Loop::loop();
@@ -503,9 +516,33 @@ void Model_Session::processEvent(const std::shared_ptr<Events_Message>& theMessa
       }
     }
   } else {  // create/update/delete
-    if (myCheckTransactions && !isOperation())
-      Events_InfoMessage("Model_Session",
-        "Modification of data structure outside of the transaction").send();
+    if (myCheckTransactions && !isOperation()) {
+      // check it is done in real opened document: 2958
+      bool aIsActual = true;
+      static const Events_ID kDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+      if (theMessage->eventID() == kDeletedEvent) {
+        aIsActual = false;
+        std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleted =
+          std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
+        std::list<std::shared_ptr<ModelAPI_Document> > allOpened =
+          Model_Session::allOpenedDocuments();
+        std::list<std::pair<std::shared_ptr<ModelAPI_Document>, std::string>>::const_iterator
+          aGIter = aDeleted->groups().cbegin();
+        for (; !aIsActual && aGIter != aDeleted->groups().cend(); aGIter++) {
+          std::list<std::shared_ptr<ModelAPI_Document> >::iterator anOpened = allOpened.begin();
+          for(; anOpened != allOpened.end(); anOpened++) {
+            if (aGIter->first == *anOpened) {
+              aIsActual = true;
+              break;
+            }
+          }
+        }
+      }
+
+      if (aIsActual)
+        Events_InfoMessage("Model_Session",
+          "Modification of data structure outside of the transaction").send();
+    }
     // if part is deleted, make the root as the current document (on undo of Parts creations)
     static const Events_ID kDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
     if (theMessage->eventID() == kDeletedEvent) {
@@ -580,6 +617,12 @@ ModelAPI_ValidatorsFactory* Model_Session::validators()
   return aFactory;
 }
 
+ModelAPI_FiltersFactory* Model_Session::filters()
+{
+  static Model_FiltersFactory* aFactory = new Model_FiltersFactory;
+  return aFactory;
+}
+
 int Model_Session::transactionID()
 {
   return ROOT_DOC->transactionID();