]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Make undo/redo lists stored/restored and managed correctly
authormpv <mpv@opencascade.com>
Mon, 9 Feb 2015 16:50:59 +0000 (19:50 +0300)
committermpv <mpv@opencascade.com>
Mon, 9 Feb 2015 16:50:59 +0000 (19:50 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Session.cpp

index c923ee4cad78d53dfacebda4f7b09fea0cb6999f..762dff5fa852d28b61d29b066954bba52def6e91 100644 (file)
@@ -291,7 +291,7 @@ void Model_Document::startOperation()
 {
   if (myDoc->HasOpenCommand()) {  // start of nested command
     if (myDoc->CommitCommand()) { // commit the current: it will contain all nested after compactification
-      (*myTransactions.rbegin())++; // if has open command, the list is not empty
+      myTransactions.rbegin()->myOCAFNum++; // if has open command, the list is not empty
     }
     myNestedNum.push_back(0); // start of nested operation with zero transactions inside yet
     myDoc->OpenCommand();
@@ -299,7 +299,7 @@ void Model_Document::startOperation()
     myDoc->NewCommand();
   }
   // starts a new operation
-  myTransactions.push_back(0);
+  myTransactions.push_back(Transaction());
   if (!myNestedNum.empty())
     (*myNestedNum.rbegin())++;
   myRedos.clear();
@@ -316,11 +316,11 @@ void Model_Document::compactNested()
     int aNumToCompact = *(myNestedNum.rbegin());
     int aSumOfTransaction = 0;
     for(int a = 0; a < aNumToCompact; a++) {
-      aSumOfTransaction += *(myTransactions.rbegin());
+      aSumOfTransaction += myTransactions.rbegin()->myOCAFNum;
       myTransactions.pop_back();
     }
     // the latest transaction is the start of lower-level operation which startes the nested
-    *(myTransactions.rbegin()) += aSumOfTransaction;
+    myTransactions.rbegin()->myOCAFNum += aSumOfTransaction;
     myNestedNum.pop_back();
   }
 }
@@ -360,7 +360,7 @@ bool Model_Document::finishOperation()
 
   // 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())++;
+    myTransactions.rbegin()->myOCAFNum++;
     aResult = true;
   }
 
@@ -368,7 +368,7 @@ bool Model_Document::finishOperation()
     compactNested();
   }
   if (!aResult && !myTransactions.empty() /* it can be for just created part document */)
