From 60e95a5502a6940c6c27ce5d561b3c684b0b0a4f Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 26 Jan 2015 14:56:13 +0300 Subject: [PATCH] FIx for issue #360 : make switching on/off checking of transactions in Session - more systematically --- src/Model/Model_Document.cpp | 34 ++++++++++++++-------------------- src/Model/Model_Session.cpp | 20 +++++++++++++++++++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index f1f10b103..3efd64be7 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -156,10 +156,14 @@ bool Model_Document::load(const char* theFileName) if (!isError) { myDoc->SetUndoLimit(UNDO_LIMIT); // to avoid the problem that feature is created in the current, not this, document - Model_Session::get()->setActiveDocument(anApp->getDocument(myID), false); + std::shared_ptr aSession = + std::dynamic_pointer_cast(Model_Session::get()); + aSession->setActiveDocument(anApp->getDocument(myID), false); + aSession->setCheckTransactions(false); synchronizeFeatures(false, true); - Model_Session::get()->setActiveDocument(Model_Session::get()->moduleDocument(), false); - Model_Session::get()->setActiveDocument(anApp->getDocument(myID), true); + aSession->setCheckTransactions(true); + aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false); + aSession->setActiveDocument(anApp->getDocument(myID), true); } return !isError; } @@ -246,7 +250,8 @@ void Model_Document::close(const bool theForever) subDoc(*aSubIter)->close(theForever); // close for thid document needs no transaction in this document - std::static_pointer_cast(Model_Session::get())->setCheckTransactions(false); + if (this == aPM->moduleDocument().get()) + std::static_pointer_cast(Model_Session::get())->setCheckTransactions(false); // delete all features of this document std::shared_ptr aThis = @@ -277,7 +282,8 @@ void Model_Document::close(const bool theForever) myDoc->Close(); } - std::static_pointer_cast(Model_Session::get())->setCheckTransactions(true); + if (this == aPM->moduleDocument().get()) + std::static_pointer_cast(Model_Session::get())->setCheckTransactions(true); } void Model_Document::startOperation() @@ -323,10 +329,6 @@ void Model_Document::finishOperation() bool isNestedClosed = !myDoc->HasOpenCommand() && !myNestedNum.empty(); static std::shared_ptr aSession = std::static_pointer_cast(Model_Session::get()); - // just to be sure that everybody knows that changes were performed - if (isNestedClosed) { - aSession->setCheckTransactions(false); // for nested transaction commit - } synchronizeBackRefs(); Events_Loop* aLoop = Events_Loop::loop(); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); @@ -347,10 +349,6 @@ void Model_Document::finishOperation() // to avoid "updated" message appearance by updater //aLoop->clear(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - if (isNestedClosed) { - aSession->setCheckTransactions(true); // for nested transaction commit - } - // finish for all subs first: to avoid nested finishing and "isOperation" calls problems inside const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); @@ -813,8 +811,6 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t std::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); // after all updates, sends a message that groups of features were created or updated - std::static_pointer_cast(Model_Session::get()) - ->setCheckTransactions(false); Events_Loop* aLoop = Events_Loop::loop(); aLoop->activateFlushes(false); @@ -886,9 +882,9 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t ModelAPI_EventCreator::get()->sendUpdated(aFeature, EVENT_DISP); aFeature->erase(); // unbind after the "erase" call: on abort sketch is removes sub-objects that corrupts aFIter - TDF_Label aLab = aFIter.Key(); - aFIter.Next(); - myObjs.UnBind(aLab); + myObjs.UnBind(aFIter.Key()); + // reinitialize iterator because unbind may corrupt the previous order in the map + aFIter.Initialize(myObjs); } else aFIter.Next(); } @@ -905,8 +901,6 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); - std::static_pointer_cast(Model_Session::get()) - ->setCheckTransactions(true); myExecuteFeatures = true; } diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 306c4d47e..9f1783fe7 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -35,7 +35,8 @@ static Model_Session* myImpl = new Model_Session(); bool Model_Session::load(const char* theFileName) { - return ROOT_DOC->load(theFileName); + bool aRes = ROOT_DOC->load(theFileName); + return aRes; } bool Model_Session::save(const char* theFileName, std::list& theResults) @@ -62,12 +63,16 @@ void Model_Session::startOperation() void Model_Session::finishOperation() { + setCheckTransactions(false); ROOT_DOC->finishOperation(); + setCheckTransactions(true); } void Model_Session::abortOperation() { + setCheckTransactions(false); ROOT_DOC->abortOperation(); + setCheckTransactions(true); // here the update mechanism may work after abort, so, supress the warnings about // modifications outside of the transactions bool aWasCheck = myCheckTransactions; @@ -96,7 +101,9 @@ bool Model_Session::canUndo() void Model_Session::undo() { + setCheckTransactions(false); ROOT_DOC->undo(); + setCheckTransactions(true); } bool Model_Session::canRedo() @@ -106,7 +113,9 @@ bool Model_Session::canRedo() void Model_Session::redo() { + setCheckTransactions(false); ROOT_DOC->redo(); + setCheckTransactions(true); } FeaturePtr Model_Session::createFeature(string theFeatureID) @@ -179,6 +188,15 @@ void Model_Session::setActiveDocument( if (myCurrentDoc != theDoc) { myCurrentDoc = theDoc; if (theSendSignal) { + // syncronize the document: it may be just opened or opened but removed before + std::shared_ptr aDoc = std::dynamic_pointer_cast(theDoc); + if (aDoc) { + bool aWasChecked = myCheckTransactions; + setCheckTransactions(false); + aDoc->synchronizeFeatures(false, true); + if (aWasChecked) + setCheckTransactions(true); + } static std::shared_ptr aMsg( new Events_Message(Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED))); Events_Loop::loop()->send(aMsg); -- 2.39.2