[evolution-kolab] CamelKolabIMAPXStore: unhide/hide PIM folders



commit 4448cc50cef321614ea127c6539140464d0c18d3
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Thu Oct 18 14:23:28 2012 +0200

    CamelKolabIMAPXStore: unhide/hide PIM folders
    
    * implemented unhiding (and hiding again) of
      Kolab PIM folders in the email view

 src/libekolab/camel-kolab-imapx-store.c |  236 +++++++++++++++++--------------
 1 files changed, 127 insertions(+), 109 deletions(-)
---
diff --git a/src/libekolab/camel-kolab-imapx-store.c b/src/libekolab/camel-kolab-imapx-store.c
index 46523ae..98374e9 100644
--- a/src/libekolab/camel-kolab-imapx-store.c
+++ b/src/libekolab/camel-kolab-imapx-store.c
@@ -73,10 +73,7 @@ struct _CamelKolabIMAPXStorePrivate {
 	GList *folder_names_do_care;
 	CamelKolabImapxAcl *kacl; /* Kolab acl (mostly identical to IMAPX acl) */
 	CamelKolabImapxMetadata *kmd; /* Kolab metadata (differs from IMAPX metadata!) */
-
-	GList *folder_names_unsubscribe;
 	gboolean show_all_folders;
-
 	gboolean is_initialized;
 };
 
@@ -136,9 +133,7 @@ camel_kolab_imapx_store_init (CamelKolabIMAPXStore *self)
 	/* metadata db and lookup table */
 	priv->kmd = camel_kolab_imapx_metadata_new ();
 
-	priv->folder_names_unsubscribe = NULL;
 	priv->show_all_folders = FALSE;
-
 	priv->is_initialized = FALSE;
 }
 
@@ -182,7 +177,6 @@ camel_kolab_imapx_store_finalize (GObject *object)
 	g_mutex_clear (&(priv->kolab_finfo_lock));
 
 	kolab_util_glib_glist_free (priv->folder_names_do_care);
-	kolab_util_glib_glist_free (priv->folder_names_unsubscribe);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_kolab_imapx_store_parent_class)->finalize (object);
@@ -664,8 +658,125 @@ imapx_store_get_folder_info_sync (CamelKolabIMAPXStore *self,
 	return k_fi;
 }
 
