summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@digia.com>2014-01-17 14:34:57 +0100
committerTim Jenssen <tim.jenssen@digia.com>2014-01-17 14:36:23 +0100
commitfe92a09482c5abf7f2c56901f2d60e287282f939 (patch)
treefbfcefcc6f86dd2980b6b5816dece03664c57a76 /src/libs
parent0b5241a696cf05612dae2c8810022f5e205d42df (diff)
parentfaa8f39bdd8c13b21c19bec1592f18e710c56206 (diff)
Merge remote-tracking branch 'origin/1.5'
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/7zip/7zip.pro3
-rw-r--r--src/libs/installer/adminauthorization_win.cpp7
-rw-r--r--src/libs/installer/applyproductkeyoperation.cpp1
-rw-r--r--src/libs/installer/binaryformat.cpp83
-rw-r--r--src/libs/installer/binaryformat.h1
-rw-r--r--src/libs/installer/binaryformatenginehandler.cpp7
-rw-r--r--src/libs/installer/binaryformatenginehandler.h1
-rw-r--r--src/libs/installer/component.cpp26
-rw-r--r--src/libs/installer/component_p.cpp5
-rw-r--r--src/libs/installer/component_p.h3
-rw-r--r--src/libs/installer/consumeoutputoperation.cpp11
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.cpp3
-rw-r--r--src/libs/installer/createshortcutoperation.cpp7
-rw-r--r--src/libs/installer/downloadarchivesjob.cpp9
-rw-r--r--src/libs/installer/downloadarchivesjob.h2
-rw-r--r--src/libs/installer/environmentvariablesoperation.cpp29
-rw-r--r--src/libs/installer/extractarchiveoperation.cpp13
-rw-r--r--src/libs/installer/extractarchiveoperation.h3
-rw-r--r--src/libs/installer/extractarchiveoperation_p.h16
-rw-r--r--src/libs/installer/fileutils.cpp74
-rw-r--r--src/libs/installer/fileutils.h2
-rw-r--r--src/libs/installer/getrepositoriesmetainfojob.cpp2
-rw-r--r--src/libs/installer/getrepositorymetainfojob.cpp80
-rw-r--r--src/libs/installer/init.cpp5
-rw-r--r--src/libs/installer/installer.pro10
-rw-r--r--src/libs/installer/link.cpp8
-rw-r--r--src/libs/installer/packagemanagercore.cpp56
-rw-r--r--src/libs/installer/packagemanagercore.h11
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp105
-rw-r--r--src/libs/installer/packagemanagercore_p.h12
-rw-r--r--src/libs/installer/packagemanagercoredata.cpp22
-rw-r--r--src/libs/installer/packagemanagergui.cpp36
-rw-r--r--src/libs/installer/packagemanagergui.h9
-rw-r--r--src/libs/installer/packagemanagerpagefactory.cpp57
-rw-r--r--src/libs/installer/packagemanagerpagefactory.h72
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.cpp6
-rw-r--r--src/libs/installer/productkeycheck.cpp28
-rw-r--r--src/libs/installer/productkeycheck.h13
-rw-r--r--src/libs/installer/progresscoordinator.cpp33
-rw-r--r--src/libs/installer/progresscoordinator.h4
-rw-r--r--src/libs/installer/qtpatch.cpp13
-rw-r--r--src/libs/installer/resources/files-to-patch-linux-emb-arm4
-rw-r--r--src/libs/installer/resources/files-to-patch-linux-emb-arm-qt412
-rw-r--r--src/libs/installer/resources/files-to-patch-linux-emb-arm-qt512
-rw-r--r--src/libs/installer/resources/files-to-patch-macx-emb-arm-qt5 (renamed from src/libs/installer/resources/files-to-patch-macx-emb-arm)0
-rw-r--r--src/libs/installer/resources/files-to-patch-windows-emb-arm2
-rw-r--r--src/libs/installer/resources/files-to-patch-windows-emb-arm-qt513
-rw-r--r--src/libs/installer/resources/patch_file_lists.qrc4
-rw-r--r--src/libs/installer/scriptengine.cpp44
-rw-r--r--src/libs/installer/scriptengine.h3
-rw-r--r--src/libs/installer/settings.cpp5
-rw-r--r--src/libs/installer/settings.h1
-rw-r--r--src/libs/installer/settingsoperation.cpp216
-rw-r--r--src/libs/installer/settingsoperation.h66
-rw-r--r--src/libs/installer/sysinfo_win.cpp5
-rw-r--r--src/libs/installer/testrepository.cpp168
-rw-r--r--src/libs/installer/testrepository.h95
-rw-r--r--src/libs/installer/updater.cpp2
-rw-r--r--src/libs/installer/utils.cpp6
-rw-r--r--src/libs/kdtools/kdgenericfactory.h29
-rw-r--r--src/libs/kdtools/kdsavefile.cpp2
-rw-r--r--src/libs/kdtools/kdsavefile.h2
-rw-r--r--src/libs/kdtools/kdsysinfo_win.cpp8
-rw-r--r--src/libs/kdtools/kdupdaterupdateoperation.cpp34
-rw-r--r--src/libs/kdtools/kdupdaterupdateoperation.h1
-rw-r--r--src/libs/kdtools/kdupdaterupdateoperations.cpp29
66 files changed, 1340 insertions, 311 deletions
diff --git a/src/libs/7zip/7zip.pro b/src/libs/7zip/7zip.pro
index 549778e67..01b69dad2 100644
--- a/src/libs/7zip/7zip.pro
+++ b/src/libs/7zip/7zip.pro
@@ -1,8 +1,7 @@
-include(../../../installerfw.pri)
-
QT = core
TARGET = 7z
TEMPLATE = lib
+include(../../../installerfw.pri)
INCLUDEPATH += . ..
CONFIG += staticlib
DESTDIR = $$IFW_LIB_PATH
diff --git a/src/libs/installer/adminauthorization_win.cpp b/src/libs/installer/adminauthorization_win.cpp
index 03003b21a..528f3403d 100644
--- a/src/libs/installer/adminauthorization_win.cpp
+++ b/src/libs/installer/adminauthorization_win.cpp
@@ -45,17 +45,14 @@
#include <QDebug>
#include <QDir>
+#include <qt_windows.h>
+
#ifdef Q_CC_MINGW
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-# endif
# ifndef SEE_MASK_NOASYNC
# define SEE_MASK_NOASYNC 0x00000100
# endif
#endif
-#include <windows.h>
-
struct DeCoInitializer
{
DeCoInitializer()
diff --git a/src/libs/installer/applyproductkeyoperation.cpp b/src/libs/installer/applyproductkeyoperation.cpp
index 4556df743..5b561bd19 100644
--- a/src/libs/installer/applyproductkeyoperation.cpp
+++ b/src/libs/installer/applyproductkeyoperation.cpp
@@ -46,6 +46,7 @@ bool ApplyProductKeyOperation::performOperation()
if (!ProductKeyCheck::instance()->applyKey(arguments())) {
setError(UserDefinedError);
setErrorString(ProductKeyCheck::instance()->lastErrorString());
+ return false;
}
return true;
}
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index b07cc90de..7aa4d94ab 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -55,6 +55,7 @@
#include <QTemporaryFile>
#include <errno.h>
+#include <string.h>
using namespace QInstaller;
using namespace QInstallerCreator;
@@ -215,38 +216,45 @@ QByteArray QInstaller::retrieveCompressedData(QIODevice *in, qint64 size)
return qUncompress(ba);
}
+/*!
+ Search through 1MB, if smaller through the whole file. Note: QFile::map() does
+ not change QFile::pos(). Fallback to read the file content in case we can't map it.
+*/
qint64 QInstaller::findMagicCookie(QFile *in, quint64 magicCookie)
{
Q_ASSERT(in);
Q_ASSERT(in->isOpen());
Q_ASSERT(in->isReadable());
- const qint64 oldPos = in->pos();
- const qint64 MAX_SEARCH = 1024 * 1024; // stop searching after one MB
- qint64 searched = 0;
- try {
- while (searched < MAX_SEARCH) {
- const qint64 pos = in->size() - searched - sizeof(qint64);
- if (pos < 0)
- throw Error(QObject::tr("Searched whole file, no marker found"));
- if (!in->seek(pos)) {
- throw Error(QObject::tr("Could not seek to %1 in file %2: %3").arg(QString::number(pos),
- in->fileName(), in->errorString()));
- }
- const quint64 num = static_cast<quint64>(retrieveInt64(in));
- if (num == magicCookie) {
- in->seek(oldPos);
- return pos;
- }
- searched += 1;
+
+ const qint64 fileSize = in->size();
+ const size_t markerSize = sizeof(qint64);
+ const qint64 maxSearch = qMin((1024LL * 1024LL), fileSize);
+
+ QByteArray data(maxSearch, Qt::Uninitialized);
+ uchar *const mapped = in->map(fileSize - maxSearch, maxSearch);
+ if (!mapped) {
+ const int pos = in->pos();
+ try {
+ in->seek(fileSize - maxSearch);
+ blockingRead(in, data.data(), maxSearch);
+ in->seek(pos);
+ } catch (const Error &error) {
+ in->seek(pos);
+ throw error;
}
- throw Error(QObject::tr("No marker found, stopped after %1.").arg(humanReadableSize(MAX_SEARCH)));
- } catch (const Error& err) {
- in->seek(oldPos);
- throw err;
- } catch (...) {
- in->seek(oldPos);
- throw Error(QObject::tr("No marker found, unknown exception caught."));
+ } else {
+ data = QByteArray((const char*)mapped, maxSearch);
+ in->unmap(mapped);
+ }
+
+ qint64 searched = maxSearch - markerSize;
+ while (searched >= 0) {
+ if (memcmp(&magicCookie, (data.data() + searched), markerSize) == 0)
+ return (fileSize - maxSearch) + searched;
+ --searched;
}
+ throw Error(QObject::tr("No marker found, stopped after %1.").arg(humanReadableSize(maxSearch)));
+
return -1; // never reached
}
@@ -802,7 +810,7 @@ BinaryContentPrivate::BinaryContentPrivate(const BinaryContentPrivate &other)
BinaryContentPrivate::~BinaryContentPrivate()
{
foreach (const QByteArray &rccData, m_resourceMappings)
- QResource::unregisterResource((const uchar*)rccData.constData());
+ QResource::unregisterResource((const uchar*)rccData.constData(), QLatin1String(":/metadata"));
m_resourceMappings.clear();
}
@@ -1144,6 +1152,29 @@ int BinaryContent::registerEmbeddedQResources()
}
/*!
+ Registers the passed file as default resource content. If the embedded resources are already mapped into
+ memory, it will replace the first with the new content.
+*/
+void BinaryContent::registerAsDefaultQResource(const QString &path)
+{
+ QFile resource(path);
+ bool success = resource.open(QIODevice::ReadOnly);
+ if (success && (d->m_resourceMappings.count() > 0)) {
+ success = QResource::unregisterResource((const uchar*)d->m_resourceMappings.first().constData(),
+ QLatin1String(":/metadata"));
+ if (success)
+ d->m_resourceMappings.remove(0);
+ }
+
+ if (success) {
+ d->m_resourceMappings.prepend(addResourceFromBinary(&resource, Range<qint64>::fromStartAndEnd(0,
+ resource.size())));
+ } else {
+ qWarning() << QString::fromLatin1("Could not register '%1' as default resource.").arg(path);
+ }
+}
+
+/*!
Returns the binary component index as read from the file.
*/
QInstallerCreator::ComponentIndex BinaryContent::componentIndex() const
diff --git a/src/libs/installer/binaryformat.h b/src/libs/installer/binaryformat.h
index d255ea8a9..0abe78030 100644
--- a/src/libs/installer/binaryformat.h
+++ b/src/libs/installer/binaryformat.h
@@ -242,6 +242,7 @@ public:
qint64 magicMarker() const;
int registerEmbeddedQResources();
+ void registerAsDefaultQResource(const QString &path);
QInstallerCreator::ComponentIndex componentIndex() const;
private:
diff --git a/src/libs/installer/binaryformatenginehandler.cpp b/src/libs/installer/binaryformatenginehandler.cpp
index d872ed229..1364ff431 100644
--- a/src/libs/installer/binaryformatenginehandler.cpp
+++ b/src/libs/installer/binaryformatenginehandler.cpp
@@ -122,3 +122,10 @@ void BinaryFormatEngineHandler::registerArchive(const QString &pathName, const Q
c.appendArchive(newArchive);
d->index.insertComponent(c);
}
+
+void BinaryFormatEngineHandler::resetRegisteredArchives()
+{
+ QVector<QInstallerCreator::Component> registeredComponents = d->index.components();
+ foreach (const QInstallerCreator::Component &component, registeredComponents)
+ d->index.removeComponent(component.name());
+}
diff --git a/src/libs/installer/binaryformatenginehandler.h b/src/libs/installer/binaryformatenginehandler.h
index cccc2f523..107f834f4 100644
--- a/src/libs/installer/binaryformatenginehandler.h
+++ b/src/libs/installer/binaryformatenginehandler.h
@@ -67,6 +67,7 @@ public:
static BinaryFormatEngineHandler *instance();
void registerArchive(const QString &fileName, const QString &path);
+ void resetRegisteredArchives();
private:
class Private;
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 0ac69aaf8..1b37cc12c 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -211,6 +211,7 @@ Component::Component(PackageManagerCore *core)
setPrivate(d);
connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
+ qRegisterMetaType<QList<QInstaller::Component*> >("QList<QInstaller::Component*>");
}
/*!
@@ -485,14 +486,12 @@ void Component::loadComponentScript()
*/
void Component::loadComponentScript(const QString &fileName)
{
- ScriptEngine *scriptEngine = d->m_core->scriptEngine();
-
// 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 = scriptEngine->loadInConext(QLatin1String("Component"), fileName, scriptInjection);
+ d->m_scriptContext = d->scriptEngine()->loadInConext(QLatin1String("Component"), fileName, scriptInjection);
emit loaded();
languageChanged();
@@ -505,7 +504,7 @@ void Component::loadComponentScript(const QString &fileName)
*/
void Component::languageChanged()
{
- d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext, QLatin1String("retranslateUi"));
+ d->scriptEngine()->callScriptMethod(d->m_scriptContext, QLatin1String("retranslateUi"));
}
/*!
@@ -590,7 +589,7 @@ void Component::loadLicenses(const QString &directory, const QHash<QString, QVar
for (it = licenseHash.begin(); it != licenseHash.end(); ++it) {
const QString &fileName = it.value().toString();
- if (!ProductKeyCheck::instance(d->m_core)->isValidLicenseTextFile(fileName))
+ if (!ProductKeyCheck::instance()->isValidLicenseTextFile(fileName))
continue;
QFileInfo fileInfo(fileName);
@@ -660,7 +659,7 @@ void Component::createOperationsForPath(const QString &path)
return;
// the script can override this method
- if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("createOperationsForPath"), QScriptValueList() << path).isValid()) {
return;
}
@@ -705,7 +704,7 @@ void Component::createOperationsForArchive(const QString &archive)
return;
// the script can override this method
- if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("createOperationsForArchive"), QScriptValueList() << archive).isValid()) {
return;
}
@@ -739,7 +738,7 @@ void Component::createOperationsForArchive(const QString &archive)
void Component::beginInstallation()
{
// the script can override this method
- if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("beginInstallation")).isValid()) {
return;
}
@@ -758,7 +757,7 @@ void Component::beginInstallation()
void Component::createOperations()
{
// the script can override this method
- if (d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ if (d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("createOperations")).isValid()) {
d->m_operationsCreated = true;
return;
@@ -899,6 +898,7 @@ OperationList Component::operations() const
if (!d->m_minimumProgressOperation) {
d->m_minimumProgressOperation = KDUpdater::UpdateOperationFactory::instance()
.create(QLatin1String("MinimumProgress"));
+ d->m_minimumProgressOperation->setValue(QLatin1String("component"), name());
d->m_operations.append(d->m_minimumProgressOperation);
}
@@ -906,6 +906,7 @@ OperationList Component::operations() const
d->m_licenseOperation = KDUpdater::UpdateOperationFactory::instance()
.create(QLatin1String("License"));
d->m_licenseOperation->setValue(QLatin1String("installer"), QVariant::fromValue(d->m_core));
+ d->m_licenseOperation->setValue(QLatin1String("component"), name());
QVariantMap licenses;
const QList<QPair<QString, QString> > values = d->m_licenses.values();
@@ -1118,7 +1119,8 @@ void Component::setValidatorCallbackName(const QString &name)
bool Component::validatePage()
{
if (!validatorCallbackName.isEmpty())
- return d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext, validatorCallbackName).toBool();
+ return d->scriptEngine()->callScriptMethod(
+ d->m_scriptContext, validatorCallbackName).toBool();
return true;
}
@@ -1198,7 +1200,7 @@ bool Component::isAutoDependOn(const QSet<QString> &componentsToInstall) const
if (autoDependOnList.first().compare(QLatin1String("script"), Qt::CaseInsensitive) == 0) {
QScriptValue valueFromScript;
try {
- valueFromScript = d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ valueFromScript = d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("isAutoDependOn"));
} catch (const Error &error) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
@@ -1248,7 +1250,7 @@ bool Component::isDefault() const
if (d->m_vars.value(scDefault).compare(QLatin1String("script"), Qt::CaseInsensitive) == 0) {
QScriptValue valueFromScript;
try {
- valueFromScript = d->m_core->scriptEngine()->callScriptMethod(d->m_scriptContext,
+ valueFromScript = d->scriptEngine()->callScriptMethod(d->m_scriptContext,
QLatin1String("isDefault"));
} catch (const Error &error) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
diff --git a/src/libs/installer/component_p.cpp b/src/libs/installer/component_p.cpp
index 560cd6544..ae4a149a5 100644
--- a/src/libs/installer/component_p.cpp
+++ b/src/libs/installer/component_p.cpp
@@ -87,6 +87,11 @@ ComponentPrivate::~ComponentPrivate()
delete widget.data();
}
+ScriptEngine *ComponentPrivate::scriptEngine() const
+{
+ return m_core->componentScriptEngine();
+}
+
// -- ComponentModelHelper
ComponentModelHelper::ComponentModelHelper()
diff --git a/src/libs/installer/component_p.h b/src/libs/installer/component_p.h
index 1da9eee1a..821e891d7 100644
--- a/src/libs/installer/component_p.h
+++ b/src/libs/installer/component_p.h
@@ -53,6 +53,7 @@ namespace QInstaller {
class Component;
class PackageManagerCore;
+class ScriptEngine;
class ComponentPrivate
{
@@ -62,6 +63,8 @@ public:
explicit ComponentPrivate(PackageManagerCore *core, Component *qq);
~ComponentPrivate();
+ ScriptEngine *scriptEngine() const;
+
PackageManagerCore *m_core;
Component *m_parentComponent;
OperationList m_operations;
diff --git a/src/libs/installer/consumeoutputoperation.cpp b/src/libs/installer/consumeoutputoperation.cpp
index 04d7c9a8c..95d143b4a 100644
--- a/src/libs/installer/consumeoutputoperation.cpp
+++ b/src/libs/installer/consumeoutputoperation.cpp
@@ -104,17 +104,20 @@ bool ConsumeOutputOperation::performOperation()
}
QByteArray executableOutput;
- QProcess process;
const QStringList processArguments = arguments().mid(2);
// in some cases it is not runable, because another process is blocking it(filewatcher ...)
int waitCount = 0;
- while (executableOutput.isEmpty() && waitCount < 60) {
-
+ while (executableOutput.isEmpty() && waitCount < 3) {
+ QProcess process;
process.start(executable.absoluteFilePath(), processArguments, QIODevice::ReadOnly);
- if (process.waitForFinished(2000)) {
+ if (process.waitForFinished(10000)) {
if (process.exitStatus() == QProcess::CrashExit) {
+ qWarning() << executable.absoluteFilePath() << processArguments
+ << "crashed with exit code" << process.exitCode()
+ << "standard output: " << process.readAllStandardOutput()
+ << "error output: " << process.readAllStandardError();
setError(UserDefinedError);
setErrorString(tr("Running '%1' resulted in a crash.").arg(
QDir::toNativeSeparators(executable.absoluteFilePath())));
diff --git a/src/libs/installer/createlocalrepositoryoperation.cpp b/src/libs/installer/createlocalrepositoryoperation.cpp
index 0eb11b3aa..c8964796d 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -365,8 +365,7 @@ bool CreateLocalRepositoryOperation::undoOperation()
if (createdDir == QDir::root() || !createdDir.exists())
return true;
- QFile::remove(createdDir.path() + QLatin1String("/.DS_Store"));
- QFile::remove(createdDir.path() + QLatin1String("/Thumbs.db"));
+ QInstaller::removeSystemGeneratedFiles(createdDir.path());
errno = 0;
const bool result = QDir::root().rmdir(createdDir.path());
diff --git a/src/libs/installer/createshortcutoperation.cpp b/src/libs/installer/createshortcutoperation.cpp
index 963f0aaf8..8c5917852 100644
--- a/src/libs/installer/createshortcutoperation.cpp
+++ b/src/libs/installer/createshortcutoperation.cpp
@@ -52,12 +52,7 @@
using namespace QInstaller;
#ifdef Q_OS_WIN
-#ifdef Q_CC_MINGW
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-# endif
-#endif
-#include <windows.h>
+#include <qt_windows.h>
#include <shlobj.h>
#ifndef PIDLIST_ABSOLUTE
diff --git a/src/libs/installer/downloadarchivesjob.cpp b/src/libs/installer/downloadarchivesjob.cpp
index 24fba689a..82f9b365c 100644
--- a/src/libs/installer/downloadarchivesjob.cpp
+++ b/src/libs/installer/downloadarchivesjob.cpp
@@ -182,7 +182,7 @@ void DownloadArchivesJob::fetchNextArchive()
if (m_downloader != 0)
m_downloader->deleteLater();
- m_downloader = setupDownloader();
+ m_downloader = setupDownloader(QString(), m_core->value(QLatin1String("UrlQueryString")));
if (!m_downloader) {
m_archivesToDownload.removeFirst();
QMetaObject::invokeMethod(this, "fetchNextArchive", Qt::QueuedConnection);
@@ -292,13 +292,16 @@ void DownloadArchivesJob::finishWithError(const QString &error)
emitFinishedWithError(QInstaller::DownloadError, msg.arg(error, m_downloader->url().toString()));
}
-KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &suffix)
+KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &suffix, const QString &queryString)
{
KDUpdater::FileDownloader *downloader = 0;
const QFileInfo fi = QFileInfo(m_archivesToDownload.first().first);
const Component *const component = m_core->componentByName(QFileInfo(fi.path()).fileName());
if (component) {
- const QUrl url(m_archivesToDownload.first().second + suffix);
+ QString fullQueryString;
+ if (!queryString.isEmpty())
+ fullQueryString = QLatin1String("?") + queryString;
+ const QUrl url(m_archivesToDownload.first().second + suffix + fullQueryString);
const QString &scheme = url.scheme();
downloader = FileDownloaderFactory::instance().create(scheme, this);
diff --git a/src/libs/installer/downloadarchivesjob.h b/src/libs/installer/downloadarchivesjob.h
index 9cf904fae..765d2c564 100644
--- a/src/libs/installer/downloadarchivesjob.h
+++ b/src/libs/installer/downloadarchivesjob.h
@@ -91,7 +91,7 @@ protected Q_SLOTS:
void emitDownloadProgress(double progress);
private:
- KDUpdater::FileDownloader *setupDownloader(const QString &suffix = QString());
+ KDUpdater::FileDownloader *setupDownloader(const QString &suffix = QString(), const QString &queryString = QString());
private:
PackageManagerCore *m_core;
diff --git a/src/libs/installer/environmentvariablesoperation.cpp b/src/libs/installer/environmentvariablesoperation.cpp
index e66c6fc0d..4c423d94f 100644
--- a/src/libs/installer/environmentvariablesoperation.cpp
+++ b/src/libs/installer/environmentvariablesoperation.cpp
@@ -67,19 +67,15 @@ void EnvironmentVariableOperation::backup()
}
#ifdef Q_OS_WIN
-static bool broadcastChange() {
+static void broadcastEnvironmentChange()
+{
// Use SendMessageTimeout to Broadcast a message to the whole system to update settings of all
// running applications. This is needed to activate the changes done above without logout+login.
- // Note that cmd.exe does not respond to any WM_SETTINGCHANGE messages...
DWORD_PTR aResult = 0;
- LRESULT sendresult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE,
- 0, (LPARAM) "Environment", SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &aResult);
- if (sendresult == 0 || aResult != 0) {
- qWarning("Failed to broadcast a WM_SETTINGCHANGE message\n");
- return false;
- }
-
- return true;
+ LRESULT sendresult = SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE,
+ 0, (LPARAM) L"Environment", SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &aResult);
+ if (sendresult == 0 || aResult != 0)
+ qWarning("Failed to broadcast the WM_SETTINGCHANGE message.");
}
#endif
@@ -161,16 +157,15 @@ bool EnvironmentVariableOperation::performOperation()
Error err = NoError;
- err = isSystemWide
- ? writeSetting<QSettingsWrapper>(regPath, name, value, &errorString, &oldvalue)
- : writeSetting<QSettingsWrapper>(regPath, name, value, &errorString, &oldvalue);
+ err = writeSetting<QSettingsWrapper>(regPath, name, value, &errorString, &oldvalue);
if (err != NoError) {
setError(err);
setErrorString(errorString);
return false;
}
- const bool bret = broadcastChange();
- Q_UNUSED(bret); // this is not critical, so fall-through
+
+ broadcastEnvironmentChange();
+
setValue(QLatin1String("oldvalue"), oldvalue);
return true;
}
@@ -215,9 +210,7 @@ bool EnvironmentVariableOperation::undoOperation()
QString errorString;
- const Error err = isSystemWide
- ? undoSetting<QSettingsWrapper>(regPath, name, value, oldvalue, &errorString)
- : undoSetting<QSettingsWrapper>(regPath, name, value, oldvalue, &errorString);
+ const Error err = undoSetting<QSettingsWrapper>(regPath, name, value, oldvalue, &errorString);
if (err != NoError) {
setError(err);
diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp
index 48c5db2c9..3897de4e4 100644
--- a/src/libs/installer/extractarchiveoperation.cpp
+++ b/src/libs/installer/extractarchiveoperation.cpp
@@ -75,13 +75,12 @@ bool ExtractArchiveOperation::performOperation()
Receiver receiver;
Callback callback;
- // usually we have to connect it as queued connection but then some blocking work is in the main thread
- connect(&callback, SIGNAL(progressChanged(QString)), this, SLOT(slotProgressChanged(QString)),
- Qt::DirectConnection);
+ connect(&callback, SIGNAL(currentFileChanged(QString)), this, SLOT(fileFinished(QString)));
+ connect(&callback, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
if (PackageManagerCore *core = this->value(QLatin1String("installer")).value<PackageManagerCore*>()) {
connect(core, SIGNAL(statusChanged(QInstaller::PackageManagerCore::Status)), &callback,
- SLOT(statusChanged(QInstaller::PackageManagerCore::Status)), Qt::QueuedConnection);
+ SLOT(statusChanged(QInstaller::PackageManagerCore::Status)));
}
//Runnable is derived from QRunable which will be deleted by the ThreadPool -> no parent is needed
@@ -125,8 +124,8 @@ bool ExtractArchiveOperation::undoOperation()
const QStringList files = value(QLatin1String("files")).toStringList();
WorkerThread *const thread = new WorkerThread(this, files);
- connect(thread, SIGNAL(outputTextChanged(QString)), this, SIGNAL(outputTextChanged(QString)),
- Qt::QueuedConnection);
+ connect(thread, SIGNAL(currentFileChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
+ connect(thread, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
QEventLoop loop;
connect(thread, SIGNAL(finished()), &loop, SLOT(quit()), Qt::QueuedConnection);
@@ -149,7 +148,7 @@ Operation *ExtractArchiveOperation::clone() const
/*!
This slot is direct connected to the caller so please don't call it from another thread in the same time.
*/
-void ExtractArchiveOperation::slotProgressChanged(const QString &filename)
+void ExtractArchiveOperation::fileFinished(const QString &filename)
{
QStringList files = value(QLatin1String("files")).toStringList();
files.prepend(filename);
diff --git a/src/libs/installer/extractarchiveoperation.h b/src/libs/installer/extractarchiveoperation.h
index 818672fd3..53df81e73 100644
--- a/src/libs/installer/extractarchiveoperation.h
+++ b/src/libs/installer/extractarchiveoperation.h
@@ -64,9 +64,10 @@ public:
Q_SIGNALS:
void outputTextChanged(const QString &progress);
+ void progressChanged(double);
private Q_SLOTS:
- void slotProgressChanged(const QString &progress);
+ void fileFinished(const QString &progress);
private:
class Callback;
diff --git a/src/libs/installer/extractarchiveoperation_p.h b/src/libs/installer/extractarchiveoperation_p.h
index 4e0632830..c7284d9c2 100644
--- a/src/libs/installer/extractarchiveoperation_p.h
+++ b/src/libs/installer/extractarchiveoperation_p.h
@@ -71,9 +71,12 @@ public:
ExtractArchiveOperation *const op = m_op;//dynamic_cast< ExtractArchiveOperation* >(parent());
Q_ASSERT(op != 0);
+ int removedCounter = 0;
foreach (const QString &file, m_files) {
+ removedCounter++;
const QFileInfo fi(file);
- emit outputTextChanged(file);
+ emit currentFileChanged(file);
+ emit progressChanged(double(removedCounter) / m_files.count());
if (fi.isFile() || fi.isSymLink()) {
op->deleteFileNowOrLater(fi.absoluteFilePath());
} else if (fi.isDir()) {
@@ -85,7 +88,8 @@ public:
}
Q_SIGNALS:
- void outputTextChanged(const QString &filename);
+ void currentFileChanged(const QString &filename);
+ void progressChanged(double);
private:
QStringList m_files;
@@ -105,7 +109,8 @@ public:
Callback() : state(S_OK), createBackups(true) {}
Q_SIGNALS:
- void progressChanged(const QString &filename);
+ void currentFileChanged(const QString &filename);
+ void progressChanged(double progress);
public Q_SLOTS:
void statusChanged(QInstaller::PackageManagerCore::Status status)
@@ -130,7 +135,7 @@ public Q_SLOTS:
protected:
void setCurrentFile(const QString &filename)
{
- emit progressChanged(QDir::toNativeSeparators(filename));
+ emit currentFileChanged(QDir::toNativeSeparators(filename));
}
static QString generateBackupName(const QString &fn)
@@ -161,8 +166,9 @@ protected:
return true;
}
- HRESULT setCompleted(quint64 /*completed*/, quint64 /*total*/)
+ HRESULT setCompleted(quint64 completed, quint64 total)
{
+ emit progressChanged(double(completed) / total);
return state;
}
};
diff --git a/src/libs/installer/fileutils.cpp b/src/libs/installer/fileutils.cpp
index 010c30621..fe10277ea 100644
--- a/src/libs/installer/fileutils.cpp
+++ b/src/libs/installer/fileutils.cpp
@@ -289,8 +289,7 @@ void QInstaller::removeDirectory(const QString &path, bool ignoreErrors)
QDirIterator it(path, QDir::NoDotAndDotDot | QDir::Dirs | QDir::NoSymLinks | QDir::Hidden,
QDirIterator::Subdirectories);
while (it.hasNext()) {
- it.next();
- dirs.prepend(it.filePath());
+ dirs.prepend(it.next());
removeFiles(dirs.at(0), ignoreErrors);
}
@@ -461,27 +460,68 @@ QString QInstaller::generateTemporaryFileName(const QString &templ)
return f.fileName();
}
-QString QInstaller::createTemporaryDirectory(const QString &templ)
+static char *installer_mkdtemp(char *templateName)
{
- const QString t = QDir::tempPath() + QLatin1String("/") + templ + QLatin1String("XXXXXX");
- QTemporaryFile f(t);
- if (!f.open())
- throw Error(QObject::tr("Could not create temporary folder for template %1: %2").arg(t, f.errorString()));
- const QString path = f.fileName() + QLatin1String("meta");
- qDebug() << "\nCreating meta data directory at" << path;
+ QDir newDir;
+#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+ static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- QInstaller::mkpath(path);
+ const size_t length = strlen(templateName);
+
+ char *XXXXXX = templateName + length - 6;
+
+ if ((length < 6u) || strncmp(XXXXXX, "XXXXXX", 6))
+ return 0;
+
+ for (int i = 0; i < 256; ++i) {
+ /* Fill in the random bits. */
+ int v = qrand();
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v = qrand();
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v = qrand();
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ QString templateNameStr = QFile::decodeName(templateName);
+
+ newDir = QDir(templateNameStr);
+ if (newDir.mkpath(templateNameStr))
+ return templateName;
+ }
+ return 0;
+#else
+ return mkdtemp(templateName);
+#endif
+}
+
+QString QInstaller::createTemporaryDirectory(const QString &templateName)
+{
+ // TODO: use QTemporaryDir if we switched to Qt5
+ QString path = QDir::tempPath() + QLatin1String("/") + templateName + QLatin1String("XXXXXX");
+ path = QFile::decodeName(installer_mkdtemp(QFile::encodeName(path).data()));
+ if (path.isEmpty()) {
+ QTemporaryFile f(path);
+ if (!f.open()) {
+ throw Error(QObject::tr("Could not create temporary directory at %1: %2"
+ ).arg(QFileInfo(f).absolutePath(), f.errorString()));
+ } else {
+ throw Error(QObject::tr("Could not create temporary directory at %1: unknown error"
+ ).arg(QFileInfo(f).absolutePath()));
+ }
+ }
+
+ qDebug() << "Temporary directory created:" << path;
return path;
}
#ifdef Q_OS_WIN
-# ifdef Q_CC_MINGW
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-# endif
-# endif
-#include <windows.h>
-
+#include <qt_windows.h>
QString QInstaller::getShortPathName(const QString &name)
{
diff --git a/src/libs/installer/fileutils.h b/src/libs/installer/fileutils.h
index 9bbcec72a..c22aa36b6 100644
--- a/src/libs/installer/fileutils.h
+++ b/src/libs/installer/fileutils.h
@@ -108,7 +108,7 @@ private:
Creates a temporary directory
@throws QInstaller::Error if creating the temporary directory fails
*/
- QString INSTALLER_EXPORT createTemporaryDirectory(const QString &templ=QString());
+ QString INSTALLER_EXPORT createTemporaryDirectory(const QString &templateName = QString());
QString INSTALLER_EXPORT generateTemporaryFileName(const QString &templ=QString());
diff --git a/src/libs/installer/getrepositoriesmetainfojob.cpp b/src/libs/installer/getrepositoriesmetainfojob.cpp
index c4564e781..cde872064 100644
--- a/src/libs/installer/getrepositoriesmetainfojob.cpp
+++ b/src/libs/installer/getrepositoriesmetainfojob.cpp
@@ -121,7 +121,7 @@ void GetRepositoriesMetaInfoJob::doStart()
{
if ((m_core->isInstaller() && !m_core->isOfflineOnly()) || (m_core->isUpdater()
|| m_core->isPackageManager())) {
- const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance(m_core);
+ const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
foreach (const Repository &repo, m_core->settings().repositories()) {
if (repo.isEnabled() && productKeyCheck->isValidRepository(repo))
m_repositories += repo;
diff --git a/src/libs/installer/getrepositorymetainfojob.cpp b/src/libs/installer/getrepositorymetainfojob.cpp
index 1c8d07525..14bcf26f2 100644
--- a/src/libs/installer/getrepositorymetainfojob.cpp
+++ b/src/libs/installer/getrepositorymetainfojob.cpp
@@ -49,6 +49,8 @@
#include "kdupdaterfiledownloader.h"
#include "kdupdaterfiledownloaderfactory.h"
+#include "productkeycheck.h"
+
#include <QTimer>
@@ -197,14 +199,14 @@ void GetRepositoryMetaInfoJob::startUpdatesXmlDownload()
}
if (!url.isValid()) {
- finished(QInstaller::InvalidUrl, tr("Invalid repository URL: %1").arg(url.toString()));
+ finished(QInstaller::InvalidUrl, tr("Invalid repository URL: %1").arg(m_repository.displayname()));
return;
}
m_downloader = FileDownloaderFactory::instance().create(url.scheme(), this);
if (!m_downloader) {
finished(QInstaller::InvalidUrl, tr("URL scheme not supported: %1 (%2)").arg(url.scheme(),
- url.toString()));
+ m_repository.displayname()));
return;
}
@@ -244,20 +246,7 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
Q_ASSERT(!fn.isEmpty());
Q_ASSERT(QFile::exists(fn));
- try {
- m_temporaryDirectory = createTemporaryDirectory(QLatin1String("remoterepo"));
- m_tempDirDeleter.add(m_temporaryDirectory);
- } catch (const QInstaller::Error& e) {
- finished(QInstaller::ExtractionError, e.message());
- return;
- }
-
QFile updatesFile(fn);
- if (!updatesFile.rename(m_temporaryDirectory + QLatin1String("/Updates.xml"))) {
- finished(QInstaller::DownloadError, tr("Could not move Updates.xml to target location. Error: %1")
- .arg(updatesFile.errorString()));
- return;
- }
if (!updatesFile.open(QIODevice::ReadOnly)) {
finished(QInstaller::DownloadError, tr("Could not open Updates.xml for reading. Error: %1")
@@ -272,7 +261,7 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
if (!success) {
const QString msg = tr("Could not fetch a valid version of Updates.xml from repository: %1. "
- "Error: %2").arg(m_repository.url().toString(), err);
+ "Error: %2").arg(m_repository.displayname(), err);
const QMessageBox::StandardButton b =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
@@ -302,15 +291,16 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
repository.setUsername(el.attribute(QLatin1String("username")));
repository.setPassword(el.attribute(QLatin1String("password")));
repository.setDisplayName(el.attribute(QLatin1String("displayname")));
- repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
-
- qDebug() << "Repository to add:" << repository.url().toString();
+ if (ProductKeyCheck::instance()->isValidRepository(repository)) {
+ repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
+ qDebug() << "Repository to add:" << repository.displayname();
+ }
} else if (action == QLatin1String("remove")) {
// remove possible default repositories using the given server url
Repository repository(el.attribute(QLatin1String("url")), true);
repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
- qDebug() << "Repository to remove:" << repository.url().toString();
+ qDebug() << "Repository to remove:" << repository.displayname();
} else if (action == QLatin1String("replace")) {
// replace possible default repositories using the given server url
Repository oldRepository(el.attribute(QLatin1String("oldUrl")), true);
@@ -319,19 +309,42 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
newRepository.setPassword(el.attribute(QLatin1String("password")));
newRepository.setDisplayName(el.attribute(QLatin1String("displayname")));
- // store the new repository and the one old it replaces
- repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository));
- qDebug() << "Replace repository:" << oldRepository.url().toString() << "with:"
- << newRepository.url().toString();
+ if (ProductKeyCheck::instance()->isValidRepository(newRepository)) {
+ // store the new repository and the one old it replaces
+ repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository));
+ qDebug() << "Replace repository:" << oldRepository.displayname() << "with:"
+ << newRepository.displayname();
+ }
} else {
qDebug() << "Invalid additional repositories action set in Updates.xml fetched from:"
- << m_repository.url().toString() << "Line:" << el.lineNumber();
+ << m_repository.displayname() << "Line:" << el.lineNumber();
}
}
}
if (!repositoryUpdates.isEmpty()) {
- if (m_core->settings().updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
+ const QSet<Repository> temporaries = m_core->settings().temporaryRepositories();
+ // in case the temp repository introduced something new, we only want that temporary
+ if (temporaries.contains(m_repository)) {
+
+ QSet<Repository> childTempRepositories;
+ typedef QPair<Repository, Repository> RepositoryPair;
+
+ QList<RepositoryPair> values = repositoryUpdates.values(QLatin1String("add"));
+ foreach (const RepositoryPair &value, values)
+ childTempRepositories.insert(value.first);
+
+ values = repositoryUpdates.values(QLatin1String("replace"));
+ foreach (const RepositoryPair &value, values)
+ childTempRepositories.insert(value.first);
+
+ QSet<Repository> newChildTempRepositories = childTempRepositories.subtract(temporaries);
+ if (newChildTempRepositories.count() > 0) {
+ m_core->settings().addTemporaryRepositories(newChildTempRepositories, true);
+ finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
+ return;
+ }
+ } else if (m_core->settings().updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
if (m_core->isUpdater() || m_core->isPackageManager())
m_core->writeMaintenanceConfigFiles();
finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
@@ -358,6 +371,19 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
}
}
+ try {
+ m_temporaryDirectory = createTemporaryDirectory(QLatin1String("remoterepo-"));
+ m_tempDirDeleter.add(m_temporaryDirectory);
+ } catch (const QInstaller::Error& e) {
+ finished(QInstaller::ExtractionError, e.message());
+ return;
+ }
+ if (!updatesFile.rename(m_temporaryDirectory + QLatin1String("/Updates.xml"))) {
+ finished(QInstaller::DownloadError, tr("Could not move Updates.xml to target location. Error: %1")
+ .arg(updatesFile.errorString()));
+ return;
+ }
+
setTotalAmount(m_packageNames.count() + 1);
setProcessedAmount(1);
emit infoMessage(this, tr("Finished updating component meta information."));
@@ -427,7 +453,7 @@ void GetRepositoryMetaInfoJob::fetchNextMetaInfo()
if (!m_downloader) {
m_currentPackageName.clear();
m_currentPackageVersion.clear();
- qWarning() << "Scheme not supported:" << url.toString();
+ qWarning() << "Scheme not supported:" << m_repository.displayname();
QMetaObject::invokeMethod(this, "fetchNextMetaInfo", Qt::QueuedConnection);
return;
}
diff --git a/src/libs/installer/init.cpp b/src/libs/installer/init.cpp
index 9ef72b4dd..12891f0e2 100644
--- a/src/libs/installer/init.cpp
+++ b/src/libs/installer/init.cpp
@@ -59,6 +59,7 @@
#include "minimumprogressoperation.h"
#include "licenseoperation.h"
#include "applyproductkeyoperation.h"
+#include "settingsoperation.h"
// QtSDK specific
#include "qtpatchoperation.h"
@@ -139,9 +140,12 @@ static void initResources()
{
Q_INIT_RESOURCE(patch_file_lists);
Q_INIT_RESOURCE(installer);
+ // Qt5 or better qmake generates that automatically, so this is only needed on Qt4
# if QT_VERSION < 0x050000
Q_IMPORT_PLUGIN(qico)
Q_UNUSED(qt_plugin_instance_qico());
+ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
+ Q_UNUSED(qt_plugin_instance_qtaccessiblewidgets());
# endif
}
#endif
@@ -237,6 +241,7 @@ void QInstaller::init()
factory.registerUpdateOperation<LicenseOperation>(QLatin1String("License"));
factory.registerUpdateOperation<ApplyProductKeyOperation>(QLatin1String("ApplyProductKey"));
factory.registerUpdateOperation<ConsumeOutputOperation>(QLatin1String("ConsumeOutput"));
+ factory.registerUpdateOperation<SettingsOperation>(QLatin1String("Settings"));
// QtSDK specific
factory.registerUpdateOperation<SetQtCreatorValueOperation>(QLatin1String("SetQtCreatorValue"));
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index a1631c4a3..149287428 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -101,7 +101,10 @@ HEADERS += packagemanagercore.h \
packagemanagercoredata.h \
applyproductkeyoperation.h \
globals.h \
- graph.h
+ graph.h \
+ settingsoperation.h \
+ testrepository.h \
+ packagemanagerpagefactory.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -163,7 +166,10 @@ HEADERS += packagemanagercore.h \
createlinkoperation.cpp \
packagemanagercoredata.cpp \
applyproductkeyoperation.cpp \
- globals.cpp
+ globals.cpp \
+ settingsoperation.cpp \
+ testrepository.cpp \
+ packagemanagerpagefactory.cpp
RESOURCES += resources/patch_file_lists.qrc \
resources/installer.qrc
diff --git a/src/libs/installer/link.cpp b/src/libs/installer/link.cpp
index f8b872f33..d7588d077 100644
--- a/src/libs/installer/link.cpp
+++ b/src/libs/installer/link.cpp
@@ -50,13 +50,7 @@
#endif
#ifdef Q_OS_WIN
-#ifdef Q_CC_MINGW
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-# endif
-#endif
-
-#include <windows.h>
+#include <qt_windows.h>
#include <winioctl.h>
#ifndef Q_CC_MINGW
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index c617dd239..09e1a5094 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -421,13 +421,26 @@ void PackageManagerCore::writeMaintenanceConfigFiles()
void PackageManagerCore::reset(const QHash<QString, QString> &params)
{
d->m_completeUninstall = false;
- d->m_forceRestart = false;
+ d->m_needsHardRestart = false;
d->m_status = PackageManagerCore::Unfinished;
d->m_installerBaseBinaryUnreplaced.clear();
d->initialize(params);
}
+void PackageManagerCore::setGuiObject(QObject *gui)
+{
+ if (gui == d->m_guiObject)
+ return;
+ d->m_guiObject = gui;
+ emit guiObjectChanged(gui);
+}
+
+QObject *PackageManagerCore::guiObject() const
+{
+ return d->m_guiObject;
+}
+
/*!
\qmlmethod void QInstaller::setCompleteUninstallation(bool complete)
@@ -532,11 +545,12 @@ quint64 PackageManagerCore::requiredDiskSpace() const
*/
quint64 PackageManagerCore::requiredTemporaryDiskSpace() const
{
- quint64 result = 0;
+ if (isOfflineOnly())
+ return 0;
+ quint64 result = 0;
foreach (QInstaller::Component *component, orderedComponentsToInstall())
result += size(component, scCompressedSize);
-
return result;
}
@@ -596,11 +610,17 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
If a component marked as important was installed during update
process true is returned.
*/
-bool PackageManagerCore::needsRestart() const
+bool PackageManagerCore::needsHardRestart() const
{
- return d->m_forceRestart;
+ return d->m_needsHardRestart;
}
+void PackageManagerCore::setNeedsHardRestart(bool needsHardRestart)
+{
+ d->m_needsHardRestart = needsHardRestart;
+}
+
+
void PackageManagerCore::rollBackInstallation()
{
emit titleMessageChanged(tr("Cancelling the Installer"));
@@ -629,6 +649,19 @@ void PackageManagerCore::rollBackInstallation()
const bool becameAdmin = !d->m_FSEngineClientHandler->isActive()
&& operation->value(QLatin1String("admin")).toBool() && gainAdminRights();
+ if (operation->hasValue(QLatin1String("uninstall-only"))) {
+ // We know the mkdir operation which is creating the target path. If we do a
+ // full uninstall, prevent a forced remove of the full install path including the
+ // target , instead try to remove the target only and only if it is empty,
+ // otherwise fail silently. Note: we will ever experience this only -if-
+ // RemoveTargetDir is set, otherwise the operation does not exist at all.
+ const bool isMkDir = (operation->name() == QLatin1String("Mkdir"));
+ const bool removeTargetDir = QVariant(value(scRemoveTargetDir)).toBool();
+ const bool uninstallOnly = operation->value(QLatin1String("uninstall-only")).toBool();
+ if (isMkDir && uninstallOnly && removeTargetDir)
+ operation->setValue(QLatin1String("forceremoval"), false);
+ }
+
PackageManagerCorePrivate::performOperationThreaded(operation, PackageManagerCorePrivate::Undo);
const QString componentName = operation->value(QLatin1String("component")).toString();
@@ -867,8 +900,8 @@ bool PackageManagerCore::fetchRemotePackagesTree()
return false;
}
- if (!ProductKeyCheck::instance(this)->hasValidKey()) {
- d->setStatus(Failure, ProductKeyCheck::instance(this)->lastErrorString());
+ if (!ProductKeyCheck::instance()->hasValidKey()) {
+ d->setStatus(Failure, ProductKeyCheck::instance()->lastErrorString());
return false;
}
@@ -1084,9 +1117,14 @@ void PackageManagerCore::setTestChecksum(bool test)
d->m_testChecksum = test;
}
-ScriptEngine *PackageManagerCore::scriptEngine()
+ScriptEngine *PackageManagerCore::componentScriptEngine() const
+{
+ return d->componentScriptEngine();
+}
+
+ScriptEngine *PackageManagerCore::controlScriptEngine() const
{
- return d->scriptEngine();
+ return d->controlScriptEngine();
}
/*!
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index 20a3293fa..392e5a018 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -125,6 +125,9 @@ public:
bool run();
void reset(const QHash<QString, QString> &params);
+ void setGuiObject(QObject *gui);
+ QObject *guiObject() const;
+
Q_INVOKABLE void setDependsOnLocalInstallerBinary();
Q_INVOKABLE bool localInstallerBinaryUsed();
@@ -177,7 +180,8 @@ public:
Q_INVOKABLE bool fileExists(const QString &filePath) const;
public:
- ScriptEngine *scriptEngine();
+ ScriptEngine *componentScriptEngine() const;
+ ScriptEngine *controlScriptEngine() const;
// component handling
@@ -248,7 +252,8 @@ public:
int downloadNeededArchives(double partProgressSize);
- bool needsRestart() const;
+ bool needsHardRestart() const;
+ void setNeedsHardRestart(bool needsHardRestart = true);
bool finishedWithSuccess() const;
public Q_SLOTS:
@@ -300,6 +305,8 @@ Q_SIGNALS:
void setAutomatedPageSwitchEnabled(bool request);
void coreNetworkSettingsChanged();
+ void guiObjectChanged(QObject *gui);
+
private:
struct Data {
Package *package;
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index cf34cc2e8..43df0cdf8 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -78,7 +78,7 @@
#include <errno.h>
#ifdef Q_OS_WIN
-#include <windows.h>
+#include <qt_windows.h>
#endif
namespace QInstaller {
@@ -212,10 +212,12 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
, m_repoFetched(false)
, m_updateSourcesAdded(false)
, m_componentsToInstallCalculated(false)
- , m_scriptEngine(0)
+ , m_componentScriptEngine(0)
+ , m_controlScriptEngine(0)
, m_proxyFactory(0)
, m_defaultModel(0)
, m_updaterModel(0)
+ , m_guiObject(0)
{
}
@@ -225,7 +227,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
, m_updaterApplication(new DummyConfigurationInterface)
, m_FSEngineClientHandler(initFSEngineClientHandler())
, m_status(PackageManagerCore::Unfinished)
- , m_forceRestart(false)
+ , m_needsHardRestart(false)
, m_testChecksum(false)
, m_launchedAsRoot(AdminAuthorization::hasAdminRights())
, m_completeUninstall(false)
@@ -239,10 +241,12 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
, m_updateSourcesAdded(false)
, m_magicBinaryMarker(magicInstallerMaker)
, m_componentsToInstallCalculated(false)
- , m_scriptEngine(0)
+ , m_componentScriptEngine(0)
+ , m_controlScriptEngine(0)
, m_proxyFactory(0)
, m_defaultModel(0)
, m_updaterModel(0)
+ , m_guiObject(0)
{
connect(this, SIGNAL(installationStarted()), m_core, SIGNAL(installationStarted()));
connect(this, SIGNAL(installationFinished()), m_core, SIGNAL(installationFinished()));
@@ -265,11 +269,13 @@ PackageManagerCorePrivate::~PackageManagerCorePrivate()
m_FSEngineClientHandler->setActive(false);
delete m_updateFinder;
- delete m_scriptEngine;
delete m_proxyFactory;
delete m_defaultModel;
delete m_updaterModel;
+
+ // at the moment the tabcontroller deletes the m_gui, this needs to be changed in the future
+ // delete m_gui;
}
/*!
@@ -392,11 +398,30 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
return true;
}
-ScriptEngine *PackageManagerCorePrivate::scriptEngine()
+void PackageManagerCorePrivate::cleanUpComponentEnvironment()
+{
+ // clean up already downloaded data, don't reset registered archives in offline installer case
+ if (QInstallerCreator::BinaryFormatEngineHandler::instance() && !m_core->isInstaller())
+ QInstallerCreator::BinaryFormatEngineHandler::instance()->resetRegisteredArchives();
+
+ // there could be still some references to already deleted components,
+ // so we need to remove the current component script engine
+ delete m_componentScriptEngine;
+ m_componentScriptEngine = 0;
+}
+
+ScriptEngine *PackageManagerCorePrivate::componentScriptEngine() const
{
- if (!m_scriptEngine)
- m_scriptEngine = new ScriptEngine(m_core);
- return m_scriptEngine;
+ if (!m_componentScriptEngine)
+ m_componentScriptEngine = new ScriptEngine(m_core);
+ return m_componentScriptEngine;
+}
+
+ScriptEngine *PackageManagerCorePrivate::controlScriptEngine() const
+{
+ if (!m_controlScriptEngine)
+ m_controlScriptEngine = new ScriptEngine(m_core);
+ return m_controlScriptEngine;
}
void PackageManagerCorePrivate::clearAllComponentLists()
@@ -411,6 +436,8 @@ void PackageManagerCorePrivate::clearAllComponentLists()
delete list.at(i).second;
m_componentsToReplaceAllMode.clear();
m_componentsToInstallCalculated = false;
+
+ cleanUpComponentEnvironment();
}
void PackageManagerCorePrivate::clearUpdaterComponentLists()
@@ -435,6 +462,8 @@ void PackageManagerCorePrivate::clearUpdaterComponentLists()
m_componentsToReplaceUpdaterMode.clear();
m_componentsToInstallCalculated = false;
+
+ cleanUpComponentEnvironment();
}
QList<Component *> &PackageManagerCorePrivate::replacementDependencyComponents()
@@ -572,16 +601,6 @@ QString PackageManagerCorePrivate::installReason(Component *component)
void PackageManagerCorePrivate::initialize(const QHash<QString, QString> &params)
{
- if (!ProductKeyCheck::instance(m_core)->hasValidKey()) {
- if (m_core->isInstaller()) {
- setStatus(PackageManagerCore::Failure, ProductKeyCheck::instance(m_core)->lastErrorString());
- } else {
- MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("ProductKeyCheckError"), ProductKeyCheck::instance(m_core)->lastErrorString(),
- ProductKeyCheck::instance(m_core)->maintainanceToolDetailErrorNotice(), QMessageBox::Ok);
- }
- }
-
m_coreCheckedHash.clear();
m_data = PackageManagerCoreData(params);
m_componentsToInstallCalculated = false;
@@ -1094,7 +1113,25 @@ void PackageManagerCorePrivate::writeUninstallerBinaryData(QIODevice *output, QF
const qint64 dataBlockStart = output->pos();
QVector<Range<qint64> >resourceSegments;
- foreach (const Range<qint64> &segment, layout.metadataResourceSegments) {
+ QVector<Range<qint64> >existingResourceSegments = layout.metadataResourceSegments;
+
+ const QString newDefaultResource = m_core->value(QString::fromLatin1("DefaultResourceReplacement"));
+ if (!newDefaultResource.isEmpty()) {
+ QFile file(newDefaultResource);
+ if (file.open(QIODevice::ReadOnly)) {
+ resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), file.size()));
+ appendData(output, &file, file.size());
+ existingResourceSegments.remove(0);
+
+ file.remove(); // clear all possible leftovers
+ m_core->setValue(QString::fromLatin1("DefaultResourceReplacement"), QString());
+ } else {
+ qWarning() << QString::fromLatin1("Could not replace default resource with '%1'.")
+ .arg(newDefaultResource);
+ }
+ }
+
+ foreach (const Range<qint64> &segment, existingResourceSegments) {
input->seek(segment.start());
resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), segment.length()));
appendData(output, input, segment.length());
@@ -1156,8 +1193,6 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
performedOperations.append(takeOwnedOperation(op));
}
- writeMaintenanceConfigFiles();
-
#ifdef Q_OS_MAC
// if it is a bundle, we need some stuff in it...
const QString sourceAppDirPath = QCoreApplication::applicationDirPath();
@@ -1264,7 +1299,7 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
bool newBinaryWritten = false;
bool replacementExists = false;
- const QString installerBaseBinary = m_core->replaceVariables(m_installerBaseBinaryUnreplaced);
+ const QString installerBaseBinary = replaceVariables(m_installerBaseBinaryUnreplaced);
if (!installerBaseBinary.isEmpty() && QFileInfo(installerBaseBinary).exists()) {
qDebug() << "Got a replacement installer base binary:" << installerBaseBinary;
@@ -1272,8 +1307,8 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
try {
openForRead(&replacementBinary, replacementBinary.fileName());
writeUninstallerBinary(&replacementBinary, replacementBinary.size(), true);
+ qDebug() << "Wrote the binary with the new replacement.";
- m_forceRestart = true;
newBinaryWritten = true;
replacementExists = true;
} catch (const Error &error) {
@@ -1283,10 +1318,17 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
if (!replacementBinary.remove()) {
// Is there anything more sensible we can do with this error? I think not. It's not serious
// enough for throwing / aborting the process.
- qDebug() << QString::fromLatin1("Could not remove installer base binary (%1) after updating "
+ qDebug() << QString::fromLatin1("Could not remove installer base binary '%1' after updating "
"the uninstaller: %2").arg(installerBaseBinary, replacementBinary.errorString());
+ } else {
+ qDebug() << QString::fromLatin1("Removed installer base binary '%1' after updating the "
+ "uninstaller/ maintenance tool.").arg(installerBaseBinary);
}
m_installerBaseBinaryUnreplaced.clear();
+ } else if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) {
+ qWarning() << QString::fromLatin1("The current uninstaller/ maintenance tool could not be "
+ "updated. '%1' does not exist. Please fix the 'setInstallerBaseBinary(<temp_installer_base_"
+ "binary_path>)' call in your script.").arg(installerBaseBinary);
}
QFile input;
@@ -1330,9 +1372,7 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
#endif
}
- performedOperations = sortOperationsBasedOnComponentDependencies(
- performedOperations);
-
+ performedOperations = sortOperationsBasedOnComponentDependencies(performedOperations);
m_core->setValue(QLatin1String("installedOperationAreSorted"), QLatin1String("true"));
try {
@@ -1363,10 +1403,11 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
appendInt64(&file, MagicCookie);
}
input.close();
+ writeMaintenanceConfigFiles();
deferredRename(dataFile + QLatin1String(".new"), dataFile, false);
if (newBinaryWritten) {
- const bool restart = replacementExists && isUpdater() && (!statusCanceledOrFailed());
+ const bool restart = replacementExists && isUpdater() && (!statusCanceledOrFailed()) && m_needsHardRestart;
deferredRename(uninstallerName() + QLatin1String(".new"), uninstallerName(), restart);
qDebug() << "Maintenance tool restart:" << (restart ? "true." : "false.");
}
@@ -1888,7 +1929,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
throw Error(operation->errorString());
if (component->value(scEssential, scFalse) == scTrue)
- m_forceRestart = true;
+ m_needsHardRestart = true;
}
registerPathesForUninstallation(component->pathesForUninstallation(), component->name());
@@ -2389,9 +2430,11 @@ OperationList PackageManagerCorePrivate::sortOperationsBasedOnComponentDependenc
// create the complete component graph
Graph<QString> componentGraph;
+ const QRegExp dash(QLatin1String("-.*"));
foreach (const Component* componentNode, m_core->availableComponents()) {
componentGraph.addNode(componentNode->name());
- componentGraph.addEdges(componentNode->name(), componentNode->dependencies());
+ const QStringList dependencies = componentNode->dependencies().replaceInStrings(dash,QString());
+ componentGraph.addEdges(componentNode->name(), dependencies);
}
foreach (const QString &componentName, componentGraph.sort())
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index d5bdc78fd..a6b9d4438 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -135,7 +135,10 @@ public:
bool buildComponentTree(QHash<QString, Component*> &components, bool loadScript);
- ScriptEngine *scriptEngine();
+ void cleanUpComponentEnvironment();
+ ScriptEngine *componentScriptEngine() const;
+ ScriptEngine *controlScriptEngine() const;
+
void clearAllComponentLists();
void clearUpdaterComponentLists();
QList<Component*> &replacementDependencyComponents();
@@ -205,7 +208,7 @@ public:
int m_status;
QString m_error;
- bool m_forceRestart;
+ bool m_needsHardRestart;
bool m_testChecksum;
bool m_launchedAsRoot;
bool m_completeUninstall;
@@ -263,7 +266,8 @@ private:
qint64 m_magicBinaryMarker;
bool m_componentsToInstallCalculated;
- ScriptEngine *m_scriptEngine;
+ mutable ScriptEngine *m_componentScriptEngine;
+ mutable ScriptEngine *m_controlScriptEngine;
// < name (component to replace), < replacement component, component to replace > >
QHash<QString, QPair<Component*, Component*> > m_componentsToReplaceAllMode;
QHash<QString, QPair<Component*, Component*> > m_componentsToReplaceUpdaterMode;
@@ -285,6 +289,8 @@ private:
ComponentModel *m_defaultModel;
ComponentModel *m_updaterModel;
+ QObject *m_guiObject;
+
private:
// remove once we deprecate isSelected, setSelected etc...
void resetComponentsToUserCheckedState();
diff --git a/src/libs/installer/packagemanagercoredata.cpp b/src/libs/installer/packagemanagercoredata.cpp
index 2294a8086..16fc6dc00 100644
--- a/src/libs/installer/packagemanagercoredata.cpp
+++ b/src/libs/installer/packagemanagercoredata.cpp
@@ -44,8 +44,14 @@
#include "fileutils.h"
#include "qsettingswrapper.h"
+#include <QDesktopServices>
#include <QDir>
+#ifdef Q_OS_WIN
+# include <windows.h>
+# include <shlobj.h>
+#endif
+
namespace QInstaller
{
@@ -61,6 +67,20 @@ PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &va
m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
m_variables.insert(scTargetConfigurationFile, QLatin1String("components.xml"));
+ QString dir = QLatin1String("/opt");
+#ifdef Q_OS_WIN
+ TCHAR buffer[MAX_PATH + 1] = { 0 };
+ SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0, buffer);
+ dir = QString::fromWCharArray(buffer);
+#elif defined (Q_OS_MAC)
+# if QT_VERSION < 0x050000
+ dir = QDesktopServices::storageLocation(QDesktopServices::ApplicationsLocation);
+# else
+ dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
+# endif
+#endif
+ m_variables.insert(QLatin1String("ApplicationsDir"), dir);
+
#ifdef Q_OS_WIN
m_variables.insert(QLatin1String("os"), QLatin1String("win"));
#elif defined(Q_OS_MAC)
@@ -138,7 +158,7 @@ QVariant PackageManagerCoreData::value(const QString &key, const QVariant &_defa
if (key == scTargetDir) {
QString dir = m_variables.value(key);
if (dir.isEmpty())
- dir = m_settings.value(key, _default).toString();
+ dir = replaceVariables(m_settings.value(key, _default).toString());
#ifdef Q_OS_WIN
return QInstaller::normalizePathName(dir);
#else
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index c70d00f13..9d6414adc 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -128,7 +128,7 @@ public:
setPixmap(QWizard::BannerPixmap, QPixmap());
setLayout(new QVBoxLayout);
- setColoredSubTitle(QString());
+ setColoredSubTitle(QLatin1String(" "));
setColoredTitle(widget->windowTitle());
m_widget->setProperty("complete", true);
m_widget->setProperty("final", false);
@@ -252,7 +252,7 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent)
connect(m_core, SIGNAL(installationFinished()), this, SLOT(showFinishedPage()), Qt::QueuedConnection);
connect(m_core, SIGNAL(uninstallationFinished()), this, SLOT(showFinishedPage()), Qt::QueuedConnection);
- connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(slotCurrentPageChanged(int)));
+ connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(executeControlScript(int)));
connect(this, SIGNAL(currentIdChanged(int)), m_core, SIGNAL(currentPageChanged(int)));
connect(button(QWizard::FinishButton), SIGNAL(clicked()), this, SIGNAL(finishButtonClicked()));
connect(button(QWizard::FinishButton), SIGNAL(clicked()), m_core, SIGNAL(finishButtonClicked()));
@@ -283,7 +283,7 @@ 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);
+ m_core->setGuiObject(this);
}
PackageManagerGui::~PackageManagerGui()
@@ -318,8 +318,8 @@ void PackageManagerGui::clickButton(int wb, int delay)
{
// transform the FinishButton to CancelButton, because of the needed misuse of the
// CancelButton as a FinishButton to have some more control of closing the wizard
- if (!m_core->isInstaller() && currentId() == PackageManagerCore::InstallationFinished &&
- wb == QWizard::FinishButton) {
+ if ((m_core->isUpdater() || m_core->isPackageManager()) && currentId() ==
+ PackageManagerCore::InstallationFinished && wb == QWizard::FinishButton) {
wb = QWizard::CancelButton;
}
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
@@ -332,8 +332,8 @@ bool PackageManagerGui::isButtonEnabled(int wb)
{
// transform the FinishButton to CancelButton, because of the needed misuse of the
// CancelButton as a FinishButton to have some more control of closing the wizard
- if (!m_core->isInstaller() && currentId() == PackageManagerCore::InstallationFinished &&
- wb == QWizard::FinishButton) {
+ if ((m_core->isUpdater() || m_core->isPackageManager()) && currentId() ==
+ PackageManagerCore::InstallationFinished && wb == QWizard::FinishButton) {
wb = QWizard::CancelButton;
}
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
@@ -365,23 +365,17 @@ void PackageManagerGui::setValidatorForCustomPageRequested(Component *component,
*/
void PackageManagerGui::loadControlScript(const QString &scriptPath)
{
- d->m_controlScriptContext = m_core->scriptEngine()->loadInConext(
+ d->m_controlScriptContext = m_core->controlScriptEngine()->loadInConext(
QLatin1String("Controller"), scriptPath);
qDebug() << "Loaded control script" << scriptPath;
}
-void PackageManagerGui::slotCurrentPageChanged(int id)
-{
- QMetaObject::invokeMethod(this, "delayedControlScriptExecution", Qt::QueuedConnection,
- Q_ARG(int, id));
-}
-
void PackageManagerGui::callControlScriptMethod(const QString &methodName)
{
if (!d->m_controlScriptContext.isValid())
return;
try {
- QScriptValue returnValue = m_core->scriptEngine()->callScriptMethod(
+ QScriptValue returnValue = m_core->controlScriptEngine()->callScriptMethod(
d->m_controlScriptContext, methodName);
if (!returnValue.isValid()) {
@@ -393,9 +387,9 @@ void PackageManagerGui::callControlScriptMethod(const QString &methodName)
}
}
-void PackageManagerGui::delayedControlScriptExecution(int id)
+void PackageManagerGui::executeControlScript(int pageId)
{
- if (PackageManagerPage *const p = qobject_cast<PackageManagerPage*> (page(id)))
+ if (PackageManagerPage *const p = qobject_cast<PackageManagerPage*> (page(pageId)))
callControlScriptMethod(p->objectName() + QLatin1String("Callback"));
}
@@ -541,6 +535,7 @@ void PackageManagerGui::cancelButtonClicked()
QDialog::reject();
}
} else {
+ m_core->setNeedsHardRestart(false);
QDialog::reject();
}
}
@@ -645,6 +640,7 @@ void PackageManagerGui::dependsOnLocalInstallerBinary()
PackageManagerPage::PackageManagerPage(PackageManagerCore *core)
: m_fresh(true)
, m_complete(true)
+ , m_needsSettingsButton(false)
, m_core(core)
, validatorComponent(0)
{
@@ -1905,7 +1901,7 @@ void FinishedPage::entering()
if (!finishedText.isEmpty())
m_msgLabel->setText(finishedText);
- if (!packageManagerCore()->value(scRunProgram).isEmpty()) {
+ if (!packageManagerCore()->isUninstaller() && !packageManagerCore()->value(scRunProgram).isEmpty()) {
m_runItCheckBox->show();
m_runItCheckBox->setText(packageManagerCore()->value(scRunProgramDescription, tr("Run %1 now."))
.arg(productName()));
@@ -1938,7 +1934,7 @@ void FinishedPage::handleFinishClicked()
{
const QString program = packageManagerCore()->replaceVariables(packageManagerCore()->value(scRunProgram));
const QStringList args = packageManagerCore()->replaceVariables(
- packageManagerCore()->value(scRunProgramArguments)).split(QLatin1Char(' '));
+ packageManagerCore()->value(scRunProgramArguments)).split(QLatin1Char(' '), QString::SkipEmptyParts);
if (!m_runItCheckBox->isChecked() || program.isEmpty())
return;
@@ -1977,7 +1973,7 @@ int RestartPage::nextId() const
void RestartPage::entering()
{
- if (!packageManagerCore()->needsRestart()) {
+ if (!packageManagerCore()->needsHardRestart()) {
if (QAbstractButton *finish = wizard()->button(QWizard::FinishButton))
finish->setVisible(false);
QMetaObject::invokeMethod(this, "restart", Qt::QueuedConnection);
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index 2039dabfb..948fb346a 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -60,7 +60,6 @@ class QListWidget;
class QListWidgetItem;
class QRadioButton;
class QTextBrowser;
-class QScriptEngine;
QT_END_NAMESPACE
namespace QInstaller {
@@ -117,8 +116,7 @@ protected Q_SLOTS:
void wizardWidgetInsertionRequested(QWidget *widget, QInstaller::PackageManagerCore::WizardPage page);
void wizardWidgetRemovalRequested(QWidget *widget);
void wizardPageVisibilityChangeRequested(bool visible, int page);
- void slotCurrentPageChanged(int id);
- void delayedControlScriptExecution(int id);
+ void executeControlScript(int pageId);
void setValidatorForCustomPageRequested(QInstaller::Component *component, const QString &name,
const QString &callbackName);
@@ -168,6 +166,10 @@ public:
void setValidatePageComponent(QInstaller::Component *component);
bool validatePage();
+
+ bool settingsButtonRequested() const { return m_needsSettingsButton; }
+ void setSettingsButtonRequested(bool request) { m_needsSettingsButton = request; }
+
signals:
void entered();
void left();
@@ -192,6 +194,7 @@ private:
bool m_fresh;
bool m_complete;
QString m_titleColor;
+ bool m_needsSettingsButton;
PackageManagerCore *m_core;
QInstaller::Component *validatorComponent;
diff --git a/src/libs/installer/packagemanagerpagefactory.cpp b/src/libs/installer/packagemanagerpagefactory.cpp
new file mode 100644
index 000000000..ddfb5b6d4
--- /dev/null
+++ b/src/libs/installer/packagemanagerpagefactory.cpp
@@ -0,0 +1,57 @@
+/**************************************************************************
+**
+** Copyright (C) 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 <packagemanagerpagefactory.h>
+
+namespace QInstaller {
+
+PackageManagerPageFactory &PackageManagerPageFactory::instance()
+{
+ static PackageManagerPageFactory factory;
+ return factory;
+}
+
+PackageManagerPage *PackageManagerPageFactory::create(int id, PackageManagerCore *core) const
+{
+ return KDGenericFactory<PackageManagerPage, int, PackageManagerCore*>::createWithArg(id, core);
+}
+
+}
diff --git a/src/libs/installer/packagemanagerpagefactory.h b/src/libs/installer/packagemanagerpagefactory.h
new file mode 100644
index 000000000..001fb6cd5
--- /dev/null
+++ b/src/libs/installer/packagemanagerpagefactory.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+**
+** Copyright (C) 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 PACKAGEMANAGERPAGEFACTORY_H
+#define PACKAGEMANAGERPAGEFACTORY_H
+
+#include <kdgenericfactory.h>
+#include <packagemanagergui.h>
+
+namespace QInstaller {
+
+class PackageManagerCore;
+class PackageManagerPage;
+
+class INSTALLER_EXPORT PackageManagerPageFactory : public KDGenericFactory<PackageManagerPage,
+ int, QInstaller::PackageManagerCore*>
+{
+ Q_DISABLE_COPY(PackageManagerPageFactory)
+
+public:
+ static PackageManagerPageFactory &instance();
+ template<typename T> void registerPackageManagerPage(int id)
+ {
+ registerProductWithArg<T>(id);
+ }
+ PackageManagerPage *create(int id, QInstaller::PackageManagerCore *core) const;
+
+private:
+ PackageManagerPageFactory() {}
+};
+
+} // namespace QInstaller
+
+#endif // PACKAGEMANAGERPAGEFACTORY_H
diff --git a/src/libs/installer/packagemanagerproxyfactory.cpp b/src/libs/installer/packagemanagerproxyfactory.cpp
index 42f8e9893..219ff5e49 100644
--- a/src/libs/installer/packagemanagerproxyfactory.cpp
+++ b/src/libs/installer/packagemanagerproxyfactory.cpp
@@ -79,8 +79,10 @@ QList<QNetworkProxy> PackageManagerProxyFactory::queryProxy(const QNetworkProxyQ
if (query.url().scheme() == QLatin1String("ftp"))
return list << settings.ftpProxy();
- if (query.url().scheme() == QLatin1String("http"))
- return list << settings.httpProxy();
+ if ((query.url().scheme() == QLatin1String("http"))
+ || (query.url().scheme() == QLatin1String("https"))) {
+ return list << settings.httpProxy();
+ }
}
return list << QNetworkProxy(QNetworkProxy::DefaultProxy);
}
diff --git a/src/libs/installer/productkeycheck.cpp b/src/libs/installer/productkeycheck.cpp
index a4af2b6d3..232dbb719 100644
--- a/src/libs/installer/productkeycheck.cpp
+++ b/src/libs/installer/productkeycheck.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (c) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (c) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Installer Framework
@@ -27,18 +27,13 @@
**
**************************************************************************/
-#include <productkeycheck.h>
-#include <packagemanagercore.h>
+#include "productkeycheck.h"
+#include "packagemanagercore.h"
class ProductKeyCheckPrivate
{
- public:
- static QPointer<QInstaller::PackageManagerCore> core;
};
-QPointer<QInstaller::PackageManagerCore> ProductKeyCheckPrivate::core = 0;
-
-
ProductKeyCheck::ProductKeyCheck()
: d(new ProductKeyCheckPrivate())
{
@@ -49,20 +44,17 @@ ProductKeyCheck::~ProductKeyCheck()
delete d;
}
-ProductKeyCheck *ProductKeyCheck::instance(QInstaller::PackageManagerCore *core)
+ProductKeyCheck *ProductKeyCheck::instance()
{
static ProductKeyCheck instance;
- if (core)
- instance.setPackageManagerCore(core);
return &instance;
}
-void ProductKeyCheck::setPackageManagerCore(QInstaller::PackageManagerCore *core)
+void ProductKeyCheck::init(QInstaller::PackageManagerCore *core)
{
- ProductKeyCheckPrivate::core = core;
+ Q_UNUSED(core)
}
-
bool ProductKeyCheck::hasValidKey()
{
return true;
@@ -89,9 +81,13 @@ bool ProductKeyCheck::isValidLicenseTextFile(const QString &/*fileName*/)
return true;
}
-
bool ProductKeyCheck::isValidRepository(const QInstaller::Repository &repository) const
{
Q_UNUSED(repository)
return true;
-} \ No newline at end of file
+}
+
+QList<int> ProductKeyCheck::registeredPages() const
+{
+ return QList<int>();
+}
diff --git a/src/libs/installer/productkeycheck.h b/src/libs/installer/productkeycheck.h
index 6d72089e2..3df747f37 100644
--- a/src/libs/installer/productkeycheck.h
+++ b/src/libs/installer/productkeycheck.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (c) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (c) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Installer Framework
@@ -30,11 +30,9 @@
#ifndef PRODUCTKEYCHECK_H
#define PRODUCTKEYCHECK_H
-#include "qinstallerglobal.h"
+#include "installer_global.h"
#include <QString>
-#include <QHash>
-#include <QPointer>
namespace QInstaller{
class PackageManagerCore;
@@ -47,8 +45,8 @@ class INSTALLER_EXPORT ProductKeyCheck
{
public:
~ProductKeyCheck();
- static ProductKeyCheck *instance(QInstaller::PackageManagerCore *core = 0);
- static void setPackageManagerCore(QInstaller::PackageManagerCore *core);
+ static ProductKeyCheck *instance();
+ void init(QInstaller::PackageManagerCore *core);
// was validLicense
bool hasValidKey();
@@ -64,9 +62,12 @@ public:
// to filter repositories not matching the license
bool isValidRepository(const QInstaller::Repository &repository) const;
+ QList<int> registeredPages() const;
+
private:
ProductKeyCheck();
ProductKeyCheckPrivate *const d;
+ Q_DISABLE_COPY(ProductKeyCheck)
};
#endif // PRODUCTKEYCHECK_H
diff --git a/src/libs/installer/progresscoordinator.cpp b/src/libs/installer/progresscoordinator.cpp
index 0850b39d0..e55f4b8bb 100644
--- a/src/libs/installer/progresscoordinator.cpp
+++ b/src/libs/installer/progresscoordinator.cpp
@@ -103,6 +103,14 @@ void ProgressCoordinator::registerPartProgress(QObject *sender, const char *sign
Q_ASSERT(isConnected);
}
+
+/*!
+ This slot gets the progress changed signals from different tasks. The values 0 and 1 are handled as
+ special values.
+
+ 0 - is just ignored, so you can use a timer which gives the progress, e.g. like a downloader does.
+ 1 - means the task is finished, even if there comes another 1 from that task, so it will be ignored.
+*/
void ProgressCoordinator::partProgressChanged(double fraction)
{
if (fraction < 0 || fraction > 1) {
@@ -110,6 +118,16 @@ void ProgressCoordinator::partProgressChanged(double fraction)
return;
}
+ // no fraction no change
+ if (fraction == 0)
+ return;
+
+ // ignore senders sending 100% multiple times
+ if (fraction == 1 && m_senderPendingCalculatedPercentageHash.contains(sender())
+ && m_senderPendingCalculatedPercentageHash.value(sender()) == 0) {
+ return;
+ }
+
double partProgressSize = m_senderPartProgressSizeHash.value(sender(), 0);
if (partProgressSize == 0) {
qWarning() << "It seems that this sender was not registered in the right way:" << sender();
@@ -137,9 +155,9 @@ void ProgressCoordinator::partProgressChanged(double fraction)
newCurrentCompletePercentage = 100;
}
- if (qRound(m_currentCompletePercentage) < qRound(newCurrentCompletePercentage)) {
- qWarning("This should not happen!");
- }
+ // In undo mode, the progress has to go backward, new has to be smaller than current
+ if (qRound(m_currentCompletePercentage) < qRound(newCurrentCompletePercentage))
+ qDebug("Something is wrong with the calculation of the progress.");
m_currentCompletePercentage = newCurrentCompletePercentage;
if (fraction == 1) {
@@ -170,12 +188,13 @@ void ProgressCoordinator::partProgressChanged(double fraction)
newCurrentCompletePercentage = 100;
}
- if (qRound(m_currentCompletePercentage) > qRound(newCurrentCompletePercentage)) {
- qWarning("This should not happen!");
- }
+ // In normal mode, the progress has to go forward, new has to be larger than current
+ if (qRound(m_currentCompletePercentage) > qRound(newCurrentCompletePercentage))
+ qDebug("Something is wrong with the calculation of the progress.");
+
m_currentCompletePercentage = newCurrentCompletePercentage;
- if (fraction == 1 || fraction == 0) {
+ if (fraction == 1) {
m_currentBasePercentage = m_currentBasePercentage + pendingCalculatedPartPercentage;
m_senderPendingCalculatedPercentageHash.insert(sender(), 0);
} else {
diff --git a/src/libs/installer/progresscoordinator.h b/src/libs/installer/progresscoordinator.h
index 263b25695..bdd154195 100644
--- a/src/libs/installer/progresscoordinator.h
+++ b/src/libs/installer/progresscoordinator.h
@@ -42,13 +42,15 @@
#ifndef PROGRESSCOORDINATOR_H
#define PROGRESSCOORDINATOR_H
+#include "installer_global.h"
+
#include <QtCore/QHash>
#include <QtCore/QObject>
#include <QtCore/QPointer>
namespace QInstaller {
-class ProgressCoordinator : public QObject
+class INSTALLER_EXPORT ProgressCoordinator : public QObject
{
Q_OBJECT
diff --git a/src/libs/installer/qtpatch.cpp b/src/libs/installer/qtpatch.cpp
index 7a1e18df3..825c9ad48 100644
--- a/src/libs/installer/qtpatch.cpp
+++ b/src/libs/installer/qtpatch.cpp
@@ -75,7 +75,7 @@ QHash<QString, QByteArray> QtPatch::qmakeValues(const QString &qmakePath, QByteA
// in some cases qmake is not runable, because another process is blocking it(filewatcher ...)
int waitCount = 0;
- while (qmakeValueHash.isEmpty() && waitCount < 60) {
+ while (qmakeValueHash.isEmpty() && waitCount < 3) {
QFileInfo qmake(qmakePath);
if (!qmake.exists()) {
@@ -92,13 +92,16 @@ QHash<QString, QByteArray> QtPatch::qmakeValues(const QString &qmakePath, QByteA
QProcess process;
process.start(qmake.absoluteFilePath(), args, QIODevice::ReadOnly);
- if (process.waitForFinished(2000)) {
+ if (process.waitForFinished(10000)) {
+ QByteArray output = process.readAllStandardOutput();
+ qmakeOutput->append(output);
if (process.exitStatus() == QProcess::CrashExit) {
- qDebug() << qmakePath << "was crashed";
+ qWarning() << qmake.absoluteFilePath() << args
+ << "crashed with exit code" << process.exitCode()
+ << "standard output: " << output
+ << "error output: " << process.readAllStandardError();
return qmakeValueHash;
}
- QByteArray output = process.readAllStandardOutput();
- qmakeOutput->append(output);
qmakeValueHash = readQmakeOutput(output);
}
if (qmakeValueHash.isEmpty()) {
diff --git a/src/libs/installer/resources/files-to-patch-linux-emb-arm b/src/libs/installer/resources/files-to-patch-linux-emb-arm
index f6a4b59b7..8ea297b50 100644
--- a/src/libs/installer/resources/files-to-patch-linux-emb-arm
+++ b/src/libs/installer/resources/files-to-patch-linux-emb-arm
@@ -8,5 +8,5 @@ host-bin/qdoc
*.la
*.prl
*.pc
-
-
+*.pri
+*.cmake
diff --git a/src/libs/installer/resources/files-to-patch-linux-emb-arm-qt4 b/src/libs/installer/resources/files-to-patch-linux-emb-arm-qt4
new file mode 100644
index 000000000..f6a4b59b7
--- /dev/null
+++ b/src/libs/installer/resources/files-to-patch-linux-emb-arm-qt4
@@ -0,0 +1,12 @@
+bin/qmake
+bin/lrelease
+bin/qdoc
+host-bin/qmake
+host-bin/lrelease
+host-bin/qdoc
+%%
+*.la
+*.prl
+*.pc
+
+
diff --git a/src/libs/installer/resources/files-to-patch-linux-emb-arm-qt5 b/src/libs/installer/resources/files-to-patch-linux-emb-arm-qt5
new file mode 100644
index 000000000..8ea297b50
--- /dev/null
+++ b/src/libs/installer/resources/files-to-patch-linux-emb-arm-qt5
@@ -0,0 +1,12 @@
+bin/qmake
+bin/lrelease
+bin/qdoc
+host-bin/qmake
+host-bin/lrelease
+host-bin/qdoc
+%%
+*.la
+*.prl
+*.pc
+*.pri
+*.cmake
diff --git a/src/libs/installer/resources/files-to-patch-macx-emb-arm b/src/libs/installer/resources/files-to-patch-macx-emb-arm-qt5
index c01fe17a1..c01fe17a1 100644
--- a/src/libs/installer/resources/files-to-patch-macx-emb-arm
+++ b/src/libs/installer/resources/files-to-patch-macx-emb-arm-qt5
diff --git a/src/libs/installer/resources/files-to-patch-windows-emb-arm b/src/libs/installer/resources/files-to-patch-windows-emb-arm
index 674adaff6..a43229d18 100644
--- a/src/libs/installer/resources/files-to-patch-windows-emb-arm
+++ b/src/libs/installer/resources/files-to-patch-windows-emb-arm
@@ -8,4 +8,6 @@ host-bin/qdoc.exe
*.la
*.prl
*.pc
+*.pri
+*.cmake
diff --git a/src/libs/installer/resources/files-to-patch-windows-emb-arm-qt5 b/src/libs/installer/resources/files-to-patch-windows-emb-arm-qt5
new file mode 100644
index 000000000..a43229d18
--- /dev/null
+++ b/src/libs/installer/resources/files-to-patch-windows-emb-arm-qt5
@@ -0,0 +1,13 @@
+bin/qmake.exe
+bin/lrelease.exe
+bin/qdoc.exe
+host-bin/qmake.exe
+host-bin/lrelease.exe
+host-bin/qdoc.exe
+%%
+*.la
+*.prl
+*.pc
+*.pri
+*.cmake
+
diff --git a/src/libs/installer/resources/patch_file_lists.qrc b/src/libs/installer/resources/patch_file_lists.qrc
index e898b9b23..b300b69ac 100644
--- a/src/libs/installer/resources/patch_file_lists.qrc
+++ b/src/libs/installer/resources/patch_file_lists.qrc
@@ -8,6 +8,8 @@
<file>files-to-patch-macx-qt5</file>
<file>files-to-patch-linux-emb-arm</file>
<file>files-to-patch-windows-emb-arm</file>
- <file>files-to-patch-macx-emb-arm</file>
+ <file>files-to-patch-windows-emb-arm-qt5</file>
+ <file>files-to-patch-macx-emb-arm-qt5</file>
+ <file>files-to-patch-linux-emb-arm-qt5</file>
</qresource>
</RCC>
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index e85ce9671..a2fe9f049 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -192,6 +192,7 @@ ScriptEngine::ScriptEngine(PackageManagerCore *core)
installTranslatorFunctions();
globalObject().setProperty(QLatin1String("QMessageBox"), generateMessageBoxObject());
+ globalObject().setProperty(QLatin1String("buttons"), generateWizardButtonsObject());
globalObject().setProperty(QLatin1String("QDesktopServices"), generateDesktopServicesObject());
globalObject().setProperty(QLatin1String("QInstaller"), generateQInstallerObject());
@@ -216,6 +217,9 @@ ScriptEngine::ScriptEngine(PackageManagerCore *core)
.setProperty(QLatin1String("components"), scriptComponentsObject);
connect(this, SIGNAL(signalHandlerException(QScriptValue)), SLOT(handleException(QScriptValue)));
+
+ connect(core, SIGNAL(guiObjectChanged(QObject*)), this, SLOT(setGuiQObject(QObject*)));
+ setGuiQObject(core->guiObject());
}
ScriptEngine::~ScriptEngine()
@@ -224,25 +228,6 @@ 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));
}
@@ -324,6 +309,27 @@ QScriptValue ScriptEngine::callScriptMethod(const QScriptValue &scriptContext,
}
+QScriptValue 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
+ return buttons;
+}
+
/*!
generates QMessageBox::StandardButton enum as an QScriptValue array
*/
diff --git a/src/libs/installer/scriptengine.h b/src/libs/installer/scriptengine.h
index 50c50539b..e52862e06 100644
--- a/src/libs/installer/scriptengine.h
+++ b/src/libs/installer/scriptengine.h
@@ -70,14 +70,15 @@ class INSTALLER_EXPORT ScriptEngine : public QScriptEngine
public:
explicit ScriptEngine(PackageManagerCore *core);
~ScriptEngine();
- void setGuiQObject(QObject *guiQObject);
QScriptValue callScriptMethod(const QScriptValue &scriptContext, const QString &methodName,
const QScriptValueList &arguments = QScriptValueList()) const;
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();
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index 067dce47c..90cb431f4 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -573,6 +573,11 @@ bool Settings::repositorySettingsPageVisible() const
return d->m_data.value(scRepositorySettingsPageVisible, true).toBool();
}
+void Settings::setRepositorySettingsPageVisible(bool visible)
+{
+ d->m_data.insert(scRepositorySettingsPageVisible, visible);
+}
+
Settings::ProxyType Settings::proxyType() const
{
return Settings::ProxyType(d->m_data.value(scProxyType, Settings::NoProxy).toInt());
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index d8c827c61..9bce8bd70 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -144,6 +144,7 @@ public:
QVariantList values(const QString &key, const QVariantList &defaultValue = QVariantList()) const;
bool repositorySettingsPageVisible() const;
+ void setRepositorySettingsPageVisible(bool visible);
Settings::ProxyType proxyType() const;
void setProxyType(Settings::ProxyType type);
diff --git a/src/libs/installer/settingsoperation.cpp b/src/libs/installer/settingsoperation.cpp
new file mode 100644
index 000000000..6fde21268
--- /dev/null
+++ b/src/libs/installer/settingsoperation.cpp
@@ -0,0 +1,216 @@
+/**************************************************************************
+**
+** Copyright (C) 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 "settingsoperation.h"
+#include "packagemanagercore.h"
+#include "kdupdaterupdateoperations.h"
+
+#include <QSettings>
+#include <QDir>
+#include <QDebug>
+
+using namespace QInstaller;
+
+SettingsOperation::SettingsOperation()
+{
+ setName(QLatin1String("Settings"));
+}
+
+void SettingsOperation::backup()
+{
+}
+
+bool SettingsOperation::checkArguments()
+{
+ const QString path = argumentKeyValue(QLatin1String("path"));
+ const QString method = argumentKeyValue(QLatin1String("method"));
+ const QString key = argumentKeyValue(QLatin1String("key"));
+ const QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ QStringList missingArguments;
+ if (path.isEmpty())
+ missingArguments << QLatin1String("path");
+ if (method.isEmpty())
+ missingArguments << QLatin1String("method");
+ if (key.isEmpty())
+ missingArguments << QLatin1String("key");
+ if (method != QLatin1String("remove") && aValue.isEmpty())
+ missingArguments << QLatin1String("value");
+
+ if (!missingArguments.isEmpty()) {
+ setError(InvalidArguments);
+ setErrorString(tr("Missing argument(s) '%1' calling '%2' with arguments '%3'.").arg(
+ missingArguments.join(QLatin1String("; ")), name(), arguments().join(QLatin1String("; "))));
+ return false;
+ }
+ QStringList possibleMethodValues;
+ possibleMethodValues << QLatin1String("set") << QLatin1String("remove") <<
+ QLatin1String("add_array_value") << QLatin1String("remove_array_value");
+
+ if (!possibleMethodValues.contains(method)) {
+ setError(InvalidArguments);
+ setErrorString(tr("Current method argument calling '%1' with arguments '%2' is not "
+ "supported. Please use set, remove, add_array_value or remove_array_value.").arg(name(),
+ arguments().join(QLatin1String("; "))));
+ return false;
+ }
+ return true;
+}
+
+
+bool SettingsOperation::performOperation()
+{
+ // Arguments:
+ // 1. path=settings file path or registry path
+ // 2. method=set|remove|add_array_value|remove_array_value
+ // 3. key=can be prepended by a category name separated by slash
+ // 4. value=just the value
+ // optional arguments are
+ // formate=native or ini TODO
+ // backup=true or false (default is true) TODO
+ // NOTE: remove and remove_array_value will do nothing at the undostep
+
+ if (!checkArguments())
+ return false;
+ const QString path = argumentKeyValue(QLatin1String("path"));
+ const QString method = argumentKeyValue(QLatin1String("method"));
+ const QString key = argumentKeyValue(QLatin1String("key"));
+ const QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ // use MkdirOperation to get the path so it can remove it with MkdirOperation::undoOperation later
+ KDUpdater::MkdirOperation mkDirOperation;
+ mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
+ mkDirOperation.backup();
+ if (!mkDirOperation.performOperation()) {
+ setError(mkDirOperation.error());
+ setErrorString(mkDirOperation.errorString());
+ return false;
+ }
+ setValue(QLatin1String("createddir"), mkDirOperation.value(QLatin1String("createddir")));
+
+ QSettings settings(path, QSettings::IniFormat);
+ if (method == QLatin1String("set"))
+ settings.setValue(key, aValue);
+ else if (method == QLatin1String("remove"))
+ settings.remove(key);
+ else if (method == QLatin1String("add_array_value")) {
+ QVariant valueVariant = settings.value(key);
+ if (valueVariant.canConvert<QStringList>()) {
+ QStringList array = valueVariant.toStringList();
+ array.append(aValue);
+ settings.setValue(key, array);
+ } else {
+ settings.setValue(key, aValue);
+ }
+ } else if (method == QLatin1String("remove_array_value")) {
+ QVariant valueVariant = settings.value(key);
+ if (valueVariant.canConvert<QStringList>()) {
+ QStringList array = valueVariant.toStringList();
+ array.removeOne(aValue);
+ settings.setValue(key, array);
+ } else {
+ settings.remove(key);
+ }
+ }
+
+ return true;
+}
+
+bool SettingsOperation::undoOperation()
+{
+ if (!checkArguments())
+ return false;
+ const QString path = argumentKeyValue(QLatin1String("path"));
+ const QString method = argumentKeyValue(QLatin1String("method"));
+ const QString key = argumentKeyValue(QLatin1String("key"));
+ const QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ if (method.startsWith(QLatin1String("remove")))
+ return true;
+
+ bool cleanUp = false;
+ { // kill the scope to kill settings object, else remove file will not work
+ QSettings settings(path, QSettings::IniFormat);
+ if (method == QLatin1String("set")) {
+ settings.remove(key);
+ } else if (method == QLatin1String("add_array_value")) {
+ QVariant valueVariant = settings.value(key);
+ if (valueVariant.canConvert<QStringList>()) {
+ QStringList array = valueVariant.toStringList();
+ array.removeOne(aValue);
+ if (array.isEmpty())
+ settings.remove(key);
+ else
+ settings.setValue(key, array);
+ } else {
+ settings.setValue(key, aValue);
+ }
+ }
+ settings.sync(); // be safe
+ cleanUp = settings.allKeys().isEmpty();
+ }
+
+ if (cleanUp) {
+ QFile settingsFile(path);
+ if (!settingsFile.remove())
+ qWarning() << settingsFile.errorString();
+ if (!value(QLatin1String("createddir")).toString().isEmpty()) {
+ KDUpdater::MkdirOperation mkDirOperation;
+ mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
+ mkDirOperation.setValue(QLatin1String("createddir"), value(QLatin1String("createddir")));
+
+ if (!mkDirOperation.undoOperation()) {
+ qWarning() << mkDirOperation.errorString();
+ }
+ }
+ }
+ return true;
+}
+
+bool SettingsOperation::testOperation()
+{
+ return true;
+}
+
+Operation *SettingsOperation::clone() const
+{
+ return new SettingsOperation();
+}
+
diff --git a/src/libs/installer/settingsoperation.h b/src/libs/installer/settingsoperation.h
new file mode 100644
index 000000000..248c9a0df
--- /dev/null
+++ b/src/libs/installer/settingsoperation.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** Copyright (C) 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 SETTINGSOPERATION_H
+#define SETTINGSOPERATION_H
+
+#include "qinstallerglobal.h"
+
+namespace QInstaller {
+
+class INSTALLER_EXPORT SettingsOperation : public Operation
+{
+public:
+ SettingsOperation();
+
+ void backup();
+ bool performOperation();
+ bool undoOperation();
+ bool testOperation();
+ Operation *clone() const;
+
+private:
+ bool checkArguments();
+};
+
+} // namespace QInstaller
+
+#endif // SETTINGSOPERATION_H
diff --git a/src/libs/installer/sysinfo_win.cpp b/src/libs/installer/sysinfo_win.cpp
index 618d6cfdb..8b14d1567 100644
--- a/src/libs/installer/sysinfo_win.cpp
+++ b/src/libs/installer/sysinfo_win.cpp
@@ -40,7 +40,6 @@
**************************************************************************/
#include "kdsysinfo.h"
-
#include "link.h"
#ifdef Q_CC_MINGW
@@ -49,10 +48,10 @@
# endif
#endif
-#include <windows.h>
+#include <qt_windows.h>
#include <psapi.h>
#include <tlhelp32.h>
-
+#include <winbase.h>
#include <winnetwk.h>
#ifndef Q_CC_MINGW
diff --git a/src/libs/installer/testrepository.cpp b/src/libs/installer/testrepository.cpp
new file mode 100644
index 000000000..a39c499a1
--- /dev/null
+++ b/src/libs/installer/testrepository.cpp
@@ -0,0 +1,168 @@
+/**************************************************************************
+**
+** 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 "testrepository.h"
+
+#include <kdupdaterfiledownloader.h>
+#include <kdupdaterfiledownloaderfactory.h>
+
+#include <QtCore/QFile>
+
+using namespace QInstaller;
+
+TestRepository::TestRepository(QObject *parent)
+ : KDJob(parent)
+ , m_downloader(0)
+{
+ setTimeout(10000);
+ setAutoDelete(false);
+ setCapabilities(Cancelable);
+}
+
+TestRepository::~TestRepository()
+{
+ if (m_downloader)
+ m_downloader->deleteLater();
+}
+
+Repository TestRepository::repository() const
+{
+ return m_repository;
+}
+
+void TestRepository::setRepository(const Repository &repository)
+{
+ cancel();
+
+ setError(NoError);
+ setErrorString(QString());
+ m_repository = repository;
+}
+
+void TestRepository::doStart()
+{
+ if (m_downloader)
+ m_downloader->deleteLater();
+
+ const QUrl url = m_repository.url();
+ if (url.isEmpty()) {
+ emitFinishedWithError(InvalidUrl, tr("Empty repository URL."));
+ return;
+ }
+
+ m_downloader = KDUpdater::FileDownloaderFactory::instance().create(url.scheme(), this);
+ if (!m_downloader) {
+ emitFinishedWithError(InvalidUrl, tr("URL scheme not supported: %1 (%2).")
+ .arg(url.scheme(), url.toString()));
+ return;
+ }
+
+ QAuthenticator auth;
+ auth.setUser(m_repository.username());
+ auth.setPassword(m_repository.password());
+ m_downloader->setAuthenticator(auth);
+
+ connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(downloadCompleted()));
+ connect(m_downloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadAborted(QString)),
+ Qt::QueuedConnection);
+ connect(m_downloader, SIGNAL(authenticatorChanged(QAuthenticator)), this,
+ SLOT(onAuthenticatorChanged(QAuthenticator)));
+
+ m_downloader->setAutoRemoveDownloadedFile(true);
+ m_downloader->setUrl(QUrl(url.toString() + QString::fromLatin1("/Updates.xml")));
+
+ m_downloader->download();
+}
+
+void TestRepository::doCancel()
+{
+ if (m_downloader) {
+ QString errorString = m_downloader->errorString();
+ if (errorString.isEmpty())
+ errorString = tr("Got a timeout while testing: '%1'").arg(m_repository.displayname());
+ // at the moment the download sends downloadCompleted() if we cancel it, so just
+ disconnect(m_downloader, 0, this, 0);
+ m_downloader->cancelDownload();
+ emitFinishedWithError(KDJob::Canceled, errorString);
+ }
+}
+
+void TestRepository::downloadCompleted()
+{
+ QString errorMsg;
+ int error = DownloadError;
+
+ if (m_downloader->isDownloaded()) {
+ QFile file(m_downloader->downloadedFileName());
+ if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ QDomDocument doc;
+ QString errorMsg;
+ if (!doc.setContent(&file, &errorMsg)) {
+ error = InvalidUpdatesXml;
+ errorMsg = tr("Could not parse Updates.xml! Error: %1.").arg(errorMsg);
+ } else {
+ error = NoError;
+ }
+ } else {
+ errorMsg = tr("Updates.xml could not be opened for reading!");
+ }
+ } else {
+ errorMsg = tr("Updates.xml could not be found on server!");
+ }
+
+ if (error > NoError)
+ emitFinishedWithError(error, errorMsg);
+ else
+ emitFinished();
+
+ m_downloader->deleteLater();
+ m_downloader = 0;
+}
+
+void TestRepository::downloadAborted(const QString &reason)
+{
+ emitFinishedWithError(DownloadError, reason);
+}
+
+void TestRepository::onAuthenticatorChanged(const QAuthenticator &authenticator)
+{
+ m_repository.setUsername(authenticator.user());
+ m_repository.setPassword(authenticator.password());
+}
diff --git a/src/libs/installer/testrepository.h b/src/libs/installer/testrepository.h
new file mode 100644
index 000000000..c1ecc039c
--- /dev/null
+++ b/src/libs/installer/testrepository.h
@@ -0,0 +1,95 @@
+/**************************************************************************
+**
+** 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 TESTREPOSITORY_H
+#define TESTREPOSITORY_H
+
+#include "qinstallerglobal.h"
+
+#include <repository.h>
+#include <settings.h>
+
+#include <kdjob.h>
+
+QT_BEGIN_NAMESPACE
+class QAuthenticator;
+class QLocale;
+class QVariant;
+QT_END_NAMESPACE
+
+namespace KDUpdater {
+ class FileDownloader;
+}
+
+namespace QInstaller {
+ class PackageManagerCore;
+}
+
+namespace QInstaller {
+
+class INSTALLER_EXPORT TestRepository : public KDJob
+{
+ Q_OBJECT
+
+public:
+
+ explicit TestRepository(QObject *parent = 0);
+ ~TestRepository();
+
+ QInstaller::Repository repository() const;
+ void setRepository(const QInstaller::Repository &repository);
+
+private:
+ void doStart();
+ void doCancel();
+
+private Q_SLOTS:
+ void downloadCompleted();
+ void downloadAborted(const QString &reason);
+ void onAuthenticatorChanged(const QAuthenticator &authenticator);
+
+private:
+ QInstaller::Repository m_repository;
+ KDUpdater::FileDownloader *m_downloader;
+};
+
+} //namespace QInstaller
+
+#endif // TESTREPOSITORY_H
diff --git a/src/libs/installer/updater.cpp b/src/libs/installer/updater.cpp
index b51b332ed..ae6eaac29 100644
--- a/src/libs/installer/updater.cpp
+++ b/src/libs/installer/updater.cpp
@@ -40,6 +40,7 @@
**************************************************************************/
#include "updater.h"
+#include "productkeycheck.h"
#include "binaryformat.h"
#include "component.h"
#include "init.h"
@@ -77,6 +78,7 @@ bool Updater::checkForUpdates()
PackageManagerCore core(content.magicMarker(), content.performedOperations());
core.setUpdater();
PackageManagerCore::setVirtualComponentsVisible(true);
+ ProductKeyCheck::instance()->init(&core);
if (!core.fetchRemotePackagesTree())
return false;
diff --git a/src/libs/installer/utils.cpp b/src/libs/installer/utils.cpp
index 2b5491f62..469ba5980 100644
--- a/src/libs/installer/utils.cpp
+++ b/src/libs/installer/utils.cpp
@@ -47,7 +47,7 @@
#include <QtCore/QVector>
#include <QCoreApplication>
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
# include "qt_windows.h"
#endif
@@ -55,10 +55,6 @@
#include <iostream>
#include <sstream>
-
-#ifdef Q_OS_WIN
-#include <windows.h> // for Sleep
-#endif
#ifdef Q_OS_UNIX
#include <errno.h>
#include <signal.h>
diff --git a/src/libs/kdtools/kdgenericfactory.h b/src/libs/kdtools/kdgenericfactory.h
index 349c5ee92..4108c16fd 100644
--- a/src/libs/kdtools/kdgenericfactory.h
+++ b/src/libs/kdtools/kdgenericfactory.h
@@ -46,13 +46,14 @@
#include <QtCore/QHash>
-template <typename T_Product, typename T_Identifier = QString>
+template <typename T_Product, typename T_Identifier = QString, typename T_Argument = QString>
class KDGenericFactory
{
public:
virtual ~KDGenericFactory() {}
typedef T_Product *(*FactoryFunction)();
+ typedef T_Product *(*FactoryFunctionWithArg)(const T_Argument &arg);
template <typename T>
void registerProduct(const T_Identifier &name)
@@ -73,6 +74,25 @@ public:
return (*it)();
}
+ template <typename T>
+ void registerProductWithArg(const T_Identifier &name)
+ {
+#ifdef Q_CC_MSVC
+ FactoryFunctionWithArg function = &KDGenericFactory::create<T>;
+#else // compile fix for old gcc
+ FactoryFunctionWithArg function = &create<T>;
+#endif
+ map2.insert(name, function);
+ }
+
+ T_Product *createWithArg(const T_Identifier &name, const T_Argument &arg) const
+ {
+ const typename QHash<T_Identifier, FactoryFunctionWithArg>::const_iterator it = map2.find(name);
+ if (it == map2.end())
+ return 0;
+ return (*it)(arg);
+ }
+
private:
template <typename T>
static T_Product *create()
@@ -80,7 +100,14 @@ private:
return new T;
}
+ template <typename T>
+ static T_Product *create(const T_Argument &arg)
+ {
+ return new T(arg);
+ }
+
QHash<T_Identifier, FactoryFunction> map;
+ QHash<T_Identifier, FactoryFunctionWithArg> map2;
};
#endif
diff --git a/src/libs/kdtools/kdsavefile.cpp b/src/libs/kdtools/kdsavefile.cpp
index 483f1b338..88b95f42e 100644
--- a/src/libs/kdtools/kdsavefile.cpp
+++ b/src/libs/kdtools/kdsavefile.cpp
@@ -299,7 +299,7 @@ bool KDSaveFile::open(OpenMode mode)
return opened;
}
-bool KDSaveFile::atEnd()
+bool KDSaveFile::atEnd() const
{
return d->tmpFile ? d->tmpFile->atEnd() : QIODevice::atEnd();
}
diff --git a/src/libs/kdtools/kdsavefile.h b/src/libs/kdtools/kdsavefile.h
index 24eee9870..7408892d0 100644
--- a/src/libs/kdtools/kdsavefile.h
+++ b/src/libs/kdtools/kdsavefile.h
@@ -76,7 +76,7 @@ public:
bool resize(qint64 size);
int handle() const;
- bool atEnd();
+ bool atEnd() const;
qint64 bytesAvailable() const;
qint64 bytesToWrite() const;
bool canReadLine() const;
diff --git a/src/libs/kdtools/kdsysinfo_win.cpp b/src/libs/kdtools/kdsysinfo_win.cpp
index edeeb6879..cc28b35d2 100644
--- a/src/libs/kdtools/kdsysinfo_win.cpp
+++ b/src/libs/kdtools/kdsysinfo_win.cpp
@@ -44,13 +44,7 @@
#include <QLibrary>
#include <QStringList>
-#ifdef Q_CC_MINGW
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-# endif
-#endif
-
-#include <windows.h>
+#include <qt_windows.h>
#include <psapi.h>
#include <tlhelp32.h>
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.cpp b/src/libs/kdtools/kdupdaterupdateoperation.cpp
index c1591f467..9ba165d4b 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.cpp
+++ b/src/libs/kdtools/kdupdaterupdateoperation.cpp
@@ -176,6 +176,40 @@ QStringList UpdateOperation::arguments() const
return m_arguments;
}
+struct StartsWith
+{
+ StartsWith(const QString &searchTerm)
+ : m_searchTerm(searchTerm) {}
+
+ bool operator()(const QString &searchString)
+ {
+ return searchString.startsWith(m_searchTerm);
+ }
+
+ QString m_searchTerm;
+};
+
+
+QString UpdateOperation::argumentKeyValue(const QString &key, const QString &defaultValue) const
+{
+ const QString keySeparater(key + QLatin1String("="));
+ const QStringList tArguments(arguments());
+ QStringList::const_iterator it = std::find_if(tArguments.begin(), tArguments.end(),
+ StartsWith(keySeparater));
+ if (it == tArguments.end())
+ return defaultValue;
+
+ const QString value = it->mid(keySeparater.size());
+
+ it = std::find_if(++it, tArguments.end(), StartsWith(keySeparater));
+ if (it != tArguments.end()) {
+ qWarning() << QString::fromLatin1("There are multiple keys in the arguments calling"
+ " '%1'. Only the first found '%2' is used: '%3'").arg(name(), key, arguments().join(
+ QLatin1String("; ")));
+ }
+ return value;
+}
+
/*!
Returns error details in case performOperation() failed.
*/
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.h b/src/libs/kdtools/kdupdaterupdateoperation.h
index cac68d2f1..21b7b64a3 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.h
+++ b/src/libs/kdtools/kdupdaterupdateoperation.h
@@ -75,6 +75,7 @@ public:
void setArguments(const QStringList &args);
QStringList arguments() const;
+ QString argumentKeyValue(const QString & key, const QString &defaultValue = QString()) const;
void clear();
QString errorString() const;
int error() const;
diff --git a/src/libs/kdtools/kdupdaterupdateoperations.cpp b/src/libs/kdtools/kdupdaterupdateoperations.cpp
index 5a4296242..be123fe61 100644
--- a/src/libs/kdtools/kdupdaterupdateoperations.cpp
+++ b/src/libs/kdtools/kdupdaterupdateoperations.cpp
@@ -65,29 +65,24 @@ static QString errnoToQString(int error)
#endif
}
-static bool removeDirectory(const QString &path, QString *errorString, bool force = true)
+static bool removeDirectory(const QString &path, QString *errorString, bool force)
{
Q_ASSERT(errorString);
- const QFileInfoList entries = QDir(path).entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
- for (QFileInfoList::const_iterator it = entries.constBegin(); it != entries.constEnd(); ++it) {
- if (it->isDir() && !it->isSymLink()) {
- removeDirectory(it->filePath(), errorString, force);
- } else if (force) {
- QFile f(it->filePath());
- if (!f.remove())
- return false;
- }
+
+ QDir dir = path;
+ const QFileInfoList entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
+ foreach (const QFileInfo &entry, entries) {
+ if (entry.isDir() && (!entry.isSymLink()))
+ removeDirectory(entry.filePath(), errorString, force);
+ else if (force && (!QFile(entry.filePath()).remove()))
+ return false;
}
// even remove some hidden, OS-created files in there
-#if defined Q_OS_MAC
- QFile::remove(path + QLatin1String("/.DS_Store"));
-#elif defined Q_OS_WIN
- QFile::remove(path + QLatin1String("/Thumbs.db"));
-#endif
+ QInstaller::removeSystemGeneratedFiles(path);
errno = 0;
- const bool success = QDir().rmdir(path);
+ const bool success = dir.rmdir(path);
if (errno)
*errorString = errnoToQString(errno);
return success;
@@ -170,7 +165,7 @@ bool CopyOperation::performOperation()
QFile sourceFile(source);
if (!sourceFile.exists()) {
setError(UserDefinedError);
- setErrorString(tr("Could not copy a none existing file: %1").arg(source));
+ setErrorString(tr("Could not copy a non-existent file: %1").arg(source));
return false;
}
// If destination file exists, we cannot use QFile::copy() because it does not overwrite an existing