X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_Document.cpp;h=ee8cebc14c9d0274a1dd486a1638fca540450c17;hb=f367061802012d6909c2619ef6b6c4cba86fc503;hp=1846045379e64f5aab250cc435c741240d53b705;hpb=f9b192f852b0e67b44cf1b6c38b639eff10b3509;p=modules%2Fshaper.git diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 184604537..ee8cebc14 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -75,7 +75,8 @@ static TCollection_ExtendedString DocFileName(const char* theFileName, const std { TCollection_ExtendedString aPath((const Standard_CString) theFileName); // remove end-separators - while(aPath.Length() && (aPath.Value(aPath.Length()) == '\\' || aPath.Value(aPath.Length()) == '/')) + while(aPath.Length() && + (aPath.Value(aPath.Length()) == '\\' || aPath.Value(aPath.Length()) == '/')) aPath.Remove(aPath.Length()); aPath += _separator_; aPath += theID.c_str(); @@ -83,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)); @@ -160,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); @@ -172,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 @@ -240,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()); } @@ -340,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"))); @@ -370,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(); @@ -397,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(); @@ -445,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); @@ -454,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() @@ -484,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 @@ -583,8 +593,8 @@ FeaturePtr Model_Document::addFeature(std::string theID) /// Appenad to the array of references a new referenced label. /// If theIndex is not -1, removes element at this index, not theReferenced. /// \returns the index of removed element -static int RemoveFromRefArray(TDF_Label theArrayLab, TDF_Label theReferenced, const int theIndex = - -1) +static int RemoveFromRefArray(TDF_Label theArrayLab, TDF_Label theReferenced, + const int theIndex = -1) { int aResult = -1; // no returned Handle(TDataStd_ReferenceArray) aRefs; @@ -820,6 +830,37 @@ ObjectPtr Model_Document::object(const std::string& theGroupID, const int theInd return ObjectPtr(); } +std::shared_ptr Model_Document::objectByName( + const std::string& theGroupID, const std::string& theName) +{ + if (theGroupID == ModelAPI_Feature::group()) { + int anIndex = 0; + TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID()); + for (; aLabIter.More(); aLabIter.Next()) { + TDF_Label aFLabel = aLabIter.Value()->Label(); + FeaturePtr aFeature = feature(aFLabel); + if (aFeature && aFeature->name() == theName) + return aFeature; + } + } else { + // comment must be in any feature: it is kind + int anIndex = 0; + TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID()); + for (; aLabIter.More(); aLabIter.Next()) { + TDF_Label aFLabel = aLabIter.Value()->Label(); + FeaturePtr aFeature = feature(aFLabel); + const std::list >& aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + if ((*aRIter)->groupName() == theGroupID && (*aRIter)->data()->name() == theName) + return *aRIter; + } + } + } + // not found + return ObjectPtr(); +} + int Model_Document::size(const std::string& theGroupID, const bool theHidden) { int aResult = 0; @@ -917,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); @@ -927,11 +969,11 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t static Events_ID aCreateEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - static Events_ID aDeleteEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + static Events_ID aDeleteEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED); static Events_ID aToHideEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); aLoop->activateFlushes(false); - // update all objects by checking are they of labels or not + // update all objects by checking are they on labels or not std::set aNewFeatures, aKeptFeatures; TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID()); for (; aLabIter.More(); aLabIter.Next()) { @@ -1008,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; } @@ -1052,7 +1096,8 @@ void Model_Document::synchronizeBackRefs() if (aFData) { std::list > > aRefs; aFData->referencesToObjects(aRefs); - std::list > >::iterator aRefsIter = aRefs.begin(); + std::list > >::iterator + aRefsIter = aRefs.begin(); for(; aRefsIter != aRefs.end(); aRefsIter++) { std::list::iterator aRefTo = aRefsIter->second.begin(); for(; aRefTo != aRefsIter->second.end(); aRefTo++) { @@ -1099,7 +1144,11 @@ void Model_Document::storeResult(std::shared_ptr theFeatureData, theResult->setDoc(aThis); initData(theResult, resultLabel(theFeatureData, theResultIndex), TAG_FEATURE_ARGUMENTS); if (theResult->data()->name().empty()) { // if was not initialized, generate event and set a name - theResult->data()->setName(theFeatureData->name()); + std::stringstream aNewName; + aNewName<name(); + if (theResultIndex > 0) // if there are several results, add unique prefix starting from second + aNewName<<"_"<data()->setName(aNewName.str()); } }