summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2018-03-09 10:21:54 +0200
committerKatja Marttila <katja.marttila@qt.io>2018-09-26 04:46:21 +0000
commit0f8d11ca8e8312fc0d0dc56e0c2a1154ff3de77c (patch)
treea0f00dbacd2c03ee3013e648464e2df61c7d1b8b /src/libs
parentb3d140a2c899219a02c1b31efa4e36723eb71c07 (diff)
Enable usage of categorized repositories
This change allows to categorize repositories in component selection page. Using categorized repositories will by default show only uncagetorized repository items in tree. Selecting one or several categories using checkbox will update the treeview to show all selected categorized repository content. Repository's metadata is fetched only after the category is selected. Categorized repositories can be defined in config.xml: <RepositoryCategories> <RemoteRepositories> <Displayname>category 1</Displayname> <Repository> <Url>(url)</Url></Repository> </RemoteReposiories> ... <RepositoryCategories Change-Id: I6eae9daee70b1afa322144d52c11f25d0b655ebf Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io> Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/constants.h1
-rw-r--r--src/libs/installer/installer.pro6
-rw-r--r--src/libs/installer/metadatajob.cpp72
-rw-r--r--src/libs/installer/metadatajob.h15
-rw-r--r--src/libs/installer/packagemanagercore.cpp1
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp4
-rw-r--r--src/libs/installer/packagemanagergui.cpp244
-rw-r--r--src/libs/installer/packagemanagergui.h1
-rw-r--r--src/libs/installer/repository.cpp22
-rw-r--r--src/libs/installer/repository.h4
-rw-r--r--src/libs/installer/repositorycategory.cpp159
-rw-r--r--src/libs/installer/repositorycategory.h86
-rw-r--r--src/libs/installer/settings.cpp60
-rw-r--r--src/libs/installer/settings.h6
14 files changed, 606 insertions, 75 deletions
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index 0e9646737..26c2a7dfe 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -91,6 +91,7 @@ static const QLatin1String scAllUsers("AllUsers");
static const QLatin1String scSupportsModify("SupportsModify");
static const QLatin1String scAllowUnstableComponents("AllowUnstableComponents");
static const QLatin1String scSaveDefaultRepositories("SaveDefaultRepositories");
+static const QLatin1String scRepositoryCategoryDisplayName("RepositoryCategoryDisplayName");
const char scRelocatable[] = "@RELOCATABLE_PATH@";
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index f649a1ecb..bdca7e0f3 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -131,7 +131,8 @@ HEADERS += packagemanagercore.h \
lib7z_guid.h \
lib7z_create.h \
lib7z_extract.h \
- lib7z_list.h
+ lib7z_list.h \
+ repositorycategory.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -206,7 +207,8 @@ SOURCES += packagemanagercore.cpp \
serverauthenticationdialog.cpp \
keepaliveobject.cpp \
systeminfo.cpp \
- packagesource.cpp
+ packagesource.cpp \
+ repositorycategory.cpp
FORMS += proxycredentialsdialog.ui \
serverauthenticationdialog.ui
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index ae29a2dcb..cb1579756 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -70,11 +70,33 @@ MetadataJob::~MetadataJob()
reset();
}
-Repository MetadataJob::repositoryForDirectory(const QString &directory) const
+/*
+ * Parse the metadata of currently selected repositories. We cannot
+ * return all metadata as that contains metadata also from categorized archived
+ * repositories which might not be currently selected.
+ */
+
+QList<Metadata> MetadataJob::metadata() const
{
- return m_metadata.value(directory).repository;
+ QList<Metadata> metadata = m_metaFromDefaultRepositories.values();
+ foreach (RepositoryCategory repositoryCategory, m_core->settings().repositoryCategories()) {
+ if (m_core->isUpdater() || (repositoryCategory.isEnabled() && m_fetchedArchive.contains(repositoryCategory.displayname()))) {
+ QList<ArchiveMetadata> archiveMetaList = m_fetchedArchive.values(repositoryCategory.displayname());
+ foreach (ArchiveMetadata archiveMeta, archiveMetaList) {
+ metadata.append(archiveMeta.metaData);
+ }
+ }
+ }
+ return metadata;
}
+Repository MetadataJob::repositoryForDirectory(const QString &directory) const
+{
+ if (m_metaFromDefaultRepositories.contains(directory))
+ return m_metaFromDefaultRepositories.value(directory).repository;
+ else
+ return m_metaFromArchive.value(directory).repository;
+}
// -- private slots
@@ -86,13 +108,12 @@ void MetadataJob::doStart()
}
const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
if (!m_addCompressedPackages) {
- reset();
emit infoMessage(this, tr("Preparing meta information download..."));
const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly();
-
if (onlineInstaller || m_core->isMaintainer()) {
QList<FileTaskItem> items;
- foreach (const Repository &repo, m_core->settings().repositories()) {
+ QSet<Repository> repositories = getRepositories();
+ foreach (const Repository &repo, repositories) {
if (repo.isEnabled() &&
productKeyCheck->isValidRepository(repo)) {
QAuthenticator authenticator;
@@ -451,7 +472,9 @@ bool MetadataJob::fetchMetaDataPackages()
void MetadataJob::reset()
{
m_packages.clear();
- m_metadata.clear();
+ m_metaFromDefaultRepositories.clear();
+ m_metaFromArchive.clear();
+ m_fetchedArchive.clear();
setError(Job::NoError);
setErrorString(QString());
@@ -587,7 +610,17 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
}
}
}
- m_metadata.insert(metadata.directory, metadata);
+ if (metadata.repository.archivename().isEmpty()) {
+ m_metaFromDefaultRepositories.insert(metadata.directory, metadata);
+ } else {
+ //Hash metadata to help checking if meta for repository is already fetched
+ ArchiveMetadata archiveMetadata;
+ archiveMetadata.metaData = metadata;
+ m_fetchedArchive.insertMulti(metadata.repository.archivename(), archiveMetadata);
+ // Hash for faster lookups
+ m_metaFromArchive.insert(metadata.directory, metadata);
+ }
+
// search for additional repositories that we might need to check
const QDomNode repositoryUpdate = root.firstChildElement(QLatin1String("RepositoryUpdate"));
@@ -670,8 +703,31 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
}
double taskCount = m_packages.length()/static_cast<double>(m_downloadableChunkSize);
m_totalTaskCount = qCeil(taskCount);
+ m_taskNumber = 0;
return XmlDownloadSuccess;
}
+QSet<Repository> MetadataJob::getRepositories()
+{
+ QSet<Repository> repositories;
+
+ //In the first run, m_metadata is empty. Get always the default repositories
+ if (m_metaFromDefaultRepositories.isEmpty()) {
+ repositories = m_core->settings().repositories();
+ }
+
+ // Fetch repositories under archive which are selected in UI.
+ // If repository is already fetched, do not fetch it again.
+ // In updater mode, fetch always all archive repositories to get updates
+ foreach (RepositoryCategory repositoryCategory, m_core->settings().repositoryCategories()) {
+ if (m_core->isUpdater() || (repositoryCategory.isEnabled() && !m_fetchedArchive.contains(repositoryCategory.displayname()))) {
+ foreach (Repository repository, repositoryCategory.repositories()) {
+ repositories.insert(repository);
+ }
+ }
+ }
+ return repositories;
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/metadatajob.h b/src/libs/installer/metadatajob.h
index e3f5aceea..973275de3 100644
--- a/src/libs/installer/metadatajob.h
+++ b/src/libs/installer/metadatajob.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -46,6 +46,12 @@ struct Metadata
Repository repository;
};
+struct ArchiveMetadata
+{
+ QString archive;
+ Metadata metaData;
+};
+
class INSTALLER_EXPORT MetadataJob : public Job
{
Q_OBJECT
@@ -61,7 +67,7 @@ public:
explicit MetadataJob(QObject *parent = 0);
~MetadataJob();
- QList<Metadata> metadata() const { return m_metadata.values(); }
+ QList<Metadata> metadata() const;
Repository repositoryForDirectory(const QString &directory) const;
void setPackageManagerCore(PackageManagerCore *core) { m_core = core; }
void addCompressedPackages(bool addCompressPackage) { m_addCompressedPackages = addCompressPackage;}
@@ -85,13 +91,13 @@ private:
void reset();
void resetCompressedFetch();
Status parseUpdatesXml(const QList<FileTaskResult> &results);
+ QSet<Repository> getRepositories();
private:
PackageManagerCore *m_core;
QList<FileTaskItem> m_packages;
TempDirDeleter m_tempDirDeleter;
- QHash<QString, Metadata> m_metadata;
QFutureWatcher<FileTaskResult> m_xmlTask;
QFutureWatcher<FileTaskResult> m_metadataTask;
QHash<QFutureWatcher<void> *, QObject*> m_unzipTasks;
@@ -103,6 +109,9 @@ private:
int m_taskNumber;
int m_totalTaskCount;
QStringList m_shaMissmatchPackages;
+ QHash<QString, ArchiveMetadata> m_fetchedArchive;
+ QHash<QString, Metadata> m_metaFromDefaultRepositories;
+ QHash<QString, Metadata> m_metaFromArchive; //for faster lookups.
};
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 747960cee..44025de55 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -1176,7 +1176,6 @@ bool PackageManagerCore::fetchCompressedPackagesTree()
return fetchPackagesTree(packages, installedPackages);
}
-
/*!
Checks for packages to install. Returns \c true if newer versions exist
and they can be installed.
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 195c16f30..1e271a0d5 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -2210,14 +2210,12 @@ LocalPackagesHash PackageManagerCorePrivate::localInstalledPackages()
bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories()
{
- if (m_repoFetched)
- return m_repoFetched;
-
m_updates = false;
m_repoFetched = false;
m_updateSourcesAdded = false;
try {
+ m_metadataJob.addCompressedPackages(false);
m_metadataJob.start();
m_metadataJob.waitForFinished();
} catch (Error &error) {
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 287bf7d38..90ff11ea3 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -39,6 +39,7 @@
#include "utils.h"
#include "scriptengine.h"
#include "productkeycheck.h"
+#include "repositorycategory.h"
#include "sysinfo.h"
@@ -71,6 +72,7 @@
#include <QVBoxLayout>
#include <QShowEvent>
#include <QFileDialog>
+#include <QGroupBox>
#ifdef Q_OS_WIN
# include <qt_windows.h>
@@ -1863,6 +1865,8 @@ public:
, m_updaterModel(m_core->updaterComponentModel())
, m_currentModel(m_allModel)
, m_compressedButtonVisible(false)
+ , m_allowCompressedRepositoryInstall(false)
+ , m_archiveButtonVisible(false)
{
m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
@@ -1871,32 +1875,42 @@ public:
connect(m_updaterModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)),
this, SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
- QHBoxLayout *hlayout = new QHBoxLayout;
- hlayout->addWidget(m_treeView, 3);
+ m_descriptionVLayout = new QVBoxLayout;
+ m_descriptionVLayout->setObjectName(QLatin1String("DescriptionLayout"));
m_descriptionLabel = new QLabel(q);
m_descriptionLabel->setWordWrap(true);
m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
-
- m_vlayout = new QVBoxLayout;
- m_vlayout->setObjectName(QLatin1String("VerticalLayout"));
- m_vlayout->addWidget(m_descriptionLabel);
+ m_descriptionVLayout->addWidget(m_descriptionLabel);
m_sizeLabel = new QLabel(q);
m_sizeLabel->setWordWrap(true);
- m_vlayout->addWidget(m_sizeLabel);
m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
-
-#ifdef INSTALLCOMPRESSED
- allowCompressedRepositoryInstall();
-#endif
- m_vlayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
+ m_descriptionVLayout->addWidget(m_sizeLabel);
+ m_descriptionVLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding));
- hlayout->addLayout(m_vlayout, 2);
- QVBoxLayout *layout = new QVBoxLayout(q);
- layout->addLayout(hlayout, 1);
+ m_mainHLayout = new QHBoxLayout;
+
+ m_treeViewVLayout = new QVBoxLayout;
+ m_treeViewVLayout->setObjectName(QLatin1String("TreeviewLayout"));
+
+ m_bspLabel = new QLabel();
+ m_bspLabel->hide();
+ m_treeViewVLayout->addWidget(m_bspLabel);
+
+ m_progressBar = new QProgressBar();
+ m_progressBar->setRange(0, 0);
+ m_progressBar->hide();
+ m_progressBar->setObjectName(QLatin1String("CompressedInstallProgressBar"));
+ m_treeViewVLayout->addWidget(m_progressBar);
+ connect(m_core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
+ connect(m_core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
+ connect(m_core, &PackageManagerCore::metaJobTotalProgress, this,
+ &ComponentSelectionPage::Private::setTotalProgress);
+
+ m_buttonHLayout = new QHBoxLayout;
m_checkDefault = new QPushButton;
connect(m_checkDefault, &QAbstractButton::clicked,
this, &ComponentSelectionPage::Private::selectDefault);
@@ -1912,62 +1926,93 @@ public:
"reset to already installed components")));
m_checkDefault->setText(ComponentSelectionPage::tr("&Reset"));
}
- hlayout = new QHBoxLayout;
- hlayout->addWidget(m_checkDefault);
+ m_buttonHLayout->addWidget(m_checkDefault);
m_checkAll = new QPushButton;
- hlayout->addWidget(m_checkAll);
connect(m_checkAll, &QAbstractButton::clicked,
this, &ComponentSelectionPage::Private::selectAll);
m_checkAll->setObjectName(QLatin1String("SelectAllComponentsButton"));
m_checkAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+S",
"select all components")));
m_checkAll->setText(ComponentSelectionPage::tr("&Select All"));
+ m_buttonHLayout->addWidget(m_checkAll);
m_uncheckAll = new QPushButton;
- hlayout->addWidget(m_uncheckAll);
connect(m_uncheckAll, &QAbstractButton::clicked,
this, &ComponentSelectionPage::Private::deselectAll);
m_uncheckAll->setObjectName(QLatin1String("DeselectAllComponentsButton"));
m_uncheckAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+D",
"deselect all components")));
m_uncheckAll->setText(ComponentSelectionPage::tr("&Deselect All"));
+ m_buttonHLayout->addWidget(m_uncheckAll);
- hlayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
- QSizePolicy::MinimumExpanding));
- layout->addLayout(hlayout);
+ m_treeViewVLayout->addLayout(m_buttonHLayout);
+ m_treeViewVLayout->addWidget(m_treeView, 3);
+
+ m_mainHLayout->addLayout(m_treeViewVLayout, 3);
+ m_mainHLayout->addLayout(m_descriptionVLayout, 2);
+ QVBoxLayout *layout = new QVBoxLayout(q);
+ layout->addLayout(m_mainHLayout, 1);
+
+#ifdef INSTALLCOMPRESSED
+ allowCompressedRepositoryInstall();
+#endif
}
void allowCompressedRepositoryInstall()
{
- if (m_compressedButtonVisible) {
+ m_allowCompressedRepositoryInstall = true;
+ }
+
+ void showCompressedRepositoryButton()
+ {
+ if (m_compressedButtonVisible || !m_allowCompressedRepositoryInstall) {
return;
}
-
connect(m_core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
connect(m_core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
- m_bspLabel = new QLabel(ComponentSelectionPage::tr("To install new "\
- "compressed repository, browse the repositories from your computer"),q);
- m_bspLabel->setWordWrap(true);
- m_bspLabel->setObjectName(QLatin1String("CompressedButtonLabel"));
-
- m_vlayout->addSpacing(50);
- m_vlayout->addWidget(m_bspLabel);
+ QWizard *wizard = qobject_cast<QWizard*>(m_core->guiObject());
+ if (wizard) {
+ wizard->setOption(QWizard::HaveCustomButton2, true);
+ wizard->setButtonText(QWizard::CustomButton2,
+ ComponentSelectionPage::tr("&Browse QBSP files"));
+ connect(wizard, &QWizard::customButtonClicked,
+ this, &ComponentSelectionPage::Private::selectCompressedPackage);
+ q->gui()->updateButtonLayout();
+ }
+ m_compressedButtonVisible = true;
+ }
- m_progressBar = new QProgressBar();
- m_progressBar->setRange(0, 0);
- m_progressBar->hide();
- m_vlayout->addWidget(m_progressBar);
- m_progressBar->setObjectName(QLatin1String("CompressedInstallProgressBar"));
+ void setupArchiveButton()
+ {
+ if (m_archiveButtonVisible)
+ return;
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ m_archiveVLayout = new QVBoxLayout;
+ m_archiveGroupBox = new QGroupBox(q);
+ m_archiveGroupBox->setTitle(m_core->settings().repositoryCategoryDisplayName());
+ QVBoxLayout *groupboxLayout = new QVBoxLayout(m_archiveGroupBox);
+
+ m_fetchArchiveButton = new QPushButton(tr("Fetch"));
+ connect(m_fetchArchiveButton, &QPushButton::clicked, this,
+ &ComponentSelectionPage::Private::fetchRepositoryCategories);
+ foreach (RepositoryCategory repository, m_core->settings().repositoryCategories()) {
+ QCheckBox *checkBox = new QCheckBox;
+ connect(checkBox, &QCheckBox::stateChanged, this,
+ &ComponentSelectionPage::Private::checkboxStateChanged);
+ checkBox->setText(repository.displayname());
+ groupboxLayout->addWidget(checkBox);
+ }
+ m_archiveVLayout->insertWidget(0, m_archiveGroupBox);
- m_installCompressButton = new QPushButton;
- connect(m_installCompressButton, &QAbstractButton::clicked,
- this, &ComponentSelectionPage::Private::selectCompressedPackage);
- m_installCompressButton->setObjectName(QLatin1String("InstallCompressedPackageButton"));
- m_installCompressButton->setText(ComponentSelectionPage::tr("&Browse QBSP files"));
- m_vlayout->addWidget(m_installCompressButton);
- m_compressedButtonVisible = true;
+ m_metadataProgressLabel = new QLabel(q);
+ m_archiveVLayout->addWidget(m_metadataProgressLabel);
+ vLayout->addWidget(m_archiveGroupBox);
+ vLayout->addWidget(m_fetchArchiveButton);
+ vLayout->addStretch();
+ m_mainHLayout->insertLayout(0, vLayout);
+ m_archiveButtonVisible = true;
}
void updateTreeView()
@@ -2061,6 +2106,77 @@ public slots:
m_currentModel->setCheckedState(ComponentModel::AllUnchecked);
}
+ void checkboxStateChanged()
+ {
+ QList<QCheckBox*> checkboxes = m_archiveGroupBox->findChildren<QCheckBox *>();
+ bool enableFetchButton = false;
+ foreach (QCheckBox *checkbox, checkboxes) {
+ if (checkbox->isChecked()) {
+ enableFetchButton = true;
+ break;
+ }
+ }
+ }
+
+ void enableArchiveRepos(int index, bool enable) {
+ RepositoryCategory archiveRepo = m_core->settings().repositoryCategories().toList().at(index);
+ RepositoryCategory replacement = archiveRepo;
+ replacement.setEnabled(enable);
+ QSet<RepositoryCategory> tmpArchiveRepos = m_core->settings().repositoryCategories();
+ if (tmpArchiveRepos.contains(archiveRepo)) {
+ tmpArchiveRepos.remove(archiveRepo);
+ tmpArchiveRepos.insert(replacement);
+ m_core->settings().addRepositoryCategories(tmpArchiveRepos);
+ }
+ }
+
+ void updateWidgetVisibility(bool show)
+ {
+ if (show) {
+ QSpacerItem *verticalSpacer2 = new QSpacerItem(0, 0, QSizePolicy::Minimum,
+ QSizePolicy::Expanding);
+ m_treeViewVLayout->addSpacerItem(verticalSpacer2);
+ } else {
+ QSpacerItem *item = m_treeViewVLayout->spacerItem();
+ m_treeViewVLayout->removeItem(item);
+ }
+ m_fetchArchiveButton->setDisabled(show);
+ m_progressBar->setVisible(show);
+ m_bspLabel->setVisible(show);
+ m_archiveGroupBox->setDisabled(show);
+
+ m_treeView->setVisible(!show);
+ m_checkDefault->setVisible(!show);
+ m_checkAll->setVisible(!show);
+ m_uncheckAll->setVisible(!show);
+ m_descriptionLabel->setVisible(!show);
+ QPushButton *const b = qobject_cast<QPushButton *>(q->gui()->button(QWizard::NextButton));
+ b->setEnabled(!show);
+
+ if (QAbstractButton *bspButton = q->gui()->button(QWizard::CustomButton2))
+ bspButton->setEnabled(!show);
+ }
+
+ void fetchRepositoryCategories()
+ {
+ updateWidgetVisibility(true);
+
+ QCheckBox *checkbox;
+ QList<QCheckBox*> checkboxes = m_archiveGroupBox->findChildren<QCheckBox *>();
+ for (int i = 0; i < checkboxes.count(); i++) {
+ checkbox = checkboxes.at(i);
+ enableArchiveRepos(i, checkbox->isChecked());
+ }
+
+ if (!m_core->fetchRemotePackagesTree()) {
+ m_metadataProgressLabel->setText(m_core->error());
+ } else {
+ updateTreeView();
+ m_metadataProgressLabel->setText(QLatin1String());
+ }
+ updateWidgetVisibility(false);
+ }
+
void selectCompressedPackage()
{
QString defaultDownloadDirectory =
@@ -2076,10 +2192,7 @@ public slots:
set.insert(repository);
}
if (set.count() > 0) {
- m_progressBar->show();
- m_installCompressButton->hide();
- QPushButton *const b = qobject_cast<QPushButton *>(q->gui()->button(QWizard::NextButton));
- b->setEnabled(false);
+ updateWidgetVisibility(true);
m_core->settings().addTemporaryRepositories(set, false);
if (!m_core->fetchCompressedPackagesTree()) {
setMessage(m_core->error());
@@ -2089,11 +2202,8 @@ public slots:
setMessage(ComponentSelectionPage::tr("To install new "\
"compressed repository, browse the repositories from your computer"));
}
-
- m_progressBar->hide();
- m_installCompressButton->show();
- b->setEnabled(true);
}
+ updateWidgetVisibility(false);
}
/*!
@@ -2114,6 +2224,12 @@ public slots:
m_bspLabel->setText(msg);
}
+ void setTotalProgress(int totalProgress)
+ {
+ if (m_progressBar)
+ m_progressBar->setRange(0, totalProgress);
+ }
+
void selectDefault()
{
m_currentModel->setCheckedState(ComponentModel::DefaultChecked);
@@ -2152,10 +2268,19 @@ public:
QPushButton *m_uncheckAll;
QPushButton *m_checkDefault;
QPushButton *m_installCompressButton;
+ QGroupBox *m_archiveGroupBox;
+ QPushButton *m_fetchArchiveButton;
QLabel *m_bspLabel;
+ QLabel *m_metadataProgressLabel;
QProgressBar *m_progressBar;
- QVBoxLayout *m_vlayout;
+ QVBoxLayout *m_descriptionVLayout;
+ QHBoxLayout *m_mainHLayout;
+ QVBoxLayout *m_treeViewVLayout;
+ QVBoxLayout *m_archiveVLayout;
+ QHBoxLayout *m_buttonHLayout;
bool m_compressedButtonVisible;
+ bool m_allowCompressedRepositoryInstall;
+ bool m_archiveButtonVisible;
};
@@ -2211,6 +2336,21 @@ void ComponentSelectionPage::entering()
d->updateTreeView();
setModified(isComplete());
+ if (core->settings().repositoryCategories().count() > 0 && !core->isOfflineOnly()
+ && !core->isUpdater()) {
+ d->setupArchiveButton();
+ }
+ d->showCompressedRepositoryButton();
+}
+
+void ComponentSelectionPage::leaving()
+{
+ QWizard *wizard = qobject_cast<QWizard*>(d->m_core->guiObject());
+ if (wizard && (gui()->options() & QWizard::HaveCustomButton2)) {
+ wizard->setOption(QWizard::HaveCustomButton2, false);
+ gui()->updateButtonLayout();
+ d->m_compressedButtonVisible = false;
+ }
}
/*!
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index 238e22a62..d67bc9bd9 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -314,6 +314,7 @@ public:
protected:
void entering();
+ void leaving();
void showEvent(QShowEvent *event);
private Q_SLOTS:
diff --git a/src/libs/installer/repository.cpp b/src/libs/installer/repository.cpp
index eb45573a9..249012786 100644
--- a/src/libs/installer/repository.cpp
+++ b/src/libs/installer/repository.cpp
@@ -57,6 +57,7 @@ Repository::Repository(const Repository &other)
, m_password(other.m_password)
, m_displayname(other.m_displayname)
, m_compressed(other.m_compressed)
+ , m_archivename(other.m_archivename)
{
registerMetaType();
}
@@ -183,7 +184,7 @@ void Repository::setPassword(const QString &password)
}
/*!
- Returns the Name for the repository to be displayed instead of the URL
+ Returns the Name for the repository to be displayed instead of the URL.
*/
QString Repository::displayname() const
{
@@ -199,6 +200,22 @@ void Repository::setDisplayName(const QString &displayname)
}
/*!
+ Returns the archive name if the repository belongs to an archive.
+*/
+QString Repository::archivename() const
+{
+ return m_archivename;
+}
+
+/*!
+ Sets the archive name to \a archivename if the repository belongs to an archive.
+*/
+void Repository::setArchiveName(const QString &archivename)
+{
+ m_archivename = archivename;
+}
+
+/*!
Returns true if repository is compressed
*/
bool Repository::isCompressed() const
@@ -248,6 +265,7 @@ const Repository &Repository::operator=(const Repository &other)
m_password = other.m_password;
m_displayname = other.m_displayname;
m_compressed = other.m_compressed;
+ m_archivename = other.m_archivename;
return *this;
}
@@ -273,7 +291,7 @@ QDataStream &operator<<(QDataStream &ostream, const Repository &repository)
{
return ostream << repository.m_url.toEncoded().toBase64() << repository.m_default << repository.m_enabled
<< repository.m_username.toUtf8().toBase64() << repository.m_password.toUtf8().toBase64()
- << repository.m_displayname.toUtf8().toBase64();
+ << repository.m_displayname.toUtf8().toBase64() << repository.m_archivename.toUtf8().toBase64();
}
}
diff --git a/src/libs/installer/repository.h b/src/libs/installer/repository.h
index b73e7bd4c..83393ead9 100644
--- a/src/libs/installer/repository.h
+++ b/src/libs/installer/repository.h
@@ -64,6 +64,9 @@ public:
QString displayname() const;
void setDisplayName(const QString &displayname);
+ QString archivename() const;
+ void setArchiveName(const QString &archivename);
+
bool isCompressed() const;
void setCompressed(bool compressed);
bool operator==(const Repository &other) const;
@@ -82,6 +85,7 @@ private:
QString m_username;
QString m_password;
QString m_displayname;
+ QString m_archivename;
bool m_compressed;
};
diff --git a/src/libs/installer/repositorycategory.cpp b/src/libs/installer/repositorycategory.cpp
new file mode 100644
index 000000000..af7f6e818
--- /dev/null
+++ b/src/libs/installer/repositorycategory.cpp
@@ -0,0 +1,159 @@
+/**************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "repositorycategory.h"
+#include "filedownloaderfactory.h"
+
+#include <QDataStream>
+#include <QFileInfo>
+#include <QStringList>
+
+namespace QInstaller {
+
+
+template <typename T>
+static QSet<T> variantListToSet(const QVariantList &list)
+{
+ QSet<T> set;
+ foreach (const QVariant &variant, list)
+ set.insert(variant.value<T>());
+ return set;
+}
+
+/*!
+ Constructs an uninitialized RepositoryCategory object.
+*/
+RepositoryCategory::RepositoryCategory()
+ : m_enabled(false)
+{
+ registerMetaType();
+}
+
+/*!
+ Constructs a new category by using all fields of the given category \a other.
+*/
+RepositoryCategory::RepositoryCategory(const RepositoryCategory &other)
+ : m_displayname(other.m_displayname), m_data(other.m_data), m_enabled(other.m_enabled)
+{
+ registerMetaType();
+}
+
+
+void RepositoryCategory::registerMetaType()
+{
+ qRegisterMetaType<RepositoryCategory>("RepositoryCategory");
+ qRegisterMetaTypeStreamOperators<RepositoryCategory>("RepositoryCategory");
+}
+
+/*!
+ Returns the Name for the category to be displayed.
+*/
+QString RepositoryCategory::displayname() const
+{
+ return m_displayname;
+}
+
+/*!
+ Sets the DisplayName of the category to \a displayname.
+*/
+void RepositoryCategory::setDisplayName(const QString &displayname)
+{
+ m_displayname = displayname;
+}
+
+/*!
+ Returns the list of repositories the category has.
+*/
+QSet<Repository> RepositoryCategory::repositories() const
+{
+ return variantListToSet<Repository>(m_data.values(QLatin1String("Repositories")));
+}
+
+/*!
+ Inserts a set of \a repositories to the category.
+*/
+void RepositoryCategory::setRepositories(const QSet<Repository> repositories)
+{
+ foreach (const Repository &repository, repositories)
+ m_data.insertMulti(QLatin1String("Repositories"), QVariant().fromValue(repository));
+}
+
+/*!
+ Inserts \a repository to the category.
+*/
+void RepositoryCategory::addRepository(const Repository repository)
+{
+ m_data.insertMulti(QLatin1String("Repositories"), QVariant().fromValue(repository));
+}
+
+/*!
+ Returns whether this category is enabled and used during information retrieval.
+*/
+bool RepositoryCategory::isEnabled() const
+{
+ return m_enabled;
+}
+
+/*!
+ Sets this category to \a enabled state and and thus determines whether to use this
+ repository for information retrieval.
+
+*/
+void RepositoryCategory::setEnabled(bool enabled)
+{
+ m_enabled = enabled;
+}
+
+/*!
+ Compares the values of this category to \a other and returns true if they are equal.
+*/
+bool RepositoryCategory::operator==(const RepositoryCategory &other) const
+{
+ return m_displayname == other.m_displayname;
+}
+
+/*!
+ Returns true if the \a other category is not equal to this repository; otherwise returns false. Two
+ categories are considered equal if they contain the same displayname. \sa operator==()
+*/
+bool RepositoryCategory::operator!=(const RepositoryCategory &other) const
+{
+ return !(*this == other);
+}
+
+QDataStream &operator>>(QDataStream &istream, RepositoryCategory &repository)
+{
+ return istream;
+}
+
+QDataStream &operator<<(QDataStream &ostream, const RepositoryCategory &repository)
+{
+ return ostream << repository.m_displayname.toUtf8().toBase64() << repository.m_data;
+}
+
+}
diff --git a/src/libs/installer/repositorycategory.h b/src/libs/installer/repositorycategory.h
new file mode 100644
index 000000000..315af761b
--- /dev/null
+++ b/src/libs/installer/repositorycategory.h
@@ -0,0 +1,86 @@
+/**************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef ARCHIVEREPOSITORY_H
+#define ARCHIVEREPOSITORY_H
+
+#include "installer_global.h"
+#include "repository.h"
+
+#include <QtCore/QMetaType>
+#include <QtCore/QUrl>
+#include <QSet>
+
+namespace QInstaller {
+
+class INSTALLER_EXPORT RepositoryCategory
+{
+
+public:
+ explicit RepositoryCategory();
+ RepositoryCategory(const RepositoryCategory &other);
+
+ static void registerMetaType();
+
+ QString displayname() const;
+ void setDisplayName(const QString &displayname);
+
+ QSet<Repository> repositories() const;
+ void setRepositories(const QSet<Repository> repositories);
+ void addRepository(const Repository repository);
+
+ bool isEnabled() const;
+ void setEnabled(bool enabled);
+
+ bool operator==(const RepositoryCategory &other) const;
+ bool operator!=(const RepositoryCategory &other) const;
+
+ uint qHash(const RepositoryCategory &repository);
+
+ friend INSTALLER_EXPORT QDataStream &operator>>(QDataStream &istream, RepositoryCategory &repository);
+ friend INSTALLER_EXPORT QDataStream &operator<<(QDataStream &ostream, const RepositoryCategory &repository);
+
+private:
+ QVariantHash m_data;
+ QString m_displayname;
+ bool m_enabled;
+};
+
+inline uint qHash(const RepositoryCategory &repository)
+{
+ return qHash(repository.displayname());
+}
+
+INSTALLER_EXPORT QDataStream &operator>>(QDataStream &istream, RepositoryCategory &repository);
+INSTALLER_EXPORT QDataStream &operator<<(QDataStream &ostream, const RepositoryCategory &repository);
+
+} // namespace QInstaller
+
+Q_DECLARE_METATYPE(QInstaller::RepositoryCategory)
+
+#endif // ARCHIVEREPOSITORY_H
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index 5761387c6..21bbe8b4c 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -30,6 +30,7 @@
#include "errors.h"
#include "qinstallerglobal.h"
#include "repository.h"
+#include "repositorycategory.h"
#include <QtCore/QFileInfo>
#include <QtCore/QStringList>
@@ -55,6 +56,7 @@ static const QLatin1String scUserRepositories("UserRepositories");
static const QLatin1String scTmpRepositories("TemporaryRepositories");
static const QLatin1String scMaintenanceToolIniFile("MaintenanceToolIniFile");
static const QLatin1String scRemoteRepositories("RemoteRepositories");
+static const QLatin1String scRepositoryCategories("RepositoryCategories");
static const QLatin1String scDependsOnLocalInstallerBinary("DependsOnLocalInstallerBinary");
static const QLatin1String scTranslations("Translations");
static const QLatin1String scCreateLocalRepository("CreateLocalRepository");
@@ -133,11 +135,15 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa
return arguments;
}
-static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefault, Settings::ParseMode parseMode)
+static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefault, Settings::ParseMode parseMode, QString *displayName = 0)
{
+ qDebug()<<__FUNCTION__;
QSet<Repository> set;
while (reader.readNextStartElement()) {
- if (reader.name() == QLatin1String("Repository")) {
+ if (reader.name() == QLatin1String("DisplayName")) {
+ //remote repository can have also displayname. Needed when creating archive repositories
+ *displayName = reader.readElementText();
+ } else if (reader.name() == QLatin1String("Repository")) {
Repository repo(QString(), isDefault);
while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("Url")) {
@@ -160,6 +166,8 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
.arg(reader.name().toString()), parseMode);
}
}
+ if (displayName && !displayName->isEmpty())
+ repo.setArchiveName(*displayName);
set.insert(repo);
} else {
raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name().toString()),
@@ -174,6 +182,23 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
return set;
}
+static QSet<RepositoryCategory> readRepositoryCategories(QXmlStreamReader &reader, bool isDefault, Settings::ParseMode parseMode,
+ QString *repositoryCategoryName)
+{
+ QSet<RepositoryCategory> archiveSet;
+ while (reader.readNextStartElement()) {
+ if (reader.name() == QLatin1String("RemoteRepositories")) {
+ RepositoryCategory archiveRepo;
+ QString displayName;
+ archiveRepo.setRepositories(readRepositories(reader, isDefault, parseMode, &displayName));
+ archiveRepo.setDisplayName(displayName);
+ archiveSet.insert(archiveRepo);
+ } else if (reader.name() == QLatin1String("RepositoryCategoryDisplayname")) {
+ *repositoryCategoryName = reader.readElementText();
+ }
+ }
+ return archiveSet;
+}
// -- Settings::Private
@@ -257,7 +282,7 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
<< scRepositorySettingsPageVisible << scTargetConfigurationFile
<< scRemoteRepositories << scTranslations << scUrlQueryString << QLatin1String(scControlScript)
<< scCreateLocalRepository << scInstallActionColumnVisible << scSupportsModify << scAllowUnstableComponents
- << scSaveDefaultRepositories;
+ << scSaveDefaultRepositories << scRepositoryCategories;
Settings s;
s.d->m_data.insert(scPrefix, prefix);
@@ -280,11 +305,16 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
s.setRunProgramArguments(readArgumentAttributes(reader, parseMode, QLatin1String("Argument")));
} else if (name == scRemoteRepositories) {
s.addDefaultRepositories(readRepositories(reader, true, parseMode));
+ } else if (name == scRepositoryCategories) {
+ QString repositoryCategoryName;
+ s.addRepositoryCategories(readRepositoryCategories(reader, true, parseMode, &repositoryCategoryName));
+ if (!repositoryCategoryName.isEmpty()) {
+ s.setRepositoryCategoryDisplayName(repositoryCategoryName);
+ }
} else {
s.d->m_data.insert(name, reader.readElementText(QXmlStreamReader::SkipChildElements));
}
}
-
if (reader.error() != QXmlStreamReader::NoError) {
throw Error(QString::fromLatin1("Error in %1, line %2, column %3: %4").arg(path).arg(reader
.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
@@ -549,6 +579,11 @@ QSet<Repository> Settings::defaultRepositories() const
return variantListToSet<Repository>(d->m_data.values(scRepositories));
}
+QSet<RepositoryCategory> Settings::repositoryCategories() const
+{
+ return variantListToSet<RepositoryCategory>(d->m_data.values(scRepositoryCategories));
+}
+
void Settings::setDefaultRepositories(const QSet<Repository> &repositories)
{
d->m_data.remove(scRepositories);
@@ -561,6 +596,12 @@ void Settings::addDefaultRepositories(const QSet<Repository> &repositories)
d->m_data.insertMulti(scRepositories, QVariant().fromValue(repository));
}
+void Settings::addRepositoryCategories(const QSet<RepositoryCategory> &repositories)
+{
+ foreach (const RepositoryCategory &repository, repositories)
+ d->m_data.insertMulti(scRepositoryCategories, QVariant().fromValue(repository));
+}
+
static bool apply(const RepoHash &updates, QHash<QUrl, Repository> *reposToUpdate)
{
bool update = false;
@@ -767,3 +808,14 @@ void Settings::setSaveDefaultRepositories(bool save)
{
d->m_data.insert(scSaveDefaultRepositories, save);
}
+
+QString Settings::repositoryCategoryDisplayName() const
+{
+ QString displayName = d->m_data.value(QLatin1String(scRepositoryCategoryDisplayName)).toString();
+ return displayName.isEmpty() ? tr("Package categories") : displayName;
+}
+
+void Settings::setRepositoryCategoryDisplayName(const QString& name)
+{
+ d->m_data.insert(scRepositoryCategoryDisplayName, name);
+}
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index bc2db655b..0ee58639d 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -31,6 +31,7 @@
#include "constants.h"
#include "installer_global.h"
+#include "repositorycategory.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QSharedDataPointer>
@@ -114,8 +115,10 @@ public:
QSet<Repository> repositories() const;
QSet<Repository> defaultRepositories() const;
+ QSet<RepositoryCategory> repositoryCategories() const;
void setDefaultRepositories(const QSet<Repository> &repositories);
void addDefaultRepositories(const QSet<Repository> &repositories);
+ void addRepositoryCategories(const QSet<RepositoryCategory> &repositories);
Settings::Update updateDefaultRepositories(const RepoHash &updates);
QSet<Repository> temporaryRepositories() const;
@@ -160,6 +163,9 @@ public:
bool saveDefaultRepositories() const;
void setSaveDefaultRepositories(bool save);
+ QString repositoryCategoryDisplayName() const;
+ void setRepositoryCategoryDisplayName(const QString &displayName);
+
private:
class Private;
QSharedDataPointer<Private> d;