[balsa/gtk4: 32/311] Various: Port menus to GtkPopover
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/gtk4: 32/311] Various: Port menus to GtkPopover
- Date: Fri, 17 Dec 2021 19:53:05 +0000 (UTC)
commit 167e7c9434138e815b6aab7a3ea76e2e663cea99
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Mon May 11 22:55:33 2020 -0400
Various: Port menus to GtkPopover
libbalsa/html.c | 9 +-
libbalsa/html.h | 1 -
src/balsa-index.c | 6 +-
src/balsa-mblist.c | 26 +--
src/balsa-message.c | 4 +-
src/balsa-mime-widget-image.c | 4 +-
src/balsa-mime-widget-text.c | 59 +-----
src/mailbox-node.c | 439 +++++++++++++++++++++++++++---------------
src/mailbox-node.h | 3 +-
src/sendmsg-window.c | 10 -
10 files changed, 322 insertions(+), 239 deletions(-)
---
diff --git a/libbalsa/html.c b/libbalsa/html.c
index 4ed0f6b30..fe7c6e985 100644
--- a/libbalsa/html.c
+++ b/libbalsa/html.c
@@ -1163,15 +1163,8 @@ libbalsa_html_get_selection_bounds(GtkWidget * widget,
}
/*
- * Get the WebKitWebView widget from the container; we need to connect
- * to its "populate-popup" signal.
+ * Get the view widget
*/
-GtkWidget *
-libbalsa_html_popup_menu_widget(GtkWidget * widget)
-{
- return NULL;
-}
-
GtkWidget *
libbalsa_html_get_view_widget(GtkWidget * widget)
{
diff --git a/libbalsa/html.h b/libbalsa/html.h
index e68867444..72ab8c9ca 100644
--- a/libbalsa/html.h
+++ b/libbalsa/html.h
@@ -70,7 +70,6 @@ gboolean libbalsa_html_get_selection_bounds(GtkWidget * widget,
selection_bounds);
#define LIBBALSA_HTML_POPUP_EVENT "libbalsa-html-popup-event"
-GtkWidget *libbalsa_html_popup_menu_widget(GtkWidget * widget);
GtkWidget *libbalsa_html_get_view_widget(GtkWidget * widget);
guint64 libbalsa_html_cache_size(void);
diff --git a/src/balsa-index.c b/src/balsa-index.c
index aa28b9144..2efbfef6a 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -244,11 +244,6 @@ bndx_destroy(GObject * obj)
bindex->search_iter = NULL;
}
- if (bindex->popup_menu) {
- g_object_unref(bindex->popup_menu);
- bindex->popup_menu = NULL;
- }
-
if (bindex->selection_changed_idle_id != 0) {
g_source_remove(bindex->selection_changed_idle_id);
bindex->selection_changed_idle_id = 0;
@@ -2219,6 +2214,7 @@ bndx_do_popup(BalsaIndex * index)
/* Replace the existing submenu */
g_menu_remove(index->popup_menu, index->move_position);
g_menu_insert_item(index->popup_menu, index->move_position, item);
+ g_object_unref(item);
gtk_widget_get_allocation(GTK_WIDGET(index), &allocation);
if (event != NULL && gdk_event_triggers_context_menu((GdkEvent *) event)) {
diff --git a/src/balsa-mblist.c b/src/balsa-mblist.c
index 2d299b21d..8252bb9e4 100644
--- a/src/balsa-mblist.c
+++ b/src/balsa-mblist.c
@@ -737,18 +737,22 @@ bmbl_do_popup(GtkTreeView *tree_view,
gtk_tree_path_free(path);
}
- menu = balsa_mailbox_node_get_context_menu(mbnode);
- g_object_ref(menu);
- g_object_ref_sink(menu);
- if (event)
- gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *) event);
- else
- gtk_menu_popup_at_widget(GTK_MENU(menu), GTK_WIDGET(tree_view),
- GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER,
- NULL);
- g_object_unref(menu);
+ menu = balsa_mailbox_node_get_context_menu(mbnode, GTK_WIDGET(tree_view));
+
+ if (event != NULL && gdk_event_triggers_context_menu((GdkEvent *) event)) {
+ GdkRectangle rectangle;
+
+ /* Pop up above the pointer */
+ rectangle.x = event->x;
+ rectangle.width = 0;
+ rectangle.y = event->y;
+ rectangle.height = 0;
+ gtk_popover_set_pointing_to(GTK_POPOVER(menu), &rectangle);
+ }
+
+ gtk_popover_popup(GTK_POPOVER(menu));
- if (mbnode)
+ if (mbnode != NULL)
g_object_unref(mbnode);
}
diff --git a/src/balsa-message.c b/src/balsa-message.c
index 19c21c54d..d6a61ae96 100644
--- a/src/balsa-message.c
+++ b/src/balsa-message.c
@@ -1757,8 +1757,10 @@ display_content(BalsaMessage * balsa_message)
balsa_message->parts_menu = g_menu_new();
+ /* Detach any existing popup: */
if (balsa_message->parts_popup != NULL)
- g_object_unref(balsa_message->parts_popup);
+ gtk_popover_set_relative_to(GTK_POPOVER(balsa_message->parts_popup), NULL);
+
balsa_message->parts_popup =
gtk_popover_new_from_model(balsa_message->attach_button,
G_MENU_MODEL(balsa_message->parts_menu));
diff --git a/src/balsa-mime-widget-image.c b/src/balsa-mime-widget-image.c
index f358b9457..ee1561057 100644
--- a/src/balsa-mime-widget-image.c
+++ b/src/balsa-mime-widget-image.c
@@ -146,7 +146,7 @@ balsa_image_button_press_cb(GtkGestureMultiPress *multi_press_gesture,
gdouble y,
gpointer user_data)
{
- GtkMenu *menu = user_data;
+ GtkPopover *menu = user_data;
GtkGesture *gesture;
GdkEventSequence *sequence;
const GdkEvent *event;
@@ -156,7 +156,7 @@ balsa_image_button_press_cb(GtkGestureMultiPress *multi_press_gesture,
event = gtk_gesture_get_last_event(gesture, sequence);
if (gdk_event_triggers_context_menu(event)) {
- gtk_menu_popup_at_pointer(menu, event);
+ gtk_popover_popup(menu);
gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
}
}
diff --git a/src/balsa-mime-widget-text.c b/src/balsa-mime-widget-text.c
index 23eb6f767..4c138bbdf 100644
--- a/src/balsa-mime-widget-text.c
+++ b/src/balsa-mime-widget-text.c
@@ -1210,7 +1210,7 @@ bmwt_html_populate_popup_menu(BalsaMessage * bm,
g_object_unref(simple);
open_menu = g_menu_new();
- libbalsa_vfs_fill_menu_by_content_type(open_menu, "text/plain",
+ 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_object_unref(open_menu);
@@ -1285,39 +1285,12 @@ bmwt_html_popup_context_menu(GtkWidget * html, BalsaMessage * bm)
return TRUE;
}
-static void
-bmwt_html_gesture_pressed_cb(GtkGestureMultiPress *multi_press,
- gint n_press,
- gdouble x,
- gdouble y,
- gpointer user_data)
-{
- GtkGesture *gesture;
- const GdkEvent *event;
- BalsaMessage *bm = user_data;
-
- gesture = GTK_GESTURE(multi_press);
- event = gtk_gesture_get_last_event(gesture, gtk_gesture_get_last_updated_sequence(gesture));
-
- if (gdk_event_triggers_context_menu(event)) {
- GtkWidget *html;
-
- html = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
- bmwt_html_popup_context_menu(html, bm);
- }
-}
-
-static void
-bmwt_html_populate_popup_cb(GtkWidget * widget, GtkMenu * menu, gpointer data)
+static gboolean
+balsa_gtk_html_button_press_cb(GtkWidget * html, GdkEventButton * event,
+ BalsaMessage * bm)
{
- BalsaMessage *bm =
- g_object_get_data(G_OBJECT(widget), "balsa-message");
- GtkWidget *html = data;
-
- /* Remove WebKitWebView's items--they're irrelevant and confusing */
- gtk_container_foreach(GTK_CONTAINER(menu),
- (GtkCallback) gtk_widget_destroy, NULL);
- bmwt_html_populate_popup_menu(bm, html, menu);
+ return(gdk_event_triggers_context_menu((GdkEvent *) event)
+ ? balsa_gtk_html_popup(html, bm) : GDK_EVENT_PROPAGATE);
}
static BalsaMimeWidget *
@@ -1326,7 +1299,6 @@ bm_widget_new_html(BalsaMessage * bm, LibBalsaMessageBody * mime_body)
BalsaMimeWidgetText *mwt = g_object_new(BALSA_TYPE_MIME_WIDGET_TEXT, NULL);
InternetAddressList *from;
GtkWidget *widget;
- GtkWidget *popup_menu;
GtkEventController *key_controller;
from = libbalsa_message_get_headers(balsa_message_get_message(bm))->from;
@@ -1343,21 +1315,10 @@ bm_widget_new_html(BalsaMessage * bm, LibBalsaMessageBody * mime_body)
g_signal_connect(key_controller, "key-pressed",
G_CALLBACK(balsa_mime_widget_key_pressed), bm);
- if ((popup_menu = libbalsa_html_popup_menu_widget(widget)) != NULL) {
- g_object_set_data(G_OBJECT(popup_menu), "balsa-message", bm);
- g_signal_connect(popup_menu, "populate-popup",
- G_CALLBACK(bmwt_html_populate_popup_cb), widget);
- } else {
- GtkGesture *gesture;
-
- gesture = gtk_gesture_multi_press_new(widget);
- gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 0);
- g_signal_connect(gesture, "pressed",
- G_CALLBACK(bmwt_html_gesture_pressed_cb), bm);
-
- g_signal_connect(widget, "popup-menu",
- G_CALLBACK(bmwt_html_popup_context_menu), bm);
- }
+ g_signal_connect(widget, "button-press-event",
+ G_CALLBACK(balsa_gtk_html_button_press_cb), bm);
+ g_signal_connect(widget, "popup-menu",
+ G_CALLBACK(balsa_gtk_html_popup), bm);
return (BalsaMimeWidget *) mwt;
}
diff --git a/src/mailbox-node.c b/src/mailbox-node.c
index 03dd11189..8cc7916d4 100644
--- a/src/mailbox-node.c
+++ b/src/mailbox-node.c
@@ -89,6 +89,7 @@ static guint balsa_mailbox_node_signals[LAST_SIGNAL];
struct _BalsaMailboxNode {
GObject object;
+
BalsaMailboxNode *parent; /* NULL for root-level folders & mailboxes */
LibBalsaMailbox *mailbox; /* != NULL for leaves only */
gchar *name; /* used for folders, i.e. when mailbox == NULL */
@@ -101,6 +102,9 @@ struct _BalsaMailboxNode {
int delim; /* IMAP delimiter so that we do not need to check it
* too often. */
+ GtkWidget *context_menu;
+ GtkWidget *relative_to;
+
unsigned subscribed:1; /* Used only by remote */
unsigned list_inbox:1; /* Used only by remote */
unsigned scanned:1; /* IMAP flag */
@@ -857,225 +861,358 @@ bmbn_scan_children_idle(BalsaMailboxNode ** mbnode)
/* ---------------------------------------------------------------------
* Context menu, helpers, and callbacks.
* --------------------------------------------------------------------- */
+
+gboolean
+balsa_mailbox_node_is_imap(const BalsaMailboxNode *mbnode)
+{
+ return (mbnode != NULL) &&
+ (mbnode->server != NULL) &&
+ (strcmp(libbalsa_server_get_protocol(mbnode->server), "imap") == 0);
+}
+
static void
-add_menu_entry(GtkWidget * menu, const gchar * label, GCallback cb,
- BalsaMailboxNode * mbnode)
+add_mbox_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- GtkWidget *menuitem;
+ mailbox_conf_add_mbox_cb(NULL, user_data);
+}
- menuitem = label ? gtk_menu_item_new_with_mnemonic(label)
- : gtk_separator_menu_item_new();
+static void
+add_maildir_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ mailbox_conf_add_maildir_cb(NULL, user_data);
+}
- if (cb)
- g_signal_connect(menuitem, "activate",
- G_CALLBACK(cb), mbnode);
+static void
+add_mh_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ mailbox_conf_add_mh_cb(NULL, user_data);
+}
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
+static void
+add_imap_folder_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ folder_conf_add_imap_cb(NULL, user_data);
}
static void
-mb_open_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+add_imap_subfolder_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
- balsa_mblist_open_mailbox(mbnode->mailbox);
+ folder_conf_add_imap_sub_cb(NULL, user_data);
}
static void
-mb_close_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+rescan_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
- balsa_window_close_mbnode(balsa_app.main_window, mbnode);
+ BalsaMailboxNode *mbnode = user_data;
+ gchar *current_mailbox_url;
+ GPtrArray *url_array;
+
+ current_mailbox_url = g_strdup(balsa_app.current_mailbox_url);
+ balsa_mailbox_node_rescan(mbnode);
+
+ /* Reopen mailboxes */
+ url_array = g_ptr_array_new();
+ if (current_mailbox_url)
+ g_ptr_array_add(url_array, current_mailbox_url);
+ balsa_add_open_mailbox_urls(url_array);
+ g_ptr_array_add(url_array, NULL);
+ balsa_open_mailbox_list((gchar **) g_ptr_array_free(url_array, FALSE));
}
static void
-mb_conf_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+show_properties_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
+ BalsaMailboxNode *mbnode = user_data;
+
balsa_mailbox_node_show_prop_dialog(mbnode);
}
static void
-mb_del_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+delete_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- if(mbnode->mailbox)
- mailbox_conf_delete(mbnode);
- else folder_conf_delete(mbnode);
+ BalsaMailboxNode *mbnode = user_data;
+
+ if (mbnode->mailbox != NULL)
+ mailbox_conf_delete(mbnode);
+ else
+ folder_conf_delete(mbnode);
}
static void
-mb_inbox_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+context_menu_set_enabled(BalsaMailboxNode *mbnode)
{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
- config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_INBOX);
+ gboolean is_open;
+ GActionGroup *action_group;
+ GActionMap *action_map;
+ GAction *action;
+
+ action_group = gtk_widget_get_action_group(mbnode->relative_to, "mbnode");
+ action_map = G_ACTION_MAP(action_group);
+
+ is_open = MAILBOX_OPEN(mbnode->mailbox);
+
+ action = g_action_map_lookup_action(action_map, "open");
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(action), !is_open);
+
+ action = g_action_map_lookup_action(action_map, "close");
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(action), is_open);
}
static void
-mb_sentbox_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+open_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
- config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_SENT);
+ BalsaMailboxNode *mbnode = user_data;
+
+ balsa_mblist_open_mailbox(mbnode->mailbox);
+ context_menu_set_enabled(mbnode);
}
static void
-mb_trash_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+close_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
- config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_TRASH);
+ BalsaMailboxNode *mbnode = user_data;
+
+ balsa_window_close_mbnode(balsa_app.main_window, mbnode);
+ context_menu_set_enabled(mbnode);
}
static void
-mb_draftbox_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+mark_as_inbox_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
- config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_DRAFT);
+ BalsaMailboxNode *mbnode = user_data;
+
+ config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_INBOX);
}
static void
-mb_rescan_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+mark_as_sentbox_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- gchar *current_mailbox_url;
- GPtrArray *url_array;
+ BalsaMailboxNode *mbnode = user_data;
- current_mailbox_url = g_strdup(balsa_app.current_mailbox_url);
- balsa_mailbox_node_rescan(mbnode);
+ config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_SENT);
+}
- /* Reopen mailboxes */
- url_array = g_ptr_array_new();
- if (current_mailbox_url)
- g_ptr_array_add(url_array, current_mailbox_url);
- balsa_add_open_mailbox_urls(url_array);
- g_ptr_array_add(url_array, NULL);
- balsa_open_mailbox_list((gchar **) g_ptr_array_free(url_array, FALSE));
+static void
+mark_as_trash_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ BalsaMailboxNode *mbnode = user_data;
+
+ config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_TRASH);
}
static void
-mb_filter_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+mark_as_draftbox_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- if (mbnode->mailbox)
- filters_run_dialog(mbnode->mailbox,
- GTK_WINDOW(balsa_app.main_window));
- else
- /* FIXME : Perhaps should we be able to apply filters on
- folders (ie recurse on all mailboxes in it), but there are
- problems of infinite recursion (when one mailbox being
- filtered is also the destination of the filter action (eg a
- copy)). So let's see that later :) */
- libbalsa_information_parented(GTK_WINDOW(balsa_app.main_window),
- LIBBALSA_INFORMATION_MESSAGE, _("You can apply filters only on mailbox"));
+ BalsaMailboxNode *mbnode = user_data;
+
+ config_mailbox_set_as_special(mbnode->mailbox, SPECIAL_DRAFT);
}
static void
-mb_empty_trash_cb(GtkWidget * widget, BalsaMailboxNode * mbnode)
+empty_trash_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
empty_trash(balsa_app.main_window);
}
-gboolean
-balsa_mailbox_node_is_imap(const BalsaMailboxNode *mbnode)
+static void
+filters_activated(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- return (mbnode != NULL) &&
- (mbnode->server != NULL) &&
- (strcmp(libbalsa_server_get_protocol(mbnode->server), "imap") == 0);
+ BalsaMailboxNode *mbnode = user_data;
+
+ if (mbnode->mailbox != NULL) {
+ filters_run_dialog(mbnode->mailbox,
+ GTK_WINDOW(balsa_app.main_window));
+ } else {
+ /* FIXME : Perhaps should we be able to apply filters on
+ folders (ie recurse on all mailboxes in it), but there are
+ problems of infinite recursion (when one mailbox being
+ filtered is also the destination of the filter action (eg a
+ copy)). So let's see that later :) */
+ g_print("You can apply filters only on mailbox\n");
+ }
}
-GtkWidget *
-balsa_mailbox_node_get_context_menu(BalsaMailboxNode * mbnode)
-{
- GtkWidget *menu;
- GtkWidget *submenu;
- GtkWidget *menuitem;
+static GtkWidget *
+create_context_menu(BalsaMailboxNode *mbnode,
+ GtkWidget *relative_to)
+{
+ static const GActionEntry entries[] = {
+ {"add-mbox", add_mbox_activated},
+ {"add-maildir", add_maildir_activated},
+ {"add-mh", add_mh_activated},
+ {"add-imap-folder", add_imap_folder_activated},
+ {"add-imap-subfolder", add_imap_subfolder_activated},
+ {"rescan", rescan_activated},
+ {"show-properties", show_properties_activated},
+ {"delete", delete_activated},
+ {"open", open_activated},
+ {"close", close_activated},
+ {"mark-as-inbox", mark_as_inbox_activated},
+ {"mark-as-sentbox", mark_as_sentbox_activated},
+ {"mark-as-trash", mark_as_trash_activated},
+ {"mark-as-draftbox", mark_as_draftbox_activated},
+ {"empty-trash", empty_trash_activated},
+ {"filters", filters_activated},
+ };
+ GSimpleActionGroup *simple;
+ GMenu *menu;
+ GMenu *submenu;
+ GMenu *section;
LibBalsaMailbox *mailbox;
gboolean special;
+ GtkWidget *context_menu;
+
+ simple = g_simple_action_group_new();
+ g_action_map_add_action_entries(G_ACTION_MAP(simple),
+ entries,
+ G_N_ELEMENTS(entries),
+ mbnode);
+ gtk_widget_insert_action_group(GTK_WIDGET(relative_to),
+ "mbnode",
+ G_ACTION_GROUP(simple));
+ g_object_unref(simple);
+
+ menu = g_menu_new();
+
+ /* "New" submenu */
+ submenu = g_menu_new();
+ g_menu_append(submenu, _("Local _mbox mailbox…"), "mbnode.add-mbox");
+ g_menu_append(submenu, _("Local Mail_dir mailbox…"), "mbnode.add-maildir");
+ g_menu_append(submenu, _("Local M_H mailbox…"), "mbnode.add-mh");
+
+ section = g_menu_new();
+ g_menu_append(section, _("Remote IMAP _folder…"), "mbnode.add-imap-folder");
+
+ if (balsa_mailbox_node_is_imap(mbnode))
+ g_menu_append(section, _("Remote IMAP _subfolder…"), "mbnode.add-imap-subfolder");
+
+ g_menu_append_section(submenu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
- /* g_return_val_if_fail(mailbox != NULL, NULL); */
-
- menu = gtk_menu_new();
- /* it's a single-use menu, so we must destroy it when we're done */
- g_signal_connect(menu, "selection-done",
- G_CALLBACK(gtk_widget_destroy), NULL);
-
- submenu = gtk_menu_new();
- add_menu_entry(submenu, _("Local _mbox mailbox…"),
- G_CALLBACK(mailbox_conf_add_mbox_cb), NULL);
- add_menu_entry(submenu, _("Local Mail_dir mailbox…"),
- G_CALLBACK(mailbox_conf_add_maildir_cb), NULL);
- add_menu_entry(submenu, _("Local M_H mailbox…"),
- G_CALLBACK(mailbox_conf_add_mh_cb), NULL);
- add_menu_entry(submenu, NULL, NULL, mbnode);
- add_menu_entry(submenu, _("Remote IMAP _folder…"),
- G_CALLBACK(folder_conf_add_imap_cb), NULL);
- if (balsa_mailbox_node_is_imap(mbnode)) {
- add_menu_entry(submenu, _("Remote IMAP _subfolder…"),
- G_CALLBACK(folder_conf_add_imap_sub_cb), mbnode);
- }
- gtk_widget_show(submenu);
-
/* Translators: popup menu item "New" mailbox or folder */
- menuitem = gtk_menu_item_new_with_mnemonic(C_("mailbox", "_New"));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
- gtk_widget_show(menuitem);
-
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
- if(mbnode == NULL) {/* clicked on the empty space */
- add_menu_entry(menu, _("_Rescan"), G_CALLBACK(mb_rescan_cb),
- NULL);
- return menu;
+ g_menu_append_submenu(menu, C_("mailbox", "_New"), G_MENU_MODEL(submenu));
+ g_object_unref(submenu);
+
+ section = g_menu_new();
+ if (mbnode == NULL) {/* clicked on the empty space */
+ g_menu_append(section, _("_Rescan"), "mbnode.rescan");
+ } else {
+ mbnode->relative_to = relative_to;
+
+ /* If we didn't click on a mailbox node then there is only one option. */
+ if (g_signal_has_handler_pending(mbnode,
+ balsa_mailbox_node_signals
+ [SHOW_PROP_DIALOG], 0, FALSE))
+ g_menu_append(section, _("_Properties…"), "mbnode.show-properties");
+
+ if (g_signal_has_handler_pending(mbnode,
+ balsa_mailbox_node_signals[APPEND_SUBTREE],
+ 0, FALSE))
+ g_menu_append(section, _("_Rescan"), "mbnode.rescan");
+
+ if (mbnode->config_prefix != NULL)
+ g_menu_append(section, _("_Delete"), "mbnode.delete");
+
+ if ((mailbox = mbnode->mailbox) != NULL) {
+ g_menu_append(section, _("_Open"), "mbnode.open");
+ g_menu_append(section, _("_Close"), "mbnode.close");
+ context_menu_set_enabled(mbnode);
+
+ special = ( mailbox == balsa_app.inbox
+ || mailbox == balsa_app.sentbox
+ || mailbox == balsa_app.draftbox
+ || mailbox == balsa_app.outbox
+ || mailbox == balsa_app.trash);
+ if (!special && !mbnode->config_prefix)
+ g_menu_append(section, _("_Delete"), "mbnode.delete");
+
+ if (!special) {
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
+ section = g_menu_new();
+
+ g_menu_append(section, _("Mark as _Inbox"), "mbnode.mark-as-inbox");
+ g_menu_append(section, _("_Mark as Sentbox"), "mbnode.mark-as-sentbox");
+ g_menu_append(section, _("Mark as _Trash"), "mbnode.mark-as-trash");
+ g_menu_append(section, _("Mark as D_raftbox"), "mbnode.mark-as-draftbox");
+ } else if (mailbox == balsa_app.trash) {
+ g_menu_append(section, _("_Empty trash"), "mbnode.empty-trash");
+ }
+
+ /* FIXME : No test on mailbox type is made yet, should we ? */
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
+ section = g_menu_new();
+
+ g_menu_append(section, _("_Edit/Apply filters"), "mbnode.filters");
+ // G_CALLBACK(mb_filter_cb), mbnode);
+ }
}
- /* If we didn't click on a mailbox node then there is only one option. */
- add_menu_entry(menu, NULL, NULL, NULL);
- if (g_signal_has_handler_pending(mbnode,
- balsa_mailbox_node_signals
- [SHOW_PROP_DIALOG], 0, FALSE))
- add_menu_entry(menu, _("_Properties…"),
- G_CALLBACK(mb_conf_cb), mbnode);
+ g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
+ g_object_unref(section);
- if (g_signal_has_handler_pending(mbnode,
- balsa_mailbox_node_signals
- [APPEND_SUBTREE], 0, FALSE))
- add_menu_entry(menu, _("_Rescan"),
- G_CALLBACK(mb_rescan_cb), mbnode);
+ context_menu = gtk_popover_new_from_model(relative_to, G_MENU_MODEL(menu));
+ g_object_unref(menu);
- if (mbnode->config_prefix)
- add_menu_entry(menu, _("_Delete"), G_CALLBACK(mb_del_cb), mbnode);
+ return context_menu;
+}
- if (!(mailbox = mbnode->mailbox))
- return menu;
+GtkWidget *
+balsa_mailbox_node_get_context_menu(BalsaMailboxNode *mbnode,
+ GtkWidget *relative_to)
+{
+ GtkWidget *context_menu;
- if (!MAILBOX_OPEN(mailbox))
- add_menu_entry(menu, _("_Open"), G_CALLBACK(mb_open_cb), mbnode);
- else
- add_menu_entry(menu, _("_Close"), G_CALLBACK(mb_close_cb), mbnode);
-
- special = ( mailbox == balsa_app.inbox
- || mailbox == balsa_app.sentbox
- || mailbox == balsa_app.draftbox
- || mailbox == balsa_app.outbox
- || mailbox == balsa_app.trash);
- if (!special && !mbnode->config_prefix)
- add_menu_entry(menu, _("_Delete"), G_CALLBACK(mb_del_cb), mbnode);
-
- if (!special) {
- add_menu_entry(menu, NULL, NULL, NULL);
- add_menu_entry(menu, _("Mark as _Inbox"),
- G_CALLBACK(mb_inbox_cb), mbnode);
- add_menu_entry(menu, _("_Mark as Sentbox"),
- G_CALLBACK(mb_sentbox_cb), mbnode);
- add_menu_entry(menu, _("Mark as _Trash"),
- G_CALLBACK(mb_trash_cb), mbnode);
- add_menu_entry(menu, _("Mark as D_raftbox"),
- G_CALLBACK(mb_draftbox_cb), mbnode);
- } else if (mailbox == balsa_app.trash)
- add_menu_entry(menu, _("_Empty trash"),
- G_CALLBACK(mb_empty_trash_cb), mbnode);
-
- /* FIXME : No test on mailbox type is made yet, should we ? */
- add_menu_entry(menu, NULL, NULL, NULL);
- add_menu_entry(menu, _("_Edit/Apply filters"),
- G_CALLBACK(mb_filter_cb), mbnode);
-
- return menu;
+ if (mbnode == NULL) {
+ static GtkWidget *null_context_menu;
+
+ if (null_context_menu == NULL) {
+ null_context_menu =
+ create_context_menu(NULL, relative_to);
+ }
+ context_menu = null_context_menu;
+ } else {
+ if (mbnode->context_menu == NULL) {
+ mbnode->context_menu =
+ create_context_menu(mbnode, relative_to);
+ }
+ context_menu = mbnode->context_menu;
+ }
+
+ return context_menu;
}
/* ---------------------------------------------------------------------
diff --git a/src/mailbox-node.h b/src/mailbox-node.h
index ef68b8c66..6683af0a3 100644
--- a/src/mailbox-node.h
+++ b/src/mailbox-node.h
@@ -58,7 +58,8 @@ BalsaMailboxNode *balsa_mailbox_node_new_imap_folder(LibBalsaServer* s,
const char*p);
BalsaMailboxNode *balsa_mailbox_node_new_from_config(const gchar* prefix);
-GtkWidget *balsa_mailbox_node_get_context_menu(BalsaMailboxNode * mbnode);
+GtkWidget *balsa_mailbox_node_get_context_menu(BalsaMailboxNode *mbnode,
+ GtkWidget *relative_to);
void balsa_mailbox_node_show_prop_dialog(BalsaMailboxNode * mbnode);
void balsa_mailbox_node_append_subtree(BalsaMailboxNode * mbnode);
void balsa_mailbox_node_load_config(BalsaMailboxNode* mn, const gchar* prefix);
diff --git a/src/sendmsg-window.c b/src/sendmsg-window.c
index d99c21999..dc5c9fb19 100644
--- a/src/sendmsg-window.c
+++ b/src/sendmsg-window.c
@@ -1790,22 +1790,12 @@ add_attachment(BalsaSendmsg * bsmsg, const gchar *filename,
g_object_unref(menu_item);
}
- if (can_inline || !is_a_temp_file) {
- /* Need a separator */
- menu_item = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(attach_data->popup_menu), menu_item);
- }
-
/* an attachment can be removed */
section = g_menu_new();
g_menu_append(section, _("Remove"), "attachment.remove");
g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
g_object_unref(section);
- /* Insert another separator */
- menu_item = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(attach_data->popup_menu), menu_item);
-
/* add the usual vfs menu so the user can inspect what (s)he actually
attached... (only for non-message attachments) */
if (!is_fwd_message) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]