[evolution-patches] Exchange, fixes delete and rename of folders



Hi,

Attached patch fixes delete and rename
of folders.

Please review it.

Fixes #310726, #309439.

Thanks,
Arunprakash.

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-exchange/ChangeLog,v
retrieving revision 1.367
diff -u -p -r1.367 ChangeLog
--- ChangeLog	2 Aug 2005 12:57:17 -0000	1.367
+++ ChangeLog	5 Aug 2005 11:30:36 -0000
@@ -1,3 +1,24 @@
+2005-08-05  Arunprakash <arunp novell com>
+
+	* camel/camel-exchange-store.c (exchange_get_folder_info) : Reverted
+	the changes for constructing the prefix, as the bug was somewhere else
+	and got fixed. These changes are wrong and worked for certain cases.
+	(stub_notification) : Added code to remove the folder entries from the
+	folders hash in case of rename and delete operations. Otherwise they
+	represent non-existent folders.
+	* mail/mail-stub-exchange.c (init) : Changed to construct the hash 
+	table with callback for destroying the values.`
+	(get_folder_info) : Cleaned up logic to return the right list of 
+	folders for the given store_flags, and setting the folder flags for
+	each hierarchy.
+	(delete_folder) (rename_folder) : Added code to update the 
+	folders_by_name hash to have the valid values. The deleted and renamed
+	folder's entries need to be cleaned up.
+	(unsubscribe_folder) (is_subscribed_folder) : Modified to make them
+	suitable for all personal, favorite and public hierarchies, as they
+	are used by all of these hierarchies.
+	Fixes #310726, #309439.
+	
 2005-08-02  Sarfraaz Ahmed <asarfraaz novell com>
 
 	* mail/mail-stub-exchange.c (get_folder_info) : Fetch only mail type
Index: camel/camel-exchange-store.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/camel/camel-exchange-store.c,v
retrieving revision 1.20
diff -u -p -r1.20 camel-exchange-store.c
--- camel/camel-exchange-store.c	29 Jul 2005 13:25:25 -0000	1.20
+++ camel/camel-exchange-store.c	5 Aug 2005 11:30:38 -0000
@@ -568,7 +568,6 @@ exchange_get_folder_info (CamelStore *st
 	CamelFolderInfo *info;
 	guint32 store_flags = 0;
 	int i;
-	gchar *prefix, *slash;
 #if 0	
 	if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
 		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get folder info in offline mode."));
@@ -623,17 +622,7 @@ exchange_get_folder_info (CamelStore *st
 	g_array_free (unread_counts, TRUE);
 	g_array_free (folder_flags, TRUE);
 
-	prefix = g_strdup (top);
-	if (prefix) {
-		slash = strrchr (prefix, '/');
-		if (slash) {
-			*slash = '\0';
-		}
-	}
-	
-	info = camel_folder_info_build (folders, prefix, '/', TRUE);
-	
-	g_free (prefix);
+	info = camel_folder_info_build (folders, top, '/', TRUE);
 	
 	if (info)
 		info = postprocess_tree (info);
@@ -885,13 +874,23 @@ stub_notification (CamelObject *object, 
 	case CAMEL_STUB_RETVAL_FOLDER_DELETED:
 	{
 		CamelFolderInfo *info;
+		CamelFolder *folder;
 		char *name, *uri;
 
 		if (camel_stub_marshal_decode_string (stub->status, &name) == -1 ||
 		    camel_stub_marshal_decode_string (stub->status, &uri) == -1)
 			break;
-
+		
 		info = make_folder_info (exch, name, uri, -1, 0);
+
+		g_mutex_lock (exch->folders_lock);
+		folder = g_hash_table_lookup (exch->folders, info->full_name);
+		if (folder) {
+			g_hash_table_remove (exch->folders, info->full_name);
+			camel_object_unref (CAMEL_OBJECT (folder));
+		}
+		g_mutex_unlock (exch->folders_lock);
+
 		camel_object_trigger_event (CAMEL_OBJECT (exch),
 					    "folder_unsubscribed", info);
 		camel_folder_info_free (info);
@@ -902,6 +901,7 @@ stub_notification (CamelObject *object, 
 	{
 		char *new_name, *new_uri;
 		CamelRenameInfo reninfo;
+		CamelFolder *folder;
 
 		if (camel_stub_marshal_decode_folder (stub->status, &reninfo.old_base) == -1 ||
 		    camel_stub_marshal_decode_folder (stub->status, &new_name) == -1 ||
@@ -909,6 +909,15 @@ stub_notification (CamelObject *object, 
 			break;
 
 		reninfo.new = make_folder_info (exch, new_name, new_uri, -1, 0);
+		
+		g_mutex_lock (exch->folders_lock);
+		folder = g_hash_table_lookup (exch->folders, reninfo.old_base);
+		if (folder) {
+			g_hash_table_remove (exch->folders, reninfo.old_base);
+			camel_object_unref (CAMEL_OBJECT (folder));
+		}
+		g_mutex_unlock (exch->folders_lock);
+		
 		camel_object_trigger_event (CAMEL_OBJECT (exch),
 					    "folder_renamed", &reninfo);
 		camel_folder_info_free (reninfo.new);
Index: mail/mail-stub-exchange.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/mail/mail-stub-exchange.c,v
retrieving revision 1.22
diff -u -p -r1.22 mail-stub-exchange.c
--- mail/mail-stub-exchange.c	2 Aug 2005 12:57:17 -0000	1.22
+++ mail/mail-stub-exchange.c	5 Aug 2005 11:30:50 -0000
@@ -132,7 +132,7 @@ static void linestatus_listener (Exchang
 						    gint linestatus,
 						    gpointer data);
 static void folder_update_linestatus (gpointer key, gpointer value, gpointer data);
-
+static void free_folder (gpointer value);
 
 static void
 class_init (GObjectClass *object_class)
@@ -171,7 +171,8 @@ init (GObject *object)
 {
 	MailStubExchange *mse = MAIL_STUB_EXCHANGE (object);
 
-	mse->folders_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+	mse->folders_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, 
+						      NULL, free_folder);
 }
 
 static void
@@ -184,7 +185,7 @@ free_message (MailStubExchangeMessage *m
 }
 
 static void
-free_folder (gpointer key, gpointer value, gpointer ctx)
+free_folder (gpointer value)
 {
 	MailStubExchangeFolder *mfld = value;
 	int i;
@@ -215,8 +216,6 @@ dispose (GObject *object)
 	MailStubExchange *mse = MAIL_STUB_EXCHANGE (object);
 
 	if (mse->folders_by_name) {
-		g_hash_table_foreach (mse->folders_by_name, free_folder,
-				      mse->ctx);
 		g_hash_table_destroy (mse->folders_by_name);
 		mse->folders_by_name = NULL;
 	}
@@ -522,7 +521,7 @@ static void
 got_folder_error (MailStubExchangeFolder *mfld, const char *error)
 {
 	mail_stub_return_error (MAIL_STUB (mfld->mse), error);
-	free_folder (NULL, mfld, NULL);
+	free_folder (mfld);
 }
 
 static const char *open_folder_sync_props[] = {
@@ -2188,7 +2187,7 @@ get_folder_info (MailStub *stub, const c
 	const char *type, *name, *uri, *path, *inbox_uri;
 	int unread_count, i, toplen = top ? strlen (top) : 0;
 	guint32 folder_flags;
-	gboolean recursive, subscribed;
+	gboolean recursive, subscribed, single_folder = FALSE;
 
 	recursive = (store_flags & CAMEL_STUB_STORE_FOLDER_INFO_RECURSIVE);
 	subscribed = (store_flags & CAMEL_STUB_STORE_FOLDER_INFO_SUBSCRIBED);
@@ -2199,7 +2198,7 @@ get_folder_info (MailStub *stub, const c
 		exchange_account_open_folder (mse->account, "/public");
 	}
 
-	if (!recursive && subscribed) {
+	if (!recursive && toplen) {
 		char *full_path;
 
 		full_path = g_strdup_printf ("/%s", top);
@@ -2211,6 +2210,7 @@ get_folder_info (MailStub *stub, const c
 				(!strcmp (type, "mail/public"))) {
 				folders = g_ptr_array_new ();
 				g_ptr_array_add (folders, folder);
+				single_folder = TRUE;
 			}
 		}
 	} else {
@@ -2229,6 +2229,10 @@ get_folder_info (MailStub *stub, const c
 			hier = e_folder_exchange_get_hierarchy (folder);
 			folder_flags = 0;
 
+			/* We ll have only that folder in the folders array */
+			if (single_folder)
+				goto return_data;
+
 			if (subscribed) {
 				if (hier->type != EXCHANGE_HIERARCHY_PERSONAL &&
 				    hier->type != EXCHANGE_HIERARCHY_FAVORITES &&
@@ -2239,34 +2243,52 @@ get_folder_info (MailStub *stub, const c
 					continue;
 			}
 
-			if (recursive && top) {
+			if (recursive && toplen) {
 				path = e_folder_exchange_get_path (folder);
 				if (strncmp (path + 1, top, toplen) != 0)
 					continue;
 			}
-
+return_data:
 			type = e_folder_get_type_string (folder);
 			name = e_folder_get_name (folder);
 			uri = e_folder_get_physical_uri (folder);
-			d(printf ("folder type is : %s\n", type));
-			if (hier->type == EXCHANGE_HIERARCHY_FAVORITES ||
-			    hier->type == EXCHANGE_HIERARCHY_PUBLIC) {
-				unread_count = e_folder_get_unread_count (folder);
-				if (exchange_account_is_favorite_folder (mse->account, folder)) {
+			d(g_print ("Uri: %s\n", uri));
+			d(g_print ("folder type is : %s\n", type));
+
+			if (!strcmp (type, "noselect")) {
+				unread_count = 0;
+				folder_flags = CAMEL_STUB_FOLDER_NOSELECT;
+			}
+
+			switch (hier->type) {
+				case EXCHANGE_HIERARCHY_FAVORITES:
+					/* folder_flags will be set only if the type
+					   is noselect and we need to include it */
+					if (strcmp (type, "mail") && !folder_flags)
+						continue;
+					/* selectable */
+					if (!folder_flags)
+						unread_count = e_folder_get_unread_count (folder);
+				case EXCHANGE_HIERARCHY_PUBLIC:
+					if (exchange_account_is_favorite_folder (mse->account, folder)) {
+						folder_flags |= CAMEL_STUB_FOLDER_SUBSCRIBED;
+						d(printf ("marked the folder as subscribed\n"));
+					}
+					break;
+				case EXCHANGE_HIERARCHY_FOREIGN:
 					folder_flags |= CAMEL_STUB_FOLDER_SUBSCRIBED;
-					d(printf ("marked the folder as subscribed\n"));
-				}
-				else
-					folder_flags = 0;
-			} else  {
-				if (!strcmp (type, "mail")) {
-					unread_count = e_folder_get_unread_count (folder);
-					folder_flags = 0;
-				} else {
-					unread_count = 0;
-					folder_flags = CAMEL_STUB_FOLDER_NOSELECT;
-				}
+				case EXCHANGE_HIERARCHY_PERSONAL:
+					if (!strcmp (type, "mail")) {
+						unread_count = e_folder_get_unread_count (folder);
+					}
+					else if(!folder_flags) {
+						continue;
+					}
+					break;
+				default:
+					break;
 			}
+
 			if (!strcmp (uri, inbox_uri))
 				folder_flags |= CAMEL_STUB_FOLDER_SYSTEM|CAMEL_STUB_FOLDER_TYPE_INBOX;
 
@@ -2435,6 +2457,7 @@ delete_folder (MailStub *stub, const cha
 	switch (result) {
 	case EXCHANGE_ACCOUNT_FOLDER_OK:
 	case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
+		g_hash_table_remove (mse->folders_by_name, folder_name);
 		break;
 
 	case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
@@ -2489,8 +2512,14 @@ rename_folder (MailStub *stub, const cha
 		mfld->folder = g_object_ref (folder);
 		mfld->name = e_folder_exchange_get_path (folder) + 1;
 
-		g_hash_table_remove (mse->folders_by_name, old_name);
+		g_hash_table_steal (mse->folders_by_name, old_name);
 		g_hash_table_insert (mse->folders_by_name, (char *)mfld->name, mfld);
+
+		mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FOLDER_RENAMED,
+				       CAMEL_STUB_ARG_FOLDER, old_name,
+				       CAMEL_STUB_ARG_FOLDER, e_folder_get_name (folder),
+				       CAMEL_STUB_ARG_STRING, e_folder_get_physical_uri (folder),
+				       CAMEL_STUB_ARG_END);
 		break;
 
 	case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
@@ -2566,8 +2595,7 @@ unsubscribe_folder (MailStub *stub, cons
 	char *path, *pub_name;
 	const char *folder_type, *physical_uri;
 
-	pub_name = strchr (folder_name, '/');
-	path = g_build_filename ("/favorites", pub_name, NULL);
+	path = g_build_filename ("/", folder_name, NULL);
 	folder = exchange_account_get_folder (mse->account, path);
 	if (!folder) {
 		mail_stub_return_error (stub, _("Folder doesn't exist"));
@@ -2577,17 +2605,34 @@ unsubscribe_folder (MailStub *stub, cons
 	g_free (path);
 	g_object_ref (folder);
 
-	if (e_folder_exchange_get_hierarchy (folder)->type != EXCHANGE_HIERARCHY_FAVORITES) {
+	/* if (e_folder_exchange_get_hierarchy (folder)->type != EXCHANGE_HIERARCHY_FAVORITES) {
+	   Should use above check, but the internal uri is the same for both 
+	   public and favorite hierarchies and any of them can be used for the check */
+	if (!exchange_account_is_favorite_folder (mse->account, folder)) {
 		g_object_unref (folder);
 		mail_stub_return_ok (stub);
 		return;
 	}
 
+	g_object_unref (folder);
+	
+	pub_name = strchr (folder_name, '/');
+	path = g_build_filename ("/favorites", pub_name, NULL);
+	folder = exchange_account_get_folder (mse->account, path);
+	if (!folder) {
+		mail_stub_return_error (stub, _("Folder doesn't exist"));
+		g_free (path);
+		return;
+	}
+	g_free (path);
+	g_object_ref (folder);
+
 	result = exchange_account_remove_favorite (mse->account, folder);
 
 	switch (result) {
 	case EXCHANGE_ACCOUNT_FOLDER_OK:
 	case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
+		g_hash_table_remove (mse->folders_by_name, path + 1);
 		break;
 
 	case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
@@ -2615,14 +2660,17 @@ is_subscribed_folder (MailStub *stub, co
 	char *path, *pub_name;
 	guint32 is_subscribed = 0;
 
-	pub_name = strchr (folder_name, '/');
-	path = g_build_filename ("/favorites", pub_name, NULL);
+	path = g_build_filename ("/", folder_name, NULL);
 	folder = exchange_account_get_folder (mse->account, path);
 	if (!folder) {
 		/* Dont ever return an exception from here as CamelException
 		is NULL for this */
 		//mail_stub_return_error (stub, _("Folder doesn't exist"));
 		g_free (path);
+		mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
+				       CAMEL_STUB_ARG_UINT32, is_subscribed,
+				       CAMEL_STUB_ARG_END);
+		mail_stub_return_ok (stub);
 		return;
 	}
 	g_object_ref (folder);


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