From deab0dd37edbc4007a3c2cf32d31811aff0e7e2d Mon Sep 17 00:00:00 2001
From: Andrea Diamantini <adjam7@gmail.com>
Date: Fri, 4 Jun 2010 23:21:46 +0200
Subject: Awesome bar speed up This commit introduces notable changes and needs
 a lot of tests

Courtesy patch from Mathias Kraus. Thanks :)

BUG: 237390
---
 src/bookmarks/bookmarksmanager.cpp |  14 +-
 src/bookmarks/bookmarksmanager.h   |  19 +--
 src/history/historymanager.cpp     |  23 ++-
 src/history/historymanager.h       |  10 +-
 src/mainwindow.cpp                 |   9 +
 src/urlbar/listitem.cpp            |  16 +-
 src/urlbar/urlresolver.cpp         | 337 ++++++++++++++++++++++++++++---------
 src/urlbar/urlresolver.h           |  84 ++++++++-
 8 files changed, 388 insertions(+), 124 deletions(-)

(limited to 'src')

diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp
index c430078b..93bb5386 100644
--- a/src/bookmarks/bookmarksmanager.cpp
+++ b/src/bookmarks/bookmarksmanager.cpp
@@ -203,7 +203,8 @@ QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark)
     }
     else
     {
-        Application::bookmarkProvider()->completionObject()->addItem(bookmark.url().url());
+        UrlSearchItem urlSearchItem(UrlSearchItem::Bookmark, bookmark.url().prettyUrl() , bookmark.fullText(), QDateTime(), 1, bookmark.description(), QString());
+        Application::bookmarkProvider()->completionObject()->addItem(urlSearchItem);
         return  new KBookmarkAction(bookmark, owner(), this);
     }
 }
@@ -222,7 +223,6 @@ void BookmarkMenu::refill()
         addAddBookmarksList();
         addNewFolder();
         addEditBookmarks();
-
     }
     else
     {
@@ -270,8 +270,9 @@ BookmarkProvider::BookmarkProvider(QObject *parent)
         , m_bookmarkMenu(0)
         , m_completion(0)
 {
+    kDebug() << "Loading Bookmarks Manager...";
     // take care of the completion object
-    m_completion = new KCompletion;
+    m_completion = new AwesomeUrlCompletion;
     m_completion->setOrder(KCompletion::Weighted);
 
     KUrl bookfile = KUrl("~/.kde/share/apps/konqueror/bookmarks.xml");  // share konqueror bookmarks
@@ -299,6 +300,8 @@ BookmarkProvider::BookmarkProvider(QObject *parent)
     // setup menu
     m_owner = new BookmarkOwner(this);
     connect(m_owner, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), this, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)));
+
+    kDebug() << "Loading Bookmarks Manager... DONE!";
 }
 
 
@@ -346,6 +349,7 @@ void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString
             fillBookmarkBar(bookmarkToolBar);
         }
     }
+    //TODO: also change completion object
 }
 
 
@@ -379,7 +383,9 @@ void BookmarkProvider::contextMenu(const QPoint &point)
 KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent)
 {
     KMenu *menu = new KMenu(parent);
+    kDebug() << "new Bookmarks Menu...";
     m_bookmarkMenu = new BookmarkMenu(m_manager, m_owner, menu, m_actionCollection);
+    kDebug() << "new Bookmarks Menu...DONE";
     KActionMenu *bookmarkActionMenu = new KActionMenu(parent);
     bookmarkActionMenu->setMenu(menu);
     bookmarkActionMenu->setText(i18n("&Bookmarks"));
@@ -425,7 +431,7 @@ KBookmarkGroup BookmarkProvider::rootGroup()
 }
 
 
-KCompletion *BookmarkProvider::completionObject() const
+AwesomeUrlCompletion *BookmarkProvider::completionObject() const
 {
     return m_completion;
 }
diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h
index ae12280b..dfebebd2 100644
--- a/src/bookmarks/bookmarksmanager.h
+++ b/src/bookmarks/bookmarksmanager.h
@@ -36,13 +36,13 @@
 
 // Local Includes
 #include "application.h"
