diff options
Diffstat (limited to 'frontends/gtk/search.c')
-rw-r--r-- | frontends/gtk/search.c | 418 |
1 files changed, 265 insertions, 153 deletions
diff --git a/frontends/gtk/search.c b/frontends/gtk/search.c index 298309679..f9a509f6e 100644 --- a/frontends/gtk/search.c +++ b/frontends/gtk/search.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net> + * Copyright 2019 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -17,228 +17,340 @@ */ - /** \file - * Free text search (front component) +/** + * \file + * find in page gtk frontend implementation + * + * \todo this whole thing should be named find rather than search as + * that generally means web search and is confusing. */ -#include <stdint.h> -#include <ctype.h> -#include <string.h> -#include <gdk/gdkkeysyms.h> - -#include "utils/config.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/nsurl.h" + +#include <stdlib.h> +#include <stdbool.h> +#include <gtk/gtk.h> + +#include "utils/nsoption.h" #include "netsurf/search.h" -#include "netsurf/browser_window.h" #include "desktop/search.h" -#include "desktop/searchweb.h" -#include "gtk/warn.h" #include "gtk/compat.h" -#include "gtk/search.h" -#include "gtk/scaffolding.h" +#include "gtk/toolbar_items.h" #include "gtk/window.h" +#include "gtk/search.h" + + +struct gtk_search { + GtkToolbar *bar; + GtkEntry *entry; + GtkToolButton *back; + GtkToolButton *forward; + GtkToolButton *close; + GtkCheckButton *checkAll; + GtkCheckButton *caseSens; + + struct browser_window *bw; +}; /** * activate search forwards button in gui. * * \param active activate/inactivate - * \param gw The gui window in which to activite the search button in. + * \param search the gtk search context */ -static void nsgtk_search_set_forward_state(bool active, struct gui_window *gw) +static void nsgtk_search_set_forward_state(bool active, struct gtk_search *search) { - if (gw != NULL && nsgtk_get_browser_window(gw) != NULL) { - struct nsgtk_scaffolding *g = nsgtk_get_scaffold(gw); - gtk_widget_set_sensitive( - GTK_WIDGET(nsgtk_scaffolding_search(g)->buttons[1]), - active); - } + gtk_widget_set_sensitive(GTK_WIDGET(search->forward), active); } + /** * activate search back button in gui. * * \param active activate/inactivate - * \param gw The gui window in which to activite the search button in. + * \param search the gtk search context */ -static void nsgtk_search_set_back_state(bool active, struct gui_window *gw) +static void nsgtk_search_set_back_state(bool active, struct gtk_search *search) { - if (gw != NULL && nsgtk_get_browser_window(gw) != NULL) { - struct nsgtk_scaffolding *g = nsgtk_get_scaffold(gw); - gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_search( - g)->buttons[0]), active); - } + gtk_widget_set_sensitive(GTK_WIDGET(search->back), active); } -/** connected to the search forward button */ -gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data) +/** + * connected to the search forward button + */ +static gboolean +nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - struct gui_window *gw = nsgtk_scaffolding_top_level(g); - struct browser_window *bw = nsgtk_get_browser_window(gw); - - assert(bw); - - search_flags_t flags = SEARCH_FLAG_FORWARDS | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->caseSens)) ? - SEARCH_FLAG_CASE_SENSITIVE : 0) | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->checkAll)) ? - SEARCH_FLAG_SHOWALL : 0); - - browser_window_search(bw, gw, flags, - gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); + struct gtk_search *search; + search_flags_t flags; + + search = (struct gtk_search *)data; + + flags = SEARCH_FLAG_FORWARDS; + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->caseSens))) { + flags |= SEARCH_FLAG_CASE_SENSITIVE; + } + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->checkAll))) { + flags |= SEARCH_FLAG_SHOWALL; + } + + browser_window_search(search->bw, search, flags, + gtk_entry_get_text(search->entry)); + return TRUE; } -/** connected to the search back button */ - -gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data) +/** + * connected to the search back button + */ +static gboolean +nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - struct gui_window *gw = nsgtk_scaffolding_top_level(g); - struct browser_window *bw = nsgtk_get_browser_window(gw); - - assert(bw); - - search_flags_t flags = 0 |(gtk_toggle_button_get_active( - GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->caseSens)) ? - SEARCH_FLAG_CASE_SENSITIVE : 0) | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->checkAll)) ? - SEARCH_FLAG_SHOWALL : 0); - - browser_window_search(bw, gw, flags, - gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); + struct gtk_search *search; + search_flags_t flags; + + search = (struct gtk_search *)data; + + flags = 0; + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->caseSens))) { + flags |= SEARCH_FLAG_CASE_SENSITIVE; + } + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->checkAll))) { + flags |= SEARCH_FLAG_SHOWALL; + } + + browser_window_search(search->bw, search, flags, + gtk_entry_get_text(search->entry)); + return TRUE; } -/** connected to the search close button */ - -gboolean nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data) +/** + * connected to the search close button + */ +static gboolean +nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - nsgtk_scaffolding_toggle_search_bar_visibility(g); - return TRUE; + struct gtk_search *search; + + search = (struct gtk_search *)data; + + nsgtk_search_toggle_visibility(search); + + return TRUE; } -/** connected to the search entry [typing] */ -gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data) +/** + * connected to the search entry [typing] + */ +static gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - struct gui_window *gw = nsgtk_scaffolding_top_level(g); - struct browser_window *bw = nsgtk_get_browser_window(gw); + struct gtk_search *search; search_flags_t flags; - assert(bw != NULL); + search = (struct gtk_search *)data; + + flags = 0; - nsgtk_search_set_forward_state(true, gw); - nsgtk_search_set_back_state(true, gw); + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->caseSens))) { + flags |= SEARCH_FLAG_CASE_SENSITIVE; + } + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->checkAll))) { + flags |= SEARCH_FLAG_SHOWALL; + } - flags = SEARCH_FLAG_FORWARDS | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->caseSens)) ? - SEARCH_FLAG_CASE_SENSITIVE : 0) | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->checkAll)) ? - SEARCH_FLAG_SHOWALL : 0); + browser_window_search(search->bw, search, flags, + gtk_entry_get_text(search->entry)); - browser_window_search(bw, gw, flags, - gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } -/** connected to the search entry [return key] */ - -gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data) +/** + * connected to the search entry [return key] + */ +static gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - struct gui_window *gw = nsgtk_scaffolding_top_level(g); - struct browser_window *bw = nsgtk_get_browser_window(gw); + struct gtk_search *search; search_flags_t flags; - assert(bw); + search = (struct gtk_search *)data; - flags = SEARCH_FLAG_FORWARDS | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->caseSens)) ? - SEARCH_FLAG_CASE_SENSITIVE : 0) | - (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( - nsgtk_scaffolding_search(g)->checkAll)) ? - SEARCH_FLAG_SHOWALL : 0); + flags = SEARCH_FLAG_FORWARDS; + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->caseSens))) { + flags |= SEARCH_FLAG_CASE_SENSITIVE; + } + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search->checkAll))) { + flags |= SEARCH_FLAG_SHOWALL; + } + + browser_window_search(search->bw, search, flags, + gtk_entry_get_text(search->entry)); - browser_window_search(bw, gw, flags, - gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return FALSE; } -/** allows escape key to close search bar too */ - -gboolean +/** + * allows escape key to close search bar too + */ +static gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_KEY(Escape)) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - nsgtk_scaffolding_toggle_search_bar_visibility(g); + struct gtk_search *search; + search = (struct gtk_search *)data; + + nsgtk_search_toggle_visibility(search); } return FALSE; } -/** connected to the websearch entry [return key] */ -gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data) +static struct gui_search_table search_table = { + .forward_state = (void *)nsgtk_search_set_forward_state, + .back_state = (void *)nsgtk_search_set_back_state, +}; + +struct gui_search_table *nsgtk_search_table = &search_table; + + +/* exported interface documented in gtk/scaffolding.h */ +nserror nsgtk_search_toggle_visibility(struct gtk_search *search) { - struct nsgtk_scaffolding *g = data; - nserror ret; - nsurl *url; - - ret = search_web_omni( - gtk_entry_get_text(GTK_ENTRY(nsgtk_scaffolding_websearch(g))), - SEARCH_WEB_OMNI_SEARCHONLY, - &url); - if (ret == NSERROR_OK) { - temp_open_background = 0; - ret = browser_window_create( - BW_CREATE_HISTORY | BW_CREATE_TAB, - url, - NULL, - nsgtk_get_browser_window(nsgtk_scaffolding_top_level(g)), - NULL); - temp_open_background = -1; - nsurl_unref(url); - } - if (ret != NSERROR_OK) { - nsgtk_warning(messages_get_errorcode(ret), 0); + gboolean vis; + + browser_window_search_clear(search->bw); + + g_object_get(G_OBJECT(search->bar), "visible", &vis, NULL); + if (vis) { + gtk_widget_hide(GTK_WIDGET(search->bar)); + } else { + gtk_widget_show(GTK_WIDGET(search->bar)); + gtk_widget_grab_focus(GTK_WIDGET(search->entry)); + nsgtk_search_entry_changed(GTK_WIDGET(search->entry), search); } - return TRUE; + return NSERROR_OK; } -/** - * allows a click in the websearch entry field to clear the name of the - * provider - */ -gboolean nsgtk_websearch_clear(GtkWidget *widget, GdkEventFocus *f, - gpointer data) +/* exported interface documented in gtk/search.h */ +nserror nsgtk_search_restyle(struct gtk_search *search) { - struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; - gtk_editable_select_region(GTK_EDITABLE( - nsgtk_scaffolding_websearch(g)), 0, -1); - gtk_widget_grab_focus(GTK_WIDGET(nsgtk_scaffolding_websearch(g))); - return TRUE; + switch (nsoption_int(button_type)) { + + case 1: /* Small icons */ + gtk_toolbar_set_style(GTK_TOOLBAR(search->bar), + GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(search->bar), + GTK_ICON_SIZE_SMALL_TOOLBAR); + break; + + case 2: /* Large icons */ + gtk_toolbar_set_style(GTK_TOOLBAR(search->bar), + GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(search->bar), + GTK_ICON_SIZE_LARGE_TOOLBAR); + break; + + case 3: /* Large icons with text */ + gtk_toolbar_set_style(GTK_TOOLBAR(search->bar), + GTK_TOOLBAR_BOTH); + gtk_toolbar_set_icon_size(GTK_TOOLBAR(search->bar), + GTK_ICON_SIZE_LARGE_TOOLBAR); + break; + + case 4: /* Text icons only */ + gtk_toolbar_set_style(GTK_TOOLBAR(search->bar), + GTK_TOOLBAR_TEXT); + break; + + default: + break; + } + return NSERROR_OK; } +/* exported interface documented in gtk/search.h */ +nserror +nsgtk_search_create(GtkBuilder *builder, + struct browser_window *bw, + struct gtk_search **search_out) +{ + struct gtk_search *search; -static struct gui_search_table search_table = { - .forward_state = (void *)nsgtk_search_set_forward_state, - .back_state = (void *)nsgtk_search_set_back_state, -}; + search = malloc(sizeof(struct gtk_search)); + if (search == NULL) { + return NSERROR_NOMEM; + } -struct gui_search_table *nsgtk_search_table = &search_table; + search->bw = bw; + + search->bar = GTK_TOOLBAR(gtk_builder_get_object(builder, "findbar")); + search->entry = GTK_ENTRY(gtk_builder_get_object(builder, "Find")); + search->back = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, + "FindBack")); + search->forward = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, + "FindForward")); + search->close = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, + "FindClose")); + search->checkAll = GTK_CHECK_BUTTON(gtk_builder_get_object(builder, + "FindHighlightAll")); + search->caseSens = GTK_CHECK_BUTTON(gtk_builder_get_object(builder, + "FindMatchCase")); + + g_signal_connect(search->forward, + "clicked", + G_CALLBACK(nsgtk_search_forward_button_clicked), + search); + + g_signal_connect(search->back, + "clicked", + G_CALLBACK(nsgtk_search_back_button_clicked), + search); + + g_signal_connect(search->entry, + "changed", + G_CALLBACK(nsgtk_search_entry_changed), + search); + + g_signal_connect(search->entry, + "activate", + G_CALLBACK(nsgtk_search_entry_activate), + search); + + g_signal_connect(search->entry, + "key-press-event", + G_CALLBACK(nsgtk_search_entry_key), + search); + + g_signal_connect(search->close, + "clicked", + G_CALLBACK(nsgtk_search_close_button_clicked), + search); + + g_signal_connect(search->caseSens, + "toggled", + G_CALLBACK(nsgtk_search_entry_changed), + search); + + g_signal_connect(search->checkAll, + "toggled", + G_CALLBACK(nsgtk_search_entry_changed), + search); + + nsgtk_search_restyle(search); + + + *search_out = search; + + return NSERROR_OK; +} |