summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@digia.com>2013-05-08 13:26:41 +0200
committerTim Jenssen <tim.jenssen@digia.com>2013-05-16 16:12:52 +0200
commit06449248ab638d3ebb23f03e56450f10b4acbb5c (patch)
treea4fb331a237b6ad5bcf2857f75fe689b505386a5 /src/libs
parent89ee32bea7d9cdfb426d3400e940a6b006b2b2f7 (diff)
introduce installerscriptengine
- it uses one scriptengine for everything and adds the components or/and the install-controller in javascript closure contexts - added the gui object to the component script context - removed tabController from controlscript context Change-Id: I3bd6c5dcf470666c30add1b7d04a8fdd094f5f11 Reviewed-by: Iikka Eklund <iikka.eklund@digia.com> Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/component.cpp99
-rw-r--r--src/libs/installer/component.h5
-rw-r--r--src/libs/installer/component_p.cpp106
-rw-r--r--src/libs/installer/component_p.h16
-rw-r--r--src/libs/installer/installer.pro2
-rw-r--r--src/libs/installer/messageboxhandler.cpp27
-rw-r--r--src/libs/installer/messageboxhandler.h2
-rw-r--r--src/libs/installer/packagemanagercore.cpp115
-rw-r--r--src/libs/installer/packagemanagercore.h4
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp11
-rw-r--r--src/libs/installer/packagemanagercore_p.h3
-rw-r--r--src/libs/installer/packagemanagergui.cpp93
-rw-r--r--src/libs/installer/packagemanagergui.h2
-rw-r--r--src/libs/installer/qinstallerglobal.h15
-rw-r--r--src/libs/installer/scriptengine.cpp400
-rw-r--r--src/libs/installer/scriptengine.h87
16 files changed, 554 insertions, 433 deletions
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index d4a770640..36e1df7fe 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -39,6 +39,7 @@
**
**************************************************************************/
#include "component.h"
+#include "scriptengine.h"
#include "errors.h"
#include "fileutils.h"
@@ -468,11 +469,6 @@ QString Component::displayName() const
return d->m_vars.value(scDisplayName);
}
-QScriptEngine *Component::scriptEngine()
-{
- return d->scriptEngine();
-}
-
void Component::loadComponentScript()
{
const QString script = d->m_vars.value(scScript);
@@ -481,7 +477,7 @@ void Component::loadComponentScript()
}
/*!
- Loads the script at \a fileName into this component's script engine. The installer and all its
+ Loads the script at \a fileName into 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.
Throws an error when either the script at \a fileName couldn't be opened, or the QScriptEngine
@@ -489,42 +485,15 @@ void Component::loadComponentScript()
*/
void Component::loadComponentScript(const QString &fileName)
{
- 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()));
- }
+ ScriptEngine *scriptEngine = d->m_core->scriptEngine();
- d->scriptEngine()->evaluate(QLatin1String(file.readAll()), fileName);
- if (d->scriptEngine()->hasUncaughtException()) {
- throw Error(tr("Exception while loading the component script: %1")
- .arg(uncaughtExceptionString(d->scriptEngine()/*, QFileInfo(file).absoluteFilePath()*/)));
- }
-
- const QList<Component*> components = d->m_core->availableComponents();
- QScriptValue comps = d->scriptEngine()->newArray(components.count());
- for (int i = 0; i < components.count(); ++i)
- comps.setProperty(i, d->scriptEngine()->newQObject(components[i]));
+ QString scriptInjection(QString::fromLatin1(
+ "var component = installer.componentByName('%1');").arg(name()));
- d->scriptEngine()->globalObject().property(QLatin1String("installer"))
- .setProperty(QLatin1String("components"), comps);
-
- QScriptValue comp = d->scriptEngine()->evaluate(QLatin1String("Component"), fileName);
- if (!d->scriptEngine()->hasUncaughtException()) {
- d->m_scriptComponent = comp;
- d->m_scriptComponent.construct();
- }
-
- //evaluate("Component") and construct can have an exception
- if (d->scriptEngine()->hasUncaughtException()) {
- throw Error(tr("Exception while loading the component script: %1")
- .arg(uncaughtExceptionString(d->scriptEngine(), QFileInfo(file).absoluteFilePath())));
- }
+ d->m_scriptContext = scriptEngine->loadInConext(QLatin1String("Component"), fileName, scriptInjection);
emit loaded();
languageChanged();
-
- //Solves a freeze seen on updater/ package manger restart.
- QCoreApplication::processEvents();
}
/*!
@@ -534,39 +503,7 @@ void Component::loadComponentScript(const QString &fileName)
*/
void Component::languageChanged()
{
- callScriptMethod(QLatin1String("retranslateUi"));
-}
-
-/*!
- 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.
-
- \note The method is not called, if the current script context is the same method, to avoid
- infinite recursion.
-*/
-QScriptValue Component::callScriptMethod(const QString &methodName, const QScriptValueList &arguments) const
-{
- if (!d->m_unexistingScriptMethods.value(methodName, true))
- return QScriptValue();
-
- // don't allow such a recursion
- if (d->scriptEngine()->currentContext()->backtrace().first().startsWith(methodName))
- return QScriptValue();
-
- QScriptValue method = d->m_scriptComponent.property(QString::fromLatin1("prototype"))
- .property(methodName);
- if (!method.isValid()) // this marks the method to be called not any longer
- d->m_unexistingScriptMethods[methodName] = false;
-
- const QScriptValue result = method.call(d->m_scriptComponent, arguments);
- if (!result.isValid())
- return result;
-
- if (d->scriptEngine()->hasUncaughtException())
- throw Error(uncaughtExceptionString(d->scriptEngine()/*, name()*/));
-
- return result;
+ d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext, QLatin1String("retranslateUi"));
}
/*!
@@ -709,8 +646,10 @@ void Component::createOperationsForPath(const QString &path)
return;
// the script can override this method
- if (callScriptMethod(QLatin1String("createOperationsForPath"), QScriptValueList() << path).isValid())
+ if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("createOperationsForPath"), QScriptValueList() << path).isValid()) {
return;
+ }
QString target;
static const QString prefix = QString::fromLatin1("installer://");
@@ -752,8 +691,10 @@ void Component::createOperationsForArchive(const QString &archive)
return;
// the script can override this method
- if (callScriptMethod(QLatin1String("createOperationsForArchive"), QScriptValueList() << archive).isValid())
+ if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("createOperationsForArchive"), QScriptValueList() << archive).isValid()) {
return;
+ }
const bool isZip = Lib7z::isSupportedArchive(archive);
@@ -784,7 +725,8 @@ void Component::createOperationsForArchive(const QString &archive)
void Component::beginInstallation()
{
// the script can override this method
- if (callScriptMethod(QLatin1String("beginInstallation")).isValid()) {
+ if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("beginInstallation")).isValid()) {
return;
}
}
@@ -802,7 +744,8 @@ void Component::beginInstallation()
void Component::createOperations()
{
// the script can override this method
- if (callScriptMethod(QLatin1String("createOperations")).isValid()) {
+ if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("createOperations")).isValid()) {
d->m_operationsCreated = true;
return;
}
@@ -1160,7 +1103,7 @@ void Component::setValidatorCallbackName(const QString &name)
bool Component::validatePage()
{
if (!validatorCallbackName.isEmpty())
- return callScriptMethod(validatorCallbackName).toBool();
+ return d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext, validatorCallbackName).toBool();
return true;
}
@@ -1240,7 +1183,8 @@ bool Component::isAutoDependOn(const QSet<QString> &componentsToInstall) const
if (autoDependOnList.first().compare(QLatin1String("script"), Qt::CaseInsensitive) == 0) {
QScriptValue valueFromScript;
try {
- valueFromScript = callScriptMethod(QLatin1String("isAutoDependOn"));
+ valueFromScript = d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("isAutoDependOn"));
} catch (const Error &error) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("isAutoDependOnError"), tr("Can't resolve isAutoDependOn in %1"
@@ -1289,7 +1233,8 @@ bool Component::isDefault() const
if (d->m_vars.value(scDefault).compare(QLatin1String("script"), Qt::CaseInsensitive) == 0) {
QScriptValue valueFromScript;
try {
- valueFromScript = callScriptMethod(QLatin1String("isDefault"));
+ valueFromScript = d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ QLatin1String("isDefault"));
} catch (const Error &error) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("isDefaultError"), tr("Can't resolve isDefault in %1").arg(name()),
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index e55e7976c..bf5ef4d18 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -125,7 +125,6 @@ public:
void removeComponent(Component *component);
QList<Component*> childComponents(Component::Kind kind) const;
- QScriptEngine *scriptEngine();
void loadComponentScript();
//move this to private
@@ -228,10 +227,6 @@ Q_SIGNALS:
void selectedChanged(bool selected);
void valueChanged(const QString &key, const QString &value);
-protected:
- QScriptValue callScriptMethod(const QString &name,
- const QScriptValueList &parameters = QScriptValueList()) const;
-
private Q_SLOTS:
void updateModelData(const QString &key, const QString &value);
diff --git a/src/libs/installer/component_p.cpp b/src/libs/installer/component_p.cpp
index 621329b50..560cd6544 100644
--- a/src/libs/installer/component_p.cpp
+++ b/src/libs/installer/component_p.cpp
@@ -69,7 +69,6 @@ ComponentPrivate::ComponentPrivate(PackageManagerCore *core, Component *qq)
, m_autoCreateOperations(true)
, m_operationsCreatedSuccessfully(true)
, m_updateIsAvailable(false)
- , m_scriptEngine(0)
{
}
@@ -88,111 +87,6 @@ ComponentPrivate::~ComponentPrivate()
delete widget.data();
}
-QScriptEngine *ComponentPrivate::scriptEngine()
-{
- if (m_scriptEngine != 0)
- return m_scriptEngine;
-
-
- m_scriptEngine = new QScriptEngine(q);
-
- // register translation stuff
- m_scriptEngine->installTranslatorFunctions();
-
- // register QMessageBox::StandardButton enum in the script connection
- registerMessageBox(m_scriptEngine);
-
- // register ::WizardPage enum in the script connection
- QScriptValue qinstaller = m_scriptEngine->newArray();
- setProperty(qinstaller, QLatin1String("Introduction"), PackageManagerCore::Introduction);
- setProperty(qinstaller, QLatin1String("LicenseCheck"), PackageManagerCore::LicenseCheck);
- setProperty(qinstaller, QLatin1String("TargetDirectory"), PackageManagerCore::TargetDirectory);
- setProperty(qinstaller, QLatin1String("ComponentSelection"), PackageManagerCore::ComponentSelection);
- setProperty(qinstaller, QLatin1String("StartMenuSelection"), PackageManagerCore::StartMenuSelection);
- setProperty(qinstaller, QLatin1String("ReadyForInstallation"), PackageManagerCore::ReadyForInstallation);
- setProperty(qinstaller, QLatin1String("PerformInstallation"), PackageManagerCore::PerformInstallation);
- setProperty(qinstaller, QLatin1String("InstallationFinished"), PackageManagerCore::InstallationFinished);
- setProperty(qinstaller, QLatin1String("End"), PackageManagerCore::End);
-
- // register ::Status enum in the script connection
- setProperty(qinstaller, QLatin1String("Success"), PackageManagerCore::Success);
- setProperty(qinstaller, QLatin1String("Failure"), PackageManagerCore::Failure);
- setProperty(qinstaller, QLatin1String("Running"), PackageManagerCore::Running);
- setProperty(qinstaller, QLatin1String("Canceled"), PackageManagerCore::Canceled);
-
- // maybe used by old scripts
- setProperty(qinstaller, QLatin1String("InstallerFailed"), PackageManagerCore::Failure);
- setProperty(qinstaller, QLatin1String("InstallerSucceeded"), PackageManagerCore::Success);
- setProperty(qinstaller, QLatin1String("InstallerUnfinished"), PackageManagerCore::Unfinished);
- setProperty(qinstaller, QLatin1String("InstallerCanceledByUser"), PackageManagerCore::Canceled);
-
- QScriptValue installerObject = m_scriptEngine->newQObject(m_core);
- installerObject.setProperty(QLatin1String("componentByName"), m_scriptEngine
- ->newFunction(qInstallerComponentByName, 1));
-
- m_scriptEngine->globalObject().setProperty(QLatin1String("QInstaller"), qinstaller);
- m_scriptEngine->globalObject().setProperty(QLatin1String("installer"), installerObject);
-
- // register QDesktopServices in the script connection
- m_scriptEngine->globalObject().setProperty(QLatin1String("QDesktopServices"), getDesktopServices());
- m_scriptEngine->globalObject().setProperty(QLatin1String("component"), m_scriptEngine->newQObject(q));
-
- QScriptValue fileDialog = m_scriptEngine->newArray();
- fileDialog.setProperty(QLatin1String("getExistingDirectory"),
- m_scriptEngine->newFunction(qFileDialogGetExistingDirectory));
- m_scriptEngine->globalObject().setProperty(QLatin1String("QFileDialog"), fileDialog);
-
- return m_scriptEngine;
-}
-
-void ComponentPrivate::setProperty(QScriptValue &scriptValue, const QString &propertyName, int value)
-{
- scriptValue.setProperty(propertyName, m_scriptEngine->newVariant(value));
-}
-
-// -- private
-
-QScriptValue ComponentPrivate::getDesktopServices()
-{
- QScriptValue desktopServices = m_scriptEngine->newArray();
-#if QT_VERSION < 0x050000
- setProperty(desktopServices, QLatin1String("DesktopLocation"), QDesktopServices::DesktopLocation);
- setProperty(desktopServices, QLatin1String("DesktopLocation"), QDesktopServices::DesktopLocation);
- setProperty(desktopServices, QLatin1String("DocumentsLocation"), QDesktopServices::DocumentsLocation);
- setProperty(desktopServices, QLatin1String("FontsLocation"), QDesktopServices::FontsLocation);
- setProperty(desktopServices, QLatin1String("ApplicationsLocation"), QDesktopServices::ApplicationsLocation);
- setProperty(desktopServices, QLatin1String("MusicLocation"), QDesktopServices::MusicLocation);
- setProperty(desktopServices, QLatin1String("MoviesLocation"), QDesktopServices::MoviesLocation);
- setProperty(desktopServices, QLatin1String("PicturesLocation"), QDesktopServices::PicturesLocation);
- setProperty(desktopServices, QLatin1String("TempLocation"), QDesktopServices::TempLocation);
- setProperty(desktopServices, QLatin1String("HomeLocation"), QDesktopServices::HomeLocation);
- setProperty(desktopServices, QLatin1String("DataLocation"), QDesktopServices::DataLocation);
- setProperty(desktopServices, QLatin1String("CacheLocation"), QDesktopServices::CacheLocation);
-#else
- setProperty(desktopServices, QLatin1String("DesktopLocation"), QStandardPaths::DesktopLocation);
- setProperty(desktopServices, QLatin1String("DesktopLocation"), QStandardPaths::DesktopLocation);
- setProperty(desktopServices, QLatin1String("DocumentsLocation"), QStandardPaths::DocumentsLocation);
- setProperty(desktopServices, QLatin1String("FontsLocation"), QStandardPaths::FontsLocation);
- setProperty(desktopServices, QLatin1String("ApplicationsLocation"), QStandardPaths::ApplicationsLocation);
- setProperty(desktopServices, QLatin1String("MusicLocation"), QStandardPaths::MusicLocation);
- setProperty(desktopServices, QLatin1String("MoviesLocation"), QStandardPaths::MoviesLocation);
- setProperty(desktopServices, QLatin1String("PicturesLocation"), QStandardPaths::PicturesLocation);
- setProperty(desktopServices, QLatin1String("TempLocation"), QStandardPaths::TempLocation);
- setProperty(desktopServices, QLatin1String("HomeLocation"), QStandardPaths::HomeLocation);
- setProperty(desktopServices, QLatin1String("DataLocation"), QStandardPaths::DataLocation);
- setProperty(desktopServices, QLatin1String("CacheLocation"), QStandardPaths::CacheLocation);
-#endif
-
- desktopServices.setProperty(QLatin1String("openUrl"),
- m_scriptEngine->newFunction(qDesktopServicesOpenUrl));
- desktopServices.setProperty(QLatin1String("displayName"),
- m_scriptEngine->newFunction(qDesktopServicesDisplayName));
- desktopServices.setProperty(QLatin1String("storageLocation"),
- m_scriptEngine->newFunction(qDesktopServicesStorageLocation));
- return desktopServices;
-}
-
-
// -- ComponentModelHelper
ComponentModelHelper::ComponentModelHelper()
diff --git a/src/libs/installer/component_p.h b/src/libs/installer/component_p.h
index 9101021ae..1f81ffd4d 100644
--- a/src/libs/installer/component_p.h
+++ b/src/libs/installer/component_p.h
@@ -47,8 +47,7 @@
#include <QtCore/QPointer>
#include <QtCore/QStringList>
#include <QtCore/QUrl>
-
-#include <QtScript/QScriptEngine>
+#include <QScriptValue>
namespace QInstaller {
@@ -63,10 +62,6 @@ public:
explicit ComponentPrivate(PackageManagerCore *core, Component *qq);
~ComponentPrivate();
- QScriptEngine *scriptEngine();
-
- void setProperty(QScriptValue &scriptValue, const QString &propertyName, int value);
-
PackageManagerCore *m_core;
Component *m_parentComponent;
OperationList m_operations;
@@ -82,25 +77,18 @@ public:
QString m_componentName;
QUrl m_repositoryUrl;
QString m_localTempPath;
- QScriptValue m_scriptComponent;
+ QScriptValue m_scriptContext;
QHash<QString, QString> m_vars;
QList<Component*> m_childComponents;
QList<Component*> m_allChildComponents;
QList<Component*> m_virtualChildComponents;
QStringList m_downloadableArchives;
QStringList m_stopProcessForUpdateRequests;
- QHash<QString, bool> m_unexistingScriptMethods;
QHash<QString, QPointer<QWidget> > m_userInterfaces;
// < display name, < file name, file content > >
QHash<QString, QPair<QString, QString> > m_licenses;
QList<QPair<QString, bool> > m_pathesForUninstallation;
-
-private:
- QScriptValue getDesktopServices();
-
-private:
- QScriptEngine* m_scriptEngine;
};
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index 79500b2d5..6ce99ddc3 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -44,6 +44,7 @@ HEADERS += packagemanagercore.h \
utils.h \
errors.h \
component.h \
+ scriptengine.h \
componentmodel.h \
qinstallerglobal.h \
qtpatch.h \
@@ -118,6 +119,7 @@ HEADERS += packagemanagercore.h \
fileutils.cpp \
utils.cpp \
component.cpp \
+ scriptengine.cpp \
componentmodel.cpp \
qtpatch.cpp \
persistentsettings.cpp \
diff --git a/src/libs/installer/messageboxhandler.cpp b/src/libs/installer/messageboxhandler.cpp
index 9905e024d..69fc62570 100644
--- a/src/libs/installer/messageboxhandler.cpp
+++ b/src/libs/installer/messageboxhandler.cpp
@@ -47,10 +47,6 @@
#include <QDialogButtonBox>
#include <QPushButton>
-#include <QScriptEngine>
-#include <QScriptValue>
-#include <QMetaEnum>
-
/*!
\qmltype QMessageBox
\inqmlmodule scripting
@@ -134,29 +130,6 @@
Opens a warning message box with the given \a title and \a text.
*/
-QScriptValue QInstaller::registerMessageBox(QScriptEngine *scriptEngine)
-{
- // register QMessageBox::StandardButton enum in the script connection
- QScriptValue messageBox = scriptEngine->newQObject(MessageBoxHandler::instance());
-
- const QMetaObject &messageBoxMetaObject = QMessageBox::staticMetaObject;
- int index = messageBoxMetaObject.indexOfEnumerator("StandardButtons");
-
- 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(QString::fromLatin1(metaEnum.valueToKey(metaEnum.value(i))),
- scriptEngine->newVariant(enumValue));
- if (enumValue == QMessageBox::LastButton)
- break;
- }
- scriptEngine->globalObject().setProperty(QLatin1String("QMessageBox"), messageBox);
-
- return messageBox;
-}
-
using namespace QInstaller;
// -- MessageBoxHandler
diff --git a/src/libs/installer/messageboxhandler.h b/src/libs/installer/messageboxhandler.h
index ec4d96e0e..bc3edce3b 100644
--- a/src/libs/installer/messageboxhandler.h
+++ b/src/libs/installer/messageboxhandler.h
@@ -51,8 +51,6 @@
namespace QInstaller {
-QScriptValue INSTALLER_EXPORT registerMessageBox(QScriptEngine *scriptEngine);
-
class INSTALLER_EXPORT MessageBoxHandler : public QObject, private QScriptable
{
Q_OBJECT
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 60a89a536..d854b018a 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -71,9 +71,6 @@
#include <QDesktopServices>
#include <QFileDialog>
-#include <QtScript/QScriptEngine>
-#include <QtScript/QScriptContext>
-
#include "kdsysinfo.h"
#include "kdupdaterupdateoperationfactory.h"
@@ -352,20 +349,6 @@ static bool sNoForceInstallation = false;
static bool sVirtualComponentsVisible = false;
static bool sCreateLocalRepositoryFromBinary = false;
-static QScriptValue checkArguments(QScriptContext *context, int amin, int amax)
-{
- if (context->argumentCount() < amin || context->argumentCount() > amax) {
- if (amin != amax) {
- return context->throwError(QObject::tr("Invalid arguments: %1 arguments given, %2 to "
- "%3 expected.").arg(QString::number(context->argumentCount()),
- QString::number(amin), QString::number(amax)));
- }
- return context->throwError(QObject::tr("Invalid arguments: %1 arguments given, %2 expected.")
- .arg(QString::number(context->argumentCount()), QString::number(amin)));
- }
- return QScriptValue();
-}
-
static bool componentMatches(const Component *component, const QString &name,
const QString &version = QString())
{
@@ -411,97 +394,6 @@ Component *PackageManagerCore::subComponentByName(const QInstaller::PackageManag
return 0;
}
-/*!
- Scriptable version of PackageManagerCore::componentByName(QString).
- \sa PackageManagerCore::componentByName
- */
-QScriptValue QInstaller::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 = dynamic_cast<PackageManagerCore*>(engine->globalObject()
- .property(QLatin1String("installer")).toQObject());
-
- const QString name = context->argument(0).toString();
- return engine->newQObject(core->componentByName(name));
-}
-
-QScriptValue QInstaller::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 QInstaller::qDesktopServicesDisplayName(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
-#if QT_VERSION < 0x050000
- const QDesktopServices::StandardLocation location =
- static_cast< QDesktopServices::StandardLocation >(context->argument(0).toInt32());
- return QDesktopServices::displayName(location);
-#else
- const QStandardPaths::StandardLocation location =
- static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
- return QStandardPaths::displayName(location);
-#endif
-}
-
-QScriptValue QInstaller::qDesktopServicesStorageLocation(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
-#if QT_VERSION < 0x050000
- const QDesktopServices::StandardLocation location =
- static_cast< QDesktopServices::StandardLocation >(context->argument(0).toInt32());
- return QDesktopServices::storageLocation(location);
-#else
- const QStandardPaths::StandardLocation location =
- static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
- return QStandardPaths::writableLocation(location);
-#endif
-}
-
-QScriptValue QInstaller::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);
-}
-
-QString QInstaller::uncaughtExceptionString(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")));
-}
-
void PackageManagerCore::writeUninstaller()
{
if (d->m_needToWriteUninstaller) {
@@ -801,6 +693,8 @@ bool PackageManagerCore::fileExists(const QString &filePath) const
PackageManagerCore::PackageManagerCore()
: d(new PackageManagerCorePrivate(this))
{
+ qRegisterMetaType<QInstaller::PackageManagerCore::Status>("QInstaller::PackageManagerCore::Status");
+ qRegisterMetaType<QInstaller::PackageManagerCore::WizardPage>("QInstaller::PackageManagerCore::WizardPage");
}
PackageManagerCore::PackageManagerCore(qint64 magicmaker, const OperationList &performedOperations)
@@ -1162,6 +1056,11 @@ void PackageManagerCore::setTestChecksum(bool test)
d->m_testChecksum = test;
}
+ScriptEngine *PackageManagerCore::scriptEngine()
+{
+ return d->scriptEngine();
+}
+
/*!
Returns the number of components in the list for installer and package manager mode. Might return 0 in
case the engine has only been run in updater mode or no components have been fetched.
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index df77cd115..712a5174c 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -57,6 +57,7 @@ namespace QInstaller {
class Component;
class ComponentModel;
+class ScriptEngine;
class PackageManagerCorePrivate;
class Settings;
@@ -173,7 +174,10 @@ public:
Q_INVOKABLE bool fileExists(const QString &filePath) const;
public:
+ ScriptEngine *scriptEngine();
+
// component handling
+
int rootComponentCount() const;
Component *rootComponent(int i) const;
QList<Component*> rootComponents() const;
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index cd413c5b0..d643fd34d 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -43,6 +43,7 @@
#include "adminauthorization.h"
#include "binaryformat.h"
#include "component.h"
+#include "scriptengine.h"
#include "componentmodel.h"
#include "errors.h"
#include "fileutils.h"
@@ -209,6 +210,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
, m_repoFetched(false)
, m_updateSourcesAdded(false)
, m_componentsToInstallCalculated(false)
+ , m_scriptEngine(0)
, m_proxyFactory(0)
, m_defaultModel(0)
, m_updaterModel(0)
@@ -234,6 +236,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
, m_updateSourcesAdded(false)
, m_magicBinaryMarker(magicInstallerMaker)
, m_componentsToInstallCalculated(false)
+ , m_scriptEngine(0)
, m_proxyFactory(0)
, m_defaultModel(0)
, m_updaterModel(0)
@@ -259,6 +262,7 @@ PackageManagerCorePrivate::~PackageManagerCorePrivate()
m_FSEngineClientHandler->setActive(false);
delete m_updateFinder;
+ delete m_scriptEngine;
delete m_proxyFactory;
delete m_defaultModel;
@@ -385,6 +389,13 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
return true;
}
+ScriptEngine *PackageManagerCorePrivate::scriptEngine()
+{
+ if (!m_scriptEngine)
+ m_scriptEngine = new ScriptEngine(m_core);
+ return m_scriptEngine;
+}
+
void PackageManagerCorePrivate::clearAllComponentLists()
{
qDeleteAll(m_rootComponents);
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index e77bff18f..80815c252 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -65,6 +65,7 @@ namespace QInstaller {
struct BinaryLayout;
class Component;
+class ScriptEngine;
class ComponentModel;
class TempDirDeleter;
@@ -112,6 +113,7 @@ public:
bool buildComponentTree(QHash<QString, Component*> &components, bool loadScript);
+ ScriptEngine *scriptEngine();
void clearAllComponentLists();
void clearUpdaterComponentLists();
QList<Component*> &replacementDependencyComponents();
@@ -238,6 +240,7 @@ private:
qint64 m_magicBinaryMarker;
bool m_componentsToInstallCalculated;
+ ScriptEngine *m_scriptEngine;
// < name (component to replace), < replacement component, component to replace > >
QHash<QString, QPair<Component*, Component*> > m_componentsToReplaceAllMode;
QHash<QString, QPair<Component*, Component*> > m_componentsToReplaceUpdaterMode;
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 25b4cafac..fe6d8beab 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -50,6 +50,7 @@
#include "performinstallationform.h"
#include "settings.h"
#include "utils.h"
+#include "scriptengine.h"
#include "kdsysinfo.h"
@@ -84,8 +85,6 @@
#include <QScrollBar>
#include <QShowEvent>
-#include <QtScript/QScriptEngine>
-
using namespace KDUpdater;
using namespace QInstaller;
@@ -216,19 +215,13 @@ public:
QHash<int, QWizardPage*> m_defaultPages;
QHash<int, QString> m_defaultButtonText;
- QScriptValue m_controlScript;
- QScriptEngine m_controlScriptEngine;
+ QScriptValue m_controlScriptContext;
QHash<QWizard::WizardButton, QString> m_wizardButtonTypes;
};
// -- PackageManagerGui
-QScriptEngine *PackageManagerGui::controlScriptEngine() const
-{
- return &d->m_controlScriptEngine;
-}
-
/*!
\class QInstaller::PackageManagerGui
Is the "gui" object in a none interactive installation
@@ -292,6 +285,8 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent)
for (int i = QWizard::BackButton; i < QWizard::CustomButton1; ++i)
d->m_defaultButtonText.insert(i, buttonText(QWizard::WizardButton(i)));
+
+ m_core->scriptEngine()->setGuiQObject(this);
}
PackageManagerGui::~PackageManagerGui()
@@ -350,58 +345,8 @@ void PackageManagerGui::setValidatorForCustomPageRequested(Component *component,
*/
void PackageManagerGui::loadControlScript(const QString &scriptPath)
{
- QFile file(scriptPath);
- if (!file.open(QIODevice::ReadOnly)) {
- throw Error(QObject::tr("Could not open the requested script file at %1: %2")
- .arg(scriptPath, file.errorString()));
- }
-
- QScriptValue installerObject = d->m_controlScriptEngine.newQObject(m_core);
- installerObject.setProperty(QLatin1String("componentByName"), d->m_controlScriptEngine
- .newFunction(qInstallerComponentByName, 1));
-
- d->m_controlScriptEngine.globalObject().setProperty(QLatin1String("installer"),
- installerObject);
- d->m_controlScriptEngine.globalObject().setProperty(QLatin1String("gui"),
- d->m_controlScriptEngine.newQObject(this));
- d->m_controlScriptEngine.globalObject().setProperty(QLatin1String("packagemanagergui"),
- d->m_controlScriptEngine.newQObject(this));
- registerMessageBox(&d->m_controlScriptEngine);
-
-#undef REGISTER_BUTTON
-#define REGISTER_BUTTON(x) buttons.setProperty(QLatin1String(#x), \
- d->m_controlScriptEngine.newVariant(static_cast<int>(QWizard::x)));
-
- QScriptValue buttons = d->m_controlScriptEngine.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
-
- d->m_controlScriptEngine.globalObject().setProperty(QLatin1String("buttons"), buttons);
-
- d->m_controlScriptEngine.evaluate(QLatin1String(file.readAll()), scriptPath);
- if (d->m_controlScriptEngine.hasUncaughtException()) {
- throw Error(QObject::tr("Exception while loading the control script %1")
- .arg(uncaughtExceptionString(&(d->m_controlScriptEngine)/*, scriptPath*/)));
- }
-
- QScriptValue comp = d->m_controlScriptEngine.evaluate(QLatin1String("Controller"));
- if (d->m_controlScriptEngine.hasUncaughtException()) {
- throw Error(QObject::tr("Exception while loading the control script %1")
- .arg(uncaughtExceptionString(&(d->m_controlScriptEngine)/*, scriptPath*/)));
- }
-
- d->m_controlScript = comp;
- d->m_controlScript.construct();
-
+ d->m_controlScriptContext = m_core->scriptEngine()->loadInConext(
+ QLatin1String("Controller"), scriptPath);
qDebug() << "Loaded control script" << scriptPath;
}
@@ -413,24 +358,18 @@ void PackageManagerGui::slotCurrentPageChanged(int id)
void PackageManagerGui::callControlScriptMethod(const QString &methodName)
{
- if (!d->m_controlScript.isValid())
- return;
-
- QScriptValue method = d->m_controlScript.property(QLatin1String("prototype")).property(methodName);
-
- if (!method.isValid()) {
- qDebug() << "Control script callback" << methodName << "does not exist.";
+ if (!d->m_controlScriptContext.isValid())
return;
- }
-
- qDebug() << "Calling control script callback" << methodName;
-
- method.call(d->m_controlScript);
+ try {
+ QScriptValue returnValue = m_core->scriptEngine()->callScriptMethod(
+ d->m_controlScriptContext, methodName);
- if (d->m_controlScriptEngine.hasUncaughtException()) {
- qCritical()
- << uncaughtExceptionString(&(d->m_controlScriptEngine) /*, QLatin1String("control script")*/);
- // TODO: handle error
+ if (!returnValue.isValid()) {
+ qDebug() << "Control script callback" << methodName << "does not exist.";
+ return;
+ }
+ } catch (const QInstaller::Error &e) {
+ qCritical() << qPrintable(e.message());
}
}
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index 93ade1552..40b8bad7e 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -84,8 +84,6 @@ public:
void loadControlScript(const QString& scriptPath);
void callControlScriptMethod(const QString& methodName);
- QScriptEngine *controlScriptEngine() const;
-
Q_INVOKABLE PackageManagerPage* page(int pageId) const;
Q_INVOKABLE QWidget* pageWidgetByObjectName(const QString& name) const;
Q_INVOKABLE QWidget* currentPageWidget() const;
diff --git a/src/libs/installer/qinstallerglobal.h b/src/libs/installer/qinstallerglobal.h
index 7f0fbbbc0..427586266 100644
--- a/src/libs/installer/qinstallerglobal.h
+++ b/src/libs/installer/qinstallerglobal.h
@@ -48,13 +48,6 @@
#include <kdupdaterupdateoperation.h>
#include <kdupdaterpackagesinfo.h>
-QT_BEGIN_NAMESPACE
-class QScriptContext;
-class QScriptEngine;
-class QScriptValue;
-QT_END_NAMESPACE
-
-
namespace QInstaller {
enum INSTALLER_EXPORT JobError
@@ -78,14 +71,6 @@ typedef QList<QInstaller::Package*> PackagesList;
typedef KDUpdater::PackageInfo LocalPackage;
typedef QHash<QString, LocalPackage> LocalPackagesHash;
-QString INSTALLER_EXPORT uncaughtExceptionString(QScriptEngine *scriptEngine, const QString &context = QString());
-QScriptValue qInstallerComponentByName(QScriptContext *context, QScriptEngine *engine);
-
-QScriptValue qDesktopServicesOpenUrl(QScriptContext *context, QScriptEngine *engine);
-QScriptValue qDesktopServicesDisplayName(QScriptContext *context, QScriptEngine *engine);
-QScriptValue qDesktopServicesStorageLocation(QScriptContext *context, QScriptEngine *engine);
-QScriptValue qFileDialogGetExistingDirectory(QScriptContext *context, QScriptEngine *engine);
-
} // namespace QInstaller
#endif // QINSTALLER_GLOBAL_H
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
new file mode 100644
index 000000000..f7bb114f5
--- /dev/null
+++ b/src/libs/installer/scriptengine.cpp
@@ -0,0 +1,400 @@
+/**************************************************************************
+**
+** Copyright (C) 2012-2013 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$
+**
+**************************************************************************/
+#include "scriptengine.h"
+
+#include "component.h"
+#include "packagemanagercore.h"
+#include "messageboxhandler.h"
+#include "errors.h"
+
+#include <QDesktopServices>
+#include <QFileDialog>
+#include <QMetaEnum>
+#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 = dynamic_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;
+
+#if QT_VERSION < 0x050000
+ const QDesktopServices::StandardLocation location =
+ static_cast< QDesktopServices::StandardLocation >(context->argument(0).toInt32());
+ return QDesktopServices::displayName(location);
+#else
+ const QStandardPaths::StandardLocation location =
+ static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
+ return QStandardPaths::displayName(location);
+#endif
+}
+
+QScriptValue qDesktopServicesStorageLocation(QScriptContext *context, QScriptEngine *engine)
+{
+ Q_UNUSED(engine);
+ const QScriptValue check = checkArguments(context, 1, 1);
+ if (check.isError())
+ return check;
+
+#if QT_VERSION < 0x050000
+ const QDesktopServices::StandardLocation location =
+ static_cast< QDesktopServices::StandardLocation >(context->argument(0).toInt32());
+ return QDesktopServices::storageLocation(location);
+#else
+ const QStandardPaths::StandardLocation location =
+ static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
+ return QStandardPaths::writableLocation(location);
+#endif
+}
+
+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, 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);
+}
+
+} //namespace QInstaller
+
+
+/*!
+ \class QInstaller::ScriptEngine
+ prepare and run the component scripts
+*/
+ScriptEngine::ScriptEngine(PackageManagerCore *core)
+ : QScriptEngine(core)
+ , m_core(core)
+{
+ // register translation stuff
+ installTranslatorFunctions();
+
+ globalObject().setProperty(QLatin1String("QMessageBox"), generateMessageBoxObject());
+ 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));
+ 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);
+}
+
+ScriptEngine::~ScriptEngine()
+{
+}
+
+void ScriptEngine::setGuiQObject(QObject *guiQObject)
+{
+ if (qobject_cast<QWizard*>(guiQObject)) {
+#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
+ globalObject().setProperty(QLatin1String("buttons"), buttons);
+ }
+ globalObject().setProperty(QLatin1String("gui"), newQObject(guiQObject));
+}
+
+/*!
+ 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.
+ \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,
+ 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()));
+ }
+
+ // create inside closure in one line to keep linenumber in the right order
+ // which is used as a debug output in an exception case
+ QString scriptContent = QString::fromLatin1(
+ "(function() { %1 %2 ; return new %3; })();");
+
+ scriptContent = scriptContent.arg(scriptInjection);
+
+ // add file content to it
+ scriptContent = scriptContent.arg(QLatin1String(file.readAll()));
+ scriptContent = scriptContent.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()));
+ }
+ return scriptContext;
+}
+
+
+/*!
+ 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.
+
+ \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
+{
+ // don't allow such a recursion
+ if (currentContext()->backtrace().first().startsWith(methodName))
+ return QScriptValue();
+
+ QScriptValue method = scriptContext.property(methodName);
+ // this marks the method to be called not any longer
+ if (!method.isValid())
+ return QScriptValue();
+
+ const QScriptValue result = method.call(scriptContext, arguments);
+ if (!result.isValid())
+ return result;
+
+ if (hasUncaughtException())
+ throw Error(uncaughtExceptionString(this));
+
+ return result;
+}
+
+
+/*!
+ generates QMessageBox::StandardButton enum as an QScriptValue array
+*/
+QScriptValue ScriptEngine::generateMessageBoxObject()
+{
+ // register QMessageBox::StandardButton enum in the script connection
+ QScriptValue messageBox = newQObject(MessageBoxHandler::instance());
+
+ const QMetaObject &messageBoxMetaObject = QMessageBox::staticMetaObject;
+ int index = messageBoxMetaObject.indexOfEnumerator("StandardButtons");
+
+ 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));
+ if (enumValue == QMessageBox::LastButton)
+ break;
+ }
+
+ return messageBox;
+}
+
+QScriptValue ScriptEngine::generateDesktopServicesObject()
+{
+ QScriptValue desktopServices = newArray();
+#if QT_VERSION < 0x050000
+ desktopServices.setProperty(QLatin1String("DesktopLocation"), QDesktopServices::DesktopLocation);
+ desktopServices.setProperty(QLatin1String("DesktopLocation"), QDesktopServices::DesktopLocation);
+ desktopServices.setProperty(QLatin1String("DocumentsLocation"), QDesktopServices::DocumentsLocation);
+ desktopServices.setProperty(QLatin1String("FontsLocation"), QDesktopServices::FontsLocation);
+ desktopServices.setProperty(QLatin1String("ApplicationsLocation"), QDesktopServices::ApplicationsLocation);
+ desktopServices.setProperty(QLatin1String("MusicLocation"), QDesktopServices::MusicLocation);
+ desktopServices.setProperty(QLatin1String("MoviesLocation"), QDesktopServices::MoviesLocation);
+ desktopServices.setProperty(QLatin1String("PicturesLocation"), QDesktopServices::PicturesLocation);
+ desktopServices.setProperty(QLatin1String("TempLocation"), QDesktopServices::TempLocation);
+ desktopServices.setProperty(QLatin1String("HomeLocation"), QDesktopServices::HomeLocation);
+ desktopServices.setProperty(QLatin1String("DataLocation"), QDesktopServices::DataLocation);
+ desktopServices.setProperty(QLatin1String("CacheLocation"), QDesktopServices::CacheLocation);
+#else
+ 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);
+#endif
+
+ desktopServices.setProperty(QLatin1String("openUrl"),
+ newFunction(qDesktopServicesOpenUrl));
+ desktopServices.setProperty(QLatin1String("displayName"),
+ newFunction(qDesktopServicesDisplayName));
+ desktopServices.setProperty(QLatin1String("storageLocation"),
+ newFunction(qDesktopServicesStorageLocation));
+ return desktopServices;
+}
+
+QScriptValue 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);
+
+ // 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);
+
+ return qinstaller;
+}
+
diff --git a/src/libs/installer/scriptengine.h b/src/libs/installer/scriptengine.h
new file mode 100644
index 000000000..9c7d84fcf
--- /dev/null
+++ b/src/libs/installer/scriptengine.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+**
+** Copyright (C) 2012-2013 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_H
+#define SCRIPTENGINE_H
+
+#include "qinstallerglobal.h"
+
+#include <QtScript/QScriptEngine>
+
+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
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ScriptEngine)
+
+public:
+ explicit ScriptEngine(PackageManagerCore *core);
+ ~ScriptEngine();
+ void setGuiQObject(QObject *guiQObject);
+ QScriptValue callScriptMethod(const QScriptValue &scriptContext, const QString &name,
+ const QScriptValueList &parameters = QScriptValueList()) const;
+
+ QScriptValue loadInConext(const QString &context, const QString &fileName, const QString &scriptInjection = QString());
+
+private:
+ QScriptValue generateMessageBoxObject();
+ QScriptValue generateDesktopServicesObject();
+ QScriptValue generateQInstallerObject();
+ PackageManagerCore *m_core;
+};
+}
+
+#endif // SCRIPTENGINE_H