X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FModel%2FModel_Document.cpp;h=c51d32a74d523db9b02a0c186ceecab79f9421aa;hb=63e954c524a2bf8ef9ee3098f6ee2eb14a9966dd;hp=9057ab82ffd1eee2a582310b9258a2d6c51a617d;hpb=2760e152b279ea889b7839e263071c6875d5f073;p=modules%2Fshaper.git diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 9057ab82f..c51d32a74 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -45,8 +45,8 @@ static const int TAG_HISTORY = 3; // tag of the history sub-tree (python dump) static const int TAG_FEATURE_ARGUMENTS = 1; ///< where the arguments are located static const int TAG_FEATURE_RESULTS = 2; ///< where the results are located -Model_Document::Model_Document(const std::string theID) - : myID(theID), +Model_Document::Model_Document(const std::string theID, const std::string theKind) + : myID(theID), myKind(theKind), myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format { myDoc->SetUndoLimit(UNDO_LIMIT); @@ -255,8 +255,12 @@ bool Model_Document::compactNested() void Model_Document::finishOperation() { - // just to be sure that everybody knows that changes were performed + // finish for all subs first: to avoid nested finishing and "isOperation" calls problems inside + std::set::iterator aSubIter = mySubs.begin(); + for (; aSubIter != mySubs.end(); aSubIter++) + subDoc(*aSubIter)->finishOperation(); + // just to be sure that everybody knows that changes were performed if (!myDoc->HasOpenCommand() && myNestedNum != -1) boost::static_pointer_cast(Model_Session::get()) ->setCheckTransactions(false); // for nested transaction commit @@ -282,10 +286,6 @@ void Model_Document::finishOperation() myTransactionsAfterSave++; } - // finish for all subs - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) - subDoc(*aSubIter)->finishOperation(); } void Model_Document::abortOperation() @@ -399,6 +399,8 @@ FeaturePtr Model_Document::addFeature(std::string theID) TDF_Label anEmptyLab; FeaturePtr anEmptyFeature; FeaturePtr aFeature = ModelAPI_Session::get()->createFeature(theID); + if (!aFeature) + return aFeature; boost::shared_ptr aDocToAdd = boost::dynamic_pointer_cast( aFeature->documentToAdd()); if (aFeature) { @@ -459,15 +461,35 @@ static int RemoveFromRefArray(TDF_Label theArrayLab, TDF_Label theReferenced, co return aResult; } -void Model_Document::removeFeature(FeaturePtr theFeature) +void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck) { + if (theCheck) { + // check the feature: it must have no depended objects on it + std::list::const_iterator aResIter = theFeature->results().cbegin(); + for(; aResIter != theFeature->results().cend(); aResIter++) { + if (myConcealedResults.find(*aResIter) != myConcealedResults.end()) { + Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); + return; + } + } + NCollection_DataMap::Iterator anObjIter(myObjs); + for(; anObjIter.More(); anObjIter.Next()) { + DataPtr aData = anObjIter.Value()->data(); + if (aData->referencesTo(theFeature)) { + Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted"); + return; + } + } + } + boost::shared_ptr aData = boost::static_pointer_cast(theFeature->data()); TDF_Label aFeatureLabel = aData->label().Father(); if (myObjs.IsBound(aFeatureLabel)) myObjs.UnBind(aFeatureLabel); else return; // not found feature => do not remove - + // erase fields + theFeature->erase(); // erase all attributes under the label of feature aFeatureLabel.ForgetAllAttributes(); // remove it from the references array @@ -475,6 +497,7 @@ void Model_Document::removeFeature(FeaturePtr theFeature) // event: feature is deleted ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group()); + /* this is in "erase" // results of this feature must be redisplayed static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); const std::list >& aResults = theFeature->results(); @@ -485,6 +508,7 @@ void Model_Document::removeFeature(FeaturePtr theFeature) ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP); ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), aRes->groupName()); } + */ } FeaturePtr Model_Document::feature(TDF_Label& theLabel) @@ -565,7 +589,12 @@ ObjectPtr Model_Document::object(const std::string& theGroupID, const int theInd const std::list >& aResults = aFeature->results(); std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { - if ((theHidden || (*aRIter)->isInHistory()) && (*aRIter)->groupName() == theGroupID) { + if ((*aRIter)->groupName() != theGroupID) continue; + bool isIn = theHidden; + if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result + isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end(); + } + if (isIn) { if (anIndex == theIndex) return *aRIter; anIndex++; @@ -597,9 +626,13 @@ int Model_Document::size(const std::string& theGroupID, const bool theHidden) const std::list >& aResults = aFeature->results(); std::list >::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { - if ((theHidden || (*aRIter)->isInHistory()) && (*aRIter)->groupName() == theGroupID) { - aResult++; + if ((*aRIter)->groupName() != theGroupID) continue; + bool isIn = theHidden; + if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result + isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end(); } + if (isIn) + aResult++; } } } @@ -725,25 +758,29 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated) if (aKeptFeatures.find(aFIter.Value()) == aKeptFeatures.end() && aNewFeatures.find(aFIter.Value()) == aNewFeatures.end()) { FeaturePtr aFeature = aFIter.Value(); - TDF_Label aLab = aFIter.Key(); - aFIter.Next(); - myObjs.UnBind(aLab); // event: model is updated - if (aFeature->isInHistory()) { + //if (aFeature->isInHistory()) { ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_Feature::group()); - } + //} // results of this feature must be redisplayed (hided) static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); const std::list >& aResults = aFeature->results(); std::list >::const_iterator aRIter = aResults.begin(); + /* for (; aRIter != aResults.cend(); aRIter++) { boost::shared_ptr aRes = *aRIter; //aRes->setData(boost::shared_ptr()); // deleted flag ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP); ModelAPI_EventCreator::get()->sendDeleted(aThis, aRes->groupName()); } + */ // redisplay also removed feature (used for sketch and AISObject) 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); } else aFIter.Next(); } @@ -752,10 +789,10 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated) aLoop->activateFlushes(true); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); if (theMarkUpdated) { aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); } - aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); boost::static_pointer_cast(Model_Session::get()) ->setCheckTransactions(true); @@ -891,6 +928,48 @@ void Model_Document::updateResults(FeaturePtr theFeature) } } +void Model_Document::objectIsReferenced(const ObjectPtr& theObject) +{ + // only bodies are concealed now + ResultBodyPtr aResult = boost::dynamic_pointer_cast(theObject); + if (aResult) { + if (myConcealedResults.find(aResult) != myConcealedResults.end()) { + Events_Error::send(std::string("The object '") + aResult->data()->name() + + "' is already referenced"); + } else { + myConcealedResults.insert(aResult); + boost::shared_ptr aThis = + Model_Application::getApplication()->getDocument(myID); + ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_ResultBody::group()); + + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + aECreator->sendUpdated(aResult, EVENT_DISP); + } + } +} + +void Model_Document::objectIsNotReferenced(const ObjectPtr& theObject) +{ + // only bodies are concealed now + ResultBodyPtr aResult = boost::dynamic_pointer_cast(theObject); + if (aResult) { + std::set::iterator aFind = myConcealedResults.find(aResult); + if (aFind != myConcealedResults.end()) { + ResultPtr aFeature = *aFind; + myConcealedResults.erase(aFind); + boost::shared_ptr aThis = + Model_Application::getApplication()->getDocument(myID); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); + ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent, false); + } else { + Events_Error::send(std::string("The object '") + aResult->data()->name() + + "' was not referenced '"); + } + } +} + Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper) { return TDF_LabelMapHasher::HashCode(theLab, theUpper);