[geary/mjog/email-templates: 68/72] Geary.App.DraftManaager: Update API to something more RAII-like



commit 2716b2e5906830503d67bb2641c8ad9370c40390
Author: Michael Gratton <mike vee net>
Date:   Mon Apr 20 23:46:02 2020 +1000

    Geary.App.DraftManaager: Update API to something more RAII-like
    
    Replace open method with an async ctor, so we can make a few properties
    non-null by default, and callers need to call one less call. Make
    destination folder configurable, and require email flags passed in
    via the ctor, not every time when saving.

 src/client/composer/composer-widget.vala | 36 +++++++++------
 src/engine/app/app-draft-manager.vala    | 78 +++++++++++++++-----------------
 2 files changed, 59 insertions(+), 55 deletions(-)
---
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 0207deef..1cb69f2f 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -468,7 +468,6 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
 
     private Geary.App.DraftManager? draft_manager = null;
     private GLib.Cancellable? draft_manager_opening = null;
-    private Geary.EmailFlags draft_flags = new Geary.EmailFlags.with(Geary.EmailFlags.DRAFT);
     private Geary.TimeoutManager draft_timer;
     private bool is_draft_saved = false;
     private string draft_status_text {
@@ -1632,11 +1631,31 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
         );
         this.draft_manager_opening = internal_cancellable;
 
-        Geary.App.DraftManager new_manager = new Geary.App.DraftManager(
-            this.sender_context.account
+        Geary.Folder? target = yield this.sender_context.account.get_required_special_folder_async(
+            DRAFTS, internal_cancellable
         );
+
+        Geary.EmailFlags? flags = (
+            target.used_as == DRAFTS
+            ? new Geary.EmailFlags.with(Geary.EmailFlags.DRAFT)
+            : new Geary.EmailFlags()
+        );
+
         try {
-            yield new_manager.open_async(editing_draft_id, internal_cancellable);
+            var new_manager = yield new Geary.App.DraftManager(
+                this.sender_context.account,
+                target,
+                flags,
+                editing_draft_id,
+                internal_cancellable
+            );
+            new_manager.notify[Geary.App.DraftManager.PROP_DRAFT_STATE]
+                .connect(on_draft_state_changed);
+            new_manager.notify[Geary.App.DraftManager.PROP_CURRENT_DRAFT_ID]
+                .connect(on_draft_id_changed);
+            new_manager.fatal
+                .connect(on_draft_manager_fatal);
+            this.draft_manager = new_manager;
             debug("Draft manager opened");
         } catch (GLib.Error err) {
             this.header.show_save_and_close = false;
@@ -1645,14 +1664,6 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             this.draft_manager_opening = null;
         }
 
-        new_manager.notify[Geary.App.DraftManager.PROP_DRAFT_STATE]
-            .connect(on_draft_state_changed);
-        new_manager.notify[Geary.App.DraftManager.PROP_CURRENT_DRAFT_ID]
-            .connect(on_draft_id_changed);
-        new_manager.fatal.connect(on_draft_manager_fatal);
-
-        this.draft_manager = new_manager;
-
         update_draft_state();
         this.header.show_save_and_close = true;
     }
@@ -1742,7 +1753,6 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             Geary.ComposedEmail draft = yield get_composed_email(null, true);
             yield this.draft_manager.update(
                 yield draft.to_rfc822_message(null, null),
-                this.draft_flags,
                 null,
                 null
             );
