diff --git a/discover/qml/UpdatesPage.qml b/discover/qml/UpdatesPage.qml --- a/discover/qml/UpdatesPage.qml +++ b/discover/qml/UpdatesPage.qml @@ -12,6 +12,7 @@ title: i18n("Updates") property string footerLabel: "" + property int footerProgress: 0 property bool isBusy: false ResourcesUpdatesModel { @@ -111,10 +112,50 @@ supportsRefreshing: true onRefreshingChanged: { - showPassiveNotification("Fetching Updates...") ResourcesModel.updateAction.triggered() refreshing = false } + + readonly property Item report: ColumnLayout { + parent: page + anchors.fill: parent + Item { + Layout.fillHeight: true + width: 1 + } + Kirigami.Heading { + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + text: page.footerLabel + } + ProgressBar { + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: Kirigami.Units.gridUnit * 20 + value: page.footerProgress + from: 0 + to: 100 + visible: page.isBusy + } + Kirigami.Icon { + Layout.alignment: Qt.AlignHCenter + visible: page.footerProgress === 0 && page.footerLabel !== "" + source: "update-none" + opacity: 0.3 + width: Kirigami.Units.gridUnit * 12 + height: width + } + Button { + Layout.alignment: Qt.AlignHCenter + text: i18n("Restart") + visible: resourcesUpdatesModel.needsReboot + onClicked: app.reboot() + } + Item { + Layout.fillHeight: true + width: 1 + } + } ListView { id: updatesView @@ -127,44 +168,6 @@ } } - footer: ColumnLayout { - anchors.right: parent.right - anchors.left: parent.left - Kirigami.Heading { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - horizontalAlignment: Text.AlignHCenter - visible: page.footerLabel !== "" - text: page.footerLabel - } - BusyIndicator { - id: indicator - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: Kirigami.Units.gridUnit * 12 - Layout.preferredHeight: Layout.preferredWidth - visible: page.isBusy - } - Kirigami.Icon { - Layout.alignment: Qt.AlignHCenter - visible: !indicator.visible && page.footerLabel !== "" - source: "update-none" - opacity: 0.3 - width: Kirigami.Units.gridUnit * 12 - height: width - } - Button { - Layout.alignment: Qt.AlignHCenter - text: i18n("Restart") - visible: resourcesUpdatesModel.needsReboot - onClicked: app.reboot() - } - Item { - visible: page.footerLabel === "" - height: Kirigami.Units.gridUnit - width: 1 - } - } - model: QSortFilterProxyModel { sourceModel: updateModel sortRole: UpdateModel.SectionResourceProgressRole @@ -320,6 +323,7 @@ State { name: "fetching" PropertyChanges { target: page; footerLabel: i18nc("@info", "Fetching Updates...") } + PropertyChanges { target: page; footerProgress: ResourcesModel.fetchingUpdatesProgress } PropertyChanges { target: page; isBusy: true } }, State { diff --git a/libdiscover/backends/PackageKitBackend/PackageKitBackend.h b/libdiscover/backends/PackageKitBackend/PackageKitBackend.h --- a/libdiscover/backends/PackageKitBackend/PackageKitBackend.h +++ b/libdiscover/backends/PackageKitBackend/PackageKitBackend.h @@ -74,6 +74,7 @@ QList componentsById(const QString &id) const; void fetchUpdates(); + int fetchingUpdatesProgress() const override; public Q_SLOTS: void reloadPackageList(); @@ -120,6 +121,7 @@ QSet m_packageNamesToFetchDetails; Packages m_packages; QSharedPointer m_reviews; + QPointer m_getUpdatesTransaction; }; #endif // PACKAGEKITBACKEND_H diff --git a/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp b/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp --- a/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp +++ b/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp @@ -268,14 +268,17 @@ if (m_updater->isProgressing()) return; - PackageKit::Transaction * tUpdates = PackageKit::Daemon::getUpdates(); - connect(tUpdates, &PackageKit::Transaction::finished, this, &PackageKitBackend::getUpdatesFinished); - connect(tUpdates, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageToUpdate); - connect(tUpdates, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); + m_getUpdatesTransaction = PackageKit::Daemon::getUpdates(); + connect(m_getUpdatesTransaction, &PackageKit::Transaction::finished, this, &PackageKitBackend::getUpdatesFinished); + connect(m_getUpdatesTransaction, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageToUpdate); + connect(m_getUpdatesTransaction, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); + connect(m_getUpdatesTransaction, &PackageKit::Transaction::percentageChanged, this, &PackageKitBackend::fetchingUpdatesProgressChanged); m_updatesPackageId.clear(); m_hasSecurityUpdates = false; m_updater->setProgressing(true); + + fetchingUpdatesProgressChanged(); } void PackageKitBackend::addPackageArch(PackageKit::Transaction::Info info, const QString& packageId, const QString& summary) @@ -661,4 +664,18 @@ return AppStreamIntegration::global()->osRelease()->prettyName(); } +int PackageKitBackend::fetchingUpdatesProgress() const +{ + if (!m_getUpdatesTransaction) + return 0; + + if (m_getUpdatesTransaction->status() == PackageKit::Transaction::StatusWait || m_getUpdatesTransaction->status() == PackageKit::Transaction::StatusUnknown) { + return m_getUpdatesTransaction->property("lastPercentage").toInt(); + } + int percentage = percentageWithStatus(m_getUpdatesTransaction->status(), m_getUpdatesTransaction->percentage()); + m_getUpdatesTransaction->setProperty("lastPercentage", percentage); + return percentage; +} + + #include "PackageKitBackend.moc" diff --git a/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h --- a/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h +++ b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h @@ -24,6 +24,8 @@ #include "PackageKitBackend.h" #include +int percentageWithStatus(PackageKit::Transaction::Status status, uint percentage); + class PackageKitUpdater : public AbstractBackendUpdater { Q_OBJECT diff --git a/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp --- a/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp +++ b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp @@ -38,6 +38,7 @@ { PackageKit::Transaction::Status::StatusDownload, 0 }, { PackageKit::Transaction::Status::StatusInstall, 1}, { PackageKit::Transaction::Status::StatusRemove, 1}, + { PackageKit::Transaction::Status::StatusLoadingCache, 1}, { PackageKit::Transaction::Status::StatusUpdate, 1} }; const auto idx = statuses.value(status, -1); diff --git a/libdiscover/resources/AbstractResourcesBackend.h b/libdiscover/resources/AbstractResourcesBackend.h --- a/libdiscover/resources/AbstractResourcesBackend.h +++ b/libdiscover/resources/AbstractResourcesBackend.h @@ -166,6 +166,8 @@ virtual bool hasApplications() const { return false; } + virtual int fetchingUpdatesProgress() const; + public Q_SLOTS: /** * This gets called when the backend should install an application. @@ -221,6 +223,7 @@ void resourceRemoved(AbstractResource* resource); void passiveMessage(const QString &message); + void fetchingUpdatesProgressChanged(); private: QString m_name; diff --git a/libdiscover/resources/AbstractResourcesBackend.cpp b/libdiscover/resources/AbstractResourcesBackend.cpp --- a/libdiscover/resources/AbstractResourcesBackend.cpp +++ b/libdiscover/resources/AbstractResourcesBackend.cpp @@ -83,6 +83,8 @@ fetchingChangedTimer->start(); else fetchingChangedTimer->stop(); + + Q_EMIT fetchingUpdatesProgressChanged(); }); } @@ -146,3 +148,8 @@ { return {}; } + +int AbstractResourcesBackend::fetchingUpdatesProgress() const +{ + return isFetching() ? 42 : 100; +} diff --git a/libdiscover/resources/ResourcesModel.h b/libdiscover/resources/ResourcesModel.h --- a/libdiscover/resources/ResourcesModel.h +++ b/libdiscover/resources/ResourcesModel.h @@ -60,6 +60,7 @@ Q_PROPERTY(QVariantList applicationBackends READ applicationBackendsVariant NOTIFY backendsChanged) Q_PROPERTY(AbstractResourcesBackend* currentApplicationBackend READ currentApplicationBackend WRITE setCurrentApplicationBackend NOTIFY currentApplicationBackendChanged) Q_PROPERTY(QAction* updateAction READ updateAction CONSTANT) + Q_PROPERTY(int fetchingUpdatesProgress READ fetchingUpdatesProgress NOTIFY fetchingUpdatesProgressChanged) public: /** This constructor should be only used by unit tests. * @p backendName defines what backend will be loaded when the backend is constructed. @@ -86,6 +87,7 @@ AbstractResourcesBackend* currentApplicationBackend() const; QAction* updateAction() const { return m_updateAction; } + int fetchingUpdatesProgress() const; public Q_SLOTS: void installApplication(AbstractResource* app, const AddonList& addons); @@ -102,6 +104,7 @@ void resourceRemoved(AbstractResource* resource); void passiveMessage(const QString &message); void currentApplicationBackendChanged(AbstractResourcesBackend* currentApplicationBackend); + void fetchingUpdatesProgressChanged(); private Q_SLOTS: void callerFetchingChanged(); diff --git a/libdiscover/resources/ResourcesModel.cpp b/libdiscover/resources/ResourcesModel.cpp --- a/libdiscover/resources/ResourcesModel.cpp +++ b/libdiscover/resources/ResourcesModel.cpp @@ -82,6 +82,7 @@ m_updateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); connect(this, &ResourcesModel::fetchingChanged, m_updateAction, [this](bool fetching) { m_updateAction->setEnabled(!fetching); + fetchingUpdatesProgressChanged(); }); connect(m_updateAction, &QAction::triggered, this, &ResourcesModel::checkForUpdates); @@ -123,6 +124,7 @@ connect(backend, &AbstractResourcesBackend::allDataChanged, this, &ResourcesModel::updateCaller); connect(backend, &AbstractResourcesBackend::resourcesChanged, this, &ResourcesModel::resourceDataChanged); connect(backend, &AbstractResourcesBackend::updatesCountChanged, this, &ResourcesModel::updatesCountChanged); + connect(backend, &AbstractResourcesBackend::fetchingUpdatesProgressChanged, this, &ResourcesModel::fetchingUpdatesProgressChanged); connect(backend, &AbstractResourcesBackend::resourceRemoved, this, &ResourcesModel::resourceRemoved); connect(backend, &AbstractResourcesBackend::passiveMessage, this, &ResourcesModel::passiveMessage); connect(backend->backendUpdater(), &AbstractBackendUpdater::progressingChanged, this, &ResourcesModel::slotFetching); @@ -400,3 +402,16 @@ } setCurrentApplicationBackend(backends.value(idx, nullptr), false); } + + +int ResourcesModel::fetchingUpdatesProgress() const +{ + if (m_backends.isEmpty()) + return 0; + + int sum = 0; + for(auto backend: m_backends) { + sum += backend->fetchingUpdatesProgress(); + } + return sum / m_backends.count(); +} diff --git a/libdiscover/resources/ResourcesUpdatesModel.h b/libdiscover/resources/ResourcesUpdatesModel.h --- a/libdiscover/resources/ResourcesUpdatesModel.h +++ b/libdiscover/resources/ResourcesUpdatesModel.h @@ -42,7 +42,6 @@ public: explicit ResourcesUpdatesModel(QObject* parent = nullptr); - quint64 downloadSpeed() const; Q_SCRIPTABLE void prepare(); bool isProgressing() const; @@ -64,6 +63,7 @@ void resourceProgressed(AbstractResource* resource, qreal progress, AbstractBackendUpdater::State state); void passiveMessage(const QString &message); void needsRebootChanged(); + void fetchingUpdatesProgressChanged(int percent); public Q_SLOTS: void updateAll(); @@ -74,7 +74,6 @@ private: void init(); - void updateFinished(); void setTransaction(UpdateTransaction* transaction); QVector m_updaters;