[evolution-mapi] BGO 580682 – Scan public folders on-demand.



commit 9e7d1b3e2236df4c9ff38949a77cf6eb0ffc5493
Author: Johnny Jacob <jjohnny novell com>
Date:   Fri May 29 10:03:28 2009 +0530

    BGO 580682 â?? Scan public folders on-demand.
    
    	* camel-mapi-store.h: Updates for new util functions.
    
    	* camel-mapi-store.c (mapi_create_folder)
    	(mapi_convert_to_folder_info): Use mapi_folder_hash_* utils functions.
    	(mapi_update_folder_hash_tables, mapi_folders_update_hash_tables_from_cache)
    	(mapi_folders_hash_table_name_lookup , mapi_folders_hash_table_fid_lookup)
    	(mapi_folders_hash_table_pfid_lookup): Added. Util functions for maintaining
    	ID <-> Name mappings
    	(mapi_folders_sync): Fetch Public folders lsit only if it is from the
    	subscription editor (using CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST).
    	(camel_mapi_store_folder_id_lookup_offline): Added.
    
    	* camel-mapi-store-summary.c (store_info_load , store_info_save)
    	(store_info_free, store_info_string, store_info_set_string)
    	(camel_mapi_store_summary_add_from_full): Folder id and Parent id.
    
    	* exchange-mapi-connection.c (get_child_folders): Updated to accomodate traversal
    	depth.
    	(exchange_mapi_get_folders_list): update for get_child_folders.
    	(exchange_mapi_get_pf_folders_list): If parent_id is given, use that as
    	the start of folder tree..
---
 src/camel/ChangeLog                            |   21 +++
 src/camel/camel-mapi-store-summary.c           |   55 +++++---
 src/camel/camel-mapi-store-summary.h           |   11 ++-
 src/camel/camel-mapi-store.c                   |  179 ++++++++++++++++++++----
 src/camel/camel-mapi-store.h                   |    1 +
 src/libexchangemapi/ChangeLog                  |    8 +
 src/libexchangemapi/exchange-mapi-connection.c |   49 +++++--
 src/libexchangemapi/exchange-mapi-connection.h |    2 +-
 8 files changed, 263 insertions(+), 63 deletions(-)

diff --git a/src/camel/ChangeLog b/src/camel/ChangeLog
index 18bf44d..aa1c12b 100644
--- a/src/camel/ChangeLog
+++ b/src/camel/ChangeLog
@@ -1,3 +1,24 @@
+2009-06-03  Johnny Jacob  <jjohnny novell com>
+
+	* camel-mapi-store.h: Updates for new util functions.
+
+	* camel-mapi-store.c (mapi_create_folder)
+	(mapi_convert_to_folder_info): Use mapi_folder_hash_* utils functions.
+	(mapi_update_folder_hash_tables, mapi_folders_update_hash_tables_from_cache)
+	(mapi_folders_hash_table_name_lookup , mapi_folders_hash_table_fid_lookup)
+	(mapi_folders_hash_table_pfid_lookup): Added. Util functions for maintaining
+	ID <-> Name mappings
+	(mapi_folders_sync): Fetch Public folders lsit only if it is from the
+	subscription editor (using CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST).
+	(camel_mapi_store_folder_id_lookup_offline): Added.
+
+	* camel-mapi-store-summary.c (store_info_load , store_info_save)
+	(store_info_free, store_info_string, store_info_set_string)
+	(camel_mapi_store_summary_add_from_full): Folder id and Parent id.
+
+	* camel-mapi-store.c (mapi_folders_sync): Do not download public folder
+	list by default.
+
 2009-04-24  Milan Crha  <mcrha redhat com>
 
 	** Part of fix for bug #563954
