totally new scripting bridge between c++ and javascript.

This commit is contained in:
Guido Ranzuglia granzuglia 2011-03-08 14:06:41 +00:00
parent 57a2e8090f
commit 69ec793bc2
5 changed files with 113 additions and 107 deletions

View File

@ -38,7 +38,9 @@ using namespace vcg;
GLArea::GLArea(MultiViewer_Container *mvcont, RichParameterSet *current)
: QGLWidget()
{
this->setParent(mvcont);
this->updateCustomSettingValues(*current);
log=mvcont->LogPtr();
animMode=AnimNone;

View File

@ -35,7 +35,7 @@
#include <QStringList>
#include <QColorDialog>
#include "../common/pluginmanager.h"
#include "../common/mlparameter.h"
#include "../common/environment.h"
#include "glarea.h"
#include "layerDialog.h"
#include "stdpardialog.h"
@ -59,7 +59,7 @@ class MainWindow : public QMainWindow, MainWindowInterface
public:
// callback function to execute a filter
void executeFilter(QAction *action, RichParameterSet &srcpar, bool isPreview);
void executeFilter(MeshLabXMLFilterContainer* mfc, FilterEnv& env, bool isPreview);
void executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, bool isPreview);
MainWindow();
static bool QCallBack(const int pos, const char * str);
@ -83,7 +83,7 @@ private slots:
void delCurrentRaster();
void endEdit();
void updateDocumentScriptBindings() {if(currentViewContainer()) PM.updateDocumentScriptBindings(*meshDoc());}
void evaluateExpression(const Expression& exp,Value** res);
//void evaluateExpression(const Expression& exp,Value** res);
public:

View File

@ -113,8 +113,8 @@ void MainWindow::createXMLStdPluginWnd()
xmldialog->close();
delete xmldialog;
}
xmldialog = new MeshLabXMLStdDialog(this);
connect(xmldialog,SIGNAL(dialogEvaluateExpression(const Expression&,Value**)),this,SLOT(evaluateExpression(const Expression&,Value**)),Qt::DirectConnection);
xmldialog = new MeshLabXMLStdDialog(PM.env,this);
//connect(xmldialog,SIGNAL(dialogEvaluateExpression(const Expression&,Value**)),this,SLOT(evaluateExpression(const Expression&,Value**)),Qt::DirectConnection);
xmldialog->setAllowedAreas ( Qt::RightDockWidgetArea);
addDockWidget(Qt::RightDockWidgetArea,xmldialog);
//stddialog->setAttribute(Qt::WA_DeleteOnClose,true);
@ -892,9 +892,10 @@ void MainWindow::startFilter()
{
XMLFilterInfo::XMLMap mp = *(it);
//Initilize the parameters inside the environment
Expression* exp = ExpressionFactory::create(mp[MLXMLElNames::paramType],mp[MLXMLElNames::paramDefExpr]);
PM.env.insertLocalExpressionBinding(mp[MLXMLElNames::paramName],exp);
ExpressionFactory::destroy(exp);
//Expression* exp = ExpressionFactory::create(mp[MLXMLElNames::paramType],mp[MLXMLElNames::paramDefExpr]);
PM.env.insertExpressionBinding(mp[MLXMLElNames::paramName],mp[MLXMLElNames::paramDefExpr]);
//ExpressionFactory::destroy(exp);
}
if(currentViewContainer())
{
@ -914,10 +915,10 @@ void MainWindow::startFilter()
meshDoc()->Log.Logf(GLLogStream::SYSTEM,"Problem with showAutoDialog.");
}
}
catch (ParsingException e)
catch (MeshLabException& e)
{
meshDoc()->Log.Logf(GLLogStream::SYSTEM,e.what());
PM.env.popContext();
PM.env.popContext();
}
}
catch(ParsingException e)
@ -1036,7 +1037,7 @@ void MainWindow::executeFilter(QAction *action, RichParameterSet &params, bool i
void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, FilterEnv& env, bool /*isPreview*/)
void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, bool /*isPreview*/)
{
MeshLabFilterInterface *iFilter = mfc->filterInterface;
@ -2020,16 +2021,16 @@ bool MainWindow::QCallBack(const int pos, const char * str)
return true;
}
void MainWindow::evaluateExpression(const Expression& exp,Value** res )
{
try
{
PM.env.pushContext();
*res = exp.eval(&PM.env);
PM.env.popContext();
}
catch (ParsingException& e)
{
GLA()->log->Logf(GLLogStream::WARNING,e.what());
}
}
//void MainWindow::evaluateExpression(const Expression& exp,Value** res )
//{
// try
// {
// PM.env.pushContext();
// *res = exp.eval(&PM.env);
// PM.env.popContext();
// }
// catch (ParsingException& e)
// {
// GLA()->log->Logf(GLLogStream::WARNING,e.what());
// }
//}

