From 70f8434967195327040485995ca62b40d029e7ab Mon Sep 17 00:00:00 2001 From: spo Date: Wed, 23 Dec 2015 17:27:48 +0300 Subject: [PATCH] Issue #1158: To use parameters in integer attributes -- Data Model --- src/GeomData/GeomData_Point.h | 4 +- src/GeomData/GeomData_Point2D.h | 4 +- src/Model/Model_AttributeDouble.cpp | 4 +- src/Model/Model_AttributeDouble.h | 4 +- src/Model/Model_AttributeInteger.cpp | 70 ++++++++-- src/Model/Model_AttributeInteger.h | 40 +++++- src/Model/Model_AttributeValidator.cpp | 11 ++ src/Model/Model_Data.cpp | 21 ++- src/Model/Model_Expression.cpp | 123 ++++++++++++------ src/Model/Model_Expression.h | 89 ++++++++++--- src/Model/Model_Update.cpp | 44 +++++-- src/ModelAPI/ModelAPI_AttributeDouble.h | 5 +- src/ModelAPI/ModelAPI_AttributeInteger.h | 30 ++++- src/ModelAPI/ModelAPI_Expression.cpp | 10 ++ src/ModelAPI/ModelAPI_Expression.h | 59 +++++++-- .../ParametersPlugin_EvalListener.cpp | 23 +++- src/PythonAPI/model/tools.py | 5 +- 17 files changed, 428 insertions(+), 118 deletions(-) diff --git a/src/GeomData/GeomData_Point.h b/src/GeomData/GeomData_Point.h index 71c663e90..56d9c042b 100644 --- a/src/GeomData/GeomData_Point.h +++ b/src/GeomData/GeomData_Point.h @@ -12,7 +12,7 @@ #include -class ModelAPI_Expression; +class ModelAPI_ExpressionDouble; /**\class GeomData_Point * \ingroup DataModel @@ -21,7 +21,7 @@ class ModelAPI_Expression; class GeomData_Point : public GeomDataAPI_Point { enum { NUM_COMPONENTS = 3 }; - std::shared_ptr myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y and Z + std::shared_ptr myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y and Z public: /// Defines the double value GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY, const double theZ); diff --git a/src/GeomData/GeomData_Point2D.h b/src/GeomData/GeomData_Point2D.h index 0384409ee..8b4affa03 100644 --- a/src/GeomData/GeomData_Point2D.h +++ b/src/GeomData/GeomData_Point2D.h @@ -12,7 +12,7 @@ #include -class ModelAPI_Expression; +class ModelAPI_ExpressionDouble; /**\class GeomData_Point2D * \ingroup DataModel @@ -22,7 +22,7 @@ class ModelAPI_Expression; class GeomData_Point2D : public GeomDataAPI_Point2D { enum { NUM_COMPONENTS = 2 }; - std::shared_ptr myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y + std::shared_ptr myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y public: /// Defines the double value GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY); diff --git a/src/Model/Model_AttributeDouble.cpp b/src/Model/Model_AttributeDouble.cpp index 91cebf736..0a8566d11 100644 --- a/src/Model/Model_AttributeDouble.cpp +++ b/src/Model/Model_AttributeDouble.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include Model_AttributeDouble::Model_AttributeDouble(TDF_Label& theLabel) { @@ -38,7 +38,7 @@ void Model_AttributeDouble::setText(const std::string& theValue) { if (text() != theValue) { myExpression->setText(theValue); - // Send it to evaluator to convert into the double and store in the attribute + // Send it to evaluator to convert text to double and store in the attribute ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this); owner()->data()->sendAttributeUpdated(this); } diff --git a/src/Model/Model_AttributeDouble.h b/src/Model/Model_AttributeDouble.h index 390cc66bc..da9ca4b55 100644 --- a/src/Model/Model_AttributeDouble.h +++ b/src/Model/Model_AttributeDouble.h @@ -12,7 +12,7 @@ #include -class ModelAPI_Expression; +class ModelAPI_ExpressionDouble; /**\class Model_AttributeDouble * \ingroup DataModel @@ -21,7 +21,7 @@ class ModelAPI_Expression; class Model_AttributeDouble : public ModelAPI_AttributeDouble { - std::shared_ptr myExpression; + std::shared_ptr myExpression; public: /// Defines the double value diff --git a/src/Model/Model_AttributeInteger.cpp b/src/Model/Model_AttributeInteger.cpp index b93bfa855..bd355d4d8 100644 --- a/src/Model/Model_AttributeInteger.cpp +++ b/src/Model/Model_AttributeInteger.cpp @@ -6,32 +6,76 @@ #include -#include #include +#include +#include #include -#include -#include +Model_AttributeInteger::Model_AttributeInteger(TDF_Label& theLabel) +{ + myIsInitialized = true; +} -void Model_AttributeInteger::setValue(const int theValue) +void Model_AttributeInteger::setCalculatedValue(const int theValue) { - if (!myIsInitialized || myInteger->Get() != theValue) { - myInteger->Set(theValue); + if (!myIsInitialized || value() != theValue) { + myExpression->setValue(theValue); owner()->data()->sendAttributeUpdated(this); } } +void Model_AttributeInteger::setValue(const int theValue) +{ + setCalculatedValue(text().empty() ? theValue : value()); +} + int Model_AttributeInteger::value() { - return myInteger->Get(); + return myExpression->value(); } -Model_AttributeInteger::Model_AttributeInteger(TDF_Label& theLabel) +void Model_AttributeInteger::setText(const std::string& theValue) { - // check the attribute could be already presented in this doc (after load document) - myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), myInteger) == Standard_True; - if (!myIsInitialized) { - // create attribute: not initialized by value yet, just zero - myInteger = TDataStd_Integer::Set(theLabel, 0); + if (text() != theValue) { + myExpression->setText(theValue); + // Send it to evaluator to convert text to integer and store in the attribute + ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this); + owner()->data()->sendAttributeUpdated(this); } } + +std::string Model_AttributeInteger::text() +{ + return myExpression->text(); +} + +void Model_AttributeInteger::setExpressionInvalid(const bool theFlag) +{ + myExpression->setInvalid(theFlag); +} + +bool Model_AttributeInteger::expressionInvalid() +{ + return myExpression->isInvalid(); +} + +void Model_AttributeInteger::setExpressionError(const std::string& theError) +{ + if (expressionError() != theError) + myExpression->setError(theError); +} + +std::string Model_AttributeInteger::expressionError() +{ + return myExpression->error(); +} + +void Model_AttributeInteger::setUsedParameters(const std::set& theUsedParameters) +{ + myExpression->setUsedParameters(theUsedParameters); +} + +std::set Model_AttributeInteger::usedParameters() const +{ + return myExpression->usedParameters(); +} diff --git a/src/Model/Model_AttributeInteger.h b/src/Model/Model_AttributeInteger.h index 88b50a504..bd6a12da3 100644 --- a/src/Model/Model_AttributeInteger.h +++ b/src/Model/Model_AttributeInteger.h @@ -11,28 +11,58 @@ #include #include -#include + +class ModelAPI_ExpressionInteger; /**\class Model_AttributeInteger * \ingroup DataModel - * \brief Attribute that contains integer (int). + * \brief Attribute that contains integer. */ class Model_AttributeInteger : public ModelAPI_AttributeInteger { - Handle_TDataStd_Integer myInteger; public: - /// Defines the int value + /// Defines the integer value MODEL_EXPORT virtual void setValue(const int theValue); - /// Returns the int value + /// Returns the integer value MODEL_EXPORT virtual int value(); + /// Defines the calculated value + MODEL_EXPORT virtual void setCalculatedValue(const int theValue); + + /// Defines the text value + MODEL_EXPORT virtual void setText(const std::string& theText); + + /// Returns the text value + MODEL_EXPORT virtual std::string text(); + + /// Allows to set expression (text) as invalid (by the parameters listener) + MODEL_EXPORT virtual void setExpressionInvalid(const bool theFlag); + + /// Returns true if text is invalid + MODEL_EXPORT virtual bool expressionInvalid(); + + /// Allows to set expression (text) error (by the parameters listener) + MODEL_EXPORT virtual void setExpressionError(const std::string& theError); + + /// Returns an expression error + MODEL_EXPORT virtual std::string expressionError(); + + /// Defines the used parameters + MODEL_EXPORT virtual void setUsedParameters(const std::set& theUsedParameters); + + /// Returns the used parameters + MODEL_EXPORT virtual std::set usedParameters() const; + protected: /// Initializes attributes Model_AttributeInteger(TDF_Label& theLabel); friend class Model_Data; + + private: + std::shared_ptr myExpression; }; #endif diff --git a/src/Model/Model_AttributeValidator.cpp b/src/Model/Model_AttributeValidator.cpp index 9a6c95465..93e321832 100644 --- a/src/Model/Model_AttributeValidator.cpp +++ b/src/Model/Model_AttributeValidator.cpp @@ -5,7 +5,10 @@ // Author: Sergey POKHODENKO #include "Model_AttributeValidator.h" + #include +#include + #include #include @@ -13,6 +16,14 @@ bool Model_AttributeValidator::isValid(const AttributePtr& theAttribute, const std::list& theArguments, std::string& theError) const { + if (theAttribute->attributeType() == ModelAPI_AttributeInteger::typeId()) { + AttributeIntegerPtr anAttribue = + std::dynamic_pointer_cast(theAttribute); + if (!anAttribue->expressionError().empty()) { + theError = anAttribue->expressionError(); + return false; + } + } else if (theAttribute->attributeType() == ModelAPI_AttributeDouble::typeId()) { AttributeDoublePtr anAttribue = std::dynamic_pointer_cast(theAttribute); diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 1072d921b..42f04f66a 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -120,12 +120,17 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin if (theAttrType == ModelAPI_AttributeDocRef::typeId()) { anAttr = new Model_AttributeDocRef(anAttrLab); } else if (theAttrType == Model_AttributeInteger::typeId()) { - anAttr = new Model_AttributeInteger(anAttrLab); + Model_AttributeInteger* anAttribute = new Model_AttributeInteger(anAttrLab); + // Expression should use the same label to support backward compatibility + TDF_Label anExpressionLab = anAttrLab; + anAttribute->myExpression.reset(new Model_ExpressionInteger(anExpressionLab)); + anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized(); + anAttr = anAttribute; } else if (theAttrType == ModelAPI_AttributeDouble::typeId()) { Model_AttributeDouble* anAttribute = new Model_AttributeDouble(anAttrLab); TDF_Label anExpressionLab = anAttrLab.FindChild(1); - anAttribute->myExpression.reset(new Model_Expression(anExpressionLab)); - anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized(); + anAttribute->myExpression.reset(new Model_ExpressionDouble(anExpressionLab)); + anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized(); anAttr = anAttribute; } else if (theAttrType == Model_AttributeBoolean::typeId()) { anAttr = new Model_AttributeBoolean(anAttrLab); @@ -149,7 +154,7 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin GeomData_Point* anAttribute = new GeomData_Point(anAttrLab); for (int aComponent = 0; aComponent < GeomData_Point::NUM_COMPONENTS; ++aComponent) { TDF_Label anExpressionLab = anAttrLab.FindChild(aComponent + 1); - anAttribute->myExpression[aComponent].reset(new Model_Expression(anExpressionLab)); + anAttribute->myExpression[aComponent].reset(new Model_ExpressionDouble(anExpressionLab)); anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression[aComponent]->isInitialized(); } anAttr = anAttribute; @@ -159,7 +164,7 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin GeomData_Point2D* anAttribute = new GeomData_Point2D(anAttrLab); for (int aComponent = 0; aComponent < GeomData_Point2D::NUM_COMPONENTS; ++aComponent) { TDF_Label anExpressionLab = anAttrLab.FindChild(aComponent + 1); - anAttribute->myExpression[aComponent].reset(new Model_Expression(anExpressionLab)); + anAttribute->myExpression[aComponent].reset(new Model_ExpressionDouble(anExpressionLab)); anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression[aComponent]->isInitialized(); } anAttr = anAttribute; @@ -509,6 +514,12 @@ void Model_Data::referencesToObjects( for(int a = aRef->size() - 1; a >= 0; a--) { aReferenced.push_back(aRef->value(a)->context()); } + } else if (aType == ModelAPI_AttributeInteger::typeId()) { // integer attribute + AttributeIntegerPtr anAttribute = + std::dynamic_pointer_cast(anAttr->second); + std::set anUsedParameters = anAttribute->usedParameters(); + std::list aParameters = findVariables(anUsedParameters, aMyFeature->document()); + aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end()); } else if (aType == ModelAPI_AttributeDouble::typeId()) { // double attribute AttributeDoublePtr anAttribute = std::dynamic_pointer_cast(anAttr->second); diff --git a/src/Model/Model_Expression.cpp b/src/Model/Model_Expression.cpp index 27e94d406..ef7408e36 100644 --- a/src/Model/Model_Expression.cpp +++ b/src/Model/Model_Expression.cpp @@ -14,21 +14,75 @@ #include #include + +static Standard_GUID kInvalidGUID("caee5ce4-34b1-4b29-abcb-685287d18096"); + + Model_Expression::Model_Expression(TDF_Label& theLabel) { myIsInitialized = true; if (!theLabel.FindAttribute(TDataStd_Name::GetID(), myText)) { myText = TDataStd_Name::Set(theLabel, TCollection_ExtendedString()); - myIsInitialized = false; +// myIsInitialized = false; } if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myError)) { myError = TDataStd_Comment::Set(theLabel, TCollection_ExtendedString()); - myIsInitialized = false; +// myIsInitialized = false; } if (!theLabel.FindAttribute(TDataStd_ExtStringList::GetID(), myUsedParameters)) { myUsedParameters = TDataStd_ExtStringList::Set(theLabel); - myIsInitialized = false; +// myIsInitialized = false; } + // All this attributes should not set myIsInitialized = false. + // This attributes are optional and may absent in old files. So this is OK. + // The reason to set myIsInitialized = false is only absence of + // the value attribute. +} + +void Model_Expression::setText(const std::string& theValue) +{ + if (text() != theValue) + myText->Set(TCollection_ExtendedString(theValue.c_str())); + + setError(text().empty() ? "" : "Not a double value."); +} + +std::string Model_Expression::text() const +{ + return TCollection_AsciiString(myText->Get()).ToCString(); +} + +void Model_Expression::setError(const std::string& theError) +{ + if (error() != theError) + myError->Set(TCollection_ExtendedString(theError.c_str())); +} + +std::string Model_Expression::error() +{ + return TCollection_AsciiString(myError->Get()).ToCString(); +} + +void Model_Expression::setUsedParameters(const std::set& theUsedParameters) +{ + myUsedParameters->Clear(); + std::set::const_iterator anIt = theUsedParameters.begin(); + for (; anIt != theUsedParameters.end(); ++anIt) + myUsedParameters->Append(TCollection_ExtendedString(anIt->c_str())); +} + +std::set Model_Expression::usedParameters() const +{ + std::set aResult; + TDataStd_ListIteratorOfListOfExtendedString aIt; + for (aIt.Initialize(myUsedParameters->List()); aIt.More(); aIt.Next()) + aResult.insert(TCollection_AsciiString(aIt.Value()).ToCString()); + return aResult; +} + +Model_ExpressionDouble::Model_ExpressionDouble(TDF_Label& theLabel) + : Model_Expression(theLabel) +{ if (!theLabel.FindAttribute(TDataStd_Real::GetID(), myReal)) { myReal = TDataStd_Real::Set(theLabel, 0.); myIsInitialized = false; @@ -52,37 +106,21 @@ Model_Expression::Model_Expression(TDF_Label& theLabel) } } } - } } -void Model_Expression::setValue(const double theValue) +void Model_ExpressionDouble::setValue(const double theValue) { if (value() != theValue) myReal->Set(theValue); } -double Model_Expression::value() +double Model_ExpressionDouble::value() { return myReal->Get(); } -void Model_Expression::setText(const std::string& theValue) -{ - if (text() != theValue) - myText->Set(TCollection_ExtendedString(theValue.c_str())); - - setError(text().empty() ? "" : "Not a double value."); -} - -std::string Model_Expression::text() const -{ - return TCollection_AsciiString(myText->Get()).ToCString(); -} - -static Standard_GUID kInvalidGUID("caee5ce4-34b1-4b29-abcb-685287d18096"); - -void Model_Expression::setInvalid(const bool theFlag) +void Model_ExpressionDouble::setInvalid(const bool theFlag) { if (theFlag) { TDataStd_UAttribute::Set(myReal->Label(), kInvalidGUID); @@ -91,35 +129,42 @@ void Model_Expression::setInvalid(const bool theFlag) } } -bool Model_Expression::isInvalid() +bool Model_ExpressionDouble::isInvalid() { return myReal->Label().IsAttribute(kInvalidGUID) == Standard_True; } -void Model_Expression::setError(const std::string& theError) + +Model_ExpressionInteger::Model_ExpressionInteger(TDF_Label& theLabel) + : Model_Expression(theLabel) { - if (error() != theError) - myError->Set(TCollection_ExtendedString(theError.c_str())); + if (!theLabel.FindAttribute(TDataStd_Integer::GetID(), myInteger)) { + myInteger = TDataStd_Integer::Set(theLabel, 0); + myIsInitialized = false; + } } -std::string Model_Expression::error() +void Model_ExpressionInteger::setValue(const int theValue) { - return TCollection_AsciiString(myError->Get()).ToCString(); + if (value() != theValue) + myInteger->Set(theValue); } -void Model_Expression::setUsedParameters(const std::set& theUsedParameters) +int Model_ExpressionInteger::value() { - myUsedParameters->Clear(); - std::set::const_iterator anIt = theUsedParameters.begin(); - for (; anIt != theUsedParameters.end(); ++anIt) - myUsedParameters->Append(TCollection_ExtendedString(anIt->c_str())); + return myInteger->Get(); } -std::set Model_Expression::usedParameters() const +void Model_ExpressionInteger::setInvalid(const bool theFlag) { - std::set aResult; - TDataStd_ListIteratorOfListOfExtendedString aIt; - for (aIt.Initialize(myUsedParameters->List()); aIt.More(); aIt.Next()) - aResult.insert(TCollection_AsciiString(aIt.Value()).ToCString()); - return aResult; + if (theFlag) { + TDataStd_UAttribute::Set(myInteger->Label(), kInvalidGUID); + } else { + myInteger->Label().ForgetAttribute(kInvalidGUID); + } +} + +bool Model_ExpressionInteger::isInvalid() +{ + return myInteger->Label().IsAttribute(kInvalidGUID) == Standard_True; } diff --git a/src/Model/Model_Expression.h b/src/Model/Model_Expression.h index 2963afd36..4e48d15cc 100644 --- a/src/Model/Model_Expression.h +++ b/src/Model/Model_Expression.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -21,31 +22,15 @@ * \ingroup DataModel * \brief Implementation of ModelAPI_Expression. */ -class Model_Expression : public ModelAPI_Expression +class Model_Expression : public virtual ModelAPI_Expression { - Handle_TDataStd_Real myReal; ///< double is Real attribute - Handle_TDataStd_Name myText; ///< Text representation of the attribute (may differ for parameters) - Handle_TDataStd_Comment myError; ///< Error of expression of the text attribute - Handle_TDataStd_ExtStringList myUsedParameters; ///< Parameters used in expression public: - /// Defines the double value - MODEL_EXPORT virtual void setValue(const double theValue); - - /// Returns the double value - MODEL_EXPORT virtual double value(); - /// Sets the text of this Expression MODEL_EXPORT virtual void setText(const std::string& theText); /// Returns the text of this Expression MODEL_EXPORT virtual std::string text() const; - /// Allows to set expression (text) as invalid (by the parameters listener) - MODEL_EXPORT virtual void setInvalid(const bool theFlag); - - /// Returns true if text is invalid - MODEL_EXPORT virtual bool isInvalid(); - /// Allows to set expression (text) error (by the parameters listener) MODEL_EXPORT virtual void setError(const std::string& theError); @@ -62,7 +47,75 @@ class Model_Expression : public ModelAPI_Expression /// Initializes attributes Model_Expression(TDF_Label& theLabel); + Handle_TDataStd_Name myText; ///< Text representation of the attribute (may differ for parameters) + Handle_TDataStd_Comment myError; ///< Error of expression of the text attribute + Handle_TDataStd_ExtStringList myUsedParameters; ///< Parameters used in expression + friend class Model_Data; }; -#endif + +/**\class Model_ExpressionDouble + * \ingroup DataModel + * \brief Implementation of ModelAPI_ExpressionDouble. + */ +class Model_ExpressionDouble : + public Model_Expression, // implementation inheritance + public ModelAPI_ExpressionDouble +{ + public: + /// Defines the double value + MODEL_EXPORT virtual void setValue(const double theValue); + + /// Returns the double value + MODEL_EXPORT virtual double value(); + + /// Allows to set expression (text) as invalid (by the parameters listener) + MODEL_EXPORT virtual void setInvalid(const bool theFlag); + + /// Returns true if text is invalid + MODEL_EXPORT virtual bool isInvalid(); + + protected: + /// Initializes attributes + Model_ExpressionDouble(TDF_Label& theLabel); + + friend class Model_Data; + + private: + Handle_TDataStd_Real myReal; ///< double is Real attribute +}; + + +/**\class Model_ExpressionInteger + * \ingroup DataModel + * \brief Implementation of ModelAPI_ExpressionInteger. + */ +class Model_ExpressionInteger : + public Model_Expression, // implementation inheritance + public ModelAPI_ExpressionInteger +{ + public: + /// Defines the integer value + MODEL_EXPORT virtual void setValue(const int theValue); + + /// Returns the integer value + MODEL_EXPORT virtual int value(); + + /// Allows to set expression (text) as invalid (by the parameters listener) + MODEL_EXPORT virtual void setInvalid(const bool theFlag); + + /// Returns true if text is invalid + MODEL_EXPORT virtual bool isInvalid(); + + protected: + /// Initializes attributes + Model_ExpressionInteger(TDF_Label& theLabel); + + friend class Model_Data; + + private: + Handle_TDataStd_Integer myInteger; +}; + +#endif // Model_Expression_H_ diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 9d655c03c..5749ee70b 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -488,19 +488,39 @@ void Model_Update::updateArguments(FeaturePtr theFeature) { if (aState == ModelAPI_StateInvalidArgument) // a chance to be corrected aState = ModelAPI_StateMustBeUpdated; // check the parameters state - // Double - std::list aDoubles = - theFeature->data()->attributes(ModelAPI_AttributeDouble::typeId()); - std::list::iterator aDoubleIter = aDoubles.begin(); - for(; aDoubleIter != aDoubles.end(); aDoubleIter++) { - AttributeDoublePtr aDouble = - std::dynamic_pointer_cast(*aDoubleIter); - if (aDouble.get() && !aDouble->text().empty()) { - if (myIsParamUpdated) { - ModelAPI_AttributeEvalMessage::send(aDouble, this); + // Integer + { + std::list anAttrinbutes = + theFeature->data()->attributes(ModelAPI_AttributeInteger::typeId()); + std::list::iterator anIter = anAttrinbutes.begin(); + for(; anIter != anAttrinbutes.end(); anIter++) { + AttributeIntegerPtr anAttribute = + std::dynamic_pointer_cast(*anIter); + if (anAttribute.get() && !anAttribute->text().empty()) { + if (myIsParamUpdated) { + ModelAPI_AttributeEvalMessage::send(anAttribute, this); + } + if (anAttribute->expressionInvalid()) { + aState = ModelAPI_StateInvalidArgument; + } } - if (aDouble->expressionInvalid()) { - aState = ModelAPI_StateInvalidArgument; + } + } + // Double + { + std::list aDoubles = + theFeature->data()->attributes(ModelAPI_AttributeDouble::typeId()); + std::list::iterator aDoubleIter = aDoubles.begin(); + for(; aDoubleIter != aDoubles.end(); aDoubleIter++) { + AttributeDoublePtr aDouble = + std::dynamic_pointer_cast(*aDoubleIter); + if (aDouble.get() && !aDouble->text().empty()) { + if (myIsParamUpdated) { + ModelAPI_AttributeEvalMessage::send(aDouble, this); + } + if (aDouble->expressionInvalid()) { + aState = ModelAPI_StateInvalidArgument; + } } } } diff --git a/src/ModelAPI/ModelAPI_AttributeDouble.h b/src/ModelAPI/ModelAPI_AttributeDouble.h index 9332e61b2..79370eedd 100644 --- a/src/ModelAPI/ModelAPI_AttributeDouble.h +++ b/src/ModelAPI/ModelAPI_AttributeDouble.h @@ -7,11 +7,10 @@ #ifndef ModelAPI_AttributeDouble_H_ #define ModelAPI_AttributeDouble_H_ -#include "ModelAPI_Attribute.h" +#include #include - -class ModelAPI_Expression; +#include /**\class ModelAPI_AttributeDouble * \ingroup DataModel diff --git a/src/ModelAPI/ModelAPI_AttributeInteger.h b/src/ModelAPI/ModelAPI_AttributeInteger.h index d16924a98..52062faef 100644 --- a/src/ModelAPI/ModelAPI_AttributeInteger.h +++ b/src/ModelAPI/ModelAPI_AttributeInteger.h @@ -7,12 +7,11 @@ #ifndef MODELAPI_ATTRIBUTEINTEGER_H_ #define MODELAPI_ATTRIBUTEINTEGER_H_ -#include #include +#include #include - /**\class ModelAPI_AttributeInteger * \ingroup DataModel * \brief API for the attribute that contains integer (int). @@ -27,6 +26,33 @@ class ModelAPI_AttributeInteger : public ModelAPI_Attribute /// Returns the integer value MODELAPI_EXPORT virtual int value() = 0; + /// Defines the calculated value + MODELAPI_EXPORT virtual void setCalculatedValue(const int theValue) = 0; + + /// Defines the text value + MODELAPI_EXPORT virtual void setText(const std::string& theText) = 0; + + /// Returns the text value + MODELAPI_EXPORT virtual std::string text() = 0; + + /// Allows to set expression (text) as invalid (by the parameters listener) + MODELAPI_EXPORT virtual void setExpressionInvalid(const bool theFlag) = 0; + + /// Returns true if text is invalid + MODELAPI_EXPORT virtual bool expressionInvalid() = 0; + + /// Allows to set expression (text) error (by the parameters listener) + MODELAPI_EXPORT virtual void setExpressionError(const std::string& theError) = 0; + + /// Returns an expression error + MODELAPI_EXPORT virtual std::string expressionError() = 0; + + /// Defines the used parameters + MODELAPI_EXPORT virtual void setUsedParameters(const std::set& theUsedParameters) = 0; + + /// Returns the used parameters + MODELAPI_EXPORT virtual std::set usedParameters() const = 0; + /// Returns the type of this class of attributes MODELAPI_EXPORT static std::string typeId() { diff --git a/src/ModelAPI/ModelAPI_Expression.cpp b/src/ModelAPI/ModelAPI_Expression.cpp index 39284ef28..bc966b131 100644 --- a/src/ModelAPI/ModelAPI_Expression.cpp +++ b/src/ModelAPI/ModelAPI_Expression.cpp @@ -25,3 +25,13 @@ void ModelAPI_Expression::setInitialized() { myIsInitialized = true; } + +ModelAPI_ExpressionDouble::ModelAPI_ExpressionDouble() +{ + +} + +ModelAPI_ExpressionInteger::ModelAPI_ExpressionInteger() +{ + +} diff --git a/src/ModelAPI/ModelAPI_Expression.h b/src/ModelAPI/ModelAPI_Expression.h index 2c140b63b..c583e58c7 100644 --- a/src/ModelAPI/ModelAPI_Expression.h +++ b/src/ModelAPI/ModelAPI_Expression.h @@ -8,6 +8,7 @@ #define ModelAPI_Expression_H_ #include "ModelAPI.h" + #include #include #include @@ -18,9 +19,6 @@ */ class ModelAPI_Expression { - protected: - bool myIsInitialized; ///< is some value assigned to this attribute - public: /// To virtually destroy the fields of successors MODELAPI_EXPORT virtual ~ModelAPI_Expression(); @@ -31,12 +29,6 @@ class ModelAPI_Expression /// Makes attribute initialized MODELAPI_EXPORT virtual void setInitialized(); - /// Defines the double value - MODELAPI_EXPORT virtual void setValue(const double theValue) = 0; - - /// Returns the double value - MODELAPI_EXPORT virtual double value() = 0; - /// Sets the text of this Expression MODELAPI_EXPORT virtual void setText(const std::string& theText) = 0; @@ -65,10 +57,57 @@ class ModelAPI_Expression /// Objects are created for features automatically MODELAPI_EXPORT ModelAPI_Expression(); + bool myIsInitialized; ///< is some value assigned to this attribute + friend class Model_Data; }; -//! Pointer on Expression object + +/**\class ModelAPI_ExpressionDouble + * \ingroup DataModel + * \brief Expression for calculated double values. + */ +class ModelAPI_ExpressionDouble : public virtual ModelAPI_Expression +{ + public: + /// Defines the double value + MODELAPI_EXPORT virtual void setValue(const double theValue) = 0; + + /// Returns the double value + MODELAPI_EXPORT virtual double value() = 0; + + protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_ExpressionDouble(); + + friend class Model_Data; +}; + + +/**\class ModelAPI_ExpressionInteger + * \ingroup DataModel + * \brief Expression for calculated integer values. + */ +class ModelAPI_ExpressionInteger : public virtual ModelAPI_Expression +{ + public: + /// Defines the integer value + MODELAPI_EXPORT virtual void setValue(const int theValue) = 0; + + /// Returns the integer value + MODELAPI_EXPORT virtual int value() = 0; + + protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_ExpressionInteger(); + + friend class Model_Data; +}; + + +//! Smart pointers for objects typedef std::shared_ptr ExpressionPtr; +typedef std::shared_ptr ExpressionDoublePtr; +typedef std::shared_ptr ExpressionIntegerPtr; #endif diff --git a/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp b/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp index 3d5212bfb..126b0b0f0 100644 --- a/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp +++ b/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp @@ -13,6 +13,8 @@ #include +#include +#include #include #include #include @@ -21,7 +23,6 @@ #include #include -#include #include #include @@ -116,6 +117,18 @@ void ParametersPlugin_EvalListener::processEvaluationEvent( std::shared_ptr aMessage = std::dynamic_pointer_cast(theMessage); + if (aMessage->attribute()->attributeType() == ModelAPI_AttributeInteger::typeId()) { + AttributeIntegerPtr anAttribute = + std::dynamic_pointer_cast(aMessage->attribute()); + std::string anError; + int aValue = (int)evaluate(anAttribute->text(), anError, anAttribute->owner()->document()); + bool isValid = anError.empty(); + if (isValid) + anAttribute->setCalculatedValue(aValue); + anAttribute->setUsedParameters(isValid ? toSet(myInterp->compile(anAttribute->text())) : std::set()); + anAttribute->setExpressionInvalid(!isValid); + anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError); + } else if (aMessage->attribute()->attributeType() == ModelAPI_AttributeDouble::typeId()) { AttributeDoublePtr anAttribute = std::dynamic_pointer_cast(aMessage->attribute()); @@ -241,6 +254,14 @@ void ParametersPlugin_EvalListener::renameInAttribute( const std::string& theOldName, const std::string& theNewName) { + if (theAttribute->attributeType() == ModelAPI_AttributeInteger::typeId()) { + AttributeIntegerPtr anAttribute = + std::dynamic_pointer_cast(theAttribute); + std::string anExpressionString = anAttribute->text(); + anExpressionString = renameInPythonExpression(anExpressionString, + theOldName, theNewName); + anAttribute->setText(anExpressionString); + } else if (theAttribute->attributeType() == ModelAPI_AttributeDouble::typeId()) { AttributeDoublePtr anAttribute = std::dynamic_pointer_cast(theAttribute); diff --git a/src/PythonAPI/model/tools.py b/src/PythonAPI/model/tools.py index 36726317a..508126186 100644 --- a/src/PythonAPI/model/tools.py +++ b/src/PythonAPI/model/tools.py @@ -62,7 +62,6 @@ def fill_attribute(attribute, value): """ if (isinstance(attribute, ModelAPI.ModelAPI_AttributeBoolean) or isinstance(attribute, ModelAPI.ModelAPI_AttributeDocRef) or - isinstance(attribute, ModelAPI.ModelAPI_AttributeInteger) or isinstance(attribute, ModelAPI.ModelAPI_AttributeReference) ): attribute.setValue(value) @@ -70,7 +69,9 @@ def fill_attribute(attribute, value): elif isinstance(attribute, ModelAPI.ModelAPI_AttributeString): attribute.setValue(str(value)) - elif isinstance(attribute, ModelAPI.ModelAPI_AttributeDouble): + elif (isinstance(attribute, ModelAPI.ModelAPI_AttributeDouble) or + isinstance(attribute, ModelAPI.ModelAPI_AttributeInteger) + ): if isinstance(value, basestring): attribute.setText(value) else: -- 2.39.2