Mercurial > projects > qtd
diff demos/browser/downloadmanager.d @ 73:7bfd46c330dc
more porting
author | mandel |
---|---|
date | Fri, 22 May 2009 10:59:00 +0000 |
parents | fd6eb3a1759d |
children | 37caa90ce503 |
line wrap: on
line diff
--- a/demos/browser/downloadmanager.d Wed May 20 22:44:31 2009 +0000 +++ b/demos/browser/downloadmanager.d Fri May 22 10:59:00 2009 +0000 @@ -38,624 +38,603 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + module downloadmanager; -import ui_downloads; -import ui_downloaditem; -import QtNetwork.QNetworkReply; +import qt.core.QFile; +import qt.core.QTime; +import qt.core.QMetaEnum; +import qt.core.QSettings; +import qt.core.QDebug; -import QtCore.QFile; -import QtCore.QTime; +import qt.gui.QDesktopServices; +import qt.gui.QFileDialog; +import qt.gui.QHeaderView; +import qt.gui.QFileIconProvider; +import qt.network.QNetworkReply; +import qt.webkit.QWebSettings; +import math; import autosaver; import browserapplication; import networkaccessmanager; - -import math; - -import QtCore.QMetaEnum; -import QtCore.QSettings; - -import QtGui.QDesktopServices; -import QtGui.QFileDialog; -import QtGui.QHeaderView; -import QtGui.QFileIconProvider; - -import QtCore.QDebug; - -import QtWebKit.QWebSettings; - +import ui_downloads; +import ui_downloaditem; class DownloadItem : public QWidget, public Ui_DownloadItem { - mixin Signal!("statusChanged"); public: -/*! - DownloadItem is a widget that is displayed in the download manager list. - It moves the data from the QNetworkReply into the QFile as well - as update the information/progressbar and report errors. - */ - this(QNetworkReply reply = null, bool requestFileName = false, QWidget parent = null) - { - super(parent); - m_reply = reply; - m_requestFileName = requestFileName; - m_bytesReceived = 0; - - setupUi(this); - QPalette p = downloadInfoLabel.palette(); - p.setColor(QPalette.Text, Qt.darkGray); - downloadInfoLabel.setPalette(p); - progressBar.setMaximum(0); - tryAgainButton.hide(); - stopButton.clicked.connect(&this.stop); - openButton.clicked.connect(&this.open); - tryAgainButton.clicked.connect(&this.tryAgain); + /*! + DownloadItem is a widget that is displayed in the download manager list. + It moves the data from the QNetworkReply into the QFile as well + as update the information/progressbar and report errors. + */ + this(QNetworkReply reply = null, bool requestFileName = false, QWidget parent = null) + { + super(parent); + m_reply = reply; + m_requestFileName = requestFileName; + m_bytesReceived = 0; - init(); - } - + setupUi(this); + QPalette p = downloadInfoLabel.palette(); + p.setColor(QPalette.Text, Qt.darkGray); + downloadInfoLabel.setPalette(p); + progressBar.setMaximum(0); + tryAgainButton.hide(); + stopButton.clicked.connect(&this.stop); + openButton.clicked.connect(&this.open); + tryAgainButton.clicked.connect(&this.tryAgain); - bool downloading() - { - return (progressBar.isVisible()); - } + init(); + } + bool downloading() + { + return (progressBar.isVisible()); + } - bool downloadedSuccessfully() - { - return (stopButton.isHidden() && tryAgainButton.isHidden()); - } + bool downloadedSuccessfully() + { + return (stopButton.isHidden() && tryAgainButton.isHidden()); + } - - QUrl m_url; - - QFile m_output; - QNetworkReply *m_reply; + QUrl m_url; + QFile m_output; + QNetworkReply m_reply; -private: // slots: - void stop() - { - setUpdatesEnabled(false); - stopButton.setEnabled(false); - stopButton.hide(); - tryAgainButton.setEnabled(true); - tryAgainButton.show(); - setUpdatesEnabled(true); - m_reply.abort(); - } +private: + + void stop() + { + setUpdatesEnabled(false); + stopButton.setEnabled(false); + stopButton.hide(); + tryAgainButton.setEnabled(true); + tryAgainButton.show(); + setUpdatesEnabled(true); + m_reply.abort(); + } - void tryAgain() - { - if (!tryAgainButton.isEnabled()) - return; + void tryAgain() + { + if (!tryAgainButton.isEnabled()) + return; - tryAgainButton.setEnabled(false); - tryAgainButton.setVisible(false); - stopButton.setEnabled(true); - stopButton.setVisible(true); - progressBar.setVisible(true); + tryAgainButton.setEnabled(false); + tryAgainButton.setVisible(false); + stopButton.setEnabled(true); + stopButton.setVisible(true); + progressBar.setVisible(true); - QNetworkReply *r = BrowserApplication.networkAccessManager().get(QNetworkRequest(m_url)); - if (m_reply) - m_reply.deleteLater(); - if (m_output.exists()) - m_output.remove(); - m_reply = r; - init(); - emit statusChanged(); - } + QNetworkReply r = BrowserApplication.networkAccessManager().get(QNetworkRequest(m_url)); + if (m_reply) + m_reply.deleteLater(); + if (m_output.exists()) + m_output.remove(); + m_reply = r; + init(); + emit statusChanged(); + } - void open() - { - QFileInfo info(m_output); - QUrl url = QUrl.fromLocalFile(info.absolutePath()); - QDesktopServices.openUrl(url); - } + void open() + { + QFileInfo info(m_output); + QUrl url = QUrl.fromLocalFile(info.absolutePath()); + QDesktopServices.openUrl(url); + } - void downloadReadyRead() - { - if (m_requestFileName && m_output.fileName().isEmpty()) - return; - if (!m_output.isOpen()) { - // in case someone else has already put a file there - if (!m_requestFileName) - getFileName(); - if (!m_output.open(QIODevice.WriteOnly)) { - downloadInfoLabel.setText(tr("Error opening save file: %1") - .arg(m_output.errorString())); - stopButton.click(); - emit statusChanged(); - return; - } - emit statusChanged(); - } - if (-1 == m_output.write(m_reply.readAll())) { - downloadInfoLabel.setText(tr("Error saving: %1") - .arg(m_output.errorString())); - stopButton.click(); - } - } + void downloadReadyRead() + { + if (m_requestFileName && m_output.fileName().isEmpty()) + return; + if (!m_output.isOpen()) { + // in case someone else has already put a file there + if (!m_requestFileName) + getFileName(); + if (!m_output.open(QIODevice.WriteOnly)) { + downloadInfoLabel.setText(tr("Error opening save file: %1") + .arg(m_output.errorString())); + stopButton.click(); + emit statusChanged(); + return; + } + emit statusChanged(); + } + if (-1 == m_output.write(m_reply.readAll())) { + downloadInfoLabel.setText(tr("Error saving: %1") + .arg(m_output.errorString())); + stopButton.click(); + } + } - void error(QNetworkReply.NetworkError code) - { - qDebug() << "DownloadItem::error" << m_reply.errorString() << m_url; - downloadInfoLabel.setText(tr("Network Error: %1").arg(m_reply.errorString())); - tryAgainButton.setEnabled(true); - tryAgainButton.setVisible(true); - } - + void error(QNetworkReply.NetworkError code) + { + qDebug() << "DownloadItem::error" << m_reply.errorString() << m_url; + downloadInfoLabel.setText(tr("Network Error: %1").arg(m_reply.errorString())); + tryAgainButton.setEnabled(true); + tryAgainButton.setVisible(true); + } - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) - { - m_bytesReceived = bytesReceived; - if (bytesTotal == -1) { - progressBar.setValue(0); - progressBar.setMaximum(0); - } else { - progressBar.setValue(bytesReceived); - progressBar.setMaximum(bytesTotal); - } - updateInfoLabel(); - } - + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) + { + m_bytesReceived = bytesReceived; + if (bytesTotal == -1) { + progressBar.setValue(0); + progressBar.setMaximum(0); + } else { + progressBar.setValue(bytesReceived); + progressBar.setMaximum(bytesTotal); + } + updateInfoLabel(); + } - void metaDataChanged() - { - qDebug() << "DownloadItem::metaDataChanged: not handled."; - } + void metaDataChanged() + { + qDebug() << "DownloadItem::metaDataChanged: not handled."; + } - void finished() - { - progressBar.hide(); - stopButton.setEnabled(false); - stopButton.hide(); - m_output.close(); - updateInfoLabel(); - emit statusChanged(); - } + void finished() + { + progressBar.hide(); + stopButton.setEnabled(false); + stopButton.hide(); + m_output.close(); + updateInfoLabel(); + emit statusChanged(); + } private: - void getFileName() - { - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QString defaultLocation = QDesktopServices.storageLocation(QDesktopServices.DesktopLocation); - QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString(); - if (!downloadDirectory.isEmpty()) - downloadDirectory += QLatin1Char('/'); + + void getFileName() + { + QSettings settings; + settings.beginGroup(QLatin1String("downloadmanager")); + QString defaultLocation = QDesktopServices.storageLocation(QDesktopServices.DesktopLocation); + QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString(); + if (!downloadDirectory.isEmpty()) + downloadDirectory += QLatin1Char('/'); - QString defaultFileName = saveFileName(downloadDirectory); - QString fileName = defaultFileName; - if (m_requestFileName) { - fileName = QFileDialog.getSaveFileName(this, tr("Save File"), defaultFileName); - if (fileName.isEmpty()) { - m_reply.close(); - fileNameLabel.setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName())); - return; - } - } - m_output.setFileName(fileName); - fileNameLabel.setText(QFileInfo(m_output.fileName()).fileName()); - if (m_requestFileName) - downloadReadyRead(); - } + QString defaultFileName = saveFileName(downloadDirectory); + QString fileName = defaultFileName; + if (m_requestFileName) { + fileName = QFileDialog.getSaveFileName(this, tr("Save File"), defaultFileName); + if (fileName.isEmpty()) { + m_reply.close(); + fileNameLabel.setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName())); + return; + } + } + m_output.setFileName(fileName); + fileNameLabel.setText(QFileInfo(m_output.fileName()).fileName()); + if (m_requestFileName) + downloadReadyRead(); + } - void init() - { - if (!m_reply) - return; + void init() + { + if (!m_reply) + return; - // attach to the m_reply - m_url = m_reply.url(); - m_reply.setParent(this); - connect(m_reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead())); - connect(m_reply, SIGNAL(error(QNetworkReply.NetworkError)), - this, SLOT(error(QNetworkReply.NetworkError))); - connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), - this, SLOT(downloadProgress(qint64, qint64))); - connect(m_reply, SIGNAL(metaDataChanged()), - this, SLOT(metaDataChanged())); - connect(m_reply, SIGNAL(finished()), - this, SLOT(finished())); + // attach to the m_reply + m_url = m_reply.url(); + m_reply.setParent(this); + m_reply.readyRead.connect(&this.downloadReadyRead); + m_reply.error.connect(&this.error); + m_reply.downloadProgress.connect(&this.downloadProgress); + m_reply.metaDataChanged.connect(&this.metaDataChanged); + m_reply.finished.connect(&this.finished); - // reset info - downloadInfoLabel.clear(); - progressBar.setValue(0); - getFileName(); + // reset info + downloadInfoLabel.clear(); + progressBar.setValue(0); + getFileName(); - // start timer for the download estimation - m_downloadTime.start(); + // start timer for the download estimation + m_downloadTime.start(); - if (m_reply.error() != QNetworkReply.NoError) { - error(m_reply.error()); - finished(); - } - } + if (m_reply.error() != QNetworkReply.NoError) { + error(m_reply.error()); + finished(); + } + } - void updateInfoLabel() - { - if (m_reply.error() == QNetworkReply.NoError) - return; + void updateInfoLabel() + { + if (m_reply.error() == QNetworkReply.NoError) + return; - qint64 bytesTotal = progressBar.maximum(); - bool running = !downloadedSuccessfully(); + qint64 bytesTotal = progressBar.maximum(); + bool running = !downloadedSuccessfully(); - // update info label - double speed = m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); - double timeRemaining = ((double)(bytesTotal - m_bytesReceived)) / speed; - QString timeRemainingString = tr("seconds"); - if (timeRemaining > 60) { - timeRemaining = timeRemaining / 60; - timeRemainingString = tr("minutes"); - } - timeRemaining = floor(timeRemaining); + // update info label + double speed = m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); + double timeRemaining = ((double)(bytesTotal - m_bytesReceived)) / speed; + QString timeRemainingString = tr("seconds"); + if (timeRemaining > 60) { + timeRemaining = timeRemaining / 60; + timeRemainingString = tr("minutes"); + } + timeRemaining = floor(timeRemaining); - // When downloading the eta should never be 0 - if (timeRemaining == 0) - timeRemaining = 1; + // When downloading the eta should never be 0 + if (timeRemaining == 0) + timeRemaining = 1; - QString info; - if (running) { - QString remaining; - if (bytesTotal != 0) - remaining = tr("- %4 %5 remaining") - .arg(timeRemaining) - .arg(timeRemainingString); - info = QString(tr("%1 of %2 (%3/sec) %4")) - .arg(dataString(m_bytesReceived)) - .arg(bytesTotal == 0 ? tr("?") : dataString(bytesTotal)) - .arg(dataString((int)speed)) - .arg(remaining); - } else { - if (m_bytesReceived == bytesTotal) - info = dataString(m_output.size()); - else - info = tr("%1 of %2 - Stopped") - .arg(dataString(m_bytesReceived)) - .arg(dataString(bytesTotal)); - } - downloadInfoLabel.setText(info); - } + QString info; + if (running) { + QString remaining; + if (bytesTotal != 0) + remaining = tr("- %4 %5 remaining") + .arg(timeRemaining) + .arg(timeRemainingString); + + info = QString(tr("%1 of %2 (%3/sec) %4")) + .arg(dataString(m_bytesReceived)) + .arg(bytesTotal == 0 ? tr("?") : dataString(bytesTotal)) + .arg(dataString((int)speed)) + .arg(remaining); + } else { + if (m_bytesReceived == bytesTotal) + info = dataString(m_output.size()); + else + info = tr("%1 of %2 - Stopped") + .arg(dataString(m_bytesReceived)) + .arg(dataString(bytesTotal)); + } + downloadInfoLabel.setText(info); + } - QString dataString(int size) - { - QString unit; - if (size < 1024) { - unit = tr("bytes"); - } else if (size < 1024*1024) { - size /= 1024; - unit = tr("kB"); - } else { - size /= 1024*1024; - unit = tr("MB"); - } - return QString(QLatin1String("%1 %2")).arg(size).arg(unit); - } - - QString saveFileName(const QString &directory); - { - // Move this function into QNetworkReply to also get file name sent from the server - QString path = m_url.path(); - QFileInfo info(path); - QString baseName = info.completeBaseName(); - QString endName = info.suffix(); + QString dataString(int size) + { + QString unit; + if (size < 1024) { + unit = tr("bytes"); + } else if (size < 1024*1024) { + size /= 1024; + unit = tr("kB"); + } else { + size /= 1024*1024; + unit = tr("MB"); + } + return QString(QLatin1String("%1 %2")).arg(size).arg(unit); + } - if (baseName.isEmpty()) { - baseName = QLatin1String("unnamed_download"); - qDebug() << "DownloadManager:: downloading unknown file:" << m_url; - } - QString name = directory + baseName + QLatin1Char('.') + endName; - if (QFile.exists(name)) { - // already exists, don't overwrite - int i = 1; - do { - name = directory + baseName + QLatin1Char('-') + QString.number(i++) + QLatin1Char('.') + endName; - } while (QFile.exists(name)); - } - return name; - } + QString saveFileName(QString &directory); + { + // Move this function into QNetworkReply to also get file name sent from the server + QString path = m_url.path(); + QFileInfo info(path); + QString baseName = info.completeBaseName(); + QString endName = info.suffix(); - bool m_requestFileName; - qint64 m_bytesReceived; - QTime m_downloadTime; -}; + if (baseName.isEmpty()) { + baseName = QLatin1String("unnamed_download"); + qDebug() << "DownloadManager:: downloading unknown file:" << m_url; + } + QString name = directory + baseName + QLatin1Char('.') + endName; + if (QFile.exists(name)) { + // already exists, don't overwrite + int i = 1; + do { + name = directory + baseName + QLatin1Char('-') + QString.number(i++) + QLatin1Char('.') + endName; + } while (QFile.exists(name)); + } + return name; + } -class AutoSaver; -class DownloadModel; -QT_BEGIN_NAMESPACE -class QFileIconProvider; -QT_END_NAMESPACE + bool m_requestFileName; + qint64 m_bytesReceived; + QTime m_downloadTime; +} + class DownloadManager : public QDialog, public Ui_DownloadDialog { - Q_OBJECT - Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy) - Q_ENUMS(RemovePolicy) + +public: + + enum RemovePolicy { + Never, + Exit, + SuccessFullDownload + }; + + /*! + DownloadManager is a Dialog that contains a list of DownloadItems + + It is a basic download manager. It only downloads the file, doesn't do BitTorrent, + extract zipped files or anything fancy. + */ + this(QWidget parent = null) : QDialog(parent) + { + m_autoSaver = new AutoSaver(this); + m_manager = BrowserApplication.networkAccessManager(); + m_iconProvider = 0; + m_removePolicy = RemovePolicy.Never; + + setupUi(this); + downloadsView.setShowGrid(false); + downloadsView.verticalHeader().hide(); + downloadsView.horizontalHeader().hide(); + downloadsView.setAlternatingRowColors(true); + downloadsView.horizontalHeader().setStretchLastSection(true); + m_model = new DownloadModel(this); + downloadsView.setModel(m_model); + connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); + load(); + } + + ~this() + { + m_autoSaver.changeOccurred(); + m_autoSaver.saveIfNeccessary(); + if (m_iconProvider) + delete m_iconProvider; + } + + int activeDownloads() + { + int count = 0; + for (int i = 0; i < m_downloads.count(); ++i) { + if (m_downloads.at(i).stopButton.isEnabled()) + ++count; + } + return count; + } + + RemovePolicy removePolicy() + { + return m_removePolicy; + } + + void setRemovePolicy(RemovePolicy policy) + { + if (policy == m_removePolicy) + return; + m_removePolicy = policy; + m_autoSaver.changeOccurred(); + } public: - enum RemovePolicy { - Never, - Exit, - SuccessFullDownload - }; - /*! - DownloadManager is a Dialog that contains a list of DownloadItems - - It is a basic download manager. It only downloads the file, doesn't do BitTorrent, - extract zipped files or anything fancy. - */ -this(QWidget *parent = null) - : QDialog(parent) - , m_autoSaver(new AutoSaver(this)) - , m_manager(BrowserApplication.networkAccessManager()) - , m_iconProvider(0) - , m_removePolicy(Never) -{ - setupUi(this); - downloadsView.setShowGrid(false); - downloadsView.verticalHeader().hide(); - downloadsView.horizontalHeader().hide(); - downloadsView.setAlternatingRowColors(true); - downloadsView.horizontalHeader().setStretchLastSection(true); - m_model = new DownloadModel(this); - downloadsView.setModel(m_model); - connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); - load(); -} - - ~this() -{ - m_autoSaver.changeOccurred(); - m_autoSaver.saveIfNeccessary(); - if (m_iconProvider) - delete m_iconProvider; -} - - int activeDownloads() -{ - int count = 0; - for (int i = 0; i < m_downloads.count(); ++i) { - if (m_downloads.at(i).stopButton.isEnabled()) - ++count; - } - return count; -} - - RemovePolicy removePolicy() -{ - return m_removePolicy; -} - - void setRemovePolicy(RemovePolicy policy) -{ - if (policy == m_removePolicy) - return; - m_removePolicy = policy; - m_autoSaver.changeOccurred(); -} + void download(QNetworkRequest request, bool requestFileName = false); + { + if (request.url().isEmpty()) + return; + handleUnsupportedContent(m_manager.get(request), requestFileName); + } -public slots: - void download(const QNetworkRequest &request, bool requestFileName = false); -{ - if (request.url().isEmpty()) - return; - handleUnsupportedContent(m_manager.get(request), requestFileName); + void download(QUrl url, bool requestFileName = false) + { + download(QNetworkRequest(url), requestFileName); + } + + void handleUnsupportedContent(QNetworkReply reply, bool requestFileName = false); + { + if (!reply || reply.url().isEmpty()) + return; + QVariant header = reply.header(QNetworkRequest.ContentLengthHeader); + bool ok; + int size = header.toInt(&ok); + if (ok && size == 0) + return; + + qDebug() << "DownloadManager::handleUnsupportedContent" << reply.url() << "requestFileName" << requestFileName; + DownloadItem item = new DownloadItem(reply, requestFileName, this); + addItem(item); + } + + void cleanup() + { + if (m_downloads.isEmpty()) + return; + m_model.removeRows(0, m_downloads.count()); + updateItemCount(); + if (m_downloads.isEmpty() && m_iconProvider) { + delete m_iconProvider; + m_iconProvider = 0; + } + m_autoSaver.changeOccurred(); + } + +private: + + void save() + { + QSettings settings; + settings.beginGroup(QLatin1String("downloadmanager")); + QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); + settings.setValue(QLatin1String("removeDownloadsPolicy"), QLatin1String(removePolicyEnum.valueToKey(m_removePolicy))); + settings.setValue(QLatin1String("size"), size()); + if (m_removePolicy == Exit) + return; + + for (int i = 0; i < m_downloads.count(); ++i) { + QString key = QString(QLatin1String("download_%1_")).arg(i); + settings.setValue(key + QLatin1String("url"), m_downloads[i].m_url); + settings.setValue(key + QLatin1String("location"), QFileInfo(m_downloads[i].m_output).filePath()); + settings.setValue(key + QLatin1String("done"), m_downloads[i].downloadedSuccessfully()); + } + int i = m_downloads.count(); + QString key = QString(QLatin1String("download_%1_")).arg(i); + while (settings.contains(key + QLatin1String("url"))) { + settings.remove(key + QLatin1String("url")); + settings.remove(key + QLatin1String("location")); + settings.remove(key + QLatin1String("done")); + key = QString(QLatin1String("download_%1_")).arg(++i); + } + } + + void updateRow() + { + DownloadItem item = qobject_cast<DownloadItem*>(sender()); + int row = m_downloads.indexOf(item); + if (-1 == row) + return; + if (!m_iconProvider) + m_iconProvider = new QFileIconProvider(); + QIcon icon = m_iconProvider.icon(item.m_output.fileName()); + if (icon.isNull()) + icon = style().standardIcon(QStyle.SP_FileIcon); + item.fileIcon.setPixmap(icon.pixmap(48, 48)); + downloadsView.setRowHeight(row, item.minimumSizeHint().height()); + + bool remove = false; + QWebSettings globalSettings = QWebSettings.globalSettings(); + if (!item.downloading() && globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled)) + remove = true; + + if (item.downloadedSuccessfully() && removePolicy() == DownloadManager.SuccessFullDownload) { + remove = true; + } + if (remove) + m_model.removeRow(row); + + cleanupButton.setEnabled(m_downloads.count() - activeDownloads() > 0); + } + +private: + + void addItem(DownloadItem item) + { + item.statusChanged.connect(&this.updateRow); + int row = m_downloads.count(); + m_model.beginInsertRows(QModelIndex(), row, row); + m_downloads.append(item); + m_model.endInsertRows(); + updateItemCount(); + if (row == 0) + show(); + downloadsView.setIndexWidget(m_model.index(row, 0), item); + QIcon icon = style().standardIcon(QStyle.SP_FileIcon); + item.fileIcon.setPixmap(icon.pixmap(48, 48)); + downloadsView.setRowHeight(row, item.sizeHint().height()); + } + + + void updateItemCount() + { + int count = m_downloads.count(); + itemCount.setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count)); + } + + void load() + { + QSettings settings; + settings.beginGroup(QLatin1String("downloadmanager")); + QSize size = settings.value(QLatin1String("size")).toSize(); + if (size.isValid()) + resize(size); + QByteArray value = settings.value(QLatin1String("removeDownloadsPolicy"), QLatin1String("Never")).toByteArray(); + QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); + m_removePolicy = removePolicyEnum.keyToValue(value) == -1 ? Never : + static_cast<RemovePolicy>(removePolicyEnum.keyToValue(value)); + + int i = 0; + QString key = QString(QLatin1String("download_%1_")).arg(i); + while (settings.contains(key + QLatin1String("url"))) { + QUrl url = settings.value(key + QLatin1String("url")).toUrl(); + QString fileName = settings.value(key + QLatin1String("location")).toString(); + bool done = settings.value(key + QLatin1String("done"), true).toBool(); + if (!url.isEmpty() && !fileName.isEmpty()) { + DownloadItem item = new DownloadItem(0, this); + item.m_output.setFileName(fileName); + item.fileNameLabel.setText(QFileInfo(item.m_output.fileName()).fileName()); + item.m_url = url; + item.stopButton.setVisible(false); + item.stopButton.setEnabled(false); + item.tryAgainButton.setVisible(!done); + item.tryAgainButton.setEnabled(!done); + item.progressBar.setVisible(!done); + addItem(item); + } + key = QString(QLatin1String("download_%1_")).arg(++i); + } + cleanupButton.setEnabled(m_downloads.count() - activeDownloads() > 0); + } + + AutoSaver m_autoSaver; + DownloadModel m_model; + QNetworkAccessManager m_manager; + QFileIconProvider m_iconProvider; + QList<DownloadItem> m_downloads; + RemovePolicy m_removePolicy; } - inline void download(const QUrl &url, bool requestFileName = false) - { download(QNetworkRequest(url), requestFileName); } - void handleUnsupportedContent(QNetworkReply *reply, bool requestFileName = false); -{ - if (!reply || reply.url().isEmpty()) - return; - QVariant header = reply.header(QNetworkRequest.ContentLengthHeader); - bool ok; - int size = header.toInt(&ok); - if (ok && size == 0) - return; - - qDebug() << "DownloadManager::handleUnsupportedContent" << reply.url() << "requestFileName" << requestFileName; - DownloadItem *item = new DownloadItem(reply, requestFileName, this); - addItem(item); -} - - void cleanup() +class DownloadModel : public QAbstractListModel { - if (m_downloads.isEmpty()) - return; - m_model.removeRows(0, m_downloads.count()); - updateItemCount(); - if (m_downloads.isEmpty() && m_iconProvider) { - delete m_iconProvider; - m_iconProvider = 0; - } - m_autoSaver.changeOccurred(); -} + +public: + + this(DownloadManager downloadManager, QObject parent = null) + { + super(parent); + m_downloadManager = downloadManager; + } -private slots: - void save() -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); - settings.setValue(QLatin1String("removeDownloadsPolicy"), QLatin1String(removePolicyEnum.valueToKey(m_removePolicy))); - settings.setValue(QLatin1String("size"), size()); - if (m_removePolicy == Exit) - return; + QVariant data(QModelIndex index, int role = Qt.DisplayRole) + { + if (index.row() < 0 || index.row() >= rowCount(index.parent())) + return QVariant(); + if (role == Qt.ToolTipRole) + if (!m_downloadManager.m_downloads.at(index.row()).downloadedSuccessfully()) + return m_downloadManager.m_downloads.at(index.row()).downloadInfoLabel.text(); + return QVariant(); + } - for (int i = 0; i < m_downloads.count(); ++i) { - QString key = QString(QLatin1String("download_%1_")).arg(i); - settings.setValue(key + QLatin1String("url"), m_downloads[i].m_url); - settings.setValue(key + QLatin1String("location"), QFileInfo(m_downloads[i].m_output).filePath()); - settings.setValue(key + QLatin1String("done"), m_downloads[i].downloadedSuccessfully()); - } - int i = m_downloads.count(); - QString key = QString(QLatin1String("download_%1_")).arg(i); - while (settings.contains(key + QLatin1String("url"))) { - settings.remove(key + QLatin1String("url")); - settings.remove(key + QLatin1String("location")); - settings.remove(key + QLatin1String("done")); - key = QString(QLatin1String("download_%1_")).arg(++i); - } -} + int rowCount(QModelIndex parent = QModelIndex()) + { + return (parent.isValid()) ? 0 : m_downloadManager.m_downloads.count(); + } + + bool removeRows(int row, int count, QModelIndex parent = QModelIndex()) + { + if (parent.isValid()) + return false; - void updateRow() -{ - DownloadItem *item = qobject_cast<DownloadItem*>(sender()); - int row = m_downloads.indexOf(item); - if (-1 == row) - return; - if (!m_iconProvider) - m_iconProvider = new QFileIconProvider(); - QIcon icon = m_iconProvider.icon(item.m_output.fileName()); - if (icon.isNull()) - icon = style().standardIcon(QStyle.SP_FileIcon); - item.fileIcon.setPixmap(icon.pixmap(48, 48)); - downloadsView.setRowHeight(row, item.minimumSizeHint().height()); - - bool remove = false; - QWebSettings *globalSettings = QWebSettings.globalSettings(); - if (!item.downloading() - && globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled)) - remove = true; - - if (item.downloadedSuccessfully() - && removePolicy() == DownloadManager.SuccessFullDownload) { - remove = true; - } - if (remove) - m_model.removeRow(row); - - cleanupButton.setEnabled(m_downloads.count() - activeDownloads() > 0); -} + int lastRow = row + count - 1; + for (int i = lastRow; i >= row; --i) { + if (m_downloadManager.m_downloads.at(i).downloadedSuccessfully() + || m_downloadManager.m_downloads.at(i).tryAgainButton.isEnabled()) { + beginRemoveRows(parent, i, i); + m_downloadManager.m_downloads.takeAt(i).deleteLater(); + endRemoveRows(); + } + } + m_downloadManager.m_autoSaver.changeOccurred(); + return true; + } private: - void addItem(DownloadItem *item) -{ - connect(item, SIGNAL(statusChanged()), this, SLOT(updateRow())); - int row = m_downloads.count(); - m_model.beginInsertRows(QModelIndex(), row, row); - m_downloads.append(item); - m_model.endInsertRows(); - updateItemCount(); - if (row == 0) - show(); - downloadsView.setIndexWidget(m_model.index(row, 0), item); - QIcon icon = style().standardIcon(QStyle.SP_FileIcon); - item.fileIcon.setPixmap(icon.pixmap(48, 48)); - downloadsView.setRowHeight(row, item.sizeHint().height()); -} - - - void updateItemCount() -{ - int count = m_downloads.count(); - itemCount.setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count)); -} - -DownloadModel.DownloadModel(DownloadManager *downloadManager, QObject *parent) - : QAbstractListModel(parent) - , m_downloadManager(downloadManager) -{ + + DownloadManager m_downloadManager; } - - void load() -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QSize size = settings.value(QLatin1String("size")).toSize(); - if (size.isValid()) - resize(size); - QByteArray value = settings.value(QLatin1String("removeDownloadsPolicy"), QLatin1String("Never")).toByteArray(); - QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); - m_removePolicy = removePolicyEnum.keyToValue(value) == -1 ? - Never : - static_cast<RemovePolicy>(removePolicyEnum.keyToValue(value)); - - int i = 0; - QString key = QString(QLatin1String("download_%1_")).arg(i); - while (settings.contains(key + QLatin1String("url"))) { - QUrl url = settings.value(key + QLatin1String("url")).toUrl(); - QString fileName = settings.value(key + QLatin1String("location")).toString(); - bool done = settings.value(key + QLatin1String("done"), true).toBool(); - if (!url.isEmpty() && !fileName.isEmpty()) { - DownloadItem *item = new DownloadItem(0, this); - item.m_output.setFileName(fileName); - item.fileNameLabel.setText(QFileInfo(item.m_output.fileName()).fileName()); - item.m_url = url; - item.stopButton.setVisible(false); - item.stopButton.setEnabled(false); - item.tryAgainButton.setVisible(!done); - item.tryAgainButton.setEnabled(!done); - item.progressBar.setVisible(!done); - addItem(item); - } - key = QString(QLatin1String("download_%1_")).arg(++i); - } - cleanupButton.setEnabled(m_downloads.count() - activeDownloads() > 0); -} - - AutoSaver *m_autoSaver; - DownloadModel *m_model; - QNetworkAccessManager *m_manager; - QFileIconProvider *m_iconProvider; - QList<DownloadItem*> m_downloads; - RemovePolicy m_removePolicy; - friend class DownloadModel; -}; - -class DownloadModel : public QAbstractListModel -{ - friend class DownloadManager; - Q_OBJECT - -public: - DownloadModel(DownloadManager *downloadManager, QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt.DisplayRole) -{ - if (index.row() < 0 || index.row() >= rowCount(index.parent())) - return QVariant(); - if (role == Qt.ToolTipRole) - if (!m_downloadManager.m_downloads.at(index.row()).downloadedSuccessfully()) - return m_downloadManager.m_downloads.at(index.row()).downloadInfoLabel.text(); - return QVariant(); -} - - int rowCount(const QModelIndex &parent = QModelIndex()) -{ - return (parent.isValid()) ? 0 : m_downloadManager.m_downloads.count(); -} - - - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) -{ - if (parent.isValid()) - return false; - - int lastRow = row + count - 1; - for (int i = lastRow; i >= row; --i) { - if (m_downloadManager.m_downloads.at(i).downloadedSuccessfully() - || m_downloadManager.m_downloads.at(i).tryAgainButton.isEnabled()) { - beginRemoveRows(parent, i, i); - m_downloadManager.m_downloads.takeAt(i).deleteLater(); - endRemoveRows(); - } - } - m_downloadManager.m_autoSaver.changeOccurred(); - return true; -} - -private: - DownloadManager *m_downloadManager; - -}