diff --git a/src/camel/camel-mapi-store-summary.c b/src/camel/camel-mapi-store-summary.c
index 894eb73..9cbcff5 100644
--- a/src/camel/camel-mapi-store-summary.c
+++ b/src/camel/camel-mapi-store-summary.c
@@ -156,7 +156,9 @@ store_info_load(CamelStoreSummary *s, FILE *in)
 
 	si = (CamelMapiStoreInfo *)camel_mapi_store_summary_parent->store_info_load(s, in);
 	if (si) {
-		if (camel_file_util_decode_string(in, &si->full_name) == -1) {
+		if (camel_file_util_decode_string(in, &si->full_name) == -1
+		    || camel_file_util_decode_string(in, &si->folder_id) == -1
+		    || camel_file_util_decode_string(in, &si->parent_id) == -1) {
 			camel_store_summary_info_free(s, (CamelStoreInfo *)si);
 			si = NULL;
 		}
@@ -169,26 +171,26 @@ store_info_save(CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi)
 {
 	CamelMapiStoreInfo *summary = (CamelMapiStoreInfo *)mi;
 	if (camel_mapi_store_summary_parent->store_info_save(s, out, mi) == -1
-	    || camel_file_util_encode_string(out, summary->full_name) == -1) 
+	    || camel_file_util_encode_string(out, summary->full_name) == -1
+	    || camel_file_util_encode_string(out, summary->folder_id) == -1
+	    || camel_file_util_encode_string(out, summary->parent_id) == -1) 
 		return -1;
 
 	return 0;
 }
 
-
 static void
 store_info_free(CamelStoreSummary *s, CamelStoreInfo *mi)
 {
 	CamelMapiStoreInfo *si = (CamelMapiStoreInfo *)mi;
 
-	g_free(si->full_name);
+	g_free (si->full_name);
+	g_free (si->folder_id);
+	g_free (si->parent_id);
+
 	camel_mapi_store_summary_parent->store_info_free(s, mi);
 }
 
-
-
-
-
 static const char *
 store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type)
 {
@@ -199,8 +201,12 @@ store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type)
 	g_assert (mi != NULL);
 
 	switch (type) {
-		case CAMEL_STORE_INFO_LAST:
+		case CAMEL_MAPI_STORE_INFO_FULL_NAME:
 			return isi->full_name;
+	        case CAMEL_MAPI_STORE_INFO_FOLDER_ID:
+		        return isi->folder_id;
+	        case CAMEL_MAPI_STORE_INFO_PARENT_ID:
+		        return isi->parent_id;
 		default:
 			return camel_mapi_store_summary_parent->store_info_string(s, mi, type);
 	}
@@ -214,13 +220,27 @@ store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, int type, const
 	g_assert(mi != NULL);
 
 	switch(type) {
-		case CAMEL_STORE_INFO_LAST:
+		case CAMEL_MAPI_STORE_INFO_FULL_NAME:
 			d(printf("Set full name %s -> %s\n", isi->full_name, str));
 			CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
 			g_free(isi->full_name);
 			isi->full_name = g_strdup(str);
 			CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
 			break;
+	        case CAMEL_MAPI_STORE_INFO_FOLDER_ID:
+			d(printf("Set folder id %s -> %s\n", isi->folder_id, str));
+			CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
+			g_free(isi->folder_id);
+			isi->folder_id = g_strdup(str);
+			CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
+			break;
+	        case CAMEL_MAPI_STORE_INFO_PARENT_ID:
+			d(printf("Set parent id %s -> %s\n", isi->parent_id, str));
+			CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
+			g_free(isi->parent_id);
+			isi->parent_id = g_strdup(str);
+			CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
+			break;
 		default:
 			camel_mapi_store_summary_parent->store_info_set_string(s, mi, type, str);
 			break;
@@ -275,7 +295,8 @@ camel_mapi_store_summary_full_to_path(CamelMapiStoreSummary *s, const char *full
 
 
 CamelMapiStoreInfo *
-camel_mapi_store_summary_add_from_full(CamelMapiStoreSummary *s, const char *full, char dir_sep)
+camel_mapi_store_summary_add_from_full(CamelMapiStoreSummary *s, const char *full, 
+				       char dir_sep, char *folder_id, char *parent_id)
 {
 	CamelMapiStoreInfo *info;
 	char *pathu8;
@@ -298,8 +319,12 @@ camel_mapi_store_summary_add_from_full(CamelMapiStoreSummary *s, const char *ful
 	}
 	pathu8 = camel_mapi_store_summary_full_to_path(s, full_name, '/');
 	info = (CamelMapiStoreInfo *)camel_store_summary_add_from_path((CamelStoreSummary *)s, pathu8);
-	if (info) 
-		camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_STORE_INFO_LAST, full_name);
+
+	if (info) {
+		camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_MAPI_STORE_INFO_FULL_NAME, full_name);
+		camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_MAPI_STORE_INFO_FOLDER_ID, folder_id);
+		camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_MAPI_STORE_INFO_PARENT_ID, parent_id);
+	}
 
 	return info;
 }
