1
/***************************************************************************
2
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
30
#include <QNetworkRequest>
31
#include <QNetworkReply>
34
#include <QFileIconProvider>
37
#include "DownloadManager.h"
38
#include "ui_DownloadManager.h"
39
#include "DockWindowManager.h"
40
#include "DownloadItem.h"
41
#include "MainWindow.h"
44
using namespace Gui::Dialog;
46
/* TRANSLATOR Gui::Dialog::DownloadManager */
48
DownloadManager* DownloadManager::self = nullptr;
50
DownloadManager* DownloadManager::getInstance()
53
self = new DownloadManager(Gui::getMainWindow());
57
DownloadManager::DownloadManager(QWidget *parent)
59
, m_autoSaver(new AutoSaver(this))
60
, m_manager(new NetworkAccessManager(this))
61
, m_iconProvider(nullptr)
62
, m_removePolicy(Never)
63
, ui(new Ui_DownloadManager())
66
ui->downloadsView->setShowGrid(false);
67
ui->downloadsView->verticalHeader()->hide();
68
ui->downloadsView->horizontalHeader()->hide();
69
ui->downloadsView->setAlternatingRowColors(true);
70
ui->downloadsView->horizontalHeader()->setStretchLastSection(true);
71
m_model = new DownloadModel(this);
72
ui->downloadsView->setModel(m_model);
73
connect(ui->cleanupButton, &QPushButton::clicked, this, &DownloadManager::cleanup);
76
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
77
QDockWidget* dw = pDockMgr->addDockWindow(QT_TR_NOOP("Download Manager"),
78
this, Qt::BottomDockWidgetArea);
79
dw->setFeatures(QDockWidget::DockWidgetMovable|
80
QDockWidget::DockWidgetFloatable|
81
QDockWidget::DockWidgetClosable);
82
dw->setAttribute(Qt::WA_DeleteOnClose);
86
DownloadManager::~DownloadManager()
88
m_autoSaver->changeOccurred();
89
m_autoSaver->saveIfNecessary();
91
delete m_iconProvider;
96
void DownloadManager::closeEvent(QCloseEvent* e)
98
QDialog::closeEvent(e);
101
int DownloadManager::activeDownloads() const
104
for (int i = 0; i < m_downloads.count(); ++i) {
105
if (m_downloads.at(i)->stopButton->isEnabled())
111
QUrl DownloadManager::redirectUrl(const QUrl& url) const
113
QUrl redirectUrl = url;
114
if (url.host() == QLatin1String("www.dropbox.com")) {
115
QUrlQuery urlQuery(url);
116
QList< QPair<QString, QString> > query = urlQuery.queryItems();
117
for (const auto & it : query) {
118
if (it.first == QLatin1String("dl")) {
119
if (it.second == QLatin1String("0\r\n")) {
120
urlQuery.removeQueryItem(QLatin1String("dl"));
121
urlQuery.addQueryItem(QLatin1String("dl"), QLatin1String("1\r\n"));
123
else if (it.second == QLatin1String("0")) {
124
urlQuery.removeQueryItem(QLatin1String("dl"));
125
urlQuery.addQueryItem(QLatin1String("dl"), QLatin1String("1"));
130
redirectUrl.setQuery(urlQuery);
133
// When the url comes from drag and drop it may end with CR+LF. This may cause problems
134
// and thus should be removed.
135
QString str = redirectUrl.toString();
136
if (str.endsWith(QLatin1String("\r\n"))) {
138
redirectUrl.setUrl(str);
145
void DownloadManager::download(const QNetworkRequest &request, bool requestFileName)
147
if (request.url().isEmpty())
150
std::cout << request.url().toString().toStdString() << std::endl;
151
handleUnsupportedContent(m_manager->get(request), requestFileName);
154
void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName)
156
if (!reply || reply->url().isEmpty())
158
QVariant header = reply->header(QNetworkRequest::ContentLengthHeader);
160
int size = header.toInt(&ok);
164
auto item = new DownloadItem(reply, requestFileName, this);
168
void DownloadManager::addItem(DownloadItem *item)
170
connect(item, &DownloadItem::statusChanged, this, &DownloadManager::updateRow);
171
int row = m_downloads.count();
172
m_model->beginInsertRows(QModelIndex(), row, row);
173
m_downloads.append(item);
174
m_model->endInsertRows();
177
ui->downloadsView->setIndexWidget(m_model->index(row, 0), item);
178
QIcon icon = style()->standardIcon(QStyle::SP_FileIcon);
179
item->fileIcon->setPixmap(icon.pixmap(48, 48));
180
ui->downloadsView->setRowHeight(row, item->sizeHint().height());
183
void DownloadManager::updateRow()
185
auto item = qobject_cast<DownloadItem*>(sender());
186
int row = m_downloads.indexOf(item);
190
m_iconProvider = new QFileIconProvider();
191
QIcon icon = m_iconProvider->icon(QFileInfo(item->m_output.fileName()));
193
icon = style()->standardIcon(QStyle::SP_FileIcon);
194
item->fileIcon->setPixmap(icon.pixmap(48, 48));
195
ui->downloadsView->setRowHeight(row, item->minimumSizeHint().height());
198
if (item->downloadedSuccessfully()
199
&& removePolicy() == DownloadManager::SuccessFullDownload) {
203
m_model->removeRow(row);
205
ui->cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0);
208
DownloadManager::RemovePolicy DownloadManager::removePolicy() const
210
return m_removePolicy;
213
void DownloadManager::setRemovePolicy(RemovePolicy policy)
215
if (policy == m_removePolicy)
217
m_removePolicy = policy;
218
m_autoSaver->changeOccurred();
221
void DownloadManager::save() const
224
settings.beginGroup(QLatin1String("downloadmanager"));
225
QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy"));
226
settings.setValue(QLatin1String("removeDownloadsPolicy"), QLatin1String(removePolicyEnum.valueToKey(m_removePolicy)));
227
settings.setValue(QLatin1String("size"), size());
228
if (m_removePolicy == Exit)
231
for (int i = 0; i < m_downloads.count(); ++i) {
232
QString key = QString(QLatin1String("download_%1_")).arg(i);
233
settings.setValue(key + QLatin1String("url"), m_downloads[i]->m_url);
234
settings.setValue(key + QLatin1String("location"), QFileInfo(m_downloads[i]->m_output).filePath());
235
settings.setValue(key + QLatin1String("done"), m_downloads[i]->downloadedSuccessfully());
237
int i = m_downloads.count();
238
QString key = QString(QLatin1String("download_%1_")).arg(i);
239
while (settings.contains(key + QLatin1String("url"))) {
240
settings.remove(key + QLatin1String("url"));
241
settings.remove(key + QLatin1String("location"));
242
settings.remove(key + QLatin1String("done"));
243
key = QString(QLatin1String("download_%1_")).arg(++i);
247
void DownloadManager::load()
250
settings.beginGroup(QLatin1String("downloadmanager"));
251
QSize size = settings.value(QLatin1String("size")).toSize();
254
QByteArray value = settings.value(QLatin1String("removeDownloadsPolicy"), QLatin1String("Never")).toByteArray();
255
QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy"));
256
m_removePolicy = removePolicyEnum.keyToValue(value) == -1 ?
258
static_cast<RemovePolicy>(removePolicyEnum.keyToValue(value));
261
QString key = QString(QLatin1String("download_%1_")).arg(i);
262
while (settings.contains(key + QLatin1String("url"))) {
263
QUrl url = settings.value(key + QLatin1String("url")).toUrl();
264
QString fileName = settings.value(key + QLatin1String("location")).toString();
265
bool done = settings.value(key + QLatin1String("done"), true).toBool();
266
if (!url.isEmpty() && !fileName.isEmpty()) {
267
auto item = new DownloadItem(nullptr, false, this);
268
item->m_output.setFileName(fileName);
269
item->fileNameLabel->setText(QFileInfo(item->m_output.fileName()).fileName());
271
item->stopButton->setVisible(false);
272
item->stopButton->setEnabled(false);
273
item->tryAgainButton->setVisible(!done);
274
item->tryAgainButton->setEnabled(!done);
275
item->progressBar->setVisible(!done);
278
key = QString(QLatin1String("download_%1_")).arg(++i);
280
ui->cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0);
283
void DownloadManager::cleanup()
285
if (m_downloads.isEmpty())
287
m_model->removeRows(0, m_downloads.count());
289
if (m_downloads.isEmpty() && m_iconProvider) {
290
delete m_iconProvider;
291
m_iconProvider = nullptr;
293
m_autoSaver->changeOccurred();
296
void DownloadManager::updateItemCount()
298
int count = m_downloads.count();
299
ui->itemCount->setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count));
302
// ----------------------------------------------------------------------------
304
DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent)
305
: QAbstractListModel(parent)
306
, m_downloadManager(downloadManager)
310
QVariant DownloadModel::data(const QModelIndex &index, int role) const
312
if (index.row() < 0 || index.row() >= rowCount(index.parent()))
314
if (role == Qt::ToolTipRole)
315
if (!m_downloadManager->m_downloads.at(index.row())->downloadedSuccessfully())
316
return m_downloadManager->m_downloads.at(index.row())->downloadInfoLabel->text();
320
int DownloadModel::rowCount(const QModelIndex &parent) const
322
return (parent.isValid()) ? 0 : m_downloadManager->m_downloads.count();
325
bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent)
327
if (parent.isValid())
330
int lastRow = row + count - 1;
331
for (int i = lastRow; i >= row; --i) {
332
if (m_downloadManager->m_downloads.at(i)->downloadedSuccessfully()
333
|| m_downloadManager->m_downloads.at(i)->tryAgainButton->isEnabled()) {
334
beginRemoveRows(parent, i, i);
335
m_downloadManager->m_downloads.takeAt(i)->deleteLater();
339
m_downloadManager->m_autoSaver->changeOccurred();
343
#include "moc_DownloadManager.cpp"