From 91968c131d13ed6e682b23f029f8bc441fc9e05d Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 18 May 2015 16:35:38 +0300 Subject: [PATCH] Debug of load/save and Parts activation --- src/Model/Model_Application.cpp | 4 ++-- src/Model/Model_Data.cpp | 18 ++++++++++++++++ src/Model/Model_Data.h | 7 ++++++ src/Model/Model_Document.cpp | 26 ++++++++++++++-------- src/Model/Model_Document.h | 3 ++- src/Model/Model_Objects.cpp | 31 ++++++++++++++++++++++++++- src/Model/Model_Objects.h | 5 ++++- src/Model/Model_Session.cpp | 2 +- src/ModelAPI/ModelAPI_Data.h | 9 +++++++- src/ModelAPI/ModelAPI_Object.cpp | 13 +++++++---- src/ModelAPI/ModelAPI_Object.h | 1 - src/PartSet/PartSet_Module.cpp | 3 ++- src/PartSet/PartSet_PartDataModel.cpp | 4 +++- 13 files changed, 103 insertions(+), 23 deletions(-) diff --git a/src/Model/Model_Application.cpp b/src/Model/Model_Application.cpp index 60bf41d9f..4a77ae9ef 100644 --- a/src/Model/Model_Application.cpp +++ b/src/Model/Model_Application.cpp @@ -33,14 +33,14 @@ const std::shared_ptr& Model_Application::getDocument(string the bool isRoot = theDocID == "root"; // the document is root std::shared_ptr aNew( new Model_Document(theDocID, isRoot ? thePartSetKind : thePartKind)); - aNew->setThis(aNew); myDocs[theDocID] = aNew; // load it if it must be loaded by demand if (myLoadedByDemand.find(theDocID) != myLoadedByDemand.end() && !myPath.empty()) { - aNew->load(myPath.c_str()); + aNew->load(myPath.c_str(), aNew); myLoadedByDemand.erase(theDocID); // done, don't do it anymore } else { + aNew->setThis(aNew); static Events_ID anId = ModelAPI_DocumentCreatedMessage::eventId(); std::shared_ptr aMessage = std::shared_ptr (new ModelAPI_DocumentCreatedMessage(anId, this)); diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index e2ef4c747..504f310d7 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include @@ -369,3 +371,19 @@ void Model_Data::copyTo(std::shared_ptr theTarget) } } } + +const Standard_GUID kIsInHistory("9275e461-4aca-46c7-ad84-1efb569d8144"); + +bool Model_Data::isInHistory() +{ + return !myLab.IsAttribute(kIsInHistory); +} + +void Model_Data::setIsInHistory(const bool theFlag) +{ + if (theFlag) { // is in histiry true: default behavior, so, remove GUID + myLab.ForgetAttribute(kIsInHistory); + } else { // not standard behavior is defined by special GUID attribute + TDataStd_UAttribute::Set(myLab, kIsInHistory); + } +} diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index b65974b14..40deee668 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -183,6 +183,13 @@ class Model_Data : public ModelAPI_Data /// Copies all atributes content into theTarget data MODEL_EXPORT virtual void copyTo(std::shared_ptr theTarget); +protected: + /// Returns true if "is in history" custom behaviors is defined for the feature + MODEL_EXPORT virtual bool isInHistory(); + + /// Defines the custom "is in history" behavior + MODEL_EXPORT virtual void setIsInHistory(const bool theFlag); + private: /// Removes all information about back references void eraseBackReferences(); diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index df8c90c79..4bf71d034 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -86,7 +86,7 @@ bool Model_Document::isRoot() const return this == Model_Session::get()->moduleDocument().get(); } -bool Model_Document::load(const char* theFileName) +bool Model_Document::load(const char* theFileName, DocumentPtr theThis) { Handle(Model_Application) anApp = Model_Application::getApplication(); if (isRoot()) { @@ -163,10 +163,12 @@ bool Model_Document::load(const char* theFileName) std::dynamic_pointer_cast(Model_Session::get()); aSession->setActiveDocument(anApp->getDocument(myID), false); aSession->setCheckTransactions(false); - DocumentPtr aThis = myObjs->owner(); - delete myObjs; + if (myObjs) + delete myObjs; myObjs = new Model_Objects(myDoc->Main()); // synchronisation is inside - myObjs->setOwner(aThis); + myObjs->setOwner(theThis); + // update the current features status + setCurrentFeature(currentFeature(false), false); aSession->setCheckTransactions(true); aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false); aSession->setActiveDocument(anApp->getDocument(myID), true); @@ -447,8 +449,11 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize); } // after redo of all sub-documents to avoid updates on not-modified data (issue 370) - if (theSynchronize) + if (theSynchronize) { + // update the current features status + setCurrentFeature(currentFeature(false), false); myObjs->synchronizeFeatures(true, true, isRoot()); + } } void Model_Document::undo() @@ -485,6 +490,8 @@ 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()); } @@ -587,10 +594,11 @@ std::shared_ptr Model_Document::subDocument(std::string theDo const std::set Model_Document::subDocuments(const bool theActivatedOnly) const { std::set aResult; - int aNum = myObjs->size(ModelAPI_ResultPart::group()); - for(int a = 0; a < aNum; a++) { - ResultPartPtr aPart = std::dynamic_pointer_cast( - myObjs->object(ModelAPI_ResultPart::group(), a)); + std::list aPartResults; + myObjs->allResults(ModelAPI_ResultPart::group(), aPartResults); + std::list::iterator aPartRes = aPartResults.begin(); + for(; aPartRes != aPartResults.end(); aPartRes++) { + ResultPartPtr aPart = std::dynamic_pointer_cast(*aPartRes); if (aPart && (!theActivatedOnly || aPart->isActivated())) aResult.insert(aPart->data()->name()); } diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 07a899ea8..fc0c0f353 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -36,8 +36,9 @@ class Model_Document : public ModelAPI_Document //! Loads the OCAF document from the file. //! \param theFileName full name of the file to load + //! \param theThis the common shared pointer to the document to manage with it later //! \returns true if file was loaded successfully - MODEL_EXPORT virtual bool load(const char* theFileName); + MODEL_EXPORT virtual bool load(const char* theFileName, DocumentPtr theThis); //! Saves the OCAF document to the file. //! \param theFileName full name of the file to store diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 5e5151bcf..0f661c874 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -43,8 +43,14 @@ static const int TAG_FEATURE_RESULTS = 2; ///< where the results are located Model_Objects::Model_Objects(TDF_Label theMainLab) : myMain(theMainLab) { +} + +void Model_Objects::setOwner(DocumentPtr theDoc) +{ + myDoc = theDoc; // update all fields and recreate features and result objects if needed synchronizeFeatures(false, true, true); + myHistory.clear(); } Model_Objects::~Model_Objects() @@ -361,6 +367,29 @@ int Model_Objects::size(const std::string& theGroupID) return myHistory[theGroupID].size(); } +void Model_Objects::allResults(const std::string& theGroupID, std::list& theResults) +{ + // iterate the array of references and get feature by feature from the array + Handle(TDataStd_ReferenceArray) aRefs; + if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { + for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { + FeaturePtr aFeature = feature(aRefs->Value(a)); + if (aFeature.get()) { + const std::list >& aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + ResultPtr aRes = *aRIter; + if (aRes->groupName() != theGroupID) break; // feature have only same group results + if (aRes->isInHistory() && !aRes->isConcealed()) { + theResults.push_back(*aRIter); + } + } + } + } + } +} + + TDF_Label Model_Objects::featuresLabel() const { return myMain.FindChild(TAG_OBJECTS); @@ -732,7 +761,7 @@ void Model_Objects::updateResults(FeaturePtr theFeature) aResIter++; } // it may be on undo - if (!theFeature->data() || !theFeature->data()->isValid()) + if (!theFeature->data() || !theFeature->data()->isValid() || theFeature->isDisabled()) return; // check that results are presented on all labels int aResSize = theFeature->results().size(); diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index bf9b2bace..06848a858 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -83,6 +83,9 @@ class Model_Objects //! Returns the number of features in the group int size(const std::string& theGroupID); + ///! Returns all (and disabled) results of the given type. Not fast method (iterates all features). + void allResults(const std::string& theGroupID, std::list& theResults); + /// Creates a construction cresults std::shared_ptr createConstruction( const std::shared_ptr& theFeatureData, const int theIndex = 0); @@ -104,7 +107,7 @@ class Model_Objects feature(const std::shared_ptr& theResult); //! Sets the owner of this manager - void setOwner(DocumentPtr theDoc) {myDoc = theDoc;} + void setOwner(DocumentPtr theDoc); //! Returns the owner of this manager DocumentPtr owner() {return myDoc;} diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 9a41142ae..ea951c796 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -37,7 +37,7 @@ static Model_Session* myImpl = new Model_Session(); bool Model_Session::load(const char* theFileName) { - bool aRes = ROOT_DOC->load(theFileName); + bool aRes = ROOT_DOC->load(theFileName, ROOT_DOC); return aRes; } diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index a03a06c9b..a9d2d6222 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -143,10 +143,17 @@ class MODELAPI_EXPORT ModelAPI_Data /// Copies all atributes content into theTarget data virtual void copyTo(std::shared_ptr theTarget) = 0; - protected: /// Objects are created for features automatically ModelAPI_Data(); + + /// Returns true if "is in history" custom behaviors is defined for the feature + virtual bool isInHistory() = 0; + + /// Defines the custom "is in history" behavior + virtual void setIsInHistory(const bool theFlag) = 0; + + friend class ModelAPI_Object; }; typedef std::shared_ptr DataPtr; diff --git a/src/ModelAPI/ModelAPI_Object.cpp b/src/ModelAPI/ModelAPI_Object.cpp index 9d07e42aa..e1b490b42 100644 --- a/src/ModelAPI/ModelAPI_Object.cpp +++ b/src/ModelAPI/ModelAPI_Object.cpp @@ -9,14 +9,19 @@ bool ModelAPI_Object::isInHistory() { - return myInHistory; + if (myData.get() && myData->isValid()) { + return myData->isInHistory(); + } + return true; // default value } void ModelAPI_Object::setInHistory( const std::shared_ptr theObject, const bool theFlag) { - if (myInHistory != theFlag) { - myInHistory = theFlag; + if (isInHistory() != theFlag) { + if (myData.get() && myData->isValid()) { + myData->setIsInHistory(theFlag); + } myDoc->updateHistory(theObject); } } @@ -40,7 +45,7 @@ void ModelAPI_Object::attributeChanged(const std::string& theID) { } -ModelAPI_Object::ModelAPI_Object() : myInHistory(true) +ModelAPI_Object::ModelAPI_Object() { } diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index 86cb4b51f..e0f4ebb0f 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -28,7 +28,6 @@ class ModelAPI_Object { std::shared_ptr myData; ///< manager of the data model of a feature std::shared_ptr myDoc; ///< document this object belongs to - bool myInHistory; ///< keep the information about the presense of the object in the history tree public: /// By default object is displayed in the object browser. MODELAPI_EXPORT virtual bool isInHistory(); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index ffe80756d..6cc3f94e8 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -677,7 +677,8 @@ void PartSet_Module::addObjectBrowserMenu(QMenu* theMenu) const if (!aPart.get()) { aPart = std::dynamic_pointer_cast(aPartFeature->firstResult()); } - aPartDoc = aPart->partDoc(); + if (aPart.get()) // this may be null is Part feature is disabled + aPartDoc; if (aMgr->activeDocument() == aPartDoc) theMenu->addAction(myMenuMgr->action("DEACTIVATE_PART_CMD")); else diff --git a/src/PartSet/PartSet_PartDataModel.cpp b/src/PartSet/PartSet_PartDataModel.cpp index e9d378c30..402244d85 100644 --- a/src/PartSet/PartSet_PartDataModel.cpp +++ b/src/PartSet/PartSet_PartDataModel.cpp @@ -472,7 +472,9 @@ DocumentPtr PartSet_PartDataModel::partDocument() const ObjectPtr aObject = aRootDoc->object(ModelAPI_Feature::group(), myId); FeaturePtr aFeature = ModelAPI_Feature::feature(aObject); ResultPartPtr aPart = std::dynamic_pointer_cast(aFeature->firstResult()); - return aPart->partDoc(); + if (aPart.get()) // this may be null is Part feature is disabled + return aPart->partDoc(); + return DocumentPtr(); } ObjectPtr PartSet_PartDataModel::object(const QModelIndex& theIndex) const -- 2.39.2