From 18396b557b013266a840f618c2b9b6cc0ff87bf7 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 29 Sep 2008 09:31:18 +0000 Subject: ** Fix for bug #530691 2008-09-29 Milan Crha ** Fix for bug #530691 * em-folder-utils.c: (emfu_delete_rec), (emfu_delete_done), (emfu_delete_folders), (emfu_delete_response), (em_folder_utils_delete_folder): * mail-ops.h: (mail_remove_folder): * mail-ops.c: (mail_remove_folder), (struct _remove_folder_msg), (remove_folder_desc), (remove_folder_rec), (remove_folder_exec), (remove_folder_done), (remove_folder_free): Remove folders in its own thread, not in main thread. svn path=/trunk/; revision=36471 --- mail/ChangeLog | 13 +++++++ mail/em-folder-utils.c | 87 +++++++++------------------------------------ mail/mail-ops.c | 95 ++++++++++++++++++++++++++++++++------------------ mail/mail-ops.h | 4 +-- 4 files changed, 94 insertions(+), 105 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index bd0db9a7b1..c73a4511b4 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,16 @@ +2008-09-29 Milan Crha + + ** Fix for bug #530691 + + * em-folder-utils.c: (emfu_delete_rec), (emfu_delete_done), + (emfu_delete_folders), (emfu_delete_response), + (em_folder_utils_delete_folder): + * mail-ops.h: (mail_remove_folder): + * mail-ops.c: (mail_remove_folder), (struct _remove_folder_msg), + (remove_folder_desc), (remove_folder_rec), (remove_folder_exec), + (remove_folder_done), (remove_folder_free): + Remove folders in its own thread, not in main thread. + 2008-09-29 Sankar P License Changes diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c index ef0af85bd2..195b66a815 100644 --- a/mail/em-folder-utils.c +++ b/mail/em-folder-utils.c @@ -367,84 +367,32 @@ em_folder_utils_copy_folder(CamelFolderInfo *folderinfo, int delete) } static void -emfu_delete_rec (CamelStore *store, CamelFolderInfo *fi, CamelException *ex) +emfu_delete_done (CamelFolder *folder, gboolean removed, CamelException *ex, void *data) { - while (fi) { - CamelFolder *folder; + GtkWidget *dialog = data; - if (fi->child) { - emfu_delete_rec (store, fi->child, ex); - if (camel_exception_is_set (ex)) - return; - } - - d(printf ("deleting folder '%s'\n", fi->full_name)); - - /* shouldn't camel do this itself? */ - if (camel_store_supports_subscriptions (store)) - camel_store_unsubscribe_folder (store, fi->full_name, NULL); - - if (!(folder = camel_store_get_folder (store, fi->full_name, 0, ex))) - return; - - if (!CAMEL_IS_VEE_FOLDER (folder)) { - GPtrArray *uids = camel_folder_get_uids (folder); - int i; - - camel_folder_freeze (folder); - for (i = 0; i < uids->len; i++) - camel_folder_delete_message (folder, uids->pdata[i]); - - camel_folder_free_uids (folder, uids); - - camel_folder_sync (folder, TRUE, NULL); - camel_folder_thaw (folder); - } - - camel_store_delete_folder (store, fi->full_name, ex); - if (camel_exception_is_set (ex)) - return; - - fi = fi->next; + if (ex && camel_exception_is_set (ex)) { + GtkWidget *w = e_error_new (NULL, + "mail:no-delete-folder", folder->full_name, camel_exception_get_description (ex), NULL); + em_utils_show_error_silent (w); + camel_exception_clear (ex); } -} -static void -emfu_delete_folders (CamelStore *store, const char *full_name, CamelException *ex) -{ - guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED; - CamelFolderInfo *fi; - - fi = camel_store_get_folder_info (store, full_name, flags, ex); - if (camel_exception_is_set (ex)) - return; - - emfu_delete_rec (store, fi, ex); - camel_store_free_folder_info (store, fi); + if (dialog) + gtk_widget_destroy (dialog); } static void emfu_delete_response (GtkWidget *dialog, int response, gpointer data) { - CamelStore *store; - CamelException ex; - char *full_name; - - full_name = g_object_get_data ((GObject *) dialog, "full_name"); - store = g_object_get_data ((GObject *) dialog, "store"); - if (response == GTK_RESPONSE_OK) { - camel_exception_init (&ex); - emfu_delete_folders (store, full_name, &ex); - if (camel_exception_is_set (&ex)) { - GtkWidget *w = e_error_new(NULL, - "mail:no-delete-folder", full_name, ex.desc, NULL); - em_utils_show_error_silent (w); - camel_exception_clear (&ex); - } - } + /* disable dialog until operation finishes */ + gtk_widget_set_sensitive (dialog, FALSE); - gtk_widget_destroy (dialog); + mail_remove_folder (g_object_get_data ((GObject *) dialog, "folder"), emfu_delete_done, dialog); + } else { + gtk_widget_destroy (dialog); + } } /* FIXME: these functions must be documented */ @@ -462,13 +410,12 @@ em_folder_utils_delete_folder (CamelFolder *folder) return; } - camel_object_ref (folder->parent_store); + camel_object_ref (folder); dialog = e_error_new(NULL, (folder->parent_store && CAMEL_IS_VEE_STORE(folder->parent_store))?"mail:ask-delete-vfolder":"mail:ask-delete-folder", folder->full_name, NULL); - g_object_set_data_full ((GObject *) dialog, "full_name", g_strdup (folder->full_name), g_free); - g_object_set_data_full ((GObject *) dialog, "store", folder->parent_store, camel_object_unref); + g_object_set_data_full ((GObject *) dialog, "folder", folder, camel_object_unref); g_signal_connect (dialog, "response", G_CALLBACK (emfu_delete_response), NULL); gtk_widget_show (dialog); } diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 00eebd201a..1f1a42d57b 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -1400,68 +1400,94 @@ mail_get_store (const char *uri, CamelOperation *op, void (*done) (char *uri, Ca struct _remove_folder_msg { MailMsg base; - char *uri; + CamelFolder *folder; gboolean removed; - void (*done) (char *uri, gboolean removed, void *data); + void (*done) (CamelFolder *folder, gboolean removed, CamelException *ex, void *data); void *data; }; static gchar * remove_folder_desc (struct _remove_folder_msg *m) { - return g_strdup_printf (_("Removing folder %s"), m->uri); + return g_strdup_printf (_("Removing folder %s"), m->folder->full_name); +} + +static void +remove_folder_rec (CamelStore *store, CamelFolderInfo *fi, CamelException *ex) +{ + while (fi) { + CamelFolder *folder; + + if (fi->child) { + remove_folder_rec (store, fi->child, ex); + if (camel_exception_is_set (ex)) + return; + } + + d(printf ("deleting folder '%s'\n", fi->full_name)); + + if (!(folder = camel_store_get_folder (store, fi->full_name, 0, ex))) + return; + + if (!CAMEL_IS_VEE_FOLDER (folder)) { + GPtrArray *uids = camel_folder_get_uids (folder); + int i; + + /* Delete every message in this folder, then expunge it */ + camel_folder_freeze (folder); + for (i = 0; i < uids->len; i++) + camel_folder_delete_message (folder, uids->pdata[i]); + + camel_folder_free_uids (folder, uids); + + camel_folder_sync (folder, TRUE, NULL); + camel_folder_thaw (folder); + } + + /* if the store supports subscriptions, unsubscribe from this folder... */ + if (camel_store_supports_subscriptions (store)) + camel_store_unsubscribe_folder (store, fi->full_name, NULL); + + /* Then delete the folder from the store */ + camel_store_delete_folder (store, fi->full_name, ex); + if (camel_exception_is_set (ex)) + return; + + fi = fi->next; + } } static void remove_folder_exec (struct _remove_folder_msg *m) { CamelStore *store; - CamelFolder *folder; - GPtrArray *uids; - int i; + CamelFolderInfo *fi; m->removed = FALSE; - folder = mail_tool_uri_to_folder (m->uri, 0, &m->base.ex); - if (!folder) - return; - - store = folder->parent_store; + store = m->folder->parent_store; - /* Delete every message in this folder, then expunge it */ - uids = camel_folder_get_uids (folder); - camel_folder_freeze(folder); - for (i = 0; i < uids->len; i++) - camel_folder_delete_message (folder, uids->pdata[i]); - camel_folder_sync (folder, TRUE, NULL); - camel_folder_thaw(folder); - camel_folder_free_uids (folder, uids); + fi = camel_store_get_folder_info (store, m->folder->full_name, CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, &m->base.ex); + if (camel_exception_is_set (&m->base.ex)) + return; - /* if the store supports subscriptions, unsubscribe from this folder... */ - if (camel_store_supports_subscriptions (store)) - camel_store_unsubscribe_folder (store, folder->full_name, NULL); + remove_folder_rec (store, fi, &m->base.ex); + camel_store_free_folder_info (store, fi); - /* Then delete the folder from the store */ - camel_store_delete_folder (store, folder->full_name, &m->base.ex); m->removed = !camel_exception_is_set (&m->base.ex); - camel_object_unref (folder); } static void remove_folder_done (struct _remove_folder_msg *m) { - if (m->removed) { - /* FIXME: Remove this folder from the folder cache ??? */ - } - if (m->done) - m->done (m->uri, m->removed, m->data); + m->done (m->folder, m->removed, &m->base.ex, m->data); } static void remove_folder_free (struct _remove_folder_msg *m) { - g_free (m->uri); + camel_object_unref (m->folder); } static MailMsgInfo remove_folder_info = { @@ -1473,12 +1499,15 @@ static MailMsgInfo remove_folder_info = { }; void -mail_remove_folder (const char *uri, void (*done) (char *uri, gboolean removed, void *data), void *data) +mail_remove_folder (CamelFolder *folder, void (*done) (CamelFolder *folder, gboolean removed, CamelException *ex, void *data), void *data) { struct _remove_folder_msg *m; + g_return_if_fail (folder != NULL); + m = mail_msg_new (&remove_folder_info); - m->uri = g_strdup (uri); + m->folder = folder; + camel_object_ref (folder); m->data = data; m->done = done; diff --git a/mail/mail-ops.h b/mail/mail-ops.h index 14654aa0b4..e615a9121d 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -111,8 +111,8 @@ int mail_get_folderinfo (CamelStore *store, CamelOperation *op, void *data); /* remove an existing folder */ -void mail_remove_folder (const char *uri, - void (*done) (char *uri, gboolean removed, void *data), +void mail_remove_folder (CamelFolder *folder, + void (*done) (CamelFolder *folder, gboolean removed, CamelException *ex, void *data), void *data); /* transfer (copy/move) a folder */ -- cgit