From 5bd7606103182a824b530a24a1f4753e04c145ec Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 23 Jun 2015 23:22:42 +0100 Subject: Update GTK url bar completion to navigate on selection --- gtk/completion.c | 140 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 30 deletions(-) (limited to 'gtk/completion.c') diff --git a/gtk/completion.c b/gtk/completion.c index a0df08ad9..1f86cc790 100644 --- a/gtk/completion.c +++ b/gtk/completion.c @@ -16,47 +16,48 @@ * along with this program. If not, see . */ +/** + * \file + * Implementation of url entry completion. + */ + #include -#include "gtk/completion.h" #include "content/urldb.h" #include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" #include "utils/nsoption.h" +#include "desktop/searchweb.h" +#include "desktop/browser.h" -GtkListStore *nsgtk_completion_list; - -static void nsgtk_completion_empty(void); -static bool nsgtk_completion_udb_callback(nsurl *url, - const struct url_data *data); - -void nsgtk_completion_init(void) -{ - nsgtk_completion_list = gtk_list_store_new(1, G_TYPE_STRING); +#include "gtk/window.h" +#include "gtk/completion.h" -} +GtkListStore *nsgtk_completion_list; -gboolean nsgtk_completion_match(GtkEntryCompletion *completion, - const gchar *key, - GtkTreeIter *iter, - gpointer user_data) +/** + * completion row matcher + */ +static gboolean nsgtk_completion_match(GtkEntryCompletion *completion, + const gchar *key, + GtkTreeIter *iter, + gpointer user_data) { - char *b[4096]; /* no way of finding out its length :( */ - gtk_tree_model_get(GTK_TREE_MODEL(nsgtk_completion_list), iter, - 0, b, -1); - - /* TODO: work out why this works, when there's no code to implement - * it. I boggle. */ - + /* the completion list is modified to only contain valid + * entries so this simply returns TRUE to indicate all rows + * are in the list should be shown. + */ return TRUE; } -void nsgtk_completion_empty(void) -{ - gtk_list_store_clear(nsgtk_completion_list); -} -bool nsgtk_completion_udb_callback(nsurl *url, const struct url_data *data) +/** + * callback for each entry to add to completion list + */ +static bool +nsgtk_completion_udb_callback(nsurl *url, const struct url_data *data) { GtkTreeIter iter; @@ -68,10 +69,89 @@ bool nsgtk_completion_udb_callback(nsurl *url, const struct url_data *data) return true; } -void nsgtk_completion_update(const char *prefix) +/** + * event handler for when a completion suggestion is selected. + */ +static gboolean +nsgtk_completion_match_select(GtkEntryCompletion *widget, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) +{ + GValue value = {0, }; + struct nsgtk_scaffolding *g = user_data; + struct browser_window *bw = nsgtk_get_browser_window(nsgtk_scaffolding_top_level(g)); + nserror ret; + nsurl *url; + + gtk_tree_model_get_value(model, iter, 0, &value); + + ret = search_web_omni(g_value_get_string(&value), + SEARCH_WEB_OMNI_NONE, + &url); + + g_value_unset(&value); + + if (ret == NSERROR_OK) { + ret = browser_window_navigate(bw, + url, NULL, BW_NAVIGATE_HISTORY, + NULL, NULL, NULL); + nsurl_unref(url); + } + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); + } + + return TRUE; +} + +/* exported interface documented in completion.h */ +void nsgtk_completion_init(void) { - nsgtk_completion_empty(); + nsgtk_completion_list = gtk_list_store_new(1, G_TYPE_STRING); + +} + +/* exported interface documented in completion.h */ +gboolean nsgtk_completion_update(GtkEntry *entry) +{ + gtk_list_store_clear(nsgtk_completion_list); + if (nsoption_bool(url_suggestion) == true) { - urldb_iterate_partial(prefix, nsgtk_completion_udb_callback); + urldb_iterate_partial(gtk_entry_get_text(entry), + nsgtk_completion_udb_callback); } + + return TRUE; +} + +/* exported interface documented in completion.h */ +GtkEntryCompletion *nsgtk_url_entry_completion_new(struct nsgtk_scaffolding *gs) +{ + GtkEntryCompletion *completion; + + completion = gtk_entry_completion_new(); + gtk_entry_completion_set_match_func(completion, + nsgtk_completion_match, NULL, NULL); + + gtk_entry_completion_set_model(completion, + GTK_TREE_MODEL(nsgtk_completion_list)); + + gtk_entry_completion_set_text_column(completion, 0); + + gtk_entry_completion_set_minimum_key_length(completion, 1); + + /* enable popup for completion */ + gtk_entry_completion_set_popup_completion(completion, TRUE); + + /* when selected callback */ + g_signal_connect(G_OBJECT(completion), "match-selected", + G_CALLBACK(nsgtk_completion_match_select), gs); + + g_object_set(G_OBJECT(completion), + "popup-set-width", TRUE, + "popup-single-match", TRUE, + NULL); + + return completion; } -- cgit v1.2.3