[evolution/webkit: 20/113] Fix handling of attachments and multipart/digest messages



commit 5376eccc0ba90a077fbff07355b4a22ad91a4b02
Author: Dan VrÃtil <dvratil redhat com>
Date:   Wed Sep 14 10:32:46 2011 +0200

    Fix handling of attachments and multipart/digest messages

 em-format/em-format.c         |  234 +++++++++++++++++++---------------
 em-format/em-format.h         |    6 +-
 mail/e-mail-request.c         |   58 +++++----
 mail/em-format-html-display.c |  275 ++++++++++++++---------------------------
 mail/em-format-html-display.h |    5 +-
 mail/em-format-html.c         |   88 +++++++++----
 6 files changed, 324 insertions(+), 342 deletions(-)
---
diff --git a/em-format/em-format.c b/em-format/em-format.c
index 6ad3576..6d20237 100644
--- a/em-format/em-format.c
+++ b/em-format/em-format.c
@@ -46,6 +46,8 @@ struct _EMFormatPrivate {
 	gchar *charset;
 	gchar *default_charset;
 	gboolean composer;
+
+	gint last_error;
 };
 
 enum {
@@ -67,14 +69,14 @@ static void emf_parse_multipart_encrypted	(EMFormat *emf, CamelMimePart *part, G
 static void emf_parse_multipart_mixed		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 static void emf_parse_multipart_signed		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 static void emf_parse_multipart_related		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
-static void emf_parse_message_rfc822		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
+static void emf_parse_multipart_digest		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 static void emf_parse_message_deliverystatus	(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 static void emf_parse_inlinepgp_signed		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 static void emf_parse_inlinepgp_encrypted	(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 static void emf_parse_source			(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
+static void emf_parse_attachment		(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 
 /* WRITERS */
-static void emf_write_message_rfc822		(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable) {};
 static void emf_write_text			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable) {};
 static void emf_write_source			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable) {}
 
@@ -274,7 +276,6 @@ emf_parse_application_mbox (EMFormat *emf,
 	messages = 0;
 	state = camel_mime_parser_step (parser, NULL, NULL);
 
-	em_format_push_level (emf);
 	while (state == CAMEL_MIME_PARSER_STATE_FROM) {
 		CamelMimeMessage *message;
 
@@ -301,7 +302,6 @@ emf_parse_application_mbox (EMFormat *emf,
 
 		messages++;
 	}
-	em_format_pull_level (emf);
 
 	g_object_unref (parser);
 }
@@ -531,8 +531,6 @@ emf_parse_multipart_mixed (EMFormat *emf,
 		return;
 	}
 
-	em_format_push_level (emf);
-
 	len = part_id->len;
 	nparts = camel_multipart_get_number (mp);
 	for (i = 0; i < nparts; i++) {
@@ -544,8 +542,6 @@ emf_parse_multipart_mixed (EMFormat *emf,
 		em_format_parse_part (emf, subpart, part_id, info, cancellable);
 		g_string_truncate (part_id, len);
 	}
-
-	em_format_pull_level (emf);
 }
 
 static void
@@ -625,7 +621,6 @@ emf_parse_multipart_signed (EMFormat *emf,
 		} else {
 			gint i, nparts, len = part_id->len;
 			nparts = camel_multipart_get_number (CAMEL_MULTIPART (mps));
-			em_format_push_level (emf);
 			for (i = 0; i < nparts; i++) {
 				CamelMimePart *subpart;
 				EMFormatParserInfo signinfo = {
@@ -640,10 +635,63 @@ emf_parse_multipart_signed (EMFormat *emf,
 				em_format_parse_part (emf, subpart, part_id, &signinfo, cancellable);
 				g_string_truncate (part_id, len);
 			}
-			em_format_pull_level (emf);
 		}
+	}
 
-		g_object_unref (cipher);
+	g_object_unref (cipher);
+}
+
+
+/* RFC 2046 */
+static void
+emf_parse_multipart_digest (EMFormat *emf,
+                     	    CamelMimePart *part,
+                     	    GString *part_id,
+                     	    EMFormatParserInfo *info,
+                     	    GCancellable *cancellable)
+{
+	CamelMultipart *mp;
+	gint i, nparts, len;
+
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
+	mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
+
+	if (!CAMEL_IS_MULTIPART (mp)) {
+		emf_parse_source (emf, part, part_id, info, cancellable);
+		return;
+	}
+
+	len = part_id->len;
+	nparts = camel_multipart_get_number (mp);
+	for (i = 0; i < nparts; i++) {
+		CamelMimePart *subpart;
+		CamelContentType *ct;
+		gchar *cts;
+		EMFormatHandler *handler;
+
+		subpart = camel_multipart_get_part (mp, i);
+
+		if (!subpart)
+			continue;
+
+		g_string_append_printf(part_id, ".digest.%d", i);
+
+		ct = camel_mime_part_get_content_type (subpart);
+		/* According to RFC this shouldn't happen, but who knows... */
+		if (ct && !camel_content_type_is (ct, "message", "rfc822")) {
+			cts = camel_content_type_simple (ct);
+			em_format_parse_part_as (emf, part, part_id, info, cts, cancellable);
+			g_free (cts);
+			g_string_truncate (part_id, len);
+			continue;
+		}
+
+		handler = em_format_find_handler (emf, "x-evolution/message/attachment");
+		handler->parse_func (emf, subpart, part_id, info, cancellable);
+
+		g_string_truncate (part_id, len);
 	}
 }
 
@@ -677,8 +725,6 @@ emf_parse_multipart_related (EMFormat *emf,
 		return;
 	}
 
-	em_format_push_level (emf);
-
 	/* The to-be-displayed part goes first */
 	partidlen = part_id->len;
 	g_string_append_printf(part_id, ".related.%d", displayid);
@@ -695,38 +741,9 @@ emf_parse_multipart_related (EMFormat *emf,
 			g_string_truncate (part_id, partidlen);
 		}
 	}
-
-	em_format_pull_level (emf);
 }
 
-static void
-emf_parse_message_rfc822 (EMFormat *emf,
-                    	  CamelMimePart *part,
-                    	  GString *part_id,
-                    	  EMFormatParserInfo *info,
-                    	  GCancellable *cancellable)
-{
-	CamelDataWrapper *dw = camel_medium_get_content ((CamelMedium *) part);
-	gint len;
-	EMFormatPURI *puri;
-
-	if (g_cancellable_is_cancelled (cancellable))
-		return;
-
-	if (!CAMEL_IS_MIME_MESSAGE (dw)) {
-		emf_parse_source (emf, part, part_id, info, cancellable);
-		return;
-	}
-
-	len = part_id->len;
-	g_string_append_printf(part_id, ".rfc822");
 
-	puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
-	puri->write_func = emf_write_message_rfc822;
-	g_string_truncate (part_id, len);
-
-	em_format_add_puri (emf, puri);
-}
 
 static void
 emf_parse_message_deliverystatus (EMFormat *emf,
@@ -771,6 +788,7 @@ emf_parse_inlinepgp_signed (EMFormat *emf,
 	gint len;
 	GError *local_error = NULL;
 	EMFormatParserInfo signinfo;
+	GByteArray *ba;
 
 	if (g_cancellable_is_cancelled (cancellable))
 		return;
@@ -814,8 +832,8 @@ emf_parse_inlinepgp_signed (EMFormat *emf,
 	/* Pass through the filters that have been setup */
 	dw = camel_medium_get_content ((CamelMedium *) ipart);
 	camel_data_wrapper_decode_to_stream_sync (
-		dw, (CamelStream *) filtered_stream, NULL, NULL);
-	camel_stream_flush ((CamelStream *) filtered_stream, NULL, NULL);
+		dw, (CamelStream *) filtered_stream, cancellable, NULL);
+	camel_stream_flush ((CamelStream *) filtered_stream, cancellable, NULL);
 	g_object_unref (filtered_stream);
 
 	/* Create a new text/plain MIME part containing the signed
@@ -832,14 +850,10 @@ emf_parse_inlinepgp_signed (EMFormat *emf,
 	type = camel_content_type_format (content_type);
 	camel_content_type_unref (content_type);
 
-	dw = camel_data_wrapper_new ();
-	camel_data_wrapper_construct_from_stream_sync (dw, ostream, NULL, NULL);
-	camel_data_wrapper_set_mime_type (dw, type);
-	g_free (type);
-
+	ba = camel_stream_mem_get_byte_array ((CamelStreamMem *) ostream);
 	opart = camel_mime_part_new ();
-	camel_medium_set_content ((CamelMedium *) opart, dw);
-	camel_data_wrapper_set_mime_type_field ((CamelDataWrapper *) opart, dw->mime_type);
+	camel_mime_part_set_content (opart, (gchar *) ba->data, ba->len, type);
+	g_free (type);
 
 	/* Pass it off to the real formatter */
 	len = part_id->len;
@@ -932,10 +946,10 @@ emf_parse_inlinepgp_encrypted (EMFormat *emf,
 
 static void
 emf_parse_source (EMFormat *emf,
-				  CamelMimePart *part,
-				  GString *part_id,
-				  EMFormatParserInfo *info,
-				  GCancellable *cancellable)
+		  CamelMimePart *part,
+		  GString *part_id,
+		  EMFormatParserInfo *info,
+		  GCancellable *cancellable)
 {
 	EMFormatPURI *puri;
 	gint len;
@@ -953,6 +967,21 @@ emf_parse_source (EMFormat *emf,
 	em_format_add_puri (emf, puri);
 }
 
+static void
+emf_parse_attachment (EMFormat *emf,
+		      CamelMimePart *part,
+		      GString *part_id,
+		      EMFormatParserInfo *info,
+		      GCancellable *cancellable)
+{
+	EMFormatPURI *puri;
+
+	puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
+	puri->is_attachment = TRUE;
+
+	em_format_add_puri (emf, puri);
+}
+
 /**************************************************************************/
 
 void
@@ -1075,11 +1104,8 @@ static EMFormatHandler type_handlers[] = {
 		{ (gchar *) "multipart/mixed", emf_parse_multipart_mixed, },
 		{ (gchar *) "multipart/signed", emf_parse_multipart_signed, },
 		{ (gchar *) "multipart/related", emf_parse_multipart_related, },
+		{ (gchar *) "multipart/digest", emf_parse_multipart_digest, },
 		{ (gchar *) "multipart/*", emf_parse_multipart_mixed, },
-		{ (gchar *) "message/rfc822", emf_parse_message_rfc822, 0, EM_FORMAT_HANDLER_INLINE },
-		{ (gchar *) "message/news", emf_parse_message_rfc822, 0, EM_FORMAT_HANDLER_INLINE },
-		{ (gchar *) "message/delivery-status", emf_parse_message_deliverystatus, },
-		{ (gchar *) "message/*", emf_parse_message_rfc822, 0, EM_FORMAT_HANDLER_INLINE },
 
 		/* Insert brokenly-named parts here */
 #ifdef ENABLE_SMIME
@@ -1090,6 +1116,7 @@ static EMFormatHandler type_handlers[] = {
 		{ (gchar *) "application/x-inlinepgp-signed", emf_parse_inlinepgp_signed, },
 		{ (gchar *) "application/x-inlinepgp-encrypted", emf_parse_inlinepgp_encrypted, },
 		{ (gchar *) "x-evolution/message/source", emf_parse_source, },
+		{ (gchar *) "x-evolution/message/attachment", emf_parse_attachment, },
 };
 
 /* note: also copied in em-mailer-prefs.c */
@@ -1300,6 +1327,8 @@ em_format_init (EMFormat *emf)
 	shell = e_shell_get_default ();
 	shell_settings = e_shell_get_shell_settings (shell);
 
+	emf->priv->last_error = 0;
+
 	emf->priv->session = e_shell_settings_get_pointer (shell_settings, "mail-session");
 	g_return_if_fail (emf->priv->session);
 
@@ -1497,51 +1526,42 @@ em_format_add_header (EMFormat *emf,
 }
 
 void
-em_format_push_level (EMFormat *emf)
+em_format_add_puri (EMFormat *emf,
+		    EMFormatPURI *puri)
 {
-	/*
-	GNode *node;
-
-	node = g_node_new (NULL);
-	if (emf->mail_part_tree == NULL) {
-		emf->mail_part_tree = node;
-	} else {
-		g_node_append (emf->priv->current_node, node);
-	}
-
-	emf->priv->current_node = node;
-
-	puri_level++;
-	printf("###### push_level to %d\n", puri_level);
-	*/
-}
+	g_return_if_fail (EM_IS_FORMAT (emf));
+	g_return_if_fail (puri != NULL);
 
-void
-em_format_pull_level (EMFormat *emf)
-{
-	/*
-	g_return_if_fail (emf->priv->current_node);
+	emf->mail_part_list = g_list_append (emf->mail_part_list, puri);
 
-	emf->priv->current_node = emf->priv->current_node->parent;
+	g_hash_table_insert (emf->mail_part_table,
+			puri->uri, puri);
 
-	puri_level--;
-	printf("###### pull_level to %d\n", puri_level);
-	*/
+	printf("  added PURI '%s', type %s, cid %s\n", puri->uri,
+			camel_content_type_simple (camel_mime_part_get_content_type (puri->part)), puri->cid);
 }
 
-void
-em_format_add_puri (EMFormat *emf,
-		    		EMFormatPURI *puri)
+EMFormatPURI*
+em_format_find_puri (EMFormat *emf,
+		     const gchar *id)
 {
-	emf->mail_part_list = g_list_append (emf->mail_part_list, puri);
+	/* First handle CIDs... */
+	if (g_str_has_prefix (id, "CID:") || g_str_has_prefix (id, "cid:")) {
+		GHashTableIter iter;
+		gpointer key, value;
+
+		g_hash_table_iter_init (&iter, emf->mail_part_table);
+		while (g_hash_table_iter_next (&iter, &key, &value)) {
+			EMFormatPURI *puri = value;
+			if (g_strcmp0 (puri->cid, id) == 0)
+				return puri;
+		}
 
-	g_hash_table_insert (emf->mail_part_table,
-			puri->uri, puri);
+		return NULL;
+	}
 
 
-	printf("  added PURI '%s', type %s\n", puri->uri,
-			camel_content_type_simple (
-					camel_mime_part_get_content_type (puri->part)));
+	return g_hash_table_lookup (emf->mail_part_table, id);
 }
 
 void
@@ -1657,20 +1677,20 @@ em_format_parse_part_as (EMFormat *emf,
 						 GCancellable *cancellable)
 {
 	const EMFormatHandler *handler;
+	EMFormatParserInfo ninfo = {
+		0,
+		info ? info->validity_type : 0,
+		info ? info->validity : 0
+	};
 
 	handler = em_format_find_handler (emf, mime_type);
 	if (handler) {
-		EMFormatParserInfo ninfo = {
-			handler,
-			info ? info->validity_type : 0,
-			info ? info->validity : 0
-		};
+		ninfo.handler = handler;
 		handler->parse_func (emf, part, part_id, &ninfo, cancellable);
 	} else {
-		EMFormatPURI *puri;
-
-		puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
-		em_format_add_puri (emf, puri);
+		handler = em_format_find_handler (emf, "x-evolution/message/attachment");
+		ninfo.handler = handler;
+		handler->parse_func (emf, part, part_id, &ninfo, cancellable);
 	}
 }
 
@@ -1718,6 +1738,14 @@ em_format_is_inline (EMFormat *emf,
 
 }
 
+gchar*
+em_format_get_error_id (EMFormat *emf)
+{
+	g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+
+	emf->priv->last_error++;
+	return g_strdup_printf (".error.%d", emf->priv->last_error);
+}
 
 void
 em_format_format_error (EMFormat *emf,
diff --git a/em-format/em-format.h b/em-format/em-format.h
index 02767de..ba3909a 100644
--- a/em-format/em-format.h
+++ b/em-format/em-format.h
@@ -217,10 +217,10 @@ void			em_format_clear_headers		(EMFormat *emf);
 void			em_format_add_header 		(EMFormat *emf,
 											 const gchar *name,
 											 guint32 flags);
-void 			em_format_push_level		(EMFormat *emf);
-void 			em_format_pull_level		(EMFormat *emf);
 void			em_format_add_puri			(EMFormat *emf,
 											 EMFormatPURI *puri);
+EMFormatPURI*	em_format_find_puri			(EMFormat *emf,
+											 const gchar *id);
 
 void			em_format_class_add_handler	(EMFormatClass *emfc,
 											 EMFormatHandler *handler);
@@ -253,6 +253,8 @@ gboolean		em_format_is_inline			(EMFormat *emf,
 											 CamelMimePart *part,
 											 const EMFormatHandler *handler);
 
+gchar*			em_format_get_error_id		(EMFormat *emf);
+
 void			em_format_format_error		(EMFormat *emf,
 											 const gchar *format,
 											 ...) G_GNUC_PRINTF (2, 3);
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index b4f7576..6497cc1 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -7,7 +7,7 @@
 
 #include "em-format-html.h"
 
-#define d(x)
+#define d(x) x
 
 G_DEFINE_TYPE (EMailRequest, e_mail_request, SOUP_TYPE_REQUEST)
 
@@ -19,6 +19,7 @@ struct _EMailRequestPrivate {
 
 	CamelContentType *content_type;
 	gchar *mime_type;
+	gint content_length;
 
 	GHashTable *uri_query;
 };
@@ -64,15 +65,14 @@ start_mail_formatting (GSimpleAsyncResult *res,
 			em_format_html_format_headers (efh, request->priv->output_stream,
 				CAMEL_MEDIUM (emf->message), all_headers, cancellable);
 		} else {
-			EMFormatPURI *puri = g_hash_table_lookup (emf->mail_part_table, part_id);
+			EMFormatPURI *puri = em_format_find_puri (emf, part_id);
 			if (puri) {
 				em_format_puri_write (puri, request->priv->output_stream, NULL);
+				mail_request_set_content_type (request,
+					camel_mime_part_get_content_type (puri->part));
 			} else {
 				g_warning ("Failed to lookup requested part '%s' - this should not happen!", part_id);
 			}
-
-			mail_request_set_content_type (request,
-					camel_mime_part_get_content_type (puri->part));
 		}
 	}
 
@@ -90,9 +90,9 @@ start_mail_formatting (GSimpleAsyncResult *res,
 }
 
 static void
-get_image_content (GSimpleAsyncResult *res,
-	       	   GObject *object,
-		   GCancellable *cancellable)
+get_file_content (GSimpleAsyncResult *res,
+	       	  GObject *object,
+		  GCancellable *cancellable)
 {
 	EMailRequest *request = E_MAIL_REQUEST (object);
 	SoupURI *uri;
@@ -107,11 +107,13 @@ get_image_content (GSimpleAsyncResult *res,
 
 	if (g_file_get_contents (uri->path, &contents, &length, NULL)) {
 		CamelContentType *ct;
-		gchar *mime_type = g_content_type_guess (uri->path, NULL, 0, NULL);
-		ct = camel_content_type_decode (mime_type);
+		request->priv->mime_type = g_content_type_guess (uri->path, NULL, 0, NULL);
+		ct = camel_content_type_decode (request->priv->mime_type);
 		mail_request_set_content_type (request, ct);
 		camel_content_type_unref (ct);
 
+		request->priv->content_length = length;
+
 		stream = g_memory_input_stream_new_from_data (contents, length, NULL);
 		g_simple_async_result_set_op_res_gpointer (res, stream, NULL);
 	}
@@ -127,6 +129,9 @@ e_mail_request_init (EMailRequest *request)
 	request->priv->part = NULL;
 	request->priv->output_stream = NULL;
 	request->priv->uri_query = NULL;
+	request->priv->content_type = NULL;
+	request->priv->mime_type = NULL;
+	request->priv->content_length = 0;
 }
 
 static void
@@ -179,6 +184,9 @@ mail_request_send_async (SoupRequest *request,
 
 	session = soup_request_get_session (request);
 	uri = soup_request_get_uri (request);
+
+	d(printf("received request for %s\n", soup_uri_to_string (uri, FALSE)));
+
 	if (g_strcmp0 (uri->scheme, "mail") == 0) {
 		gchar *uri_str;
 
@@ -201,7 +209,7 @@ mail_request_send_async (SoupRequest *request,
 		/* WebKit won't allow us to load data through local file:// protocol, when using "remote" mail://
 		   protocol, so we have evo-file:// which WebKit thinks it's remote, but in fact it behaves like file:// */
 		result = g_simple_async_result_new (G_OBJECT (request), callback, user_data, mail_request_send_async);
-		g_simple_async_result_run_in_thread (result, get_image_content, G_PRIORITY_DEFAULT, cancellable);
+		g_simple_async_result_run_in_thread (result, get_file_content, G_PRIORITY_DEFAULT, cancellable);
 	}
 }
 
@@ -225,14 +233,16 @@ mail_request_get_content_length (SoupRequest *request)
 	GByteArray *ba;
 	gint content_length = 0;
 
-	if (emr->priv->output_stream) {
+	if (emr->priv->content_length > 0)
+		content_length = emr->priv->content_length;
+	else if (emr->priv->output_stream) {
 		ba = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (emr->priv->output_stream));
 		if (ba) {
 			content_length = ba->len;
 		}
 	}
 
-	d(printf("Content-Length: %d bytes", content_length));
+	d(printf("Content-Length: %d bytes\n", content_length));
 	return content_length;
 }
 
@@ -241,27 +251,23 @@ mail_request_get_content_type (SoupRequest *request)
 {
 	EMailRequest *emr = E_MAIL_REQUEST (request);
 
-	if (emr->priv->mime_type)
-		g_free (emr->priv->mime_type);
+	if (emr->priv->mime_type) {
+		d(printf("Content-Type: %s\n", emr->priv->mime_type));
+		return emr->priv->mime_type;
+	}
 
 	if (emr->priv->content_type == NULL) {
-		emr->priv->mime_type = g_strdup ("text/html");
-
-	/* For text/html return native content type, since it can contain
-	 * informations about charset
-	 */
-	} else if (camel_content_type_is (emr->priv->content_type, "text", "html")) {
-		emr->priv->mime_type = camel_content_type_format (emr->priv->content_type);
+		emr->priv->mime_type = g_strdup ("text/html; charset=utf-8");
 
-	/* For any other text/* content type, return text/html, because we
+	/* For text/* content type, return text/html, because we
 	 * have converted it from whatever type it was to HTML */
 	} else if (camel_content_type_is (emr->priv->content_type, "text", "*")) {
-		emr->priv->mime_type = g_strdup ("text/html");
+		emr->priv->mime_type = g_strdup ("text/html; charset=utf-8");
 
 	/* For any other format return it's native format, because then it is
-	 * most probably image or something similar	 */
+	 * most probably image or something similar */
 	} else {
-		emr->priv->mime_type = camel_content_type_format (emr->priv->content_type);
+		emr->priv->mime_type = camel_content_type_simple (emr->priv->content_type);
 	}
 
 	d(printf("Content-Type: %s\n", emr->priv->mime_type));
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index f1f2610..52da1c5 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -62,6 +62,8 @@
 #include "widgets/misc/e-attachment.h"
 #include "widgets/misc/e-attachment-button.h"
 #include "widgets/misc/e-attachment-view.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-window.h"
 
 #define EM_FORMAT_HTML_DISPLAY_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -70,7 +72,7 @@
 #define d(x)
 
 struct _EMFormatHTMLDisplayPrivate {
-	GHashTable *attachment_views;  /* weak reference; message_part_id->EAttachmentView */
+	EAttachmentView *attachment_view;
 };
 
 /* TODO: move the dialogue elsehwere */
@@ -99,15 +101,15 @@ static const gchar *smime_sign_colour[5] = {
 	"", " bgcolor=\"#88bb88\"", " bgcolor=\"#bb8888\"", " bgcolor=\"#e8d122\"",""
 };
 
-static void efhd_attachment_frame (EMFormat *emf, CamelStream *stream, EMFormatPURI *puri, GCancellable *cancellable);
-static void efhd_message_add_bar (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
-static GtkWidget* efhd_attachment_button (EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
-static GtkWidget* efhd_attachment_optional (EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
-static void efhd_free_attach_puri_data (EMFormatPURI *puri);
-
+static void efhd_message_prefix 	(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
+static void efhd_message_add_bar	(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
+static void efhd_parse_attachment	(EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
 
-static void efhd_message_prefix (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
+static GtkWidget* efhd_attachment_bar		(EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
+static GtkWidget* efhd_attachment_button	(EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
+static GtkWidget* efhd_attachment_optional	(EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
 
+static void efhd_free_attach_puri_data (EMFormatPURI *puri);
 static void efhd_builtin_init (EMFormatHTMLDisplayClass *efhc);
 
 static gpointer parent_class;
@@ -338,38 +340,6 @@ efhd_xpkcs7mime_button (EMFormat *emf,
 	return widget;
 }
 
-static gboolean
-remove_attachment_view_cb (gpointer message_part_id,
-                           gpointer attachment_view,
-                           gpointer gone_attachment_view)
-{
-	return attachment_view == gone_attachment_view;
-}
-
-static void
-efhd_attachment_view_gone_cb (gpointer efh,
-                              GObject *gone_attachment_view)
-{
-	EMFormatHTMLDisplay *efhd = EM_FORMAT_HTML_DISPLAY (efh);
-
-	g_return_if_fail (efhd != NULL);
-
-	g_hash_table_foreach_remove (
-		efhd->priv->attachment_views,
-		remove_attachment_view_cb,
-		gone_attachment_view);
-}
-
-static void
-weak_unref_attachment_view_cb (gpointer message_part_id,
-                               gpointer attachment_view,
-                               gpointer efh)
-{
-	g_object_weak_unref (
-		G_OBJECT (attachment_view),
-		efhd_attachment_view_gone_cb, efh);
-}
-
 static void
 efhd_parse (EMFormat *emf,
 	    CamelMimeMessage *msg,
@@ -381,9 +351,6 @@ efhd_parse (EMFormat *emf,
 	efhd = EM_FORMAT_HTML_DISPLAY (emf);
 	g_return_if_fail (efhd != NULL);
 
-	g_hash_table_foreach (efhd->priv->attachment_views, weak_unref_attachment_view_cb, efhd);
-	g_hash_table_remove_all (efhd->priv->attachment_views);
-
 	/* FIXME WEBKIT Duh?
 	if (emf != src)
 		EM_FORMAT_HTML (emf)->header_wrap_flags = 0;
@@ -394,22 +361,25 @@ efhd_parse (EMFormat *emf,
 }
 
 static void
-efhd_format_attachment (EMFormat *emf,
-                        EMFormatPURI *puri,
-                        GCancellable *cancellable)
+efhd_parse_attachment (EMFormat *emf,
+                       CamelMimePart *part,
+                       GString *part_id,
+                       EMFormatParserInfo *info,
+                       GCancellable *cancellable)
 {
 	gchar *classid, *text, *html;
-	EMFormatAttachmentPURI *info;
+	EMFormatAttachmentPURI *puri;
 	const EMFormatHandler *handler;
 	CamelContentType *ct;
 	gchar *mime_type;
+	const gchar *cid;
 
 	if (g_cancellable_is_cancelled (cancellable))
 		return;
 
-	classid = g_strdup_printf ("attachment.%s", puri->uri);
+	classid = g_strdup_printf ("attachment.%s", part_id->str);
 
-	ct = camel_mime_part_get_content_type (puri->part);
+	ct = camel_mime_part_get_content_type (part);
 	if (ct) {
 		mime_type = camel_content_type_simple (ct);
 
@@ -417,36 +387,38 @@ efhd_format_attachment (EMFormat *emf,
 	}
 
 	/* FIXME: should we look up mime_type from object again? */
-	text = em_format_describe_part (puri->part, mime_type);
+	text = em_format_describe_part (part, mime_type);
 	html = camel_text_to_html (
 		text, EM_FORMAT_HTML (emf)->text_html_flags &
 		CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
 	g_free (text);
 	g_free (mime_type);
 
-	info = (EMFormatAttachmentPURI*) em_format_puri_new (
-			emf, sizeof (EMFormatAttachmentPURI), puri->part, classid);
-	info->puri.free = efhd_free_attach_puri_data;
-	/* FIXME WEBKIT HEEEEEEELP, this func is killing me
-	info->widget_func = efhd_attachment_frame;
-	*/
-	info->shown = em_format_is_inline (
-		emf, info->puri.uri, info->puri.part, handler);
-	info->snoop_mime_type = em_format_snoop_type (puri->part);
-	info->attachment = e_attachment_new ();
-	info->attachment_view_part_id = g_strdup (puri->uri);
-	info->description = html;
+	puri = (EMFormatAttachmentPURI*) em_format_puri_new (
+			emf, sizeof (EMFormatAttachmentPURI), part, classid);
+	puri->puri.free = efhd_free_attach_puri_data;
+	puri->puri.widget_func = efhd_attachment_button;
+	puri->shown = em_format_is_inline (
+		emf, part_id->str,part, info->handler);
+	puri->snoop_mime_type = em_format_snoop_type (part);
+	puri->attachment = e_attachment_new ();
+	puri->attachment_view_part_id = g_strdup (classid);
+	puri->description = html;
+
+	cid = camel_mime_part_get_content_id (part);
+	if (cid)
+		puri->puri.cid = g_strdup_printf ("cid:%s", cid);
 
 	if (handler)
-		info->puri.write_func = handler->write_func;
+		puri->puri.write_func = handler->write_func;
 
-	em_format_add_puri (emf, (EMFormatPURI *) info);
+	em_format_add_puri (emf, (EMFormatPURI *) puri);
 
-	e_attachment_set_mime_part (info->attachment, info->puri.part);
+	e_attachment_set_mime_part (puri->attachment, part);
 
-	if (puri->validity) {
-		info->sign = puri->validity->sign.status;
-		info->encrypt = puri->validity->encrypt.status;
+	if (info->validity) {
+		puri->sign = info->validity->sign.status;
+		puri->encrypt = info->validity->encrypt.status;
 	}
 
 	g_free (classid);
@@ -509,7 +481,7 @@ efhd_format_secure (EMFormat *emf,
 				emf, sizeof (EMFormatSMIMEPURI), puri->part, puri->uri);
 		pobj->puri.free = efhd_xpkcs7mime_free;
 		pobj->valid = camel_cipher_validity_clone (puri->validity);
-		pobj->widget_func = efhd_xpkcs7mime_button;
+		pobj->puri.widget_func = efhd_xpkcs7mime_button;
 
 		em_format_add_puri (emf, (EMFormatPURI*) pobj);
 
@@ -708,12 +680,9 @@ efhd_finalize (GObject *object)
 	efhd = EM_FORMAT_HTML_DISPLAY (object);
 	g_return_if_fail (efhd != NULL);
 
-	if (efhd->priv->attachment_views) {
-		g_hash_table_foreach (
-			efhd->priv->attachment_views,
-			weak_unref_attachment_view_cb, efhd);
-		g_hash_table_destroy (efhd->priv->attachment_views);
-		efhd->priv->attachment_views = NULL;
+	if (efhd->priv->attachment_view) {
+		gtk_widget_destroy (GTK_WIDGET (efhd->priv->attachment_view));
+		efhd->priv->attachment_view = NULL;
 	}
 
 	/* Chain up to parent's finalize() method. */
@@ -735,7 +704,9 @@ efhd_class_init (EMFormatHTMLDisplayClass *class)
 
 	format_class = EM_FORMAT_CLASS (class);
 	format_class->parse = efhd_parse;
+/* FIXME WEBKIT format attachment?
 	format_class->format_attachment = efhd_format_attachment;
+*/
 	format_class->format_optional = efhd_format_optional;
 	format_class->format_secure = efhd_format_secure;
 
@@ -822,7 +793,8 @@ em_format_html_display_new (void)
 
 static EMFormatHandler type_builtin_table[] = {
 	{ (gchar *) "x-evolution/message/prefix", efhd_message_prefix, },
-	{ (gchar *) "x-evolution/message/post-header", (EMFormatParseFunc) efhd_message_add_bar, }
+	{ (gchar *) "x-evolution/message/post-header", (EMFormatParseFunc) efhd_message_add_bar, },
+	{ (gchar *) "x-evolution/message/attachment", efhd_parse_attachment, },
 };
 
 static void
@@ -837,21 +809,6 @@ efhd_builtin_init (EMFormatHTMLDisplayClass *efhc)
 }
 
 static void
-efhd_write_image (EMFormat *emf,
-                  CamelStream *stream,
-                  EMFormatPURI *puri,
-                  GCancellable *cancellable)
-{
-	CamelDataWrapper *dw = camel_medium_get_content ((CamelMedium *) puri->part);
-
-	/* TODO: identical to efh_write_image */
-	d(printf("writing image '%s'\n", puri->cid));
-	camel_data_wrapper_decode_to_stream_sync (
-		dw, stream, cancellable, NULL);
-	camel_stream_close (stream, cancellable, NULL);
-}
-
-static void
 efhd_message_prefix (EMFormat *emf,
                      CamelMimePart *part,
                      GString *part_id,
@@ -935,14 +892,17 @@ efhd_attachment_button (EMFormat *emf,
 						EMFormatPURI *puri,
 						GCancellable *cancellable)
 {
+	EShell *shell;
+	GtkWindow *window;
 	EMFormatAttachmentPURI *info = (EMFormatAttachmentPURI *) puri;
 	EMFormatHTML *efh = (EMFormatHTML *) emf;
 	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh;
-	EAttachmentView *view;
 	EAttachmentStore *store;
 	EAttachment *attachment;
-	//EWebView *web_view;
+	GFileInfo *finfo;
+	const gchar *name;
 	GtkWidget *widget;
+	GtkWidget *box;
 	gpointer parent;
 	guint32 size = 0;
 
@@ -982,19 +942,15 @@ efhd_attachment_button (EMFormat *emf,
 	e_attachment_set_encrypted (attachment, info->encrypt);
 	e_attachment_set_can_show (attachment, info->handle != NULL);
 
-	/* FIXME WEBKIT: We need some root-element
-	web_view = em_format_html_get_web_view (efh);
-	g_return_val_if_fail (web_view != NULL, TRUE);
-	parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
-	parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
-	*/
-	parent = NULL;
-
-	view = em_format_html_display_get_attachment_view (efhd, info->attachment_view_part_id);
-	g_return_val_if_fail (view != NULL, TRUE);
-	gtk_widget_show (GTK_WIDGET (view));
+	/* FIXME: Try to find a better way? */
+	shell = e_shell_get_default ();
+	window = e_shell_get_active_window (shell);
+	if (E_IS_SHELL_WINDOW (window))
+		parent = GTK_WIDGET (window);
+	else
+		parent = NULL;
 
-	store = e_attachment_view_get_store (view);
+	store = e_attachment_view_get_store (efhd->priv->attachment_view);
 	e_attachment_store_add_attachment (store, info->attachment);
 
 	e_attachment_load_async (
@@ -1008,11 +964,32 @@ efhd_attachment_button (EMFormat *emf,
 		e_attachment_set_file_info (info->attachment, fileinfo);
 	}
 
-	widget = e_attachment_button_new (view);
+	box = gtk_hbox_new (FALSE, 5);
+	gtk_widget_show (box);
+
+	widget = e_attachment_button_new (efhd->priv->attachment_view);
 	e_attachment_button_set_attachment (
 		E_ATTACHMENT_BUTTON (widget), attachment);
 	gtk_widget_set_can_focus (widget, TRUE);
 	gtk_widget_show (widget);
+	gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 5);
+
+	finfo = e_attachment_get_file_info (info->attachment);
+	name = NULL;
+	if (finfo)
+		name = g_file_info_get_display_name (finfo);
+
+	if (name == NULL)
+		name = _("attachment.dat");
+
+	widget = gtk_label_new (name);
+	gtk_widget_show (widget);
+	gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 5);
+
+	/* Makes the EAttachmentButton and label with name to be aligned to left */
+	widget = gtk_label_new ("");
+	gtk_widget_show (widget);
+	gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 5);
 
 	/* FIXME Not sure why the expanded callback can't just use
 	 *       info->puri.format, but there seems to be lifecycle
@@ -1020,27 +997,17 @@ efhd_attachment_button (EMFormat *emf,
 	 *       a reference count? */
 	g_object_set_data (G_OBJECT (widget), "efh", efh);
 
-	return widget;
+	return box;
 }
 
-static void
-efhd_attachment_frame (EMFormat *emf,
-                       CamelStream *stream,
-                       EMFormatPURI *puri,
-                       GCancellable *cancellable)
+static GtkWidget*
+efhd_attachment_bar (EMFormat *emf,
+		     EMFormatPURI *puri,
+		     GCancellable *cancellable)
 {
-	/* FIXME WEBKIT Heeeelp, I can't force Evo to call this function
-	 * so I don't know what it actually does :(
-
-	struct _attach_puri *info = (struct _attach_puri *) puri;
-
-	if (info->shown)
-		info->handle->handler (
-			emf, stream, info->puri.part,
-			info->handle, cancellable, FALSE);
+	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) emf;
 
-	camel_stream_close (stream, cancellable, NULL);
-	*/
+	return GTK_WIDGET (efhd->priv->attachment_view);
 }
 
 static void
@@ -1069,46 +1036,11 @@ efhd_bar_resize (EMFormatHTML *efh,
 	widget = GTK_WIDGET (web_view);
 	gtk_widget_get_allocation (widget, &allocation);
 	width = allocation.width - 12;
-	*/
 
 	if (width > 0) {
 		g_hash_table_foreach (priv->attachment_views, set_size_request_cb, GINT_TO_POINTER (width));
 	}
-}
-
-static GtkWidget*
-efhd_add_bar (EMFormat *emf,
-			  EMFormatPURI *puri,
-              GCancellable *cancellable)
-{
-    EMFormatAttachmentPURI *info = (EMFormatAttachmentPURI *) puri;
-    EMFormatHTML *efh = (EMFormatHTML *) emf;
-	EMFormatHTMLDisplayPrivate *priv;
-	GtkWidget *widget;
-
-	if (g_cancellable_is_cancelled (cancellable))
-		return NULL;
-
-	/* XXX See note in efhd_message_add_bar(). */
-	if (!EM_IS_FORMAT_HTML_DISPLAY (efh))
-		return FALSE;
-
-	g_return_val_if_fail (info != NULL, FALSE);
-	g_return_val_if_fail (g_str_has_prefix (info->puri.uri, "attachment-bar:"), FALSE);
-
-	priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efh);
-
-	widget = e_mail_attachment_bar_new ();
-
-	g_hash_table_insert (priv->attachment_views, g_strdup (strchr (info->puri.uri, ':') + 1), widget);
-	g_object_weak_ref (G_OBJECT (widget), efhd_attachment_view_gone_cb, efh);
-	gtk_widget_hide (widget);
-
-	g_signal_connect_swapped (
-		widget, "size-allocate",
-		G_CALLBACK (efhd_bar_resize), efh);
-
-	return widget;
+	*/
 }
 
 static void
@@ -1119,7 +1051,6 @@ efhd_message_add_bar (EMFormat *emf,
                       GCancellable *cancellable)
 {
 	gchar *classid;
-	gchar *content;
 	EMFormatAttachmentPURI *puri;
 
 	if (g_cancellable_is_cancelled (cancellable))
@@ -1128,17 +1059,11 @@ efhd_message_add_bar (EMFormat *emf,
 	classid = g_strdup_printf (
 		"attachment-bar:%s", part_id->str);
 
-	/* XXX Apparently this installs the callback for -all-
-	 *     EMFormatHTML subclasses, not just this subclass.
-	 *     Bad idea.  So we have to filter out other types
-	 *     in the callback. */
-	/* FIXME WEBKIT: oh, rly? ^^^ */
 	puri = (EMFormatAttachmentPURI *) em_format_puri_new (
 			emf, sizeof (EMFormatAttachmentPURI), part, classid);
-	puri->puri.widget_func = efhd_add_bar;
+	puri->puri.widget_func = efhd_attachment_bar;
 	em_format_add_puri (emf, (EMFormatPURI*) puri);
 
-
 	g_free (classid);
 }
 
@@ -1181,10 +1106,8 @@ efhd_attachment_optional (EMFormat *efh,
 	GtkWidget *hbox, *vbox, *button, *mainbox, *scroll, *label, *img;
 	AtkObject *a11y;
 	GtkWidget *view;
-	GtkAllocation allocation;
 	GtkTextBuffer *buffer;
 	GByteArray *byte_array;
-	EWebView *web_view;
 	EMFormatAttachmentPURI *info = (EMFormatAttachmentPURI *) puri;
 
 	if (g_cancellable_is_cancelled (cancellable))
@@ -1294,17 +1217,9 @@ efhd_free_attach_puri_data (EMFormatPURI *puri)
 
 /* returned object owned by html_display, thus do not unref it */
 EAttachmentView *
-em_format_html_display_get_attachment_view (EMFormatHTMLDisplay *html_display,
-                                            const gchar *message_part_id)
+em_format_html_display_get_attachment_view (EMFormatHTMLDisplay *efhd)
 {
-	gpointer aview;
-
-	g_return_val_if_fail (EM_IS_FORMAT_HTML_DISPLAY (html_display), NULL);
-	g_return_val_if_fail (message_part_id != NULL, NULL);
-
-	/* it should be added in efhd_add_bar() with this message_part_id */
-	aview = g_hash_table_lookup (html_display->priv->attachment_views, message_part_id);
-	g_return_val_if_fail (aview != NULL, NULL);
+	g_return_val_if_fail (EM_IS_FORMAT_HTML_DISPLAY (efhd), NULL);
 
-	return E_ATTACHMENT_VIEW (aview);
+	return E_ATTACHMENT_VIEW (efhd->priv->attachment_view);
 }
diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h
index fae5a96..0136c8e 100644
--- a/mail/em-format-html-display.h
+++ b/mail/em-format-html-display.h
@@ -88,8 +88,6 @@ struct _EMFormatAttachmentPURI {
 struct _EMFormatSMIMEPURI {
 	EMFormatPURI puri;
 
-	EMFormatWidgetFunc widget_func;
-
 	gchar *description;
 
 	gint signature;
@@ -114,8 +112,7 @@ EMFormatHTMLDisplay *
 		em_format_html_display_new	(void);
 EAttachmentView *
 		em_format_html_display_get_attachment_view
-						(EMFormatHTMLDisplay *html_display,
-						 const gchar *message_part_id);
+						(EMFormatHTMLDisplay *html_display);
 G_END_DECLS
 
 #endif /* EM_FORMAT_HTML_DISPLAY_H */
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 49978d6..430fec4 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -145,6 +145,7 @@ static void efh_write_text_enriched		(EMFormat *emf, EMFormatPURI *puri, CamelSt
 static void efh_write_text_plain		(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable);
 static void efh_write_text_html			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable);
 static void efh_write_source			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable);
+static void efh_write_message_rfc822		(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, GCancellable *cancellable);
 /*****************************************************************************/
 static void
 efh_parse_image (EMFormat *emf,
@@ -161,18 +162,20 @@ efh_parse_image (EMFormat *emf,
 	if (g_cancellable_is_cancelled (cancellable))
 		return;
 
+
 	tmp = camel_mime_part_get_content_id (part);
 	if (!tmp) {
-		cid = g_strdup_printf ("em-no-cid:%s", part_id->str);
-	} else {
-		cid = g_strdup_printf ("cid:%s", tmp);
+		em_format_parse_part_as (emf, part, part_id, info, "x-evolution/message-attachment", cancellable);
+		return;
 	}
 
+	cid = g_strdup_printf ("cid:%s", tmp);
 	len = part_id->len;
 	g_string_append (part_id, ".image");
 	puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
 	puri->cid = cid;
 	puri->write_func = efh_write_image;
+	puri->is_attachment = TRUE;
 
 	em_format_add_puri (emf, puri);
 	g_string_truncate (part_id, len);
@@ -218,6 +221,7 @@ efh_parse_text_plain (EMFormat *emf,
 		      GCancellable *cancellable)
 {
 	EMFormatHTML *efh = EM_FORMAT_HTML (emf);
+	EMFormatPURI *puri;
 	CamelStream *filtered_stream;
 	CamelMultipart *mp;
 	CamelDataWrapper *dw;
@@ -309,7 +313,6 @@ efh_parse_text_plain (EMFormat *emf,
 
 		type = camel_mime_part_get_content_type (newpart);
 		if (camel_content_type_is (type, "text", "*") && (!camel_content_type_is (type, "text", "calendar"))) {
-			EMFormatPURI *puri;
 			gint s_len = part_id->len;
 
 			g_string_append (part_id, ".plain_text");
@@ -510,10 +513,28 @@ efh_parse_message_deliverystatus (EMFormat *emf,
 	g_string_truncate (part_id, len);
 }
 
+static void
+efh_parse_message_rfc822 (EMFormat *emf,
+			  CamelMimePart *part,
+			  GString *part_id,
+			  EMFormatParserInfo *info,
+			  GCancellable *cancellable)
+{
+	EMFormatPURI *puri;
+	gint len;
+
+	len = part_id->len;
+	g_string_append (part_id, ".rfc822");
+	puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
+	puri->write_func = efh_write_message_rfc822;
 
-/*****************************************************************************/
+	em_format_add_puri (emf, puri);
+	g_string_truncate (part_id, len);
+}
 
 
+/*****************************************************************************/
+
 static void
 efh_write_image (EMFormat *emf,
 		 EMFormatPURI *puri,
@@ -530,10 +551,20 @@ efh_write_image (EMFormat *emf,
 	/* FIXME: What about some error string when dw == NULL? */
 	dw = camel_medium_get_content (CAMEL_MEDIUM (puri->part));
 	if (dw) {
+		CamelStream *stream_filter;
+		CamelMimeFilter *filter;
+
+		filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
+		stream_filter = camel_stream_filter_new (stream);
+		camel_stream_filter_add ((CamelStreamFilter *) stream_filter, filter);
+
 		ba = camel_data_wrapper_get_byte_array (dw);
 		content = g_strndup ((gchar *) ba->data, ba->len);
-		camel_stream_write_string (stream, content, cancellable, NULL);
+		camel_stream_write_string (stream_filter, content, cancellable, NULL);
 		g_free (content);
+
+		g_object_unref (filter);
+		g_object_unref (stream_filter);
 	}
 }
 
@@ -642,29 +673,18 @@ efh_write_text_plain (EMFormat *emf,
 
 	content = g_strdup_printf (
 			EFH_HTML_HEADER	"<div id=\"pre\" style=\"background: #%06x; padding: 10px;\">\n",
-			e_color_to_value (
-				&efh->priv->colors[
-				EM_FORMAT_HTML_COLOR_BODY]),
-			e_color_to_value (
-				&efh->priv->colors[
-				EM_FORMAT_HTML_COLOR_HEADER]),
-			e_color_to_value (
-				&efh->priv->colors[
-				EM_FORMAT_HTML_COLOR_CONTENT]));
-
-	camel_stream_write_string (
-			stream, content, cancellable, NULL);
-	g_free (content);
+			e_color_to_value (&efh->priv->colors[EM_FORMAT_HTML_COLOR_BODY]),
+			e_color_to_value (&efh->priv->colors[EM_FORMAT_HTML_COLOR_HEADER]),
+			e_color_to_value (&efh->priv->colors[EM_FORMAT_HTML_COLOR_CONTENT]));
 
-	em_format_format_text (
-			emf, filtered_stream,
-			(CamelDataWrapper *) puri->part,
-			cancellable);
+	camel_stream_write_string (stream, content, cancellable, NULL);
+	em_format_format_text (emf, filtered_stream, (CamelDataWrapper *) puri->part, cancellable);
 
 	g_object_unref (filtered_stream);
+	g_free (content);
 
 	camel_stream_write_string (stream, "</div>\n", cancellable, NULL);
-	camel_stream_write_string (stream, EFH_HTML_FOOTER, cancellable, NULL);
+	camel_stream_write_string (stream, EFH_HTML_FOOTER "\n", cancellable, NULL);
 }
 
 static void
@@ -709,6 +729,16 @@ efh_write_source (EMFormat *emf,
 	g_object_unref (filtered_stream);
 }
 
+static void
+efh_write_message_rfc822 (EMFormat *emf,
+			  EMFormatPURI *puri,
+			  CamelStream *stream,
+			  GCancellable *cancellable)
+{
+
+
+}
+
 /*****************************************************************************/
 
 /* Notes:
@@ -741,12 +771,15 @@ static EMFormatHandler type_builtin_table[] = {
 	{ (gchar *) "text/html", efh_parse_text_html, efh_write_text_html, },
 	{ (gchar *) "text/richtext", efh_parse_text_enriched, efh_write_text_enriched, },
 	{ (gchar *) "text/*", efh_parse_text_plain, efh_write_text_plain, },
-	{ (gchar *) "message/external-body", efh_parse_message_external, 0 },
+        { (gchar *) "nessage/rfc822", efh_parse_message_rfc822, efh_write_message_rfc822, EM_FORMAT_HANDLER_INLINE },
+        { (gchar *) "message/news", efh_parse_message_rfc822, efh_write_message_rfc822, EM_FORMAT_HANDLER_INLINE },
+        { (gchar *) "message/delivery-status", efh_parse_message_deliverystatus, efh_write_message_rfc822, },
+	{ (gchar *) "message/external-body", efh_parse_message_external, efh_write_message_rfc822, },
+        { (gchar *) "message/*", efh_parse_message_rfc822, 0, EM_FORMAT_HANDLER_INLINE },
 
 	/* This is where one adds those busted, non-registered types,
 	   that some idiot mailer writers out there decide to pull out
 	   of their proverbials at random. */
-
 	{ (gchar *) "image/jpg", efh_parse_image, efh_write_image, },
 	{ (gchar *) "image/pjpeg", efh_parse_image, efh_write_image, },
 
@@ -979,6 +1012,7 @@ efh_format_error (EMFormat *emf,
 	CamelMimePart *part;
 	GString *buffer;
 	gchar *html;
+	gchar *part_id;
 
 	buffer = g_string_new ("<em><font color=\"red\">");
 
@@ -993,7 +1027,7 @@ efh_format_error (EMFormat *emf,
 	part = camel_mime_part_new ();
 	camel_mime_part_set_content (part, buffer->str, buffer->len, "text/html");
 
-	puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, ".error");
+	puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, em_format_get_error_id (emf));
 	puri->write_func = efh_write_text_html;
 
 	em_format_add_puri (emf, puri);



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