View File

@ -1,8 +1,8 @@
#include "xmlstdpardialog.h"
#include <QtGui>
MeshLabXMLStdDialog::MeshLabXMLStdDialog( QWidget *p )
:QDockWidget(QString("Plugin"), p),showHelp(false)
MeshLabXMLStdDialog::MeshLabXMLStdDialog( Env& environ,QWidget *p )
:QDockWidget(QString("Plugin"), p),showHelp(false),env(environ)
{
curmask = 0;
qf = NULL;
@ -49,12 +49,13 @@ void MeshLabXMLStdDialog::loadFrameContent( )
gridLayout->addWidget(ql,0,0,1,2,Qt::AlignTop); // this widgets spans over two columns.
stdParFrame = new XMLStdParFrame(this,curgla);
connect(stdParFrame,SIGNAL(frameEvaluateExpression(const Expression&,Value**)),this,SIGNAL(dialogEvaluateExpression(const Expression&,Value**)),Qt::DirectConnection);
//connect(stdParFrame,SIGNAL(frameEvaluateExpression(const Expression&,Value**)),this,SIGNAL(dialogEvaluateExpression(const Expression&,Value**)),Qt::DirectConnection);
XMLFilterInfo::XMLMapList mplist = curmfc->xmlInfo->filterParametersExtendedInfo(fname);
stdParFrame->loadFrameContent(mplist);
EnvWrap wrap(env);
stdParFrame->loadFrameContent(mplist,wrap);
gridLayout->addWidget(stdParFrame,1,0,1,2);
//int buttonRow = 2; // the row where the line of buttons start
QPushButton *helpButton = new QPushButton("Help", qf);
@ -153,17 +154,14 @@ bool MeshLabXMLStdDialog::showAutoDialog(MeshLabXMLFilterContainer& mfc,MeshDocu
void MeshLabXMLStdDialog::applyClick()
{
filtEnv.clear();
env.pushContext();
assert(curParMap.size() == stdParFrame->xmlfieldwidgets.size());
for(int ii = 0;ii < curParMap.size();++ii)
{
XMLMeshLabWidget* wid = stdParFrame->xmlfieldwidgets[ii];
Expression* exp = wid->getWidgetExpression();
//the result value will be destructed when the FilterEnv will be disposed
Value* res = NULL;
emit dialogEvaluateExpression(*exp,&res);
filtEnv.insertValueBinding(curParMap[ii][MLXMLElNames::paramName],res);
delete exp;
QString exp = wid->getWidgetExpression();
env.insertExpressionBinding(curParMap[ii][MLXMLElNames::paramName],exp);
//delete exp;
}
////int mask = 0;//curParSet.getDynamicFloatMask();
if(curmask)
@ -176,8 +174,9 @@ void MeshLabXMLStdDialog::applyClick()
// meshCacheState.apply(curModel);
//else
QString nm = curmfc->act->text();
curmwi->executeFilter(curmfc,filtEnv,false);
EnvWrap wrap(env);
curmwi->executeFilter(curmfc,wrap,false);
env.popContext();
if(curmask)
meshState.create(curmask, curModel);
@ -258,7 +257,7 @@ bool MeshLabXMLStdDialog::isDynamic() const
return ((curmask != MeshModel::MM_UNKNOWN) && (curmask != MeshModel::MM_NONE) && !(curmask & MeshModel::MM_VERTNUMBER) && !(curmask & MeshModel::MM_FACENUMBER));
}
XMLStdParFrame::XMLStdParFrame( QWidget *p, QWidget *gla/*=0*/ )
XMLStdParFrame::XMLStdParFrame( QWidget *p,QWidget *gla/*=0*/ )
:QFrame(p),extended(false)
{
curr_gla=gla;
@ -279,11 +278,11 @@ XMLStdParFrame::~XMLStdParFrame()
}
void XMLStdParFrame::loadFrameContent(const XMLFilterInfo::XMLMapList& parMap)
void XMLStdParFrame::loadFrameContent(const XMLFilterInfo::XMLMapList& parMap,EnvWrap& envir)
{
for(XMLFilterInfo::XMLMapList::const_iterator it = parMap.constBegin();it != parMap.constEnd();++it)
{
XMLMeshLabWidget* widg = XMLMeshLabWidgetFactory::create(*it,this);
XMLMeshLabWidget* widg = XMLMeshLabWidgetFactory::create(*it,envir,this);
if (widg == NULL)
return;
xmlfieldwidgets.push_back(widg);
@ -312,20 +311,15 @@ void XMLStdParFrame::extendedView(bool ext,bool help)
adjustSize();
}
XMLMeshLabWidget::XMLMeshLabWidget(const XMLFilterInfo::XMLMap& mp,QWidget* parent )
:QWidget(parent)
XMLMeshLabWidget::XMLMeshLabWidget(const XMLFilterInfo::XMLMap& mp,EnvWrap& envir,QWidget* parent )
:QWidget(parent),env(envir)
{
//WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//It's not nice at all doing the connection for an external object! The connect should be called in XMLStdParFrame::loadFrameContent but in this way
//we must break the construction of the widget in two steps because otherwise in the constructor (called by XMLMeshLabWidgetFactory::create) the emit is invoked
//before the connection!
connect(this,SIGNAL(widgetEvaluateExpression(const Expression&,Value**)),parent,SIGNAL(frameEvaluateExpression(const Expression&,Value**)),Qt::DirectConnection);
Value* isImp = NULL;
BoolExpression isImpExp(mp[MLXMLElNames::paramIsImportant]);
emit widgetEvaluateExpression(isImpExp,&isImp);
isImportant = isImp->getBool();
delete isImp;
//connect(this,SIGNAL(widgetEvaluateExpression(const Expression&,Value**)),parent,SIGNAL(frameEvaluateExpression(const Expression&,Value**)),Qt::DirectConnection);
isImportant = env.getBool(mp[MLXMLElNames::paramIsImportant]);
setVisible(isImportant);
helpLab = new QLabel("<small>"+ mp[MLXMLElNames::paramHelpTag] +"</small>",this);
@ -359,17 +353,14 @@ void XMLMeshLabWidget::setVisibility( const bool vis )
setVisible(vis);
}
XMLCheckBoxWidget::XMLCheckBoxWidget( const XMLFilterInfo::XMLMap& xmlWidgetTag,QWidget* parent )
:XMLMeshLabWidget(xmlWidgetTag,parent)
XMLCheckBoxWidget::XMLCheckBoxWidget( const XMLFilterInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* parent )
:XMLMeshLabWidget(xmlWidgetTag,envir,parent)
{
cb = new QCheckBox(xmlWidgetTag[MLXMLElNames::paramName],this);
cb->setToolTip(xmlWidgetTag[MLXMLElNames::paramHelpTag]);
BoolExpression exp(xmlWidgetTag[MLXMLElNames::paramDefExpr]);
Value* boolVal = NULL;
emit widgetEvaluateExpression(exp,&boolVal);
cb->setChecked(boolVal->getBool());
bool defVal = env.getBool(xmlWidgetTag[MLXMLElNames::paramDefExpr]);
cb->setChecked(defVal);
cb->setVisible(isImportant);
delete boolVal;
//gridlay->addWidget(this,i,0,1,1,Qt::AlignTop);
@ -416,32 +407,32 @@ void XMLCheckBoxWidget::updateVisibility( const bool vis )
cb->setVisible(vis);
}
Expression* XMLCheckBoxWidget::getWidgetExpression()
QString XMLCheckBoxWidget::getWidgetExpression()
{
QString state;
if (cb->isChecked())
state = QString("true");
else
state = QString("false");
return new BoolExpression(state);
return state;
}
XMLMeshLabWidget* XMLMeshLabWidgetFactory::create(const XMLFilterInfo::XMLMap& widgetTable,QWidget* parent)
XMLMeshLabWidget* XMLMeshLabWidgetFactory::create(const XMLFilterInfo::XMLMap& widgetTable,EnvWrap& env,QWidget* parent)
{
QString guiType = widgetTable[MLXMLElNames::guiType];
if (guiType == MLXMLElNames::editTag)
return new XMLEditWidget(widgetTable,parent);
return new XMLEditWidget(widgetTable,env,parent);
if (guiType == MLXMLElNames::checkBoxTag)
return new XMLCheckBoxWidget(widgetTable,parent);
return new XMLCheckBoxWidget(widgetTable,env,parent);
if (guiType == MLXMLElNames::absPercTag)
return new XMLAbsWidget(widgetTable,parent);
return new XMLAbsWidget(widgetTable,env,parent);
return NULL;
}
XMLEditWidget::XMLEditWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,QWidget* parent)
:XMLMeshLabWidget(xmlWidgetTag,parent)
XMLEditWidget::XMLEditWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* parent)
:XMLMeshLabWidget(xmlWidgetTag,envir,parent)
{
fieldDesc = new QLabel(xmlWidgetTag[MLXMLElNames::paramName],this);
lineEdit = new QLineEdit(this);
@ -495,38 +486,35 @@ void XMLEditWidget::updateVisibility( const bool vis )
void XMLEditWidget::tooltipEvaluation()
{
QString exp = lineEdit->selectedText();
FloatExpression flExp(exp);
Value* val = NULL;
emit widgetEvaluateExpression(flExp,&val);
if (val != NULL)
lineEdit->setToolTip(QString::number(val->getFloat()));
delete val;
try
{
QString exp = lineEdit->selectedText();
float res = env.getFloat(exp);
lineEdit->setToolTip(QString::number(res));
}
catch (MeshLabException& /*e*/)
{
//WARNING!!! it's needed otherwise there is a stack overflow due to the Qt selection mechanism!
return;
}
}
Expression* XMLEditWidget::getWidgetExpression()
QString XMLEditWidget::getWidgetExpression()
{
return new FloatExpression(this->lineEdit->text());
return this->lineEdit->text();
}
XMLAbsWidget::XMLAbsWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag, QWidget* parent )
:XMLMeshLabWidget(xmlWidgetTag,parent),minVal(NULL),maxVal(NULL)
XMLAbsWidget::XMLAbsWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag, EnvWrap& envir,QWidget* parent )
:XMLMeshLabWidget(xmlWidgetTag,envir,parent),minVal(NULL),maxVal(NULL)
{
FloatExpression minExp(xmlWidgetTag[MLXMLElNames::guiMinExpr]);
FloatExpression maxExp(xmlWidgetTag[MLXMLElNames::guiMaxExpr]);
emit widgetEvaluateExpression(minExp,&minVal);
emit widgetEvaluateExpression(maxExp,&maxVal);
float m_min = env.getFloat(xmlWidgetTag[MLXMLElNames::guiMinExpr]);
float m_max = env.getFloat(xmlWidgetTag[MLXMLElNames::guiMaxExpr]);
fieldDesc = new QLabel(xmlWidgetTag[MLXMLElNames::paramName] + " (abs and %)",this);
fieldDesc->setToolTip(xmlWidgetTag[MLXMLElNames::paramHelpTag]);
absSB = new QDoubleSpinBox(this);
percSB = new QDoubleSpinBox(this);
//called with m_* only to maintain backward compatibility
float m_min = minVal->getFloat();
float m_max = maxVal->getFloat();
absSB->setMinimum(m_min-(m_max-m_min));
absSB->setMaximum(m_max*2);
absSB->setAlignment(Qt::AlignRight);
@ -608,9 +596,9 @@ void XMLAbsWidget::updateVisibility( const bool vis )
this->percSB->setVisible(vis);
}
Expression* XMLAbsWidget::getWidgetExpression()
QString XMLAbsWidget::getWidgetExpression()
{
return new FloatExpression(QString::number(absSB->value()));
return QString::number(absSB->value());
}
ExpandButtonWidget::ExpandButtonWidget( QWidget* parent )