+#include "urlresolver.h"
 
 // Qt Includes
 #include <QWidget>
 
 // KDE Includes
 #include <KBookmarkOwner>
-#include <KCompletion>
 
 // Forward Declarations
 class BookmarkProvider;
@@ -226,19 +226,14 @@ public:
      */
     KBookmarkGroup rootGroup();
 
-    KBookmarkManager *bookmarkManager()
-    {
-        return m_manager;
-    }
-    BookmarkOwner *bookmarkOwner()
-    {
-        return m_owner;
-    }
+    inline KBookmarkManager *bookmarkManager() { return m_manager; }
+    
+    inline BookmarkOwner *bookmarkOwner() { return m_owner; }
 
     /**
-    * @returns the KCompletion object.
+    * @returns the AwesomeUrlCompletion object.
     */
-    KCompletion *completionObject() const;
+    AwesomeUrlCompletion *completionObject() const;
 
     QString titleForBookmarkUrl(QString url);
 
@@ -278,7 +273,7 @@ private:
     KActionCollection *m_actionCollection;
     BookmarkMenu *m_bookmarkMenu;
     QList<KToolBar*> m_bookmarkToolBars;
-    KCompletion *m_completion;
+    AwesomeUrlCompletion *m_completion;
 };
 
 
diff --git a/src/history/historymanager.cpp b/src/history/historymanager.cpp
index c0f87935..d531c189 100644
--- a/src/history/historymanager.cpp
+++ b/src/history/historymanager.cpp
@@ -69,8 +69,9 @@ HistoryManager::HistoryManager(QObject *parent)
         , m_historyModel(0)
         , m_historyFilterModel(0)
         , m_historyTreeModel(0)
-        , m_completion(new KCompletion)
+        , m_completion(new AwesomeUrlCompletion)
 {
+    kDebug() << "Loading HistoryManager...";
     // take care of the completion object
     m_completion->setOrder(KCompletion::Weighted);
 
@@ -87,6 +88,7 @@ HistoryManager::HistoryManager(QObject *parent)
 
     // QWebHistoryInterface will delete the history manager
     QWebHistoryInterface::setDefaultInterface(this);
+    kDebug() << "Loading HistoryManager... DONE";
 }
 
 
@@ -131,7 +133,8 @@ void HistoryManager::addHistoryEntry(const QString &url)
     // Add item to completion object
     QString _url(url);
     _url.remove(QRegExp("^http://|/$"));
-    m_completion->addItem(_url);
+    UrlSearchItem urlSearchItem(UrlSearchItem::History, _url, QString(), item.dateTime, 1, QString(), QString());
+    m_completion->addItem(urlSearchItem);
 }
 
 
@@ -251,20 +254,21 @@ void HistoryManager::removeHistoryEntry(const HistoryItem &item)
 
 void HistoryManager::removeHistoryEntry(const KUrl &url, const QString &title)
 {
+    HistoryItem item;
     for (int i = 0; i < m_history.count(); ++i)
     {
         if (url == m_history.at(i).url
                 && (title.isEmpty() || title == m_history.at(i).title))
         {
-            removeHistoryEntry(m_history.at(i));
+            item = m_history.at(i);
+            removeHistoryEntry(item);
             break;
         }
     }
 
     // Remove item from completion object
-    QString _url = url.path();
-    _url.remove(QRegExp("^http://|/$"));
-    m_completion->removeItem(_url);
+    UrlSearchItem urlSearchItem(UrlSearchItem::History, item.url, item.title, item.dateTime, 0, QString(), QString());
+    m_completion->removeItem(urlSearchItem);
 }
 
 
@@ -367,9 +371,10 @@ void HistoryManager::load()
         lastInsertedItem = item;
 
         // Add item to completion object
-        QString _url = item.url;
+        //QString _url = item.url;
         //_url.remove(QRegExp("^http://|/$"));
-        m_completion->addItem(_url);
+        UrlSearchItem urlSearchItem(UrlSearchItem::History, item.url, item.title, item.dateTime, 1, QString(), QString());
+        m_completion->addItem(urlSearchItem);
     }
     if (needToSort)
         qSort(list.begin(), list.end());
