summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/application.cpp19
-rw-r--r--src/application.h22
-rw-r--r--src/download.cpp184
-rw-r--r--src/download.h76
-rw-r--r--src/mainwindow.cpp10
-rw-r--r--src/rekonq.kcfg3
-rw-r--r--src/settings_general.ui7
-rw-r--r--src/webview.cpp4
8 files changed, 265 insertions, 60 deletions
diff --git a/src/application.cpp b/src/application.cpp
index 65f6e8a8..3399dde4 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -50,7 +50,7 @@
HistoryManager *Application::s_historyManager = 0;
NetworkAccessManager *Application::s_networkAccessManager = 0;
-
+DownloadManager *Application::s_downloadManager = 0;
Application::Application()
: KUniqueApplication()
@@ -67,6 +67,7 @@ Application::Application()
Application::~Application()
{
+ delete s_downloadManager;
delete s_networkAccessManager;
delete s_historyManager;
}
@@ -117,12 +118,6 @@ void Application::postLaunch()
}
-void Application::downloadUrl(const KUrl &srcUrl, const KUrl &destUrl)
-{
- new Download(srcUrl, destUrl);
-}
-
-
void Application::openUrl(const KUrl &url)
{
mainWindow()->loadUrl(url);
@@ -169,6 +164,16 @@ HistoryManager *Application::historyManager()
}
+DownloadManager *Application::downloadManager()
+{
+ if (!s_downloadManager)
+ {
+ s_downloadManager = new DownloadManager();
+ }
+ return s_downloadManager;
+}
+
+
KIcon Application::icon(const KUrl &url) const
{
KIcon icon = KIcon(QWebSettings::iconForUrl(url));
diff --git a/src/application.h b/src/application.h
index 654d554f..8393e184 100644
--- a/src/application.h
+++ b/src/application.h
@@ -19,8 +19,12 @@
-#ifndef REKONQ_APPLICATION_H
-#define REKONQ_APPLICATION_H
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+
+// Local Includes
+#include "download.h"
// KDE Includes
#include <KUniqueApplication>
@@ -31,12 +35,14 @@
#include <kio/job.h>
#include <kio/jobclasses.h>
+
// Forward Declarations
class MainWindow;
class WebView;
-class CookieJar;
class HistoryManager;
+class CookieJar;
class NetworkAccessManager;
+class DownloadManager;
/**
*
@@ -56,15 +62,10 @@ public:
KIcon icon(const KUrl &url) const;
- /**
- * This method lets you to download a file from a source remote url
- * to a local destination url.
- */
- void downloadUrl(const KUrl &srcUrl, const KUrl &destUrl);
-
static HistoryManager *historyManager();
static CookieJar *cookieJar();
static NetworkAccessManager *networkAccessManager();
+ static DownloadManager *downloadManager();
private slots:
@@ -77,9 +78,10 @@ private slots:
private:
static HistoryManager *s_historyManager;
static NetworkAccessManager *s_networkAccessManager;
+ static DownloadManager *s_downloadManager;
MainWindow* m_mainWindow;
};
-#endif // REKONQ_APPLICATION_H
+#endif // APPLICATION_H
diff --git a/src/download.cpp b/src/download.cpp
index 9de8dd36..dba7f98f 100644
--- a/src/download.cpp
+++ b/src/download.cpp
@@ -18,26 +18,165 @@
*
* ============================================================ */
+
// local Includes
#include "download.h"
#include "download.moc"
// KDE Includes
#include <KDebug>
+#include <KFileDialog>
+#include <KGlobalSettings>
+#include <KMessageBox>
+#include <KMimeType>
+#include <KStandardDirs>
// Qt Includes
#include <QFile>
#include <QFileInfo>
+// Local Includes
+#include "application.h"
+#include "mainwindow.h"
+
+
+DownloadManager::DownloadManager()
+ : QObject()
+{
+}
+
+
+DownloadManager::~DownloadManager()
+{
+ foreach(Download *download, m_downloads)
+ {
+ // cancel all unfinished downloads
+ download->cancel();
+ delete download;
+ }
+}
+
+
+void DownloadManager::newDownload(const KUrl &srcUrl, const KUrl &destUrl)
+{
+ KUrl destination = destUrl;
+ Download::DownloadType type;
+
+ KSharedPtr<KMimeType> mimeType = KMimeType::findByPath(srcUrl.prettyUrl());
+
+ QString typeText = KMimeType::extractKnownExtension(srcUrl.fileName());
+ typeText += " (" + mimeType->name() + ")";
+
+ int answer = KMessageBox::questionYesNoCancel( NULL,
+ i18n("Download '%1'?\n""Type: %2", srcUrl.prettyUrl(), typeText ),
+ i18n("Download '%1'...", srcUrl.fileName() ),
+ KStandardGuiItem::save(),
+ KStandardGuiItem::open(),
+ KStandardGuiItem::cancel(),
+ "showOpenSaveDownloadDialog"
+ );
+
+ switch(answer)
+ {
+ case KMessageBox::Cancel:
+ return;
+ break;
+
+ case KMessageBox::Yes: // ----- SAVE
+ // if destination is empty than ask for download path (if showOpenSaveDownloadDialog setting enabled)
+ if (destination.isEmpty())
+ {
+ destination = downloadDestination(srcUrl.fileName());
+ }
+ type = Download::Save;
+ break;
+
+ case KMessageBox::No: // ----- OPEN
+ // Download file to tmp dir
+ destination.setDirectory(KStandardDirs::locateLocal("tmp", "", true));
+ destination.addPath(srcUrl.fileName());
+ type = Download::Open;
+ break;
+
+ default:
+ // impossible
+ break;
+ };
+
+ // if user canceled download than abort
+ if (destination.isEmpty())
+ return;
+
+ Download *download = new Download(srcUrl, destination, type);
+ connect(download, SIGNAL(downloadFinished(int)), this, SLOT(slotDownloadFinished(int)));
+ m_downloads.append(download);
+}
+
-Download::Download(const KUrl &srcUrl, const KUrl &destUrl)
+const QList<Download *> &DownloadManager::downloads() const
+{
+ return m_downloads;
+};
+
+
+KUrl DownloadManager::downloadDestination(const QString &filename)
+{
+ KUrl destination = ReKonfig::downloadDir();
+ if (destination.isEmpty())
+ destination = KGlobalSettings::downloadPath();
+ destination.addPath(filename);
+
+ if (!ReKonfig::downloadToDefaultDir())
+ {
+ destination = KFileDialog::getSaveUrl(destination);
+ // if user canceled the download return empty url
+ if (destination.isEmpty())
+ return KUrl();
+ }
+ return destination;
+}
+
+
+void DownloadManager::slotDownloadFinished(int errorCode)
+{
+ Q_UNUSED(errorCode)
+
+ // if sender exists and list contains it - (open and) delete it
+ Download *download = qobject_cast<Download *>(sender());
+ if (download && m_downloads.contains(download))
+ {
+ if (download->type() == Download::Open)
+ {
+ KSharedPtr<KMimeType> mimeType = KMimeType::findByPath(download->destUrl().prettyUrl());
+ KRun::runUrl(download->destUrl(), mimeType->name(), NULL, true);
+ }
+ disconnect(download, SIGNAL(downloadFinished(int)), this, SLOT(slotDownloadFinished(int)));
+ int index = m_downloads.indexOf(download);
+ delete m_downloads.takeAt(index);
+ return;
+ }
+ kWarning() << "Could not find download or invalid sender. Sender:" << sender();
+}
+
+
+//----
+
+#include <KJob>
+#include <KIO/Job>
+#include <KIO/CopyJob>
+
+
+Download::Download(const KUrl &srcUrl, const KUrl &destUrl, DownloadType type)
: QObject()
, m_srcUrl(srcUrl)
, m_destUrl(destUrl)
+ , m_type(type)
{
- kWarning() << "DownloadFile: " << m_srcUrl.url() << " to dest: " << m_destUrl.url();
- m_copyJob = KIO::get(m_srcUrl);
- connect(m_copyJob, SIGNAL(data(KIO::Job*, const QByteArray &)), SLOT(slotData(KIO::Job*, const QByteArray&)));
+ Q_ASSERT(!m_srcUrl.isEmpty());
+ Q_ASSERT(!m_destUrl.isEmpty());
+ kDebug() << "DownloadFile: " << m_srcUrl.url() << " to dest: " << m_destUrl.url();
+
+ m_copyJob = KIO::file_copy(m_srcUrl, m_destUrl);
connect(m_copyJob, SIGNAL(result(KJob *)), SLOT(slotResult(KJob *)));
}
@@ -47,45 +186,38 @@ Download::~Download()
}
-void Download::slotData(KIO::Job *job, const QByteArray& data)
+void Download::cancel()
{
- Q_UNUSED(job);
- m_data.append(data);
+ bool result = m_copyJob->kill(KJob::EmitResult);
+ Q_ASSERT(result);
}
-void Download::slotResult(KJob * job)
+void Download::slotResult(KJob *job)
{
switch (job->error())
{
- case 0://The download has finished
+ case 0: //The download has finished
{
- kDebug(5001) << "Downloading successfully finished: " << m_destUrl.url();
- QFile destFile(m_destUrl.path());
- int n = 1;
- QString fn = destFile.fileName();
- while (destFile.exists())
- {
- destFile.setFileName(fn + "." + QString::number(n));
- n++;
- }
- if (destFile.open(QIODevice::WriteOnly | QIODevice::Text))
- {
- destFile.write(m_data);
- destFile.close();
- }
- m_data = 0;
+ kDebug() << "Downloading successfully finished: " << m_destUrl.url();
break;
}
case KIO::ERR_FILE_ALREADY_EXIST:
{
kWarning() << "ERROR - File already exists";
- m_data = 0;
+ break;
+ }
+ case KIO::ERR_USER_CANCELED:
+ {
+ kWarning() << "ERROR - User canceled the downlaod";
break;
}
default:
kWarning() << "We are sorry to say you, that there were errors while downloading :(";
- m_data = 0;
break;
}
+
+ // inform the world
+ emit downloadFinished(job->error());
}
+
diff --git a/src/download.h b/src/download.h
index 001c90f3..7b7a5bbf 100644
--- a/src/download.h
+++ b/src/download.h
@@ -18,57 +18,113 @@
*
* ============================================================ */
+
#ifndef DOWNLOAD_H
#define DOWNLOAD_H
+// Auto Includes
+#include "rekonq.h"
+
// KDE Includes
-#include <KUrl>
-#include <kio/job.h>
+#include <KIO/FileCopyJob>
// Qt Includes
#include <QObject>
-#include <QByteArray>
+
+// Forward Declarations
+class KJob;
+
+namespace KIO
+{
+ class Job;
+}
+
/**
* This class lets rekonq to download an object from the network.
* Creating a new object, you can continue downloading a file also
* when rekonq is closed.
*
- * @author Lukas Appelhans <l.appelhans@gmx.de>
- * @author Andrea Diamantini <adjam7@gmail.com>
- *
*/
class Download : public QObject
{
Q_OBJECT
+
public:
+ enum DownloadType { Save, Open };
+
/**
* Class constructor. This is the unique method we need to
* use this class. In fact Download class needs to know just
* "where" catch the file to download and where it has to put it
*
* @param srcUrl the source url
- *
* @param destUrl the destination url
*
*/
- Download(const KUrl &srcUrl, const KUrl &destUrl);
+ Download(const KUrl &srcUrl, const KUrl &destUrl, DownloadType type);
/**
* class destructor
*/
~Download();
+ KUrl srcUrl() const { return m_srcUrl; }
+ KUrl destUrl() const { return m_destUrl; }
+ DownloadType type() const { return m_type; }
+ void cancel();
+
+signals:
+ void downloadFinished(int errorCode);
+
private slots:
void slotResult(KJob *job);
- void slotData(KIO::Job *job, const QByteArray& data);
private:
- KIO::TransferJob *m_copyJob;
+ KIO::FileCopyJob *m_copyJob;
KUrl m_srcUrl;
KUrl m_destUrl;
KUrl m_destFile;
QByteArray m_data;
+ DownloadType m_type;
};
+
+// ----------------------
+
+
+class DownloadManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ DownloadManager();
+ ~DownloadManager();
+
+ /**
+ * @short Creates new download job.
+ * This method lets you to download a file from a remote source url
+ * to a local destination url.
+ *
+ * @param srcUrl the source url
+ * @param destUrl the destination url (default value is your default download destination setting)
+ *
+ */
+ void newDownload(const KUrl &srcUrl, const KUrl &destUrl = KUrl());
+
+ const QList<Download *> &downloads() const;
+
+public slots:
+ void slotDownloadFinished(int errorCode);
+
+private:
+ KUrl downloadDestination(const QString &filename);
+
+ QList<Download *> m_downloads;
+};
+
+
+//--
+
+
#endif
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 9b04cbbd..8180b1e1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -36,6 +36,7 @@
#include "webview.h"
#include "mainview.h"
#include "bookmarks.h"
+#include "download.h"
// KDE Includes
#include <KUrl>
@@ -51,6 +52,7 @@
#include <KMenu>
#include <KGlobalSettings>
#include <KPushButton>
+#include <KTemporaryFile>
// Qt Includes
@@ -428,9 +430,7 @@ void MainWindow::slotOpenLocation()
void MainWindow::slotFileSaveAs()
{
KUrl srcUrl = currentTab()->url();
- QString destPath = KFileDialog::getSaveFileName();
- KUrl destUrl = KUrl(destPath);
- Application::instance()->downloadUrl(srcUrl, destUrl);
+ Application::downloadManager()->newDownload(srcUrl);
}
@@ -492,6 +492,7 @@ void MainWindow::slotFileOpen()
}
+// TODO: Port to KDE
void MainWindow::slotFilePrintPreview()
{
if (!currentTab())
@@ -510,6 +511,7 @@ void MainWindow::slotFilePrint()
}
+// TODO: Port to KDE
void MainWindow::printRequested(QWebFrame *frame)
{
QPrinter printer;
@@ -684,8 +686,6 @@ void MainWindow::slotViewPageSource()
KRun::runUrl(url, QLatin1String("text/plain"), this, isTempFile);
}
-}
-
void MainWindow::slotHome()
{
diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg
index a7b7f848..a02f10ad 100644
--- a/src/rekonq.kcfg
+++ b/src/rekonq.kcfg
@@ -17,6 +17,9 @@
<entry name="downloadDir" type="Path">
<default>$HOME</default>
</entry>
+ <entry name="downloadToDefaultDir" type="Bool">
+ <default>false</default>
+ </entry>
<entry name="alwaysShowTabBar" type="Bool">
<default>true</default>
</entry>
diff --git a/src/settings_general.ui b/src/settings_general.ui
index 4d47ef4b..3b117854 100644
--- a/src/settings_general.ui
+++ b/src/settings_general.ui
@@ -77,6 +77,13 @@
</property>
</widget>
</item>
+ <item row="3" column="1">
+ <widget class="QCheckBox" name="kcfg_downloadToDefaultDir">
+ <property name="text">
+ <string>ask where saving downloads</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/webview.cpp b/src/webview.cpp
index 004a4642..91a5b988 100644
--- a/src/webview.cpp
+++ b/src/webview.cpp
@@ -194,7 +194,7 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply)
KUrl srcUrl = reply->url();
QString path = ReKonfig::downloadDir() + QString("/") + srcUrl.fileName();
KUrl destUrl = KUrl(path);
- Application::instance()->downloadUrl(srcUrl, destUrl);
+ Application::downloadManager()->newDownload(srcUrl);
return;
}
@@ -387,7 +387,7 @@ void WebView::downloadRequested(const QNetworkRequest &request)
KUrl srcUrl = request.url();
QString path = ReKonfig::downloadDir() + QString("/") + srcUrl.fileName();
KUrl destUrl = KUrl(path);
- Application::instance()->downloadUrl(srcUrl, destUrl);
+ Application::downloadManager()->newDownload(srcUrl);
}