[geary/geary-0.6: 14/14] Don't save draft when UIDPLUS is not present: Closes bgo#713983



commit 6607c9944e62ead75150524a4550b02bd7b81984
Author: Charles Lindsay <chaz yorba org>
Date:   Fri Apr 4 13:01:01 2014 -0700

    Don't save draft when UIDPLUS is not present: Closes bgo#713983
    
    Without UIDPLUS Geary currently cannot determine the UID of the drafts
    it saves to the server, and so it cannot delete them when the draft is
    saved again or the message is sent.  This patch simply checks if
    UIDPLUS is supported, and if not, does not save the draft to the
    server.
    
    Although a string is included in this patch, it's a duplicate of an
    existing string and so technically does not break string freeze.

 src/client/composer/composer-window.vala           |   37 +++++++++++++++-----
 .../api/geary-aggregated-folder-properties.vala    |    2 +-
 src/engine/api/geary-folder-properties.vala        |   11 +++++-
 src/engine/api/geary-search-folder.vala            |    2 +-
 .../outbox/smtp-outbox-folder-properties.vala      |    2 +-
 src/engine/imap/api/imap-folder-properties.vala    |    8 +++-
 src/engine/imap/api/imap-folder.vala               |    2 +
 7 files changed, 49 insertions(+), 15 deletions(-)
---
diff --git a/src/client/composer/composer-window.vala b/src/client/composer/composer-window.vala
index d0a83e4..7351e2f 100644
--- a/src/client/composer/composer-window.vala
+++ b/src/client/composer/composer-window.vala
@@ -667,28 +667,39 @@ public class ComposerWindow : Gtk.Window {
         update_from_field();
     }
     
