summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2018-10-22 14:10:15 +0300
committerKatja Marttila <katja.marttila@qt.io>2018-10-23 10:05:55 +0000
commit3053efe754bfac6f0d7faa07bbcece3ebfd30270 (patch)
treefebd6bca24c490787114aeb468f46bacad3da46c
parent70273f9931aad662d1697b142140791a100059f5 (diff)
Refactor component selection page
Component selection page has a lot of widgets compared to other pages so moved the implementation to own file. Also fixed the following issues in component selection page: 1. Fixed crash when there were no categories and QBsp button was pressed 2. QBsp button opened multiple dialogs if next/back buttons were pressed 3. Made progressbar use the entire vertical space Change-Id: I30cf1599ecb06a633719622427855a57696d5987 Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
-rw-r--r--src/libs/installer/componentselectionpage_p.cpp454
-rw-r--r--src/libs/installer/componentselectionpage_p.h108
-rw-r--r--src/libs/installer/installer.pro6
-rw-r--r--src/libs/installer/packagemanagergui.cpp451
-rw-r--r--src/libs/installer/packagemanagergui.h6
5 files changed, 573 insertions, 452 deletions
diff --git a/src/libs/installer/componentselectionpage_p.cpp b/src/libs/installer/componentselectionpage_p.cpp
new file mode 100644
index 000000000..22c478beb
--- /dev/null
+++ b/src/libs/installer/componentselectionpage_p.cpp
@@ -0,0 +1,454 @@
+/**************************************************************************
+**
+** 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 "componentselectionpage_p.h"
+
+#include "packagemanagergui.h"
+#include "componentmodel.h"
+#include "settings.h"
+#include "component.h"
+#include "fileutils.h"
+#include "messageboxhandler.h"
+
+#include <QTreeView>
+#include <QLabel>
+#include <QPushButton>
+#include <QGroupBox>
+#include <QProgressBar>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QCheckBox>
+#include <QHeaderView>
+#include <QStandardPaths>
+#include <QFileDialog>
+
+namespace QInstaller {
+
+ComponentSelectionPagePrivate::ComponentSelectionPagePrivate(ComponentSelectionPage *qq, PackageManagerCore *core)
+ : q(qq)
+ , m_core(core)
+ , m_treeView(new QTreeView(q))
+ , m_allModel(m_core->defaultComponentModel())
+ , m_updaterModel(m_core->updaterComponentModel())
+ , m_currentModel(m_allModel)
+ , m_allowCompressedRepositoryInstall(false)
+ , m_categoryWidget(Q_NULLPTR)
+{
+ m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
+
+ connect(m_allModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)), this,
+ SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
+ connect(m_updaterModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)),
+ this, SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
+
+ m_descriptionVLayout = new QVBoxLayout;
+ m_descriptionVLayout->setObjectName(QLatin1String("DescriptionLayout"));
+
+ m_descriptionLabel = new QLabel(q);
+ m_descriptionLabel->setWordWrap(true);
+ m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
+ m_descriptionVLayout->addWidget(m_descriptionLabel);
+
+ m_sizeLabel = new QLabel(q);
+ m_sizeLabel->setWordWrap(true);
+ m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
+ m_descriptionVLayout->addWidget(m_sizeLabel);
+ m_descriptionVLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
+ QSizePolicy::MinimumExpanding));
+
+ m_treeViewVLayout = new QVBoxLayout;
+ m_treeViewVLayout->setObjectName(QLatin1String("TreeviewLayout"));
+
+ QHBoxLayout *buttonHLayout = new QHBoxLayout;
+ m_checkDefault = new QPushButton;
+ connect(m_checkDefault, &QAbstractButton::clicked,
+ this, &ComponentSelectionPagePrivate::selectDefault);
+ if (m_core->isInstaller()) {
+ m_checkDefault->setObjectName(QLatin1String("SelectDefaultComponentsButton"));
+ m_checkDefault->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+A",
+ "select default components")));
+ m_checkDefault->setText(ComponentSelectionPage::tr("Def&ault"));
+ } else {
+ m_checkDefault->setEnabled(false);
+ m_checkDefault->setObjectName(QLatin1String("ResetComponentsButton"));
+ m_checkDefault->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+R",
+ "reset to already installed components")));
+ m_checkDefault->setText(ComponentSelectionPage::tr("&Reset"));
+ }
+ buttonHLayout->addWidget(m_checkDefault);
+
+ m_checkAll = new QPushButton;
+ connect(m_checkAll, &QAbstractButton::clicked,
+ this, &ComponentSelectionPagePrivate::selectAll);
+ m_checkAll->setObjectName(QLatin1String("SelectAllComponentsButton"));
+ m_checkAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+S",
+ "select all components")));
+ m_checkAll->setText(ComponentSelectionPage::tr("&Select All"));
+ buttonHLayout->addWidget(m_checkAll);
+
+ m_uncheckAll = new QPushButton;
+ connect(m_uncheckAll, &QAbstractButton::clicked,
+ this, &ComponentSelectionPagePrivate::deselectAll);
+ m_uncheckAll->setObjectName(QLatin1String("DeselectAllComponentsButton"));
+ m_uncheckAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+D",
+ "deselect all components")));
+ m_uncheckAll->setText(ComponentSelectionPage::tr("&Deselect All"));
+ buttonHLayout->addWidget(m_uncheckAll);
+
+ m_treeViewVLayout->addLayout(buttonHLayout);
+
+ m_metadataProgressLabel = new QLabel();
+ m_metadataProgressLabel->hide();
+ m_treeViewVLayout->addWidget(m_metadataProgressLabel);
+
+ 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,
+ &ComponentSelectionPagePrivate::setTotalProgress);
+
+ m_treeViewVLayout->addWidget(m_treeView, 3);
+
+ m_mainHLayout = new QHBoxLayout(q);
+ m_mainHLayout->addLayout(m_treeViewVLayout, 3);
+ m_mainHLayout->addLayout(m_descriptionVLayout, 2);
+
+#ifdef INSTALLCOMPRESSED
+ allowCompressedRepositoryInstall();
+#endif
+}
+
+ComponentSelectionPagePrivate::~ComponentSelectionPagePrivate()
+{
+
+}
+
+void ComponentSelectionPagePrivate::allowCompressedRepositoryInstall()
+{
+ m_allowCompressedRepositoryInstall = true;
+}
+
+void ComponentSelectionPagePrivate::showCompressedRepositoryButton()
+{
+ QWizard *wizard = qobject_cast<QWizard*>(m_core->guiObject());
+ if (wizard && !(wizard->options() & QWizard::HaveCustomButton2) && m_allowCompressedRepositoryInstall) {
+ wizard->setOption(QWizard::HaveCustomButton2, true);
+ wizard->setButtonText(QWizard::CustomButton2,
+ ComponentSelectionPage::tr("&Browse QBSP files"));
+ connect(wizard, &QWizard::customButtonClicked,
+ this, &ComponentSelectionPagePrivate::customButtonClicked);
+ q->gui()->updateButtonLayout();
+ }
+}
+
+void ComponentSelectionPagePrivate::hideCompressedRepositoryButton()
+{
+ QWizard *wizard = qobject_cast<QWizard*>(m_core->guiObject());
+ if (wizard && (wizard->options() & QWizard::HaveCustomButton2)) {
+ wizard->setOption(QWizard::HaveCustomButton2, false);
+ disconnect(wizard, &QWizard::customButtonClicked,
+ this, &ComponentSelectionPagePrivate::customButtonClicked);
+ q->gui()->updateButtonLayout();
+ }
+}
+
+void ComponentSelectionPagePrivate::setupCategoryLayout()
+{
+ if (m_categoryWidget)
+ return;
+ m_categoryWidget = new QWidget();
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ m_categoryWidget->setLayout(vLayout);
+ m_categoryGroupBox = new QGroupBox(q);
+ m_categoryGroupBox->setTitle(m_core->settings().repositoryCategoryDisplayName());
+ m_categoryGroupBox->setObjectName(QLatin1String("CategoryGroupBox"));
+ QVBoxLayout *categoryLayout = new QVBoxLayout(m_categoryGroupBox);
+ QPushButton *fetchCategoryButton = new QPushButton(tr("Fetch"));
+ fetchCategoryButton->setObjectName(QLatin1String("FetchCategoryButton"));
+ connect(fetchCategoryButton, &QPushButton::clicked, this,
+ &ComponentSelectionPagePrivate::fetchRepositoryCategories);
+
+ foreach (RepositoryCategory repository, m_core->settings().repositoryCategories()) {
+ QCheckBox *checkBox = new QCheckBox;
+ checkBox->setObjectName(repository.displayname());
+ connect(checkBox, &QCheckBox::stateChanged, this,
+ &ComponentSelectionPagePrivate::checkboxStateChanged);
+ checkBox->setText(repository.displayname());
+ categoryLayout->addWidget(checkBox);
+ }
+
+ vLayout->addWidget(m_categoryGroupBox);
+ vLayout->addWidget(fetchCategoryButton);
+ vLayout->addStretch();
+ m_mainHLayout->insertWidget(0, m_categoryWidget);
+}
+
+void ComponentSelectionPagePrivate::updateTreeView()
+{
+ m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
+ if (m_treeView->selectionModel()) {
+ disconnect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &ComponentSelectionPagePrivate::currentSelectedChanged);
+ }
+
+ m_currentModel = m_core->isUpdater() ? m_updaterModel : m_allModel;
+ m_treeView->setModel(m_currentModel);
+ m_treeView->setExpanded(m_currentModel->index(0, 0), true);
+ foreach (Component *component, m_core->components(PackageManagerCore::ComponentType::All)) {
+ if (component->isExpandedByDefault()) {
+ const QModelIndex index = m_currentModel->indexFromComponentName(component->name());
+ m_treeView->setExpanded(index, true);
+ }
+ }
+
+ const bool installActionColumnVisible = m_core->settings().installActionColumnVisible();
+ if (!installActionColumnVisible)
+ m_treeView->hideColumn(ComponentModelHelper::ActionColumn);
+
+ m_treeView->header()->setSectionResizeMode(
+ ComponentModelHelper::NameColumn, QHeaderView::ResizeToContents);
+ if (m_core->isInstaller()) {
+ m_treeView->setHeaderHidden(true);
+ for (int i = ComponentModelHelper::InstalledVersionColumn; i < m_currentModel->columnCount(); ++i)
+ m_treeView->hideColumn(i);
+
+ if (installActionColumnVisible) {
+ m_treeView->header()->setStretchLastSection(false);
+ m_treeView->header()->setSectionResizeMode(
+ ComponentModelHelper::NameColumn, QHeaderView::Stretch);
+ m_treeView->header()->setSectionResizeMode(
+ ComponentModelHelper::ActionColumn, QHeaderView::ResizeToContents);
+ }
+ } else {
+ m_treeView->header()->setStretchLastSection(true);
+ if (installActionColumnVisible) {
+ m_treeView->header()->setSectionResizeMode(
+ ComponentModelHelper::NameColumn, QHeaderView::Interactive);
+ m_treeView->header()->setSectionResizeMode(
+ ComponentModelHelper::ActionColumn, QHeaderView::Interactive);
+ }
+ for (int i = 0; i < m_currentModel->columnCount(); ++i)
+ m_treeView->resizeColumnToContents(i);
+ }
+
+ bool hasChildren = false;
+ const int rowCount = m_currentModel->rowCount();
+ for (int row = 0; row < rowCount && !hasChildren; ++row)
+ hasChildren = m_currentModel->hasChildren(m_currentModel->index(row, 0));
+ m_treeView->setRootIsDecorated(hasChildren);
+
+ connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &ComponentSelectionPagePrivate::currentSelectedChanged);
+
+ m_treeView->setCurrentIndex(m_currentModel->index(0, 0));
+}
+
+void ComponentSelectionPagePrivate::currentSelectedChanged(const QModelIndex &current)
+{
+ if (!current.isValid())
+ return;
+
+ m_sizeLabel->setText(QString());
+ m_descriptionLabel->setText(m_currentModel->data(m_currentModel->index(current.row(),
+ ComponentModelHelper::NameColumn, current.parent()), Qt::ToolTipRole).toString());
+
+ Component *component = m_currentModel->componentFromIndex(current);
+ if ((m_core->isUninstaller()) || (!component))
+ return;
+
+ if (component->isSelected() && (component->value(scUncompressedSizeSum).toLongLong() > 0)) {
+ m_sizeLabel->setText(ComponentSelectionPage::tr("This component "
+ "will occupy approximately %1 on your hard disk drive.")
+ .arg(humanReadableSize(component->value(scUncompressedSizeSum).toLongLong())));
+ }
+}
+
+void ComponentSelectionPagePrivate::selectAll()
+{
+ m_currentModel->setCheckedState(ComponentModel::AllChecked);
+}
+
+void ComponentSelectionPagePrivate::deselectAll()
+{
+ m_currentModel->setCheckedState(ComponentModel::AllUnchecked);
+}
+
+void ComponentSelectionPagePrivate::checkboxStateChanged()
+{
+ QList<QCheckBox*> checkboxes = m_categoryGroupBox->findChildren<QCheckBox *>();
+ bool enableFetchButton = false;
+ foreach (QCheckBox *checkbox, checkboxes) {
+ if (checkbox->isChecked()) {
+ enableFetchButton = true;
+ break;
+ }
+ }
+}
+
+void ComponentSelectionPagePrivate::enableRepositoryCategory(int index, bool enable) {
+ RepositoryCategory repoCategory = m_core->settings().repositoryCategories().toList().at(index);
+ RepositoryCategory replacement = repoCategory;
+ replacement.setEnabled(enable);
+ QSet<RepositoryCategory> tmpRepoCategories = m_core->settings().repositoryCategories();
+ if (tmpRepoCategories.contains(repoCategory)) {
+ tmpRepoCategories.remove(repoCategory);
+ tmpRepoCategories.insert(replacement);
+ m_core->settings().addRepositoryCategories(tmpRepoCategories);
+ }
+}
+
+void ComponentSelectionPagePrivate::updateWidgetVisibility(bool show)
+{
+ if (show) {
+ QSpacerItem *verticalSpacer2 = new QSpacerItem(0, 0, QSizePolicy::Minimum,
+ QSizePolicy::Expanding);
+ m_treeViewVLayout->addSpacerItem(verticalSpacer2);
+ m_mainHLayout->removeItem(m_descriptionVLayout);
+ } else {
+ QSpacerItem *item = m_treeViewVLayout->spacerItem();
+ m_treeViewVLayout->removeItem(item);
+ m_mainHLayout->addLayout(m_descriptionVLayout, 2);
+ }
+ if (m_categoryWidget)
+ m_categoryWidget->setDisabled(show);
+ m_progressBar->setVisible(show);
+ m_metadataProgressLabel->setVisible(show);
+
+ m_treeView->setVisible(!show);
+ m_checkDefault->setVisible(!show);
+ m_checkAll->setVisible(!show);
+ m_uncheckAll->setVisible(!show);
+ m_descriptionLabel->setVisible(!show);
+ m_sizeLabel->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 ComponentSelectionPagePrivate::fetchRepositoryCategories()
+{
+ updateWidgetVisibility(true);
+
+ QCheckBox *checkbox;
+ QList<QCheckBox*> checkboxes = m_categoryGroupBox->findChildren<QCheckBox *>();
+ for (int i = 0; i < checkboxes.count(); i++) {
+ checkbox = checkboxes.at(i);
+ enableRepositoryCategory(i, checkbox->isChecked());
+ }
+
+ if (!m_core->fetchRemotePackagesTree()) {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("FailToFetchPackages"), tr("Error"), m_core->error());
+ }
+ updateWidgetVisibility(false);
+}
+
+void ComponentSelectionPagePrivate::customButtonClicked(int which)
+{
+ if (QWizard::WizardButton(which) == QWizard::CustomButton2) {
+ QString defaultDownloadDirectory =
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+ QStringList fileNames = QFileDialog::getOpenFileNames(NULL,
+ ComponentSelectionPage::tr("Open File"),defaultDownloadDirectory,
+ QLatin1String("QBSP or 7z Files (*.qbsp *.7z)"));
+
+ QSet<Repository> set;
+ foreach (QString fileName, fileNames) {
+ Repository repository = Repository::fromUserInput(fileName, true);
+ repository.setEnabled(true);
+ set.insert(repository);
+ }
+ if (set.count() > 0) {
+ updateWidgetVisibility(true);
+ m_core->settings().addTemporaryRepositories(set, false);
+ if (!m_core->fetchCompressedPackagesTree()) {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("FailToFetchPackages"), tr("Error"), m_core->error());
+ }
+ }
+ updateWidgetVisibility(false);
+ }
+}
+
+/*!
+ Updates the value of \a progress on the progress bar.
+*/
+void ComponentSelectionPagePrivate::onProgressChanged(int progress)
+{
+ m_progressBar->setValue(progress);
+}
+
+/*!
+ Displays the message \a msg on the page.
+*/
+void ComponentSelectionPagePrivate::setMessage(const QString &msg)
+{
+ QWizardPage *page = q->gui()->currentPage();
+ if (m_metadataProgressLabel && page && page->objectName() == QLatin1String("ComponentSelectionPage"))
+ m_metadataProgressLabel->setText(msg);
+}
+
+void ComponentSelectionPagePrivate::setTotalProgress(int totalProgress)
+{
+ if (m_progressBar)
+ m_progressBar->setRange(0, totalProgress);
+}
+
+void ComponentSelectionPagePrivate::selectDefault()
+{
+ m_currentModel->setCheckedState(ComponentModel::DefaultChecked);
+}
+
+void ComponentSelectionPagePrivate::onModelStateChanged(QInstaller::ComponentModel::ModelState state)
+{
+ q->setModified(state.testFlag(ComponentModel::DefaultChecked) == false);
+ // If all components in the checked list are only checkable when run without forced
+ // installation, set ComponentModel::AllUnchecked as well, as we cannot uncheck anything.
+ // Helps to keep the UI correct.
+ if ((!m_core->noForceInstallation())
+ && (m_currentModel->checked() == m_currentModel->uncheckable())) {
+ state |= ComponentModel::AllUnchecked;
+ }
+ // enable the button if the corresponding flag is not set
+ m_checkAll->setEnabled(state.testFlag(ComponentModel::AllChecked) == false);
+ m_uncheckAll->setEnabled(state.testFlag(ComponentModel::AllUnchecked) == false);
+ m_checkDefault->setEnabled(state.testFlag(ComponentModel::DefaultChecked) == false);
+
+ // update the current selected node (important to reflect possible sub-node changes)
+ if (m_treeView->selectionModel())
+ currentSelectedChanged(m_treeView->selectionModel()->currentIndex());
+}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/componentselectionpage_p.h b/src/libs/installer/componentselectionpage_p.h
new file mode 100644
index 000000000..bc1e6ed7a
--- /dev/null
+++ b/src/libs/installer/componentselectionpage_p.h
@@ -0,0 +1,108 @@
+/**************************************************************************
+**
+** 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 COMPONENTSELECTIONPAGE_P_H
+#define COMPONENTSELECTIONPAGE_P_H
+
+#include <QObject>
+#include <QWidget>
+
+#include "componentmodel.h"
+#include "packagemanagergui.h"
+
+class QTreeView;
+class QLabel;
+class QPushButton;
+class QGroupBox;
+class QListWidgetItem;
+class QProgressBar;
+class QVBoxLayout;
+class QHBoxLayout;
+
+namespace QInstaller {
+
+class PackageManagerCore;
+class ComponentModel;
+class ComponentSelectionPage;
+
+class ComponentSelectionPagePrivate : public QObject
+{
+ Q_OBJECT
+ friend class ComponentSelectionPage;
+ Q_DISABLE_COPY(ComponentSelectionPagePrivate)
+
+public:
+ explicit ComponentSelectionPagePrivate(ComponentSelectionPage *qq, PackageManagerCore *core);
+ ~ComponentSelectionPagePrivate();
+
+ void allowCompressedRepositoryInstall();
+ void showCompressedRepositoryButton();
+ void hideCompressedRepositoryButton();
+ void setupCategoryLayout();
+ void updateTreeView();
+
+public slots:
+ void currentSelectedChanged(const QModelIndex &current);
+ void selectAll();
+ void deselectAll();
+ void checkboxStateChanged();
+ void enableRepositoryCategory(int index, bool enable);
+ void updateWidgetVisibility(bool show);
+ void fetchRepositoryCategories();
+ void customButtonClicked(int which);
+ void onProgressChanged(int progress);
+ void setMessage(const QString &msg);
+ void setTotalProgress(int totalProgress);
+ void selectDefault();
+ void onModelStateChanged(QInstaller::ComponentModel::ModelState state);
+
+private:
+ ComponentSelectionPage *q;
+ PackageManagerCore *m_core;
+ QTreeView *m_treeView;
+ QLabel *m_sizeLabel;
+ QLabel *m_descriptionLabel;
+ QVBoxLayout *m_descriptionVLayout;
+ QPushButton *m_checkAll;
+ QPushButton *m_uncheckAll;
+ QPushButton *m_checkDefault;
+ QWidget *m_categoryWidget;
+ QGroupBox *m_categoryGroupBox;
+ QLabel *m_metadataProgressLabel;
+ QProgressBar *m_progressBar;
+ QHBoxLayout *m_mainHLayout;
+ QVBoxLayout *m_treeViewVLayout;
+ bool m_allowCompressedRepositoryInstall;
+ ComponentModel *m_allModel;
+ ComponentModel *m_updaterModel;
+ ComponentModel *m_currentModel;
+};
+
+} // namespace QInstaller
+
+#endif // COMPONENTSELECTIONPAGE_P_H
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index bdca7e0f3..a6dfbde50 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -132,7 +132,8 @@ HEADERS += packagemanagercore.h \
lib7z_create.h \
lib7z_extract.h \
lib7z_list.h \
- repositorycategory.h
+ repositorycategory.h \
+ componentselectionpage_p.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -208,7 +209,8 @@ SOURCES += packagemanagercore.cpp \
keepaliveobject.cpp \
systeminfo.cpp \
packagesource.cpp \
- repositorycategory.cpp
+ repositorycategory.cpp \
+ componentselectionpage_p.cpp
FORMS += proxycredentialsdialog.ui \
serverauthenticationdialog.ui
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 8961e3a19..a7a0aa45e 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -40,6 +40,7 @@
#include "scriptengine.h"
#include "productkeycheck.h"
#include "repositorycategory.h"
+#include "componentselectionpage_p.h"
#include "sysinfo.h"
@@ -57,7 +58,6 @@
#include <QFileDialog>
#include <QGridLayout>
#include <QHBoxLayout>
-#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
@@ -68,7 +68,7 @@
#include <QRadioButton>
#include <QStringListModel>
#include <QTextBrowser>
-#include <QTreeView>
+
#include <QVBoxLayout>
#include <QShowEvent>
#include <QFileDialog>
@@ -1849,444 +1849,6 @@ void LicenseAgreementPage::updateUi()
}
-
-// -- ComponentSelectionPage::Private
-
-class ComponentSelectionPage::Private : public QObject
-{
- Q_OBJECT
-
-public:
- Private(ComponentSelectionPage *qq, PackageManagerCore *core)
- : q(qq)
- , m_core(core)
- , m_treeView(new QTreeView(q))
- , m_allModel(m_core->defaultComponentModel())
- , m_updaterModel(m_core->updaterComponentModel())
- , m_currentModel(m_allModel)
- , m_compressedButtonVisible(false)
- , m_allowCompressedRepositoryInstall(false)
- , m_categoryLayoutVisible(false)
- {
- m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
-
- connect(m_allModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)), this,
- SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
- connect(m_updaterModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)),
- this, SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
-
- m_descriptionVLayout = new QVBoxLayout;
- m_descriptionVLayout->setObjectName(QLatin1String("DescriptionLayout"));
-
- m_descriptionLabel = new QLabel(q);
- m_descriptionLabel->setWordWrap(true);
- m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
- m_descriptionVLayout->addWidget(m_descriptionLabel);
-
- m_sizeLabel = new QLabel(q);
- m_sizeLabel->setWordWrap(true);
- m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
- m_descriptionVLayout->addWidget(m_sizeLabel);
- m_descriptionVLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
- QSizePolicy::MinimumExpanding));
-
- 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);
- if (m_core->isInstaller()) {
- m_checkDefault->setObjectName(QLatin1String("SelectDefaultComponentsButton"));
- m_checkDefault->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+A",
- "select default components")));
- m_checkDefault->setText(ComponentSelectionPage::tr("Def&ault"));
- } else {
- m_checkDefault->setEnabled(false);
- m_checkDefault->setObjectName(QLatin1String("ResetComponentsButton"));
- m_checkDefault->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+R",
- "reset to already installed components")));
- m_checkDefault->setText(ComponentSelectionPage::tr("&Reset"));
- }
- m_buttonHLayout->addWidget(m_checkDefault);
-
- m_checkAll = new QPushButton;
- 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;
- 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);
-
- 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()
- {
- 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)));
-
- 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;
- }
-
- void setupCategoryLayout()
- {
- if (m_categoryLayoutVisible)
- return;
- QVBoxLayout *vLayout = new QVBoxLayout;
- m_categoryVLayout = new QVBoxLayout;
- m_categoryGroupBox = new QGroupBox(q);
- m_categoryGroupBox->setTitle(m_core->settings().repositoryCategoryDisplayName());
- m_categoryGroupBox->setObjectName(QLatin1String("CategoryGroupBox"));
- QVBoxLayout *categoryLayout = new QVBoxLayout(m_categoryGroupBox);
- m_fetchCategoryButton = new QPushButton(tr("Fetch"));
- m_fetchCategoryButton->setObjectName(QLatin1String("FetchCategoryButton"));
- connect(m_fetchCategoryButton, &QPushButton::clicked, this,
- &ComponentSelectionPage::Private::fetchRepositoryCategories);
-
- foreach (RepositoryCategory repository, m_core->settings().repositoryCategories()) {
- QCheckBox *checkBox = new QCheckBox;
- checkBox->setObjectName(repository.displayname());
- connect(checkBox, &QCheckBox::stateChanged, this,
- &ComponentSelectionPage::Private::checkboxStateChanged);
- checkBox->setText(repository.displayname());
- categoryLayout->addWidget(checkBox);
- }
- m_categoryVLayout->insertWidget(0, m_categoryGroupBox);
-
- m_metadataProgressLabel = new QLabel(q);
- m_categoryVLayout->addWidget(m_metadataProgressLabel);
- vLayout->addWidget(m_categoryGroupBox);
- vLayout->addWidget(m_fetchCategoryButton);
- vLayout->addStretch();
- m_mainHLayout->insertLayout(0, vLayout);
- m_categoryLayoutVisible = true;
- }
-
- void updateTreeView()
- {
- m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
- if (m_treeView->selectionModel()) {
- disconnect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
- this, &ComponentSelectionPage::Private::currentSelectedChanged);
- }
-
- m_currentModel = m_core->isUpdater() ? m_updaterModel : m_allModel;
- m_treeView->setModel(m_currentModel);
- m_treeView->setExpanded(m_currentModel->index(0, 0), true);
- foreach (Component *component, m_core->components(PackageManagerCore::ComponentType::All)) {
- if (component->isExpandedByDefault()) {
- const QModelIndex index = m_currentModel->indexFromComponentName(component->name());
- m_treeView->setExpanded(index, true);
- }
- }
-
- const bool installActionColumnVisible = m_core->settings().installActionColumnVisible();
- if (!installActionColumnVisible)
- m_treeView->hideColumn(ComponentModelHelper::ActionColumn);
-
- m_treeView->header()->setSectionResizeMode(
- ComponentModelHelper::NameColumn, QHeaderView::ResizeToContents);
- if (m_core->isInstaller()) {
- m_treeView->setHeaderHidden(true);
- for (int i = ComponentModelHelper::InstalledVersionColumn; i < m_currentModel->columnCount(); ++i)
- m_treeView->hideColumn(i);
-
- if (installActionColumnVisible) {
- m_treeView->header()->setStretchLastSection(false);
- m_treeView->header()->setSectionResizeMode(
- ComponentModelHelper::NameColumn, QHeaderView::Stretch);
- m_treeView->header()->setSectionResizeMode(
- ComponentModelHelper::ActionColumn, QHeaderView::ResizeToContents);
- }
- } else {
- m_treeView->header()->setStretchLastSection(true);
- if (installActionColumnVisible) {
- m_treeView->header()->setSectionResizeMode(
- ComponentModelHelper::NameColumn, QHeaderView::Interactive);
- m_treeView->header()->setSectionResizeMode(
- ComponentModelHelper::ActionColumn, QHeaderView::Interactive);
- }
- for (int i = 0; i < m_currentModel->columnCount(); ++i)
- m_treeView->resizeColumnToContents(i);
- }
-
- bool hasChildren = false;
- const int rowCount = m_currentModel->rowCount();
- for (int row = 0; row < rowCount && !hasChildren; ++row)
- hasChildren = m_currentModel->hasChildren(m_currentModel->index(row, 0));
- m_treeView->setRootIsDecorated(hasChildren);
-
- connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
- this, &ComponentSelectionPage::Private::currentSelectedChanged);
-
- m_treeView->setCurrentIndex(m_currentModel->index(0, 0));
- }
-
-public slots:
- void currentSelectedChanged(const QModelIndex &current)
- {
- if (!current.isValid())
- return;
-
- m_sizeLabel->setText(QString());
- m_descriptionLabel->setText(m_currentModel->data(m_currentModel->index(current.row(),
- ComponentModelHelper::NameColumn, current.parent()), Qt::ToolTipRole).toString());
-
- Component *component = m_currentModel->componentFromIndex(current);
- if ((m_core->isUninstaller()) || (!component))
- return;
-
- if (component->isSelected() && (component->value(scUncompressedSizeSum).toLongLong() > 0)) {
- m_sizeLabel->setText(ComponentSelectionPage::tr("This component "
- "will occupy approximately %1 on your hard disk drive.")
- .arg(humanReadableSize(component->value(scUncompressedSizeSum).toLongLong())));
- }
- }
-
- void selectAll()
- {
- m_currentModel->setCheckedState(ComponentModel::AllChecked);
- }
-
- void deselectAll()
- {
- m_currentModel->setCheckedState(ComponentModel::AllUnchecked);
- }
-
- void checkboxStateChanged()
- {
- QList<QCheckBox*> checkboxes = m_categoryGroupBox->findChildren<QCheckBox *>();
- bool enableFetchButton = false;
- foreach (QCheckBox *checkbox, checkboxes) {
- if (checkbox->isChecked()) {
- enableFetchButton = true;
- break;
- }
- }
- }
-
- void enableRepositoryCategory(int index, bool enable) {
- RepositoryCategory repoCategory = m_core->settings().repositoryCategories().toList().at(index);
- RepositoryCategory replacement = repoCategory;
- replacement.setEnabled(enable);
- QSet<RepositoryCategory> tmpRepoCategories = m_core->settings().repositoryCategories();
- if (tmpRepoCategories.contains(repoCategory)) {
- tmpRepoCategories.remove(repoCategory);
- tmpRepoCategories.insert(replacement);
- m_core->settings().addRepositoryCategories(tmpRepoCategories);
- }
- }
-
- 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_fetchCategoryButton->setDisabled(show);
- m_progressBar->setVisible(show);
- m_bspLabel->setVisible(show);
- m_categoryGroupBox->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_categoryGroupBox->findChildren<QCheckBox *>();
- for (int i = 0; i < checkboxes.count(); i++) {
- checkbox = checkboxes.at(i);
- enableRepositoryCategory(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 =
- QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
- QStringList fileNames = QFileDialog::getOpenFileNames(NULL,
- ComponentSelectionPage::tr("Open File"),defaultDownloadDirectory,
- QLatin1String("QBSP or 7z Files (*.qbsp *.7z)"));
-
- QSet<Repository> set;
- foreach (QString fileName, fileNames) {
- Repository repository = Repository::fromUserInput(fileName, true);
- repository.setEnabled(true);
- set.insert(repository);
- }
- if (set.count() > 0) {
- updateWidgetVisibility(true);
- m_core->settings().addTemporaryRepositories(set, false);
- if (!m_core->fetchCompressedPackagesTree()) {
- setMessage(m_core->error());
- }
- else {
- updateTreeView();
- setMessage(ComponentSelectionPage::tr("To install new "\
- "compressed repository, browse the repositories from your computer"));
- }
- }
- updateWidgetVisibility(false);
- }
-
- /*!
- Updates the value of \a progress on the progress bar.
- */
- void onProgressChanged(int progress)
- {
- m_progressBar->setValue(progress);
- }
-
- /*!
- Displays the message \a msg on the page.
- */
- void setMessage(const QString &msg)
- {
- QWizardPage *page = q->gui()->currentPage();
- if (m_bspLabel && page && page->objectName() == QLatin1String("ComponentSelectionPage"))
- m_bspLabel->setText(msg);
- }
-
- void setTotalProgress(int totalProgress)
- {
- if (m_progressBar)
- m_progressBar->setRange(0, totalProgress);
- }
-
- void selectDefault()
- {
- m_currentModel->setCheckedState(ComponentModel::DefaultChecked);
- }
-
- void onModelStateChanged(QInstaller::ComponentModel::ModelState state)
- {
- q->setModified(state.testFlag(ComponentModel::DefaultChecked) == false);
- // If all components in the checked list are only checkable when run without forced
- // installation, set ComponentModel::AllUnchecked as well, as we cannot uncheck anything.
- // Helps to keep the UI correct.
- if ((!m_core->noForceInstallation())
- && (m_currentModel->checked() == m_currentModel->uncheckable())) {
- state |= ComponentModel::AllUnchecked;
- }
- // enable the button if the corresponding flag is not set
- m_checkAll->setEnabled(state.testFlag(ComponentModel::AllChecked) == false);
- m_uncheckAll->setEnabled(state.testFlag(ComponentModel::AllUnchecked) == false);
- m_checkDefault->setEnabled(state.testFlag(ComponentModel::DefaultChecked) == false);
-
- // update the current selected node (important to reflect possible sub-node changes)
- if (m_treeView->selectionModel())
- currentSelectedChanged(m_treeView->selectionModel()->currentIndex());
- }
-
-public:
- ComponentSelectionPage *q;
- PackageManagerCore *m_core;
- QTreeView *m_treeView;
- ComponentModel *m_allModel;
- ComponentModel *m_updaterModel;
- ComponentModel *m_currentModel;
- QLabel *m_sizeLabel;
- QLabel *m_descriptionLabel;
- QPushButton *m_checkAll;
- QPushButton *m_uncheckAll;
- QPushButton *m_checkDefault;
- QPushButton *m_installCompressButton;
- QGroupBox *m_categoryGroupBox;
- QPushButton *m_fetchCategoryButton;
- QLabel *m_bspLabel;
- QLabel *m_metadataProgressLabel;
- QProgressBar *m_progressBar;
- QVBoxLayout *m_descriptionVLayout;
- QHBoxLayout *m_mainHLayout;
- QVBoxLayout *m_treeViewVLayout;
- QVBoxLayout *m_categoryVLayout;
- QHBoxLayout *m_buttonHLayout;
- bool m_compressedButtonVisible;
- bool m_allowCompressedRepositoryInstall;
- bool m_categoryLayoutVisible;
-};
-
-
// -- ComponentSelectionPage
/*!
@@ -2301,7 +1863,7 @@ public:
*/
ComponentSelectionPage::ComponentSelectionPage(PackageManagerCore *core)
: PackageManagerPage(core)
- , d(new Private(this, core))
+ , d(new ComponentSelectionPagePrivate(this, core))
{
setPixmap(QWizard::WatermarkPixmap, QPixmap());
setObjectName(QLatin1String("ComponentSelectionPage"));
@@ -2348,12 +1910,7 @@ void ComponentSelectionPage::entering()
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;
- }
+ d->hideCompressedRepositoryButton();
}
/*!
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index d67bc9bd9..59ea6572e 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -57,7 +57,7 @@ namespace QInstaller {
class PackageManagerCore;
class PackageManagerPage;
class PerformInstallationForm;
-
+class ComponentSelectionPagePrivate;
// -- PackageManagerGui
@@ -321,8 +321,8 @@ private Q_SLOTS:
void setModified(bool modified);
private:
- class Private;
- Private *d;
+ friend class ComponentSelectionPagePrivate;
+ ComponentSelectionPagePrivate *const d;
};