From c130b98205c701e153fd4a8372c6d1aa4e8257df Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 24 Nov 2014 14:12:16 +0300 Subject: [PATCH] Issue #271: referencing between documents is implemented (the issue for filtering out the Part-Extrusion for PartSet sketch will be registered) --- src/Model/Model_AttributeReference.cpp | 55 +++++++++++++++---- src/Model/Model_AttributeSelection.cpp | 4 +- src/Model/Model_Session.cpp | 6 ++ src/Model/Model_Session.h | 3 + src/ModelAPI/ModelAPI_Session.h | 3 + src/ModuleBase/ModuleBase_ViewerFilters.cpp | 2 +- .../ModuleBase_WidgetShapeSelector.cpp | 2 +- 7 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index e209eb0e1..e65cb91c2 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -7,6 +7,11 @@ #include "Model_Events.h" #include "Model_Data.h" #include +#include + +#include +#include +#include using namespace std; @@ -15,12 +20,25 @@ void Model_AttributeReference::setValue(ObjectPtr theObject) if(!theObject) return; if (!myIsInitialized || value() != theObject) { - std::shared_ptr aData = std::dynamic_pointer_cast( - theObject->data()); + std::shared_ptr aData = std::dynamic_pointer_cast( + theObject->data()); + TDF_Label anObjLab = aData->label().Father(); // object label - std::shared_ptr aDoc = - std::dynamic_pointer_cast(owner()->document()); - myRef->Set(aData->label().Father()); // references to the feature label + if (owner()->document() == theObject->document()) { // same document, use reference attribute + + std::shared_ptr aDoc = + std::dynamic_pointer_cast(owner()->document()); + myRef->Set(anObjLab); // references to the object label + // remove external link attributes (if any) + anObjLab.ForgetAttribute(TDataStd_Comment::GetID()); + anObjLab.ForgetAttribute(TDataStd_AsciiString::GetID()); + } else { // different document: store the document name (comment) and entry (string): external + // if these attributes exist, the link is external: keep reference to access the label + TDataStd_Comment::Set(myRef->Label(), theObject->document()->id().c_str()); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(anObjLab, anEntry); + TDataStd_AsciiString::Set(myRef->Label(), anEntry); + } owner()->data()->sendAttributeUpdated(this); } @@ -29,11 +47,28 @@ void Model_AttributeReference::setValue(ObjectPtr theObject) ObjectPtr Model_AttributeReference::value() { if (myIsInitialized) { - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); - if (aDoc) { - TDF_Label aRefLab = myRef->Get(); - return aDoc->object(aRefLab); + Handle(TDataStd_Comment) aDocID; + if (myRef->Label().FindAttribute(TDataStd_Comment::GetID(), aDocID)) { // external ref + DocumentPtr aRefDoc = + ModelAPI_Session::get()->document(TCollection_AsciiString(aDocID->Get()).ToCString()); + if (aRefDoc) { + Handle(TDataStd_AsciiString) anEntry; + if (myRef->Label().FindAttribute(TDataStd_AsciiString::GetID(), anEntry)) { + std::shared_ptr aDR = std::dynamic_pointer_cast(aRefDoc); + TDF_Label aRefLab; + TDF_Tool::Label(aDR->featuresLabel().Data(), anEntry->Get().ToCString(), aRefLab); + if (!aRefLab.IsNull()) { + return aDR->object(aRefLab); + } + } + } + } else { // internal ref + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + TDF_Label aRefLab = myRef->Get(); + return aDoc->object(aRefLab); + } } } // not initialized diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 0ae4bf6a8..4f95dc83f 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -127,7 +127,7 @@ bool Model_AttributeSelection::update() bool aNoIndexes = !aLab.FindAttribute(TDataStd_IntPackedMap::GetID(), aSubIds) || aSubIds->Extent() == 0; // for now working only with composite features - FeaturePtr aContextFeature = owner()->document()->feature(aContext); + FeaturePtr aContextFeature = aContext->document()->feature(aContext); CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aContextFeature); if (!aComposite || aComposite->numberOfSubs() == 0) { @@ -296,7 +296,7 @@ void Model_AttributeSelection::selectBody( void Model_AttributeSelection::selectConstruction( const ResultPtr& theContext, const std::shared_ptr& theSubShape) { - FeaturePtr aContextFeature = owner()->document()->feature(theContext); + FeaturePtr aContextFeature = theContext->document()->feature(theContext); CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aContextFeature); if (!aComposite || aComposite->numberOfSubs() == 0) { diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index d8e516698..88f87b73e 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -141,6 +141,12 @@ std::shared_ptr Model_Session::moduleDocument() Model_Application::getApplication()->getDocument("root")); } +std::shared_ptr Model_Session::document(std::string theDocID) +{ + return std::shared_ptr( + Model_Application::getApplication()->getDocument(theDocID)); +} + bool Model_Session::hasModuleDocument() { return Model_Application::getApplication()->hasDocument("root"); diff --git a/src/Model/Model_Session.h b/src/Model/Model_Session.h index 72977752a..41d62e4f9 100644 --- a/src/Model/Model_Session.h +++ b/src/Model/Model_Session.h @@ -69,6 +69,9 @@ class Model_Session : public ModelAPI_Session, public Events_Listener /// Returns the root document of the application (that may contains sub-documents) MODEL_EXPORT virtual std::shared_ptr moduleDocument(); + /// Returns the document by ID, loads if not loaded yet. Returns null if no such document. + MODEL_EXPORT virtual std::shared_ptr document(std::string theDocID); + /// Return true if root document has been already created MODEL_EXPORT virtual bool hasModuleDocument(); diff --git a/src/ModelAPI/ModelAPI_Session.h b/src/ModelAPI/ModelAPI_Session.h index 811174e7c..67186674d 100644 --- a/src/ModelAPI/ModelAPI_Session.h +++ b/src/ModelAPI/ModelAPI_Session.h @@ -71,6 +71,9 @@ class MODELAPI_EXPORT ModelAPI_Session /// Returns the root document of the application (that may contains sub-documents) virtual std::shared_ptr moduleDocument() = 0; + /// Returns the document by ID, loads if not loaded yet. Returns null if no such document. + virtual std::shared_ptr document(std::string theDocID) = 0; + /// Return true if root document has been already created virtual bool hasModuleDocument() = 0; diff --git a/src/ModuleBase/ModuleBase_ViewerFilters.cpp b/src/ModuleBase/ModuleBase_ViewerFilters.cpp index a7e2cd3f7..e7309ca07 100644 --- a/src/ModuleBase/ModuleBase_ViewerFilters.cpp +++ b/src/ModuleBase/ModuleBase_ViewerFilters.cpp @@ -37,7 +37,7 @@ Standard_Boolean ModuleBase_ShapeDocumentFilter::IsOk(const Handle(SelectMgr_Ent if (aObj) { DocumentPtr aDoc = aObj->document(); SessionPtr aMgr = ModelAPI_Session::get(); - return (aDoc == aMgr->activeDocument() /* MPV: for the current moment selection in other document is not possible || (aDoc == aMgr->moduleDocument()*/); + return (aDoc == aMgr->activeDocument() || aDoc == aMgr->moduleDocument()); } } } diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp index 146e62efb..2ec2248e4 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp @@ -205,7 +205,7 @@ void ModuleBase_WidgetShapeSelector::onSelectionChanged() // Check that object belongs to active document or PartSet DocumentPtr aDoc = aRes->document(); SessionPtr aMgr = ModelAPI_Session::get(); - if (!(aDoc == aMgr->activeDocument()) || (aDoc == aMgr->moduleDocument())) + if (!(aDoc == aMgr->activeDocument()) && !(aDoc == aMgr->moduleDocument())) return; // Check that the result has a shape -- 2.39.2