From f7d87a40a875d2a6a771e6beca62cb93d9a5d5d8 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Wed, 8 Apr 2015 18:40:40 +0200 Subject: [PATCH] browser-plugin: Add search support Add a search button to the toolbar, that shows a popover with a EvSearchBox. --- browser-plugin/EvBrowserPlugin.cpp | 34 ++++++++++++ browser-plugin/EvBrowserPlugin.h | 7 +++ browser-plugin/EvBrowserPluginToolbar.cpp | 68 +++++++++++++++++++++++ 3 files changed, 109 insertions(+) diff --git a/browser-plugin/EvBrowserPlugin.cpp b/browser-plugin/EvBrowserPlugin.cpp index 003e30dc..3b401585 100644 --- a/browser-plugin/EvBrowserPlugin.cpp +++ b/browser-plugin/EvBrowserPlugin.cpp @@ -479,6 +479,40 @@ void EvBrowserPlugin::setToolbarVisible(bool isVisible) gtk_widget_hide(m_toolbar); } +void EvBrowserPlugin::setSearchModeEnabled(bool enabled) +{ + ev_view_find_set_highlight_search(m_view, enabled); +} + +void EvBrowserPlugin::search(EvJobFind *job) +{ + ev_view_find_search_changed(m_view); + ev_view_find_started(m_view, job); +} + +void EvBrowserPlugin::search(SearchDirection direction) +{ + switch (direction) { + case Next: + ev_view_find_next(m_view); + break; + case Previous: + ev_view_find_previous(m_view); + break; + } +} + +void EvBrowserPlugin::clearSearch() +{ + ev_view_find_search_changed(m_view); + gtk_widget_queue_draw(GTK_WIDGET(m_view)); +} + +void EvBrowserPlugin::restartSearch() +{ + ev_view_find_restart(m_view, ev_document_model_get_page(m_model)); +} + // Scripting interface NPObject *EvBrowserPlugin::allocate(NPP instance, NPClass *) { diff --git a/browser-plugin/EvBrowserPlugin.h b/browser-plugin/EvBrowserPlugin.h index b6e16382..6a3533d8 100644 --- a/browser-plugin/EvBrowserPlugin.h +++ b/browser-plugin/EvBrowserPlugin.h @@ -75,6 +75,13 @@ class EvBrowserPlugin: public NPObject { bool canDownload() const; + void setSearchModeEnabled(bool); + void search(EvJobFind *); + enum SearchDirection { Next, Previous }; + void search(SearchDirection); + void clearSearch(); + void restartSearch(); + private: EvBrowserPlugin(NPP); virtual ~EvBrowserPlugin(); diff --git a/browser-plugin/EvBrowserPluginToolbar.cpp b/browser-plugin/EvBrowserPluginToolbar.cpp index 0e487bb7..c7e4bc32 100644 --- a/browser-plugin/EvBrowserPluginToolbar.cpp +++ b/browser-plugin/EvBrowserPluginToolbar.cpp @@ -20,6 +20,7 @@ #include "EvBrowserPluginToolbar.h" #include "ev-page-action-widget.h" +#include "ev-search-box.h" #include enum { @@ -35,6 +36,8 @@ struct _EvBrowserPluginToolbarPrivate { GtkWidget *zoomFitPageRadioButton; GtkWidget *zoomFitWidthRadioButton; GtkWidget *zoomAutomaticRadioButton; + GtkWidget *searchToggleButton; + GtkWidget *searchPopover; }; G_DEFINE_TYPE(EvBrowserPluginToolbar, ev_browser_plugin_toolbar, GTK_TYPE_TOOLBAR) @@ -102,6 +105,60 @@ static void downloadDocument(EvBrowserPluginToolbar *toolbar) toolbar->priv->plugin->download(); } +static void searchPopoverClosed(EvBrowserPluginToolbar *toolbar) +{ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->priv->searchToggleButton))) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->priv->searchToggleButton), FALSE); +} + +static void searchStarted(EvBrowserPluginToolbar *toolbar, EvJobFind *job) +{ + toolbar->priv->plugin->search(job); +} + +static void searchCleared(EvBrowserPluginToolbar *toolbar) +{ + toolbar->priv->plugin->clearSearch(); +} + +static void searchNext(EvBrowserPluginToolbar *toolbar) +{ + toolbar->priv->plugin->search(EvBrowserPlugin::SearchDirection::Next); +} + +static void searchPrevious(EvBrowserPluginToolbar *toolbar) +{ + toolbar->priv->plugin->search(EvBrowserPlugin::SearchDirection::Previous); +} + +static void toggleSearch(EvBrowserPluginToolbar *toolbar) +{ + if (!toolbar->priv->searchPopover) { + toolbar->priv->searchPopover = gtk_popover_new(toolbar->priv->searchToggleButton); + g_signal_connect_swapped(toolbar->priv->searchPopover, "closed", G_CALLBACK(searchPopoverClosed), toolbar); + GtkWidget *searchBox = ev_search_box_new(toolbar->priv->plugin->model()); + g_signal_connect_swapped(searchBox, "started", G_CALLBACK(searchStarted), toolbar); + g_signal_connect_swapped(searchBox, "cleared", G_CALLBACK(searchCleared), toolbar); + g_signal_connect_swapped(searchBox, "next", G_CALLBACK(searchNext), toolbar); + g_signal_connect_swapped(searchBox, "previous", G_CALLBACK(searchPrevious), toolbar); + gtk_container_add(GTK_CONTAINER(toolbar->priv->searchPopover), searchBox); + gtk_widget_show(searchBox); + } + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->priv->searchToggleButton))) { + gtk_widget_show(toolbar->priv->searchPopover); + toolbar->priv->plugin->setSearchModeEnabled(true); + + GtkSearchEntry *entry = ev_search_box_get_entry(EV_SEARCH_BOX(gtk_bin_get_child(GTK_BIN(toolbar->priv->searchPopover)))); + const char *searchString = gtk_entry_get_text(GTK_ENTRY(entry)); + if (searchString && searchString[0]) + toolbar->priv->plugin->restartSearch(); + } else { + gtk_widget_hide(toolbar->priv->searchPopover); + toolbar->priv->plugin->setSearchModeEnabled(false); + } +} + class SignalBlocker { public: SignalBlocker(gpointer instance, void (* closure)(EvBrowserPluginToolbar *), gpointer data) @@ -300,6 +357,17 @@ static void evBrowserPluginToolbarConstructed(GObject *object) gtk_container_add(GTK_CONTAINER(toolbar), toolItem); gtk_widget_show(toolItem); + // Search. + button = createToggleButton(toolbar, "edit-find-symbolic", _("Find a word or phrase in the document"), + false, G_CALLBACK(toggleSearch)); + toolbar->priv->searchToggleButton = button; + toolItem = GTK_WIDGET(gtk_tool_item_new()); + gtk_container_add(GTK_CONTAINER(toolItem), button); + gtk_widget_show(button); + + gtk_container_add(GTK_CONTAINER(toolbar), toolItem); + gtk_widget_show(toolItem); + // Separator toolItem = GTK_WIDGET(gtk_tool_item_new()); gtk_tool_item_set_expand(GTK_TOOL_ITEM(toolItem), TRUE);