+static void
+imapx_store_folder_info_diff_expand (GHashTable *tbl,
+                                     CamelFolderInfo *fi)
+{
+	g_return_if_fail (tbl != NULL);
+
+	if (fi == NULL)
+		return;
+
+	g_hash_table_replace (tbl, fi->full_name, fi);
+
+	imapx_store_folder_info_diff_expand (tbl, fi->child);
+	imapx_store_folder_info_diff_expand (tbl, fi->next);
+}
+
+static void
+imapx_store_folder_info_diff_reduce (GHashTable *tbl,
+                                     CamelFolderInfo *fi)
+{
+	g_return_if_fail (tbl != NULL);
+
+	if (fi == NULL)
+		return;
+
+	(void) g_hash_table_remove (tbl, fi->full_name);
+
+	imapx_store_folder_info_diff_reduce (tbl, fi->child);
+	imapx_store_folder_info_diff_reduce (tbl, fi->next);
+}
+
+static GHashTable*
+imapx_store_folder_info_diff_create (CamelFolderInfo *full_fi,
+                                     CamelFolderInfo *k_fi)
+{
+	GHashTable *tbl = g_hash_table_new_full (g_str_hash,
+	                                         g_str_equal,
+	                                         NULL,
+	                                         NULL);
+
+	imapx_store_folder_info_diff_expand (tbl, full_fi);
+	imapx_store_folder_info_diff_reduce (tbl, k_fi);
+
+	return tbl;
+}
+
+static gboolean
+imapx_store_folder_info_update_visible (CamelKolabIMAPXStore *self,
+                                        CamelFolderInfo *full_fi,
+                                        CamelFolderInfo *k_fi,
+                                        gboolean show_all,
+                                        GCancellable *cancellable,
+                                        GError **err)
+{
+	CamelFolderInfo *fi = NULL;
+	GHashTable *diff = NULL;
+	GList *diff_keys = NULL;
+	GList *diff_keys_ptr = NULL;
+	GError *tmp_err = NULL;
+	gboolean ok = TRUE;
+
+	g_return_val_if_fail (CAMEL_IS_KOLAB_IMAPX_STORE (self), FALSE);
+	/* full_fi may be NULL */
+	/* k_fi may be NULL */
+	/* cancellable may be NULL */
+	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
+
+	diff = imapx_store_folder_info_diff_create (full_fi, k_fi);
+
+	diff_keys = g_hash_table_get_keys (diff);
+	diff_keys_ptr = diff_keys;
+	while (diff_keys_ptr != NULL) {
+		fi = g_hash_table_lookup (diff, diff_keys_ptr->data);
+		if (fi == NULL) {
+			/* should not happen */
+			g_warning ("%s()[%u] NULL CamelFolderInfo",
+			           __func__, __LINE__);
+			goto skip;
+		}
+
+		if (show_all)
+			camel_subscribable_subscribe_folder_sync (CAMEL_SUBSCRIBABLE (self),
+			                                          fi->full_name,
+			                                          cancellable,
+			                                          &tmp_err);
+		else
+			camel_subscribable_unsubscribe_folder_sync (CAMEL_SUBSCRIBABLE (self),
+			                                            fi->full_name,
+			                                            cancellable,
+			                                            &tmp_err);
+		if (tmp_err != NULL)
+			goto exit;
+
+		if (show_all)
+			camel_store_folder_created (CAMEL_STORE (self), fi);
+		else
+			camel_store_folder_deleted (CAMEL_STORE (self), fi);
+
+	skip:
+		diff_keys_ptr = g_list_next (diff_keys_ptr);
+	}
+
+ exit:
+
+	if (tmp_err != NULL) {
+		g_propagate_error (err, tmp_err);
+		ok = FALSE;
+	}
+
+	if (diff_keys != NULL)
+		g_list_free (diff_keys);
+
+	g_hash_table_destroy (diff);
+
+	return ok;
+}
+
 static gboolean
 imapx_store_show_all_folders (CamelKolabIMAPXStore *self,
+                              gboolean show_all,
                               GCancellable *cancellable,
                               GError **err)
 {
@@ -705,12 +816,12 @@ imapx_store_show_all_folders (CamelKolabIMAPXStore *self,
 	if (tmp_err != NULL)
 		goto exit;
 
-	/* find and show (subscribe) the folders not shown
-	 * by default
-	 */
-	/* FIXME implement me */
-	g_warning ("%s: FIXME implement me", __func__);
-
+	ok = imapx_store_folder_info_update_visible (self,
+	                                             fi,
+	                                             k_fi,
+	                                             show_all,
+	                                             cancellable,
+	                                             &tmp_err);
  exit:
 	if (fi != NULL)
 		camel_store_free_folder_info (CAMEL_STORE (self), fi);
@@ -725,95 +836,6 @@ imapx_store_show_all_folders (CamelKolabIMAPXStore *self,
 	return ok;
 }
 
-static gboolean
-imapx_store_show_pim_only (CamelKolabIMAPXStore *self,
-                           GCancellable *cancellable,
-                           GError **err)
-{
-	CamelKolabIMAPXStorePrivate *priv = NULL;
-	GList *name_ptr = NULL;
-	GList *fi_lst = NULL;
-	GList *fi_ptr = NULL;
-	GError *tmp_err = NULL;
-	gboolean ok = TRUE;
-
-	g_assert (CAMEL_IS_KOLAB_IMAPX_STORE (self));
-	/* cancellable may be NULL */
-	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
-
-	priv = CAMEL_KOLAB_IMAPX_STORE_PRIVATE (self);
-
-	/* if there are no PIM-folders which have been
-	 * subscribed by a previously set show_all, then
-	 * we're done
-	 */
-	if (priv->folder_names_unsubscribe == NULL)
-		return TRUE;
-
-	/* get all folder info first, so we can be sure
-	 * all is well before signaling unsubscription
-	 */
-	name_ptr = priv->folder_names_unsubscribe;
-	while (name_ptr != NULL) {
-		gchar *foldername = NULL;
-		CamelFolderInfo *fi = NULL;
-
-		foldername = (gchar *) name_ptr->data;
-		fi = camel_store_get_folder_info_sync (CAMEL_STORE (self),
-		                                       foldername,
-		                                       CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL,
-		                                       cancellable,
-		                                       &tmp_err);
-		if (tmp_err != NULL)
-			goto exit;
-
-		/* need to keep folder infos in order, otherwise
-		 * we may mess up the Evo side_bar foldertree when
-		 * signaling
-		 */
-		fi_lst = g_list_append (fi_lst, fi);
-
-		name_ptr = g_list_next (name_ptr);
-	}
-
-	/* send the signals to unsubscribe the PIM folders
-	 * subscribed before, so they will vanish again
-	 */
-	fi_ptr = fi_lst;
-	while (fi_ptr != NULL) {
-		CamelFolderInfo *fi = (CamelFolderInfo *) fi_ptr->data;
-		camel_subscribable_folder_unsubscribed (CAMEL_SUBSCRIBABLE (self),
-		                                        fi);
-		fi_ptr = g_list_next (fi_ptr);
-	}
-
- exit:
-	/* fi_lst is freed here (instead of right while signaling)
-	 * so it is also properly freed in case of errors during
-	 * getting the folder info
-	 */
-	fi_ptr = fi_lst;
-	while (fi_ptr != NULL) {
-		CamelFolderInfo *fi = (CamelFolderInfo *) fi_ptr->data;
-		camel_store_free_folder_info (CAMEL_STORE (self), fi);
-		fi_ptr = g_list_next (fi_ptr);
-	}
-	if (fi_lst != NULL)
-		g_list_free (fi_lst);
-
-	if (tmp_err != NULL) {
-		g_propagate_error (err, tmp_err);
-		ok = FALSE;
-	}
-
-	if (ok) {
-		kolab_util_glib_glist_free (priv->folder_names_unsubscribe);
-		priv->folder_names_unsubscribe = NULL;
-	}
-
-	return ok;
-}
-
 /*----------------------------------------------------------------------------*/
 /* class functions */
 
@@ -1279,14 +1301,10 @@ kolab_imapx_store_set_show_all_folders (CamelKolabIMAPXStore *self,
 	if (priv->show_all_folders == show_all)
 		goto exit;
 
-	if (show_all)
-		ok = imapx_store_show_all_folders (self,
-		                                   cancellable,
-		                                   &tmp_err);
-	else
-		ok = imapx_store_show_pim_only (self,
-		                                cancellable,
-		                                &tmp_err);
+	ok = imapx_store_show_all_folders (self,
+	                                   show_all,
+	                                   cancellable,
+	                                   &tmp_err);
 
 	if (ok)
 		priv->show_all_folders = show_all;



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