From f367061802012d6909c2619ef6b6c4cba86fc503 Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 1 Apr 2015 12:34:40 +0300 Subject: [PATCH] Fix for the issue #370 : activization of updater only once per undo/redo for all sub-documents --- src/Model/Model_Document.cpp | 46 +++++++++++++++++++++++------------- src/Model/Model_Document.h | 7 +++++- src/Model/Model_Session.cpp | 4 ++-- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index c2da1a479..ee8cebc14 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -84,10 +84,15 @@ static TCollection_ExtendedString DocFileName(const char* theFileName, const std return aPath; } +bool Model_Document::isRoot() const +{ + return this == Model_Session::get()->moduleDocument().get(); +} + bool Model_Document::load(const char* theFileName) { Handle(Model_Application) anApp = Model_Application::getApplication(); - if (this == Model_Session::get()->moduleDocument().get()) { + if (isRoot()) { anApp->setLoadPath(theFileName); } TCollection_ExtendedString aPath(DocFileName(theFileName, myID)); @@ -161,7 +166,7 @@ bool Model_Document::load(const char* theFileName) std::dynamic_pointer_cast(Model_Session::get()); aSession->setActiveDocument(anApp->getDocument(myID), false); aSession->setCheckTransactions(false); - synchronizeFeatures(false, true); + synchronizeFeatures(false, true, true); aSession->setCheckTransactions(true); aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false); aSession->setActiveDocument(anApp->getDocument(myID), true); @@ -173,7 +178,7 @@ bool Model_Document::save(const char* theFileName, std::list& theRe { // create a directory in the root document if it is not yet exist Handle(Model_Application) anApp = Model_Application::getApplication(); - if (this == Model_Session::get()->moduleDocument().get()) { + if (isRoot()) { #ifdef WIN32 CreateDirectory(theFileName, NULL); #else @@ -241,9 +246,9 @@ bool Model_Document::save(const char* theFileName, std::list& theRe void Model_Document::close(const bool theForever) { std::shared_ptr aPM = Model_Session::get(); - if (this != aPM->moduleDocument().get() && this == aPM->activeDocument().get()) { + if (!isRoot() && this == aPM->activeDocument().get()) { aPM->setActiveDocument(aPM->moduleDocument()); - } else if (this == aPM->moduleDocument().get()) { + } else if (isRoot()) { // erase the active document if root is closed aPM->setActiveDocument(DocumentPtr()); } @@ -341,7 +346,7 @@ bool Model_Document::finishOperation() // this must be here just after everything is finished but before real transaction stop // to avoid messages about modifications outside of the transaction // and to rebuild everything after all updates and creates - if (Model_Session::get()->moduleDocument().get() == this) { // once for root document + if (isRoot()) { // once for root document Events_Loop::loop()->autoFlush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); static std::shared_ptr aFinishMsg (new Events_Message(Events_Loop::eventByName("FinishOperation"))); @@ -371,7 +376,7 @@ bool Model_Document::finishOperation() if (!aResult && !myTransactions.empty() /* it can be for just created part document */) aResult = myTransactions.rbegin()->myOCAFNum != 0; - if (!aResult && Model_Session::get()->moduleDocument().get() == this) { + if (!aResult && isRoot()) { // nothing inside in all documents, so remove this transaction from the transactions list undoInternal(true, false); myDoc->ClearRedos(); @@ -398,7 +403,8 @@ void Model_Document::abortOperation() myDoc->Undo(); myDoc->ClearRedos(); } - synchronizeFeatures(true, false); // references were not changed since transaction start + // references were not changed since transaction start + synchronizeFeatures(true, false, isRoot()); // abort for all subs const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); @@ -446,8 +452,6 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron for(int a = 0; a < aNumTransactions; a++) myDoc->Undo(); - if (theSynchronize) - synchronizeFeatures(true, true); if (theWithSubs) { // undo for all subs const std::set aSubs = subDocuments(true); @@ -455,6 +459,9 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize); } + // after redo of all sub-documents to avoid updates on not-modified data (issue 370) + if (theSynchronize) + synchronizeFeatures(true, true, isRoot()); } void Model_Document::undo() @@ -485,12 +492,14 @@ void Model_Document::redo() for(int a = 0; a < aNumRedos; a++) myDoc->Redo(); - synchronizeFeatures(true, true); // redo for all subs const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->redo(); + + // after redo of all sub-documents to avoid updates on not-modified data (issue 370) + synchronizeFeatures(true, true, isRoot()); } std::list Model_Document::undoList() const @@ -949,7 +958,8 @@ void Model_Document::initData(ObjectPtr theObj, TDF_Label theLab, const int theT theObj->initAttributes(); } -void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences) +void Model_Document::synchronizeFeatures( + const bool theMarkUpdated, const bool theUpdateReferences, const bool theFlush) { std::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); @@ -1040,11 +1050,13 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t myExecuteFeatures = false; aLoop->activateFlushes(true); - aLoop->flush(aCreateEvent); - aLoop->flush(aDeleteEvent); - aLoop->flush(anUpdateEvent); - aLoop->flush(aRedispEvent); - aLoop->flush(aToHideEvent); + if (theFlush) { + aLoop->flush(aCreateEvent); + aLoop->flush(aDeleteEvent); + aLoop->flush(anUpdateEvent); + aLoop->flush(aRedispEvent); + aLoop->flush(aToHideEvent); + } myExecuteFeatures = true; } diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index ef7c98a10..59631304e 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -170,7 +170,9 @@ class Model_Document : public ModelAPI_Document //! Synchronizes myFeatures list with the updated document //! \param theMarkUpdated causes the "update" event for all features //! \param theUpdateReferences causes the update of back-references - void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences); + //! \param theFlush makes flush all events in the end of all modifications of this method + void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences, + const bool theFlush); //! Synchronizes the BackReferences list in Data of Features and Results void synchronizeBackRefs(); @@ -219,6 +221,9 @@ class Model_Document : public ModelAPI_Document /// Internally makes document know that feature was removed or added in history after creation MODEL_EXPORT virtual void addToHistory(const std::shared_ptr theObject); + /// Returns true if the document is root module document + bool isRoot() const; + friend class Model_Application; friend class Model_Session; friend class Model_Update; diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index e7f21bf88..8dcd0a11b 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -216,7 +216,7 @@ void Model_Session::setActiveDocument( if (aDoc.get()) { bool aWasChecked = myCheckTransactions; setCheckTransactions(false); - aDoc->synchronizeFeatures(false, true); + aDoc->synchronizeFeatures(false, true, true); if (aWasChecked) setCheckTransactions(true); } @@ -266,7 +266,7 @@ std::shared_ptr Model_Session::copy( aRT->SetRelocation(aSourceRoot, aTargetRoot); TDF_CopyTool::Copy(aDS, aRT); - aNew->synchronizeFeatures(false, true); + aNew->synchronizeFeatures(false, true, true); return aNew; } -- 2.39.2