From fb871ac2b4c5d20489c8d77022269b99634b5778 Mon Sep 17 00:00:00 2001
From: megabigbug <megabigbug@arrakis.(none)>
Date: Fri, 23 Apr 2010 08:25:45 +0200
Subject: refractoring on search engines

---
 src/CMakeLists.txt              |   1 +
 src/searchengine.cpp            | 166 ++++++++++++++++++++++++++++++++++++++++
 src/searchengine.h              |  60 +++++++++++++++
 src/urlbar/completionwidget.cpp |  36 +--------
 src/urlbar/completionwidget.h   |   9 +--
 src/urlbar/listitem.cpp         |  95 +++++++++--------------
 src/urlbar/listitem.h           |  14 ++--
 src/urlbar/urlresolver.cpp      |  10 +--
 src/webview.cpp                 |  37 +++------
 9 files changed, 286 insertions(+), 142 deletions(-)
 create mode 100644 src/searchengine.cpp
 create mode 100644 src/searchengine.h

(limited to 'src')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 119b7f3e..6eb9bf1a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,6 +28,7 @@ SET( rekonq_KDEINIT_SRCS
     websnap.cpp
     webview.cpp
     webtab.cpp
+    searchengine.cpp
     #----------------------------------------
     history/autosaver.cpp 
     history/historymanager.cpp
diff --git a/src/searchengine.cpp b/src/searchengine.cpp
new file mode 100644
index 00000000..65f2a4e8
--- /dev/null
+++ b/src/searchengine.cpp
@@ -0,0 +1,166 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+*
+*
+* 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/>.
+*
+* ============================================================ */
+
+//local includes
+#include "searchengine.h"
+
+//KDE includes
+#include <KConfigGroup>
+#include <KServiceTypeTrader>
+
+
+// Defines
+#define QL1S(x)  QLatin1String(x)
+
+
+QString SearchEngine::m_delimiter = "";
+
+
+QString SearchEngine::delimiter()
+{
+    if (m_delimiter=="") loadDelimiter();
+    return m_delimiter;
+}
+
+
+void SearchEngine::loadDelimiter()
+{
+    KConfig config("kuriikwsfilterrc"); //Share with konqueror
+    KConfigGroup cg = config.group("General");
+    m_delimiter = cg.readEntry("KeywordDelimiter", ":");
+}
+
+
+KService::Ptr SearchEngine::m_defaultWS;
+
+
+KService::Ptr SearchEngine::defaultWS()
+{   
+    if (!m_defaultWS) loadDefaultWS();
+    return m_defaultWS;
+}
+
+
+void SearchEngine::loadDefaultWS()
+{    
+    KConfig config("kuriikwsfilterrc"); //Share with konqueror
+    KConfigGroup cg = config.group("General");
+    QString d = cg.readEntry("DefaultSearchEngine", "google");
+    m_defaultWS = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d));
+}
+
+
+KService::Ptr SearchEngine::fromString(QString text)
+{
+    KService::List providers = KServiceTypeTrader::self()->query("SearchProvider");
+    int i = 0;
+    bool found = false;
+    KService::Ptr service;
+    while(!found && i<providers.size())
+    {
+        foreach(QString key, providers.at(i)->property("Keys").toStringList())
+        {
+            const QString searchPrefix = key + delimiter();
+            if (text.startsWith(searchPrefix))
+            {
+                service = providers.at(i);
+                found = true;
+            }
+        }
+        i++;
+    }
+    
+    return service;
+}
+
+
+QString SearchEngine::buildQuery(KService::Ptr engine, QString text)
+{   
+    QString query = engine->property("Query").toString();
+    query = query.replace("\\{@}", KUrl::toPercentEncoding(text));
+    return query;
+}
+
+
+KService::List SearchEngine::m_favorites;
+
+
+KService::List SearchEngine::favorites()
+{
+    if (m_favorites.isEmpty()) loadFavorites();
+    return m_favorites;
+}
+
+
+void SearchEngine::loadFavorites()
+{
+    KConfig config("kuriikwsfilterrc"); //Share with konqueror
+    KConfigGroup cg = config.group("General");
+    QStringList f;
+    f << "wikipedia" << "google"; //defaults
+    f = cg.readEntry("FavoriteSearchEngines", f);
+    
+    KService::List favorites;
+    KService::Ptr service;
+    foreach(QString e, f)
+    {
+        service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(e));
+        if (service) favorites << service;
+    }
+    
+    m_favorites = favorites;
+}
+
+
+KService::Ptr SearchEngine::defaultEngine()
+{
+    int n = ReKonfig::searchEngine();
+    QString engine;
+    switch(n)
+    {
+        case 0:
+            engine = QL1S("google");
+            break;
+        case 1:
+            engine = QL1S("altavista");
+            break;
+        case 2:
+            engine = QL1S("lycos");
+            break;
+        case 3:
+            engine = QL1S("wikipedia");
+            break;
+        case 4:
+            engine = QL1S("wolfram");
+            break;
+        default:
+            engine = QL1S("google");
+            break;
+    }
+    
+    return KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine));
+}
+
diff --git a/src/searchengine.h b/src/searchengine.h
new file mode 100644
index 00000000..8cb09b6d
--- /dev/null
+++ b/src/searchengine.h
@@ -0,0 +1,60 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+*
+*
+* 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 SEARCHENGINE_H
+#define SEARCHENGINE_H
+
+// Auto Includes
+#include "rekonq.h"
+
+// KDE Includes
+#include <KService>
+
+//Qt Includes
+#include <QString>
+
+class SearchEngine
+{   
+public:
+    
+    static QString delimiter();
+    static KService::Ptr defaultEngine();
+    static KService::List favorites();
+    static KService::Ptr fromString(QString text);
+    static QString buildQuery(KService::Ptr engine, QString text);
+    static KService::Ptr defaultWS();
+
+    static void loadDelimiter();
+    static void loadFavorites();
+    static void loadDefaultWS();
+    
+private:
+    static QString m_delimiter;
+    static KService::List m_favorites;
+    static KService::Ptr m_defaultWS;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/urlbar/completionwidget.cpp b/src/urlbar/completionwidget.cpp
index 8307940b..e0027a92 100644
--- a/src/urlbar/completionwidget.cpp
+++ b/src/urlbar/completionwidget.cpp
@@ -34,6 +34,7 @@
 // Local Includes
 #include "application.h"
 #include "urlresolver.h"
+#include "searchengine.h"
 
 // KDE Includes
 #include <KGlobalSettings>
@@ -48,15 +49,12 @@
 #include <QEvent>
 #include <QKeyEvent>
 
-// Defines
-#define QL1S(x)  QLatin1String(x)
-
 
 CompletionWidget::CompletionWidget(QWidget *parent)
     : QFrame(parent, Qt::ToolTip)
     , _parent(parent)
     , _currentIndex(-1)
-    , _searchEngine( defaultSearchEngine() )
+    , _searchEngine( SearchEngine::defaultEngine() )
 {
     setFrameStyle(QFrame::Panel);
     setLayoutDirection(Qt::LeftToRight);
@@ -259,8 +257,6 @@ void CompletionWidget::itemChosen(ListItem *item, Qt::MouseButton button)
 }
 
 
-
-
 void CompletionWidget::suggestUrls(const QString &text)
 {   
     QWidget *w = qobject_cast<QWidget *>(parent());
@@ -284,31 +280,3 @@ void CompletionWidget::suggestUrls(const QString &text)
 }
 
 
-QString CompletionWidget::defaultSearchEngine()
-{
-    int n = ReKonfig::searchEngine();
-    QString engine;
-    switch(n)
-    {
-    case 0:
-        engine = QL1S("google");
-        break;
-    case 1:
-        engine = QL1S("altavista");
-        break;
-    case 2:
-        engine = QL1S("lycos");
-        break;
-    case 3:
-        engine = QL1S("wikipedia");
-        break;
-    case 4:
-        engine = QL1S("wolfram");
-        break;
-    default:
-        engine = QL1S("google");
-        break;
-    }
-
-    return engine;
-}
diff --git a/src/urlbar/completionwidget.h b/src/urlbar/completionwidget.h
index e9851484..afd9b7e1 100644
--- a/src/urlbar/completionwidget.h
+++ b/src/urlbar/completionwidget.h
@@ -34,6 +34,7 @@
 
 // KDE Includes
 #include <KLineEdit>
+#include <KService>
 
 // Qt Includes
 #include <QFrame>
@@ -49,8 +50,8 @@ public:
     virtual bool eventFilter(QObject *obj, QEvent *ev);
     void setVisible(bool visible);
     
-    QString searchEngine() { return _searchEngine; };
-    void setCurrentEngine(const QString &engine) { _searchEngine = engine; };
+    KService::Ptr searchEngine() { return _searchEngine; };
+    void setCurrentEngine(KService::Ptr engine) { _searchEngine = engine; };
     
 private slots:
     void itemChosen(ListItem *item, Qt::MouseButton = Qt::LeftButton);
@@ -61,8 +62,6 @@ signals:
     void nextItemSubChoice();
     
 private:
-    QString defaultSearchEngine();
-    
     void insertSearchList(const UrlSearchList &list, const QString& text);
     void popup();
     void clear();
@@ -76,7 +75,7 @@ private:
     UrlSearchList _list;
     int _currentIndex;
 
-    QString _searchEngine;
+    KService::Ptr _searchEngine;
 };
 
 #endif // COMPLETION_WIDGET_H
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
index 8f299e4f..8671c126 100644
--- a/src/urlbar/listitem.cpp
+++ b/src/urlbar/listitem.cpp
@@ -36,13 +36,12 @@
 #include "application.h"
 #include "websnap.h"
 #include "completionwidget.h"
