[geary/mjog/account-command-stacks: 44/77] Implement deleting conversations as non-undoable commands



commit df780d72a12c8eb7b3ae9cf6099169441f0c95f6
Author: Michael Gratton <mike vee net>
Date:   Sun Oct 6 10:54:52 2019 +1100

    Implement deleting conversations as non-undoable commands

 src/client/application/application-controller.vala | 75 ++++++++++++++++++++++
 src/client/components/main-window.vala             | 62 ++++++++++++++++++
 2 files changed, 137 insertions(+)
---
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index 13a3033b..b9a6dd2a 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -796,6 +796,33 @@ public class Application.Controller : Geary.BaseObject {
         }
     }
 
+    public async void delete_conversations(Geary.FolderSupport.Remove target,
+                                           Gee.Collection<Geary.App.Conversation> conversations)
+        throws GLib.Error {
+        AccountContext? context = this.accounts.get(target.account.information);
+        if (context != null) {
+            yield this.commands.execute(
+                new DeleteEmailCommand(
+                    target,
+                    to_in_folder_email_ids(conversations)
+                ),
+                context.cancellable
+            );
+        }
+    }
+
+    public async void delete_messages(Geary.FolderSupport.Remove target,
+                                      Gee.Collection<Geary.EmailIdentifier> messages)
+        throws GLib.Error {
+        AccountContext? context = this.accounts.get(target.account.information);
+        if (context != null) {
+            yield this.commands.execute(
+                new DeleteEmailCommand(target, messages),
+                context.cancellable
+            );
+        }
+    }
+
     /** Expunges removed accounts while the controller remains open. */
     internal async void expunge_accounts() {
         try {
@@ -2440,9 +2467,57 @@ private class Application.CopyEmailCommand : Command {
         throws GLib.Error {
         throw new Geary.EngineError.UNSUPPORTED(
             "Cannot undo copy, not yet supported"
+        );
+    }
+
+}
+
+
+private class Application.DeleteEmailCommand : Command {
+
+
+    public override bool can_undo {
+        get { return false; }
+    }
+
+    private Geary.FolderSupport.Remove target;
+    private Gee.Collection<Geary.EmailIdentifier> messages;
+
+
+    public DeleteEmailCommand(Geary.FolderSupport.Remove target,
+                              Gee.Collection<Geary.EmailIdentifier> messages) {
+        this.target = target;
+        this.messages = messages;
+    }
+
+    public override async void execute(GLib.Cancellable? cancellable)
+        throws GLib.Error {
+        bool open = false;
+        try {
+            yield this.target.open_async(
+                Geary.Folder.OpenFlags.NO_DELAY, cancellable
+            );
+            open = true;
+            yield this.target.remove_email_async(this.messages, cancellable);
+        } finally {
+            if (open) {
+                try {
+                    yield this.target.close_async(null);
+                } catch (GLib.Error err) {
+                    // ignored
+                }
+            }
         }
     }
 
+    public override async void undo(GLib.Cancellable? cancellable)
+        throws GLib.Error {
+        throw new Geary.EngineError.UNSUPPORTED(
+            "Cannot undo emptying a folder: %s",
+            this.target.path.to_string()
+        );
+    }
+
 }
 
 
diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala
index 7acf5b74..27b941a1 100644
--- a/src/client/components/main-window.vala
+++ b/src/client/components/main-window.vala
@@ -714,6 +714,36 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         );
     }
 
+    private bool prompt_delete_conversations(int count) {
+        ConfirmationDialog dialog = new ConfirmationDialog(
+            this,
+            /// Translators: Primary text for a confirmation dialog
+            ngettext(
+                "Do you want to permanently delete this conversation?",
+                "Do you want to permanently delete these conversations?",
+                count
+            ),
+            null,
+            _("Delete"), "destructive-action"
+        );
+        return (dialog.run() == Gtk.ResponseType.OK);
+    }
+
+    private bool prompt_delete_messages(int count) {
+        ConfirmationDialog dialog = new ConfirmationDialog(
+            this,
+            /// Translators: Primary text for a confirmation dialog
+            ngettext(
+                "Do you want to permanently delete this message?",
+                "Do you want to permanently delete these messages?",
+                count
+            ),
+            null,
+            _("Delete"), "destructive-action"
+        );
+        return (dialog.run() == Gtk.ResponseType.OK);
+    }
+
     private inline void handle_error(Geary.AccountInformation? account,
                                      GLib.Error error) {
         Geary.ProblemReport? report = (account != null)
@@ -1600,6 +1630,23 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
     }
 
     private void on_delete_conversation() {
+        Geary.FolderSupport.Remove target =
+            this.current_folder as Geary.FolderSupport.Remove;
+        Gee.Collection<Geary.App.Conversation> conversations =
+            this.conversation_list_view.get_selected_conversations();
+        if (target != null && this.prompt_delete_conversations(conversations.size)) {
+            this.application.controller.delete_conversations.begin(
+                target,
+                conversations,
+                (obj, res) => {
+                    try {
+                        this.application.controller.delete_conversations.end(res);
+                    } catch (GLib.Error err) {
+                        handle_error(target.account.information, err);
+                    }
+                }
+            );
+        }
     }
 
     private void on_empty_spam() {
@@ -1767,6 +1814,21 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
     }
 
     private void on_delete_message(ConversationEmail target_view) {
+        Geary.FolderSupport.Remove? source =
+            this.current_folder as Geary.FolderSupport.Remove;
+        if (source != null && prompt_delete_messages(1)) {
+            this.application.controller.delete_messages.begin(
+                source,
+                Geary.Collection.single(target_view.email.id),
+                (obj, res) => {
+                    try {
+                        this.application.controller.delete_messages.end(res);
+                    } catch (GLib.Error err) {
+                        handle_error(source.account.information, err);
+                    }
+                }
+            );
+        }
     }
 
     private void on_link_activated(string uri) {


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