[evolution-data-server] [IMAPx] Correct expunge and real trash/junk handling



commit 5350edde5c444d1597dbf7a2294d0b45f03baa5a
Author: Milan Crha <mcrha redhat com>
Date:   Tue Aug 18 18:04:19 2015 +0200

    [IMAPx] Correct expunge and real trash/junk handling

 camel/providers/imapx/camel-imapx-conn-manager.c |  339 ++++++++++++++++++++-
 camel/providers/imapx/camel-imapx-folder.c       |  231 +--------------
 camel/providers/imapx/camel-imapx-folder.h       |    6 +
 camel/providers/imapx/camel-imapx-server.c       |   54 ++--
 4 files changed, 364 insertions(+), 266 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c 
b/camel/providers/imapx/camel-imapx-conn-manager.c
index 9aea32c..4ef48d0 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -26,6 +26,7 @@
 #include <glib/gi18n-lib.h>
 
 #include "camel-imapx-conn-manager.h"
+#include "camel-imapx-folder.h"
 #include "camel-imapx-job.h"
 #include "camel-imapx-settings.h"
 #include "camel-imapx-store.h"
@@ -94,6 +95,16 @@ G_DEFINE_TYPE (
        camel_imapx_conn_manager,
        G_TYPE_OBJECT)
 
+static gboolean
+imapx_conn_manager_copy_message_sync (CamelIMAPXConnManager *conn_man,
+                                     CamelIMAPXMailbox *mailbox,
+                                     CamelIMAPXMailbox *destination,
+                                     GPtrArray *uids,
+                                     gboolean delete_originals,
+                                     gboolean remove_deleted_flags,
+                                     gboolean skip_sync_changes,
+                                     GCancellable *cancellable,
+                                     GError **error);
 
 typedef struct _MailboxRefreshData {
        CamelIMAPXConnManager *conn_man;
@@ -319,6 +330,29 @@ imapx_conn_manager_abort_jobs (CamelIMAPXConnManager *conn_man)
        JOB_QUEUE_UNLOCK (conn_man);
 }
 
+static CamelFolder *
+imapx_conn_manager_ref_folder_sync (CamelIMAPXConnManager *conn_man,
+                                   CamelIMAPXMailbox *mailbox,
+                                   GCancellable *cancellable,
+                                   GError **error)
+{
+       CamelIMAPXStore *store;
+       CamelFolder *folder;
+       gchar *folder_path;
+
+       store = camel_imapx_conn_manager_ref_store (conn_man);
+       folder_path = camel_imapx_mailbox_dup_folder_path (mailbox);
+
+       folder = camel_store_get_folder_sync (CAMEL_STORE (store), folder_path, 0, cancellable, NULL);
+       if (folder)
+               camel_imapx_folder_set_mailbox (CAMEL_IMAPX_FOLDER (folder), mailbox);
+
+       g_free (folder_path);
+       g_clear_object (&store);
+
+       return folder;
+}
+
 static void
 imapx_conn_manager_set_store (CamelIMAPXConnManager *conn_man,
                               CamelStore *store)
