From 8eebe695f053abb390ddc9894415f595ad7f4177 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 27 Aug 2019 23:46:40 +0100 Subject: allow menu activation to use the toolbar button implementations --- frontends/gtk/completion.c | 1 + frontends/gtk/download.c | 1 + frontends/gtk/gui.c | 1 + frontends/gtk/preferences.c | 1 + frontends/gtk/scaffolding.c | 132 +++++++---------------- frontends/gtk/scaffolding.h | 2 - frontends/gtk/search.c | 1 + frontends/gtk/selection.c | 1 + frontends/gtk/tabs.c | 3 +- frontends/gtk/toolbar.c | 236 +++++++++++++++++++++++++++++++++++++++++- frontends/gtk/toolbar.h | 13 +++ frontends/gtk/toolbar_items.h | 12 +-- frontends/gtk/window.c | 10 +- frontends/gtk/window.h | 9 ++ 14 files changed, 317 insertions(+), 106 deletions(-) (limited to 'frontends/gtk') diff --git a/frontends/gtk/completion.c b/frontends/gtk/completion.c index 983ecabb3..1a765416b 100644 --- a/frontends/gtk/completion.c +++ b/frontends/gtk/completion.c @@ -32,6 +32,7 @@ #include "gtk/compat.h" #include "gtk/warn.h" #include "gtk/scaffolding.h" +#include "gtk/toolbar_items.h" #include "gtk/window.h" #include "gtk/completion.h" diff --git a/frontends/gtk/download.c b/frontends/gtk/download.c index 3eab53221..0bb5bb362 100644 --- a/frontends/gtk/download.c +++ b/frontends/gtk/download.c @@ -34,6 +34,7 @@ #include "gtk/warn.h" #include "gtk/scaffolding.h" +#include "gtk/toolbar_items.h" #include "gtk/window.h" #include "gtk/compat.h" #include "gtk/resources.h" diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c index 7f3331571..2c23364b9 100644 --- a/frontends/gtk/gui.c +++ b/frontends/gtk/gui.c @@ -63,6 +63,7 @@ #include "gtk/global_history.h" #include "gtk/hotlist.h" #include "gtk/throbber.h" +#include "gtk/toolbar_items.h" #include "gtk/scaffolding.h" #include "gtk/window.h" #include "gtk/schedule.h" diff --git a/frontends/gtk/preferences.c b/frontends/gtk/preferences.c index 652075cac..efef4a2ea 100644 --- a/frontends/gtk/preferences.c +++ b/frontends/gtk/preferences.c @@ -30,6 +30,7 @@ #include "desktop/searchweb.h" #include "gtk/compat.h" +#include "gtk/toolbar_items.h" #include "gtk/window.h" #include "gtk/gui.h" #include "gtk/scaffolding.h" diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c index 13a2ed58d..10d96810f 100644 --- a/frontends/gtk/scaffolding.c +++ b/frontends/gtk/scaffolding.c @@ -69,8 +69,8 @@ #include "gtk/print.h" #include "gtk/search.h" #include "gtk/throbber.h" -#include "gtk/toolbar.h" #include "gtk/toolbar_items.h" +#include "gtk/toolbar.h" #include "gtk/window.h" #include "gtk/gdk.h" #include "gtk/scaffolding.h" @@ -601,105 +601,40 @@ static void nsgtk_openfile_open(const char *filename) /* signal handlers for menu entries */ -MULTIHANDLER(newwindow) +/** + * menu signal handler for activation on new window item + */ +static gboolean +nsgtk_on_newwindow_activate_menu(GtkMenuItem *widget, gpointer data) { - struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - const char *addr; - nsurl *url; - nserror error; - - if (nsoption_charp(homepage_url) != NULL) { - addr = nsoption_charp(homepage_url); - } else { - addr = NETSURF_HOMEPAGE; - } - - error = nsurl_create(addr, &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - bw, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - nsgtk_warning(messages_get_errorcode(error), 0); - } - + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + nsgtk_window_item_activate(g->top_level, NEWWINDOW_BUTTON); return TRUE; } -/* exported interface documented in gtk/scaffolding.h */ -nserror nsgtk_scaffolding_new_tab(struct gui_window *gw) -{ - struct browser_window *bw = nsgtk_get_browser_window(gw); - nsurl *url = NULL; - nserror error; - - if (!nsoption_bool(new_blank)) { - const char *addr; - if (nsoption_charp(homepage_url) != NULL) { - addr = nsoption_charp(homepage_url); - } else { - addr = NETSURF_HOMEPAGE; - } - error = nsurl_create(addr, &url); - if (error != NSERROR_OK) { - nsgtk_warning(messages_get_errorcode(error), 0); - } - } - - error = browser_window_create(BW_CREATE_HISTORY | - BW_CREATE_TAB, - url, - NULL, - bw, - NULL); - if (url != NULL) { - nsurl_unref(url); - } - return error; -} - -MULTIHANDLER(newtab) +/** + * menu signal handler for activation on new tab item + */ +static gboolean +nsgtk_on_newtab_activate_menu(GtkMenuItem *widget, gpointer data) { - nserror error; - - error = nsgtk_scaffolding_new_tab(g->top_level); - if (error != NSERROR_OK) { - nsgtk_warning(messages_get_errorcode(error), 0); - } + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + nsgtk_window_item_activate(g->top_level, NEWTAB_BUTTON); return TRUE; } -MULTIHANDLER(openfile) +/** + * menu signal handler for activation on openfile item + */ +static gboolean +nsgtk_on_openfile_activate_menu(GtkMenuItem *widget, gpointer data) { - GtkWidget *dlgOpen; - gint response; - - scaf_current = g; - dlgOpen = gtk_file_chooser_dialog_new("Open File", - scaf_current->window, - GTK_FILE_CHOOSER_ACTION_OPEN, - NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NSGTK_STOCK_OPEN, GTK_RESPONSE_OK, - NULL, NULL); - - response = gtk_dialog_run(GTK_DIALOG(dlgOpen)); - if (response == GTK_RESPONSE_OK) { - gchar *filename; - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlgOpen)); - - nsgtk_openfile_open((const char *)filename); - - g_free(filename); - } - - gtk_widget_destroy(dlgOpen); + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + nsgtk_window_item_activate(g->top_level, OPENFILE_BUTTON); return TRUE; } + /** * callback to determine if a path is a directory. * @@ -1001,12 +936,19 @@ MULTIHANDLER(print) return TRUE; } -MULTIHANDLER(closewindow) + +/** + * menu signal handler for activation on close window item + */ +static gboolean +nsgtk_on_closewindow_activate_menu(GtkMenuItem *widget, gpointer data) { - gtk_widget_destroy(GTK_WIDGET(g->window)); + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + nsgtk_window_item_activate(g->top_level, CLOSEWINDOW_BUTTON); return TRUE; } + MULTIHANDLER(quit) { struct nsgtk_scaffolding *gs; @@ -1639,10 +1581,14 @@ MULTIHANDLER(prevtab) return TRUE; } -MULTIHANDLER(closetab) +/** + * menu signal handler for activation on close tab item + */ +static gboolean +nsgtk_on_closetab_activate_menu(GtkMenuItem *widget, gpointer data) { - nsgtk_tab_close_current(g->notebook); - + struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data; + nsgtk_window_item_activate(g->top_level, CLOSETAB_BUTTON); return TRUE; } diff --git a/frontends/gtk/scaffolding.h b/frontends/gtk/scaffolding.h index 261d2f0a2..d5a916fe8 100644 --- a/frontends/gtk/scaffolding.h +++ b/frontends/gtk/scaffolding.h @@ -155,8 +155,6 @@ void nsgtk_scaffolding_context_menu(struct nsgtk_scaffolding *g, gdouble x, gdou gboolean nsgtk_window_url_changed(GtkWidget *, GdkEventKey *, gpointer); -nserror nsgtk_scaffolding_new_tab(struct gui_window *gw); - /* core acessors */ /** * set the title in the window diff --git a/frontends/gtk/search.c b/frontends/gtk/search.c index 40c0253b0..6baf7f6ae 100644 --- a/frontends/gtk/search.c +++ b/frontends/gtk/search.c @@ -38,6 +38,7 @@ #include "gtk/warn.h" #include "gtk/compat.h" #include "gtk/search.h" +#include "gtk/toolbar_items.h" #include "gtk/scaffolding.h" #include "gtk/window.h" diff --git a/frontends/gtk/selection.c b/frontends/gtk/selection.c index 228d65dbe..871526047 100644 --- a/frontends/gtk/selection.c +++ b/frontends/gtk/selection.c @@ -24,6 +24,7 @@ #include "netsurf/browser_window.h" #include "netsurf/clipboard.h" +#include "gtk/toolbar_items.h" #include "gtk/window.h" static GString *current_selection = NULL; diff --git a/frontends/gtk/tabs.c b/frontends/gtk/tabs.c index 9e5c1b39e..04bd69f23 100644 --- a/frontends/gtk/tabs.c +++ b/frontends/gtk/tabs.c @@ -25,6 +25,7 @@ #include "desktop/search.h" #include "gtk/compat.h" +#include "gtk/toolbar_items.h" #include "gtk/scaffolding.h" #include "gtk/window.h" #include "gtk/search.h" @@ -179,7 +180,7 @@ nsgtk_tab_switch_page_after(GtkNotebook *notebook, srcpage = gtk_notebook_get_nth_page(notebook, srcpagenum); gw = g_object_get_data(G_OBJECT(srcpage), "gui_window"); if ((gw != NULL) && (nsgtk_get_scaffold(gw) != NULL)) { - error = nsgtk_scaffolding_new_tab(gw); + error = nsgtk_window_item_activate(gw, NEWTAB_BUTTON); if (error != NSERROR_OK) { NSLOG(netsurf, INFO, "Failed to open new tab."); diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c index b1cd51c15..4b3f23b04 100644 --- a/frontends/gtk/toolbar.c +++ b/frontends/gtk/toolbar.c @@ -35,7 +35,9 @@ #include "utils/nsoption.h" #include "utils/file.h" #include "utils/nsurl.h" +#include "utils/corestrings.h" +#include "gtk/toolbar_items.h" #include "gtk/completion.h" #include "gtk/gui.h" #include "gtk/warn.h" @@ -45,10 +47,9 @@ #include "gtk/window.h" #include "gtk/compat.h" #include "gtk/resources.h" -#include "gtk/toolbar_items.h" -#include "gtk/toolbar.h" #include "gtk/schedule.h" #include "gtk/local_history.h" +#include "gtk/toolbar.h" /** * button location indicating button is not to be shown @@ -2029,6 +2030,205 @@ websearch_entry_button_press_cb(GtkWidget *widget, } +/** + * handler for new window tool bar item clicked signal + * + * \param widget The widget the signal is being delivered to. + * \param data The toolbar context passed when the signal was connected + * \return TRUE + */ +static gboolean +newwindow_button_clicked_cb(GtkWidget *widget, gpointer data) +{ + nserror res; + struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data; + struct browser_window *bw; + const char *addr; + nsurl *url; + + if (nsoption_charp(homepage_url) != NULL) { + addr = nsoption_charp(homepage_url); + } else { + addr = NETSURF_HOMEPAGE; + } + + res = nsurl_create(addr, &url); + if (res == NSERROR_OK) { + bw = tb->get_bw(tb->get_bw_ctx); + res = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + bw, + NULL); + nsurl_unref(url); + } + if (res != NSERROR_OK) { + nsgtk_warning(messages_get_errorcode(res), 0); + } + + return TRUE; +} + + +/** + * handler for new tab tool bar item clicked signal + * + * \param widget The widget the signal is being delivered to. + * \param data The toolbar context passed when the signal was connected + * \return TRUE + */ +static gboolean +newtab_button_clicked_cb(GtkWidget *widget, gpointer data) +{ + nserror res = NSERROR_OK; + nsurl *url = NULL; + struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data; + struct browser_window *bw; + + if (!nsoption_bool(new_blank)) { + const char *addr; + if (nsoption_charp(homepage_url) != NULL) { + addr = nsoption_charp(homepage_url); + } else { + addr = NETSURF_HOMEPAGE; + } + res = nsurl_create(addr, &url); + } + + if (res == NSERROR_OK) { + bw = tb->get_bw(tb->get_bw_ctx); + + res = browser_window_create(BW_CREATE_HISTORY | + BW_CREATE_TAB, + url, + NULL, + bw, + NULL); + } + if (url != NULL) { + nsurl_unref(url); + } + if (res != NSERROR_OK) { + nsgtk_warning(messages_get_errorcode(res), 0); + } + return TRUE; +} + + +/** + * handler for open file tool bar item clicked signal + * + * \param widget The widget the signal is being delivered to. + * \param data The toolbar context passed when the signal was connected + * \return TRUE + */ +static gboolean +openfile_button_clicked_cb(GtkWidget *widget, gpointer data) +{ + GtkWidget *dlgOpen; + gint response; + GtkWidget *toplevel; + struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data; + struct browser_window *bw; + + toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + + dlgOpen = gtk_file_chooser_dialog_new("Open File", + GTK_WINDOW(toplevel), + GTK_FILE_CHOOSER_ACTION_OPEN, + NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NSGTK_STOCK_OPEN, GTK_RESPONSE_OK, + NULL, NULL); + + response = gtk_dialog_run(GTK_DIALOG(dlgOpen)); + if (response == GTK_RESPONSE_OK) { + char *urltxt; + gchar *filename; + nserror res; + nsurl *url; + + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlgOpen)); + + urltxt = malloc(strlen(filename) + FILE_SCHEME_PREFIX_LEN + 1); + if (urltxt != NULL) { + sprintf(urltxt, FILE_SCHEME_PREFIX"%s", filename); + + res = nsurl_create(urltxt, &url); + if (res == NSERROR_OK) { + bw = tb->get_bw(tb->get_bw_ctx); + res = browser_window_navigate(bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (res != NSERROR_OK) { + nsgtk_warning(messages_get_errorcode(res), 0); + } + free(urltxt); + } + + + g_free(filename); + } + + gtk_widget_destroy(dlgOpen); + + return TRUE; +} + + +/** + * handler for close tab tool bar item clicked signal + * + * \param widget The widget the signal is being delivered to. + * \param data The toolbar context passed when the signal was connected + * \return TRUE + */ +static gboolean +closetab_button_clicked_cb(GtkWidget *widget, gpointer data) +{ + struct nsgtk_toolbar *tb = (struct nsgtk_toolbar *)data; + + nsgtk_tab_close_current(tb->widget); + + return TRUE; +} + + +/** + * handler for close window tool bar item clicked signal + * + * \param widget The widget the signal is being delivered to. + * \param data The toolbar context passed when the signal was connected + * \return TRUE + */ +static gboolean +closewindow_button_clicked_cb(GtkWidget *widget, gpointer data) +{ + GtkWidget *toplevel; + toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + gtk_widget_destroy(toplevel); + return TRUE; +} + + +/** + * handler for new window tool bar item clicked signal + * + * \param widget The widget the signal is being delivered to. + * \param data The toolbar context passed when the signal was connected + * \return TRUE + */ +static gboolean +savepage_button_clicked_cb(GtkWidget *widget, gpointer data) +{ +} + + /** * create a toolbar item * @@ -2403,3 +2603,35 @@ nserror nsgtk_toolbar_set_url(struct nsgtk_toolbar *tb, nsurl *url) return NSERROR_OK; } + + +/* exported interface documented in toolbar.h */ +nserror +nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb, + nsgtk_toolbar_button itemid) +{ + GtkWidget *widget; + + /* ensure item id in range */ + if ((itemid < BACK_BUTTON) || (itemid >= PLACEHOLDER_BUTTON)) { + return NSERROR_BAD_PARAMETER; + } + + if (tb->buttons[itemid]->bhandler == NULL) { + return NSERROR_INVALID; + } + + /* + * if item has a widget in the current toolbar use that as the + * signal source otherwise use the toolbar widget itself. + */ + if (tb->buttons[itemid]->button != NULL) { + widget = GTK_WIDGET(tb->buttons[itemid]->button); + } else { + widget = tb->widget; + } + + tb->buttons[itemid]->bhandler(widget, tb); + + return NSERROR_OK; +} diff --git a/frontends/gtk/toolbar.h b/frontends/gtk/toolbar.h index f04d807c3..b89774ba2 100644 --- a/frontends/gtk/toolbar.h +++ b/frontends/gtk/toolbar.h @@ -70,6 +70,19 @@ nserror nsgtk_toolbar_throbber(struct nsgtk_toolbar *tb, bool active); */ nserror nsgtk_toolbar_set_url(struct nsgtk_toolbar *tb, nsurl *url); + +/** + * activate the handler for a toolbar item + * + * This allows the same action to be performed for menu enties as if + * the user had clicked the toolbar widget. + * + * \param toolbar A toolbar returned from a creation + * \param itemid the id of the item to activate + * \return NSERROR_OK on success + */ +nserror nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid); + /** * sets up the images for scaffolding. */ diff --git a/frontends/gtk/toolbar_items.h b/frontends/gtk/toolbar_items.h index 5281ab696..03188c2b8 100644 --- a/frontends/gtk/toolbar_items.h +++ b/frontends/gtk/toolbar_items.h @@ -97,12 +97,12 @@ TOOLBAR_ITEM(HOME_BUTTON, home, true, home_button_clicked_cb) TOOLBAR_ITEM(URL_BAR_ITEM, url_bar, true, NULL) TOOLBAR_ITEM(WEBSEARCH_ITEM, websearch, true, NULL) TOOLBAR_ITEM(THROBBER_ITEM, throbber, true, NULL) -TOOLBAR_ITEM(NEWWINDOW_BUTTON, newwindow, true, NULL) -TOOLBAR_ITEM(NEWTAB_BUTTON, newtab, true, NULL) -TOOLBAR_ITEM(OPENFILE_BUTTON, openfile, true, NULL) -TOOLBAR_ITEM(CLOSETAB_BUTTON, closetab, false, NULL) -TOOLBAR_ITEM(CLOSEWINDOW_BUTTON, closewindow, true, NULL) -TOOLBAR_ITEM(SAVEPAGE_BUTTON, savepage, true, NULL) +TOOLBAR_ITEM(NEWWINDOW_BUTTON, newwindow, true, newwindow_button_clicked_cb) +TOOLBAR_ITEM(NEWTAB_BUTTON, newtab, true, newtab_button_clicked_cb) +TOOLBAR_ITEM(OPENFILE_BUTTON, openfile, true, openfile_button_clicked_cb) +TOOLBAR_ITEM(CLOSETAB_BUTTON, closetab, false, closetab_button_clicked_cb) +TOOLBAR_ITEM(CLOSEWINDOW_BUTTON, closewindow, true, closewindow_button_clicked_cb) +TOOLBAR_ITEM(SAVEPAGE_BUTTON, savepage, true, savepage_button_clicked_cb) TOOLBAR_ITEM(PDF_BUTTON, pdf, false, NULL) TOOLBAR_ITEM(PLAINTEXT_BUTTON, plaintext, true, NULL) TOOLBAR_ITEM(DRAWFILE_BUTTON, drawfile, false, NULL) diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c index ce67004ca..015b5faaf 100644 --- a/frontends/gtk/window.c +++ b/frontends/gtk/window.c @@ -47,12 +47,12 @@ #include "desktop/textinput.h" #include "utils/nsurl.h" -#include "gtk/window.h" #include "gtk/selection.h" #include "gtk/warn.h" #include "gtk/compat.h" #include "gtk/gui.h" #include "gtk/scaffolding.h" +#include "gtk/toolbar_items.h" #include "gtk/toolbar.h" #include "gtk/local_history.h" #include "gtk/plotters.h" @@ -61,6 +61,7 @@ #include "gtk/bitmap.h" #include "gtk/gdk.h" #include "gtk/resources.h" +#include "gtk/window.h" static GtkWidget *select_menu; static struct form_control *select_menu_control; @@ -894,7 +895,12 @@ gui_window_create(struct browser_window *bw, return g; } - +/* exported interface documented in window.h */ +nserror +nsgtk_window_item_activate(struct gui_window *gw, nsgtk_toolbar_button itemid) +{ + return nsgtk_toolbar_item_activate(gw->toolbar, itemid); +} void nsgtk_reflow_all_windows(void) { diff --git a/frontends/gtk/window.h b/frontends/gtk/window.h index 462ed17a8..a991f0337 100644 --- a/frontends/gtk/window.h +++ b/frontends/gtk/window.h @@ -92,4 +92,13 @@ GtkWidget *nsgtk_window_get_tab(struct gui_window *gw); */ void nsgtk_window_set_tab(struct gui_window *gw, GtkWidget *w); +/** + * activate the handler for a item in a toolbar of a gui window + * + * \param gw The gui window handle + * \param itemid The id of the item to activate + */ +nserror nsgtk_window_item_activate(struct gui_window *gw, nsgtk_toolbar_button itemid); + + #endif /* NETSURF_GTK_WINDOW_H */ -- cgit v1.2.3