summaryrefslogtreecommitdiff
path: root/frontends/gtk/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/gtk/search.c')
-rw-r--r--frontends/gtk/search.c418
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;
+}