summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/constants.h3
-rw-r--r--src/libs/installer/fileutils.cpp16
-rw-r--r--src/libs/installer/fileutils.h2
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp27
-rw-r--r--src/libs/installer/packagemanagercoredata.cpp82
-rw-r--r--src/libs/installer/packagemanagercoredata.h3
-rw-r--r--src/libs/kdtools/kdupdaterupdateoperation.cpp43
7 files changed, 123 insertions, 53 deletions
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index e7cc3fe98..df31a2cd8 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -89,6 +89,9 @@ static const QLatin1String scWizardDefaultWidth("WizardDefaultWidth");
static const QLatin1String scWizardDefaultHeight("WizardDefaultHeight");
static const QLatin1String scProductUUID("ProductUUID");
static const QLatin1String scAllUsers("AllUsers");
+
+const char scRelocatable[] = "@RELOCATABLE_PATH@";
+
}
#endif // CONSTANTS_H
diff --git a/src/libs/installer/fileutils.cpp b/src/libs/installer/fileutils.cpp
index 7da62a367..8f0472a08 100644
--- a/src/libs/installer/fileutils.cpp
+++ b/src/libs/installer/fileutils.cpp
@@ -585,3 +585,19 @@ bool QInstaller::isInBundle(const QString &path, QString *bundlePath)
#endif
return false;
}
+
+/*!
+ Replaces the path \a before with the path \a after at the beginning of \a path and returns
+ the replaced path. If \a before cannot be found in \a path, the original value is returned.
+*/
+QString QInstaller::replacePath(const QString &path, const QString &before, const QString &after)
+{
+ if (path.isEmpty() || before.isEmpty())
+ return path;
+
+ QString pathToPatch = QDir::cleanPath(path);
+ const QString pathToReplace = QDir::cleanPath(before);
+ if (pathToPatch.startsWith(pathToReplace))
+ return QDir::cleanPath(after) + pathToPatch.mid(pathToReplace.size());
+ return path;
+}
diff --git a/src/libs/installer/fileutils.h b/src/libs/installer/fileutils.h
index ca85bbf89..ca8891c50 100644
--- a/src/libs/installer/fileutils.h
+++ b/src/libs/installer/fileutils.h
@@ -100,6 +100,8 @@ private:
quint64 INSTALLER_EXPORT fileSize(const QFileInfo &info);
bool INSTALLER_EXPORT isInBundle(const QString &path, QString *bundlePath = 0);
+ QString replacePath(const QString &path, const QString &pathBefore, const QString &pathAfter);
+
#ifdef Q_OS_WIN
QString INSTALLER_EXPORT getLongPathName(const QString &name);
QString INSTALLER_EXPORT getShortPathName(const QString &name);
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index ad2e03ead..f240a309f 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -554,6 +554,7 @@ void PackageManagerCorePrivate::initialize(const QHash<QString, QString> &params
#endif
}
processFilesForDelayedDeletion();
+ m_data.setDynamicPredefinedVariables();
disconnect(this, &PackageManagerCorePrivate::installationStarted,
ProgressCoordinator::instance(), &ProgressCoordinator::reset);
@@ -733,15 +734,20 @@ void PackageManagerCorePrivate::writeMaintenanceConfigFiles()
// write current state (variables) to the maintenance tool ini file
const QString iniPath = targetDir() + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile();
- QVariantHash variables;
+ QVariantHash variables; // Do not change to QVariantMap! Breaks existing .ini files,
+ // cause the variant types do not match while restoring the variables from the file.
QSettingsWrapper cfg(iniPath, QSettingsWrapper::IniFormat);
foreach (const QString &key, m_data.keys()) {
- if (key != scRunProgramDescription && key != scRunProgram && key != scRunProgramArguments)
- variables.insert(key, m_data.value(key));
+ if (key == scRunProgramDescription || key == scRunProgram || key == scRunProgramArguments)
+ continue;
+ QVariant value = m_data.value(key);
+ if (value.canConvert(QVariant::String))
+ value = replacePath(value.toString(), targetDir(), QLatin1String(scRelocatable));
+ variables.insert(key, value);
}
cfg.setValue(QLatin1String("Variables"), variables);
- QVariantList repos;
+ QVariantList repos; // Do not change either!
foreach (const Repository &repo, m_data.settings().defaultRepositories())
repos.append(QVariant().fromValue(repo));
cfg.setValue(QLatin1String("DefaultRepositories"), repos);
@@ -796,12 +802,15 @@ void PackageManagerCorePrivate::readMaintenanceConfigFiles(const QString &target
{
QSettingsWrapper cfg(targetDir + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile(),
QSettingsWrapper::IniFormat);
- const QVariantHash vars = cfg.value(QLatin1String("Variables")).toHash();
- for (QHash<QString, QVariant>::ConstIterator it = vars.constBegin(); it != vars.constEnd(); ++it)
- m_data.setValue(it.key(), it.value().toString());
-
+ const QVariantHash v = cfg.value(QLatin1String("Variables")).toHash(); // Do not change to
+ // QVariantMap! Breaks reading from existing .ini files, cause the variant types do not match.
+ for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); ++it) {
+ m_data.setValue(it.key(), replacePath(it.value().toString(), QLatin1String(scRelocatable),
+ targetDir));
+ }
QSet<Repository> repos;
- const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories")).toList();
+ const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories"))
+ .toList(); // Do not change either!
foreach (const QVariant &variant, variants)
repos.insert(variant.value<Repository>());
if (!repos.isEmpty())
diff --git a/src/libs/installer/packagemanagercoredata.cpp b/src/libs/installer/packagemanagercoredata.cpp
index 77103b61e..399f929f9 100644
--- a/src/libs/installer/packagemanagercoredata.cpp
+++ b/src/libs/installer/packagemanagercoredata.cpp
@@ -52,27 +52,14 @@ namespace QInstaller
PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &variables)
{
m_variables = variables;
+ setDynamicPredefinedVariables();
// Set some common variables that may used e.g. as placeholder in some of the settings variables or
// in a script or...
- m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
- m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
- m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
- m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
m_variables.insert(scTargetConfigurationFile, QLatin1String("components.xml"));
m_variables.insert(QLatin1String("InstallerDirPath"), QCoreApplication::applicationDirPath());
m_variables.insert(QLatin1String("InstallerFilePath"), QCoreApplication::applicationFilePath());
- 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_OSX)
- dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
-#endif
- m_variables.insert(QLatin1String("ApplicationsDir"), dir);
-
#ifdef Q_OS_WIN
m_variables.insert(QLatin1String("os"), QLatin1String("win"));
#elif defined(Q_OS_OSX)
@@ -83,26 +70,6 @@ PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &va
// TODO: add more platforms as needed...
#endif
-#ifdef Q_OS_WIN
- QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
- "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat);
- QSettingsWrapper system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\"
- "CurrentVersion\\Explorer\\Shell Folders"), QSettingsWrapper::NativeFormat);
-
- const QString programs = user.value(QLatin1String("Programs"), QString()).toString();
- const QString allPrograms = system.value(QLatin1String("Common Programs"), QString()).toString();
-
- QString desktop;
- if (m_variables.value(scAllUsers) == scTrue) {
- desktop = system.value(QLatin1String("Desktop")).toString();
- } else {
- desktop = user.value(QLatin1String("Desktop")).toString();
- }
- m_variables.insert(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
- m_variables.insert(QLatin1String("UserStartMenuProgramsPath"), replaceWindowsEnvironmentVariables(programs));
- m_variables.insert(QLatin1String("AllUsersStartMenuProgramsPath"), replaceWindowsEnvironmentVariables(allPrograms));
-#endif
-
m_settings = Settings::fromFileAndPrefix(QLatin1String(":/metadata/installer-config/config.xml"),
QLatin1String(":/metadata/installer-config/"), Settings::RelaxedParseMode);
@@ -132,12 +99,57 @@ void PackageManagerCoreData::clear()
m_settings = Settings();
}
+/*!
+ Set some common variables that may be used e.g. as placeholder in some of the settings
+ variables or in a script or...
+*/
+void PackageManagerCoreData::setDynamicPredefinedVariables()
+{
+ m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
+ m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
+
+ 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_OSX)
+ dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
+#endif
+ m_variables.insert(QLatin1String("ApplicationsDir"), dir);
+
+#ifdef Q_OS_WIN
+ QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat);
+ QSettingsWrapper system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Explorer\\Shell Folders"), QSettingsWrapper::NativeFormat);
+
+ const QString programs = user.value(QLatin1String("Programs"), QString()).toString();
+ const QString allPrograms = system.value(QLatin1String("Common Programs"), QString())
+ .toString();
+
+ QString desktop;
+ if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
+ desktop = system.value(QLatin1String("Desktop")).toString();
+ } else {
+ desktop = user.value(QLatin1String("Desktop")).toString();
+ }
+ m_variables.insert(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
+ m_variables.insert(QLatin1String("UserStartMenuProgramsPath"),
+ replaceWindowsEnvironmentVariables(programs));
+ m_variables.insert(QLatin1String("AllUsersStartMenuProgramsPath"),
+ replaceWindowsEnvironmentVariables(allPrograms));
+#endif
+}
+
Settings &PackageManagerCoreData::settings() const
{
return m_settings;
}
-QList<QString> PackageManagerCoreData::keys() const
+QStringList PackageManagerCoreData::keys() const
{
return m_variables.keys();
}
diff --git a/src/libs/installer/packagemanagercoredata.h b/src/libs/installer/packagemanagercoredata.h
index b9e94878d..6e29ca79e 100644
--- a/src/libs/installer/packagemanagercoredata.h
+++ b/src/libs/installer/packagemanagercoredata.h
@@ -46,9 +46,10 @@ public:
explicit PackageManagerCoreData(const QHash<QString, QString> &variables);
void clear();
+ void setDynamicPredefinedVariables();
Settings &settings() const;
- QList<QString> keys() const;
+ QStringList keys() const;
bool contains(const QString &key) const;
bool setValue(const QString &key, const QString &normalizedValue);
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.cpp b/src/libs/kdtools/kdupdaterupdateoperation.cpp
index 6ede07ae7..f4505d6da 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.cpp
+++ b/src/libs/kdtools/kdupdaterupdateoperation.cpp
@@ -34,6 +34,8 @@
#include "kdupdaterupdateoperation.h"
+#include "constants.h"
+#include "fileutils.h"
#include "packagemanagercore.h"
#include <QDataStream>
@@ -401,10 +403,13 @@ QDomDocument UpdateOperation::toXml() const
QDomDocument doc;
QDomElement root = doc.createElement(QLatin1String("operation"));
doc.appendChild(root);
+
QDomElement args = doc.createElement(QLatin1String("arguments"));
+ const QString target = m_core ? m_core->value(QInstaller::scTargetDir) : QString();
Q_FOREACH (const QString &s, arguments()) {
QDomElement arg = doc.createElement(QLatin1String("argument"));
- arg.appendChild(doc.createTextNode(s));
+ arg.appendChild(doc.createTextNode(QInstaller::replacePath(s, target,
+ QLatin1String(QInstaller::scRelocatable))));
args.appendChild(arg);
}
root.appendChild(args);
@@ -413,22 +418,31 @@ QDomDocument UpdateOperation::toXml() const
// append all values set with setValue
QDomElement values = doc.createElement(QLatin1String("values"));
- for (QVariantMap::const_iterator it = m_values.begin(); it != m_values.end(); ++it) {
+ for (QVariantMap::const_iterator it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
// the installer can't be put into XML, ignore
if (it.key() == QLatin1String("installer"))
continue;
QDomElement value = doc.createElement(QLatin1String("value"));
- const QVariant& variant = it.value();
+ QVariant variant = it.value();
value.setAttribute(QLatin1String("name"), it.key());
- value.setAttribute(QLatin1String("type"), QLatin1String( QVariant::typeToName( variant.type())));
+ value.setAttribute(QLatin1String("type"), QLatin1String(variant.typeName()));
if (variant.type() != QVariant::List && variant.type() != QVariant::StringList
&& variant.canConvert(QVariant::String)) {
- // it can convert to string? great!
- value.appendChild( doc.createTextNode(variant.toString()));
+ // it can convert to string? great!
+ value.appendChild(doc.createTextNode(QInstaller::replacePath(variant.toString(),
+ target, QLatin1String(QInstaller::scRelocatable))));
} else {
// no? then we have to go the hard way...
+ if (variant.type() == QVariant::StringList) {
+ QStringList list = variant.toStringList();
+ for (int i = 0; i < list.count(); ++i) {
+ list[i] = QInstaller::replacePath(list.at(i), target,
+ QLatin1String(QInstaller::scRelocatable));
+ }
+ variant = QVariant::fromValue(list);
+ }
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << variant;
@@ -446,14 +460,19 @@ QDomDocument UpdateOperation::toXml() const
*/
bool UpdateOperation::fromXml(const QDomDocument &doc)
{
+ QString target = QCoreApplication::applicationDirPath();
+ QInstaller::isInBundle(target, &target); // Does not change target on non OSX platforms.
+
QStringList args;
const QDomElement root = doc.documentElement();
const QDomElement argsElem = root.firstChildElement(QLatin1String("arguments"));
Q_ASSERT(! argsElem.isNull());
for (QDomNode n = argsElem.firstChild(); ! n.isNull(); n = n.nextSibling()) {
const QDomElement e = n.toElement();
- if (!e.isNull() && e.tagName() == QLatin1String("argument"))
- args << e.text();
+ if (!e.isNull() && e.tagName() == QLatin1String("argument")) {
+ args << QInstaller::replacePath(e.text(), QLatin1String(QInstaller::scRelocatable),
+ target);
+ }
}
setArguments(args);
@@ -473,6 +492,14 @@ bool UpdateOperation::fromXml(const QDomDocument &doc)
if (t == QVariant::List || t == QVariant::StringList || !var.convert(t)) {
QDataStream stream(QByteArray::fromBase64( value.toLatin1()));
stream >> var;
+ if (t == QVariant::StringList) {
+ QStringList list = var.toStringList();
+ for (int i = 0; i < list.count(); ++i) {
+ list[i] = QInstaller::replacePath(list.at(i),
+ QLatin1String(QInstaller::scRelocatable), target);
+ }
+ var = QVariant::fromValue(list);
+ }
}
m_values[name] = var;