/* ============================================================ * * This file is a part of the rekonq project * * Copyright (C) 2008-2012 by Andrea Diamantini * Copyright (C) 2011 by Pierre Rossi * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ // Self Includes #include "downloadmanager.h" #include "downloadmanager.moc" // Auto Includes #include "rekonq.h" // KDE Includes #include #include #include #include #include #include #include #include // Qt Includes #include #include #include #include #include #include #include #include #include #include #include QWeakPointer DownloadManager::s_downloadManager; DownloadManager *DownloadManager::self() { if (s_downloadManager.isNull()) { s_downloadManager = new DownloadManager(qApp); } return s_downloadManager.data(); } // ---------------------------------------------------------------------------------------------- DownloadManager::DownloadManager(QObject *parent) : QObject(parent) , m_needToSave(false) { init(); } DownloadManager::~DownloadManager() { if (!m_needToSave) return; QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); QFile downloadFile(downloadFilePath); if (!downloadFile.open(QFile::WriteOnly)) { kDebug() << "Unable to open download file (WRITE mode).."; return; } QDataStream out(&downloadFile); Q_FOREACH(DownloadItem * item, m_downloadList) { out << item->originUrl(); out << item->destinationUrlString(); out << item->dateTime(); } downloadFile.close(); } void DownloadManager::init() { QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); QFile downloadFile(downloadFilePath); if (!downloadFile.open(QFile::ReadOnly)) { kDebug() << "Unable to open download file (READ mode).."; return; } QDataStream in(&downloadFile); while (!in.atEnd()) { QString srcUrl; in >> srcUrl; QString destUrl; in >> destUrl; QDateTime dt; in >> dt; DownloadItem *item = new DownloadItem(srcUrl, destUrl, dt, this); m_downloadList.append(item); } } DownloadItem* DownloadManager::addDownload(KIO::CopyJob *job) { 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; } bool DownloadManager::clearDownloadsHistory() { m_downloadList.clear(); QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); QFile downloadFile(downloadFilePath); return downloadFile.remove(); } void DownloadManager::downloadLinksWithKGet(const QVariant &contentList) { if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) { KToolInvocation::kdeinitExecWait("kget"); } QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main"); if (kget.isValid()) { kget.call("importLinks", contentList); } } void DownloadManager::removeDownloadItem(int index) { DownloadItem *item = m_downloadList.takeAt(index); delete item; m_needToSave = true; } // NOTE // These 2 functions have been copied from the KWebPage class to implement a local version of the downloadResponse method. // In this way, we can easily provide the extra functionality we need: // 1. KGet Integration // 2. Save downloads history bool DownloadManager::downloadResource(const KUrl &srcUrl, const KIO::MetaData &metaData, QWidget *parent, bool forceDirRequest, const QString &suggestedName, bool registerDownload) { // manage downloads with KGet if found if (ReKonfig::kgetDownload() && !KStandardDirs::findExe("kget").isNull()) { //KGet integration: if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) { KToolInvocation::kdeinitExecWait("kget"); } QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main"); if (!kget.isValid()) return false; QDBusMessage transfer = kget.call(QL1S("addTransfer"), srcUrl.prettyUrl(), QString(), true); return true; } KUrl destUrl; const QString fileName((suggestedName.isEmpty() ? srcUrl.fileName() : suggestedName)); if (forceDirRequest || ReKonfig::askDownloadPath()) { // follow bug:184202 fixes // Downloads should default to the default download directory. At the // same time when the user has been using a different directory // previously, it should be used instead. // To enable this behavior we inject the default download path into // KRecentDirs (which is internally used by KFileDialog to get the // most recently used directory of a fileclass). // If a user then uses a different directory it will replace the // downloads directory in KRecentDirs and become the new default when // trying to save a file. Also see KFileDialog, KFileWidget and // KRecentDirs documentation. // If this is the first invocation insert the defaults downloads directory. static const QString fileClass = QL1S(":download"); if (KRecentDirs::list(fileClass).count() <= 1) // Always has one entry by default. KRecentDirs::add(fileClass, KGlobalSettings::downloadPath()); const KUrl startDir(QString("kfiledialog:///download/%1").arg(fileName)); // NOTE: We used to use getSaveFileName here but it proved unable to // handle remote URLs, which we need to handle here, making the use of // getSaveUrl deliberate. destUrl = KFileDialog::getSaveUrl(startDir, QString(), parent); } else { destUrl = KUrl(ReKonfig::downloadPath().path() + QL1C('/') + fileName); } kDebug() << "DEST URL: " << destUrl; if (!destUrl.isValid()) return false; KIO::CopyJob *job = KIO::copy(srcUrl, destUrl); 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->ui()->setWindow((parent ? parent->window() : 0)); job->ui()->setAutoErrorHandlingEnabled(true); if (registerDownload) addDownload(job); return true; }