summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/scripting-api/packagemanagercore.qdoc19
-rw-r--r--doc/scripting-api/qfiledialog.qdoc7
-rw-r--r--src/libs/installer/commandlineparser.cpp6
-rw-r--r--src/libs/installer/constants.h1
-rw-r--r--src/libs/installer/packagemanagercore.cpp49
-rw-r--r--src/libs/installer/packagemanagercore.h5
-rw-r--r--src/libs/installer/scriptengine.cpp69
-rw-r--r--src/libs/installer/scriptengine_p.h22
-rw-r--r--src/sdk/sdkapp.h12
-rw-r--r--tests/auto/installer/cliinterface/data/filequeryrepository/A/1.0.2-1meta.7zbin0 -> 907 bytes
-rw-r--r--tests/auto/installer/cliinterface/data/filequeryrepository/Updates.xml13
-rw-r--r--tests/auto/installer/cliinterface/settings.qrc2
-rw-r--r--tests/auto/installer/cliinterface/tst_cliinterface.cpp25
13 files changed, 218 insertions, 12 deletions
diff --git a/doc/scripting-api/packagemanagercore.qdoc b/doc/scripting-api/packagemanagercore.qdoc
index 1cff11c84..cb11cef0d 100644
--- a/doc/scripting-api/packagemanagercore.qdoc
+++ b/doc/scripting-api/packagemanagercore.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -332,6 +332,23 @@
*/
/*!
+ \qmlmethod void installer::setFileDialogAutomaticAnswer(string identifier, string &value)
+
+ Automatically sets the existing directory or filename \a value to QFileDialog with the ID
+ \a identifier.
+
+ \sa removeFileDialogAutomaticAnswer
+*/
+
+/*!
+ \qmlmethod void installer::removeFileDialogAutomaticAnswer(string identifier)
+
+ Removes the automatic answer from QFileDialog with the ID \a identifier.
+
+ \sa setFileDialogAutomaticAnswer
+*/
+
+/*!
\qmlmethod float installer::requiredDiskSpace()
Returns the additional estimated amount of disk space in bytes required after installation.
diff --git a/doc/scripting-api/qfiledialog.qdoc b/doc/scripting-api/qfiledialog.qdoc
index 661a702f7..e6cdfdb24 100644
--- a/doc/scripting-api/qfiledialog.qdoc
+++ b/doc/scripting-api/qfiledialog.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -34,6 +34,11 @@
that displays an existing directory selected by the user. Use the
QFileDialog::getOpenFileName() method to create a dialog that displays
matching files in the directory selected by the user.
+ When a command line interface is used, a dialog is not displayed. Instead,
+ the user can type the directory or the file name in the console. For
+ automatic installations, \c{--file-query} with \c{identifier=value} pairs
+ can be given separated with a comma. For example,
+ \c{--file-query filedialog.id=C:/Temp,filedialog.id2=C:/Temp2}.
*/
/*!
diff --git a/src/libs/installer/commandlineparser.cpp b/src/libs/installer/commandlineparser.cpp
index 60b02c3ae..f3939dc36 100644
--- a/src/libs/installer/commandlineparser.cpp
+++ b/src/libs/installer/commandlineparser.cpp
@@ -163,6 +163,12 @@ CommandLineParser::CommandLineParser()
QLatin1String("Automatically answers to message queries with their default values.")));
m_parser.addOption(QCommandLineOption(QStringList() << CommandLineOptions::scAcceptLicenses,
QLatin1String("Accepts all licenses without user input.")));
+ m_parser.addOption(QCommandLineOption(QStringList() << CommandLineOptions::scFileDialogAutomaticAnswer,
+ QLatin1String("Automatically sets the QFileDialog values getExistingDirectory() or getOpenFileName() "
+ "requested by install script. "
+ "Several identifier=value pairs can be given separated with comma, "
+ "for example --file-query filedialog.id=C:\Temp,filedialog.id2=C:\Temp2"),
+ QLatin1String("identifier=value")));
// Developer options
m_parser.addOption(QCommandLineOption(QStringList()
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index fecba0e6c..9e90d9383 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -158,6 +158,7 @@ static const QLatin1String scRejectMessageQuery("reject-messages");
static const QLatin1String scMessageAutomaticAnswer("auto-answer");
static const QLatin1String scMessageDefaultAnswer("default-answer");
static const QLatin1String scAcceptLicenses("accept-licenses");
+static const QLatin1String scFileDialogAutomaticAnswer("file-query");
// Misc installation options
static const QLatin1String scRootShort("t");
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 2287e5a73..0bfde19c3 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -625,6 +625,55 @@ void PackageManagerCore::setAutoAcceptLicenses()
}
/*!
+ Automatically sets the existing directory or filename \a value to QFileDialog with the ID
+ \a identifier. QFileDialog can be called from script.
+
+ This can be used for unattended (automatic) installations.
+
+ \sa {installer::setFileDialogAutomaticAnswer){installer.setFileDialogAutomaticAnswer}
+ \sa {QFileDialog::getExistingDirectory}{QFileDialog.getExistingDirectory}
+ \sa {QFileDialog::getOpenFileName}{QFileDialog.getOpenFileName}
+ */
+void PackageManagerCore::setFileDialogAutomaticAnswer(const QString &identifier, const QString &value)
+{
+ m_fileDialogAutomaticAnswers.insert(identifier, value);
+}
+
+/*!
+ Removes the automatic answer from QFileDialog with the ID \a identifier.
+ QFileDialog can be called from script.
+
+ \sa {installer::removeFileDialogAutomaticAnswer){installer.removeFileDialogAutomaticAnswer}
+ \sa {QFileDialog::getExistingDirectory}{QFileDialog.getExistingDirectory}
+ \sa {QFileDialog::getOpenFileName}{QFileDialog.getOpenFileName}
+ */
+void PackageManagerCore::removeFileDialogAutomaticAnswer(const QString &identifier)
+{
+ m_fileDialogAutomaticAnswers.remove(identifier);
+}
+
+/*!
+ Returns \c true if QFileDialog with the ID \a identifier has an automatic answer set.
+
+ \sa {installer.containsFileDialogAutomaticAnswer}{installer::containsFileDialogAutomaticAnswer}
+ \sa {installer::removeFileDialogAutomaticAnswer){installer.removeFileDialogAutomaticAnswer}
+ \sa {QFileDialog::getExistingDirectory}{QFileDialog.getExistingDirectory}
+ \sa {QFileDialog::getOpenFileName}{QFileDialog.getOpenFileName}
+ */
+bool PackageManagerCore::containsFileDialogAutomaticAnswer(const QString &identifier) const
+{
+ return m_fileDialogAutomaticAnswers.contains(identifier);
+}
+/*!
+ * Returns the hash of file dialog automatic answers
+ * \sa setFileDialogAutomaticAnswer()
+ */
+QHash<QString, QString> PackageManagerCore::fileDialogAutomaticAnswers() const
+{
+ return m_fileDialogAutomaticAnswers;
+}
+
+/*!
Returns the size of the component \a component as \a value.
*/
quint64 PackageManagerCore::size(QInstaller::Component *component, const QString &value) const
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index 67e7d6365..e188ed34d 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -187,6 +187,10 @@ public:
Q_INVOKABLE void acceptMessageBoxDefaultButton();
Q_INVOKABLE void setAutoAcceptLicenses();
+ Q_INVOKABLE void setFileDialogAutomaticAnswer(const QString &identifier, const QString &value);
+ Q_INVOKABLE void removeFileDialogAutomaticAnswer(const QString &identifier);
+ Q_INVOKABLE bool containsFileDialogAutomaticAnswer(const QString &identifier) const;
+ QHash<QString, QString> fileDialogAutomaticAnswers() const;
quint64 size(QInstaller::Component *component, const QString &value) const;
@@ -385,6 +389,7 @@ private:
private:
PackageManagerCorePrivate *const d;
friend class PackageManagerCorePrivate;
+ QHash<QString, QString> m_fileDialogAutomaticAnswers;
private:
// remove once we deprecate isSelected, setSelected etc...
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index 994fa1406..accd54957 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -265,6 +265,71 @@ void GuiProxy::setModified(bool value)
m_gui->setModified(value);
}
+QFileDialogProxy::QFileDialogProxy(PackageManagerCore *core): m_core(core)
+{
+}
+
+QString QFileDialogProxy::getExistingDirectory(const QString &caption,
+ const QString &dir, const QString &identifier)
+{
+ if (m_core->isCommandLineInstance()) {
+ return getExistingFileOrDirectory(caption, identifier, true);
+ } else {
+ return QFileDialog::getExistingDirectory(0, caption, dir);
+ }
+}
+
+QString QFileDialogProxy::getOpenFileName(const QString &caption, const QString &dir,
+ const QString &filter, const QString &identifier)
+{
+ if (m_core->isCommandLineInstance()) {
+ return getExistingFileOrDirectory(caption, identifier, false);
+ } else {
+ return QFileDialog::getOpenFileName(0, caption, dir, filter);
+ }
+}
+
+QString QFileDialogProxy::getExistingFileOrDirectory(const QString &caption,
+ const QString &identifier, bool isDirectory)
+{
+ QHash<QString, QString> autoAnswers = m_core->fileDialogAutomaticAnswers();
+ QString selectedDirectoryOrFile;
+ QString errorString;
+ if (autoAnswers.contains(identifier)) {
+ selectedDirectoryOrFile = autoAnswers.value(identifier);
+ QFileInfo fileInfo(selectedDirectoryOrFile);
+ if (isDirectory ? fileInfo.isDir() : fileInfo.isFile()) {
+ qCDebug(QInstaller::lcInstallerInstallLog).nospace() << "Automatic answer for "<< identifier
+ << ": " << selectedDirectoryOrFile;
+ } else {
+ if (isDirectory)
+ errorString = QString::fromLatin1("Automatic answer for %1: Directory '%2' not found.")
+ .arg(identifier, selectedDirectoryOrFile);
+ else
+ errorString = QString::fromLatin1("Automatic answer for %1: File '%2' not found.")
+ .arg(identifier, selectedDirectoryOrFile);
+ selectedDirectoryOrFile = QString();
+ }
+ } else {
+ qDebug().nospace().noquote() << identifier << ": " << caption << ": ";
+ QTextStream stream(stdin);
+ stream.readLineInto(&selectedDirectoryOrFile);
+ QFileInfo fileInfo(selectedDirectoryOrFile);
+ if (isDirectory ? !fileInfo.isDir() : !fileInfo.isFile()) {
+ if (isDirectory)
+ errorString = QString::fromLatin1("Directory '%1' not found.")
+ .arg(selectedDirectoryOrFile);
+ else
+ errorString = QString::fromLatin1("File '%1' not found.")
+ .arg(selectedDirectoryOrFile);
+ selectedDirectoryOrFile = QString();
+ }
+ }
+ if (!errorString.isEmpty())
+ qCWarning(QInstaller::lcInstallerInstallLog).nospace() << errorString;
+ return selectedDirectoryOrFile;
+}
+
/*!
Constructs a script engine with \a core as parent.
@@ -275,7 +340,7 @@ ScriptEngine::ScriptEngine(PackageManagerCore *core) :
{
QJSValue global = m_engine.globalObject();
global.setProperty(QLatin1String("console"), m_engine.newQObject(new ConsoleProxy));
- global.setProperty(QLatin1String("QFileDialog"), m_engine.newQObject(new QFileDialogProxy));
+ global.setProperty(QLatin1String("QFileDialog"), m_engine.newQObject(new QFileDialogProxy(core)));
const QJSValue proxy = m_engine.newQObject(new InstallerProxy(this, core));
global.setProperty(QLatin1String("InstallerProxy"), proxy);
global.setProperty(QLatin1String("print"), m_engine.newQObject(new ConsoleProxy)
diff --git a/src/libs/installer/scriptengine_p.h b/src/libs/installer/scriptengine_p.h
index 928f903cb..0fc963bf9 100644
--- a/src/libs/installer/scriptengine_p.h
+++ b/src/libs/installer/scriptengine_p.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -77,15 +77,21 @@ class QFileDialogProxy : public QObject
Q_DISABLE_COPY(QFileDialogProxy)
public:
- QFileDialogProxy() {}
+ QFileDialogProxy(PackageManagerCore *core);
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);
- }
+ QString getExistingDirectory(const QString &caption, const QString &dir,
+ const QString &identifier = QLatin1String("GetExistingDirectory"));
+
+ QString getOpenFileName(const QString &caption, const QString &dir, const QString &filter,
+ const QString &identifier = QLatin1String("GetExistingFile"));
+
+private:
+ QString getExistingFileOrDirectory(const QString &caption, const QString &identifier,
+ bool isDirectory);
+
+private:
+ PackageManagerCore *m_core;
};
class QDesktopServicesProxy : public QObject
diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h
index ecaee3758..378555633 100644
--- a/src/sdk/sdkapp.h
+++ b/src/sdk/sdkapp.h
@@ -292,6 +292,18 @@ public:
}
}
+ if (m_parser.isSet(CommandLineOptions::scFileDialogAutomaticAnswer)) {
+ const QString positionalArguments = m_parser.value(CommandLineOptions::scFileDialogAutomaticAnswer);
+ const QStringList items = positionalArguments.split(QLatin1Char(','), QString::SkipEmptyParts);
+
+ foreach (const QString &item, items) {
+ if (item.contains(QLatin1Char('='))) {
+ const QString name = item.section(QLatin1Char('='), 0, 0);
+ QString value = item.section(QLatin1Char('='), 1, 1);
+ m_core->setFileDialogAutomaticAnswer(name, value);
+ }
+ }
+ }
if (m_parser.isSet(CommandLineOptions::scMessageDefaultAnswer)) {
m_core->acceptMessageBoxDefaultButton();
}
diff --git a/tests/auto/installer/cliinterface/data/filequeryrepository/A/1.0.2-1meta.7z b/tests/auto/installer/cliinterface/data/filequeryrepository/A/1.0.2-1meta.7z
new file mode 100644
index 000000000..a006c5c96
--- /dev/null
+++ b/tests/auto/installer/cliinterface/data/filequeryrepository/A/1.0.2-1meta.7z
Binary files differ
diff --git a/tests/auto/installer/cliinterface/data/filequeryrepository/Updates.xml b/tests/auto/installer/cliinterface/data/filequeryrepository/Updates.xml
new file mode 100644
index 000000000..72b7938d9
--- /dev/null
+++ b/tests/auto/installer/cliinterface/data/filequeryrepository/Updates.xml
@@ -0,0 +1,13 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <PackageUpdate>
+ <Name>A</Name>
+ <DisplayName>A</DisplayName>
+ <Description>A component</Description>
+ <Version>1.0.2-1</Version>
+ <ReleaseDate>2015-01-01</ReleaseDate>
+ <Default>true</Default>
+ <Script>script.qs</Script>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/cliinterface/settings.qrc b/tests/auto/installer/cliinterface/settings.qrc
index 85e344d1b..be97adfbe 100644
--- a/tests/auto/installer/cliinterface/settings.qrc
+++ b/tests/auto/installer/cliinterface/settings.qrc
@@ -19,6 +19,8 @@
<file>data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file>
<file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file>
<file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file>
+ <file>data/filequeryrepository/Updates.xml</file>
+ <file>data/filequeryrepository/A/1.0.2-1meta.7z</file>
<file>data/componentsFromInstallPackagesRepository.xml</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/cliinterface/tst_cliinterface.cpp b/tests/auto/installer/cliinterface/tst_cliinterface.cpp
index 6040927ea..ebf63ff9d 100644
--- a/tests/auto/installer/cliinterface/tst_cliinterface.cpp
+++ b/tests/auto/installer/cliinterface/tst_cliinterface.cpp
@@ -351,6 +351,31 @@ private slots:
<< "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"
<< "installcontentB.txt" << "installcontentD.txt");
}
+ void testFileQuery()
+ {
+ PackageManagerCore *core = PackageManager::getPackageManagerWithInit(m_installDir,
+ ":///data/filequeryrepository");
+ core->setCommandLineInstance(true);
+ core->setFileDialogAutomaticAnswer("ValidDirectory", m_installDir);
+
+ QString testFile = qApp->applicationDirPath() + QDir::toNativeSeparators("/test");
+ QFile file(testFile);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ core->setFileDialogAutomaticAnswer("ValidFile", testFile);
+
+ //File dialog launched without ID
+ core->setFileDialogAutomaticAnswer("GetExistingDirectory", m_installDir);
+ core->setFileDialogAutomaticAnswer("GetExistingFile", testFile);
+
+ core->installDefaultComponentsSilently();
+
+ QVERIFY(core->containsFileDialogAutomaticAnswer("ValidFile"));
+ core->removeFileDialogAutomaticAnswer("ValidFile");
+ QVERIFY(!core->containsFileDialogAutomaticAnswer("ValidFile"));
+
+ QVERIFY(file.remove());
+ core->deleteLater();
+ }
void init()
{