From 3b8c09ffeba67fea673ab45fed821a5e7d5e1a73 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 29 Jan 2015 19:24:13 +0300 Subject: [PATCH] Fix for issue #388 : do not allow to undo/redo transaction which did nothing (like export to old GEOM) --- src/Model/Model_Document.cpp | 31 +++++++++++++++++++++++-------- src/Model/Model_Document.h | 6 +++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 2499f0366..ec10e7963 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -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 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 aSubs = subDocuments(true); std::set::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 aSubs = subDocuments(true); std::set::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() diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index f57349d7e..a766b981e 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -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 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; -- 2.39.2