2016-02-17 10:11:00 +03:00
|
|
|
/***************************************************************************
|
|
|
|
* This file is part of the Lime Report project *
|
|
|
|
* Copyright (C) 2015 by Alexander Arin *
|
|
|
|
* arin_a@bk.ru *
|
|
|
|
* *
|
|
|
|
** GNU General Public License Usage **
|
|
|
|
* *
|
|
|
|
* This library is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
* *
|
|
|
|
** GNU Lesser General Public License **
|
|
|
|
* *
|
|
|
|
* This library is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
|
|
* License, or (at your option) any later version. *
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
* License along with this library. *
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
* *
|
|
|
|
* This library is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
****************************************************************************/
|
|
|
|
#include "lrscriptenginemanager.h"
|
|
|
|
|
|
|
|
#include <QDate>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QScriptValueIterator>
|
2017-04-20 23:34:32 +03:00
|
|
|
#include <QMessageBox>
|
2016-06-10 18:05:18 +03:00
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
#include <QUiLoader>
|
|
|
|
#include <QBuffer>
|
|
|
|
#include <QWidget>
|
|
|
|
#endif
|
2016-02-17 10:11:00 +03:00
|
|
|
#include "lrdatasourcemanager.h"
|
2017-04-20 23:34:32 +03:00
|
|
|
#include "lrbasedesignintf.h"
|
2016-02-17 10:11:00 +03:00
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(QColor)
|
|
|
|
Q_DECLARE_METATYPE(QFont)
|
2016-02-17 10:39:17 +03:00
|
|
|
Q_DECLARE_METATYPE(LimeReport::ScriptEngineManager *)
|
2016-02-17 10:11:00 +03:00
|
|
|
|
|
|
|
QScriptValue constructColor(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
QColor color(context->argument(0).toString());
|
|
|
|
return engine->toScriptValue(color);
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace LimeReport{
|
|
|
|
|
|
|
|
ScriptEngineNode::~ScriptEngineNode()
|
|
|
|
{
|
|
|
|
for (int i = 0; i<m_childs.count(); ++i){
|
|
|
|
delete m_childs[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-17 10:18:19 +03:00
|
|
|
ScriptEngineNode*ScriptEngineNode::addChild(const QString& name, const QString& description, ScriptEngineNode::NodeType type, const QIcon& icon)
|
2016-02-17 10:11:00 +03:00
|
|
|
{
|
2016-02-17 10:18:19 +03:00
|
|
|
ScriptEngineNode* res = new ScriptEngineNode(name, description, type,this,icon);
|
2016-02-17 10:11:00 +03:00
|
|
|
m_childs.push_back(res);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ScriptEngineNode::row()
|
|
|
|
{
|
|
|
|
if (m_parent){
|
|
|
|
return m_parent->m_childs.indexOf(const_cast<ScriptEngineNode*>(this));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineNode::clear()
|
|
|
|
{
|
|
|
|
for (int i=0; i<m_childs.count(); ++i){
|
|
|
|
delete m_childs[i];
|
|
|
|
}
|
|
|
|
m_childs.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
ScriptEngineModel::ScriptEngineModel(ScriptEngineManager* scriptManager)
|
|
|
|
:m_rootNode(new ScriptEngineNode())
|
|
|
|
{
|
|
|
|
setScriptEngineManager(scriptManager);
|
|
|
|
}
|
|
|
|
|
|
|
|
ScriptEngineModel::~ScriptEngineModel() {
|
|
|
|
delete m_rootNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex ScriptEngineModel::parent(const QModelIndex& child) const
|
|
|
|
{
|
|
|
|
if (!child.isValid()) return QModelIndex();
|
|
|
|
|
|
|
|
ScriptEngineNode* childNode = nodeFromIndex(child);
|
|
|
|
if (!childNode) return QModelIndex();
|
|
|
|
|
|
|
|
ScriptEngineNode* parentNode = childNode->parent();
|
|
|
|
if ((parentNode == m_rootNode) || (!parentNode)) return QModelIndex();
|
|
|
|
return createIndex(parentNode->row(),0,parentNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex ScriptEngineModel::index(int row, int column, const QModelIndex& parent) const
|
|
|
|
{
|
|
|
|
if (!m_rootNode)
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
if (!hasIndex(row,column,parent))
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
ScriptEngineNode* parentNode;
|
|
|
|
if (parent.isValid()){
|
|
|
|
parentNode = nodeFromIndex(parent);
|
|
|
|
} else {
|
|
|
|
parentNode = m_rootNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
ScriptEngineNode* childNode = parentNode->child(row);
|
|
|
|
if (childNode){
|
|
|
|
return createIndex(row,column,childNode);
|
|
|
|
} else return QModelIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
int ScriptEngineModel::rowCount(const QModelIndex& parent) const
|
|
|
|
{
|
|
|
|
if (!m_rootNode) return 0;
|
|
|
|
ScriptEngineNode* parentNode;
|
|
|
|
if (parent.isValid())
|
|
|
|
parentNode = nodeFromIndex(parent);
|
|
|
|
else
|
|
|
|
parentNode = m_rootNode;
|
|
|
|
return parentNode->childCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
int ScriptEngineModel::columnCount(const QModelIndex& parent) const
|
|
|
|
{
|
|
|
|
Q_UNUSED(parent)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ScriptEngineModel::data(const QModelIndex& index, int role) const
|
|
|
|
{
|
|
|
|
ScriptEngineNode *node = nodeFromIndex(index);
|
|
|
|
switch (role) {
|
|
|
|
case Qt::DisplayRole:
|
|
|
|
if (!node) return QVariant();
|
|
|
|
return node->name();
|
|
|
|
break;
|
|
|
|
case Qt::DecorationRole :
|
|
|
|
if (!node) return QIcon();
|
|
|
|
return node->icon();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineModel::setScriptEngineManager(ScriptEngineManager* scriptManager)
|
|
|
|
{
|
|
|
|
m_scriptManager = scriptManager;
|
|
|
|
updateModel();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineModel::slotScriptEngineChanged()
|
|
|
|
{
|
|
|
|
updateModel();
|
|
|
|
}
|
|
|
|
|
|
|
|
ScriptEngineNode*ScriptEngineModel::nodeFromIndex(const QModelIndex& index) const
|
|
|
|
{
|
|
|
|
if (index.isValid()){
|
|
|
|
return static_cast<ScriptEngineNode*>(index.internalPointer());
|
|
|
|
} else return m_rootNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineModel::updateModel()
|
|
|
|
{
|
|
|
|
beginResetModel();
|
|
|
|
m_rootNode->clear();
|
|
|
|
QMap<QString,ScriptEngineNode*> categories;
|
2016-11-01 20:42:45 +03:00
|
|
|
foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescribers()){
|
2016-02-17 10:11:00 +03:00
|
|
|
ScriptEngineNode* categ;
|
|
|
|
QString categoryName = (!funcDesc.category.isEmpty())?funcDesc.category:"NO CATEGORY";
|
|
|
|
if (categories.contains(categoryName)){
|
|
|
|
categ = categories.value(categoryName);
|
|
|
|
} else {
|
2016-02-17 10:18:19 +03:00
|
|
|
categ = m_rootNode->addChild(categoryName,"",ScriptEngineNode::Category,QIcon(":/report/images/folder"));
|
2016-02-17 10:11:00 +03:00
|
|
|
categories.insert(categoryName,categ);
|
|
|
|
}
|
2016-02-17 10:18:19 +03:00
|
|
|
categ->addChild(funcDesc.name,funcDesc.description,ScriptEngineNode::Function,QIcon(":/report/images/function"));
|
2016-02-17 10:11:00 +03:00
|
|
|
}
|
|
|
|
endResetModel();
|
|
|
|
}
|
|
|
|
|
|
|
|
ScriptEngineManager::~ScriptEngineManager()
|
|
|
|
{
|
2016-02-18 21:09:00 +03:00
|
|
|
delete m_model;
|
|
|
|
m_model = 0;
|
2016-02-17 10:11:00 +03:00
|
|
|
delete m_scriptEngine;
|
|
|
|
}
|
|
|
|
|
2016-02-17 10:28:27 +03:00
|
|
|
bool ScriptEngineManager::isFunctionExists(const QString &functionName) const
|
|
|
|
{
|
|
|
|
foreach (ScriptFunctionDesc desc, m_functions) {
|
|
|
|
if (desc.name.compare(functionName,Qt::CaseInsensitive)==0){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineManager::deleteFunction(const QString &functionsName)
|
|
|
|
{
|
|
|
|
QMutableListIterator<ScriptFunctionDesc> it(m_functions);
|
|
|
|
while(it.hasNext()){
|
|
|
|
if (it.next().name.compare(functionsName, Qt::CaseInsensitive)==0){
|
|
|
|
it.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-01 20:42:45 +03:00
|
|
|
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 {
|
2017-06-28 17:15:05 +03:00
|
|
|
m_lastError = tr("Function manger with name \"%1\" already exists!");
|
2016-11-01 20:42:45 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-08-12 21:14:05 +03:00
|
|
|
bool ScriptEngineManager::containsFunction(const QString& functionName){
|
|
|
|
foreach (ScriptFunctionDesc funct, m_functions) {
|
|
|
|
if (funct.name.compare(functionName)== 0){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-11-01 20:42:45 +03:00
|
|
|
#ifndef USE_QJSENGINE
|
|
|
|
Q_DECL_DEPRECATED bool ScriptEngineManager::addFunction(const QString& name,
|
2016-02-17 10:11:00 +03:00
|
|
|
QScriptEngine::FunctionSignature function,
|
|
|
|
const QString& category,
|
|
|
|
const QString& description)
|
|
|
|
{
|
2016-08-12 21:14:05 +03:00
|
|
|
if (!containsFunction(name)){
|
|
|
|
ScriptFunctionDesc funct;
|
|
|
|
funct.name = name;
|
|
|
|
funct.description = description;
|
|
|
|
funct.category = category;
|
|
|
|
funct.scriptValue = scriptEngine()->newFunction(function);
|
|
|
|
funct.scriptValue.setProperty("functionName",name);
|
|
|
|
funct.scriptValue.setData(m_scriptEngine->toScriptValue(this));
|
|
|
|
funct.type = ScriptFunctionDesc::Native;
|
|
|
|
m_functions.append(funct);
|
|
|
|
if (m_model)
|
|
|
|
m_model->updateModel();
|
|
|
|
m_scriptEngine->globalObject().setProperty(funct.name,funct.scriptValue);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2016-11-01 20:42:45 +03:00
|
|
|
#endif
|
2016-08-12 21:14:05 +03:00
|
|
|
|
|
|
|
bool ScriptEngineManager::addFunction(const QString& name, const QString& script, const QString& category, const QString& description)
|
2016-02-17 10:11:00 +03:00
|
|
|
{
|
2016-11-01 20:42:45 +03:00
|
|
|
ScriptValueType functionValue = m_scriptEngine->evaluate(script);
|
|
|
|
if (!functionValue.isError()){
|
2016-02-17 10:11:00 +03:00
|
|
|
ScriptFunctionDesc funct;
|
2016-11-01 20:42:45 +03:00
|
|
|
funct.scriptValue = functionValue;
|
2016-02-17 10:11:00 +03:00
|
|
|
funct.name = name;
|
|
|
|
funct.category = category;
|
|
|
|
funct.description = description;
|
|
|
|
funct.type = ScriptFunctionDesc::Script;
|
|
|
|
m_functions.append(funct);
|
2016-08-12 21:14:05 +03:00
|
|
|
m_model->updateModel();
|
|
|
|
return true;
|
2016-02-17 10:11:00 +03:00
|
|
|
} else {
|
2016-11-01 20:42:45 +03:00
|
|
|
m_lastError = functionValue.toString();
|
2016-08-12 21:14:05 +03:00
|
|
|
return false;
|
2016-02-17 10:11:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList ScriptEngineManager::functionsNames()
|
|
|
|
{
|
|
|
|
QStringList res;
|
|
|
|
foreach(ScriptFunctionDesc func, m_functions){
|
|
|
|
res<<func.name;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2016-02-17 10:28:27 +03:00
|
|
|
void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
|
|
|
|
if (m_dataManager != dataManager){
|
|
|
|
m_dataManager = dataManager;
|
|
|
|
if (m_dataManager){
|
|
|
|
foreach(QString func, m_dataManager->groupFunctionNames()){
|
2016-11-01 20:42:45 +03:00
|
|
|
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);
|
2017-02-08 19:21:08 +03:00
|
|
|
|
2016-02-17 10:28:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-28 02:20:15 +03:00
|
|
|
QString ScriptEngineManager::expandUserVariables(QString context, RenderPass pass, ExpandType expandType, QVariant &varValue)
|
|
|
|
{
|
|
|
|
QRegExp rx(Const::VARIABLE_RX);
|
|
|
|
if (context.contains(rx)){
|
|
|
|
int pos = 0;
|
|
|
|
while ((pos = rx.indexIn(context,pos))!=-1){
|
|
|
|
QString variable=rx.cap(1);
|
|
|
|
pos += rx.matchedLength();
|
|
|
|
if (dataManager()->containsVariable(variable) ){
|
|
|
|
try {
|
|
|
|
if (pass==dataManager()->variablePass(variable)){
|
|
|
|
varValue = dataManager()->variable(variable);
|
|
|
|
switch (expandType){
|
|
|
|
case EscapeSymbols:
|
|
|
|
context.replace(rx.cap(0),escapeSimbols(varValue.toString()));
|
|
|
|
break;
|
|
|
|
case NoEscapeSymbols:
|
|
|
|
context.replace(rx.cap(0),varValue.toString());
|
|
|
|
break;
|
|
|
|
case ReplaceHTMLSymbols:
|
|
|
|
context.replace(rx.cap(0),replaceHTMLSymbols(varValue.toString()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pos=0;
|
|
|
|
}
|
|
|
|
} catch (ReportError e){
|
|
|
|
dataManager()->putError(e.what());
|
|
|
|
if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
|
|
|
context.replace(rx.cap(0),e.what());
|
|
|
|
else
|
|
|
|
context.replace(rx.cap(0),"");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
QString error;
|
|
|
|
error = tr("Variable %1 not found").arg(variable);
|
|
|
|
dataManager()->putError(error);
|
|
|
|
if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
|
|
|
context.replace(rx.cap(0),error);
|
|
|
|
else
|
|
|
|
context.replace(rx.cap(0),"");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ScriptEngineManager::expandDataFields(QString context, ExpandType expandType, QVariant &varValue, QObject *reportItem)
|
|
|
|
{
|
|
|
|
QRegExp rx(Const::FIELD_RX);
|
|
|
|
|
|
|
|
if (context.contains(rx)){
|
|
|
|
while ((rx.indexIn(context))!=-1){
|
|
|
|
QString field=rx.cap(1);
|
|
|
|
|
|
|
|
if (dataManager()->containsField(field)) {
|
|
|
|
QString fieldValue;
|
|
|
|
varValue = dataManager()->fieldData(field);
|
|
|
|
if (expandType == EscapeSymbols) {
|
|
|
|
if (dataManager()->fieldData(field).isNull()) {
|
|
|
|
fieldValue="\"\"";
|
|
|
|
} else {
|
|
|
|
fieldValue = escapeSimbols(varValue.toString());
|
|
|
|
switch (dataManager()->fieldData(field).type()) {
|
|
|
|
case QVariant::Char:
|
|
|
|
case QVariant::String:
|
|
|
|
case QVariant::StringList:
|
|
|
|
case QVariant::Date:
|
|
|
|
case QVariant::DateTime:
|
|
|
|
fieldValue = "\""+fieldValue+"\"";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (expandType == ReplaceHTMLSymbols)
|
|
|
|
fieldValue = replaceHTMLSymbols(varValue.toString());
|
|
|
|
else fieldValue = varValue.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
context.replace(rx.cap(0),fieldValue);
|
|
|
|
|
|
|
|
} else {
|
2017-03-03 01:12:29 +03:00
|
|
|
QString error;
|
|
|
|
if (reportItem){
|
2017-06-28 17:15:05 +03:00
|
|
|
error = tr("Field %1 not found in %2!").arg(field).arg(reportItem->objectName());
|
2017-03-03 01:12:29 +03:00
|
|
|
dataManager()->putError(error);
|
|
|
|
}
|
2017-01-28 02:20:15 +03:00
|
|
|
varValue = QVariant();
|
|
|
|
if (!dataManager()->reportSettings() || !dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
|
|
|
context.replace(rx.cap(0),error);
|
|
|
|
else
|
|
|
|
context.replace(rx.cap(0),"");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, QObject *reportItem)
|
|
|
|
{
|
|
|
|
QRegExp rx(Const::SCRIPT_RX);
|
|
|
|
|
|
|
|
if (context.contains(rx)){
|
|
|
|
|
|
|
|
if (ScriptEngineManager::instance().dataManager()!=dataManager())
|
|
|
|
ScriptEngineManager::instance().setDataManager(dataManager());
|
|
|
|
|
2017-02-11 00:21:03 +03:00
|
|
|
ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
|
2017-01-28 02:20:15 +03:00
|
|
|
|
|
|
|
if (reportItem){
|
2017-02-11 00:21:03 +03:00
|
|
|
|
|
|
|
ScriptValueType svThis;
|
|
|
|
|
|
|
|
#ifdef USE_QJSENGINE
|
|
|
|
svThis = getCppOwnedJSValue(*se, reportItem);
|
|
|
|
se->globalObject().setProperty("THIS",svThis);
|
|
|
|
#else
|
|
|
|
svThis = se->globalObject().property("THIS");
|
2017-01-28 02:20:15 +03:00
|
|
|
if (svThis.isValid()){
|
2017-02-11 00:21:03 +03:00
|
|
|
se->newQObject(svThis, reportItem);
|
2017-01-28 02:20:15 +03:00
|
|
|
} else {
|
2017-02-11 00:21:03 +03:00
|
|
|
svThis = se->newQObject(reportItem);
|
2017-01-28 02:20:15 +03:00
|
|
|
se->globalObject().setProperty("THIS",svThis);
|
|
|
|
}
|
2017-02-11 00:21:03 +03:00
|
|
|
#endif
|
2017-01-28 02:20:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
ScriptExtractor scriptExtractor(context);
|
|
|
|
if (scriptExtractor.parse()){
|
|
|
|
for(int i=0; i<scriptExtractor.count();++i){
|
|
|
|
QString scriptBody = expandDataFields(scriptExtractor.bodyAt(i),EscapeSymbols, varValue, reportItem);
|
|
|
|
scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
|
2017-02-11 00:21:03 +03:00
|
|
|
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
|
2017-01-28 02:20:15 +03:00
|
|
|
if (!se->hasUncaughtException()) {
|
|
|
|
varValue = value.toVariant();
|
|
|
|
context.replace(scriptExtractor.scriptAt(i),value.toString());
|
|
|
|
} else {
|
|
|
|
context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString());
|
|
|
|
}
|
2017-02-11 00:21:03 +03:00
|
|
|
#endif
|
2017-01-28 02:20:15 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-11 00:21:03 +03:00
|
|
|
|
2017-01-28 02:20:15 +03:00
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ScriptEngineManager::evaluateScript(const QString& script){
|
|
|
|
|
|
|
|
QRegExp rx(Const::SCRIPT_RX);
|
|
|
|
QVariant varValue;
|
|
|
|
|
|
|
|
if (script.contains(rx)){
|
|
|
|
|
|
|
|
if (ScriptEngineManager::instance().dataManager()!=dataManager())
|
|
|
|
ScriptEngineManager::instance().setDataManager(dataManager());
|
|
|
|
|
2017-02-11 00:21:03 +03:00
|
|
|
ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
|
2017-01-28 02:20:15 +03:00
|
|
|
|
|
|
|
ScriptExtractor scriptExtractor(script);
|
|
|
|
if (scriptExtractor.parse()){
|
|
|
|
QString scriptBody = expandDataFields(scriptExtractor.bodyAt(0),EscapeSymbols, varValue, 0);
|
|
|
|
scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
|
2017-02-11 00:21:03 +03:00
|
|
|
ScriptValueType value = se->evaluate(scriptBody);
|
|
|
|
#ifdef USE_QJSENGINE
|
|
|
|
if (!value.isError()){
|
|
|
|
#else
|
2017-01-28 02:20:15 +03:00
|
|
|
if (!se->hasUncaughtException()) {
|
2017-02-11 00:21:03 +03:00
|
|
|
#endif
|
2017-01-28 02:20:15 +03:00
|
|
|
return value.toVariant();
|
2016-02-17 10:28:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-28 02:20:15 +03:00
|
|
|
return QVariant();
|
2016-02-17 10:28:27 +03:00
|
|
|
}
|
|
|
|
|
2016-06-10 18:05:18 +03:00
|
|
|
void ScriptEngineManager::updateModel()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-11-01 20:42:45 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2017-02-11 00:21:03 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-02-17 10:11:00 +03:00
|
|
|
ScriptEngineManager::ScriptEngineManager()
|
2016-02-17 10:28:27 +03:00
|
|
|
:m_model(0), m_dataManager(0)
|
2016-02-17 10:11:00 +03:00
|
|
|
{
|
2016-11-01 20:42:45 +03:00
|
|
|
m_scriptEngine = new ScriptEngineType;
|
|
|
|
m_functionManager = new ScriptFunctionsManager(this);
|
|
|
|
m_functionManager->setScriptEngineManager(this);
|
|
|
|
|
|
|
|
createLineFunction();
|
|
|
|
createNumberFomatFunction();
|
|
|
|
createDateFormatFunction();
|
|
|
|
createTimeFormatFunction();
|
|
|
|
createDateTimeFormatFunction();
|
|
|
|
createDateFunction();
|
|
|
|
createNowFunction();
|
2016-10-03 21:56:48 +03:00
|
|
|
#if QT_VERSION>0x040800
|
2016-11-01 20:42:45 +03:00
|
|
|
createCurrencyFormatFunction();
|
|
|
|
createCurrencyUSBasedFormatFunction();
|
2016-10-03 21:56:48 +03:00
|
|
|
#endif
|
2016-11-01 20:42:45 +03:00
|
|
|
createSetVariableFunction();
|
2017-02-11 00:21:03 +03:00
|
|
|
createGetFieldFunction();
|
|
|
|
createGetVariableFunction();
|
2016-11-01 20:42:45 +03:00
|
|
|
#ifndef USE_QJSENGINE
|
2016-02-17 10:11:00 +03:00
|
|
|
QScriptValue colorCtor = m_scriptEngine->newFunction(constructColor);
|
|
|
|
m_scriptEngine->globalObject().setProperty("QColor", colorCtor);
|
|
|
|
|
|
|
|
QScriptValue fontProto(m_scriptEngine->newQObject(new QFontPrototype,QScriptEngine::ScriptOwnership));
|
|
|
|
m_scriptEngine->setDefaultPrototype(qMetaTypeId<QFont>(), fontProto);
|
|
|
|
QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto);
|
|
|
|
m_scriptEngine->globalObject().setProperty("QFont", fontConstructor);
|
2016-11-01 20:42:45 +03:00
|
|
|
#endif
|
2016-02-17 10:11:00 +03:00
|
|
|
m_model = new ScriptEngineModel(this);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::parse()
|
|
|
|
{
|
|
|
|
int currentPos = 0;
|
|
|
|
parse(currentPos,None);
|
|
|
|
return m_scriptsBody.count()>0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::parse(int &curPos,const State& state)
|
|
|
|
{
|
|
|
|
while (curPos<m_context.length()){
|
|
|
|
switch (state) {
|
|
|
|
case OpenBracketFound:
|
|
|
|
if (m_context[curPos]=='}'){
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (m_context[curPos]=='{')
|
|
|
|
extractBracket(curPos);
|
|
|
|
}
|
|
|
|
case None:
|
|
|
|
if (m_context[curPos]=='$'){
|
|
|
|
int startPos = curPos;
|
|
|
|
if (isStartScriptLexem(curPos))
|
|
|
|
extractScript(curPos,substring(m_context,startPos,curPos));
|
|
|
|
if (isStartFieldLexem(curPos) || isStartVariableLexem(curPos))
|
|
|
|
skipField(curPos);
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
curPos++;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptExtractor::extractScript(int &curPos, const QString& startStr)
|
|
|
|
{
|
|
|
|
int startPos = curPos;
|
|
|
|
if (extractBracket(curPos)){
|
|
|
|
QString scriptBody = substring(m_context,startPos+1,curPos);
|
|
|
|
m_scriptsBody.push_back(scriptBody);
|
|
|
|
m_scriptsStartLex.push_back(startStr+'{');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptExtractor::skipField(int &curPos){
|
|
|
|
while (curPos<m_context.length()) {
|
|
|
|
if (m_context[curPos]=='}'){
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
curPos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::extractBracket(int &curPos)
|
|
|
|
{
|
|
|
|
curPos++;
|
|
|
|
return parse(curPos,OpenBracketFound);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::isStartLexem(int& curPos, QChar value){
|
|
|
|
int pos = curPos+1;
|
|
|
|
State ls = BuksFound;
|
|
|
|
while (pos<m_context.length()){
|
|
|
|
switch (ls){
|
|
|
|
case BuksFound:
|
|
|
|
if (m_context[pos]==value){
|
|
|
|
ls = SignFound;
|
|
|
|
} else {
|
|
|
|
if (m_context[pos]!=' ')
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SignFound:
|
|
|
|
if (m_context[pos]=='{'){
|
|
|
|
curPos=pos;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
if (m_context[pos]!=' ')
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::isStartScriptLexem(int& curPos)
|
|
|
|
{
|
|
|
|
return isStartLexem(curPos, SCRIPT_SIGN);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::isStartFieldLexem(int& curPos){
|
|
|
|
return isStartLexem(curPos, FIELD_SIGN);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptExtractor::isStartVariableLexem(int &curPos)
|
|
|
|
{
|
|
|
|
return isStartLexem(curPos, VARIABLE_SIGN);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString ScriptExtractor::substring(const QString &value, int start, int end)
|
|
|
|
{
|
|
|
|
return value.mid(start,end-start);
|
|
|
|
}
|
|
|
|
|
2016-06-10 18:05:18 +03:00
|
|
|
QString DialogDescriber::name() const
|
|
|
|
{
|
|
|
|
return m_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialogDescriber::setName(const QString& name)
|
|
|
|
{
|
|
|
|
m_name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray DialogDescriber::description() const
|
|
|
|
{
|
|
|
|
return m_description;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialogDescriber::setDescription(const QByteArray &description)
|
|
|
|
{
|
|
|
|
m_description = description;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
void ScriptEngineContext::addDialog(const QString& name, const QByteArray& description)
|
|
|
|
{
|
|
|
|
m_dialogs.push_back(DialogDescriber::create(name,description));
|
2017-04-14 02:43:34 +03:00
|
|
|
emit dialogAdded(name);
|
2016-06-10 18:05:18 +03:00
|
|
|
}
|
|
|
|
|
2017-04-11 11:23:34 +03:00
|
|
|
bool ScriptEngineContext::changeDialog(const QString& name, const QByteArray& description)
|
|
|
|
{
|
|
|
|
foreach( DialogDescriber::Ptr describer, m_dialogs){
|
|
|
|
if (describer->name().compare(name) == 0){
|
|
|
|
describer->setDescription(description);
|
2017-04-14 02:43:34 +03:00
|
|
|
{
|
|
|
|
QList<DialogPtr>::Iterator it = m_createdDialogs.begin();
|
|
|
|
while(it!=m_createdDialogs.end()){
|
|
|
|
if ((*it)->objectName()==name){
|
|
|
|
it = m_createdDialogs.erase(it);
|
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptEngineContext::changeDialogName(const QString& oldName, const QString& newName)
|
|
|
|
{
|
|
|
|
foreach( DialogDescriber::Ptr describer, m_dialogs){
|
|
|
|
if (describer->name().compare(oldName) == 0){
|
|
|
|
describer->setName(newName);
|
|
|
|
{
|
|
|
|
QList<DialogPtr>::Iterator it = m_createdDialogs.begin();
|
|
|
|
while(it!=m_createdDialogs.end()){
|
|
|
|
if ((*it)->objectName()==oldName){
|
|
|
|
it = m_createdDialogs.erase(it);
|
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-04-11 11:23:34 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-06-10 18:05:18 +03:00
|
|
|
bool ScriptEngineContext::previewDialog(const QString& dialogName)
|
|
|
|
{
|
|
|
|
QDialog* dialog = getDialog(dialogName);
|
|
|
|
if (dialog) {
|
|
|
|
dialog->exec();
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
m_lastError = tr("Dialog with name: %1 can`t be created").arg(dialogName);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ScriptEngineContext::containsDialog(const QString& dialogName)
|
|
|
|
{
|
|
|
|
foreach(DialogDescriber::Ptr dialog, m_dialogs){
|
|
|
|
if (dialog->name()==dialogName)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineContext::deleteDialog(const QString& dialogName)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QVector<DialogDescriber::Ptr>::Iterator it = m_dialogs.begin();
|
|
|
|
while(it!=m_dialogs.end()){
|
|
|
|
if ((*it)->name()==dialogName){
|
|
|
|
it = m_dialogs.erase(it);
|
2017-04-14 02:43:34 +03:00
|
|
|
emit dialogDeleted(dialogName);
|
2016-06-10 18:05:18 +03:00
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
QList<DialogPtr>::Iterator it = m_createdDialogs.begin();
|
|
|
|
while(it!=m_createdDialogs.end()){
|
|
|
|
if ((*it)->objectName()==dialogName){
|
|
|
|
it = m_createdDialogs.erase(it);
|
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void ScriptEngineContext::clear()
|
|
|
|
{
|
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
m_dialogs.clear();
|
|
|
|
m_createdDialogs.clear();
|
|
|
|
#endif
|
|
|
|
m_initScript.clear();
|
|
|
|
m_lastError="";
|
|
|
|
}
|
|
|
|
|
|
|
|
QObject* ScriptEngineContext::createElement(const QString& collectionName, const QString& elementType)
|
|
|
|
{
|
|
|
|
Q_UNUSED(elementType)
|
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
if (collectionName.compare("dialogs",Qt::CaseInsensitive)==0){
|
|
|
|
m_dialogs.push_back(DialogDescriber::create());
|
|
|
|
return m_dialogs.at(m_dialogs.count()-1).data();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
Q_UNUSED(collectionName)
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ScriptEngineContext::elementsCount(const QString& collectionName)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
if (collectionName.compare("dialogs",Qt::CaseInsensitive)==0){
|
|
|
|
return m_dialogs.count();
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
Q_UNUSED(collectionName)
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QObject* ScriptEngineContext::elementAt(const QString& collectionName, int index)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
if (collectionName.compare("dialogs",Qt::CaseInsensitive)==0){
|
|
|
|
return m_dialogs.at(index).data();
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
Q_UNUSED(collectionName)
|
|
|
|
Q_UNUSED(index)
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineContext::collectionLoadFinished(const QString& collectionName)
|
|
|
|
{
|
|
|
|
Q_UNUSED(collectionName);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_UI_LOADER
|
|
|
|
QDialog* ScriptEngineContext::createDialog(DialogDescriber* cont)
|
|
|
|
{
|
|
|
|
QUiLoader loader;
|
|
|
|
QByteArray desc = cont->description();
|
|
|
|
QBuffer buffer(&desc);
|
|
|
|
buffer.open(QIODevice::ReadOnly);
|
|
|
|
QDialog* dialog = dynamic_cast<QDialog*>(loader.load(&buffer));
|
|
|
|
m_createdDialogs.push_back(QSharedPointer<QDialog>(dialog));
|
2017-04-14 02:43:34 +03:00
|
|
|
if (cont->name().compare(dialog->objectName())){
|
|
|
|
cont->setName(dialog->objectName());
|
|
|
|
emit dialogNameChanged(dialog->objectName());
|
|
|
|
}
|
2016-06-10 18:05:18 +03:00
|
|
|
return dialog;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDialog* ScriptEngineContext::findDialog(const QString& dialogName)
|
|
|
|
{
|
|
|
|
foreach(DialogPtr dialog, m_createdDialogs){
|
|
|
|
if (dialog->objectName()==dialogName)
|
|
|
|
return dialog.data();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DialogDescriber* ScriptEngineContext::findDialogContainer(const QString& dialogName)
|
|
|
|
{
|
|
|
|
foreach (DialogDescriber::Ptr dialogCont , m_dialogs) {
|
|
|
|
if (dialogCont->name().compare(dialogName,Qt::CaseInsensitive)==0){
|
|
|
|
return dialogCont.data();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDialog* ScriptEngineContext::getDialog(const QString& dialogName)
|
|
|
|
{
|
|
|
|
QDialog* dialog = findDialog(dialogName);
|
|
|
|
if (dialog){
|
|
|
|
return dialog;
|
|
|
|
} else {
|
|
|
|
DialogDescriber* cont = findDialogContainer(dialogName);
|
|
|
|
if (cont){
|
|
|
|
dialog = createDialog(cont);
|
|
|
|
if (dialog)
|
|
|
|
return dialog;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2017-04-14 02:43:34 +03:00
|
|
|
|
|
|
|
QString ScriptEngineContext::getNewDialogName()
|
|
|
|
{
|
|
|
|
QString result = "Dialog";
|
|
|
|
int index = m_dialogs.size() - 1;
|
|
|
|
while (containsDialog(result)){
|
|
|
|
index++;
|
|
|
|
result = QString("Dialog%1").arg(index);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-06-10 18:05:18 +03:00
|
|
|
#endif
|
2017-04-20 23:34:32 +03:00
|
|
|
|
|
|
|
void ScriptEngineContext::baseDesignIntfToScript(BaseDesignIntf* item)
|
|
|
|
{
|
|
|
|
if ( item ) {
|
|
|
|
|
|
|
|
if (item->metaObject()->indexOfSignal("beforeRender()")!=-1)
|
|
|
|
item->disconnect(SIGNAL(beforeRender()));
|
|
|
|
if (item->metaObject()->indexOfSignal("afterData()")!=-1)
|
|
|
|
item->disconnect(SIGNAL(afterData()));
|
|
|
|
if (item->metaObject()->indexOfSignal("afterRender()")!=-1)
|
|
|
|
item->disconnect(SIGNAL(afterRender()));
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#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 ScriptEngineContext::initDialogs(){
|
|
|
|
ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
|
|
|
|
foreach(DialogDescriber::Ptr dialog, dialogDescribers()){
|
|
|
|
ScriptValueType sv = se->newQObject(getDialog(dialog->name()));
|
|
|
|
#ifdef USE_QJSENGINE
|
|
|
|
registerChildObjects(se,&sv);
|
|
|
|
#endif
|
|
|
|
se->globalObject().setProperty(dialog->name(),sv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
bool ScriptEngineContext::runInitScript(){
|
|
|
|
|
|
|
|
ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine();
|
|
|
|
#ifndef USE_QJSENGINE
|
|
|
|
engine->pushContext();
|
|
|
|
#endif
|
|
|
|
ScriptValueType res = engine->evaluate(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;
|
|
|
|
}
|
|
|
|
|
2016-06-10 18:05:18 +03:00
|
|
|
QString ScriptEngineContext::initScript() const
|
|
|
|
{
|
|
|
|
return m_initScript;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptEngineContext::setInitScript(const QString& initScript)
|
|
|
|
{
|
|
|
|
m_initScript = initScript;
|
|
|
|
}
|
|
|
|
|
|
|
|
DialogDescriber::Ptr DialogDescriber::create(const QString& name, const QByteArray& desc) {
|
|
|
|
Ptr res(new DialogDescriber());
|
|
|
|
res->setName(name);
|
|
|
|
res->setDescription(desc);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2016-11-01 20:42:45 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-02-11 00:21:03 +03:00
|
|
|
QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName)
|
2016-11-01 20:42:45 +03:00
|
|
|
{
|
|
|
|
if (m_scriptEngineManager->dataManager()){
|
2017-03-08 04:59:40 +03:00
|
|
|
QString expression = m_scriptEngineManager->dataManager()->getExpression(expressionID);
|
2017-02-11 00:21:03 +03:00
|
|
|
GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName);
|
2016-11-01 20:42:45 +03:00
|
|
|
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);
|
|
|
|
}
|
2017-02-11 00:21:03 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-11-01 20:42:45 +03:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
2016-02-17 10:11:00 +03:00
|
|
|
} //namespace LimeReport
|
|
|
|
|