[evolution-patches] 43091 make empty trash fully async



The empty trash code assumes that it can safely call mail_tool_get_trash
from the main thread, which works for vtrash-using stores, but not for
Connector. Making that safe (by resolving the Deleted Items folder at
connect time rather than waiting until the user requests it) would fix
this problem, but would make Connector startup much slower. This works
around the problem by moving the get_trash call into the async part of
the operation.

As written, the code breaks string freeze. I could rewrite it to just
use the "Expunging folder" string and leave a FIXME for post-1.4...


Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.2725
diff -u -r1.2725 ChangeLog
--- mail/ChangeLog	15 May 2003 23:37:01 -0000	1.2725
+++ mail/ChangeLog	16 May 2003 19:13:54 -0000
@@ -1,3 +1,10 @@
+2003-05-16  Dan Winship  <danw ximian com>
+
+	* mail-ops.c (mail_empty_trash): New async "empty trash" op.
+
+	* mail-callbacks.c (empty_trash): Use it rather than requiring
+	that mail_tool_get_vtrash() work without blocking. #43091
+
 2003-05-15  Not Zed  <NotZed Ximian com>
 
 	** See bug #42838.
Index: mail/mail-callbacks.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-callbacks.c,v
retrieving revision 1.440
diff -u -r1.440 mail-callbacks.c
--- mail/mail-callbacks.c	2 May 2003 16:07:17 -0000	1.440
+++ mail/mail-callbacks.c	16 May 2003 19:13:54 -0000
@@ -3188,12 +3188,6 @@
 	camel_operation_cancel (NULL);
 }
 
-static void
-empty_trash_expunged_cb (CamelFolder *folder, void *data)
-{
-	camel_object_unref (folder);
-}
-
 void
 empty_trash (BonoboUIComponent *uih, void *user_data, const char *path)
 {
@@ -3225,11 +3219,7 @@
 				/* make sure this store is a remote store */
 				if (provider->flags & CAMEL_PROVIDER_IS_STORAGE &&
 				    provider->flags & CAMEL_PROVIDER_IS_REMOTE) {
-					vtrash = mail_tool_get_trash (account->source->url, FALSE, &ex);
-					
-					if (vtrash) {
-						mail_expunge_folder (vtrash, empty_trash_expunged_cb, NULL);
-					}
+					mail_empty_trash (account, NULL, NULL);
 				}
 			}
 			
@@ -3243,9 +3233,5 @@
 	g_object_unref (iter);
 	
 	/* Now empty the local trash folder */
-	vtrash = mail_tool_get_trash ("file:/", TRUE, &ex);
-	if (vtrash)
-		mail_expunge_folder (vtrash, empty_trash_expunged_cb, NULL);
-	
-	camel_exception_clear (&ex);
+	mail_empty_trash (NULL, NULL, NULL);
 }
Index: mail/mail-ops.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-ops.c,v
retrieving revision 1.390
diff -u -r1.390 mail-ops.c
--- mail/mail-ops.c	20 Mar 2003 16:44:05 -0000	1.390
+++ mail/mail-ops.c	16 May 2003 19:13:55 -0000
@@ -1623,6 +1623,76 @@
 	e_thread_put(mail_thread_queued, (EMsg *)m);
 }
 
+/* ******************************************************************************** */
+
+struct _empty_trash_msg {
+	struct _mail_msg msg;
+
+	EAccount *account;
+	void (*done) (EAccount *account, void *data);
+	void *data;
+};
+
+static char *empty_trash_desc(struct _mail_msg *mm, int done)
+{
+	struct _empty_trash_msg *m = (struct _empty_trash_msg *)mm;
+
+	return g_strdup_printf (_("Emptying trash in \'%s\'"), 
+				m->account ? m->account->name : _("Local Folders"));
+}
+
+static void empty_trash_empty(struct _mail_msg *mm)
+{
+	struct _empty_trash_msg *m = (struct _empty_trash_msg *)mm;
+	CamelFolder *trash;
+
+	if (m->account)
+		trash = mail_tool_get_trash (m->account->source->url, FALSE, &mm->ex);
+	else
+		trash = mail_tool_get_trash ("file:/", TRUE, &mm->ex);
+	if (trash)
+		camel_folder_expunge (trash, &mm->ex);
+	camel_object_unref(trash);
+}
+
+static void empty_trash_emptied(struct _mail_msg *mm)
+{
+	struct _empty_trash_msg *m = (struct _empty_trash_msg *)mm;
+
+	if (m->done)
+		m->done(m->account, m->data);
+}
+
+static void empty_trash_free(struct _mail_msg *mm)
+{
+	struct _empty_trash_msg *m = (struct _empty_trash_msg *)mm;
+
+	if (m->account)
+		g_object_unref(m->account);
+}
+
+static struct _mail_msg_op empty_trash_op = {
+	empty_trash_desc,
+	empty_trash_empty,
+	empty_trash_emptied,
+	empty_trash_free,
+};
+
+void
+mail_empty_trash(EAccount *account, void (*done) (EAccount *account, void *data), void *data)
+{
+	struct _empty_trash_msg *m;
+
+	m = mail_msg_new(&empty_trash_op, NULL, sizeof(*m));
+	m->account = account;
+	if (account)
+		g_object_ref(account);
+	m->data = data;
+	m->done = done;
+
+	e_thread_put(mail_thread_queued, (EMsg *)m);
+}
+
 /* ** GET MESSAGE(s) ***************************************************** */
 
 struct _get_message_msg {
Index: mail/mail-ops.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-ops.h,v
retrieving revision 1.58
diff -u -r1.58 mail-ops.h
--- mail/mail-ops.h	25 Jul 2002 07:46:06 -0000	1.58
+++ mail/mail-ops.h	16 May 2003 19:13:55 -0000
@@ -37,6 +37,7 @@
 
 #include "evolution-storage.h"	/*EvolutionStorage */
 #include "e-util/e-msgport.h"
+#include "e-util/e-account.h"
 
 void mail_append_mail (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info,
 		       void (*done)(CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *info, int ok,
@@ -87,6 +88,10 @@
 void mail_expunge_folder (CamelFolder *folder,
 			  void (*done) (CamelFolder *folder, void *data),
 			  void *data);
+
+void mail_empty_trash (EAccount *account,
+		       void (*done) (EAccount *account, void *data),
+		       void *data);
 
 /* get folder info asynchronously */
 int mail_get_folderinfo (CamelStore *store,


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