[geary/cherry-pick-a21982ae] Merge branch 'mjog/draft-errors' into 'mainline'




commit 5c94414fb1349a12862b22bc14a2a1a8b05b3271
Author: Michael Gratton <mike vee net>
Date:   Thu Nov 5 08:14:32 2020 +0000

    Merge branch 'mjog/draft-errors' into 'mainline'
    
    Misc draft management issues
    
    Closes #858 and #1044
    
    See merge request GNOME/geary!613
    
    (cherry picked from commit a21982ae42868c9ced43e92d4b3be97a6d5f3a1c)
    
    6530c66e Geary.Imap.FolderSession: Fix null param critical with vala 0.50
    6f1f94e5 Composer.Widget: Suppress unsupported draft folder messages
    be793831 Geary.App.DraftManager: Wait for remote to be open in ctor
    6d5b0bc5 Composer.Widget: Rework draft manager management
    36daf801 Composer.Widget: Clean up set_save_to_override method signature
    5533ae32 Composer.Widget: Hide save button by default

 .../application/application-plugin-manager.vala    | 14 +---
 src/client/composer/composer-widget.vala           | 96 +++++++++++++++-------
 src/engine/app/app-draft-manager.vala              | 13 ++-
 src/engine/imap/api/imap-folder-session.vala       |  4 +-
 4 files changed, 79 insertions(+), 48 deletions(-)
---
diff --git a/src/client/application/application-plugin-manager.vala 
b/src/client/application/application-plugin-manager.vala
index de1e01b0b..1d736222e 100644
--- a/src/client/application/application-plugin-manager.vala
+++ b/src/client/application/application-plugin-manager.vala
@@ -402,19 +402,7 @@ public class Application.PluginManager : GLib.Object {
         public void save_to_folder(Plugin.Folder? location) {
             var engine = this.application.globals.folders.to_engine_folder(location);
             if (engine != null && engine.account == this.backing.sender_context.account) {
-                this.backing.set_save_to_override.begin(
-                    engine,
-                    (obj, res) => {
-                        try {
-                            this.backing.set_save_to_override.end(res);
-                        } catch (GLib.Error err) {
-                            debug(
-                                "Error setting folder for saving: %s",
-                                err.message
-                            );
-                        }
-                    }
-                );
+                this.backing.set_save_to_override(engine);
             }
         }
 
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 37e93fb43..fc1f9657a 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -439,6 +439,8 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
 
         this.header = new Headerbar(config);
         this.header.expand_composer.connect(on_expand_compact_headers);
+        // Hide until we know we can save drafts
+        this.header.show_save_and_close = false;
 
         // Setup drag 'n drop
         const Gtk.TargetEntry[] target_entries = { { URI_LIST_MIME_TYPE, 0, 0 } };
@@ -971,7 +973,21 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
         this.header.set_sensitive(enabled);
 
         if (enabled) {
-            this.open_draft_manager.begin(this.saved_id, null);
+            var current_account = this.sender_context.account;
+            this.open_draft_manager.begin(
+                this.saved_id,
+                (obj, res) => {
+                    try {
+                        this.open_draft_manager.end(res);
+                    } catch (GLib.Error error) {
+                        this.application.report_problem(
+                            new Geary.AccountProblemReport(
+                                current_account.information, error
+                            )
+                        );
+                    }
+                }
+            );
         } else {
             if (this.container != null) {
                 this.container.close();
@@ -980,11 +996,10 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
         }
     }
 
-    /** Overrides the draft folder as a destination for saving. */
-    public async void set_save_to_override(Geary.Folder? save_to)
-        throws GLib.Error {
+    /** Overrides the folder used for saving drafts. */
+    public void set_save_to_override(Geary.Folder? save_to) {
         this.save_to = save_to;
-        yield reopen_draft_manager();
+        this.reopen_draft_manager.begin();
     }
 
     /**
@@ -1418,11 +1433,21 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             is_body_complete
         );
 
-        try {
-            yield open_draft_manager(this.saved_id);
-        } catch (Error e) {
-            debug("Could not open draft manager: %s", e.message);
-        }
+        var current_account = this.sender_context.account;
+        this.open_draft_manager.begin(
+            this.saved_id,
+            (obj, res) => {
+                try {
+                    this.open_draft_manager.end(res);
+                } catch (GLib.Error error) {
+                    this.application.report_problem(
+                        new Geary.AccountProblemReport(
+                            current_account.information, error
+                        )
+                    );
+                }
+            }
+        );
     }
 
     private async bool should_send() {
@@ -1495,6 +1520,11 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
 
     /**
      * Creates and opens the composer's draft manager.
+     *
+     * Note that since the draft manager may block until a remote
+     * connection is open, this method may likewise do so. Hence this
+     * method typically needs to be called from the main loop as a
+     * background async task using the `begin` async call form.
      */
     private async void open_draft_manager(Geary.EmailIdentifier? editing_draft_id)
         throws GLib.Error {
@@ -1527,6 +1557,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             : new Geary.EmailFlags()
         );
 
+        bool opened = false;
         try {
             var new_manager = yield new Geary.App.DraftManager(
                 this.sender_context.account,
@@ -1542,7 +1573,13 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             new_manager.fatal
                 .connect(on_draft_manager_fatal);
             this.draft_manager = new_manager;
+            opened = true;
             debug("Draft manager opened");
+        } catch (Geary.EngineError.UNSUPPORTED err) {
+            debug(
+                "Drafts folder unsupported, no drafts will be saved: %s",
+                err.message
+            );
         } catch (GLib.Error err) {
             this.header.show_save_and_close = false;
             throw err;
@@ -1550,20 +1587,30 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             this.draft_manager_opening = null;
         }
 
-        update_draft_state();
-        this.header.show_save_and_close = true;
+        this.header.show_save_and_close = opened;
+        if (opened) {
+            update_draft_state();
+        }
     }
 
     /**
      * Closes current draft manager, if any, then opens a new one.
      */
-    private async void reopen_draft_manager()
-        throws GLib.Error {
+    private async void reopen_draft_manager() {
         // Discard the draft, if any, since it may be on a different
         // account
-        yield close_draft_manager(DISCARD);
-        yield open_draft_manager(null);
-        yield save_draft();
+        var current_account = this.sender_context.account;
+        try {
+            yield close_draft_manager(DISCARD);
+            yield open_draft_manager(null);
+            yield save_draft();
+        } catch (GLib.Error error) {
+            this.application.report_problem(
+                new Geary.AccountProblemReport(
+                    current_account.information, error
+                )
+            );
+        }
     }
 
     private async void close_draft_manager(DraftPolicy draft_policy)
@@ -2239,20 +2286,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
                 this.update_signature.begin(null);
                 load_entry_completions();
 
-                var current_account = this.sender_context.account;
-                this.reopen_draft_manager.begin(
-                    (obj, res) => {
-                        try {
-                            this.reopen_draft_manager.end(res);
-                        } catch (GLib.Error error) {
-                            this.application.report_problem(
-                                new Geary.AccountProblemReport(
-                                    current_account.information, error
-                                )
-                            );
-                        }
-                    }
-                );
+                this.reopen_draft_manager.begin();
             }
         }
     }
