From 7775c24bea17646e17dd9370befe98b8336de9d8 Mon Sep 17 00:00:00 2001 From: sbh Date: Tue, 7 Apr 2015 17:42:39 +0300 Subject: [PATCH] Show result/error of the parameter --- src/Model/Model_Document.cpp | 3 +- src/Model/Model_ResultParameter.cpp | 38 ++++++------ src/Model/Model_ResultParameter.h | 34 +++++++---- src/ModelAPI/CMakeLists.txt | 1 - src/ModelAPI/ModelAPI_ResultParameter.cpp | 7 +-- src/ModelAPI/ModelAPI_ResultParameter.h | 8 ++- .../ModuleBase_WidgetExprEditor.cpp | 12 ++++ src/ModuleBase/ModuleBase_WidgetExprEditor.h | 2 + .../ParametersPlugin_Parameter.cpp | 42 +++++++++---- .../ParametersPlugin_Parameter.h | 5 +- .../ParametersPlugin_PyInterp.cpp | 57 +++++++++--------- .../ParametersPlugin_PyInterp.h | 5 +- src/XGUI/pictures/expression.png | Bin 297 -> 404 bytes 13 files changed, 128 insertions(+), 86 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 71019bc6d..24854af14 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -1234,7 +1235,7 @@ std::shared_ptr Model_Document::createParameter( aResult = std::dynamic_pointer_cast(anOldObject); } if (!aResult) { - aResult = std::shared_ptr(new ModelAPI_ResultParameter); + aResult = std::shared_ptr(new Model_ResultParameter); storeResult(theFeatureData, aResult, theIndex); } return aResult; diff --git a/src/Model/Model_ResultParameter.cpp b/src/Model/Model_ResultParameter.cpp index 641155b1e..e5110e677 100644 --- a/src/Model/Model_ResultParameter.cpp +++ b/src/Model/Model_ResultParameter.cpp @@ -1,32 +1,28 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -// File: Model_ResultParameter.h +// File: Model_ResultParameter.cpp // Created: 02 Apr 2015 // Author: Sergey BELASH -#ifndef MODEL_RESULTPARAMETER_H_ -#define MODEL_RESULTPARAMETER_H_ +#include "Model_ResultParameter.h" +#include +#include -#include "Model.h" -#include +Model_ResultParameter::~Model_ResultParameter() +{ -#include -#include +} -/**\class Model_ResultParameter - * \ingroup DataModel - * \brief - */ -class Model_ResultParameter : public ModelAPI_ResultParameter +void Model_ResultParameter::initAttributes() { - public: - MODEL_EXPORT virtual ~Model_ResultParameter(); - MODEL_EXPORT virtual void initAttributes(); - - protected: - Model_ResultParameter(); + data()->addAttribute(ModelAPI_ResultParameter::VALUE(), + ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(ModelAPI_ResultParameter::STATE(), + ModelAPI_AttributeString::typeId()); +} - friend class Model_Document; -}; -#endif +Model_ResultParameter::Model_ResultParameter() +{ + setIsConcealed(false); +} diff --git a/src/Model/Model_ResultParameter.h b/src/Model/Model_ResultParameter.h index 08c3e2db7..641155b1e 100644 --- a/src/Model/Model_ResultParameter.h +++ b/src/Model/Model_ResultParameter.h @@ -1,24 +1,32 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -// File: Model_ResultParameter.cpp +// File: Model_ResultParameter.h // Created: 02 Apr 2015 // Author: Sergey BELASH -#include "Model_ResultParameter.h" +#ifndef MODEL_RESULTPARAMETER_H_ +#define MODEL_RESULTPARAMETER_H_ -Model_ResultParameter::~Model_ResultParameter() -{ +#include "Model.h" +#include -} +#include +#include -void Model_ResultParameter::initAttributes() +/**\class Model_ResultParameter + * \ingroup DataModel + * \brief + */ +class Model_ResultParameter : public ModelAPI_ResultParameter { - data()->addAttribute(ModelAPI_ResultParameter::VALUE(), - ModelAPI_AttributeDouble::typeId()); -} + public: + MODEL_EXPORT virtual ~Model_ResultParameter(); + MODEL_EXPORT virtual void initAttributes(); + protected: + Model_ResultParameter(); -Model_ResultParameter::Model_ResultParameter() -{ - setIsConcealed(false); -} + friend class Model_Document; +}; + +#endif diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 249ee64ac..a171d2748 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -68,7 +68,6 @@ SET(PROJECT_SOURCES ModelAPI_Session.cpp ModelAPI_ShapeValidator.cpp ModelAPI_Tools.cpp - ModelAPI_ResultParameter.cpp ModelAPI_AttributeValidator.cpp ) diff --git a/src/ModelAPI/ModelAPI_ResultParameter.cpp b/src/ModelAPI/ModelAPI_ResultParameter.cpp index 781fe33df..c911a414c 100644 --- a/src/ModelAPI/ModelAPI_ResultParameter.cpp +++ b/src/ModelAPI/ModelAPI_ResultParameter.cpp @@ -1,14 +1,11 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -// File: ModelAPI_ResultParameter.h +// File: ModelAPI_ResultParameter.cpp // Created: 07 Jul 2014 // Author: Vitaly SMETANNIKOV #include "ModelAPI_ResultParameter.h" -#include -void ModelAPI_ResultParameter::initAttributes() +ModelAPI_ResultParameter::~ModelAPI_ResultParameter() { - data()->addAttribute(ModelAPI_ResultParameter::VALUE(), - ModelAPI_AttributeDouble::typeId()); } diff --git a/src/ModelAPI/ModelAPI_ResultParameter.h b/src/ModelAPI/ModelAPI_ResultParameter.h index f4b4734c4..1b9dccdf7 100644 --- a/src/ModelAPI/ModelAPI_ResultParameter.h +++ b/src/ModelAPI/ModelAPI_ResultParameter.h @@ -38,7 +38,13 @@ class ModelAPI_ResultParameter : public ModelAPI_Result return MY_VALUE_ID; } - MODELAPI_EXPORT virtual void initAttributes(); + inline static const std::string& STATE() + { + static const std::string MY_VALUE_ID("State"); + return MY_VALUE_ID; + } + + virtual void initAttributes() = 0; }; diff --git a/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp b/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp index 64ca2e312..01d7ba4d5 100644 --- a/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp +++ b/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -149,6 +150,9 @@ ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor(QWidget* theParent, QVBoxLayout* aMainLay = new QVBoxLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); + myResultLabel = new QLabel(this); + myResultLabel->setWordWrap(true); + aMainLay->addWidget(myResultLabel); myEditor = new ExpressionEditor(this); myEditor->setMinimumHeight(20); aMainLay->addWidget(myEditor); @@ -171,6 +175,14 @@ bool ModuleBase_WidgetExprEditor::storeValueCustom() const QString aWidgetValue = myEditor->toPlainText(); aStringAttr->setValue(aWidgetValue.toStdString()); updateObject(myFeature); + + if(!myFeature->firstResult().get()) + return true; + + ResultParameterPtr aResult = + std::dynamic_pointer_cast(myFeature->firstResult()); + AttributeStringPtr aErrorAttr = aResult->data()->string(ModelAPI_ResultParameter::STATE()); + myResultLabel->setText(QString::fromStdString(aErrorAttr->value())); return true; } diff --git a/src/ModuleBase/ModuleBase_WidgetExprEditor.h b/src/ModuleBase/ModuleBase_WidgetExprEditor.h index 41a209f20..b234364f7 100644 --- a/src/ModuleBase/ModuleBase_WidgetExprEditor.h +++ b/src/ModuleBase/ModuleBase_WidgetExprEditor.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -79,6 +80,7 @@ protected: private: /// A line edit control + QLabel* myResultLabel; ExpressionEditor* myEditor; }; diff --git a/src/ParametersPlugin/ParametersPlugin_Parameter.cpp b/src/ParametersPlugin/ParametersPlugin_Parameter.cpp index 073c83cb5..b32afe718 100644 --- a/src/ParametersPlugin/ParametersPlugin_Parameter.cpp +++ b/src/ParametersPlugin/ParametersPlugin_Parameter.cpp @@ -22,6 +22,7 @@ ParametersPlugin_Parameter::ParametersPlugin_Parameter() ParametersPlugin_Parameter::~ParametersPlugin_Parameter() { + myInterp->destroy(); delete myInterp; } @@ -33,28 +34,49 @@ void ParametersPlugin_Parameter::initAttributes() ModelAPI_AttributeString::typeId()); } +bool ParametersPlugin_Parameter::isInHistory() +{ + return false; +} + void ParametersPlugin_Parameter::execute() { + ResultParameterPtr aParam = document()->createParameter(data()); + std::string anExpression = string(ParametersPlugin_Parameter::EXPRESSION_ID())->value(); - if(anExpression.empty()) + if(anExpression.empty()) { + // clear error/result if the expression is empty + aParam->data()->string(ModelAPI_ResultParameter::STATE())->setValue(""); return; - - ResultParameterPtr aParameterResult = document()->createParameter(data()); + } // Value - AttributeDoublePtr aValueAttribute = aParameterResult->data()->real(ModelAPI_ResultParameter::VALUE()); - double aValue = evaluate(anExpression); + std::string outErrorMessage; + double aValue = evaluate(anExpression, outErrorMessage); + AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE()); aValueAttribute->setValue(aValue); - setResult(aParameterResult); + setResult(aParam); // Name std::string aName = string(ParametersPlugin_Parameter::VARIABLE_ID())->value(); std::ostringstream sstream; sstream << aValue; std::string aParamValue = sstream.str(); data()->setName(aName + " ("+ aParamValue + ")"); - aParameterResult->data()->setName(aName); + aParam->data()->setName(aName); + // Error + AttributeStringPtr aErrorAttr = aParam->data()->string(ModelAPI_ResultParameter::STATE()); + std::string aStateMsg; + if (outErrorMessage.empty()) { + aStateMsg = "Result: " + aParamValue; + } else { + aStateMsg = "Error:\n" + outErrorMessage; + } + aErrorAttr->setValue(aStateMsg); + //if(!outErrorMessage.empty()) { + // data()->execState(ModelAPI_StateExecFailed); + //} } -double ParametersPlugin_Parameter::evaluate(std::string theExpression) +double ParametersPlugin_Parameter::evaluate(const std::string& theExpression, std::string& theError) { std::list anExprParams = myInterp->compile(theExpression); // find expression's params in the model @@ -72,7 +94,5 @@ double ParametersPlugin_Parameter::evaluate(std::string theExpression) aContext.push_back(aParamName + "=" + aParamValue); } myInterp->extendLocalContext(aContext); - std::string outError; - return myInterp->evaluate(theExpression, outError); - + return myInterp->evaluate(theExpression, theError); } diff --git a/src/ParametersPlugin/ParametersPlugin_Parameter.h b/src/ParametersPlugin/ParametersPlugin_Parameter.h index 66cd99bfa..9eea5e160 100644 --- a/src/ParametersPlugin/ParametersPlugin_Parameter.h +++ b/src/ParametersPlugin/ParametersPlugin_Parameter.h @@ -51,11 +51,14 @@ class ParametersPlugin_Parameter : public ModelAPI_Feature /// Request for initialization of data model of the feature: adding all attributes PARAMETERSPLUGIN_EXPORT virtual void initAttributes(); + PARAMETERSPLUGIN_EXPORT virtual bool isInHistory(); //false + //bool isI + /// Use plugin manager for features creation ParametersPlugin_Parameter(); protected: - double evaluate(std::string); + double evaluate(const std::string& theExpression, std::string& theError); private: ParametersPlugin_PyInterp* myInterp; diff --git a/src/ParametersPlugin/ParametersPlugin_PyInterp.cpp b/src/ParametersPlugin/ParametersPlugin_PyInterp.cpp index c3546ea92..61b8cfd33 100644 --- a/src/ParametersPlugin/ParametersPlugin_PyInterp.cpp +++ b/src/ParametersPlugin/ParametersPlugin_PyInterp.cpp @@ -20,32 +20,7 @@ ParametersPlugin_PyInterp::~ParametersPlugin_PyInterp() std::list ParametersPlugin_PyInterp::compile(const std::string& theExpression) { - PyGILState_STATE aGilState = PyGILState_Ensure(); - std::list res = this->_compile(theExpression); - PyGILState_Release(aGilState); - return res; -} - -void ParametersPlugin_PyInterp::extendLocalContext(const std::list& theParameters) -{ - PyGILState_STATE aGilState = PyGILState_Ensure(); - this->_extendLocalContext(theParameters); - PyGILState_Release(aGilState); -} - -double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression, - std::string& theError) -{ - PyGILState_STATE aGilState = PyGILState_Ensure(); - double res = this->_evaluate(theExpression, theError); - PyGILState_Release(aGilState); - return res; -} - - -std::list ParametersPlugin_PyInterp::_compile(const std::string& theExpression) -{ - + PyLockWrapper lck; // Acquire GIL until the end of the method std::list aResult; PyObject *aCodeopModule = PyImport_AddModule("codeop"); if(!aCodeopModule) { // Fatal error. No way to go on. @@ -62,6 +37,7 @@ std::list ParametersPlugin_PyInterp::_compile(const std::string& th } PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj; + std::string aCodeName(PyString_AsString(aCodeObj->co_code)); // co_names should be tuple, but can be changed in modern versions of python (>2.7.3) if(!PyTuple_Check(aCodeObj->co_names)) return aResult; @@ -80,8 +56,9 @@ std::list ParametersPlugin_PyInterp::_compile(const std::string& th return aResult; } -void ParametersPlugin_PyInterp::_extendLocalContext(const std::list& theParameters) +void ParametersPlugin_PyInterp::extendLocalContext(const std::list& theParameters) { + PyLockWrapper lck; // Acquire GIL until the end of the method if (theParameters.empty()) return; std::list::const_iterator it = theParameters.begin(); @@ -92,8 +69,9 @@ void ParametersPlugin_PyInterp::_extendLocalContext(const std::list } -double ParametersPlugin_PyInterp::_evaluate(const std::string& theExpression, std::string& theError) +double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression, std::string& theError) { + PyLockWrapper lck; // Acquire GIL until the end of the method PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileString(theExpression.c_str(), "", Py_eval_input); if(!anExprCode) { @@ -115,7 +93,14 @@ double ParametersPlugin_PyInterp::_evaluate(const std::string& theExpression, st Py_XDECREF(anExprCode); Py_XDECREF(anEvalResult); Py_XDECREF(anEvalStrObj); - return std::stod(anEvalStr); + double result = 0.; + try { + result = std::stod(anEvalStr); + } catch (const std::invalid_argument&) { + theError = "Unable to eval " + anEvalStr; + } + + return result; } std::string ParametersPlugin_PyInterp::errorMessage() @@ -134,3 +119,17 @@ std::string ParametersPlugin_PyInterp::errorMessage() } return aPyError; } + +bool ParametersPlugin_PyInterp::initContext() +{ + PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context) + if(!m){ + PyErr_Print(); + return false; + } + _global_context = PyModule_GetDict(m); // get interpreter global variable context + Py_INCREF(_global_context); + _local_context = _global_context; + + return PyRun_SimpleString("from math import *") == 0; +} diff --git a/src/ParametersPlugin/ParametersPlugin_PyInterp.h b/src/ParametersPlugin/ParametersPlugin_PyInterp.h index 6bb2a210d..4151f4e23 100644 --- a/src/ParametersPlugin/ParametersPlugin_PyInterp.h +++ b/src/ParametersPlugin/ParametersPlugin_PyInterp.h @@ -25,10 +25,9 @@ class PARAMETERSPLUGIN_EXPORT ParametersPlugin_PyInterp : public PyInterp_Interp double evaluate(const std::string&, std::string&); protected: - std::list _compile(const std::string&); - void _extendLocalContext(const std::list&); - double _evaluate(const std::string&, std::string&); std::string errorMessage(); + // Overrides PyInterp_Interp + virtual bool initContext(); }; #endif /* PARAMETERSPLUGIN_PYINTERP_H_ */ diff --git a/src/XGUI/pictures/expression.png b/src/XGUI/pictures/expression.png index 74ab35722a14844fa64fe2d6e110eb92ea572a1d..c656b115654fc1658fa884ef151495ca7e265cb3 100644 GIT binary patch delta 377 zcmV-<0fzpm0+a)gB!32COGiWiGXOIHGloAy_5c6?32;bRa{vGf6951U69E94oEQKA z00(qQO+^Ra1P2Qp483Gk^#A|?AxT6*R5;6})4xhwK@`XF&nzo?gRBZRb~fHhn>1E} zAqu{MZxF&DzJo#t777x$_993iRciAJg6KQg+4yIZLQjgl#DC4=3hO;E%wag+A7{=V z8d_4uGJc^oBKw4oNg218d}9K4tp+emwrghzzej{8a7h`Vj3RRHHL~epL}XL-O&NtU z;$PuXMPwV;uY<-TDpF7<5HgbW?9;ba!ELWdLwtX>N2bZe?^JG%heMHD!e|WdHyGnn^@K zR5(w?QNay>APi&#M{olSgg=`*f+IMBBPiEgO*Q=}CSKCC_J7W!l+cZw^ZqtcN^_S1 z;u{0r<`GoXts$gfWxd51hr3q3Z_Smtq6XJCy&yM(QF#D8#Kl0Kh0rPN z*p_zHfg) U`hYie00000Ne4wvM6N<$g20DrUjP6A -- 2.39.2