From db0584f81e6b37b3e381841b7ca34f77b4adf717 Mon Sep 17 00:00:00 2001 From: Javier Llorente Date: Sat, 15 Apr 2023 22:49:35 +0200 Subject: [PATCH] Implement download integration with Plasma --- CMakeLists.txt | 4 +- src/lib/CMakeLists.txt | 2 + src/lib/downloads/downloaditem.cpp | 16 +++++ src/lib/downloads/downloaditem.h | 4 ++ src/lib/downloads/downloadmanager.cpp | 22 ++++--- src/lib/downloads/downloadmanager.h | 9 ++- src/lib/downloads/downloadmanagermodel.cpp | 65 +++++++++++++++++++ src/lib/downloads/downloadmanagermodel.h | 45 +++++++++++++ .../KDEFrameworksIntegration/CMakeLists.txt | 3 + .../KDEFrameworksIntegration/downloadkjob.cpp | 44 +++++++++++++ .../KDEFrameworksIntegration/downloadkjob.h | 44 +++++++++++++ .../kdeframeworksintegrationplugin.cpp | 20 ++++++ .../kdeframeworksintegrationplugin.h | 2 + 13 files changed, 268 insertions(+), 12 deletions(-) create mode 100644 src/lib/downloads/downloadmanagermodel.cpp create mode 100644 src/lib/downloads/downloadmanagermodel.h create mode 100644 src/plugins/KDEFrameworksIntegration/downloadkjob.cpp create mode 100644 src/plugins/KDEFrameworksIntegration/downloadkjob.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 428681e5b..771898422 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,8 +124,10 @@ set_package_properties(KF5Crash PROPERTIES DESCRIPTION "KDE Frameworks Integrati find_package(KF5CoreAddons ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5CoreAddons PROPERTIES DESCRIPTION "KDE Frameworks Integration plugin" TYPE OPTIONAL) find_package(KF5Purpose ${KF5_MIN_VERSION} CONFIG) +find_package(KF5JobWidgets ${KF5_MIN_VERSION} CONFIG) +set_package_properties(KF5JobWidgets PROPERTIES DESCRIPTION "KDE Frameworks Integration plugin" TYPE OPTIONAL) set_package_properties(KF5Purpose PROPERTIES DESCRIPTION "KDE Frameworks Integration plugin" TYPE OPTIONAL) -if (KF5Wallet_FOUND AND KF5KIO_FOUND AND KF5Crash_FOUND AND KF5CoreAddons_FOUND AND KF5Purpose_FOUND) +if (KF5Wallet_FOUND AND KF5KIO_FOUND AND KF5Crash_FOUND AND KF5CoreAddons_FOUND AND KF5Purpose_FOUND AND KF5JobWidgets_FOUND) set(ENABLE_KDE_FRAMEWORKS_INTEGRATION_PLUGIN TRUE) endif() diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index d8a688305..fdb225d92 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -102,6 +102,7 @@ set(SRCS ${SRCS} cookies/cookiemanager.cpp downloads/downloaditem.cpp downloads/downloadmanager.cpp + downloads/downloadmanagermodel.cpp downloads/downloadoptionsdialog.cpp downloads/downloadsbutton.cpp history/history.cpp @@ -328,6 +329,7 @@ set(SRCS ${SRCS} cookies/cookiemanager.h downloads/downloaditem.h downloads/downloadmanager.h + downloads/downloadmanagermodel.h downloads/downloadoptionsdialog.h downloads/downloadsbutton.h history/history.h diff --git a/src/lib/downloads/downloaditem.cpp b/src/lib/downloads/downloaditem.cpp index 08726607d..924691901 100644 --- a/src/lib/downloads/downloaditem.cpp +++ b/src/lib/downloads/downloaditem.cpp @@ -172,6 +172,7 @@ void DownloadItem::downloadProgress(qint64 received, qint64 total) m_total = total; updateDownloadInfo(m_currSpeed, m_received, m_total); + progressChanged(m_currSpeed, m_received, m_total); } int DownloadItem::progress() @@ -363,6 +364,21 @@ void DownloadItem::openFolder() #endif } +QUrl DownloadItem::url() const +{ + return m_downUrl; +} + +QString DownloadItem::path() const +{ + return m_path; +} + +QString DownloadItem::fileName() const +{ + return m_fileName; +} + DownloadItem::~DownloadItem() { delete ui; diff --git a/src/lib/downloads/downloaditem.h b/src/lib/downloads/downloaditem.h index 38edb6600..f025330d3 100644 --- a/src/lib/downloads/downloaditem.h +++ b/src/lib/downloads/downloaditem.h @@ -48,6 +48,9 @@ public: QTime remainingTime() const { return m_remTime; } double currentSpeed() const { return m_currSpeed; } int progress(); + QUrl url() const; + QString path() const; + QString fileName() const; ~DownloadItem() override; void setDownTimer(const QTime &timer) { m_downTimer = timer; } @@ -59,6 +62,7 @@ public: Q_SIGNALS: void deleteItem(DownloadItem*); void downloadFinished(bool success); + void progressChanged(double currSpeed, qint64 received, qint64 total); private Q_SLOTS: void parentResized(const QSize &size); diff --git a/src/lib/downloads/downloadmanager.cpp b/src/lib/downloads/downloadmanager.cpp index 1313a1238..2a3540d05 100644 --- a/src/lib/downloads/downloadmanager.cpp +++ b/src/lib/downloads/downloadmanager.cpp @@ -21,6 +21,10 @@ #include "mainapplication.h" #include "downloadoptionsdialog.h" #include "downloaditem.h" +#include "downloadmanagermodel.h" +#ifdef PLASMA_DOWNLOADS +#include "downloadkjob.h" +#endif #include "networkmanager.h" #include "desktopnotificationsfactory.h" #include "qztools.h" @@ -52,6 +56,7 @@ DownloadManager::DownloadManager(QWidget* parent) : QWidget(parent) , ui(new Ui::DownloadManager) + , m_model(new DownloadManagerModel(this)) , m_isClosing(false) , m_lastDownloadOption(NoOption) { @@ -73,6 +78,8 @@ DownloadManager::DownloadManager(QWidget* parent) loadSettings(); QzTools::setWmClass("Download Manager", this); + + connect(m_model, &DownloadManagerModel::downloadAdded, this, &DownloadManager::downloadAdded); } void DownloadManager::loadSettings() @@ -365,8 +372,10 @@ void DownloadManager::download(QWebEngineDownloadItem *downloadItem) auto* downItem = new DownloadItem(listItem, downloadItem, QFileInfo(downloadPath).absolutePath(), QFileInfo(downloadPath).fileName(), openFile, this); downItem->setDownTimer(downloadTimer); downItem->startDownloading(); - connect(downItem, &DownloadItem::deleteItem, this, &DownloadManager::deleteItem); - connect(downItem, &DownloadItem::downloadFinished, this, &DownloadManager::downloadFinished); + connect(downItem, &DownloadItem::deleteItem, m_model, &DownloadManagerModel::removeDownload); + connect(downItem, &DownloadItem::downloadFinished, this, QOverload::of(&DownloadManager::downloadFinished)); + connect(downItem, &DownloadItem::downloadFinished, this, QOverload<>::of(&DownloadManager::downloadFinished)); + m_model->addDownload(downItem); ui->list->setItemWidget(listItem, downItem); listItem->setSizeHint(downItem->sizeHint()); downItem->show(); @@ -377,7 +386,7 @@ void DownloadManager::download(QWebEngineDownloadItem *downloadItem) int DownloadManager::downloadsCount() const { - return ui->list->count(); + return m_model->count(); } int DownloadManager::activeDownloadsCount() const @@ -424,13 +433,6 @@ void DownloadManager::downloadFinished(bool success) } } -void DownloadManager::deleteItem(DownloadItem* item) -{ - if (item && !item->isDownloading()) { - delete item; - } -} - bool DownloadManager::canClose() { if (m_isClosing) { diff --git a/src/lib/downloads/downloadmanager.h b/src/lib/downloads/downloadmanager.h index eda9a988a..db301e9ab 100644 --- a/src/lib/downloads/downloadmanager.h +++ b/src/lib/downloads/downloadmanager.h @@ -36,6 +36,10 @@ class QWebEngineDownloadItem; class QWinTaskbarButton; class DownloadItem; +class DownloadManagerModel; +#ifdef PLASMA_DOWNLOADS +class DownloadKJob; +#endif class WebPage; class FALKON_EXPORT DownloadManager : public QWidget @@ -82,12 +86,14 @@ public Q_SLOTS: private Q_SLOTS: void clearList(); - void deleteItem(DownloadItem* item); void downloadFinished(bool success); Q_SIGNALS: void resized(QSize); void downloadsCountChanged(); + void downloadAdded(DownloadItem *item); + void downloadRemoved(DownloadItem *item); + void downloadFinished(); private: void timerEvent(QTimerEvent* e) override; @@ -99,6 +105,7 @@ private: QWinTaskbarButton *taskbarButton(); Ui::DownloadManager* ui; + DownloadManagerModel *m_model; QBasicTimer m_timer; QString m_lastDownloadPath; diff --git a/src/lib/downloads/downloadmanagermodel.cpp b/src/lib/downloads/downloadmanagermodel.cpp new file mode 100644 index 000000000..b41cc22fa --- /dev/null +++ b/src/lib/downloads/downloadmanagermodel.cpp @@ -0,0 +1,65 @@ +/* ============================================================ +* Falkon - Qt web browser +* Copyright (C) 2019 Javier Llorente +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* ============================================================ */ +#include "downloadmanagermodel.h" + +DownloadManagerModel::DownloadManagerModel(QObject *parent) + : QAbstractListModel(parent) +{ + +} + +int DownloadManagerModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return count(); +} + +QVariant DownloadManagerModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::DisplayRole) { + const DownloadItem *item = m_downloads.at(index.row()); + return item; + } + return QVariant(); +} + +void DownloadManagerModel::addDownload(DownloadItem *item) +{ + m_downloads.append(item); + connect(item, &DownloadItem::deleteItem, this, &DownloadManagerModel::removeDownload); + emit downloadAdded(item); +} + +void DownloadManagerModel::removeDownload(DownloadItem *item) +{ + if (item && !item->isDownloading()) { + delete item; + emit downloadRemoved(item); + } +} + +int DownloadManagerModel::count() const +{ + return m_downloads.count(); +} + +DownloadItem *DownloadManagerModel::at(int index) +{ + return m_downloads.at(index); +} + diff --git a/src/lib/downloads/downloadmanagermodel.h b/src/lib/downloads/downloadmanagermodel.h new file mode 100644 index 000000000..e2492716d --- /dev/null +++ b/src/lib/downloads/downloadmanagermodel.h @@ -0,0 +1,45 @@ +/* ============================================================ +* Falkon - Qt web browser +* Copyright (C) 2019 Javier Llorente +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* ============================================================ */ +#ifndef DOWNLOADMANAGERMODEL_H +#define DOWNLOADMANAGERMODEL_H + +#include +#include "downloaditem.h" + +class DownloadManagerModel : public QAbstractListModel +{ + Q_OBJECT + +public: + DownloadManagerModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + void addDownload(DownloadItem *item); + void removeDownload(DownloadItem *item); + int count() const; + DownloadItem *at(int index); + +private: + QList m_downloads; + +signals: + void downloadAdded(DownloadItem *item); + void downloadRemoved(DownloadItem *item); +}; + +#endif // DOWNLOADMANAGERMODEL_H diff --git a/src/plugins/KDEFrameworksIntegration/CMakeLists.txt b/src/plugins/KDEFrameworksIntegration/CMakeLists.txt index 1d6da035e..47a9941e2 100644 --- a/src/plugins/KDEFrameworksIntegration/CMakeLists.txt +++ b/src/plugins/KDEFrameworksIntegration/CMakeLists.txt @@ -2,9 +2,11 @@ set(KDEFrameworksIntegration_SRCS kdeframeworksintegrationplugin.cpp kwalletpasswordbackend.cpp kioschemehandler.cpp + downloadkjob.cpp kdeframeworksintegrationplugin.h kwalletpasswordbackend.h kioschemehandler.h + downloadkjob.h ) ecm_create_qm_loader(KDEFrameworksIntegration_SRCS falkon_kdeframeworksintegration_qt) @@ -24,4 +26,5 @@ target_link_libraries(KDEFrameworksIntegration KF5::Crash KF5::CoreAddons KF5::PurposeWidgets + KF5::JobWidgets ) diff --git a/src/plugins/KDEFrameworksIntegration/downloadkjob.cpp b/src/plugins/KDEFrameworksIntegration/downloadkjob.cpp new file mode 100644 index 000000000..26c6fce44 --- /dev/null +++ b/src/plugins/KDEFrameworksIntegration/downloadkjob.cpp @@ -0,0 +1,44 @@ +/* ============================================================ +* Falkon - Qt web browser +* Copyright (C) 2019 Javier Llorente +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* ============================================================ */ +#include "downloadkjob.h" + +DownloadKJob::DownloadKJob(const QUrl &url, const QString &path, const QString &fileName, QObject *parent) + : KJob(parent), + m_url(url), + m_path(path), + m_fileName(fileName) +{ +} + +void DownloadKJob::start() +{ +} + +void DownloadKJob::updateDescription() +{ + emit description(this, tr("Downloading"), + qMakePair(tr("Source"), m_url.toDisplayString()), + qMakePair(tr("Destination"), QString("%1/%2").arg(m_path, m_fileName))); +} + +void DownloadKJob::progress(double currSpeed, qint64 received, qint64 total) +{ + setProcessedAmount(Bytes, received); + setTotalAmount(Bytes, total); + emit speed(this, currSpeed); +} diff --git a/src/plugins/KDEFrameworksIntegration/downloadkjob.h b/src/plugins/KDEFrameworksIntegration/downloadkjob.h new file mode 100644 index 000000000..3fa941fac --- /dev/null +++ b/src/plugins/KDEFrameworksIntegration/downloadkjob.h @@ -0,0 +1,44 @@ +/* ============================================================ +* Falkon - Qt web browser +* Copyright (C) 2019 Javier Llorente +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* ============================================================ */ +#ifndef DOWNLOADKJOB_H +#define DOWNLOADKJOB_H + +#include "qzcommon.h" +#include +#include + +class FALKON_EXPORT DownloadKJob : public KJob +{ + Q_OBJECT + +public: + DownloadKJob(const QUrl &url, const QString &path, const QString &fileName, QObject *parent = nullptr); + void start(); + void updateDescription(); + +public slots: + void progress(double currSpeed, qint64 received, qint64 total); + +private: + QUrl m_url; + QString m_path; + QString m_fileName; + +}; + +#endif // DOWNLOADKJOB_H diff --git a/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.cpp b/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.cpp index e8e596eab..5f6c18041 100644 --- a/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.cpp +++ b/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.cpp @@ -23,14 +23,18 @@ #include "mainapplication.h" #include "autofill.h" #include "passwordmanager.h" +#include "downloadmanager.h" #include "kioschemehandler.h" #include "webpage.h" #include "webview.h" +#include "downloadkjob.h" +#include "downloaditem.h" #include #include #include #include +#include #include #include @@ -53,6 +57,22 @@ void KDEFrameworksIntegrationPlugin::init(InitState state, const QString &settin if (qgetenv("KDE_FULL_SESSION") == QByteArray("true")) { mApp->autoFill()->passwordManager()->switchBackend(QSL("KWallet")); } + + m_jobTracker = new KUiServerJobTracker(this); + + auto manager = mApp->downloadManager(); + connect(manager, &DownloadManager::downloadAdded, [=](DownloadItem *item) { + auto job = new DownloadKJob(item->url(), item->path(), item->fileName(), this); + m_jobTracker->registerJob(job); + job->start(); + job->updateDescription(); + + connect(item, &DownloadItem::progressChanged, job, &DownloadKJob::progress); + connect(manager, QOverload<>::of(&DownloadManager::downloadFinished), m_jobTracker, [=]() { + m_jobTracker->unregisterJob(job); + }); + }); + const auto protocols = KProtocolInfo::protocols(); for (const QString &protocol : protocols) { diff --git a/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.h b/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.h index c9a667751..a78d8e0bd 100644 --- a/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.h +++ b/src/plugins/KDEFrameworksIntegration/kdeframeworksintegrationplugin.h @@ -23,6 +23,7 @@ class KWalletPasswordBackend; class KIOSchemeHandler; +class KUiServerJobTracker; class KDEFrameworksIntegrationPlugin : public QObject, public PluginInterface { @@ -42,4 +43,5 @@ private: KWalletPasswordBackend *m_backend = nullptr; QVector m_kioSchemeHandlers; Purpose::Menu *m_sharePageMenu = nullptr; + KUiServerJobTracker *m_jobTracker = nullptr; };