From ca309c0701544f1cf5716ab527dc823d21a45386 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Thu, 19 Jul 2018 18:43:27 +0200 Subject: [PATCH] Implement search suggestion. --- kiwix-desktop.pro | 6 ++-- src/searchbar.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++++ src/searchbar.h | 31 +++++++++++++++++ src/topwidget.h | 4 ++- 4 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 src/searchbar.cpp create mode 100644 src/searchbar.h diff --git a/kiwix-desktop.pro b/kiwix-desktop.pro index 4d24946..446e418 100644 --- a/kiwix-desktop.pro +++ b/kiwix-desktop.pro @@ -39,7 +39,8 @@ SOURCES += \ src/requestinterceptor.cpp \ src/urlschemehandler.cpp \ src/tabwidget.cpp \ - src/webview.cpp + src/webview.cpp \ + src/searchbar.cpp HEADERS += \ src/mainwindow.h \ @@ -51,7 +52,8 @@ HEADERS += \ src/requestinterceptor.h \ src/urlschemehandler.h \ src/tabwidget.h \ - src/webview.h + src/webview.h \ + src/searchbar.h FORMS += \ ui/mainwindow.ui diff --git a/src/searchbar.cpp b/src/searchbar.cpp new file mode 100644 index 0000000..a91c269 --- /dev/null +++ b/src/searchbar.cpp @@ -0,0 +1,87 @@ +#include "searchbar.h" + +#include +#include + +#include "kiwixapp.h" + +SearchBar::SearchBar(QWidget *parent) : + QLineEdit(parent), + m_completer(&m_completionModel, this), + m_icon(":icons/search.svg") +{ + setTextMargins(37, 1, 1, 1); + setPlaceholderText("Search"); + setClearButtonEnabled(true); + m_completer.setCompletionMode(QCompleter::UnfilteredPopupCompletion); + setCompleter(&m_completer); + connect(this, &QLineEdit::textEdited, this, &SearchBar::updateCompletion); +#if 0 //The `activated` signal seems to not be emitted if user navigate in the page. + // Something is broken here .. :/ + connect(&m_completer, QOverload::of(&QCompleter::activated), + this, &SearchBar::openCompletion); +#else + connect(this, &QLineEdit::returnPressed, this, &SearchBar::openTitle); +#endif +} + +void SearchBar::paintEvent(QPaintEvent *event) +{ + QLineEdit::paintEvent(event); + QPainter painter(this); + QPixmap pxm = m_icon.pixmap(height() - 6, height() - 6); + painter.drawPixmap(3, 3, pxm); +} + +void SearchBar::updateCompletion(const QString &text) +{ + QStringList wordList; + m_urlList.clear(); + auto tabWidget = KiwixApp::instance()->getTabWidget(); + auto qurl = tabWidget->currentWidget()->url(); + m_currentHost = qurl.host(); + auto reader = KiwixApp::instance()->getLibrary()->getReader(m_currentHost); + if ( reader == nullptr) { + m_completionModel.setStringList(wordList); + return; + } + reader->searchSuggestionsSmart(text.toStdString(), 15); + std::string title, url; + while (reader->getNextSuggestion(title, url)) { + wordList << QString::fromStdString(title); + m_urlList.push_back(url); + } + m_completionModel.setStringList(wordList); +} + +void SearchBar::openTitle() +{ + QString title = text(); + clear(); + auto tabWidget = KiwixApp::instance()->getTabWidget(); + auto qurl = tabWidget->currentWidget()->url(); + auto reader = KiwixApp::instance()->getLibrary()->getReader(qurl.host()); + if ( reader == nullptr) { + return; + } + std::string url; + if (reader->getPageUrlFromTitle(title.toStdString(), url)) + { + QUrl qurl_; + qurl_.setScheme("zim"); + qurl_.setHost(qurl.host()); + qurl_.setPath("/" + QString::fromStdString(url)); + QTimer::singleShot(0, [=](){KiwixApp::instance()->openUrl(qurl_, true);}); + } +} + +void SearchBar::openCompletion(const QModelIndex &index) +{ + auto url = m_urlList.at(index.row()); + QUrl qurl; + qurl.setScheme("zim"); + qurl.setHost(m_currentHost); + qurl.setPath(QString::fromStdString(url)); + QTimer::singleShot(0, [=](){KiwixApp::instance()->openUrl(qurl, true);}); +} + diff --git a/src/searchbar.h b/src/searchbar.h new file mode 100644 index 0000000..717c870 --- /dev/null +++ b/src/searchbar.h @@ -0,0 +1,31 @@ +#ifndef SEARCHBAR_H +#define SEARCHBAR_H + +#include +#include +#include +#include + +class SearchBar : public QLineEdit +{ + Q_OBJECT +public: + SearchBar(QWidget *parent = nullptr); + +protected: + virtual void paintEvent(QPaintEvent *event); + +private: + QStringListModel m_completionModel; + QCompleter m_completer; + std::vector m_urlList; + QString m_currentHost; + QIcon m_icon; + +private slots: + void updateCompletion(const QString& text); + void openCompletion(const QModelIndex& index); + void openTitle(); +}; + +#endif // SEARCHBAR_H diff --git a/src/topwidget.h b/src/topwidget.h index 5fa3637..439d92c 100644 --- a/src/topwidget.h +++ b/src/topwidget.h @@ -5,6 +5,8 @@ #include #include +#include "searchbar.h" + class TopWidget : public QToolBar { Q_OBJECT @@ -17,7 +19,7 @@ protected: void mouseMoveEvent(QMouseEvent *event); private: - QLineEdit m_searchEntry; + SearchBar m_searchEntry; QAction* mp_historyBackAction; QAction* mp_historyForwardAction; QAction* mp_fullScreenAction;