diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ if(KREPORT_SCRIPTING) find_package(Qt5Qml REQUIRED) - set(SCRIPTING_LIBS Qt5Qml) + set(SCRIPTING_LIBS Qt5::Qml) endif() add_subdirectory(plugins) @@ -154,6 +154,7 @@ Qt5::Xml KF5::CoreAddons KProperty + Qt5::Network PRIVATE KF5::WidgetsAddons KF5::ConfigGui # KStandardShortcut diff --git a/src/common/KoReportData.cpp b/src/common/KoReportData.cpp --- a/src/common/KoReportData.cpp +++ b/src/common/KoReportData.cpp @@ -70,7 +70,6 @@ QStringList KoReportData::dataSourceNames() const { - qDebug() << "Returning data sources"; return dataSources(); } diff --git a/src/common/renderobjects.cpp b/src/common/renderobjects.cpp --- a/src/common/renderobjects.cpp +++ b/src/common/renderobjects.cpp @@ -43,7 +43,10 @@ OROPage* ORODocument::page(int pnum) { - return m_pages.at(pnum); + if (pnum >= 0 && pnum < m_pages.count()) { + return m_pages.at(pnum); + } + return nullptr; } void ORODocument::addPage(OROPage* p) diff --git a/src/renderer/KoReportPreRenderer.cpp b/src/renderer/KoReportPreRenderer.cpp --- a/src/renderer/KoReportPreRenderer.cpp +++ b/src/renderer/KoReportPreRenderer.cpp @@ -505,8 +505,11 @@ if (i.key() == QLatin1String("field")) QObject::connect(d->m_scriptHandler, SIGNAL(groupChanged(QString)), i.value(), SLOT(setWhere(QString))); } - //execute the script - d->m_scriptHandler->trigger(); + //execute the script, if it fails, abort and return the empty document + if (!d->m_scriptHandler->trigger()) { + d->m_scriptHandler->displayErrors(); + return d->m_document; + } } #endif diff --git a/src/renderer/KoReportScreenRenderer.cpp b/src/renderer/KoReportScreenRenderer.cpp --- a/src/renderer/KoReportScreenRenderer.cpp +++ b/src/renderer/KoReportScreenRenderer.cpp @@ -46,6 +46,10 @@ OROPage *p = document->page(page); + if (p == nullptr) { + return false; + } + // Render Page Objects for (int i = 0; i < p->primitives(); i++) { OROPrimitive *prim = p->primitive(i); diff --git a/src/renderer/scripting/krscripthandler.h b/src/renderer/scripting/krscripthandler.h --- a/src/renderer/scripting/krscripthandler.h +++ b/src/renderer/scripting/krscripthandler.h @@ -48,7 +48,7 @@ QVariant evaluate(const QString&); void displayErrors(); QJSValue registerScriptObject(QObject*, const QString&); - void trigger(); + bool trigger(); public Q_SLOTS: diff --git a/src/renderer/scripting/krscripthandler.cpp b/src/renderer/scripting/krscripthandler.cpp --- a/src/renderer/scripting/krscripthandler.cpp +++ b/src/renderer/scripting/krscripthandler.cpp @@ -23,18 +23,16 @@ #include "krscriptreport.h" #include "krscriptdraw.h" #include "krscriptconstants.h" - #include "krsectiondata.h" #include "KoReportItemBase.h" #include "krreportdata.h" #include "krdetailsectiondata.h" #include "renderobjects.h" +#include "kreport_debug.h" #include - -#include "kreport_debug.h" -#include -#include +#include +#include KRScriptHandler::KRScriptHandler(const KoReportData* kodata, KoReportReportData* d) { @@ -81,27 +79,29 @@ kreportDebug() << "Report name is" << m_reportData->name(); } -void KRScriptHandler::trigger() +bool KRScriptHandler::trigger() { - //kreportDebug() << m_engine->code(); QString code = m_koreportData->scriptCode(m_reportData->script()); - qDebug() << code; - m_scriptValue = m_engine->evaluate(code); + kreportDebug() << code; + + if (code.isEmpty()) { + return true; + } + + m_scriptValue = m_engine->evaluate(code, m_reportData->script()); if (m_scriptValue.isError()) { - QMessageBox::warning(0, tr("Script Error"), m_scriptValue.toString()); + return false; }/*TODO else { kreportDebug() << "Function Names:" << m_engine->functionNames(); }*/ m_report->eventOnOpen(); + return true; } KRScriptHandler::~KRScriptHandler() { delete m_report; - delete m_constants; - delete m_debug; - delete m_draw; delete m_engine; } @@ -142,10 +142,13 @@ { if (!m_scriptValue.isError()) { QJSValue result = m_engine->evaluate(code); - return result.toVariant(); - } else { - return QVariant(); + if (!result.isError()) { + return result.toVariant(); + } else { + QMessageBox::warning(0, tr("Script Error"), m_scriptValue.toString()); + } } + return QVariant(); } void KRScriptHandler::displayErrors() @@ -171,10 +174,8 @@ QJSValue KRScriptHandler::registerScriptObject(QObject* obj, const QString& name) { QJSValue val; - if (m_engine) { - val = m_engine->newQObject(obj); - m_engine->globalObject().setProperty(name, val); - } + val = m_engine->newQObject(obj); + m_engine->globalObject().setProperty(name, val); return val; } diff --git a/src/renderer/scripting/krscriptreport.h b/src/renderer/scripting/krscriptreport.h --- a/src/renderer/scripting/krscriptreport.h +++ b/src/renderer/scripting/krscriptreport.h @@ -43,7 +43,7 @@ QObject* sectionByName(const QString &); - void initialize(QJSValue val); + void initialize(const QJSValue &val); void eventOnOpen(); void eventOnComplete(); void eventOnNewPage(); diff --git a/src/renderer/scripting/krscriptreport.cpp b/src/renderer/scripting/krscriptreport.cpp --- a/src/renderer/scripting/krscriptreport.cpp +++ b/src/renderer/scripting/krscriptreport.cpp @@ -92,26 +92,26 @@ } } -void Report::initialize(QJSValue val) +void Report::initialize(const QJSValue &val) { m_scriptObject = val; } void Report::eventOnOpen() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnOpen"))) m_scriptObject.property(QLatin1String("OnOpen")).call(); } void Report::eventOnComplete() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnComlete"))) m_scriptObject.property(QLatin1String("OnComplete")).call(); } void Report::eventOnNewPage() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnNewPage"))) m_scriptObject.property(QLatin1String("OnNewPage")).call(); } diff --git a/src/renderer/scripting/krscriptsection.h b/src/renderer/scripting/krscriptsection.h --- a/src/renderer/scripting/krscriptsection.h +++ b/src/renderer/scripting/krscriptsection.h @@ -55,7 +55,7 @@ /**Returns an object in the section, by name*/ QObject* objectByName(const QString&); - void initialize(QJSValue s); + void initialize(const QJSValue &s); void eventOnRender(); private: diff --git a/src/renderer/scripting/krscriptsection.cpp b/src/renderer/scripting/krscriptsection.cpp --- a/src/renderer/scripting/krscriptsection.cpp +++ b/src/renderer/scripting/krscriptsection.cpp @@ -95,14 +95,14 @@ return 0; } -void Section::initialize(QJSValue s) +void Section::initialize(const QJSValue &s) { m_scriptObject = s; } void Section::eventOnRender() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnRender"))) m_scriptObject.property(QLatin1String("OnRender")).call(); } } diff --git a/src/wrtembed/KoReportDesigner.cpp b/src/wrtembed/KoReportDesigner.cpp --- a/src/wrtembed/KoReportDesigner.cpp +++ b/src/wrtembed/KoReportDesigner.cpp @@ -33,6 +33,7 @@ #include "common/krutils.h" #include "common/KoReportPluginInterface.h" #include "common/KoReportPluginManager.h" +#include "kreport_debug.h" #include #include @@ -46,7 +47,7 @@ #include #include #include -#include "kreport_debug.h" +#include //! Also add public method for runtime? const char ns[] = "http://kexi-project.org/report/2.0"; @@ -196,6 +197,9 @@ bool modified; // true if this document has been modified, false otherwise + QString loadInterpreter; //Value of the script interpreter at load time + QString loadScript; //Value of the script at load time + KoReportData *kordata; }; @@ -282,8 +286,16 @@ setReportTitle(it.firstChild().nodeValue()); #ifdef KREPORT_SCRIPTING } else if (n == QLatin1String("report:script")) { -//!TODO d->interpreter->setValue(it.toElement().attribute(QLatin1String("report:script-interpreter"))); - d->script->setValue(it.firstChild().nodeValue()); + d->loadInterpreter = it.toElement().attribute(QLatin1String("report:script-interpreter")); + d->loadScript = it.firstChild().nodeValue(); + d->script->setValue(d->loadScript); + + if (d->loadInterpreter != QLatin1String("javascript") || d->loadInterpreter != QLatin1String("qtscript")) { + QString msg = tr("This report is using a script type other than 'javascript'\n" + "To prevent data loss, the type of script will not be changed unless the script is changed.\n\n" + "Please be aware that the script will not work unless it is changed to a 'javascript' script."); + QMessageBox::warning(this, tr("Invalid Script Detected"), msg); + } #endif } else if (n == QLatin1String("report:grid")) { d->showGrid->setValue(it.toElement().attribute(QLatin1String("report:grid-visible"), QString::number(1)).toInt() != 0); @@ -352,6 +364,7 @@ QDomElement KoReportDesigner::document() const { QDomDocument doc; + QString saveInterpreter; QDomElement content = doc.createElement(QLatin1String("report:content")); content.setAttribute(QLatin1String("xmlns:report"), QLatin1String(ns)); @@ -364,8 +377,15 @@ content.appendChild(propertyToElement(&doc, d->title)); #ifdef KREPORT_SCRIPTING + if (d->script->value().toString() != d->loadScript || d->loadInterpreter == QLatin1String("qtscript")) { + //The script has changed so force interpreter to 'javascript'. Also set if was using qtscript + saveInterpreter = QLatin1String("javascript"); + } else { + saveInterpreter = d->loadInterpreter; + } + QDomElement scr = propertyToElement(&doc, d->script); - //KRUtils::addPropertyAsAttribute(&scr, d->interpreter); + scr.setAttribute(QLatin1String("report:interpreter"), saveInterpreter); content.appendChild(scr); #endif @@ -780,11 +800,10 @@ void KoReportDesigner::slotPageButton_Pressed() { - qDebug() << "page button pressed"; #ifdef KREPORT_SCRIPTING if (d->kordata) { QStringList sl = d->kordata->scriptList(); - sl.push_front(QLatin1String("")); + sl.prepend(QLatin1String("")); d->script->setListData(sl, sl); } changeSet(d->set);