From d57ad65dd41c26cd7c937cc68bc32a23bffd644f Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 23 Dec 2014 16:04:02 +0300 Subject: [PATCH] Issue #295: the rest files for the fix --- src/Model/Model_Document.cpp | 91 +++++++++++++++++++++------------- src/Model/Model_Document.h | 8 ++- src/Model/Model_ResultPart.cpp | 8 ++- src/Model/Model_ResultPart.h | 3 ++ src/Model/Model_Session.cpp | 5 +- src/Model/Model_Update.cpp | 2 +- 6 files changed, 74 insertions(+), 43 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 3dedf9e1a..1e38773f0 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -205,19 +205,17 @@ bool Model_Document::save(const char* theFileName, std::list& theRe myTransactionSave = myTransactionsCounter; if (isDone) { // save also sub-documents if any theResults.push_back(TCollection_AsciiString(aPath).ToCString()); - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end() && isDone; aSubIter++) { + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end() && isDone; aSubIter++) { isDone = subDoc(*aSubIter)->save(theFileName, theResults); } + const std::set allSubs = subDocuments(false); if (isDone) { // also try to copy the not-activated sub-documents - // they are not in mySubs but as ResultParts - int aPartsNum = size(ModelAPI_ResultPart::group()); - for(int aPart = 0; aPart < aPartsNum; aPart++) { - ResultPartPtr aPartRes = std::dynamic_pointer_cast - (object(ModelAPI_ResultPart::group(), aPart)); - if (aPartRes) { - std::string aDocName = aPartRes->data()->name(); - if (!aDocName.empty() && mySubs.find(aDocName) == mySubs.end()) { + for(aSubIter = allSubs.begin(); aSubIter != allSubs.end(); aSubIter++) { + if (aSubs.find(*aSubIter) == aSubs.end()) { // filter out the active subs + std::string aDocName = *aSubIter; + if (!aDocName.empty() && aSubs.find(aDocName) == aSubs.end()) { // just copy file TCollection_AsciiString aSubPath(DocFileName(anApp->loadPath().c_str(), aDocName)); OSD_Path aPath(aSubPath); @@ -246,10 +244,10 @@ void Model_Document::close(const bool theForever) aPM->setActiveDocument(aPM->moduleDocument()); } // close all subs - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->close(theForever); - mySubs.clear(); // close for thid document needs no transaction in this document std::static_pointer_cast(Model_Session::get())->setCheckTransactions(false); @@ -294,8 +292,9 @@ void Model_Document::startOperation() myDoc->NewCommand(); } // new command for all subs - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->startOperation(); } @@ -353,8 +352,9 @@ void Model_Document::finishOperation() ->setCheckTransactions(true); // for nested transaction commit // 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++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->finishOperation(); if (myNestedNum != -1) // this nested transaction is owervritten @@ -388,8 +388,9 @@ void Model_Document::abortOperation() } synchronizeFeatures(true, false); // references were not changed since transaction start // abort for all subs - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->abortOperation(); } @@ -411,8 +412,9 @@ bool Model_Document::canUndo() && myTransactionsCounter != 0 /* for omitting the first useless transaction */) return true; // check other subs contains operation that can be undoed - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) if (subDoc(*aSubIter)->canUndo()) return true; return false; @@ -427,8 +429,9 @@ void Model_Document::undo() myDoc->Undo(); synchronizeFeatures(true, true); // undo for all subs - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->undo(); } @@ -437,8 +440,9 @@ bool Model_Document::canRedo() if (myDoc->GetAvailableRedos() > 0) return true; // check other subs contains operation that can be redoed - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) if (subDoc(*aSubIter)->canRedo()) return true; return false; @@ -453,8 +457,9 @@ void Model_Document::redo() myTransactionsCounter++; synchronizeFeatures(true, true); // redo for all subs - std::set::iterator aSubIter = mySubs.begin(); - for (; aSubIter != mySubs.end(); aSubIter++) + const std::set aSubs = subDocuments(true); + std::set::iterator aSubIter = aSubs.begin(); + for (; aSubIter != aSubs.end(); aSubIter++) subDoc(*aSubIter)->redo(); } @@ -579,7 +584,7 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck) ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group()); } -FeaturePtr Model_Document::feature(TDF_Label& theLabel) +FeaturePtr Model_Document::feature(TDF_Label& theLabel) const { if (myObjs.IsBound(theLabel)) return myObjs.Find(theLabel); @@ -609,17 +614,35 @@ ObjectPtr Model_Document::object(TDF_Label theLabel) std::shared_ptr Model_Document::subDocument(std::string theDocID) { - // just store sub-document identifier here to manage it later - if (mySubs.find(theDocID) == mySubs.end()) - mySubs.insert(theDocID); return Model_Application::getApplication()->getDocument(theDocID); } +const std::set Model_Document::subDocuments(const bool theActivatedOnly) const +{ + std::set aResult; + // 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() != ModelAPI_ResultPart::group()) continue; + if ((*aRIter)->isInHistory()) { + ResultPartPtr aPart = std::dynamic_pointer_cast(*aRIter); + if (aPart && (!theActivatedOnly || aPart->isActivated())) + aResult.insert(aPart->data()->name()); + } + } + } + return aResult; +} + std::shared_ptr Model_Document::subDoc(std::string theDocID) { // just store sub-document identifier here to manage it later - if (mySubs.find(theDocID) == mySubs.end()) - mySubs.insert(theDocID); return std::dynamic_pointer_cast( Model_Application::getApplication()->getDocument(theDocID)); } @@ -710,7 +733,7 @@ int Model_Document::size(const std::string& theGroupID, const bool theHidden) return aResult; } -TDF_Label Model_Document::featuresLabel() +TDF_Label Model_Document::featuresLabel() const { return myDoc->Main().FindChild(TAG_OBJECTS); } diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 758255864..6aa9ef4e8 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -85,7 +85,7 @@ class Model_Document : public ModelAPI_Document //! Returns the existing feature by the label //! \param theLabel base label of the feature - MODEL_EXPORT virtual FeaturePtr feature(TDF_Label& theLabel); + MODEL_EXPORT virtual FeaturePtr feature(TDF_Label& theLabel) const; //! Returns the existing object: result or feature //! \param theLabel base label of the object @@ -144,7 +144,7 @@ class Model_Document : public ModelAPI_Document protected: //! Returns (creates if needed) the features label - TDF_Label featuresLabel(); + TDF_Label featuresLabel() const; //! Initializes feature with a unique name in this group (unique name is generated as //! feature type + "_" + index @@ -184,7 +184,7 @@ class Model_Document : public ModelAPI_Document void updateResults(FeaturePtr theFeature); //! Returns all sub documents - const std::set& subDocuments() const {return mySubs;} + const std::set subDocuments(const bool theActivatedOnly) const; friend class Model_Application; friend class Model_Session; @@ -208,8 +208,6 @@ class Model_Document : public ModelAPI_Document /// Optimization for finding the shape-label by topological naming names std::map myNamingNames; - ///< set of identifiers of sub-documents of this document - std::set mySubs; /// transaction indexes (related to myTransactionsAfterSave) which were empty in this doc std::map myIsEmptyTr; /// If it is true, features are not executed on update (on abort, undo, redo) diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index cc1666e5b..1ec015c90 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -36,7 +36,7 @@ void Model_ResultPart::activate() { std::shared_ptr aDocRef = data()->document(DOC_REF()); - if (!aDocRef->value()) { // create (or open) a document if it is not yet created + if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created std::shared_ptr aDoc = document()->subDocument(data()->name()); if (aDoc) { aDocRef->setValue(aDoc); @@ -45,3 +45,9 @@ void Model_ResultPart::activate() if (aDocRef->value()) ModelAPI_Session::get()->setActiveDocument(aDocRef->value()); } + +bool Model_ResultPart::isActivated() +{ + std::shared_ptr aDocRef = data()->document(DOC_REF()); + return aDocRef->value().get(); +} diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index e88d22aa2..8397a9766 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -35,6 +35,9 @@ protected: /// Sets the data manager of an object (document does), here also attributes are initialized virtual void setData(std::shared_ptr theData); + /// Returns true if document is activated (loaded into the memory) + virtual bool isActivated(); + friend class Model_Document; }; diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 9430c7a16..88d9f81d4 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -190,8 +190,9 @@ std::list > Model_Session::allOpenedDocuments DocumentPtr anAPIDoc = *aDoc; std::shared_ptr aDoc = std::dynamic_pointer_cast(anAPIDoc); if (aDoc) { - std::set::const_iterator aSubIter = aDoc->subDocuments().cbegin(); - for(; aSubIter != aDoc->subDocuments().cend(); aSubIter++) { + const std::set aSubs = aDoc->subDocuments(true); + std::set::const_iterator aSubIter = aSubs.cbegin(); + for(; aSubIter != aSubs.cend(); aSubIter++) { if (!Model_Application::getApplication()->isLoadByDemand(*aSubIter)) { aResult.push_back(Model_Application::getApplication()->getDocument(*aSubIter)); } diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 91751aa77..d6f02c5f7 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -155,7 +155,7 @@ void Model_Update::updateInDoc(std::shared_ptr theDoc) // all sub-documents one by one std::shared_ptr aDoc = std::dynamic_pointer_cast(theDoc); if (aDoc) { - const std::set& aSubs = aDoc->subDocuments(); + const std::set aSubs = aDoc->subDocuments(true); for(std::set::iterator aSub = aSubs.begin(); aSub != aSubs.end(); aSub++) { DocumentPtr aSubDoc = theDoc->subDocument(*aSub); if (aSubDoc) { -- 2.39.2