diff --git a/common.pri b/common.pri index 121fc2f..6154dbc 100644 --- a/common.pri +++ b/common.pri @@ -1,6 +1,6 @@ CONFIG += build_translations CONFIG += zint - +CONFIG += qjsengine greaterThan(QT_MAJOR_VERSION, 4) { QT += uitools } @@ -68,11 +68,15 @@ TRANSLATIONS_PATH = $$PWD/translations greaterThan(QT_MAJOR_VERSION, 4) { DEFINES+=HAVE_QT5 - QT+= printsupport widgets + QT+= printsupport widgets qml contains(QT,uitools){ message(uitools) DEFINES += HAVE_UI_LOADER } + contains(CONFIG, qjsengine){ + message(qjsengine) + DEFINES += USE_QJSENGINE + } } lessThan(QT_MAJOR_VERSION, 5){ diff --git a/demo_r1/mainwindow.cpp b/demo_r1/mainwindow.cpp index d695a4e..c459715 100644 --- a/demo_r1/mainwindow.cpp +++ b/demo_r1/mainwindow.cpp @@ -95,8 +95,8 @@ MainWindow::MainWindow(QWidget *parent) : report->dataManager()->addModel("string_list",stringListModel,true); QStringList strList; strList<<"value1"<<"value2"; - QScriptValue value = qScriptValueFromSequence(report->scriptManager()->scriptEngine(),strList); - report->scriptManager()->scriptEngine()->globalObject().setProperty("test_list",value); + //QScriptValue value = qScriptValueFromSequence(report->scriptManager()->scriptEngine(),strList); + //report->scriptManager()->scriptEngine()->globalObject().setProperty("test_list",value); } diff --git a/include/lrglobal.h b/include/lrglobal.h index 3b8aa7d..421f8d7 100644 --- a/include/lrglobal.h +++ b/include/lrglobal.h @@ -42,6 +42,13 @@ # define LIMEREPORT_EXPORT /**/ #endif +#ifdef USE_QJSENGINE +//#include +#include +#else +#include +#endif + namespace LimeReport { #ifdef __GNUC__ @@ -91,6 +98,7 @@ namespace Const{ const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; const int SCENE_MARGIN = 50; + const QString FUNCTION_MANAGER_NAME = "LimeReport"; } QString extractClassName(QString className); QString escapeSimbols(const QString& value); @@ -130,6 +138,20 @@ namespace Const{ typedef QStyleOptionViewItem StyleOptionViewItem; #endif +#ifdef USE_QJSENGINE + typedef QQmlEngine ScriptEngineType; + typedef QJSValue ScriptValueType; + template + static inline QJSValue getCppOwnedJSValue(QJSEngine &e, T *p) + { + QJSValue res = e.newQObject(p); + QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership); + return res; + } +#else + typedef QScriptEngine ScriptEngineType; + typedef QScriptValue ScriptValueType; +#endif } // namespace LimeReport diff --git a/include/lrreportengine.h b/include/lrreportengine.h index dbbb2a8..9bd87b5 100644 --- a/include/lrreportengine.h +++ b/include/lrreportengine.h @@ -33,6 +33,7 @@ #include #include #include +//#include #include "lrglobal.h" #include "lrdatasourcemanagerintf.h" diff --git a/include/lrscriptenginemanagerintf.h b/include/lrscriptenginemanagerintf.h index d7662ff..4c2767a 100644 --- a/include/lrscriptenginemanagerintf.h +++ b/include/lrscriptenginemanagerintf.h @@ -30,15 +30,19 @@ #ifndef LRSCRIPTENGINEMANAGERINTF_H #define LRSCRIPTENGINEMANAGERINTF_H -#include +//#include +#include "lrglobal.h" namespace LimeReport{ + class IScriptEngineManager{ public: - virtual QScriptEngine* scriptEngine() = 0; - virtual bool addFunction(const QString& name, QScriptEngine::FunctionSignature function, + virtual ScriptEngineType* scriptEngine() = 0; +#ifndef USE_QJSENGINE + virtual bool addFunction(const QString& name, ScriptEngineType::FunctionSignature function, const QString& category="", const QString& description="") = 0; +#endif virtual bool addFunction(const QString &name, const QString& script, const QString &category="", const QString &description="") = 0; virtual const QString& lastError() const = 0; @@ -46,4 +50,5 @@ public: }; } //namespace LimeReport + #endif // LRSCRIPTENGINEMANAGERINTF_H diff --git a/limereport/items/lrtextitemeditor.cpp b/limereport/items/lrtextitemeditor.cpp index e2b6778..cba99ff 100644 --- a/limereport/items/lrtextitemeditor.cpp +++ b/limereport/items/lrtextitemeditor.cpp @@ -133,7 +133,7 @@ void TextItemEditor::initUI() ui->tabWidget->setVisible(false); } - foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescriber()) { + foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescribers()) { dataWords< +#include +#else +#include +#endif + namespace LimeReport { #ifdef __GNUC__ @@ -91,6 +98,7 @@ namespace Const{ const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; const int SCENE_MARGIN = 50; + const QString FUNCTION_MANAGER_NAME = "LimeReport"; } QString extractClassName(QString className); QString escapeSimbols(const QString& value); @@ -130,6 +138,20 @@ namespace Const{ typedef QStyleOptionViewItem StyleOptionViewItem; #endif +#ifdef USE_QJSENGINE + typedef QQmlEngine ScriptEngineType; + typedef QJSValue ScriptValueType; + template + static inline QJSValue getCppOwnedJSValue(QJSEngine &e, T *p) + { + QJSValue res = e.newQObject(p); + QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership); + return res; + } +#else + typedef QScriptEngine ScriptEngineType; + typedef QScriptValue ScriptValueType; +#endif } // namespace LimeReport diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp index fb7ee7c..d4b4fa2 100644 --- a/limereport/lrreportengine.cpp +++ b/limereport/lrreportengine.cpp @@ -874,7 +874,7 @@ IDataSourceManager *ReportEngine::dataManager() return d->dataManagerIntf(); } -IScriptEngineManager* ReportEngine::scriptManager() +IScriptEngineManager *ReportEngine::scriptManager() { Q_D(ReportEngine); return d->scriptManagerIntf(); diff --git a/limereport/lrreportengine.h b/limereport/lrreportengine.h index dbbb2a8..9bd87b5 100644 --- a/limereport/lrreportengine.h +++ b/limereport/lrreportengine.h @@ -33,6 +33,7 @@ #include #include #include +//#include #include "lrglobal.h" #include "lrdatasourcemanagerintf.h" diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp index 11c3ae0..4092f82 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -167,17 +167,29 @@ void ReportRender::setScriptContext(ScriptEngineContext* scriptContext) bool ReportRender::runInitScript(){ if (m_scriptEngineContext){ - QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine(); +#ifndef USE_QJSENGINE engine->pushContext(); - QScriptValue res = engine->evaluate(m_scriptEngineContext->initScript()); +#endif + ScriptValueType res = engine->evaluate(m_scriptEngineContext->initScript()); if (res.isBool()) return res.toBool(); +#ifdef USE_QJSENGINE + if (res.isError()){ + QMessageBox::critical(0,tr("Error"), + QString("Line %1: %2 ").arg(res.property("lineNumber").toString()) + .arg(res.toString()) + ); + return false; + } +#else if (engine->hasUncaughtException()) { QMessageBox::critical(0,tr("Error"), QString("Line %1: %2 ").arg(engine->uncaughtExceptionLineNumber()) .arg(engine->uncaughtException().toString()) ); return false; - } + } +#endif } return true; } @@ -269,8 +281,9 @@ void ReportRender::renderPage(PageDesignIntf* patternPage) renderBand(tearOffBand, 0, StartNewPageAsNeeded); savePage(true); - +#ifndef USE_QJSENGINE ScriptEngineManager::instance().scriptEngine()->popContext(); +#endif } } @@ -314,11 +327,24 @@ void ReportRender::initVariables() } #ifdef HAVE_UI_LOADER + +#ifdef USE_QJSENGINE +void registerChildObjects(ScriptEngineType* se, ScriptValueType* sv){ + foreach(QObject* obj, sv->toQObject()->children()){ + ScriptValueType child = se->newQObject(obj); + sv->setProperty(obj->objectName(),child); + registerChildObjects(se, &child); + } +} +#endif void ReportRender::initDialogs(){ if (m_scriptEngineContext){ - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); foreach(DialogDescriber::Ptr dialog, m_scriptEngineContext->dialogsDescriber()){ - QScriptValue sv = se->newQObject(m_scriptEngineContext->getDialog(dialog->name())); + ScriptValueType sv = se->newQObject(m_scriptEngineContext->getDialog(dialog->name())); +#ifdef USE_QJSENGINE + registerChildObjects(se,&sv); +#endif se->globalObject().setProperty(dialog->name(),sv); } } @@ -1249,18 +1275,26 @@ void ReportRender::baseDesignIntfToScript(BaseDesignIntf *item) if (item->metaObject()->indexOfSignal("afterRender()")!=-1) item->disconnect(SIGNAL(afterRender())); - QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine(); - QScriptValue sItem = engine->globalObject().property(item->patternName()); + ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine(); + +#ifdef USE_QJSENGINE + //sItem = engine->newQObject(item); + ScriptValueType sItem = getCppOwnedJSValue(*engine, item); + engine->globalObject().setProperty(item->patternName(), sItem); +#else + ScriptValueType sItem = engine->globalObject().property(item->patternName()); if (sItem.isValid()){ engine->newQObject(sItem, item); } else { sItem = engine->newQObject(item); engine->globalObject().setProperty(item->patternName(),sItem); } +#endif foreach(BaseDesignIntf* child, item->childBaseItems()){ baseDesignIntfToScript(child); } } + } } diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp index f69283b..dab7272 100644 --- a/limereport/lrscriptenginemanager.cpp +++ b/limereport/lrscriptenginemanager.cpp @@ -181,7 +181,7 @@ void ScriptEngineModel::updateModel() beginResetModel(); m_rootNode->clear(); QMap categories; - foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescriber()){ + foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescribers()){ ScriptEngineNode* categ; QString categoryName = (!funcDesc.category.isEmpty())?funcDesc.category:"NO CATEGORY"; if (categories.contains(categoryName)){ @@ -196,141 +196,141 @@ void ScriptEngineModel::updateModel() endResetModel(); } -QScriptValue line(QScriptContext* pcontext, QScriptEngine* pengine){ - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - QString band = pcontext->argument(0).toString(); - QScriptValue res; - QString varName = QLatin1String("line_")+band.toLower(); - if (dm->variable(varName).isValid()){ - res=pengine->newVariant(dm->variable(varName)); - } else res=pengine->newVariant(QString("Variable line for band %1 not found").arg(band)); - return res; -} +//QScriptValue line(QScriptContext* pcontext, QScriptEngine* pengine){ +// ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); +// DataSourceManager* dm = sm->dataManager(); +// QString band = pcontext->argument(0).toString(); +// QScriptValue res; +// QString varName = QLatin1String("line_")+band.toLower(); +// if (dm->variable(varName).isValid()){ +// res=pengine->newVariant(dm->variable(varName)); +// } else res=pengine->newVariant(QString("Variable line for band %1 not found").arg(band)); +// return res; +//} -QScriptValue setVariable(QScriptContext* pcontext, QScriptEngine* /*pengine*/){ +//QScriptValue setVariable(QScriptContext* pcontext, QScriptEngine* /*pengine*/){ - QString name = pcontext->argument(0).toString(); - QVariant value = pcontext->argument(1).toVariant(); +// QString name = pcontext->argument(0).toString(); +// QVariant value = pcontext->argument(1).toVariant(); - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); +// ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); +// DataSourceManager* dm = sm->dataManager(); - dm->changeVariable(name,value); - return QScriptValue(); -} +// dm->changeVariable(name,value); +// return QScriptValue(); +//} -QScriptValue getVariable(QScriptContext* pcontext, QScriptEngine* pengine){ +//QScriptValue getVariable(QScriptContext* pcontext, QScriptEngine* pengine){ - QString name = pcontext->argument(0).toString(); +// QString name = pcontext->argument(0).toString(); - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - QScriptValue res = pengine->newVariant(dm->variable(name)); +// ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); +// DataSourceManager* dm = sm->dataManager(); +// QScriptValue res = pengine->newVariant(dm->variable(name)); - return res; -} +// return res; +//} -QScriptValue getField(QScriptContext* pcontext, QScriptEngine* pengine){ +//QScriptValue getField(QScriptContext* pcontext, QScriptEngine* pengine){ - QString name = pcontext->argument(0).toString(); +// QString name = pcontext->argument(0).toString(); - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - QScriptValue res = pengine->newVariant(dm->fieldData(name)); +// ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); +// DataSourceManager* dm = sm->dataManager(); +// QScriptValue res = pengine->newVariant(dm->fieldData(name)); - return res; -} +// return res; +//} -QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f'; - int precision = (pcontext->argumentCount()>2)?pcontext->argument(2).toInt32():2; - QString locale = (pcontext->argumentCount()>3)?pcontext->argument(3).toString():""; - QScriptValue res = (locale.isEmpty())?pengine->newVariant(QString::number(value.toDouble(),format,precision)): - pengine->newVariant(QLocale(locale).toString(value.toDouble(),format,precision)); - return res; -} -#if QT_VERSION>0x040800 -QScriptValue currencyFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString locale = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().name(); - return pengine->newVariant(QLocale(locale).toCurrencyString(value.toDouble())); -} +//QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){ +// QVariant value = pcontext->argument(0).toVariant(); +// char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f'; +// int precision = (pcontext->argumentCount()>2)?pcontext->argument(2).toInt32():2; +// QString locale = (pcontext->argumentCount()>3)?pcontext->argument(3).toString():""; +// QScriptValue res = (locale.isEmpty())?pengine->newVariant(QString::number(value.toDouble(),format,precision)): +// pengine->newVariant(QLocale(locale).toString(value.toDouble(),format,precision)); +// return res; +//} +//#if QT_VERSION>0x040800 +//QScriptValue currencyFormat(QScriptContext* pcontext, QScriptEngine* pengine){ +// QVariant value = pcontext->argument(0).toVariant(); +// QString locale = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().name(); +// return pengine->newVariant(QLocale(locale).toCurrencyString(value.toDouble())); +//} -QScriptValue currencyUSBasedFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString CurrencySymbol = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().currencySymbol(); - // Format it using USA locale - QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble()); - // Replace currency symbol if necesarry - if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol); - return pengine->newVariant(vTempStr); -} -#endif -QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy"; - QScriptValue res = pengine->newVariant(QLocale().toString(value.toDate(),format)); - return res; -} +//QScriptValue currencyUSBasedFormat(QScriptContext* pcontext, QScriptEngine* pengine){ +// QVariant value = pcontext->argument(0).toVariant(); +// QString CurrencySymbol = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().currencySymbol(); +// // Format it using USA locale +// QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble()); +// // Replace currency symbol if necesarry +// if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol); +// return pengine->newVariant(vTempStr); +//} +//#endif +//QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){ +// QVariant value = pcontext->argument(0).toVariant(); +// QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy"; +// QScriptValue res = pengine->newVariant(QLocale().toString(value.toDate(),format)); +// return res; +//} -QScriptValue timeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm"; - QScriptValue res = pengine->newVariant(QLocale().toString(value.toTime(),format)); - return res; -} +//QScriptValue timeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ +// QVariant value = pcontext->argument(0).toVariant(); +// QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm"; +// QScriptValue res = pengine->newVariant(QLocale().toString(value.toTime(),format)); +// return res; +//} -QScriptValue dateTimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy hh:mm"; - QScriptValue res = pengine->newVariant(QLocale().toString(value.toDateTime(),format)); - return res; -} +//QScriptValue dateTimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ +// QVariant value = pcontext->argument(0).toVariant(); +// QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy hh:mm"; +// QScriptValue res = pengine->newVariant(QLocale().toString(value.toDateTime(),format)); +// return res; +//} -QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ - return pengine->newVariant(QDateTime::currentDateTime()); -} +//QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ +// return pengine->newVariant(QDateTime::currentDateTime()); +//} -QScriptValue date(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ - return pengine->newVariant(QDate::currentDate()); -} +//QScriptValue date(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ +// return pengine->newVariant(QDate::currentDate()); +//} -QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcontext, QScriptEngine* pengine){ +//QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcontext, QScriptEngine* pengine){ - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); +// ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); +// DataSourceManager* dm = sm->dataManager(); - QString expression; - QString band; +// QString expression; +// QString band; - if (functionName.compare("COUNT",Qt::CaseInsensitive) == 0 && pcontext->argumentCount()==1){ - expression = " "; - band = pcontext->argument(0).toString(); - } else { - expression = dm->getExpression(pcontext->argument(0).toString()); - band = pcontext->argument(1).toString(); - } +// if (functionName.compare("COUNT",Qt::CaseInsensitive) == 0 && pcontext->argumentCount()==1){ +// expression = " "; +// band = pcontext->argument(0).toString(); +// } else { +// expression = dm->getExpression(pcontext->argument(0).toString()); +// band = pcontext->argument(1).toString(); +// } - QScriptValue res; - GroupFunction* gf = dm->groupFunction(functionName,expression,band); - if (gf){ - if (gf->isValid()){ - res=pengine->newVariant(gf->calculate()); - }else{ - res=pengine->newVariant(gf->error()); - } - } - else { - res=pengine->newVariant(QString(QObject::tr("Function %1 not found or have wrong arguments").arg(functionName))); - } - return res; -} +// QScriptValue res; +// GroupFunction* gf = dm->groupFunction(functionName,expression,band); +// if (gf){ +// if (gf->isValid()){ +// res=pengine->newVariant(gf->calculate()); +// }else{ +// res=pengine->newVariant(gf->error()); +// } +// } +// else { +// res=pengine->newVariant(QString(QObject::tr("Function %1 not found or have wrong arguments").arg(functionName))); +// } +// return res; +//} -QScriptValue groupFunction(QScriptContext* pcontext, QScriptEngine* pengine){ - return callGroupFunction(pcontext->callee().property("functionName").toString(),pcontext,pengine); -} +//QScriptValue groupFunction(QScriptContext* pcontext, QScriptEngine* pengine){ +// return callGroupFunction(pcontext->callee().property("functionName").toString(),pcontext,pengine); +//} ScriptEngineManager::~ScriptEngineManager() { @@ -359,6 +359,44 @@ void ScriptEngineManager::deleteFunction(const QString &functionsName) } } +bool ScriptEngineManager::addFunction(const JSFunctionDesc &functionDescriber) +{ + ScriptValueType functionManager = scriptEngine()->globalObject().property(functionDescriber.managerName()); +#ifdef USE_QJSENGINE + if (functionManager.isUndefined()){ +#else + if (!functionManager.isValid()){ +#endif + functionManager = scriptEngine()->newQObject(functionDescriber.manager()); + scriptEngine()->globalObject().setProperty( + functionDescriber.managerName(), + functionManager + ); + } + + if (functionManager.toQObject() == functionDescriber.manager()){ + ScriptValueType checkWrapper = scriptEngine()->evaluate(functionDescriber.scriptWrapper()); + if (!checkWrapper.isError()){ + ScriptFunctionDesc funct; + funct.name = functionDescriber.name(); + funct.description = functionDescriber.description(); + funct.category = functionDescriber.category(); + funct.type = ScriptFunctionDesc::Native; + m_functions.append(funct); + if (m_model) + m_model->updateModel(); + return true; + } else { + m_lastError = checkWrapper.toString(); + return false; + } + } else { + m_lastError = tr("Function manger with name \"%1\" already exists !"); + return false; + } + +} + bool ScriptEngineManager::containsFunction(const QString& functionName){ foreach (ScriptFunctionDesc funct, m_functions) { if (funct.name.compare(functionName)== 0){ @@ -368,7 +406,8 @@ bool ScriptEngineManager::containsFunction(const QString& functionName){ return false; } -bool ScriptEngineManager::addFunction(const QString& name, +#ifndef USE_QJSENGINE +Q_DECL_DEPRECATED bool ScriptEngineManager::addFunction(const QString& name, QScriptEngine::FunctionSignature function, const QString& category, const QString& description) @@ -391,23 +430,23 @@ bool ScriptEngineManager::addFunction(const QString& name, return false; } } +#endif bool ScriptEngineManager::addFunction(const QString& name, const QString& script, const QString& category, const QString& description) { - QScriptSyntaxCheckResult cr = m_scriptEngine->checkSyntax(script); - if (cr.state() == QScriptSyntaxCheckResult::Valid){ + ScriptValueType functionValue = m_scriptEngine->evaluate(script); + if (!functionValue.isError()){ ScriptFunctionDesc funct; - funct.scriptValue = m_scriptEngine->evaluate(script); + funct.scriptValue = functionValue; funct.name = name; funct.category = category; funct.description = description; funct.type = ScriptFunctionDesc::Script; - funct.scriptValue.setData(m_scriptEngine->toScriptValue(this)); m_functions.append(funct); m_model->updateModel(); return true; } else { - m_lastError = cr.errorMessage(); + m_lastError = functionValue.toString(); return false; } } @@ -426,12 +465,19 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){ m_dataManager = dataManager; if (m_dataManager){ foreach(QString func, m_dataManager->groupFunctionNames()){ - if (isFunctionExists(func)) deleteFunction(func); - addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("Value")+"\",\""+tr("BandName")+"\")"); - } - foreach(ScriptFunctionDesc func, m_functions){ - if (func.type==ScriptFunctionDesc::Native) - m_scriptEngine->globalObject().setProperty(func.name,func.scriptValue); + JSFunctionDesc describer( + func, + "GROUP FUNCTIONS", + func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")", + LimeReport::Const::FUNCTION_MANAGER_NAME, + m_functionManager, + QString("function %1(fieldName,bandName){\ + return %2.calcGroupFunction(\"%1\",fieldName,bandName);}" + ).arg(func) + .arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + addFunction(describer); + } } } @@ -543,16 +589,24 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, if (ScriptEngineManager::instance().dataManager()!=dataManager()) ScriptEngineManager::instance().setDataManager(dataManager()); - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); if (reportItem){ - QScriptValue svThis = se->globalObject().property("THIS"); + + ScriptValueType svThis; + +#ifdef USE_QJSENGINE + svThis = getCppOwnedJSValue(*se, reportItem); + se->globalObject().setProperty("THIS",svThis); +#else + svThis = se->globalObject().property("THIS"); if (svThis.isValid()){ - se->newQObject(svThis, this); + se->newQObject(svThis, reportItem); } else { - svThis = se->newQObject(this); + svThis = se->newQObject(reportItem); se->globalObject().setProperty("THIS",svThis); } +#endif } ScriptExtractor scriptExtractor(context); @@ -560,16 +614,26 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, for(int i=0; ievaluate(scriptBody); + ScriptValueType value = se->evaluate(scriptBody); +#ifdef USE_QJSENGINE + if (!value.isError()){ + varValue = value.toVariant(); + context.replace(scriptExtractor.scriptAt(i),value.toString()); + } else { + context.replace(scriptExtractor.scriptAt(i),value.toString()); + } +#else if (!se->hasUncaughtException()) { varValue = value.toVariant(); context.replace(scriptExtractor.scriptAt(i),value.toString()); } else { context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString()); } +#endif } } } + return context; } @@ -583,14 +647,18 @@ QVariant ScriptEngineManager::evaluateScript(const QString& script){ if (ScriptEngineManager::instance().dataManager()!=dataManager()) ScriptEngineManager::instance().setDataManager(dataManager()); - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); ScriptExtractor scriptExtractor(script); if (scriptExtractor.parse()){ QString scriptBody = expandDataFields(scriptExtractor.bodyAt(0),EscapeSymbols, varValue, 0); scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue); - QScriptValue value = se->evaluate(scriptBody); + ScriptValueType value = se->evaluate(scriptBody); +#ifdef USE_QJSENGINE + if (!value.isError()){ +#else if (!se->hasUncaughtException()) { +#endif return value.toVariant(); } } @@ -603,29 +671,243 @@ void ScriptEngineManager::updateModel() } +bool ScriptEngineManager::createLineFunction() +{ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("SYSTEM"); + fd.setName("line"); + fd.setDescription("line(\""+tr("BandName")+"\")"); + fd.setScriptWrapper(QString("function line(bandName){ return %1.line(bandName);}").arg(LimeReport::Const::FUNCTION_MANAGER_NAME)); + + return addFunction(fd); + +} + +bool ScriptEngineManager::createNumberFomatFunction() +{ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("NUMBER"); + fd.setName("numberFormat"); + fd.setDescription("numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+ + tr("Precision")+"\",\""+ + tr("Locale")+"\")" + ); + fd.setScriptWrapper(QString("function numberFormat(value, format, precision, locale){" + " if(typeof(format)==='undefined') format = \"f\"; " + " if(typeof(precision)==='undefined') precision=2; " + " if(typeof(locale)==='undefined') locale=\"\"; " + "return %1.numberFormat(value,format,precision,locale);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createDateFormatFunction(){ +// addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("DATE&TIME"); + fd.setName("dateFormat"); + fd.setDescription("dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + fd.setScriptWrapper(QString("function dateFormat(value, format){" + " if(typeof(format)==='undefined') format = \"dd.MM.yyyy\"; " + "return %1.dateFormat(value,format);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createTimeFormatFunction(){ +// addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("DATE&TIME"); + fd.setName("timeFormat"); + fd.setDescription("timeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + fd.setScriptWrapper(QString("function timeFormat(value, format){" + " if(typeof(format)==='undefined') format = \"hh:mm\"; " + "return %1.timeFormat(value,format);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createDateTimeFormatFunction(){ +// addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("DATE&TIME"); + fd.setName("dateTimeFormat"); + fd.setDescription("dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + fd.setScriptWrapper(QString("function dateTimeFormat(value, format){" + " if(typeof(format)==='undefined') format = \"dd.MM.yyyy hh:mm\"; " + "return %1.dateTimeFormat(value,format);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createDateFunction(){ +// addFunction("date",date,"DATE&TIME","date()"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("DATE&TIME"); + fd.setName("date"); + fd.setDescription("date()"); + fd.setScriptWrapper(QString("function date(){" + "return %1.date();}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + + +bool ScriptEngineManager::createNowFunction(){ +// addFunction("now",now,"DATE&TIME","now()"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("DATE&TIME"); + fd.setName("now"); + fd.setDescription("now()"); + fd.setScriptWrapper(QString("function now(){" + "return %1.now();}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createCurrencyFormatFunction(){ +// addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("NUMBER"); + fd.setName("currencyFormat"); + fd.setDescription("currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); + fd.setScriptWrapper(QString("function currencyFormat(value, locale){" + " if(typeof(locale)==='undefined') locale = \"\"; " + "return %1.currencyFormat(value,locale);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createCurrencyUSBasedFormatFunction(){ +// addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("NUMBER"); + fd.setName("currencyUSBasedFormat"); + fd.setDescription("currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); + fd.setScriptWrapper(QString("function currencyUSBasedFormat(value, currencySymbol){" + " if(typeof(currencySymbol)==='undefined') currencySymbol = \"\"; " + "return %1.currencyFormat(value,currencySymbol);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createSetVariableFunction(){ +// addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("GENERAL"); + fd.setName("setVariable"); + fd.setDescription("setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); + fd.setScriptWrapper(QString("function setVariable(name, value){" + "return %1.setVariable(name,value);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createGetVariableFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("GENERAL"); + fd.setName("getVariable"); + fd.setDescription("getVariable(\""+tr("Name")+"\")"); + fd.setScriptWrapper(QString("function getVariable(name){" + "return %1.getVariable(name);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createGetFieldFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory("GENERAL"); + fd.setName("getField"); + fd.setDescription("getField(\""+tr("Name")+"\")"); + fd.setScriptWrapper(QString("function getField(name){" + "return %1.getField(name);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + ScriptEngineManager::ScriptEngineManager() :m_model(0), m_dataManager(0) { - m_scriptEngine = new QScriptEngine; + m_scriptEngine = new ScriptEngineType; + m_functionManager = new ScriptFunctionsManager(this); + m_functionManager->setScriptEngineManager(this); - //addFunction("dateToStr",dateToStr,"DATE", "dateToStr(\"value\",\"format\")"); - addFunction("line",line,"SYSTEM", "line(\""+tr("BandName")+"\")"); - addFunction("numberFormat",numberFormat,"NUMBER", "numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+ - tr("Precision")+"\",\""+ - tr("Locale")+"\")"); - addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("date",date,"DATE&TIME","date()"); - addFunction("now",now,"DATE&TIME","now()"); + createLineFunction(); + createNumberFomatFunction(); + createDateFormatFunction(); + createTimeFormatFunction(); + createDateTimeFormatFunction(); + createDateFunction(); + createNowFunction(); #if QT_VERSION>0x040800 - addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); - addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); + createCurrencyFormatFunction(); + createCurrencyUSBasedFormatFunction(); #endif - addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); - addFunction("getVariable", getVariable, "GENERAL", "getVariable(\""+tr("Name")+"\")"); - addFunction("getField", getField, "GENERAL", "getField(\""+tr("Name")+"\")"); + createSetVariableFunction(); + createGetFieldFunction(); + createGetVariableFunction(); +// addFunction("line",line,"SYSTEM", "line(\""+tr("BandName")+"\")"); +// addFunction("numberFormat",numberFormat,"NUMBER", "numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+ +// tr("Precision")+"\",\""+ +// tr("Locale")+"\")"); + +// addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); +// addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); +// addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); +// addFunction("date",date,"DATE&TIME","date()"); +// addFunction("now",now,"DATE&TIME","now()"); +// addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); +// addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); +// addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); +#ifndef USE_QJSENGINE QScriptValue colorCtor = m_scriptEngine->newFunction(constructColor); m_scriptEngine->globalObject().setProperty("QColor", colorCtor); @@ -633,7 +915,7 @@ ScriptEngineManager::ScriptEngineManager() m_scriptEngine->setDefaultPrototype(qMetaTypeId(), fontProto); QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto); m_scriptEngine->globalObject().setProperty("QFont", fontConstructor); - +#endif // foreach(QString func, dataManager()->groupFunctionNames()){ // addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")"); // } @@ -947,5 +1229,203 @@ DialogDescriber::Ptr DialogDescriber::create(const QString& name, const QByteArr return res; } +QString JSFunctionDesc::name() const +{ + return m_name; +} + +void JSFunctionDesc::setName(const QString &name) +{ + m_name = name; +} + +QString JSFunctionDesc::category() const +{ + return m_category; +} + +void JSFunctionDesc::setCategory(const QString &category) +{ + m_category = category; +} + +QString JSFunctionDesc::description() const +{ + return m_description; +} + +void JSFunctionDesc::setDescription(const QString &description) +{ + m_description = description; +} + +QString JSFunctionDesc::managerName() const +{ + return m_managerName; +} + +void JSFunctionDesc::setManagerName(const QString &managerName) +{ + m_managerName = managerName; +} + +QObject *JSFunctionDesc::manager() const +{ + return m_manager; +} + +void JSFunctionDesc::setManager(QObject *manager) +{ + m_manager = manager; +} + +QString JSFunctionDesc::scriptWrapper() const +{ + return m_scriptWrapper; +} + +void JSFunctionDesc::setScriptWrapper(const QString &scriptWrapper) +{ + m_scriptWrapper = scriptWrapper; +} + +QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName) +{ + if (m_scriptEngineManager->dataManager()){ + QString expression = ""; + if (name.compare("COUNT",Qt::CaseInsensitive) == 0){ + expression = " "; + } else { + expression = m_scriptEngineManager->dataManager()->getExpression(expressionID); + } + + GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName); + if (gf){ + if (gf->isValid()){ + return gf->calculate(); + }else{ + return gf->error(); + } + } + else { + return QString(QObject::tr("Function %1 not found or have wrong arguments").arg(name)); + } + } else { + return QString(QObject::tr("Datasource manager not found")); + } +} + +QVariant ScriptFunctionsManager::line(const QString &bandName) +{ + QString varName = QLatin1String("line_")+bandName.toLower(); + QVariant res; + if (scriptEngineManager()->dataManager()->variable(varName).isValid()){ + res=scriptEngineManager()->dataManager()->variable(varName); + } else res=QString("Variable line for band %1 not found").arg(bandName); + return res; +} + +QVariant ScriptFunctionsManager::numberFormat(QVariant value, const char &format, int precision, const QString& locale) +{ + return (locale.isEmpty())?QString::number(value.toDouble(),format,precision): + QLocale(locale).toString(value.toDouble(),format,precision); +} + +QVariant ScriptFunctionsManager::dateFormat(QVariant value, const QString &format) +{ + return QLocale().toString(value.toDate(),format); +} + +QVariant ScriptFunctionsManager::timeFormat(QVariant value, const QString &format) +{ + return QLocale().toString(value.toTime(),format); +} + +QVariant ScriptFunctionsManager::dateTimeFormat(QVariant value, const QString &format) +{ + return QLocale().toString(value.toDateTime(),format); +} + +QVariant ScriptFunctionsManager::date() +{ + return QDate::currentDate(); +} + +QVariant ScriptFunctionsManager::now() +{ + return QDateTime::currentDateTime(); +} + +QVariant ScriptFunctionsManager::currencyFormat(QVariant value, const QString &locale) +{ + QString l = (!locale.isEmpty())?locale:QLocale::system().name(); + return QLocale(l).toCurrencyString(value.toDouble()); +} + +QVariant ScriptFunctionsManager::currencyUSBasedFormat(QVariant value, const QString ¤cySymbol) +{ + QString CurrencySymbol = (!currencySymbol.isEmpty())?currencySymbol:QLocale::system().currencySymbol(); + // Format it using USA locale + QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble()); + // Replace currency symbol if necesarry + if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol); + return vTempStr; +} + +void ScriptFunctionsManager::setVariable(const QString &name, QVariant value) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + dm->changeVariable(name,value); +} + +QVariant ScriptFunctionsManager::getVariable(const QString &name) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->variable(name); +} + +QVariant ScriptFunctionsManager::getField(const QString &field) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->fieldData(field); +} + +#ifdef USE_QJSENGINE +QFont ScriptFunctionsManager::font(const QString &family, int pointSize, bool bold, bool italic, bool underLine) +{ + QFont result (family, pointSize); + result.setBold(bold); + result.setItalic(italic); + result.setUnderline(underLine); + return result; +} +#endif +QFont ScriptFunctionsManager::font(QVariantMap params){ + if (!params.contains("family")){ + return QFont(); + } else { + QFont result(params.value("family").toString()); + if (params.contains("pointSize")) + result.setPointSize(params.value("pointSize").toInt()); + if (params.contains("bold")) + result.setBold(params.value("bold").toBool()); + if (params.contains("italic")) + result.setItalic(params.value("italic").toBool()); + if (params.contains("underline")) + result.setUnderline(params.value("underline").toBool()); + return result; + } +} + +ScriptEngineManager *ScriptFunctionsManager::scriptEngineManager() const +{ + return m_scriptEngineManager; +} + +void ScriptFunctionsManager::setScriptEngineManager(ScriptEngineManager *scriptEngineManager) +{ + m_scriptEngineManager = scriptEngineManager; +} + } //namespace LimeReport diff --git a/limereport/lrscriptenginemanager.h b/limereport/lrscriptenginemanager.h index 545580b..726013b 100644 --- a/limereport/lrscriptenginemanager.h +++ b/limereport/lrscriptenginemanager.h @@ -39,11 +39,15 @@ #include #include + +//#include + #ifdef HAVE_UI_LOADER #include #endif #include "base/lrsingleton.h" +#include "lrglobal.h" #include "lrscriptenginemanagerintf.h" #include "lrcollection.h" @@ -53,7 +57,7 @@ class DataSourceManager; struct ScriptFunctionDesc{ enum FuncType {Native,Script}; - QScriptValue scriptValue; + ScriptValueType scriptValue; QString name; QString description; QString category; @@ -169,22 +173,93 @@ private: QString m_initScript; }; +class JSFunctionDesc{ +public: + JSFunctionDesc(){} + JSFunctionDesc(const QString& functionName, + const QString& functionCategory, + const QString& functionDescription, + const QString& functionManagerName, + QObject* functionManger, + const QString& functionScriptWrapper + ): m_name(functionName), m_category(functionCategory), m_description(functionDescription), + m_managerName(functionManagerName), m_manager(functionManger), m_scriptWrapper(functionScriptWrapper) + {} + QString name() const; + void setName(const QString &name); + + QString category() const; + void setCategory(const QString &category); + + QString description() const; + void setDescription(const QString &description); + + QString managerName() const; + void setManagerName(const QString &managerName); + + QObject *manager() const; + void setManager(QObject *manager); + + QString scriptWrapper() const; + void setScriptWrapper(const QString &scriptWrapper); + +private: + QString m_name; + QString m_category; + QString m_description; + QString m_managerName; + QObject* m_manager; + QString m_scriptWrapper; +}; + +class ScriptFunctionsManager : public QObject{ + Q_OBJECT +public: + explicit ScriptFunctionsManager(QObject* parent = 0):QObject(parent){} + Q_INVOKABLE QVariant calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName); + Q_INVOKABLE QVariant line(const QString& bandName); + Q_INVOKABLE QVariant numberFormat(QVariant value, const char &format, int precision, const QString &locale); + Q_INVOKABLE QVariant dateFormat(QVariant value, const QString& format); + Q_INVOKABLE QVariant timeFormat(QVariant value, const QString& format); + Q_INVOKABLE QVariant dateTimeFormat(QVariant value, const QString& format); + Q_INVOKABLE QVariant date(); + Q_INVOKABLE QVariant now(); + Q_INVOKABLE QVariant currencyFormat(QVariant value, const QString& locale); + Q_INVOKABLE QVariant currencyUSBasedFormat(QVariant value, const QString& currencySymbol); + Q_INVOKABLE void setVariable(const QString& name, QVariant value); + Q_INVOKABLE QVariant getVariable(const QString& name); + Q_INVOKABLE QVariant getField(const QString& field); + Q_INVOKABLE QVariant color(const QString& color){ return QColor(color);} +#ifdef USE_QJSENGINE + Q_INVOKABLE QFont font(const QString& family, int pointSize = -1, bool bold = false, bool italic = false, bool underLine = false); +#endif + Q_INVOKABLE QFont font(QVariantMap params); + ScriptEngineManager *scriptEngineManager() const; + void setScriptEngineManager(ScriptEngineManager *scriptEngineManager); + static QColor createQColor(const QString& color){ return QColor(color);} +private: + ScriptEngineManager* m_scriptEngineManager; +}; + class ScriptEngineManager : public QObject, public Singleton, public IScriptEngineManager { Q_OBJECT public: - QScriptEngine* scriptEngine(){return m_scriptEngine;} - ~ScriptEngineManager(); friend class Singleton; + ScriptEngineType* scriptEngine(){return m_scriptEngine;} + ~ScriptEngineManager(); bool isFunctionExists(const QString& functionName) const; void deleteFunction(const QString& functionsName); - bool addFunction(const QString& name, QScriptEngine::FunctionSignature function, - const QString& category="", const QString& description=""); + + bool addFunction(const JSFunctionDesc& functionsDescriber); +#ifndef USE_QJSENGINE + bool addFunction(const QString &name, QScriptEngine::FunctionSignature function, const QString &category, const QString &description); +#endif bool addFunction(const QString &name, const QString& script, const QString &category="", const QString &description=""); const QString& lastError() const {return m_lastError;} QStringList functionsNames(); - const QList& functionsDescriber(){return m_functions;} + const QList& functionsDescribers(){return m_functions;} ScriptEngineModel* model(){return m_model;} void setContext(ScriptEngineContext* context){m_context=context;} DataSourceManager* dataManager() const {return m_dataManager;} @@ -200,14 +275,27 @@ protected: bool containsFunction(const QString &functionName); private: Q_DISABLE_COPY(ScriptEngineManager) + bool createLineFunction(); + bool createNumberFomatFunction(); + bool createDateFormatFunction(); + bool createTimeFormatFunction(); + bool createDateTimeFormatFunction(); + bool createDateFunction(); + bool createNowFunction(); + bool createCurrencyFormatFunction(); + bool createCurrencyUSBasedFormatFunction(); + bool createSetVariableFunction(); + bool createGetVariableFunction(); + bool createGetFieldFunction(); private: ScriptEngineManager(); - QScriptEngine* m_scriptEngine; + ScriptEngineType* m_scriptEngine; QString m_lastError; QList m_functions; ScriptEngineModel* m_model; ScriptEngineContext* m_context; DataSourceManager* m_dataManager; + ScriptFunctionsManager* m_functionManager; }; class ScriptExtractor diff --git a/limereport/lrscriptenginemanagerintf.h b/limereport/lrscriptenginemanagerintf.h index d7662ff..4c2767a 100644 --- a/limereport/lrscriptenginemanagerintf.h +++ b/limereport/lrscriptenginemanagerintf.h @@ -30,15 +30,19 @@ #ifndef LRSCRIPTENGINEMANAGERINTF_H #define LRSCRIPTENGINEMANAGERINTF_H -#include +//#include +#include "lrglobal.h" namespace LimeReport{ + class IScriptEngineManager{ public: - virtual QScriptEngine* scriptEngine() = 0; - virtual bool addFunction(const QString& name, QScriptEngine::FunctionSignature function, + virtual ScriptEngineType* scriptEngine() = 0; +#ifndef USE_QJSENGINE + virtual bool addFunction(const QString& name, ScriptEngineType::FunctionSignature function, const QString& category="", const QString& description="") = 0; +#endif virtual bool addFunction(const QString &name, const QString& script, const QString &category="", const QString &description="") = 0; virtual const QString& lastError() const = 0; @@ -46,4 +50,5 @@ public: }; } //namespace LimeReport + #endif // LRSCRIPTENGINEMANAGERINTF_H diff --git a/limereport/scriptbrowser/lrscriptbrowser.cpp b/limereport/scriptbrowser/lrscriptbrowser.cpp index 5f90bf3..8e6dcc3 100644 --- a/limereport/scriptbrowser/lrscriptbrowser.cpp +++ b/limereport/scriptbrowser/lrscriptbrowser.cpp @@ -67,7 +67,7 @@ void ScriptBrowser::updateFunctionTree() ui->twFunctions->clear(); ScriptEngineManager* sm = reportEditor()->scriptManager(); QMap categ; - foreach(ScriptFunctionDesc fd, sm->functionsDescriber()){ + foreach(ScriptFunctionDesc fd, sm->functionsDescribers()){ QString functionCategory = (fd.category!="") ? fd.category : tr("NO CATEGORY"); if (categ.contains(functionCategory)){ QTreeWidgetItem* item = new QTreeWidgetItem(categ.value(fd.category),QStringList(fd.name));