diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2011-05-17 10:43:46 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2011-05-17 10:43:46 +0800 |
commit | b61d2c08d7f16171e3c6a2ddb4759a2a2803aaf3 (patch) | |
tree | 2d523fb23c6f77f47f430ad9bc2af9e7f9dd9aa5 /mail | |
parent | 41337195f36e4795d7976df4e07a11ff336cd89c (diff) | |
download | gsoc2013-evolution-b61d2c08d7f16171e3c6a2ddb4759a2a2803aaf3.tar.gz gsoc2013-evolution-b61d2c08d7f16171e3c6a2ddb4759a2a2803aaf3.tar.zst gsoc2013-evolution-b61d2c08d7f16171e3c6a2ddb4759a2a2803aaf3.zip |
Remove mail_remove_attachments().
Use e_mail_folder_remove_attachments() instead.
Diffstat (limited to 'mail')
-rw-r--r-- | mail/e-mail-folder-utils.c | 216 | ||||
-rw-r--r-- | mail/e-mail-folder-utils.h | 17 | ||||
-rw-r--r-- | mail/e-mail-reader-utils.c | 63 | ||||
-rw-r--r-- | mail/e-mail-reader-utils.h | 2 | ||||
-rw-r--r-- | mail/e-mail-reader.c | 17 | ||||
-rw-r--r-- | mail/mail-ops.c | 138 | ||||
-rw-r--r-- | mail/mail.error.xml | 5 |
7 files changed, 309 insertions, 149 deletions
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 diff --git a/mail/e-mail-folder-utils.h b/mail/e-mail-folder-utils.h index 12fe1c8502..f526c3273b 100644 --- a/mail/e-mail-folder-utils.h +++ b/mail/e-mail-folder-utils.h @@ -97,6 +97,23 @@ GHashTable * e_mail_folder_get_multiple_messages_finish GAsyncResult *result, GError **error); +gboolean e_mail_folder_remove_attachments_sync + (CamelFolder *folder, + GPtrArray *message_uids, + GCancellable *cancellable, + GError **error); +void e_mail_folder_remove_attachments + (CamelFolder *folder, + GPtrArray *message_uids, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean e_mail_folder_remove_attachments_finish + (CamelFolder *folder, + GAsyncResult *result, + GError **error); + gchar * e_mail_folder_uri_build (CamelStore *store, const gchar *folder_name); gboolean e_mail_folder_uri_parse (CamelSession *session, diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c index 6df8ebe71d..281acbbe52 100644 --- a/mail/e-mail-reader-utils.c +++ b/mail/e-mail-reader-utils.c @@ -422,6 +422,69 @@ e_mail_reader_print (EMailReader *reader, } static void +mail_reader_remove_attachments_cb (CamelFolder *folder, + GAsyncResult *result, + AsyncContext *context) +{ + EAlertSink *alert_sink; + GError *error = NULL; + + alert_sink = e_mail_reader_get_alert_sink (context->reader); + + e_mail_folder_remove_attachments_finish (folder, result, &error); + + if (e_activity_handle_cancellation (context->activity, error)) { + g_error_free (error); + + } else if (error != NULL) { + e_alert_submit ( + alert_sink, + "mail:remove-attachments", + error->message, NULL); + g_error_free (error); + } + + async_context_free (context); +} + +void +e_mail_reader_remove_attachments (EMailReader *reader) +{ + EActivity *activity; + AsyncContext *context; + GCancellable *cancellable; + CamelFolder *folder; + GPtrArray *uids; + + g_return_if_fail (E_IS_MAIL_READER (reader)); + + folder = e_mail_reader_get_folder (reader); + uids = e_mail_reader_get_selected_uids (reader); + g_return_if_fail (uids != NULL); + + /* XXX Either e_mail_reader_get_selected_uids() + * or MessageList should do this itself. */ + g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free); + + /* Remove attachments asynchronously. */ + + activity = e_mail_reader_new_activity (reader); + cancellable = e_activity_get_cancellable (activity); + + context = g_slice_new0 (AsyncContext); + context->activity = activity; + context->reader = g_object_ref (reader); + + e_mail_folder_remove_attachments ( + folder, uids, G_PRIORITY_DEFAULT, + cancellable, (GAsyncReadyCallback) + mail_reader_remove_attachments_cb, + context); + + g_ptr_array_unref (uids); +} + +static void mail_reader_remove_duplicates_cb (CamelFolder *folder, GAsyncResult *result, AsyncContext *context) diff --git a/mail/e-mail-reader-utils.h b/mail/e-mail-reader-utils.h index f06d4db2d4..b574f03bfe 100644 --- a/mail/e-mail-reader-utils.h +++ b/mail/e-mail-reader-utils.h @@ -47,6 +47,8 @@ guint e_mail_reader_mark_selected (EMailReader *reader, guint e_mail_reader_open_selected (EMailReader *reader); void e_mail_reader_print (EMailReader *reader, GtkPrintOperationAction action); +void e_mail_reader_remove_attachments + (EMailReader *reader); void e_mail_reader_remove_duplicates (EMailReader *reader); void e_mail_reader_reply_to_message (EMailReader *reader, CamelMimeMessage *message, diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index ee0579f5c8..0a6cb06848 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -400,20 +400,15 @@ action_mail_filters_apply_cb (GtkAction *action, } static void -action_mail_remove_attachments_cb (GtkAction *action, EMailReader *reader) +action_mail_remove_attachments_cb (GtkAction *action, + EMailReader *reader) { - CamelFolder *folder; - GPtrArray *uids; - - folder = e_mail_reader_get_folder (reader); - uids = e_mail_reader_get_selected_uids (reader); - - mail_remove_attachments (folder, uids); + e_mail_reader_remove_attachments (reader); } static void -action_mail_remove_duplicates (GtkAction *action, - EMailReader *reader) +action_mail_remove_duplicates_cb (GtkAction *action, + EMailReader *reader) { e_mail_reader_remove_duplicates (reader); } @@ -2146,7 +2141,7 @@ static GtkActionEntry mail_reader_entries[] = { N_("Remove Du_plicate Messages"), NULL, N_("Checks selected messages for duplicates"), - G_CALLBACK (action_mail_remove_duplicates) }, + G_CALLBACK (action_mail_remove_duplicates_cb) }, { "mail-reply-all", NULL, diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 1c8b900a87..9f3d2dad28 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -2123,141 +2123,3 @@ mail_disconnect_store (CamelStore *store) return id; } -/* ---------------------------------------------------------------------------------- */ - -struct _remove_attachments_msg { - MailMsg base; - - CamelFolder *folder; - GPtrArray *uids; -}; - -static gchar * -remove_attachments_desc (struct _remove_attachments_msg *m) -{ - return g_strdup_printf (_("Removing attachments")); -} - -static void -remove_attachments_exec (struct _remove_attachments_msg *m, - GCancellable *cancellable, - GError **error) -{ - CamelFolder *folder = m->folder; - GPtrArray *uids = m->uids; - gint ii, jj; - - camel_folder_freeze (folder); - for (ii = 0; ii < (uids ? uids->len : 0); ii++) { - gint pc = ((ii + 1) * 100) / uids->len; - CamelMimeMessage *message; - CamelDataWrapper *containee; - gchar *uid; - - uid = g_ptr_array_index (uids, ii); - - /* retrieve the message from the CamelFolder */ - message = camel_folder_get_message_sync (folder, uid, cancellable, NULL); - if (!message) { - camel_operation_progress (cancellable, pc); - continue; - } - - containee = camel_medium_get_content (CAMEL_MEDIUM (message)); - if (containee == NULL) { - camel_operation_progress (cancellable, pc); - continue; - } - - if (CAMEL_IS_MULTIPART (containee)) { - gboolean deleted = FALSE; - gint parts; - - parts = camel_multipart_get_number (CAMEL_MULTIPART (containee)); - for (jj = 0; jj < parts; jj++) { - CamelMimePart *mpart = camel_multipart_get_part (CAMEL_MULTIPART (containee), jj); - const gchar *disposition = camel_mime_part_get_disposition (mpart); - if (disposition && (!strcmp (disposition, "attachment") || !strcmp (disposition, "inline"))) { - gchar *desc; - const gchar *filename; - - filename = camel_mime_part_get_filename (mpart); - desc = g_strdup_printf (_("File \"%s\" has been removed."), filename ? filename : ""); - camel_mime_part_set_disposition (mpart, "inline"); - camel_mime_part_set_content (mpart, desc, strlen (desc), "text/plain"); - camel_mime_part_set_content_type (mpart, "text/plain"); - deleted = TRUE; - } - } - - if (deleted) { - /* copy the original message with the deleted attachment */ - CamelMessageInfo *info, *newinfo; - guint32 flags; - GError *local_error = NULL; - - info = camel_folder_get_message_info (folder, uid); - newinfo = camel_message_info_new_from_header (NULL, CAMEL_MIME_PART (message)->headers); - flags = camel_folder_get_message_flags (folder, uid); - - /* make a copy of the message */ - camel_message_info_set_flags (newinfo, flags, flags); - camel_folder_append_message_sync (folder, message, newinfo, NULL, cancellable, &local_error); - - if (!local_error) { - /* marked the original message deleted */ - camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); - } - - camel_folder_free_message_info (folder, info); - camel_message_info_free (newinfo); - - if (local_error) { - g_propagate_error (error, local_error); - break; - } - } - } - - camel_operation_progress (cancellable, pc); - } - - if (!error || !*error) - camel_folder_synchronize_sync (folder, FALSE, cancellable, error); - camel_folder_thaw (folder); -} - -static void -remove_attachments_free (struct _remove_attachments_msg *m) -{ - g_object_unref (m->folder); - em_utils_uids_free (m->uids); -} - -static MailMsgInfo remove_attachments_info = { - sizeof (struct _remove_attachments_msg), - (MailMsgDescFunc) remove_attachments_desc, - (MailMsgExecFunc) remove_attachments_exec, - (MailMsgDoneFunc) NULL, - (MailMsgFreeFunc) remove_attachments_free -}; - -/* it takes ownership of 'uids' array */ -gint -mail_remove_attachments (CamelFolder *folder, GPtrArray *uids) -{ - struct _remove_attachments_msg *m; - gint id; - - g_return_val_if_fail (folder != NULL, -1); - g_return_val_if_fail (uids != NULL, -1); - - m = mail_msg_new (&remove_attachments_info); - m->folder = g_object_ref (folder); - m->uids = uids; - - id = m->base.seq; - mail_msg_unordered_push (m); - - return id; -} diff --git a/mail/mail.error.xml b/mail/mail.error.xml index 292c36c4b0..8eab30e396 100644 --- a/mail/mail.error.xml +++ b/mail/mail.error.xml @@ -520,5 +520,10 @@ An mbox account will be created to preserve the old mbox folders. You can delete <_secondary>The reported error was "{0}".</_secondary> </error> + <error id="remove-attachments" type="error"> + <_primary>Failed to remove attachments from messages.</_primary> + <_secondary>The reported error was "{0}".</_secondary> + </error> + </error-list> |