From 6cc73856118850c1dae3398096b87e2f7ab6b1c6 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 1 Mar 2019 16:16:59 +0100 Subject: [PATCH] WIP: New DownloadManager --- src/lib/downloads/downloaditem.cpp | 136 ++++++++++++++++++++++++++ src/lib/downloads/downloaditem.h | 76 ++++++++++++++ src/lib/downloads/downloadmanager.cpp | 68 +++++++++++++ src/lib/downloads/downloadmanager.h | 37 +++++++ 4 files changed, 317 insertions(+) diff --git a/src/lib/downloads/downloaditem.cpp b/src/lib/downloads/downloaditem.cpp index 5d00cd4c6..a3bfa3da6 100644 --- a/src/lib/downloads/downloaditem.cpp +++ b/src/lib/downloads/downloaditem.cpp @@ -340,3 +340,139 @@ DownloadItem::~DownloadItem() delete ui; delete m_item; } + + + + + + +DownloadItem2::DownloadItem2(QObject *parent) + : QObject(parent) +{ +} + +DownloadItem2::Flags DownloadItem2::flags() const +{ + return m_flags; +} + +DownloadItem2::State DownloadItem2::state() const +{ + return m_state; +} + +DownloadItem2::Error DownloadItem2::error() const +{ + return m_error; +} + +bool DownloadItem2::isError() const +{ + return m_state == DownloadError; +} + +bool DownloadItem2::isPaused() const +{ + return m_state == DownloadPaused; +} + +bool DownloadItem2::isFinished() const +{ + return m_state == DownloadFinished; +} + +bool DownloadItem2::isCanceled() const +{ + return m_state == DownloadCanceled; +} + +QUrl DownloadItem2::url() const +{ + return m_url; +} + +QString DownloadItem2::path() const +{ + return m_path; +} + +int DownloadItem2::progress() const +{ + if (m_bytesReceived >= 0 && m_bytesTotal > 0) { + return (m_bytesReceived / double(m_bytesTotal)) * 100; + } + return -1; +} + +qint64 DownloadItem2::bytesReceived() const +{ + return m_bytesReceived; +} + +qint64 DownloadItem2::bytesTotal() const +{ + return m_bytesTotal; +} + +qint64 DownloadItem2::currentSpeed() const +{ + return m_currentSpeed; +} + +void DownloadItem2::cancel() +{ +} + +void DownloadItem2::pause() +{ +} + +void DownloadItem2::resume() +{ +} + +void DownloadItem2::setFlags(Flags flags) +{ + m_flags = flags; +} + +void DownloadItem2::setState(State state) +{ + m_state = state; + emit stateChanged(m_state); + if (m_state == DownloadFinished) { + emit finished(); + } +} + +void DownloadItem2::setError(Error error) +{ + m_error = error; + setState(DownloadError); +} + +void DownloadItem2::setUrl(const QUrl &url) +{ + m_url = url; +} + +void DownloadItem2::setPath(const QString &path) +{ + m_path = path; +} + +void DownloadItem2::updateProgress(qint64 received, qint64 total) +{ + m_currentSpeed = (received - m_bytesReceived) / (m_speedTimer.elapsed() / 1000.0); + m_speedTimer.restart(); + + m_bytesReceived = received; + m_bytesTotal = total; + + emit downloadProgress(m_bytesReceived, m_bytesTotal); +} + +void DownloadItem2::resetSpeedTimer() +{ + m_speedTimer.restart(); +} diff --git a/src/lib/downloads/downloaditem.h b/src/lib/downloads/downloaditem.h index e59761dea..91080069e 100644 --- a/src/lib/downloads/downloaditem.h +++ b/src/lib/downloads/downloaditem.h @@ -94,4 +94,80 @@ private: qint64 m_total; }; +class FALKON_EXPORT DownloadItem2 : public QObject +{ + Q_OBJECT + +public: + enum Flag { + CanPause = 1, + ActiveDownload = 2, // inactive download = eg. download from history + }; + Q_DECLARE_FLAGS(Flags, Flag) + + enum State { + DownloadStarting = 0, + DownloadInProgress, + DownloadPaused, + DownloadFinished, + DownloadCanceled, + DownloadError + }; + + enum Error { + NoError = 0, + UnknownError + }; + + explicit DownloadItem2(QObject *parent = nullptr); + + Flags flags() const; + State state() const; + Error error() const; + bool isError() const; + bool isPaused() const; + bool isFinished() const; + bool isCanceled() const; + + QUrl url() const; + QString path() const; + + int progress() const; + qint64 bytesReceived() const; + qint64 bytesTotal() const; + qint64 currentSpeed() const; + + virtual void cancel(); + virtual void pause(); + virtual void resume(); + +Q_SIGNALS: + void finished(); + void stateChanged(State state); + void downloadProgress(qint64 received, qint64 total); + +protected: + void setFlags(Flags flags); + void setState(State state); + void setError(Error error); + void setUrl(const QUrl &url); + void setPath(const QString &path); + void updateProgress(qint64 received, qint64 total); + + void resetSpeedTimer(); + +private: + Flags m_flags; + State m_state = DownloadStarting; + Error m_error = NoError; + QUrl m_url; + QString m_path; + qint64 m_bytesReceived = 0; + qint64 m_bytesTotal = 0; + qint64 m_currentSpeed = 0; + QTime m_speedTimer; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(DownloadItem2::Flags) + #endif // DOWNLOADITEM_H diff --git a/src/lib/downloads/downloadmanager.cpp b/src/lib/downloads/downloadmanager.cpp index 683a6584d..260adcd2a 100644 --- a/src/lib/downloads/downloadmanager.cpp +++ b/src/lib/downloads/downloadmanager.cpp @@ -514,3 +514,71 @@ DownloadManager::~DownloadManager() delete ui; } + + + + +DownloadManager2::DownloadManager2(QObject *parent) + : QObject(parent) +{ + loadSettings(); +} + +QString DownloadManager2::defaultDownloadPath() const +{ + return m_downloadPath; +} + +QString DownloadManager2::lastDownloadPath() const +{ + return m_lastDownloadPath; +} + +void DownloadManager2::setLastDownloadPath(const QString &path) +{ + m_lastDownloadPath = path; + Settings().setValue(QSL("DownloadManager/lastDownloadPath"), m_lastDownloadPath); +} + +void DownloadManager2::loadSettings() +{ + Settings settings; + settings.beginGroup(QSL("DownloadManager")); + m_downloadPath = settings.value(QSL("defaultDownloadPath"), QString()).toString(); + m_lastDownloadPath = settings.value(QSL("lastDownloadPath"), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)).toString(); + + m_useExternalManager = settings.value(QSL("UseExternalManager"), false).toBool(); + m_externalExecutable = settings.value(QSL("ExternalManagerExecutable"), QString()).toString(); + m_externalArguments = settings.value(QSL("ExternalManagerArguments"), QString()).toString(); + settings.endGroup(); + + if (!m_externalArguments.contains(QLatin1String("%d"))) { + m_externalArguments.append(QLatin1String(" %d")); + } +} + +QVector DownloadManager2::downloads() const +{ + return m_downloads; +} + +void DownloadManager2::addDownload(DownloadItem2 *item) +{ + m_downloads.append(item); + emit downloadAdded(item); +} + +void DownloadManager2::removeDownload(DownloadItem2 *item) +{ + if (m_downloads.removeOne(item)) { + item->deleteLater(); + emit downloadRemoved(item); + } +} + +void DownloadManager2::startExternalManager(const QUrl &url) +{ + QString arguments = m_externalArguments; + arguments.replace(QLatin1String("%d"), url.toEncoded()); + QzTools::startExternalProcess(m_externalExecutable, arguments); +} diff --git a/src/lib/downloads/downloadmanager.h b/src/lib/downloads/downloadmanager.h index f31649e54..63e07e78a 100644 --- a/src/lib/downloads/downloadmanager.h +++ b/src/lib/downloads/downloadmanager.h @@ -117,4 +117,41 @@ private: QPointer m_taskbarButton; }; +class DownloadItem2; + +class FALKON_EXPORT DownloadManager2 : public QObject +{ + Q_OBJECT + +public: + explicit DownloadManager2(QObject *parent = nullptr); + + QString defaultDownloadPath() const; + + QString lastDownloadPath() const; + void setLastDownloadPath(const QString &path); + + void loadSettings(); + + QVector downloads() const; + + void addDownload(DownloadItem2 *item); + void removeDownload(DownloadItem2 *item); + + void startExternalManager(const QUrl &url); + +Q_SIGNALS: + void downloadAdded(DownloadItem2 *item); + void downloadRemoved(DownloadItem2 *item); + +private: + QVector m_downloads; + QString m_downloadPath; + QString m_lastDownloadPath; + + bool m_useExternalManager = false; + QString m_externalExecutable; + QString m_externalArguments; +}; + #endif // DOWNLOADMANAGER_H