diff options
Diffstat (limited to 'src/libs/installer/settings.cpp')
-rw-r--r-- | src/libs/installer/settings.cpp | 192 |
1 files changed, 133 insertions, 59 deletions
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp index 537f6060b..e18f63689 100644 --- a/src/libs/installer/settings.cpp +++ b/src/libs/installer/settings.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2023 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -34,8 +34,11 @@ #include "globals.h" #include "fileutils.h" +#include <QtCore/QDir> #include <QtCore/QFileInfo> #include <QtCore/QStringList> +#include <QtCore/QStandardPaths> +#include <QtCore/QUuid> #include <QtGui/QFontMetrics> #include <QtWidgets/QApplication> @@ -66,6 +69,7 @@ static const QLatin1String scMaintenanceToolName("MaintenanceToolName"); static const QLatin1String scUserRepositories("UserRepositories"); static const QLatin1String scTmpRepositories("TemporaryRepositories"); static const QLatin1String scMaintenanceToolIniFile("MaintenanceToolIniFile"); +static const QLatin1String scMaintenanceToolAlias("MaintenanceToolAlias"); static const QLatin1String scDependsOnLocalInstallerBinary("DependsOnLocalInstallerBinary"); static const QLatin1String scTranslations("Translations"); static const QLatin1String scCreateLocalRepository("CreateLocalRepository"); @@ -75,6 +79,8 @@ static const QLatin1String scFtpProxy("FtpProxy"); static const QLatin1String scHttpProxy("HttpProxy"); static const QLatin1String scProxyType("ProxyType"); +static const QLatin1String scLocalCachePath("LocalCachePath"); + const char scControlScript[] = "ControlScript"; template <typename T> @@ -132,7 +138,7 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa if (reader.isWhitespace()) continue; arguments.append(reader.text().toString().split(QRegularExpression(QLatin1String("\\s+")), - QString::SkipEmptyParts)); + Qt::SkipEmptyParts)); } break; case QXmlStreamReader::EndElement: { @@ -145,6 +151,26 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa return arguments; } +static QMap<QString, QVariant> readProductImages(QXmlStreamReader &reader) +{ + QMap<QString, QVariant> productImages; + while (reader.readNextStartElement()) { + if (reader.name() == QLatin1String("ProductImage")) { + QString key = QString(); + QString value = QString(); + while (reader.readNextStartElement()) { + if (reader.name() == QLatin1String("Image")) { + key = reader.readElementText(); + } else if (reader.name() == QLatin1String("Url")) { + value = reader.readElementText(); + } + } + productImages.insert(key, value); + } + } + return productImages; +} + static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefault, Settings::ParseMode parseMode, QString *displayName = nullptr, bool *preselected = nullptr, QString *tooltip = nullptr) @@ -229,7 +255,7 @@ public: : m_replacementRepos(false) {} - QVariantHash m_data; + QMultiHash<QString, QVariant> m_data; bool m_replacementRepos; QString absolutePathFromKey(const QString &key, const QString &suffix = QString()) const @@ -292,12 +318,13 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix, elementList << scName << scVersion << scTitle << scPublisher << scProductUrl << scTargetDir << scAdminTargetDir << scInstallerApplicationIcon << scInstallerWindowIcon - << scLogo << scWatermark << scBanner << scBackground << scPageListPixmap - << scStartMenuDir << scMaintenanceToolName << scMaintenanceToolIniFile << scRemoveTargetDir + << scLogo << scWatermark << scBanner << scBackground << scPageListPixmap << scAliasDefinitionsFile + << scStartMenuDir << scMaintenanceToolName << scMaintenanceToolIniFile << scMaintenanceToolAlias + << scRemoveTargetDir << scLocalCacheDir << scPersistentLocalCache << scRunProgram << scRunProgramArguments << scRunProgramDescription << scDependsOnLocalInstallerBinary - << scAllowSpaceInPath << scAllowNonAsciiCharacters << scDisableAuthorizationFallback - << scDisableCommandLineInterface + << scAllowSpaceInPath << scAllowNonAsciiCharacters << scAllowRepositoriesForOfflineInstaller + << scDisableAuthorizationFallback << scDisableCommandLineInterface << scWizardStyle << scStyleSheet << scTitleColor << scWizardDefaultWidth << scWizardDefaultHeight << scWizardMinimumWidth << scWizardMinimumHeight << scWizardShowPageList << scProductImages @@ -307,7 +334,7 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix, << scSaveDefaultRepositories << scRepositoryCategories; Settings s; - s.d->m_data.insert(scPrefix, prefix); + s.d->m_data.replace(scPrefix, prefix); while (reader.readNextStartElement()) { const QString name = reader.name().toString(); if (!elementList.contains(name)) @@ -326,7 +353,7 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix, } else if (name == scRunProgramArguments) { s.setRunProgramArguments(readArgumentAttributes(reader, parseMode, QLatin1String("Argument"))); } else if (name == scProductImages) { - s.setProductImages(readArgumentAttributes(reader, parseMode, QLatin1String("Image"))); + s.setProductImages(readProductImages(reader)); } else if (name == scRemoteRepositories) { s.addDefaultRepositories(readRepositories(reader, true, parseMode)); } else if (name == scRepositoryCategories) { @@ -336,7 +363,7 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix, s.setRepositoryCategoryDisplayName(repositoryCategoryName); } } else { - s.d->m_data.insert(name, reader.readElementText(QXmlStreamReader::SkipChildElements)); + s.d->m_data.replace(name, reader.readElementText(QXmlStreamReader::SkipChildElements)); } } if (reader.error() != QXmlStreamReader::NoError) { @@ -351,39 +378,40 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix, // Add some possible missing values if (!s.d->m_data.contains(scInstallerApplicationIcon)) - s.d->m_data.insert(scInstallerApplicationIcon, QLatin1String(":/installer")); + s.d->m_data.replace(scInstallerApplicationIcon, QLatin1String(":/installer")); if (!s.d->m_data.contains(scInstallerWindowIcon)) { - s.d->m_data.insert(scInstallerWindowIcon, + s.d->m_data.replace(scInstallerWindowIcon, QString(QLatin1String(":/installer") + s.systemIconSuffix())); } if (!s.d->m_data.contains(scRemoveTargetDir)) - s.d->m_data.insert(scRemoveTargetDir, scTrue); + s.d->m_data.replace(scRemoveTargetDir, scTrue); if (s.d->m_data.value(scMaintenanceToolName).toString().isEmpty()) { - s.d->m_data.insert(scMaintenanceToolName, + s.d->m_data.replace(scMaintenanceToolName, // TODO: Remove deprecated 'UninstallerName'. s.d->m_data.value(QLatin1String("UninstallerName"), QLatin1String("maintenancetool")) .toString()); } + if (s.d->m_data.value(scTargetConfigurationFile).toString().isEmpty()) - s.d->m_data.insert(scTargetConfigurationFile, QLatin1String("components.xml")); + s.d->m_data.replace(scTargetConfigurationFile, QLatin1String("components.xml")); if (s.d->m_data.value(scMaintenanceToolIniFile).toString().isEmpty()) { - s.d->m_data.insert(scMaintenanceToolIniFile, + s.d->m_data.replace(scMaintenanceToolIniFile, // TODO: Remove deprecated 'UninstallerIniFile'. s.d->m_data.value(QLatin1String("UninstallerIniFile"), QString(s.maintenanceToolName() + QLatin1String(".ini"))).toString()); } if (!s.d->m_data.contains(scDependsOnLocalInstallerBinary)) - s.d->m_data.insert(scDependsOnLocalInstallerBinary, false); + s.d->m_data.replace(scDependsOnLocalInstallerBinary, false); if (!s.d->m_data.contains(scRepositorySettingsPageVisible)) - s.d->m_data.insert(scRepositorySettingsPageVisible, true); + s.d->m_data.replace(scRepositorySettingsPageVisible, true); if (!s.d->m_data.contains(scCreateLocalRepository)) - s.d->m_data.insert(scCreateLocalRepository, false); + s.d->m_data.replace(scCreateLocalRepository, false); if (!s.d->m_data.contains(scInstallActionColumnVisible)) - s.d->m_data.insert(scInstallActionColumnVisible, false); + s.d->m_data.replace(scInstallActionColumnVisible, false); if (!s.d->m_data.contains(scAllowUnstableComponents)) - s.d->m_data.insert(scAllowUnstableComponents, false); + s.d->m_data.replace(scAllowUnstableComponents, false); if (!s.d->m_data.contains(scSaveDefaultRepositories)) - s.d->m_data.insert(scSaveDefaultRepositories, true); + s.d->m_data.replace(scSaveDefaultRepositories, true); return s; } @@ -457,11 +485,11 @@ static int lengthToInt(const QVariant &variant) QString length = variant.toString().trimmed(); if (length.endsWith(QLatin1String("em"), Qt::CaseInsensitive)) { length.chop(2); - return qRound(length.toDouble() * QApplication::fontMetrics().height()); + return qRound(length.toDouble() * QFontMetricsF(QApplication::font()).height()); } if (length.endsWith(QLatin1String("ex"), Qt::CaseInsensitive)) { length.chop(2); - return qRound(length.toDouble() * QApplication::fontMetrics().xHeight()); + return qRound(length.toDouble() * QFontMetricsF(QApplication::font()).xHeight()); } if (length.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) { length.chop(2); @@ -497,25 +525,23 @@ bool Settings::wizardShowPageList() const return d->m_data.value(scWizardShowPageList, true).toBool(); } -QStringList Settings::productImages() const +QMap<QString, QVariant> Settings::productImages() const { const QVariant variant = d->m_data.value(scProductImages); - QStringList imagePaths; - if (variant.canConvert<QStringList>()) { - foreach (auto image, variant.value<QStringList>()) { - QString imagePath = QFileInfo(image).isAbsolute() - ? image - : d->m_data.value(scPrefix).toString() + QLatin1Char('/') + image; - QInstaller::replaceHighDpiImage(imagePath); - imagePaths.append(imagePath); - } - } + QMap<QString, QVariant> imagePaths; + if (variant.canConvert<QVariantMap>()) + imagePaths = variant.toMap(); return imagePaths; } -void Settings::setProductImages(const QStringList &images) +void Settings::setProductImages(const QMap<QString, QVariant> &images) +{ + d->m_data.insert(scProductImages, QVariant::fromValue(images)); +} + +QString Settings::aliasDefinitionsFile() const { - d->m_data.insert(scProductImages, images); + return d->absolutePathFromKey(scAliasDefinitionsFile); } QString Settings::installerApplicationIcon() const @@ -554,6 +580,11 @@ QString Settings::maintenanceToolIniFile() const return d->m_data.value(scMaintenanceToolIniFile).toString(); } +QString Settings::maintenanceToolAlias() const +{ + return d->m_data.value(scMaintenanceToolAlias).toString(); +} + QString Settings::runProgram() const { return d->m_data.value(scRunProgram).toString(); @@ -569,7 +600,7 @@ QStringList Settings::runProgramArguments() const void Settings::setRunProgramArguments(const QStringList &arguments) { - d->m_data.insert(scRunProgramArguments, arguments); + d->m_data.replace(scRunProgramArguments, arguments); } @@ -618,6 +649,11 @@ bool Settings::allowNonAsciiCharacters() const return d->m_data.value(scAllowNonAsciiCharacters, false).toBool(); } +bool Settings::allowRepositoriesForOfflineInstaller() const +{ + return d->m_data.value(scAllowRepositoriesForOfflineInstaller, true).toBool(); +} + bool Settings::disableAuthorizationFallback() const { return d->m_data.value(scDisableAuthorizationFallback, false).toBool(); @@ -676,7 +712,7 @@ void Settings::setDefaultRepositories(const QSet<Repository> &repositories) void Settings::addDefaultRepositories(const QSet<Repository> &repositories) { foreach (const Repository &repository, repositories) - d->m_data.insertMulti(scRepositories, QVariant().fromValue(repository)); + d->m_data.insert(scRepositories, QVariant().fromValue(repository)); } void Settings::setRepositoryCategories(const QSet<RepositoryCategory> &repositories) @@ -688,7 +724,7 @@ void Settings::setRepositoryCategories(const QSet<RepositoryCategory> &repositor void Settings::addRepositoryCategories(const QSet<RepositoryCategory> &repositories) { foreach (const RepositoryCategory &repository, repositories) - d->m_data.insertMulti(scRepositoryCategories, QVariant().fromValue(repository)); + d->m_data.insert(scRepositoryCategories, QVariant().fromValue(repository)); } Settings::Update Settings::updateRepositoryCategories(const RepoHash &updates) @@ -713,13 +749,13 @@ Settings::Update Settings::updateRepositoryCategories(const RepoHash &updates) } } if (update) { - categories = categoriesList.toSet(); + categories = QSet<RepositoryCategory>(categoriesList.begin(), categoriesList.end()); setRepositoryCategories(categories); } return update ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; } -static bool apply(const RepoHash &updates, QHash<QUrl, Repository> *reposToUpdate) +static bool apply(const RepoHash &updates, QMultiHash<QUrl, Repository> *reposToUpdate) { bool update = false; QList<QPair<Repository, Repository> > values = updates.values(QLatin1String("replace")); @@ -757,15 +793,17 @@ Settings::Update Settings::updateDefaultRepositories(const RepoHash &updates) if (updates.isEmpty()) return Settings::NoUpdatesApplied; - QHash <QUrl, Repository> defaultRepos; + QMultiHash <QUrl, Repository> defaultRepos; foreach (const QVariant &variant, d->m_data.values(scRepositories)) { const Repository repository = variant.value<Repository>(); defaultRepos.insert(repository.url(), repository); } const bool updated = apply(updates, &defaultRepos); - if (updated) - setDefaultRepositories(defaultRepos.values().toSet()); + if (updated) { + const QList<Repository> repositoriesList = defaultRepos.values(); + setDefaultRepositories(QSet<Repository>(repositoriesList.begin(), repositoriesList.end())); + } return updated ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; } @@ -784,7 +822,7 @@ void Settings::addTemporaryRepositories(const QSet<Repository> &repositories, bo { d->m_replacementRepos = replace; foreach (const Repository &repository, repositories) - d->m_data.insertMulti(scTmpRepositories, QVariant().fromValue(repository)); + d->m_data.insert(scTmpRepositories, QVariant().fromValue(repository)); } QSet<Repository> Settings::userRepositories() const @@ -801,7 +839,7 @@ void Settings::setUserRepositories(const QSet<Repository> &repositories) void Settings::addUserRepositories(const QSet<Repository> &repositories) { foreach (const Repository &repository, repositories) - d->m_data.insertMulti(scUserRepositories, QVariant().fromValue(repository)); + d->m_data.insert(scUserRepositories, QVariant().fromValue(repository)); } Settings::Update Settings::updateUserRepositories(const RepoHash &updates) @@ -809,15 +847,17 @@ Settings::Update Settings::updateUserRepositories(const RepoHash &updates) if (updates.isEmpty()) return Settings::NoUpdatesApplied; - QHash <QUrl, Repository> reposToUpdate; + QMultiHash <QUrl, Repository> reposToUpdate; foreach (const QVariant &variant, d->m_data.values(scUserRepositories)) { const Repository repository = variant.value<Repository>(); reposToUpdate.insert(repository.url(), repository); } const bool updated = apply(updates, &reposToUpdate); - if (updated) - setUserRepositories(reposToUpdate.values().toSet()); + if (updated) { + const QList<Repository> repositoriesList = reposToUpdate.values(); + setUserRepositories(QSet<Repository>(repositoriesList.begin(), repositoriesList.end())); + } return updated ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; } @@ -844,7 +884,41 @@ bool Settings::repositorySettingsPageVisible() const void Settings::setRepositorySettingsPageVisible(bool visible) { - d->m_data.insert(scRepositorySettingsPageVisible, visible); + d->m_data.replace(scRepositorySettingsPageVisible, visible); +} + +bool Settings::persistentLocalCache() const +{ + return d->m_data.value(scPersistentLocalCache, true).toBool(); +} + +void Settings::setPersistentLocalCache(bool enable) +{ + d->m_data.replace(scPersistentLocalCache, enable); +} + +QString Settings::localCacheDir() const +{ + const QString fallback = QLatin1String("qt-installer-framework") + QDir::separator() + + QUuid::createUuidV3(QUuid(), applicationName()).toString(QUuid::WithoutBraces); + return d->m_data.value(scLocalCacheDir, fallback).toString(); +} + +void Settings::setLocalCacheDir(const QString &dir) +{ + d->m_data.replace(scLocalCacheDir, dir); +} + +QString Settings::localCachePath() const +{ + const QString fallback = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + + QDir::separator() + localCacheDir(); + return d->m_data.value(scLocalCachePath, fallback).toString(); +} + +void Settings::setLocalCachePath(const QString &path) +{ + d->m_data.replace(scLocalCachePath, path); } Settings::ProxyType Settings::proxyType() const @@ -854,7 +928,7 @@ Settings::ProxyType Settings::proxyType() const void Settings::setProxyType(Settings::ProxyType type) { - d->m_data.insert(scProxyType, type); + d->m_data.replace(scProxyType, type); } QNetworkProxy Settings::ftpProxy() const @@ -867,7 +941,7 @@ QNetworkProxy Settings::ftpProxy() const void Settings::setFtpProxy(const QNetworkProxy &proxy) { - d->m_data.insert(scFtpProxy, QVariant::fromValue(proxy)); + d->m_data.replace(scFtpProxy, QVariant::fromValue(proxy)); } QNetworkProxy Settings::httpProxy() const @@ -880,7 +954,7 @@ QNetworkProxy Settings::httpProxy() const void Settings::setHttpProxy(const QNetworkProxy &proxy) { - d->m_data.insert(scHttpProxy, QVariant::fromValue(proxy)); + d->m_data.replace(scHttpProxy, QVariant::fromValue(proxy)); } QStringList Settings::translations() const @@ -893,7 +967,7 @@ QStringList Settings::translations() const void Settings::setTranslations(const QStringList &translations) { - d->m_data.insert(scTranslations, translations); + d->m_data.replace(scTranslations, translations); } QString Settings::controlScript() const @@ -913,7 +987,7 @@ bool Settings::allowUnstableComponents() const void Settings::setAllowUnstableComponents(bool allow) { - d->m_data.insert(scAllowUnstableComponents, allow); + d->m_data.replace(scAllowUnstableComponents, allow); } bool Settings::saveDefaultRepositories() const @@ -923,16 +997,16 @@ bool Settings::saveDefaultRepositories() const void Settings::setSaveDefaultRepositories(bool save) { - d->m_data.insert(scSaveDefaultRepositories, save); + d->m_data.replace(scSaveDefaultRepositories, save); } QString Settings::repositoryCategoryDisplayName() const { QString displayName = d->m_data.value(QLatin1String(scRepositoryCategoryDisplayName)).toString(); - return displayName.isEmpty() ? tr("Select Categories") : displayName; + return displayName.isEmpty() ? tr("Categories") : displayName; } void Settings::setRepositoryCategoryDisplayName(const QString& name) { - d->m_data.insert(scRepositoryCategoryDisplayName, name); + d->m_data.replace(scRepositoryCategoryDisplayName, name); } |