@@ -1021,6 +1055,8 @@ static gboolean
 imapx_conn_manager_matches_sync_changes_or_refresh_info (CamelIMAPXJob *job,
                                                         CamelIMAPXJob *other_job)
 {
+       CamelIMAPXJobKind other_job_kind;
+
        g_return_val_if_fail (job != NULL, FALSE);
        g_return_val_if_fail (other_job != NULL, FALSE);
        g_return_val_if_fail (job != other_job, FALSE);
@@ -1028,8 +1064,10 @@ imapx_conn_manager_matches_sync_changes_or_refresh_info (CamelIMAPXJob *job,
        if (camel_imapx_job_get_mailbox (job) != camel_imapx_job_get_mailbox (other_job))
                return FALSE;
 
-       return camel_imapx_job_get_kind (other_job) == CAMEL_IMAPX_JOB_SYNC_CHANGES ||
-               camel_imapx_job_get_kind (other_job) == CAMEL_IMAPX_JOB_REFRESH_INFO;
+       other_job_kind = camel_imapx_job_get_kind (other_job);
+
+       return other_job_kind == CAMEL_IMAPX_JOB_SYNC_CHANGES ||
+              other_job_kind == CAMEL_IMAPX_JOB_REFRESH_INFO;
 }
 
 struct ListJobData {
@@ -1158,6 +1196,9 @@ camel_imapx_conn_manager_refresh_info_sync (CamelIMAPXConnManager *conn_man,
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (conn_man), FALSE);
 
+       if (!camel_imapx_conn_manager_sync_changes_sync (conn_man, mailbox, cancellable, error))
+               return FALSE;
+
        job = camel_imapx_job_new (CAMEL_IMAPX_JOB_REFRESH_INFO, mailbox,
                imapx_conn_manager_refresh_info_run_sync, NULL, NULL);
 
@@ -1171,6 +1212,195 @@ camel_imapx_conn_manager_refresh_info_sync (CamelIMAPXConnManager *conn_man,
 }
 
 static gboolean
+imapx_conn_manager_move_to_real_junk_sync (CamelIMAPXConnManager *conn_man,
+                                          CamelFolder *folder,
+                                          GCancellable *cancellable,
+                                          gboolean *out_need_to_expunge,
+                                          GError **error)
+{
+       CamelIMAPXFolder *imapx_folder;
+       CamelIMAPXMailbox *mailbox;
+       CamelIMAPXSettings *settings;
+       GPtrArray *uids_to_copy;
+       gchar *real_junk_path = NULL;
+       gboolean success = TRUE;
+
+       *out_need_to_expunge = FALSE;
+
+       /* Caller already obtained the mailbox from the folder,
+        * so the folder should still have it readily available. */
+       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
+       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
+       uids_to_copy = g_ptr_array_new_with_free_func (
+               (GDestroyNotify) camel_pstring_free);
+
+       settings = CAMEL_IMAPX_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE 
(camel_folder_get_parent_store (folder))));
+       if (camel_imapx_settings_get_use_real_junk_path (settings)) {
+               real_junk_path = camel_imapx_settings_dup_real_junk_path (settings);
+               camel_imapx_folder_claim_move_to_real_junk_uids (imapx_folder, uids_to_copy);
+       }
+       g_object_unref (settings);
+
+       if (uids_to_copy->len > 0) {
+               CamelIMAPXStore *imapx_store;
+               CamelIMAPXMailbox *destination = NULL;
+
+               imapx_store = camel_imapx_conn_manager_ref_store (conn_man);
+
+               if (real_junk_path != NULL) {
+                       folder = camel_store_get_folder_sync (
+                               CAMEL_STORE (imapx_store),
+                               real_junk_path, 0,
+                               cancellable, error);
+               } else {
+                       g_set_error (
+                               error, CAMEL_FOLDER_ERROR,
+                               CAMEL_FOLDER_ERROR_INVALID_PATH,
+                               _("No destination folder specified"));
+                       folder = NULL;
+               }
+
+               if (folder != NULL) {
+                       destination = camel_imapx_folder_list_mailbox (
+                               CAMEL_IMAPX_FOLDER (folder),
+                               cancellable, error);
+                       g_object_unref (folder);
+               }
+
+               /* Avoid duplicating messages in the Junk folder. */
+               if (destination == mailbox) {
+                       success = TRUE;
+               } else if (destination != NULL) {
+                       success = imapx_conn_manager_copy_message_sync (
+                               conn_man, mailbox, destination,
+                               uids_to_copy, TRUE, FALSE, TRUE,
+                               cancellable, error);
+                       *out_need_to_expunge = success;
+               } else {
+                       success = FALSE;
+               }
+
+               if (!success) {
+                       g_prefix_error (
+                               error, "%s: ",
+                               _("Unable to move junk messages"));
+               }
+
+               g_clear_object (&destination);
+               g_clear_object (&imapx_store);
+       }
+
+       g_ptr_array_unref (uids_to_copy);
+       g_free (real_junk_path);
+
+       g_clear_object (&mailbox);
+
+       return success;
+}
+
+static gboolean
+imapx_conn_manager_move_to_real_trash_sync (CamelIMAPXConnManager *conn_man,
+                                           CamelFolder *folder,
+                                           GCancellable *cancellable,
+                                           gboolean *out_need_to_expunge,
+                                           GError **error)
+{
+       CamelIMAPXFolder *imapx_folder;
+       CamelIMAPXMailbox *mailbox, *destination = NULL;
+       CamelIMAPXSettings *settings;
+       CamelIMAPXStore *imapx_store;
+       GPtrArray *uids_to_copy;
+       gchar *real_trash_path = NULL;
+       guint32 folder_deleted_count = 0;
+       gboolean success = TRUE;
+
+       *out_need_to_expunge = FALSE;
+
+       /* Caller already obtained the mailbox from the folder,
+        * so the folder should still have it readily available. */
+       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
+       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
+       g_return_val_if_fail (mailbox != NULL, FALSE);
+
+       uids_to_copy = g_ptr_array_new_with_free_func (
+               (GDestroyNotify) camel_pstring_free);
+
+       settings = CAMEL_IMAPX_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE 
(camel_folder_get_parent_store (folder))));
+       if (camel_imapx_settings_get_use_real_trash_path (settings)) {
+               real_trash_path = camel_imapx_settings_dup_real_trash_path (settings);
+               camel_imapx_folder_claim_move_to_real_trash_uids (CAMEL_IMAPX_FOLDER (folder), uids_to_copy);
+       }
+       g_object_unref (settings);
+
+       imapx_store = camel_imapx_conn_manager_ref_store (conn_man);
+
+       if (real_trash_path != NULL) {
+               folder = camel_store_get_folder_sync (
+                       CAMEL_STORE (imapx_store),
+                       real_trash_path, 0,
+                       cancellable, error);
+       } else {
+               if (uids_to_copy->len > 0) {
+                       g_set_error (
+                               error, CAMEL_FOLDER_ERROR,
+                               CAMEL_FOLDER_ERROR_INVALID_PATH,
+                               _("No destination folder specified"));
+               }
+
+               folder = NULL;
+       }
+
+       if (folder != NULL) {
+               destination = camel_imapx_folder_list_mailbox (
+                       CAMEL_IMAPX_FOLDER (folder),
+                       cancellable, error);
+               folder_deleted_count = camel_folder_summary_get_deleted_count (folder->summary);
+               g_object_unref (folder);
+       }
+
+       /* Avoid duplicating messages in the Trash folder. */
+       if (destination == mailbox) {
+               success = TRUE;
+               /* Deleted messages in the real Trash folder will be permanently deleted immediately. */
+               *out_need_to_expunge = folder_deleted_count > 0 || uids_to_copy->len > 0;
+       } else if (destination != NULL) {
+               if (uids_to_copy->len > 0) {
+                       success = imapx_conn_manager_copy_message_sync (
+                               conn_man, mailbox, destination,
+                               uids_to_copy, TRUE, TRUE, TRUE,
+                               cancellable, error);
+                       *out_need_to_expunge = success;
+               }
+       } else if (uids_to_copy->len > 0) {
+               success = FALSE;
+       }
+
+       if (!success) {
+               g_prefix_error (
+                       error, "%s: ",
+                       _("Unable to move deleted messages"));
+       }
+
+       g_ptr_array_unref (uids_to_copy);
+       g_free (real_trash_path);
+
+       g_clear_object (&imapx_store);
+       g_clear_object (&destination);
+       g_clear_object (&mailbox);
+
+       return success;
+}
+
+static gboolean
+imapx_conn_manager_expunge_sync (CamelIMAPXConnManager *conn_man,
+                                CamelIMAPXMailbox *mailbox,
+                                gboolean skip_sync_changes,
+                                GCancellable *cancellable,
+                                GError **error);
+
+static gboolean
 imapx_conn_manager_sync_changes_run_sync (CamelIMAPXJob *job,
                                          CamelIMAPXServer *server,
                                          GCancellable *cancellable,
@@ -1203,6 +1433,8 @@ camel_imapx_conn_manager_sync_changes_sync (CamelIMAPXConnManager *conn_man,
                                            GError **error)
 {
        CamelIMAPXJob *job;
+       CamelFolder *folder = NULL;
+       gboolean need_to_expunge = FALSE, expunge = FALSE;
        gboolean success;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (conn_man), FALSE);
@@ -1216,6 +1448,32 @@ camel_imapx_conn_manager_sync_changes_sync (CamelIMAPXConnManager *conn_man,
 
        camel_imapx_job_unref (job);
 
+       if (success) {
+               folder = imapx_conn_manager_ref_folder_sync (conn_man, mailbox, cancellable, error);
+               if (!folder)
+                       success = FALSE;
+       }
+
+       if (success) {
+               success = imapx_conn_manager_move_to_real_junk_sync (
+                       conn_man, folder, cancellable,
+                       &need_to_expunge, error);
+               expunge |= need_to_expunge;
+       }
+
+       if (success) {
+               success = imapx_conn_manager_move_to_real_trash_sync (
+                       conn_man, folder, cancellable,
+                       &need_to_expunge, error);
+               expunge |= need_to_expunge;
+       }
+
+       if (success && expunge) {
+               success = imapx_conn_manager_expunge_sync (conn_man, mailbox, TRUE, cancellable, error);
+       }
+
+       g_clear_object (&folder);
+
        return success;
 }
 
@@ -1246,16 +1504,20 @@ imapx_conn_manager_expunge_run_sync (CamelIMAPXJob *job,
 }
 
 gboolean
-camel_imapx_conn_manager_expunge_sync (CamelIMAPXConnManager *conn_man,
-                                      CamelIMAPXMailbox *mailbox,
-                                      GCancellable *cancellable,
-                                      GError **error)
+imapx_conn_manager_expunge_sync (CamelIMAPXConnManager *conn_man,
+                                CamelIMAPXMailbox *mailbox,
+                                gboolean skip_sync_changes,
+                                GCancellable *cancellable,
+                                GError **error)
 {
        CamelIMAPXJob *job;
        gboolean success;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (conn_man), FALSE);
 
+       if (!skip_sync_changes && !camel_imapx_conn_manager_sync_changes_sync (conn_man, mailbox, 
cancellable, error))
+               return FALSE;
+
        job = camel_imapx_job_new (CAMEL_IMAPX_JOB_EXPUNGE, mailbox,
                imapx_conn_manager_expunge_run_sync, NULL, NULL);
 
@@ -1266,6 +1528,15 @@ camel_imapx_conn_manager_expunge_sync (CamelIMAPXConnManager *conn_man,
        return success;
 }
 
+gboolean
+camel_imapx_conn_manager_expunge_sync (CamelIMAPXConnManager *conn_man,
+                                      CamelIMAPXMailbox *mailbox,
+                                      GCancellable *cancellable,
+                                      GError **error)
+{
+       return imapx_conn_manager_expunge_sync (conn_man, mailbox, FALSE, cancellable, error);
+}
+
 struct GetMessageJobData {
        CamelFolderSummary *summary;
        CamelDataCache *message_cache;
@@ -1446,15 +1717,16 @@ imapx_conn_manager_copy_message_run_sync (CamelIMAPXJob *job,
        return success;
 }
 
-gboolean
-camel_imapx_conn_manager_copy_message_sync (CamelIMAPXConnManager *conn_man,
-                                           CamelIMAPXMailbox *mailbox,
-                                           CamelIMAPXMailbox *destination,
-                                           GPtrArray *uids,
-                                           gboolean delete_originals,
-                                           gboolean remove_deleted_flags,
-                                           GCancellable *cancellable,
-                                           GError **error)
+static gboolean
+imapx_conn_manager_copy_message_sync (CamelIMAPXConnManager *conn_man,
+                                     CamelIMAPXMailbox *mailbox,
+                                     CamelIMAPXMailbox *destination,
+                                     GPtrArray *uids,
+                                     gboolean delete_originals,
+                                     gboolean remove_deleted_flags,
+                                     gboolean skip_sync_changes,
+                                     GCancellable *cancellable,
+                                     GError **error)
 {
        CamelIMAPXJob *job;
        struct CopyMessageJobData *job_data;
@@ -1463,6 +1735,9 @@ camel_imapx_conn_manager_copy_message_sync (CamelIMAPXConnManager *conn_man,
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (conn_man), FALSE);
 
+       if (!skip_sync_changes && !camel_imapx_conn_manager_sync_changes_sync (conn_man, mailbox, 
cancellable, error))
+               return FALSE;
+
        job = camel_imapx_job_new (CAMEL_IMAPX_JOB_COPY_MESSAGE, mailbox,
                imapx_conn_manager_copy_message_run_sync,
                imapx_conn_manager_nothing_matches,
@@ -1484,9 +1759,39 @@ camel_imapx_conn_manager_copy_message_sync (CamelIMAPXConnManager *conn_man,
 
        camel_imapx_job_unref (job);
 
+       if (success) {
+               CamelFolder *dest;
+
+               dest = imapx_conn_manager_ref_folder_sync (conn_man, destination, cancellable, NULL);
+
+               /* Update destination folder only if it's not frozen,
+                * to avoid updating for each "move" action on a single
+                * message while filtering. */
+               if (dest && !camel_folder_is_frozen (dest)) {
+                       /* Ignore errors here */
+                       camel_imapx_conn_manager_refresh_info_sync (conn_man, destination, cancellable, NULL);
+               }
+
+               g_clear_object (&dest);
+       }
+
        return success;
 }
 
+gboolean
+camel_imapx_conn_manager_copy_message_sync (CamelIMAPXConnManager *conn_man,
+                                           CamelIMAPXMailbox *mailbox,
+                                           CamelIMAPXMailbox *destination,
+                                           GPtrArray *uids,
+                                           gboolean delete_originals,
+                                           gboolean remove_deleted_flags,
+                                           GCancellable *cancellable,
+                                           GError **error)
+{
+       return imapx_conn_manager_copy_message_sync (conn_man, mailbox, destination, uids,
+               delete_originals, remove_deleted_flags, FALSE, cancellable, error);
+}
+
 struct AppendMessageJobData {
        CamelFolderSummary *summary;
        CamelDataCache *message_cache;
@@ -2139,7 +2444,7 @@ camel_imapx_conn_manager_dump_queue_status (CamelIMAPXConnManager *conn_man)
 
        CON_READ_UNLOCK (conn_man);
 
-       g_rec_mutex_lock (&conn_man->priv->job_queue_lock);
+       JOB_QUEUE_LOCK (conn_man);
 
        printf ("Queued jobs:%d\n", g_slist_length (conn_man->priv->job_queue));
        for (slink = conn_man->priv->job_queue; slink; slink = g_slist_next (slink)) {
@@ -2150,5 +2455,5 @@ camel_imapx_conn_manager_dump_queue_status (CamelIMAPXConnManager *conn_man)
                        job && camel_imapx_job_get_mailbox (job) ? camel_imapx_mailbox_get_name 
(camel_imapx_job_get_mailbox (job)) : "[null]");
        }
 
-       g_rec_mutex_unlock (&conn_man->priv->job_queue_lock);
+       JOB_QUEUE_UNLOCK (conn_man);
 }
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index 729d22e..532f321 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -66,9 +66,9 @@ G_DEFINE_TYPE (CamelIMAPXFolder, camel_imapx_folder, CAMEL_TYPE_OFFLINE_FOLDER)
 
 static gboolean imapx_folder_get_apply_filters (CamelIMAPXFolder *folder);
 
-static void
-imapx_folder_claim_move_to_real_junk_uids (CamelIMAPXFolder *folder,
-                                           GPtrArray *out_uids_to_copy)
+void
+camel_imapx_folder_claim_move_to_real_junk_uids (CamelIMAPXFolder *folder,
+                                                GPtrArray *out_uids_to_copy)
 {
        GList *keys;
 
@@ -85,9 +85,9 @@ imapx_folder_claim_move_to_real_junk_uids (CamelIMAPXFolder *folder,
        }
 }
 
-static void
-imapx_folder_claim_move_to_real_trash_uids (CamelIMAPXFolder *folder,
-                                            GPtrArray *out_uids_to_copy)
+void
+camel_imapx_folder_claim_move_to_real_trash_uids (CamelIMAPXFolder *folder,
+                                                 GPtrArray *out_uids_to_copy)
 {
        GList *keys;
 
@@ -750,192 +750,6 @@ imapx_refresh_info_sync (CamelFolder *folder,
        return success;
 }
 
-/* Helper for imapx_synchronize_sync() */
-static gboolean
-imapx_move_to_real_junk (CamelIMAPXConnManager *conn_man,
-                         CamelFolder *folder,
-                         GCancellable *cancellable,
-                         gboolean *out_need_to_expunge,
-                         GError **error)
-{
-       CamelIMAPXFolder *imapx_folder;
-       CamelIMAPXMailbox *mailbox;
-       CamelIMAPXSettings *settings;
-       GPtrArray *uids_to_copy;
-       gchar *real_junk_path = NULL;
-       gboolean success = TRUE;
-
-       *out_need_to_expunge = FALSE;
-
-       /* Caller already obtained the mailbox from the folder,
-        * so the folder should still have it readily available. */
-       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
-       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
-       g_return_val_if_fail (mailbox != NULL, FALSE);
-
-       uids_to_copy = g_ptr_array_new_with_free_func (
-               (GDestroyNotify) camel_pstring_free);
-
-       settings = CAMEL_IMAPX_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE 
(camel_folder_get_parent_store (folder))));
-       if (camel_imapx_settings_get_use_real_junk_path (settings)) {
-               real_junk_path =
-                       camel_imapx_settings_dup_real_junk_path (settings);
-               imapx_folder_claim_move_to_real_junk_uids (
-                       imapx_folder, uids_to_copy);
-       }
-       g_object_unref (settings);
-
-       if (uids_to_copy->len > 0) {
-               CamelIMAPXStore *imapx_store;
-               CamelIMAPXMailbox *destination = NULL;
-
-               imapx_store = camel_imapx_conn_manager_ref_store (conn_man);
-
-               if (real_junk_path != NULL) {
-                       folder = camel_store_get_folder_sync (
-                               CAMEL_STORE (imapx_store),
-                               real_junk_path, 0,
-                               cancellable, error);
-               } else {
-                       g_set_error (
-                               error, CAMEL_FOLDER_ERROR,
-                               CAMEL_FOLDER_ERROR_INVALID_PATH,
-                               _("No destination folder specified"));
-                       folder = NULL;
-               }
-
-               if (folder != NULL) {
-                       destination = camel_imapx_folder_list_mailbox (
-                               CAMEL_IMAPX_FOLDER (folder),
-                               cancellable, error);
-                       g_object_unref (folder);
-               }
-
-               /* Avoid duplicating messages in the Junk folder. */
-               if (destination == mailbox) {
-                       success = TRUE;
-               } else if (destination != NULL) {
-                       success = camel_imapx_conn_manager_copy_message_sync (
-                               conn_man, mailbox, destination,
-                               uids_to_copy, TRUE, FALSE,
-                               cancellable, error);
-                       *out_need_to_expunge = success;
-               } else {
-                       success = FALSE;
-               }
-
-               if (!success) {
-                       g_prefix_error (
-                               error, "%s: ",
-                               _("Unable to move junk messages"));
-               }
-
-               g_clear_object (&destination);
-               g_clear_object (&imapx_store);
-       }
-
-       g_ptr_array_unref (uids_to_copy);
-       g_free (real_junk_path);
-
-       g_clear_object (&mailbox);
-
-       return success;
-}
-
-/* Helper for imapx_synchronize_sync() */
-static gboolean
-imapx_move_to_real_trash (CamelIMAPXConnManager *conn_man,
-                          CamelFolder *folder,
-                          GCancellable *cancellable,
-                          gboolean *out_need_to_expunge,
-                          GError **error)
-{
-       CamelIMAPXFolder *imapx_folder;
-       CamelIMAPXMailbox *mailbox;
-       CamelIMAPXSettings *settings;
-       GPtrArray *uids_to_copy;
-       gchar *real_trash_path = NULL;
-       gboolean success = TRUE;
-
-       *out_need_to_expunge = FALSE;
-
-       /* Caller already obtained the mailbox from the folder,
-        * so the folder should still have it readily available. */
-       imapx_folder = CAMEL_IMAPX_FOLDER (folder);
-       mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
-       g_return_val_if_fail (mailbox != NULL, FALSE);
-
-       uids_to_copy = g_ptr_array_new_with_free_func (
-               (GDestroyNotify) camel_pstring_free);
-
-       settings = CAMEL_IMAPX_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE 
(camel_folder_get_parent_store (folder))));
-       if (camel_imapx_settings_get_use_real_trash_path (settings)) {
-               real_trash_path =
-                       camel_imapx_settings_dup_real_trash_path (settings);
-               imapx_folder_claim_move_to_real_trash_uids (
-                       CAMEL_IMAPX_FOLDER (folder), uids_to_copy);
-       }
-       g_object_unref (settings);
-
-       if (uids_to_copy->len > 0) {
-               CamelIMAPXStore *imapx_store;
-               CamelIMAPXMailbox *destination = NULL;
-
-               imapx_store = camel_imapx_conn_manager_ref_store (conn_man);
-
-               if (real_trash_path != NULL) {
-                       folder = camel_store_get_folder_sync (
-                               CAMEL_STORE (imapx_store),
-                               real_trash_path, 0,
-                               cancellable, error);
-               } else {
-                       g_set_error (
-                               error, CAMEL_FOLDER_ERROR,
-                               CAMEL_FOLDER_ERROR_INVALID_PATH,
-                               _("No destination folder specified"));
-                       folder = NULL;
-               }
-
-               if (folder != NULL) {
-                       destination = camel_imapx_folder_list_mailbox (
-                               CAMEL_IMAPX_FOLDER (folder),
-                               cancellable, error);
-                       g_object_unref (folder);
-               }
-
-               /* Avoid duplicating messages in the Trash folder. */
-               if (destination == mailbox) {
-                       success = TRUE;
-                       /* Deleted messages in the real Trash folder will be permanently deleted immediately. 
*/
-                       *out_need_to_expunge = TRUE;
-               } else if (destination != NULL) {
-                       success = camel_imapx_conn_manager_copy_message_sync (
-                               conn_man, mailbox, destination,
-                               uids_to_copy, TRUE, TRUE,
-                               cancellable, error);
-                       *out_need_to_expunge = success;
-               } else {
-                       success = FALSE;
-               }
-
-               if (!success) {
-                       g_prefix_error (
-                               error, "%s: ",
-                               _("Unable to move deleted messages"));
-               }
-
-               g_clear_object (&destination);
-               g_clear_object (&imapx_store);
-       }
-
-       g_ptr_array_unref (uids_to_copy);
-       g_free (real_trash_path);
-
-       g_clear_object (&mailbox);
-
-       return success;
-}
-
 static gboolean
 imapx_synchronize_sync (CamelFolder *folder,
                         gboolean expunge,
@@ -946,7 +760,6 @@ imapx_synchronize_sync (CamelFolder *folder,
        CamelIMAPXStore *imapx_store;
        CamelIMAPXConnManager *conn_man;
        CamelIMAPXMailbox *mailbox = NULL;
-       gboolean need_to_expunge;
        gboolean success = FALSE;
 
        store = camel_folder_get_parent_store (folder);
@@ -964,32 +777,10 @@ imapx_synchronize_sync (CamelFolder *folder,
        if (mailbox == NULL || (camel_application_is_exiting &&
            camel_imapx_mailbox_get_permanentflags (mailbox) == ~0)) {
                success = mailbox != NULL;
-               goto exit;
-       }
-
-       success = camel_imapx_conn_manager_sync_changes_sync (conn_man, mailbox, cancellable, error);
-
-       if (success) {
-               success = imapx_move_to_real_junk (
-                       conn_man, folder, cancellable,
-                       &need_to_expunge, error);
-               expunge |= need_to_expunge;
-       }
-
-       if (success) {
-               success = imapx_move_to_real_trash (
-                       conn_man, folder, cancellable,
-                       &need_to_expunge, error);
-               expunge |= need_to_expunge;
+       } else {
+               success = camel_imapx_conn_manager_sync_changes_sync (conn_man, mailbox, cancellable, error);
        }
 
-       /* Sync twice - make sure deleted flags are written out,
-        * then sync again incase expunge changed anything */
-
-       if (success && expunge)
-               success = camel_imapx_conn_manager_expunge_sync (conn_man, mailbox, cancellable, error);
-
-exit:
        g_clear_object (&mailbox);
 
        return success;
@@ -1066,12 +857,6 @@ imapx_transfer_messages_to_sync (CamelFolder *source,
                conn_man, src_mailbox, dst_mailbox, uids,
                delete_originals, FALSE, cancellable, error);
 
-       /* Update destination folder only if it's not frozen,
-        * to avoid updating for each "move" action on a single
-        * message while filtering. */
-       if (!camel_folder_is_frozen (dest))
-               imapx_refresh_info_sync (dest, cancellable, NULL);
-
 exit:
        g_clear_object (&src_mailbox);
        g_clear_object (&dst_mailbox);
diff --git a/camel/providers/imapx/camel-imapx-folder.h b/camel/providers/imapx/camel-imapx-folder.h
index a894ced..12c3d9b 100644
--- a/camel/providers/imapx/camel-imapx-folder.h
+++ b/camel/providers/imapx/camel-imapx-folder.h
@@ -96,6 +96,12 @@ gboolean     camel_imapx_folder_get_check_folder
 void           camel_imapx_folder_set_check_folder
                                                (CamelIMAPXFolder *folder,
                                                 gboolean check_folder);
+void           camel_imapx_folder_claim_move_to_real_junk_uids
+                                               (CamelIMAPXFolder *folder,
+                                                GPtrArray *out_uids_to_copy);
+void           camel_imapx_folder_claim_move_to_real_trash_uids
+                                               (CamelIMAPXFolder *folder,
+                                                GPtrArray *out_uids_to_copy);
 
 G_END_DECLS
 
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 321daf1..71dfda6 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -4983,12 +4983,11 @@ imapx_unset_folder_flagged_flag (CamelFolderSummary *summary,
        }
 }
 
-static gboolean
-imapx_server_sync_changes_sync (CamelIMAPXServer *is,
-                               CamelIMAPXMailbox *mailbox,
-                               gboolean is_expunge,
-                               GCancellable *cancellable,
-                               GError **error)
+gboolean
+camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
+                                     CamelIMAPXMailbox *mailbox,
+                                     GCancellable *cancellable,
+                                     GError **error)
 {
        guint i, jj, on, on_orset, off_orset;
        GPtrArray *changed_uids;
@@ -5001,10 +5000,13 @@ imapx_server_sync_changes_sync (CamelIMAPXServer *is,
        gint unread_change = 0;
        gboolean use_real_junk_path;
        gboolean use_real_trash_path;
-       gboolean remove_deleted_flags;
+       gboolean remove_deleted_flags = FALSE;
        gboolean nothing_to_do;
        gboolean success;
 
+       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
+       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
+
        folder = imapx_server_ref_folder (is, mailbox);
        g_return_val_if_fail (folder != NULL, FALSE);
 
@@ -5029,9 +5031,25 @@ imapx_server_sync_changes_sync (CamelIMAPXServer *is,
        settings = camel_imapx_server_ref_settings (is);
        use_real_junk_path = camel_imapx_settings_get_use_real_junk_path (settings);
        use_real_trash_path = camel_imapx_settings_get_use_real_trash_path (settings);
-       g_object_unref (settings);
+       if (use_real_trash_path) {
+               CamelFolder *trash_folder = NULL;
+               gchar *real_trash_path;
+
+               real_trash_path = camel_imapx_settings_dup_real_trash_path (settings);
+               if (real_trash_path)
+                       trash_folder = camel_store_get_folder_sync (
+                               camel_folder_get_parent_store (folder),
+                               real_trash_path, 0, cancellable, NULL);
 
-       remove_deleted_flags = use_real_trash_path && is_expunge;
+               /* Remove deleted flags in all but the trash folder itself */
+               remove_deleted_flags = !trash_folder || trash_folder != folder;
+
+               use_real_trash_path = trash_folder != NULL;
+
+               g_clear_object (&trash_folder);
+               g_free (real_trash_path);
+       }
+       g_object_unref (settings);
 
        off_orset = on_orset = 0;
        for (i = 0; i < changed_uids->len; i++) {
@@ -5063,7 +5081,7 @@ imapx_server_sync_changes_sync (CamelIMAPXServer *is,
                        (flags & CAMEL_MESSAGE_JUNK);
 
                move_to_real_trash =
-                       use_real_trash_path &&
+                       use_real_trash_path && remove_deleted_flags &&
                        (flags & CAMEL_MESSAGE_DELETED);
 
                if (move_to_real_junk)
@@ -5350,19 +5368,6 @@ imapx_server_sync_changes_sync (CamelIMAPXServer *is,
 }
 
 gboolean
-camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
-                                     CamelIMAPXMailbox *mailbox,
-                                     GCancellable *cancellable,
-                                     GError **error)
-{
-       g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
-       g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), FALSE);
-
-       return imapx_server_sync_changes_sync (is, mailbox, FALSE, cancellable, error);
-}
-
-/* expunge-uids? */
-gboolean
 camel_imapx_server_expunge_sync (CamelIMAPXServer *is,
                                 CamelIMAPXMailbox *mailbox,
                                 GCancellable *cancellable,
@@ -5379,9 +5384,6 @@ camel_imapx_server_expunge_sync (CamelIMAPXServer *is,
 
        success = camel_imapx_server_ensure_selected_sync (is, mailbox, cancellable, error);
 
-       if (success)
-               success = imapx_server_sync_changes_sync (is, mailbox, TRUE, cancellable, error);
-
        if (success) {
                CamelIMAPXCommand *ic;
 


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