From 502609e3fb08fe0ac9ffd1cfa3025f67189391ca Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 25 Apr 2014 20:15:13 +0400 Subject: [PATCH] Sending events on attributes data changed --- src/GeomData/CMakeLists.txt | 3 ++- src/GeomData/GeomData_Dir.cpp | 13 ++++++++++--- src/GeomData/GeomData_Point.cpp | 13 ++++++++++--- src/GeomData/GeomData_Point2D.cpp | 11 +++++++++-- src/Model/Model_AttributeDocRef.cpp | 11 ++++++++++- src/Model/Model_AttributeDouble.cpp | 9 ++++++++- src/Model/Model_Data.cpp | 4 +++- src/Model/Model_Data.h | 12 ++++++------ src/Model/Model_Document.cpp | 18 ++++++++++-------- src/Model/Model_Events.cpp | 10 ++-------- src/Model/Model_Events.h | 15 ++++++--------- src/ModelAPI/ModelAPI_Attribute.h | 16 +++++++++++++--- src/ModelAPI/ModelAPI_AttributeDocRef.h | 14 +++++++------- src/ModelAPI/ModelAPI_AttributeDouble.h | 14 +++++++------- src/ModelAPI/ModelAPI_Data.h | 3 --- src/ModelAPI/ModelAPI_Feature.h | 8 ++++++++ src/XGUI/XGUI_DocumentDataModel.cpp | 6 +++--- 17 files changed, 114 insertions(+), 66 deletions(-) diff --git a/src/GeomData/CMakeLists.txt b/src/GeomData/CMakeLists.txt index de9142621..b69c280d0 100644 --- a/src/GeomData/CMakeLists.txt +++ b/src/GeomData/CMakeLists.txt @@ -16,7 +16,7 @@ SET(PROJECT_SOURCES ADD_DEFINITIONS(-DGEOMDATA_EXPORTS ${CAS_DEFINITIONS} ${BOOST_DEFINITIONS}) ADD_LIBRARY(GeomData SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) -TARGET_LINK_LIBRARIES(GeomData ${PROJECT_LIBRARIES} ${CAS_OCAF} ModelAPI GeomAPI) +TARGET_LINK_LIBRARIES(GeomData ${PROJECT_LIBRARIES} ${CAS_OCAF} ModelAPI GeomAPI Events) INCLUDE_DIRECTORIES( ../ModelAPI @@ -24,6 +24,7 @@ INCLUDE_DIRECTORIES( ../GeomAPI ../Events ../Config + ../Model ${CAS_INCLUDE_DIRS} ) diff --git a/src/GeomData/GeomData_Dir.cpp b/src/GeomData/GeomData_Dir.cpp index 22dac3fe4..5090a0626 100644 --- a/src/GeomData/GeomData_Dir.cpp +++ b/src/GeomData/GeomData_Dir.cpp @@ -5,14 +5,21 @@ #include "GeomData_Dir.h" #include "GeomAPI_Dir.h" #include +#include "Model_Events.h" +#include using namespace std; void GeomData_Dir::setValue(const double theX, const double theY, const double theZ) { - myCoords->SetValue(0, theX); - myCoords->SetValue(1, theY); - myCoords->SetValue(2, theZ); + if (myCoords->Value(0) != theX || myCoords->Value(1) != theY || myCoords->Value(2) != theZ) { + myCoords->SetValue(0, theX); + myCoords->SetValue(1, theY); + myCoords->SetValue(2, theZ); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } } double GeomData_Dir::x() const diff --git a/src/GeomData/GeomData_Point.cpp b/src/GeomData/GeomData_Point.cpp index 6f57d4157..b928f3695 100644 --- a/src/GeomData/GeomData_Point.cpp +++ b/src/GeomData/GeomData_Point.cpp @@ -3,14 +3,21 @@ // Author: Mikhail PONIKAROV #include "GeomData_Point.h" +#include "Model_Events.h" +#include using namespace std; void GeomData_Point::setValue(const double theX, const double theY, const double theZ) { - myCoords->SetValue(0, theX); - myCoords->SetValue(1, theY); - myCoords->SetValue(2, theZ); + if (myCoords->Value(0) != theX || myCoords->Value(1) != theY || myCoords->Value(2) != theZ) { + myCoords->SetValue(0, theX); + myCoords->SetValue(1, theY); + myCoords->SetValue(2, theZ); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } } double GeomData_Point::x() const diff --git a/src/GeomData/GeomData_Point2D.cpp b/src/GeomData/GeomData_Point2D.cpp index 3e576226b..bbf3e55fb 100644 --- a/src/GeomData/GeomData_Point2D.cpp +++ b/src/GeomData/GeomData_Point2D.cpp @@ -3,13 +3,20 @@ // Author: Mikhail PONIKAROV #include "GeomData_Point2D.h" +#include "Model_Events.h" +#include using namespace std; void GeomData_Point2D::setValue(const double theX, const double theY) { - myCoords->SetValue(0, theX); - myCoords->SetValue(1, theY); + if (myCoords->Value(0) != theX || myCoords->Value(1) != theY) { + myCoords->SetValue(0, theX); + myCoords->SetValue(1, theY); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } } double GeomData_Point2D::x() const diff --git a/src/Model/Model_AttributeDocRef.cpp b/src/Model/Model_AttributeDocRef.cpp index 9df9c2219..82492e2d6 100644 --- a/src/Model/Model_AttributeDocRef.cpp +++ b/src/Model/Model_AttributeDocRef.cpp @@ -4,12 +4,21 @@ #include "Model_AttributeDocRef.h" #include "Model_Application.h" +#include "Model_Events.h" +#include using namespace std; void Model_AttributeDocRef::setValue(boost::shared_ptr theDoc) { - myComment->Set(TCollection_ExtendedString(theDoc->id().c_str())); + TCollection_ExtendedString aNewID(theDoc->id().c_str()); + if (myComment->Get() != aNewID) { + myComment->Set(TCollection_ExtendedString(theDoc->id().c_str())); + + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } } boost::shared_ptr Model_AttributeDocRef::value() diff --git a/src/Model/Model_AttributeDouble.cpp b/src/Model/Model_AttributeDouble.cpp index 23e15f0e1..13b4c97c6 100644 --- a/src/Model/Model_AttributeDouble.cpp +++ b/src/Model/Model_AttributeDouble.cpp @@ -3,12 +3,19 @@ // Author: Mikhail PONIKAROV #include "Model_AttributeDouble.h" +#include "Model_Events.h" +#include using namespace std; void Model_AttributeDouble::setValue(const double theValue) { - myReal->Set(theValue); + if (myReal->Get() != theValue) { + myReal->Set(theValue); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } } double Model_AttributeDouble::value() diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 0bb5a12c8..5b26417a2 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -49,8 +49,10 @@ void Model_Data::addAttribute(string theID, string theAttrType) else if (theAttrType == GeomData_Point2D::type()) anAttr = new GeomData_Point2D(anAttrLab); - if (anAttr) + if (anAttr) { myAttrs[theID] = boost::shared_ptr(anAttr); + anAttr->setFeature(myFeature); + } else ; // TODO: generate error on unknown attribute request and/or add mechanism for customization } diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 647024e6d..1548c709e 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -12,6 +12,7 @@ #include class ModelAPI_Attribute; +class ModelAPI_Feature; /**\class Model_Data * \ingroup DataModel @@ -25,7 +26,8 @@ class Model_Data: public ModelAPI_Data /// All attributes of the object identified by the attribute ID std::map > myAttrs; - boost::shared_ptr myDoc; ///< document this feature belongs to + /// needed here to emit signal that feature changed on change of the attribute + boost::shared_ptr myFeature; Model_Data(); @@ -53,14 +55,12 @@ public: /// \param theAttrType type of the created attribute (received from the type method) MODEL_EXPORT virtual void addAttribute(std::string theID, std::string theAttrType); - /// Returns the document of this data - MODEL_EXPORT virtual boost::shared_ptr document() {return myDoc;} - /// Puts feature to the document data sub-structure MODEL_EXPORT void setLabel(TDF_Label& theLab); - /// Sets the document of this data - MODEL_EXPORT virtual void setDocument(const boost::shared_ptr& theDoc) {myDoc = theDoc;} + /// Sets the feature of this data + MODEL_EXPORT virtual void setFeature(boost::shared_ptr theFeature) + {myFeature = theFeature;} }; #endif diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index d33caaae8..304bef421 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -223,10 +223,11 @@ void Model_Document::addFeature(const boost::shared_ptr theFea TDF_Label aGroupLab = groupLabel(aGroup); TDF_Label anObjLab = aGroupLab.NewChild(); boost::shared_ptr aData(new Model_Data); + aData->setFeature(theFeature); aData->setLabel(anObjLab); boost::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); - aData->setDocument(aThis); theFeature->setData(aData); + theFeature->setDoc(aThis); setUniqueName(theFeature); theFeature->initAttributes(); // keep the feature ID to restore document later correctly @@ -237,7 +238,7 @@ void Model_Document::addFeature(const boost::shared_ptr theFea // event: feature is added static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED); - ModelAPI_FeatureUpdatedMessage aMsg(aThis, theFeature, anEvent); + Model_FeatureUpdatedMessage aMsg(theFeature, anEvent); Events_Loop::loop()->send(aMsg); } @@ -256,8 +257,8 @@ boost::shared_ptr Model_Document::feature(TDF_Label& theLabel) int Model_Document::featureIndex(boost::shared_ptr theFeature) { - if (theFeature->data()->document().get() != this) { - return theFeature->data()->document()->featureIndex(theFeature); + if (theFeature->document().get() != this) { + return theFeature->document()->featureIndex(theFeature); } boost::shared_ptr aData = boost::dynamic_pointer_cast(theFeature->data()); Handle(TDataStd_Integer) aFeatureIndex; @@ -370,7 +371,7 @@ void Model_Document::synchronizeFeatures() myGroups.erase(aGroupName); aGroupNamesIter = myGroupsNames.erase(aGroupNamesIter); // say that features were deleted from group - ModelAPI_FeatureDeletedMessage aMsg(aThis, aGroupName); + Model_FeatureDeletedMessage aMsg(aThis, aGroupName); Events_Loop::loop()->send(aMsg); } // create new groups basing on the following data model update @@ -407,7 +408,7 @@ void Model_Document::synchronizeFeatures() if (aDSTag > aFeatureTag) { // feature is removed aFIter = aFeatures.erase(aFIter); // event: model is updated - ModelAPI_FeatureDeletedMessage aMsg(aThis, aGroupName); + Model_FeatureDeletedMessage aMsg(aThis, aGroupName); Events_Loop::loop()->send(aMsg); } else if (aDSTag < aFeatureTag) { // a new feature is inserted // create a feature @@ -418,12 +419,13 @@ void Model_Document::synchronizeFeatures() boost::shared_ptr aData(new Model_Data); TDF_Label aLab = aFLabIter.Value()->Label(); aData->setLabel(aLab); - aData->setDocument(Model_Application::getApplication()->getDocument(myID)); + aData->setFeature(aFeature); + aFeature->setDoc(aThis); aFeature->setData(aData); aFeature->initAttributes(); // event: model is updated static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED); - ModelAPI_FeatureUpdatedMessage aMsg(aThis, aFeature, anEvent); + Model_FeatureUpdatedMessage aMsg(aFeature, anEvent); Events_Loop::loop()->send(aMsg); if (aFIter == aFeatures.end()) { diff --git a/src/Model/Model_Events.cpp b/src/Model/Model_Events.cpp index b71ecff50..f4bede4e4 100644 --- a/src/Model/Model_Events.cpp +++ b/src/Model/Model_Events.cpp @@ -5,20 +5,14 @@ #include #include -ModelAPI_FeatureUpdatedMessage::ModelAPI_FeatureUpdatedMessage( - const boost::shared_ptr& theDoc, - const boost::shared_ptr& theFeature, const Events_ID& theEvent) - : Events_Message(theEvent, 0), myFeature(theFeature), myDoc(theDoc) -{} - -ModelAPI_FeatureDeletedMessage::ModelAPI_FeatureDeletedMessage( +Model_FeatureDeletedMessage::Model_FeatureDeletedMessage( const boost::shared_ptr& theDoc, const std::string& theGroup) : Events_Message(messageId(), 0), myDoc(theDoc), myGroup(theGroup) { } -const Events_ID ModelAPI_FeatureDeletedMessage::messageId() +const Events_ID Model_FeatureDeletedMessage::messageId() { static Events_ID MY_ID = Events_Loop::eventByName(EVENT_FEATURE_DELETED); return MY_ID; diff --git a/src/Model/Model_Events.h b/src/Model/Model_Events.h index feda6ab02..5c526db97 100644 --- a/src/Model/Model_Events.h +++ b/src/Model/Model_Events.h @@ -21,29 +21,26 @@ static const char * EVENT_FEATURE_UPDATED = "FeatureUpdated"; static const char * EVENT_FEATURE_DELETED = "FeatureDeleted"; /// Message that feature was changed (used for Object Browser update) -class ModelAPI_FeatureUpdatedMessage : public Events_Message { - boost::shared_ptr myDoc; ///< document owner of the feature +class Model_FeatureUpdatedMessage : public Events_Message { boost::shared_ptr myFeature; ///< which feature is changed public: /// sender is not important, all information is located in the feature - ModelAPI_FeatureUpdatedMessage( - const boost::shared_ptr& theDoc, + Model_FeatureUpdatedMessage( const boost::shared_ptr& theFeature, - const Events_ID& theEvent); + const Events_ID& theEvent) : Events_Message(theEvent, 0), myFeature(theFeature) + {} /// Returns the feature that has been updated boost::shared_ptr feature() const {return myFeature;} - /// Returns the document that has been updated - boost::shared_ptr document() const {return myDoc;} }; /// Message that feature was deleted (used for Object Browser update) -class ModelAPI_FeatureDeletedMessage : public Events_Message { +class Model_FeatureDeletedMessage : public Events_Message { boost::shared_ptr myDoc; ///< document owner of the feature std::string myGroup; ///< group identifier that contained the deleted feature public: /// creates a message by initialization of fields - ModelAPI_FeatureDeletedMessage(const boost::shared_ptr& theDoc, + Model_FeatureDeletedMessage(const boost::shared_ptr& theDoc, const std::string& theGroup); /// Returns the ID of this message (EVENT_FEATURE_DELETED) diff --git a/src/ModelAPI/ModelAPI_Attribute.h b/src/ModelAPI/ModelAPI_Attribute.h index dfcdae495..011430d72 100644 --- a/src/ModelAPI/ModelAPI_Attribute.h +++ b/src/ModelAPI/ModelAPI_Attribute.h @@ -7,21 +7,31 @@ #include "ModelAPI.h" #include +#include + +class ModelAPI_Feature; /**\class ModelAPI_Attribute * \ingroup DataModel * \brief Generic attribute of the Object. */ -class MODELAPI_EXPORT ModelAPI_Attribute +class ModelAPI_Attribute { + ///< needed here to emit signal that feature changed on change of the attribute + boost::shared_ptr myFeature; public: /// Returns the type of this class of attributes, not static method - virtual std::string attributeType() = 0; + MODELAPI_EXPORT virtual std::string attributeType() = 0; /// To virtually destroy the fields of successors - virtual ~ModelAPI_Attribute() {} + MODELAPI_EXPORT virtual ~ModelAPI_Attribute() {} + + MODELAPI_EXPORT void setFeature(const boost::shared_ptr& theFeature) + {myFeature = theFeature;} + MODELAPI_EXPORT const boost::shared_ptr& feature() + {return myFeature;} protected: /// Objects are created for features automatically ModelAPI_Attribute(){} diff --git a/src/ModelAPI/ModelAPI_AttributeDocRef.h b/src/ModelAPI/ModelAPI_AttributeDocRef.h index 473db7a44..4765542cd 100644 --- a/src/ModelAPI/ModelAPI_AttributeDocRef.h +++ b/src/ModelAPI/ModelAPI_AttributeDocRef.h @@ -13,27 +13,27 @@ * \brief Attribute that contains reference to another document. */ -class MODELAPI_EXPORT ModelAPI_AttributeDocRef : public ModelAPI_Attribute +class ModelAPI_AttributeDocRef : public ModelAPI_Attribute { public: /// Defines the document referenced from this attribute - virtual void setValue(boost::shared_ptr theDoc) = 0; + MODELAPI_EXPORT virtual void setValue(boost::shared_ptr theDoc) = 0; /// Returns document referenced from this attribute - virtual boost::shared_ptr value() = 0; + MODELAPI_EXPORT virtual boost::shared_ptr value() = 0; /// Returns the type of this class of attributes - static std::string type() {return "DocRef";} + MODELAPI_EXPORT static std::string type() {return "DocRef";} /// Returns the type of this class of attributes, not static method - virtual std::string attributeType() {return type();} + MODELAPI_EXPORT virtual std::string attributeType() {return type();} /// To virtually destroy the fields of successors - virtual ~ModelAPI_AttributeDocRef() {} + MODELAPI_EXPORT virtual ~ModelAPI_AttributeDocRef() {} protected: /// Objects are created for features automatically - ModelAPI_AttributeDocRef() + MODELAPI_EXPORT ModelAPI_AttributeDocRef() {} }; diff --git a/src/ModelAPI/ModelAPI_AttributeDouble.h b/src/ModelAPI/ModelAPI_AttributeDouble.h index 024da5ea5..81bdb6690 100644 --- a/src/ModelAPI/ModelAPI_AttributeDouble.h +++ b/src/ModelAPI/ModelAPI_AttributeDouble.h @@ -12,27 +12,27 @@ * \brief Attribute that contains real value with double precision. */ -class MODELAPI_EXPORT ModelAPI_AttributeDouble : public ModelAPI_Attribute +class ModelAPI_AttributeDouble : public ModelAPI_Attribute { public: /// Defines the double value - virtual void setValue(const double theValue) = 0; + MODELAPI_EXPORT virtual void setValue(const double theValue) = 0; /// Returns the double value - virtual double value() = 0; + MODELAPI_EXPORT virtual double value() = 0; /// Returns the type of this class of attributes - static std::string type() {return "Double";} + MODELAPI_EXPORT static std::string type() {return "Double";} /// Returns the type of this class of attributes, not static method - virtual std::string attributeType() {return type();} + MODELAPI_EXPORT virtual std::string attributeType() {return type();} /// To virtually destroy the fields of successors - virtual ~ModelAPI_AttributeDouble() {} + MODELAPI_EXPORT virtual ~ModelAPI_AttributeDouble() {} protected: /// Objects are created for features automatically - ModelAPI_AttributeDouble() + MODELAPI_EXPORT ModelAPI_AttributeDouble() {} }; diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 077e75d27..2922f6d9b 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -45,9 +45,6 @@ public: /// \param theAttrType type of the created attribute (received from the type method) virtual void addAttribute(std::string theID, std::string theAttrType) = 0; - /// Returns the document of this data - virtual boost::shared_ptr document() = 0; - /// To virtually destroy the fields of successors virtual ~ModelAPI_Data() {} diff --git a/src/ModelAPI/ModelAPI_Feature.h b/src/ModelAPI/ModelAPI_Feature.h index 8c1a82e75..6c458bab4 100644 --- a/src/ModelAPI/ModelAPI_Feature.h +++ b/src/ModelAPI/ModelAPI_Feature.h @@ -22,6 +22,7 @@ class ModelAPI_Document; class ModelAPI_Feature { boost::shared_ptr myData; ///< manager of the data model of a feature + boost::shared_ptr myDoc; ///< document this feature belongs to public: /// Returns the kind of a feature (like "Point") @@ -44,6 +45,10 @@ public: MODELAPI_EXPORT virtual boost::shared_ptr documentToAdd() {return ModelAPI_PluginManager::get()->currentDocument();} + /// Returns document this feature belongs to + MODELAPI_EXPORT virtual boost::shared_ptr document() + {return myDoc;} + /// To virtually destroy the fields of successors virtual ~ModelAPI_Feature() {} @@ -55,6 +60,9 @@ protected: /// Sets the data manager of an object (document does) MODELAPI_EXPORT void setData(boost::shared_ptr theData) {myData = theData;} + /// Sets the data manager of an object (document does) + MODELAPI_EXPORT void setDoc(boost::shared_ptr theDoc) {myDoc = theDoc;} + friend class Model_Document; }; diff --git a/src/XGUI/XGUI_DocumentDataModel.cpp b/src/XGUI/XGUI_DocumentDataModel.cpp index 50ea7c707..1ee46e331 100644 --- a/src/XGUI/XGUI_DocumentDataModel.cpp +++ b/src/XGUI/XGUI_DocumentDataModel.cpp @@ -42,9 +42,9 @@ void XGUI_DocumentDataModel::processEvent(const Events_Message* theMessage) { // Created object event ******************* if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_CREATED) { - const ModelAPI_FeatureUpdatedMessage* aUpdMsg = dynamic_cast(theMessage); - boost::shared_ptr aDoc = aUpdMsg->document(); + const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast(theMessage); boost::shared_ptr aFeature = aUpdMsg->feature(); + boost::shared_ptr aDoc = aFeature->document(); if (aDoc == myDocument) { // If root objects if (aFeature->getGroup().compare(PARTS_GROUP) == 0) { // Updsate only Parts group @@ -79,7 +79,7 @@ void XGUI_DocumentDataModel::processEvent(const Events_Message* theMessage) // Deteted object event *********************** } else if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_DELETED) { - const ModelAPI_FeatureDeletedMessage* aUpdMsg = dynamic_cast(theMessage); + const Model_FeatureDeletedMessage* aUpdMsg = dynamic_cast(theMessage); boost::shared_ptr aDoc = aUpdMsg->document(); if (aDoc == myDocument) { // If root objects -- 2.30.2