+#include "searchengine.h"
 
 // KDE Includes
 #include <KIcon>
-#include <KStandardDirs>
 #include <KDebug>
 #include <QActionGroup>
-#include <KConfigGroup>
 #include <KIcon>
 
 // Qt Includes
@@ -254,29 +253,37 @@ PreviewLabel::PreviewLabel(const QString &url, int width, int height, QWidget *p
 
 // ---------------------------------------------------------------
 
-
 SearchListItem::SearchListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
     : ListItem(item, parent)
     , m_text(text)
 {
-    CompletionWidget *w = qobject_cast<CompletionWidget *>(parent);
-    QString currentEngine = w->searchEngine();
-    kDebug() << currentEngine;
+    KService::Ptr currentEngine = SearchEngine::defaultEngine();
     
-    m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
-    m_titleLabel = new TextLabel( searchItemTitle(currentEngine, text), QString(), this);
-    m_engineBar = new EngineBar(text, currentEngine, parent);
+    QString query = text;
+    KService::Ptr engine = SearchEngine::fromString(text);
+    if (engine)
+    {
+        query = query.remove(0, text.indexOf(SearchEngine::delimiter())+1);
+    }
+    else
+    {
+        engine = currentEngine;
+    }
     
-    // without this it will not work :)
-    m_url = m_engineBar->url();
+    m_url = SearchEngine::buildQuery(engine, query);
+
+    m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
+    m_titleLabel = new TextLabel( searchItemTitle(engine->name(), query), QString(), this);
+    m_engineBar = new EngineBar(currentEngine, parent);
+
     
     layout()->addWidget( m_iconLabel );
     layout()->addWidget( m_titleLabel );
     layout()->addWidget( new QLabel( i18n("Engines: "), this ) );
     layout()->addWidget( m_engineBar );
     layout()->addWidget( new TypeIconLabel(item.type, this) );
-    
-    connect(m_engineBar, SIGNAL(searchEngineChanged(QString, QString)), this, SLOT(changeSearchEngine(QString, QString)));
+
+    connect(m_engineBar, SIGNAL(searchEngineChanged(KService::Ptr)), this, SLOT(changeSearchEngine(KService::Ptr)));
 }
 
 
@@ -285,13 +292,11 @@ QString SearchListItem::searchItemTitle(QString engine, QString text)
     return QString(i18nc("%1=search engine, e.g. Google, Wikipedia %2=text to search for", "Search %1 for <b>%2</b>", engine, text));
 }
 