diff --git a/src/engine/app/app-draft-manager.vala b/src/engine/app/app-draft-manager.vala
index 8e9863af4..9d5a31b1b 100644
--- a/src/engine/app/app-draft-manager.vala
+++ b/src/engine/app/app-draft-manager.vala
@@ -219,8 +219,17 @@ public class Geary.App.DraftManager : BaseObject {
 
         yield drafts_folder.open_async(Folder.OpenFlags.NO_DELAY, cancellable);
 
-        // if drafts folder doesn't return the identifier of newly created emails, then this object
-        // can't do it's work ... wait until open to check for this, to be absolutely sure
+        // if drafts folder doesn't return the identifier of newly
+        // created emails, then this object can't do it's work
+        // ... wait until open to check for this, to be absolutely
+        // sure
+        //
+        // Since open_async returns before a remote connection is
+        // made, need to wait for it here to ensure
+        var engine = this.drafts_folder as ImapEngine.MinimalFolder;
+        if (engine != null) {
+            yield engine.claim_remote_session(cancellable);
+        }
         if (drafts_folder.properties.create_never_returns_id) {
             try {
                 yield drafts_folder.close_async();
diff --git a/src/engine/imap/api/imap-folder-session.vala b/src/engine/imap/api/imap-folder-session.vala
index 8a2290cb8..3b777ee6a 100644
--- a/src/engine/imap/api/imap-folder-session.vala
+++ b/src/engine/imap/api/imap-folder-session.vala
@@ -85,8 +85,8 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
 
     public async FolderSession(ClientSession session,
                                Imap.Folder folder,
-                               Cancellable cancellable)
-        throws Error {
+                               GLib.Cancellable? cancellable)
+        throws GLib.Error {
         base(session);
         this.folder = folder;
         this.quirks = session.quirks;


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