]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix for issue #388 : do not allow to undo/redo transaction which did nothing (like...
authormpv <mpv@opencascade.com>
Thu, 29 Jan 2015 16:24:13 +0000 (19:24 +0300)
committermpv <mpv@opencascade.com>
Thu, 29 Jan 2015 16:24:13 +0000 (19:24 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h

index 2499f0366272ae454b0d4c83f9be503a46a30d95..ec10e79632777634a6ca203b35b9d2f7edced0b1 100644 (file)
@@ -325,7 +325,7 @@ void Model_Document::compactNested()
   }
 }
 
-void Model_Document::finishOperation()
+bool Model_Document::finishOperation()
 {
   bool isNestedClosed = !myDoc->HasOpenCommand() && !myNestedNum.empty();
   static std::shared_ptr<Model_Session> aSession = 
@@ -351,25 +351,39 @@ void Model_Document::finishOperation()
   //aLoop->clear(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
 
   // finish for all subs first: to avoid nested finishing and "isOperation" calls problems inside
+  bool aResult = false;
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
   for (; aSubIter != aSubs.end(); aSubIter++)
-    subDoc(*aSubIter)->finishOperation();
+    if (subDoc(*aSubIter)->finishOperation())
+      aResult = true;
 
-  if (myDoc->CommitCommand()) { // if commit is successfull, just increment counters
+  // transaction may be empty if this document was created during this transaction (create part)
+  if (!myTransactions.empty() && myDoc->CommitCommand()) { // if commit is successfull, just increment counters
     (*myTransactions.rbegin())++;
+    aResult = true;
   }
 
   if (isNestedClosed) {
     compactNested();
   }
+  if (!aResult && !myTransactions.empty() /* it can be for just created part document */)
+    aResult = *(myTransactions.rbegin()) != 0;
+
+  if (!aResult && Model_Session::get()->moduleDocument().get() == this) {
+    // nothing inside in all documents, so remove this transaction from the transactions list
+    undoInternal(true, false);
+    myDoc->ClearRedos();
+    myRedos.clear();
+  }
+  return aResult;
 }
 
 void Model_Document::abortOperation()
 {
   if (!myNestedNum.empty() && !myDoc->HasOpenCommand()) {  // abort all what was done in nested
     compactNested();
-    undoInternal(false);
+    undoInternal(false, false);
     myDoc->ClearRedos();
     myRedos.clear();
   } else { // abort the current
@@ -417,7 +431,7 @@ bool Model_Document::canUndo()
   return false;
 }
 
-void Model_Document::undoInternal(const bool theWithSubs)
+void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchronize)
 {
   int aNumTransactions = *myTransactions.rbegin();
   myTransactions.pop_back();
@@ -428,19 +442,20 @@ void Model_Document::undoInternal(const bool theWithSubs)
   for(int a = 0; a < aNumTransactions; a++)
     myDoc->Undo();
 
-  if (theWithSubs) {
+  if (theSynchronize)
     synchronizeFeatures(true, true);
+  if (theWithSubs) {
     // 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++)
-      subDoc(*aSubIter)->undo();
+      subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize);
   }
 }
 
 void Model_Document::undo()
 {
-  undoInternal(true);
+  undoInternal(true, true);
 }
 
 bool Model_Document::canRedo()
index f57349d7e19a77802835904792fa6fc4ce60cd60..a766b981e7bfeaf81b34118840c17d80a4792160 100644 (file)
@@ -56,8 +56,8 @@ class Model_Document : public ModelAPI_Document
   //! Starts a new operation (opens a tansaction)
   MODEL_EXPORT virtual void startOperation();
   //! Finishes the previously started operation (closes the transaction)
-  //! Returns true if transaction in this document is not empty and really was performed
-  MODEL_EXPORT virtual void finishOperation();
+  //! \returns true if transaction in this document is not empty and really was performed
+  MODEL_EXPORT virtual bool finishOperation();
   //! Aborts the operation 
   MODEL_EXPORT virtual void abortOperation();
   //! Returns true if operation has been started, but not yet finished or aborted
@@ -190,7 +190,7 @@ class Model_Document : public ModelAPI_Document
   const std::set<std::string> subDocuments(const bool theActivatedOnly) const;
 
   //! The implementation of undo: with or without recoursive calls in the sub-documents
-  void undoInternal(const bool theWithSubs);
+  void undoInternal(const bool theWithSubs, const bool theSynchronize);
 
   friend class Model_Application;
   friend class Model_Session;