[geary/mjog/424-remove-empty-folder-menu-items: 1/2] Plugin.Application: Add support for emptying folders



commit de96c20abfd104ac52a94154d924bba2b4906d5c
Author: Michael Gratton <mike vee net>
Date:   Fri Mar 20 18:19:38 2020 +1100

    Plugin.Application: Add support for emptying folders
    
    Allow plugins to delete all email from a folder after getting user
    confirmation.

 src/client/application/application-controller.vala | 24 ++++++++++++++
 .../application/application-main-window.vala       | 33 ++++++++++---------
 .../application/application-plugin-manager.vala    | 37 ++++++++++++++++++++++
 src/client/plugin/plugin-application.vala          | 16 ++++++++++
 4 files changed, 93 insertions(+), 17 deletions(-)
---
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index 2be8537e..39f0bf18 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -830,6 +830,30 @@ internal class Application.Controller : Geary.BaseObject {
         }
     }
 
+    public async void empty_folder(Geary.Folder target)
+        throws GLib.Error {
+        AccountContext? context = this.accounts.get(target.account.information);
+        if (context != null) {
+            Geary.FolderSupport.Empty? emptyable = (
+                target as Geary.FolderSupport.Empty
+            );
+            if (emptyable == null) {
+                throw new Geary.EngineError.UNSUPPORTED(
+                    "Emptying folder not supported %s", target.path.to_string()
+                );
+            }
+
+            Command command = new EmptyFolderCommand(emptyable);
+            command.executed.connect(
+                // Not quite accurate, but close enough
+                () => context.controller_stack.folders_removed(
+                    Geary.Collection.single(emptyable)
+                )
+            );
+            yield context.commands.execute(command, context.cancellable);
+        }
+    }
+
     public async void empty_folder_special(Geary.Account source,
                                            Geary.SpecialFolderType type)
         throws GLib.Error {
diff --git a/src/client/application/application-main-window.vala 
b/src/client/application/application-main-window.vala
index 2b97de96..9c7c7afd 100644
--- a/src/client/application/application-main-window.vala
+++ b/src/client/application/application-main-window.vala
@@ -1285,6 +1285,22 @@ public class Application.MainWindow :
         return base.key_release_event(event);
     }
 
+    internal bool prompt_empty_folder(Geary.SpecialFolderType type) {
+        ConfirmationDialog dialog = new ConfirmationDialog(
+            this,
+            _("Empty all email from your %s folder?").printf(
+                type.get_display_name()
+            ),
+            _("This removes the email from Geary and your email server.") +
+            "  <b>" + _("This cannot be undone.") + "</b>",
+            _("Empty %s").printf(type.get_display_name()),
+            "destructive-action"
+        );
+        dialog.use_secondary_markup(true);
+        dialog.set_focus_response(Gtk.ResponseType.CANCEL);
+        return (dialog.run() == Gtk.ResponseType.OK);
+    }
+
     /** Un-does the last executed application command, if any. */
     private async void undo() {
         AccountContext? selected = get_selected_account_context();
@@ -1359,23 +1375,6 @@ public class Application.MainWindow :
         return (dialog.run() == Gtk.ResponseType.OK);
     }
 
-    private bool prompt_empty_folder(Geary.SpecialFolderType type) {
-        ConfirmationDialog dialog = new ConfirmationDialog(
-            this,
-            _("Empty all email from your %s folder?").printf(
-                type.get_display_name()
-            ),
-            _("This removes the email from Geary and your email server.") +
-            "  <b>" + _("This cannot be undone.") + "</b>",
-            _("Empty %s").printf(type.get_display_name()),
-            "destructive-action"
-        );
-        dialog.use_secondary_markup(true);
-        dialog.set_focus_response(Gtk.ResponseType.CANCEL);
-        return (dialog.run() == Gtk.ResponseType.OK);
-    }
-
-
     private async Gee.Collection<Geary.App.Conversation>
         load_conversations_for_email(
             Geary.Folder location,
diff --git a/src/client/application/application-plugin-manager.vala 
b/src/client/application/application-plugin-manager.vala
index 84a30921..3fd1ce44 100644
--- a/src/client/application/application-plugin-manager.vala
+++ b/src/client/application/application-plugin-manager.vala
@@ -17,6 +17,7 @@ public class Application.PluginManager : GLib.Object {
         "desktop-notifications",
         "folder-highlight",
         "notification-badge",
+        "special-folders",
     };
 
 
@@ -89,6 +90,42 @@ public class Application.PluginManager : GLib.Object {
             }
         }
 
+        public override async void empty_folder(Plugin.Folder folder)
+           throws Plugin.Error.PERMISSION_DENIED {
+           MainWindow main = this.backing.last_active_main_window;
+           if (main == null) {
+               throw new Plugin.Error.PERMISSION_DENIED(
+                   "Cannot prompt for permission"
+               );
+           }
+
+           Geary.Folder? target = this.folders.get_engine_folder(folder);
+           if (target != null) {
+               if (!main.prompt_empty_folder(target.special_folder_type)) {
+                   throw new Plugin.Error.PERMISSION_DENIED(
+                       "Permission not granted"
+                   );
+               }
+
+               Application.Controller controller = this.backing.controller;
+               controller.empty_folder.begin(
+                   target,
+                   (obj, res) => {
+                       try {
+                           controller.empty_folder.end(res);
+                       } catch (GLib.Error error) {
+                           controller.report_problem(
+                               new Geary.AccountProblemReport(
+                                   target.account.information,
+                                   error
+                               )
+                           );
+                       }
+                   }
+               );
+           }
+        }
+
         private void on_window_added(Gtk.Window window) {
             if (this.action_group != null) {
                 var main = window as MainWindow;
diff --git a/src/client/plugin/plugin-application.vala b/src/client/plugin/plugin-application.vala
index 0d0687ef..585f2b7a 100644
--- a/src/client/plugin/plugin-application.vala
+++ b/src/client/plugin/plugin-application.vala
@@ -37,4 +37,20 @@ public interface Plugin.Application : Geary.BaseObject {
     /** Displays a folder in the most recently used main window. */
     public abstract void show_folder(Folder folder);
 
+    /**
+     * Reversibly deletes all email from a folder.
+     *
+     * A prompt will be displayed for confirmation before the folder
+     * is actually emptied, if declined an exception will be thrown.
+     *
+     * This method will return once the engine has completed emptying
+     * the folder, however it may take additional time for the changes
+     * to be fully committed and reflected on the remote server.
+     *
+     * @throws Error.PERMISSIONS if permission was not granted to
+     * empty the folder
+     */
+    public abstract async void empty_folder(Folder folder)
+        throws Error.PERMISSION_DENIED;
+
 }


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