1 // For license of this file, see <project-root-folder>/LICENSE.md.
2 
3 #ifndef DOWNLOADMANAGER_H
4 #define DOWNLOADMANAGER_H
5 
6 #include "ui_downloaditem.h"
7 #include "ui_downloadmanager.h"
8 
9 #include "gui/tabcontent.h"
10 
11 #include <QDateTime>
12 #include <QElapsedTimer>
13 #include <QFile>
14 #include <QNetworkReply>
15 
16 class AutoSaver;
17 class DownloadModel;
18 class QFileIconProvider;
19 class QMimeData;
20 
21 class DownloadItem : public QWidget {
22   Q_OBJECT
23 
24   friend class DownloadManager;
25   friend class DownloadModel;
26 
27   public:
28     explicit DownloadItem(QNetworkReply* reply = 0, QWidget* parent = nullptr);
29     virtual ~DownloadItem();
30 
31     bool downloading() const;
32     bool downloadedSuccessfully() const;
33 
34     qint64 bytesTotal() const;
35     qint64 bytesReceived() const;
36     double remainingTime() const;
37     double currentSpeed() const;
38 
39   private slots:
40     void stop();
41     void tryAgain();
42     void openFile();
43     void openFolder();
44 
45     void downloadReadyRead();
46     void error(QNetworkReply::NetworkError code);
47     void downloadProgress(qint64 bytes_received, qint64 bytes_total);
48     void metaDataChanged();
49     void finished();
50 
51   signals:
52     void statusChanged();
53     void progress(qint64 bytes_received, qint64 bytes_total);
54     void downloadFinished();
55 
56   private:
57     void updateInfoAndUrlLabel();
58     void getFileName();
59     void init();
60     void updateDownloadInfoLabel();
61     QString saveFileName(const QString& directory) const;
62 
63     Ui::DownloadItem* m_ui;
64     QUrl m_url;
65     QFile m_output;
66     QNetworkReply* m_reply;
67     qint64 m_bytesReceived;
68     QElapsedTimer m_downloadTime;
69     QTime m_lastProgressTime;
70     bool m_requestFileName;
71     bool m_startedSaving;
72     bool m_finishedDownloading;
73     bool m_gettingFileName;
74     bool m_canceledFileSelect;
75 };
76 
77 #if defined(USE_WEBENGINE)
78 class WebBrowser;
79 #endif
80 
81 class SilentNetworkAccessManager;
82 
83 class DownloadManager : public TabContent {
84   Q_OBJECT
85   Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy NOTIFY removePolicyChanged)
86 
87   friend class DownloadModel;
88 
89   public:
90     enum class RemovePolicy {
91       Never,
92       OnExit,
93       OnSuccessfullDownload
94     };
95 
96     Q_ENUM(RemovePolicy)
97 
98     explicit DownloadManager(QWidget* parent = nullptr);
99     virtual ~DownloadManager();
100 
101 #if defined(USE_WEBENGINE)
102     virtual WebBrowser* webBrowser() const;
103 #endif
104 
105     SilentNetworkAccessManager* networkManager() const;
106 
107     int totalDownloads() const;
108     int activeDownloads() const;
109     int downloadProgress() const;
110 
111     RemovePolicy removePolicy() const;
112     void setRemovePolicy(RemovePolicy policy);
113 
114     void setDownloadDirectory(const QString& directory);
115     QString downloadDirectory();
116 
117     static QString timeString(double time_remaining);
118     static QString dataString(qint64 size);
119 
120   public slots:
121     void download(const QNetworkRequest& request);
122     void download(const QUrl& url);
123     void handleUnsupportedContent(QNetworkReply* reply);
124     void cleanup();
125 
126   private slots:
127     void save() const;
128     void load();
129 
130     void updateRow(DownloadItem* item);
131     void updateRow();
132     void itemProgress();
133     void itemFinished();
134 
135   signals:
136     void removePolicyChanged();
137     void downloadProgressed(int progress, const QString& description);
138     void downloadFinished();
139 
140   private:
141     void addItem(DownloadItem* item);
142 
143     QScopedPointer<Ui::DownloadManager> m_ui;
144     AutoSaver* m_autoSaver;
145     DownloadModel* m_model;
146     SilentNetworkAccessManager* m_networkManager;
147 
148     QScopedPointer<QFileIconProvider> m_iconProvider;
149     QList<DownloadItem*> m_downloads;
150     RemovePolicy m_removePolicy;
151     QString m_downloadDirectory;
152 };
153 
154 #if defined(USE_WEBENGINE)
webBrowser()155 inline WebBrowser* DownloadManager::webBrowser() const {
156   return nullptr;
157 }
158 
159 #endif
160 
161 class DownloadModel : public QAbstractListModel {
162   Q_OBJECT
163 
164   friend class DownloadManager;
165 
166   public:
167     explicit DownloadModel(DownloadManager* download_manager, QObject* parent = nullptr);
168 
169     virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
170     virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
171     virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
172     virtual Qt::ItemFlags flags(const QModelIndex& index) const;
173     virtual QMimeData* mimeData(const QModelIndexList& indexes) const;
174 
175   private:
176     DownloadManager* m_downloadManager;
177 };
178 
179 #endif // DOWNLOADMANAGER_H
180