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;
\r
std::string myGroupId; //Id of feature's group\r
std::string myWorkbenchId; //Id of feature's workbench\r
+ std::string myDocumentKind; // kind of the document of the workbench (all documents if empty)\r
std::string myPluginLibrary; //Name of feature's library\r
\r
bool myUseInput; //Action is being checked until user commit the operation\r
CONFIG_EXPORT const std::string& tooltip() const;\r
CONFIG_EXPORT const std::string& groupId() const;\r
CONFIG_EXPORT const std::string& workbenchId() const;\r
+ CONFIG_EXPORT const std::string& documentKind() const;\r
CONFIG_EXPORT const std::string& pluginLibrary() const;\r
CONFIG_EXPORT const std::string& nestedFeatures() const;\r
CONFIG_EXPORT bool isUseInput() const;\r
CONFIG_EXPORT void setTooltip(const std::string& tooltip);\r
CONFIG_EXPORT void setGroupId(const std::string& groupId);\r
CONFIG_EXPORT void setWorkbenchId(const std::string& workbenchId);\r
+ CONFIG_EXPORT void setDocumentKind(const std::string& documentKind);\r
CONFIG_EXPORT void setPluginLibrary(const std::string& thePluginLibrary);\r
CONFIG_EXPORT void setNestedFeatures(const std::string& theNestedFeatures);\r
CONFIG_EXPORT void setUseInput(bool isUseInput);\r
if (myDocs.find(theDocID) != myDocs.end())
return myDocs[theDocID];
- boost::shared_ptr<Model_Document> aNew(new Model_Document(theDocID));
+ static const std::string thePartSetKind("PartSet");
+ static const std::string thePartKind("Part");
+ boost::shared_ptr<Model_Document> 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()) {
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);
if (!myIsInitialized || value() != theObject) {
boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(
theObject->data());
+
+ boost::shared_ptr<Model_Document> aDoc =
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
+ if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Label()));
myRef->Set(aData->label().Father()); // references to the feature label
+ boost::shared_dynamic_cast<Model_Document>(owner()->document())->objectIsReferenced(theObject);
+
owner()->data()->sendAttributeUpdated(this);
}
}
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<Model_Document> aDoc =
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
+ if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Label()));
+ }
+}
+
+Model_AttributeReference::~Model_AttributeReference()
+{
+ boost::shared_ptr<Model_Document> aDoc =
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
+ if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Label()));
}
/// 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);
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);
const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
std::list<boost::shared_ptr<ModelAPI_Result> >::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++;
const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
std::list<boost::shared_ptr<ModelAPI_Result> >::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++;
}
}
}
}
}
+void Model_Document::objectIsReferenced(const ObjectPtr& theObject)
+{
+ // only bodies are concealed now
+ ResultBodyPtr aResult = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(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<ModelAPI_Document> 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<ModelAPI_ResultBody>(theObject);
+ if (aResult) {
+ std::set<ResultPtr>::iterator aFind = myConcealedResults.find(aResult);
+ if (aFind != myConcealedResults.end()) {
+ myConcealedResults.erase(aFind);
+ boost::shared_ptr<ModelAPI_Document> 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);
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
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()
{
//! 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;
/// All features managed by this document (not only in history of OB)
/// For optimization mapped by labels
NCollection_DataMap<TDF_Label, FeaturePtr> myObjs;
+ /// Results that are referenced and must be concealed for object browser
+ std::set<ResultPtr> myConcealedResults;
///< set of identifiers of sub-documents of this document
std::set<std::string> mySubs;
LoadPluginsInfo();
if (myPlugins.find(theFeatureID) != myPlugins.end()) {
- myCurrentPluginName = myPlugins[theFeatureID];
+ std::pair<std::string, std::string>& 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);
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<std::string, std::string>(
+ aMsg->pluginLibrary(), aMsg->documentKind());
}
}
// plugins information was started to load, so, it will be loaded
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<std::string, std::string> myPlugins;
+ /// map of feature IDs to plugin name and document kind
+ std::map<std::string, std::pair<std::string, std::string> > myPlugins;
std::map<std::string, ModelAPI_Plugin*> myPluginObjs; ///< instances of the already plugins
std::string myCurrentPluginName; ///< name of the plugin that must be loaded currently
boost::shared_ptr<ModelAPI_Document> myCurrentDoc; ///< current working document
*/
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;