[evolution-data-server] Bug 789555 - "Synchronize for offline" works on opened folders only



commit 2c30b3175f1ca1cd56c568ed1d2ea22876c87801
Author: Milan Crha <mcrha redhat com>
Date:   Tue Oct 31 11:42:57 2017 +0100

    Bug 789555 - "Synchronize for offline" works on opened folders only

 src/camel/camel-folder.c                      |    6 ++-
 src/camel/camel-mime-filter-gzip.h            |    2 +-
 src/camel/camel-mime-filter-yenc.h            |    2 +-
 src/camel/camel-offline-store.c               |   64 ++++++++++++++++++++-----
 src/camel/camel-offline-store.h               |    8 ++-
 src/camel/providers/imapx/camel-imapx-store.c |   51 ++++++++++++++++++++
 6 files changed, 116 insertions(+), 17 deletions(-)
---
diff --git a/src/camel/camel-folder.c b/src/camel/camel-folder.c
index f1c8c02..ee67b63 100644
--- a/src/camel/camel-folder.c
+++ b/src/camel/camel-folder.c
@@ -4574,11 +4574,15 @@ camel_folder_change_info_add_uid (CamelFolderChangeInfo *info,
 
        if (g_hash_table_lookup_extended (p->uid_stored, uid, (gpointer) &olduid, (gpointer) &olduids)) {
                /* if it was removed then added, promote it to a changed */
-               /* if it was changed then added, leave as changed */
+               /* if it was changed then added, make it added */
                if (olduids == info->uid_removed) {
                        g_ptr_array_remove_fast (olduids, olduid);
                        g_ptr_array_add (info->uid_changed, olduid);
                        g_hash_table_insert (p->uid_stored, olduid, info->uid_changed);
+               } else if (olduids == info->uid_changed) {
+                       g_ptr_array_remove_fast (olduids, olduid);
+                       g_ptr_array_add (info->uid_added, olduid);
+                       g_hash_table_insert (p->uid_stored, olduid, info->uid_changed);
                }
                return;
        }
diff --git a/src/camel/camel-mime-filter-gzip.h b/src/camel/camel-mime-filter-gzip.h
index 0b92411..7739892 100644
--- a/src/camel/camel-mime-filter-gzip.h
+++ b/src/camel/camel-mime-filter-gzip.h
@@ -43,7 +43,7 @@
        (G_TYPE_CHECK_CLASS_TYPE \
        ((cls), CAMEL_TYPE_MIME_FILTER_GZIP))
 #define CAMEL_MIME_FILTER_GZIP_GET_CLASS(obj) \
-       (CAMEL_CHECK_GET_CLASS \
+       (G_TYPE_INSTANCE_GET_CLASS \
        ((obj), CAMEL_TYPE_MIME_FILTER_GZIP, CamelMimeFilterGZipClass))
 
 G_BEGIN_DECLS
diff --git a/src/camel/camel-mime-filter-yenc.h b/src/camel/camel-mime-filter-yenc.h
index 8fce654..bf31439 100644
--- a/src/camel/camel-mime-filter-yenc.h
+++ b/src/camel/camel-mime-filter-yenc.h
@@ -43,7 +43,7 @@
        (G_TYPE_CHECK_CLASS_TYPE \
        ((cls), CAMEL_TYPE_MIME_FILTER_YENC))
 #define CAMEL_MIME_FILTER_YENC_GET_CLASS(obj) \
-       (CAMEL_CHECK_GET_CLASS \
+       (G_TYPE_INSTANCE_GET_CLASS \
        ((obj), CAMEL_TYPE_MIME_FILTER_YENC, CamelMimeFilterYencClass))
 
 G_BEGIN_DECLS
diff --git a/src/camel/camel-offline-store.c b/src/camel/camel-offline-store.c
index 73216c3..55273fc 100644
--- a/src/camel/camel-offline-store.c
+++ b/src/camel/camel-offline-store.c
@@ -227,9 +227,9 @@ camel_offline_store_set_online_sync (CamelOfflineStore *store,
                GPtrArray *folders;
                guint ii;
 
-               folders = camel_store_dup_opened_folders (CAMEL_STORE (store));
+               folders = camel_offline_store_dup_downsync_folders (store);
 
-               for (ii = 0; ii < folders->len; ii++) {
+               for (ii = 0; folders && ii < folders->len; ii++) {
                        CamelFolder *folder = folders->pdata[ii];
                        CamelOfflineFolder *offline_folder;
 
@@ -242,8 +242,10 @@ camel_offline_store_set_online_sync (CamelOfflineStore *store,
                                camel_offline_folder_downsync_sync (offline_folder, NULL, cancellable, NULL);
                }
 
-               g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
-               g_ptr_array_free (folders, TRUE);
+               if (folders) {
+                       g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
+                       g_ptr_array_free (folders, TRUE);
+               }
 
                camel_store_synchronize_sync (
                        CAMEL_STORE (store), FALSE, cancellable, NULL);
@@ -380,9 +382,9 @@ camel_offline_store_prepare_for_offline_sync (CamelOfflineStore *store,
                GPtrArray *folders;
                guint ii;
 
-               folders = camel_store_dup_opened_folders (CAMEL_STORE (store));
+               folders = camel_offline_store_dup_downsync_folders (store);
 
-               for (ii = 0; ii < folders->len; ii++) {
+               for (ii = 0; folders && ii < folders->len; ii++) {
                        CamelFolder *folder = folders->pdata[ii];
                        CamelOfflineFolder *offline_folder;
 
@@ -395,8 +397,10 @@ camel_offline_store_prepare_for_offline_sync (CamelOfflineStore *store,
                                camel_offline_folder_downsync_sync (offline_folder, NULL, cancellable, NULL);
                }
 
-               g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
-               g_ptr_array_free (folders, TRUE);
+               if (folders) {
+                       g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
+                       g_ptr_array_free (folders, TRUE);
+               }
        }
 
        if (host_reachable)
@@ -450,9 +454,9 @@ camel_offline_store_requires_downsync (CamelOfflineStore *store)
                GPtrArray *folders;
                guint ii;
 
-               folders = camel_store_dup_opened_folders (CAMEL_STORE (store));
+               folders = camel_offline_store_dup_downsync_folders (store);
 
-               for (ii = 0; ii < folders->len && !sync_any_folder; ii++) {
+               for (ii = 0; folders && ii < folders->len && !sync_any_folder; ii++) {
                        CamelFolder *folder = folders->pdata[ii];
 
                        if (!CAMEL_IS_OFFLINE_FOLDER (folder))
@@ -461,9 +465,45 @@ camel_offline_store_requires_downsync (CamelOfflineStore *store)
                        sync_any_folder = camel_offline_folder_can_downsync (CAMEL_OFFLINE_FOLDER (folder));
                }
 
-               g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
-               g_ptr_array_free (folders, TRUE);
+               if (folders) {
+                       g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
+                       g_ptr_array_free (folders, TRUE);
+               }
        }
 
        return sync_any_folder && host_reachable;
 }
+
+/**
+ * camel_offline_store_dup_downsync_folders:
+ * @store: a #CamelOfflineStore
+ *
+ * Returns a #GPtrArray of #CamelFolder objects which should be checked
+ * for offline synchronization. Free the returned pointer with the below
+ * calls, when no longer needed:
+ *
+ * |[
+ *     g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
+ *     g_ptr_array_free (array, TRUE);
+ * ]|
+ *
+ * Returns: (element-type CamelFolder) (transfer full): an array with folders
+ *   to be checked for offline synchronization.
+ *
+ * Since: 3.28
+ **/
+GPtrArray *
+camel_offline_store_dup_downsync_folders (CamelOfflineStore *store)
+{
+       CamelOfflineStoreClass *klass;
+
+       g_return_val_if_fail (CAMEL_IS_OFFLINE_STORE (store), NULL);
+
+       klass = CAMEL_OFFLINE_STORE_GET_CLASS (store);
+       g_return_val_if_fail (klass != NULL, NULL);
+
+       if (klass->dup_downsync_folders)
+               return klass->dup_downsync_folders (store);
+
+       return camel_store_dup_opened_folders (CAMEL_STORE (store));
+}
diff --git a/src/camel/camel-offline-store.h b/src/camel/camel-offline-store.h
index e017d29..0003d8b 100644
--- a/src/camel/camel-offline-store.h
+++ b/src/camel/camel-offline-store.h
@@ -42,7 +42,7 @@
        (G_TYPE_CHECK_CLASS_TYPE \
        ((cls), CAMEL_TYPE_OFFLINE_STORE))
 #define CAMEL_OFFLINE_STORE_GET_CLASS(obj) \
-       (CAMEL_CHECK_GET_CLASS \
+       (G_TYPE_INSTANCE_GET_CLASS \
        ((obj), CAMEL_TYPE_OFFLINE_STORE, CamelOfflineStoreClass))
 
 G_BEGIN_DECLS
@@ -59,8 +59,10 @@ struct _CamelOfflineStore {
 struct _CamelOfflineStoreClass {
        CamelStoreClass parent_class;
 
+       GPtrArray *     (*dup_downsync_folders) (CamelOfflineStore *store);
+
        /* Padding for future expansion */
-       gpointer reserved[20];
+       gpointer reserved[19];
 };
 
 GType          camel_offline_store_get_type (void);
@@ -86,6 +88,8 @@ gboolean      camel_offline_store_prepare_for_offline_sync
                                                 GError **error);
 gboolean       camel_offline_store_requires_downsync
                                                (CamelOfflineStore *store);
+GPtrArray *    camel_offline_store_dup_downsync_folders
+                                               (CamelOfflineStore *store);
 
 G_END_DECLS
 
diff --git a/src/camel/providers/imapx/camel-imapx-store.c b/src/camel/providers/imapx/camel-imapx-store.c
index 8f7c550..32b7e45 100644
--- a/src/camel/providers/imapx/camel-imapx-store.c
+++ b/src/camel/providers/imapx/camel-imapx-store.c
@@ -2777,6 +2777,53 @@ imapx_initial_setup_sync (CamelStore *store,
 }
 
 static void
+imapx_store_dup_downsync_folders_recurse (CamelStore *store,
+                                         CamelFolderInfo *info,
+                                         GPtrArray **inout_folders)
+{
+       while (info) {
+               CamelFolder *folder;
+
+               if (info->child)
+                       imapx_store_dup_downsync_folders_recurse (store, info->child, inout_folders);
+
+               folder = camel_store_get_folder_sync (store, info->full_name, 0, NULL, NULL);
+               if (folder && CAMEL_IS_IMAPX_FOLDER (folder) &&
+                   camel_offline_folder_can_downsync (CAMEL_OFFLINE_FOLDER (folder))) {
+                       if (!*inout_folders)
+                               *inout_folders = g_ptr_array_sized_new (32);
+                       g_ptr_array_add (*inout_folders, g_object_ref (folder));
+               }
+
+               g_clear_object (&folder);
+
+               info = info->next;
+       }
+}
+
+static GPtrArray *
+imapx_store_dup_downsync_folders (CamelOfflineStore *offline_store)
+{
+       CamelStore *store;
+       CamelFolderInfo *fi;
+       GPtrArray *folders = NULL;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (offline_store), NULL);
+
+       store = CAMEL_STORE (offline_store);
+
+       fi = get_folder_info_offline (store, NULL,
+               CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL,
+               NULL, NULL);
+
+       imapx_store_dup_downsync_folders_recurse (store, fi, &folders);
+
+       camel_folder_info_free (fi);
+
+       return folders;
+}
+
+static void
 imapx_migrate_to_user_cache_dir (CamelService *service)
 {
        const gchar *user_data_dir, *user_cache_dir;
@@ -3100,6 +3147,7 @@ camel_imapx_store_class_init (CamelIMAPXStoreClass *class)
        GObjectClass *object_class;
        CamelServiceClass *service_class;
        CamelStoreClass *store_class;
+       CamelOfflineStoreClass *offline_store_class;
 
        g_type_class_add_private (class, sizeof (CamelIMAPXStorePrivate));
 
@@ -3131,6 +3179,9 @@ camel_imapx_store_class_init (CamelIMAPXStoreClass *class)
        store_class->rename_folder_sync = imapx_store_rename_folder_sync;
        store_class->initial_setup_sync = imapx_initial_setup_sync;
 
+       offline_store_class = CAMEL_OFFLINE_STORE_CLASS (class);
+       offline_store_class->dup_downsync_folders = imapx_store_dup_downsync_folders;
+
        class->mailbox_created = imapx_store_mailbox_created;
        class->mailbox_renamed = imapx_store_mailbox_renamed;
        class->mailbox_updated = imapx_store_mailbox_updated;


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