-
-void SearchListItem::changeSearchEngine(QString url, QString engine)
+void SearchListItem::changeSearchEngine(KService::Ptr engine)
 {
-    m_titleLabel->setText(searchItemTitle(engine,m_text));
-    m_iconLabel->setPixmap(Application::icon( KUrl(url) ).pixmap(16));
-    QString url2 = url.replace( QL1S("\\{@}"), m_text);
-    m_url = KUrl(url2);
+    m_titleLabel->setText(searchItemTitle(engine->name(),m_text));
+    m_iconLabel->setPixmap(Application::icon( KUrl(engine->property("Query").toString()) ).pixmap(16));
+    m_url = SearchEngine::buildQuery(engine, m_text);
 
     CompletionWidget *w = qobject_cast<CompletionWidget *>(parent());
     w->setCurrentEngine( engine );
@@ -307,42 +312,21 @@ void SearchListItem::nextItemSubChoice()
 // -----------------------------------------------------------------------------------------------
 
 
-EngineBar::EngineBar(const QString &text, const QString &selectedEngine, QWidget *parent)
-    : KToolBar(parent)
+EngineBar::EngineBar(KService::Ptr selectedEngine, QWidget *parent)
+: KToolBar(parent)
 {   
     setIconSize(QSize(16,16));
     setToolButtonStyle(Qt::ToolButtonIconOnly);
     
     m_engineGroup = new QActionGroup(this);
     m_engineGroup->setExclusive(true);
-    
-    KConfig config("kuriikwsfilterrc"); //Share with konqueror
-    KConfigGroup cg = config.group("General");
-    QStringList favoriteEngines;
-    favoriteEngines << "wikipedia" << "google"; //defaults
-    favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines);
-    
-    // default engine
-    CompletionWidget *w = qobject_cast<CompletionWidget *>(parent);
-    QString defaultEngine = w->searchEngine();
-    KService::Ptr service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(defaultEngine));
-    
-    m_engineGroup->addAction(newEngineAction(service, selectedEngine));
-    
-    // set url;
-    QString url = service->property("Query").toString();
-    url = url.replace("\\{@}",text);
-    m_url = KUrl(url);
-    
-    Q_FOREACH(const QString &engine, favoriteEngines)
+
+    m_engineGroup->addAction(newEngineAction(SearchEngine::defaultEngine(), selectedEngine));    
+    foreach(KService::Ptr engine, SearchEngine::favorites())
     {
-        if(!engine.isEmpty())
+        if(engine->desktopEntryName()!=SearchEngine::defaultEngine()->desktopEntryName())
         {
-            service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine));
-            if(service && service->desktopEntryName() != defaultEngine)
-            {
-                m_engineGroup->addAction(newEngineAction(service, selectedEngine));
-            }
+            m_engineGroup->addAction(newEngineAction(engine, selectedEngine));
         }
     }
     
