diff options
author | kh <karsten.heimrich@theqtcompany.com> | 2014-11-25 12:21:33 +0100 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@theqtcompany.com> | 2014-11-26 14:48:53 +0100 |
commit | d18b9696e573aa7b3f38784f6c5764b9fe6fd81b (patch) | |
tree | b322cefe545a6425a0d87c7ef191fcda973fbb98 /src/libs | |
parent | d81176d2dd3b03cc6a2f9d69e1fd1e90832a0374 (diff) |
Implement server authentication and updating repository credentials.
Task-number: QTIFW-570
Change-Id: I7b6b1fab8279331e5cb4b4da86726322b44a1109
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@theqtcompany.com>
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/installer/downloadfiletask.cpp | 52 | ||||
-rw-r--r-- | src/libs/installer/downloadfiletask.h | 23 | ||||
-rw-r--r-- | src/libs/installer/installer.pro | 9 | ||||
-rw-r--r-- | src/libs/installer/metadatajob.cpp | 66 | ||||
-rw-r--r-- | src/libs/installer/serverauthenticationdialog.cpp | 70 | ||||
-rw-r--r-- | src/libs/installer/serverauthenticationdialog.h | 64 | ||||
-rw-r--r-- | src/libs/installer/serverauthenticationdialog.ui | 134 | ||||
-rw-r--r-- | src/libs/installer/settings.cpp | 61 | ||||
-rw-r--r-- | src/libs/installer/settings.h | 5 |
9 files changed, 413 insertions, 71 deletions
diff --git a/src/libs/installer/downloadfiletask.cpp b/src/libs/installer/downloadfiletask.cpp index bdab318b4..f48718b9d 100644 --- a/src/libs/installer/downloadfiletask.cpp +++ b/src/libs/installer/downloadfiletask.cpp @@ -47,10 +47,9 @@ namespace QInstaller { -ProxyAuthenticationRequiredException::ProxyAuthenticationRequiredException(const QNetworkProxy &proxy) - : TaskException(QCoreApplication::translate("ProxyAuthenticationRequiredException", - "Proxy requires authentication.")), - m_proxy(proxy) +AuthenticationRequiredException::AuthenticationRequiredException(Type type, const QString &message) + : TaskException(message) + , m_type(type) { } @@ -86,8 +85,8 @@ void Downloader::download(QFutureInterface<FileTaskResult> &fi, const QList<File fi.setExpectedResultCount(items.count()); m_nam.setProxyFactory(networkProxyFactory); - connect(&m_nam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, - SLOT(onAuthenticationRequired(QNetworkReply*, QAuthenticator*))); + connect(&m_nam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, + SLOT(onAuthenticationRequired(QNetworkReply*,QAuthenticator*))); connect(&m_nam, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(onProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); QTimer::singleShot(0, this, SLOT(doDownload())); @@ -192,8 +191,8 @@ void Downloader::onFinished(QNetworkReply *reply) reply->deleteLater(); return; } else { - m_futureInterface->reportException( - TaskException(tr("Redirect loop detected '%1'.").arg(url.toString()))); + m_futureInterface->reportException(TaskException(tr("Redirect loop detected '%1'.") + .arg(url.toString()))); return; } } @@ -209,9 +208,8 @@ void Downloader::onFinished(QNetworkReply *reply) const QByteArray expectedCheckSum = data.taskItem.value(TaskRole::Checksum).toByteArray(); if (!expectedCheckSum.isEmpty()) { if (expectedCheckSum != data.observer->checkSum().toHex()) { - m_futureInterface->reportException( - TaskException(tr("Checksum mismatch detected '%1'.").arg( - reply->url().toString()))); + m_futureInterface->reportException(TaskException(tr("Checksum mismatch detected '%1'.") + .arg(reply->url().toString()))); } } m_futureInterface->reportResult(FileTaskResult(filename, data.observer->checkSum(), data.taskItem)); @@ -235,10 +233,10 @@ void Downloader::onError(QNetworkReply::NetworkError error) { QNetworkReply *const reply = qobject_cast<QNetworkReply *>(sender()); - if (error == QNetworkReply::ProxyAuthenticationRequiredError) { - // already handled by onProxyAuthenticationRequired - return; - } + if (error == QNetworkReply::ProxyAuthenticationRequiredError) + return; // already handled by onProxyAuthenticationRequired + if (error = QNetworkReply::AuthenticationRequiredError) + return; // already handled by onAuthenticationRequired if (reply) { const Data &data = m_downloads[reply]; @@ -280,14 +278,17 @@ void Downloader::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator * FileTaskItem *item = &m_downloads[reply].taskItem; const QAuthenticator auth = item->value(TaskRole::Authenticator).value<QAuthenticator>(); - if (!auth.user().isEmpty()) { + if (auth.user().isEmpty()) { + AuthenticationRequiredException e(AuthenticationRequiredException::Type::Server, + QCoreApplication::translate("AuthenticationRequiredException", "%1 at %2") + .arg(authenticator->realm(), reply->url().host())); + item->insert(TaskRole::Authenticator, QVariant::fromValue(QAuthenticator(*authenticator))); + e.setFileTaskItem(*item); + m_futureInterface->reportException(e); + } else { authenticator->setUser(auth.user()); authenticator->setPassword(auth.password()); item->insert(TaskRole::Authenticator, QVariant()); // clear so we fail on next call - } else { - m_futureInterface->reportException( - TaskException(tr("Could not authenticate using the provided credentials. " - "Source: '%1'.").arg(reply->url().toString()))); } } @@ -295,7 +296,11 @@ void Downloader::onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuth { // Report to GUI thread. // (MetadataJob will ask for username/password, and restart the download ...) - m_futureInterface->reportException(ProxyAuthenticationRequiredException(proxy)); + AuthenticationRequiredException e(AuthenticationRequiredException::Type::Proxy, + QCoreApplication::translate("AuthenticationRequiredException", + "Proxy requires authentication.")); + e.setProxy(proxy); + m_futureInterface->reportException(e); } @@ -317,9 +322,8 @@ QNetworkReply *Downloader::startDownload(const FileTaskItem &item) QUrl const source = item.source(); if (!source.isValid()) { //: %2 is a sentence describing the error - m_futureInterface->reportException( - TaskException(tr("Invalid source '%1'. Error: %2.").arg( - source.toString(), source.errorString()))); + m_futureInterface->reportException(TaskException(tr("Invalid source '%1'. Error: %2.") + .arg(source.toString(), source.errorString()))); return 0; } diff --git a/src/libs/installer/downloadfiletask.h b/src/libs/installer/downloadfiletask.h index c9f7281da..e11c86ae6 100644 --- a/src/libs/installer/downloadfiletask.h +++ b/src/libs/installer/downloadfiletask.h @@ -50,20 +50,33 @@ enum }; } -class ProxyAuthenticationRequiredException : public TaskException +class AuthenticationRequiredException : public TaskException { public: - ProxyAuthenticationRequiredException(const QNetworkProxy &proxy); - ~ProxyAuthenticationRequiredException() throw() {} + enum struct Type { + Proxy, + Server + }; + + explicit AuthenticationRequiredException(Type type, const QString &message); + ~AuthenticationRequiredException() throw() {} + + Type type() const { return m_type; } QNetworkProxy proxy() const { return m_proxy; } + void setProxy(const QNetworkProxy &proxy) { m_proxy = proxy; } + + FileTaskItem taskItem() const { return m_fileTaskItem; } + void setFileTaskItem(const FileTaskItem &item) { m_fileTaskItem = item; } void raise() const { throw *this; } - ProxyAuthenticationRequiredException *clone() const { - return new ProxyAuthenticationRequiredException(*this); } + AuthenticationRequiredException *clone() const { + return new AuthenticationRequiredException(*this); } private: + Type m_type; QNetworkProxy m_proxy; + FileTaskItem m_fileTaskItem; }; class INSTALLER_EXPORT DownloadFileTask : public AbstractFileTask diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro index aa9d4b099..75dd44daf 100644 --- a/src/libs/installer/installer.pro +++ b/src/libs/installer/installer.pro @@ -118,7 +118,8 @@ HEADERS += packagemanagercore.h \ binarylayout.h \ installercalculator.h \ uninstallercalculator.h \ - proxycredentialsdialog.h + proxycredentialsdialog.h \ + serverauthenticationdialog.h SOURCES += packagemanagercore.cpp \ packagemanagercore_p.cpp \ @@ -186,9 +187,11 @@ SOURCES += packagemanagercore.cpp \ binarylayout.cpp \ installercalculator.cpp \ uninstallercalculator.cpp \ - proxycredentialsdialog.cpp + proxycredentialsdialog.cpp \ + serverauthenticationdialog.cpp -FORMS += proxycredentialsdialog.ui +FORMS += proxycredentialsdialog.ui \ + serverauthenticationdialog.ui RESOURCES += resources/installer.qrc diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp index ead3dd922..2b5b798b4 100644 --- a/src/libs/installer/metadatajob.cpp +++ b/src/libs/installer/metadatajob.cpp @@ -38,6 +38,7 @@ #include "packagemanagerproxyfactory.h" #include "productkeycheck.h" #include "proxycredentialsdialog.h" +#include "serverauthenticationdialog.h" #include "settings.h" #include <QTemporaryDir> @@ -117,24 +118,55 @@ void MetadataJob::xmlTaskFinished() try { m_xmlTask.waitForFinished(); status = parseUpdatesXml(m_xmlTask.future().results()); - } catch (const ProxyAuthenticationRequiredException &e) { - //! will be shown as title in the UI dialog - - const QNetworkProxy proxy = e.proxy(); - ProxyCredentialsDialog proxyCredentials(proxy); - qDebug() << e.message(); - - if (proxyCredentials.exec() == QDialog::Accepted) { - qDebug() << "Retrying with new credentials ..."; - PackageManagerProxyFactory *factory = m_core->proxyFactory(); + } catch (const AuthenticationRequiredException &e) { + if (e.type() == AuthenticationRequiredException::Type::Proxy) { + const QNetworkProxy proxy = e.proxy(); + ProxyCredentialsDialog proxyCredentials(proxy); + qDebug() << e.message(); + + if (proxyCredentials.exec() == QDialog::Accepted) { + qDebug() << "Retrying with new credentials ..."; + PackageManagerProxyFactory *factory = m_core->proxyFactory(); + + factory->setProxyCredentials(proxy, proxyCredentials.userName(), + proxyCredentials.password()); + m_core->setProxyFactory(factory); + status = XmlDownloadRetry; + } else { + reset(); + emitFinishedWithError(QInstaller::DownloadError, tr("Missing proxy credentials.")); + } + } else if (e.type() == AuthenticationRequiredException::Type::Server) { + qDebug() << e.message(); + ServerAuthenticationDialog dlg(e.message(), e.taskItem()); + if (dlg.exec() == QDialog::Accepted) { + Repository original = e.taskItem().value(TaskRole::UserRole) + .value<Repository>(); + Repository replacement = original; + replacement.setUsername(dlg.user()); + replacement.setPassword(dlg.password()); + + Settings &s = m_core->settings(); + QSet<Repository> temporaries = s.temporaryRepositories(); + if (temporaries.contains(original)) { + temporaries.remove(original); + temporaries.insert(replacement); + s.addTemporaryRepositories(temporaries, true); + } else { + QHash<QString, QPair<Repository, Repository> > update; + update.insert(QLatin1String("replace"), qMakePair(original, replacement)); - factory->setProxyCredentials(proxy, proxyCredentials.userName(), - proxyCredentials.password()); - m_core->setProxyFactory(factory); - status = XmlDownloadRetry; - } else { - reset(); - emitFinishedWithError(QInstaller::DownloadError, tr("Missing proxy credentials.")); + if (s.updateDefaultRepositories(update) == Settings::UpdatesApplied + || s.updateUserRepositories(update) == Settings::UpdatesApplied) { + if (m_core->isUpdater() || m_core->isPackageManager()) + m_core->writeMaintenanceConfigFiles(); + } + } + status = XmlDownloadRetry; + } else { + reset(); + emitFinishedWithError(QInstaller::DownloadError, tr("Authentication failed.")); + } } } catch (const TaskException &e) { reset(); diff --git a/src/libs/installer/serverauthenticationdialog.cpp b/src/libs/installer/serverauthenticationdialog.cpp new file mode 100644 index 000000000..c49839499 --- /dev/null +++ b/src/libs/installer/serverauthenticationdialog.cpp @@ -0,0 +1,70 @@ +/************************************************************************** +** +** Copyright (C) 2014 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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. +** +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "serverauthenticationdialog.h" + +#include "downloadfiletask.h" +#include "ui_serverauthenticationdialog.h" + +#include <QAuthenticator> + +namespace QInstaller { + +ServerAuthenticationDialog::ServerAuthenticationDialog(const QString &m, const FileTaskItem &item) + : ui(new Ui::ServerAuthenticationDialog) +{ + ui->setupUi(this); + ui->siteDescription->setText(m); + setWindowFlags(windowFlags() &~Qt::WindowContextHelpButtonHint); + + const QAuthenticator auth = item.value(TaskRole::Authenticator).value<QAuthenticator>(); + ui->userEdit->setText(auth.user()); + ui->passwordEdit->setText(auth.password()); +} + +ServerAuthenticationDialog::~ServerAuthenticationDialog() +{ + delete ui; +} + +QString ServerAuthenticationDialog::user() const +{ + return ui->userEdit->text(); +} + +QString ServerAuthenticationDialog::password() const +{ + return ui->passwordEdit->text(); +} + +} // namespace QInstaller diff --git a/src/libs/installer/serverauthenticationdialog.h b/src/libs/installer/serverauthenticationdialog.h new file mode 100644 index 000000000..f227639e9 --- /dev/null +++ b/src/libs/installer/serverauthenticationdialog.h @@ -0,0 +1,64 @@ +/************************************************************************** +** +** Copyright (C) 2014 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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. +** +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#ifndef SERVERAUTHENTICATIONDIALOG_H +#define SERVERAUTHENTICATIONDIALOG_H + +#include <QDialog> + +namespace QInstaller { + +namespace Ui { + class ServerAuthenticationDialog; +} +class FileTaskItem; + +class ServerAuthenticationDialog : public QDialog +{ + Q_OBJECT + Q_DISABLE_COPY(ServerAuthenticationDialog) + +public: + explicit ServerAuthenticationDialog(const QString &message, const FileTaskItem &item); + ~ServerAuthenticationDialog(); + + QString user() const; + QString password() const; + +private: + Ui::ServerAuthenticationDialog *ui; +}; + +} // QInstaller + +#endif // SERVERAUTHENTICATIONDIALOG_H diff --git a/src/libs/installer/serverauthenticationdialog.ui b/src/libs/installer/serverauthenticationdialog.ui new file mode 100644 index 000000000..84cc55a92 --- /dev/null +++ b/src/libs/installer/serverauthenticationdialog.ui @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QInstaller::ServerAuthenticationDialog</class> + <widget class="QDialog" name="QInstaller::ServerAuthenticationDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>330</width> + <height>137</height> + </rect> + </property> + <property name="windowTitle"> + <string>Server Requires Authentication</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>You need to supply a username and password to access this site.</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Username:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="userEdit"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Password:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="passwordEdit"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + <item row="5" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="siteDescription"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>%1 at %2</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0"> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>QInstaller::ServerAuthenticationDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>165</x> + <y>116</y> + </hint> + <hint type="destinationlabel"> + <x>165</x> + <y>68</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>QInstaller::ServerAuthenticationDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>165</x> + <y>116</y> + </hint> + <hint type="destinationlabel"> + <x>165</x> + <y>68</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp index 6006e6349..d38a39eb6 100644 --- a/src/libs/installer/settings.cpp +++ b/src/libs/installer/settings.cpp @@ -496,50 +496,54 @@ void Settings::addDefaultRepositories(const QSet<Repository> &repositories) d->m_data.insertMulti(scRepositories, QVariant().fromValue(repository)); } -Settings::Update -Settings::updateDefaultRepositories(const QHash<QString, QPair<Repository, Repository> > &updates) +static bool apply(const RepoHash &updates, QHash<QUrl, Repository> *reposToUpdate) { - if (updates.isEmpty()) - return Settings::NoUpdatesApplied; - - QHash <QUrl, Repository> defaultRepos; - foreach (const QVariant &variant, d->m_data.values(scRepositories)) { - const Repository repository = variant.value<Repository>(); - defaultRepos.insert(repository.url(), repository); - } - bool update = false; QList<QPair<Repository, Repository> > values = updates.values(QLatin1String("replace")); for (int a = 0; a < values.count(); ++a) { const QPair<Repository, Repository> data = values.at(a); - if (defaultRepos.contains(data.second.url())) { + if (reposToUpdate->contains(data.first.url())) { update = true; - defaultRepos.remove(data.second.url()); - defaultRepos.insert(data.first.url(), data.first); + reposToUpdate->remove(data.first.url()); + reposToUpdate->insert(data.second.url(), data.second); } } values = updates.values(QLatin1String("remove")); for (int a = 0; a < values.count(); ++a) { const QPair<Repository, Repository> data = values.at(a); - if (defaultRepos.contains(data.first.url())) { + if (reposToUpdate->contains(data.first.url())) { update = true; - defaultRepos.remove(data.first.url()); + reposToUpdate->remove(data.first.url()); } } values = updates.values(QLatin1String("add")); for (int a = 0; a < values.count(); ++a) { const QPair<Repository, Repository> data = values.at(a); - if (!defaultRepos.contains(data.first.url())) { + if (!reposToUpdate->contains(data.first.url())) { update = true; - defaultRepos.insert(data.first.url(), data.first); + reposToUpdate->insert(data.first.url(), data.first); } } + return update; +} - if (update) +Settings::Update Settings::updateDefaultRepositories(const RepoHash &updates) +{ + if (updates.isEmpty()) + return Settings::NoUpdatesApplied; + + QHash <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()); - return update ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; + return updated ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; } QSet<Repository> Settings::temporaryRepositories() const @@ -577,6 +581,23 @@ void Settings::addUserRepositories(const QSet<Repository> &repositories) d->m_data.insertMulti(scUserRepositories, QVariant().fromValue(repository)); } +Settings::Update Settings::updateUserRepositories(const RepoHash &updates) +{ + if (updates.isEmpty()) + return Settings::NoUpdatesApplied; + + QHash <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()); + return updated ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; +} + bool Settings::containsValue(const QString &key) const { return d->m_data.contains(key); diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h index 2128d6383..ab74886bb 100644 --- a/src/libs/installer/settings.h +++ b/src/libs/installer/settings.h @@ -47,6 +47,7 @@ namespace QInstaller { class Repository; +typedef QHash<QString, QPair<Repository, Repository> > RepoHash; class INSTALLER_EXPORT Settings { @@ -68,7 +69,6 @@ public: StrictParseMode, RelaxedParseMode }; - explicit Settings(); ~Settings(); @@ -116,7 +116,7 @@ public: QSet<Repository> defaultRepositories() const; void setDefaultRepositories(const QSet<Repository> &repositories); void addDefaultRepositories(const QSet<Repository> &repositories); - Settings::Update updateDefaultRepositories(const QHash<QString, QPair<Repository, Repository> > &updates); + Settings::Update updateDefaultRepositories(const RepoHash &updates); QSet<Repository> temporaryRepositories() const; void setTemporaryRepositories(const QSet<Repository> &repositories, bool replace); @@ -125,6 +125,7 @@ public: QSet<Repository> userRepositories() const; void setUserRepositories(const QSet<Repository> &repositories); void addUserRepositories(const QSet<Repository> &repositories); + Settings::Update updateUserRepositories(const RepoHash &updates); bool allowSpaceInPath() const; bool allowNonAsciiCharacters() const; |