diff options
author | Vincent Sanders <vince@kyllikki.org> | 2014-07-07 23:29:06 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2014-07-07 23:29:06 +0100 |
commit | 5ce4f11eac7fae76fe2965f92daf2910f80eb6a1 (patch) | |
tree | 71b28cc100bd7b6248405fd03a1755a533180fec /gtk/scaffolding.c | |
parent | 07f1ae746145022fb07ecb9e9163c013f432d13f (diff) | |
download | netsurf-5ce4f11eac7fae76fe2965f92daf2910f80eb6a1.tar.gz netsurf-5ce4f11eac7fae76fe2965f92daf2910f80eb6a1.tar.bz2 |
add link context menu to gtk and add link copying and bookmarking
Diffstat (limited to 'gtk/scaffolding.c')
-rw-r--r-- | gtk/scaffolding.c | 174 |
1 files changed, 124 insertions, 50 deletions
diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index ee2d46227..d6cb58b27 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -107,7 +107,10 @@ struct gtk_scaffolding { struct nsgtk_bar_submenu *menu_bar; /** right click popup menu hierarchy */ - struct nsgtk_popup_submenu *menu_popup; + struct nsgtk_popup_menu *menu_popup; + + /** link popup menu */ + struct nsgtk_link_menu *link_menu; GtkToolbar *tool_bar; struct nsgtk_button_connect *buttons[PLACEHOLDER_BUTTON]; @@ -147,7 +150,7 @@ static struct contextual_content current_menu_ctx; /** * Helper to hide popup menu entries by grouping */ -static void popup_menu_hide(struct nsgtk_popup_submenu *menu, bool submenu, +static void popup_menu_hide(struct nsgtk_popup_menu *menu, bool submenu, bool link, bool nav, bool cnp, bool custom) { if (submenu){ @@ -190,7 +193,7 @@ static void popup_menu_hide(struct nsgtk_popup_submenu *menu, bool submenu, /** * Helper to show popup menu entries by grouping */ -static void popup_menu_show(struct nsgtk_popup_submenu *menu, bool submenu, +static void popup_menu_show(struct nsgtk_popup_menu *menu, bool submenu, bool link, bool nav, bool cnp, bool custom) { if (submenu){ @@ -1023,6 +1026,44 @@ MENUHANDLER(link_opentab) return TRUE; } +/** + * Handler for bookmarking a link. attached to the popup menu. + */ +MENUHANDLER(link_bookmark) +{ + nsurl *url; + nserror error; + + if (current_menu_ctx.link_url == NULL) + return FALSE; + + error = nsurl_create(current_menu_ctx.link_url, &url); + if (error == NSERROR_OK) { + hotlist_add_url(url); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } + + return TRUE; +} + +/** + * Handler for copying a link. attached to the popup menu. + */ +MENUHANDLER(link_copy) +{ + GtkClipboard *clipboard; + + if (current_menu_ctx.link_url == NULL) + return FALSE; + + clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, current_menu_ctx.link_url, -1); + return TRUE; +} + MULTIHANDLER(cut) { @@ -1755,23 +1796,21 @@ static void nsgtk_attach_menu_handlers(struct gtk_scaffolding *g) * Create and connect handlers to popup menu. * * \param g scaffoliding to attach popup menu to. - * \return true on success or false on error. + * \return menu structure on sucess or NULL on error. */ -static bool nsgtk_new_scaffolding_popup(struct gtk_scaffolding *g, GtkAccelGroup *group) +static struct nsgtk_popup_menu * +nsgtk_new_scaffolding_popup(struct gtk_scaffolding *g, GtkAccelGroup *group) { - struct nsgtk_popup_submenu *nmenu; - - nmenu = nsgtk_menu_popup_create(group); + struct nsgtk_popup_menu *nmenu; - if (nmenu == NULL) - return false; + nmenu = nsgtk_popup_menu_create(group); -/** Connect a GTK signal handler to a widget */ -#define SIG_CONNECT(obj, sig, callback, ptr) \ - g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + if (nmenu == NULL) { + return NULL; + } - SIG_CONNECT(nmenu->popup_menu, "hide", - nsgtk_window_popup_menu_hidden, g); + g_signal_connect(nmenu->popup_menu, "hide", + G_CALLBACK(nsgtk_window_popup_menu_hidden), g); g_signal_connect(nmenu->savelink_menuitem, "activate", G_CALLBACK(nsgtk_on_savelink_activate_menu), g); @@ -1797,9 +1836,42 @@ static bool nsgtk_new_scaffolding_popup(struct gtk_scaffolding *g, GtkAccelGroup /* set initial popup menu visibility */ popup_menu_hide(nmenu, true, false, false, false, true); - g->menu_popup = nmenu; + return nmenu; +} - return true; +/** + * Create and connect handlers to link popup menu. + * + * \param g scaffoliding to attach popup menu to. + * \return true on success or false on error. + */ +static struct nsgtk_link_menu * +nsgtk_new_scaffolding_link_popup(struct gtk_scaffolding *g, GtkAccelGroup *group) +{ + struct nsgtk_link_menu *nmenu; + + nmenu = nsgtk_link_menu_create(group); + + if (nmenu == NULL) { + return NULL; + } + + g_signal_connect(nmenu->save_menuitem, "activate", + G_CALLBACK(nsgtk_on_savelink_activate_menu), g); + + g_signal_connect(nmenu->opentab_menuitem, "activate", + G_CALLBACK(nsgtk_on_link_opentab_activate_menu), g); + + g_signal_connect(nmenu->openwin_menuitem, "activate", + G_CALLBACK(nsgtk_on_link_openwin_activate_menu), g); + + g_signal_connect(nmenu->bookmark_menuitem, "activate", + G_CALLBACK(nsgtk_on_link_bookmark_activate_menu), g); + + g_signal_connect(nmenu->copy_menuitem, "activate", + G_CALLBACK(nsgtk_on_link_copy_activate_menu), g); + + return nmenu; } nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) @@ -2061,7 +2133,9 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) nsgtk_window_tool_bar_clicked, g); /* create popup menu */ - nsgtk_new_scaffolding_popup(g, group); + g->menu_popup = nsgtk_new_scaffolding_popup(g, group); + + g->link_menu = nsgtk_new_scaffolding_link_popup(g, group); /* set up the menu signal handlers */ nsgtk_scaffolding_toolbar_init(g); @@ -2509,53 +2583,53 @@ void nsgtk_scaffolding_initial_sensitivity(struct gtk_scaffolding *g) gtk_widget_set_sensitive(GTK_WIDGET(g->menu_bar->view_submenu->images_menuitem), FALSE); } -/** - * Checks if a location is over a link. - * - * Side effect of this function is to set the global current_menu_ctx - */ -static bool is_menu_over_link(struct gtk_scaffolding *g, gdouble x, gdouble y) +/* exported interface documented in gtk/scaffolding.h */ +void nsgtk_scaffolding_context_menu(struct gtk_scaffolding *g, + gdouble x, + gdouble y) { + GtkMenu *gtkmenu; + + /* update the global current_menu_ctx */ browser_window_get_contextual_content( nsgtk_get_browser_window(g->top_level), x, y, ¤t_menu_ctx); - if (current_menu_ctx.link_url == NULL) - return false; - return true; -} + if (current_menu_ctx.link_url != NULL) { + /* menu is opening over a link */ + gtkmenu = g->link_menu->link_menu; -void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, gdouble x, gdouble y) -{ - if (is_menu_over_link(g, x, y)) { popup_menu_show(g->menu_popup, false, true, false, false, false); + } else { - popup_menu_hide(g->menu_popup, false, true, false, false, false); - } + gtkmenu = g->menu_popup->popup_menu; - nsgtk_scaffolding_update_edit_actions_sensitivity(g); + popup_menu_hide(g->menu_popup, false, true, false, false, false); + + nsgtk_scaffolding_update_edit_actions_sensitivity(g); - if (!(g->buttons[COPY_BUTTON]->sensitivity)) - gtk_widget_hide(GTK_WIDGET(g->menu_popup->copy_menuitem)); - else - gtk_widget_show(GTK_WIDGET(g->menu_popup->copy_menuitem)); + if (!(g->buttons[COPY_BUTTON]->sensitivity)) + gtk_widget_hide(GTK_WIDGET(g->menu_popup->copy_menuitem)); + else + gtk_widget_show(GTK_WIDGET(g->menu_popup->copy_menuitem)); - if (!(g->buttons[CUT_BUTTON]->sensitivity)) - gtk_widget_hide(GTK_WIDGET(g->menu_popup->cut_menuitem)); - else - gtk_widget_show(GTK_WIDGET(g->menu_popup->cut_menuitem)); + if (!(g->buttons[CUT_BUTTON]->sensitivity)) + gtk_widget_hide(GTK_WIDGET(g->menu_popup->cut_menuitem)); + else + gtk_widget_show(GTK_WIDGET(g->menu_popup->cut_menuitem)); - if (!(g->buttons[PASTE_BUTTON]->sensitivity)) - gtk_widget_hide(GTK_WIDGET(g->menu_popup->paste_menuitem)); - else - gtk_widget_show(GTK_WIDGET(g->menu_popup->paste_menuitem)); + if (!(g->buttons[PASTE_BUTTON]->sensitivity)) + gtk_widget_hide(GTK_WIDGET(g->menu_popup->paste_menuitem)); + else + gtk_widget_show(GTK_WIDGET(g->menu_popup->paste_menuitem)); - /* hide customize */ - popup_menu_hide(g->menu_popup, false, false, false, false, true); + /* hide customize */ + popup_menu_hide(g->menu_popup, false, false, false, false, true); + } - gtk_menu_popup(g->menu_popup->popup_menu, NULL, NULL, NULL, NULL, 0, - gtk_get_current_event_time()); + gtk_menu_popup(gtkmenu, NULL, NULL, NULL, NULL, 0, + gtk_get_current_event_time()); } /** |