@@ -309,10 +334,6 @@ camel_mapi_store_summary_full_from_path(CamelMapiStoreSummary *s, const char *pa
 {
 	char *name = NULL;
 
-/* 	ns = camel_mapi_store_summary_namespace_find_path(s, path); */
-/* 	if (ns) */
-/* 		name = camel_mapi_store_summary_path_to_full(s, path, ns->sep); */
-
 	d(printf("looking up path %s -> %s\n", path, name?name:"not found"));
 
 	return name;
diff --git a/src/camel/camel-mapi-store-summary.h b/src/camel/camel-mapi-store-summary.h
index 3323e55..0ef1c45 100644
--- a/src/camel/camel-mapi-store-summary.h
+++ b/src/camel/camel-mapi-store-summary.h
@@ -42,12 +42,16 @@ typedef struct _CamelMapiStoreInfo CamelMapiStoreInfo;
 
 enum {
 	CAMEL_MAPI_STORE_INFO_FULL_NAME = CAMEL_STORE_INFO_LAST,
+	CAMEL_MAPI_STORE_INFO_FOLDER_ID,
+	CAMEL_MAPI_STORE_INFO_PARENT_ID,
 	CAMEL_MAPI_STORE_INFO_LAST,
 };
 
 struct _CamelMapiStoreInfo {
 	CamelStoreInfo info;
 	char *full_name;
+	char *folder_id;
+	char *parent_id;
 };
 
 struct _CamelMapiStoreSummary {
@@ -67,13 +71,16 @@ struct _CamelMapiStoreSummaryClass {
 CamelType                        camel_mapi_store_summary_get_type      (void);
 CamelMapiStoreSummary      *camel_mapi_store_summary_new        (void);
 CamelMapiStoreInfo *camel_mapi_store_summary_full_name(CamelMapiStoreSummary *s, const char *full_name) ;
-CamelMapiStoreInfo *camel_mapi_store_summary_add_from_full(CamelMapiStoreSummary *s, const char *full, char dir_sep) ;
+CamelMapiStoreInfo *camel_mapi_store_summary_add_from_full(CamelMapiStoreSummary *s, const char *full, char dir_sep, 
+							   char *folder_id, char *parent_id);
 
 char *camel_mapi_store_summary_full_to_path(CamelMapiStoreSummary *s, const char *full_name, char dir_sep) ;
 char *camel_mapi_store_summary_path_to_full(CamelMapiStoreSummary *s, const char *path, char dir_sep) ;
 char *camel_mapi_store_summary_full_from_path(CamelMapiStoreSummary *s, const char *path) ;
 
-#define camel_mapi_store_info_full_name(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_STORE_INFO_LAST))
+#define camel_mapi_store_info_full_name(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_MAPI_STORE_INFO_FULL_NAME))
+#define camel_mapi_store_info_folder_id(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_MAPI_STORE_INFO_FOLDER_ID))
+#define camel_mapi_store_info_parent_id(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_MAPI_STORE_INFO_PARENT_ID))
 
 G_END_DECLS
 
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index e33e25e..4796f7b 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -109,9 +109,15 @@ static gboolean mapi_folder_subscribed (CamelStore *store, const char *folder_na
 static void		mapi_unsubscribe_folder(CamelStore *, const char *, CamelException *);
 static void		mapi_noop(CamelStore *, CamelException *);
 static CamelFolderInfo * mapi_build_folder_info(CamelMapiStore *mapi_store, const char *parent_name, const char *folder_name);
-static void mapi_folders_sync (CamelMapiStore *store, CamelException *ex);
+static void mapi_folders_sync (CamelMapiStore *store, char *top, guint32 flags, CamelException *ex);
 static gboolean mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const char *fid);
 
+static void mapi_update_folder_hash_tables (CamelMapiStore *store, gchar *name, gchar *fid, gchar *parent_id);
+static const gchar* mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache);
+static const gchar* mapi_folders_hash_table_pfid_lookup (CamelMapiStore *store, const gchar *fid, gboolean use_cache);
+static const gchar* mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name, gboolean use_cache);
+
+
 static guint
 mapi_hash_folder_name(gconstpointer key)
 {
@@ -465,15 +471,14 @@ mapi_create_folder(CamelStore *store, const char *parent_name, const char *folde
 	new_folder_id = exchange_mapi_create_folder(olFolderInbox, parent_fid, folder_name);
 	if (new_folder_id != 0) {
 		CamelMapiStoreInfo *si;
+		gchar *fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", new_folder_id);
 
 		root = mapi_build_folder_info(mapi_store, parent_name, folder_name);
 
-		si = camel_mapi_store_summary_add_from_full(mapi_store->summary, root->full_name, '/');
+		si = camel_mapi_store_summary_add_from_full(mapi_store->summary, root->full_name, '/', fid, parent_id);
 		camel_store_summary_save((CamelStoreSummary *)mapi_store->summary);
 
-		g_hash_table_insert (priv->id_hash, g_strdup_printf ("%016" G_GINT64_MODIFIER "X", new_folder_id), g_strdup(folder_name));
-		g_hash_table_insert (priv->name_hash, g_strdup(root->full_name), g_strdup_printf ("%016" G_GINT64_MODIFIER "X", new_folder_id));
-		g_hash_table_insert (priv->parent_hash, g_strdup_printf ("%016" G_GINT64_MODIFIER "X", new_folder_id), g_strdup(parent_id));
+		mapi_update_folder_hash_tables (mapi_store, folder_name, fid, parent_id);
 
 		camel_object_trigger_event (CAMEL_OBJECT (store), "folder_created", root);
 	}
@@ -512,10 +517,10 @@ mapi_forget_folder (CamelMapiStore *mapi_store, const char *folder_name, CamelEx
 	g_rmdir (folder_dir);
 	g_free (folder_dir);
 
-	camel_store_summary_remove_path ( (CamelStoreSummary *)mapi_store->summary, folder_name);
-	camel_store_summary_save ( (CamelStoreSummary *)mapi_store->summary);
+	camel_store_summary_remove_path ((CamelStoreSummary *)mapi_store->summary, folder_name);
+	camel_store_summary_save ((CamelStoreSummary *)mapi_store->summary);
 
-	fi = mapi_build_folder_info(mapi_store, NULL, folder_name);
+	fi = mapi_build_folder_info (mapi_store, NULL, folder_name);
 	camel_object_trigger_event (CAMEL_OBJECT (mapi_store), "folder_deleted", fi);
 	camel_folder_info_free (fi);
 }
@@ -914,7 +919,6 @@ mapi_get_folder_info_offline (CamelStore *store, const char *top,
 
 	path = mapi_concat (name, "*");
 
-
 	for (i=0;i<camel_store_summary_count((CamelStoreSummary *)mapi_store->summary);i++) {
 		CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)mapi_store->summary, i);
 
@@ -1037,7 +1041,8 @@ mapi_convert_to_folder_info (CamelMapiStore *store, ExchangeMAPIFolder *folder,
 
 	mapi_id_folder = exchange_mapi_folder_get_parent_id (folder);
 	parent = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", mapi_id_folder);
-	par_name = g_hash_table_lookup (priv->id_hash, parent);
+
+	par_name = mapi_folders_hash_table_name_lookup (store, parent, TRUE);
 
 	if (par_name != NULL) {
 		gchar *temp_parent = NULL;
@@ -1046,17 +1051,18 @@ mapi_convert_to_folder_info (CamelMapiStore *store, ExchangeMAPIFolder *folder,
 
 		fi->name = g_strdup (name);
 
-		temp_parent = g_hash_table_lookup (priv->parent_hash, parent);
+		temp_parent = mapi_folders_hash_table_pfid_lookup (store, parent, TRUE);
+
 		while (temp_parent) {
-			temp = g_hash_table_lookup (priv->id_hash, temp_parent );
+			temp = mapi_folders_hash_table_name_lookup (store, temp_parent, TRUE);
 			if (temp == NULL) {
 				break;
 			}	
 			str = g_strconcat ( temp, "/", str, NULL);
 
-			temp_parent = g_hash_table_lookup (priv->parent_hash, temp_parent);
-
+			temp_parent = mapi_folders_hash_table_pfid_lookup (store, temp_parent, TRUE);
 		} 
+
 		fi->full_name = g_strdup (str);
 		fi->uri = g_strconcat (url, str, NULL);
 		g_free (str);
@@ -1087,13 +1093,104 @@ camel_mapi_store_connected (CamelMapiStore *store, CamelException *ex)
 	return FALSE;
 }
 
+
+static void
+mapi_update_folder_hash_tables (CamelMapiStore *store, gchar *name, gchar *fid,
+				gchar *parent_id)
+{
+	CamelMapiStorePrivate  *priv = store->priv;
+
+	if (fid && name) {
+		/*id_hash returns the name for a given container id*/
+		g_hash_table_insert (priv->id_hash, g_strdup (fid), g_strdup(name)); 
+
+		/* name_hash : name <-> fid mapping */
+		g_hash_table_insert (priv->name_hash, g_strdup(name), g_strdup (fid));
+	}
+
+	/*parent_hash returns the parent container id, given an id*/
+	if (fid && parent_id)
+		g_hash_table_insert (priv->parent_hash, g_strdup(fid), g_strdup(parent_id));
+
+}
+
+static void
+mapi_folders_update_hash_tables_from_cache (CamelMapiStore *store)
+{
+	CamelStoreSummary *summary = (CamelStoreSummary *) store->summary;
+	gint summary_count = camel_store_summary_count (summary);
+	guint i = 0;
+
+	for (i = 0; i < summary_count; i++) {
+		CamelMapiStoreInfo *si = (CamelMapiStoreInfo *) camel_store_summary_index(summary, i);
+		gchar *name, *pfid = NULL;
+		
+		if (si == NULL) continue;
+
+		name = g_strrstr(si->full_name, "/");
+		name ? ++name : si->full_name;
+
+		mapi_update_folder_hash_tables (store, name, si->folder_id, si->parent_id);
+		
+	}
+}
+
+static const gchar*
+mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const gchar *fid,
+				     gboolean use_cache)
+{
+	CamelMapiStorePrivate  *priv = store->priv;
+	const gchar *name = g_hash_table_lookup (priv->id_hash, fid);
+
+	if (!name && use_cache)
+		mapi_folders_update_hash_tables_from_cache (store);
+
+	name = g_hash_table_lookup (priv->id_hash, fid);
+
+	return name;
+}
+
+static const gchar*
+mapi_folders_hash_table_fid_lookup (CamelMapiStore *store, const gchar *name,
+				    gboolean use_cache)
+{
+	CamelMapiStorePrivate  *priv = store->priv;
+
+	const gchar *fid = g_hash_table_lookup (priv->name_hash, name);
+
+	if (!fid && use_cache)
+		mapi_folders_update_hash_tables_from_cache (store);
+
+	fid = g_hash_table_lookup (priv->name_hash, name);
+
+	return fid;
+}
+
+/*Parent FID.*/
+static const gchar*
+mapi_folders_hash_table_pfid_lookup (CamelMapiStore *store, const gchar *fid,
+				    gboolean use_cache)
+{
+	CamelMapiStorePrivate  *priv = store->priv;
+
+	const gchar *pfid = g_hash_table_lookup (priv->parent_hash, fid);
+
+	if (!pfid && use_cache)
+		mapi_folders_update_hash_tables_from_cache (store);
+
+	pfid = g_hash_table_lookup (priv->parent_hash, fid);
+
+	return pfid;
+}
+
 static void
-mapi_folders_sync (CamelMapiStore *store, CamelException *ex)
+mapi_folders_sync (CamelMapiStore *store, char *top, guint32 flags, CamelException *ex)
 {
 	CamelMapiStorePrivate  *priv = store->priv;
 	gboolean status;
 	GSList *folder_list = NULL, *temp_list = NULL, *list = NULL;
 	char *url, *temp_url;
+	gboolean subscription_list = false;
 	CamelFolderInfo *info = NULL;
 	CamelMapiStoreInfo *mapi_si = NULL;
 
@@ -1116,10 +1213,22 @@ mapi_folders_sync (CamelMapiStore *store, CamelException *ex)
 		return;
 	}
 
-	status = exchange_mapi_get_pf_folders_list (&folder_list);
-	if (!status) {
-		g_warning ("Could not get Public folder list..\n");
-//		return;
+	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+
+	if (subscription_list) {
+		/*Consult the name <-> fid hash table for a FID.*/
+		gchar *parent_id = NULL;
+		mapi_id_t pid = 0;
+
+		parent_id = (top) ? g_strdup (camel_mapi_store_folder_id_lookup_offline (store, top)) : NULL; 
+		exchange_mapi_util_mapi_id_from_string (parent_id, &pid);
+
+		status = exchange_mapi_get_pf_folders_list (&folder_list, pid);
+
+		if (!status)
+			g_warning ("Could not get Public folder list..\n");
+
+		g_free (parent_id);
 	}
 
 	temp_list = folder_list;
@@ -1145,14 +1254,7 @@ mapi_folders_sync (CamelMapiStore *store, CamelException *ex)
 		fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(temp_list->data)));
 		parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", exchange_mapi_folder_get_parent_id ((ExchangeMAPIFolder *)(temp_list->data)));
 
-		/*id_hash returns the name for a given container id*/
-		g_hash_table_insert (priv->id_hash, g_strdup (fid), g_strdup(name)); 
-
-		/* name_hash : name <-> fid mapping */
-		g_hash_table_insert (priv->name_hash, g_strdup(name), g_strdup (fid));
-
-		/*parent_hash returns the parent container id, given an id*/
-		g_hash_table_insert (priv->parent_hash, g_strdup(fid), g_strdup(parent_id));
+		mapi_update_folder_hash_tables (store, name, fid, parent_id);
 
 		if (((ExchangeMAPIFolder *)(temp_list->data))->is_default) {
 			guint *type = g_new0 (guint, 1);
@@ -1173,7 +1275,15 @@ mapi_folders_sync (CamelMapiStore *store, CamelException *ex)
 
 		info = mapi_convert_to_folder_info (store, folder, (const char *)url, ex);
 		if (!(mapi_si = (CamelMapiStoreInfo *) camel_store_summary_path ((CamelStoreSummary *)store->summary, info->full_name))){
-			mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/');
+			gchar *fid, *pfid = NULL;
+
+			fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", 
+					       exchange_mapi_folder_get_fid((ExchangeMAPIFolder *)(folder_list->data)));
+			pfid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", 
+						exchange_mapi_folder_get_parent_id((ExchangeMAPIFolder *)(folder_list->data)));
+
+			mapi_si = camel_mapi_store_summary_add_from_full (store->summary, info->full_name, '/', fid, pfid);
+
 			if (mapi_si == NULL) {
 				continue;
 			}
@@ -1214,7 +1324,8 @@ mapi_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExc
 	}
 
 	if (check_for_connection((CamelService *)store, ex)) {
-		mapi_folders_sync (mapi_store, ex);
+		mapi_folders_sync (mapi_store, top, flags, ex);
+
 		if (camel_exception_is_set (ex)) {
 			CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 			return NULL;
@@ -1231,6 +1342,16 @@ mapi_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExc
 }
 
 const gchar *
+camel_mapi_store_folder_id_lookup_offline (CamelMapiStore *mapi_store, const char *folder_name)
+{
+	CamelMapiStorePrivate *priv = mapi_store->priv;
+	CamelMapiStoreInfo *mapi_si = NULL;
+
+	mapi_si = camel_store_summary_path ((CamelStoreSummary *)mapi_store->summary, folder_name);
+	return mapi_si->folder_id;
+}
+
+const gchar *
 camel_mapi_store_folder_id_lookup (CamelMapiStore *mapi_store, const char *folder_name)
 {
 	CamelMapiStorePrivate *priv = mapi_store->priv;
diff --git a/src/camel/camel-mapi-store.h b/src/camel/camel-mapi-store.h
index 12b4f7a..f2540fa 100644
--- a/src/camel/camel-mapi-store.h
+++ b/src/camel/camel-mapi-store.h
@@ -95,6 +95,7 @@ const gchar* camel_mapi_store_folder_id_lookup (CamelMapiStore *mapi_store, cons
 const gchar* camel_mapi_store_folder_lookup (CamelMapiStore *mapi_store, const char *folder_id);
 const gchar* camel_mapi_store_get_profile_name (CamelMapiStore *mapi_store);
 const gchar *camel_mapi_store_system_folder_fid (CamelMapiStore *mapi_store, guint folder_type);
+const gchar *camel_mapi_store_folder_id_lookup_offline (CamelMapiStore *mapi_store, const char *folder_name);
 
 __END_DECLS
 
diff --git a/src/libexchangemapi/ChangeLog b/src/libexchangemapi/ChangeLog
index 674843a..cbeda5c 100644
--- a/src/libexchangemapi/ChangeLog
+++ b/src/libexchangemapi/ChangeLog
@@ -1,3 +1,11 @@
+2009-06-03  Johnny Jacob  <jjohnny novell com>
+
+	* exchange-mapi-connection.c (get_child_folders): Updated to accomodate traversal
+	depth.
+	(exchange_mapi_get_folders_list): update for get_child_folders.
+	(exchange_mapi_get_pf_folders_list): If parent_id is given, use that as
+	the start of folder tree..
+
 2009-04-07  Milan Crha  <mcrha redhat com>
 
 	* exchange-mapi-connection.c: (mapi_profile_load):
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index f81add6..90e0019 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -2421,7 +2421,8 @@ cleanup:
 }
 
 static gboolean
-get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, mapi_object_t *parent, mapi_id_t folder_id, GSList **mapi_folders)
+get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, mapi_object_t *parent, 
+		  mapi_id_t folder_id, GSList **mapi_folders, gint32 depth)
 {
 	enum MAPISTATUS		retval;
 	mapi_object_t		obj_folder;
@@ -2435,6 +2436,9 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 	g_return_val_if_fail (mem_ctx != NULL, FALSE);
 	g_return_val_if_fail (parent != NULL, FALSE);
 
+	/*We reached the depth we wanted.*/
+	if (!depth ) return true;
+
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_table);
 
@@ -2473,6 +2477,8 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 		goto cleanup;
 	}
 
+	depth--;
+
 	for (i = 0; i < rowset.cRows; i++) {
 		ExchangeMAPIFolder *folder = NULL;
 		gchar *newname = NULL;
@@ -2488,13 +2494,17 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 			class = IPF_NOTE;
 
 		newname = utf8tolinux (name);
-		g_print("\n|---+ %-15s : (Container class: %s %016" G_GINT64_MODIFIER "X) UnRead : %d Total : %d ", newname, class, *fid, unread ? *unread : 0, total ? *total : 0);
+		g_print("\n|---+ %-15s : (Container class: %s %016" G_GINT64_MODIFIER "X) UnRead : %d Total : %d ", 
+			newname, class, *fid, unread ? *unread : 0, total ? *total : 0);
+
+		folder = exchange_mapi_folder_new (newname, class, folder_hier, *fid, folder_id,
+						   child ? *child : 0, unread ? *unread : 0, total ? *total : 0);
 
-		folder = exchange_mapi_folder_new (newname, class, folder_hier, *fid, folder_id, child ? *child : 0, unread ? *unread : 0, total ? *total : 0);
 		*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
-		if (child && *child)
-			result = (result && get_child_folders(mem_ctx, folder_hier, &obj_folder, *fid, mapi_folders));
+		if (child && *child && (depth != 0))
+			result = (result && get_child_folders(mem_ctx, folder_hier, &obj_folder, *fid, 
+							      mapi_folders, depth));
 
 		g_free (newname);
 	}
@@ -2714,7 +2724,7 @@ exchange_mapi_get_folders_list (GSList **mapi_folders)
 	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
 	/* FIXME: check status of get_child_folders */
-	get_child_folders (mem_ctx, MAPI_PERSONAL_FOLDER, &obj_store, mailbox_id, mapi_folders);
+	get_child_folders (mem_ctx, MAPI_PERSONAL_FOLDER, &obj_store, mailbox_id, mapi_folders, -1);
 
 	g_free(utf8_mailbox_name);
 
@@ -2738,7 +2748,7 @@ cleanup:
 }
 
 gboolean 
-exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
+exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_fid)
 {
 	enum MAPISTATUS 	retval;
 	TALLOC_CTX 		*mem_ctx;
@@ -2746,6 +2756,7 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 	gboolean 		result = FALSE;
 	mapi_id_t		mailbox_id;
 	ExchangeMAPIFolder 	*folder;
+	mapi_object_t obj_parent_folder;
 
 	d(g_print("\n%s: Entering %s ", G_STRLOC, G_STRFUNC));
 
@@ -2761,13 +2772,22 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 		goto cleanup;
 	}
 
