From 831d6dca44ecaa272b4ef5e1cfc29578e7ba5435 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 30 Oct 2010 14:23:01 -0400 Subject: Kill mail_append_mail(). Use e_mail_folder_append_message() instead. --- mail/e-mail-folder-utils.c | 87 ++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 33 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 7186589849..f2ba207e01 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -27,15 +27,19 @@ typedef struct _AsyncContext AsyncContext; struct _AsyncContext { - GCancellable *cancellable; + CamelMimeMessage *message; + CamelMessageInfo *info; gchar *message_uid; }; static void async_context_free (AsyncContext *context) { - if (context->cancellable != NULL) - g_object_unref (context->cancellable); + if (context->message != NULL) + g_object_unref (context->message); + + if (context->info != NULL) + camel_message_info_free (context->info); g_free (context->message_uid); @@ -43,28 +47,58 @@ async_context_free (AsyncContext *context) } static void -mail_folder_append_message_ready (CamelFolder *folder, - GAsyncResult *result, - GSimpleAsyncResult *simple) +mail_folder_append_message_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) { AsyncContext *context; GError *error = NULL; context = g_simple_async_result_get_op_res_gpointer (simple); - camel_folder_append_message_finish ( - folder, result, &context->message_uid, &error); + e_mail_folder_append_message_sync ( + CAMEL_FOLDER (object), context->message, + context->info, &context->message_uid, + cancellable, &error); if (error != NULL) { g_simple_async_result_set_from_error (simple, error); g_error_free (error); } +} + +gboolean +e_mail_folder_append_message_sync (CamelFolder *folder, + CamelMimeMessage *message, + CamelMessageInfo *info, + gchar **appended_uid, + GCancellable *cancellable, + GError **error) +{ + CamelMedium *medium; + gboolean success; - camel_operation_pop_message (context->cancellable); + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); + g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE); - g_simple_async_result_complete (simple); + medium = CAMEL_MEDIUM (message); - g_object_unref (simple); + camel_operation_push_message ( + cancellable, + _("Saving message to folder '%s'"), + camel_folder_get_full_name (folder)); + + if (camel_medium_get_header (medium, "X-Mailer") == NULL) + camel_medium_set_header (medium, "X-Mailer", X_MAILER); + + camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); + + success = camel_folder_append_message_sync ( + folder, message, info, appended_uid, cancellable, error); + + camel_operation_pop_message (cancellable); + + return success; } void @@ -78,17 +112,15 @@ e_mail_folder_append_message (CamelFolder *folder, { GSimpleAsyncResult *simple; AsyncContext *context; - CamelMedium *medium; g_return_if_fail (CAMEL_IS_FOLDER (folder)); g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - medium = CAMEL_MEDIUM (message); - context = g_slice_new0 (AsyncContext); + context->message = g_object_ref (message); - if (G_IS_CANCELLABLE (cancellable)) - context->cancellable = g_object_ref (cancellable); + if (info != NULL) + context->info = camel_message_info_ref (info); simple = g_simple_async_result_new ( G_OBJECT (folder), callback, user_data, @@ -97,20 +129,11 @@ e_mail_folder_append_message (CamelFolder *folder, g_simple_async_result_set_op_res_gpointer ( simple, context, (GDestroyNotify) async_context_free); - camel_operation_push_message ( - context->cancellable, - _("Saving message to folder '%s'"), - camel_folder_get_full_name (folder)); - - if (camel_medium_get_header (medium, "X-Mailer") == NULL) - camel_medium_set_header (medium, "X-Mailer", X_MAILER); - - camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); + g_simple_async_result_run_in_thread ( + simple, mail_folder_append_message_thread, + io_priority, cancellable); - camel_folder_append_message ( - folder, message, info, io_priority, - context->cancellable, (GAsyncReadyCallback) - mail_folder_append_message_ready, simple); + g_object_unref (simple); } gboolean @@ -130,13 +153,11 @@ e_mail_folder_append_message_finish (CamelFolder *folder, simple = G_SIMPLE_ASYNC_RESULT (result); context = g_simple_async_result_get_op_res_gpointer (simple); - if (g_simple_async_result_propagate_error (simple, error)) - return FALSE; - if (appended_uid != NULL) { *appended_uid = context->message_uid; context->message_uid = NULL; } - return TRUE; + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); } -- cgit v1.2.3 From b21a89d79c6bb6a380b58988d30cff6de03ab91d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 3 May 2011 06:06:20 -0400 Subject: Add some handy folder URI utility functions. e_mail_folder_uri_parse() Parses a folder URI and returns a corresponding CamelStore instance and folder name string, or else sets a GError. e_mail_folder_uri_equal() Compares two folder URIs for equality. Replaces camel_store_folder_uri_equal(). e_mail_folder_uri_from_folder() This will eventually replace camel_folder_get_uri(), but for now it just calls camel_folder_get_uri() and duplicates the URI string. --- mail/e-mail-folder-utils.c | 155 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index f2ba207e01..bcf649728a 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -161,3 +161,158 @@ e_mail_folder_append_message_finish (CamelFolder *folder, /* Assume success unless a GError is set. */ return !g_simple_async_result_propagate_error (simple, error); } + +/** + * e_mail_folder_uri_parse: + * @session: a #CamelSession + * @folder_uri: a folder URI + * @out_store: return location for a #CamelStore, or %NULL + * @out_folder_name: return location for a folder name, or %NULL + * @error: return location for a #GError, or %NULL + * + * Parses a folder URI and returns the corresponding #CamelStore instance + * in @out_store and folder name string in @out_folder_name. If the URI + * is malformed or no corresponding store exists, the function sets @error + * and returns %FALSE. + * + * If the function is able to parse the URI, the #CamelStore instance + * set in @out_store should be unreferenced with g_object_unref() when + * done with it, and the folder name string set in @out_folder_name + * should be freed with g_free(). + * + * Returns: %TRUE if @folder_uri could be parsed, %FALSE otherwise + **/ +gboolean +e_mail_folder_uri_parse (CamelSession *session, + const gchar *folder_uri, + CamelStore **out_store, + gchar **out_folder_name, + GError **error) +{ + CamelURL *url; + CamelService *service = NULL; + const gchar *folder_name = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); + g_return_val_if_fail (folder_uri != NULL, FALSE); + + url = camel_url_new (folder_uri, error); + if (url == NULL) + return FALSE; + + service = camel_session_get_service_by_url ( + session, url, CAMEL_PROVIDER_STORE); + + if (CAMEL_IS_STORE (service)) { + CamelProvider *provider; + + provider = camel_service_get_provider (service); + + if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) + folder_name = url->fragment; + else if (url->path != NULL && *url->path == '/') + folder_name = url->path + 1; + } + + if (CAMEL_IS_STORE (service) && folder_name != NULL) { + if (out_store != NULL) + *out_store = g_object_ref (service); + + if (out_folder_name != NULL) + *out_folder_name = g_strdup (folder_name); + + success = TRUE; + } else { + g_set_error ( + error, CAMEL_FOLDER_ERROR, + CAMEL_FOLDER_ERROR_INVALID, + _("Invalid folder URI '%s'"), + folder_uri); + } + + camel_url_free (url); + + return success; +} + +/** + * e_mail_folder_uri_equal: + * @session: a #CamelSession + * @folder_uri_a: a folder URI + * @folder_uri_b: another folder URI + * + * Compares two folder URIs for equality. If either URI is invalid, + * the function returns %FALSE. + * + * Returns: %TRUE if the URIs are equal, %FALSE if not + **/ +gboolean +e_mail_folder_uri_equal (CamelSession *session, + const gchar *folder_uri_a, + const gchar *folder_uri_b) +{ + CamelStore *store_a; + CamelStore *store_b; + CamelStoreClass *class; + gchar *folder_name_a; + gchar *folder_name_b; + gboolean success_a; + gboolean success_b; + gboolean equal = FALSE; + + g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); + g_return_val_if_fail (folder_uri_a != NULL, FALSE); + g_return_val_if_fail (folder_uri_b != NULL, FALSE); + + success_a = e_mail_folder_uri_parse ( + session, folder_uri_a, &store_a, &folder_name_a, NULL); + + success_b = e_mail_folder_uri_parse ( + session, folder_uri_b, &store_b, &folder_name_b, NULL); + + if (!success_a || !success_b) + goto exit; + + if (store_a != store_b) + goto exit; + + /* Doesn't matter which store we use since they're the same. */ + class = CAMEL_STORE_GET_CLASS (store_a); + g_return_val_if_fail (class->compare_folder_name != NULL, FALSE); + + equal = class->compare_folder_name (folder_name_a, folder_name_b); + +exit: + if (success_a) { + g_object_unref (store_a); + g_free (folder_name_a); + } + + if (success_b) { + g_object_unref (store_b); + g_free (folder_name_b); + } + + return equal; +} + +/** + * e_mail_folder_uri_from_folder: + * @folder: a #CamelFolder + * + * Convenience function for building a folder URI from a #CamelFolder. + * Free the returned URI string with g_free(). + * + * Returns: a newly-allocated folder URI string + **/ +gchar * +e_mail_folder_uri_from_folder (CamelFolder *folder) +{ + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); + + /* XXX This looks silly because it's just a temporary + * implementation. I have other plans in store. */ + + return g_strdup (camel_folder_get_uri (folder)); +} -- cgit v1.2.3 From 4d08cc60e5401caba786e74bf6c1fb5bf9424e3f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 5 May 2011 13:25:47 -0400 Subject: Teach e_mail_folder_uri_parse() to parse 'email://' URIs. --- mail/e-mail-folder-utils.c | 69 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 9 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index bcf649728a..3c87ca4de0 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -201,18 +201,69 @@ e_mail_folder_uri_parse (CamelSession *session, if (url == NULL) return FALSE; - service = camel_session_get_service_by_url ( - session, url, CAMEL_PROVIDER_STORE); + /* This style was used to reference accounts by UID before + * CamelServices themselves had UIDs. Some examples are: + * + * Special cases: + * + * 'email://local@local/' FOLDER_PATH + * 'email://vfolder@local/' FOLDER_PATH + * + * General case: + * + * 'email://' ACCOUNT_UID '/' FOLDER_PATH + * + * Note: ACCOUNT_UID is now equivalent to STORE_UID, and + * the STORE_UIDs for the special cases are 'local' + * and 'vfolder'. + */ + if (g_strcmp0 (url->protocol, "email") == 0) { + gchar *uid = NULL; + + /* Handle the special cases. */ + if (g_strcmp0 (url->host, "local") == 0) { + if (g_strcmp0 (url->user, "local") == 0) + uid = g_strdup ("local"); + if (g_strcmp0 (url->user, "vfolder") == 0) + uid = g_strdup ("vfolder"); + } + + /* Handle the general case. */ + if (uid == NULL && url->host != NULL) { + if (url->user == NULL) + uid = g_strdup (url->host); + else + uid = g_strdup_printf ( + "%s@%s", url->user, url->host); + } + + if (uid != NULL) { + service = camel_session_get_service (session, uid); + g_free (uid); + } + + if (url->path != NULL && *url->path == '/') + folder_name = url->path + 1; + + /* CamelFolderInfo URIs used to embed the store's URI, so the + * folder name is appended as either a path part or a fragment + * part, depending whether the store's URI used the path part. + * To determine which it is, you have to check the provider + * flags for CAMEL_URL_FRAGMENT_IS_PATH. */ + } else { + service = camel_session_get_service_by_url ( + session, url, CAMEL_PROVIDER_STORE); - if (CAMEL_IS_STORE (service)) { - CamelProvider *provider; + if (CAMEL_IS_STORE (service)) { + CamelProvider *provider; - provider = camel_service_get_provider (service); + provider = camel_service_get_provider (service); - if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) - folder_name = url->fragment; - else if (url->path != NULL && *url->path == '/') - folder_name = url->path + 1; + if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) + folder_name = url->fragment; + else if (url->path != NULL && *url->path == '/') + folder_name = url->path + 1; + } } if (CAMEL_IS_STORE (service) && folder_name != NULL) { -- cgit v1.2.3 From 1ffacfeee95b69419b96423afef91b66be2a7d34 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 5 May 2011 16:02:56 -0400 Subject: Introduce a new, simpler folder URI format. Folder URIs shall henceforth be exclusive to Evolution. The new format is: 'folder://' CAMEL_STORE_UID '/' CAMEL_FOLDER_PATH Add e_mail_folder_uri_build() to construct such a URI from a CamelStore and folder path string, change e_mail_folder_uri_from_folder() to build the new URI, and teach e_mail_folder_uri_parse() to parse it. e_mail_folder_uri_parse() will continue to know how to parse the older URI formats still present in config files and GConf keys. This captures the legacy knowledge neatly into one function. --- mail/e-mail-folder-utils.c | 71 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 3c87ca4de0..fbd2dd3055 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -162,6 +162,40 @@ e_mail_folder_append_message_finish (CamelFolder *folder, return !g_simple_async_result_propagate_error (simple, error); } +/** + * e_mail_folder_uri_build: + * @store: a #CamelStore + * @folder_name: a folder name + * + * Builds a folder URI string from @store and @folder_name. + * + * Returns: a newly-allocated folder URI string + **/ +gchar * +e_mail_folder_uri_build (CamelStore *store, + const gchar *folder_name) +{ + const gchar *uid; + gchar *encoded_uid; + gchar *uri; + + g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); + g_return_val_if_fail (folder_name != NULL, NULL); + + /* Skip the leading slash, if present. */ + if (*folder_name == '/') + folder_name++; + + uid = camel_service_get_uid (CAMEL_SERVICE (store)); + encoded_uid = camel_url_encode (uid, ":;@/"); + + uri = g_strdup_printf ("folder://%s/%s", encoded_uid, folder_name); + + g_free (encoded_uid); + + return uri; +} + /** * e_mail_folder_uri_parse: * @session: a #CamelSession @@ -170,16 +204,21 @@ e_mail_folder_append_message_finish (CamelFolder *folder, * @out_folder_name: return location for a folder name, or %NULL * @error: return location for a #GError, or %NULL * - * Parses a folder URI and returns the corresponding #CamelStore instance - * in @out_store and folder name string in @out_folder_name. If the URI - * is malformed or no corresponding store exists, the function sets @error - * and returns %FALSE. + * Parses a folder URI generated by e_mail_folder_uri_build() and + * returns the corresponding #CamelStore instance in @out_store and + * folder name string in @out_folder_name. If the URI is malformed + * or no corresponding store exists, the function sets @error and + * returns %FALSE. * * If the function is able to parse the URI, the #CamelStore instance * set in @out_store should be unreferenced with g_object_unref() when * done with it, and the folder name string set in @out_folder_name * should be freed with g_free(). * + * The function also handles older style URIs, such as ones where the + * #CamelStore's #CamelStore::uri string was embedded directly in the + * folder URI, and account-based URIs that used an "email://" prefix. + * * Returns: %TRUE if @folder_uri could be parsed, %FALSE otherwise **/ gboolean @@ -201,6 +240,19 @@ e_mail_folder_uri_parse (CamelSession *session, if (url == NULL) return FALSE; + /* Current URI Format: 'folder://' STORE_UID '/' FOLDER_PATH */ + if (g_strcmp0 (url->protocol, "folder") == 0) { + + if (url->host != NULL) { + gchar *uid = g_strdup (url->host); + camel_url_decode (uid); + service = camel_session_get_service (session, uid); + g_free (uid); + } + + if (url->path != NULL && *url->path == '/') + folder_name = url->path + 1; + /* This style was used to reference accounts by UID before * CamelServices themselves had UIDs. Some examples are: * @@ -217,7 +269,7 @@ e_mail_folder_uri_parse (CamelSession *session, * the STORE_UIDs for the special cases are 'local' * and 'vfolder'. */ - if (g_strcmp0 (url->protocol, "email") == 0) { + } else if (g_strcmp0 (url->protocol, "email") == 0) { gchar *uid = NULL; /* Handle the special cases. */ @@ -360,10 +412,13 @@ exit: gchar * e_mail_folder_uri_from_folder (CamelFolder *folder) { + CamelStore *store; + const gchar *folder_name; + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - /* XXX This looks silly because it's just a temporary - * implementation. I have other plans in store. */ + store = camel_folder_get_parent_store (folder); + folder_name = camel_folder_get_full_name (folder); - return g_strdup (camel_folder_get_uri (folder)); + return e_mail_folder_uri_build (store, folder_name); } -- cgit v1.2.3 From eeb642c416a847a81c1aa85548bdcabc0c30b716 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 8 May 2011 22:01:19 -0400 Subject: Encode the path part of folder URIs. Wasn't sure if this was necessary, but it -is- in order to handle the local Junk and Trash vfolder names correctly: .#evolution/Junk .#evolution/Trash If we don't escape the path and we feed camel_url_new() something like "folder://local/.#evolution/Trash", it's gonna think the path is '.' and the rest of it's a fragment. --- mail/e-mail-folder-utils.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index fbd2dd3055..d73f13ad5c 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -176,6 +176,7 @@ e_mail_folder_uri_build (CamelStore *store, const gchar *folder_name) { const gchar *uid; + gchar *encoded_name; gchar *encoded_uid; gchar *uri; @@ -187,11 +188,14 @@ e_mail_folder_uri_build (CamelStore *store, folder_name++; uid = camel_service_get_uid (CAMEL_SERVICE (store)); + encoded_uid = camel_url_encode (uid, ":;@/"); + encoded_name = camel_url_encode (folder_name, "#"); - uri = g_strdup_printf ("folder://%s/%s", encoded_uid, folder_name); + uri = g_strdup_printf ("folder://%s/%s", encoded_uid, encoded_name); g_free (encoded_uid); + g_free (encoded_name); return uri; } @@ -230,7 +234,7 @@ e_mail_folder_uri_parse (CamelSession *session, { CamelURL *url; CamelService *service = NULL; - const gchar *folder_name = NULL; + gchar *folder_name = NULL; gboolean success = FALSE; g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); @@ -251,7 +255,7 @@ e_mail_folder_uri_parse (CamelSession *session, } if (url->path != NULL && *url->path == '/') - folder_name = url->path + 1; + folder_name = camel_url_decode_path (url->path + 1); /* This style was used to reference accounts by UID before * CamelServices themselves had UIDs. Some examples are: @@ -295,7 +299,7 @@ e_mail_folder_uri_parse (CamelSession *session, } if (url->path != NULL && *url->path == '/') - folder_name = url->path + 1; + folder_name = g_strdup (url->path + 1); /* CamelFolderInfo URIs used to embed the store's URI, so the * folder name is appended as either a path part or a fragment @@ -312,9 +316,9 @@ e_mail_folder_uri_parse (CamelSession *session, provider = camel_service_get_provider (service); if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) - folder_name = url->fragment; + folder_name = g_strdup (url->fragment); else if (url->path != NULL && *url->path == '/') - folder_name = url->path + 1; + folder_name = g_strdup (url->path + 1); } } @@ -322,8 +326,10 @@ e_mail_folder_uri_parse (CamelSession *session, if (out_store != NULL) *out_store = g_object_ref (service); - if (out_folder_name != NULL) - *out_folder_name = g_strdup (folder_name); + if (out_folder_name != NULL) { + *out_folder_name = folder_name; + folder_name = NULL; + } success = TRUE; } else { @@ -334,6 +340,8 @@ e_mail_folder_uri_parse (CamelSession *session, folder_uri); } + g_free (folder_name); + camel_url_free (url); return success; -- cgit v1.2.3 From f8122e8f92a58776ca1ddc82a45f73234b7fccd9 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 8 May 2011 22:11:09 -0400 Subject: "email://" URIs have encoded paths too. --- mail/e-mail-folder-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index d73f13ad5c..6332e9c1ae 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -299,7 +299,7 @@ e_mail_folder_uri_parse (CamelSession *session, } if (url->path != NULL && *url->path == '/') - folder_name = g_strdup (url->path + 1); + folder_name = camel_url_decode_path (url->path + 1); /* CamelFolderInfo URIs used to embed the store's URI, so the * folder name is appended as either a path part or a fragment -- cgit v1.2.3 From f9a3112069857536ec14921746f506ffae5bd64d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 11 May 2011 17:38:16 +0200 Subject: Bug #649939 - Cann't create new folder (second shot) The previous patch worked for local account only, for anything which has '@' in account's UID it still failed. --- mail/e-mail-folder-utils.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 6332e9c1ae..f6c295d040 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -248,8 +248,13 @@ e_mail_folder_uri_parse (CamelSession *session, if (g_strcmp0 (url->protocol, "folder") == 0) { if (url->host != NULL) { - gchar *uid = g_strdup (url->host); - camel_url_decode (uid); + gchar *uid; + + if (!url->user || !*url->user) + uid = g_strdup (url->host); + else + uid = g_strconcat (url->user, "@", url->host, NULL); + service = camel_session_get_service (session, uid); g_free (uid); } -- cgit v1.2.3 From ef53113a39de1b26ea93e13cfe473b5846dffdaa Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 10 May 2011 15:08:25 -0400 Subject: Add e_mail_folder_get_multiple_messages(). Replaces mail_get_messages() from mail-ops.c. --- mail/e-mail-folder-utils.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index f6c295d040..742fb06eab 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -29,6 +29,8 @@ typedef struct _AsyncContext AsyncContext; struct _AsyncContext { CamelMimeMessage *message; CamelMessageInfo *info; + GHashTable *hash_table; + GPtrArray *ptr_array; gchar *message_uid; }; @@ -41,6 +43,12 @@ async_context_free (AsyncContext *context) if (context->info != NULL) camel_message_info_free (context->info); + if (context->hash_table != NULL) + g_hash_table_unref (context->hash_table); + + if (context->ptr_array != NULL) + g_ptr_array_unref (context->ptr_array); + g_free (context->message_uid); g_slice_free (AsyncContext, context); @@ -162,6 +170,136 @@ e_mail_folder_append_message_finish (CamelFolder *folder, return !g_simple_async_result_propagate_error (simple, error); } +static void +mail_folder_get_multiple_messages_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + AsyncContext *context; + GError *error = NULL; + + context = g_simple_async_result_get_op_res_gpointer (simple); + + context->hash_table = e_mail_folder_get_multiple_messages_sync ( + CAMEL_FOLDER (object), context->ptr_array, + cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +GHashTable * +e_mail_folder_get_multiple_messages_sync (CamelFolder *folder, + GPtrArray *message_uids, + GCancellable *cancellable, + GError **error) +{ + GHashTable *hash_table; + CamelMimeMessage *message; + guint ii; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); + g_return_val_if_fail (message_uids != NULL, NULL); + + camel_operation_push_message ( + cancellable, + ngettext ( + "Retrieving %d message", + "Retrieving %d messages", + message_uids->len), + message_uids->len); + + hash_table = g_hash_table_new_full ( + (GHashFunc) g_str_hash, + (GEqualFunc) g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + /* This is an all or nothing operation. Destroy the + * hash table if we fail to retrieve any message. */ + + for (ii = 0; ii < message_uids->len; ii++) { + const gchar *uid; + gint percent; + + uid = g_ptr_array_index (message_uids, ii); + percent = ((ii + 1) * 100) / message_uids->len; + + message = camel_folder_get_message_sync ( + folder, uid, cancellable, error); + + camel_operation_progress (cancellable, percent); + + if (CAMEL_IS_MIME_MESSAGE (message)) { + g_hash_table_insert ( + hash_table, g_strdup (uid), message); + } else { + g_hash_table_destroy (hash_table); + hash_table = NULL; + break; + } + } + + camel_operation_pop_message (cancellable); + + return hash_table; +} + +void +e_mail_folder_get_multiple_messages (CamelFolder *folder, + GPtrArray *message_uids, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message_uids != NULL); + + context = g_slice_new0 (AsyncContext); + context->ptr_array = g_ptr_array_ref (message_uids); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, user_data, + e_mail_folder_get_multiple_messages); + + g_simple_async_result_set_op_res_gpointer ( + simple, context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_get_multiple_messages_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +GHashTable * +e_mail_folder_get_multiple_messages_finish (CamelFolder *folder, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_get_multiple_messages), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + context = g_simple_async_result_get_op_res_gpointer (simple); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + return g_hash_table_ref (context->hash_table); +} + /** * e_mail_folder_uri_build: * @store: a #CamelStore -- cgit v1.2.3 From aab2f68defecbc83627eea3a72a3b296057b3e97 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 10 May 2011 16:40:09 -0400 Subject: Add e_mail_folder_find_duplicate_messages(). Moves the non-interactive logic out of EMailReader. --- mail/e-mail-folder-utils.c | 200 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 742fb06eab..7ff54eb7d6 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -170,6 +170,206 @@ e_mail_folder_append_message_finish (CamelFolder *folder, return !g_simple_async_result_propagate_error (simple, error); } +static void +mail_folder_find_duplicate_messages_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + AsyncContext *context; + GError *error = NULL; + + context = g_simple_async_result_get_op_res_gpointer (simple); + + context->hash_table = e_mail_folder_find_duplicate_messages_sync ( + CAMEL_FOLDER (object), context->ptr_array, + cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +GHashTable * +e_mail_folder_find_duplicate_messages_sync (CamelFolder *folder, + GPtrArray *message_uids, + GCancellable *cancellable, + GError **error) +{ + GQueue trash = G_QUEUE_INIT; + GHashTable *hash_table; + GHashTable *unique_ids; + GHashTableIter iter; + gpointer key, value; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); + g_return_val_if_fail (message_uids != NULL, NULL); + + /* hash_table = { MessageUID : CamelMessage } */ + hash_table = e_mail_folder_get_multiple_messages_sync ( + folder, message_uids, cancellable, error); + + if (hash_table == NULL) + return NULL; + + camel_operation_push_message ( + cancellable, _("Scanning messages for duplicates")); + + unique_ids = g_hash_table_new_full ( + (GHashFunc) g_int64_hash, + (GEqualFunc) g_int64_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + + g_hash_table_iter_init (&iter, hash_table); + + while (g_hash_table_iter_next (&iter, &key, &value)) { + const CamelSummaryMessageID *message_id; + CamelDataWrapper *content; + CamelMessageFlags flags; + CamelMessageInfo *info; + CamelStream *stream; + GByteArray *buffer; + gboolean duplicate; + gssize n_bytes; + gchar *digest; + + info = camel_folder_get_message_info (folder, key); + message_id = camel_message_info_message_id (info); + flags = camel_message_info_flags (info); + + /* Skip messages marked for deletion. */ + if (flags & CAMEL_MESSAGE_DELETED) { + g_queue_push_tail (&trash, key); + camel_message_info_free (info); + continue; + } + + /* Generate a digest string from the message's content. */ + + content = camel_medium_get_content (CAMEL_MEDIUM (value)); + + if (content == NULL) { + g_queue_push_tail (&trash, key); + camel_message_info_free (info); + continue; + } + + stream = camel_stream_mem_new (); + + n_bytes = camel_data_wrapper_decode_to_stream_sync ( + content, stream, cancellable, error); + + if (n_bytes < 0) { + camel_message_info_free (info); + g_object_unref (stream); + goto fail; + } + + /* The CamelStreamMem owns the buffer. */ + buffer = camel_stream_mem_get_byte_array ( + CAMEL_STREAM_MEM (stream)); + g_return_val_if_fail (buffer != NULL, NULL); + + digest = g_compute_checksum_for_data ( + G_CHECKSUM_SHA256, buffer->data, buffer->len); + + g_object_unref (stream); + + /* Determine if the message a duplicate. */ + + value = g_hash_table_lookup (unique_ids, &message_id->id.id); + duplicate = (value != NULL) && g_str_equal (digest, value); + + if (duplicate) + g_free (digest); + else { + gint64 *v_int64; + + /* XXX Might be better to create a GArray + * of 64-bit integers and have the hash + * table keys point to array elements. */ + v_int64 = g_new0 (gint64, 1); + *v_int64 = (gint64) message_id->id.id; + + g_hash_table_insert (unique_ids, v_int64, digest); + g_queue_push_tail (&trash, key); + } + + camel_message_info_free (info); + } + + /* Delete all non-duplicate messages from the hash table. */ + while ((key = g_queue_pop_head (&trash)) != NULL) + g_hash_table_remove (hash_table, key); + + goto exit; + +fail: + g_hash_table_destroy (hash_table); + hash_table = NULL; + +exit: + camel_operation_pop_message (cancellable); + + g_hash_table_destroy (unique_ids); + + return hash_table; +} + +void +e_mail_folder_find_duplicate_messages (CamelFolder *folder, + GPtrArray *message_uids, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message_uids != NULL); + + context = g_slice_new0 (AsyncContext); + context->ptr_array = g_ptr_array_ref (message_uids); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, user_data, + e_mail_folder_find_duplicate_messages); + + g_simple_async_result_set_op_res_gpointer ( + simple, context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_find_duplicate_messages_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +GHashTable * +e_mail_folder_find_duplicate_messages_finish (CamelFolder *folder, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_find_duplicate_messages), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + context = g_simple_async_result_get_op_res_gpointer (simple); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + return g_hash_table_ref (context->hash_table); +} + static void mail_folder_get_multiple_messages_thread (GSimpleAsyncResult *simple, GObject *object, -- cgit v1.2.3 From bf44bd68f2564be25896ee29bf405d7e111fe49f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 10 May 2011 20:36:29 -0400 Subject: Add e_mail_folder_build_attachment(). Replaces mail_build_attachment() from mail-ops.c. --- mail/e-mail-folder-utils.c | 168 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 7ff54eb7d6..6f23158ab5 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -21,6 +21,8 @@ #include #include +#include "mail/mail-tools.h" + /* X-Mailer header value */ #define X_MAILER ("Evolution " VERSION SUB_VERSION " " VERSION_COMMENT) @@ -29,8 +31,10 @@ typedef struct _AsyncContext AsyncContext; struct _AsyncContext { CamelMimeMessage *message; CamelMessageInfo *info; + CamelMimePart *part; GHashTable *hash_table; GPtrArray *ptr_array; + gchar *fwd_subject; gchar *message_uid; }; @@ -43,12 +47,16 @@ async_context_free (AsyncContext *context) if (context->info != NULL) camel_message_info_free (context->info); + if (context->part != NULL) + g_object_unref (context->part); + if (context->hash_table != NULL) g_hash_table_unref (context->hash_table); if (context->ptr_array != NULL) g_ptr_array_unref (context->ptr_array); + g_free (context->fwd_subject); g_free (context->message_uid); g_slice_free (AsyncContext, context); @@ -170,6 +178,166 @@ e_mail_folder_append_message_finish (CamelFolder *folder, return !g_simple_async_result_propagate_error (simple, error); } +static void +mail_folder_build_attachment_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + AsyncContext *context; + GError *error = NULL; + + context = g_simple_async_result_get_op_res_gpointer (simple); + + context->part = e_mail_folder_build_attachment_sync ( + CAMEL_FOLDER (object), context->ptr_array, + &context->fwd_subject, cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +CamelMimePart * +e_mail_folder_build_attachment_sync (CamelFolder *folder, + GPtrArray *message_uids, + gchar **fwd_subject, + GCancellable *cancellable, + GError **error) +{ + GHashTable *hash_table; + CamelMimeMessage *message; + CamelMimePart *part; + const gchar *uid; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); + g_return_val_if_fail (message_uids != NULL, NULL); + + /* Need at least one message UID to make an attachment. */ + g_return_val_if_fail (message_uids->len > 0, NULL); + + hash_table = e_mail_folder_get_multiple_messages_sync ( + folder, message_uids, cancellable, error); + + if (hash_table == NULL) + return NULL; + + /* Create the forward subject from the first message. */ + + uid = g_ptr_array_index (message_uids, 0); + g_return_val_if_fail (uid != NULL, NULL); + + message = g_hash_table_lookup (hash_table, uid); + g_return_val_if_fail (message != NULL, NULL); + + if (fwd_subject != NULL) + *fwd_subject = mail_tool_generate_forward_subject (message); + + if (message_uids->len == 1) { + part = mail_tool_make_message_attachment (message); + + } else { + CamelMultipart *multipart; + guint ii; + + multipart = camel_multipart_new (); + camel_data_wrapper_set_mime_type ( + CAMEL_DATA_WRAPPER (multipart), "multipart/digest"); + camel_multipart_set_boundary (multipart, NULL); + + for (ii = 0; ii < message_uids->len; ii++) { + uid = g_ptr_array_index (message_uids, ii); + g_return_val_if_fail (uid != NULL, NULL); + + message = g_hash_table_lookup (hash_table, uid); + g_return_val_if_fail (message != NULL, NULL); + + part = mail_tool_make_message_attachment (message); + camel_multipart_add_part (multipart, part); + g_object_unref (part); + } + + part = camel_mime_part_new (); + + camel_medium_set_content ( + CAMEL_MEDIUM (part), + CAMEL_DATA_WRAPPER (multipart)); + + camel_mime_part_set_description ( + part, _("Forwarded messages")); + + g_object_unref (multipart); + } + + g_hash_table_unref (hash_table); + + return part; +} + +void +e_mail_folder_build_attachment (CamelFolder *folder, + GPtrArray *message_uids, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message_uids != NULL); + + /* Need at least one message UID to make an attachment. */ + g_return_if_fail (message_uids->len > 0); + + context = g_slice_new0 (AsyncContext); + context->ptr_array = g_ptr_array_ref (message_uids); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, user_data, + e_mail_folder_build_attachment); + + g_simple_async_result_set_op_res_gpointer ( + simple, context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_build_attachment_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +CamelMimePart * +e_mail_folder_build_attachment_finish (CamelFolder *folder, + GAsyncResult *result, + gchar **fwd_subject, + GError **error) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_build_attachment), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + context = g_simple_async_result_get_op_res_gpointer (simple); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + if (fwd_subject != NULL) { + *fwd_subject = context->fwd_subject; + context->fwd_subject = NULL; + } + + g_return_val_if_fail (CAMEL_IS_MIME_PART (context->part), NULL); + + return g_object_ref (context->part); +} + static void mail_folder_find_duplicate_messages_thread (GSimpleAsyncResult *simple, GObject *object, -- cgit v1.2.3 From b6324935dbfe1e26ae883955f0939ce734a4d0ae Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 12 May 2011 08:26:58 +0200 Subject: Cannot send message with just enabled account Everything in UI seemed as working fine, but the message is just lost, even there was printed a runtime warning on the console. This is fixing couple things along this issue: - differentiate between NULL and invalid pointers/objects in new e_mail_folder_uri_...() functions - report error to UI if mail_session_send_to_thread() fails to find corresponding transport service - call e_mail_store_add_by_account() in mail_store_load_accounts() (a side-effect of this change is no code duplication and unified processing of the same action) --- mail/e-mail-folder-utils.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 6f23158ab5..905874e6ac 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -686,6 +686,7 @@ e_mail_folder_uri_build (CamelStore *store, gchar *encoded_uid; gchar *uri; + g_return_val_if_fail (store != NULL, NULL); g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); g_return_val_if_fail (folder_name != NULL, NULL); @@ -743,6 +744,7 @@ e_mail_folder_uri_parse (CamelSession *session, gchar *folder_name = NULL; gboolean success = FALSE; + g_return_val_if_fail (session != NULL, FALSE); g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); g_return_val_if_fail (folder_uri != NULL, FALSE); @@ -883,6 +885,7 @@ e_mail_folder_uri_equal (CamelSession *session, gboolean success_b; gboolean equal = FALSE; + g_return_val_if_fail (session != NULL, FALSE); g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); g_return_val_if_fail (folder_uri_a != NULL, FALSE); g_return_val_if_fail (folder_uri_b != NULL, FALSE); @@ -934,6 +937,7 @@ e_mail_folder_uri_from_folder (CamelFolder *folder) CamelStore *store; const gchar *folder_name; + g_return_val_if_fail (folder != NULL, NULL); g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); store = camel_folder_get_parent_store (folder); -- cgit v1.2.3 From b61d2c08d7f16171e3c6a2ddb4759a2a2803aaf3 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 16 May 2011 22:43:46 -0400 Subject: Remove mail_remove_attachments(). Use e_mail_folder_remove_attachments() instead. --- mail/e-mail-folder-utils.c | 216 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 905874e6ac..10546c15d5 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -668,6 +668,222 @@ e_mail_folder_get_multiple_messages_finish (CamelFolder *folder, return g_hash_table_ref (context->hash_table); } +static void +mail_folder_remove_attachments_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + AsyncContext *context; + GError *error = NULL; + + context = g_simple_async_result_get_op_res_gpointer (simple); + + e_mail_folder_remove_attachments_sync ( + CAMEL_FOLDER (object), context->ptr_array, + cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +/* Helper for e_mail_folder_remove_attachments_sync() */ +static gboolean +mail_folder_strip_message (CamelFolder *folder, + CamelMimeMessage *message, + const gchar *message_uid, + GCancellable *cancellable, + GError **error) +{ + CamelDataWrapper *content; + CamelMultipart *multipart; + gboolean modified = FALSE; + gboolean success = TRUE; + guint ii, n_parts; + + content = camel_medium_get_content (CAMEL_MEDIUM (message)); + + if (!CAMEL_IS_MULTIPART (content)) + return TRUE; + + multipart = CAMEL_MULTIPART (content); + n_parts = camel_multipart_get_number (multipart); + + /* Replace MIME parts with "attachment" or "inline" dispositions + * with a small "text/plain" part saying the file was removed. */ + for (ii = 0; ii < n_parts; ii++) { + CamelMimePart *mime_part; + const gchar *disposition; + gboolean is_attachment; + + mime_part = camel_multipart_get_part (multipart, ii); + disposition = camel_mime_part_get_disposition (mime_part); + + is_attachment = + (g_strcmp0 (disposition, "attachment") == 0) || + (g_strcmp0 (disposition, "inline") == 0); + + if (is_attachment) { + const gchar *filename; + const gchar *content_type; + gchar *content; + + disposition = "inline"; + content_type = "text/plain"; + filename = camel_mime_part_get_filename (mime_part); + + if (filename != NULL && *filename != '\0') + content = g_strdup_printf ( + _("File \"%s\" has been removed."), + filename); + else + content = g_strdup ( + _("File has been removed.")); + + camel_mime_part_set_content ( + mime_part, content, + strlen (content), content_type); + camel_mime_part_set_content_type ( + mime_part, content_type); + camel_mime_part_set_disposition ( + mime_part, disposition); + + modified = TRUE; + } + } + + /* Append the modified message with removed attachments to + * the folder and mark the original message for deletion. */ + if (modified) { + CamelMessageInfo *orig_info; + CamelMessageInfo *copy_info; + CamelMessageFlags flags; + + orig_info = + camel_folder_get_message_info (folder, message_uid); + copy_info = + camel_message_info_new_from_header ( + NULL, CAMEL_MIME_PART (message)->headers); + + flags = camel_folder_get_message_flags (folder, message_uid); + camel_message_info_set_flags (copy_info, flags, flags); + + success = camel_folder_append_message_sync ( + folder, message, copy_info, NULL, cancellable, error); + if (success) + camel_message_info_set_flags ( + orig_info, + CAMEL_MESSAGE_DELETED, + CAMEL_MESSAGE_DELETED); + + camel_folder_free_message_info (folder, orig_info); + camel_message_info_free (copy_info); + } + + return success; +} + +gboolean +e_mail_folder_remove_attachments_sync (CamelFolder *folder, + GPtrArray *message_uids, + GCancellable *cancellable, + GError **error) +{ + gboolean success = TRUE; + guint ii; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); + g_return_val_if_fail (message_uids != NULL, FALSE); + + camel_folder_freeze (folder); + + camel_operation_push_message (cancellable, _("Removing attachments")); + + for (ii = 0; success && ii < message_uids->len; ii++) { + CamelMimeMessage *message; + const gchar *uid; + gint percent; + + uid = g_ptr_array_index (message_uids, ii); + + message = camel_folder_get_message_sync ( + folder, uid, cancellable, error); + + if (message == NULL) { + success = FALSE; + break; + } + + success = mail_folder_strip_message ( + folder, message, uid, cancellable, error); + + percent = ((ii + 1) * 100) / message_uids->len; + camel_operation_progress (cancellable, percent); + + g_object_unref (message); + } + + camel_operation_pop_message (cancellable); + + if (success) + camel_folder_synchronize_sync ( + folder, FALSE, cancellable, error); + + camel_folder_thaw (folder); + + return success; +} + +void +e_mail_folder_remove_attachments (CamelFolder *folder, + GPtrArray *message_uids, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message_uids != NULL); + + context = g_slice_new0 (AsyncContext); + context->ptr_array = g_ptr_array_ref (message_uids); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, user_data, + e_mail_folder_remove_attachments); + + g_simple_async_result_set_op_res_gpointer ( + simple, context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_remove_attachments_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +gboolean +e_mail_folder_remove_attachments_finish (CamelFolder *folder, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_remove_attachments), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); +} + /** * e_mail_folder_uri_build: * @store: a #CamelStore -- cgit v1.2.3 From f0a011f941bab3f6ac7228be4e1bec86a0de0d2a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 17 May 2011 19:50:33 -0400 Subject: Remove mail_save_messages(). Use e_mail_folder_save_messages() instead. --- mail/e-mail-folder-utils.c | 242 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 10546c15d5..f244260bf5 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -34,6 +34,7 @@ struct _AsyncContext { CamelMimePart *part; GHashTable *hash_table; GPtrArray *ptr_array; + GFile *destination; gchar *fwd_subject; gchar *message_uid; }; @@ -56,6 +57,9 @@ async_context_free (AsyncContext *context) if (context->ptr_array != NULL) g_ptr_array_unref (context->ptr_array); + if (context->destination != NULL) + g_object_unref (context->destination); + g_free (context->fwd_subject); g_free (context->message_uid); @@ -884,6 +888,244 @@ e_mail_folder_remove_attachments_finish (CamelFolder *folder, return !g_simple_async_result_propagate_error (simple, error); } +static void +mail_folder_save_messages_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + AsyncContext *context; + GError *error = NULL; + + context = g_simple_async_result_get_op_res_gpointer (simple); + + e_mail_folder_save_messages_sync ( + CAMEL_FOLDER (object), context->ptr_array, + context->destination, cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +/* Helper for e_mail_folder_save_messages_sync() */ +static void +mail_folder_save_prepare_part (CamelMimePart *mime_part) +{ + CamelDataWrapper *content; + + content = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); + + if (content == NULL) + return; + + if (CAMEL_IS_MULTIPART (content)) { + guint n_parts, ii; + + n_parts = camel_multipart_get_number ( + CAMEL_MULTIPART (content)); + for (ii = 0; ii < n_parts; ii++) { + mime_part = camel_multipart_get_part ( + CAMEL_MULTIPART (content), ii); + mail_folder_save_prepare_part (mime_part); + } + + } else if (CAMEL_IS_MIME_MESSAGE (content)) { + mail_folder_save_prepare_part (CAMEL_MIME_PART (content)); + + } else { + CamelContentType *type; + + /* Save textual parts as 8-bit, not encoded. */ + type = camel_data_wrapper_get_mime_type_field (content); + if (camel_content_type_is (type, "text", "*")) + camel_mime_part_set_encoding ( + mime_part, CAMEL_TRANSFER_ENCODING_8BIT); + } +} + +gboolean +e_mail_folder_save_messages_sync (CamelFolder *folder, + GPtrArray *message_uids, + GFile *destination, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStream *file_output_stream; + GByteArray *byte_array; + CamelMimeFilter *filter; + CamelStream *base_stream; + CamelStream *stream; + gboolean success = TRUE; + guint ii; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); + g_return_val_if_fail (message_uids != NULL, FALSE); + g_return_val_if_fail (G_IS_FILE (destination), FALSE); + + /* Need at least one message UID to save. */ + g_return_val_if_fail (message_uids->len > 0, FALSE); + + camel_operation_push_message ( + cancellable, ngettext ( + "Saving %d message", + "Saving %d messages", + message_uids->len), + message_uids->len); + + file_output_stream = g_file_replace ( + destination, NULL, FALSE, + G_FILE_CREATE_PRIVATE | + G_FILE_CREATE_REPLACE_DESTINATION, + cancellable, error); + + if (file_output_stream == NULL) { + camel_operation_pop_message (cancellable); + return FALSE; + } + + /* CamelStreamMem takes ownership of the GByteArray. */ + byte_array = g_byte_array_new (); + filter = camel_mime_filter_from_new (); + base_stream = camel_stream_mem_new_with_byte_array (byte_array); + stream = camel_stream_filter_new (base_stream); + camel_stream_filter_add (CAMEL_STREAM_FILTER (stream), filter); + g_object_unref (base_stream); + g_object_unref (filter); + + for (ii = 0; ii < message_uids->len; ii++) { + CamelMimeMessage *message; + const gchar *uid; + gchar *from_line; + gint percent; + gint retval; + + uid = g_ptr_array_index (message_uids, ii); + + message = camel_folder_get_message_sync ( + folder, uid, cancellable, error); + if (message == NULL) { + success = FALSE; + goto exit; + } + + mail_folder_save_prepare_part (CAMEL_MIME_PART (message)); + + from_line = camel_mime_message_build_mbox_from (message); + g_return_val_if_fail (from_line != NULL, FALSE); + + success = g_output_stream_write_all ( + G_OUTPUT_STREAM (file_output_stream), + from_line, strlen (from_line), NULL, + cancellable, error); + + g_free (from_line); + + if (!success) { + g_object_unref (message); + goto exit; + } + + retval = camel_data_wrapper_write_to_stream_sync ( + CAMEL_DATA_WRAPPER (message), + stream, cancellable, error); + + if (retval == -1) { + g_object_unref (message); + goto exit; + } + + g_byte_array_append (byte_array, (guint8 *) "\n", 1); + + success = g_output_stream_write_all ( + G_OUTPUT_STREAM (file_output_stream), + byte_array->data, byte_array->len, + NULL, cancellable, error); + + if (!success) { + g_object_unref (message); + goto exit; + } + + percent = ((ii + 1) * 100) / message_uids->len; + camel_operation_progress (cancellable, percent); + + /* Flush the buffer for the next message. + * For memory streams this never fails. */ + camel_stream_reset (stream, NULL); + + g_object_unref (message); + } + +exit: + g_object_unref (file_output_stream); + g_object_unref (stream); + + camel_operation_pop_message (cancellable); + + if (!success) { + /* Try deleting the destination file. */ + g_file_delete (destination, NULL, NULL); + } + + return success; +} + +void +e_mail_folder_save_messages (CamelFolder *folder, + GPtrArray *message_uids, + GFile *destination, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message_uids != NULL); + g_return_if_fail (G_IS_FILE (destination)); + + /* Need at least one message UID to save. */ + g_return_if_fail (message_uids->len > 0); + + context = g_slice_new0 (AsyncContext); + context->ptr_array = g_ptr_array_ref (message_uids); + context->destination = g_object_ref (destination); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, user_data, + e_mail_folder_save_messages); + + g_simple_async_result_set_op_res_gpointer ( + simple, context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_save_messages_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +gboolean +e_mail_folder_save_messages_finish (CamelFolder *folder, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_save_messages), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); +} + /** * e_mail_folder_uri_build: * @store: a #CamelStore -- cgit v1.2.3 From 86c9c4d793b3f9eff93fe00ad579427f254c5882 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 19 May 2011 14:56:17 -0400 Subject: Remove mail_remove_folder(). Use e_mail_folder_remove() instead. --- mail/e-mail-folder-utils.c | 203 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index f244260bf5..e0b4471041 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -672,6 +672,209 @@ e_mail_folder_get_multiple_messages_finish (CamelFolder *folder, return g_hash_table_ref (context->hash_table); } +static void +mail_folder_remove_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + GError *error = NULL; + + e_mail_folder_remove_sync ( + CAMEL_FOLDER (object), cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +static gboolean +mail_folder_remove_recursive (CamelStore *store, + CamelFolderInfo *folder_info, + GCancellable *cancellable, + GError **error) +{ + gboolean success = TRUE; + + while (folder_info != NULL) { + CamelFolder *folder; + + if (folder_info->child != NULL) { + success = mail_folder_remove_recursive ( + store, folder_info->child, cancellable, error); + if (!success) + break; + } + + folder = camel_store_get_folder_sync ( + store, folder_info->full_name, 0, cancellable, error); + if (folder == NULL) { + success = FALSE; + break; + } + + if (!CAMEL_IS_VEE_FOLDER (folder)) { + GPtrArray *uids; + guint ii; + + /* Delete every message in this folder, + * then expunge it. */ + + camel_folder_freeze (folder); + + uids = camel_folder_get_uids (folder); + + for (ii = 0; ii < uids->len; ii++) + camel_folder_delete_message ( + folder, uids->pdata[ii]); + + camel_folder_free_uids (folder, uids); + + success = camel_folder_synchronize_sync ( + folder, TRUE, cancellable, error); + + camel_folder_thaw (folder); + } + + g_object_unref (folder); + + if (!success) + break; + + /* If the store supports subscriptions, + * then unsubscribe from this folder. */ + if (camel_store_supports_subscriptions (store)) { + success = camel_store_unsubscribe_folder_sync ( + store, folder_info->full_name, + cancellable, error); + if (!success) + break; + } + + success = camel_store_delete_folder_sync ( + store, folder_info->full_name, cancellable, error); + if (!success) + break; + + folder_info = folder_info->next; + } + + return success; +} + +gboolean +e_mail_folder_remove_sync (CamelFolder *folder, + GCancellable *cancellable, + GError **error) +{ + CamelFolderInfo *folder_info; + CamelFolderInfo *to_remove; + CamelFolderInfo *next = NULL; + CamelStore *parent_store; + const gchar *full_name; + gboolean success = TRUE; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); + + full_name = camel_folder_get_full_name (folder); + parent_store = camel_folder_get_parent_store (folder); + + folder_info = camel_store_get_folder_info_sync ( + parent_store, full_name, + CAMEL_STORE_FOLDER_INFO_FAST | + CAMEL_STORE_FOLDER_INFO_RECURSIVE | + CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, + cancellable, error); + + if (folder_info == NULL) + return FALSE; + + to_remove = folder_info; + + /* For cases when the top-level folder_info contains siblings, + * such as when full_name contains a wildcard letter, compare + * the folder name against folder_info->full_name to avoid + * removing more folders than requested. */ + if (folder_info->next != NULL) { + while (to_remove != NULL) { + if (g_strcmp0 (to_remove->full_name, full_name) == 0) + break; + to_remove = to_remove->next; + } + + /* XXX Should we set a GError and return FALSE here? */ + if (to_remove == NULL) { + g_warning ( + "%s: Failed to find folder '%s'", + G_STRFUNC, full_name); + camel_store_free_folder_info ( + parent_store, folder_info); + return TRUE; + } + + /* Prevent iterating over siblings. */ + next = to_remove->next; + to_remove->next = NULL; + } + + camel_operation_push_message ( + cancellable, _("Removing folder '%s'"), + camel_folder_get_full_name (folder)); + + success = mail_folder_remove_recursive ( + parent_store, to_remove, cancellable, error); + + camel_operation_pop_message (cancellable); + + /* Restore the folder_info tree to its original + * state so we don't leak folder_info nodes. */ + to_remove->next = next; + + camel_store_free_folder_info (parent_store, folder_info); + + return success; +} + +void +e_mail_folder_remove (CamelFolder *folder, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, + user_data, e_mail_folder_remove); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_remove_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +gboolean +e_mail_folder_remove_finish (CamelFolder *folder, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_remove), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); +} + static void mail_folder_remove_attachments_thread (GSimpleAsyncResult *simple, GObject *object, -- cgit v1.2.3 From cb97c2dc8fd97b381af048f206333d5e557892ae Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 21 May 2011 10:02:58 -0400 Subject: Coding style and whitespace cleanup. --- mail/e-mail-folder-utils.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index e0b4471041..f621d7464d 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -1419,10 +1419,11 @@ e_mail_folder_uri_parse (CamelSession *session, if (url->host != NULL) { gchar *uid; - if (!url->user || !*url->user) + if (url->user == NULL || *url->user == '\0') uid = g_strdup (url->host); else - uid = g_strconcat (url->user, "@", url->host, NULL); + uid = g_strconcat ( + url->user, "@", url->host, NULL); service = camel_session_get_service (session, uid); g_free (uid); -- cgit v1.2.3 From 756c8abcb840b8da588031f4a0d7e1fc979fab70 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 27 May 2011 15:23:07 +0200 Subject: Bug #646109 - Fix use of include to make sure translations work --- mail/e-mail-folder-utils.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index f621d7464d..659d51e02e 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -16,9 +16,12 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "e-mail-folder-utils.h" -#include #include #include "mail/mail-tools.h" -- cgit v1.2.3 From 15e3850a5b8af68b3343578607b067b449c0a8cc Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 1 Jun 2011 06:22:35 -0400 Subject: e-mail-folder-utils.c cleanups. --- mail/e-mail-folder-utils.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 659d51e02e..f255c730b6 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -1350,7 +1350,6 @@ e_mail_folder_uri_build (CamelStore *store, gchar *encoded_uid; gchar *uri; - g_return_val_if_fail (store != NULL, NULL); g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); g_return_val_if_fail (folder_name != NULL, NULL); @@ -1408,7 +1407,6 @@ e_mail_folder_uri_parse (CamelSession *session, gchar *folder_name = NULL; gboolean success = FALSE; - g_return_val_if_fail (session != NULL, FALSE); g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); g_return_val_if_fail (folder_uri != NULL, FALSE); @@ -1550,7 +1548,6 @@ e_mail_folder_uri_equal (CamelSession *session, gboolean success_b; gboolean equal = FALSE; - g_return_val_if_fail (session != NULL, FALSE); g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); g_return_val_if_fail (folder_uri_a != NULL, FALSE); g_return_val_if_fail (folder_uri_b != NULL, FALSE); @@ -1602,7 +1599,6 @@ e_mail_folder_uri_from_folder (CamelFolder *folder) CamelStore *store; const gchar *folder_name; - g_return_val_if_fail (folder != NULL, NULL); g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); store = camel_folder_get_parent_store (folder); -- cgit v1.2.3 From 17127fbee9fd1b0baecb4e305c005d6abbf8d880 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 5 Jul 2011 08:16:13 -0400 Subject: Prefer g_seekable_seek() over camel_stream_reset(). When a stream is obviously a file or memory stream (both of which implement the GSeekable interface), use g_seekable_seek() instead of camel_stream_reset(). This is helping me discover if it's safe to remove camel_stream_reset(). We want to eventually move to GIO streams, which have no reset method. --- mail/e-mail-folder-utils.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index f255c730b6..64bdbdb821 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -1159,9 +1159,7 @@ e_mail_folder_save_messages_sync (CamelFolder *folder, { GFileOutputStream *file_output_stream; GByteArray *byte_array; - CamelMimeFilter *filter; CamelStream *base_stream; - CamelStream *stream; gboolean success = TRUE; guint ii; @@ -1192,15 +1190,12 @@ e_mail_folder_save_messages_sync (CamelFolder *folder, /* CamelStreamMem takes ownership of the GByteArray. */ byte_array = g_byte_array_new (); - filter = camel_mime_filter_from_new (); base_stream = camel_stream_mem_new_with_byte_array (byte_array); - stream = camel_stream_filter_new (base_stream); - camel_stream_filter_add (CAMEL_STREAM_FILTER (stream), filter); - g_object_unref (base_stream); - g_object_unref (filter); for (ii = 0; ii < message_uids->len; ii++) { CamelMimeMessage *message; + CamelMimeFilter *filter; + CamelStream *stream; const gchar *uid; gchar *from_line; gint percent; @@ -1232,10 +1227,17 @@ e_mail_folder_save_messages_sync (CamelFolder *folder, goto exit; } + filter = camel_mime_filter_from_new (); + stream = camel_stream_filter_new (base_stream); + camel_stream_filter_add (CAMEL_STREAM_FILTER (stream), filter); + retval = camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (message), stream, cancellable, error); + g_object_unref (filter); + g_object_unref (stream); + if (retval == -1) { g_object_unref (message); goto exit; @@ -1258,14 +1260,16 @@ e_mail_folder_save_messages_sync (CamelFolder *folder, /* Flush the buffer for the next message. * For memory streams this never fails. */ - camel_stream_reset (stream, NULL); + g_seekable_seek ( + G_SEEKABLE (base_stream), + 0, G_SEEK_SET, NULL, NULL); g_object_unref (message); } exit: g_object_unref (file_output_stream); - g_object_unref (stream); + g_object_unref (base_stream); camel_operation_pop_message (cancellable); -- cgit v1.2.3 From 80f4a16462a23e45a173dd1fa1ea6f9332fa9405 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 15 Aug 2011 17:32:20 +0200 Subject: Bug #655942 - Shows 'Storing folder...' when deleting a local folder --- mail/e-mail-folder-utils.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 64bdbdb821..d7d4808058 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -765,6 +765,12 @@ mail_folder_remove_recursive (CamelStore *store, return success; } +static void +follow_cancel_cb (GCancellable *cancellable, GCancellable *transparent_cancellable) +{ + g_cancellable_cancel (transparent_cancellable); +} + gboolean e_mail_folder_remove_sync (CamelFolder *folder, GCancellable *cancellable, @@ -776,6 +782,8 @@ e_mail_folder_remove_sync (CamelFolder *folder, CamelStore *parent_store; const gchar *full_name; gboolean success = TRUE; + GCancellable *transparent_cancellable = NULL; + gulong cbid = 0; g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); @@ -824,8 +832,18 @@ e_mail_folder_remove_sync (CamelFolder *folder, cancellable, _("Removing folder '%s'"), camel_folder_get_full_name (folder)); + if (cancellable) { + transparent_cancellable = g_cancellable_new (); + cbid = g_cancellable_connect (cancellable, G_CALLBACK (follow_cancel_cb), transparent_cancellable, NULL); + } + success = mail_folder_remove_recursive ( - parent_store, to_remove, cancellable, error); + parent_store, to_remove, transparent_cancellable, error); + + if (transparent_cancellable) { + g_cancellable_disconnect (cancellable, cbid); + g_object_unref (transparent_cancellable); + } camel_operation_pop_message (cancellable); -- cgit v1.2.3 From f3648e1cb5f1a2537b557bce2ff9b0bc4f17c751 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 15 Aug 2011 17:36:43 -0400 Subject: Adapt to new CamelSubscribable interface. --- mail/e-mail-folder-utils.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index d7d4808058..72afb08c6f 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -746,9 +746,10 @@ mail_folder_remove_recursive (CamelStore *store, /* If the store supports subscriptions, * then unsubscribe from this folder. */ - if (camel_store_supports_subscriptions (store)) { - success = camel_store_unsubscribe_folder_sync ( - store, folder_info->full_name, + if (CAMEL_IS_SUBSCRIBABLE (store)) { + success = camel_subscribable_unsubscribe_folder_sync ( + CAMEL_SUBSCRIBABLE (store), + folder_info->full_name, cancellable, error); if (!success) break; -- cgit v1.2.3 From fcbbdfbd18e15b4ee8322a0217cf03a689a5e033 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 16 Aug 2011 11:25:56 -0400 Subject: Coding style and whitespace cleanup. --- mail/e-mail-folder-utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 72afb08c6f..7c84957f6a 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -767,7 +767,8 @@ mail_folder_remove_recursive (CamelStore *store, } static void -follow_cancel_cb (GCancellable *cancellable, GCancellable *transparent_cancellable) +follow_cancel_cb (GCancellable *cancellable, + GCancellable *transparent_cancellable) { g_cancellable_cancel (transparent_cancellable); } -- cgit v1.2.3 From 807184393ae4d9bd271797d74775939dd353dbd3 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 27 Sep 2011 18:00:33 -0400 Subject: Bug 659726 - Search Folders contain ambiguous reference to accounts This introduces a new function called e_mail_folder_uri_to_markup(), which may prove useful in other contexts. --- mail/e-mail-folder-utils.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 7c84957f6a..77a9708e5f 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -1630,3 +1630,51 @@ e_mail_folder_uri_from_folder (CamelFolder *folder) return e_mail_folder_uri_build (store, folder_name); } + +/** + * e_mail_folder_uri_to_markup: + * @session: a #CamelSession + * @folder_uri: a folder URI + * @error: return location for a #GError, or %NULL + * + * Converts @folder_uri to a markup string suitable for displaying to users. + * The string consists of the #CamelStore display name (in bold), followed + * by the folder path. If the URI is malformed or no corresponding store + * exists, the function sets @error and returns %NULL. Free the returned + * string with g_free(). + * + * Returns: a newly-allocated markup string, or %NULL + **/ +gchar * +e_mail_folder_uri_to_markup (CamelSession *session, + const gchar *folder_uri, + GError **error) +{ + CamelStore *store = NULL; + const gchar *display_name; + gchar *folder_name = NULL; + gchar *markup; + gboolean success; + + g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); + g_return_val_if_fail (folder_uri != NULL, NULL); + + success = e_mail_folder_uri_parse ( + session, folder_uri, &store, &folder_name, error); + + if (!success) + return NULL; + + g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); + g_return_val_if_fail (folder_name != NULL, NULL); + + display_name = camel_service_get_display_name (CAMEL_SERVICE (store)); + + markup = g_markup_printf_escaped ( + "%s : %s", display_name, folder_name); + + g_object_unref (store); + g_free (folder_name); + + return markup; +} -- cgit v1.2.3