summaryrefslogtreecommitdiffstats
path: root/src/libs/installer
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@digia.com>2013-06-27 11:20:29 +0200
committerTim Jenssen <tim.jenssen@digia.com>2013-06-27 11:20:29 +0200
commit72dfa6df1eeed9526ae8d7dfc0cb4b96b26dbb40 (patch)
tree1428d86aae7b4a12ce700c5f60bf35457b74e36e /src/libs/installer
parentb38573f2da0d7de7f9e7abad3e03b666d65ac341 (diff)
parent5409e2f56265639454a0f97270de7e584d949120 (diff)
Merge remote-tracking branch 'origin/1.4'
Conflicts: installerfw.pri tools/binarycreator/binarycreator.cpp tools/common/repositorygen.cpp tools/common/repositorygen.h tools/repogen/repogen.cpp Change-Id: I97767b2e4ef9b7afd5ce368d99c6a7d38dfbd947
Diffstat (limited to 'src/libs/installer')
-rw-r--r--src/libs/installer/adminauthorization_win.cpp40
-rw-r--r--src/libs/installer/component.cpp21
-rw-r--r--src/libs/installer/createdesktopentryoperation.cpp3
-rw-r--r--src/libs/installer/createshortcutoperation.cpp49
-rw-r--r--src/libs/installer/elevatedexecuteoperation.cpp11
-rw-r--r--src/libs/installer/environmentvariablesoperation.cpp4
-rw-r--r--src/libs/installer/fsengineserver.cpp2
-rw-r--r--src/libs/installer/getrepositorymetainfojob.cpp7
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp14
-rw-r--r--src/libs/installer/packagemanagergui.cpp4
-rw-r--r--src/libs/installer/qprocesswrapper.cpp8
-rw-r--r--src/libs/installer/qprocesswrapper.h1
-rw-r--r--src/libs/installer/qtpatchoperation.cpp9
-rw-r--r--src/libs/installer/settings.cpp40
-rw-r--r--src/libs/installer/settings.h4
15 files changed, 176 insertions, 41 deletions
diff --git a/src/libs/installer/adminauthorization_win.cpp b/src/libs/installer/adminauthorization_win.cpp
index 20420cef0..03003b21a 100644
--- a/src/libs/installer/adminauthorization_win.cpp
+++ b/src/libs/installer/adminauthorization_win.cpp
@@ -49,6 +49,9 @@
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0501
# endif
+# ifndef SEE_MASK_NOASYNC
+# define SEE_MASK_NOASYNC 0x00000100
+# endif
#endif
#include <windows.h>
@@ -99,6 +102,31 @@ bool AdminAuthorization::hasAdminRights()
return isInAdminGroup;
}
+//copied from qsystemerror.cpp in Qt
+static QString windowsErrorString(int errorCode)
+{
+ QString ret;
+ wchar_t *string = 0;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPWSTR)&string,
+ 0,
+ NULL);
+ ret = QString::fromWCharArray(string);
+ LocalFree((HLOCAL)string);
+
+ if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
+ ret = QString::fromLatin1("The specified module could not be found.");
+
+ ret.append(QLatin1String(" (0x"));
+ ret.append(QString::number(uint(errorCode), 16).rightJustified(8, QLatin1Char('0')));
+ ret.append(QLatin1String(")"));
+
+ return ret;
+}
+
bool AdminAuthorization::execute(QWidget *, const QString &program, const QStringList &arguments)
{
DeCoInitializer _;
@@ -112,10 +140,16 @@ bool AdminAuthorization::execute(QWidget *, const QString &program, const QStrin
shellExecuteInfo.lpFile = (wchar_t *)file.utf16();
shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
shellExecuteInfo.lpParameters = (wchar_t *)args.utf16();
+ shellExecuteInfo.fMask = SEE_MASK_NOASYNC;
qDebug() << QString::fromLatin1("Starting elevated process %1 with arguments: %2.").arg(file, args);
- ShellExecuteExW(&shellExecuteInfo);
- qDebug() << "Finished starting elevated process.";
- return GetLastError() == ERROR_SUCCESS;
+ if (ShellExecuteExW(&shellExecuteInfo)) {
+ qDebug() << "Finished starting elevated process.";
+ return true;
+ } else {
+ qWarning() << QString::fromLatin1("Error while starting elevated process: %1, "
+ "Error: %2").arg(program, windowsErrorString(GetLastError()));
+ }
+ return false;
}
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index e3bff0727..6bc3e803a 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -46,8 +46,9 @@
#include "fsengineclient.h"
#include "globals.h"
#include "lib7z_facade.h"
-#include "packagemanagercore.h"
#include "messageboxhandler.h"
+#include "packagemanagercore.h"
+#include "settings.h"
#include <kdupdaterupdatesourcesinfo.h>
#include <kdupdaterupdateoperationfactory.h>
@@ -516,10 +517,22 @@ void Component::languageChanged()
void Component::loadTranslations(const QDir &directory, const QStringList &qms)
{
QDirIterator it(directory.path(), qms, QDir::Files);
+ const QStringList translations = d->m_core->settings().translations();
+ const QString uiLanguage = QLocale().uiLanguages().value(0, QLatin1String("en_us"))
+ .replace(QLatin1Char('-'), QLatin1Char('_'));
while (it.hasNext()) {
const QString filename = it.next();
- if (QFileInfo(filename).baseName().toLower() != QLocale().name().toLower())
- continue;
+ const QString basename = QFileInfo(filename).baseName();
+ if (!uiLanguage.startsWith(QFileInfo(filename).baseName(), Qt::CaseInsensitive))
+ continue; // do not load the file if it does not match the UI language
+
+ if (!translations.isEmpty()) {
+ bool found = false;
+ foreach (const QString &translation, translations)
+ found |= translation.startsWith(basename, Qt::CaseInsensitive);
+ if (!found) // don't load the file if it does match the UI language but is not allowed to be used
+ continue;
+ }
QScopedPointer<QTranslator> translator(new QTranslator(this));
if (!translator->load(filename))
@@ -554,7 +567,7 @@ void Component::loadUserInterfaces(const QDir &directory, const QStringList &uis
static QUiLoader loader;
loader.setTranslationEnabled(true);
loader.setLanguageChangeEnabled(true);
- QWidget *const widget = loader.load(&file, MessageBoxHandler::currentBestSuitParent());
+ QWidget *const widget = loader.load(&file, 0);
if (!widget) {
throw Error(tr("Could not load the requested UI file '%1'. Error: %2").arg(it.fileName(),
#if QT_VERSION < 0x050000
diff --git a/src/libs/installer/createdesktopentryoperation.cpp b/src/libs/installer/createdesktopentryoperation.cpp
index 42b2c3aab..cd79bc65d 100644
--- a/src/libs/installer/createdesktopentryoperation.cpp
+++ b/src/libs/installer/createdesktopentryoperation.cpp
@@ -118,7 +118,6 @@ CreateDesktopEntryOperation::CreateDesktopEntryOperation()
CreateDesktopEntryOperation::~CreateDesktopEntryOperation()
{
- deleteFileNowOrLater(value(QLatin1String("backupOfExistingDesktopEntry")).toString());
}
void CreateDesktopEntryOperation::backup()
@@ -165,7 +164,7 @@ bool CreateDesktopEntryOperation::performOperation()
}
QFile::setPermissions(filename, QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::ReadGroup
- | QFile::ReadOther);
+ | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther);
QTextStream stream(&file);
stream.setCodec("UTF-8");
diff --git a/src/libs/installer/createshortcutoperation.cpp b/src/libs/installer/createshortcutoperation.cpp
index 0a52198ea..963f0aaf8 100644
--- a/src/libs/installer/createshortcutoperation.cpp
+++ b/src/libs/installer/createshortcutoperation.cpp
@@ -79,12 +79,17 @@ struct DeCoInitializer
};
#endif
-struct StartsWithWorkingDirectory
+struct StartsWith
{
- bool operator()(const QString &s)
+ StartsWith(const QString &searchTerm)
+ : m_searchTerm(searchTerm) {}
+
+ bool operator()(const QString &searchString)
{
- return s.startsWith(QLatin1String("workingDirectory="));
+ return searchString.startsWith(m_searchTerm);
}
+
+ QString m_searchTerm;
};
static QString parentDirectory(const QString &current)
@@ -92,20 +97,21 @@ static QString parentDirectory(const QString &current)
return current.mid(0, current.lastIndexOf(QLatin1Char('/')));
}
-static QString takeWorkingDirArgument(QStringList &args)
+static QString takeArgument(const QString argument, QStringList *arguments)
{
- // if the arguments contain an option in the form "workingDirectory=...", find it and consume it
- QStringList::iterator wdiropt = std::find_if (args.begin(), args.end(), StartsWithWorkingDirectory());
- if (wdiropt == args.end())
+ // if the arguments contain an option in the form "argument=...", find it and consume it
+ QStringList::iterator it = std::find_if(arguments->begin(), arguments->end(), StartsWith(argument));
+ if (it == arguments->end())
return QString();
- const QString workingDir = wdiropt->mid(QString::fromLatin1("workingDirectory=").size());
- args.erase(wdiropt);
- return workingDir;
+ const QString value = it->mid(argument.size());
+ arguments->erase(it);
+ return value;
}
static bool createLink(const QString &fileName, const QString &linkName, QString workingDir,
- QString arguments = QString())
+ const QString &arguments = QString(), const QString &iconPath = QString(),
+ const QString &iconId = QString())
{
#ifdef Q_OS_WIN
bool success = QFile::link(fileName, linkName);
@@ -129,6 +135,8 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
if (!arguments.isNull())
psl->SetArguments((wchar_t*)arguments.utf16());
+ if (!iconPath.isNull())
+ psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
IPersistFile *ppf = NULL;
if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
@@ -153,7 +161,8 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
Q_UNUSED(workingDir)
Q_UNUSED(fileName)
Q_UNUSED(linkName)
-
+ Q_UNUSED(iconPath)
+ Q_UNUSED(iconId)
return true;
#endif
}
@@ -183,12 +192,16 @@ void CreateShortcutOperation::backup()
bool CreateShortcutOperation::performOperation()
{
QStringList args = arguments();
- const QString workingDir = takeWorkingDirArgument(args);
+
+ const QString iconId = takeArgument(QString::fromLatin1("iconId="), &args);
+ const QString iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
+ const QString workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
if (args.count() != 2 && args.count() != 3) {
setError(InvalidArguments);
setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"), tr(" (optional: 'workingDirectory=...')")));
+ .arg(name()).arg(arguments().count()).arg(tr("2 or 3"),
+ tr(" (optional: 'workingDirectory=...', 'iconPath=...', 'iconId=...')")));
return false;
}
@@ -196,10 +209,8 @@ bool CreateShortcutOperation::performOperation()
const QString linkLocation = args.at(1);
const QString targetArguments = args.value(2); //used value because it could be not existing
- const QString linkPath = QFileInfo(linkLocation).absolutePath();
-
- const bool linkPathAlreadyExists = QDir(linkPath).exists();
- const bool created = linkPathAlreadyExists || QDir::root().mkpath(linkPath);
+ const QString linkPath = QFileInfo(linkLocation).absolutePath().trimmed();
+ const bool created = QDir(linkPath).exists() || QDir::root().mkpath(linkPath);
if (!created) {
setError(UserDefinedError);
@@ -225,7 +236,7 @@ bool CreateShortcutOperation::performOperation()
return false;
}
- const bool linked = createLink(linkTarget, linkLocation, workingDir, targetArguments);
+ const bool linked = createLink(linkTarget, linkLocation, workingDir, targetArguments, iconPath, iconId);
if (!linked) {
setError(UserDefinedError);
setErrorString(tr("Could not create link %1: %2").arg(QDir::toNativeSeparators(linkLocation),
diff --git a/src/libs/installer/elevatedexecuteoperation.cpp b/src/libs/installer/elevatedexecuteoperation.cpp
index 2e1d050a2..d797f2077 100644
--- a/src/libs/installer/elevatedexecuteoperation.cpp
+++ b/src/libs/installer/elevatedexecuteoperation.cpp
@@ -232,6 +232,12 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
} else {
q->setErrorString(customErrorMessage);
}
+
+ QByteArray standardErrorOutput = process->readAllStandardError();
+ // in error case it would be useful to see something in verbose output
+ if (!standardErrorOutput.isEmpty())
+ qWarning() << standardErrorOutput;
+
returnValue = false;
}
@@ -260,7 +266,10 @@ void ElevatedExecuteOperation::Private::readProcessOutput()
}
const QByteArray output = process->readAll();
if (!output.isEmpty()) {
- qDebug() << output;
+ if (q->error() == UserDefinedError)
+ qWarning() << output;
+ else
+ qDebug() << output;
emit q->outputTextChanged(QString::fromLocal8Bit(output));
}
}
diff --git a/src/libs/installer/environmentvariablesoperation.cpp b/src/libs/installer/environmentvariablesoperation.cpp
index de2eae899..192272a8d 100644
--- a/src/libs/installer/environmentvariablesoperation.cpp
+++ b/src/libs/installer/environmentvariablesoperation.cpp
@@ -137,10 +137,10 @@ UpdateOperation::Error undoSetting(const QString &regPath,
bool EnvironmentVariableOperation::performOperation()
{
QStringList args = arguments();
- if (args.count() != 2 && args.count() != 3) {
+ if (args.count() < 2 || args.count() > 4) {
setError(InvalidArguments);
setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"), QLatin1String("")));
+ .arg(name()).arg(arguments().count()).arg(tr("2 to 4"), QLatin1String("")));
return false;
}
diff --git a/src/libs/installer/fsengineserver.cpp b/src/libs/installer/fsengineserver.cpp
index b17e1ae0a..326a2a02a 100644
--- a/src/libs/installer/fsengineserver.cpp
+++ b/src/libs/installer/fsengineserver.cpp
@@ -408,6 +408,8 @@ QByteArray FSEngineConnectionThread::handleCommand(const QString &command)
returnStream << process->readAll();
} else if (command == QLatin1String("QProcess::readAllStandardOutput")) {
returnStream << process->readAllStandardOutput();
+ } else if (command == QLatin1String("QProcess::readAllStandardError")) {
+ returnStream << process->readAllStandardError();
} else if (command == QLatin1String("QProcess::startDetached")) {
QString program;
QStringList arguments;
diff --git a/src/libs/installer/getrepositorymetainfojob.cpp b/src/libs/installer/getrepositorymetainfojob.cpp
index 14299fbb4..6913a63e5 100644
--- a/src/libs/installer/getrepositorymetainfojob.cpp
+++ b/src/libs/installer/getrepositorymetainfojob.cpp
@@ -267,7 +267,10 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
QString err;
QDomDocument doc;
- if (!doc.setContent(&updatesFile, &err)) {
+ const bool success = doc.setContent(&updatesFile, &err);
+ updatesFile.close();
+
+ 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);
@@ -370,7 +373,7 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadError(const QString &err)
{
if (m_retriesLeft <= 0) {
const QString msg = tr("Could not fetch Updates.xml from repository: %1. Error: %2")
- .arg(m_repository.url().toString(), err);
+ .arg(m_repository.displayname(), err);
QMessageBox::StandardButtons buttons = QMessageBox::Retry | QMessageBox::Cancel;
const QMessageBox::StandardButton b =
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index f514f8a5c..1728a85b2 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -782,8 +782,17 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
void PackageManagerCorePrivate::writeMaintenanceConfigFiles()
{
+ bool gainedAdminRights = false;
// write current state (variables) to the uninstaller ini file
const QString iniPath = targetDir() + QLatin1Char('/') + m_data.settings().uninstallerIniFile();
+ {
+ QFile tmp(iniPath); // force gaining admin rights in case we haven't done already and we need it
+ if (!tmp.open(QIODevice::ReadWrite) || !tmp.isWritable()) {
+ if (!m_FSEngineClientHandler->isActive()) // check if nobody did it before...
+ gainedAdminRights = m_core->gainAdminRights();
+ }
+ tmp.close();
+ }
QVariantHash variables;
QSettingsWrapper cfg(iniPath, QSettingsWrapper::IniFormat);
@@ -800,6 +809,8 @@ void PackageManagerCorePrivate::writeMaintenanceConfigFiles()
cfg.sync();
if (cfg.status() != QSettingsWrapper::NoError) {
+ if (gainedAdminRights)
+ m_core->dropAdminRights();
const QString reason = cfg.status() == QSettingsWrapper::AccessError ? tr("Access error")
: tr("Format error");
throw Error(tr("Could not write installer configuration to %1: %2").arg(iniPath, reason));
@@ -841,6 +852,9 @@ void PackageManagerCorePrivate::writeMaintenanceConfigFiles()
writer.writeEndElement();
writer.writeEndElement();
}
+
+ if (gainedAdminRights)
+ m_core->dropAdminRights();
}
void PackageManagerCorePrivate::readMaintenanceConfigFiles(const QString &targetDir)
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index dddec8aae..295057a44 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -1430,12 +1430,12 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
QString StartMenuDirectoryPage::startMenuDir() const
{
- return m_lineEdit->text();
+ return m_lineEdit->text().trimmed();
}
void StartMenuDirectoryPage::setStartMenuDir(const QString &startMenuDir)
{
- m_lineEdit->setText(startMenuDir);
+ m_lineEdit->setText(startMenuDir.trimmed());
}
void StartMenuDirectoryPage::leaving()
diff --git a/src/libs/installer/qprocesswrapper.cpp b/src/libs/installer/qprocesswrapper.cpp
index 416ca9f4c..9544d6682 100644
--- a/src/libs/installer/qprocesswrapper.cpp
+++ b/src/libs/installer/qprocesswrapper.cpp
@@ -329,6 +329,14 @@ QByteArray QProcessWrapper::readAllStandardOutput()
return d->process.readAllStandardOutput();
}
+QByteArray QProcessWrapper::readAllStandardError()
+{
+ const Private::TimerBlocker blocker(this);
+ if (d->createSocket())
+ return callRemoteMethod<QByteArray>(d->stream, QLatin1String("QProcess::readAllStandardError"));
+ return d->process.readAllStandardError();
+}
+
void QProcessWrapper::start(const QString &param1, const QStringList &param2, QIODevice::OpenMode param3)
{
const Private::TimerBlocker blocker(this);
diff --git a/src/libs/installer/qprocesswrapper.h b/src/libs/installer/qprocesswrapper.h
index 15e6f1fba..e7caf61f6 100644
--- a/src/libs/installer/qprocesswrapper.h
+++ b/src/libs/installer/qprocesswrapper.h
@@ -84,6 +84,7 @@ public:
void terminate();
QByteArray readAll();
QByteArray readAllStandardOutput();
+ QByteArray readAllStandardError();
void setWorkingDirectory(const QString &dir);
void start(const QString &program);
diff --git a/src/libs/installer/qtpatchoperation.cpp b/src/libs/installer/qtpatchoperation.cpp
index 997b92b77..822d5e3a4 100644
--- a/src/libs/installer/qtpatchoperation.cpp
+++ b/src/libs/installer/qtpatchoperation.cpp
@@ -167,12 +167,13 @@ bool QtPatchOperation::performOperation()
// 1. type
// 2. new/target qtpath
// 3. version if greather Qt4
+ // optional QmakeOutputInstallerKey=<used_installer_value>
// the possible 2 argument case is here to support old syntax
- if (arguments().count() < 2 || arguments().count() > 3) {
+ if (arguments().count() < 2 && arguments().count() > 4) {
setError(InvalidArguments);
setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 3"), QLatin1String("")));
+ .arg(name()).arg(arguments().count()).arg(tr("3 or 4"), QLatin1String("")));
return false;
}
@@ -204,7 +205,7 @@ bool QtPatchOperation::performOperation()
return false;
}
- if (!filteredQmakeOutputInstallerKey.isEmpty() && core->value(qmakeOutputInstallerKey).isEmpty()) {
+ if (core && !filteredQmakeOutputInstallerKey.isEmpty() && core->value(qmakeOutputInstallerKey).isEmpty()) {
setError(UserDefinedError);
setErrorString(tr("Could not find the needed QmakeOutputInstallerKey(%1) value on the installer "
"object. The ConsumeOutput operation on the valid qmake needs to be called first.").arg(
@@ -220,7 +221,7 @@ bool QtPatchOperation::performOperation()
#endif
QHash<QString, QByteArray> qmakeValueHash;
- if (!core->value(qmakeOutputInstallerKey).isEmpty()) {
+ if (core && !core->value(qmakeOutputInstallerKey).isEmpty()) {
qmakeValueHash = QtPatch::readQmakeOutput(core->value(qmakeOutputInstallerKey).toLatin1());
} else {
if (!QFile::exists(qmakePath)) {
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index 8ef248db8..d8f409f46 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -67,6 +67,7 @@ static const QLatin1String scTmpRepositories("TemporaryRepositories");
static const QLatin1String scUninstallerIniFile("UninstallerIniFile");
static const QLatin1String scRemoteRepositories("RemoteRepositories");
static const QLatin1String scDependsOnLocalInstallerBinary("DependsOnLocalInstallerBinary");
+static const QLatin1String scTranslations("Translations");
static const QLatin1String scFtpProxy("FtpProxy");
static const QLatin1String scHttpProxy("HttpProxy");
@@ -97,6 +98,25 @@ static void raiseError(QXmlStreamReader &reader, const QString &error, Settings:
}
}
+static QStringList readTranslations(QXmlStreamReader &reader, Settings::ParseMode parseMode)
+{
+ QStringList translations;
+ while (reader.readNextStartElement()) {
+ if (reader.name() == QLatin1String("Translation")) {
+ translations.append(reader.readElementText().toLower());
+ } else {
+ raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name().toString()),
+ parseMode);
+ }
+
+ if (!reader.attributes().isEmpty()) {
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.").arg(reader
+ .name().toString()), parseMode);
+ }
+ }
+ return translations;
+}
+
static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefault, Settings::ParseMode parseMode)
{
QSet<Repository> set;
@@ -212,7 +232,7 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
<< scDependsOnLocalInstallerBinary
<< scAllowSpaceInPath << scAllowNonAsciiCharacters
<< scRepositorySettingsPageVisible << scTargetConfigurationFile
- << scRemoteRepositories;
+ << scRemoteRepositories << scTranslations;
Settings s;
s.d->m_data.insert(scPrefix, prefix);
@@ -232,7 +252,9 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
if (s.d->m_data.contains(name))
reader.raiseError(QString::fromLatin1("Element '%1' has been defined before.").arg(name));
- if (name == scRemoteRepositories) {
+ if (name == scTranslations) {
+ s.setTranslations(readTranslations(reader, parseMode));
+ } else if (name == scRemoteRepositories) {
s.addDefaultRepositories(readRepositories(reader, true, parseMode));
} else {
s.d->m_data.insert(name, reader.readElementText(QXmlStreamReader::SkipChildElements));
@@ -576,3 +598,17 @@ void Settings::setHttpProxy(const QNetworkProxy &proxy)
{
d->m_data.insert(scHttpProxy, QVariant::fromValue(proxy));
}
+
+QStringList Settings::translations() const
+{
+ const QVariant variant = d->m_data.values(scTranslations);
+ if (variant.canConvert<QStringList>())
+ return variant.value<QStringList>();
+ return QStringList();
+}
+
+void Settings::setTranslations(const QStringList &translations)
+{
+ d->m_data.remove(scTranslations);
+ d->m_data.insert(scTranslations, translations);
+}
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index 277264f79..85a2ea68e 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -47,6 +47,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QSharedDataPointer>
+#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtNetwork/QNetworkProxy>
@@ -151,6 +152,9 @@ public:
QNetworkProxy httpProxy() const;
void setHttpProxy(const QNetworkProxy &proxy);
+ QStringList translations() const;
+ void setTranslations(const QStringList &translations);
+
private:
class Private;
QSharedDataPointer<Private> d;