FreeCAD

Форк
0
/
DownloadManager.cpp 
343 строки · 12.2 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
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.      *
10
 *                                                                         *
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.                  *
15
 *                                                                         *
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                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#include <cstdio>
25
#include <iostream>
26

27
#include <QByteArray>
28
#include <QDockWidget>
29
#include <QFileInfo>
30
#include <QNetworkRequest>
31
#include <QNetworkReply>
32
#include <QMetaEnum>
33
#include <QSettings>
34
#include <QFileIconProvider>
35
#include <QUrlQuery>
36

37
#include "DownloadManager.h"
38
#include "ui_DownloadManager.h"
39
#include "DockWindowManager.h"
40
#include "DownloadItem.h"
41
#include "MainWindow.h"
42

43

44
using namespace Gui::Dialog;
45

46
/* TRANSLATOR Gui::Dialog::DownloadManager */
47

48
DownloadManager* DownloadManager::self = nullptr;
49

50
DownloadManager* DownloadManager::getInstance()
51
{
52
    if (!self)
53
        self = new DownloadManager(Gui::getMainWindow());
54
    return self;
55
}
56

57
DownloadManager::DownloadManager(QWidget *parent)
58
    : QDialog(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())
64
{
65
    ui->setupUi(this);
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);
74
    load();
75

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);
83
    dw->show();
84
}
85

86
DownloadManager::~DownloadManager()
87
{
88
    m_autoSaver->changeOccurred();
89
    m_autoSaver->saveIfNecessary();
90
    if (m_iconProvider)
91
        delete m_iconProvider;
92
    delete ui;
93
    self = nullptr;
94
}
95

96
void DownloadManager::closeEvent(QCloseEvent* e)
97
{
98
    QDialog::closeEvent(e);
99
}
100

101
int DownloadManager::activeDownloads() const
102
{
103
    int count = 0;
104
    for (int i = 0; i < m_downloads.count(); ++i) {
105
        if (m_downloads.at(i)->stopButton->isEnabled())
106
            ++count;
107
    }
108
    return count;
109
}
110

111
QUrl DownloadManager::redirectUrl(const QUrl& url) const
112
{
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"));
122
                }
123
                else if (it.second == QLatin1String("0")) {
124
                    urlQuery.removeQueryItem(QLatin1String("dl"));
125
                    urlQuery.addQueryItem(QLatin1String("dl"), QLatin1String("1"));
126
                }
127
                break;
128
            }
129
        }
130
        redirectUrl.setQuery(urlQuery);
131
    }
132
    else {
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"))) {
137
            str.chop(2);
138
            redirectUrl.setUrl(str);
139
        }
140
    }
141

142
    return redirectUrl;
143
}
144

145
void DownloadManager::download(const QNetworkRequest &request, bool requestFileName)
146
{
147
    if (request.url().isEmpty())
148
        return;
149

150
    std::cout << request.url().toString().toStdString() << std::endl;
151
    handleUnsupportedContent(m_manager->get(request), requestFileName);
152
}
153

154
void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName)
155
{
156
    if (!reply || reply->url().isEmpty())
157
        return;
158
    QVariant header = reply->header(QNetworkRequest::ContentLengthHeader);
159
    bool ok;
160
    int size = header.toInt(&ok);
161
    if (ok && size == 0)
162
        return;
163

164
    auto item = new DownloadItem(reply, requestFileName, this);
165
    addItem(item);
166
}
167

168
void DownloadManager::addItem(DownloadItem *item)
169
{
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();
175
    updateItemCount();
176
    show();
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());
181
}
182

183
void DownloadManager::updateRow()
184
{
185
    auto item = qobject_cast<DownloadItem*>(sender());
186
    int row = m_downloads.indexOf(item);
187
    if (-1 == row)
188
        return;
189
    if (!m_iconProvider)
190
        m_iconProvider = new QFileIconProvider();
191
    QIcon icon = m_iconProvider->icon(QFileInfo(item->m_output.fileName()));
192
    if (icon.isNull())
193
        icon = style()->standardIcon(QStyle::SP_FileIcon);
194
    item->fileIcon->setPixmap(icon.pixmap(48, 48));
195
    ui->downloadsView->setRowHeight(row, item->minimumSizeHint().height());
196

197
    bool remove = false;
198
    if (item->downloadedSuccessfully()
199
        && removePolicy() == DownloadManager::SuccessFullDownload) {
200
        remove = true;
201
    }
202
    if (remove)
203
        m_model->removeRow(row);
204

205
    ui->cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0);
206
}
207

208
DownloadManager::RemovePolicy DownloadManager::removePolicy() const
209
{
210
    return m_removePolicy;
211
}
212

213
void DownloadManager::setRemovePolicy(RemovePolicy policy)
214
{
215
    if (policy == m_removePolicy)
216
        return;
217
    m_removePolicy = policy;
218
    m_autoSaver->changeOccurred();
219
}
220

221
void DownloadManager::save() const
222
{
223
    QSettings settings;
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)
229
        return;
230

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());
236
    }
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);
244
    }
245
}
246

247
void DownloadManager::load()
248
{
249
    QSettings settings;
250
    settings.beginGroup(QLatin1String("downloadmanager"));
251
    QSize size = settings.value(QLatin1String("size")).toSize();
252
    if (size.isValid())
253
        resize(size);
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 ?
257
                        Never :
258
                        static_cast<RemovePolicy>(removePolicyEnum.keyToValue(value));
259

260
    int i = 0;
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());
270
            item->m_url = url;
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);
276
            addItem(item);
277
        }
278
        key = QString(QLatin1String("download_%1_")).arg(++i);
279
    }
280
    ui->cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0);
281
}
282

283
void DownloadManager::cleanup()
284
{
285
    if (m_downloads.isEmpty())
286
        return;
287
    m_model->removeRows(0, m_downloads.count());
288
    updateItemCount();
289
    if (m_downloads.isEmpty() && m_iconProvider) {
290
        delete m_iconProvider;
291
        m_iconProvider = nullptr;
292
    }
293
    m_autoSaver->changeOccurred();
294
}
295

296
void DownloadManager::updateItemCount()
297
{
298
    int count = m_downloads.count();
299
    ui->itemCount->setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count));
300
}
301

302
// ----------------------------------------------------------------------------
303

304
DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent)
305
    : QAbstractListModel(parent)
306
    , m_downloadManager(downloadManager)
307
{
308
}
309

310
QVariant DownloadModel::data(const QModelIndex &index, int role) const
311
{
312
    if (index.row() < 0 || index.row() >= rowCount(index.parent()))
313
        return {};
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();
317
    return {};
318
}
319

320
int DownloadModel::rowCount(const QModelIndex &parent) const
321
{
322
    return (parent.isValid()) ? 0 : m_downloadManager->m_downloads.count();
323
}
324

325
bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent)
326
{
327
    if (parent.isValid())
328
        return false;
329

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();
336
            endRemoveRows();
337
        }
338
    }
339
    m_downloadManager->m_autoSaver->changeOccurred();
340
    return true;
341
}
342

343
#include "moc_DownloadManager.cpp"
344

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.