[evolution/webkit: 136/171] Convert EMFormatPURI to a thread-safe EMPart object
- From: Dan VrÃtil <dvratil src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit: 136/171] Convert EMFormatPURI to a thread-safe EMPart object
- Date: Fri, 24 Feb 2012 12:45:54 +0000 (UTC)
commit 5eda7074dcbf0f2d8169644f8b50bda5f2bc74d0
Author: Dan VrÃtil <dvratil redhat com>
Date: Tue Feb 7 17:34:40 2012 +0100
Convert EMFormatPURI to a thread-safe EMPart object
EMFormatPURI structures are now represented by a EMPart objects which
wrap all the PURI's properties as private and make them accessible only
via em_part_{get,set}_* methods which take care of locking. Also the
EMPart is a subclass of GObject, thus it's possible to use reference
counting to ensure life-span of the object.
Unfortunately it's now a little bit more complicated to create subclasses,
because it is necessary to define a whole new class.
TODO:
- convert image-inline, itip-formatter, mail-to-task, tnef-attachments
and vcard-inline plugins
- move EMPart's private mutex to EMPartClass so that subclasses don't have
to have their own mutex.
Note: won't compile due to EMailDisplay not being ported
em-format/Makefile.am | 2 +
em-format/em-format-quote.c | 125 ++++---
em-format/em-format.c | 249 +++++-------
em-format/em-format.h | 75 ++---
em-format/em-part.c | 678 +++++++++++++++++++++++++++++++
em-format/em-part.h | 140 +++++++
mail/Makefile.am | 2 +
mail/e-mail-request.c | 78 +++--
mail/em-format-html-display-parts.c | 722 ++++++++++++++++++++++++++++++++++
mail/em-format-html-display-parts.h | 242 ++++++++++++
mail/em-format-html-display.c | 395 ++++++++++---------
mail/em-format-html-display.h | 46 ---
mail/em-format-html-print.c | 190 ++++++---
mail/em-format-html.c | 295 +++++++++------
mail/em-format-html.h | 1 -
mail/em-utils.c | 12 +-
plugins/audio-inline/Makefile.am | 4 +-
plugins/audio-inline/audio-inline.c | 232 +++++------
plugins/audio-inline/em-part-audio.c | 346 ++++++++++++++++
plugins/audio-inline/em-part-audio.h | 112 ++++++
widgets/misc/e-web-view.c | 185 +---------
widgets/misc/e-web-view.h | 4 -
22 files changed, 3114 insertions(+), 1021 deletions(-)
---
diff --git a/em-format/Makefile.am b/em-format/Makefile.am
index 392a195..186f300 100644
--- a/em-format/Makefile.am
+++ b/em-format/Makefile.am
@@ -6,6 +6,7 @@ emformatinclude_HEADERS = \
em-format.h \
em-format-quote.h \
em-inline-filter.h \
+ em-part.h \
em-stripsig-filter.h
libemformat_la_CPPFLAGS = \
@@ -21,6 +22,7 @@ libemformat_la_SOURCES = \
em-format.c \
em-format-quote.c \
em-inline-filter.c \
+ em-part.c \
em-stripsig-filter.c
libemformat_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
diff --git a/em-format/em-format-quote.c b/em-format/em-format-quote.c
index 23994f2..d107757 100644
--- a/em-format/em-format-quote.c
+++ b/em-format/em-format-quote.c
@@ -32,6 +32,7 @@
#include "em-inline-filter.h"
#include "em-stripsig-filter.h"
#include "em-format-quote.h"
+#include "em-part.h"
#define EM_FORMAT_QUOTE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -53,9 +54,9 @@ static void emfq_parse_text_enriched (EMFormat *emf, CamelMimePart *part, GSt
static void emfq_parse_text_html (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
static void emfq_parse_attachment (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
-static void emfq_write_text_plain (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void emfq_write_text_enriched (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void emfq_write_text_html (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void emfq_write_text_plain (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void emfq_write_text_enriched (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void emfq_write_text_html (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
static gpointer parent_class;
@@ -386,8 +387,8 @@ emfq_parse_text_plain (EMFormat* emf,
EMFormatParserInfo* info,
GCancellable* cancellable)
{
- EMFormatPURI *puri;
- CamelMimePart *mp;
+ EMPart *emp;
+ CamelMimePart *mp;
gint len;
len = part_id->len;
@@ -403,10 +404,9 @@ emfq_parse_text_plain (EMFormat* emf,
g_object_unref (mp);
}
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = emfq_write_text_plain;
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, emfq_write_text_plain);
+ em_part_set_mime_type (emp, "text/html");
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
}
@@ -418,16 +418,15 @@ emfq_parse_text_html (EMFormat* emf,
EMFormatParserInfo* info,
GCancellable* cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
len = part_id->len;
g_string_append (part_id, ".text_html");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = emfq_write_text_html;
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, emfq_write_text_html);
+ em_part_set_mime_type (emp, "text/html");
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
}
@@ -439,16 +438,15 @@ emfq_parse_text_enriched (EMFormat* emf,
EMFormatParserInfo* info,
GCancellable* cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
len = part_id->len;
g_string_append (part_id, ".text_enriched");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = emfq_write_text_enriched;
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, emfq_write_text_enriched);
+ em_part_set_mime_type (emp, "text/html");
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
}
@@ -460,17 +458,16 @@ emfq_parse_attachment (EMFormat* emf,
EMFormatParserInfo* info,
GCancellable* cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
len = part_id->len;
g_string_append (part_id, ".attachment");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = emfq_write_text_html;
- puri->mime_type = g_strdup ("text/html");
- puri->is_attachment = TRUE;
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, emfq_write_text_html);
+ em_part_set_mime_type (emp, "text/html");
+ em_part_set_is_attachment (emp, TRUE);
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
}
@@ -483,7 +480,7 @@ emfq_parse_attachment (EMFormat* emf,
static void
emfq_write_attachment (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -492,9 +489,13 @@ emfq_write_attachment (EMFormat *emf,
const EMFormatHandler *handler;
gchar *text, *html;
CamelContentType *ct;
+ CamelMimePart *part;
const gchar *mime_type;
+ gchar *uri;
- ct = camel_mime_part_get_content_type (puri->part);
+ part = em_part_get_mime_part (emp);
+ uri = em_part_get_uri (emp);
+ ct = camel_mime_part_get_content_type (part);
if (ct) {
mime_type = camel_content_type_simple (ct);
camel_content_type_unref (ct);
@@ -504,15 +505,18 @@ emfq_write_attachment (EMFormat *emf,
handler = em_format_find_handler (emf, mime_type);
- if (!em_format_is_inline (emf, puri->uri, puri->part, handler))
+ if (!em_format_is_inline (emf, uri, part, handler)) {
+ g_free (uri);
+ g_object_unref (part);
return;
+ }
camel_stream_write_string (
stream, "<table border=1 cellspacing=0 cellpadding=0>"
"<tr><td><font size=-1>\n", cancellable, NULL);
/* output some info about it */
- text = em_format_describe_part (puri->part, mime_type);
+ text = em_format_describe_part (part, mime_type);
html = camel_text_to_html (
text, emfq->priv->text_html_flags &
CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
@@ -524,7 +528,10 @@ emfq_write_attachment (EMFormat *emf,
stream, "</font></td></tr></table>", cancellable, NULL);
if (handler && handler->write_func)
- handler->write_func (emf, puri, stream, info, cancellable);
+ handler->write_func (emf, emp, stream, info, cancellable);
+
+ g_object_unref (part);
+ g_free (uri);
}
static void
@@ -627,7 +634,7 @@ em_format_quote_write (EMFormatQuote* emfq,
camel_stream_write_string (
stream, "<br>\n", cancellable, NULL);
g_object_unref (settings);
-
+
if (emfq->priv->credits && *emfq->priv->credits) {
gchar *credits = g_strdup_printf ("%s<br/>", emfq->priv->credits);
camel_stream_write_string (stream, credits, cancellable, NULL);
@@ -643,21 +650,26 @@ em_format_quote_write (EMFormatQuote* emfq,
"<blockquote type=cite>\n", cancellable, NULL);
for (iter = emf->mail_part_list; iter; iter = iter->next) {
- EMFormatPURI *puri = iter->data;
-
- if (puri->is_attachment || !puri->write_func)
+ EMPart *emp = iter->data;
+ EMPartObjectWriteFunc write_func;
+
+ write_func = em_part_get_write_func (emp);
+ if (em_part_get_is_attachment (emp) || !write_func)
continue;
- puri = iter->data;
-
- if (emfq->priv->flags & EM_FORMAT_QUOTE_HEADERS) {
+ if (emfq->priv->flags & EM_FORMAT_QUOTE_HEADERS) {
GString *buffer = g_string_new ("");
- emfq_format_headers (emfq, buffer, (CamelMedium *) puri->part);
+ CamelMimePart *part;
+
+ part = em_part_get_mime_part (emp);
+ emfq_format_headers (emfq, buffer, (CamelMedium *) part);
camel_stream_write_string (stream, buffer->str, cancellable, NULL);
+
g_string_free (buffer, TRUE);
+ g_object_unref (part);
}
- puri->write_func (emf, puri, stream, &info, cancellable);
+ em_part_write (emp, stream, &info, cancellable);
}
if (emfq->priv->flags & EM_FORMAT_QUOTE_CITE)
@@ -669,7 +681,7 @@ em_format_quote_write (EMFormatQuote* emfq,
static void
emfq_write_text_plain (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -679,16 +691,16 @@ emfq_write_text_plain (EMFormat *emf,
CamelMimeFilter *html_filter;
CamelMimeFilter *sig_strip;
CamelContentType *type;
+ CamelMimePart *part;
const gchar *format;
guint32 rgb = 0x737373, flags;
- if (!puri->part)
- return;
-
flags = emfq->priv->text_html_flags;
+ part = em_part_get_mime_part (emp);
+
/* Check for RFC 2646 flowed text. */
- type = camel_mime_part_get_content_type (puri->part);
+ type = camel_mime_part_get_content_type (part);
if (camel_content_type_is(type, "text", "plain")
&& (format = camel_content_type_param(type, "format"))
&& !g_ascii_strcasecmp(format, "flowed"))
@@ -710,15 +722,17 @@ emfq_write_text_plain (EMFormat *emf,
em_format_format_text (
EM_FORMAT (emfq), filtered_stream,
- CAMEL_DATA_WRAPPER (puri->part), cancellable);
+ CAMEL_DATA_WRAPPER (part), cancellable);
camel_stream_flush (filtered_stream, cancellable, NULL);
g_object_unref (filtered_stream);
+
+ g_object_unref (part);
}
static void
emfq_write_text_enriched (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -727,9 +741,12 @@ emfq_write_text_enriched (EMFormat *emf,
CamelMimeFilter *enriched;
guint32 flags = 0;
CamelContentType *ct;
+ CamelMimePart *part;
const gchar *mime_type = NULL;
- ct = camel_mime_part_get_content_type (puri->part);
+ part = em_part_get_mime_part (emp);
+
+ ct = camel_mime_part_get_content_type (part);
if (ct) {
mime_type = camel_content_type_simple (ct);
camel_content_type_unref (ct);
@@ -754,21 +771,25 @@ emfq_write_text_enriched (EMFormat *emf,
camel_stream_write_string (stream, "<br><hr><br>", cancellable, NULL);
em_format_format_text (
- emf, filtered_stream, CAMEL_DATA_WRAPPER (puri->part), cancellable);
+ emf, filtered_stream, CAMEL_DATA_WRAPPER (part), cancellable);
camel_stream_flush (filtered_stream, cancellable, NULL);
g_object_unref (filtered_stream);
+
+ g_object_unref (part);
}
static void
emfq_write_text_html (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
EMFormatQuotePrivate *priv;
+ CamelMimePart *part;
priv = EM_FORMAT_QUOTE_GET_PRIVATE (emf);
+ part = em_part_get_mime_part (emp);
camel_stream_write_string (
stream, "\n<!-- text/html -->\n", cancellable, NULL);
@@ -786,14 +807,16 @@ emfq_write_text_html (EMFormat *emf,
em_format_format_text (
emf, filtered_stream,
- (CamelDataWrapper *) puri->part, cancellable);
+ (CamelDataWrapper *) part, cancellable);
camel_stream_flush (filtered_stream, cancellable, NULL);
g_object_unref (filtered_stream);
} else {
em_format_format_text (
emf, stream,
- (CamelDataWrapper *) puri->part, cancellable);
+ (CamelDataWrapper *) part, cancellable);
}
+
+ g_object_unref (part);
}
/****************************************************************************/
diff --git a/em-format/em-format.c b/em-format/em-format.c
index a7c2935..caf0cdb 100644
--- a/em-format/em-format.c
+++ b/em-format/em-format.c
@@ -92,9 +92,9 @@ static void emf_parse_post_headers (EMFormat *emf, CamelMimePart *part, GString
static void emf_parse_source (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
/* WRITERS */
-static void emf_write_text (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void emf_write_source (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void emf_write_error (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void emf_write_text (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void emf_write_source (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void emf_write_error (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
/**************************************************************************/
@@ -636,7 +636,7 @@ emf_parse_multipart_signed (EMFormat *emf,
emf, "%s",
local_error->message);
g_clear_error (&local_error);
- emf_parse_multipart_mixed (emf, part, part_id,info, cancellable);
+ emf_parse_multipart_mixed (emf, part, part_id, info, cancellable);
} else {
gint i, nparts, len = part_id->len;
gboolean secured;
@@ -792,7 +792,7 @@ emf_parse_message_deliverystatus (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
if (g_cancellable_is_cancelled (cancellable))
@@ -801,15 +801,14 @@ emf_parse_message_deliverystatus (EMFormat *emf,
len = part_id->len;
g_string_append (part_id, ".deliverystatus");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = emf_write_text;
- puri->mime_type = g_strdup ("text/html");
- puri->validity = info->validity ? camel_cipher_validity_clone (info->validity) : NULL;
- puri->validity_type = info->validity_type;
+ emp = em_part_new (emf, part, part_id->str, emf_write_text);
+ em_part_set_mime_type (emp, "text/html");
+ em_part_set_validity (emp, info->validity);
+ em_part_set_validity_type (emp, info->validity_type);
g_string_truncate (part_id, len);
- em_format_add_puri (emf, puri);
+ em_format_add_part_object (emf, emp);
}
static void
@@ -1044,16 +1043,15 @@ emf_parse_headers (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
len = part_id->len;
g_string_append (part_id, ".headers");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = info->handler->write_func;
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, info->handler->write_func);
+ em_part_set_mime_type (emp, "text/html");
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
}
@@ -1078,7 +1076,7 @@ emf_parse_source (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
if (g_cancellable_is_cancelled (cancellable))
@@ -1087,19 +1085,18 @@ emf_parse_source (EMFormat *emf,
len = part_id->len;
g_string_append (part_id, ".source");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = info->handler->write_func;
- puri->mime_type = g_strdup ("text/html");
- g_string_truncate (part_id, len);
+ emp = em_part_new (emf, part, part_id->str, info->handler->write_func);
+ em_part_set_mime_type (emp, "text/html");
+ em_format_add_part_object (emf, emp);
- em_format_add_puri (emf, puri);
+ g_string_truncate (part_id, len);
}
/**************************************************************************/
void
em_format_empty_writer (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -1109,48 +1106,62 @@ em_format_empty_writer (EMFormat *emf,
static void
emf_write_error (EMFormat* emf,
- EMFormatPURI* puri,
+ EMPart *emp,
CamelStream* stream,
EMFormatWriterInfo* info,
GCancellable* cancellable)
{
- camel_data_wrapper_decode_to_stream_sync ((CamelDataWrapper *) puri->part,
+ CamelMimePart *part;
+
+ part = em_part_get_mime_part (emp);
+ camel_data_wrapper_decode_to_stream_sync ((CamelDataWrapper *) part,
stream, cancellable, NULL);
+
+ g_object_unref (part);
}
static void
emf_write_text (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
CamelContentType *ct;
+ CamelMimePart *part;
- ct = camel_mime_part_get_content_type (puri->part);
+ part = em_part_get_mime_part (emp);
+ ct = camel_mime_part_get_content_type (part);
if (!camel_content_type_is (ct, "text", "plain")) {
camel_stream_write_string (stream, _("Cannot proccess non-text mime/part"),
cancellable, NULL);
+
+ g_object_unref (part);
return;
}
-
- camel_data_wrapper_decode_to_stream_sync ((CamelDataWrapper *) puri->part,
+
+ camel_data_wrapper_decode_to_stream_sync ((CamelDataWrapper *) part,
stream, cancellable, NULL);
+
+ g_object_unref (part);
}
static void
emf_write_source (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
+ CamelMimePart *part;
GByteArray *ba;
gchar *data;
g_return_if_fail (EM_IS_FORMAT (emf));
- ba = camel_data_wrapper_get_byte_array ((CamelDataWrapper *) puri->part);
+ part = em_part_get_mime_part (emp);
+ ba = camel_data_wrapper_get_byte_array ((CamelDataWrapper *) part);
+ g_object_unref (part);
data = g_strndup ((gchar *) ba->data, ba->len);
camel_stream_write_string (stream, data, cancellable, NULL);
@@ -1322,8 +1333,7 @@ em_format_finalize (GObject *object)
}
if (emf->mail_part_table) {
- /* This will destroy all the EMFormatPURI objects stored
- * inside!!!! */
+ /* This will destroy all the EMPartObjects stored inside!!!! */
g_hash_table_destroy (emf->mail_part_table);
emf->mail_part_table = NULL;
}
@@ -1430,9 +1440,9 @@ static void
mail_part_table_item_free (gpointer data)
{
GList *iter = data;
- EMFormatPURI *puri = iter->data;
+ EMPart *emp = iter->data;
- em_format_puri_free (puri);
+ g_object_unref (emp);
}
static void
@@ -1448,8 +1458,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) mail_part_table_item_free);
- /* No need to free the key, because it's owned and free'd by the PURI */
+ g_free, mail_part_table_item_free);
shell = e_shell_get_default ();
shell_settings = e_shell_get_shell_settings (shell);
@@ -1725,27 +1734,48 @@ em_format_remove_header_struct (EMFormat* emf,
em_format_remove_header (emf, header->name, header->value);
}
+/**
+ * em_format_add_part_object:
+ *
+ * @emf: an #EMFormat
+ * @emp: an #EMPart to be added
+ *
+ * Reference count of @emp is not increased, the #EMFormat takes
+ * ownership from caller.
+ */
void
-em_format_add_puri (EMFormat *emf,
- EMFormatPURI *puri)
+em_format_add_part_object (EMFormat *emf,
+ EMPart *emp)
{
GList *item;
+ gchar *uri;
g_return_if_fail (EM_IS_FORMAT (emf));
- g_return_if_fail (puri != NULL);
+ g_return_if_fail (EM_IS_PART (emp));
- emf->mail_part_list = g_list_append (emf->mail_part_list, puri);
+ emf->mail_part_list = g_list_append (emf->mail_part_list, emp);
item = g_list_last (emf->mail_part_list);
- g_hash_table_insert (emf->mail_part_table,
- puri->uri, item);
+ uri = em_part_get_uri (emp);
+ g_hash_table_insert (emf->mail_part_table, uri, item);
- d(printf("Added PURI %s\n", puri->uri));
+ d(printf("Added EMPart %s\n", uri));
}
-EMFormatPURI*
-em_format_find_puri (EMFormat *emf,
- const gchar *id)
+/**
+ * em_format_find_part_object:
+ *
+ * @emf: an #EMFormat object
+ * @id: an part URI or CID.
+ *
+ * Looks up EMPartObject by it's URI or CID.
+ *
+ * Returns: Referenced #EMPart that has to be unreferenced when no
+ * longer needed, or %NULL when no part with such %id is found.
+ */
+EMPart *
+em_format_find_part_object (EMFormat *emf,
+ const gchar *id)
{
GList *list_iter;
@@ -1756,9 +1786,11 @@ 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 = ((GList *) value)->data;
- if (g_strcmp0 (puri->cid, id) == 0)
- return puri;
+ EMPart *emp = ((GList *) value)->data;
+ gchar *cid = em_part_get_cid (emp);
+
+ if (g_strcmp0 (cid, id) == 0)
+ return g_object_ref (emp);
}
return NULL;
@@ -1766,7 +1798,7 @@ em_format_find_puri (EMFormat *emf,
list_iter = g_hash_table_lookup (emf->mail_part_table, id);
if (list_iter)
- return list_iter->data;
+ return g_object_ref (list_iter->data);
return NULL;
}
@@ -1872,7 +1904,7 @@ em_format_parse (EMFormat *emf,
GCancellable *cancellable)
{
GString *part_id;
- EMFormatPURI *puri;
+ EMPart *emp;
EMFormatParserInfo info = { 0 };
g_return_if_fail (EM_IS_FORMAT (emf));
@@ -1902,11 +1934,10 @@ em_format_parse (EMFormat *emf,
part_id = g_string_new (".message");
- /* Create a special PURI with entire message */
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI),
- (CamelMimePart *) emf->message, part_id->str);
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (emf, puri);
+ /* Create a special EMPart with entire message */
+ emp = em_part_new (emf, (CamelMimePart *) emf->message, part_id->str, NULL);
+ em_part_set_mime_type (emp, "text/plain");
+ em_format_add_part_object (emf, emp);
info.force_handler = TRUE;
em_format_parse_part_as (emf, CAMEL_MIME_PART (emf->message), part_id, &info,
@@ -1962,6 +1993,7 @@ em_format_parse_async (EMFormat *emf,
result = g_simple_async_result_new (G_OBJECT (emf), callback,
user_data, em_format_parse_async);
+
g_simple_async_result_run_in_thread (result, emf_start_async_parser,
G_PRIORITY_DEFAULT, cancellable);
}
@@ -2062,7 +2094,7 @@ em_format_format_error (EMFormat *emf,
const gchar *format,
...)
{
- EMFormatPURI *puri;
+ EMPart *emp;
CamelMimePart *part;
const EMFormatHandler *handler;
gchar *errmsg;
@@ -2084,14 +2116,16 @@ em_format_format_error (EMFormat *emf,
emf->priv->last_error++;
uri = g_strdup_printf (".error.%d", emf->priv->last_error);
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, uri);
- puri->mime_type = g_strdup ("text/html");
+
+ emp = em_part_new (emf, part, uri, NULL);
+ em_part_set_mime_type (emp, "text/html");
+
if (handler && handler->write_func)
- puri->write_func = handler->write_func;
+ em_part_set_write_func (emp, handler->write_func);
else
- puri->write_func = emf_write_error;
+ em_part_set_write_func (emp, emf_write_error);
- em_format_add_puri (emf, puri);
+ em_format_add_part_object (emf, emp);
g_free (uri);
g_object_unref (part);
@@ -2509,95 +2543,6 @@ em_format_redraw (EMFormat *emf)
/**************************************************************************/
-EMFormatPURI*
-em_format_puri_new (EMFormat *emf,
- gsize puri_size,
- CamelMimePart *part,
- const gchar *uri)
-{
- EMFormatPURI *puri;
-
- g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
- g_return_val_if_fail (puri_size >= sizeof (EMFormatPURI), NULL);
-
- puri = (EMFormatPURI *) g_malloc0 (puri_size);
- puri->emf = emf;
-
- if (part)
- puri->part = g_object_ref (part);
-
- if (uri)
- puri->uri = g_strdup (uri);
-
- return puri;
-}
-
-void
-em_format_puri_free (EMFormatPURI *puri)
-{
- g_return_if_fail (puri);
-
- if (puri->part)
- g_object_unref (puri->part);
-
- if (puri->uri)
- g_free (puri->uri);
-
- if (puri->cid)
- g_free (puri->cid);
-
- if (puri->mime_type)
- g_free (puri->mime_type);
-
- if (puri->validity)
- camel_cipher_validity_free (puri->validity);
-
- if (puri->validity_parent)
- camel_cipher_validity_free (puri->validity_parent);
-
- if (puri->free)
- puri->free(puri);
-
- g_free (puri);
-}
-
-
-void
-em_format_puri_write (EMFormatPURI *puri,
- CamelStream *stream,
- EMFormatWriterInfo *info,
- GCancellable *cancellable)
-{
- g_return_if_fail (puri);
- g_return_if_fail (CAMEL_IS_STREAM (stream));
-
- if (info->mode == EM_FORMAT_WRITE_MODE_SOURCE) {
- const EMFormatHandler *handler;
- handler = em_format_find_handler (puri->emf, "x-evolution/message/source");
- handler->write_func (puri->emf, puri, stream, info, cancellable);
- return;
- }
-
- if (puri->write_func) {
- puri->write_func (puri->emf, puri, stream, info, cancellable);
- } else {
- const EMFormatHandler *handler;
- const gchar *mime_type;
-
- if (puri->mime_type) {
- mime_type = puri->mime_type;
- } else {
- mime_type = (gchar *) "plain/text";
- }
-
- handler = em_format_find_handler (puri->emf, mime_type);
- if (handler && handler->write_func) {
- handler->write_func (puri->emf,
- puri, stream, info, cancellable);
- }
- }
-}
-
EMFormatHeader*
em_format_header_new (const gchar *name,
const gchar *value)
diff --git a/em-format/em-format.h b/em-format/em-format.h
index c9c38be..d9c27d8 100644
--- a/em-format/em-format.h
+++ b/em-format/em-format.h
@@ -60,26 +60,29 @@ typedef struct _EMFormat EMFormat;
typedef struct _EMFormatClass EMFormatClass;
typedef struct _EMFormatPrivate EMFormatPrivate;
-typedef struct _EMFormatPURI EMFormatPURI;
typedef struct _EMFormatHeader EMFormatHeader;
typedef struct _EMFormatHandler EMFormatHandler;
typedef struct _EMFormatParserInfo EMFormatParserInfo;
typedef struct _EMFormatWriterInfo EMFormatWriterInfo;
+typedef struct _EMPart EMPart;
+
typedef void (*EMFormatParseFunc) (EMFormat *emf,
CamelMimePart *part,
GString *part_id,
EMFormatParserInfo *info,
GCancellable *cancellable);
-typedef void (*EMFormatWriteFunc) (EMFormat *emf,
- EMFormatPURI *puri,
- CamelStream *stream,
- EMFormatWriterInfo *info,
- GCancellable *cancellable);
-typedef GtkWidget* (*EMFormatWidgetFunc) (EMFormat *emf,
- EMFormatPURI *puri,
- GCancellable *cancellable);
-
+/* FIXME: Redeclared in em-part-object.h */
+typedef void (*EMPartObjectWriteFunc)
+ (EMFormat *emf,
+ EMPart *empo,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
+ GCancellable *cancellable);
+typedef GtkWidget* (*EMPartObjectWidgetFunc)
+ (EMFormat *emf,
+ EMPart *empo,
+ GCancellable *cancellable);
typedef enum {
EM_FORMAT_HANDLER_INLINE = 1 << 0,
@@ -97,7 +100,7 @@ typedef enum {
struct _EMFormatHandler {
gchar *mime_type;
EMFormatParseFunc parse_func;
- EMFormatWriteFunc write_func;
+ EMPartObjectWriteFunc write_func;
EMFormatHandlerFlags flags;
EMFormatHandler *old;
@@ -124,7 +127,7 @@ struct _EMFormatWriterInfo {
gboolean headers_collapsable;
gboolean headers_collapsed;
- /* When TRUE, EMFormatWriteFunc's will put the content of the PURI part
+ /* When TRUE, EMPartObjectWriteFunc's will put the content of the EMPart
between EFH_HTML_HEADER and EFH_HTML_FOOTER */
gboolean with_html_header;
};
@@ -138,28 +141,6 @@ struct _EMFormatHeader {
#define EM_FORMAT_HEADER_BOLD (1<<0)
#define EM_FORMAT_HEADER_LAST (1<<4) /* reserve 4 slots */
-
-struct _EMFormatPURI {
- CamelMimePart *part;
-
- EMFormat *emf;
- EMFormatWriteFunc write_func;
- EMFormatWidgetFunc widget_func;
-
- gchar *uri;
- gchar *cid;
- gchar *mime_type;
-
- /* EM_FORMAT_VALIDITY_* flags */
- guint32 validity_type;
- CamelCipherValidity *validity;
- CamelCipherValidity *validity_parent;
-
- gboolean is_attachment;
-
- void (*free)(EMFormatPURI *puri); /* optional callback for freeing user-fields */
-};
-
struct _EMFormat {
GObject parent;
EMFormatPrivate *priv;
@@ -232,9 +213,9 @@ void em_format_remove_header (EMFormat *emf,
void em_format_remove_header_struct (EMFormat *emf,
const EMFormatHeader *header);
-void em_format_add_puri (EMFormat *emf,
- EMFormatPURI *puri);
-EMFormatPURI* em_format_find_puri (EMFormat *emf,
+void em_format_add_part_object (EMFormat *emf,
+ EMPart *empo);
+EMPart* em_format_find_part_object (EMFormat *emf,
const gchar *id);
void em_format_class_add_handler (EMFormatClass *emfc,
@@ -252,6 +233,11 @@ void em_format_parse (EMFormat *emf,
CamelFolder *folder,
GCancellable *cancellable);
+void em_format_write (EMFormat *emf,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
+ GCancellable *cancellable);
+
void em_format_parse_async (EMFormat *emf,
CamelMimeMessage *message,
CamelFolder *folder,
@@ -303,10 +289,10 @@ void em_format_empty_parser (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable);
-/* EMFormatWriteFunc that does nothing. Use it to disable
+/* EMPartObjectWriteFunc that does nothing. Use it to disable
* writing of a specific mime type parts */
void em_format_empty_writer (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *empo,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable);
@@ -314,17 +300,6 @@ void em_format_empty_writer (EMFormat *emf,
void em_format_redraw (EMFormat *emf);
-EMFormatPURI* em_format_puri_new (EMFormat *emf,
- gsize puri_size,
- CamelMimePart *part,
- const gchar *uri);
-void em_format_puri_free (EMFormatPURI *puri);
-
-void em_format_puri_write (EMFormatPURI *puri,
- CamelStream *stream,
- EMFormatWriterInfo *info,
- GCancellable *cancellable);
-
EMFormatHeader* em_format_header_new (const gchar *name,
const gchar *value);
void em_format_header_free (EMFormatHeader *header);
diff --git a/em-format/em-part.c b/em-format/em-part.c
new file mode 100644
index 0000000..26c4c4b
--- /dev/null
+++ b/em-format/em-part.c
@@ -0,0 +1,678 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "em-part.h"
+#include "em-format.h"
+
+G_DEFINE_TYPE (EMPart, em_part, G_TYPE_OBJECT);
+
+struct _EMPartPrivate {
+
+ CamelMimePart *part;
+
+ EMFormat *formatter;
+ EMPartWriteFunc write_func;
+ EMPartWidgetFunc widget_func;
+
+ gchar *uri;
+ gchar *cid;
+ gchar *mime_type;
+
+ /* EM_FORMAT_VALIDITY_* flags */
+ guint32 validity_type;
+ CamelCipherValidity *validity;
+ CamelCipherValidity *validity_parent;
+
+ gboolean is_attachment;
+
+ GMutex *mutex;
+};
+
+static void
+em_part_finalize (GObject *object)
+{
+ EMPartPrivate *priv = EM_PART (object)->priv;
+
+ g_mutex_lock (priv->mutex);
+
+ if (priv->cid) {
+ g_free (priv->cid);
+ priv->cid = NULL;
+ }
+
+ if (priv->formatter) {
+ g_object_unref (priv->formatter);
+ priv->formatter = NULL;
+ }
+
+ if (priv->mime_type) {
+ g_free (priv->mime_type);
+ priv->mime_type = NULL;
+ }
+
+ if (priv->part) {
+ g_object_unref (priv->part);
+ priv->part = NULL;
+ }
+
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->validity) {
+ camel_cipher_validity_free (priv->validity);
+ priv->validity = NULL;
+ }
+
+ if (priv->validity_parent) {
+ camel_cipher_validity_free (priv->validity_parent);
+ priv->validity_parent = NULL;
+ }
+
+ g_mutex_unlock (priv->mutex);
+ g_mutex_free (priv->mutex);
+}
+
+static void
+em_part_class_init (EMPartClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EMPartPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = em_part_finalize;
+
+}
+
+static void
+em_part_init (EMPart *emp)
+{
+ emp->priv = G_TYPE_INSTANCE_GET_PRIVATE (emp,
+ EM_TYPE_PART, EMPartPrivate);
+
+ emp->priv->mutex = g_mutex_new ();
+ emp->priv->cid = NULL;
+ emp->priv->formatter = NULL;
+ emp->priv->is_attachment = FALSE;
+ emp->priv->mime_type = NULL;
+ emp->priv->part = NULL;
+ emp->priv->uri = NULL;
+ emp->priv->validity = NULL;
+ emp->priv->validity_parent = NULL;
+ emp->priv->validity_type = 0;
+ emp->priv->widget_func = NULL;
+ emp->priv->write_func = NULL;
+}
+
+/**
+ * em_part_new:
+ * @emf: an #EMFormat
+ * @part: a #CamelMimePart which this objects wraps
+ * @uri: an URI of the object within hierarchy of mime parts
+ * @write_func: an #EMPartWriteFunc that will write parsed content of the
+ * @part to a stream, or %NULL.
+ *
+ * Constructs a new #EMPart.
+ *
+ * Returns: A new #EMPart, or %NULL on failure.
+ */
+EMPart *
+em_part_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func)
+{
+ EMPart *emp;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+ g_return_val_if_fail ((part == NULL) || CAMEL_IS_MIME_PART (part), NULL);
+ g_return_val_if_fail (uri && *uri, NULL);
+
+ emp = EM_PART (g_object_new (EM_TYPE_PART, NULL));
+
+ em_part_set_mime_part (emp, part);
+ em_part_set_formatter (emp, emf);
+ em_part_set_uri (emp, uri);
+
+ if (write_func)
+ em_part_set_write_func (emp, write_func);
+
+ return emp;
+}
+
+void
+em_part_set_formatter (EMPart *emp,
+ EMFormat *emf)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+ g_return_if_fail (EM_IS_FORMAT (emf));
+
+ g_mutex_lock (emp->priv->mutex);
+
+ g_object_ref (emf);
+
+ if (emp->priv->formatter)
+ g_object_unref (emp->priv->formatter);
+
+ emp->priv->formatter = emf;
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+/**
+ * em_part_get_formatter:
+ *
+ * @emp: an #EMPart
+ *
+ * Returns: An #EMFormat that has to ne unreferenced when no longer needed.
+ */
+EMFormat *
+em_part_get_formatter (EMPart *emp)
+{
+ EMFormat *formatter;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->formatter)
+ formatter = g_object_ref (emp->priv->formatter);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return formatter;
+}
+
+
+/**
+ * em_part_set_mime_part:
+ *
+ * @emp: an #EMPart
+ * @widget_func: a #CamelMimePart, or %NULL to unset.
+ */
+void
+em_part_set_mime_part (EMPart *emp,
+ CamelMimePart *part)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+ g_return_if_fail ((part == NULL) || CAMEL_IS_MIME_PART (part));
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (part)
+ g_object_ref (part);
+
+ if (emp->priv->part)
+ g_object_unref (emp->priv->part);
+
+ emp->priv->part = part;
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+/**
+ * em_part_get_mime_part:
+ *
+ * @emp: an #EMPart
+ *
+ * Returns: A #CamelMimePart that has to be unreferenced when no longer needed.
+ */
+CamelMimePart *
+em_part_get_mime_part (EMPart *emp)
+{
+ CamelMimePart *part;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->part)
+ part = g_object_ref (emp->priv->part);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return part;
+}
+
+/**
+ * em_part_set_write_func:
+ *
+ * @emp: an #EMPart
+ * @write_func: an #EMPartWriteFunc, or %NULL to unset.
+ */
+void
+em_part_set_write_func (EMPart *emp,
+ EMPartWriteFunc write_func)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+ emp->priv->write_func = write_func;
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+EMPartWriteFunc
+em_part_get_write_func (EMPart *emp)
+{
+ EMPartWriteFunc write_func;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+ write_func = emp->priv->write_func;
+ g_mutex_unlock (emp->priv->mutex);
+
+ return write_func;
+}
+
+/**
+ * em_part_set_widget_func:
+ *
+ * @emp: an #EMPart
+ * @widget_func: an #EMPartWidgetFunc, or %NULL to unset.
+ */
+void
+em_part_set_widget_func (EMPart *emp,
+ EMPartWidgetFunc widget_func)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+ emp->priv->widget_func = widget_func;
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+EMPartWidgetFunc
+em_part_get_widget_func (EMPart *emp)
+{
+ EMPartWidgetFunc widget_func;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+ widget_func = emp->priv->widget_func;
+ g_mutex_unlock (emp->priv->mutex);
+
+ return widget_func;
+}
+
+void
+em_part_set_uri (EMPart *emp,
+ const gchar *uri)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+ g_return_if_fail (uri && *uri);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->uri)
+ g_free (emp->priv->uri);
+
+ emp->priv->uri = g_strdup (uri);
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+gchar *
+em_part_get_uri (EMPart *emp)
+{
+ gchar *uri = NULL;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->uri)
+ uri = g_strdup (emp->priv->uri);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return uri;
+}
+
+/**
+ * em_part_set_cid:
+ *
+ * @emp: an #EMPart
+ * @cid: part content ID, or %NULL to unset
+ */
+void
+em_part_set_cid (EMPart *emp,
+ const gchar *cid)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->cid)
+ g_free (emp->priv->cid);
+
+ if (cid)
+ emp->priv->cid = g_strdup (cid);
+ else
+ emp->priv->cid = NULL;
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+gchar *
+em_part_get_cid (EMPart *emp)
+{
+ gchar *cid = NULL;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (cid)
+ cid = g_strdup (emp->priv->cid);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return cid;
+}
+
+void
+em_part_set_mime_type (EMPart *emp,
+ const gchar *mime_type)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+ g_return_if_fail (mime_type && *mime_type);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->mime_type)
+ g_free (emp->priv->mime_type);
+
+ emp->priv->mime_type = g_strdup (mime_type);
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+gchar *
+em_part_get_mime_type (EMPart *emp)
+{
+ gchar *mime_type = NULL;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (mime_type)
+ mime_type = g_strdup (emp->priv->mime_type);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return mime_type;
+}
+
+
+
+void
+em_part_set_validity_type (EMPart *emp,
+ guint32 validity_type)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+ emp->priv->validity_type = validity_type;
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+guint32
+em_part_get_validity_type (EMPart *emp)
+{
+ guint32 validity_type;
+
+ g_return_val_if_fail (EM_IS_PART (emp), 0);
+
+ g_mutex_lock (emp->priv->mutex);
+ validity_type = emp->priv->validity_type;
+ g_mutex_unlock (emp->priv->mutex);
+
+ return validity_type;
+}
+
+/**
+ * em_part_set_validity:
+ *
+ * @emp: an #EMPart
+ * @validity: a #CamelCipherValidity object, or %NULL to unset
+ */
+void
+em_part_set_validity (EMPart *emp,
+ CamelCipherValidity *validity)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->validity)
+ camel_cipher_validity_free (emp->priv->validity);
+
+ if (validity)
+ emp->priv->validity = camel_cipher_validity_clone (validity);
+ else
+ emp->priv->validity = NULL;
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+/**
+ * em_part_get_validity:
+ *
+ * @emp: an #EMPart
+ *
+ * Returns: A copy of #CamelCipherValidity. Must be freed when no longer needed.
+ */
+CamelCipherValidity *
+em_part_get_validity (EMPart *emp)
+{
+ CamelCipherValidity *validity = NULL;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->validity)
+ validity = camel_cipher_validity_clone (emp->priv->validity);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return validity;
+}
+
+/**
+ * em_part_set_validity_parent:
+ *
+ * @emp: an #EMPart
+ * @validity: a #CamelCipherValidity object, or %NULL to unset
+ */
+void
+em_part_set_validity_parent (EMPart *emp,
+ CamelCipherValidity *validity)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->validity_parent)
+ camel_cipher_validity_free (emp->priv->validity_parent);
+
+ if (validity)
+ emp->priv->validity_parent = camel_cipher_validity_clone (validity);
+ else
+ emp->priv->validity_parent = NULL;
+
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+/**
+ * em_part_get_validity_parent:
+ *
+ * @emp: an #EMPart
+ *
+ * Returns: A copy of #CamelCipherValidity. Must be freed when no longer needed.
+ */
+CamelCipherValidity *
+em_part_get_validity_parent (EMPart *emp)
+{
+ CamelCipherValidity *validity = NULL;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+
+ if (emp->priv->validity_parent)
+ validity = camel_cipher_validity_clone (emp->priv->validity_parent);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ return validity;
+}
+
+void
+em_part_set_is_attachment (EMPart *emp,
+ gboolean is_attachment)
+{
+ g_return_if_fail (EM_IS_PART (emp));
+
+ g_mutex_lock (emp->priv->mutex);
+ emp->priv->is_attachment = is_attachment;
+ g_mutex_unlock (emp->priv->mutex);
+}
+
+gboolean
+em_part_get_is_attachment (EMPart *emp)
+{
+ gboolean is_attachment;
+
+ g_return_val_if_fail (EM_IS_PART (emp), FALSE);
+
+ g_mutex_lock (emp->priv->mutex);
+ is_attachment = emp->priv->is_attachment;
+ g_mutex_unlock (emp->priv->mutex);
+
+ return is_attachment;
+}
+
+/**
+ * em_part_get_widget:
+ *
+ * @emp: an #EMPart
+ * @cancellable: optional #GCancellable object, or %NULL
+ *
+ * Calls assigned #EMPartWidgetFunc to get GtkWidget
+ * representing content of the mime part.
+ *
+ * Returns: a #GtkWidget that has to be unreferenced when no longer needed.
+ */
+GtkWidget *
+em_part_get_widget (EMPart *emp,
+ GCancellable *cancellable)
+{
+ EMPartWidgetFunc widget_func;
+ EMFormat *formatter;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (EM_IS_PART (emp), NULL);
+
+ g_mutex_lock (emp->priv->mutex);
+ widget_func = emp->priv->widget_func;
+ formatter = g_object_ref (emp->priv->formatter);
+ g_mutex_unlock (emp->priv->mutex);
+
+ if (!widget_func)
+ return NULL;
+
+ g_object_ref (emp);
+ widget = widget_func (formatter, emp, cancellable);
+ g_object_unref (emp);
+
+ return widget;
+}
+
+/**
+ * em_part_write:
+ *
+ * @emp: an #EMPart
+ * @stream: a #CamelStream to which the data should be written
+ * @info: additional information for write function, or %NULL
+ * @cancellable: optional #GCancellable object, or %NULL
+ *
+ * Calls assigned #EMPartWriteFunc to write parsed
+ * content of mime part to the @stream.
+ */
+void
+em_part_write (EMPart *emp,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
+ GCancellable *cancellable)
+{
+ EMPartWriteFunc write_func;
+ EMFormat *formatter;
+ gchar *mime_type = NULL;
+
+ g_return_if_fail (EM_IS_PART (emp));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+
+ g_mutex_lock (emp->priv->mutex);
+ write_func = emp->priv->write_func;
+ formatter = g_object_ref (emp->priv->formatter);
+
+ if (emp->priv->mime_type)
+ mime_type = g_strdup (emp->priv->mime_type);
+
+ g_mutex_unlock (emp->priv->mutex);
+
+ g_object_ref (emp);
+
+ if (info->mode == EM_FORMAT_WRITE_MODE_SOURCE) {
+ const EMFormatHandler *handler;
+ handler = em_format_find_handler (formatter, "x-evolution/message/source");
+ handler->write_func (formatter, emp, stream, info, cancellable);
+
+ } else {
+
+ if (write_func) {
+ write_func (formatter, emp, stream, info, cancellable);
+ } else {
+ const EMFormatHandler *handler;
+
+ if (!mime_type)
+ mime_type = g_strdup ("plain/text");
+
+ handler = em_format_find_handler (formatter, mime_type);
+
+ if (handler && handler->write_func) {
+ handler->write_func (formatter, emp,
+ stream, info, cancellable);
+ }
+ }
+ }
+
+ g_object_unref (emp);
+ g_object_unref (formatter);
+
+ if (mime_type)
+ g_free (mime_type);
+}
diff --git a/em-format/em-part.h b/em-format/em-part.h
new file mode 100644
index 0000000..2b20be5
--- /dev/null
+++ b/em-format/em-part.h
@@ -0,0 +1,140 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EM_PART_H
+#define EM_PART_H
+
+#include <camel/camel.h>
+#include <glib-object.h>
+
+#include <em-format.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_PART \
+ (em_part_get_type ())
+#define EM_PART(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_PART, EMPart))
+#define EM_PART_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_PART, EMPartClass))
+#define EM_IS_PART(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_PART))
+#define EM_IS_PART_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_PART))
+#define EM_PART_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_PART, EMPartClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMPart EMPart;
+typedef struct _EMPartClass EMPartClass;
+typedef struct _EMPartPrivate EMPartPrivate;
+
+
+typedef void (*EMPartWriteFunc) (EMFormat *emf,
+ EMPart *emp,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
+ GCancellable *cancellable);
+typedef GtkWidget* (*EMPartWidgetFunc) (EMFormat *emf,
+ EMPart *emp,
+ GCancellable *cancellable);
+
+
+struct _EMPart {
+ GObject parent;
+ EMPartPrivate *priv;
+};
+
+struct _EMPartClass {
+ GObjectClass parent_class;
+
+};
+
+EMPart* em_part_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func);
+
+GType em_part_get_type ();
+
+void em_part_set_formatter (EMPart *emp,
+ EMFormat *emf);
+
+EMFormat* em_part_get_formatter (EMPart *emp);
+
+void em_part_set_mime_part (EMPart *emp,
+ CamelMimePart *part);
+CamelMimePart* em_part_get_mime_part (EMPart * emp);
+
+void em_part_set_write_func (EMPart *emp,
+ EMPartWriteFunc write_func);
+EMPartWriteFunc em_part_get_write_func (EMPart *emp);
+
+void em_part_set_widget_func (EMPart *emp,
+ EMPartWidgetFunc widget_func);
+EMPartWidgetFunc em_part_get_widget_func (EMPart *emp);
+
+void em_part_set_uri (EMPart *emp,
+ const gchar *uri);
+gchar* em_part_get_uri (EMPart *emp);
+
+void em_part_set_cid (EMPart *emp,
+ const gchar *cid);
+gchar* em_part_get_cid (EMPart *emp);
+
+void em_part_set_mime_type
+ (EMPart *emp,
+ const gchar *mime_type);
+gchar* em_part_get_mime_type (EMPart *emp);
+
+void em_part_set_validity_type
+ (EMPart *emp,
+ guint32 validity_type);
+guint32 em_part_get_validity_type
+ (EMPart *emp);
+
+void em_part_set_validity (EMPart *emp,
+ CamelCipherValidity *validity);
+CamelCipherValidity* em_part_get_validity (EMPart *emp);
+
+void em_part_set_validity_parent
+ (EMPart *emp,
+ CamelCipherValidity *validity);
+CamelCipherValidity* em_part_get_validity_parent
+ (EMPart *emp);
+
+void em_part_set_is_attachment
+ (EMPart *emp,
+ gboolean is_attachment);
+gboolean em_part_get_is_attachment
+ (EMPart *emp);
+
+GtkWidget* em_part_get_widget (EMPart *emp,
+ GCancellable *cancellable);
+
+void em_part_write (EMPart *emp,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
+ GCancellable *cancellable);
+
+G_END_DECLS
+
+#endif /* EM_PART_H */
\ No newline at end of file
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 48119c1..3ca6fc4 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -83,6 +83,7 @@ mailinclude_HEADERS = \
em-folder-utils.h \
em-format-hook.h \
em-format-html-display.h \
+ em-format-html-display-parts.h \
em-format-html-print.h \
em-format-html.h \
em-search-context.h \
@@ -149,6 +150,7 @@ libevolution_mail_la_SOURCES = \
em-folder-utils.c \
em-format-hook.c \
em-format-html-display.c \
+ em-format-html-display-parts.c \
em-format-html-print.c \
em-format-html.c \
em-search-context.c \
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index ea59a6d..4220058 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -11,6 +11,8 @@
#include "em-format-html.h"
+#include <em-format/em-part.h>
+
#include <e-util/e-icon-factory.h>
#include <e-util/e-util.h>
@@ -23,7 +25,7 @@ struct _EMailRequestPrivate {
EMFormatHTML *efh;
CamelStream *output_stream;
- EMFormatPURI *puri;
+ EMPart *emp;
gchar *mime_type;
gint content_length;
@@ -45,6 +47,8 @@ handle_mail_request (GSimpleAsyncResult *res,
GInputStream *stream;
GByteArray *ba;
gchar *part_id;
+ EMFormatWriterInfo info = {0};
+ gchar *val;
if (g_cancellable_is_cancelled (cancellable))
return;
@@ -57,34 +61,33 @@ handle_mail_request (GSimpleAsyncResult *res,
part_id = g_hash_table_lookup (request->priv->uri_query, "part_id");
- if (part_id) {
- /* original part_id is owned by the GHashTable */
- part_id = soup_uri_decode (part_id);
- request->priv->puri = em_format_find_puri (emf, part_id);
+ val = g_hash_table_lookup (request->priv->uri_query, "headers_collapsed");
+ if (val)
+ info.headers_collapsed = atoi (val);
- if (request->priv->puri) {
- EMFormatWriterInfo info = {0};
- gchar *val;
+ val = g_hash_table_lookup (request->priv->uri_query, "headers_collapsable");
+ if (val)
+ info.headers_collapsable = atoi (val);
- val = g_hash_table_lookup (request->priv->uri_query, "headers_collapsed");
- if (val)
- info.headers_collapsed = atoi (val);
+ val = g_hash_table_lookup (request->priv->uri_query, "mode");
+ if (val)
+ info.mode = atoi (val);
- val = g_hash_table_lookup (request->priv->uri_query, "headers_collapsable");
- if (val)
- info.headers_collapsable = atoi (val);
+ val = g_hash_table_lookup (request->priv->uri_query, "with_html_headers");
+ if (val)
+ info.with_html_header = atoi (val);
+ else
+ info.with_html_header = FALSE; /* By default this is TRUE!! */
- val = g_hash_table_lookup (request->priv->uri_query, "mode");
- if (val)
- info.mode = atoi (val);
- val = g_hash_table_lookup (request->priv->uri_query, "with_html_headers");
- if (val)
- info.with_html_header = atoi (val);
- else
- info.with_html_header = TRUE; /* By default this is TRUE!! */
+ if (part_id) {
+ /* original part_id is owned by the GHashTable */
+ part_id = soup_uri_decode (part_id);
+ request->priv->emp = em_format_find_part_object (emf, part_id);
- em_format_puri_write (request->priv->puri, request->priv->output_stream, &info, NULL);
+ if (request->priv->emp) {
+ em_part_write (request->priv->emp, request->priv->output_stream,
+ &info, NULL);
} else {
g_warning ("Failed to lookup requested part '%s' - this should not happen!", part_id);
}
@@ -436,7 +439,7 @@ e_mail_request_init (EMailRequest *request)
request->priv->efh = NULL;
request->priv->output_stream = NULL;
request->priv->uri_query = NULL;
- request->priv->puri = NULL;
+ request->priv->emp = NULL;
request->priv->mime_type = NULL;
request->priv->content_length = 0;
}
@@ -471,6 +474,11 @@ mail_request_finalize (GObject *object)
request->priv->ret_data = NULL;
}
+ if (request->priv->emp) {
+ g_object_unref (request->priv->emp);
+ request->priv->emp = NULL;
+ }
+
G_OBJECT_CLASS (e_mail_request_parent_class)->finalize (object);
}
@@ -526,7 +534,7 @@ mail_request_send_async (SoupRequest *request,
formatters = g_object_get_data (G_OBJECT (session), "formatters");
g_return_if_fail (formatters != NULL);
- /* Get HTML content of given PURI part */
+ /* Get HTML content of given EMPart */
if (g_strcmp0 (uri->scheme, "mail") == 0) {
gchar *uri_str;
@@ -613,17 +621,27 @@ static const gchar*
mail_request_get_content_type (SoupRequest *request)
{
EMailRequest *emr = E_MAIL_REQUEST (request);
- gchar *mime_type;
+ gchar *mime_type, *part_mime_type;
+
+ if (emr->priv->emp)
+ part_mime_type = em_part_get_mime_type (emr->priv->emp);
+ else
+ part_mime_type = NULL;
if (emr->priv->mime_type) {
mime_type = g_strdup (emr->priv->mime_type);
- } else if (!emr->priv->puri) {
+ } else if (!emr->priv->emp) {
mime_type = g_strdup ("text/html");
- } else if (!emr->priv->puri->mime_type) {
- CamelContentType *ct = camel_mime_part_get_content_type (emr->priv->puri->part);
+ } else if (!part_mime_type) {
+ CamelMimePart *part;
+ CamelContentType *ct;
+
+ part = em_part_get_mime_part (emr->priv->emp);
+ ct = camel_mime_part_get_content_type (part);
mime_type = camel_content_type_simple (ct);
+ g_object_unref (part);
} else {
- mime_type = g_strdup (emr->priv->puri->mime_type);
+ mime_type = em_part_get_mime_type (emr->priv->emp);
}
if (g_strcmp0 (mime_type, "text/html") == 0) {
diff --git a/mail/em-format-html-display-parts.c b/mail/em-format-html-display-parts.c
new file mode 100644
index 0000000..d7c7965
--- /dev/null
+++ b/mail/em-format-html-display-parts.c
@@ -0,0 +1,722 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "em-format-html-display-parts.h"
+
+#include <glib.h>
+
+struct _EMPartAttachmentBarPrivate {
+ EAttachmentStore *store;
+
+ GMutex *mutex;
+};
+
+G_DEFINE_TYPE (EMPartAttachmentBar, em_part_attachment_bar, EM_TYPE_PART);
+
+static void
+em_part_attachment_bar_finalize (GObject *object)
+{
+ EMPartAttachmentBarPrivate *priv =
+ EM_PART_ATTACHMENT_BAR (object)->priv;
+
+ g_mutex_lock (priv->mutex);
+
+ if (priv->store) {
+ g_object_unref (priv->store);
+ priv->store = NULL;
+ }
+
+ g_mutex_unlock (priv->mutex);
+ g_mutex_free (priv->mutex);
+}
+
+static void
+em_part_attachment_bar_class_init (EMPartAttachmentBarClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EMPartAttachmentBarPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = em_part_attachment_bar_finalize;
+}
+
+
+static void
+em_part_attachment_bar_init (EMPartAttachmentBar *empab)
+{
+
+ empab->priv = G_TYPE_INSTANCE_GET_PRIVATE (empab,
+ EM_TYPE_PART_ATTACHMENT_BAR, EMPartAttachmentBarPrivate);
+
+ empab->priv->store = NULL;
+
+ empab->priv->mutex = g_mutex_new ();
+}
+
+EMPart*
+em_part_attachment_bar_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func)
+{
+ EMPart *emp;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+ g_return_val_if_fail ((part == NULL) || CAMEL_IS_MIME_PART (part), NULL);
+ g_return_val_if_fail (uri && *uri, NULL);
+
+ emp = (EMPart *) g_object_new (EM_TYPE_PART_ATTACHMENT_BAR, NULL);
+ em_part_set_formatter (emp, emf);
+ em_part_set_mime_part (emp, part);
+ em_part_set_uri (emp, uri);
+ em_part_set_write_func (emp, write_func);
+
+ return emp;
+}
+
+void
+em_part_attachment_bar_set_store (EMPartAttachmentBar *empab,
+ EAttachmentStore *store)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT_BAR (empab));
+ g_return_if_fail ((store == NULL) || E_IS_ATTACHMENT_STORE (store));
+
+ g_mutex_lock (empab->priv->mutex);
+
+ if (store)
+ g_object_ref (store);
+
+ if (empab->priv->store)
+ g_object_unref (empab->priv->store);
+
+ empab->priv->store = store;
+
+ g_mutex_unlock (empab->priv->mutex);
+}
+
+
+EAttachmentStore*
+em_part_attachment_bar_get_store (EMPartAttachmentBar *empab)
+{
+ EAttachmentStore *store = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT_BAR (empab), NULL);
+
+ g_mutex_lock (empab->priv->mutex);
+ if (empab->priv->store)
+ store = g_object_ref (empab->priv->store);
+ g_mutex_unlock (empab->priv->mutex);
+
+ return store;
+}
+
+/******************************************************************************/
+
+struct _EMPartAttachmentPrivate {
+
+ gchar *snoop_mime_type;
+
+ /* The > and v buttons */
+ GtkWidget *forward;
+ GtkWidget *down;
+ gint shown:1;
+
+ EAttachment *attachment;
+ gchar *view_part_id;
+ gchar *description;
+
+ CamelStream *mstream;
+
+ const EMFormatHandler *handler;
+
+ GMutex *mutex;
+};
+
+G_DEFINE_TYPE (EMPartAttachment, em_part_attachment, EM_TYPE_PART);
+
+static void
+em_part_attachment_finalize (GObject *object)
+{
+ EMPartAttachmentPrivate *priv = EM_PART_ATTACHMENT (object)->priv;
+
+ g_mutex_lock (priv->mutex);
+
+ if (priv->attachment) {
+ g_object_unref (priv->attachment);
+ priv->attachment = NULL;
+ }
+
+ if (priv->description) {
+ g_free (priv->description);
+ priv->description = NULL;
+ }
+
+ if (priv->down) {
+ g_object_unref (priv->down);
+ priv->down = NULL;
+ }
+
+ if (priv->forward) {
+ g_object_unref (priv->forward);
+ priv->forward = NULL;
+ }
+
+ if (priv->mstream) {
+ g_object_unref (priv->mstream);
+ priv->mstream = NULL;
+ }
+
+ if (priv->snoop_mime_type) {
+ g_free (priv->snoop_mime_type);
+ priv->snoop_mime_type = NULL;
+ }
+
+ if (priv->view_part_id) {
+ g_free (priv->view_part_id);
+ priv->view_part_id = NULL;
+ }
+
+ g_mutex_unlock (priv->mutex);
+ g_mutex_free (priv->mutex);
+}
+
+static void
+em_part_attachment_class_init (EMPartAttachmentClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EMPartAttachmentPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = em_part_attachment_finalize;
+}
+
+static void
+em_part_attachment_init (EMPartAttachment *empa)
+{
+ empa->priv = G_TYPE_INSTANCE_GET_PRIVATE (empa,
+ EM_TYPE_PART_ATTACHMENT, EMPartAttachmentPrivate);
+
+ empa->priv->attachment = NULL;
+ empa->priv->description = NULL;
+ empa->priv->down = NULL;
+ empa->priv->forward = NULL;
+ empa->priv->mstream = NULL;
+ empa->priv->shown = FALSE;
+ empa->priv->snoop_mime_type = NULL;
+ empa->priv->view_part_id = NULL;
+ empa->priv->handler = NULL;
+
+ empa->priv->mutex = g_mutex_new ();
+}
+
+EMPart*
+em_part_attachment_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func)
+{
+ EMPart *emp;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+ g_return_val_if_fail ((part == NULL) || (CAMEL_IS_MIME_PART (part)), NULL);
+ g_return_val_if_fail (uri && *uri, NULL);
+
+ emp = (EMPart *) g_object_new (EM_TYPE_PART_ATTACHMENT, NULL);
+ em_part_set_formatter (emp, emf);
+ em_part_set_mime_part (emp, part);
+ em_part_set_uri (emp, uri);
+ em_part_set_write_func (emp, write_func);
+
+ return emp;
+}
+
+void
+em_part_attachment_set_snoop_mime_type (EMPartAttachment *empa,
+ const gchar *snoop_mime_type)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (empa->priv->snoop_mime_type)
+ g_free (empa->priv->snoop_mime_type);
+
+ if (snoop_mime_type)
+ empa->priv->snoop_mime_type = g_strdup (snoop_mime_type);
+ else
+ empa->priv->snoop_mime_type = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+gchar*
+em_part_attachment_get_snoop_mime_part (EMPartAttachment *empa)
+{
+ gchar *mime_type = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->snoop_mime_type)
+ mime_type = g_strdup (empa->priv->snoop_mime_type);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return mime_type;
+}
+
+void
+em_part_attachment_set_forward_widget (EMPartAttachment *empa,
+ GtkWidget *forward)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+ g_return_if_fail ((forward == NULL) || GTK_IS_WIDGET (forward));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (forward)
+ g_object_ref (forward);
+
+ if (empa->priv->forward)
+ g_object_unref (empa->priv->forward);
+
+ if (forward)
+ empa->priv->forward = forward;
+ else
+ empa->priv->forward = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GtkWidget*
+em_part_attachment_get_forward_widget (EMPartAttachment *empa)
+{
+ GtkWidget *widget = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->down)
+ widget = g_object_ref (empa->priv->down);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return widget;
+}
+
+
+void
+em_part_attachment_set_down_widget (EMPartAttachment *empa,
+ GtkWidget *down)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+ g_return_if_fail ((down == NULL) || GTK_IS_WIDGET (down));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (down)
+ g_object_ref (down);
+
+ if (empa->priv->down)
+ g_object_unref (empa->priv->down);
+
+ if (down)
+ empa->priv->down = down;
+ else
+ empa->priv->down = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GtkWidget*
+em_part_attachment_get_down_widget (EMPartAttachment *empa)
+{
+ GtkWidget *widget = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->down)
+ widget = g_object_ref (empa->priv->down);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return widget;
+}
+
+void
+em_part_attachment_set_is_shown (EMPartAttachment *empa,
+ gboolean is_shown)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+ empa->priv->shown = is_shown;
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+gboolean
+em_part_attachment_get_is_shown (EMPartAttachment *empa)
+{
+ gboolean is_shown;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), FALSE);
+
+ g_mutex_lock (empa->priv->mutex);
+ is_shown = empa->priv->shown;
+ g_mutex_unlock (empa->priv->mutex);
+
+ return is_shown;
+}
+
+void
+em_part_attachment_set_attachment (EMPartAttachment *empa,
+ EAttachment *attachment)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+ g_return_if_fail ((attachment == NULL) || E_IS_ATTACHMENT (attachment));
+
+ if (attachment)
+ g_object_ref (attachment);
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (empa->priv->attachment)
+ g_object_unref (empa->priv->attachment);
+
+ if (attachment)
+ empa->priv->attachment = attachment;
+ else
+ empa->priv->attachment = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+EAttachment*
+em_part_attachment_get_attachment (EMPartAttachment *empa)
+{
+ EAttachment *attachment = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->mutex)
+ attachment = g_object_ref (empa->priv->attachment);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return attachment;
+}
+
+void
+em_part_attachment_set_view_part_id (EMPartAttachment *empa,
+ const gchar *view_part_id)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (empa->priv->view_part_id)
+ g_free (empa->priv->view_part_id);
+
+ if (view_part_id)
+ empa->priv->view_part_id = g_strdup (view_part_id);
+ else
+ empa->priv->view_part_id = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+gchar*
+em_part_attachment_get_view_part_id (EMPartAttachment *empa)
+{
+ gchar *view_part_id = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->view_part_id)
+ view_part_id = g_strdup (view_part_id);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return view_part_id;
+}
+
+void
+em_part_attachment_set_description (EMPartAttachment *empa,
+ const gchar *description)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (empa->priv->description)
+ g_free (empa->priv->description);
+
+ if (description)
+ empa->priv->description = g_strdup (description);
+ else
+ empa->priv->description = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+gchar*
+em_part_attachment_get_description (EMPartAttachment *empa)
+{
+ gchar *description = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->description)
+ description = g_strdup (empa->priv->description);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return description;
+}
+
+void
+em_part_attachment_set_mstream (EMPartAttachment *empa,
+ CamelStream *mstream)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+ g_return_if_fail ((mstream == NULL) || CAMEL_IS_STREAM (mstream));
+
+ g_mutex_lock (empa->priv->mutex);
+ if (mstream)
+ g_object_ref (mstream);
+
+ if (empa->priv->mstream)
+ g_object_unref (empa->priv->mstream);
+
+ empa->priv->mstream = mstream;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+CamelStream*
+em_part_attachment_get_mstream (EMPartAttachment *empa)
+{
+ CamelStream *stream = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->mstream)
+ stream = g_object_ref (empa->priv->mstream);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return stream;
+}
+
+void
+em_part_attachment_set_handler (EMPartAttachment *empa,
+ const EMFormatHandler *handler)
+{
+ g_return_if_fail (EM_IS_PART_ATTACHMENT (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+ empa->priv->handler = handler;
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+const EMFormatHandler*
+em_part_attachment_get_handler (EMPartAttachment *empa)
+{
+ const EMFormatHandler *handler;
+
+ g_return_val_if_fail (EM_IS_PART_ATTACHMENT (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ handler = empa->priv->handler;
+ g_mutex_unlock (empa->priv->mutex);
+
+ return handler;
+}
+
+
+
+/******************************************************************************/
+
+struct _EMPartSMIMEPrivate {
+ gchar *description;
+ gint signature;
+ GtkWidget *widget;
+
+ GMutex *mutex;
+};
+
+G_DEFINE_TYPE (EMPartSMIME, em_part_smime, EM_TYPE_PART);
+
+
+static void
+em_part_smime_finalize (GObject *object)
+{
+ EMPartSMIMEPrivate *priv = EM_PART_SMIME (object)->priv;
+
+ g_mutex_lock (priv->mutex);
+
+ if (priv->description) {
+ g_free (priv->description);
+ priv->description = NULL;
+ }
+
+ if (priv->widget) {
+ g_object_unref (priv->widget);
+ priv->widget = NULL;
+ }
+
+ g_mutex_unlock (priv->mutex);
+ g_mutex_free (priv->mutex);
+}
+
+static void
+em_part_smime_class_init (EMPartSMIMEClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EMPartSMIMEPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = em_part_smime_finalize;
+}
+
+static void
+em_part_smime_init (EMPartSMIME *emps)
+{
+ emps->priv = G_TYPE_INSTANCE_GET_PRIVATE (emps,
+ EM_TYPE_PART_SMIME, EMPartSMIMEPrivate);
+
+ emps->priv->description = NULL;
+ emps->priv->signature = 0;
+ emps->priv->widget = NULL;
+
+ emps->priv->mutex = g_mutex_new ();
+}
+
+EMPart*
+em_part_smime_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func)
+{
+ EMPart *emp;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+ g_return_val_if_fail ((part == NULL) || CAMEL_IS_MIME_PART (part), NULL);
+ g_return_val_if_fail (uri && *uri, NULL);
+
+ emp = (EMPart *) g_object_new (EM_TYPE_PART_SMIME, NULL);
+ em_part_set_formatter (emp, emf);
+ em_part_set_mime_part (emp, part);
+ em_part_set_uri (emp, uri);
+ em_part_set_write_func (emp, write_func);
+
+ return emp;
+}
+
+void
+em_part_smime_set_description (EMPartSMIME *emps,
+ const gchar *description)
+{
+ g_return_if_fail (EM_IS_PART_SMIME (emps));
+
+ g_mutex_lock (emps->priv->mutex);
+
+ if (emps->priv->description)
+ g_free (emps->priv->description);
+
+ if (description)
+ emps->priv->description = g_strdup (description);
+ else
+ emps->priv->description = NULL;
+
+ g_mutex_unlock (emps->priv->mutex);
+}
+
+gchar*
+em_part_smime_get_description (EMPartSMIME *emps)
+{
+ gchar *description = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_SMIME (emps), NULL);
+
+ g_mutex_lock (emps->priv->mutex);
+ if (emps->priv->description)
+ description = g_strdup (emps->priv->description);
+ g_mutex_unlock (emps->priv->mutex);
+
+ return description;
+}
+
+void
+em_part_smime_set_signature (EMPartSMIME *emps,
+ gint signature)
+{
+ g_return_if_fail (EM_IS_PART_SMIME (emps));
+
+ g_mutex_lock (emps->priv->mutex);
+ emps->priv->signature = signature;
+ g_mutex_unlock (emps->priv->mutex);
+}
+
+gint
+em_part_smime_get_signature (EMPartSMIME *emps)
+{
+ gint signature;
+
+ g_return_val_if_fail (EM_IS_PART_SMIME (emps), 0);
+
+ g_mutex_lock (emps->priv->mutex);
+ signature = emps->priv->signature;
+ g_mutex_unlock (emps->priv->mutex);
+
+ return signature;
+}
+
+void
+em_part_smime_set_widget (EMPartSMIME *emps,
+ GtkWidget *widget)
+{
+ g_return_if_fail (EM_IS_PART_SMIME (emps));
+ g_return_if_fail ((widget == NULL) || GTK_IS_WIDGET (widget));
+
+ if (widget)
+ g_object_ref (widget);
+
+ g_mutex_lock (emps->priv->mutex);
+
+ if (emps->priv->widget)
+ g_object_unref (emps->priv->widget);
+
+ emps->priv->widget = widget;
+
+ g_mutex_unlock (emps->priv->mutex);
+}
+
+GtkWidget*
+em_part_smime_get_widget (EMPartSMIME *emps)
+{
+ GtkWidget *widget = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_SMIME (emps), NULL);
+
+ g_mutex_lock (emps->priv->mutex);
+ if (emps->priv->widget)
+ widget = g_object_ref (emps->priv->widget);
+ g_mutex_unlock (emps->priv->mutex);
+
+ return widget;
+}
diff --git a/mail/em-format-html-display-parts.h b/mail/em-format-html-display-parts.h
new file mode 100644
index 0000000..78967d0
--- /dev/null
+++ b/mail/em-format-html-display-parts.h
@@ -0,0 +1,242 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EM_FORMAT_HTML_DISPLAY_PARTS_H
+#define EM_FORMAT_HTML_DISPLAY_PARTS_H
+
+#include <em-format/em-part.h>
+#include <widgets/misc/e-attachment-store.h>
+#include <widgets/misc/e-attachment.h>
+#include <camel/camel.h>
+#include <gtk/gtk.h>
+
+
+/* Standard GObject macros */
+#define EM_TYPE_PART_ATTACHMENT_BAR \
+ (em_part_attachment_bar_get_type ())
+#define EM_PART_ATTACHMENT_BAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_PART_ATTACHMENT_BAR, EMPartAttachmentBar))
+#define EM_PART_ATTACHMENT_BAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_PART_ATTACHMENT_BAR, EMPartAttachmentBarClass))
+#define EM_IS_PART_ATTACHMENT_BAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_PART_ATTACHMENT_BAR))
+#define EM_IS_PART_ATTACHMENT_BAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_PART_ATTACHMENT_BAR))
+#define EM_PART_ATTACHMENT_BAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_PART_ATTACHMENT_BAR, EMPartAttachmentBarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMPartAttachmentBar EMPartAttachmentBar;
+typedef struct _EMPartAttachmentBarClass EMPartAttachmentBarClass;
+typedef struct _EMPartAttachmentBarPrivate EMPartAttachmentBarPrivate;
+
+struct _EMPartAttachmentBar {
+ EMPart parent;
+ EMPartAttachmentBarPrivate *priv;
+};
+
+struct _EMPartAttachmentBarClass {
+ EMPartClass parent_class;
+};
+
+EMPart* em_part_attachment_bar_new
+ (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func);
+
+GType em_part_attachment_bar_get_type ();
+
+void em_part_attachment_bar_set_store
+ (EMPartAttachmentBar *empab,
+ EAttachmentStore *store);
+
+EAttachmentStore* em_part_attachment_bar_get_store
+ (EMPartAttachmentBar *empab);
+
+G_END_DECLS
+
+/******************************************************************************/
+
+/* Standard GObject macros */
+#define EM_TYPE_PART_ATTACHMENT \
+ (em_part_attachment_get_type ())
+#define EM_PART_ATTACHMENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_PART_ATTACHMENT, EMPartAttachment))
+#define EM_PART_ATTACHMENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_PART_ATTACHMENT, EMPartAttachmentClass))
+#define EM_IS_PART_ATTACHMENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_PART_ATTACHMENT))
+#define EM_IS_PART_ATTACHMENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_PART_ATTACHMENT))
+#define EM_PART_ATTACHMENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_PART_ATTACHMENT, EMPartAttachmentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMPartAttachment EMPartAttachment;
+typedef struct _EMPartAttachmentClass EMPartAttachmentClass;
+typedef struct _EMPartAttachmentPrivate EMPartAttachmentPrivate;
+
+struct _EMPartAttachment {
+ EMPart parent;
+ EMPartAttachmentPrivate *priv;
+};
+
+struct _EMPartAttachmentClass {
+ EMPartClass parent_class;
+};
+
+EMPart* em_part_attachment_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func);
+
+GType em_part_attachment_get_type ();
+
+void em_part_attachment_set_snoop_mime_type
+ (EMPartAttachment *empa,
+ const gchar *snoop_mime_type);
+gchar* em_part_attachment_get_snoop_mime_part
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_forward_widget
+ (EMPartAttachment *empa,
+ GtkWidget *forward);
+GtkWidget* em_part_attachment_get_forward_widget
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_down_widget
+ (EMPartAttachment *empa,
+ GtkWidget *down);
+GtkWidget* em_part_attachment_get_down_widget
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_is_shown
+ (EMPartAttachment *empa,
+ gboolean is_shown);
+gboolean em_part_attachment_get_is_shown
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_attachment
+ (EMPartAttachment *empa,
+ EAttachment *attachment);
+EAttachment* em_part_attachment_get_attachment
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_view_part_id
+ (EMPartAttachment *empa,
+ const gchar *view_part_id);
+gchar* em_part_attachment_get_view_part_id
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_description
+ (EMPartAttachment *empa,
+ const gchar *description);
+gchar* em_part_attachment_get_description
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_mstream
+ (EMPartAttachment *empa,
+ CamelStream *mstream);
+CamelStream* em_part_attachment_get_mstream
+ (EMPartAttachment *empa);
+
+void em_part_attachment_set_handler
+ (EMPartAttachment *empa,
+ const EMFormatHandler *handler);
+
+const EMFormatHandler* em_part_attachment_get_handler
+ (EMPartAttachment *empa);
+
+G_END_DECLS
+
+/******************************************************************************/
+
+/* Standard GObject macros */
+#define EM_TYPE_PART_SMIME \
+ (em_part_smime_get_type ())
+#define EM_PART_SMIME(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_PART_SMIME, EMPartSMIME))
+#define EM_PART_SMIME_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_PART_SMIME, EMPartSMIMEClass))
+#define EM_IS_PART_SMIME(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_PART_SMIME))
+#define EM_IS_PART_SMIME_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_PART_SMIME))
+#define EM_PART_SMIME_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_PART_SMIME, EMPartSMIMEClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMPartSMIME EMPartSMIME;
+typedef struct _EMPartSMIMEClass EMPartSMIMEClass;
+typedef struct _EMPartSMIMEPrivate EMPartSMIMEPrivate;
+
+struct _EMPartSMIME {
+ EMPart parent;
+ EMPartSMIMEPrivate *priv;
+};
+
+struct _EMPartSMIMEClass {
+ EMPartClass parent_class;
+};
+
+EMPart* em_part_smime_new
+ (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func);
+
+GType em_part_smime_get_type ();
+
+void em_part_smime_set_description
+ (EMPartSMIME *emps,
+ const gchar *description);
+gchar* em_part_smime_get_description
+ (EMPartSMIME *emps);
+
+void em_part_smime_set_signature
+ (EMPartSMIME *emps,
+ gint signature);
+gint em_part_smime_get_signature
+ (EMPartSMIME *emps);
+
+void em_part_smime_set_widget
+ (EMPartSMIME *emps,
+ GtkWidget *widget);
+GtkWidget* em_part_smime_get_widget
+ (EMPartSMIME *emps);
+
+G_END_DECLS
+
+#endif /* EM_FORMAT_HTML_DISPLAY_PARTS_H */
\ No newline at end of file
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index e989019..130b4bd 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -60,6 +60,7 @@
#include "e-mail-display.h"
#include "e-mail-attachment-bar.h"
#include "em-format-html-display.h"
+#include "em-format-html-display-parts.h"
#include "em-utils.h"
#include "widgets/misc/e-attachment.h"
#include "widgets/misc/e-attachment-button.h"
@@ -113,11 +114,10 @@ static void efhd_parse_attachment (EMFormat *emf, CamelMimePart *part, GString *
static void efhd_parse_secure (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
static void efhd_parse_optional (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 GtkWidget* efhd_attachment_bar (EMFormat *emf, EMPart *emp, GCancellable *cancellable);
+static GtkWidget* efhd_attachment_button (EMFormat *emf, EMPart *emp, GCancellable *cancellable);
+static GtkWidget* efhd_attachment_optional (EMFormat *emf, EMPart *emp, GCancellable *cancellable);
-static void efhd_free_attach_puri_data (EMFormatPURI *puri);
static void efhd_builtin_init (EMFormatHTMLDisplayClass *efhc);
static gpointer parent_class;
@@ -126,7 +126,7 @@ static EAttachmentStore*
find_parent_attachment_store (EMFormatHTMLDisplay *efhd, GString *part_id)
{
EMFormat *emf = (EMFormat *) efhd;
- EMFormatAttachmentBarPURI *abp;
+ EMPartAttachmentBar *empab;
gchar *tmp, *pos;
GList *item;
@@ -151,55 +151,27 @@ find_parent_attachment_store (EMFormatHTMLDisplay *efhd, GString *part_id)
g_free (tmp);
- abp = (EMFormatAttachmentBarPURI *) item->data;
+ empab = item->data;
- if (abp)
- return abp->store;
+ if (empab)
+ return em_part_attachment_bar_get_store (empab);
else
return NULL;
}
static void
-efhd_attachment_bar_puri_free (EMFormatPURI *puri)
-{
- EMFormatAttachmentBarPURI *abp;
-
- abp = (EMFormatAttachmentBarPURI *) puri;
-
- if (abp->store) {
- g_object_unref (abp->store);
- abp->store = NULL;
- }
-}
-
-static void
-efhd_xpkcs7mime_free (EMFormatPURI *puri)
-{
- EMFormatSMIMEPURI *sp = (EMFormatSMIMEPURI *) puri;
-
- if (sp->widget)
- gtk_widget_destroy (sp->widget);
-
- if (sp->description)
- g_free (sp->description);
-
- if (sp->valid)
- camel_cipher_validity_free (sp->valid);
-}
-
-static void
efhd_xpkcs7mime_info_response (GtkWidget *widget,
guint button,
- EMFormatSMIMEPURI *po)
+ EMPartSMIME *emps)
{
gtk_widget_destroy (widget);
- po->widget = NULL;
+ em_part_smime_set_widget (emps, NULL);
}
#if defined (HAVE_NSS) && defined (ENABLE_SMIME)
static void
efhd_xpkcs7mime_viewcert_clicked (GtkWidget *button,
- EMFormatSMIMEPURI *po)
+ EMPartSMIME *emps)
{
CamelCipherCertInfo *info = g_object_get_data((GObject *)button, "e-cert-info");
ECert *ec = NULL;
@@ -209,6 +181,7 @@ efhd_xpkcs7mime_viewcert_clicked (GtkWidget *button,
if (ec != NULL) {
GtkWidget *w = certificate_viewer_show (ec);
+ GtkWidget *widget;
/* oddly enough certificate_viewer_show doesn't ... */
gtk_widget_show (w);
@@ -216,8 +189,12 @@ efhd_xpkcs7mime_viewcert_clicked (GtkWidget *button,
w, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
- if (w && po->widget)
- gtk_window_set_transient_for ((GtkWindow *) w, (GtkWindow *) po->widget);
+ widget = em_part_smime_get_widget (emps);
+ if (w && widget)
+ gtk_window_set_transient_for ((GtkWindow *) w, (GtkWindow *) widget);
+
+ if (widget)
+ g_object_unref (widget);
g_object_unref (ec);
} else {
@@ -229,7 +206,7 @@ efhd_xpkcs7mime_viewcert_clicked (GtkWidget *button,
static void
efhd_xpkcs7mime_add_cert_table (GtkWidget *grid,
GQueue *certlist,
- EMFormatSMIMEPURI *po)
+ EMPartSMIME *emps)
{
GList *head, *link;
GtkTable *table;
@@ -291,31 +268,39 @@ efhd_xpkcs7mime_add_cert_table (GtkWidget *grid,
static void
efhd_xpkcs7mime_validity_clicked (GtkWidget *button,
- EMFormatPURI *puri)
+ EMPartSMIME *emps)
{
- EMFormatSMIMEPURI *po = (EMFormatSMIMEPURI *) puri;
GtkBuilder *builder;
GtkWidget *grid, *w;
+ GtkWidget *part_widget;
+ CamelCipherValidity *validity;
- if (po->widget)
+ part_widget = em_part_smime_get_widget (emps);
+ if (part_widget) {
+ g_object_unref (part_widget);
/* FIXME: window raise? */
return;
+ }
+
+ validity = em_part_get_validity ((EMPart *) emps);
builder = gtk_builder_new ();
e_load_ui_builder_definition (builder, "mail-dialogs.ui");
- po->widget = e_builder_get_widget(builder, "message_security_dialog");
+ part_widget = e_builder_get_widget(builder, "message_security_dialog");
+ em_part_smime_set_widget (emps, part_widget);
grid = e_builder_get_widget(builder, "signature_grid");
- w = gtk_label_new (_(smime_sign_table[po->valid->sign.status].description));
+ w = gtk_label_new (_(smime_sign_table[validity->sign.status].description));
gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
gtk_container_add (GTK_CONTAINER (grid), w);
- if (po->valid->sign.description) {
+ if (validity->sign.description) {
GtkTextBuffer *buffer;
buffer = gtk_text_buffer_new (NULL);
- gtk_text_buffer_set_text (buffer, po->valid->sign.description, strlen (po->valid->sign.description));
+ gtk_text_buffer_set_text (buffer, validity->sign.description,
+ strlen (validity->sign.description));
w = g_object_new (gtk_scrolled_window_get_type (),
"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
"vscrollbar_policy", GTK_POLICY_AUTOMATIC,
@@ -335,20 +320,21 @@ efhd_xpkcs7mime_validity_clicked (GtkWidget *button,
}
if (!g_queue_is_empty (&po->valid->sign.signers))
- efhd_xpkcs7mime_add_cert_table (grid, &po->valid->sign.signers, po);
+ efhd_xpkcs7mime_add_cert_table (grid, &validity->sign.signers, emps);
gtk_widget_show_all (grid);
grid = e_builder_get_widget(builder, "encryption_grid");
- w = gtk_label_new (_(smime_encrypt_table[po->valid->encrypt.status].description));
+ w = gtk_label_new (_(smime_encrypt_table[validity->encrypt.status].description));
gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
gtk_container_add (GTK_CONTAINER (grid), w);
- if (po->valid->encrypt.description) {
+ if (validity->encrypt.description) {
GtkTextBuffer *buffer;
buffer = gtk_text_buffer_new (NULL);
- gtk_text_buffer_set_text (buffer, po->valid->encrypt.description, strlen (po->valid->encrypt.description));
+ gtk_text_buffer_set_text (buffer, validity->encrypt.description,
+ strlen (validity->encrypt.description));
w = g_object_new (gtk_scrolled_window_get_type (),
"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
"vscrollbar_policy", GTK_POLICY_AUTOMATIC,
@@ -368,38 +354,47 @@ efhd_xpkcs7mime_validity_clicked (GtkWidget *button,
}
if (!g_queue_is_empty (&po->valid->encrypt.encrypters))
- efhd_xpkcs7mime_add_cert_table (grid, &po->valid->encrypt.encrypters, po);
+ efhd_xpkcs7mime_add_cert_table (grid,
+ &validity->encrypt.encrypters, emps);
gtk_widget_show_all (grid);
g_object_unref (builder);
g_signal_connect (
- po->widget, "response",
- G_CALLBACK (efhd_xpkcs7mime_info_response), po);
+ part_widget, "response",
+ G_CALLBACK(efhd_xpkcs7mime_info_response), emps);
+ gtk_widget_show (part_widget);
- gtk_widget_show (po->widget);
+ g_object_unref (part_widget);
+ camel_cipher_validity_free (validity);
}
static GtkWidget*
efhd_xpkcs7mime_button (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
GCancellable *cancellable)
{
GtkWidget *box, *button, *layout, *widget;
- EMFormatSMIMEPURI *po = (EMFormatSMIMEPURI *) puri;
+ EMPartSMIME *emps = (EMPartSMIME *) emp;
const gchar *icon_name;
+ gchar *description;
+ CamelCipherValidity *validity;
+
+ validity = em_part_get_validity (emp);
+ if (!validity)
+ return NULL;
/* FIXME: need to have it based on encryption and signing too */
- if (po->valid->sign.status != 0)
- icon_name = smime_sign_table[po->valid->sign.status].icon;
+ if (validity->sign.status != 0)
+ icon_name = smime_sign_table[validity->sign.status].icon;
else
- icon_name = smime_encrypt_table[po->valid->encrypt.status].icon;
+ icon_name = smime_encrypt_table[validity->encrypt.status].icon;
box = gtk_event_box_new ();
- if (po->valid->sign.status != 0)
+ if (validity->sign.status != 0)
gtk_widget_override_background_color (box, GTK_STATE_FLAG_NORMAL,
- &smime_sign_colour[po->valid->sign.status]);
+ &smime_sign_colour[validity->sign.status]);
layout = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_container_add (GTK_CONTAINER (box), layout);
@@ -407,17 +402,21 @@ efhd_xpkcs7mime_button (EMFormat *emf,
button = gtk_button_new ();
gtk_box_pack_start (GTK_BOX (layout), button, FALSE, FALSE, 0);
g_signal_connect (button, "clicked",
- G_CALLBACK (efhd_xpkcs7mime_validity_clicked), puri);
+ G_CALLBACK (efhd_xpkcs7mime_validity_clicked), emp);
widget = gtk_image_new_from_icon_name (
icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_button_set_image (GTK_BUTTON (button), widget);
- widget = gtk_label_new (po->description);
+ description = em_part_smime_get_description (emps);
+ widget = gtk_label_new (description);
gtk_box_pack_start (GTK_BOX (layout), widget, FALSE, FALSE, 0);
gtk_widget_show_all (box);
+ g_free (description);
+ camel_cipher_validity_free (validity);
+
return box;
}
@@ -465,8 +464,9 @@ efhd_parse_attachment (EMFormat *emf,
{
gchar *text, *html;
EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) emf;
- EMFormatAttachmentPURI *puri;
+ EMPartAttachment *empa;
EAttachmentStore *store;
+ EAttachment *attachment;
const EMFormatHandler *handler;
CamelContentType *ct;
gchar *mime_type;
@@ -496,39 +496,46 @@ efhd_parse_attachment (EMFormat *emf,
g_free (text);
g_free (mime_type);
- puri = (EMFormatAttachmentPURI*) em_format_puri_new (
- emf, sizeof (EMFormatAttachmentPURI), part, part_id->str);
- puri->puri.free = efhd_free_attach_puri_data;
- puri->puri.widget_func = efhd_attachment_button;
- puri->shown = (handler && em_format_is_inline (emf, part_id->str, part, handler));
- puri->snoop_mime_type = em_format_snoop_type (part);
- puri->attachment = e_attachment_new ();
- puri->attachment_view_part_id = g_strdup (part_id->str);
- puri->description = html;
- puri->handle = handler;
- if (info->validity)
- puri->puri.validity = camel_cipher_validity_clone (info->validity);
+ attachment = e_attachment_new ();
+ empa = EM_PART_ATTACHMENT (em_part_attachment_new (emf, part,
+ part_id->str, NULL));
+ em_part_set_widget_func ((EMPart *) empa, efhd_attachment_button);
+ em_part_attachment_set_is_shown (empa,
+ (handler && em_format_is_inline (emf, part_id->str, part, handler)));
+ em_part_attachment_set_snoop_mime_type (empa, em_format_snoop_type (part));
+ em_part_attachment_set_attachment (empa, attachment);
+ em_part_attachment_set_view_part_id (empa, part_id->str);
+ em_part_attachment_set_description (empa, html);
+ em_part_attachment_set_handler (empa, handler);
+ em_part_set_validity ((EMPart *) empa, info->validity);
cid = camel_mime_part_get_content_id (part);
- if (cid)
- puri->puri.cid = g_strdup_printf ("cid:%s", cid);
+ if (cid) {
+ gchar *new_cid = g_strdup_printf ("cid:%s", cid);
+ em_part_set_cid ((EMPart *) empa, new_cid);
+ g_free (new_cid);
+ }
if (handler) {
CamelContentType *ct;
- puri->puri.write_func = handler->write_func;
+ em_part_set_write_func ((EMPart *) empa, handler->write_func);
/* This mime_type is important for WebKit to determine content type.
* We have converted text/ * to text/html, other (binary) formats remained
* untouched. */
ct = camel_content_type_decode (handler->mime_type);
if (g_strcmp0 (ct->type, "text") == 0)
- puri->puri.mime_type = g_strdup ("text/html");
- else
- puri->puri.mime_type = camel_content_type_simple (ct);
+ em_part_set_mime_type ((EMPart *) empa, "text/html");
+ else {
+ gchar *ct_s = camel_content_type_simple (ct);
+ em_part_set_mime_type ((EMPart *) empa, ct_s);
+ g_free (ct_s);
+ }
+
camel_content_type_unref (ct);
}
- em_format_add_puri (emf, (EMFormatPURI *) puri);
+ em_format_add_part_object (emf, (EMPart *) empa);
/* Though it is an attachment, we still might be able to parse it and
* so discover some parts that we might be event able to display. */
@@ -537,34 +544,34 @@ efhd_parse_attachment (EMFormat *emf,
(handler->flags & EM_FORMAT_HANDLER_INLINE_DISPOSITION))) {
EMFormatParserInfo attachment_info = { .handler = handler,
.is_attachment = TRUE };
- handler->parse_func (emf, puri->puri.part, part_id, &attachment_info, cancellable);
+ handler->parse_func (emf, part, part_id, &attachment_info, cancellable);
}
- e_attachment_set_mime_part (puri->attachment, part);
- e_attachment_set_shown (puri->attachment, puri->shown);
- if (puri->puri.validity) {
- e_attachment_set_signed (puri->attachment, puri->puri.validity->sign.status);
- e_attachment_set_encrypted (puri->attachment, puri->puri.validity->encrypt.status);
+ e_attachment_set_mime_part (attachment, part);
+ e_attachment_set_shown (attachment, em_part_attachment_get_is_shown (empa));
+ if (info->validity) {
+ e_attachment_set_signed (attachment, info->validity->sign.status);
+ e_attachment_set_encrypted (attachment, info->validity->encrypt.status);
}
- e_attachment_set_can_show (puri->attachment, puri->handle != NULL && puri->handle->write_func);
+ e_attachment_set_can_show (attachment, handler != NULL && handler->write_func);
store = find_parent_attachment_store (efhd, part_id);
- e_attachment_store_add_attachment (store, puri->attachment);
+ e_attachment_store_add_attachment (store, attachment);
if (emf->folder && emf->folder->summary && emf->message_uid) {
- CamelDataWrapper *dw = camel_medium_get_content (CAMEL_MEDIUM (puri->puri.part));
+ CamelDataWrapper *dw = camel_medium_get_content (CAMEL_MEDIUM (part));
GByteArray *ba;
ba = camel_data_wrapper_get_byte_array (dw);
if (ba) {
size = ba->len;
- if (camel_mime_part_get_encoding (puri->puri.part) == CAMEL_TRANSFER_ENCODING_BASE64)
+ if (camel_mime_part_get_encoding (part) == CAMEL_TRANSFER_ENCODING_BASE64)
size = size / 1.37;
}
}
load_data = g_new0 (struct attachment_load_data, 1);
- load_data->attachment = g_object_ref (puri->attachment);
+ load_data->attachment = g_object_ref (attachment);
load_data->flag = e_flag_new ();
e_flag_clear (load_data->flag);
@@ -581,9 +588,9 @@ efhd_parse_attachment (EMFormat *emf,
if (size != 0) {
GFileInfo *fileinfo;
- fileinfo = e_attachment_get_file_info (puri->attachment);
+ fileinfo = e_attachment_get_file_info (attachment);
g_file_info_set_size (fileinfo, size);
- e_attachment_set_file_info (puri->attachment, fileinfo);
+ e_attachment_set_file_info (attachment, fileinfo);
}
g_string_truncate (part_id, len);
@@ -596,35 +603,42 @@ efhd_parse_optional (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatAttachmentPURI *puri;
+ EMPartAttachment *empa;
+ EAttachment *attachment;
+ CamelStream *stream;
gint len;
len = part_id->len;
g_string_append (part_id, ".optional");
- puri = (EMFormatAttachmentPURI *) em_format_puri_new (
- emf, sizeof (EMFormatAttachmentPURI), part, part_id->str);
- puri->puri.free = efhd_free_attach_puri_data;
- puri->puri.widget_func = efhd_attachment_optional;
- puri->attachment_view_part_id = g_strdup (part_id->str);
- puri->handle = em_format_find_handler (emf, "text/plain");
- puri->shown = FALSE;
- puri->snoop_mime_type = "text/plain";
- puri->attachment = e_attachment_new ();
- e_attachment_set_mime_part (puri->attachment, puri->puri.part);
- puri->description = g_strdup(_("Evolution cannot render this email as it is too "
- "large to process. You can view it unformatted or "
- "with an external text editor."));
+ attachment = e_attachment_new ();
+ empa = (EMPartAttachment *) em_part_attachment_new (
+ emf, part, part_id->str, NULL);
+ em_part_attachment_set_view_part_id (empa, part_id->str);
+ em_part_attachment_set_handler (empa, em_format_find_handler (emf, "text/plain"));
+ em_part_attachment_set_is_shown (empa, FALSE);
+ em_part_attachment_set_snoop_mime_type (empa, "text/plain");
+ em_part_attachment_set_attachment (empa, attachment);
+ em_part_set_widget_func ((EMPart *) empa, efhd_attachment_optional);
- puri->mstream = CAMEL_STREAM_MEM (camel_stream_mem_new ());
+ e_attachment_set_mime_part (attachment, part);
+ em_part_attachment_set_description (empa,
+ N_("Evolution cannot render this email as it is too "
+ "large to process. You can view it unformatted or "
+ "with an external text editor."));
+
+
+ stream = camel_stream_mem_new ();
+ em_part_attachment_set_mstream (empa, stream);
+
camel_data_wrapper_decode_to_stream_sync ((CamelDataWrapper *) part,
- (CamelStream *) puri->mstream, cancellable, NULL);
+ (CamelStream *) stream, cancellable, NULL);
if (info->validity) {
- puri->puri.validity = camel_cipher_validity_clone (info->validity);
+ em_part_set_validity ((EMPart *) empa, info->validity);
}
- em_format_add_puri (emf, (EMFormatPURI *) puri);
+ em_format_add_part_object (emf, (EMPart *) empa);
g_string_truncate (part_id, len);
}
@@ -640,15 +654,13 @@ efhd_parse_secure (EMFormat *emf,
&& (info->validity->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE
|| info->validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)) {
GString *buffer;
- EMFormatSMIMEPURI *pobj;
+ EMPart *emp;
- pobj = (EMFormatSMIMEPURI *) em_format_puri_new (
- emf, sizeof (EMFormatSMIMEPURI), part, part_id->str);
- pobj->puri.free = efhd_xpkcs7mime_free;
- pobj->valid = camel_cipher_validity_clone (info->validity);
- pobj->puri.widget_func = efhd_xpkcs7mime_button;
-
- em_format_add_puri (emf, (EMFormatPURI*) pobj);
+ emp = em_part_smime_new (emf, part, part_id->str, NULL);
+ em_part_set_widget_func (emp, efhd_xpkcs7mime_button);
+ em_part_set_validity (emp, info->validity);
+
+ em_format_add_part_object (emf, emp);
buffer = g_string_new ("");
@@ -677,7 +689,8 @@ efhd_parse_secure (EMFormat *emf,
g_string_append (buffer, gettext (desc));
}
- pobj->description = g_string_free (buffer, FALSE);
+ em_part_smime_set_description ((EMPartSMIME *) emp, buffer->str);
+ g_string_free (buffer, TRUE);
}
}
@@ -788,20 +801,25 @@ efhd_message_prefix (EMFormat *emf,
time_t date;
gchar *iconpath, *due_date_str;
GString *buffer;
- EMFormatAttachmentPURI *puri;
+ EMPartAttachment *empa;
- if (emf->folder == NULL || emf->message_uid == NULL
- || (flag = camel_folder_get_message_user_tag(emf->folder, emf->message_uid, "follow-up")) == NULL
- || flag[0] == 0)
+ if ((emf->folder == NULL) || (emf->message_uid == NULL)
+ || ((flag = camel_folder_get_message_user_tag (emf->folder,
+ emf->message_uid, "follow-up")) == NULL)
+ || (flag[0] == 0))
return;
- puri = (EMFormatAttachmentPURI *) em_format_puri_new (
- emf, sizeof (EMFormatAttachmentPURI), part, ".message_prefix");
-
- puri->attachment_view_part_id = g_strdup (part_id->str);
+ empa = (EMPartAttachment *) em_part_attachment_new (
+ emf, part, ".message_prefix", NULL);
+ em_part_attachment_set_view_part_id (empa, part_id->str);
comp = camel_folder_get_message_user_tag(emf->folder, emf->message_uid, "completed-on");
- iconpath = e_icon_factory_get_icon_filename (comp && comp[0] ? "stock_mail-flag-for-followup-done" : "stock_mail-flag-for-followup", GTK_ICON_SIZE_MENU);
+ iconpath = e_icon_factory_get_icon_filename (
+ comp && comp[0] ?
+ "stock_mail-flag-for-followup-done" :
+ "stock_mail-flag-for-followup",
+ GTK_ICON_SIZE_MENU);
+
if (iconpath) {
gchar *classid;
@@ -810,7 +828,7 @@ efhd_message_prefix (EMFormat *emf,
part_id->str,
comp && comp[0] ? "comp" : "uncomp");
- puri->puri.uri = classid;
+ em_part_set_uri ((EMPart *) empa, classid);
g_free (classid);
}
@@ -826,7 +844,8 @@ efhd_message_prefix (EMFormat *emf,
flag, _("Completed on"),
due_date_str ? due_date_str : "???");
g_free (due_date_str);
- } else if ((due = camel_folder_get_message_user_tag(emf->folder, emf->message_uid, "due-by")) != NULL && due[0]) {
+ } else if ((due = camel_folder_get_message_user_tag (emf->folder,
+ emf->message_uid, "due-by")) != NULL && due[0]) {
time_t now;
date = camel_header_decode_date (due, NULL);
@@ -850,7 +869,8 @@ efhd_message_prefix (EMFormat *emf,
g_string_append (buffer, flag);
}
- puri->description = g_string_free (buffer, FALSE);
+ em_part_attachment_set_description (empa, buffer->str);
+ g_string_free (buffer, TRUE);
}
/* ********************************************************************** */
@@ -858,10 +878,11 @@ efhd_message_prefix (EMFormat *emf,
/* attachment button callback */
static GtkWidget*
efhd_attachment_button (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
GCancellable *cancellable)
{
- EMFormatAttachmentPURI *info = (EMFormatAttachmentPURI *) puri;
+ EMPartAttachment *empa = (EMPartAttachment *) emp;
+ EAttachment *attachment;
GtkWidget *widget;
/* FIXME: handle default shown case */
@@ -870,29 +891,38 @@ efhd_attachment_button (EMFormat *emf,
if (g_cancellable_is_cancelled (cancellable))
return NULL;
- if (!info || info->forward) {
+ widget = em_part_attachment_get_forward_widget (empa);
+ if (widget) {
g_warning ("unable to expand the attachment\n");
+ g_object_unref (widget);
return NULL;
}
+ g_object_unref (widget);
+ attachment = em_part_attachment_get_attachment (empa);
widget = e_attachment_button_new ();
e_attachment_button_set_attachment (
- E_ATTACHMENT_BUTTON (widget), info->attachment);
+ E_ATTACHMENT_BUTTON (widget), attachment);
gtk_widget_set_can_focus (widget, TRUE);
gtk_widget_show (widget);
+ g_object_unref (attachment);
+
return widget;
}
static GtkWidget*
efhd_attachment_bar (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
GCancellable *cancellable)
{
- EMFormatAttachmentBarPURI *abp = (EMFormatAttachmentBarPURI *) puri;
+ EMPartAttachmentBar *empab = (EMPartAttachmentBar *) emp;
GtkWidget *widget;
+ EAttachmentStore *store;
- widget = e_mail_attachment_bar_new (abp->store);
+ store = em_part_attachment_bar_get_store (empab);
+ widget = e_mail_attachment_bar_new (store);
+ g_object_unref (store);
return widget;
}
@@ -904,7 +934,8 @@ efhd_message_add_bar (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatAttachmentBarPURI *puri;
+ EMPart *emp;
+ EAttachmentStore *store;
gint len;
if (g_cancellable_is_cancelled (cancellable))
@@ -912,15 +943,18 @@ efhd_message_add_bar (EMFormat *emf,
len = part_id->len;
g_string_append (part_id, ".attachment-bar");
- puri = (EMFormatAttachmentBarPURI *) em_format_puri_new (
- emf, sizeof (EMFormatAttachmentBarPURI), part, part_id->str);
- puri->puri.widget_func = efhd_attachment_bar;
- puri->puri.free = efhd_attachment_bar_puri_free;
- puri->store = E_ATTACHMENT_STORE (e_attachment_store_new ());
- em_format_add_puri (emf, (EMFormatPURI*) puri);
+ store = E_ATTACHMENT_STORE (e_attachment_store_new ());
+
+ emp = em_part_attachment_bar_new (emf, part, part_id->str, NULL);
+ em_part_set_widget_func (emp, efhd_attachment_bar);
+ em_part_attachment_bar_set_store ((EMPartAttachmentBar *) emp, store);
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
+
+ /* Store is now owned only by the EMPart */
+ g_object_unref (store);
}
static void
@@ -942,7 +976,7 @@ efhd_optional_button_show (GtkWidget *widget,
/* optional render attachment button callback */
static GtkWidget*
efhd_attachment_optional (EMFormat *efh,
- EMFormatPURI *puri,
+ EMPart *emp,
GCancellable *cancellable)
{
GtkWidget *hbox, *vbox, *button, *mainbox, *scroll, *label, *img;
@@ -950,7 +984,9 @@ efhd_attachment_optional (EMFormat *efh,
GtkWidget *view;
GtkTextBuffer *buffer;
GByteArray *byte_array;
- EMFormatAttachmentPURI *info = (EMFormatAttachmentPURI *) puri;
+ EMPartAttachment *empa = (EMPartAttachment *) emp;
+ const EMFormatHandler *handler;
+ CamelStream *stream;
if (g_cancellable_is_cancelled (cancellable))
return NULL;
@@ -958,10 +994,13 @@ efhd_attachment_optional (EMFormat *efh,
/* FIXME: handle default shown case */
d(printf("adding attachment button/content for optional rendering\n"));
- if (!info || info->forward) {
+ button = em_part_attachment_get_forward_widget (empa);
+ if (button) {
g_warning ("unable to expand the attachment\n");
+ g_object_unref (button);
return NULL;
}
+ g_object_unref (button);
scroll = gtk_scrolled_window_new (NULL, NULL);
mainbox = gtk_hbox_new (FALSE, 0);
@@ -976,7 +1015,9 @@ efhd_attachment_optional (EMFormat *efh,
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 2);
gtk_widget_show_all (hbox);
gtk_container_add (GTK_CONTAINER (button), GTK_WIDGET (hbox));
- if (info->handle)
+
+ handler = em_part_attachment_get_handler (empa);
+ if (handler)
g_signal_connect (
button, "clicked",
G_CALLBACK (efhd_optional_button_show), scroll);
@@ -1013,11 +1054,14 @@ efhd_attachment_optional (EMFormat *efh,
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- byte_array = camel_stream_mem_get_byte_array (info->mstream);
+
+ stream = em_part_attachment_get_mstream (empa);
+ byte_array = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (stream));
gtk_text_buffer_set_text (
buffer, (gchar *) byte_array->data, byte_array->len);
- g_object_unref (info->mstream);
- info->mstream = NULL;
+ g_object_unref (stream);
+ em_part_attachment_set_mstream (empa, NULL);
+
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
@@ -1025,39 +1069,12 @@ efhd_attachment_optional (EMFormat *efh,
gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 6);
gtk_widget_show (GTK_WIDGET (view));
- if (!info->shown)
+ if (!em_part_attachment_get_is_shown (empa))
gtk_widget_hide (scroll);
gtk_widget_show (vbox);
- info->handle = NULL;
- return view;
-}
-
-static void
-efhd_free_attach_puri_data (EMFormatPURI *puri)
-{
- EMFormatAttachmentPURI *info = (EMFormatAttachmentPURI *) puri;
-
- g_return_if_fail (puri != NULL);
-
- if (info->attachment) {
- g_object_unref (info->attachment);
- info->attachment = NULL;
- }
+ em_part_attachment_set_handler (empa, NULL);
- if (info->description) {
- g_free (info->description);
- info->description = NULL;
- }
-
- if (info->attachment_view_part_id) {
- g_free (info->attachment_view_part_id);
- info->attachment_view_part_id = NULL;
- }
-
- if (info->mstream) {
- g_object_unref (info->mstream);
- info->mstream = NULL;
- }
+ return view;
}
diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h
index cf3cac4..52d95e0 100644
--- a/mail/em-format-html-display.h
+++ b/mail/em-format-html-display.h
@@ -52,52 +52,6 @@ G_BEGIN_DECLS
typedef struct _EMFormatHTMLDisplay EMFormatHTMLDisplay;
typedef struct _EMFormatHTMLDisplayClass EMFormatHTMLDisplayClass;
typedef struct _EMFormatHTMLDisplayPrivate EMFormatHTMLDisplayPrivate;
-typedef struct _EMFormatAttachmentBarPURI EMFormatAttachmentBarPURI;
-typedef struct _EMFormatAttachmentPURI EMFormatAttachmentPURI;
-typedef struct _EMFormatSMIMEPURI EMFormatSMIMEPURI;
-
-struct _EMFormatAttachmentBarPURI {
- EMFormatPURI puri;
-
- EAttachmentStore *store;
-};
-
-struct _EMFormatAttachmentPURI {
- EMFormatPURI puri;
-
- const EMFormatHandler *handle;
-
- const gchar *snoop_mime_type;
-
- /* for the > and V buttons */
- GtkWidget *forward, *down;
- guint shown:1;
-
- /* Attachment */
- EAttachment *attachment;
- gchar *attachment_view_part_id;
- gchar *description;
-
- /* image stuff */
- gint fit_width;
- gint fit_height;
- GtkImage *image;
- GtkWidget *event_box;
-
- /* Optional Text Mem Stream */
- CamelStreamMem *mstream;
-};
-
-struct _EMFormatSMIMEPURI {
- EMFormatPURI puri;
-
- gchar *description;
-
- gint signature;
- CamelCipherValidity *valid;
- GtkWidget *widget;
-};
-
struct _EMFormatHTMLDisplay {
EMFormatHTML parent;
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index f968ede..a86e7fb 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -31,6 +31,7 @@
#include "em-format-html-print.h"
#include "em-format-html-display.h"
+#include "em-format-html-display-parts.h"
#include "e-mail-attachment-bar.h"
#include <e-util/e-print.h>
#include <e-util/e-util.h>
@@ -39,14 +40,15 @@
#include "em-format-html-print.h"
+
static gpointer parent_class = NULL;
struct _EMFormatHTMLPrintPrivate {
EMFormatHTML *original_formatter;
- EMFormatPURI *top_level_puri;
+ EMPart *top_level_part;
- /* List of attachment PURIs */
+ /* List of attachment EMParts */
GList *attachments;
};
@@ -56,9 +58,9 @@ enum {
PROP_ORIGINAL_FORMATTER
};
-static void efhp_write_print_layout (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void efhp_write_headers (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void efhp_write_inline_attachment(EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efhp_write_print_layout (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efhp_write_headers (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efhp_write_inline_attachment(EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
static void
efhp_write_attachments_list (EMFormatHTMLPrint *efhp,
@@ -79,17 +81,20 @@ efhp_write_attachments_list (EMFormatHTMLPrint *efhp,
_("Attachments"), _("Name"), _("Size"));
for (iter = efhp->priv->attachments; iter; iter = iter->next) {
- EMFormatPURI *puri = iter->data;
+ EMPart *emp = iter->data;
EAttachment *attachment;
GFileInfo *fi;
gchar *name, *size;
GByteArray *ba;
CamelDataWrapper *dw;
+ CamelMimePart *part;
- attachment = ((EMFormatAttachmentPURI *) puri)->attachment;
+ attachment = em_part_attachment_get_attachment (EM_PART_ATTACHMENT (emp));
fi = e_attachment_get_file_info (attachment);
- if (!fi)
+ if (!fi) {
+ g_object_unref (attachment);
continue;
+ }
if (e_attachment_get_description (attachment) &&
*e_attachment_get_description (attachment)) {
@@ -100,7 +105,8 @@ efhp_write_attachments_list (EMFormatHTMLPrint *efhp,
name = g_strdup (g_file_info_get_display_name (fi));
}
- dw = camel_medium_get_content ((CamelMedium *) puri->part);
+ part = em_part_get_mime_part (emp);
+ dw = camel_medium_get_content ((CamelMedium *) part);
ba = camel_data_wrapper_get_byte_array (dw);
size = g_format_size (ba->len);
@@ -109,6 +115,9 @@ efhp_write_attachments_list (EMFormatHTMLPrint *efhp,
g_free (name);
g_free (size);
+
+ g_object_unref (attachment);
+ g_object_unref (part);
}
g_string_append (str, "</table>\n");
@@ -119,7 +128,7 @@ efhp_write_attachments_list (EMFormatHTMLPrint *efhp,
static void
efhp_write_headers (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -128,12 +137,17 @@ efhp_write_headers (EMFormat *emf,
GString *str, *tmp;
gchar *subject;
const gchar *buf;
- EMFormatPURI *p;
+ EMPart *p;
GList *iter;
gint attachments_count;
gchar *puri_prefix;
+ CamelMimePart *part;
+ gchar *uri;
+
+ part = em_part_get_mime_part (emp);
+ buf = camel_medium_get_header (CAMEL_MEDIUM (part), "subject");
+ g_object_unref (part);
- buf = camel_medium_get_header (CAMEL_MEDIUM (puri->part), "subject");
subject = camel_header_decode_string (buf, "UTF-8");
str = g_string_new ("<table border=\"0\" cellspacing=\"5\" " \
"cellpadding=\"0\" class=\"printing-header\">\n");
@@ -153,7 +167,7 @@ efhp_write_headers (EMFormat *emf,
if (header->value && *header->value) {
raw_header.value = header->value;
em_format_html_format_header (emf, str,
- CAMEL_MEDIUM (puri->part), &raw_header,
+ CAMEL_MEDIUM (part), &raw_header,
header->flags | EM_FORMAT_HTML_HEADER_NOLINKS,
"UTF-8");
} else {
@@ -162,7 +176,7 @@ efhp_write_headers (EMFormat *emf,
if (raw_header.value && *raw_header.value) {
em_format_html_format_header (emf, str,
- CAMEL_MEDIUM (puri->part), &raw_header,
+ CAMEL_MEDIUM (part), &raw_header,
header->flags | EM_FORMAT_HTML_HEADER_NOLINKS,
"UTF-8");
}
@@ -172,40 +186,51 @@ efhp_write_headers (EMFormat *emf,
}
}
- /* Get prefix of this PURI */
- puri_prefix = g_strndup (puri->uri, g_strrstr (puri->uri, ".") - puri->uri);
+ /* Get prefix of this EMPart */
+ uri = em_part_get_uri (emp);
+ puri_prefix = g_strndup (uri, g_strrstr (uri, ".") - uri);
+ g_free (uri);
/* Add encryption/signature header */
raw_header.name = _("Security");
tmp = g_string_new ("");
/* Find first secured part. */
- for (iter = emf->mail_part_list, puri; iter; iter = iter->next) {
+ for (iter = emf->mail_part_list, emp; iter; iter = iter->next) {
+
+ gint32 validity_type;
+ gchar *uri;
p = iter->data;
- if (p->validity_type == 0)
+ validity_type = em_part_get_validity_type (p);
+
+ if (validity_type == 0)
continue;
- if (!g_str_has_prefix (p->uri, puri_prefix))
+ uri = em_part_get_uri (p);
+ if (!g_str_has_prefix (uri, puri_prefix)) {
+ g_free (uri);
continue;
+ }
+ g_free (uri);
- if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_PGP) &&
- (p->validity_type & EM_FORMAT_VALIDITY_FOUND_SIGNED)) {
+ if ((validity_type & EM_FORMAT_VALIDITY_FOUND_PGP) &&
+ (validity_type & EM_FORMAT_VALIDITY_FOUND_SIGNED)) {
g_string_append (tmp, _("GPG signed"));
}
- if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_PGP) &&
- (p->validity_type & EM_FORMAT_VALIDITY_FOUND_ENCRYPTED)) {
+ if ((validity_type & EM_FORMAT_VALIDITY_FOUND_PGP) &&
+ (validity_type & EM_FORMAT_VALIDITY_FOUND_ENCRYPTED)) {
if (tmp->len > 0) g_string_append (tmp, ", ");
g_string_append (tmp, _("GPG encrpyted"));
}
- if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_SMIME) &&
- (p->validity_type & EM_FORMAT_VALIDITY_FOUND_SIGNED)) {
+ if ((validity_type & EM_FORMAT_VALIDITY_FOUND_SMIME) &&
+ (validity_type & EM_FORMAT_VALIDITY_FOUND_SIGNED)) {
if (tmp->len > 0) g_string_append (tmp, ", ");
g_string_append (tmp, _("S/MIME signed"));
}
- if ((p->validity_type & EM_FORMAT_VALIDITY_FOUND_SMIME) &&
- (p->validity_type & EM_FORMAT_VALIDITY_FOUND_ENCRYPTED)) {
+ if ((validity_type & EM_FORMAT_VALIDITY_FOUND_SMIME) &&
+ (validity_type & EM_FORMAT_VALIDITY_FOUND_ENCRYPTED)) {
if (tmp->len > 0) g_string_append (tmp, ", ");
g_string_append (tmp, _("S/MIME encrpyted"));
@@ -214,11 +239,19 @@ efhp_write_headers (EMFormat *emf,
break;
}
+ if (!p) {
+ g_free (puri_prefix);
+ g_string_free (str, TRUE);
+ return;
+ }
+
+ part = em_part_get_mime_part (p);
if (tmp->len > 0) {
raw_header.value = tmp->str;
- em_format_html_format_header (emf, str, CAMEL_MEDIUM (p->part),
+ em_format_html_format_header (emf, str, CAMEL_MEDIUM (part),
&raw_header, EM_FORMAT_HEADER_BOLD | EM_FORMAT_HTML_HEADER_NOLINKS, "UTF-8");
}
+ g_object_unref (p);
g_string_free (tmp, TRUE);
/* Count attachments and display the number as a header */
@@ -226,21 +259,31 @@ efhp_write_headers (EMFormat *emf,
for (iter = emf->mail_part_list; iter; iter = iter->next) {
+ gchar *uri;
+
p = iter->data;
- if (!g_str_has_prefix (p->uri, puri_prefix))
+ uri = em_part_get_uri (p);
+ if (!g_str_has_prefix (uri, puri_prefix)) {
+ g_free (uri);
continue;
+ }
- if (p->is_attachment || g_str_has_suffix(p->uri, ".attachment"))
+ if (em_part_get_is_attachment (p) || g_str_has_suffix(uri, ".attachment"))
attachments_count++;
+
+ g_free (uri);
}
+
+ part = em_part_get_mime_part (emp);
if (attachments_count > 0) {
raw_header.name = _("Attachments");
raw_header.value = g_strdup_printf ("%d", attachments_count);
- em_format_html_format_header (emf, str, CAMEL_MEDIUM (puri->part),
+ em_format_html_format_header (emf, str, CAMEL_MEDIUM (part),
&raw_header, EM_FORMAT_HEADER_BOLD | EM_FORMAT_HTML_HEADER_NOLINKS, "UTF-8");
g_free (raw_header.value);
}
+ g_object_unref (part);
g_string_append (str, "</table>");
@@ -251,17 +294,17 @@ efhp_write_headers (EMFormat *emf,
static void
efhp_write_inline_attachment (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
gchar *name;
- EMFormatAttachmentPURI *att_puri = (EMFormatAttachmentPURI *) puri;
+ EMPartAttachment *empa = (EMPartAttachment *) emp;
EAttachment *attachment;
GFileInfo *fi;
- attachment = att_puri->attachment;
+ attachment = em_part_attachment_get_attachment (empa);
fi = e_attachment_get_file_info (attachment);
if (e_attachment_get_description (attachment) &&
@@ -276,13 +319,14 @@ efhp_write_inline_attachment (EMFormat *emf,
camel_stream_write_string (stream, name, cancellable, NULL);
g_free (name);
+ g_object_unref (attachment);
- puri->write_func (emf, puri, stream, info, cancellable);
+ em_part_write (emp, stream, info, cancellable);
}
static void
efhp_write_print_layout (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -305,46 +349,58 @@ efhp_write_print_layout (EMFormat *emf,
for (iter = emf->mail_part_list; iter != NULL; iter = iter->next) {
- EMFormatPURI *puri = iter->data;
+ EMPart *p = iter->data;
+ gchar *uri;
- if (g_str_has_suffix (puri->uri, "print_layout"))
+ uri = em_part_get_uri (p);
+ if (g_str_has_suffix (uri, "print_layout")) {
+ g_free (uri);
continue;
+ }
/* To late to change .headers writer_func, do it manually. */
- if (g_str_has_suffix (puri->uri, ".headers")) {
- efhp_write_headers (emf, puri, stream, info, cancellable);
+ if (g_str_has_suffix (uri, ".headers")) {
+ efhp_write_headers (emf, emp, stream, info, cancellable);
+ g_free (uri);
continue;
}
- if (puri->is_attachment || g_str_has_suffix (puri->uri, ".attachment")) {
+ if (em_part_get_is_attachment (p) || g_str_has_suffix (uri, ".attachment")) {
const EMFormatHandler *handler;
+ CamelMimePart *part;
+ CamelContentType *ct;
+ gchar *mime_type;
- CamelContentType *ct = camel_mime_part_get_content_type (puri->part);
- gchar *mime_type = camel_content_type_simple (ct);
+ part = em_part_get_mime_part (p);
+ ct = camel_mime_part_get_content_type (part);
+ mime_type = camel_content_type_simple (ct);
- handler = em_format_find_handler (puri->emf, mime_type);
- g_message ("Handler for PURI %s (%s): %s", puri->uri, mime_type,
+ handler = em_format_find_handler (emf, mime_type);
+ g_message ("Handler for EMPart %s (%s): %s", uri, mime_type,
handler ? handler->mime_type : "(null)");
g_free (mime_type);
efhp->priv->attachments =
- g_list_append (efhp->priv->attachments, puri);
+ g_list_append (efhp->priv->attachments, emp);
/* If we can't inline this attachment, skip it */
- if (handler && puri->write_func) {
- efhp_write_inline_attachment (puri->emf, puri,
+ if (handler && em_part_get_write_func (p)) {
+ efhp_write_inline_attachment (emf, emp,
stream, &print_info, cancellable);
}
+ g_free (uri);
continue;
}
+ g_free (uri);
+
/* Ignore widget parts and unwritable non-attachment parts */
- if (puri->write_func == NULL)
+ if (em_part_get_write_func (p) == NULL)
continue;
/* Passed all tests, probably a regular part - display it */
- puri->write_func(puri->emf, puri, stream, &print_info, cancellable);
+ em_part_write (emp, stream, &print_info, cancellable);
}
@@ -364,9 +420,9 @@ efhp_finalize (GObject *object)
efhp->priv->original_formatter = NULL;
}
- if (efhp->priv->top_level_puri) {
- em_format_puri_free (efhp->priv->top_level_puri);
- efhp->priv->top_level_puri = NULL;
+ if (efhp->priv->top_level_part) {
+ g_object_unref (efhp->priv->top_level_part);
+ efhp->priv->top_level_part = NULL;
}
if (efhp->priv->attachments) {
@@ -393,7 +449,7 @@ efhp_set_orig_formatter (EMFormatHTMLPrint *efhp,
EMFormat *formatter)
{
EMFormat *emfp, *emfs;
- EMFormatPURI *puri;
+ EMPart *emp;
GHashTableIter iter;
gpointer key, value;
@@ -404,29 +460,31 @@ efhp_set_orig_formatter (EMFormatHTMLPrint *efhp,
emfp->mail_part_list = g_list_copy (emfs->mail_part_list);
- /* Make a shallow copy of the table. This table will NOT destroy
- * the PURIs when free'd! */
+ /* Make a shallow copy of the table. */
if (emfp->mail_part_table)
g_hash_table_unref (emfp->mail_part_table);
- emfp->mail_part_table = g_hash_table_new (g_str_hash, g_str_equal);
+ emfp->mail_part_table = g_hash_table_new_full
+ (g_str_hash, g_str_equal, g_free, g_object_unref);
g_hash_table_iter_init (&iter, emfs->mail_part_table);
- while (g_hash_table_iter_next (&iter, &key, &value))
- g_hash_table_insert (emfp->mail_part_table, key, value);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GList *item = value;
+ g_hash_table_insert (emfp->mail_part_table,
+ g_strdup ((gchar *) key), g_object_ref (item->data));
+ }
if (emfs->folder)
emfp->folder = g_object_ref (emfs->folder);
emfp->message_uid = g_strdup (emfs->message_uid);
emfp->message = g_object_ref (emfs->message);
- /* Add a generic PURI that will write a HTML layout
+ /* Add a generic EMPart that will write a HTML layout
for all the parts */
- puri = em_format_puri_new (EM_FORMAT (efhp),
- sizeof (EMFormatPURI), NULL, "print_layout");
- puri->write_func = efhp_write_print_layout;
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (EM_FORMAT (efhp), puri);
- efhp->priv->top_level_puri = puri;
+ emp = em_part_new (emfp, NULL, "print_layout", efhp_write_print_layout);
+ em_part_set_mime_type (emp, "text/html");
+ em_format_add_part_object (emfp, emp);
+
+ efhp->priv->top_level_part = g_object_ref (emp);
}
static EMFormatHandler type_builtin_table[] = {
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 1ff57a3..034d585 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -66,7 +66,9 @@
#include "em-format-html.h"
#include "em-utils.h"
#include "e-mail-display.h"
+
#include <em-format/em-inline-filter.h>
+#include <em-format/em-part.h>
#define EM_FORMAT_HTML_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -121,16 +123,16 @@ static void efh_parse_message_external (EMFormat *emf, CamelMimePart *part, GSt
static void efh_parse_message_deliverystatus (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
static void efh_parse_message_rfc822 (EMFormat *emf, CamelMimePart *part, GString *part_id, EMFormatParserInfo *info, GCancellable *cancellable);
-static void efh_write_image (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void efh_write_text_enriched (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-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_headers (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void efh_write_attachment (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static void efh_write_error (EMFormat *emf, EMFormatPURI *puri, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_image (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_text_enriched (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_text_plain (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_text_html (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_source (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_headers (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_attachment (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
+static void efh_write_error (EMFormat *emf, EMPart *emp, CamelStream *stream, EMFormatWriterInfo *info, GCancellable *cancellable);
-static GtkWidget* efh_widget_message_rfc822 (EMFormat *emf, EMFormatPURI *puri, GCancellable *cancellable);
+static GtkWidget* efh_widget_message_rfc822 (EMFormat *emf, EMPart *emp, 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);
@@ -138,14 +140,17 @@ static void efh_format_short_headers (EMFormatHTML *efh, GString *buffer, Came
/*****************************************************************************/
static GtkWidget*
efh_widget_message_rfc822 (EMFormat* emf,
- EMFormatPURI* puri,
+ EMPart *emp,
GCancellable* cancellable)
{
EMailDisplay *display;
gchar *msg_uri;
+ gchar *uri;
+ uri = em_part_get_uri (emp);
msg_uri = em_format_build_mail_uri (emf->folder, emf->message_uid,
- "part_id", G_TYPE_STRING, puri->uri, NULL);
+ "part_id", G_TYPE_STRING, uri, NULL);
+ g_free (uri);
display = g_object_new (E_TYPE_MAIL_DISPLAY, NULL);
e_mail_display_set_formatter (display, EM_FORMAT_HTML (emf));
@@ -165,7 +170,7 @@ efh_parse_image (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
const gchar *tmp;
gchar *cid;
gint len;
@@ -176,23 +181,26 @@ efh_parse_image (EMFormat *emf,
tmp = camel_mime_part_get_content_id (part);
if (!tmp) {
- em_format_parse_part_as (emf, part, part_id, info, "x-evolution/message/attachment", cancellable);
+ 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->mime_type = g_strdup (info->handler->mime_type);
- puri->is_attachment = TRUE;
- puri->validity = info->validity ? camel_cipher_validity_clone (info->validity) : NULL;
- puri->validity_type = info->validity_type;
-
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, efh_write_image);
+ em_part_set_cid (emp, cid);
+ em_part_set_mime_type (emp, info->handler->mime_type);
+ em_part_set_is_attachment (emp, TRUE);
+ em_part_set_validity_type (emp, info->validity_type);
+ em_part_set_validity (emp, info->validity);
+
+ em_format_add_part_object (emf, emp);
+
g_string_truncate (part_id, len);
+
+ g_free (cid);
}
static void
@@ -202,7 +210,7 @@ efh_parse_text_enriched (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
const gchar *tmp;
gchar *cid;
gint len;
@@ -219,16 +227,18 @@ efh_parse_text_enriched (EMFormat *emf,
len = part_id->len;
g_string_append (part_id, ".text_enriched");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->cid = cid;
- puri->mime_type = g_strdup (info->handler->mime_type);
- puri->write_func = efh_write_text_enriched;
- puri->validity = info->validity ? camel_cipher_validity_clone (info->validity) : NULL;
- puri->validity_type = info->validity_type;
- puri->is_attachment = info->is_attachment;
-
- em_format_add_puri (emf, puri);
+
+ emp = em_part_new (emf, part, part_id->str, efh_write_text_enriched);
+ em_part_set_cid (emp, cid);
+ em_part_set_mime_type (emp, info->handler->mime_type);
+ em_part_set_is_attachment (emp, info->is_attachment);
+ em_part_set_validity_type (emp, info->validity_type);
+ em_part_set_validity (emp, info->validity);
+
+ em_format_add_part_object (emf, emp);
+
g_string_truncate (part_id, len);
+ g_free (cid);
}
static void
@@ -238,7 +248,7 @@ efh_parse_text_plain (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
CamelStream *filtered_stream, *null;
CamelMultipart *mp;
CamelDataWrapper *dw;
@@ -317,14 +327,15 @@ efh_parse_text_plain (EMFormat *emf,
gint s_len = part_id->len;
g_string_append (part_id, ".plain_text");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), newpart, part_id->str);
- puri->write_func = efh_write_text_plain;
- puri->mime_type = g_strdup ("text/html");
- puri->validity = info->validity ? camel_cipher_validity_clone (info->validity) : NULL;
- puri->validity_type = info->validity_type;
- puri->is_attachment = info->is_attachment;
+
+ emp = em_part_new (emf, newpart, part_id->str, efh_write_text_plain);
+ em_part_set_mime_type (emp, "text/html");
+ em_part_set_is_attachment (emp, info->is_attachment);
+ em_part_set_validity_type (emp, info->validity_type);
+ em_part_set_validity (emp, info->validity);
+
g_string_truncate (part_id, s_len);
- em_format_add_puri (emf, puri);
+ em_format_add_part_object (emf, emp);
} else {
g_string_append_printf (part_id, ".inline.%d", i);
em_format_parse_part (emf, CAMEL_MIME_PART (newpart), part_id, info, cancellable);
@@ -342,7 +353,7 @@ efh_parse_text_html (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
const gchar *location;
gchar *cid = NULL;
CamelURL *base;
@@ -372,13 +383,15 @@ efh_parse_text_html (EMFormat *emf,
len = part_id->len;
g_string_append (part_id, ".text_html");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = efh_write_text_html;
- puri->validity = info->validity ? camel_cipher_validity_clone (info->validity) : NULL;
- puri->validity_type = info->validity_type;
- puri->is_attachment = info->is_attachment;
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, efh_write_text_html);
+ em_part_set_is_attachment (emp, info->is_attachment);
+ em_part_set_validity_type (emp, info->validity_type);
+ em_part_set_validity (emp, info->validity);
+ em_part_set_cid (emp, cid);
+
+ em_format_add_part_object (emf, emp);
+
g_string_truncate (part_id, len);
if (cid)
@@ -392,7 +405,7 @@ efh_parse_message_external (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
CamelMimePart *newpart;
CamelContentType *type;
const gchar *access_type;
@@ -494,11 +507,12 @@ fail:
addPart:
len = part_id->len;
g_string_append (part_id, ".msg_external");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = efh_write_text_html;
- puri->mime_type = g_strdup ("text/html");
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, part_id->str, efh_write_text_html);
+ em_part_set_mime_type (emp, "text/html");
+
+ em_format_add_part_object (emf, emp);
+
g_string_truncate (part_id, len);
}
@@ -509,7 +523,7 @@ efh_parse_message_deliverystatus (EMFormat *emf,
EMFormatParserInfo *info,
GCancellable *cancellable)
{
- EMFormatPURI *puri;
+ EMPart *emp;
gint len;
if (g_cancellable_is_cancelled (cancellable))
@@ -517,14 +531,15 @@ efh_parse_message_deliverystatus (EMFormat *emf,
len = part_id->len;
g_string_append (part_id, ".deliverystatus");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), part, part_id->str);
- puri->write_func = efh_write_source;
- puri->mime_type = g_strdup ("text/html");
- puri->validity = info->validity ? camel_cipher_validity_clone (info->validity) : NULL;
- puri->validity_type = info->validity_type;
- puri->is_attachment = info->is_attachment;
-
- em_format_add_puri (emf, puri);
+
+ emp = em_part_new (emf, part, part_id->str, efh_write_source);
+ em_part_set_mime_type (emp, "text/html");
+ em_part_set_is_attachment (emp, info->is_attachment);
+ em_part_set_validity_type (emp, info->validity_type);
+ em_part_set_validity (emp, info->validity);
+
+ em_format_add_part_object (emf, emp);
+
g_string_truncate (part_id, len);
}
@@ -541,18 +556,21 @@ efh_parse_message_rfc822 (EMFormat *emf,
CamelMimeParser *parser;
gint len;
EMFormatParserInfo oinfo = *info;
- EMFormatPURI *puri;
+ EMPart *emp;
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 = info->handler->write_func ? info->handler->write_func : em_format_empty_writer;
- em_format_add_puri (emf, puri);
+ /* Create an empty EMPart that will represent start of the RFC message */
+ emp = em_part_new (emf, part, part_id->str, NULL);
+ em_part_set_widget_func (emp, efh_widget_message_rfc822);
+ em_part_set_write_func (emp, info->handler->write_func ?
+ info->handler->write_func :
+ em_format_empty_writer);
+
+ em_format_add_part_object (emf, emp);
- /* Now parse the message, creating multiple sub-PURIs */
+ /* Now parse the message, creating multiple sub-EMParts */
stream = camel_stream_mem_new ();
dw = camel_medium_get_content ((CamelMedium *) part);
camel_data_wrapper_write_to_stream_sync (dw, stream, cancellable, NULL);
@@ -567,14 +585,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. */
+ /* Add another generic EMPart that represents end of the RFC message.
+ * This is required for every EMPart that has EMailDisplay widget_func.
+ * The parent EMailDisplay then skips all EMParts between the ".rfc822" EMPart
+ * ".rfc822.end" EMPart (they were displayed by the child EMailDisplay called
+ * from ".rfc822"'s widget_func) and continues with the following EMPart. */
g_string_append (part_id, ".end");
- puri = em_format_puri_new (emf, sizeof (EMFormatPURI), NULL, part_id->str);
- em_format_add_puri (emf, puri);
+
+ emp = em_part_new (emf, NULL, part_id->str, NULL);
+ em_format_add_part_object (emf, emp);
g_string_truncate (part_id, len);
@@ -588,7 +607,7 @@ efh_parse_message_rfc822 (EMFormat *emf,
static void
efh_write_image (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -596,11 +615,15 @@ efh_write_image (EMFormat *emf,
gchar *content;
CamelDataWrapper *dw;
GByteArray *ba;
+ CamelMimePart *part;
if (g_cancellable_is_cancelled (cancellable))
return;
- dw = camel_medium_get_content (CAMEL_MEDIUM (puri->part));
+ part = em_part_get_mime_part (emp);
+ dw = camel_medium_get_content (CAMEL_MEDIUM (part));
+ g_object_unref (part);
+
g_return_if_fail (dw);
ba = camel_data_wrapper_get_byte_array (dw);
@@ -615,15 +638,21 @@ efh_write_image (EMFormat *emf,
image. */
if (!info->with_html_header) {
gchar *buffer;
+ gchar *mime_type;
+ mime_type = em_part_get_mime_type (emp);
+ if (!mime_type)
+ mime_type = g_strdup ("image/*");
/* The image is already base64-encrypted so we can directly
paste it to the output */
buffer = g_strdup_printf ("<img src=\"data:%s;base64,%s\" style=\"max-width: 100%%;\" />",
- puri->mime_type, content);
+ mime_type, content);
camel_stream_write_string (stream, buffer, cancellable, NULL);
g_free (buffer);
+ if (mime_type)
+ g_free (mime_type);
} else {
@@ -645,7 +674,7 @@ efh_write_image (EMFormat *emf,
static void
efh_write_text_enriched (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -656,12 +685,14 @@ efh_write_text_enriched (EMFormat *emf,
guint32 flags = 0;
GString *buffer;
CamelContentType *ct;
+ CamelMimePart *part;
gchar *mime_type = NULL;
if (g_cancellable_is_cancelled (cancellable))
return;
- ct = camel_mime_part_get_content_type (puri->part);
+ part = em_part_get_mime_part (emp);
+ ct = camel_mime_part_get_content_type (part);
if (ct) {
mime_type = camel_content_type_simple (ct);
}
@@ -710,24 +741,28 @@ efh_write_text_enriched (EMFormat *emf,
em_format_format_text (
emf, (CamelStream *) filtered_stream,
- (CamelDataWrapper *) puri->part, cancellable);
+ (CamelDataWrapper *) part, cancellable);
g_object_unref (filtered_stream);
camel_stream_write_string (stream, "</div>", cancellable, NULL);
- if (info->with_html_header)
+ if (info->with_html_header) {
camel_stream_write_string (stream, EFH_HTML_FOOTER,
cancellable, NULL);
+ }
+
+ g_object_unref (part);
}
static void
efh_write_text_plain (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
CamelDataWrapper *dw;
+ CamelMimePart *part;
CamelStream *filtered_stream;
CamelMimeFilter *html_filter;
EMFormatHTML *efh = (EMFormatHTML*) emf;
@@ -741,7 +776,8 @@ efh_write_text_plain (EMFormat *emf,
flags = efh->text_html_flags;
- dw = camel_medium_get_content (CAMEL_MEDIUM (puri->part));
+ part = em_part_get_mime_part (emp);
+ dw = camel_medium_get_content (CAMEL_MEDIUM (part));
/* Check for RFC 2646 flowed text. */
if (camel_content_type_is(dw->mime_type, "text", "plain")
@@ -768,7 +804,7 @@ efh_write_text_plain (EMFormat *emf,
e_color_to_value (&efh->priv->colors[EM_FORMAT_HTML_COLOR_CONTENT]));
camel_stream_write_string (stream, content, cancellable, NULL);
- em_format_format_text (emf, filtered_stream, (CamelDataWrapper *) puri->part, cancellable);
+ em_format_format_text (emf, filtered_stream, (CamelDataWrapper *) part, cancellable);
g_object_unref (filtered_stream);
g_free (content);
@@ -777,21 +813,27 @@ efh_write_text_plain (EMFormat *emf,
if (info->with_html_header)
camel_stream_write_string (stream, EFH_HTML_FOOTER, cancellable, NULL);
+
+ g_object_unref (part);
}
static void
efh_write_text_html (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
+ CamelMimePart *part;
+
+ part = em_part_get_mime_part (emp);
+
if (g_cancellable_is_cancelled (cancellable))
return;
if (info->with_html_header) {
em_format_format_text (emf, stream,
- (CamelDataWrapper *) puri->part, cancellable);
+ (CamelDataWrapper *) part, cancellable);
} else {
CamelStream *format_stream;
@@ -801,7 +843,7 @@ efh_write_text_html (EMFormat *emf,
format_stream = camel_stream_mem_new ();
em_format_format_text (
- emf, format_stream, (CamelDataWrapper *) puri->part, cancellable);
+ emf, format_stream, (CamelDataWrapper *) part, cancellable);
str = g_string_new ("");
ba = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (format_stream));
@@ -828,11 +870,13 @@ efh_write_text_html (EMFormat *emf,
g_string_free (str, TRUE);
}
+
+ g_object_unref (part);
}
static void
efh_write_source (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
@@ -841,7 +885,11 @@ efh_write_source (EMFormat *emf,
GString *buffer;
CamelStream *filtered_stream;
CamelMimeFilter *filter;
- CamelDataWrapper *dw = (CamelDataWrapper *) puri->part;
+ CamelMimePart *part;
+ CamelDataWrapper *dw;
+
+ part = em_part_get_mime_part (emp);
+ dw = (CamelDataWrapper *) part;
filtered_stream = camel_stream_filter_new (stream);
@@ -879,21 +927,25 @@ efh_write_source (EMFormat *emf,
camel_stream_write_string (stream, EFH_HTML_FOOTER, cancellable, NULL);
g_object_unref (filtered_stream);
+ g_object_unref (part);
g_string_free (buffer, TRUE);
}
static void
efh_write_headers (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
GString *buffer;
EMFormatHTML *efh = (EMFormatHTML *) emf;
+ CamelMimePart *part;
gint bg_color;
- if (!puri->part)
+ part = em_part_get_mime_part (emp);
+
+ if (!part)
return;
buffer = g_string_new ("");
@@ -957,12 +1009,12 @@ efh_write_headers (EMFormat *emf,
EVOLUTION_IMAGESDIR,
(info->headers_collapsed) ? "plus.png" : "minus.png");
- efh_format_short_headers (efh, buffer, (CamelMedium *) puri->part,
+ efh_format_short_headers (efh, buffer, (CamelMedium *) part,
info->headers_collapsed,
cancellable);
}
- efh_format_full_headers (efh, buffer, (CamelMedium *) puri->part,
+ efh_format_full_headers (efh, buffer, (CamelMedium *) part,
(info->mode == EM_FORMAT_WRITE_MODE_ALL_HEADERS),
!info->headers_collapsed,
cancellable);
@@ -975,23 +1027,27 @@ efh_write_headers (EMFormat *emf,
camel_stream_write_string (stream, buffer->str, cancellable, NULL);
g_string_free (buffer, true);
+
+ g_object_unref (part);
}
static void
efh_write_error (EMFormat *emf,
- EMFormatPURI *puri,
+ EMPart *emp,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
CamelStream *filtered_stream;
CamelMimeFilter *filter;
+ CamelMimePart *part;
CamelDataWrapper *dw;
if (info->with_html_header)
camel_stream_write_string (stream, EFH_HTML_HEADER, cancellable, NULL);
- dw = camel_medium_get_content ((CamelMedium *) puri->part);
+ part = em_part_get_mime_part (emp);
+ dw = camel_medium_get_content ((CamelMedium *) part);
camel_stream_write_string (stream, "<em><font color=\"red\">", cancellable, NULL);
@@ -1009,6 +1065,8 @@ efh_write_error (EMFormat *emf,
if (info->with_html_header)
camel_stream_write_string (stream, EFH_HTML_FOOTER, cancellable, NULL);
+
+ g_object_unref (part);
}
/*****************************************************************************/
@@ -1261,18 +1319,21 @@ efh_finalize (GObject *object)
static void
efh_write_attachment (EMFormat *emf,
- EMFormatPURI *puri,
- CamelStream *stream,
- EMFormatWriterInfo *info,
+ EMPart *emp,
+ CamelStream *stream,
+ EMFormatWriterInfo *info,
GCancellable *cancellable)
{
gchar *text, *html;
CamelContentType *ct;
+ CamelMimePart *part;
gchar *mime_type;
const EMFormatHandler *handler;
/* we display all inlined attachments only */
+ part = em_part_get_mime_part (emp);
+
/* this could probably be cleaned up ... */
camel_stream_write_string (
stream,
@@ -1283,11 +1344,11 @@ efh_write_attachment (EMFormat *emf,
"<tr><td></td></tr></table></td><td><font size=-1>\n",
cancellable, NULL);
- ct = camel_mime_part_get_content_type (puri->part);
+ ct = camel_mime_part_get_content_type (part);
mime_type = camel_content_type_simple (ct);
/* output some info about it */
- text = em_format_describe_part (puri->part, mime_type);
+ text = em_format_describe_part (part, mime_type);
html = camel_text_to_html (
text, ((EMFormatHTML *) emf)->text_html_flags &
CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
@@ -1300,11 +1361,14 @@ efh_write_attachment (EMFormat *emf,
handler = em_format_find_handler (emf, mime_type);
if (handler && handler->write_func && handler->write_func != efh_write_attachment) {
- if (em_format_is_inline (emf, puri->uri, puri->part, handler))
- handler->write_func (emf, puri, stream, info, cancellable);
+ gchar *uri = em_part_get_uri (emp);
+ if (em_format_is_inline (emf, uri, part, handler))
+ handler->write_func (emf, emp, stream, info, cancellable);
+ g_free (uri);
}
g_free (mime_type);
+ g_object_unref (part);
}
static void
@@ -2444,7 +2508,7 @@ efh_format_full_headers (EMFormatHTML *efh,
photopart = em_utils_contact_photo (cia, only_local_photo);
if (photopart) {
- EMFormatPURI *puri;
+ EMPart *emp;
contact_has_photo = TRUE;
classid = "icon:///em-format-html/headers/photo";
g_string_append_printf (
@@ -2452,10 +2516,9 @@ efh_format_full_headers (EMFormatHTML *efh,
"<td align=\"right\" valign=\"top\">"
"<img width=64 src=\"%s\"></td>",
classid);
- puri = em_format_puri_new (
- emf, sizeof (EMFormatPURI), photopart, classid);
- puri->write_func = efh_write_image;
- em_format_add_puri (emf, puri);
+
+ emp = em_part_new (emf, photopart, classid, efh_write_image);
+ em_format_add_part_object (emf, emp);
g_object_unref (photopart);
}
g_object_unref (cia);
@@ -2464,7 +2527,7 @@ efh_format_full_headers (EMFormatHTML *efh,
if (!contact_has_photo && face_decoded) {
const gchar *classid;
CamelMimePart *part;
- EMFormatPURI *puri;
+ EMPart *emp;
part = camel_mime_part_new ();
camel_mime_part_set_content (
@@ -2478,10 +2541,8 @@ efh_format_full_headers (EMFormatHTML *efh,
"<img width=48 src=\"%s\"></td>",
classid);
- puri = em_format_puri_new (
- emf, sizeof (EMFormatPURI), part, classid);
- puri->write_func = efh_write_image;
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, part, classid, efh_write_image);
+ em_format_add_part_object (emf, emp);
g_object_unref (part);
g_free (face_header_value);
@@ -2491,7 +2552,7 @@ efh_format_full_headers (EMFormatHTML *efh,
GtkIconInfo *icon_info;
const gchar *classid;
CamelMimePart *iconpart = NULL;
- EMFormatPURI *puri;
+ EMPart *emp;
classid = "icon:///em-format-html/header/icon";
g_string_append_printf (
@@ -2510,10 +2571,8 @@ efh_format_full_headers (EMFormatHTML *efh,
gtk_icon_info_free (icon_info);
}
if (iconpart) {
- puri = em_format_puri_new (
- emf, sizeof (EMFormatPURI), iconpart, classid);
- puri->write_func = efh_write_image;
- em_format_add_puri (emf, puri);
+ emp = em_part_new (emf, iconpart, classid, efh_write_image);
+ em_format_add_part_object (emf, emp);
g_object_unref (iconpart);
}
}
diff --git a/mail/em-format-html.h b/mail/em-format-html.h
index 689167f..170b2ae 100644
--- a/mail/em-format-html.h
+++ b/mail/em-format-html.h
@@ -56,7 +56,6 @@ G_BEGIN_DECLS
typedef struct _EMFormatHTML EMFormatHTML;
typedef struct _EMFormatHTMLClass EMFormatHTMLClass;
typedef struct _EMFormatHTMLPrivate EMFormatHTMLPrivate;
-typedef struct _EMFormatWidgetPURI EMFormatWidgetPURI;
enum _em_format_html_header_flags {
EM_FORMAT_HTML_HEADER_TO = 1 << 0,
diff --git a/mail/em-utils.c b/mail/em-utils.c
index f019863..b0b4354 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -77,6 +77,7 @@
#include "em-utils.h"
#include "e-mail-printer.h"
#include "em-format/em-format-quote.h"
+#include "em-format/em-part.h"
/* XXX This is a dirty hack on a dirty hack. We really need
* to rework or get rid of the functions that use this. */
@@ -1220,12 +1221,15 @@ em_utils_message_to_html (CamelMimeMessage *message,
/* Return all found validities */
for (iter = emf->mail_part_list; iter; iter = iter->next) {
- EMFormatPURI *puri = iter->data;
- if (!puri)
+ EMPart *emp = iter->data;
+ gint32 validity_type;
+
+ if (!emp)
continue;
- if (*validity_found && puri->validity_type)
- *validity_found |= puri->validity_type;
+ validity_type = em_part_get_validity_type (emp);
+ if (*validity_found && validity_type)
+ *validity_found |= validity_type;
}
}
diff --git a/plugins/audio-inline/Makefile.am b/plugins/audio-inline/Makefile.am
index fc204f9..3e04573 100644
--- a/plugins/audio-inline/Makefile.am
+++ b/plugins/audio-inline/Makefile.am
@@ -20,7 +20,9 @@ liborg_gnome_audio_inline_la_CPPFLAGS = \
$(GSTREAMER_CFLAGS) \
$(GTKHTML_CFLAGS)
-liborg_gnome_audio_inline_la_SOURCES = audio-inline.c
+liborg_gnome_audio_inline_la_SOURCES = \
+ audio-inline.c \
+ em-part-audio.c
liborg_gnome_audio_inline_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
diff --git a/plugins/audio-inline/audio-inline.c b/plugins/audio-inline/audio-inline.c
index 4942370..7250277 100644
--- a/plugins/audio-inline/audio-inline.c
+++ b/plugins/audio-inline/audio-inline.c
@@ -24,13 +24,14 @@
#include <config.h>
#endif
+#include "em-part-audio.h"
+
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include "e-util/e-mktemp.h"
#include "mail/em-format-hook.h"
#include "mail/em-format-html.h"
-#include "gtkhtml/gtkhtml-embedded.h"
-#include "gst/gst.h"
+#include <gst/gst.h>
#define d(x)
@@ -47,82 +48,31 @@ void org_gnome_audio_inline_format (gpointer ep, EMFormatHookTarget *t);
static volatile gint org_gnome_audio_class_id_counter = 0;
-typedef struct _EMFormatInlineAudioPURI EMFormatInlineAudioPURI;
-
-struct _EMFormatInlineAudioPURI {
- EMFormatPURI puri;
-
- gchar *filename;
- GstElement *playbin;
- gulong bus_id;
- GstState target_state;
- GtkWidget *play_button;
- GtkWidget *pause_button;
- GtkWidget *stop_button;
-};
-
-static void
-org_gnome_audio_inline_pobject_free (EMFormatPURI *o)
-{
- EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) o;
-
- d(printf ("audio inline formatter: pobject free\n"));
-
- if (po->play_button) {
- g_object_unref (po->play_button);
- po->play_button = NULL;
- }
-
- if (po->pause_button) {
- g_object_unref (po->pause_button);
- po->pause_button = NULL;
- }
-
- if (po->stop_button) {
- g_object_unref (po->stop_button);
- po->stop_button = NULL;
- }
-
- if (po->filename) {
- g_unlink (po->filename);
- g_free (po->filename);
- po->filename = NULL;
- }
-
- if (po->bus_id) {
- g_source_remove (po->bus_id);
- po->bus_id = 0;
- }
-
- if (po->playbin) {
- gst_element_set_state (po->playbin, GST_STATE_NULL);
- gst_object_unref (po->playbin);
- po->playbin = NULL;
- }
-}
static void
org_gnome_audio_inline_pause_clicked (GtkWidget *button,
- EMFormatPURI *puri)
+ EMPartAudio *empa)
{
- EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri;
+ GstElement *playbin = em_part_audio_get_playbin (empa);
- if (po->playbin) {
+ if (playbin) {
/* pause playing */
- gst_element_set_state (po->playbin, GST_STATE_PAUSED);
+ gst_element_set_state (playbin, GST_STATE_PAUSED);
+ g_object_unref (playbin);
}
}
static void
org_gnome_audio_inline_stop_clicked (GtkWidget *button,
- EMFormatPURI *puri)
+ EMPartAudio *empa)
{
- EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri;
+ GstElement *playbin = em_part_audio_get_playbin (empa);
- if (po->playbin) {
+ if (playbin) {
/* ready to play */
- gst_element_set_state (po->playbin, GST_STATE_READY);
- po->target_state = GST_STATE_READY;
+ gst_element_set_state (playbin, GST_STATE_READY);
+ em_part_audio_set_target_state (empa, GST_STATE_READY);
+ g_object_unref (playbin);
}
}
@@ -147,39 +97,57 @@ org_gnome_audio_inline_gst_callback (GstBus *bus,
GstMessage *message,
gpointer data)
{
- EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) data;
+ EMPartAudio *empa = data;
GstMessageType msg_type;
+ GstElement *playbin;
+
+ g_return_val_if_fail (data != NULL, TRUE);
- g_return_val_if_fail (po != NULL, TRUE);
- g_return_val_if_fail (po->playbin != NULL, TRUE);
+ playbin = em_part_audio_get_playbin (empa);
+ g_return_val_if_fail (playbin != NULL, TRUE);
msg_type = GST_MESSAGE_TYPE (message);
switch (msg_type) {
case GST_MESSAGE_ERROR:
- gst_element_set_state (po->playbin, GST_STATE_NULL);
+ gst_element_set_state (playbin, GST_STATE_NULL);
break;
case GST_MESSAGE_EOS:
- gst_element_set_state (po->playbin, GST_STATE_READY);
+ gst_element_set_state (playbin, GST_STATE_READY);
break;
case GST_MESSAGE_STATE_CHANGED:
{
- GstState old_state, new_state;
-
- if (GST_MESSAGE_SRC (message) != GST_OBJECT (po->playbin))
- break;
-
- gst_message_parse_state_changed (message, &old_state, &new_state, NULL);
-
- if (old_state == new_state)
- break;
-
- if (po->play_button)
- gtk_widget_set_sensitive (po->play_button, new_state <= GST_STATE_PAUSED);
- if (po->pause_button)
- gtk_widget_set_sensitive (po->pause_button, new_state > GST_STATE_PAUSED);
- if (po->stop_button)
- gtk_widget_set_sensitive (po->stop_button, new_state >= GST_STATE_PAUSED);
+ GstState old_state, new_state;
+ GtkWidget *button;
+
+ if (GST_MESSAGE_SRC (message) != GST_OBJECT (playbin))
+ break;
+
+ gst_message_parse_state_changed (message, &old_state, &new_state, NULL);
+
+ if (old_state == new_state)
+ break;
+
+ button = em_part_audio_get_play_button (empa);
+ if (button) {
+ gtk_widget_set_sensitive (button,
+ new_state <= GST_STATE_PAUSED);
+ g_object_unref (button);
+ }
+
+ button = em_part_audio_get_pause_button (empa);
+ if (button) {
+ gtk_widget_set_sensitive (button,
+ new_state > GST_STATE_PAUSED);
+ g_object_unref (button);
+ }
+
+ button = em_part_audio_get_stop_button (empa);
+ if (button) {
+ gtk_widget_set_sensitive (button,
+ new_state >= GST_STATE_PAUSED);
+ g_object_unref (button);
+ }
}
break;
@@ -187,36 +155,45 @@ org_gnome_audio_inline_gst_callback (GstBus *bus,
break;
}
+ g_object_unref (playbin);
+
return TRUE;
}
static void
org_gnome_audio_inline_play_clicked (GtkWidget *button,
- EMFormatPURI *puri)
+ EMPartAudio *empa)
{
- EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri;
GstState cur_state;
+ GstElement *playbin;
+ gchar *filename;
d(printf ("audio inline formatter: play\n"));
- if (!po->filename) {
+ filename = em_part_audio_get_filename (empa);
+ if (!filename) {
CamelStream *stream;
+ CamelMimePart *part;
CamelDataWrapper *data;
GError *error = NULL;
gint argc = 1;
const gchar *argv [] = { "org_gnome_audio_inline", NULL };
/* FIXME this is ugly, we should stream this directly to gstreamer */
- po->filename = e_mktemp ("org-gnome-audio-inline-file-XXXXXX");
+
+ filename = e_mktemp ("org-gnome-audio-inline-file-XXXXXX");
+ em_part_audio_set_filename (empa, filename);
- d(printf ("audio inline formatter: write to temp file %s\n", po->filename));
+ d(printf ("audio inline formatter: write to temp file %s\n", filename));
- stream = camel_stream_fs_new_with_name (po->filename, O_RDWR | O_CREAT | O_TRUNC, 0600, NULL);
- data = camel_medium_get_content (CAMEL_MEDIUM (po->puri.part));
+ stream = camel_stream_fs_new_with_name (filename, O_RDWR | O_CREAT | O_TRUNC, 0600, NULL);
+ part = em_part_get_mime_part (EM_PART (empa));
+ data = camel_medium_get_content (CAMEL_MEDIUM (part));
camel_data_wrapper_decode_to_stream_sync (
data, stream, NULL, NULL);
camel_stream_flush (stream, NULL, NULL);
g_object_unref (stream);
+ g_object_unref (part);
d(printf ("audio inline formatter: init gst playbin\n"));
@@ -225,38 +202,45 @@ org_gnome_audio_inline_play_clicked (GtkWidget *button,
GstBus *bus;
/* create a disk reader */
- po->playbin = gst_element_factory_make ("playbin", "playbin");
- if (po->playbin == NULL) {
+ playbin = gst_element_factory_make ("playbin", "playbin");
+ if (playbin == NULL) {
g_printerr ("Failed to create gst_element_factory playbin; check your installation\n");
return;
}
+ em_part_audio_set_playbin (empa, playbin);
- uri = g_filename_to_uri (po->filename, NULL, NULL);
- g_object_set (po->playbin, "uri", uri, NULL);
+ uri = g_filename_to_uri (filename, NULL, NULL);
+ g_object_set (playbin, "uri", uri, NULL);
g_free (uri);
- org_gnome_audio_inline_set_audiosink (po->playbin);
+ org_gnome_audio_inline_set_audiosink (playbin);
+
+ bus = gst_element_get_bus (playbin);
+ em_part_audio_set_bus_id (empa,
+ gst_bus_add_watch (bus, org_gnome_audio_inline_gst_callback, empa));
- bus = gst_element_get_bus (po->playbin);
- po->bus_id = gst_bus_add_watch (bus, org_gnome_audio_inline_gst_callback, po);
gst_object_unref (bus);
} else {
g_printerr ("GStreamer failed to initialize: %s",error ? error->message : "");
g_error_free (error);
}
+
+ g_free (filename);
}
- gst_element_get_state (po->playbin, &cur_state, NULL, 0);
+ gst_element_get_state (playbin, &cur_state, NULL, 0);
if (cur_state >= GST_STATE_PAUSED) {
- gst_element_set_state (po->playbin, GST_STATE_READY);
+ gst_element_set_state (playbin, GST_STATE_READY);
}
- if (po->playbin) {
+ if (playbin) {
/* start playing */
- gst_element_set_state (po->playbin, GST_STATE_PLAYING);
+ gst_element_set_state (playbin, GST_STATE_PLAYING);
}
+
+ g_object_unref (playbin);
}
static GtkWidget *
@@ -280,18 +264,26 @@ org_gnome_audio_inline_add_button (GtkWidget *box,
static GtkWidget*
org_gnome_audio_inline_button_panel (EMFormat *emf,
- EMFormatPURI *puri,
- GCancellable *cancellable)
+ EMPartAudio *empa,
+ GCancellable *cancellable)
{
GtkWidget *box;
- EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri;
-
/* it is OK to call UI functions here, since we are called from UI thread */
box = gtk_hbutton_box_new ();
- po->play_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_PLAY, G_CALLBACK (org_gnome_audio_inline_play_clicked), po, TRUE));
- po->pause_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_PAUSE, G_CALLBACK (org_gnome_audio_inline_pause_clicked), po, FALSE));
- po->stop_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_STOP, G_CALLBACK (org_gnome_audio_inline_stop_clicked), po, FALSE));
+
+ em_part_audio_set_play_button (empa,
+ org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_PLAY,
+ G_CALLBACK (org_gnome_audio_inline_play_clicked),
+ empa, TRUE));
+ em_part_audio_set_pause_button (empa,
+ org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_PAUSE,
+ G_CALLBACK (org_gnome_audio_inline_pause_clicked),
+ empa, FALSE));
+ em_part_audio_set_stop_button (empa,
+ org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_STOP,
+ G_CALLBACK (org_gnome_audio_inline_stop_clicked),
+ empa, FALSE));
gtk_widget_show (box);
@@ -302,7 +294,7 @@ void
org_gnome_audio_inline_format (gpointer ep,
EMFormatHookTarget *t)
{
- EMFormatInlineAudioPURI *pobj;
+ EMPart *emp;
gchar *classid;
classid = g_strdup_printf (
@@ -313,18 +305,8 @@ org_gnome_audio_inline_format (gpointer ep,
d(printf ("audio inline formatter: format classid %s\n", classid));
- pobj = (EMFormatInlineAudioPURI *) em_format_puri_new (
- t->format, sizeof (EMFormatInlineAudioPURI), t->part, classid);
- pobj->puri.widget_func = org_gnome_audio_inline_button_panel;
- pobj->puri.part = g_object_ref (t->part);
- pobj->filename = NULL;
- pobj->playbin = NULL;
- pobj->play_button = NULL;
- pobj->stop_button = NULL;
- pobj->pause_button = NULL;
- pobj->bus_id = 0;
- pobj->puri.free = org_gnome_audio_inline_pobject_free;
- pobj->target_state = GST_STATE_NULL;
-
- em_format_add_puri (t->format, (EMFormatPURI *) pobj);
+ emp = em_part_audio_new (t->format, t->part, t->part_id, NULL);
+ em_part_set_widget_func (emp, org_gnome_audio_inline_button_panel);
+
+ em_format_add_part_object (t->format, emp);
}
diff --git a/plugins/audio-inline/em-part-audio.c b/plugins/audio-inline/em-part-audio.c
new file mode 100644
index 0000000..749cd83
--- /dev/null
+++ b/plugins/audio-inline/em-part-audio.c
@@ -0,0 +1,346 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "em-part-audio.h"
+
+G_DEFINE_TYPE (EMPartAudio, em_part_audio, EM_TYPE_PART);
+
+struct _EMPartAudioPrivate {
+
+ gchar *filename;
+
+ GstState target_state;
+ GstElement *playbin;
+ gulong bus_id;
+
+
+ GtkWidget *play_button;
+ GtkWidget *pause_button;
+ GtkWidget *stop_button;
+
+ GMutex *mutex;
+};
+
+static void
+em_part_audio_finalize (GObject *object)
+{
+ EMPartAudioPrivate *priv = EM_PART_AUDIO (object)->priv;
+
+ g_mutex_lock (priv->mutex);
+
+ if (priv->filename) {
+ g_free (priv->filename);
+ priv->filename = NULL;
+ }
+
+ if (priv->playbin) {
+ g_object_unref (priv->playbin);
+ priv->playbin = NULL;
+ }
+
+ if (priv->play_button) {
+ g_object_unref (priv->play_button);
+ priv->play_button = NULL;
+ }
+
+ if (priv->pause_button) {
+ g_object_unref (priv->pause_button);
+ priv->pause_button = NULL;
+ }
+
+ if (priv->stop_button) {
+ g_object_unref (priv->stop_button);
+ priv->stop_button = NULL;
+ }
+
+ g_mutex_unlock (priv->mutex);
+ g_mutex_free (priv->mutex);
+}
+
+static void
+em_part_audio_class_init (EMPartAudioClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EMPartAudioPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = em_part_audio_finalize;
+}
+
+static void
+em_part_audio_init (EMPartAudio *empa)
+{
+ empa->priv = G_TYPE_INSTANCE_GET_PRIVATE (empa,
+ EM_TYPE_PART_AUDIO, EMPartAudioPrivate);
+
+ empa->priv->mutex = g_mutex_new ();
+ empa->priv->filename = NULL;
+ empa->priv->pause_button = NULL;
+ empa->priv->play_button = NULL;
+ empa->priv->stop_button = NULL;
+ empa->priv->playbin = NULL;
+ empa->priv->target_state = GST_STATE_NULL;
+ empa->priv->bus_id = 0;
+}
+
+EMPart *
+em_part_audio_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWidgetFunc widget_func)
+{
+ EMPart *emp;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+ g_return_val_if_fail ((part == NULL) || CAMEL_IS_MIME_PART (part), NULL);
+ g_return_val_if_fail (uri && *uri, NULL);
+
+ emp = EM_PART (g_object_new (EM_TYPE_PART_AUDIO, NULL));
+ em_part_set_mime_part (emp, part);
+ em_part_set_formatter (emp, emf);
+ em_part_set_uri (emp, uri);
+
+ if (widget_func)
+ em_part_set_widget_func (emp, widget_func);
+
+ return emp;
+}
+
+void
+em_part_audio_set_filename (EMPartAudio *empa,
+ const gchar *filename)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->filename)
+ g_free (empa->priv->filename);
+
+ if (filename)
+ empa->priv->filename = g_strdup (filename);
+ else
+ empa->priv->filename = NULL;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+gchar*
+em_part_audio_get_filename (EMPartAudio *empa)
+{
+ gchar *filename = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->filename)
+ filename = g_strdup (empa->priv->filename);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return filename;
+}
+
+void em_part_audio_set_playbin (EMPartAudio *empa,
+ GstElement *playbin)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+ g_return_if_fail (playbin == NULL || GST_IS_ELEMENT (playbin));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (playbin)
+ g_object_ref (playbin);
+
+ if (empa->priv->playbin)
+ g_object_unref (empa->priv->playbin);
+
+ empa->priv->playbin = playbin;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GstElement*
+em_part_audio_get_playbin (EMPartAudio *empa)
+{
+ GstElement *element = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->playbin)
+ element = g_object_ref (empa->priv->playbin);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return element;
+}
+
+void em_part_audio_set_bus_id (EMPartAudio *empa,
+ gulong bus_id)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+ empa->priv->bus_id = bus_id;
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+gulong
+em_part_audio_get_bus_id (EMPartAudio *empa)
+{
+ gulong bus_id = 0;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), 0);
+
+ g_mutex_lock (empa->priv->mutex);
+ bus_id = empa->priv->bus_id;
+ g_mutex_unlock (empa->priv->mutex);
+
+ return bus_id;
+}
+
+void
+em_part_audio_set_target_state (EMPartAudio *empa,
+ GstState state)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+
+ g_mutex_lock (empa->priv->mutex);
+ empa->priv->target_state = state;
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GstState
+em_part_audio_get_target_state (EMPartAudio *empa)
+{
+ GstState state;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), GST_STATE_NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ state = empa->priv->target_state;
+ g_mutex_unlock (empa->priv->mutex);
+
+ return state;
+}
+
+void
+em_part_audio_set_play_button (EMPartAudio *empa,
+ GtkWidget *button)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+ g_return_if_fail (button == NULL || GTK_IS_WIDGET (button));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (button)
+ g_object_ref (button);
+
+ if (empa->priv->play_button)
+ g_object_unref (empa->priv->play_button);
+
+ empa->priv->play_button = button;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GtkWidget*
+em_part_audio_get_play_button (EMPartAudio *empa)
+{
+ GtkWidget *widget = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->play_button)
+ widget = g_object_ref (empa->priv->play_button);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return widget;
+}
+
+void
+em_part_audio_set_pause_button (EMPartAudio *empa,
+ GtkWidget *button)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+ g_return_if_fail (button == NULL || GTK_IS_WIDGET (button));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (button)
+ g_object_ref (button);
+
+ if (empa->priv->pause_button)
+ g_object_unref (empa->priv->pause_button);
+
+ empa->priv->pause_button = button;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GtkWidget*
+em_part_audio_get_pause_button (EMPartAudio *empa)
+{
+ GtkWidget *widget = NULL;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->pause_button)
+ widget = g_object_ref (empa->priv->pause_button);
+ g_mutex_unlock (empa->priv->mutex);
+
+ return widget;
+}
+
+void
+em_part_audio_set_stop_button (EMPartAudio *empa,
+ GtkWidget *button)
+{
+ g_return_if_fail (EM_IS_PART_AUDIO (empa));
+ g_return_if_fail (button == NULL || GTK_IS_WIDGET (button));
+
+ g_mutex_lock (empa->priv->mutex);
+
+ if (button)
+ g_object_ref (button);
+
+ if (empa->priv->stop_button)
+ g_object_unref (empa->priv->stop_button);
+
+ empa->priv->stop_button = button;
+
+ g_mutex_unlock (empa->priv->mutex);
+}
+
+GtkWidget*
+em_part_audio_get_stop_button (EMPartAudio *empa)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (EM_IS_PART_AUDIO (empa), NULL);
+
+ g_mutex_lock (empa->priv->mutex);
+ if (empa->priv->stop_button)
+ widget = g_object_ref (empa->priv->stop_button);
+ g_mutex_unlock (empa->priv->stop_button);
+
+ return widget;
+}
diff --git a/plugins/audio-inline/em-part-audio.h b/plugins/audio-inline/em-part-audio.h
new file mode 100644
index 0000000..e8d7853
--- /dev/null
+++ b/plugins/audio-inline/em-part-audio.h
@@ -0,0 +1,112 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EM_PART_AUDIO_H
+#define EM_PART_AUDIO_H
+
+#include <em-format/em-part.h>
+#include <gst/gst.h>
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_PART_AUDIO \
+ (em_part_audio_get_type ())
+#define EM_PART_AUDIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_PART_AUDIO, EMPartAudio))
+#define EM_PART_AUDIO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_PART_AUDIO, EMPartAudioClass))
+#define EM_IS_PART_AUDIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_PART_AUDIO))
+#define EM_IS_PART_AUDIO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_PART_AUDIO))
+#define EM_PART_AUDIO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_PART_AUDIO, EMPartAudioClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMPartAudio EMPartAudio;
+typedef struct _EMPartAudioClass EMPartAudioClass;
+typedef struct _EMPartAudioPrivate EMPartAudioPrivate;
+
+
+struct _EMPartAudio {
+ EMPart parent;
+ EMPartAudioPrivate *priv;
+};
+
+struct _EMPartAudioClass {
+ GObjectClass parent_class;
+
+};
+
+EMPart* em_part_audio_new (EMFormat *emf,
+ CamelMimePart *part,
+ const gchar *uri,
+ EMPartWriteFunc write_func);
+
+GType em_part_audio_get_type ();
+
+void em_part_audio_set_filename
+ (EMPartAudio *empa,
+ const gchar *filename);
+
+gchar* em_part_audio_get_filename
+ (EMPartAudio *empa);
+
+void em_part_audio_set_playbin
+ (EMPartAudio *empa,
+ GstElement *playbin);
+GstElement* em_part_audio_get_playbin
+ (EMPartAudio *empa);
+
+void em_part_audio_set_bus_id
+ (EMPartAudio *empa,
+ gulong bus_id);
+gulong em_part_audio_get_bus_id
+ (EMPartAudio *empa);
+
+void em_part_audio_set_target_state
+ (EMPartAudio *empa,
+ GstState state);
+GstState em_part_audio_get_target_state
+ (EMPartAudio *empa);
+
+void em_part_audio_set_play_button
+ (EMPartAudio *empa,
+ GtkWidget *button);
+GtkWidget* em_part_audio_get_play_button
+ (EMPartAudio *empa);
+
+void em_part_audio_set_pause_button
+ (EMPartAudio *empa,
+ GtkWidget *button);
+GtkWidget* em_part_audio_get_pause_button
+ (EMPartAudio *empa);
+
+void em_part_audio_set_stop_button
+ (EMPartAudio *empa,
+ GtkWidget *button);
+GtkWidget* em_part_audio_get_stop_button
+ (EMPartAudio *empa);
+
+G_END_DECLS
+
+#endif /* EM_PART_AUDIO_H */
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 4dd58bb..62fb2ca 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -371,24 +371,6 @@ web_view_connect_proxy_cb (EWebView *web_view,
G_CALLBACK (web_view_menu_item_deselect_cb), web_view);
}
-static GtkWidget *
-web_view_create_plugin_widget_cb (EWebView *web_view,
- const gchar *mime_type,
- const gchar *uri,
- GHashTable *param)
-{
- EWebViewClass *class;
-
- /* XXX WebKitWebView does not provide a class method for
- * this signal, so we do so we can override the default
- * behavior from subclasses for special URI types. */
-
- class = E_WEB_VIEW_GET_CLASS (web_view);
- g_return_val_if_fail (class->create_plugin_widget != NULL, NULL);
-
- return class->create_plugin_widget (web_view, mime_type, uri, param);
-}
-
static void
web_view_hovering_over_link_cb (EWebView *web_view,
const gchar *title,
@@ -831,165 +813,6 @@ web_view_scroll_event (GtkWidget *widget,
return FALSE;
}
-static void
-web_view_get_preferred_height (GtkWidget *widget,
- gint *minimum_height,
- gint *natural_height)
-{
- WebKitWebView *web_view;
- WebKitDOMDocument *document;
- WebKitDOMElement *body, *last_el, *style_el;
- gint doc_height;
-
- if (!minimum_height && !natural_height)
- return;
-
- web_view = WEBKIT_WEB_VIEW (widget);
- document = webkit_web_view_get_dom_document (web_view);
- if (!document)
- return;
-
- body = WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document));
- if (!body)
- return;
-
- /* Make sure our Evo CSS stylesheet is loaded.
- * Note: there's 'user-stylesheet-uri' property of WebKitWebSettings but
- * it does not seem to be loaded in webviews with native text/html emails. */
- style_el = webkit_dom_document_get_element_by_id (document, "_evo_stylesheet");
- if (!style_el) {
- WebKitDOMNodeList *list;
- WebKitDOMNode *head;
- style_el = webkit_dom_document_create_element (document, "LINK", NULL);
- webkit_dom_html_link_element_set_rel (
- WEBKIT_DOM_HTML_LINK_ELEMENT (style_el), "stylesheet");
- webkit_dom_html_link_element_set_href(
- WEBKIT_DOM_HTML_LINK_ELEMENT (style_el),
- "evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css");
- webkit_dom_element_set_attribute (style_el, "type", "text/css", NULL);
- webkit_dom_html_element_set_id (
- WEBKIT_DOM_HTML_ELEMENT (style_el), "_evo_stylesheet");
-
- list = webkit_dom_document_get_elements_by_tag_name (document, "head");
- /* Broken HTML! Try to add head */
- if (webkit_dom_node_list_get_length (list) == 0) {
- WebKitDOMNodeList *body;
- head = WEBKIT_DOM_NODE (
- webkit_dom_document_create_element (
- document, "HEAD", NULL));
- body = webkit_dom_document_get_elements_by_tag_name (document, "body");
- if (webkit_dom_node_list_get_length(body) == 0) {
- /* The document is totally screwed up, there's
- * nothing more we can do. */
- return;
- }
-
- webkit_dom_node_insert_before(WEBKIT_DOM_NODE (document),
- head, webkit_dom_node_list_item (body, 0), NULL);
-
- } else {
- head = webkit_dom_node_list_item (list, 0);
- }
-
- webkit_dom_node_append_child (head, WEBKIT_DOM_NODE (style_el), NULL);
- }
-
- /* Last element in DOM != the undermost element displayed.
- * Thus we create our own element which is guaranteed to be displayed
- * at the very bottom (via CSS in webview.css) */
- last_el = webkit_dom_document_get_element_by_id (document, "_evo_bottom_element");
- if (!last_el) {
- last_el = webkit_dom_document_create_element (document, "DIV", NULL);
- webkit_dom_html_element_set_id (WEBKIT_DOM_HTML_ELEMENT (last_el),
- "_evo_bottom_element");
- webkit_dom_node_append_child (WEBKIT_DOM_NODE (body),
- WEBKIT_DOM_NODE (last_el), NULL);
-
- /* When the _evo_bottom_element is inserted to the DOM, the
- * subsequent call of webkit_dom_element_get_offset_top() makes
- * WebKit to recalculate layout and invoke content size change
- * which results in a recursive call of this function.
- * Gtk would prevent the recursion to happen but it would
- * throw an ugly warning, therefor we won't be doing any math now.
- * When the email is being rendered, the _get_preferred_height()
- * gets called multiple times, so we will calculate the actual
- * height next time, when WebKit will not be trying to update the
- * layout. */
-
- return;
- }
-
- /* The _actual_ height of page content is top + height of the
- * very last element in body. The 2px height is hardocded in
- * webview.ccs in #_evo_bottom_element */
- doc_height = webkit_dom_element_get_offset_top (last_el) + 2;
-
-
- /* Hardcoded padding */
- doc_height += 18;
-
- /* When full content zoom is enabled then the elements are not resized
- * but rather scaled and thus they still report their original height
- * instead of their actual display height. */
- if (webkit_web_view_get_full_content_zoom (web_view)) {
- doc_height = ceil((gfloat) doc_height *
- webkit_web_view_get_zoom_level (web_view));
- }
-
- if (minimum_height)
- *minimum_height = doc_height;
-
- if (natural_height)
- *natural_height = doc_height;
-
-}
-
-static GtkWidget *
-web_view_create_plugin_widget (EWebView *web_view,
- const gchar *mime_type,
- const gchar *uri,
- GHashTable *param)
-{
- GtkWidget *widget = NULL;
-
- if (g_strcmp0 (mime_type, "image/x-themed-icon") == 0) {
- GtkIconTheme *icon_theme;
- GdkPixbuf *pixbuf;
- gpointer data;
- glong size = 0;
- GError *error = NULL;
-
- icon_theme = gtk_icon_theme_get_default ();
-
- if (size == 0) {
- data = g_hash_table_lookup (param, "width");
- if (data != NULL)
- size = MAX (size, strtol (data, NULL, 10));
- }
-
- if (size == 0) {
- data = g_hash_table_lookup (param, "height");
- if (data != NULL)
- size = MAX (size, strtol (data, NULL, 10));
- }
-
- if (size == 0)
- size = 32; /* arbitrary default */
-
- pixbuf = gtk_icon_theme_load_icon (
- icon_theme, uri, size, 0, &error);
- if (pixbuf != NULL) {
- widget = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (pixbuf);
- } else if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- }
-
- return widget;
-}
-
static gchar *
web_view_extract_uri (EWebView *web_view,
GdkEventButton *event)
@@ -1422,14 +1245,12 @@ e_web_view_class_init (EWebViewClass *class)
widget_class = GTK_WIDGET_CLASS (class);
widget_class->button_press_event = web_view_button_press_event;
widget_class->scroll_event = web_view_scroll_event;
- widget_class->get_preferred_height = web_view_get_preferred_height;
#if 0 /* WEBKIT */
html_class = GTK_HTML_CLASS (class);
html_class->url_requested = web_view_url_requested;
#endif
- class->create_plugin_widget = web_view_create_plugin_widget;
class->extract_uri = web_view_extract_uri;
class->hovering_over_link = web_view_hovering_over_link;
class->link_clicked = web_view_link_clicked;
@@ -1653,10 +1474,6 @@ e_web_view_init (EWebView *web_view)
web_view->priv = E_WEB_VIEW_GET_PRIVATE (web_view);
g_signal_connect (
- web_view, "create-plugin-widget",
- G_CALLBACK (web_view_create_plugin_widget_cb), NULL);
-
- g_signal_connect (
web_view, "hovering-over-link",
G_CALLBACK (web_view_hovering_over_link_cb), NULL);
@@ -2782,7 +2599,7 @@ e_web_view_get_default_settings(GtkWidget *parent_widget)
"default-font-size", (pango_font_description_get_size (font) / PANGO_SCALE),
"default-monospace-font-size", (pango_font_description_get_size (font) / PANGO_SCALE),
"enable-frame-flattening", TRUE,
- "enable-plugins", FALSE,
+ "enable-plugins", TRUE,
"enable-java-applet", FALSE,
"enable-html5-database", FALSE,
"enable-html5-local-storage", FALSE,
diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h
index 6b32501..656c8b6 100644
--- a/widgets/misc/e-web-view.h
+++ b/widgets/misc/e-web-view.h
@@ -69,10 +69,6 @@ struct _EWebViewClass {
WebKitWebViewClass parent_class;
/* Methods */
- GtkWidget * (*create_plugin_widget) (EWebView *web_view,
- const gchar *mime_type,
- const gchar *uri,
- GHashTable *param);
gchar * (*extract_uri) (EWebView *web_view,
GdkEventButton *event);
void (*hovering_over_link) (EWebView *web_view,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]