}
-ModelAPI_DocumentCreatedMessage::ModelAPI_DocumentCreatedMessage(const Events_ID theID, const void* theSender)
+ModelAPI_DocumentCreatedMessage::ModelAPI_DocumentCreatedMessage(const Events_ID theID,
+ const void* theSender)
: Events_Message(theID, theSender)
{
{
myDocument = theDocument;
}
+
+ModelAPI_AttributeEvalMessage::ModelAPI_AttributeEvalMessage(const Events_ID theID,
+ const void* theSender)
+: Events_Message(theID, theSender)
+{
+
+}
+
+ModelAPI_AttributeEvalMessage::~ModelAPI_AttributeEvalMessage()
+{
+
+}
+
+AttributePtr ModelAPI_AttributeEvalMessage::attribute() const
+{
+ return myAttribute;
+}
+
+void ModelAPI_AttributeEvalMessage::setAttribute(AttributePtr theDocument)
+{
+ myAttribute = theDocument;
+}
#include <ModelAPI.h>
#include <ModelAPI_Object.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Attribute.h>
#include <Events_MessageGroup.h>
#include <Events_Loop.h>
MODELAPI_EXPORT void setDocument(DocumentPtr theDocument);
};
+/// Message that attribute text should be evaluated in the attribute value
+class ModelAPI_AttributeEvalMessage : public Events_Message
+{
+ AttributePtr myAttribute;
+
+ public:
+ /// Creates an empty message
+ MODELAPI_EXPORT ModelAPI_AttributeEvalMessage(const Events_ID theID, const void* theSender = 0);
+ /// The virtual destructor
+ MODELAPI_EXPORT virtual ~ModelAPI_AttributeEvalMessage();
+ /// Static. Returns EventID of the message.
+ MODELAPI_EXPORT static Events_ID eventId()
+ {
+ static const char * MY_ATTRIBUTE_EVALUATION_EVENT_ID("AttributeEvaluationRequest");
+ return Events_Loop::eventByName(MY_ATTRIBUTE_EVALUATION_EVENT_ID);
+ }
+
+ /// Returns a document stored in the message
+ MODELAPI_EXPORT AttributePtr attribute() const;
+ /// Sets a document to the message
+ MODELAPI_EXPORT void setAttribute(AttributePtr theDocument);
+};
+
#endif
*/
double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
{
- if (!hasVariable(theText))
+ if (!hasVariable(theText)) {
return ModuleBase_DoubleSpinBox::valueFromText(theText);
-
- double aValue = 0;
- findVariable(theText, aValue);
- return aValue;
+ }
+ // small hack: return length of the string to iniiate valuesChanged signal
+ return theText.length();
}
QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
return ModuleBase_DoubleSpinBox::validate(str, pos);
QValidator::State res = QValidator::Invalid;
-
- // Considering the input text as a variable name
- // Applying Python identifier syntax:
- // either a string starting with a letter, or a string starting with
- // an underscore followed by at least one alphanumeric character
if (isAcceptVariables()) {
- QRegExp varNameMask("[_a-zA-Z][a-zA-Z0-9_]*");
- if (varNameMask.exactMatch(str))
- res = QValidator::Acceptable;
-
- if (res == QValidator::Invalid) {
- varNameMask.setPattern("_");
- if (varNameMask.exactMatch(str))
- res = QValidator::Intermediate;
- }
+ res = QValidator::Acceptable;
}
return res;
}
bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
{
- QRegExp varNameMask("([a-z]|[A-Z]|_).*");
- return varNameMask.exactMatch(theText);
+ QRegExp varNameMask("[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
+ return !varNameMask.exactMatch(theText);
}
/*!
// Created: 04 June 2014
// Author: Vitaly Smetannikov
-#include <ModuleBase_WidgetDoubleValue.h>
-#include <ModuleBase_ParamSpinBox.h>
-#include <ModuleBase_Tools.h>
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_Data.h>
-
#include <Config_Keywords.h>
#include <Config_WidgetAPI.h>
-#include <Events_Loop.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Object.h>
#include <ModelAPI_Events.h>
-#include <QWidget>
+#include <ModuleBase_ParamSpinBox.h>
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_WidgetDoubleValue.h>
+
#include <QFormLayout>
#include <QLabel>
-#include <QEvent>
-#include <QTimer>
+#include <QList>
+#include <QObject>
+#include <QPixmap>
+#include <QString>
-#include <math.h>
+#include <cfloat>
+#include <xstring>
#ifndef DBL_MAX
#define DBL_MAX 1.7976931348623158e+308
mySpinBox->setToolTip(aTTip);
aControlLay->addRow(myLabel, mySpinBox);
- connect(mySpinBox, SIGNAL(valueChanged(double)), this, SIGNAL(valuesChanged()));
+ connect(mySpinBox, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesChanged()));
}
ModuleBase_WidgetDoubleValue::~ModuleBase_WidgetDoubleValue()
{
DataPtr aData = myFeature->data();
AttributeDoublePtr aReal = aData->real(attributeID());
- aReal->setValue(mySpinBox->value());
- std::string aTextRepr = aReal->text();
- if (mySpinBox->hasVariable()) {
- aTextRepr = mySpinBox->text().toStdString();
+ if (!mySpinBox->hasVariable()) {
+ aReal->setValue(mySpinBox->value());
} else {
- aTextRepr = "";
+ // Here is a text of a real value or an expression.
+ std::string aText = mySpinBox->text().toStdString();
+ aReal->setText(aText);
+ // Send it to evaluator to convert into the double and store in the attribute
+ static Events_ID anId = ModelAPI_AttributeEvalMessage::eventId();
+ std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
+ std::shared_ptr<ModelAPI_AttributeEvalMessage>(new ModelAPI_AttributeEvalMessage(anId, this));
+ aMessage->setAttribute(aData->attribute(attributeID()));
+ Events_Loop::loop()->send(aMessage);
}
- aReal->setText(aTextRepr);
updateObject(myFeature);
return true;
}
double aValue = outText.toDouble(&isDouble);
if (isDouble) {
outValue = aValue;
- outText = ""; // return empty string, if it's can be converted to a double
+ // outText = ""; // return empty string, if it's can be converted to a double
}
aPopup->deleteLater();
}
ParametersPlugin_Parameter.h
ParametersPlugin_PyInterp.h
ParametersPlugin_Validators.h
+ ParametersPlugin_EvalListener.h
)
SET(PROJECT_SOURCES
ParametersPlugin_Parameter.cpp
ParametersPlugin_PyInterp.cpp
ParametersPlugin_Validators.cpp
+ ParametersPlugin_EvalListener.cpp
)
SET(XML_RESOURCES
--- /dev/null
+/*
+ * ParametersPlugin_EvalListener.cpp
+ *
+ * Created on: Apr 28, 2015
+ * Author: sbh
+ */
+
+#include <ParametersPlugin_EvalListener.h>
+
+#include <Events_Error.h>
+
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_AttributeDouble.h>
+
+#include <string>
+#include <sstream>
+
+ParametersPlugin_EvalListener::ParametersPlugin_EvalListener()
+{
+ Events_Loop* aLoop = Events_Loop::loop();
+ const Events_ID kEvaluationEvent = ModelAPI_AttributeEvalMessage::eventId();
+ aLoop->registerListener(this, kEvaluationEvent, NULL, true);
+
+ myInterp = std::shared_ptr<ParametersPlugin_PyInterp>(new ParametersPlugin_PyInterp());
+ myInterp->initialize();
+}
+
+ParametersPlugin_EvalListener::~ParametersPlugin_EvalListener()
+{
+}
+
+void ParametersPlugin_EvalListener::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+ if (!theMessage.get())
+ return;
+
+ const Events_ID kEvaluationEvent = ModelAPI_AttributeEvalMessage::eventId();
+ if (theMessage->eventID() == kEvaluationEvent) {
+ std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
+ std::dynamic_pointer_cast<ModelAPI_AttributeEvalMessage>(theMessage);
+ AttributeDoublePtr aDoubleAttribute =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aMessage->attribute());
+ if (aDoubleAttribute.get()) {
+ std::string anError;
+ double aValue = evaluate(aDoubleAttribute->text(), anError);
+ if (anError.empty()) {
+ aDoubleAttribute->setValue(aValue);
+ }
+ }
+ } else {
+ Events_Error::send(std::string("ParametersPlugin python interpreter, unhandled message caught: ")
+ + theMessage->eventID().eventText());
+ }
+}
+
+double ParametersPlugin_EvalListener::evaluate(const std::string& theExpression,
+ std::string& theError)
+{
+ std::list<std::string> anExprParams = myInterp->compile(theExpression);
+ // find expression's params in the model
+ std::list<std::string> aContext;
+ std::list<std::string>::iterator it = anExprParams.begin();
+ for ( ; it != anExprParams.end(); it++) {
+ double aValue;
+ if (!ModelAPI_Tools::findVariable(*it, aValue)) continue;
+
+ std::ostringstream sstream;
+ sstream << aValue;
+ std::string aParamValue = sstream.str();
+ aContext.push_back(*it + "=" + aParamValue);
+ }
+ myInterp->extendLocalContext(aContext);
+ double result = myInterp->evaluate(theExpression, theError);
+ myInterp->clearLocalContext();
+ return result;
+}
+
--- /dev/null
+/*
+ * ParametersPlugin_EvalListener.h
+ *
+ * Created on: Apr 28, 2015
+ * Author: sbh
+ */
+
+#ifndef SRC_PARAMETERSPLUGIN_EVALLISTENER_H_
+#define SRC_PARAMETERSPLUGIN_EVALLISTENER_H_
+
+#include <ParametersPlugin.h>
+#include <Events_Loop.h>
+#include <ParametersPlugin_PyInterp.h>
+
+class PARAMETERSPLUGIN_EXPORT ParametersPlugin_EvalListener : public Events_Listener
+{
+ public:
+ ParametersPlugin_EvalListener();
+ virtual ~ParametersPlugin_EvalListener();
+
+ virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
+ protected:
+ double evaluate(const std::string& theExpression,
+ std::string& theError) ;
+
+ private:
+ std::shared_ptr<ParametersPlugin_PyInterp> myInterp;
+};
+
+#endif /* SRC_PARAMETERSPLUGIN_PARAMETERSPLUGIN_EVALLISTENER_H_ */
ParametersPlugin_Parameter::ParametersPlugin_Parameter()
{
- myInterp = new ParametersPlugin_PyInterp();
+ myInterp = std::shared_ptr<ParametersPlugin_PyInterp>(new ParametersPlugin_PyInterp());
myInterp->initialize();
}
ParametersPlugin_Parameter::~ParametersPlugin_Parameter()
{
- delete myInterp;
}
void ParametersPlugin_Parameter::initAttributes()
#include "ParametersPlugin.h"
#include <ModelAPI_Feature.h>
+#include <memory>
+
class ParametersPlugin_PyInterp;
class ParametersPlugin_Parameter : public ModelAPI_Feature
double evaluate(const std::string& theExpression, std::string& theError);
private:
- ParametersPlugin_PyInterp* myInterp;
+ std::shared_ptr<ParametersPlugin_PyInterp> myInterp;
};
#endif
new ParametersPlugin_VariableValidator);
aFactory->registerValidator("Parameters_ExpressionValidator",
new ParametersPlugin_ExpressionValidator);
+
+ myEvalListener = std::shared_ptr<ParametersPlugin_EvalListener>(new ParametersPlugin_EvalListener());
}
FeaturePtr ParametersPlugin_Plugin::createFeature(std::string theFeatureID)
#define PARAMETERSPLUGIN_PLUGIN_H_
#include <ParametersPlugin.h>
+#include <ParametersPlugin_EvalListener.h>
+
#include <ModelAPI_Plugin.h>
#include <ModelAPI_Feature.h>
public:
ParametersPlugin_Plugin();
+
+ std::shared_ptr<ParametersPlugin_EvalListener> myEvalListener;
};
#endif