View File

@ -2,8 +2,9 @@
#define MESHLAB_XMLSTDPARDIALOG
#include "../common/xmlfilterinfo.h"
#include "../common/mlparameter.h"
#include "../common/environment.h"
#include "../common/interfaces.h"
#include "../common/mlexception.h"
#include<QCheckBox>
#include<QPushButton>
#include<QRadioButton>
@ -16,16 +17,27 @@
#include<QTextEdit>
#include<QLabel>
class XMLWidgetException : public MeshLabException
{
public:
XMLWidgetException(const QString& text)
:MeshLabException(QString("XML Widget Error: ") + text){}
~XMLWidgetException() throw() {}
};
//
class XMLMeshLabWidget : public QWidget
{
Q_OBJECT
public:
XMLMeshLabWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,QWidget* parent);
//WARNING! This constructor could rise up a set of MeshLabExceptions! this does it mean that the object COULD BE NOT correctly constructed!
XMLMeshLabWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* parent);
// bring the values from the Qt widgets to the parameter (e.g. from the checkBox to the parameter).
virtual void collectWidgetValue() = 0;
virtual void setWidgetExpression(const QString& nwExpStr) = 0;
virtual Expression* getWidgetExpression() = 0;
virtual QString getWidgetExpression() = 0;
virtual void updateWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag) = 0;
void setVisibility(const bool vis);
virtual void updateVisibility(const bool vis) = 0;
@ -42,13 +54,14 @@ public:
signals:
void parameterChanged();
void widgetEvaluateExpression(const Expression& exp,Value** res);
void insertParamInEnv(const QString& paramName,Expression* paramExp);
//void widgetEvaluateExpression(const Expression& exp,Value** res);
//void insertParamInEnv(const QString& paramName,Expression* paramExp);
protected:
int row;
QGridLayout* gridLay;
QLabel* helpLab;
EnvWrap env;
//QLineEdit* lExprEditor;
//QTextEdit* tExprEditor;
};
@ -56,7 +69,9 @@ protected:
class XMLMeshLabWidgetFactory
{
public:
static XMLMeshLabWidget* create(const XMLFilterInfo::XMLMap& widgetTable,QWidget* parent);
//WARNING! this function call constructors that could rise up a set of MeshLabExceptions but it is not able to manage it, so let the exceptions floating up!
//IN ANY CASE the callee MUST check if the returned value is not NULL.
static XMLMeshLabWidget* create(const XMLFilterInfo::XMLMap& widgetTable,EnvWrap& env,QWidget* parent);
};
//
@ -64,7 +79,7 @@ class XMLCheckBoxWidget : public XMLMeshLabWidget
{
Q_OBJECT
public:
XMLCheckBoxWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,QWidget* parent);
XMLCheckBoxWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* parent);
~XMLCheckBoxWidget();
void resetWidgetValue();
// bring the values from the Qt widgets to the parameter (e.g. from the checkBox to the parameter).
@ -72,7 +87,7 @@ public:
void setWidgetExpression(const QString& nv);
void updateWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag);
void updateVisibility(const bool vis);
Expression* getWidgetExpression();
QString getWidgetExpression();
private:
@ -85,7 +100,7 @@ class XMLEditWidget : public XMLMeshLabWidget
{
Q_OBJECT
public:
XMLEditWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,QWidget* parent);
XMLEditWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* parent);
~XMLEditWidget();
void resetWidgetValue();
// bring the values from the Qt widgets to the parameter (e.g. from the checkBox to the parameter).
@ -93,7 +108,7 @@ public:
void setWidgetExpression(const QString& nv);
void updateWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag);
void updateVisibility(const bool vis);
Expression* getWidgetExpression();
QString getWidgetExpression();
private slots:
void tooltipEvaluation();
private:
@ -104,7 +119,7 @@ private:
class XMLAbsWidget : public XMLMeshLabWidget
{
public:
XMLAbsWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,QWidget* parent);
XMLAbsWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* parent);
~XMLAbsWidget();
void resetWidgetValue();
@ -113,7 +128,7 @@ public:
void setWidgetExpression(const QString& nv);
void updateWidget(const XMLFilterInfo::XMLMap& xmlWidgetTag);
void updateVisibility(const bool vis);
Expression* getWidgetExpression();
QString getWidgetExpression();
private:
QLabel* fieldDesc;
@ -137,8 +152,8 @@ class XMLStdParFrame : public QFrame
{
Q_OBJECT
public:
XMLStdParFrame(QWidget *p, QWidget *gla=0);
void loadFrameContent(const XMLFilterInfo::XMLMapList& parMap);
XMLStdParFrame(QWidget *p,QWidget *gla=0);
void loadFrameContent(const XMLFilterInfo::XMLMapList& parMap,EnvWrap& envir);
void extendedView(bool ext,bool help);
//void loadFrameContent(RichParameter* par,MeshDocument *mdPt = 0);
@ -154,8 +169,8 @@ public:
QWidget *curr_gla; // used for having a link to the glarea that spawned the parameter asking.
~XMLStdParFrame();
signals:
void frameEvaluateExpression(const Expression& exp,Value** res);
//signals:
//void frameEvaluateExpression(const Expression& exp,Value** res);
private:
QGridLayout * vLayout;
@ -190,7 +205,7 @@ class MeshLabXMLStdDialog : public QDockWidget
Q_OBJECT
public:
MeshLabXMLStdDialog(QWidget *p);
MeshLabXMLStdDialog(Env& envir,QWidget *p);
~MeshLabXMLStdDialog();
void clearValues();
@ -199,9 +214,8 @@ public:
bool showAutoDialog(MeshLabXMLFilterContainer& mfc, MeshDocument * md, MainWindowInterface *mwi, QWidget *gla=0);
bool isDynamic() const;
FilterEnv filtEnv;
signals:
void dialogEvaluateExpression(const Expression& exp,Value** res);
//signals:
//void dialogEvaluateExpression(const Expression& exp,Value** res);
//void expandView(bool exp);
private slots:
@ -215,6 +229,7 @@ private slots:
void extendedView(bool ext);
private:
Env& env;
QFrame *qf;
XMLStdParFrame *stdParFrame;
//QAction *curAction;