diff --git a/src/engine/app/app-draft-manager.vala b/src/engine/app/app-draft-manager.vala
index bcaf26c9..4e9d1513 100644
--- a/src/engine/app/app-draft-manager.vala
+++ b/src/engine/app/app-draft-manager.vala
@@ -1,28 +1,29 @@
-/* Copyright 2016 Software Freedom Conservancy Inc.
+/*
+ * Copyright 2016 © Software Freedom Conservancy Inc.
+ * Copyright 2020 © Michael Gratton <mike vee net>
  *
  * This software is licensed under the GNU Lesser General Public License
- * (version 2.1 or later).  See the COPYING file in this distribution.
+ * (version 2.1 or later). See the COPYING file in this distribution.
  */
 
 /**
- * Manage saving, replacing, and deleting the various versions of a draft message while the user is
- * editing it.
+ * Manage saving, replacing, and deleting an email being edited.
  *
- * Each composer should create a single DraftManager object for the lifetime of the compose
- * session.  The DraftManager interface offers "fire-and-forget" nonblocking (but not
- * asynchronous) methods for the composer to schedule remote operations without worrying about
- * synchronization, operation ordering, error-handling, and so forth.
+ * Each composer should create a single DraftManager object for the
+ * lifetime of the compose session.  The DraftManager interface offers
+ * "fire-and-forget" nonblocking methods for the composer to schedule
+ * remote operations without worrying about synchronization, operation
+ * ordering, error-handling, and so forth.
  *
- * If successive drafts are submitted for storage, drafts waiting in the queue (i.e. not yet sent
- * to the server) are dropped without further consideration.  This prevents needless I/O with the
- * server saving drafts that are only to be replaced by later versions.
+ * If successive drafts are submitted for storage, drafts waiting in
+ * the queue (i.e. not yet sent to the server) are dropped without
+ * further consideration.  This prevents needless I/O with the server
+ * saving drafts that are only to be replaced by later versions.
  *
- * Important: This object should be used ''per'' composed email and not to manage multiple emails
- * being composed to the same {@link Account}.  DraftManager's internal state is solely for managing
- * the lifecycle of a single email being composed by the user.
- *
- * The only async calls for DraftManager is {@link open_async} and {@link close_async}, which give
- * it a chance to initialize and tear-down in an orderly manner.
+ * Important: This object should be used ''per'' composed email and
+ * not to manage multiple emails being composed to the same {@link
+ * Account}.  DraftManager's internal state is solely for managing the
+ * lifecycle of a single email being composed by the user.
  */
 
 public class Geary.App.DraftManager : BaseObject {
@@ -114,12 +115,12 @@ public class Geary.App.DraftManager : BaseObject {
     public int versions_dropped { get; private set; default = 0; }
 
     private Account account;
-    private Folder? drafts_folder = null;
+    private Folder drafts_folder = null;
+    private Geary.EmailFlags flags = null;
     private FolderSupport.Create? create_support = null;
     private FolderSupport.Remove? remove_support = null;
     private Nonblocking.Queue<Operation?> mailbox =
         new Nonblocking.Queue<Operation?>.fifo();
-    private bool was_opened = false;
     private Error? fatal_err = null;
 
 
@@ -163,10 +164,6 @@ public class Geary.App.DraftManager : BaseObject {
         debug("%s: Irrecoverable failure: %s", to_string(), err.message);
     }
 
-    public DraftManager(Geary.Account account) {
-        this.account = account;
-    }
-
     protected virtual void notify_stored(Geary.RFC822.Message draft) {
         versions_saved++;
         stored(draft);
@@ -192,32 +189,30 @@ public class Geary.App.DraftManager : BaseObject {
      *
      * @see is_open
      */
-    public async void open_async(Geary.EmailIdentifier? initial_draft_id, Cancellable? cancellable = null)
-        throws Error {
-        if (is_open)
-            throw new EngineError.ALREADY_OPEN("%s is already open", to_string());
-        else if (was_opened)
-            throw new EngineError.UNSUPPORTED("%s cannot be re-opened", to_string());
-
-        was_opened = true;
+    public async DraftManager(Account account,
+                              Folder save_to,
+                              EmailFlags flags,
+                              EmailIdentifier? initial_draft_id,
+                              GLib.Cancellable? cancellable = null)
+        throws GLib.Error {
+        this.account = account;
+        this.drafts_folder = save_to;
+        this.flags = flags;
 
-        current_draft_id = initial_draft_id;
-        if (current_draft_id != null)
+        this.current_draft_id = initial_draft_id;
+        if (this.current_draft_id != null) {
             draft_state = DraftState.STORED;
-
-        drafts_folder = account.get_special_folder(DRAFTS);
-        if (drafts_folder == null)
-            throw new EngineError.NOT_FOUND("%s: No drafts folder found", to_string());
+        }
 
         // if drafts folder doesn't support create and remove, call it quits
-        create_support = drafts_folder as Geary.FolderSupport.Create;
-        remove_support = drafts_folder as Geary.FolderSupport.Remove;
-        if (create_support == null || remove_support == null) {
+        this.create_support = drafts_folder as Geary.FolderSupport.Create;
+        this.remove_support = drafts_folder as Geary.FolderSupport.Remove;
+        if (this.create_support == null || this.remove_support == null) {
             throw new EngineError.UNSUPPORTED("%s: Drafts folder %s does not support create and remove",
                 to_string(), drafts_folder.to_string());
         }
 
-        drafts_folder.closed.connect(on_folder_closed);
+        this.drafts_folder.closed.connect(on_folder_closed);
 
         yield drafts_folder.open_async(Folder.OpenFlags.NO_DELAY, cancellable);
 
@@ -304,7 +299,6 @@ public class Geary.App.DraftManager : BaseObject {
      * date_received arguments.
      */
     public async void update(Geary.RFC822.Message draft,
-                             Geary.EmailFlags? flags,
                              DateTime? date_received,
                              GLib.Cancellable? cancellable) throws GLib.Error {
         check_open();


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