From 3bbfba5e0757af9c02dc5cec637e51b67365a896 Mon Sep 17 00:00:00 2001
From: Andrea Diamantini <adjam7@gmail.com>
Date: Tue, 26 Jan 2010 02:09:05 +0100
Subject: MultiThreaded rekonq !! Yeah, you're reading well... rekonq is using
 multithreading for the loadUrl slot. This (in theory) should mean: "NO MORE
 UI FREEZES ON LOAD URLS"

:D
---
 src/CMakeLists.txt   |   2 +
 src/application.cpp  | 132 ++++++++++++++++++++++++++++++---------------------
 src/application.h    |   7 ++-
 src/filterurljob.cpp |  67 ++++++++++++++++++++++++++
 src/filterurljob.h   |  61 ++++++++++++++++++++++++
 src/webtab.cpp       |   2 +-
 6 files changed, 214 insertions(+), 57 deletions(-)
 create mode 100644 src/filterurljob.cpp
 create mode 100644 src/filterurljob.h

(limited to 'src')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7a77c25c..b0a3fbd8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -24,6 +24,7 @@ SET( rekonq_KDEINIT_SRCS
     webinspectorpanel.cpp
     walletbar.cpp
     protocolhandler.cpp
+    filterurljob.cpp
     #----------------------------------------
     history/autosaver.cpp 
     history/historymanager.cpp
@@ -93,6 +94,7 @@ TARGET_LINK_LIBRARIES ( kdeinit_rekonq
                         ${KDE4_KDEUI_LIBS}
                         ${KDE4_KIO_LIBS}
                         ${KDE4_KPARTS_LIBS}
+                        ${KDE4_THREADWEAVER_LIBRARIES}
 )
 
 
diff --git a/src/application.cpp b/src/application.cpp
index e93e5b8e..e9f0561d 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -43,6 +43,7 @@
 #include "sessionmanager.h"
 #include "adblockmanager.h"
 #include "webview.h"
+#include "filterurljob.h"
 
 // KDE Includes
 #include <KCmdLineArgs>
@@ -54,6 +55,7 @@
 #include <KMessageBox>
 #include <KWindowInfo>
 #include <KUrl>
+#include <ThreadWeaver/Weaver>
 
 // Qt Includes
 #include <QRegExp>
@@ -71,6 +73,8 @@ QPointer<AdBlockManager> Application::s_adblockManager;
 Application::Application()
     : KUniqueApplication()
 {
+    connect(Weaver::instance(), SIGNAL( jobDone(ThreadWeaver::Job*) ), 
+            this, SLOT( loadResolvedUrl(ThreadWeaver::Job*) ) );
 }
 
 
@@ -284,25 +288,36 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type)
         return;
     }
 
-    WebView *view = createView(type);
-   
-//     if (!ReKonfig::openTabsBack())
-//     {
-//         w->mainView()->urlBar()->setUrl(loadingUrl.prettyUrl());
-//     }
+    // first, create the webview(s) to not let hangs UI..
+    WebTab *tab = 0;
+    MainWindow *w = 0;
+    w = (type == Rekonq::NewWindow) 
+        ? newMainWindow()
+        : mainWindow();
+        
+    switch(type)
+    {
+    case Rekonq::SettingOpenTab:
+        tab = w->mainView()->newWebTab(!ReKonfig::openTabsBack(), ReKonfig::openTabsNearCurrent());
+        break;
+    case Rekonq::NewCurrentTab:
+        tab = w->mainView()->newWebTab(true);
+        break;
+    case Rekonq::NewBackTab:
+        tab = w->mainView()->newWebTab(false, ReKonfig::openTabsNearCurrent());
+        break;
+    case Rekonq::NewWindow:
+    case Rekonq::CurrentTab:
+        tab = w->mainView()->currentWebTab();
+        break;
+    };
+    
+    WebView *view = tab->view();
     
     if (view)
     {
-        loadingUrl = resolvUrl( loadingUrl.pathOrUrl() );
-
-        // we are sure of the url now, let's add it to history
-        // anyway we store here just http sites because local and ftp ones are
-        // added trough the protocol handler and the other are ignored
-        if( url.protocol() == QLatin1String("http") || url.protocol() == QLatin1String("https") )
-            historyManager()->addHistoryEntry( loadingUrl.prettyUrl() );
-        
-        view->setFocus();
-        view->load(loadingUrl);
+        FilterUrlJob *job = new FilterUrlJob(view, loadingUrl.pathOrUrl(), this);
+        Weaver::instance()->enqueue(job);
     }
 }
 
@@ -348,45 +363,54 @@ AdBlockManager *Application::adblockManager()
 }
 
 
