extragear/base/konq-plugins/searchbar

View: New views
1 Messages — Rating Filter:   Alert me  

extragear/base/konq-plugins/searchbar

by Bugzilla from fyanardi@gmail.com :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

SVN commit 988313 by fyanardi:

Implemented a new feature for Konqueror searchbar plugin: suggestion engine. For now only google suggestion is available. Thanks to Germain Garand who reviewed this feature.

CCMAIL: kfm-devel@...


 M  +5 -1      CMakeLists.txt  
 A             SearchSuggestion.cpp   [License: GPL (v2+)]
 A             SearchSuggestion.h   [License: GPL (v2+)]
 A             SuggestionEngine.cpp   [License: GPL (v2+)]
 A             SuggestionEngine.h   [License: GPL (v2+)]
 A             engines (directory)  
 A             engines/GoogleSuggestionEngine.cpp   [License: GPL (v2+)]
 A             engines/GoogleSuggestionEngine.h   [License: GPL (v2+)]
 M  +115 -4    searchbar.cpp  
 M  +28 -1     searchbar.h  


--- trunk/extragear/base/konq-plugins/searchbar/CMakeLists.txt #988312:988313
@@ -4,7 +4,11 @@
 
 ########### next target ###############
 
-set(searchbarplugin_PART_SRCS searchbar.cpp )
+set(searchbarplugin_PART_SRCS
+    searchbar.cpp
+    SearchSuggestion.cpp
+    SuggestionEngine.cpp
+    engines/GoogleSuggestionEngine.cpp)
 
 kde4_add_plugin(searchbarplugin ${searchbarplugin_PART_SRCS})
 
--- trunk/extragear/base/konq-plugins/searchbar/searchbar.cpp #988312:988313
@@ -19,10 +19,13 @@
 
 #include "searchbar.h"
 
+#include "SearchSuggestion.h"
+
 #include <unistd.h>
 #include <QLineEdit>
 #include <QApplication>
 #include <kaction.h>
+#include <KCompletionBox>
 #include <kconfig.h>
 #include <ksharedconfig.h>
 #include <kdebug.h>
@@ -46,6 +49,8 @@
 #include <qstyle.h>
 #include <QPixmap>
 #include <QMouseEvent>
+#include <QtGui/QCompleter>
+#include <QtCore/QTimer>
 
 K_PLUGIN_FACTORY(SearchBarPluginFactory, registerPlugin<SearchBarPlugin>();)
 K_EXPORT_PLUGIN(SearchBarPluginFactory("searchbarplugin"))
@@ -56,7 +61,8 @@
     m_searchCombo(0),
     m_searchMode(UseSearchProvider),
     m_urlEnterLock(false),
-    m_process(0)
+    m_process(0),
+    m_searchSuggestion(new SearchSuggestion(this))
 {
     m_searchCombo = new SearchBarCombo(0);
     m_searchCombo->lineEdit()->installEventFilter(this);
@@ -73,7 +79,6 @@
     m_searchComboAction->setDefaultWidget(m_searchCombo);
     m_searchComboAction->setShortcutConfigurable(false);
 
-
     KAction *a = actionCollection()->addAction("focus_search_bar");
     a->setText(i18n("Focus Searchbar"));
     a->setShortcut(Qt::CTRL+Qt::Key_S);
@@ -83,6 +88,12 @@
 
     // parent is the KonqMainWindow and we want to listen to PartActivateEvent events.
     parent->installEventFilter(this);
+    connect(m_searchCombo->lineEdit(), SIGNAL(textEdited(const QString &)), SLOT(searchTextChanged(const QString &)));
+    connect(m_searchSuggestion, SIGNAL(suggestionReceived(const QStringList &)),
+            SLOT(addSearchSuggestion(const QStringList &)));
+    m_timer = new QTimer(this);
+    m_timer->setSingleShot(true);
+    connect(m_timer, SIGNAL(timeout()), SLOT(requestSuggestion()));
 }
 
 SearchBarPlugin::~SearchBarPlugin()
@@ -409,8 +420,33 @@
     m_searchCombo->setFocus(Qt::ShortcutFocusReason);
 }
 
+void SearchBarPlugin::searchTextChanged(const QString &text)
+{
+    m_searchCombo->clearSuggestions();
+
+    if (m_searchMode != FindInThisPage && m_searchSuggestion->isEngineAvailable(m_currentEngine) && !text.isEmpty()) {
+        if (m_timer->isActive()) {
+            m_timer->stop();
+        }
+
+        // 400 ms delay before requesting for suggestions, so we don't flood the provider with suggestion request
+        m_timer->start(400);
+    }
+}
+
+void SearchBarPlugin::requestSuggestion() {
+    if (!m_searchCombo->lineEdit()->text().isEmpty()) {
+        m_searchSuggestion->requestSuggestion(m_currentEngine, m_searchCombo->lineEdit()->text());
+    }
+}
+
+void SearchBarPlugin::addSearchSuggestion(const QStringList &suggestions)
+{
+    m_searchCombo->setSuggestionItems(suggestions);
+}
+
 SearchBarCombo::SearchBarCombo(QWidget *parent) :
