Salome HOME
updated copyright message
[modules/shaper.git] / src / Model / Model_Session.cpp
index 16f55677b2dc611a97f2c905fe3cf7b942295e4a..b80cdd8eaf92737a34e09d233bece4bb6f4f0dc6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Plugin.h>
 #include <Model_Data.h>
-#include <Model_Document.h>
 #include <Model_Objects.h>
 #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>
@@ -59,7 +59,9 @@ static Model_Session* myImpl = new Model_Session();
 
 bool Model_Session::load(const char* theFileName)
 {
+  myIsLoading = true;
   bool aRes = ROOT_DOC->load(theFileName, "root", ROOT_DOC);
+  myIsLoading = false;
   return aRes;
 }
 
@@ -71,15 +73,16 @@ bool Model_Session::save(const char* theFileName, std::list<std::string>& theRes
 void Model_Session::closeAll()
 {
   Model_Application::getApplication()->deleteAllDocuments();
-  static const Events_ID aDocChangeEvent = Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED);
-  static std::shared_ptr<Events_Message> aMsg(new Events_Message(aDocChangeEvent));
+  static const Events_ID aDocsCloseEvent = Events_Loop::eventByName(EVENT_DOCUMENTS_CLOSED);
+  myCurrentDoc = NULL;
+  static std::shared_ptr<Events_Message> aMsg(new Events_Message(aDocsCloseEvent));
   Events_Loop::loop()->send(aMsg);
-  Events_Loop::loop()->flush(aDocChangeEvent);
+  Events_Loop::loop()->flush(aDocsCloseEvent);
 }
 
 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 +100,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 +115,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
@@ -169,6 +180,16 @@ std::list<std::string> Model_Session::redoList()
   return ROOT_DOC->redoList();
 }
 
+void Model_Session::clearUndoRedo()
+{
+  return ROOT_DOC->clearUndoRedo();
+}
+
+bool Model_Session::checkLicense(const std::string& thePluginName)
+{
+  return getPlugin(thePluginName);
+}
+
 ModelAPI_Plugin* Model_Session::getPlugin(const std::string& thePluginName)
 {
   if (myPluginObjs.find(thePluginName) == myPluginObjs.end()) {
@@ -242,6 +263,12 @@ std::shared_ptr<ModelAPI_Document> Model_Session::moduleDocument()
     anApp->createDocument(0); // 0 is a root ID
     // creation of the root document is always outside of the transaction, so, avoid checking it
     setCheckTransactions(true);
+    if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id())) {
+      myCurrentDoc = moduleDocument();
+      static std::shared_ptr<Events_Message> aMsg(
+        new Events_Message(Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED)));
+      Events_Loop::loop()->send(aMsg);
+    }
   }
   return anApp->rootDocument();
 }
@@ -259,8 +286,9 @@ bool Model_Session::hasModuleDocument()
 
 std::shared_ptr<ModelAPI_Document> Model_Session::activeDocument()
 {
-  if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id()))
-    myCurrentDoc = moduleDocument();
+  if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id())) {
+    return moduleDocument();
+  }
   return myCurrentDoc;
 }
 
@@ -338,9 +366,9 @@ std::list<std::shared_ptr<ModelAPI_Document> > Model_Session::allOpenedDocuments
   std::list<std::shared_ptr<ModelAPI_Document> > aResult;
   aResult.push_back(moduleDocument());
   // add subs recursively
-  std::list<std::shared_ptr<ModelAPI_Document> >::iterator aDoc = aResult.begin();
-  for(; aDoc != aResult.end(); aDoc++) {
-    DocumentPtr anAPIDoc = *aDoc;
+  std::list<std::shared_ptr<ModelAPI_Document> >::iterator aDocIt = aResult.begin();
+  for(; aDocIt != aResult.end(); aDocIt++) {
+    DocumentPtr anAPIDoc = *aDocIt;
     std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(anAPIDoc);
     if (aDoc) {
       const std::set<int> aSubs = aDoc->subDocuments();
@@ -353,7 +381,7 @@ std::list<std::shared_ptr<ModelAPI_Document> > Model_Session::allOpenedDocuments
   return aResult;
 }
 
-bool Model_Session::isLoadByDemand(const std::string theDocID, const int theDocIndex)
+bool Model_Session::isLoadByDemand(const std::wstring theDocID, const int theDocIndex)
 {
   return Model_Application::getApplication()->isLoadByDemand(theDocID, theDocIndex);
 }
@@ -426,7 +454,7 @@ Model_Session::Model_Session()
 {
   myPluginsInfoLoaded = false;
   myCheckTransactions = true;
-  myOperationAttachedToNext = false;
+  myIsLoading = false;
   ModelAPI_Session::setSession(std::shared_ptr<ModelAPI_Session>(this));
   // register the configuration reading listener
   Events_Loop* aLoop = Events_Loop::loop();
@@ -503,9 +531,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 +632,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();
@@ -609,7 +667,7 @@ void Model_Session::blockAutoUpdate(const bool theBlock)
       aLoop->send(aMsg);
     } else {
       // if there is no operation, start it to avoid modifications outside of transaction
-      bool isOperation = this->isOperation();
+      isOperation = this->isOperation();
       if (!isOperation)
         startOperation("Auto update enabling");
       static const Events_ID kAutoOn = aLoop->eventByName(EVENT_AUTOMATIC_RECOMPUTATION_ENABLE);
@@ -623,3 +681,10 @@ void Model_Session::blockAutoUpdate(const bool theBlock)
     }
   }
 }
+
+#ifdef TINSPECTOR
+Handle(TDocStd_Application) Model_Session::application()
+{
+  return Model_Application::getApplication();
+}
+#endif