-WebView *Application::createView(const Rekonq::OpenType &type)
+// WebView *Application::createView(const Rekonq::OpenType &type)
+// {
+//     // first, create the webview(s) to not let hangs UI..
+//     WebTab *tab = 0;
+//     MainWindow *w = 0;
+//     w = (type == Rekonq::NewWindow) 
+//         ? newMainWindow()
+//         : mainWindow();
+//         
+//     switch(type)
+//     {
+//     case Rekonq::SettingOpenTab:
+//         tab = w->mainView()->newWebTab(!ReKonfig::openTabsBack(), ReKonfig::openTabsNearCurrent());
+//         break;
+//     case Rekonq::NewCurrentTab:
+//         tab = w->mainView()->newWebTab(true);
+//         break;
+//     case Rekonq::NewBackTab:
+//         tab = w->mainView()->newWebTab(false, ReKonfig::openTabsNearCurrent());
+//         break;
+//     case Rekonq::NewWindow:
+//     case Rekonq::CurrentTab:
+//         tab = w->mainView()->currentWebTab();
+//         break;
+//     };
+//     
+//     return tab->view();
+// }
+
+
+void Application::loadResolvedUrl(ThreadWeaver::Job *job)
 {
-    // first, create the webview(s) to not let hangs UI..
-    WebTab *tab = 0;
-    MainWindow *w = 0;
-    w = (type == Rekonq::NewWindow) 
-        ? newMainWindow()
-        : mainWindow();
-        
-    switch(type)
-    {
-    case Rekonq::SettingOpenTab:
-        tab = w->mainView()->newWebTab(!ReKonfig::openTabsBack(), ReKonfig::openTabsNearCurrent());
-        break;
-    case Rekonq::NewCurrentTab:
-        tab = w->mainView()->newWebTab(true);
-        break;
-    case Rekonq::NewBackTab:
-        tab = w->mainView()->newWebTab(false, ReKonfig::openTabsNearCurrent());
-        break;
-    case Rekonq::NewWindow:
-    case Rekonq::CurrentTab:
-        tab = w->mainView()->currentWebTab();
-        break;
-    };
+    FilterUrlJob *threadedJob = static_cast<FilterUrlJob *>(job);
+    KUrl url = threadedJob->url();
+    WebView *view = threadedJob->view();
     
-    return tab->view();
-}
-
-
-KUrl Application::resolvUrl(const QString &urlString)
-{
-    // this should let rekonq filtering URI info and supporting
-    // the beautiful KDE web browsing shortcuts
-    KUriFilterData data(urlString);
-    data.setCheckForExecutables(false); // if true, queries like "rekonq" or "dolphin" are considered as executables
-    KUrl url = KUriFilter::self()->filterUri(data) 
-        ? data.uri().pathOrUrl() 
-        : QUrl::fromUserInput( urlString );
+    if (view)
+    {
+        view->setFocus();
+        view->load(url);    
         
-    return url;
+        // we are sure of the url now, let's add it to history
+        // anyway we store here just http sites because local and ftp ones are
+        // added trough the protocol handler and the other are ignored
+        if( url.protocol() == QLatin1String("http") || url.protocol() == QLatin1String("https") )
+            historyManager()->addHistoryEntry( url.prettyUrl() );
+    }
+    
+    // Bye and thanks :)
+    delete threadedJob;
 }
diff --git a/src/application.h b/src/application.h
index c9fb079d..a326015d 100644
--- a/src/application.h
+++ b/src/application.h
@@ -35,6 +35,7 @@
 #include <KIcon>
 #include <kio/job.h>
 #include <kio/jobclasses.h>
+#include <ThreadWeaver/Job>
 
 // Qt Includes
 #include <QPointer>
@@ -135,11 +136,13 @@ private slots:
      */
     void postLaunch();
 
+    void loadResolvedUrl(ThreadWeaver::Job *);
+    
 private:
     
     // loadUrl Utilities
-    WebView *createView(const Rekonq::OpenType &);
-    KUrl resolvUrl(const QString &);
+//     WebView *createView(const Rekonq::OpenType &);
+//     KUrl resolvUrl(const QString &);
     
     static QPointer<HistoryManager> s_historyManager;
     static QPointer<BookmarkProvider> s_bookmarkProvider;
diff --git a/src/filterurljob.cpp b/src/filterurljob.cpp
new file mode 100644
index 00000000..00bdee36
--- /dev/null
+++ b/src/filterurljob.cpp
@@ -0,0 +1,67 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+// Self Includes
+#include "filterurljob.h"
+
+// KDE Includes
+#include <KUriFilter>
+#include <KUriFilterData>
+
+// Qt Includes
+#include <QUrl>
+
+
+FilterUrlJob::FilterUrlJob(WebView *view, const QString &urlString, QObject *parent)
+    : Job(parent)
+    , _view(view)
+    , _urlString(urlString)
+{
+}
+
+
+WebView *FilterUrlJob::view()
+{
+    return _view;
+}
+
+
+KUrl FilterUrlJob::url()
+{
+    return _url;
+}
+
+
+void FilterUrlJob::run()
+{
+    // this should let rekonq filtering URI info and supporting
+    // the beautiful KDE web browsing shortcuts
+    KUriFilterData data(_urlString);
+    data.setCheckForExecutables(false); // if true, queries like "rekonq" or "dolphin" are considered as executables
+    _url = KUriFilter::self()->filterUri(data) 
+        ? data.uri().pathOrUrl() 
+        : QUrl::fromUserInput( _urlString );
+}
diff --git a/src/filterurljob.h b/src/filterurljob.h
new file mode 100644
index 00000000..3a9511ea
--- /dev/null
+++ b/src/filterurljob.h
@@ -0,0 +1,61 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+#ifndef FILTER_URL_JOB_H
+#define FILTER_URL_JOB_H
+
+// Local Includes
+#include "webview.h"
+
+// KDE Includes
+#include <KUrl>
+#include <ThreadWeaver/Job>
+
+// Qt Includes
+#include <QString>
+
+
+using namespace ThreadWeaver;
+
+
+class FilterUrlJob : public Job
+{
+public:
+    FilterUrlJob(WebView *view, const QString &urlString, QObject *parent = 0);
+
+    WebView *view();
+    KUrl url();
+    
+protected:
+    void run();
+    
+private:
+    WebView *_view;
+    QString _urlString;
+    KUrl _url;
+};
+
+#endif // FILTER_URL_JOB_H
diff --git a/src/webtab.cpp b/src/webtab.cpp
index 3ff69a2f..b1f2cdfc 100644
--- a/src/webtab.cpp
+++ b/src/webtab.cpp
@@ -108,7 +108,7 @@ WebView *WebTab::view()
 
 WebPage *WebTab::page()
 {
-    return m_view->page();
+    return m_view->page();  // FIXME
 }
 
 
-- 
cgit v1.2.1