From 61f4d694c0eec98ce5036f2a7536c570a7f75950 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Thu, 24 May 2012 01:08:51 +0200 Subject: Add informations to download items --- src/downloaditem.cpp | 140 ++++++++++++++++++++++-------------------------- src/downloaditem.h | 68 +++++++++++------------ src/downloadmanager.cpp | 60 ++++++++++++++------- src/downloadmanager.h | 6 ++- src/newtabpage.cpp | 63 +++++++++++++++------- 5 files changed, 187 insertions(+), 150 deletions(-) diff --git a/src/downloaditem.cpp b/src/downloaditem.cpp index cc528275..f1f0b9d9 100644 --- a/src/downloaditem.cpp +++ b/src/downloaditem.cpp @@ -2,7 +2,7 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2008-2010 by Andrea Diamantini +* Copyright (C) 2008-2012 by Andrea Diamantini * Copyright (C) 2011 by Pierre Rossi * * @@ -45,42 +45,79 @@ DownloadItem::DownloadItem(const QString &srcUrl, const QString &destUrl, const , m_srcUrlString(srcUrl) , m_destUrl(KUrl(destUrl)) , m_dateTime(d) - , m_shouldAbort(false) + , m_job(0) + , m_state(0) { } +DownloadItem::DownloadItem(KIO::CopyJob *job, const QDateTime &d, QObject *parent) + : QObject(parent) + , m_srcUrlString(job->srcUrls().at(0).url()) + , m_destUrl(job->destUrl()) + , m_dateTime(d) + , m_job(job) + , m_state(0) +{ + QObject::connect(job, SIGNAL(percent(KJob*,ulong)), this, SLOT(updateProgress(KJob*,ulong))); + QObject::connect(job, SIGNAL(finished(KJob*)), this, SLOT(onFinished(KJob*))); + QObject::connect(job, SIGNAL(suspended(KJob*)), this, SLOT(onSuspended(KJob*))); +} + + +KUrl DownloadItem::destUrl() const +{ + return m_destUrl; +} + + +QString DownloadItem::originUrl() const +{ + return m_srcUrlString; +} + + QString DownloadItem::fileDirectory() const { - return (QL1S("file://") + m_destUrl.directory()); + KUrl u = destUrl(); + return (QL1S("file://") + u.directory()); } QString DownloadItem::fileName() const { - return m_destUrl.fileName(); + return destUrl().fileName(); } -QString DownloadItem::destinationUrl() const +QString DownloadItem::destinationUrlString() const { - return m_destUrl.url(KUrl::RemoveTrailingSlash); + return destUrl().url(KUrl::RemoveTrailingSlash); } QString DownloadItem::icon() const { KIconLoader *loader = KIconLoader::global(); - QString iconForMimeType = KMimeType::iconNameForUrl(m_destUrl); + QString iconForMimeType = KMimeType::iconNameForUrl(destUrl()); return (QL1S("file://") + loader->iconPath(iconForMimeType, KIconLoader::Desktop)); } +void DownloadItem::setIsKGetDownload() +{ + m_state = KGetManaged; +} + + // update progress for the plain KIO::Job backend void DownloadItem::updateProgress(KJob *job, unsigned long value) { - if (m_shouldAbort) - job->kill(KJob::EmitResult); + Q_UNUSED(job); + + if (value > 0 && value < 100) + m_state = Downloading; + emit downloadProgress(value); } @@ -88,82 +125,33 @@ void DownloadItem::updateProgress(KJob *job, unsigned long value) // emit downloadFinished signal in KJob case void DownloadItem::onFinished(KJob *job) { - if (!job->error()) + if (job->error()) + { + m_state = Errors; + m_errorString = job->errorString(); + } + else + { + m_state = Done; emit downloadProgress(100); + } + emit downloadFinished(!job->error()); } -// sets up progress handling for the KGet backend -void DownloadItem::setKGetTransferDbusPath(const QString &path) +void DownloadItem::onSuspended(KJob *job) { - m_kGetPath = path; - QTimer *updateTimer = new QTimer(this); - updateTimer->setInterval(300); - updateTimer->setSingleShot(false); - connect(updateTimer, SIGNAL(timeout()), SLOT(updateProgress())); - updateTimer->start(); -} + Q_UNUSED(job); + + m_state = Suspended; - -/* -* update progress (polling in KGet case) -* -* Notes for KGet dbus interface: -* status values: -* - 0 running -* - 2 stopped -* - 4 finished -*/ -void DownloadItem::updateProgress() -{ - if (m_kGetPath.isEmpty()) - return; - QDBusInterface kgetTransfer(QL1S("org.kde.kget"), m_kGetPath, QL1S("org.kde.kget.transfer")); - if (!kgetTransfer.isValid()) - return; - // Fetch percent from DBus - QDBusMessage percentRes = kgetTransfer.call(QL1S("percent")); - if (percentRes.arguments().isEmpty()) - return; - bool ok = false; - const int percent = percentRes.arguments().first().toInt(&ok); - if (!ok) - return; - // Fetch status from DBus - QDBusMessage statusRes = kgetTransfer.call(QL1S("status")); - if (statusRes.arguments().isEmpty()) - return; - ok = false; - const int status = statusRes.arguments().first().toInt(&ok); - if (!ok) - return; - emit downloadProgress(percent); - // TODO: expose resume if stopped - // special case for status 2 will come later when we have a way to support resume. - if (percent == 100 || status == 4 || status == 2) - { - emit downloadFinished(true); - QTimer *timer = qobject_cast(sender()); - if (timer) - timer->stop(); - } + // TODO: + // connect to job->resume() to let rekonq resume it } -void DownloadItem::abort() const +QString DownloadItem::errorString() const { - if (!m_kGetPath.isEmpty()) - { - QDBusInterface kgetTransfer(QL1S("org.kde.kget"), m_kGetPath, QL1S("org.kde.kget.transfer")); - if (kgetTransfer.isValid()) - kgetTransfer.call(QL1S("stop")); - } - else - { - // using KIO::JOB, kill at the next update :) - m_shouldAbort = true; - } + return m_errorString; } - -// TODO: ability to remove single items from the page... diff --git a/src/downloaditem.h b/src/downloaditem.h index 45015f5c..f7b12782 100644 --- a/src/downloaditem.h +++ b/src/downloaditem.h @@ -2,7 +2,7 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2008-2010 by Andrea Diamantini +* Copyright (C) 2008-2012 by Andrea Diamantini * Copyright (C) 2011 by Pierre Rossi * * @@ -40,51 +40,52 @@ // KDE Includes #include #include - -// Forward Declarations -class KJob; +#include class DownloadItem : public QObject { Q_OBJECT - Q_PROPERTY(QString destinationUrl READ destinationUrl) - Q_PROPERTY(QString originUrl READ originUrl) - Q_PROPERTY(QString fileName READ fileName) - Q_PROPERTY(QString fileDirectory READ fileDirectory) - Q_PROPERTY(QDateTime date READ dateTime()) - Q_PROPERTY(QString iconFile READ icon) public: + + enum JobState + { + Done = 0, + Downloading = 1, + Errors = 2, + Suspended = 3, + KGetManaged = 4 + }; + explicit DownloadItem(const QString &srcUrl, const QString &destUrl, const QDateTime &d, QObject *parent = 0); + // This is used to add a DownloadItem managed with KIO + explicit DownloadItem(KIO::CopyJob *job, const QDateTime &d, QObject *parent = 0); + + inline QDateTime dateTime() const { return m_dateTime; } - inline QString originUrl() const - { - return m_srcUrlString; - } - QString destinationUrl() const; + + KUrl destUrl() const; + + QString originUrl() const; + QString destinationUrlString() const; QString fileName() const; QString fileDirectory() const; QString icon() const; - - // Necessary to provide i18nized strings to javascript. - Q_INVOKABLE QString i18nOpenDir() const - { - return i18n("Open directory"); - } - Q_INVOKABLE QString i18nOpenFile() const + QString errorString() const; + + inline int state() const { - return i18n("Open file"); + return m_state; } - // For transfer control and notification - void setKGetTransferDbusPath(const QString &path); - Q_INVOKABLE void abort() const; - + void setIsKGetDownload(); + + Q_SIGNALS: void downloadProgress(int percent); void downloadFinished(bool success); @@ -92,17 +93,18 @@ Q_SIGNALS: public Q_SLOTS: void updateProgress(KJob *job, unsigned long value); void onFinished(KJob *job); - -private Q_SLOTS: - void updateProgress(); + void onSuspended(KJob*); private: QString m_srcUrlString; KUrl m_destUrl; + QDateTime m_dateTime; - QString m_kGetPath; - mutable bool m_shouldAbort; - KJob *m_job; + + KIO::CopyJob *m_job; + int m_state; + + QString m_errorString; }; diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 5a2467d3..f313a68d 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -83,7 +83,7 @@ DownloadManager::~DownloadManager() Q_FOREACH(DownloadItem * item, m_downloadList) { out << item->originUrl(); - out << item->destinationUrl(); + out << item->destinationUrlString(); out << item->dateTime(); } @@ -116,11 +116,39 @@ void DownloadManager::init() } -DownloadItem* DownloadManager::addDownload(const QString &srcUrl, const QString &destUrl) +DownloadItem* DownloadManager::addDownload(KIO::CopyJob *job) { QWebSettings *globalSettings = QWebSettings::globalSettings(); if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) return 0; + + KIO::CopyJob *cJob = qobject_cast(job); + + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); + QFile downloadFile(downloadFilePath); + if (!downloadFile.open(QFile::WriteOnly | QFile::Append)) + { + kDebug() << "Unable to open download file (WRITE mode).."; + return 0; + } + QDataStream out(&downloadFile); + out << cJob->srcUrls().at(0).url(); + out << cJob->destUrl().url(); + out << QDateTime::currentDateTime(); + downloadFile.close(); + DownloadItem *item = new DownloadItem(job, QDateTime::currentDateTime(), this); + m_downloadList.append(item); + emit newDownloadAdded(item); + return item; +} + + +DownloadItem* DownloadManager::addKGetDownload(const QString &srcUrl, const QString &destUrl) +{ + QWebSettings *globalSettings = QWebSettings::globalSettings(); + if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) + return 0; + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); QFile downloadFile(downloadFilePath); if (!downloadFile.open(QFile::WriteOnly | QFile::Append)) @@ -134,6 +162,7 @@ DownloadItem* DownloadManager::addDownload(const QString &srcUrl, const QString out << QDateTime::currentDateTime(); downloadFile.close(); DownloadItem *item = new DownloadItem(srcUrl, destUrl, QDateTime::currentDateTime(), this); + item->setIsKGetDownload(); m_downloadList.append(item); emit newDownloadAdded(item); return item; @@ -199,11 +228,8 @@ bool DownloadManager::downloadResource(const KUrl &srcUrl, const KIO::MetaData & if (!destUrl.isValid()) return false; - // Save download history - DownloadItem *item = addDownload(srcUrl.pathOrUrl(), destUrl.pathOrUrl()); - emit notifyDownload(fileName); - - if (!KStandardDirs::findExe("kget").isNull() && ReKonfig::kgetDownload()) + // manage downloads with KGet if found + if (ReKonfig::kgetDownload() && !KStandardDirs::findExe("kget").isNull()) { //KGet integration: if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) @@ -215,26 +241,22 @@ bool DownloadManager::downloadResource(const KUrl &srcUrl, const KIO::MetaData & return false; QDBusMessage transfer = kget.call(QL1S("addTransfer"), srcUrl.prettyUrl(), destUrl.prettyUrl(), true); - if (transfer.arguments().isEmpty()) - return true; - const QString transferPath = transfer.arguments().first().toString(); - item->setKGetTransferDbusPath(transferPath); + addKGetDownload(srcUrl.pathOrUrl(), destUrl.pathOrUrl()); + emit notifyDownload(fileName); return true; } - KIO::Job *job = KIO::copy(srcUrl, destUrl, KIO::Overwrite); - if (item) - { - QObject::connect(job, SIGNAL(percent(KJob*,ulong)), item, SLOT(updateProgress(KJob*,ulong))); - QObject::connect(job, SIGNAL(finished(KJob*)), item, SLOT(onFinished(KJob*))); - } + KIO::CopyJob *job = KIO::copy(srcUrl, destUrl, KIO::Overwrite); if (!metaData.isEmpty()) job->setMetaData(metaData); - job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache. - job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available. + job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache. + job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available. job->uiDelegate()->setAutoErrorHandlingEnabled(true); + + addDownload(job); + emit notifyDownload(fileName); return true; } diff --git a/src/downloadmanager.h b/src/downloadmanager.h index 7033ef6c..bc20ff13 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -37,6 +37,7 @@ // KDE Includes #include +#include // Qt Includes #include @@ -72,8 +73,9 @@ public: private: void init(); - DownloadItem* addDownload(const QString &srcUrl, const QString &destUrl); - + DownloadItem* addDownload(KIO::CopyJob *job); + DownloadItem* addKGetDownload(const QString &srcUrl, const QString &destUrl); + Q_SIGNALS: void newDownloadAdded(QObject *item); void notifyDownload(const QString&, Rekonq::Notify = Rekonq::Download); diff --git a/src/newtabpage.cpp b/src/newtabpage.cpp index 8d5e5780..f74e5cf1 100644 --- a/src/newtabpage.cpp +++ b/src/newtabpage.cpp @@ -600,7 +600,7 @@ void NewTabPage::downloadsPage(const QString & filter) Q_FOREACH(DownloadItem * item, list) { - KUrl u = KUrl(item->destinationUrl()); + KUrl u = item->destUrl(); QString fName = u.fileName(); QString srcUrl = item->originUrl(); @@ -634,31 +634,54 @@ void NewTabPage::downloadsPage(const QString & filter) div.appendInside(QL1S("")); div.appendInside(QL1S("
")); - if (QFile::exists(file)) + switch (item->state()) { - div.appendInside(markup(QL1S("a"))); - div.lastChild().setAttribute(QL1S("class"), QL1S("greylink")); - div.lastChild().setAttribute(QL1S("href"), QL1S("about:downloads/opendir?q=") + QL1S("file://") + dir); - div.lastChild().setPlainText(i18n("Open directory")); + case DownloadItem::KGetManaged: + div.appendInside(QL1S("") + i18n("This download is managed by KGet. Check it to grab information about its state") + QL1S("")); + break; + + case DownloadItem::Suspended: + div.appendInside(QL1S("") + i18n("Suspended") + QL1S("")); + break; + + case DownloadItem::Downloading: + div.appendInside(QL1S("") + i18n("Downloading now...") + QL1S("")); + break; + + case DownloadItem::Errors: + div.appendInside(QL1S("") + i18nc("%1 = Error description", "Error: %1", item->errorString()) + QL1S("")); + break; + + case DownloadItem::Done: + default: + if (QFile::exists(file)) + { + div.appendInside(markup(QL1S("a"))); + div.lastChild().setAttribute(QL1S("class"), QL1S("greylink")); + div.lastChild().setAttribute(QL1S("href"), QL1S("about:downloads/opendir?q=") + QL1S("file://") + dir); + div.lastChild().setPlainText(i18n("Open directory")); + + div.appendInside(QL1S(" - ")); + + div.appendInside(markup(QL1S("a"))); + div.lastChild().setAttribute(QL1S("class"), QL1S("greylink")); + div.lastChild().setAttribute(QL1S("href"), QL1S("file://") + file); + div.lastChild().setPlainText(i18n("Open file")); + } + else + { + div.appendInside(QL1S("") + QL1S("Removed") + QL1S("")); + } div.appendInside(QL1S(" - ")); - + div.appendInside(markup(QL1S("a"))); div.lastChild().setAttribute(QL1S("class"), QL1S("greylink")); - div.lastChild().setAttribute(QL1S("href"), QL1S("file://") + file); - div.lastChild().setPlainText(i18n("Open file")); + div.lastChild().setAttribute(QL1S("href"), QL1S("about:downloads/removeItem?item=") + QString::number(i)); + div.lastChild().setPlainText(i18n("Remove from list")); + + break; } - else - { - div.appendInside(QL1S("") + QL1S("Removed") + QL1S("")); - } - - div.appendInside(QL1S(" - ")); - - div.appendInside(markup(QL1S("a"))); - div.lastChild().setAttribute(QL1S("class"), QL1S("greylink")); - div.lastChild().setAttribute(QL1S("href"), QL1S("about:downloads/removeItem?item=") + QString::number(i)); - div.lastChild().setPlainText(i18n("Remove from list")); i++; } -- cgit v1.2.1