[balsa/popover: 1/2] mblist: Port the MRU menu to GMenu



commit 1fcf3c946d3d00b2e339507509ded6eb64a4ce13
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Tue May 5 10:52:14 2020 -0400

    mblist: Port the MRU menu to GMenu
    
    Also drop its GtkWindow parameter, as the caller is now responsible for
    popping up the parented GtkDialog.
    
    Add two helpers for coping with the "Other..." option, which results in
    an empty url string.

 src/balsa-mblist.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/balsa-mblist.h |   7 +-
 2 files changed, 192 insertions(+), 6 deletions(-)
---
diff --git a/src/balsa-mblist.c b/src/balsa-mblist.c
index d634246ae..39305b28b 100644
--- a/src/balsa-mblist.c
+++ b/src/balsa-mblist.c
@@ -1682,7 +1682,6 @@ static void bmbl_mru_activated_cb(GtkTreeView * tree_view,
 /*
  * balsa_mblist_mru_menu:
  *
- * window:      parent window for the `Other...' dialog;
  * url_list:    pointer to a list of urls;
  * action:      the action to be taken on selecting an item
  *
@@ -1693,8 +1692,7 @@ static void bmbl_mru_activated_cb(GtkTreeView * tree_view,
  * last entry that pops up the whole mailbox tree.
  */
 GMenu *
-balsa_mblist_mru_menu(GtkWindow * window,
-                      GList ** url_list,
+balsa_mblist_mru_menu(GList ** url_list,
                       const gchar *action)
 {
     GMenu *menu;
@@ -1702,7 +1700,6 @@ balsa_mblist_mru_menu(GtkWindow * window,
     GList *list;
     GMenuItem *other_item;
 
-    g_return_val_if_fail(GTK_IS_WINDOW(window), NULL);
     g_return_val_if_fail(url_list != NULL, NULL);
     g_return_val_if_fail(action != NULL, NULL);
 
@@ -2225,3 +2222,189 @@ balsa_mblist_mailbox_node_redraw(BalsaMailboxNode * mbnode)
        bmbl_store_redraw_mbnode(&iter, mbnode);
     balsa_window_update_tab(mbnode);
 }
+
+/*
+ * balsa_mblist_choose_mailbox
+ *
+ * Pops up a GtkDialog with a BalsaMBList.
+ * Returns the mailbox that the user selects
+ */
+
+/*
+ * bmbl_choose_mailbox_activated_cb:
+ *
+ * Callback for the "row-activated" signal of the GtkTreeView in the
+ * BalsaMBList object. This permits keyboard selection of a mailbox.
+ */
+static void
+bmbl_choose_mailbox_row_activated(GtkTreeView       *tree_view,
+                                  GtkTreePath       *path,
+                                  GtkTreeViewColumn *column,
+                                  gpointer           data)
+{
+    GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
+    GtkTreeIter iter;
+    BalsaMailboxNode *mbnode;
+    LibBalsaMailbox **mailbox = data;
+
+    gtk_tree_model_get_iter(model, &iter, path);
+    gtk_tree_model_get(model, &iter, MBNODE_COLUMN, &mbnode, -1);
+    *mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+    g_object_unref(mbnode);
+
+    gtk_dialog_response(GTK_DIALOG
+                        (gtk_widget_get_ancestor
+                        (GTK_WIDGET(tree_view), GTK_TYPE_DIALOG)),
+                        GTK_RESPONSE_OK);
+}
+
+/*
+ * bmbl_choose_mailbox_selected_cb:
+ *
+ * Callback for the "changed" signal of the GtkTreeSelection in the
+ * BalsaMBList object. This permits one-click selection of a mailbox.
+ */
+static void
+bmbl_choose_mailbox_selected_cb(GtkTreeSelection * selection,
+                                gpointer           data)
+{
+    GdkEvent *event;
+    GtkTreeView *tree_view;
+    GtkTreePath *path;
+    LibBalsaMailbox **mailbox = data;
+
+    *mailbox = NULL;
+
+    event = gtk_get_current_event();
+    if (event == NULL)
+        return;
+
+    tree_view = gtk_tree_selection_get_tree_view(selection);
+    if (event->type != GDK_BUTTON_PRESS ||
+        !gtk_tree_view_get_path_at_pos(tree_view, event->button.x,
+                                       event->button.y, &path,
+                                       NULL, NULL, NULL)) {
+        gtk_tree_selection_unselect_all(selection);
+        gdk_event_free(event);
+        return;
+    }
+
+    if (gtk_tree_selection_path_is_selected(selection, path)) {
+        GtkTreeModel *model;
+        GtkTreeIter iter;
+        BalsaMailboxNode *mbnode;
+
+        model = gtk_tree_view_get_model(tree_view);
+        gtk_tree_model_get_iter(model, &iter, path);
+        gtk_tree_model_get(model, &iter, 0, &mbnode, -1);
+        *mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+       g_object_unref(mbnode);
+
+        gtk_dialog_response(GTK_DIALOG
+                            (gtk_widget_get_ancestor
+                             (GTK_WIDGET(tree_view), GTK_TYPE_DIALOG)),
+                            GTK_RESPONSE_OK);
+    }
+
+    gtk_tree_path_free(path);
+    gdk_event_free(event);
+}
+
+static LibBalsaMailbox *
+bmbl_choose_mailbox(GtkWidget *widget)
+{
+    GtkWidget *mblist;
+    LibBalsaMailbox *mailbox;
+    GtkTreeSelection *selection;
+    GtkWidget *scroll;
+    GtkWidget *dialog;
+
+    mblist = balsa_mblist_new();
+    g_signal_connect(mblist, "row-activated",
+                     G_CALLBACK(bmbl_choose_mailbox_row_activated), &mailbox);
+
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mblist));
+    g_signal_connect(selection, "changed",
+                     G_CALLBACK(bmbl_choose_mailbox_selected_cb), &mailbox);
+
+    scroll = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+                                   GTK_POLICY_AUTOMATIC,
+                                   GTK_POLICY_AUTOMATIC);
+    gtk_container_add(GTK_CONTAINER(scroll), mblist);
+    gtk_widget_show_all(scroll);
+
+    dialog =
+        gtk_dialog_new_with_buttons(_("Choose destination folder"),
+                                    GTK_WINDOW(gtk_widget_get_toplevel(widget)),
+                                    GTK_DIALOG_MODAL |
+                                    libbalsa_dialog_flags(),
+                                    _("_Cancel"), GTK_RESPONSE_CANCEL,
+                                    NULL);
+#if HAVE_MACOSX_DESKTOP
+    libbalsa_macosx_menu_for_parent(dialog, window);
+#endif
+    gtk_box_pack_start(GTK_BOX
+                      (gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                      scroll, TRUE, TRUE, 0);
+
+    g_signal_connect(dialog, "size-allocate",
+                     G_CALLBACK(bmbl_mru_size_allocate_cb), NULL);
+    gtk_window_set_default_size(GTK_WINDOW(dialog),
+                                balsa_app.mru_tree_width,
+                                balsa_app.mru_tree_height);
+
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+
+    return mailbox;
+}
+
+/*
+ * balsa_mblist_mru_get_url_from_variant,
+ * balsa_mblist_mru_get_mailbox_from_variant:
+ *
+ * Helpers for "_change_state" actions of mru_menus
+ *
+ * Get the url from the GVariant parameter. If it is an empty string,
+ * the user selected "Other...", so we must pop up the mailbox list dialog
+ * and let the user choose the mailbox. That dialog can be canceled,
+ * returning a NULL mailbox, so we must be careful; the caller must be
+ * prepared for the return of an empty url string or a NULL mailbox,
+ * respectively.
+ */
+
+const gchar *
+balsa_mblist_mru_get_url_from_variant(GVariant *parameter, GtkWidget *widget)
+{
+    const gchar *url;
+
+    url = g_variant_get_string(parameter, NULL);
+
+    if (url[0] == '\0') {
+        LibBalsaMailbox *mailbox;
+
+        mailbox = bmbl_choose_mailbox(widget);
+
+        if (mailbox != NULL)
+            url = libbalsa_mailbox_get_url(mailbox);
+    }
+
+    return url;
+}
+
+LibBalsaMailbox *
+balsa_mblist_mru_get_mailbox_from_variant(GVariant *parameter, GtkWidget *widget)
+{
+    LibBalsaMailbox *mailbox;
+    const gchar *url;
+
+    url = g_variant_get_string(parameter, NULL);
+
+    if (url[0] == '\0')
+        mailbox = bmbl_choose_mailbox(widget);
+    else
+        mailbox = balsa_find_mailbox_by_url(url);
+
+    return mailbox;
+}
diff --git a/src/balsa-mblist.h b/src/balsa-mblist.h
index ee6b4f6a2..c07318e3f 100644
--- a/src/balsa-mblist.h
+++ b/src/balsa-mblist.h
@@ -50,8 +50,7 @@ BalsaMailboxNode *balsa_mblist_get_selected_node(BalsaMBList * mblist);
 BalsaMailboxNode *balsa_mblist_get_node_by_mailbox(BalsaMBList * mblist,
                                                    LibBalsaMailbox *
                                                    mailbox);
-GMenu *balsa_mblist_mru_menu(GtkWindow * window,
-                             GList ** url_list,
+GMenu *balsa_mblist_mru_menu(GList ** url_list,
                              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);
@@ -60,6 +59,10 @@ GtkWidget *balsa_mblist_mru_option_menu(GtkWindow * window,
 void balsa_mblist_mru_option_menu_set(GtkWidget * option_menu,
                                       const gchar * url);
 const gchar *balsa_mblist_mru_option_menu_get(GtkWidget * option_menu);
+const gchar *balsa_mblist_mru_get_url_from_variant(GVariant  *parameter,
+                                                   GtkWidget *widget);
+LibBalsaMailbox *balsa_mblist_mru_get_mailbox_from_variant(GVariant  *parameter,
+                                                           GtkWidget *widget);
 
 /* BalsaMailboxNode methods */
 void balsa_mblist_mailbox_node_append(BalsaMailboxNode * root,


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