From 4b1af7d32b062f954a84616e28bb6296a28522b4 Mon Sep 17 00:00:00 2001 From: Arttu Tarkiainen Date: Thu, 31 Mar 2022 12:33:31 +0300 Subject: Show additional progress information on PerformInstallationPage In a similar fashion to the archive download status, display: * Performed operations - total operations, on unpack. * Installed components - total components, on install. * Rolled back operations - total undo operations, on uninstall. Task-number: QTIFW-2513 Change-Id: I61690a25afadd1ca1e4a46b5b980ac094429135b Reviewed-by: Katja Marttila --- src/libs/installer/concurrentoperationrunner.cpp | 17 +++++++ src/libs/installer/concurrentoperationrunner.h | 4 ++ src/libs/installer/packagemanagercore.cpp | 4 +- src/libs/installer/packagemanagercore_p.cpp | 57 ++++++++++++++++++------ src/libs/installer/packagemanagercore_p.h | 3 ++ src/libs/installer/performinstallationform.cpp | 22 ++++----- src/libs/installer/performinstallationform.h | 4 +- src/libs/installer/progresscoordinator.cpp | 4 +- src/libs/installer/progresscoordinator.h | 4 +- 9 files changed, 87 insertions(+), 32 deletions(-) (limited to 'src/libs') diff --git a/src/libs/installer/concurrentoperationrunner.cpp b/src/libs/installer/concurrentoperationrunner.cpp index c10f72784..03012c593 100644 --- a/src/libs/installer/concurrentoperationrunner.cpp +++ b/src/libs/installer/concurrentoperationrunner.cpp @@ -52,11 +52,19 @@ using namespace QInstaller; Emitted when the execution of all pooled operations is finished. */ +/*! + \fn QInstaller::ConcurrentOperationRunner::progressChanged(const int completed, const int total) + + Emitted when the count of \c completed of the \c total operations changes. +*/ + /*! Constructs an operation runner with \a parent as the parent object. */ ConcurrentOperationRunner::ConcurrentOperationRunner(QObject *parent) : QObject(parent) + , m_completedOperations(0) + , m_totalOperations(0) , m_operations(nullptr) , m_type(Operation::OperationType::Perform) { @@ -69,9 +77,12 @@ ConcurrentOperationRunner::ConcurrentOperationRunner(QObject *parent) ConcurrentOperationRunner::ConcurrentOperationRunner(OperationList *operations, const Operation::OperationType type, QObject *parent) : QObject(parent) + , m_completedOperations(0) + , m_totalOperations(0) , m_operations(operations) , m_type(type) { + m_totalOperations = m_operations->size(); } /*! @@ -88,6 +99,7 @@ ConcurrentOperationRunner::~ConcurrentOperationRunner() void ConcurrentOperationRunner::setOperations(OperationList *operations) { m_operations = operations; + m_totalOperations = m_operations->size(); } /*! @@ -181,6 +193,9 @@ void ConcurrentOperationRunner::onOperationfinished() qCritical() << "Caught unhandled exception in:" << Q_FUNC_INFO; m_results.insert(op, false); } + ++m_completedOperations; + emit progressChanged(m_completedOperations, m_totalOperations); + } else { // Remember also operations canceled before execution m_results.insert(op, false); @@ -203,4 +218,6 @@ void ConcurrentOperationRunner::reset() qDeleteAll(m_operationWatchers); m_operationWatchers.clear(); m_results.clear(); + + m_completedOperations = 0; } diff --git a/src/libs/installer/concurrentoperationrunner.h b/src/libs/installer/concurrentoperationrunner.h index 29cd2adfb..a74010f3e 100644 --- a/src/libs/installer/concurrentoperationrunner.h +++ b/src/libs/installer/concurrentoperationrunner.h @@ -54,6 +54,7 @@ public: QHash run(); signals: + void progressChanged(const int completed, const int total); void finished(); public slots: @@ -66,6 +67,9 @@ private: void reset(); private: + int m_completedOperations; + int m_totalOperations; + QHash *> m_operationWatchers; QHash m_results; diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 5fdb599d8..0cea20032 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -799,7 +799,7 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize) connect(&archivesJob, &DownloadArchivesJob::outputTextChanged, ProgressCoordinator::instance(), &ProgressCoordinator::emitLabelAndDetailTextChanged); connect(&archivesJob, &DownloadArchivesJob::downloadStatusChanged, - ProgressCoordinator::instance(), &ProgressCoordinator::downloadStatusChanged); + ProgressCoordinator::instance(), &ProgressCoordinator::additionalProgressStatusChanged); ProgressCoordinator::instance()->registerPartProgress(&archivesJob, SIGNAL(progressChanged(double)), partProgressSize); @@ -815,7 +815,7 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize) if (d->statusCanceledOrFailed()) throw Error(tr("Installation canceled by user.")); - ProgressCoordinator::instance()->emitDownloadStatus(tr("All downloads finished.")); + ProgressCoordinator::instance()->emitAdditionalProgressStatus(tr("All downloads finished.")); emit downloadArchivesFinished(); return archivesJob.numberOfDownloads(); diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 35d881f80..4fffcab35 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -1694,12 +1694,8 @@ bool PackageManagerCorePrivate::runInstaller() + (PackageManagerCore::createLocalRepositoryFromBinary() ? 1 : 0); double progressOperationSize = componentsInstallPartProgressSize / progressOperationCount; - // Perform extract operations - unpackComponents(componentsToInstall, progressOperationSize, adminRightsGained); - - // Perform rest of the operations and mark component as installed - foreach (Component *component, componentsToInstall) - installComponent(component, progressOperationSize, adminRightsGained); + // Now install the requested components + unpackAndInstallComponents(componentsToInstall, progressOperationSize, adminRightsGained); if (m_core->isOfflineOnly() && PackageManagerCore::createLocalRepositoryFromBinary()) { emit m_core->titleMessageChanged(tr("Creating local repository")); @@ -1922,12 +1918,8 @@ bool PackageManagerCorePrivate::runPackageUpdater() const double progressOperationCount = countProgressOperations(componentsToInstall); const double progressOperationSize = componentsInstallPartProgressSize / progressOperationCount; - // Perform extract operations - unpackComponents(componentsToInstall, progressOperationSize, adminRightsGained); - - // Perform rest of the operations and mark component as installed - foreach (Component *component, componentsToInstall) - installComponent(component, progressOperationSize, adminRightsGained); + // Now install the requested new components + unpackAndInstallComponents(componentsToInstall, progressOperationSize, adminRightsGained); emit m_core->titleMessageChanged(tr("Creating Maintenance Tool")); @@ -2176,7 +2168,7 @@ void PackageManagerCorePrivate::unpackComponents(const QList &compo OperationList unpackOperations; bool becameAdmin = false; - ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(tr("\nUnpacking components...")); + ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(tr("\nPreparing to unpack components...")); // 1. Collect operations quint64 totalOperationsSizeHint = 0; @@ -2214,6 +2206,16 @@ void PackageManagerCorePrivate::unpackComponents(const QList &compo connect(m_core, &PackageManagerCore::installationInterrupted, &runner, &ConcurrentOperationRunner::cancel); + connect(&runner, &ConcurrentOperationRunner::progressChanged, [](const int completed, const int total) { + const QString statusText = tr("%1 of %2 operations completed.") + .arg(QString::number(completed), QString::number(total)); + ProgressCoordinator::instance()->emitAdditionalProgressStatus(statusText); + }); + connect(&runner, &ConcurrentOperationRunner::finished, [] { + // Clear the status text to not cause confusion when installations begin. + ProgressCoordinator::instance()->emitAdditionalProgressStatus(QLatin1String("")); + }); + const QHash backupResults = runner.run(); const OperationList backupOperations = backupResults.keys(); @@ -2242,6 +2244,8 @@ void PackageManagerCorePrivate::unpackComponents(const QList &compo return lhs->sizeHint() > rhs->sizeHint(); }); + ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(tr("\nUnpacking components...")); + runner.setType(Operation::Perform); const QHash results = runner.run(); const OperationList performedOperations = backupResults.keys(); @@ -2558,6 +2562,9 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera bool adminRightsGained, bool deleteOperation) { try { + const int operationsCount = undoOperations.size(); + int rolledBackOperations = 0; + foreach (Operation *undoOperation, undoOperations) { if (statusCanceledOrFailed()) throw Error(tr("Installation canceled by user")); @@ -2596,6 +2603,10 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera } } + ++rolledBackOperations; + ProgressCoordinator::instance()->emitAdditionalProgressStatus(tr("%1 of %2 operations rolled back.") + .arg(QString::number(rolledBackOperations), QString::number(operationsCount))); + if (becameAdmin) m_core->dropAdminRights(); @@ -2610,6 +2621,7 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera throw Error(tr("Unknown error")); } m_localPackageHub->writeToDisk(); + ProgressCoordinator::instance()->emitAdditionalProgressStatus(tr("Rollbacks complete.")); } PackagesList PackageManagerCorePrivate::remotePackages() @@ -2856,6 +2868,25 @@ void PackageManagerCorePrivate::handleMethodInvocationRequest(const QString &inv QMetaObject::invokeMethod(obj, qPrintable(invokableMethodName)); } +void PackageManagerCorePrivate::unpackAndInstallComponents(const QList &components, + const double progressOperationSize, const bool adminRightsGained) +{ + // Perform extract operations + unpackComponents(components, progressOperationSize, adminRightsGained); + + // Perform rest of the operations and mark component as installed + const int componentsToInstallCount = components.size(); + int installedComponents = 0; + foreach (Component *component, components) { + installComponent(component, progressOperationSize, adminRightsGained); + + ++installedComponents; + ProgressCoordinator::instance()->emitAdditionalProgressStatus(tr("%1 of %2 components installed.") + .arg(QString::number(installedComponents), QString::number(componentsToInstallCount))); + } + ProgressCoordinator::instance()->emitAdditionalProgressStatus(tr("All components installed.")); +} + void PackageManagerCorePrivate::processFilesForDelayedDeletion() { if (m_filesForDelayedDeletion.isEmpty()) diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h index fef8a0431..8c5191dea 100644 --- a/src/libs/installer/packagemanagercore_p.h +++ b/src/libs/installer/packagemanagercore_p.h @@ -234,6 +234,9 @@ private slots: void handleMethodInvocationRequest(const QString &invokableMethodName); private: + void unpackAndInstallComponents(const QList &components, + const double progressOperationSize, const bool adminRightsGained); + void deleteMaintenanceTool(); void registerMaintenanceTool(); void unregisterMaintenanceTool(); diff --git a/src/libs/installer/performinstallationform.cpp b/src/libs/installer/performinstallationform.cpp index e97767b04..d8d1e3dcb 100644 --- a/src/libs/installer/performinstallationform.cpp +++ b/src/libs/installer/performinstallationform.cpp @@ -87,7 +87,7 @@ PerformInstallationForm::PerformInstallationForm(PackageManagerCore *core, QObje : QObject(parent) , m_progressBar(nullptr) , m_progressLabel(nullptr) - , m_downloadStatus(nullptr) + , m_additionalProgressStatus(nullptr) , m_productImagesScrollArea(nullptr) , m_productImagesLabel(nullptr) , m_detailsButton(nullptr) @@ -126,14 +126,14 @@ void PerformInstallationForm::setupUi(QWidget *widget) m_progressLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); topLayout->addWidget(m_progressLabel); - m_downloadStatus = new QLabel(widget); - m_downloadStatus->setObjectName(QLatin1String("DownloadStatus")); - m_downloadStatus->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); - m_downloadStatus->setWordWrap(true); - m_downloadStatus->setTextFormat(Qt::TextFormat::RichText); - topLayout->addWidget(m_downloadStatus); - connect(ProgressCoordinator::instance(), &ProgressCoordinator::downloadStatusChanged, this, - &PerformInstallationForm::onDownloadStatusChanged); + m_additionalProgressStatus = new QLabel(widget); + m_additionalProgressStatus->setObjectName(QLatin1String("DownloadStatus")); + m_additionalProgressStatus->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); + m_additionalProgressStatus->setWordWrap(true); + m_additionalProgressStatus->setTextFormat(Qt::TextFormat::RichText); + topLayout->addWidget(m_additionalProgressStatus); + connect(ProgressCoordinator::instance(), &ProgressCoordinator::additionalProgressStatusChanged, this, + &PerformInstallationForm::onAdditionalProgressStatusChanged); m_detailsButton = new QPushButton(tr("&Show Details"), widget); m_detailsButton->setObjectName(QLatin1String("DetailsButton")); @@ -290,9 +290,9 @@ bool PerformInstallationForm::isShowingDetails() const Changes the label text according to the changes in the download status specified by \a status. */ -void PerformInstallationForm::onDownloadStatusChanged(const QString &status) +void PerformInstallationForm::onAdditionalProgressStatusChanged(const QString &status) { - m_downloadStatus->setText(status); + m_additionalProgressStatus->setText(status); } /*! diff --git a/src/libs/installer/performinstallationform.h b/src/libs/installer/performinstallationform.h index 7fe0e743e..d5f87eeaa 100644 --- a/src/libs/installer/performinstallationform.h +++ b/src/libs/installer/performinstallationform.h @@ -71,13 +71,13 @@ public slots: void updateProgress(); void toggleDetails(); void clearDetailsBrowser(); - void onDownloadStatusChanged(const QString &status); + void onAdditionalProgressStatusChanged(const QString &status); void setImageFromFileName(const QString &fileName, const QString &url); private: QProgressBar *m_progressBar; QLabel *m_progressLabel; - QLabel *m_downloadStatus; + QLabel *m_additionalProgressStatus; QScrollArea *m_productImagesScrollArea; AspectRatioLabel *m_productImagesLabel; QPushButton *m_detailsButton; diff --git a/src/libs/installer/progresscoordinator.cpp b/src/libs/installer/progresscoordinator.cpp index 01b92bff8..8b02711b1 100644 --- a/src/libs/installer/progresscoordinator.cpp +++ b/src/libs/installer/progresscoordinator.cpp @@ -306,9 +306,9 @@ double ProgressCoordinator::allPendingCalculatedPartPercentages(QObject *exclude return result; } -void ProgressCoordinator::emitDownloadStatus(const QString &status) +void ProgressCoordinator::emitAdditionalProgressStatus(const QString &status) { - emit downloadStatusChanged(status); + emit additionalProgressStatusChanged(status); } void ProgressCoordinator::printProgressPercentage(int progress) diff --git a/src/libs/installer/progresscoordinator.h b/src/libs/installer/progresscoordinator.h index 380c90df0..3540b5d16 100644 --- a/src/libs/installer/progresscoordinator.h +++ b/src/libs/installer/progresscoordinator.h @@ -72,14 +72,14 @@ public slots: void emitDetailTextChanged(const QString &text); void emitLabelAndDetailTextChanged(const QString &text); - void emitDownloadStatus(const QString &status); + void emitAdditionalProgressStatus(const QString &status); void printProgressPercentage(int progress); void printProgressMessage(const QString &message); signals: void detailTextChanged(const QString &text); void detailTextResetNeeded(); - void downloadStatusChanged(const QString &status); + void additionalProgressStatusChanged(const QString &status); protected: explicit ProgressCoordinator(QObject *parent); -- cgit v1.2.3