-	/* Prepare the directory listing */
-	retval = GetDefaultPublicFolder(&obj_store, &mailbox_id, olFolderPublicIPMSubtree);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("GetDefaultPublicFolder", GetLastError());
-		goto cleanup;
-	}
+	/* Open the folder if parent_fid is given. */
+	if (parent_fid) {
+		mapi_object_init(&obj_parent_folder);
 
+		retval = OpenFolder(&obj_store, parent_fid, &obj_parent_folder);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("OpenFolder", GetLastError());
+			goto cleanup;
+		}
+	} else {
+		retval = GetDefaultPublicFolder(&obj_store, &mailbox_id, olFolderPublicIPMSubtree);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultPublicFolder", GetLastError());
+			goto cleanup;
+		}
+	}
 	/*  TODO : Localized string */
 	folder = exchange_mapi_folder_new ("All Public Folders", IPF_NOTE, 0, 
 					   mailbox_id, 0, 0, 0 ,0);
@@ -2777,7 +2797,8 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
 	/* FIXME: check status of get_child_folders */
-	get_child_folders (mem_ctx, MAPI_FAVOURITE_FOLDER, &obj_store, mailbox_id, mapi_folders);
+	get_child_folders (mem_ctx, MAPI_FAVOURITE_FOLDER, parent_fid ? &obj_parent_folder : &obj_store,
+			   parent_fid ? parent_fid : mailbox_id, mapi_folders, 1);
 
 	result = TRUE;
 
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index 95b085d..bdd8bf3 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -175,7 +175,7 @@ exchange_mapi_move_items ( mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids);
 
 
 gboolean exchange_mapi_get_folders_list (GSList **mapi_folders); 
-gboolean exchange_mapi_get_pf_folders_list (GSList **mapi_folders); 
+gboolean exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_id); 
 
 struct SPropTagArray *
 exchange_mapi_util_resolve_named_props (uint32_t olFolder, mapi_id_t fid, 



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