summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@theqtcompany.com>2015-06-23 14:01:14 +0200
committerAndy Shaw <andy.shaw@theqtcompany.com>2015-11-26 07:04:11 +0000
commiteb574d77b0ab9a92b61e7738d089cd4ea4304e51 (patch)
treea022863e1bd9cdf017743e4dbb39a43ddbefd1f9
parenta81f19295745d081306f9417d6c45fda252fcb89 (diff)
Use QQmlV4Function to correctly get empty parameters from script.
By using QQmlV4Function to get the parameters, empty strings passed are correctly kept as empty and not null. Task-number: QTIFW-724 Change-Id: I592e2230e574ba82e765bd0079964db29452b2e9 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r--doc/scripting-api/component.qdoc12
-rw-r--r--src/libs/installer/component.cpp80
-rw-r--r--src/libs/installer/component.h19
-rw-r--r--src/libs/installer/installer.pro3
-rw-r--r--tests/auto/installer/scriptengine/data/addOperation.qs53
-rw-r--r--tests/auto/installer/scriptengine/scriptengine.qrc1
-rw-r--r--tests/auto/installer/scriptengine/tst_scriptengine.cpp67
7 files changed, 177 insertions, 58 deletions
diff --git a/doc/scripting-api/component.qdoc b/doc/scripting-api/component.qdoc
index 8e38c7e92..aa986ff38 100644
--- a/doc/scripting-api/component.qdoc
+++ b/doc/scripting-api/component.qdoc
@@ -325,18 +325,6 @@
*/
/*!
- \qmlmethod boolean component::addOperation(string operation, string parameter1 = "", string parameter2 = "", ..., string parameter10 = "")
-
- Convenience method for calling addOperation(string, stringlist) with up to 10 arguments.
-*/
-
-/*!
- \qmlmethod boolean component::addElevatedOperation(string operation, string parameter1 = "", string parameter2 = "", ..., string parameter10 = "")
-
- Convenience method for calling addElevatedOperation(string, stringlist) with up to 10 arguments.
-*/
-
-/*!
\qmlmethod boolean component::addElevatedOperation(string operation, stringlist parameters)
Creates and adds an installation operation for \a operation. Add any number of parameters.
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index b49bfe3a4..f3ba9c63c 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -56,6 +56,10 @@
#include <QtUiTools/QUiLoader>
+#include <private/qv8engine_p.h>
+#include <private/qv4scopedvalue_p.h>
+#include <private/qv4global_p.h>
+
#include <algorithm>
using namespace QInstaller;
@@ -703,11 +707,11 @@ void Component::createOperationsForPath(const QString &path)
if (fi.isFile()) {
static const QString copy = QString::fromLatin1("Copy");
- addOperation(copy, fi.filePath(), target);
+ addOperation(copy, QStringList() << fi.filePath() << target);
} else if (fi.isDir()) {
qApp->processEvents();
static const QString mkdir = QString::fromLatin1("Mkdir");
- addOperation(mkdir, target);
+ addOperation(mkdir, QStringList(target));
QDirIterator it(fi.filePath());
while (it.hasNext())
@@ -747,7 +751,7 @@ void Component::createOperationsForArchive(const QString &archive)
if (isZip) {
// archives get completely extracted per default (if the script isn't doing other stuff)
- addOperation(QLatin1String("Extract"), archive, QLatin1String("@TargetDir@"));
+ addOperation(QLatin1String("Extract"), QStringList() << archive << QLatin1String("@TargetDir@"));
} else {
createOperationsForPath(archive);
}
@@ -1009,23 +1013,44 @@ Operation *Component::createOperation(const QString &operationName, const QStrin
return operation;
}
-/*!
- Convenience method for calling the operation \a operation with up to ten parameters:
- \a parameter1, \a parameter2, \a parameter3, \a parameter4, \a parameter5, \a parameter6,
- \a parameter7, \a parameter8, \a parameter9, and \a parameter10.
+namespace {
- \sa {component::addOperation}{component.addOperation}
-*/
-bool Component::addOperation(const QString &operation, const QString &parameter1, const QString &parameter2,
- const QString &parameter3, const QString &parameter4, const QString &parameter5, const QString &parameter6,
- const QString &parameter7, const QString &parameter8, const QString &parameter9, const QString &parameter10)
+inline bool convert(QQmlV4Function *func, QStringList *toArgs)
{
- if (Operation *op = createOperation(operation, parameter1, parameter2, parameter3, parameter4, parameter5,
- parameter6, parameter7, parameter8, parameter9, parameter10)) {
- addOperation(op);
- return true;
+ if (func->length() < 2)
+ return false;
+
+ QV4::Scope scope(func->v4engine());
+ QV4::ScopedValue val(scope);
+ val = (*func)[0];
+
+ *toArgs << val->toQString();
+ for (int i = 1; i < func->length(); i++) {
+ val = (*func)[i];
+ if (val->isObject() && val->asObject()->isArrayObject()) {
+ QV4::ScopedValue valtmp(scope);
+ QV4::Object *array = val->asObject();
+ uint length = array->getLength();
+ for (uint ii = 0; ii < length; ++ii) {
+ valtmp = array->getIndexed(ii);
+ *toArgs << valtmp->toQStringNoThrow();
+ }
+ } else {
+ *toArgs << val->toQString();
+ }
}
+ return true;
+}
+}
+/*!
+ \internal
+*/
+bool Component::addOperation(QQmlV4Function *func)
+{
+ QStringList args;
+ if (convert(func, &args))
+ return addOperation(args[0], args.mid(1));
return false;
}
@@ -1033,6 +1058,8 @@ bool Component::addOperation(const QString &operation, const QString &parameter1
Creates and adds an installation operation for \a operation. Add any number of \a parameters.
The variables that the parameters contain, such as \c @TargetDir@, are replaced with their
values.
+
+ \sa {component::addOperation}{component.addOperation}
*/
bool Component::addOperation(const QString &operation, const QStringList &parameters)
{
@@ -1045,23 +1072,13 @@ bool Component::addOperation(const QString &operation, const QStringList &parame
}
/*!
- Convenience method for calling the elevated operation \a operation with up to ten parameters:
- \a parameter1, \a parameter2, \a parameter3, \a parameter4, \a parameter5, \a parameter6,
- \a parameter7, \a parameter8, \a parameter9, and \a parameter10.
-
- \sa {component::addElevatedOperation}{component.addElevatedOperation}
+ \internal
*/
-bool Component::addElevatedOperation(const QString &operation, const QString &parameter1,
- const QString &parameter2, const QString &parameter3, const QString &parameter4, const QString &parameter5,
- const QString &parameter6, const QString &parameter7, const QString &parameter8, const QString &parameter9,
- const QString &parameter10)
+bool Component::addElevatedOperation(QQmlV4Function *func)
{
- if (Operation *op = createOperation(operation, parameter1, parameter2, parameter3, parameter4, parameter5,
- parameter6, parameter7, parameter8, parameter9, parameter10)) {
- addElevatedOperation(op);
- return true;
- }
-
+ QStringList args;
+ if (convert(func, &args))
+ return addElevatedOperation(args[0], args.mid(1));
return false;
}
@@ -1070,6 +1087,7 @@ bool Component::addElevatedOperation(const QString &operation, const QString &pa
The variables that the parameters contain, such as \c @TargetDir@, are replaced with their
values. The operation is executed with elevated rights.
+ \sa {component::addElevatedOperation}{component.addElevatedOperation}
*/
bool Component::addElevatedOperation(const QString &operation, const QStringList &parameters)
{
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index b184d27d2..e679be593 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -45,6 +45,7 @@
#include <QtCore/QUrl>
QT_FORWARD_DECLARE_CLASS(QDebug)
+QT_FORWARD_DECLARE_CLASS(QQmlV4Function)
namespace KDUpdater {
class Update;
@@ -131,22 +132,12 @@ public:
OperationList operations() const;
void addOperation(Operation *operation);
- Q_INVOKABLE bool addOperation(const QString &operation, const QString &parameter1 = QString(),
- const QString &parameter2 = QString(), const QString &parameter3 = QString(),
- const QString &parameter4 = QString(), const QString &parameter5 = QString(),
- const QString &parameter6 = QString(), const QString &parameter7 = QString(),
- const QString &parameter8 = QString(), const QString &parameter9 = QString(),
- const QString &parameter10 = QString());
- Q_INVOKABLE bool addOperation(const QString &operation, const QStringList &parameters);
+ Q_INVOKABLE bool addOperation(QQmlV4Function *args);
+ bool addOperation(const QString &operation, const QStringList &parameters);
void addElevatedOperation(Operation *operation);
- Q_INVOKABLE bool addElevatedOperation(const QString &operation,
- const QString &parameter1 = QString(), const QString &parameter2 = QString(),
- const QString &parameter3 = QString(), const QString &parameter4 = QString(),
- const QString &parameter5 = QString(), const QString &parameter6 = QString(),
- const QString &parameter7 = QString(), const QString &parameter8 = QString(),
- const QString &parameter9 = QString(), const QString &parameter10 = QString());
- Q_INVOKABLE bool addElevatedOperation(const QString &operation, const QStringList &parameters);
+ Q_INVOKABLE bool addElevatedOperation(QQmlV4Function *args);
+ bool addElevatedOperation(const QString &operation, const QStringList &parameters);
QStringList downloadableArchives() const;
Q_INVOKABLE void addDownloadableArchive(const QString &path);
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index 87af31f3c..cfa83d08d 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -34,7 +34,8 @@ QT += \
xml \
concurrent \
widgets \
- core-private
+ core-private \
+ qml-private
win32:QT += winextras
HEADERS += packagemanagercore.h \
diff --git a/tests/auto/installer/scriptengine/data/addOperation.qs b/tests/auto/installer/scriptengine/data/addOperation.qs
new file mode 100644
index 000000000..9be112aaf
--- /dev/null
+++ b/tests/auto/installer/scriptengine/data/addOperation.qs
@@ -0,0 +1,53 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+function Component()
+{
+}
+
+Component.prototype.createOperations = function ()
+{
+ console.log("Component::createOperations()");
+ component.createOperations();
+
+ component.addOperation("EmptyArg", "Arg", "Arg2", "");
+ component.addOperation("EmptyArg", "Arg", "", "Arg3");
+ component.addOperation("EmptyArg", "", "Arg2", "Arg3");
+ component.addOperation("EmptyArg", ["Arg", "Arg2", ""]);
+
+ component.addElevatedOperation("EmptyArg", "eArg", "eArg2", "");
+ component.addElevatedOperation("EmptyArg", "eArg", "", "eArg3");
+ component.addElevatedOperation("EmptyArg", "", "eArg2", "eArg3");
+ component.addElevatedOperation("EmptyArg", ["eArg", "eArg2", ""]);
+}
diff --git a/tests/auto/installer/scriptengine/scriptengine.qrc b/tests/auto/installer/scriptengine/scriptengine.qrc
index d630f3196..9c72e686f 100644
--- a/tests/auto/installer/scriptengine/scriptengine.qrc
+++ b/tests/auto/installer/scriptengine/scriptengine.qrc
@@ -8,5 +8,6 @@
<file>data/enteringpage.qs</file>
<file>data/form.ui</file>
<file>data/userinterface.qs</file>
+ <file>data/addOperation.qs</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/scriptengine/tst_scriptengine.cpp b/tests/auto/installer/scriptengine/tst_scriptengine.cpp
index 0bbb79060..04a5e0b63 100644
--- a/tests/auto/installer/scriptengine/tst_scriptengine.cpp
+++ b/tests/auto/installer/scriptengine/tst_scriptengine.cpp
@@ -34,6 +34,7 @@
#include <component.h>
#include <errors.h>
+#include <kdupdaterupdateoperationfactory.h>
#include <packagemanagercore.h>
#include <packagemanagergui.h>
#include <scriptengine.h>
@@ -157,6 +158,30 @@ signals:
void emitted();
};
+class EmptyArgOperation : public KDUpdater::UpdateOperation
+{
+public:
+ EmptyArgOperation() {
+ setName("EmptyArg");
+ }
+
+ void backup() {}
+ bool performOperation() {
+ return true;
+ }
+ bool undoOperation() {
+ return true;
+ }
+ bool testOperation() {
+ return true;
+ }
+ UpdateOperation *clone() const {
+ return 0;
+ }
+};
+
+
+// -- tst_ScriptEngine
class tst_ScriptEngine : public QObject
{
@@ -173,6 +198,10 @@ private slots:
m_component->setValue("Default", "Script");
m_component->setValue(scName, "component.test.name");
+ Component *component = new Component(&m_core);
+ component->setValue(scName, "component.test.addOperation");
+ m_core.appendRootComponent(component);
+
m_scriptEngine = m_core.componentScriptEngine();
}
@@ -460,6 +489,44 @@ private slots:
QCOMPARE(enteringPage->invocationOrder(), expectedOrder);
}
+ void testAddOperation_AddElevatedOperation()
+ {
+ using namespace KDUpdater;
+ UpdateOperationFactory &factory = UpdateOperationFactory::instance();
+ factory.registerUpdateOperation<EmptyArgOperation>(QLatin1String("EmptyArg"));
+
+ try {
+ m_core.setPackageManager();
+ Component *component = m_core.componentByName("component.test.addOperation");
+ component->loadComponentScript(":///data/addOperation.qs");
+
+ setExpectedScriptOutput("\"Component::createOperations()\"");
+ component->createOperations();
+
+ const OperationList operations = component->operations();
+ QCOMPARE(operations.count(), 8);
+
+ struct {
+ const char* args[3];
+ const char* operator[](int i) const {
+ return args[i];
+ }
+ } expectedArgs[] = {
+ { "Arg", "Arg2", "" }, { "Arg", "", "Arg3" }, { "", "Arg2", "Arg3" }, { "Arg", "Arg2", "" },
+ { "eArg", "eArg2", "" }, { "eArg", "", "eArg3" }, { "", "eArg2", "eArg3" }, { "eArg", "eArg2", "" }
+ };
+
+ for (int i = 0; i < operations.count(); ++i) {
+ const QStringList arguments = operations[i]->arguments();
+ QCOMPARE(arguments.count(), 3);
+ for (int j = 0; j < 3; ++j)
+ QCOMPARE(arguments[j], QString(expectedArgs[i][j]));
+ }
+ } catch (const QInstaller::Error &error) {
+ QFAIL(qPrintable(error.message()));
+ }
+ }
+
private:
void setExpectedScriptOutput(const char *message)
{