@@ -350,18 +334,14 @@ EngineBar::EngineBar(const QString &text, const QString &selectedEngine, QWidget
 }
 
 
-KAction *EngineBar::newEngineAction(KService::Ptr service, QString selectedEngine)
+KAction *EngineBar::newEngineAction(KService::Ptr engine, KService::Ptr selectedEngine)
 {
-    KAction *a = new KAction(Application::icon(m_url), service->name(), this);
+    QString url = engine->property("Query").toString();
+    KAction *a = new KAction(Application::icon(url), engine->name(), this);
     a->setCheckable(true);
-    if (service->name()==selectedEngine) 
-        a->setChecked(true);
-    
-    QString url = service->property("Query").toString();
-    
-    a->setData( QStringList() << url << service->desktopEntryName() );
+    if (engine->desktopEntryName()==selectedEngine->desktopEntryName()) a->setChecked(true);
+    a->setData(engine->entryPath());
     connect(a, SIGNAL(triggered(bool)), this, SLOT(changeSearchEngine()));
-
     return a;
 }
 
@@ -369,8 +349,7 @@ KAction *EngineBar::newEngineAction(KService::Ptr service, QString selectedEngin
 void EngineBar::changeSearchEngine()
 {
     KAction *a = qobject_cast<KAction*>(sender());
-    QStringList list = a->data().toStringList();    
-    emit searchEngineChanged(list.first(), list.last());
+    emit searchEngineChanged(KService::serviceByDesktopPath(a->data().toString()));
 }
 
 
diff --git a/src/urlbar/listitem.h b/src/urlbar/listitem.h
index de42fd03..c15ef3f9 100644
--- a/src/urlbar/listitem.h
+++ b/src/urlbar/listitem.h
@@ -126,22 +126,18 @@ class EngineBar : public KToolBar
     Q_OBJECT
     
 public:
-    EngineBar(const QString &text, const QString &selectedEngine, QWidget *parent = 0);
-    
+    EngineBar(KService::Ptr selectedEngine, QWidget *parent = 0);
     void selectNextEngine();
-    KUrl url() { return m_url; };
     
 signals:
-    void searchEngineChanged(QString url, QString engine);
+    void searchEngineChanged(KService::Ptr engine);
 
 private slots:
     void changeSearchEngine();
 
 private:
-    KAction *newEngineAction(KService::Ptr service, QString selectedEngine);
-
+    KAction *newEngineAction(KService::Ptr engine, KService::Ptr selectedEngine);
     QActionGroup *m_engineGroup;
-    KUrl m_url;
 };
 
 
