From df4a8eb7ab6f107aab55ef5014ecb7fa49a22830 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sat, 13 Jun 2020 07:24:43 +0200 Subject: [PATCH] Document/DocumentObject: onUndoRedoFinished() ============================================= New mechanism for on-demand signaling of undo/redo transaction finalisation. The mechanism consists of: 1) A status bit that is set, when an object should receive this signaling (e.g. because changes during transaction have been inhibited) 2) The new function to be called by the Document undo/redo actions when the transaction is over (for those objects having the status bit set). Note 1: The undo/redo signals are now outside the undoing FlagToggler, this means that: 1) a call to isPerformingTransaction will return false. 2) a recompute the slot of such a signal will not be inhibited. Note 2: The undo/redo signals are called once the documentobjects that requested to be notified after the trasaction is over have been notified. The consequence is that the viewprovider can rely on the documentobject having a correct status. I think that the behaviour of Note and Note 2 is the wanted behaviour of this signals, I cannot rule out that other parts of FC rely on the old implementation. --- src/App/Document.cpp | 22 +++++++++++++++++++++- src/App/DocumentObject.cpp | 5 +++++ src/App/DocumentObject.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index e3a6ae1eee..7b0bca9af9 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -963,6 +963,7 @@ bool Document::undo(int id) d->activeUndoTransaction = new Transaction(mUndoTransactions.back()->getID()); d->activeUndoTransaction->Name = mUndoTransactions.back()->Name; + { Base::FlagToggler flag(d->undoing); // applying the undo mUndoTransactions.back()->apply(*this,false); @@ -976,7 +977,17 @@ bool Document::undo(int id) delete mUndoTransactions.back(); mUndoTransactions.pop_back(); - signalUndo(*this); + } + + for(auto & obj:d->objectArray) { + if(obj->testStatus(ObjectStatus::PendingTransactionUpdate)) { + obj->onUndoRedoFinished(); + obj->setStatus(ObjectStatus::PendingTransactionUpdate,false); + } + } + + signalUndo(*this); // now signal the undo + return true; } @@ -1004,6 +1015,7 @@ bool Document::redo(int id) d->activeUndoTransaction->Name = mRedoTransactions.back()->Name; // do the redo + { Base::FlagToggler flag(d->undoing); mRedoTransactions.back()->apply(*this,true); @@ -1014,6 +1026,14 @@ bool Document::redo(int id) mRedoMap.erase(mRedoTransactions.back()->getID()); delete mRedoTransactions.back(); mRedoTransactions.pop_back(); + } + + for(auto & obj:d->objectArray) { + if(obj->testStatus(ObjectStatus::PendingTransactionUpdate)) { + obj->onUndoRedoFinished(); + obj->setStatus(ObjectStatus::PendingTransactionUpdate,false); + } + } signalRedo(*this); return true; diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index ed51e299c2..262633cc00 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -936,6 +936,11 @@ void DocumentObject::onDocumentRestored() Visibility.setStatus(Property::NoModify,true); } +void DocumentObject::onUndoRedoFinished() +{ + +} + void DocumentObject::onSettingDocument() { //call all extensions diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index f4202f6eb8..ae50454fc6 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -64,6 +64,7 @@ enum ObjectStatus { GeoExcluded = 15, // mark as a member but not claimed by GeoFeatureGroup Expand = 16, // indicate the object's tree item expansion status NoAutoExpand = 17, // disable tree item auto expand on selection for this object + PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished. }; /** Return object for feature execution @@ -592,6 +593,8 @@ protected: virtual void onChanged(const Property* prop) override; /// get called after a document has been fully restored virtual void onDocumentRestored(); + /// get called after an undo/redo transaction is finished + virtual void onUndoRedoFinished(); /// get called after setting the document virtual void onSettingDocument(); /// get called after a brand new object was created