From 2034aa15c82570c989dfe5ab3647c55e8106e852 Mon Sep 17 00:00:00 2001 From: Arin Alex Date: Tue, 1 Nov 2016 20:42:45 +0300 Subject: [PATCH] QJSEngine has been added --- common.pri | 8 +- demo_r1/mainwindow.cpp | 4 +- include/lrglobal.h | 14 + include/lrreportengine.h | 1 + include/lrscriptenginemanagerintf.h | 11 +- limereport/items/lrtextitemeditor.cpp | 2 +- limereport/lrglobal.h | 14 + limereport/lritemdesignintf.cpp | 22 +- limereport/lrreportengine.cpp | 2 +- limereport/lrreportengine.h | 1 + limereport/lrreportrender.cpp | 2 +- limereport/lrscriptenginemanager.cpp | 463 +++++++++++++++++-- limereport/lrscriptenginemanager.h | 98 +++- limereport/lrscriptenginemanagerintf.h | 11 +- limereport/scriptbrowser/lrscriptbrowser.cpp | 2 +- 15 files changed, 595 insertions(+), 60 deletions(-) diff --git a/common.pri b/common.pri index 8eee2c5..78398e5 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 b5afab8..0634a15 100644 --- a/demo_r1/mainwindow.cpp +++ b/demo_r1/mainwindow.cpp @@ -93,8 +93,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 e64cd43..ea1d3ce 100644 --- a/include/lrglobal.h +++ b/include/lrglobal.h @@ -42,6 +42,12 @@ # define LIMEREPORT_EXPORT /**/ #endif +#ifdef USE_QJSENGINE +#include +#else +#include +#endif + namespace LimeReport { #ifdef __GNUC__ @@ -83,6 +89,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); enum RenderPass {FirstPass, SecondPass}; @@ -117,6 +124,13 @@ namespace Const{ typedef QStyleOptionViewItem StyleOptionViewItem; #endif +#ifdef USE_QJSENGINE + typedef QJSEngine ScriptEngineType; + typedef QJSValue ScriptValueType; +#else + typedef QScriptEngine ScriptEngineType; + typedef QScriptValue ScriptValueType; +#endif } // namespace LimeReport diff --git a/include/lrreportengine.h b/include/lrreportengine.h index 814d831..804e764 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< +#else +#include +#endif + namespace LimeReport { #ifdef __GNUC__ @@ -83,6 +89,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); enum RenderPass {FirstPass, SecondPass}; @@ -117,6 +124,13 @@ namespace Const{ typedef QStyleOptionViewItem StyleOptionViewItem; #endif +#ifdef USE_QJSENGINE + typedef QJSEngine ScriptEngineType; + typedef QJSValue ScriptValueType; +#else + typedef QScriptEngine ScriptEngineType; + typedef QScriptValue ScriptValueType; +#endif } // namespace LimeReport diff --git a/limereport/lritemdesignintf.cpp b/limereport/lritemdesignintf.cpp index db18eb2..655c39b 100644 --- a/limereport/lritemdesignintf.cpp +++ b/limereport/lritemdesignintf.cpp @@ -215,27 +215,27 @@ QString ContentItemDesignIntf::expandScripts(QString context, DataSourceManager* if (context.contains(rx)){ ScriptEngineManager::instance().setDataManager(dataManager); - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); - QScriptValue svThis = se->globalObject().property("THIS"); - if (svThis.isValid()){ - se->newQObject(svThis, this); - } else { - svThis = se->newQObject(this); - se->globalObject().setProperty("THIS",svThis); - } + //QJSValue svThis = se->globalObject().property("THIS"); + //if (!svThis.isUndefined()){ + // se->newQObject(svThis, this); + //} else { + ScriptValueType svThis = se->newQObject(this); + se->globalObject().setProperty("THIS",svThis); + //} ScriptExtractor scriptExtractor(context); if (scriptExtractor.parse()){ for(int i=0; ievaluate(scriptBody); - if (!se->hasUncaughtException()) { + ScriptValueType value = se->evaluate(scriptBody); + if (!value.isError()) { m_varValue = value.toVariant(); context.replace(scriptExtractor.scriptAt(i),value.toString()); } else { - context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString()); + context.replace(scriptExtractor.scriptAt(i),value.toString()); } } } diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp index 7ff4095..2ce78ee 100644 --- a/limereport/lrreportengine.cpp +++ b/limereport/lrreportengine.cpp @@ -775,7 +775,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 814d831..804e764 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 42dacef..1f4924c 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -167,7 +167,7 @@ void ReportRender::setScriptContext(ScriptEngineContext* scriptContext) bool ReportRender::runInitScript(){ if (m_scriptEngineContext){ - QScriptValue res = ScriptEngineManager::instance().scriptEngine()->evaluate(m_scriptEngineContext->initScript()); + ScriptValueType res = ScriptEngineManager::instance().scriptEngine()->evaluate(m_scriptEngineContext->initScript()); if (res.isBool()) return res.toBool(); } return true; diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp index 976aa22..6aaedca 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)){ @@ -328,6 +328,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){ @@ -337,7 +375,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) @@ -360,23 +399,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; } } @@ -395,12 +434,18 @@ 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("FieldName")+"\",\""+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); } } } @@ -411,27 +456,211 @@ 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); +} + 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")+"\")"); + createSetVariableFunction(); +// 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); @@ -439,7 +668,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")+"\")"); // } @@ -753,5 +982,183 @@ 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 &fieldName, const QString &bandName) +{ + if (m_scriptEngineManager->dataManager()){ + GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,fieldName,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); +} +#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 0c738d9..63a2f45 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,91 @@ 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& fieldName, 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 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;} @@ -195,14 +268,25 @@ 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(); 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 ea38798..8719229 100644 --- a/limereport/scriptbrowser/lrscriptbrowser.cpp +++ b/limereport/scriptbrowser/lrscriptbrowser.cpp @@ -66,7 +66,7 @@ void ScriptBrowser::updateFunctionTree() { 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));