From 82d3040fd8846335e0df735011e682806fb1bb5b Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 28 Nov 2017 13:53:01 +0300 Subject: [PATCH] Synchronize folders as features on the document opening --- src/Model/Model_Objects.cpp | 59 +++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index dafcd5c28..fc9e9ff2a 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -789,16 +789,23 @@ void Model_Objects::synchronizeFeatures( } // update all objects by checking are they on labels or not - std::set aNewFeatures, aKeptFeatures; + std::set aNewFeatures, aKeptFeatures; TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID()); for (; aLabIter.More(); aLabIter.Next()) { TDF_Label aFeatureLabel = aLabIter.Value()->Label(); - FeaturePtr aFeature; - if (!myFeatures.IsBound(aFeatureLabel)) { // a new feature is inserted + if (!myFeatures.IsBound(aFeatureLabel) && !myFolders.IsBound(aFeatureLabel)) { + // a new feature or folder is inserted + + std::string aFeatureID = TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast( + aLabIter.Value())->Get()).ToCString(); + bool isFolder = aFeatureID == ModelAPI_Folder::ID(); + + std::shared_ptr aSession = + std::dynamic_pointer_cast(ModelAPI_Session::get()); + // create a feature - aFeature = std::dynamic_pointer_cast(ModelAPI_Session::get())->createFeature( - TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(aLabIter.Value())->Get()) - .ToCString(), anOwner); + ObjectPtr aFeature = isFolder ? ObjectPtr(new ModelAPI_Folder) + : aSession->createFeature(aFeatureID, anOwner); if (!aFeature.get()) { // somethig is wrong, most probably, the opened document has invalid structure Events_InfoMessage("Model_Objects", "Invalid type of object in the document").send(); @@ -807,7 +814,10 @@ void Model_Objects::synchronizeFeatures( } aFeature->init(); // this must be before "setData" to redo the sketch line correctly - myFeatures.Bind(aFeatureLabel, aFeature); + if (isFolder) + myFolders.Bind(aFeatureLabel, aFeature); + else + myFeatures.Bind(aFeatureLabel, std::dynamic_pointer_cast(aFeature)); aNewFeatures.insert(aFeature); initData(aFeature, aFeatureLabel, TAG_FEATURE_ARGUMENTS); updateHistory(aFeature); @@ -815,18 +825,25 @@ void Model_Objects::synchronizeFeatures( // event: model is updated ModelAPI_EventCreator::get()->sendUpdated(aFeature, aCreateEvent); } else { // nothing is changed, both iterators are incremented - aFeature = myFeatures.Find(aFeatureLabel); - aKeptFeatures.insert(aFeature); + ObjectPtr anObject; + FeaturePtr aFeature; + if (myFeatures.Find(aFeatureLabel, aFeature)) { + aKeptFeatures.insert(aFeature); + anObject = aFeature; + } else + if (myFolders.Find(aFeatureLabel, anObject)) + aKeptFeatures.insert(anObject); + if (anUpdatedMap.Contains(aFeatureLabel)) { if (!theOpen) { // on abort/undo/redo reinitialize attributes if something is changed std::list > anAttrs = - aFeature->data()->attributes(""); + anObject->data()->attributes(""); std::list >::iterator anAttr = anAttrs.begin(); for(; anAttr != anAttrs.end(); anAttr++) (*anAttr)->reinit(); } - ModelAPI_EventCreator::get()->sendUpdated(aFeature, anUpdateEvent); - if (aFeature->getKind() == "Parameter") { + ModelAPI_EventCreator::get()->sendUpdated(anObject, anUpdateEvent); + if (aFeature && aFeature->getKind() == "Parameter") { // if parameters are changed, update the results (issue 937) const std::list >& aResults = aFeature->results(); std::list >::const_iterator aRIter = aResults.begin(); @@ -865,6 +882,24 @@ void Model_Objects::synchronizeFeatures( } else aFIter.Next(); } + // verify folders are checked: if not => is was removed + for (NCollection_DataMap::Iterator aFldIt(myFolders); + aFldIt.More(); aFldIt.Next()) { + ObjectPtr aCurObj = aFldIt.Value(); + if (aKeptFeatures.find(aCurObj) == aKeptFeatures.end() && + aNewFeatures.find(aCurObj) == aNewFeatures.end()) { + ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Folder::group()); + // results of this feature must be redisplayed (hided) + // redisplay also removed feature (used for sketch and AISObject) + ModelAPI_EventCreator::get()->sendUpdated(aCurObj, aRedispEvent); + updateHistory(aCurObj); + aCurObj->erase(); + + // unbind after the "erase" call: on abort sketch + // is removes sub-objects that corrupts aFIter + myFolders.UnBind(aFldIt.Key()); + } + } if (theUpdateReferences) { synchronizeBackRefs(); -- 2.39.2