[evolution/webkit: 60/123] Handle properly embedded message/rfc822



commit e9d4704429d3f9cf737aba3edacbbf0f0684a07a
Author: Dan VrÃtil <dvratil redhat com>
Date:   Fri Nov 25 16:11:30 2011 +0100

    Handle properly embedded message/rfc822
    
    Every message/rfc822 will create a trailing ".rfc822" PURI with widget_func
    that would return new EMailDisplay. Following PURIs will represent content
    of the particular message and finally, an empty ".rfc822.end" PURI will be added.
    
    This way we can easily display attached messages as well as mboxes or digests.

 em-format/em-format.c         |   33 +++++++++++++++++++------
 mail/em-format-html-display.c |    7 +++--
 mail/em-format-html.c         |   53 ++++++++++++++++++++++++++++++++++------
 3 files changed, 74 insertions(+), 19 deletions(-)
---
diff --git a/em-format/em-format.c b/em-format/em-format.c
index 4435295..a036b28 100644
--- a/em-format/em-format.c
+++ b/em-format/em-format.c
@@ -316,8 +316,8 @@ emf_parse_application_mbox (EMFormat *emf,
 		}
 
 		g_string_append_printf (part_id, ".mbox.%d", messages);
-		em_format_parse_part (emf, CAMEL_MIME_PART (message),
-				part_id, info, cancellable);
+		em_format_parse_part_as (emf, CAMEL_MIME_PART (message),
+				part_id, info, "message/rfc822", cancellable);
 		g_string_truncate (part_id, old_len);
 
 		g_object_unref (message);
@@ -1187,11 +1187,11 @@ emf_parse (EMFormat *emf,
 	g_return_if_fail (emf->message);
 	g_return_if_fail (emf->folder);
 
-	part_id = g_string_new ("");
+	part_id = g_string_new (".message");
 
 	/* Create a special PURI with entire message */
 	puri = em_format_puri_new (emf, sizeof (EMFormatPURI),
-		(CamelMimePart *) message, ".message");
+		(CamelMimePart *) message, part_id->str);
 	puri->mime_type = g_strdup ("text/html");
 	em_format_add_puri (emf, puri);
 
@@ -1461,6 +1461,15 @@ em_format_class_init (EMFormatClass *class)
 }
 
 static void
+mail_part_table_item_free (gpointer data)
+{
+	GList *iter = data;
+	EMFormatPURI *puri = iter->data;
+
+	em_format_puri_free (puri);
+}
+
+static void
 em_format_init (EMFormat *emf)
 {
 	EShell *shell;
@@ -1474,7 +1483,7 @@ em_format_init (EMFormat *emf)
 	emf->folder = NULL;
 	emf->mail_part_list = NULL;
 	emf->mail_part_table = g_hash_table_new_full (g_str_hash, g_str_equal,
-			NULL, (GDestroyNotify) em_format_puri_free);
+			NULL, (GDestroyNotify) mail_part_table_item_free);
 	/* No need to free the key, because it's owned and free'd by the PURI */
 	
 	shell = e_shell_get_default ();
@@ -1745,13 +1754,16 @@ void
 em_format_add_puri (EMFormat *emf,
                     EMFormatPURI *puri)
 {
+        GList *item;
+
         g_return_if_fail (EM_IS_FORMAT (emf));
         g_return_if_fail (puri != NULL);
 
         emf->mail_part_list = g_list_append (emf->mail_part_list, puri);
+        item = g_list_last (emf->mail_part_list);
 
         g_hash_table_insert (emf->mail_part_table,
-                        puri->uri, puri);
+                        puri->uri, item);
 
         d(printf("Added PURI %s\n", puri->uri));
 }
@@ -1760,6 +1772,8 @@ EMFormatPURI*
 em_format_find_puri (EMFormat *emf,
 		     const gchar *id)
 {
+	GList *list_iter;
+
 	/* First handle CIDs... */
 	if (g_str_has_prefix (id, "CID:") || g_str_has_prefix (id, "cid:")) {
 		GHashTableIter iter;
@@ -1767,7 +1781,7 @@ em_format_find_puri (EMFormat *emf,
 
 		g_hash_table_iter_init (&iter, emf->mail_part_table);
 		while (g_hash_table_iter_next (&iter, &key, &value)) {
-			EMFormatPURI *puri = value;
+			EMFormatPURI *puri = ((GList *) value)->data;
 			if (g_strcmp0 (puri->cid, id) == 0)
 				return puri;
 		}
@@ -1775,8 +1789,11 @@ em_format_find_puri (EMFormat *emf,
 		return NULL;
 	}
 
+	list_iter = g_hash_table_lookup (emf->mail_part_table, id);
+	if (list_iter)
+		return list_iter->data;
 
-	return g_hash_table_lookup (emf->mail_part_table, id);
+	return NULL;
 }
 
 void
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 3ba6c17..1f2e9b7 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -122,6 +122,7 @@ find_parent_attachment_store (EMFormatHTMLDisplay *efhd, GString *part_id)
 	EMFormatAttachmentBarPURI *abp;
 	EMFormatPURI *puri;
 	gchar *tmp, *pos;
+        GList *item;
 
 	tmp = g_strdup (part_id->str);
 
@@ -136,15 +137,15 @@ find_parent_attachment_store (EMFormatHTMLDisplay *efhd, GString *part_id)
 		tmp = g_strndup (part_id->str, pos - tmp);
 		id = g_strdup_printf ("%s.attachment-bar", tmp);
 
-		puri = g_hash_table_lookup (emf->mail_part_table, id);
+		item = g_hash_table_lookup (emf->mail_part_table, id);
 
 		g_free (id);
 
-	} while (pos && !puri);
+	} while (pos && !item);
 
 	g_free (tmp);
 