@@ -453,7 +458,7 @@ void HistoryManager::save()
 }
 
 
-KCompletion * HistoryManager::completionObject() const
+AwesomeUrlCompletion * HistoryManager::completionObject() const
 {
     return m_completion;
 }
diff --git a/src/history/historymanager.h b/src/history/historymanager.h
index 0f131782..7b82579d 100644
--- a/src/history/historymanager.h
+++ b/src/history/historymanager.h
@@ -32,6 +32,7 @@
 
 // Rekonq Includes
 #include "rekonq_defines.h"
+#include "urlresolver.h"
 
 // KDE Includes
 #include <KUrl>
@@ -113,9 +114,6 @@ class HistoryModel;
 class HistoryFilterModel;
 class HistoryTreeModel;
 
-class KCompletion;
-
-
 /**
  * THE History Manager:
  * It manages rekonq history
@@ -155,9 +153,9 @@ public:
     HistoryTreeModel *historyTreeModel() const;
 
     /**
-    * @returns the KCompletion object.
+    * @returns the AwesomeUrlCompletion object.
     */
-    KCompletion *completionObject() const;
+    AwesomeUrlCompletion *completionObject() const;
 
     void addDownload(const QString &srcUrl, const QString &destUrl);
     DownloadList downloads();
@@ -189,7 +187,7 @@ private:
     HistoryTreeModel *m_historyTreeModel;
 
     // the completion object we sync with
-    KCompletion *m_completion;
+    AwesomeUrlCompletion *m_completion;
 };
 
 
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index dc1dc708..805f3d45 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -109,6 +109,7 @@ MainWindow::MainWindow()
         , m_hidePopup(new QTimer(this))
         , m_ac(new KActionCollection(this))
 {
+    kDebug() << "MainWindow ctor...";
     // enable window size "auto-save"
     setAutoSaveSettings();
 
@@ -152,6 +153,8 @@ MainWindow::MainWindow()
     connect(m_hidePopup, SIGNAL(timeout()), m_popup, SLOT(hide()));
 
     QTimer::singleShot(0, this, SLOT(postLaunch()));
+
+    kDebug() << "MainWindow ctor...DONE";
 }
 
 
@@ -185,6 +188,8 @@ MainWindow::~MainWindow()
 
 void MainWindow::setupToolbars()
 {
+    kDebug() << "setup toolbars...";
+    
     // ============ Main ToolBar  ================================
     m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Back)));
     m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Forward)));