@@ -159,7 +155,7 @@ public slots:
     virtual void nextItemSubChoice();
     
 private slots:
-    void changeSearchEngine(QString url, QString engine);
+    void changeSearchEngine(KService::Ptr engine);
     
 private:
     QString searchItemTitle(QString engine, QString text);
@@ -167,8 +163,8 @@ private:
     TextLabel* m_titleLabel;
     IconLabel* m_iconLabel;
     EngineBar* m_engineBar;
-    
     QString m_text;
+    KService::Ptr m_currentEngine;
 };
 
 
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
index e4a45105..362484a6 100644
--- a/src/urlbar/urlresolver.cpp
+++ b/src/urlbar/urlresolver.cpp
@@ -184,15 +184,7 @@ UrlSearchList UrlResolver::qurlFromUserInputResolution()
 // STEP 2 = Web Searches
 UrlSearchList UrlResolver::webSearchesResolution()
 {
-    UrlSearchList list;
-
-    if(KUrl(_typedString).isRelative())
-    {        
-        UrlSearchItem gItem(UrlSearchItem::Search, KUrl(), QString() );    // others will find this url..
-        list << gItem;
-    }
-
-    return list;
+    return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, KUrl(), QString());
 }
 
 
diff --git a/src/webview.cpp b/src/webview.cpp
index f48afffb..78fd2eaa 100644
--- a/src/webview.cpp
+++ b/src/webview.cpp
@@ -37,6 +37,7 @@
 #include "mainview.h"
 #include "webpage.h"
 #include "bookmarksmanager.h"
+#include "searchengine.h"
 
 // KDE Includes
 #include <KService>
@@ -162,31 +163,13 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
     {
         KActionMenu *searchMenu = new KActionMenu(KIcon("edit-find"), i18n("Search with"), this);
 
-        KConfig config("kuriikwsfilterrc"); //Share with konqueror
-        KConfigGroup cg = config.group("General");
-        QStringList favoriteEngines;
-        favoriteEngines << "wikipedia" << "google"; //defaults
-        favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines);
-        QString keywordDelimiter = cg.readEntry("KeywordDelimiter", ":");
-        KService::Ptr service;
-        KUriFilterData data;
-
-        Q_FOREACH(const QString &engine, favoriteEngines)
+        foreach(KService::Ptr engine, SearchEngine::favorites())
         {
-            if(!engine.isEmpty())
-            {
-                service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine));
-                if(service)
-                {
-                    const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + keywordDelimiter;
-                    data.setData(searchProviderPrefix + "some keyword");
-                    a = new KAction(service->name(), this);
-                    a->setIcon( Application::icon( data.uri() ) );
-                    a->setData(searchProviderPrefix);
-                    connect(a, SIGNAL(triggered(bool)), this, SLOT(search()));
-                    searchMenu->addAction(a);
-                }
-            }
+             a = new KAction(engine->name(), this);
+             a->setIcon( Application::icon( SearchEngine::buildQuery(engine,"")) );
+             a->setData(engine->entryPath());
+             connect(a, SIGNAL(triggered(bool)), this, SLOT(search()));
+             searchMenu->addAction(a);
         }
 
         if (!searchMenu->menu()->isEmpty())
@@ -401,9 +384,9 @@ QPoint WebView::mousePos()
 void WebView::search()
 {
     KAction *a = qobject_cast<KAction*>(sender());
-    QString search = a->data().toString() + selectedText();
-    KUrl urlSearch = KUrl::fromEncoded(search.toUtf8());
-    
+    KService::Ptr engine = KService::serviceByDesktopPath(a->data().toString());
+    KUrl urlSearch = KUrl(SearchEngine::buildQuery(engine, selectedText()));
+
     emit loadUrl(urlSearch, Rekonq::NewCurrentTab);
 }
 
-- 
cgit v1.2.1