From b501b9b003ec4f01c5369b4c281280269b596889 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 18 Sep 2014 16:34:46 +0400 Subject: [PATCH] Make referenced Bodies no more displayed in the Object Browser --- src/Config/Config_FeatureMessage.cpp | 10 +++++ src/Config/Config_FeatureMessage.h | 3 ++ src/Model/Model_Application.cpp | 5 ++- src/Model/Model_AttributeRefAttr.cpp | 1 - src/Model/Model_AttributeReference.cpp | 20 +++++++++- src/Model/Model_AttributeReference.h | 4 +- src/Model/Model_Document.cpp | 55 +++++++++++++++++++++++--- src/Model/Model_Document.h | 15 ++++++- src/Model/Model_Session.cpp | 12 +++++- src/Model/Model_Session.h | 4 +- src/ModelAPI/ModelAPI_Document.h | 7 +++- 11 files changed, 121 insertions(+), 15 deletions(-) diff --git a/src/Config/Config_FeatureMessage.cpp b/src/Config/Config_FeatureMessage.cpp index 041405eb3..de0966349 100644 --- a/src/Config/Config_FeatureMessage.cpp +++ b/src/Config/Config_FeatureMessage.cpp @@ -91,6 +91,16 @@ void Config_FeatureMessage::setWorkbenchId(const std::string& workbenchId) myWorkbenchId = workbenchId; } +const std::string& Config_FeatureMessage::documentKind() const +{ + return myDocumentKind; +} + +void Config_FeatureMessage::setDocumentKind(const std::string& documentKind) +{ + myDocumentKind = documentKind; +} + void Config_FeatureMessage::setTooltip(const std::string& tooltip) { myTooltip = tooltip; diff --git a/src/Config/Config_FeatureMessage.h b/src/Config/Config_FeatureMessage.h index 0cfe67def..cd6ce1d47 100644 --- a/src/Config/Config_FeatureMessage.h +++ b/src/Config/Config_FeatureMessage.h @@ -24,6 +24,7 @@ class Config_FeatureMessage : public Events_Message std::string myGroupId; //Id of feature's group std::string myWorkbenchId; //Id of feature's workbench + std::string myDocumentKind; // kind of the document of the workbench (all documents if empty) std::string myPluginLibrary; //Name of feature's library bool myUseInput; //Action is being checked until user commit the operation @@ -43,6 +44,7 @@ class Config_FeatureMessage : public Events_Message CONFIG_EXPORT const std::string& tooltip() const; CONFIG_EXPORT const std::string& groupId() const; CONFIG_EXPORT const std::string& workbenchId() const; + CONFIG_EXPORT const std::string& documentKind() const; CONFIG_EXPORT const std::string& pluginLibrary() const; CONFIG_EXPORT const std::string& nestedFeatures() const; CONFIG_EXPORT bool isUseInput() const; @@ -55,6 +57,7 @@ class Config_FeatureMessage : public Events_Message CONFIG_EXPORT void setTooltip(const std::string& tooltip); CONFIG_EXPORT void setGroupId(const std::string& groupId); CONFIG_EXPORT void setWorkbenchId(const std::string& workbenchId); + CONFIG_EXPORT void setDocumentKind(const std::string& documentKind); CONFIG_EXPORT void setPluginLibrary(const std::string& thePluginLibrary); CONFIG_EXPORT void setNestedFeatures(const std::string& theNestedFeatures); CONFIG_EXPORT void setUseInput(bool isUseInput); diff --git a/src/Model/Model_Application.cpp b/src/Model/Model_Application.cpp index fe51e99a8..797d00e19 100644 --- a/src/Model/Model_Application.cpp +++ b/src/Model/Model_Application.cpp @@ -24,7 +24,10 @@ const boost::shared_ptr& Model_Application::getDocument(string t if (myDocs.find(theDocID) != myDocs.end()) return myDocs[theDocID]; - boost::shared_ptr aNew(new Model_Document(theDocID)); + static const std::string thePartSetKind("PartSet"); + static const std::string thePartKind("Part"); + boost::shared_ptr aNew( + new Model_Document(theDocID, theDocID == "root" ? thePartSetKind : thePartKind)); myDocs[theDocID] = aNew; // load it if it must be loaded by demand if (myLoadedByDemand.find(theDocID) != myLoadedByDemand.end() && !myPath.empty()) { diff --git a/src/Model/Model_AttributeRefAttr.cpp b/src/Model/Model_AttributeRefAttr.cpp index 560a3fd06..85446ef24 100644 --- a/src/Model/Model_AttributeRefAttr.cpp +++ b/src/Model/Model_AttributeRefAttr.cpp @@ -21,7 +21,6 @@ void Model_AttributeRefAttr::setAttr(boost::shared_ptr theAt string anID = aData->id(theAttr); if (myIsInitialized && object() == theAttr->owner() && myID->Get().IsEqual(anID.c_str())) return; // nothing is changed - myRef->Set(aData->label().Father()); myID->Set(aData->id(theAttr).c_str()); owner()->data()->sendAttributeUpdated(this); diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index 120291627..4e14efc0a 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -17,7 +17,13 @@ void Model_AttributeReference::setValue(ObjectPtr theObject) if (!myIsInitialized || value() != theObject) { boost::shared_ptr aData = boost::dynamic_pointer_cast( theObject->data()); + + boost::shared_ptr aDoc = + boost::dynamic_pointer_cast(owner()->document()); + if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Label())); myRef->Set(aData->label().Father()); // references to the feature label + boost::shared_dynamic_cast(owner()->document())->objectIsReferenced(theObject); + owner()->data()->sendAttributeUpdated(this); } } @@ -39,6 +45,18 @@ ObjectPtr Model_AttributeReference::value() Model_AttributeReference::Model_AttributeReference(TDF_Label& theLabel) { myIsInitialized = theLabel.FindAttribute(TDF_Reference::GetID(), myRef) == Standard_True; - if (!myIsInitialized) + if (!myIsInitialized) { myRef = TDF_Reference::Set(theLabel, theLabel); // not initialized references to itself + } else { + boost::shared_ptr aDoc = + boost::dynamic_pointer_cast(owner()->document()); + if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Label())); + } +} + +Model_AttributeReference::~Model_AttributeReference() +{ + boost::shared_ptr aDoc = + boost::dynamic_pointer_cast(owner()->document()); + if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Label())); } diff --git a/src/Model/Model_AttributeReference.h b/src/Model/Model_AttributeReference.h index da4eb7fbc..e8f9c9997 100644 --- a/src/Model/Model_AttributeReference.h +++ b/src/Model/Model_AttributeReference.h @@ -26,7 +26,9 @@ class Model_AttributeReference : public ModelAPI_AttributeReference /// Returns object referenced from this attribute MODEL_EXPORT virtual ObjectPtr value(); - protected: + MODEL_EXPORT ~Model_AttributeReference(); + +protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeReference(TDF_Label& theLabel); diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index d2fcb36eb..4adcc0aa6 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); @@ -565,7 +565,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 +602,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++; } } } @@ -891,6 +900,42 @@ 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()); + } + } +} + +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()) { + 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(*aFind, 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); diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index f9bbd0809..e67556cc9 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -31,6 +31,10 @@ static Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLa class Model_Document : public ModelAPI_Document { public: + //! Returns the kind of the document: "PartSet", "Part", or something else. + //! This kind is used for feature buttons enable/disable depending on active document + //! (it uses workbench "document" identifier in XML configuration file for this) + MODEL_EXPORT virtual const std::string& kind() const {return myKind;} //! Loads the OCAF document from the file. //! \param theFileName full name of the file to load @@ -138,7 +142,7 @@ class Model_Document : public ModelAPI_Document void synchronizeFeatures(const bool theMarkUpdated = false); //! Creates new document with binary file format - Model_Document(const std::string theID); + Model_Document(const std::string theID, const std::string theKind); Handle_TDocStd_Document document() { @@ -163,12 +167,19 @@ class Model_Document : public ModelAPI_Document //! Updates the results list of the feature basing on the current data tree void updateResults(FeaturePtr theFeature); + //! Stores information that there is a reference to this object + void objectIsReferenced(const ObjectPtr& theObject); + //! Removes information that there is a reference to this object + void objectIsNotReferenced(const ObjectPtr& theObject); + friend class Model_Application; friend class Model_Session; + friend class Model_AttributeReference; friend class DFBrowser; private: std::string myID; ///< identifier of the document in the application + std::string myKind; ///< kind of the document in the application Handle_TDocStd_Document myDoc; ///< OCAF document /// number of transactions after the last "save" call, used for "IsModified" method int myTransactionsAfterSave; @@ -177,6 +188,8 @@ class Model_Document : public ModelAPI_Document /// All features managed by this document (not only in history of OB) /// For optimization mapped by labels NCollection_DataMap myObjs; + /// Results that are referenced and must be concealed for object browser + std::set myConcealedResults; ///< set of identifiers of sub-documents of this document std::set mySubs; diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index d0879860c..a6d12d8fb 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -90,7 +90,14 @@ FeaturePtr Model_Session::createFeature(string theFeatureID) LoadPluginsInfo(); if (myPlugins.find(theFeatureID) != myPlugins.end()) { - myCurrentPluginName = myPlugins[theFeatureID]; + std::pair& aPlugin = myPlugins[theFeatureID]; // plugin and doc kind + if (!aPlugin.second.empty() && aPlugin.second != activeDocument()->kind()) { + Events_Error::send( + string("Feature '") + theFeatureID + "' can not be created in document '" + + aPlugin.second + "' by the XML definition"); + return FeaturePtr(); + } + myCurrentPluginName = aPlugin.first; if (myPluginObjs.find(myCurrentPluginName) == myPluginObjs.end()) { // load plugin library if not yet done Config_ModuleReader::loadLibrary(myCurrentPluginName); @@ -186,7 +193,8 @@ void Model_Session::processEvent(const boost::shared_ptr& theMes if (aMsg) { // proccess the plugin info, load plugin if (myPlugins.find(aMsg->id()) == myPlugins.end()) { - myPlugins[aMsg->id()] = aMsg->pluginLibrary(); + myPlugins[aMsg->id()] = std::pair( + aMsg->pluginLibrary(), aMsg->documentKind()); } } // plugins information was started to load, so, it will be loaded diff --git a/src/Model/Model_Session.h b/src/Model/Model_Session.h index 845d93f7e..dca8f220b 100644 --- a/src/Model/Model_Session.h +++ b/src/Model/Model_Session.h @@ -23,8 +23,8 @@ class Model_Document; class Model_Session : public ModelAPI_Session, public Events_Listener { bool myPluginsInfoLoaded; ///< it true if plugins information is loaded - /// map of feature IDs to plugin name - std::map myPlugins; + /// map of feature IDs to plugin name and document kind + std::map > myPlugins; std::map myPluginObjs; ///< instances of the already plugins std::string myCurrentPluginName; ///< name of the plugin that must be loaded currently boost::shared_ptr myCurrentDoc; ///< current working document diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index a76ee1a2c..cfd0eadf0 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -27,7 +27,12 @@ class ModelAPI_Data; */ class ModelAPI_Document { - public: +public: + //! Returns the kind of the document: "PartSet", "Part", or something else. + //! This kind is used for feature buttons enable/disable depending on active document + //! (it uses workbench "document" identifier in XML configuration file for this) + virtual const std::string& kind() const = 0; + //! Removes document data virtual void close() = 0; -- 2.39.2