X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_Document.cpp;h=6e9fbf778da1aeca0802669c0e14285f9681ff9c;hb=0c0c2fd5b941ad2e65a0e82251dca2f796750b97;hp=e5c87013ede6a926641a0f41b1c82a0c4fa167aa;hpb=07eadc6d62935271cf75fec5ad99a25eeda273a4;p=modules%2Fshaper.git diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index e5c87013e..6e9fbf778 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -46,9 +48,11 @@ static const int TAG_GENERAL = 1; // general properties tag // general sub-labels static const int TAG_CURRENT_FEATURE = 1; ///< where the reference to the current feature label is located (or no attribute if null feature) +static const int TAG_CURRENT_TRANSACTION = 2; ///< integer, index of the cransaction +static const int TAG_SELECTION_FEATURE = 3; ///< integer, tag of the selection feature label Model_Document::Model_Document(const std::string theID, const std::string theKind) - : myID(theID), myKind(theKind), + : myID(theID), myKind(theKind), myIsActive(false), myDoc(new TDocStd_Document("BinOcaf")) // binary OCAF format { myObjs = new Model_Objects(myDoc->Main()); @@ -171,7 +175,8 @@ bool Model_Document::load(const char* theFileName, DocumentPtr theThis) setCurrentFeature(currentFeature(false), false); aSession->setCheckTransactions(true); aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false); - aSession->setActiveDocument(anApp->getDocument(myID), true); + // this is done in Part result "activate", so no needed here. Causes not-blue active part. + // aSession->setActiveDocument(anApp->getDocument(myID), true); } return !isError; } @@ -257,8 +262,11 @@ void Model_Document::close(const bool theForever) // close all subs const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); - for (; aSubIter != aSubs.end(); aSubIter++) - subDoc(*aSubIter)->close(theForever); + for (; aSubIter != aSubs.end(); aSubIter++) { + std::shared_ptr aSub = subDoc(*aSubIter); + if (aSub->myObjs) // if it was not closed before + aSub->close(theForever); + } // close for thid document needs no transaction in this document std::static_pointer_cast(Model_Session::get())->setCheckTransactions(false); @@ -269,6 +277,7 @@ void Model_Document::close(const bool theForever) myObjs = 0; if (myDoc->CanClose() == CDM_CCS_OK) myDoc->Close(); + mySelectionFeature.reset(); } else { setCurrentFeature(FeaturePtr(), false); // disables all features } @@ -288,6 +297,7 @@ void Model_Document::startOperation() myDoc->NewCommand(); } // starts a new operation + incrementTransactionID(); myTransactions.push_back(Transaction()); if (!myNestedNum.empty()) (*myNestedNum.rbegin())++; @@ -324,7 +334,6 @@ bool Model_Document::finishOperation() aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); 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)); aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); // this must be here just after everything is finished but before real transaction stop // to avoid messages about modifications outside of the transaction @@ -424,9 +433,14 @@ bool Model_Document::canUndo() // check other subs contains operation that can be undoed const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); - for (; aSubIter != aSubs.end(); aSubIter++) - if (subDoc(*aSubIter)->canUndo()) - return true; + for (; aSubIter != aSubs.end(); aSubIter++) { + std::shared_ptr aSub = subDoc(*aSubIter); + if (aSub->myObjs) {// if it was not closed before + if (aSub->canUndo()) + return true; + } + } + return false; } @@ -445,14 +459,17 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron // undo for all subs const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); - for (; aSubIter != aSubs.end(); aSubIter++) + for (; aSubIter != aSubs.end(); aSubIter++) { + if (!subDoc(*aSubIter)->myObjs) + continue; subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize); + } } // after redo of all sub-documents to avoid updates on not-modified data (issue 370) if (theSynchronize) { + myObjs->synchronizeFeatures(true, true, isRoot()); // update the current features status setCurrentFeature(currentFeature(false), false); - myObjs->synchronizeFeatures(true, true, isRoot()); } } @@ -468,9 +485,12 @@ bool Model_Document::canRedo() // check other subs contains operation that can be redoed const std::set aSubs = subDocuments(true); std::set::iterator aSubIter = aSubs.begin(); - for (; aSubIter != aSubs.end(); aSubIter++) + for (; aSubIter != aSubs.end(); aSubIter++) { + if (!subDoc(*aSubIter)->myObjs) + continue; if (subDoc(*aSubIter)->canRedo()) return true; + } return false; } @@ -490,10 +510,10 @@ void Model_Document::redo() for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->redo(); - // update the current features status - setCurrentFeature(currentFeature(false), false); // after redo of all sub-documents to avoid updates on not-modified data (issue 370) myObjs->synchronizeFeatures(true, true, isRoot()); + // update the current features status + setCurrentFeature(currentFeature(false), false); } std::list Model_Document::undoList() const @@ -545,10 +565,10 @@ FeaturePtr Model_Document::addFeature(std::string theID, const bool theMakeCurre aDocToAdd = this; } if (aFeature) { - aDocToAdd->myObjs->addFeature(aFeature, currentFeature(false)); + aDocToAdd->myObjs->addFeature(aFeature, aDocToAdd->currentFeature(false)); if (!aFeature->isAction()) { // do not add action to the data model if (theMakeCurrent) // after all this feature stays in the document, so make it current - setCurrentFeature(aFeature, false); + aDocToAdd->setCurrentFeature(aFeature, false); } else { // feature must be executed // no creation event => updater not working, problem with remove part aFeature->execute(); @@ -566,17 +586,14 @@ void Model_Document::refsToFeature(FeaturePtr theFeature, void Model_Document::removeFeature(FeaturePtr theFeature) { - // if this feature is current, make the current the previous feature - if (theFeature == currentFeature(false)) { - int aCurrentIndex = index(theFeature); - if (aCurrentIndex != -1) { - setCurrentFeature(std::dynamic_pointer_cast( - object(ModelAPI_Feature::group(), aCurrentIndex - 1)), false); - } - } myObjs->removeFeature(theFeature); } +void Model_Document::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis) +{ + myObjs->moveFeature(theMoved, theAfterThis); +} + void Model_Document::updateHistory(const std::shared_ptr theObject) { myObjs->updateHistory(theObject); @@ -636,13 +653,16 @@ int Model_Document::size(const std::string& theGroupID) std::shared_ptr Model_Document::currentFeature(const bool theVisible) { + if (!myObjs) // on close document feature destruction it may call this method + return std::shared_ptr(); TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE); Handle(TDF_Reference) aRef; if (aRefLab.FindAttribute(TDF_Reference::GetID(), aRef)) { TDF_Label aLab = aRef->Get(); FeaturePtr aResult = myObjs->feature(aLab); if (theVisible) { // get nearest visible (in history) going up - while(aResult.get() && !aResult->isInHistory()) { + while(aResult.get() && // sub-composites are never in history + (!aResult->isInHistory() || ModelAPI_Tools::compositeOwner(aResult).get())) { aResult = myObjs->nextFeature(aResult, true); } } @@ -654,32 +674,47 @@ std::shared_ptr Model_Document::currentFeature(const bool theV void Model_Document::setCurrentFeature(std::shared_ptr theCurrent, const bool theVisible) { + // blocks the flush signals to avoid each objects visualization in the viewer + // they should not be shown once after all modifications are performed + Events_Loop* aLoop = Events_Loop::loop(); + bool isActive = aLoop->activateFlushes(false); + TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE); + CompositeFeaturePtr aMain; // main feature that may nest the new current if (theCurrent.get()) { - /* - if (theVisible) { // make features below which are not in history also enabled: sketch subs - FeaturePtr aNext = myObjs->nextFeature(theCurrent); - for (; aNext.get(); aNext = myObjs->nextFeature(theCurrent)) { - if (aNext->isInHistory()) { - break; // next in history is not needed - } else { // next not in history is good for making current - theCurrent = aNext; + aMain = std::dynamic_pointer_cast(theCurrent); + if (!aMain.get()) { + // if feature nests into compisite feature, make the composite feature as current + const std::set& aRefsToMe = theCurrent->data()->refsToMe(); + std::set::const_iterator aRefToMe = aRefsToMe.begin(); + for(; aRefToMe != aRefsToMe.end(); aRefToMe++) { + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast((*aRefToMe)->owner()); + if (aComposite.get() && aComposite->isSub(theCurrent)) { + aMain = aComposite; + break; } } - }*/ - // if feature nests into compisite feature, make the composite feature as current - const std::set& aRefsToMe = theCurrent->data()->refsToMe(); - std::set::const_iterator aRefToMe = aRefsToMe.begin(); - for(; aRefToMe != aRefsToMe.end(); aRefToMe++) { - CompositeFeaturePtr aComposite = - std::dynamic_pointer_cast((*aRefToMe)->owner()); - if (aComposite.get() && aComposite->isSub(theCurrent)) { - theCurrent = aComposite; - } } + } + if (theVisible) { // make features below which are not in history also enabled: sketch subs + FeaturePtr aNext = + theCurrent.get() ? myObjs->nextFeature(theCurrent) : myObjs->firstFeature(); + for (; aNext.get(); aNext = myObjs->nextFeature(theCurrent)) { + if (aNext->isInHistory()) { + break; // next in history is not needed + } else { // next not in history is good for making current + theCurrent = aNext; + } + } + } + if (theCurrent.get()) { std::shared_ptr aData = std::static_pointer_cast(theCurrent->data()); - if (!aData.get()) return; // unknown case + if (!aData.get() || !aData->isValid()) { + aLoop->activateFlushes(isActive); + return; + } TDF_Label aFeatureLabel = aData->label().Father(); Handle(TDF_Reference) aRef; @@ -692,31 +727,60 @@ void Model_Document::setCurrentFeature(std::shared_ptr theCurr aRefLab.ForgetAttribute(TDF_Reference::GetID()); } // make all features after this feature disabled in reversed order (to remove results without deps) - static Events_Loop* aLoop = Events_Loop::loop(); static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - - // if the current feature is composite features, all sub-features also must be enabled - CompositeFeaturePtr aCurComp = std::dynamic_pointer_cast(theCurrent); - + static Events_ID aCreateEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); + static Events_ID aDeleteEvent = aLoop->eventByName(EVENT_OBJECT_DELETED); bool aPassed = false; // flag that the current object is already passed in cycle FeaturePtr anIter = myObjs->lastFeature(); + bool aWasChanged = false; for(; anIter.get(); anIter = myObjs->nextFeature(anIter, true)) { // check this before passed become enabled: the current feature is enabled! if (anIter == theCurrent) aPassed = true; bool aDisabledFlag = !aPassed; - if (aCurComp.get() && aCurComp->isSub(anIter)) + if (aMain.get() && aMain->isSub(anIter)) // sub-elements of not-disabled feature are not disabled aDisabledFlag = false; + if (anIter->getKind() == "Parameter") {// parameters are always out of the history of features, but not parameters + if (theCurrent.get() && theCurrent->getKind() != "Parameter") + aDisabledFlag = false; + } if (anIter->setDisabled(aDisabledFlag)) { // state of feature is changed => so feature become updated static Events_ID anUpdateEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED); ModelAPI_EventCreator::get()->sendUpdated(anIter, anUpdateEvent); // flush is in the end of this method ModelAPI_EventCreator::get()->sendUpdated(anIter, aRedispEvent /*, false*/); + aWasChanged = true; + } + // update for everyone the concealment flag immideately: on edit feature in the midle of history + if (aWasChanged) { + const std::list >& aResList = anIter->results(); + std::list >::const_iterator aRes = aResList.begin(); + for(; aRes != aResList.end(); aRes++) { + if ((*aRes).get() && (*aRes)->data()->isValid() && !(*aRes)->isDisabled()) + std::dynamic_pointer_cast((*aRes)->data())->updateConcealmentFlag(); + } + } } + // unblock the flush signals and up them after this + aLoop->activateFlushes(isActive); + + aLoop->flush(aCreateEvent); aLoop->flush(aRedispEvent); + aLoop->flush(aDeleteEvent); +} + +void Model_Document::setCurrentFeatureUp() +{ + // on remove just go up for minimum step: highlight external objects in sketch causes + // problems if it is true: here and in "setCurrentFeature" + FeaturePtr aCurrent = currentFeature(false); + if (aCurrent.get()) { // if not, do nothing because null is the upper + FeaturePtr aPrev = myObjs->nextFeature(aCurrent, true); + setCurrentFeature(aPrev, false); + } } TDF_Label Model_Document::generalLabel() const @@ -742,6 +806,14 @@ std::shared_ptr Model_Document::createPart( return myObjs->createPart(theFeatureData, theIndex); } +std::shared_ptr Model_Document::copyPart( + const std::shared_ptr& theOldPart, + const std::shared_ptr& theOrigin, + const int theIndex) +{ + return myObjs->copyPart(theOldPart, theOrigin, theIndex); +} + std::shared_ptr Model_Document::createGroup( const std::shared_ptr& theFeatureData, const int theIndex) { @@ -792,3 +864,120 @@ ResultPtr Model_Document::findByName(const std::string theName) { return myObjs->findByName(theName); } + +std::list > Model_Document::allFeatures() +{ + return myObjs->allFeatures(); +} + +void Model_Document::setActive(const bool theFlag) +{ + if (theFlag != myIsActive) { + myIsActive = theFlag; + // redisplay all the objects of this part + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + + for(int a = size(ModelAPI_Feature::group()) - 1; a >= 0; a--) { + FeaturePtr aFeature = std::dynamic_pointer_cast( + object(ModelAPI_Feature::group(), a)); + if (aFeature.get() && aFeature->data()->isValid()) { + const std::list >& aResList = aFeature->results(); + std::list >::const_iterator aRes = aResList.begin(); + for(; aRes != aResList.end(); aRes++) { + ModelAPI_EventCreator::get()->sendUpdated(*aRes, aRedispEvent); + } + } + } + } +} + +bool Model_Document::isActive() const +{ + return myIsActive; +} + +int Model_Document::transactionID() +{ + Handle(TDataStd_Integer) anIndex; + if (!generalLabel().FindChild(TAG_CURRENT_TRANSACTION). + FindAttribute(TDataStd_Integer::GetID(), anIndex)) { + anIndex = TDataStd_Integer::Set(generalLabel().FindChild(TAG_CURRENT_TRANSACTION), 1); + } + return anIndex->Get(); +} + +void Model_Document::incrementTransactionID() +{ + int aNewVal = transactionID() + 1; + TDataStd_Integer::Set(generalLabel().FindChild(TAG_CURRENT_TRANSACTION), aNewVal); +} +void Model_Document::decrementTransactionID() +{ + int aNewVal = transactionID() - 1; + TDataStd_Integer::Set(generalLabel().FindChild(TAG_CURRENT_TRANSACTION), aNewVal); +} + +bool Model_Document::isOpened() +{ + return myObjs && !myDoc.IsNull(); +} + +int Model_Document::numInternalFeatures() +{ + return myObjs->numInternalFeatures(); +} + +std::shared_ptr Model_Document::internalFeature(const int theIndex) +{ + return myObjs->internalFeature(theIndex); +} + +// Feature that is used for selection in the Part document by the external request +class Model_SelectionInPartFeature : public ModelAPI_Feature { +public: + /// Nothing to do in constructor + Model_SelectionInPartFeature() : ModelAPI_Feature() {} + + /// Returns the unique kind of a feature + virtual const std::string& getKind() { + static std::string MY_KIND("InternalSelectionInPartFeature"); + return MY_KIND; + } + /// Request for initialization of data model of the object: adding all attributes + virtual void initAttributes() { + data()->addAttribute("selection", ModelAPI_AttributeSelectionList::typeId()); + } + /// Nothing to do in the execution function + virtual void execute() {} + +}; + +//! Returns the feature that is used for calculation of selection externally from the document +AttributeSelectionListPtr Model_Document::selectionInPartFeature() +{ + // return already created, otherwise create + if (!mySelectionFeature.get() || !mySelectionFeature->data()->isValid()) { + // create a new one + mySelectionFeature = FeaturePtr(new Model_SelectionInPartFeature); + + TDF_Label aFeatureLab = generalLabel().FindChild(TAG_SELECTION_FEATURE); + std::shared_ptr aData(new Model_Data); + aData->setLabel(aFeatureLab.FindChild(1)); + aData->setObject(mySelectionFeature); + mySelectionFeature->setDoc(myObjs->owner()); + mySelectionFeature->setData(aData); + std::string aName = id() + "_Part"; + mySelectionFeature->data()->setName(aName); + mySelectionFeature->setDoc(myObjs->owner()); + mySelectionFeature->initAttributes(); + } + return mySelectionFeature->selectionList("selection"); +} + +FeaturePtr Model_Document::lastFeature() +{ + if (myObjs) + return myObjs->lastFeature(); + return FeaturePtr(); +}