-	abp = (EMFormatAttachmentBarPURI *) puri;
+	abp = (EMFormatAttachmentBarPURI *) item->data;
 
         if (abp)
 	        return abp->store;
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index d00fb34..3079c73 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -65,6 +65,7 @@
 
 #include "em-format-html.h"
 #include "em-utils.h"
+#include "e-mail-display.h"
 #include <em-format/em-inline-filter.h>
 
 #define EM_FORMAT_HTML_GET_PRIVATE(obj) \
@@ -125,13 +126,36 @@ static void efh_write_text_enriched		(EMFormat *emf, EMFormatPURI *puri, CamelSt
 static void efh_write_text_plain		(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
 static void efh_write_text_html			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
 static void efh_write_source			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void efh_write_message_rfc822		(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
 static void efh_write_headers			(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
 
+static GtkWidget* efh_widget_message_rfc822     (EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
+
 static void efh_format_full_headers 		(EMFormatHTML *efh, GString *buffer, CamelMedium *part, gboolean all_headers, gboolean visible, GCancellable *cancellable);
 static void efh_format_short_headers 		(EMFormatHTML *efh, GString *buffer, CamelMedium *part, gboolean visible, GCancellable *cancellable);
 
 /*****************************************************************************/
+static GtkWidget*
+efh_widget_message_rfc822 (EMFormat* emf,
+                           EMFormatPURI* puri,
+                           GCancellable* cancellable)
+{
+        EMailDisplay *display;
+        gchar *msg_uri;
+
+        msg_uri = em_format_build_mail_uri (emf->folder, emf->message_uid,
+                "part_id", G_TYPE_STRING, puri->uri, NULL);
+
+        display = g_object_new (E_TYPE_MAIL_DISPLAY, NULL);
+        e_mail_display_set_formatter (display, EM_FORMAT_HTML (emf));
+        e_mail_display_load (display, msg_uri);
+
+        g_free (msg_uri);
+
+        return GTK_WIDGET (display);
+}
+
+
+/*****************************************************************************/
 static void
 efh_parse_image (EMFormat *emf,
 		 CamelMimePart *part,
@@ -250,9 +274,10 @@ efh_parse_text_plain (EMFormat *emf,
 		CamelStream *null;
 		CamelContentType *ct;
 		gboolean charset_added = FALSE;
-		const gchar *snoop_type;
+		const gchar *snoop_type = NULL;
 
-		snoop_type = em_format_snoop_type (part);
+                if (!dw->mime_type)
+                        snoop_type = em_format_snoop_type (part);
 
 		/* if we had to snoop the part type to get here, then
 		 * use that as the base type, yuck */
@@ -333,7 +358,6 @@ efh_parse_text_html (EMFormat *emf,
 		     EMFormatParserInfo *info,
 		     GCancellable *cancellable)
 {
-	EMFormatHTML *efh = EM_FORMAT_HTML (emf);
 	EMFormatPURI *puri;
 	const gchar *location;
 	gchar *cid = NULL;
@@ -531,14 +555,20 @@ efh_parse_message_rfc822 (EMFormat *emf,
 	CamelMimePart *opart;
 	CamelStream *stream;
 	CamelMimeParser *parser;
-	CamelContentType *ct;
-	gchar *cts;
 	gint len;
 	EMFormatParserInfo oinfo = *info;
+        EMFormatPURI *puri;
 
 	len = part_id->len;
 	g_string_append (part_id, ".rfc822");
 
+        /* Create an empty PURI that will represent start of the RFC message */
+        puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
+        puri->widget_func = efh_widget_message_rfc822;
+        puri->write_func = em_format_empty_writer;
+        em_format_add_puri (emf, puri);
+
+        /* Now parse the message, creating multiple sub-PURIs */
 	stream = camel_stream_mem_new ();
 	dw = camel_medium_get_content ((CamelMedium *) part);
 	camel_data_wrapper_write_to_stream_sync (dw, stream, cancellable, NULL);
@@ -553,6 +583,15 @@ efh_parse_message_rfc822 (EMFormat *emf,
 	em_format_parse_part_as (emf, opart, part_id, &oinfo,
 		"x-evolution/message", cancellable);
 
+        /* Add another generic PURI that represents end of the RFC message.
+         * This is required for every PURI that has EMailDisplay widget_func.
+         * The parent EMailDisplay then skips all PURIs between the ".rfc822" PURI
+         * ".rfc822.end" PURI (they were displayed by the child EMailDisplay called
+         * from ".rfc822"'s widget_func) and continues with the following PURI. */
+        g_string_append (part_id, ".end");
+        puri = em_format_puri_new (emf, sizeof (EMFormatPURI), NULL, part_id->str);
+        em_format_add_puri (emf, puri);
+
 	g_string_truncate (part_id, len);
 
 	g_object_unref (opart);
@@ -1181,7 +1220,6 @@ static void
 efh_finalize (GObject *object)
 {
 	EMFormatHTML *efh = EM_FORMAT_HTML (object);
-	EMFormatHTMLPrivate *priv = efh->priv;
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -1195,7 +1233,6 @@ efh_format_error (EMFormat *emf,
 	CamelMimePart *part;
 	GString *buffer;
 	gchar *html;
-	gchar *part_id;
 
 	buffer = g_string_new ("<em><font color=\"red\">");
 



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