From a98f9532370f05480a9c5871c8cbc4b07de96dbc Mon Sep 17 00:00:00 2001 From: Michael Gratton Date: Sat, 18 Apr 2020 18:56:27 +1000 Subject: [PATCH] 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. --- .../application/application-client.vala | 148 ++++++++++++------ .../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? 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 plugin_accounts = new Gee.HashMap(); - private FolderStoreFactory folders_factory; - private EmailStoreFactory email_factory; private Gee.Map plugin_set = new Gee.HashMap(); 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 ); }