-    KHistoryComboBox(parent),
+    KHistoryComboBox(true, parent),
     m_pluginActive(true)
 {
     setDuplicatesEnabled(false);
@@ -421,9 +457,11 @@
 
     KConfigGroup config(KGlobal::config(), "SearchBar");
     QStringList list = config.readEntry( "History list", QStringList() );
-    list.prepend(QString()); // empty item
     setHistoryItems(list, true);
     Q_ASSERT(currentText().isEmpty()); // KHistoryComboBox calls clearEditText
+
+    // use our own item delegate to display our fancy stuff :D
+    completionBox()->setItemDelegate(new SearchBarItemDelegate(this));
 }
 
 const QPixmap &SearchBarCombo::icon() const
@@ -480,6 +518,36 @@
     m_pluginActive = pluginActive;
 }
 
+void SearchBarCombo::setSuggestionItems(const QStringList &suggestions)
+{
+    if (m_suggestions.count() > 0) {
+        clearSuggestions();
+    }
+
+    m_suggestions = suggestions;
+    if (suggestions.count() > 0) {
+        int size = completionBox()->count();
+        QListWidgetItem *item = new QListWidgetItem(suggestions.at(0));
+        item->setData(Qt::UserRole, "suggestion");
+        completionBox()->insertItem(size + 1, item);
+        for (int i = 1; i < suggestions.count(); i++) {
+            completionBox()->insertItem(size + 1 + i, suggestions.at(i));
+        }
+        completionBox()->popup();
+    }
+}
+
+void SearchBarCombo::clearSuggestions()
+{
+    int size = completionBox()->count();
+    if (!m_suggestions.isEmpty() && size >= m_suggestions.count()) {
+        for (int i = size - 1; i >= size - m_suggestions.size(); i--) {
+            completionBox()->takeItem(i);
+        }
+    }
+    m_suggestions.clear();
+}
+
 void SearchBarCombo::show()
 {
     if (m_pluginActive) {
@@ -493,4 +561,47 @@
     config.writeEntry( "History list", historyItems() );
 }
 
+SearchBarItemDelegate::SearchBarItemDelegate(QObject *parent)
+    : QItemDelegate(parent)
+{
+}
+
+void SearchBarItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    QString userText = index.data(Qt::UserRole).toString();
+    QString text = index.data(Qt::DisplayRole).toString();
+
+    // Get item data
+    if (!userText.isEmpty()) {
+        // This font is for the "information" text, small size + italic + gray in color
+        QFont usrTxtFont = option.font;
+        usrTxtFont.setItalic(true);
+        usrTxtFont.setPointSize(6);
+
+        QFontMetrics usrTxtFontMetrics(usrTxtFont);
+        int width = usrTxtFontMetrics.width(userText);
+        QRect rect(option.rect.x(), option.rect.y(), option.rect.width() - width, option.rect.height());
+        QFontMetrics textFontMetrics(option.font);
+        QString elidedText = textFontMetrics.elidedText(text,
+                Qt::ElideRight, option.rect.width() - width - option.decorationSize.width());
+
+        QAbstractItemModel *itemModel = const_cast<QAbstractItemModel *>(index.model());
+        itemModel->setData(index, elidedText, Qt::DisplayRole);
+        QItemDelegate::paint(painter, option, index);
+        itemModel->setData(index, text, Qt::DisplayRole);
+
+        painter->setFont(usrTxtFont);
+        painter->setPen(QPen(QColor(Qt::gray)));
+        painter->drawText(option.rect, Qt::AlignRight, userText);
+
+        // Draw a separator above this item
+        if (index.row() > 0) {
+            painter->drawLine(option.rect.x(), option.rect.y(), option.rect.x() + option.rect.width(), option.rect.y());
+        }
+    }
+    else {
+        QItemDelegate::paint(painter, option, index);
+    }
+}
+
 #include "searchbar.moc"
--- trunk/extragear/base/konq-plugins/searchbar/searchbar.h #988312:988313
@@ -31,10 +31,12 @@
 #include <qpixmap.h>
 #include <qstring.h>
 #include <KProcess>
+#include <QtGui/QItemDelegate>
 
+class SearchSuggestion;
 class KHTMLPart;
-
 class QMenu;
+class QTimer;
 /**
  * Combo box which catches mouse clicks on the pixmap.
  */
@@ -75,6 +77,10 @@
      */
     void setPluginActive(bool pluginActive);
 
+    void setSuggestionItems(const QStringList &suggestions);
+
+    void clearSuggestions();
+
 public slots:
     virtual void show();
 
@@ -97,6 +103,7 @@
 private:
     QPixmap m_icon;
     bool    m_pluginActive;
+    QStringList m_suggestions;
 };
 
 /**
@@ -156,6 +163,13 @@
     void updateComboVisibility();
 
     void focusSearchbar();
+
+    void searchTextChanged(const QString &text);
+
+    void addSearchSuggestion(const QStringList &suggestion);
+
+    void requestSuggestion();
+
 private:
     void nextSearchEntry();
     void previousSearchEntry();
@@ -173,6 +187,19 @@
     QStringList            m_searchEngines;
     QChar                  m_delimiter;
     KProcess              *m_process;
+    SearchSuggestion *m_searchSuggestion;
+    QTimer *m_timer;
 };
 
+/**
+ * An item delegate for combo box completion items, to give some fancy stuff
+ * to the completion items
+ */
+class SearchBarItemDelegate : public QItemDelegate
+{
+public:
+    SearchBarItemDelegate(QObject *parent = 0);
+    virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
+};
+
 #endif // SEARCHBAR_PLUGIN