-    aResult = *(myTransactions.rbegin()) != 0;
+    aResult = myTransactions.rbegin()->myOCAFNum != 0;
 
   if (!aResult && Model_Session::get()->moduleDocument().get() == this) {
     // nothing inside in all documents, so remove this transaction from the transactions list
@@ -387,7 +387,7 @@ void Model_Document::abortOperation()
     myDoc->ClearRedos();
     myRedos.clear();
   } else { // abort the current
-    int aNumTransactions = *myTransactions.rbegin();
+    int aNumTransactions = myTransactions.rbegin()->myOCAFNum;
     myTransactions.pop_back();
     if (!myNestedNum.empty())
       (*myNestedNum.rbegin())--;
@@ -433,9 +433,9 @@ bool Model_Document::canUndo()
 
 void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchronize)
 {
-  int aNumTransactions = *myTransactions.rbegin();
+  int aNumTransactions = myTransactions.rbegin()->myOCAFNum;
+  myRedos.push_back(*myTransactions.rbegin());
   myTransactions.pop_back();
-  myRedos.push_back(aNumTransactions);
   if (!myNestedNum.empty())
     (*myNestedNum.rbegin())--;
   // roll back the needed number of transactions
@@ -475,9 +475,9 @@ void Model_Document::redo()
 {
   if (!myNestedNum.empty())
     (*myNestedNum.rbegin())++;
-  int aNumRedos = *myRedos.rbegin();
+  int aNumRedos = myRedos.rbegin()->myOCAFNum;
+  myTransactions.push_back(*myRedos.rbegin());
   myRedos.pop_back();
-  myTransactions.push_back(aNumRedos);
   for(int a = 0; a < aNumRedos; a++)
     myDoc->Redo();
 
@@ -489,6 +489,34 @@ void Model_Document::redo()
     subDoc(*aSubIter)->redo();
 }
 
+std::list<std::string> Model_Document::undoList() const
+{
+  std::list<std::string> aResult;
+  std::list<Transaction>::const_reverse_iterator aTrIter = myTransactions.crbegin();
+  int aNumUndo = myTransactions.size();
+  if (!myNestedNum.empty())
+    aNumUndo = *myNestedNum.rbegin();
+  for( ; aNumUndo > 0; aTrIter++, aNumUndo--) {
+    aResult.push_back(aTrIter->myId);
+  }
+  return aResult;
+}
+
+std::list<std::string> Model_Document::redoList() const
+{
+  std::list<std::string> aResult;
+  std::list<Transaction>::const_reverse_iterator aTrIter = myRedos.crbegin();
+  for( ; aTrIter != myRedos.crend(); aTrIter++) {
+    aResult.push_back(aTrIter->myId);
+  }
+  return aResult;
+}
+
+void Model_Document::operationId(const std::string& theId)
+{
+  myTransactions.rbegin()->myId = theId;
+}
+
 /// Append to the array of references a new referenced label
 static void AddToRefArray(TDF_Label& theArrayLab, TDF_Label& theReferenced)
 {
index cb99181f9ddb8a9ce6b1d2233d0f6c508701edb6..62bd3ad40710380d92ebddb4c99ac84c967808b4 100644 (file)
@@ -199,6 +199,15 @@ class Model_Document : public ModelAPI_Document
   //! The implementation of undo: with or without recoursive calls in the sub-documents
   void undoInternal(const bool theWithSubs, const bool theSynchronize);
 
+  //! Stores the Id of the current operation (normally is called for the root document)
+  void operationId(const std::string& theId);
+
+  //! Returns the list of Ids of the operations that can be undoed (called for the root document)
+  std::list<std::string> undoList() const;
+
+  //! Returns the list of Ids of the operations that can be redoed (called for the root document)
+  std::list<std::string> redoList() const;
+
   friend class Model_Application;
   friend class Model_Session;
   friend class Model_Update;
@@ -216,11 +225,19 @@ class Model_Document : public ModelAPI_Document
   /// the list is empty if not nested transaction is performed
   std::list<int> myNestedNum;
 
-  /// transaction indexes (related to myTransactionsAfterSave) and number of real transactions 
+  /// Information related to the every user-transaction
+  struct Transaction {
+    int myOCAFNum; ///< number of OCAF transactions related to each "this" transaction, may be 0
+    std::string myId; ///< user-identifier string of transaction
+    /// default constructor with default Id
+    Transaction(): myOCAFNum(0), myId("") {}
+  };
+
+  /// transaction indexes (related to myTransactionsAfterSave) and info about the real transactions
   /// in myDocument connected to this operation (may be zero for empty transaction)
-  std::list<int> myTransactions;
-  /// list of numbers of real document transactions undone (first is oldest undone)
-  std::list<int> myRedos;
+  std::list<Transaction> myTransactions;
+  /// list of info about transactions undone (first is oldest undone)
+  std::list<Transaction> myRedos;
   /// All features managed by this document (not only in history of OB)
   /// For optimization mapped by labels
   NCollection_DataMap<TDF_Label, FeaturePtr> myObjs;
index e9edb8856c2c0d1c9ba490caa0c8400951cbc07e..8b81240a2bcc185126d3b6f582bce8cdc9059396 100644 (file)
@@ -53,6 +53,7 @@ void Model_Session::closeAll()
 void Model_Session::startOperation(const std::string& theId)
 {
   ROOT_DOC->startOperation();
+  ROOT_DOC->operationId(theId);
   static std::shared_ptr<Events_Message> aStartedMsg
     (new Events_Message(Events_Loop::eventByName("StartOperation")));
   Events_Loop::loop()->send(aStartedMsg);
@@ -121,17 +122,12 @@ void Model_Session::redo()
 //! Returns stack of performed operations
 std::list<std::string> Model_Session::undoList()
 {
-  std::list<std::string> temp;
-  temp.push_front("Part");
-  temp.push_front("Sketch");
-  temp.push_front("Extrusion");
-  return temp;
+  return ROOT_DOC->undoList();
 }
 //! Returns stack of rolled back operations
 std::list<std::string> Model_Session::redoList()
 {
-  std::list<std::string> temp;
-  return temp;
+  return ROOT_DOC->redoList();
 }
 
 FeaturePtr Model_Session::createFeature(string theFeatureID)