diff --git a/frontends/gtk/completion.c b/frontends/gtk/completion.c index 3da3410ad..983ecabb3 100644 --- a/frontends/gtk/completion.c +++ b/frontends/gtk/completion.c @@ -37,6 +37,18 @@ GtkListStore *nsgtk_completion_list; +struct nsgtk_completion_ctx { + /** + * callback to obtain a browser window for navigation + */ + struct browser_window *(*get_bw)(void *ctx); + + /** + * context passed to get_bw function + */ + void *get_bw_ctx; +}; + /** * completion row matcher */ @@ -50,7 +62,6 @@ static gboolean nsgtk_completion_match(GtkEntryCompletion *completion, * are in the list should be shown. */ return TRUE; - } @@ -77,14 +88,17 @@ static gboolean nsgtk_completion_match_select(GtkEntryCompletion *widget, GtkTreeModel *model, GtkTreeIter *iter, - gpointer user_data) + gpointer data) { + struct nsgtk_completion_ctx *cb_ctx; GValue value = G_VALUE_INIT; - struct nsgtk_scaffolding *g = user_data; - struct browser_window *bw = nsgtk_get_browser_window(nsgtk_scaffolding_top_level(g)); + struct browser_window *bw; nserror ret; nsurl *url; + cb_ctx = data; + bw = cb_ctx->get_bw(cb_ctx->get_bw_ctx); + gtk_tree_model_get_value(model, iter, 0, &value); ret = search_web_omni(g_value_get_string(&value), @@ -127,11 +141,20 @@ gboolean nsgtk_completion_update(GtkEntry *entry) } /* exported interface documented in completion.h */ -GtkEntryCompletion *nsgtk_url_entry_completion_new(struct nsgtk_scaffolding *gs) +nserror +nsgtk_completion_connect_signals(GtkEntry *entry, + struct browser_window *(*get_bw)(void *ctx), + void *get_bw_ctx) { GtkEntryCompletion *completion; + struct nsgtk_completion_ctx *cb_ctx; + + cb_ctx = calloc(1, sizeof(struct nsgtk_completion_ctx)); + cb_ctx->get_bw = get_bw; + cb_ctx->get_bw_ctx = get_bw_ctx; + + completion = gtk_entry_get_completion(entry); - completion = gtk_entry_completion_new(); gtk_entry_completion_set_match_func(completion, nsgtk_completion_match, NULL, NULL); @@ -146,13 +169,15 @@ GtkEntryCompletion *nsgtk_url_entry_completion_new(struct nsgtk_scaffolding *gs) 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_signal_connect(G_OBJECT(completion), + "match-selected", + G_CALLBACK(nsgtk_completion_match_select), + cb_ctx); g_object_set(G_OBJECT(completion), - "popup-set-width", TRUE, - "popup-single-match", TRUE, - NULL); + "popup-set-width", TRUE, + "popup-single-match", TRUE, + NULL); - return completion; + return NSERROR_OK; } diff --git a/frontends/gtk/completion.h b/frontends/gtk/completion.h index 9a1db293d..a81f1301a 100644 --- a/frontends/gtk/completion.h +++ b/frontends/gtk/completion.h @@ -37,10 +37,11 @@ void nsgtk_completion_init(void); gboolean nsgtk_completion_update(GtkEntry *entry); /** - * create a new entry completion on a scaffold. - * - * \param gs The scaffoliding which the url entry is in. + * connect signals on entry completion */ -GtkEntryCompletion *nsgtk_url_entry_completion_new(struct nsgtk_scaffolding *gs); +nserror +nsgtk_completion_connect_signals(GtkEntry *entry, + struct browser_window *(*get_bw)(void *ctx), + void *get_bw_ctx); #endif diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c index 7ebf2ebdb..a17ffd32c 100644 --- a/frontends/gtk/toolbar.c +++ b/frontends/gtk/toolbar.c @@ -105,6 +105,10 @@ struct nsgtk_toolbar { * callback to obtain a browser window for navigation */ struct browser_window *(*get_bw)(void *ctx); + + /** + * context passed to get_bw function + */ void *get_bw_ctx; }; @@ -577,14 +581,20 @@ make_toolbar_item(nsgtk_toolbar_button i, struct nsgtk_theme *theme) break; case URL_BAR_ITEM: { - GtkWidget *entry = nsgtk_entry_new(); - w = GTK_WIDGET(gtk_tool_item_new()); + /* create a gtk entry widget with a completion attached */ + GtkWidget *entry; + GtkEntryCompletion *completion; - if ((entry == NULL) || (w == NULL)) { + w = GTK_WIDGET(gtk_tool_item_new()); + entry = nsgtk_entry_new(); + completion = gtk_entry_completion_new(); + + if ((entry == NULL) || (completion == NULL) || (w == NULL)) { nsgtk_warning(messages_get("NoMemory"), 0); return NULL; } + gtk_entry_set_completion(entry, completion); gtk_container_add(GTK_CONTAINER(w), entry); gtk_tool_item_set_expand(GTK_TOOL_ITEM(w), TRUE); break; @@ -1906,9 +1916,13 @@ toolbar_connect_signal(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid) "changed", G_CALLBACK(url_entry_changed_cb), tb); - } + + nsgtk_completion_connect_signals(url_entry, + tb->get_bw, + tb->get_bw_ctx); break; } + } return NSERROR_OK; } @@ -1996,10 +2010,6 @@ nsgtk_toolbar_create(GtkBuilder *builder, /* set the throbber start frame. */ tb->throb_frame = 0; - /* set up URL bar completion */ - /** \todo sort out completion */ - //tb->url_bar_completion = nsgtk_url_entry_completion_new(gs); - res = toolbar_connect_signals(tb); if (res != NSERROR_OK) { free(tb);