@@ -267,6 +272,8 @@ QSize MainWindow::sizeHint() const
 
 void MainWindow::setupActions()
 {
+    kDebug() << "setup actions...";
+    
     // this let shortcuts work..
     actionCollection()->addAssociatedWidget(this);
 
@@ -454,6 +461,7 @@ void MainWindow::setupActions()
 
 void MainWindow::setupTools()
 {
+    kDebug() << "setup tools...";
     KActionMenu *toolsMenu = new KActionMenu(KIcon("configure"), i18n("&Tools"), this);
     toolsMenu->setDelayed(false);
 
@@ -531,6 +539,7 @@ void MainWindow::setupTools()
 
 void MainWindow::setupPanels()
 {
+    kDebug() << "setup panels...";
     KAction* a;
 
     // STEP 1
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
index a8878418..c0d163c9 100644
--- a/src/urlbar/listitem.cpp
+++ b/src/urlbar/listitem.cpp
@@ -212,8 +212,8 @@ PreviewListItem::PreviewListItem(const UrlSearchItem &item, const QString &text,
 
     QLabel *previewLabelIcon = new QLabel(this);
     previewLabelIcon->setFixedSize(45, 33);
-    new PreviewLabel(item.url.url(), 38, 29, previewLabelIcon);
-    IconLabel* icon = new IconLabel(item.url.url(), previewLabelIcon);
+    new PreviewLabel(item.url, 38, 29, previewLabelIcon);
+    IconLabel* icon = new IconLabel(item.url, previewLabelIcon);
     icon->move(27, 16);
     hLayout->addWidget(previewLabelIcon);
 
@@ -223,13 +223,13 @@ PreviewListItem::PreviewListItem(const UrlSearchItem &item, const QString &text,
     QString title = item.title;
     if (title.isEmpty())
     {
-        title = item.url.url();
+        title = item.url;
         title = title.remove("http://");
-	title.truncate(title.indexOf("/"));
+        title.truncate(title.indexOf("/"));
     }
 
     vLayout->addWidget(new TextLabel(title, text, this));
-    vLayout->addWidget(new TextLabel("<i>" + item.url.url() + "</i>", text, this));
+    vLayout->addWidget(new TextLabel("<i>" + item.url + "</i>", text, this));
 
     hLayout->addLayout(vLayout);
 
@@ -278,7 +278,7 @@ SearchListItem::SearchListItem(const UrlSearchItem &item, const QString &text, Q
 
     m_url = SearchEngine::buildQuery(engine, query);
 
-    m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
+    m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon (will be easy in KDE SC 4.5)
     m_titleLabel = new TextLabel(searchItemTitle(engine->name(), query), QString(), this);
     m_engineBar = new EngineBar(engine, parent);
 
@@ -397,8 +397,8 @@ BrowseListItem::BrowseListItem(const UrlSearchItem &item, const QString &text, Q
     QHBoxLayout *hLayout = new QHBoxLayout;
     hLayout->setSpacing(4);
 
-    hLayout->addWidget(new IconLabel(item.url.url(), this));
-    hLayout->addWidget(new TextLabel(item.url.url(), text, this));
+    hLayout->addWidget(new IconLabel(item.url, this));
+    hLayout->addWidget(new TextLabel(item.url, text, this));
     hLayout->addWidget(new TypeIconLabel(item.type, this));
 
     setLayout(hLayout);
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
index 7333e305..7131766b 100644
--- a/src/urlbar/urlresolver.cpp
+++ b/src/urlbar/urlresolver.cpp
@@ -43,7 +43,7 @@
 #include <QByteArray>
 
 // defines
-#define MAX_ELEMENTS 9
+#define MAX_ELEMENTS 10
 
 
 // NOTE 
@@ -55,12 +55,6 @@
 // 5. "fixhosturifilter"
 
 
-bool UrlSearchItem::operator==(const UrlSearchItem &i) const
-{
-    return url == i.url;
-}
-
-
 // ------------------------------------------------------------------------
 
 
@@ -99,27 +93,31 @@ UrlResolver::UrlResolver(const QString &typedUrl)
 
 UrlSearchList UrlResolver::orderedSearchItems()
 {
-    // NOTE: the logic here is : "we wanna suggest (at least) 9 elements"
-    // so we have (more or less) 3 from first results (1 from QUrl Resolutions, 2 from
-    // default search engines).
-    // There are 6 remaining: if bookmarkResults + historyResults <= 6, catch all, else
-    // catch first 3 results from the two resulting lists :)
-
+    // NOTE 
+    // the logic here is : "we wanna suggest (at least) 10 elements"
+    // so we have (more or less) 2 from first results (1 from QUrl Resolutions, 1 from
+    // search engines).
+    // There are 8 remaining: if bookmarkResults + historyResults <= 8, catch all, else
+    // catch first 4 results from the two resulting lists :)
+
+    QTime myTime;
+    myTime.start();
+    
     UrlSearchList list;
 
     if( _typedString == QL1S("about:") )
     {
-        UrlSearchItem home(UrlSearchItem::Browse, KUrl("about:home"),       QL1S("home") );
+        UrlSearchItem home(UrlSearchItem::Browse, QString("about:home"),       QL1S("home") );
         list << home;
-        UrlSearchItem favs(UrlSearchItem::Browse, KUrl("about:favorites"),  QL1S("favorites") );
+        UrlSearchItem favs(UrlSearchItem::Browse, QString("about:favorites"),  QL1S("favorites") );
         list << favs;
-        UrlSearchItem clos(UrlSearchItem::Browse, KUrl("about:closedTabs"), QL1S("closed tabs") );
+        UrlSearchItem clos(UrlSearchItem::Browse, QString("about:closedTabs"), QL1S("closed tabs") );
         list << clos;
-        UrlSearchItem book(UrlSearchItem::Browse, KUrl("about:bookmarks"),  QL1S("bookmarks") );
+        UrlSearchItem book(UrlSearchItem::Browse, QString("about:bookmarks"),  QL1S("bookmarks") );
         list << book;
-        UrlSearchItem hist(UrlSearchItem::Browse, KUrl("about:history"),    QL1S("history") );
+        UrlSearchItem hist(UrlSearchItem::Browse, QString("about:history"),    QL1S("history") );
         list << hist;
-        UrlSearchItem down(UrlSearchItem::Browse, KUrl("about:downloads"),  QL1S("downloads") );
+        UrlSearchItem down(UrlSearchItem::Browse, QString("about:downloads"),  QL1S("downloads") );
         list << down;
 
         return list;
@@ -136,59 +134,135 @@ UrlSearchList UrlResolver::orderedSearchItems()
         list << qurlFromUserInputResolution();
     }
 
-    
-    int firstResults = list.count();
-    int checkPoint = 9 - firstResults;
-
+    //find the history items that match the typed string
     UrlSearchList historyList = historyResolution();
     UrlSearchItem privileged = privilegedItem(&historyList);
     int historyResults = historyList.count();
     
-    UrlSearchList bookmarksList = bookmarksResolution(); 
+    //find the bookmarks items that match the typed string
+    UrlSearchList bookmarksList = bookmarksResolution();
     if (privileged.type == UrlSearchItem::Undefined)
     {
         privileged = privilegedItem(&bookmarksList);
     }
-    
-    if (privileged.type != UrlSearchItem::Undefined)
+    else if(privileged.type == UrlSearchItem::History && bookmarksList.removeOne(privileged))
     {
-        list.insert(0,privileged);
+        privileged.type |= UrlSearchItem::Bookmark;
     }
-
     int bookmarksResults = bookmarksList.count();
-
-    if (historyResults + bookmarksResults > checkPoint)
+    
+    if (privileged.type != UrlSearchItem::Undefined)
     {
-        historyList = historyList.mid(0, 3);
-        bookmarksList = bookmarksList.mid(0, 3);
+        list.prepend(privileged);
     }
-
-    QList<UrlSearchItem> common;
-
-    foreach(UrlSearchItem i, historyList)
+    
+    int availableEntries = MAX_ELEMENTS - list.count();
+    
+    UrlSearchList commonList;
+    int commonResutls = 0;
+    
+    //prefer items which are history items als well bookmarks item
+    //if there are more than 1000 bookmark results, the performance impact is noticeable
+    if(bookmarksResults < 1000)
     {
-        if (!bookmarksList.contains(i))
+        //add as many items to the common list as there are available entries in the dropdown list
+        UrlSearchItem urlSearchItem;
+        for(int i = 0; i < historyList.count(); i++)
         {
-            list << i;
+            if (bookmarksList.removeOne(historyList.at(i)))
+            {
+                urlSearchItem = historyList.takeAt(i);
+                urlSearchItem.type |= UrlSearchItem::Bookmark;
+                commonList << urlSearchItem;
+                commonResutls++;
+                if(commonResutls >= availableEntries)
+                {
+                    break;
+                }
+            }
         }
-        else
+        
+        commonResutls = commonList.count();
+        if(commonResutls >= availableEntries)
+        {
+            commonList = commonList.mid(0, availableEntries);
+            historyList = UrlSearchList();
+            bookmarksList = UrlSearchList();
+            availableEntries = 0;
+        }
+        else        //remove all items from the history and bookmarks list up to the remaining entries in the dropdown list
         {
-            i.type |= UrlSearchItem::Bookmark;
-            common << i;
+            availableEntries -= commonResutls;
+            if(historyResults >= availableEntries)
+            {
+                historyList = historyList.mid(0, availableEntries);
+            }
+            if(bookmarksResults >= availableEntries)
+            {
+                bookmarksList = bookmarksList.mid(0, availableEntries);
+            }
         }
     }
-
-    foreach(const UrlSearchItem &i, common)
+    else        //if there are too many bookmarks items, remove all items up to the remaining entries in the dropdown list
     {
-        list << i;
-    }
+        
+        if(historyResults >= availableEntries)
+        {
+            historyList = historyList.mid(0, availableEntries);
+        }
+        if(bookmarksResults >= availableEntries)
+        {
+            bookmarksList = bookmarksList.mid(0, availableEntries);
+        }
 
-    foreach(const UrlSearchItem &i, bookmarksList)
+        UrlSearchItem urlSearchItem;
+        for(int i = 0; i < historyList.count(); i++)
+        {
+            if (bookmarksList.removeOne(historyList.at(i)))
+            {
+                urlSearchItem = historyList.takeAt(i);
+                urlSearchItem.type |= UrlSearchItem::Bookmark;
+                commonList << urlSearchItem;
+            }
+        }
+        
+        availableEntries -= commonList.count();
+    }
+    
+    historyResults = historyList.count();
+    bookmarksResults = bookmarksList.count();
+    commonResutls = commonList.count();
+    
+    //now fill the list to MAX_ELEMENTS
+    if(availableEntries > 0)
     {
-        if (!common.contains(i))
-            list << i;
+        int historyEntries = ((int) (availableEntries / 2)) + availableEntries % 2;
+        int bookmarksEntries = availableEntries - historyEntries;
+        
+        if (historyResults >= historyEntries && bookmarksResults >= bookmarksEntries)
+        {
+            historyList = historyList.mid(0, historyEntries);
+            bookmarksList = bookmarksList.mid(0, bookmarksEntries);
+        }
+        else if (historyResults < historyEntries && bookmarksResults >= bookmarksEntries)
+        {
+            if(historyResults + bookmarksResults > availableEntries)
+            {
+                bookmarksList = bookmarksList.mid(0, availableEntries - historyResults);
+            }
+        }
+        else if (historyResults >= historyEntries && bookmarksResults < bookmarksEntries)
+        {
+            if(historyResults + bookmarksResults > availableEntries)
+            {
+                historyList = historyList.mid(0, availableEntries - bookmarksResults);
+            }
+        }
     }
-
+    
+    list = list + historyList + commonList + bookmarksList;
+    qWarning() << "orderedSearchItems leave: " << " elapsed: " << myTime.elapsed();
+    
     return list;
 }
 
@@ -206,7 +280,7 @@ UrlSearchList UrlResolver::qurlFromUserInputResolution()
     if (urlFromUserInput.isValid())
     {
         QString gTitle = i18nc("Browse a website", "Browse");
-        UrlSearchItem gItem(UrlSearchItem::Browse, urlFromUserInput, gTitle);
+        UrlSearchItem gItem(UrlSearchItem::Browse, urlFromUserInput.toString(), gTitle);
         list << gItem;
     }
 
@@ -217,57 +291,166 @@ UrlSearchList UrlResolver::qurlFromUserInputResolution()
 // STEP 2 = Web Searches
 UrlSearchList UrlResolver::webSearchesResolution()
 {
-    return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, KUrl(), QString());
+    return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, QString(), QString());
 }
 
 
 // STEP 3 = history completion
 UrlSearchList UrlResolver::historyResolution()
 {
-    UrlSearchList list;
+    AwesomeUrlCompletion *historyCompletion = Application::historyManager()->completionObject();
+    return historyCompletion->substringCompletion(_typedString);
+}
+
+
+// STEP 4 = bookmarks completion
+UrlSearchList UrlResolver::bookmarksResolution()
+{
+    AwesomeUrlCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject();
+    return bookmarkCompletion->substringCompletion(_typedString);
+}
+
+
+UrlSearchItem UrlResolver::privilegedItem(UrlSearchList* list)
+{
+    UrlSearchItem item;
+    QString dot;
+    if(!_typedString.endsWith(QL1C('.')))
+    {
+        dot = QString(QL1C('.'));
+    }
+    
+    for(int i = 0; i<list->count(); i++)
+    {
+        item = list->at(i);
+        //kDebug() << item.url.host();
+        //TODO: move this to AwesomeUrlCompletion::substringCompletion and add a priviledged flag to UrlSearchItem
+        if (item.url.contains(_typedString + dot))
+        {
+            list->removeAt(i);
+            return item;
+        }
+    }
+    return UrlSearchItem();
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+
+AwesomeUrlCompletion::AwesomeUrlCompletion()
+{
+    m_resetCompletion = true;
+}
+
+
+AwesomeUrlCompletion::~AwesomeUrlCompletion()
+{
+
+}
+
 
-    KCompletion *historyCompletion = Application::historyManager()->completionObject();
-    QStringList historyResults = historyCompletion->substringCompletion(_typedString);
-    Q_FOREACH(const QString &s, historyResults)
+void AwesomeUrlCompletion::addItem(const UrlSearchItem& itemToAdd)
+{
+    bool match = false;
+    QTime myTime;
+    myTime.start();
+    for(int i = 0; i < m_items.count(); i++)
     {
-        UrlSearchItem it(UrlSearchItem::History, KUrl(s), Application::historyManager()->titleForHistoryUrl(s));
-        list << it;
+        //check if item is already in list; the items are equal if the url and the title are equal
+        if(m_items[i] == itemToAdd)
+        {
+            match = true;
+            //TODO: check what to do if comment or bookmarkPath are different
+            if(m_items[i] < itemToAdd)
+            {
+                m_items[i].visitDateTime = itemToAdd.visitDateTime;
+            }
+            m_items[i].visitCount += itemToAdd.visitCount;
+        }
     }
+    if(!match)
+    {
+        m_items.append(itemToAdd);
+    }
+    m_resetCompletion = true;
+}
 
-    return list;
+
+void AwesomeUrlCompletion::removeItem(const UrlSearchItem& item)
+{
+    m_resetCompletion = m_items.removeOne(item);
 }
 
 
-// STEP 4 = bookmarks completion
-UrlSearchList UrlResolver::bookmarksResolution()
+void AwesomeUrlCompletion::setOrder(KCompletion::CompOrder)
 {
-    UrlSearchList list;
+    //TODO
+}
 
-    KCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject();
-    QStringList bookmarkResults = bookmarkCompletion->substringCompletion(_typedString);
-    Q_FOREACH(const QString &s, bookmarkResults)
+
+void AwesomeUrlCompletion::updateTitle(const UrlSearchItem& item, const QString& newTitle)
+{
+    foreach(UrlSearchItem i, m_items)
     {
-        UrlSearchItem it(UrlSearchItem::Bookmark, KUrl(s), Application::bookmarkProvider()->titleForBookmarkUrl(s));
-        list << it;
+        if(i == item)
+        {
+            i.title = newTitle;
+        }
     }
+    m_resetCompletion = true;
+}
 
-    return list;
+
+void AwesomeUrlCompletion::clear()
+{
+    m_items.clear();
+    m_resetCompletion = true;
 }
 
 
-UrlSearchItem UrlResolver::privilegedItem(UrlSearchList* list)
+UrlSearchList AwesomeUrlCompletion::substringCompletion(const QString& completionString)
 {
-    int i=0;
-    while(i<list->count())
+    UrlSearchList* searchList;
+    UrlSearchList tempList;
+    
+    if(!m_resetCompletion)
     {
-        UrlSearchItem item = list->at(i);
-        kDebug() << item.url.host();
-        if (item.url.host().contains( _typedString + QL1C('.') ) )
+        if(completionString.length() <= 1)
         {
-            list->removeAt(i);
-            return item;
+            m_resetCompletion = true;
+        }
+        if(!m_resetCompletion && completionString.length() < m_lastCompletionString.length())
+        {
+            m_resetCompletion = true;
+        }
+        if(!m_resetCompletion && !completionString.startsWith(m_lastCompletionString, Qt::CaseInsensitive))
+        {
+            m_resetCompletion = true;
         }
-        i++;
     }
-    return UrlSearchItem();
+    
+    if(m_resetCompletion)
+    {
+        searchList = &m_items;
+        m_resetCompletion = false;
+    }
+    else
+    {
+        searchList = &m_filteredItems;
+    }
+    
+    Q_FOREACH(const UrlSearchItem &i, *searchList)
+    {
+        //TODO: split string and also search for each word if the are more than one word separated with space
+        if(    i.url.contains(completionString, Qt::CaseInsensitive) 
+            || i.title.contains(completionString, Qt::CaseInsensitive) 
+            || i.description.contains(completionString, Qt::CaseInsensitive)
+          )
+        {
+            tempList.append(i);
+        }
+    }
+    m_lastCompletionString = completionString;
+    m_filteredItems = tempList;
+    return m_filteredItems;
 }
diff --git a/src/urlbar/urlresolver.h b/src/urlbar/urlresolver.h
index 2249ea32..83228140 100644
--- a/src/urlbar/urlresolver.h
+++ b/src/urlbar/urlresolver.h
@@ -33,11 +33,14 @@
 
 // KDE Includes
 #include <KUrl>
+#include <KCompletion>
 
 // Qt Includes
 #include <QString>
 #include <QList>
+#include <QDateTime>
 
+class AwesomeUrlCompletion;
 
 class UrlSearchItem
 {
@@ -53,22 +56,62 @@ public:
     };
 
     int type;
-    KUrl url;
+    QString url;
     QString title;
+    QDateTime visitDateTime;
+    int visitCount;
+    QString description;
+    QString bookmarkPath;
     
-    UrlSearchItem(const UrlSearchItem &item)
-    : type(item.type), url(item.url), title(item.title)
+    UrlSearchItem(const UrlSearchItem &item) : type(item.type),
+                                               url(item.url),
+                                               title(item.title),
+                                               visitDateTime(item.visitDateTime),
+                                               visitCount(item.visitCount),
+                                               description(item.description),
+                                               bookmarkPath(item.bookmarkPath)
     {};
     
-    UrlSearchItem()
-    : type(UrlSearchItem::Undefined), url(KUrl()), title("")
+    UrlSearchItem() : type(UrlSearchItem::Undefined),
+                      url(QString()),
+                      title(QString()),
+                      visitDateTime(QDateTime()),
+                      visitCount(0),
+                      description(QString()),
+                      bookmarkPath(QString())
     {};
     
-    UrlSearchItem(const int &_type, const KUrl &_url, const QString &_title = QString())
-            : type(_type), url(_url), title(_title)
+    UrlSearchItem(const int &_type,
+                  const QString &_url,
+                  const QString &_title = QString(),
+                  const QDateTime &visitDateTime  = QDateTime(),
+                  const int       &visitCount     = 0,
+                  const QString   &description    = QString(),
+                  const QString   &bookmarkPath   = QString()
+                  )
+                  : type(_type),
+                  url(_url),
+                  title(_title),
+                  visitDateTime(visitDateTime),
+                  visitCount(visitCount),
+                  description(description),
+                  bookmarkPath(bookmarkPath)
     {};
 
-    bool operator==(const UrlSearchItem &i) const;
+    inline bool operator==(const UrlSearchItem &i) const
+    {
+        return i.url == url;//TODO && i.title == title;
+    }
+    
+    inline bool operator <(const UrlSearchItem &i) const
+    {
+        return visitDateTime < i.visitDateTime;
+    }
+    
+    inline bool operator >(const UrlSearchItem &i) const
+    {
+        return visitDateTime > i.visitDateTime;
+    }
 };
 
 typedef QList <UrlSearchItem> UrlSearchList;
@@ -96,4 +139,29 @@ private:
     static QRegExp _browseRegexp;
 };
 
+// ------------------------------------------------------------------------------
+
+
+/**
+ * This class represents all searchable item for the awesomebar.
+ */
+class AwesomeUrlCompletion// : public KCompletion
+{
+public:
+    AwesomeUrlCompletion();
+    ~AwesomeUrlCompletion();
+    void addItem(const UrlSearchItem& item);
+    void removeItem(const UrlSearchItem& item);
+    void setOrder(KCompletion::CompOrder);
+    void updateTitle(const UrlSearchItem& item, const QString& newTitle);
+    void clear();
+    UrlSearchList substringCompletion(const QString& completionString);
+    
+private:
+    UrlSearchList m_items;
+    UrlSearchList m_filteredItems;
+    bool m_resetCompletion;
+    QString m_lastCompletionString;
+};
+
 #endif // URL_RESOLVER_H
-- 
cgit v1.2.1