aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-05-17 10:43:46 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-05-17 10:43:46 +0800
commitb61d2c08d7f16171e3c6a2ddb4759a2a2803aaf3 (patch)
tree2d523fb23c6f77f47f430ad9bc2af9e7f9dd9aa5 /mail
parent41337195f36e4795d7976df4e07a11ff336cd89c (diff)
downloadgsoc2013-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.c216
-rw-r--r--mail/e-mail-folder-utils.h17
-rw-r--r--mail/e-mail-reader-utils.c63
-rw-r--r--mail/e-mail-reader-utils.h2
-rw-r--r--mail/e-mail-reader.c17
-rw-r--r--mail/mail-ops.c138
-rw-r--r--mail/mail.error.xml5
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 &quot;{0}&quot;.</_secondary>
</error>
+ <error id="remove-attachments" type="error">
+ <_primary>Failed to remove attachments from messages.</_primary>
+ <_secondary>The reported error was &quot;{0}&quot;.</_secondary>
+ </error>
+
</error-list>