diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/application.cpp | 19 | ||||
| -rw-r--r-- | src/application.h | 22 | ||||
| -rw-r--r-- | src/download.cpp | 184 | ||||
| -rw-r--r-- | src/download.h | 76 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 10 | ||||
| -rw-r--r-- | src/rekonq.kcfg | 3 | ||||
| -rw-r--r-- | src/settings_general.ui | 7 | ||||
| -rw-r--r-- | src/webview.cpp | 4 | 
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);  }  | 
