[geary/mjog/email-templates: 58/72] Application.Client: Use plugin variant formats for app actions



commit a98f9532370f05480a9c5871c8cbc4b07de96dbc
Author: Michael Gratton <mike vee net>
Date:   Sat Apr 18 18:56:27 2020 +1000

    Application.Client: Use plugin variant formats for app actions
    
    Expect the same variant format for the `show-folder` and `show-email`
    application actions. Use existing email and folder store factory
    lookup methods for these. Update DesktopNotifications plugin to simply
    pass variant values from plugin classes through to notifications.

 src/client/application/application-client.vala     | 148 ++++++++++++++-------
 .../application/application-plugin-manager.vala    |   8 +-
 .../desktop-notifications.vala                     |  10 +-
 3 files changed, 109 insertions(+), 57 deletions(-)
---
diff --git a/src/client/application/application-client.vala b/src/client/application/application-client.vala
index 50516548..7a784c90 100644
--- a/src/client/application/application-client.vala
+++ b/src/client/application/application-client.vala
@@ -84,8 +84,8 @@ public class Application.Client : Gtk.Application {
         { Action.Application.NEW_WINDOW, on_activate_new_window },
         { Action.Application.PREFERENCES, on_activate_preferences},
         { Action.Application.QUIT, on_activate_quit},
-        { Action.Application.SHOW_EMAIL, on_activate_show_email, "(vv)"},
-        { Action.Application.SHOW_FOLDER, on_activate_show_folder, "(v)"}
+        { Action.Application.SHOW_EMAIL, on_activate_show_email, "(sv)"},
+        { Action.Application.SHOW_FOLDER, on_activate_show_folder, "(sv)"}
     };
 
     // This is also the order in which they are presented to the user,
@@ -600,15 +600,105 @@ public class Application.Client : Gtk.Application {
         this.controller.expunge_accounts.begin();
     }
 
