[evolution/wip/gsettings] Remove mail_remove_attachments().



commit b5cadb77f188e2f426550ea7d5623420865636d2
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon May 16 22:43:46 2011 -0400

    Remove mail_remove_attachments().
    
    Use e_mail_folder_remove_attachments() instead.

 mail/e-mail-folder-utils.c |  216 ++++++++++++++++++++++++++++++++++++++++++++
 mail/e-mail-folder-utils.h |   17 ++++
 mail/e-mail-reader-utils.c |   63 +++++++++++++
 mail/e-mail-reader-utils.h |    2 +
 mail/e-mail-reader.c       |   17 ++---
 mail/mail-ops.c            |  138 ----------------------------
 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 905874e..10546c1 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 12fe1c8..f526c32 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 6df8ebe..281acbb 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 f06d4db..b574f03 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 ee0579f..0a6cb06 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 1c8b900..9f3d2da 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 292c36c..8eab30e 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>
 



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