[balsa/popover: 6/6] balsa-mblist and friends: Start porting to GMenu



commit 60d056a2b01c01c2c39968d91c966809ce536fa1
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Wed Apr 29 15:52:40 2020 -0400

    balsa-mblist and friends: Start porting to GMenu
    
    Very incomplete--badly broken!

 src/balsa-mblist.c                | 126 ++++++++------------------------------
 src/balsa-mblist.h                |   2 +-
 src/balsa-message.c               | 103 ++++++++++++++++++-------------
 src/balsa-mime-widget-callbacks.c |   4 +-
 src/balsa-mime-widget-callbacks.h |   2 +-
 src/balsa-mime-widget-message.c   |   2 -
 6 files changed, 90 insertions(+), 149 deletions(-)
---
diff --git a/src/balsa-mblist.c b/src/balsa-mblist.c
index f1c3ddda3..29674d8e4 100644
--- a/src/balsa-mblist.c
+++ b/src/balsa-mblist.c
@@ -1662,26 +1662,14 @@ struct _BalsaMBListMRUEntry {
     GCallback user_func;
     gpointer user_data;
     gchar *url;
-    GCallback setup_cb;
 };
 typedef struct _BalsaMBListMRUEntry BalsaMBListMRUEntry;
 
 /* The callback that's passed in must fit this prototype, although it's
  * cast as a GCallback */
 typedef void (*MRUCallback) (gchar * url, gpointer user_data);
-/* Callback used internally for letting the option menu know that the
- * option menu needs to be set up */
-typedef void (*MRUSetup) (gpointer user_data);
 
 /* Forward references */