+    private bool can_save() {
+        return (drafts_folder != null && drafts_folder.get_open_state() == Geary.Folder.OpenState.BOTH
+            && !drafts_folder.properties.create_never_returns_id && editor.can_undo());
+    }
+
     public bool should_close() {
-        if (!editor.can_undo())
-            return true;
+        bool try_to_save = can_save();
         
         present();
         AlertDialog dialog;
         
-        if (drafts_folder == null) {
+        if (drafts_folder == null && try_to_save) {
             dialog = new ConfirmationDialog(this,
                 _("Do you want to discard the unsaved message?"), null, Stock._DISCARD);
-        } else {
+        } else if (try_to_save) {
             dialog = new TernaryConfirmationDialog(this,
                 _("Do you want to discard this message?"), null, Stock._KEEP, Stock._DISCARD,
                 Gtk.ResponseType.CLOSE);
+        } else {
+            dialog = new ConfirmationDialog(this,
+                _("Do you want to discard this message?"), null, Stock._DISCARD);
         }
         
         Gtk.ResponseType response = dialog.run();
         if (response == Gtk.ResponseType.CANCEL || response == Gtk.ResponseType.DELETE_EVENT) {
             return false; // Cancel
         } else if (response == Gtk.ResponseType.OK) {
-            save_and_exit.begin(); // Save
-            return false;
+            if (try_to_save) {
+                save_and_exit.begin(); // Save
+                return false;
+            } else {
+                return true;
+            }
         } else {
             delete_and_exit.begin(); // Discard
             return false;
@@ -798,6 +809,11 @@ public class ComposerWindow : Gtk.Window {
         destroy(); // Only close window after draft is deleted; this closes the drafts folder.
     }
     
+    private void on_drafts_opened(Geary.Folder.OpenState open_state, int count) {
+        if (open_state == Geary.Folder.OpenState.BOTH)
+            reset_draft_timer();
+    }
+    
     // Returns the drafts folder for the current From account.
     private async void open_drafts_folder_async(Cancellable cancellable) throws Error {
         yield close_drafts_folder_async(cancellable);
@@ -808,9 +824,11 @@ public class ComposerWindow : Gtk.Window {
         if (folder == null)
             return; // No drafts folder.
         
-        yield folder.open_async(Geary.Folder.OpenFlags.FAST_OPEN, cancellable);
+        yield folder.open_async(Geary.Folder.OpenFlags.FAST_OPEN | Geary.Folder.OpenFlags.NO_DELAY,
+            cancellable);
         
         drafts_folder = folder;
+        drafts_folder.opened.connect(on_drafts_opened);
     }
     
     private async void close_drafts_folder_async(Cancellable? cancellable = null) throws Error {
@@ -818,6 +836,7 @@ public class ComposerWindow : Gtk.Window {
             return;
         
         // Close existing folder.
+        drafts_folder.opened.disconnect(on_drafts_opened);
         yield drafts_folder.close_async(cancellable);
         drafts_folder = null;
     }
@@ -835,7 +854,7 @@ public class ComposerWindow : Gtk.Window {
     }
     
     private async void save_async(Cancellable? cancellable) {
-        if (drafts_folder == null)
+        if (drafts_folder == null || !can_save())
             return;
         
         draft_save_label.label = DRAFT_SAVING_TEXT;
@@ -1555,7 +1574,7 @@ public class ComposerWindow : Gtk.Window {
     
     // Resets the draft save timeout.
     private void reset_draft_timer() {
-        if (!editor.can_undo())
+        if (!can_save())
             return;
         
         draft_save_label.label = "";
diff --git a/src/engine/api/geary-aggregated-folder-properties.vala 
b/src/engine/api/geary-aggregated-folder-properties.vala
index ea165e2..986b9e6 100644
--- a/src/engine/api/geary-aggregated-folder-properties.vala
+++ b/src/engine/api/geary-aggregated-folder-properties.vala
@@ -23,7 +23,7 @@ private class Geary.AggregatedFolderProperties : Geary.FolderProperties {
      */
     public AggregatedFolderProperties(bool is_local_only, bool is_virtual) {
         // Set defaults.
-        base(0, 0, Trillian.UNKNOWN, Trillian.UNKNOWN, Trillian.UNKNOWN, is_local_only, is_virtual);
+        base(0, 0, Trillian.UNKNOWN, Trillian.UNKNOWN, Trillian.UNKNOWN, is_local_only, is_virtual, false);
     }
     
     /**
diff --git a/src/engine/api/geary-folder-properties.vala b/src/engine/api/geary-folder-properties.vala
index f40cf7c..2f571da 100644
--- a/src/engine/api/geary-folder-properties.vala
+++ b/src/engine/api/geary-folder-properties.vala
@@ -59,8 +59,16 @@ public abstract class Geary.FolderProperties : BaseObject {
      */
     public bool is_virtual { get; private set; }
     
+    /**
+     * True if APPEND on the folder will never return the created UID.  This is
+     * for servers that don't support UIDPLUS.  Most servers support UIDPLUS,
+     * so this will usually be false.
+     */
+    public bool create_never_returns_id { get; protected set; }
+    
     protected FolderProperties(int email_total, int email_unread, Trillian has_children,
-        Trillian supports_children, Trillian is_openable, bool is_local_only, bool is_virtual) {
+        Trillian supports_children, Trillian is_openable, bool is_local_only, bool is_virtual,
+        bool create_never_returns_id) {
         this.email_total = email_total;
         this.email_unread = email_unread;
         this.has_children = has_children;
@@ -68,6 +76,7 @@ public abstract class Geary.FolderProperties : BaseObject {
         this.is_openable = is_openable;
         this.is_local_only = is_local_only;
         this.is_virtual = is_virtual;
+        this.create_never_returns_id = create_never_returns_id;
     }
 }
 
diff --git a/src/engine/api/geary-search-folder.vala b/src/engine/api/geary-search-folder.vala
index 518b409..672853f 100644
--- a/src/engine/api/geary-search-folder.vala
+++ b/src/engine/api/geary-search-folder.vala
@@ -14,7 +14,7 @@ public class Geary.SearchFolderRoot : Geary.FolderRoot {
 
 public class Geary.SearchFolderProperties : Geary.FolderProperties {
     public SearchFolderProperties(int total, int unread) {
-        base(total, unread, Trillian.FALSE, Trillian.FALSE, Trillian.TRUE, true, true);
+        base(total, unread, Trillian.FALSE, Trillian.FALSE, Trillian.TRUE, true, true, false);
     }
     
     public void set_total(int total) {
diff --git a/src/engine/imap-db/outbox/smtp-outbox-folder-properties.vala 
b/src/engine/imap-db/outbox/smtp-outbox-folder-properties.vala
index 1873439..535e3ef 100644
--- a/src/engine/imap-db/outbox/smtp-outbox-folder-properties.vala
+++ b/src/engine/imap-db/outbox/smtp-outbox-folder-properties.vala
@@ -6,7 +6,7 @@
 
 private class Geary.SmtpOutboxFolderProperties : Geary.FolderProperties {
     public SmtpOutboxFolderProperties(int total, int unread) {
-        base (total, unread, Trillian.FALSE, Trillian.FALSE, Trillian.TRUE, true, false);
+        base (total, unread, Trillian.FALSE, Trillian.FALSE, Trillian.TRUE, true, false, false);
     }
     
     public void set_total(int total) {
diff --git a/src/engine/imap/api/imap-folder-properties.vala b/src/engine/imap/api/imap-folder-properties.vala
index 4b7b4b3..c062186 100644
--- a/src/engine/imap/api/imap-folder-properties.vala
+++ b/src/engine/imap/api/imap-folder-properties.vala
@@ -67,7 +67,7 @@ public class Geary.Imap.FolderProperties : Geary.FolderProperties {
         // give the base class a zero email_unread, as the notion of "unknown" doesn't exist in
         // its contract
         base (messages, email_unread, Trillian.UNKNOWN, Trillian.UNKNOWN, Trillian.UNKNOWN, false,
-            false);
+            false, false);
         
         select_examine_messages = messages;
         status_messages = -1;
@@ -82,7 +82,7 @@ public class Geary.Imap.FolderProperties : Geary.FolderProperties {
     
     public FolderProperties.status(StatusData status, MailboxAttributes attrs) {
         base (status.messages, status.unseen, Trillian.UNKNOWN, Trillian.UNKNOWN, Trillian.UNKNOWN,
-            false, false);
+            false, false, false);
         
         select_examine_messages = -1;
         status_messages = status.messages;
@@ -213,5 +213,9 @@ public class Geary.Imap.FolderProperties : Geary.FolderProperties {
         // update base class value (which clients see)
         email_unread = count;
     }
+    
+    public void set_from_session_capabilities(Capabilities capabilities) {
+        create_never_returns_id = !capabilities.supports_uidplus();
+    }
 }
 
diff --git a/src/engine/imap/api/imap-folder.vala b/src/engine/imap/api/imap-folder.vala
index 71741ad..72c2c23 100644
--- a/src/engine/imap/api/imap-folder.vala
+++ b/src/engine/imap/api/imap-folder.vala
@@ -95,6 +95,8 @@ private class Geary.Imap.Folder : BaseObject {
         session.status_response_received.connect(on_status_response);
         session.disconnected.connect(on_disconnected);
         
+        properties.set_from_session_capabilities(session.capabilities);
+        
         StatusResponse response = yield session.select_async(
             new MailboxSpecifier.from_folder_path(path, info.delim), cancellable);
         if (response.status != Status.OK) {


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