[balsa/gtk4: 38/312] balsa-mime-widget-text: Port HTML popup
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/gtk4: 38/312] balsa-mime-widget-text: Port HTML popup
- Date: Tue, 5 Oct 2021 20:00:49 +0000 (UTC)
commit 53d19901e4293fefc7b832ed0a5bf1e3f641a765
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Thu May 14 17:31:37 2020 -0400
balsa-mime-widget-text: Port HTML popup
to GtkPopover
src/balsa-message.c | 1 -
src/balsa-mime-widget-text.c | 264 ++++++++++++++++++++++++++++---------------
2 files changed, 173 insertions(+), 92 deletions(-)
---
diff --git a/src/balsa-message.c b/src/balsa-message.c
index d6a61ae96..20e517b09 100644
--- a/src/balsa-message.c
+++ b/src/balsa-message.c
@@ -2781,7 +2781,6 @@ balsa_message_zoom(BalsaMessage * balsa_message, gint in_out)
GINT_TO_POINTER(zoom));
libbalsa_html_zoom(GTK_WIDGET(balsa_message->current_part->mime_widget), in_out);
-
}
#endif /* HAVE_HTML_WIDGET */
diff --git a/src/balsa-mime-widget-text.c b/src/balsa-mime-widget-text.c
index 0bfd77312..83f601926 100644
--- a/src/balsa-mime-widget-text.c
+++ b/src/balsa-mime-widget-text.c
@@ -625,6 +625,10 @@ text_view_populate_popup(GtkWidget *widget, GtkMenu *menu,
GMenu *open_menu;
GtkWidget *submenu;
+ /* GtkTextView's populate-popup signal handler is supposed to check: */
+ if (!GTK_IS_MENU(menu))
+ return;
+
gtk_widget_hide(GTK_WIDGET(menu));
gtk_container_foreach(GTK_CONTAINER(menu),
(GtkCallback) gtk_widget_hide, NULL);
@@ -1115,155 +1119,228 @@ bm_widget_on_url(const gchar *url)
}
#ifdef HAVE_HTML_WIDGET
+
+/*
+ * Context menu
+ */
+
static void
-bmwt_html_zoom_in(BalsaMessage * bm)
+zoom_in_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
+ GtkWidget *html = user_data;
+ BalsaMessage *bm = g_object_get_data(G_OBJECT(html), "bm");
+
balsa_message_zoom(bm, 1);
}
static void
-bmwt_html_zoom_out(BalsaMessage * bm)
+zoom_out_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
+ GtkWidget *html = user_data;
+ BalsaMessage *bm = g_object_get_data(G_OBJECT(html), "bm");
+
balsa_message_zoom(bm, -1);
}
static void
-bmwt_html_zoom_reset(BalsaMessage * bm)
+zoom_reset_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
+ GtkWidget *html = user_data;
+ BalsaMessage *bm = g_object_get_data(G_OBJECT(html), "bm");
+
balsa_message_zoom(bm, 0);
}
static void
-bmwt_html_select_all_cb(GtkWidget * html)
+select_all_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
+ GtkWidget *html = user_data;
+
libbalsa_html_select_all(html);
}
static void
-bmwt_html_prefer_html_changed(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
+html_open_with_change_state(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- libbalsa_html_prefer_set_prefer_html(INTERNET_ADDRESS_LIST(user_data),
- gtk_check_menu_item_get_active(checkmenuitem));
+ GtkWidget *html = user_data;
+ gpointer mime_body = g_object_get_data(G_OBJECT(html), "mime-body");
+ GtkPopover *popover = g_object_get_data(G_OBJECT(html), "popover");
+
+ open_with_change_state(action, parameter, mime_body);
+
+ gtk_popover_popdown(popover);
}
static void
-bmwt_html_load_images_changed(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
+prefer_html_change_state(GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
{
- libbalsa_html_prefer_set_load_images(INTERNET_ADDRESS_LIST(user_data),
- gtk_check_menu_item_get_active(checkmenuitem));
+ GtkWidget *html = user_data;
+ BalsaMessage *bm = g_object_get_data(G_OBJECT(html), "bm");
+ InternetAddressList *from;
+
+ from = libbalsa_message_get_headers(balsa_message_get_message(bm))->from;
+ libbalsa_html_prefer_set_prefer_html(from, g_variant_get_boolean(state);
+
+ g_simple_action_set_state(G_SIMPLE_ACTION(action), state);
}
static void
-bmwt_html_populate_popup_menu(BalsaMessage * bm,
- GtkWidget * html,
- GtkMenu * menu)
+load_images_change_state(GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
{
- GtkWidget *menuitem;
+ GtkWidget *html = user_data;
+ BalsaMessage *bm = g_object_get_data(G_OBJECT(html), "bm");
InternetAddressList *from;
- gpointer mime_body = g_object_get_data(G_OBJECT(html), "mime-body");
- GSimpleActionGroup *simple;
- static const GActionEntry text_view_popup_entries[] = {
- {"open-with", libbalsa_radio_activated, "s", "''", open_with_change_state},
- };
- GMenu *open_menu;
- GtkWidget *submenu;
- menuitem = gtk_menu_item_new_with_label(_("Zoom In"));
- g_signal_connect_swapped(menuitem, "activate",
- G_CALLBACK(bmwt_html_zoom_in), bm);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ from = libbalsa_message_get_headers(balsa_message_get_message(bm))->from;
+ libbalsa_html_prefer_set_load_images(from, g_variant_get_boolean(state);
- menuitem = gtk_menu_item_new_with_label(_("Zoom Out"));
- g_signal_connect_swapped(menuitem, "activate",
- G_CALLBACK(bmwt_html_zoom_out), bm);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ g_simple_action_set_state(G_SIMPLE_ACTION(action), state);
+}
- menuitem = gtk_menu_item_new_with_label(_("Zoom 100%"));
- g_signal_connect_swapped(menuitem, "activate",
- G_CALLBACK(bmwt_html_zoom_reset), bm);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+static void
+save_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkWidget *html = user_data;
+ gpointer mime_body = g_object_get_data(G_OBJECT(html), "mime-body");
- menuitem = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ balsa_mime_widget_ctx_menu_save(html, mime_body);
+}
- if (libbalsa_html_can_select(html)) {
- menuitem = gtk_menu_item_new_with_mnemonic(_("Select _All"));
- g_signal_connect_swapped(menuitem, "activate",
- G_CALLBACK(bmwt_html_select_all_cb), html);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+static void
+print_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkWidget *html = user_data;
- menuitem = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- }
+ libbalsa_html_print(html);
+}
- /* Set up the "open-with" action: */
+static void
+bmwt_populate_popup_menu(BalsaMessage * bm,
+ GtkWidget * html,
+ GMenu * menu)
+{
+ GSimpleActionGroup *simple;
+ static const GActionEntry text_view_popup_entries[] = {
+ {"zoom-in", zoom_in_activated},
+ {"zoom-out", zoom_out_activated},
+ {"zoom-reset", zoom_reset_activated},
+ {"select-all", select_all_activated},
+ {"open-with", libbalsa_radio_activated, "s", "''", html_open_with_change_state},
+ {"save", save_activated},
+ {"print", print_activated},
+ {"prefer-html", NULL, NULL, "false", prefer_html_change_state},
+ {"load-images", NULL, NULL, "false", load_images_change_state}
+ };
+ GAction *print_action;
+ GMenu *open_menu;
+ GMenu *section;
+ InternetAddressList *from;
+
+ /* Set up the actions: */
simple = g_simple_action_group_new();
g_action_map_add_action_entries(G_ACTION_MAP(simple),
text_view_popup_entries,
G_N_ELEMENTS(text_view_popup_entries),
- mime_body);
- gtk_widget_insert_action_group(GTK_WIDGET(menu),
+ html);
+ gtk_widget_insert_action_group(GTK_WIDGET(html),
"text-view-popup",
G_ACTION_GROUP(simple));
+
+ print_action = g_action_map_lookup_action(G_ACTION_MAP(simple), "print");
g_object_unref(simple);
+ section = g_menu_new();
+
+ g_menu_append(section, _("Zoom In"), "text-view-popup.zoom-in");
+ g_menu_append(section, _("Zoom Out"), "text-view-popup.zoom-out");
+ g_menu_append(section, _("Zoom 100%"), "text-view-popup.zoom-reset");
+
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
+
+ if (libbalsa_html_can_select(html)) {
+ section = g_menu_new();
+ g_menu_append(section, _("Select _All"), "text-view-popup.select-all");
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
+ }
+
+ section = g_menu_new();
+
open_menu = g_menu_new();
libbalsa_vfs_fill_menu_by_content_type(open_menu, "text/html",
"text-view-popup.open-with");
- submenu = gtk_menu_new_from_model(G_MENU_MODEL(open_menu));
+
+ g_menu_append_submenu(section, _("Open…"), G_MENU_MODEL(open_menu));
g_object_unref(open_menu);
- menuitem = gtk_menu_item_new_with_label(_("Open…"));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ g_menu_append(section, _("Save…"), "text-view-popup.save");
- menuitem = gtk_menu_item_new_with_label(_("Save…"));
- g_signal_connect(menuitem, "activate",
- G_CALLBACK(balsa_mime_widget_ctx_menu_save),
- mime_body);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
- menuitem = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ section = g_menu_new();
- menuitem = gtk_menu_item_new_with_label(_("Print…"));
- g_signal_connect_swapped(menuitem, "activate",
- G_CALLBACK(libbalsa_html_print), html);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_set_sensitive(menuitem, libbalsa_html_can_print(html));
+ g_menu_append(section, _("Print…"), "text-view-popup.print");
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(print_action),
+ libbalsa_html_can_print(html));
- menuitem = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
from = libbalsa_message_get_headers(balsa_message_get_message(bm))->from;
- menuitem = gtk_check_menu_item_new_with_label(_("Prefer HTML for this sender"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
- libbalsa_html_get_prefer_html(from));
- gtk_widget_set_sensitive(menuitem, from != NULL);
- g_signal_connect(menuitem, "toggled", G_CALLBACK(bmwt_html_prefer_html_changed), from);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
- menuitem = gtk_check_menu_item_new_with_label(_("Load images for this sender"));
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
- libbalsa_html_get_load_images(from));
- gtk_widget_set_sensitive(menuitem, from != NULL);
- g_signal_connect(menuitem, "toggled", G_CALLBACK(bmwt_html_load_images_changed), from);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ section = g_menu_new();
- gtk_widget_show_all(GTK_WIDGET(menu));
+ g_menu_append(section, _("Prefer HTML for this sender"), "text-view-popup.prefer-html");
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(prefer_html_action),
+ libbalsa_html_get_prefer_html(from));
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(prefer_html_action), from != NULL);
+
+ g_menu_append(section, _("Load images for this sender") "text-view-popup.prefer-html");
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(load_images_action),
+ libbalsa_html_get_load_images(from));
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(load_images_action), from != NULL);
+
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
+
+ g_object_set_data(G_OBJECT(html), "bm", bm);
}
static gboolean
bmwt_html_popup_context_menu(GtkWidget * html, BalsaMessage * bm)
{
- GtkWidget *menu;
+ GtkWidget *popover;
const GdkEvent *event;
GdkEvent *current_event = NULL;
- menu = gtk_menu_new();
- bmwt_html_populate_popup_menu(bm, html, GTK_MENU(menu));
+ popover = g_object_get_data(G_OBJECT(html), "popover");
+ if (popover == NULL) {
+ GMenu *menu;
+
+ menu = g_menu_new();
+ bmwt_populate_popup_menu(bm, html, menu);
+ popover = gtk_popover_new_from_model(html, G_MENU_MODEL(menu));
+ g_object_set_data(G_OBJECT(html), "popover", popover);
+ }
/* In WebKit2, the context menu signal is asynchronous, so the
* GdkEvent is no longer current; instead it is preserved and passed
@@ -1271,14 +1348,19 @@ bmwt_html_popup_context_menu(GtkWidget * html, BalsaMessage * bm)
event = g_object_get_data(G_OBJECT(html), LIBBALSA_HTML_POPUP_EVENT);
if (event == NULL)
event = current_event = gtk_get_current_event();
- if (event != NULL)
- gtk_menu_popup_at_pointer(GTK_MENU(menu),
- (GdkEvent *) event);
- else
- gtk_menu_popup_at_widget(GTK_MENU(menu),
- GTK_WIDGET(bm),
- GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER,
- NULL);
+
+ if (event != NULL && gdk_event_triggers_context_menu(event)) {
+ GdkRectangle rectangle;
+
+ /* Pop up above the pointer */
+ rectangle.x = event->button.x;
+ rectangle.width = 0;
+ rectangle.y = event->button.y;
+ rectangle.height = 0;
+ gtk_popover_set_pointing_to(GTK_POPOVER(popover), &rectangle);
+ }
+ gtk_popover_popup(GTK_POPOVER(popover));
+
if (current_event != NULL)
gdk_event_free(current_event);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]