summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkh1 <karsten.heimrich@digia.com>2014-06-02 15:14:12 +0200
committerKarsten Heimrich <karsten.heimrich@digia.com>2014-06-03 10:51:51 +0200
commit8addcf763bc0644de1f3548a2a65876aed65a7c9 (patch)
tree12f2735f9e757d415f5200000de17b3231b9c053
parent3aaca15ef8a8dd13ba877821a3683ba86241be9b (diff)
Replace script with js engine.
Change-Id: Ic9c88e27dca1e936ba09a3776df3df7ec166c606 Reviewed-by: Tim Jenssen <tim.jenssen@digia.com>
-rw-r--r--installerfw.pri2
-rw-r--r--src/libs/installer/component.cpp49
-rw-r--r--src/libs/installer/component.h5
-rw-r--r--src/libs/installer/component_p.h4
-rw-r--r--src/libs/installer/installer.pro5
-rw-r--r--src/libs/installer/messageboxhandler.cpp12
-rw-r--r--src/libs/installer/messageboxhandler.h5
-rw-r--r--src/libs/installer/packagemanagergui.cpp21
-rw-r--r--src/libs/installer/scriptengine.cpp428
-rw-r--r--src/libs/installer/scriptengine.h51
-rw-r--r--src/libs/installer/scriptengine_p.h127
-rw-r--r--src/sdk/sdk.pro2
-rw-r--r--tests/auto/installer/componentmodel/componentmodel.pro2
-rw-r--r--tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro2
-rw-r--r--tests/auto/installer/fakestopprocessforupdateoperation/fakestopprocessforupdateoperation.pro2
-rw-r--r--tests/auto/installer/messageboxhandler/messageboxhandler.pro2
-rw-r--r--tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp44
-rw-r--r--tests/auto/installer/packagemanagercore/packagemanagercore.pro2
-rw-r--r--tests/auto/installer/scriptengine/scriptengine.pro2
-rw-r--r--tests/auto/installer/scriptengine/tst_scriptengine.cpp124
-rw-r--r--tools/archivegen/archivegen.pro2
-rw-r--r--tools/binarycreator/binarycreator.pro2
-rw-r--r--tools/common/repositorygen.cpp10
-rw-r--r--tools/repogen/repogen.pro2
24 files changed, 459 insertions, 448 deletions
diff --git a/installerfw.pri b/installerfw.pri
index bde64c66f..86b9b6c84 100644
--- a/installerfw.pri
+++ b/installerfw.pri
@@ -95,7 +95,7 @@ macx:LIBS += -framework Carbon -framework Security
QT += uitools core-private
CONFIG(static, static|shared) {
QTPLUGIN += qico qtaccessiblewidgets
- QT += concurrent network script xml
+ QT += concurrent network qml xml
}
CONFIG += depend_includepath no_private_qt_headers_warning
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index a1550b47c..3cb8ce2f6 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -488,10 +488,9 @@ void Component::loadComponentScript(const QString &fileName)
{
// introduce the component object as javascript value and call the name to check that it
// was successful
- QString scriptInjection(QString::fromLatin1(
- "var component = installer.componentByName('%1'); component.name;").arg(name()));
-
- d->m_scriptContext = d->scriptEngine()->loadInConext(QLatin1String("Component"), fileName, scriptInjection);
+ d->m_scriptContext = d->scriptEngine()->loadInContext(QLatin1String("Component"), fileName,
+ QString::fromLatin1("var component = installer.componentByName('%1'); component.name;")
+ .arg(name()));
emit loaded();
languageChanged();
@@ -650,9 +649,9 @@ void Component::createOperationsForPath(const QString &path)
return;
// the script can override this method
- if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
- QLatin1String("createOperationsForPath"), QScriptValueList() << path).isValid()) {
- return;
+ if (!d->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("createOperationsForPath"), QJSValueList() << path).isUndefined()) {
+ return;
}
QString target;
@@ -695,9 +694,9 @@ void Component::createOperationsForArchive(const QString &archive)
return;
// the script can override this method
- if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
- QLatin1String("createOperationsForArchive"), QScriptValueList() << archive).isValid()) {
- return;
+ if (!d->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("createOperationsForArchive"), QJSValueList() << archive).isUndefined()) {
+ return;
}
const bool isZip = Lib7z::isSupportedArchive(archive);
@@ -729,10 +728,7 @@ void Component::createOperationsForArchive(const QString &archive)
void Component::beginInstallation()
{
// the script can override this method
- if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
- QLatin1String("beginInstallation")).isValid()) {
- return;
- }
+ d->scriptEngine()->callScriptMethod(d->m_scriptContext, QLatin1String("beginInstallation"));
}
/*!
@@ -748,10 +744,10 @@ void Component::beginInstallation()
void Component::createOperations()
{
// the script can override this method
- if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
- QLatin1String("createOperations")).isValid()) {
- d->m_operationsCreated = true;
- return;
+ if (!d->scriptEngine()->callScriptMethod(d->m_scriptContext, QLatin1String("createOperations"))
+ .isUndefined()) {
+ d->m_operationsCreated = true;
+ return;
}
foreach (const QString &archive, archives())
@@ -1110,8 +1106,7 @@ void Component::setValidatorCallbackName(const QString &name)
bool Component::validatePage()
{
if (!validatorCallbackName.isEmpty())
- return d->scriptEngine()->callScriptMethod(
- d->m_scriptContext, validatorCallbackName).toBool();
+ return d->scriptEngine()->callScriptMethod(d->m_scriptContext, validatorCallbackName).toBool();
return true;
}
@@ -1189,7 +1184,7 @@ bool Component::isAutoDependOn(const QSet<QString> &componentsToInstall) const
// The script can override this method and determines if the component needs to be installed.
if (autoDependOnList.first().compare(QLatin1String("script"), Qt::CaseInsensitive) == 0) {
- QScriptValue valueFromScript;
+ QJSValue valueFromScript;
try {
valueFromScript = d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("isAutoDependOn"));
@@ -1200,9 +1195,10 @@ bool Component::isAutoDependOn(const QSet<QString> &componentsToInstall) const
return false;
}
- if (valueFromScript.isValid())
+ if (!valueFromScript.isError())
return valueFromScript.toBool();
- qDebug() << "value from script is not valid";
+ qDebug() << "Value from script is not valid." << (valueFromScript.toString().isEmpty()
+ ? QString::fromLatin1("Unknown error.") : valueFromScript.toString());
return false;
}
@@ -1239,7 +1235,7 @@ bool Component::isDefault() const
// the script can override this method
if (d->m_vars.value(scDefault).compare(QLatin1String("script"), Qt::CaseInsensitive) == 0) {
- QScriptValue valueFromScript;
+ QJSValue valueFromScript;
try {
valueFromScript = d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("isDefault"));
@@ -1249,9 +1245,10 @@ bool Component::isDefault() const
error.message());
return false;
}
- if (valueFromScript.isValid())
+ if (!valueFromScript.isError())
return valueFromScript.toBool();
- qDebug() << "value from script is not valid";
+ qDebug() << "Value from script is not valid." << (valueFromScript.toString().isEmpty()
+ ? QString::fromLatin1("Unknown error.") : valueFromScript.toString());
return false;
}
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index 3ff814a30..3e7e91048 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -51,9 +51,6 @@
#include <QtCore/QObject>
#include <QtCore/QUrl>
-#include <QtScript/QScriptable>
-#include <QtScript/QScriptValueList>
-
QT_FORWARD_DECLARE_CLASS(QDebug)
namespace KDUpdater {
@@ -65,7 +62,7 @@ namespace QInstaller {
class PackageManagerCore;
-class INSTALLER_EXPORT Component : public QObject, public QScriptable, public ComponentModelHelper
+class INSTALLER_EXPORT Component : public QObject, public ComponentModelHelper
{
Q_OBJECT
Q_DISABLE_COPY(Component)
diff --git a/src/libs/installer/component_p.h b/src/libs/installer/component_p.h
index 98d3cf2f4..81ade9cf6 100644
--- a/src/libs/installer/component_p.h
+++ b/src/libs/installer/component_p.h
@@ -44,8 +44,8 @@
#include "qinstallerglobal.h"
+#include <QJSValue>
#include <QPointer>
-#include <QScriptValue>
#include <QStringList>
#include <QUrl>
@@ -80,7 +80,7 @@ public:
QString m_componentName;
QUrl m_repositoryUrl;
QString m_localTempPath;
- QScriptValue m_scriptContext;
+ QJSValue m_scriptContext;
QHash<QString, QString> m_vars;
QList<Component*> m_childComponents;
QList<Component*> m_allChildComponents;
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index 0b8ec0524..7a679d554 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -29,7 +29,7 @@ DLLDESTDIR = $$IFW_APP_PATH
DEFINES += BUILD_LIB_INSTALLER
QT += \
- script \
+ qml \
network \
xml \
concurrent \
@@ -111,7 +111,8 @@ HEADERS += packagemanagercore.h \
runextensions.h \
metadatajob.h \
metadatajob_p.h \
- installer_global.h
+ installer_global.h \
+ scriptengine_p.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
diff --git a/src/libs/installer/messageboxhandler.cpp b/src/libs/installer/messageboxhandler.cpp
index 09aa43c1d..4b5380754 100644
--- a/src/libs/installer/messageboxhandler.cpp
+++ b/src/libs/installer/messageboxhandler.cpp
@@ -231,25 +231,29 @@ QMessageBox::StandardButton MessageBoxHandler::warning(QWidget *parent, const QS
int MessageBoxHandler::critical(const QString &identifier, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton button) const
{
- return showMessageBox(criticalType, currentBestSuitParent(), identifier, title, text, buttons, button);
+ return showMessageBox(criticalType, currentBestSuitParent(), identifier, title, text,
+ QMessageBox::StandardButtons(buttons), QMessageBox::StandardButton(button));
}
int MessageBoxHandler::information(const QString &identifier, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton button) const
{
- return showMessageBox(informationType, currentBestSuitParent(), identifier, title, text, buttons, button);
+ return showMessageBox(informationType, currentBestSuitParent(), identifier, title, text,
+ QMessageBox::StandardButtons(buttons), QMessageBox::StandardButton(button));
}
int MessageBoxHandler::question(const QString &identifier, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton button) const
{
- return showMessageBox(questionType, currentBestSuitParent(), identifier, title, text, buttons, button);
+ return showMessageBox(questionType, currentBestSuitParent(), identifier, title, text,
+ QMessageBox::StandardButtons(buttons), QMessageBox::StandardButton(button));
}
int MessageBoxHandler::warning(const QString &identifier, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton button) const
{
- return showMessageBox(warningType, currentBestSuitParent(), identifier, title, text, buttons, button);
+ return showMessageBox(warningType, currentBestSuitParent(), identifier, title, text,
+ QMessageBox::StandardButtons(buttons), QMessageBox::StandardButton(button));
}
// -- private
diff --git a/src/libs/installer/messageboxhandler.h b/src/libs/installer/messageboxhandler.h
index bc3edce3b..95935bbde 100644
--- a/src/libs/installer/messageboxhandler.h
+++ b/src/libs/installer/messageboxhandler.h
@@ -47,11 +47,10 @@
#include <QHash>
#include <QMessageBox>
#include <QObject>
-#include <QScriptable>
namespace QInstaller {
-class INSTALLER_EXPORT MessageBoxHandler : public QObject, private QScriptable
+class INSTALLER_EXPORT MessageBoxHandler : public QObject
{
Q_OBJECT
@@ -134,5 +133,7 @@ private:
};
}
+Q_DECLARE_METATYPE(QMessageBox::StandardButton)
+Q_DECLARE_METATYPE(QMessageBox::StandardButtons)
#endif // QINSTALLER_MESSAGEBOXHANDLER_H
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index d5599791a..5a7ed98d1 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -219,7 +219,7 @@ public:
QHash<int, QWizardPage*> m_defaultPages;
QHash<int, QString> m_defaultButtonText;
- QScriptValue m_controlScriptContext;
+ QJSValue m_controlScriptContext;
QHash<QWizard::WizardButton, QString> m_wizardButtonTypes;
};
@@ -403,20 +403,19 @@ void PackageManagerGui::setValidatorForCustomPageRequested(Component *component,
*/
void PackageManagerGui::loadControlScript(const QString &scriptPath)
{
- d->m_controlScriptContext = m_core->controlScriptEngine()->loadInConext(
+ d->m_controlScriptContext = m_core->controlScriptEngine()->loadInContext(
QLatin1String("Controller"), scriptPath);
qDebug() << "Loaded control script" << scriptPath;
}
void PackageManagerGui::callControlScriptMethod(const QString &methodName)
{
- if (!d->m_controlScriptContext.isValid())
+ if (d->m_controlScriptContext.isUndefined())
return;
try {
- QScriptValue returnValue = m_core->controlScriptEngine()->callScriptMethod(
+ const QJSValue returnValue = m_core->controlScriptEngine()->callScriptMethod(
d->m_controlScriptContext, methodName);
-
- if (!returnValue.isValid()) {
+ if (returnValue.isUndefined()) {
qDebug() << "Control script callback" << methodName << "does not exist.";
return;
}
@@ -480,7 +479,10 @@ void PackageManagerGui::wizardPageInsertionRequested(QWidget *widget,
--pageId;
// add it
- setPage(pageId, new DynamicInstallerPage(widget, m_core));
+ DynamicInstallerPage *dynamicPage = new DynamicInstallerPage(widget, m_core);
+ packageManagerCore()->controlScriptEngine()->addQObjectChildren(dynamicPage);
+ packageManagerCore()->componentScriptEngine()->addQObjectChildren(dynamicPage);
+ setPage(pageId, dynamicPage);
}
void PackageManagerGui::wizardPageRemovalRequested(QWidget *widget)
@@ -500,8 +502,11 @@ void PackageManagerGui::wizardWidgetInsertionRequested(QWidget *widget,
QInstaller::PackageManagerCore::WizardPage page)
{
Q_ASSERT(widget);
- if (QWizardPage *const p = QWizard::page(page))
+ if (QWizardPage *const p = QWizard::page(page)) {
p->layout()->addWidget(widget);
+ packageManagerCore()->controlScriptEngine()->addQObjectChildren(p);
+ packageManagerCore()->componentScriptEngine()->addQObjectChildren(p);
+ }
}
void PackageManagerGui::wizardWidgetRemovalRequested(QWidget *widget)
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index e131390b3..252c3480b 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -40,201 +40,94 @@
**************************************************************************/
#include "scriptengine.h"
-#include "component.h"
-#include "globals.h"
-#include "packagemanagercore.h"
#include "messageboxhandler.h"
#include "errors.h"
+#include "scriptengine_p.h"
-#include <QDesktopServices>
-#include <QFileDialog>
#include <QMetaEnum>
+#include <QQmlEngine>
+#include <QUuid>
#include <QWizard>
-using namespace QInstaller;
-
namespace QInstaller {
-QString uncaughtExceptionString(const QScriptEngine *scriptEngine, const QString &context)
-{
- QString error(QLatin1String("\n\n%1\n\nBacktrace:\n\t%2"));
- if (!context.isEmpty())
- error.prepend(context);
-
- return error.arg(scriptEngine->uncaughtException().toString(), scriptEngine->uncaughtExceptionBacktrace()
- .join(QLatin1String("\n\t")));
-}
-
-/*!
- Scriptable version of PackageManagerCore::componentByName(QString).
- \sa PackageManagerCore::componentByName
- */
-QScriptValue qInstallerComponentByName(QScriptContext *context, QScriptEngine *engine)
-{
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
- // well... this is our "this" pointer
- PackageManagerCore *const core = qobject_cast<PackageManagerCore*>(engine->globalObject()
- .property(QLatin1String("installer")).toQObject());
-
- const QString name = context->argument(0).toString();
- return engine->newQObject(core->componentByName(name));
-}
-
-QScriptValue checkArguments(QScriptContext *context, int minimalArgumentCount, int maximalArgumentCount)
-{
- if (context->argumentCount() < minimalArgumentCount || context->argumentCount() > maximalArgumentCount) {
- if (minimalArgumentCount != maximalArgumentCount) {
- return context->throwError(QObject::tr("Invalid arguments: %1 arguments given, %2 to "
- "%3 expected.").arg(QString::number(context->argumentCount()),
- QString::number(minimalArgumentCount), QString::number(maximalArgumentCount)));
- }
- return context->throwError(QObject::tr("Invalid arguments: %1 arguments given, %2 expected.")
- .arg(QString::number(context->argumentCount()), QString::number(minimalArgumentCount)));
- }
- return QScriptValue();
-}
-
-QScriptValue qDesktopServicesOpenUrl(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
- QString url = context->argument(0).toString();
- url.replace(QLatin1String("\\\\"), QLatin1String("/"));
- url.replace(QLatin1String("\\"), QLatin1String("/"));
- return QDesktopServices::openUrl(QUrl::fromUserInput(url));
-}
-
-QScriptValue qDesktopServicesDisplayName(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
- const QStandardPaths::StandardLocation location =
- static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
- return QStandardPaths::displayName(location);
-}
-
-QScriptValue qDesktopServicesStorageLocation(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
- const QStandardPaths::StandardLocation location =
- static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
- return QStandardPaths::writableLocation(location);
-}
-
-QScriptValue qFileDialogGetExistingDirectory(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 0, 2);
- if (check.isError())
- return check;
- QString caption;
- QString dir;
- if (context->argumentCount() > 0)
- caption = context->argument(0).toString();
- if (context->argumentCount() > 1)
- dir = context->argument(1).toString();
- return QFileDialog::getExistingDirectory(0, caption, dir);
-}
-
-QScriptValue qFileDialogGetOpenFileName(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 0, 3);
- if (check.isError())
- return check;
- QString caption;
- QString dir;
- QString fileNameFilter;
- if (context->argumentCount() > 0)
- caption = context->argument(0).toString();
- if (context->argumentCount() > 1)
- dir = context->argument(1).toString();
- if (context->argumentCount() > 2)
- fileNameFilter = context->argument(2).toString();
- return QFileDialog::getOpenFileName(0, caption, dir, fileNameFilter);
-}
-
-} //namespace QInstaller
-
-
/*!
\class QInstaller::ScriptEngine
prepare and run the component scripts
*/
ScriptEngine::ScriptEngine(PackageManagerCore *core)
- : QScriptEngine(core)
- , m_core(core)
+ : QObject(core)
{
- // register translation stuff
- installTranslatorFunctions();
-
- globalObject().setProperty(QLatin1String("QMessageBox"), generateMessageBoxObject());
- globalObject().setProperty(QLatin1String("buttons"), generateWizardButtonsObject());
- globalObject().setProperty(QLatin1String("QDesktopServices"), generateDesktopServicesObject());
- globalObject().setProperty(QLatin1String("QInstaller"), generateQInstallerObject());
-
- QScriptValue installerObject = newQObject(m_core);
- installerObject.setProperty(QLatin1String("componentByName"), newFunction(qInstallerComponentByName, 1));
-
- globalObject().setProperty(QLatin1String("installer"), installerObject);
-
- QScriptValue fileDialog = newArray();
- fileDialog.setProperty(QLatin1String("getExistingDirectory"),
- newFunction(qFileDialogGetExistingDirectory));
- fileDialog.setProperty(QLatin1String("getOpenFileName"),
- newFunction(qFileDialogGetOpenFileName));
- globalObject().setProperty(QLatin1String("QFileDialog"), fileDialog);
-
- const QList<Component*> components = m_core->availableComponents();
- QScriptValue scriptComponentsObject = newArray(components.count());
- for (int i = 0; i < components.count(); ++i)
- scriptComponentsObject.setProperty(i, newQObject(components[i]));
-
- globalObject().property(QLatin1String("installer"))
- .setProperty(QLatin1String("components"), scriptComponentsObject);
-
- connect(this, SIGNAL(signalHandlerException(QScriptValue)), SLOT(handleException(QScriptValue)));
+ QJSValue global = m_engine.globalObject();
+ global.setProperty(QLatin1String("console"), m_engine.newQObject(new ConsoleProxy));
+ global.setProperty(QLatin1String("QFileDialog"), m_engine.newQObject(new QFileDialogProxy));
+ const QJSValue proxy = m_engine.newQObject(new InstallerProxy(&m_engine, core));
+ global.setProperty(QLatin1String("InstallerProxy"), proxy);
+ global.setProperty(QLatin1String("print"), m_engine.newQObject(new ConsoleProxy)
+ .property(QLatin1String("log")));
+
+ global.setProperty(QLatin1String("QInstaller"), generateQInstallerObject());
+ global.setProperty(QLatin1String("buttons"), generateWizardButtonsObject());
+ global.setProperty(QLatin1String("QMessageBox"), generateMessageBoxObject());
+ global.setProperty(QLatin1String("QDesktopServices"), generateDesktopServicesObject());
+
+ if (core) {
+ setGuiQObject(core->guiObject());
+ QQmlEngine::setObjectOwnership(core, QQmlEngine::CppOwnership);
+ global.setProperty(QLatin1String("installer"), m_engine.newQObject(core));
+ connect(core, SIGNAL(guiObjectChanged(QObject*)), this, SLOT(setGuiQObject(QObject*)));
+
+ const QList<Component*> components = core->availableComponents();
+ QJSValue scriptComponentsObject = m_engine.newArray(components.count());
+ for (int i = 0; i < components.count(); ++i)
+ scriptComponentsObject.setProperty(i, newQObject(components[i]));
+ global.property(QLatin1String("installer")).setProperty(QLatin1String("components"),
+ scriptComponentsObject);
+ } else {
+ global.setProperty(QLatin1String("installer"), m_engine.newQObject(new QObject));
+ }
- connect(core, SIGNAL(guiObjectChanged(QObject*)), this, SLOT(setGuiQObject(QObject*)));
- setGuiQObject(core->guiObject());
+ global.property(QLatin1String("installer")).setProperty(QLatin1String("componentByName"),
+ proxy.property(QLatin1String("componentByName")));
}
-ScriptEngine::~ScriptEngine()
+QJSValue ScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber)
{
+ return m_engine.evaluate(program, fileName, lineNumber);
}
-void ScriptEngine::setGuiQObject(QObject *guiQObject)
+void ScriptEngine::addQObjectChildren(QObject *root)
{
- globalObject().setProperty(QLatin1String("gui"), newQObject(guiQObject));
+ if ((!root) || root->objectName().isEmpty())
+ return;
+
+ const QObjectList children = root->children();
+ QJSValue jsParent = newQObject(root);
+ m_engine.globalObject().setProperty(root->objectName(), jsParent);
+
+ foreach (QObject *const child, children) {
+ if (child->objectName().isEmpty())
+ continue;
+ jsParent.setProperty(child->objectName(), m_engine.newQObject(child));
+ addQObjectChildren(child);
+ }
}
/*!
Loads a script into the given \a context at \a fileName inside the ScriptEngine.
- The installer and all its components as well as other useful stuff are being exported into the script.
- Read \link componentscripting Component Scripting \endlink for details.
+ The installer and all its components as well as other useful stuff are being exported into the
+ script. Read \link componentscripting Component Scripting \endlink for details.
\throws Error when either the script at \a fileName couldn't be opened, or the QScriptEngine
couldn't evaluate the script.
*/
-QScriptValue ScriptEngine::loadInConext(const QString &context, const QString &fileName,
+QJSValue ScriptEngine::loadInContext(const QString &context, const QString &fileName,
const QString &scriptInjection)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested script file at %1: %2.").arg(
- fileName, file.errorString()));
+ throw Error(tr("Could not open the requested script file at %1: %2.")
+ .arg(fileName, file.errorString()));
}
// Create a closure. Put the content in the first line to keep line number order in case of an
@@ -248,149 +141,162 @@ QScriptValue ScriptEngine::loadInConext(const QString &context, const QString &f
" else"
" throw \"Missing Component constructor. Please check your script.\";"
"})();").arg(context);
- QScriptValue scriptContext = evaluate(scriptContent, fileName);
-
- if (hasUncaughtException()) {
- throw Error(tr("Exception while loading the component script: '%1'").arg(
- uncaughtExceptionString(this, QFileInfo(file).absoluteFilePath())));
- }
- if (!scriptContext.isValid()) {
- throw Error(tr("Could not load the component script inside a script context: '%1'").arg(
- QFileInfo(file).absoluteFilePath()));
+ QJSValue scriptContext = evaluate(scriptContent, fileName);
+ scriptContext.setProperty(QLatin1String("Uuid"), QUuid::createUuid().toString());
+ if (scriptContext.isError()) {
+ throw Error(tr("Exception while loading the component script '%1'. (%2)").arg(
+ QFileInfo(file).absoluteFilePath(), scriptContext.toString().isEmpty() ?
+ QString::fromLatin1("Unknown error.") : scriptContext.toString()));
}
return scriptContext;
}
-void ScriptEngine::handleException(const QScriptValue &value)
-{
- if (!value.engine())
- return;
- throw Error(uncaughtExceptionString(this, tr("Fatal error while evaluating a script.")));
-}
-
/*!
Tries to call the method with \a name within the script and returns the result. If the method
- doesn't exist, an invalid result is returned. If the method has an uncaught exception, its
- string representation is thrown as an Error exception.
+ doesn't exist or is not callable, an undefined result is returned. If the call to the method
+ succeeds and the return value is still undefined, a null value will be returned instead.
+ If the method call has an exception, its string representation is thrown as an Error exception.
\note The method is not called, if the current script context is the same method, to avoid
infinite recursion.
*/
-QScriptValue ScriptEngine::callScriptMethod(const QScriptValue &scriptContext,
- const QString &methodName, const QScriptValueList &arguments) const
+QJSValue ScriptEngine::callScriptMethod(const QJSValue &scriptContext, const QString &methodName,
+ const QJSValueList &arguments)
{
- // don't allow such a recursion
- if (currentContext()->backtrace().first().startsWith(methodName))
- return QScriptValue();
+ // don't allow a recursion
+ const QString key = scriptContext.property(QLatin1String("Uuid")).toString();
+ QStringList stack = m_callstack.value(key);
+ if (m_callstack.contains(key) && stack.value(stack.size() - 1).startsWith(methodName))
+ return QJSValue(QJSValue::UndefinedValue);
+
+ stack.append(methodName);
+ m_callstack.insert(key, stack);
+
+ QJSValue method = scriptContext.property(methodName);
+ if (!method.isCallable())
+ return QJSValue(QJSValue::UndefinedValue);
+ if (method.isError()) {
+ throw Error(method.toString().isEmpty() ? QString::fromLatin1("Unknown error.")
+ : method.toString());
+ }
+
+ const QJSValue result = method.call(arguments);
+ if (result.isError()) {
+ throw Error(result.toString().isEmpty() ? QString::fromLatin1("Unknown error.")
+ : result.toString());
+ }
- QScriptValue method = scriptContext.property(methodName);
- // this marks the method to be called not any longer
- if (!method.isValid())
- return QScriptValue();
+ stack.removeLast();
+ m_callstack.insert(key, stack);
+ return result.isUndefined() ? QJSValue(QJSValue::NullValue) : result;
+}
- const QScriptValue result = method.call(scriptContext, arguments);
- if (!result.isValid())
- return result;
- if (hasUncaughtException())
- throw Error(uncaughtExceptionString(this));
+// -- private slots
- return result;
+void ScriptEngine::setGuiQObject(QObject *guiQObject)
+{
+ QQmlEngine::setObjectOwnership(guiQObject, QQmlEngine::CppOwnership);
+ m_engine.globalObject().setProperty(QLatin1String("gui"), m_engine.newQObject(guiQObject));
}
-QScriptValue ScriptEngine::generateWizardButtonsObject()
+// -- private
+
+#undef SETPROPERTY
+#define SETPROPERTY(a, x, t) a.setProperty(QLatin1String(#x), QJSValue(t::x));
+
+QJSValue ScriptEngine::generateWizardButtonsObject()
{
-#undef REGISTER_BUTTON
-#define REGISTER_BUTTON(x) buttons.setProperty(QLatin1String(#x), \
- newVariant(static_cast<int>(QWizard::x)));
-
- QScriptValue buttons = newArray();
- REGISTER_BUTTON(BackButton)
- REGISTER_BUTTON(NextButton)
- REGISTER_BUTTON(CommitButton)
- REGISTER_BUTTON(FinishButton)
- REGISTER_BUTTON(CancelButton)
- REGISTER_BUTTON(HelpButton)
- REGISTER_BUTTON(CustomButton1)
- REGISTER_BUTTON(CustomButton2)
- REGISTER_BUTTON(CustomButton3)
-
-#undef REGISTER_BUTTON
+ QJSValue buttons = m_engine.newArray();
+ SETPROPERTY(buttons, BackButton, QWizard)
+ SETPROPERTY(buttons, NextButton, QWizard)
+ SETPROPERTY(buttons, CommitButton, QWizard)
+ SETPROPERTY(buttons, FinishButton, QWizard)
+ SETPROPERTY(buttons, CancelButton, QWizard)
+ SETPROPERTY(buttons, HelpButton, QWizard)
+ SETPROPERTY(buttons, CustomButton1, QWizard)
+ SETPROPERTY(buttons, CustomButton2, QWizard)
+ SETPROPERTY(buttons, CustomButton3, QWizard)
return buttons;
}
/*!
generates QMessageBox::StandardButton enum as an QScriptValue array
*/
-QScriptValue ScriptEngine::generateMessageBoxObject()
+QJSValue ScriptEngine::generateMessageBoxObject()
{
- // register QMessageBox::StandardButton enum in the script connection
- QScriptValue messageBox = newQObject(MessageBoxHandler::instance());
+ QJSValue messageBox = m_engine.newQObject(MessageBoxHandler::instance());
const QMetaObject &messageBoxMetaObject = QMessageBox::staticMetaObject;
- int index = messageBoxMetaObject.indexOfEnumerator("StandardButtons");
+ const int index = messageBoxMetaObject.indexOfEnumerator("StandardButtons");
- QMetaEnum metaEnum = messageBoxMetaObject.enumerator(index);
+ QJSValue value = m_engine.newArray();
+ value.setProperty(QLatin1String("NoButton"), QJSValue(QMessageBox::NoButton));
+
+ const QMetaEnum metaEnum = messageBoxMetaObject.enumerator(index);
for (int i = 0; i < metaEnum.keyCount(); i++) {
- int enumValue = metaEnum.value(i);
- if (enumValue < QMessageBox::FirstButton)
- continue;
- messageBox.setProperty(QLatin1String(metaEnum.valueToKey(metaEnum.value(i))), newVariant(enumValue));
+ const int enumValue = metaEnum.value(i);
+ if (enumValue >= QMessageBox::FirstButton)
+ value.setProperty(QLatin1String(metaEnum.valueToKey(enumValue)), QJSValue(enumValue));
if (enumValue == QMessageBox::LastButton)
break;
}
+ messageBox.setPrototype(value);
return messageBox;
}
-QScriptValue ScriptEngine::generateDesktopServicesObject()
+QJSValue ScriptEngine::generateDesktopServicesObject()
{
- QScriptValue desktopServices = newArray();
- desktopServices.setProperty(QLatin1String("DesktopLocation"), QStandardPaths::DesktopLocation);
- desktopServices.setProperty(QLatin1String("DesktopLocation"), QStandardPaths::DesktopLocation);
- desktopServices.setProperty(QLatin1String("DocumentsLocation"), QStandardPaths::DocumentsLocation);
- desktopServices.setProperty(QLatin1String("FontsLocation"), QStandardPaths::FontsLocation);
- desktopServices.setProperty(QLatin1String("ApplicationsLocation"), QStandardPaths::ApplicationsLocation);
- desktopServices.setProperty(QLatin1String("MusicLocation"), QStandardPaths::MusicLocation);
- desktopServices.setProperty(QLatin1String("MoviesLocation"), QStandardPaths::MoviesLocation);
- desktopServices.setProperty(QLatin1String("PicturesLocation"), QStandardPaths::PicturesLocation);
- desktopServices.setProperty(QLatin1String("TempLocation"), QStandardPaths::TempLocation);
- desktopServices.setProperty(QLatin1String("HomeLocation"), QStandardPaths::HomeLocation);
- desktopServices.setProperty(QLatin1String("DataLocation"), QStandardPaths::DataLocation);
- desktopServices.setProperty(QLatin1String("CacheLocation"), QStandardPaths::CacheLocation);
-
- desktopServices.setProperty(QLatin1String("openUrl"),
- newFunction(qDesktopServicesOpenUrl));
- desktopServices.setProperty(QLatin1String("displayName"),
- newFunction(qDesktopServicesDisplayName));
- desktopServices.setProperty(QLatin1String("storageLocation"),
- newFunction(qDesktopServicesStorageLocation));
- return desktopServices;
+ QJSValue desktopServices = m_engine.newArray();
+ SETPROPERTY(desktopServices, DesktopLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, DocumentsLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, FontsLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, ApplicationsLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, MusicLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, MoviesLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, PicturesLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, TempLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, HomeLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, DataLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, CacheLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, GenericDataLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, RuntimeLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, ConfigLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, DownloadLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, GenericCacheLocation, QStandardPaths)
+ SETPROPERTY(desktopServices, GenericConfigLocation, QStandardPaths)
+
+ QJSValue object = m_engine.newQObject(new QDesktopServicesProxy);
+ object.setPrototype(desktopServices); // attach the properties
+ return object;
}
-QScriptValue ScriptEngine::generateQInstallerObject()
+QJSValue ScriptEngine::generateQInstallerObject()
{
// register ::WizardPage enum in the script connection
- QScriptValue qinstaller = newArray();
- qinstaller.setProperty(QLatin1String("Introduction"), PackageManagerCore::Introduction);
- qinstaller.setProperty(QLatin1String("LicenseCheck"), PackageManagerCore::LicenseCheck);
- qinstaller.setProperty(QLatin1String("TargetDirectory"), PackageManagerCore::TargetDirectory);
- qinstaller.setProperty(QLatin1String("ComponentSelection"), PackageManagerCore::ComponentSelection);
- qinstaller.setProperty(QLatin1String("StartMenuSelection"), PackageManagerCore::StartMenuSelection);
- qinstaller.setProperty(QLatin1String("ReadyForInstallation"), PackageManagerCore::ReadyForInstallation);
- qinstaller.setProperty(QLatin1String("PerformInstallation"), PackageManagerCore::PerformInstallation);
- qinstaller.setProperty(QLatin1String("InstallationFinished"), PackageManagerCore::InstallationFinished);
- qinstaller.setProperty(QLatin1String("End"), PackageManagerCore::End);
+ QJSValue qinstaller = m_engine.newArray();
+ SETPROPERTY(qinstaller, Introduction, PackageManagerCore)
+ SETPROPERTY(qinstaller, LicenseCheck, PackageManagerCore)
+ SETPROPERTY(qinstaller, TargetDirectory, PackageManagerCore)
+ SETPROPERTY(qinstaller, ComponentSelection, PackageManagerCore)
+ SETPROPERTY(qinstaller, StartMenuSelection, PackageManagerCore)
+ SETPROPERTY(qinstaller, ReadyForInstallation, PackageManagerCore)
+ SETPROPERTY(qinstaller, PerformInstallation, PackageManagerCore)
+ SETPROPERTY(qinstaller, InstallationFinished, PackageManagerCore)
+ SETPROPERTY(qinstaller, End, PackageManagerCore)
// register ::Status enum in the script connection
- qinstaller.setProperty(QLatin1String("Success"), PackageManagerCore::Success);
- qinstaller.setProperty(QLatin1String("Failure"), PackageManagerCore::Failure);
- qinstaller.setProperty(QLatin1String("Running"), PackageManagerCore::Running);
- qinstaller.setProperty(QLatin1String("Canceled"), PackageManagerCore::Canceled);
- qinstaller.setProperty(QLatin1String("Unfinished"), PackageManagerCore::Unfinished);
- qinstaller.setProperty(QLatin1String("ForceUpdate"), PackageManagerCore::ForceUpdate);
-
+ SETPROPERTY(qinstaller, Success, PackageManagerCore)
+ SETPROPERTY(qinstaller, Failure, PackageManagerCore)
+ SETPROPERTY(qinstaller, Running, PackageManagerCore)
+ SETPROPERTY(qinstaller, Canceled, PackageManagerCore)
+ SETPROPERTY(qinstaller, Unfinished, PackageManagerCore)
+ SETPROPERTY(qinstaller, ForceUpdate, PackageManagerCore)
return qinstaller;
}
+#undef SETPROPERTY
+
+} // namespace QInstaller
diff --git a/src/libs/installer/scriptengine.h b/src/libs/installer/scriptengine.h
index e52862e06..0c5a70bfa 100644
--- a/src/libs/installer/scriptengine.h
+++ b/src/libs/installer/scriptengine.h
@@ -44,46 +44,47 @@
#include "qinstallerglobal.h"
-#include <QtScript/QScriptEngine>
+#include <QJSValue>
+#include <QJSEngine>
namespace QInstaller {
-QString INSTALLER_EXPORT uncaughtExceptionString(const QScriptEngine *scriptEngine, const QString &context = QString());
-QScriptValue INSTALLER_EXPORT qInstallerComponentByName(QScriptContext *context, QScriptEngine *engine);
-
-QScriptValue INSTALLER_EXPORT qDesktopServicesOpenUrl(QScriptContext *context, QScriptEngine *engine);
-QScriptValue INSTALLER_EXPORT qDesktopServicesDisplayName(QScriptContext *context, QScriptEngine *engine);
-QScriptValue INSTALLER_EXPORT qDesktopServicesStorageLocation(QScriptContext *context, QScriptEngine *engine);
-
-QScriptValue INSTALLER_EXPORT qFileDialogGetExistingDirectory(QScriptContext *context, QScriptEngine *engine);
-QScriptValue INSTALLER_EXPORT qFileDialogGetOpenFileName(QScriptContext *context, QScriptEngine *engine);
-
-QScriptValue INSTALLER_EXPORT checkArguments(QScriptContext *context, int minimalArgumentCount, int maximalArgumentCount);
-
class PackageManagerCore;
-class INSTALLER_EXPORT ScriptEngine : public QScriptEngine
+class INSTALLER_EXPORT ScriptEngine : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(ScriptEngine)
public:
- explicit ScriptEngine(PackageManagerCore *core);
- ~ScriptEngine();
- QScriptValue callScriptMethod(const QScriptValue &scriptContext, const QString &methodName,
- const QScriptValueList &arguments = QScriptValueList()) const;
+ explicit ScriptEngine(PackageManagerCore *core = 0);
+
+ QJSValue globalObject() const { return m_engine.globalObject(); }
+ QJSValue newQObject(QObject *object) { return m_engine.newQObject(object); }
+ QJSValue evaluate(const QString &program, const QString &fileName = QString(),
+ int lineNumber = 1);
+
+ void addQObjectChildren(QObject *root);
+ QJSValue loadInContext(const QString &context, const QString &fileName,
+ const QString &scriptInjection = QString());
+ QJSValue callScriptMethod(const QJSValue &context, const QString &methodName,
+ const QJSValueList &arguments = QJSValueList());
- QScriptValue loadInConext(const QString &context, const QString &fileName, const QString &scriptInjection = QString());
private slots:
- void handleException(const QScriptValue &value);
void setGuiQObject(QObject *guiQObject);
+
private:
- QScriptValue generateWizardButtonsObject();
- QScriptValue generateMessageBoxObject();
- QScriptValue generateDesktopServicesObject();
- QScriptValue generateQInstallerObject();
- PackageManagerCore *m_core;
+ QJSValue generateMessageBoxObject();
+ QJSValue generateQInstallerObject();
+ QJSValue generateWizardButtonsObject();
+ QJSValue generateDesktopServicesObject();
+
+private:
+ QJSEngine m_engine;
+ QHash<QString, QStringList> m_callstack;
};
+
}
+Q_DECLARE_METATYPE(QInstaller::ScriptEngine*)
#endif // SCRIPTENGINE_H
diff --git a/src/libs/installer/scriptengine_p.h b/src/libs/installer/scriptengine_p.h
new file mode 100644
index 000000000..72cf1aa74
--- /dev/null
+++ b/src/libs/installer/scriptengine_p.h
@@ -0,0 +1,127 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef SCRIPTENGINE_P_H
+#define SCRIPTENGINE_P_H
+
+#include "component.h"
+#include "packagemanagercore.h"
+
+#include <QDebug>
+#include <QDesktopServices>
+#include <QFileDialog>
+#include <QJSEngine>
+#include <QStandardPaths>
+
+namespace QInstaller {
+
+class ConsoleProxy : public QObject
+{
+ Q_OBJECT
+public:
+ ConsoleProxy() {}
+
+public slots :
+ void log(const QString &log) { qDebug() << log; }
+};
+
+class InstallerProxy : public QObject
+{
+ Q_OBJECT
+public:
+ InstallerProxy(QJSEngine *engine, PackageManagerCore *core)
+ : m_engine(engine), m_core(core) {}
+
+public slots :
+ QJSValue componentByName(const QString &componentName) {
+ if (m_core)
+ return m_engine->newQObject(m_core->componentByName(componentName));
+ return QJSValue();
+ }
+
+private:
+ QJSEngine *m_engine;
+ PackageManagerCore *m_core;
+};
+
+class QFileDialogProxy : public QObject
+{
+ Q_OBJECT
+public:
+ QFileDialogProxy() {}
+
+public slots :
+ QString getExistingDirectory(const QString &caption, const QString &dir) const {
+ return QFileDialog::getExistingDirectory(0, caption, dir);
+ }
+ QString getOpenFileName(const QString &caption, const QString &dir, const QString &filter) const {
+ return QFileDialog::getOpenFileName(0, caption, dir, filter);
+ }
+};
+
+class QDesktopServicesProxy : public QObject
+{
+ Q_OBJECT
+public:
+ QDesktopServicesProxy() {}
+
+public slots :
+ bool openUrl(const QString &url) const {
+ QString urlToOpen = url;
+ urlToOpen.replace(QLatin1String("\\\\"), QLatin1String("/"));
+ urlToOpen.replace(QLatin1String("\\"), QLatin1String("/"));
+ return QDesktopServices::openUrl(QUrl::fromUserInput(urlToOpen));
+ }
+ QString displayName(qint32 location) const {
+ return QStandardPaths::displayName(QStandardPaths::StandardLocation(location));
+ }
+ QString storageLocation(qint32 location) const {
+ return QStandardPaths::writableLocation(QStandardPaths::StandardLocation(location));
+ }
+};
+
+}
+Q_DECLARE_METATYPE(QInstaller::ConsoleProxy*)
+Q_DECLARE_METATYPE(QInstaller::InstallerProxy*)
+Q_DECLARE_METATYPE(QInstaller::QFileDialogProxy*)
+Q_DECLARE_METATYPE(QInstaller::QDesktopServicesProxy*)
+
+#endif // SCRIPTENGINE_H
diff --git a/src/sdk/sdk.pro b/src/sdk/sdk.pro
index 3cbc0347e..416892310 100644
--- a/src/sdk/sdk.pro
+++ b/src/sdk/sdk.pro
@@ -4,7 +4,7 @@ TARGET = installerbase
include(../../installerfw.pri)
-QT += network script xml widgets
+QT += network qml xml widgets
# add the minimal plugin in static build to be able to start the installer headless with:
# installer-binary -platform minimal
# using QT += qpa_minimal_plugin would result in a minimal only compiled version
diff --git a/tests/auto/installer/componentmodel/componentmodel.pro b/tests/auto/installer/componentmodel/componentmodel.pro
index 7e18ff1ba..431969578 100644
--- a/tests/auto/installer/componentmodel/componentmodel.pro
+++ b/tests/auto/installer/componentmodel/componentmodel.pro
@@ -1,7 +1,7 @@
include(../../qttest.pri)
QT -= gui
-QT += network xml script
+QT += network xml qml
SOURCES += tst_componentmodel.cpp
diff --git a/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro b/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro
index a6fbc60f9..3eacd46ac 100644
--- a/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro
+++ b/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro
@@ -1,7 +1,7 @@
include(../../qttest.pri)
QT -= gui
-QT += testlib
+QT += testlib qml
SOURCES = tst_consumeoutputoperationtest.cpp
diff --git a/tests/auto/installer/fakestopprocessforupdateoperation/fakestopprocessforupdateoperation.pro b/tests/auto/installer/fakestopprocessforupdateoperation/fakestopprocessforupdateoperation.pro
index 871b668b2..0c1e6bdfa 100644
--- a/tests/auto/installer/fakestopprocessforupdateoperation/fakestopprocessforupdateoperation.pro
+++ b/tests/auto/installer/fakestopprocessforupdateoperation/fakestopprocessforupdateoperation.pro
@@ -1,6 +1,6 @@
include(../../qttest.pri)
QT -= gui
-QT += network script
+QT += network qml
SOURCES += tst_fakestopprocessforupdateoperation.cpp
diff --git a/tests/auto/installer/messageboxhandler/messageboxhandler.pro b/tests/auto/installer/messageboxhandler/messageboxhandler.pro
index 619668315..c63b2e35b 100644
--- a/tests/auto/installer/messageboxhandler/messageboxhandler.pro
+++ b/tests/auto/installer/messageboxhandler/messageboxhandler.pro
@@ -1,5 +1,5 @@
include(../../qttest.pri)
-QT += script widgets
+QT += qml widgets
SOURCES += tst_messageboxhandler.cpp
diff --git a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp
index 604b8e0a0..75df29949 100644
--- a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp
+++ b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp
@@ -5,7 +5,6 @@
#include <QTest>
#include <QMetaEnum>
-#include <QScriptEngine>
#include <QDebug>
#include <stdlib.h> /* srand, rand */
@@ -50,50 +49,42 @@ private slots:
void testScriptButtonValues()
{
PackageManagerCore core;
- ScriptEngine scriptEngine(&core);
+ ScriptEngine *scriptEngine = new ScriptEngine(&core);
QMapIterator<QMessageBox::StandardButton, QString> i(m_standardButtonValueMap);
while (i.hasNext()) {
i.next();
- QString scriptString = QString::fromLatin1("QMessageBox.%1").arg(i.value());
- QScriptValue scriptValue(scriptEngine.evaluate(scriptString));
+ const QString scriptString = QString::fromLatin1("QMessageBox.%1").arg(i.value());
+ const QJSValue scriptValue = scriptEngine->evaluate(scriptString);
+ QVERIFY2(!scriptValue.isError(), qPrintable(scriptValue.toString()));
QVERIFY2(!scriptValue.isUndefined(), qPrintable(
QString::fromLatin1("It seems that %1 is undefined.").arg(scriptString)));
-
- qint32 evaluatedValue = scriptValue.toInt32();
- QVERIFY2(!scriptEngine.hasUncaughtException(), qPrintable(
- QInstaller::uncaughtExceptionString(&scriptEngine)));
-
- QCOMPARE(static_cast<QMessageBox::StandardButton>(evaluatedValue), i.key());
+ QCOMPARE(static_cast<QMessageBox::StandardButton>(scriptValue.toInt()), i.key());
}
}
void testDefaultAction()
{
- int standardButtons = QMessageBox::NoButton;
- QList<QMessageBox::Button> orderedButtons = MessageBoxHandler::orderedButtons();
- MessageBoxHandler *messageBoxHandler = MessageBoxHandler::instance();
-
- messageBoxHandler->setDefaultAction(MessageBoxHandler::Reject);
- QString testidentifier(QLatin1String("TestError"));
- QString testTitle(QLatin1String("A test error"));
- QString testMessage(QLatin1String("This is a test error message."));
+ const char ignoreMessage[] = "\"created critical message box TestError: 'A test error', "
+ "This is a test error message.\" ";
+ srand(time(0)); /* initialize random seed: */
- const char *ignoreMessage("\"created critical message box TestError: 'A test error', This is a test error message.\" ");
- /* initialize random seed: */
- srand(time(0));
+ int standardButtons = QMessageBox::NoButton;
+ MessageBoxHandler::instance()->setDefaultAction(MessageBoxHandler::Reject);
+ const QList<QMessageBox::Button> orderedButtons = MessageBoxHandler::orderedButtons();
do {
standardButtons += QMessageBox::FirstButton;
/* generate secret number between 1 and 10: */
- int iSecret = rand() % 10 + 1;
+ const int iSecret = rand() % 10 + 1;
// use only every 5th run to reduce the time which it takes to run this test
if (iSecret > 2)
continue;
+
QTest::ignoreMessage(QtDebugMsg, ignoreMessage);
- const QMessageBox::StandardButton returnButton = static_cast<QMessageBox::StandardButton>(
- messageBoxHandler->critical(testidentifier, testTitle, testMessage,
- static_cast<QMessageBox::StandardButton>(standardButtons)));
+ int returnButton = MessageBoxHandler::instance()->critical(QLatin1String("TestError"),
+ QLatin1String("A test error"), QLatin1String("This is a test error message."),
+ static_cast<QMessageBox::StandardButton>(standardButtons));
QMessageBox::StandardButton wantedButton = QMessageBox::NoButton;
// find the last button which is the wanted reject button in the current
@@ -104,8 +95,7 @@ private slots:
}
QVERIFY2(wantedButton != QMessageBox::NoButton, "Could not find a wantedButton.");
- QCOMPARE(returnButton, wantedButton);
-
+ QCOMPARE(static_cast<QMessageBox::StandardButton>(returnButton), wantedButton);
} while (standardButtons < m_maxStandardButtons);
}
diff --git a/tests/auto/installer/packagemanagercore/packagemanagercore.pro b/tests/auto/installer/packagemanagercore/packagemanagercore.pro
index 34c3bd6ac..6e9e387fa 100644
--- a/tests/auto/installer/packagemanagercore/packagemanagercore.pro
+++ b/tests/auto/installer/packagemanagercore/packagemanagercore.pro
@@ -1,6 +1,6 @@
include(../../qttest.pri)
-QT += script
+QT += qml
SOURCES += tst_packagemanagercore.cpp
diff --git a/tests/auto/installer/scriptengine/scriptengine.pro b/tests/auto/installer/scriptengine/scriptengine.pro
index 72bb7028e..71d8196a1 100644
--- a/tests/auto/installer/scriptengine/scriptengine.pro
+++ b/tests/auto/installer/scriptengine/scriptengine.pro
@@ -1,6 +1,6 @@
include(../../qttest.pri)
-QT += script widgets
+QT += qml widgets
SOURCES += tst_scriptengine.cpp
diff --git a/tests/auto/installer/scriptengine/tst_scriptengine.cpp b/tests/auto/installer/scriptengine/tst_scriptengine.cpp
index 5c67afd0c..cc9f7aab7 100644
--- a/tests/auto/installer/scriptengine/tst_scriptengine.cpp
+++ b/tests/auto/installer/scriptengine/tst_scriptengine.cpp
@@ -70,108 +70,99 @@ private slots:
m_scriptEngine->globalObject().setProperty(QLatin1String("emiter"),
m_scriptEngine->newQObject(&emiter));
- QScriptValue context = m_scriptEngine->loadInConext(QLatin1String("BrokenConnect"),
+ QJSValue context = m_scriptEngine->loadInContext(QLatin1String("BrokenConnect"),
":///data/broken_connect.qs");
- QVERIFY(context.isValid());
-
- if (m_scriptEngine->hasUncaughtException()) {
- QFAIL(qPrintable(QString::fromLatin1("ScriptEngine hasUncaughtException:\n %1").arg(
- uncaughtExceptionString(m_scriptEngine))));
+ if (context.isError()) {
+ QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
+ context.toString())));
}
+ QCOMPARE(context.isError(), false);
- const QString debugMesssage(
- "create Error-Exception: \"Fatal error while evaluating a script.\n\n"
- "ReferenceError: Can't find variable: foo\n\n"
- "Backtrace:\n"
-#if QT_VERSION < 0x050000
- "\t<anonymous>()@:///data/broken_connect.qs:10\" ");
-#else
- "\treceive() at :///data/broken_connect.qs:10\n"
- "\t<global>() at -1\" ");
-#endif
- try {
- // ignore Output from script
- setExpectedScriptOutput("function receive()");
- setExpectedScriptOutput(qPrintable(debugMesssage));
- emiter.produceSignal();
- } catch (const Error &error) {
- QVERIFY2(debugMesssage.contains(error.message()), "There was some unexpected error.");
- }
+ // ignore Output from script
+ setExpectedScriptOutput("\"function receive()\"");
+
+ emiter.produceSignal();
+
+ const QJSValue value = m_scriptEngine->evaluate("");
+ QCOMPARE(value.isError(), true);
+ QCOMPARE(value.toString(), QLatin1String("ReferenceError: foo is not defined"));
}
void testScriptPrint()
{
- setExpectedScriptOutput("test");
- m_scriptEngine->evaluate("print(\"test\");");
- if (m_scriptEngine->hasUncaughtException()) {
- QFAIL(qPrintable(QString::fromLatin1("ScriptEngine hasUncaughtException:\n %1").arg(
- uncaughtExceptionString(m_scriptEngine))));
+ setExpectedScriptOutput("\"test\"");
+ const QJSValue value = m_scriptEngine->evaluate("print(\"test\");");
+ if (value.isError()) {
+ QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
+ value.toString())));
}
}
void testExistingInstallerObject()
{
- setExpectedScriptOutput("object");
- m_scriptEngine->evaluate("print(typeof installer)");
- if (m_scriptEngine->hasUncaughtException()) {
- QFAIL(qPrintable(QString::fromLatin1("ScriptEngine hasUncaughtException:\n %1").arg(
- uncaughtExceptionString(m_scriptEngine))));
+ setExpectedScriptOutput("\"object\"");
+ const QJSValue value = m_scriptEngine->evaluate("print(typeof installer)");
+ if (value.isError()) {
+ QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
+ value.toString())));
}
}
void testComponentByName()
{
- const QString printComponentNameScript = QString::fromLatin1("var correctComponent = "
- "installer.componentByName('%1');\nprint(correctComponent.name);").arg(m_component->name());
-
- setExpectedScriptOutput("component.test.name");
- m_scriptEngine->evaluate(printComponentNameScript);
- if (m_scriptEngine->hasUncaughtException()) {
- QFAIL(qPrintable(QString::fromLatin1("ScriptEngine hasUncaughtException:\n %1").arg(
- uncaughtExceptionString(m_scriptEngine))));
+ const QString script = QString::fromLatin1("var component = installer.componentByName('%1');"
+ "\n"
+ "print(component.name);").arg(m_component->name());
+
+ setExpectedScriptOutput("\"component.test.name\"");
+ const QJSValue value = m_scriptEngine->evaluate(script);
+ if (value.isError()) {
+ QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
+ value.toString())));
}
}
void testComponentByWrongName()
{
- const QString printComponentNameScript = QString::fromLatin1( "var brokenComponent = "
- "installer.componentByName('%1');\nprint(brokenComponent.name);").arg("MyNotExistingComponentName");
+ const QString script = QString::fromLatin1( "var component = installer.componentByName('%1');"
+ "\n"
+ "print(brokenComponent.name);").arg("NotExistingComponentName");
- m_scriptEngine->evaluate(printComponentNameScript);
- QVERIFY(m_scriptEngine->hasUncaughtException());
+ const QJSValue value = m_scriptEngine->evaluate(script);
+ QCOMPARE(value.isError(), true);
}
void loadSimpleComponentScript()
{
try {
// ignore retranslateUi which is called by loadComponentScript
- setExpectedScriptOutput("Component constructor - OK");
- setExpectedScriptOutput("retranslateUi - OK");
+ setExpectedScriptOutput("\"Component constructor - OK\"");
+ setExpectedScriptOutput("\"retranslateUi - OK\"");
m_component->loadComponentScript(":///data/component1.qs");
- setExpectedScriptOutput("retranslateUi - OK");
+ setExpectedScriptOutput("\"retranslateUi - OK\"");
m_component->languageChanged();
- setExpectedScriptOutput("createOperationsForPath - OK");
+ setExpectedScriptOutput("\"createOperationsForPath - OK\"");
m_component->createOperationsForPath(":///data/");
- setExpectedScriptOutput("createOperationsForArchive - OK");
+ setExpectedScriptOutput("\"createOperationsForArchive - OK\"");
// ignore createOperationsForPath which is called by createOperationsForArchive
- setExpectedScriptOutput("createOperationsForPath - OK");
+ setExpectedScriptOutput("\"createOperationsForPath - OK\"");
m_component->createOperationsForArchive("test.7z");
- setExpectedScriptOutput("beginInstallation - OK");
+ setExpectedScriptOutput("\"beginInstallation - OK\"");
m_component->beginInstallation();
- setExpectedScriptOutput("createOperations - OK");
+ setExpectedScriptOutput("\"createOperations - OK\"");
m_component->createOperations();
- setExpectedScriptOutput("isAutoDependOn - OK");
+ setExpectedScriptOutput("\"isAutoDependOn - OK\"");
bool returnIsAutoDependOn = m_component->isAutoDependOn(QSet<QString>());
QCOMPARE(returnIsAutoDependOn, false);
- setExpectedScriptOutput("isDefault - OK");
+ setExpectedScriptOutput("\"isDefault - OK\"");
bool returnIsDefault = m_component->isDefault();
QCOMPARE(returnIsDefault, false);
@@ -185,28 +176,19 @@ private slots:
Component *testComponent = new Component(&m_core);
testComponent->setValue(scName, "broken.component");
- // now m_core becomes the owner of testComponent
- // so it will delete it then at the destuctor
+ // m_core becomes the owner of testComponent, it will delete it in the destructor
m_core.appendRootComponent(testComponent);
const QString debugMesssage(
- "create Error-Exception: \"Exception while loading the component script: ':///data/component2.qs\n\n"
- "ReferenceError: Can't find variable: broken\n\n"
- "Backtrace:\n"
-#if QT_VERSION < 0x050000
- "\t<anonymous>()@:///data/component2.qs:5'\" ");
-#else
- "\tComponent() at :///data/component2.qs:5\n"
- "\t<anonymous>() at :///data/component2.qs:7\n"
- "\t<global>() at :///data/component2.qs:7'\" ");
-#endif
+ "create Error-Exception: \"Exception while loading the component script '"
+ ":///data/component2.qs'. (ReferenceError: broken is not defined)\"");
try {
// ignore Output from script
- setExpectedScriptOutput("script function: Component");
+ setExpectedScriptOutput("\"script function: Component\"");
setExpectedScriptOutput(qPrintable(debugMesssage));
testComponent->loadComponentScript(":///data/component2.qs");
} catch (const Error &error) {
- QVERIFY2(debugMesssage.contains(error.message()), "There was some unexpected error.");
+ QVERIFY2(debugMesssage.contains(error.message()), "(ReferenceError: broken is not defined)");
}
}
@@ -226,7 +208,7 @@ private slots:
QTest::ignoreMessage(QtWarningMsg, "Button with type: \"unknown button\" not found! ");
testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::ComponentSelection);
- setExpectedScriptOutput("FinishedPageCallback - OK");
+ setExpectedScriptOutput("\"FinishedPageCallback - OK\"");
testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::InstallationFinished);
} catch (const Error &error) {
QFAIL(qPrintable(error.message()));
diff --git a/tools/archivegen/archivegen.pro b/tools/archivegen/archivegen.pro
index 51bccb11b..135c34010 100644
--- a/tools/archivegen/archivegen.pro
+++ b/tools/archivegen/archivegen.pro
@@ -5,7 +5,7 @@ INCLUDEPATH += . .. ../common
include(../../installerfw.pri)
QT -= gui
-QT += script xml
+QT += qml xml
CONFIG += console
DESTDIR = $$IFW_APP_PATH
diff --git a/tools/binarycreator/binarycreator.pro b/tools/binarycreator/binarycreator.pro
index 88e3464d9..674fbdbe8 100644
--- a/tools/binarycreator/binarycreator.pro
+++ b/tools/binarycreator/binarycreator.pro
@@ -5,7 +5,7 @@ INCLUDEPATH += . .. rcc ../common
include(../../installerfw.pri)
QT -= gui
-QT += script xml
+QT += qml xml
CONFIG += console
DESTDIR = $$IFW_APP_PATH
diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp
index a5634f25f..b99b538f9 100644
--- a/tools/common/repositorygen.cpp
+++ b/tools/common/repositorygen.cpp
@@ -310,12 +310,12 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
foundDownloadableArchives |= scriptContent.contains(QLatin1String("addDownloadableArchive"))
|| scriptContent.contains(QLatin1String("removeDownloadableArchive"));
- static QScriptEngine testScriptEngine;
- testScriptEngine.evaluate(scriptContent, scriptFile.fileName());
- if (testScriptEngine.hasUncaughtException()) {
+ static QInstaller::ScriptEngine testScriptEngine;
+ const QJSValue value = testScriptEngine.evaluate(scriptContent, scriptFile.fileName());
+ if (value.isError()) {
throw QInstaller::Error(QString::fromLatin1("Exception while loading component "
- "script: '%1'").arg(QInstaller::uncaughtExceptionString(&testScriptEngine,
- scriptFile.fileName())));
+ "script: '%1'. (%2)").arg(scriptFile.fileName(), value.toString().isEmpty() ?
+ QString::fromLatin1("Unknown error.") : value.toString()));
}
// add RequiresAdminRights tag to xml if addElevatedOperation is used somewhere
diff --git a/tools/repogen/repogen.pro b/tools/repogen/repogen.pro
index 7fad2ad96..e6ee4476a 100644
--- a/tools/repogen/repogen.pro
+++ b/tools/repogen/repogen.pro
@@ -5,7 +5,7 @@ INCLUDEPATH += . .. ../common
include(../../installerfw.pri)
QT -= gui
-QT += script xml
+QT += qml xml
CONFIG += console
DESTDIR = $$IFW_APP_PATH