-    public async void show_email(Geary.Folder folder,
-                                 Geary.EmailIdentifier id) {
+    /**
+     * Displays a specific email in a main window.
+     *
+     * This method is invoked by the application `show-email`
+     * action. A folder containing the email will be selected if the
+     * current folder does not select it.
+     *
+     * The email is identified by the given variant, which can be
+     * obtained by calling {@link Plugin.EmailIdentifier.to_variant}.
+     */
+    public async void show_email(GLib.Variant? id) {
         MainWindow main = yield this.present();
-        main.show_email.begin(folder, Geary.Collection.single(id), true);
+        if (id != null) {
+            EmailStoreFactory email = this.controller.plugins.email_factory;
+            AccountContext? context = email.get_account_from_variant(id);
+            Geary.EmailIdentifier? email_id =
+                email.get_email_identifier_from_variant(id);
+            if (context != null && email_id != null) {
+                // Determine what folders the email is in
+                Gee.MultiMap<Geary.EmailIdentifier,Geary.FolderPath>? folders = null;
+                try {
+                    folders = yield context.account.get_containing_folders_async(
+                        Geary.Collection.single(email_id),
+                        context.cancellable
+                    );
+                } catch (GLib.Error err) {
+                    warning("Error listing folders for email: %s", err.message);
+                }
+                if (folders != null) {
+                    // Determine what folder containing the email
+                    // should be selected. If the current folder
+                    // contains the email then use that, else use the
+                    // inbox if that contains it, else use the first
+                    // path found
+                    var paths = folders.get(email_id);
+                    Geary.Folder? selected = main.selected_folder;
+                    if (selected == null ||
+                        selected.account != context.account ||
+                        !(selected.path in paths)) {
+                        selected = null;
+                        foreach (var path in paths) {
+                            try {
+                                Geary.Folder folder =
+                                    context.account.get_folder(path);
+                                if (folder.used_as == INBOX) {
+                                    selected = folder;
+                                    break;
+                                }
+                            } catch (GLib.Error err) {
+                                warning(
+                                    "Error getting folder for email: %s",
+                                    err.message
+                                );
+                            }
+                        }
+
+                        if (selected == null && !paths.is_empty) {
+                            try {
+                                selected = context.account.get_folder(
+                                    Geary.Collection.first(paths)
+                                );
+                            } catch (GLib.Error err) {
+                                warning(
+                                    "Error getting folder for email: %s",
+                                    err.message
+                                );
+                            }
+                        }
+                    }
+
+                    if (selected != null) {
+                        yield main.show_email(
+                            selected,
+                            Geary.Collection.single(email_id),
+                            true
+                        );
+                    }
+                }
+            }
+        }
     }
 
-    public async void show_folder(Geary.Folder folder) {
+    /**
+     * Selects a specific folder in a main window.
+     *
+     * This method is invoked by the application `show-folder` action.
+     *
+     * The folder is identified by the given variant, which can be
+     * obtained by calling {@link Plugin.Folder.to_variant}.
+     */
+    public async void show_folder(GLib.Variant? id) {
         MainWindow main = yield this.present();
-        yield main.select_folder(folder, true);
+        if (id != null) {
+            Geary.Folder? folder =
+                this.controller.plugins.folders_factory.get_folder_from_variant(id);
+            if (folder != null) {
+                yield main.select_folder(folder, true);
+            }
+        }
     }
 
     public async void show_inspector() {
@@ -1037,23 +1127,6 @@ public class Application.Client : Gtk.Application {
         }
     }
 
-    private Geary.Folder? get_folder_from_action_target(GLib.Variant target) {
-        Geary.Folder? folder = null;
-        GLib.Variant param = target.get_child_value(0).get_variant();
-        string id = (string) param.get_child_value(0);
-        try {
-            Geary.Account account = this.engine.get_account_for_id(id);
-            Geary.FolderPath? path =
-                account.to_folder_path(
-                    param.get_child_value(1).get_variant()
-                );
-            folder = account.get_folder(path);
-        } catch (GLib.Error err) {
-            debug("Could not find account/folder %s", err.message);
-        }
-        return folder;
-    }
-
     private void load_css(Gtk.CssProvider provider, string resource_uri) {
         provider.parsing_error.connect(on_css_parse_error);
         try {
@@ -1106,33 +1179,12 @@ public class Application.Client : Gtk.Application {
 
     private void on_activate_show_email(GLib.SimpleAction action,
                                         GLib.Variant? target) {
-        if (target != null) {
-            Geary.Folder? folder = get_folder_from_action_target(target);
-            Geary.EmailIdentifier? email_id = null;
-            if (folder != null) {
-                try {
-                    email_id = folder.account.to_email_identifier(
-                        target.get_child_value(1).get_variant()
-                    );
-                } catch (GLib.Error err) {
-                    debug("Could not find email id: %s", err.message);
-                }
-
-                if (email_id != null) {
-                    this.show_email.begin(folder, email_id);
-                }
-            }
-        }
+        this.show_email.begin(target);
     }
 
     private void on_activate_show_folder(GLib.SimpleAction action,
-                                        GLib.Variant? target) {
-        if (target != null) {
-            Geary.Folder? folder = get_folder_from_action_target(target);
-            if (folder != null) {
-                this.show_folder.begin(folder);
-            }
-        }
+                                         GLib.Variant? target) {
+        this.show_folder.begin(target);
     }
 
     private void on_activate_help() {
diff --git a/src/client/application/application-plugin-manager.vala 
b/src/client/application/application-plugin-manager.vala
index cf91cc50..378e65f4 100644
--- a/src/client/application/application-plugin-manager.vala
+++ b/src/client/application/application-plugin-manager.vala
@@ -95,7 +95,8 @@ public class Application.PluginManager : GLib.Object {
         public void show_folder(Plugin.Folder folder) {
             Geary.Folder? target = this.folders.get_engine_folder(folder);
             if (target != null) {
-                this.backing.show_folder.begin(target);
+                MainWindow window = this.backing.get_active_main_window();
+                window.select_folder.begin(target, true);
             }
         }
 
@@ -208,6 +209,9 @@ public class Application.PluginManager : GLib.Object {
                                           GLib.Error? error);
 
 
+    internal FolderStoreFactory folders_factory { get; private set; }
+    internal EmailStoreFactory email_factory { get; private set; }
+
     private Client application;
     private Controller controller;
     private Configuration config;
@@ -217,8 +221,6 @@ public class Application.PluginManager : GLib.Object {
 
     private Gee.Map<AccountContext,AccountImpl> plugin_accounts =
         new Gee.HashMap<AccountContext,AccountImpl>();
-    private FolderStoreFactory folders_factory;
-    private EmailStoreFactory email_factory;
 
     private Gee.Map<Peas.PluginInfo,PluginContext> plugin_set =
         new Gee.HashMap<Peas.PluginInfo,PluginContext>();
diff --git a/src/client/plugin/desktop-notifications/desktop-notifications.vala 
b/src/client/plugin/desktop-notifications/desktop-notifications.vala
index 67c7d07e..353c0abe 100644
--- a/src/client/plugin/desktop-notifications/desktop-notifications.vala
+++ b/src/client/plugin/desktop-notifications/desktop-notifications.vala
@@ -182,15 +182,13 @@ public class Plugin.DesktopNotifications :
         clear_arrived_notification();
 
         string? action = null;
-        GLib.Variant[] target_param = new GLib.Variant[] {
-            new GLib.Variant.variant(folder.to_variant())
-        };
-
+        GLib.Variant? target_param = null;
         if (id == null) {
             action = Action.Application.SHOW_FOLDER;
+            target_param = folder.to_variant();
         } else {
             action = Action.Application.SHOW_EMAIL;
-            target_param += new GLib.Variant.variant(id.to_variant());
+            target_param = id.to_variant();
         }
 
         this.arrived_notification = issue_notification(
@@ -199,7 +197,7 @@ public class Plugin.DesktopNotifications :
             body,
             icon,
             Action.Application.prefix(action),
-            new GLib.Variant.tuple(target_param)
+            target_param
         );
     }
 


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