-static GtkWidget *bmbl_mru_menu(GtkWindow * window, GList ** url_list,
-                                GCallback user_func, gpointer user_data,
-                                gboolean allow_empty, GCallback setup_cb);
-static BalsaMBListMRUEntry *bmbl_mru_new(GList ** url_list,
-                                         GCallback user_func,
-                                         gpointer user_data,
-                                         gchar * url);
-static void bmbl_mru_free(BalsaMBListMRUEntry * mru);
 static void bmbl_mru_activate_cb(GtkWidget * widget, gpointer data);
 static void bmbl_mru_show_tree(GtkWidget * widget, gpointer data);
 static void bmbl_mru_selected_cb(GtkTreeSelection * selection,
@@ -1696,113 +1684,52 @@ static void bmbl_mru_activated_cb(GtkTreeView * tree_view,
  *
  * window:      parent window for the `Other...' dialog;
  * url_list:    pointer to a list of urls;
- * user_func:   called when an item is selected, with the url and
- *              the user_data as arguments;
- * user_data:   passed to the user_func callback.
+ * action:      the action to be taken on selecting an item
  *
  * Returns a pointer to a GtkMenu.
  *
  * Takes a list of urls and creates a menu with an entry for each one
  * that resolves to a mailbox, labeled with the mailbox name, with a
- * last entry that pops up the whole mailbox tree. When an item is
- * clicked, user_func is called with the url and user_data as
- * arguments, and the url_list is updated.
+ * last entry that pops up the whole mailbox tree.
  */
 GtkWidget *
-balsa_mblist_mru_menu(GtkWindow * window, GList ** url_list,
-                      GCallback user_func, gpointer user_data)
+balsa_mblist_mru_menu(GtkWindow * window,
+                      GList ** url_list,
+                      const gchar *action)
 {
-    g_return_val_if_fail(url_list != NULL, NULL);
-    return bmbl_mru_menu(window, url_list, user_func, user_data, FALSE,
-                         NULL);
-}
-
-/*
- * bmbl_mru_menu:
- *
- * window, url_list, user_func, user_data:
- *              as for balsa_mblist_mru_menu;
- * allow_empty: if TRUE, a list with an empty url
- *              will be allowed into the menu;
- * setup_cb:    called when the tree has been displayed, to allow the
- *              display to be reset.
- *
- * Returns the GtkMenu.
- */
-static GtkWidget *
-bmbl_mru_menu(GtkWindow * window, GList ** url_list,
-              GCallback user_func, gpointer user_data,
-              gboolean allow_empty, GCallback setup_cb)
-{
-    GtkWidget *menu = gtk_menu_new();
-    GtkWidget *item;
+    GMenu *menu;
+    GMenu *other_menu;
     GList *list;
-    BalsaMBListMRUEntry *mru;
+    GMenuItem *item;
+
+    g_return_val_if_fail(GTK_IS_WINDOW(window));
+    g_return_val_if_fail(url_list != NULL, NULL);
+    g_return_val_if_fail(action != NULL, NULL);
 
-    for (list = *url_list; list; list = g_list_next(list)) {
+    menu = g_menu_new();
+    for (list = *url_list; list != NULL; list = list->next) {
         gchar *url = list->data;
         LibBalsaMailbox *mailbox = balsa_find_mailbox_by_url(url);
 
-        if (mailbox || (allow_empty && !*url)) {
-            mru = bmbl_mru_new(url_list, user_func, user_data, url);
-            item =
-                gtk_menu_item_new_with_label(mailbox ? libbalsa_mailbox_get_name(mailbox) : "");
-            gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-            g_signal_connect_data(item, "activate",
-                                  G_CALLBACK(bmbl_mru_activate_cb), mru,
-                                  (GClosureNotify) bmbl_mru_free,
-                                  (GConnectFlags) 0);
+        if (mailbox != NULL) {
+            const gchar *name = libbalsa_mailbox_get_name(mailbox);
+
+            item = g_menu_item_new(name, NULL);
+            g_menu_item_set_action_and_target(item, action, "s", url);
+            g_menu_append_item(menu, item);
         }
     }
 
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu),
-                          gtk_separator_menu_item_new());
-
-    mru = bmbl_mru_new(url_list, user_func, user_data, NULL);
-    mru->window = window;
-    mru->setup_cb = setup_cb;
-    item = gtk_menu_item_new_with_mnemonic(_("_Other…"));
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-    g_signal_connect_data(item, "activate",
-                          G_CALLBACK(bmbl_mru_show_tree), mru,
-                          (GClosureNotify) g_free, (GConnectFlags) 0);
+    other_menu = g_menu_new();
+    item = g_menu_item_new(_("_Other…"), NULL);
+    g_menu_item_set_action_and_target(item, action, "s", "");
+    g_menu_append_item(other_menu, item);
 
-    gtk_widget_show_all(menu);
+    g_menu_append_section(menu, G_MENU_MODEL(other_menu));
 
     return menu;
 }
 
-/*
- * bmbl_mru_new:
- *
- * url_list, user_func, user_data:
- *              as for balsa_mblist_mru_menu;
- * url:         url of a mailbox.
- *
- * Returns a newly allocated BalsaMBListMRUEntry structure, initialized
- * with the data.
- */
-static BalsaMBListMRUEntry *
-bmbl_mru_new(GList ** url_list, GCallback user_func, gpointer user_data,
-             gchar * url)
-{
-    BalsaMBListMRUEntry *mru = g_new(BalsaMBListMRUEntry, 1);
-
-    mru->url_list = url_list;
-    mru->user_func = user_func;
-    mru->user_data = user_data;
-    mru->url = g_strdup(url);
-
-    return mru;
-}
-
-static void
-bmbl_mru_free(BalsaMBListMRUEntry * mru)
-{
-    g_free(mru->url);
-    g_free(mru);
-}
-
 /*
  * bmbl_mru_activate_cb:
  *
@@ -1899,8 +1826,6 @@ bmbl_mru_show_tree(GtkWidget * widget, gpointer data)
 
     gtk_dialog_run(GTK_DIALOG(dialog));
     gtk_widget_destroy(dialog);
-    if (mru->setup_cb)
-        ((MRUSetup) mru->setup_cb) (mru->user_data);
 }
 
 /*
@@ -2099,7 +2024,6 @@ bmbl_mru_combo_box_changed(GtkComboBox * combo_box,
     mru.window = mro->window;
     mru.url_list = mro->url_list;
     mru.user_func = NULL;
-    mru.setup_cb = NULL;
     mru.user_data = combo_box;
     mru.url = NULL;
     bmbl_mru_show_tree(NULL, &mru);
diff --git a/src/balsa-mblist.h b/src/balsa-mblist.h
index 9b0f1d69e..3d7e9cff3 100644
--- a/src/balsa-mblist.h
+++ b/src/balsa-mblist.h
@@ -51,7 +51,7 @@ BalsaMailboxNode *balsa_mblist_get_node_by_mailbox(BalsaMBList * mblist,
                                                    LibBalsaMailbox *
                                                    mailbox);
 GtkWidget *balsa_mblist_mru_menu(GtkWindow * window, GList ** url_list,
-                                 GCallback user_func, gpointer user_data);
+                                 const gchar *action);
 void balsa_mblist_mru_add(GList ** url_list, const gchar * url);
 void balsa_mblist_mru_drop(GList ** url_list, const gchar * url);
 GtkWidget *balsa_mblist_mru_option_menu(GtkWindow * window, 
diff --git a/src/balsa-message.c b/src/balsa-message.c
index 00238a784..e32614c6e 100644
--- a/src/balsa-message.c
+++ b/src/balsa-message.c
@@ -904,23 +904,11 @@ tree_mult_selection_popup(BalsaMessage * balsa_message, GdkEventButton * event,
     selected = g_list_length(balsa_message->save_all_list);
     if (selected == 1) {
         BalsaPartInfo *info = BALSA_PART_INFO(balsa_message->save_all_list->data);
-        if (info->popup_menu) {
+        if (info->popup_menu != NULL) {
 #if GTK_CHECK_VERSION(3, 22, 0)
-            if (event)
-                gtk_menu_popup_at_pointer(GTK_MENU(info->popup_menu),
-                                          (GdkEvent *) event);
-            else
-                gtk_menu_popup_at_widget(GTK_MENU(info->popup_menu),
-                                         GTK_WIDGET(balsa_message),
-                                         GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER,
-                                         NULL);
+            gtk_popover_popup(GTK_POPOVER(info->popup_menu));
 #else                           /*GTK_CHECK_VERSION(3, 22, 0) */
-            if (event)
-                gtk_menu_popup(GTK_MENU(info->popup_menu), NULL, NULL, NULL,
-                               NULL, event->button, event->time);
-            else
-                gtk_menu_popup(GTK_MENU(info->popup_menu), NULL, NULL, NULL,
-                               NULL, 0, gtk_get_current_event_time());
+            gtk_widget_show_all(info->popup_menu);
 #endif                          /*GTK_CHECK_VERSION(3, 22, 0) */
         }
         g_list_free(balsa_message->save_all_list);
@@ -1011,14 +999,12 @@ tree_button_press_cb(GtkWidget * widget, GdkEventButton * event,
                                      FALSE);
             if (gtk_tree_model_get_iter (model, &iter, path)) {
                 gtk_tree_model_get(model, &iter, PART_INFO_COLUMN, &info, -1);
-                if (info) {
-                    if (info->popup_menu) {
+                if (info != NULL) {
+                    if (info->popup_menu != NULL) {
 #if GTK_CHECK_VERSION(3, 22, 0)
-                        gtk_menu_popup_at_pointer(GTK_MENU(info->popup_menu),
-                                                  (GdkEvent *) event);
+                        gtk_popover_popup(GTK_POPOVER(info->popup_menu));
 #else                           /*GTK_CHECK_VERSION(3, 22, 0) */
-                        gtk_menu_popup(GTK_MENU(info->popup_menu), NULL, NULL,
-                                       NULL, NULL, event->button, event->time);
+                        gtk_widget_show_all(info->popup_menu);
 #endif                          /*GTK_CHECK_VERSION(3, 22, 0) */
                     }
                     g_object_unref(info);
@@ -1610,7 +1596,28 @@ balsa_message_copy_part(const gchar *url, LibBalsaMessageBody *part)
 }
 
 static void
-part_create_menu (BalsaPartInfo* info)
+save_cb(GSimpleAction *action,
+        GVariant      *parameter,
+        gpointer       user_data)
+{
+    BalsaPartInfo *info = user_data;
+
+    balsa_mime_widget_ctx_menu_save(GTK_WIDGET(info->mime_widget), info->body);
+}
+
+static void
+open_with_cb(GSimpleAction *action,
+             GVariant      *parameter,
+             gpointer       user_data)
+{
+    BalsaPartInfo *info = user_data;
+
+    balsa_mime_widget_ctx_menu_cb(g_variant_get_string(parameter, NULL),
+                                  info->body);
+}
+
+static void
+part_create_menu(BalsaPartInfo *info)
 /* Remarks: Will add items in the following order:
             1) Default application according to GnomeVFS.
             2) GNOME MIME/GnomeVFS key values that don't match default
@@ -1618,40 +1625,52 @@ part_create_menu (BalsaPartInfo* info)
             3) GnomeVFS shortlist applications, with the default one (sometimes
                included on shortlist, sometimes not) excluded. */
 {
-    GtkWidget* menu_item;
-    gchar* content_type;
-
-    info->popup_menu = gtk_menu_new ();
-    g_object_ref_sink(info->popup_menu);
+    GSimpleActionGroup *simple;
+    static const GActionEntry part_menu_entries[] = {
+        {"save", save_cb},
+        {"open-with", open_with_cb}
+    };
+    GMenu *menu;
+    gchar *content_type;
+
+    simple = g_simple_action_group_new();
+    g_action_map_add_action_entries(G_ACTION_MAP(simple),
+                                    part_menu_entries,
+                                    G_N_ELEMENTS(part_menu_entries),
+                                    info);
+    gtk_widget_insert_action_group(GTK_WIDGET(info->mime_widget),
+                                   "part-menu",
+                                   G_ACTION_GROUP(simple));
+    g_object_unref(simple);
+
+    menu = g_menu_new();
 
     content_type = libbalsa_message_body_get_mime_type (info->body);
-    libbalsa_vfs_fill_menu_by_content_type(GTK_MENU(info->popup_menu),
+    libbalsa_vfs_fill_menu_by_content_type(menu,
                                           content_type,
-                                          G_CALLBACK (balsa_mime_widget_ctx_menu_cb),
-                                          (gpointer)info->body);
+                                           "part-menu.open-with"
+                                          /* G_CALLBACK (balsa_mime_widget_ctx_menu_cb), */
+                                          /* (gpointer)info->body */);
 
-    menu_item = gtk_menu_item_new_with_mnemonic (_("_Save…"));
-    g_signal_connect (menu_item, "activate",
-                      G_CALLBACK (balsa_mime_widget_ctx_menu_save), (gpointer) info->body);
-    gtk_menu_shell_append (GTK_MENU_SHELL (info->popup_menu), menu_item);
+    g_menu_append(menu, _("Save…"), "part-menu.save");
 
     if (strcmp(content_type, "message/rfc822") == 0) {
-        GtkWidget *submenu;
-
-        menu_item =
-            gtk_menu_item_new_with_mnemonic(_("_Copy to folder…"));
-        gtk_menu_shell_append(GTK_MENU_SHELL(info->popup_menu), menu_item);
+        GMenu *submenu;
 
         submenu =
             balsa_mblist_mru_menu(GTK_WINDOW(gtk_widget_get_toplevel(info->popup_menu)),
                                   &balsa_app.folder_mru,
                                   G_CALLBACK(balsa_message_copy_part),
                                   info->body);
-        gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
+
+        g_menu_append_submenu(menu, _("_Copy to folder…"), G_MENU_MODEL(submenu));
     }
 
-    gtk_widget_show_all (info->popup_menu);
-    g_free (content_type);
+    g_free(content_type);
+
+    info->popup_menu =
+        gtk_popover_new_from_model(GTK_WIDGET(info->mime_widget), G_MENU_MODEL(menu));
+    g_object_ref_sink(info->popup_menu);
 }
 
 static void
diff --git a/src/balsa-mime-widget-callbacks.c b/src/balsa-mime-widget-callbacks.c
index f67699706..06e61f818 100644
--- a/src/balsa-mime-widget-callbacks.c
+++ b/src/balsa-mime-widget-callbacks.c
@@ -37,7 +37,7 @@
 
 
 void
-balsa_mime_widget_ctx_menu_cb(GtkWidget * menu_item,
+balsa_mime_widget_ctx_menu_cb(const gchar *action,
                              LibBalsaMessageBody * mime_body)
 {
     GError *err = NULL;
@@ -45,7 +45,7 @@ balsa_mime_widget_ctx_menu_cb(GtkWidget * menu_item,
 
     g_return_if_fail(mime_body != NULL);
     result = libbalsa_vfs_launch_app_for_body(mime_body,
-                                              G_OBJECT(menu_item),
+                                              action,
                                               &err);
     if (!result)
         balsa_information(LIBBALSA_INFORMATION_WARNING,
diff --git a/src/balsa-mime-widget-callbacks.h b/src/balsa-mime-widget-callbacks.h
index 5e0a82454..42f9b8751 100644
--- a/src/balsa-mime-widget-callbacks.h
+++ b/src/balsa-mime-widget-callbacks.h
@@ -27,7 +27,7 @@
 G_BEGIN_DECLS
 
 
-void balsa_mime_widget_ctx_menu_cb(GtkWidget * menu_item, LibBalsaMessageBody * mime_body);
+void balsa_mime_widget_ctx_menu_cb(const gchar * action, LibBalsaMessageBody * mime_body);
 void balsa_mime_widget_ctx_menu_save(GtkWidget * parent_widget,
                                      LibBalsaMessageBody * mime_body);
 gint balsa_mime_widget_key_press_event(GtkWidget * widget, GdkEventKey * event,
diff --git a/src/balsa-mime-widget-message.c b/src/balsa-mime-widget-message.c
index e6a166e1a..3232b00c1 100644
--- a/src/balsa-mime-widget-message.c
+++ b/src/balsa-mime-widget-message.c
@@ -434,8 +434,6 @@ balsa_mime_widget_new_message_tl(BalsaMessage * bm,
 }
 
 
-/* Callback for the "realized" signal; set header frame and text base
- * color when first realized. */
 #define BALSA_MESSAGE_GRID "balsa-message-grid"
 #define bm_header_widget_get_grid(header_widget) \
     g_object_get_data(G_OBJECT(header_widget), BALSA_MESSAGE_GRID)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]