aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog56
-rw-r--r--mail/em-folder-view.c12
-rw-r--r--mail/em-format-html-display.c49
-rw-r--r--mail/em-format-html-print.c6
-rw-r--r--mail/em-format-html-print.h2
-rw-r--r--mail/em-format-html-quote.c13
-rw-r--r--mail/em-format-html.c79
-rw-r--r--mail/em-format-quote.c10
-rw-r--r--mail/em-format.c105
-rw-r--r--mail/em-format.h20
-rw-r--r--mail/em-icon-stream.c60
-rw-r--r--mail/em-icon-stream.h5
-rw-r--r--mail/em-utils.c2
13 files changed, 329 insertions, 90 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 05ce863ecb..8699f99a2d 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,59 @@
+2004-01-13 Ross Burton <ross@burtonini.com>
+
+ * em-folder-browser.c (emfb_empty_trash):
+ Pass the parent window, fixing a crasher. Bug #52161.
+
+2004-01-14 Not Zed <NotZed@Ximian.com>
+
+ ** See bug 51660.
+
+ * em-format-html-quote.c (efhq_multipart_related): setup part_id
+ appropriately.
+
+ * em-format-html-display.c (efhd_output_secure): use part_id in
+ classid, and add .signed to part_id for subpart.
+ (efhd_bonobo_unknown): use part_id in classid.
+ (efhd_format_attachment): use part_id in classid's.
+
+ * em-format-html.c (efh_multipart_related)
+ (emfh_multipart_related_check): setup part_id for each subpart.
+ (efh_output_secure): as above, and use the part_id for the
+ classid.
+ (em_format_html_add_pobject): use part_id for a generated classid.
+ (efh_text_plain): setup pseudo-parts into part_id.
+
+ * em-format.c (emf_format_clone): setup the part_id base, folder +
+ uid.
+ (emf_finalise): free the part_id gstring.
+ (emf_init): allocate the part_id gstring.
+ (em_format_add_puri): build the cid from the part_id rather than
+ an arbitrary number, so it is more persistent. Also save the
+ part_id in the puri for multipart/related use.
+ (emf_multipart_mixed, emf_multipart_alternative)
+ (emf_multipart_appledouble, emf_multipart_encrypted)
+ (emf_multipart_related, emf_multipart_signed): Set the part_id for
+ each subpart.
+ (emf_clear_puri_node): free part_id.
+
+2004-01-13 Not Zed <NotZed@Ximian.com>
+
+ ** See bug 51660.
+
+ * em-format-html-print.c (em_format_html_print_print): dont take
+ message, get the message from the source formatter.
+
+ * em-format.c (emf_format_clone): Added folder and uid parameters,
+ changed camelmedium to a mimemessage.
+
+ * em-format-html-display.c (efhd_attachment_button): check the
+ icon image cache and if the image is there use it.
+
+ * em-icon-stream.c (em_icon_stream_get_image): api to lookup
+ finished images in cache.
+ (em_icon_stream_new): add a cache key arg.
+ (emis_sync_close): store the image in the cache once its
+ completed.
+
2004-01-13 Jeffrey Stedfast <fejj@ximian.com>
* em-migrate.c (em_migrate): Handle upgrading from 1.0.x and 1.2.x
diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c
index ab35e7a090..cc41f8f501 100644
--- a/mail/em-folder-view.c
+++ b/mail/em-folder-view.c
@@ -386,7 +386,7 @@ static void
emfv_set_folder_uri(EMFolderView *emfv, const char *uri)
{
if (emfv->preview)
- em_format_format((EMFormat *)emfv->preview, NULL);
+ em_format_format((EMFormat *)emfv->preview, NULL, NULL, NULL);
mail_get_folder(uri, 0, emfv_got_folder, emfv, mail_thread_queued);
}
@@ -1597,7 +1597,7 @@ int em_folder_view_print(EMFolderView *emfv, int preview)
EMFormatHTMLPrint *print;
GnomePrintConfig *config = NULL;
int res;
- struct _CamelMedium *msg;
+ struct _CamelMimeMessage *msg;
/* FIXME: need to load the message first */
if (!emfv->preview_active)
@@ -1630,7 +1630,7 @@ int em_folder_view_print(EMFolderView *emfv, int preview)
print = em_format_html_print_new();
em_format_set_session((EMFormat *)print, ((EMFormat *)emfv->preview)->session);
- res = em_format_html_print_print(print, msg, (EMFormatHTML *)emfv->preview, config, preview);
+ res = em_format_html_print_print(print, (EMFormatHTML *)emfv->preview, config, preview);
g_object_unref(print);
if (config)
g_object_unref(config);
@@ -1701,7 +1701,7 @@ emfv_list_done_message_selected(CamelFolder *folder, const char *uid, CamelMimeM
{
EMFolderView *emfv = data;
- em_format_format((EMFormat *)emfv->preview, (struct _CamelMedium *)msg);
+ em_format_format((EMFormat *)emfv->preview, folder, uid, msg);
if (emfv->priv->seen_id)
g_source_remove(emfv->priv->seen_id);
@@ -1737,7 +1737,7 @@ emfv_list_message_selected(MessageList *ml, const char *uid, EMFolderView *emfv)
} else {
g_free(emfv->priv->displayed_uid);
emfv->priv->displayed_uid = NULL;
- em_format_format((EMFormat *)emfv->preview, NULL);
+ em_format_format((EMFormat *)emfv->preview, NULL, NULL, NULL);
}
}
@@ -2047,7 +2047,7 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
em_format_default_headers(emf);
/* force a redraw */
if (emf->message)
- em_format_format_clone(emf, emf->message, emf);
+ em_format_format_clone(emf, emf->folder, emf->uid, emf->message, emf);
break; }
}
}
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 2c9b3c513e..60c096ac65 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -126,7 +126,7 @@ static void efhd_iframe_created(GtkHTML *html, GtkHTML *iframe, EMFormatHTMLDisp
static gboolean efhd_object_requested(GtkHTML *html, GtkHTMLEmbedded *eb, EMFormatHTMLDisplay *efh);*/
static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const char *mime_type);
-static void efhd_format_clone(EMFormat *, CamelMedium *, EMFormat *);
+static void efhd_format_clone(EMFormat *, CamelFolder *folder, const char *, CamelMimeMessage *msg, EMFormat *);
static void efhd_format_error(EMFormat *emf, CamelStream *stream, const char *txt);
static void efhd_format_message(EMFormat *, CamelStream *, CamelMedium *);
static void efhd_format_source(EMFormat *, CamelStream *, CamelMimePart *);
@@ -383,7 +383,7 @@ em_format_html_display_set_search(EMFormatHTMLDisplay *efhd, int type, GSList *s
}
d(printf("redrawing with search\n"));
- em_format_format_clone((EMFormat *)efhd, ((EMFormat *)efhd)->message, (EMFormat *)efhd);
+ em_format_redraw((EMFormat *)efhd);
}
static void
@@ -836,9 +836,9 @@ static void
efhd_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
{
CamelCipherValidity *save = ((EMFormatHTML *)emf)->valid_parent;
+ int len;
/* Note: this same logic is in efh_output_secure */
-
if (((EMFormatHTML *)emf)->valid == NULL) {
((EMFormatHTML *)emf)->valid = valid;
} else {
@@ -847,7 +847,12 @@ efhd_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
}
((EMFormatHTML *)emf)->valid_parent = valid;
+
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".signed");
em_format_part(emf, stream, part);
+ g_string_truncate(emf->part_id, len);
+
((EMFormatHTML *)emf)->valid_parent = save;
if (((EMFormatHTML *)emf)->valid == valid
@@ -858,7 +863,8 @@ efhd_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
camel_stream_printf(stream, "<table border=0 width=\"100%%\" cellpadding=3 cellspacing=0 bgcolor=%s><tr>",
valid->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_GOOD?"#88bb88":"#bb8888");
- classid = g_strdup_printf("smime:///em-format-html/%p/icon/signed", part);
+
+ classid = g_strdup_printf("smime:///em-format-html/%s/icon/signed", emf->part_id->str);
pobj = (struct _smime_pobject *)em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(*pobj), classid, part, efhd_xpkcs7mime_button);
pobj->valid = camel_cipher_validity_clone(valid);
pobj->object.free = efhd_xpkcs7mime_free;
@@ -970,10 +976,9 @@ efhd_builtin_init(EMFormatHTMLDisplayClass *efhc)
static void
efhd_bonobo_unknown(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
- static int partid;
char *classid;
- classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%p/%d", part, partid++);
+ classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str);
em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object);
camel_stream_printf(stream, "<object classid=\"%s\" type=\"%s\">\n", classid, info->mime_type);
g_free(classid);
@@ -1001,9 +1006,9 @@ static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const char *mime_
return handle;
}
-static void efhd_format_clone(EMFormat *emf, CamelMedium *part, EMFormat *src)
+static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src)
{
- ((EMFormatClass *)efhd_parent)->format_clone(emf, part, src);
+ ((EMFormatClass *)efhd_parent)->format_clone(emf, folder, uid, msg, src);
}
/* TODO: if these aren't going to do anything should remove */
@@ -1033,7 +1038,7 @@ efhd_attachment_show(GtkWidget *w, struct _attach_puri *info)
info->shown = ~info->shown;
em_format_set_inline(info->puri.format, info->puri.part, info->shown);
/* FIXME: do this in an idle handler */
- em_format_format_clone(info->puri.format, info->puri.format->message, info->puri.format);
+ em_format_redraw(info->puri.format);
#if 0
/* FIXME: track shown state in parent */
@@ -1249,14 +1254,24 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
simple_type = camel_content_type_simple (((CamelDataWrapper *)pobject->part)->mime_type);
camel_strdown(simple_type);
- /* cache? */
/* FIXME: offline parts, just get icon */
if (camel_content_type_is (((CamelDataWrapper *)pobject->part)->mime_type, "image", "*")) {
EMFormatHTMLJob *job;
-
- job = em_format_html_job_new(efh, efhd_write_icon_job, pobject);
- job->stream = (CamelStream *)em_icon_stream_new((GtkImage *)w);
- em_format_html_job_queue(efh, job);
+ GdkPixbuf *mini;
+ char *key;
+
+ key = pobject->classid;
+ mini = em_icon_stream_get_image(key);
+ if (mini) {
+ d(printf("got image from cache '%s'\n", key));
+ gtk_image_set_from_pixbuf((GtkImage *)w, mini);
+ g_object_unref(mini);
+ } else {
+ d(printf("need to create icon image '%s'\n", key));
+ job = em_format_html_job_new(efh, efhd_write_icon_job, pobject);
+ job->stream = (CamelStream *)em_icon_stream_new((GtkImage *)w, key);
+ em_format_html_job_queue(efh, job);
+ }
} else {
GdkPixbuf *pixbuf = e_icon_for_mime_type(simple_type, 24);
GdkPixbuf *mini = gdk_pixbuf_scale_simple(pixbuf, 24, 24, GDK_INTERP_BILINEAR);
@@ -1457,7 +1472,7 @@ efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
char *classid, *text, *html;
struct _attach_puri *info;
- classid = g_strdup_printf("attachment-%p", part);
+ classid = g_strdup_printf("attachment%s", emf->part_id->str);
info = (struct _attach_puri *)em_format_add_puri(emf, sizeof(*info), classid, part, efhd_attachment_frame);
em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_attachment_button);
info->handle = handle;
@@ -1492,11 +1507,9 @@ efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
handle->handler(emf, stream, part, handle);
/*camel_stream_printf(stream, "<iframe src=\"%s\" marginheight=0 marginwidth=0>%s</iframe>\n", classid, _("Attachment content could not be loaded"));*/
} else if (efhd_use_component(mime_type)) {
- static int partid;
-
g_free(classid); /* messy */
- classid = g_strdup_printf("bonobo-unknown:///em-formath-html-display/%p/%d", part, partid++);
+ classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str);
em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object);
camel_stream_printf(stream, "<object classid=\"%s\" type=\"%s\">\n", classid, mime_type);
}
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index 44da5abb73..b684378405 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -152,8 +152,10 @@ emfhp_complete(EMFormatHTMLPrint *efhp, void *data)
g_object_unref(efhp);
}
-int em_format_html_print_print(EMFormatHTMLPrint *efhp, struct _CamelMedium *msg, EMFormatHTML *source, struct _GnomePrintConfig *print_config, int preview)
+int em_format_html_print_print(EMFormatHTMLPrint *efhp, EMFormatHTML *source, struct _GnomePrintConfig *print_config, int preview)
{
+ EMFormat *emfs = (EMFormat *)source;
+
efhp->config = print_config;
if (print_config)
g_object_ref(print_config);
@@ -164,7 +166,7 @@ int em_format_html_print_print(EMFormatHTMLPrint *efhp, struct _CamelMedium *msg
g_signal_connect(efhp, "complete", G_CALLBACK(emfhp_complete), efhp);
g_object_ref(efhp);
- em_format_format_clone((EMFormat *)efhp, msg, (EMFormat *)source);
+ em_format_format_clone((EMFormat *)efhp, emfs->folder, emfs->uid, emfs->message, (EMFormat *)source);
return 0; /* damn async ... */
}
diff --git a/mail/em-format-html-print.h b/mail/em-format-html-print.h
index 78e3139e0f..5c8731ef12 100644
--- a/mail/em-format-html-print.h
+++ b/mail/em-format-html-print.h
@@ -32,6 +32,6 @@ GType em_format_html_print_get_type(void);
EMFormatHTMLPrint *em_format_html_print_new(void);
-int em_format_html_print_print(EMFormatHTMLPrint *efhp, struct _CamelMedium *msg, EMFormatHTML *source, struct _GnomePrintConfig *print_config, int preview);
+int em_format_html_print_print(EMFormatHTMLPrint *efhp, EMFormatHTML *source, struct _GnomePrintConfig *print_config, int preview);
#endif /* ! _EM_FORMAT_HTML_PRINT_H */
diff --git a/mail/em-format-html-quote.c b/mail/em-format-html-quote.c
index d00b8bf5f7..49749969d8 100644
--- a/mail/em-format-html-quote.c
+++ b/mail/em-format-html-quote.c
@@ -34,7 +34,7 @@ struct _EMFormatHTMLQuotePrivate {
char *credits;
};
-static void efhq_format_clone (EMFormat *, CamelMedium *, EMFormat *);
+static void efhq_format_clone (EMFormat *, CamelFolder *, const char *, CamelMimeMessage *, EMFormat *);
static void efhq_format_error (EMFormat *emf, CamelStream *stream, const char *txt);
static void efhq_format_message (EMFormat *, CamelStream *, CamelMedium *);
static void efhq_format_source (EMFormat *, CamelStream *, CamelMimePart *);
@@ -126,9 +126,9 @@ em_format_html_quote_new_with_credits (const char *credits)
}
static void
-efhq_format_clone (EMFormat *emf, CamelMedium *part, EMFormat *src)
+efhq_format_clone (EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src)
{
- ((EMFormatClass *) efhq_parent)->format_clone (emf, part, src);
+ ((EMFormatClass *) efhq_parent)->format_clone (emf, folder, uid, msg, src);
}
static void
@@ -182,7 +182,7 @@ efhq_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
CamelMimePart *body_part, *display_part = NULL;
CamelContentType *content_type;
const char *location, *start;
- int i, nparts;
+ int i, nparts, partidlen, displayid = 0;
CamelURL *base_save = NULL;
if (!CAMEL_IS_MULTIPART(mp)) {
@@ -209,6 +209,7 @@ efhq_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
if (cid && !strncmp(cid, start, len) && strlen(cid) == len) {
display_part = body_part;
+ displayid = i;
break;
}
}
@@ -229,7 +230,11 @@ efhq_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
}
em_format_push_level(emf);
+ partidlen = emf->part_id->len;
+ g_string_append_printf(emf->part_id, "related.%d", displayid);
em_format_part(emf, stream, display_part);
+ g_string_truncate(emf->part_id, partidlen);
+
em_format_pull_level(emf);
if (location) {
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 236492eb17..96239fb925 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -77,7 +77,7 @@
#define EFH_TABLE_OPEN "<table>"
struct _EMFormatHTMLPrivate {
- struct _CamelMedium *last_part; /* not reffed, DO NOT dereference */
+ struct _CamelMimeMessage *last_part; /* not reffed, DO NOT dereference */
volatile int format_id; /* format thread id */
guint format_timeout_id;
struct _format_msg *format_timeout_msg;
@@ -93,7 +93,7 @@ static void efh_url_requested(GtkHTML *html, const char *url, GtkHTMLStream *han
static gboolean efh_object_requested(GtkHTML *html, GtkHTMLEmbedded *eb, EMFormatHTML *efh);
static void efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh);
-static void efh_format_clone(EMFormat *, CamelMedium *, EMFormat *);
+static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource);
static void efh_format_error(EMFormat *emf, CamelStream *stream, const char *txt);
static void efh_format_message(EMFormat *, CamelStream *, CamelMedium *);
static void efh_format_source(EMFormat *, CamelStream *, CamelMimePart *);
@@ -256,7 +256,7 @@ void em_format_html_load_http(EMFormatHTML *emfh)
/* This will remain set while we're still rendering the same message, then it wont be */
emfh->load_http_now = TRUE;
d(printf("redrawing with images forced on\n"));
- em_format_format_clone((EMFormat *)emfh, emfh->format.message, (EMFormat *)emfh);
+ em_format_redraw((EMFormat *)emfh);
}
void
@@ -264,7 +264,7 @@ em_format_html_set_load_http(EMFormatHTML *emfh, int state)
{
if (emfh->load_http ^ state) {
emfh->load_http = state;
- em_format_format_clone((EMFormat *)emfh, emfh->format.message, (EMFormat *)emfh);
+ em_format_redraw((EMFormat *)emfh);
}
}
@@ -274,7 +274,7 @@ em_format_html_set_mark_citations(EMFormatHTML *emfh, int state, guint32 citatio
if (emfh->mark_citations ^ state || emfh->citation_colour != citation_colour) {
emfh->mark_citations = state;
emfh->citation_colour = citation_colour;
- em_format_format_clone((EMFormat *)emfh, emfh->format.message, (EMFormat *)emfh);
+ em_format_redraw((EMFormat *)emfh);
}
}
@@ -283,7 +283,7 @@ em_format_html_set_xmailer_mask(EMFormatHTML *emfh, unsigned int xmailer_mask)
{
if (emfh->xmailer_mask ^ xmailer_mask) {
emfh->xmailer_mask = xmailer_mask;
- em_format_format_clone((EMFormat *)emfh, emfh->format.message, (EMFormat *)emfh);
+ em_format_redraw((EMFormat *)emfh);
}
}
@@ -325,13 +325,10 @@ em_format_html_add_pobject(EMFormatHTML *efh, size_t size, const char *classid,
g_assert(size >= sizeof(EMFormatHTMLPObject));
pobj = g_malloc0(size);
- if (classid) {
+ if (classid)
pobj->classid = g_strdup(classid);
- } else {
- static unsigned int uriid = 0;
-
- pobj->classid = g_strdup_printf("e-object:///%u", uriid++);
- }
+ else
+ pobj->classid = g_strdup_printf("e-object:///%s", ((EMFormat *)efh)->part_id->str);
pobj->format = efh;
pobj->func = func;
@@ -582,6 +579,7 @@ static void
efh_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
{
CamelCipherValidity *save = ((EMFormatHTML *)emf)->valid_parent;
+ int len;
/* Note: this same logic is in efhd_output_secure */
if (((EMFormatHTML *)emf)->valid == NULL) {
@@ -592,7 +590,12 @@ efh_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Camel
}
((EMFormatHTML *)emf)->valid_parent = valid;
+
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".signed");
em_format_part(emf, stream, part);
+ g_string_truncate(emf->part_id, len);
+
((EMFormatHTML *)emf)->valid_parent = save;
if (((EMFormatHTML *)emf)->valid == valid
@@ -604,7 +607,7 @@ efh_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Camel
camel_stream_printf(stream, "<table border=0 width=\"100%%\" cellpadding=3 cellspacing=0 bgcolor=%s><tr>",
valid->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_GOOD?"#88bb88":"#bb8888");
- classid = g_strdup_printf("smime:///em-format-html/%p/icon/signed", part);
+ classid = g_strdup_printf("smime:///em-format-html/%s/icon/signed", emf->part_id->str);
camel_stream_printf(stream, "<td valign=\"top\"><img src=\"%s\"></td><td valign=\"top\" width=\"100%%\">", classid);
iconpart = em_format_html_file_part((EMFormatHTML *)emf, "image/png",
EVOLUTION_ICONSDIR, smime_sign_table[valid->sign.status].icon);
@@ -662,7 +665,7 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
CamelContentType *type;
const char *format;
guint32 rgb = 0x737373, flags;
- int i, count;
+ int i, count, len;
camel_stream_printf (stream,
"<table bgcolor=\"#%06x\" cellspacing=0 cellpadding=1 width=100%%><tr><td>\n"
@@ -715,6 +718,7 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
/* We handle our made-up multipart here, so we don't recursively call ourselves */
+ len = ((EMFormat *)efh)->part_id->len;
count = camel_multipart_get_number(mp);
for (i=0;i<count;i++) {
CamelMimePart *newpart = camel_multipart_get_part(mp, i);
@@ -726,7 +730,9 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
camel_stream_flush((CamelStream *)filtered_stream);
camel_stream_write_string(stream, "</tt>\n");
} else {
+ g_string_append_printf(((EMFormat *)efh)->part_id, ".inline.%d", i);
em_format_part((EMFormat *)efh, stream, newpart);
+ g_string_truncate(((EMFormat *)efh)->part_id, len);
}
}
@@ -921,11 +927,13 @@ emfh_multipart_related_check(struct _EMFormatHTMLJob *job, int cancelled)
{
struct _EMFormatPURITree *ptree;
EMFormatPURI *puri, *purin;
+ char *oldpartid;
if (cancelled)
return;
d(printf(" running multipart/related check task\n"));
+ oldpartid = g_strdup(((EMFormat *)job->format)->part_id->str);
ptree = job->puri_level;
puri = (EMFormatPURI *)ptree->uri_list.head;
@@ -933,13 +941,18 @@ emfh_multipart_related_check(struct _EMFormatHTMLJob *job, int cancelled)
while (purin) {
if (puri->use_count == 0) {
d(printf("part '%s' '%s' used '%d'\n", puri->uri?puri->uri:"", puri->cid, puri->use_count));
- if (puri->func == emfh_write_related)
+ if (puri->func == emfh_write_related) {
+ g_string_printf(((EMFormat *)job->format)->part_id, puri->part_id);
em_format_part((EMFormat *)job->format, (CamelStream *)job->stream, puri->part);
+ }
/* else it was probably added by a previous format this loop */
}
puri = purin;
purin = purin->next;
}
+
+ g_string_printf(((EMFormat *)job->format)->part_id, "%s", oldpartid);
+ g_free(oldpartid);
}
/* RFC 2387 */
@@ -950,7 +963,7 @@ efh_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
CamelMimePart *body_part, *display_part = NULL;
CamelContentType *content_type;
const char *location, *start;
- int i, nparts;
+ int i, nparts, partidlen, displayid = 0;
CamelURL *base_save = NULL;
EMFormatPURI *puri;
struct _EMFormatHTMLJob *job;
@@ -977,6 +990,7 @@ efh_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
if (cid && !strncmp(cid, start, len) && strlen(cid) == len) {
display_part = body_part;
+ displayid = i;
break;
}
}
@@ -998,16 +1012,22 @@ efh_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
}
em_format_push_level(emf);
+ partidlen = emf->part_id->len;
+
/* queue up the parts for possible inclusion */
for (i = 0; i < nparts; i++) {
body_part = camel_multipart_get_part(mp, i);
if (body_part != display_part) {
+ g_string_append_printf(emf->part_id, "related.%d", i);
puri = em_format_add_puri(emf, sizeof(EMFormatPURI), NULL, body_part, emfh_write_related);
+ g_string_truncate(emf->part_id, partidlen);
d(printf(" part '%s' '%s' added\n", puri->uri?puri->uri:"", puri->cid));
}
}
+ g_string_append_printf(emf->part_id, "related.%d", displayid);
em_format_part(emf, stream, display_part);
+ g_string_truncate(emf->part_id, partidlen);
camel_stream_flush(stream);
/* queue a job to check for un-referenced parts to add as attachments */
@@ -1144,7 +1164,9 @@ struct _format_msg {
EMFormatHTML *format;
EMFormat *format_source;
EMHTMLStream *estream;
- CamelMedium *message;
+ CamelFolder *folder;
+ char *uid;
+ CamelMimeMessage *message;
};
static char *efh_format_desc(struct _mail_msg *mm, int done)
@@ -1175,7 +1197,7 @@ static void efh_format_do(struct _mail_msg *mm)
if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE)
em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message);
else
- em_format_format_message((EMFormat *)m->format, (CamelStream *)m->estream, m->message);
+ em_format_format_message((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMedium *)m->message);
camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n");
camel_stream_close((CamelStream *)m->estream);
@@ -1239,6 +1261,9 @@ static void efh_format_free(struct _mail_msg *mm)
camel_stream_close((CamelStream *)m->estream);
camel_object_unref(m->estream);
}
+ if (m->folder)
+ camel_object_unref(m->folder);
+ g_free(m->uid);
if (m->message)
camel_object_unref(m->message);
if (m->format_source)
@@ -1275,7 +1300,7 @@ efh_format_timeout(struct _format_msg *m)
d(printf(" ready to go, firing off format thread\n"));
/* call super-class to kick it off */
- efh_parent->format_clone((EMFormat *)efh, m->message, m->format_source);
+ efh_parent->format_clone((EMFormat *)efh, m->folder, m->uid, m->message, m->format_source);
em_format_html_clear_pobject(m->format);
if (efh->valid) {
@@ -1319,7 +1344,7 @@ efh_format_timeout(struct _format_msg *m)
return FALSE;
}
-static void efh_format_clone(EMFormat *emf, CamelMedium *part, EMFormat *emfsource)
+static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource)
{
EMFormatHTML *efh = (EMFormatHTML *)emf;
struct _format_msg *m;
@@ -1344,9 +1369,13 @@ static void efh_format_clone(EMFormat *emf, CamelMedium *part, EMFormat *emfsour
m->format_source = emfsource;
if (emfsource)
g_object_ref(emfsource);
- m->message = part;
- if (part)
- camel_object_ref(part);
+ m->folder = folder;
+ if (folder)
+ camel_object_ref(folder);
+ m->uid = g_strdup(uid);
+ m->message = msg;
+ if (msg)
+ camel_object_ref(msg);
if (efh->priv->format_id == -1) {
d(printf(" idle, forcing format\n"));
@@ -1582,7 +1611,7 @@ static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMedium *
efh->valid = NULL;
efh->valid_parent = NULL;
- if (emf->message != part)
+ if (emf->message != (CamelMimeMessage *)part)
camel_stream_printf(stream, "<blockquote>\n");
if (!efh->hide_headers)
@@ -1591,7 +1620,7 @@ static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMedium *
camel_stream_printf(stream, "<table height=6><tr><td><a></a></td></tr></table>\n");
em_format_part(emf, stream, (CamelMimePart *)part);
- if (emf->message != part)
+ if (emf->message != (CamelMimeMessage *)part)
camel_stream_printf(stream, "</blockquote>\n");
camel_cipher_validity_free(efh->valid);
diff --git a/mail/em-format-quote.c b/mail/em-format-quote.c
index 1b26ff255e..b8173376e8 100644
--- a/mail/em-format-quote.c
+++ b/mail/em-format-quote.c
@@ -36,7 +36,7 @@ struct _EMFormatQuotePrivate {
int dummy;
};
-static void emfq_format_clone(EMFormat *, CamelMedium *, EMFormat *);
+static void emfq_format_clone(EMFormat *, CamelFolder *, const char *, CamelMimeMessage *, EMFormat *);
static void emfq_format_error(EMFormat *emf, CamelStream *stream, const char *txt);
static void emfq_format_message(EMFormat *, CamelStream *, CamelMedium *);
static void emfq_format_source(EMFormat *, CamelStream *, CamelMimePart *);
@@ -127,14 +127,14 @@ em_format_quote_new(const char *credits, CamelStream *stream, guint32 flags)
}
static void
-emfq_format_clone(EMFormat *emf, CamelMedium *part, EMFormat *src)
+emfq_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src)
{
#define emfq ((EMFormatQuote *)emf)
- ((EMFormatClass *)emfq_parent)->format_clone(emf, part, src);
+ ((EMFormatClass *)emfq_parent)->format_clone(emf, folder, uid, msg, src);
camel_stream_reset(emfq->stream);
- em_format_format_message(emf, emfq->stream, part);
+ em_format_format_message(emf, emfq->stream, (CamelMedium *)msg);
camel_stream_flush(emfq->stream);
g_signal_emit_by_name(emf, "complete");
@@ -151,7 +151,7 @@ static void
emfq_format_message(EMFormat *emf, CamelStream *stream, CamelMedium *part)
{
EMFormatQuote *emfq =(EMFormatQuote *) emf;
-
+
if (emfq->credits)
camel_stream_printf(stream, "%s", emfq->credits);
diff --git a/mail/em-format.c b/mail/em-format.c
index fef764f6ba..4ced33aee2 100644
--- a/mail/em-format.c
+++ b/mail/em-format.c
@@ -58,7 +58,7 @@ static void emf_builtin_init(EMFormatClass *);
static const char *emf_snoop_part(CamelMimePart *part);
static const EMFormatHandler *emf_find_handler(EMFormat *emf, const char *mime_type);
-static void emf_format_clone(EMFormat *emf, CamelMedium *msg, EMFormat *emfsource);
+static void emf_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource);
static gboolean emf_busy(EMFormat *emf);
enum {
@@ -77,6 +77,7 @@ emf_init(GObject *o)
emf->inline_table = g_hash_table_new(NULL, NULL);
e_dlist_init(&emf->header_list);
em_format_default_headers(emf);
+ emf->part_id = g_string_new("");
}
static void
@@ -92,7 +93,8 @@ emf_finalise(GObject *o)
em_format_clear_headers(emf);
g_free(emf->charset);
-
+ g_string_free(emf->part_id, TRUE);
+
/* FIXME: check pending jobs */
((GObjectClass *)emf_parent)->finalize(o);
@@ -262,7 +264,6 @@ em_format_add_puri(EMFormat *emf, size_t size, const char *cid, CamelMimePart *p
{
EMFormatPURI *puri;
const char *tmp;
- static unsigned int uriid;
g_assert(size >= sizeof(*puri));
puri = g_malloc0(size);
@@ -271,6 +272,7 @@ em_format_add_puri(EMFormat *emf, size_t size, const char *cid, CamelMimePart *p
puri->func = func;
puri->use_count = 0;
puri->cid = g_strdup(cid);
+ puri->part_id = g_strdup(emf->part_id->str);
if (part) {
camel_object_ref(part);
@@ -282,7 +284,7 @@ em_format_add_puri(EMFormat *emf, size_t size, const char *cid, CamelMimePart *p
if (tmp)
puri->cid = g_strdup_printf("cid:%s", tmp);
else
- puri->cid = g_strdup_printf("em-no-cid-%u", uriid++);
+ puri->cid = g_strdup_printf("em-no-cid:%s", emf->part_id->str);
d(printf("built cid '%s'\n", puri->cid));
@@ -421,6 +423,7 @@ emf_clear_puri_node(struct _EMFormatPURITree *node)
while (pn) {
g_free(pw->uri);
g_free(pw->cid);
+ g_free(pw->part_id);
if (pw->part)
camel_object_unref(pw->part);
g_free(pw);
@@ -515,7 +518,7 @@ emf_clone_inlines(void *key, void *val, void *data)
}
static void
-emf_format_clone(EMFormat *emf, CamelMedium *msg, EMFormat *emfsource)
+emf_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource)
{
em_format_clear_puri_tree(emf);
@@ -532,6 +535,20 @@ emf_format_clone(EMFormat *emf, CamelMedium *msg, EMFormat *emfsource)
}
}
+ /* what a mess */
+ if (folder != emf->folder) {
+ if (emf->folder)
+ camel_object_unref(emf->folder);
+ if (folder)
+ camel_object_ref(folder);
+ emf->folder = folder;
+ }
+
+ if (uid != emf->uid) {
+ g_free(emf->uid);
+ emf->uid = g_strdup(uid);
+ }
+
if (msg != emf->message) {
if (emf->message)
camel_object_unref(emf->message);
@@ -539,6 +556,13 @@ emf_format_clone(EMFormat *emf, CamelMedium *msg, EMFormat *emfsource)
camel_object_ref(msg);
emf->message = msg;
}
+
+ g_string_truncate(emf->part_id, 0);
+ if (folder != NULL)
+ /* TODO build some string based on the folder name/location? */
+ g_string_append_printf(emf->part_id, ".%p", folder);
+ if (uid != NULL)
+ g_string_append_printf(emf->part_id, ".%s", uid);
}
static gboolean
@@ -550,7 +574,9 @@ emf_busy(EMFormat *emf)
/**
* em_format_format_clone:
* @emf: Mail formatter.
- * @msg: Mail message.
+ * @folder: Camel Folder.
+ * @uid: Uid of message.
+ * @msg: Camel Message.
* @emfsource: Used as a basis for user-altered layout, e.g. inline viewed
* attachments.
*
@@ -600,7 +626,7 @@ em_format_set_mode(EMFormat *emf, em_format_mode_t type)
/* force redraw if type changed afterwards */
if (emf->message)
- em_format_format_clone(emf, emf->message, emf);
+ em_format_redraw(emf);
}
/**
@@ -623,10 +649,9 @@ em_format_set_charset(EMFormat *emf, const char *charset)
emf->charset = g_strdup(charset);
if (emf->message)
- em_format_format_clone(emf, emf->message, emf);
+ em_format_redraw(emf);
}
-
/**
* em_format_set_default_charset:
* @emf:
@@ -648,7 +673,7 @@ em_format_set_default_charset(EMFormat *emf, const char *charset)
emf->default_charset = g_strdup(charset);
if (emf->message && emf->charset == NULL)
- em_format_format_clone(emf, emf->message, emf);
+ em_format_redraw(emf);
}
/**
@@ -960,14 +985,18 @@ static void
emf_multipart_appledouble(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
-
+ int len;
+
if (!CAMEL_IS_MULTIPART(mp)) {
em_format_format_source(emf, stream, part);
return;
}
/* try the data fork for something useful, doubtful but who knows */
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".appledouble.1");
em_format_part(emf, stream, camel_multipart_get_part(mp, 1));
+ g_string_truncate(emf->part_id, len);
}
/* RFC ??? */
@@ -975,17 +1004,20 @@ static void
emf_multipart_mixed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
- int i, nparts;
+ int i, nparts, len;
if (!CAMEL_IS_MULTIPART(mp)) {
em_format_format_source(emf, stream, part);
return;
}
-
+
+ len = emf->part_id->len;
nparts = camel_multipart_get_number(mp);
for (i = 0; i < nparts; i++) {
part = camel_multipart_get_part(mp, i);
+ g_string_append_printf(emf->part_id, ".mixed.%d", i);
em_format_part(emf, stream, part);
+ g_string_truncate(emf->part_id, len);
}
}
@@ -994,7 +1026,7 @@ static void
emf_multipart_alternative(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
- int i, nparts;
+ int i, nparts, bestid;
CamelMimePart *best = NULL;
if (!CAMEL_IS_MULTIPART(mp)) {
@@ -1015,15 +1047,21 @@ emf_multipart_alternative(EMFormat *emf, CamelStream *stream, CamelMimePart *par
return part;*/
if (em_format_find_handler(emf, mime_type)
- || (best == NULL && em_format_fallback_handler(emf, mime_type)))
+ || (best == NULL && em_format_fallback_handler(emf, mime_type))) {
best = part;
+ bestid = i;
+ }
g_free(mime_type);
}
- if (best)
+ if (best) {
+ int len = emf->part_id->len;
+
+ g_string_append_printf(emf->part_id, ".alternative.%d", bestid);
em_format_part(emf, stream, best);
- else
+ g_string_truncate(emf->part_id, len);
+ } else
emf_multipart_mixed(emf, stream, part, info);
}
@@ -1035,6 +1073,7 @@ emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
CamelCipherContext *cipher;
CamelException ex;
const char *protocol;
+ int len;
/* Currently we only handle RFC2015-style PGP encryption. */
protocol = camel_content_type_param (((CamelDataWrapper *) part)->mime_type, "protocol");
@@ -1060,7 +1099,10 @@ emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
return;
}
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".encrypted");
em_format_part(emf, stream, mime_part);
+ g_string_truncate(emf->part_id, len);
camel_object_unref(mime_part);
}
@@ -1079,7 +1121,8 @@ emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
CamelMimePart *body_part, *display_part = NULL;
CamelContentType *content_type;
const char *location, *start;
- int i, nparts;
+ int i, nparts, partidlen, displayid = 0;
+ char *oldpartid;
CamelURL *base_save = NULL;
struct _EMFormatPURITree *ptree;
EMFormatPURI *puri, *purin;
@@ -1107,6 +1150,7 @@ emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
if (cid && !strncmp(cid, start, len) && strlen(cid) == len) {
display_part = body_part;
+ displayid = i;
break;
}
}
@@ -1128,16 +1172,24 @@ emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
}
em_format_push_level(emf);
+ oldpartid = g_strdup(emf->part_id->str);
+ partidlen = emf->part_id->len;
+
/* queue up the parts for possible inclusion */
for (i = 0; i < nparts; i++) {
body_part = camel_multipart_get_part(mp, i);
if (body_part != display_part) {
+ /* set the partid since add_puri uses it */
+ g_string_append_printf(emf->part_id, ".related.%d", i);
puri = em_format_add_puri(emf, sizeof(EMFormatPURI), NULL, body_part, emf_write_related);
+ g_string_truncate(emf->part_id, partidlen);
d(printf(" part '%s' '%s' added\n", puri->uri?puri->uri:"", puri->cid));
}
}
+ g_string_append_printf(emf->part_id, ".related.%d", displayid);
em_format_part(emf, stream, display_part);
+ g_string_truncate(emf->part_id, partidlen);
camel_stream_flush(stream);
ptree = emf->pending_uri_level;
@@ -1146,14 +1198,19 @@ emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
while (purin) {
if (purin->use_count == 0) {
d(printf("part '%s' '%s' used '%d'\n", purin->uri?purin->uri:"", purin->cid, purin->use_count));
- if (purin->func == emf_write_related)
+ if (purin->func == emf_write_related) {
+ g_string_printf(emf->part_id, "%s", puri->part_id);
em_format_part(emf, stream, puri->part);
- else
+ } else
printf("unreferenced uri generated by format code: %s\n", purin->uri?purin->uri:purin->cid);
}
puri = purin;
purin = purin->next;
}
+
+ g_string_printf(emf->part_id, "%s", oldpartid);
+ g_free(oldpartid);
+
em_format_pull_level(emf);
if (location) {
@@ -1172,6 +1229,7 @@ emf_multipart_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, co
CamelException ex;
const char *message = NULL;
gboolean good = FALSE;
+ int len;
mps = (CamelMultipartSigned *)camel_medium_get_content_object((CamelMedium *)part);
if (!CAMEL_IS_MULTIPART_SIGNED(mps)
@@ -1180,7 +1238,10 @@ emf_multipart_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, co
return;
}
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".signed");
em_format_part(emf, stream, cpart);
+ g_string_truncate(emf->part_id, len);
/* FIXME: This sequence is also copied in em-format-html.c */
@@ -1228,13 +1289,17 @@ static void
emf_message_rfc822(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part);
+ int len;
if (!CAMEL_IS_MIME_MESSAGE(dw)) {
em_format_format_source(emf, stream, part);
return;
}
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".rfc822");
em_format_format_message(emf, stream, (CamelMedium *)dw);
+ g_string_truncate(emf->part_id, len);
}
static EMFormatHandler type_builtin_table[] = {
diff --git a/mail/em-format.h b/mail/em-format.h
index f4cbb3fbbc..d01b50bc7e 100644
--- a/mail/em-format.h
+++ b/mail/em-format.h
@@ -36,6 +36,7 @@ struct _CamelMedium;
struct _CamelSession;
struct _CamelURL;
struct _CamelDataWrapper;
+struct _CamelMimeMessage;
typedef struct _EMFormat EMFormat;
typedef struct _EMFormatClass EMFormatClass;
@@ -68,6 +69,7 @@ struct _EMFormatPURI {
char *uri; /* will be the location of the part, may be empty */
char *cid; /* will always be set, a fake one created if needed */
+ char *part_id; /* will always be set, emf->part_id->str for this part */
EMFormatPURIFunc func;
struct _CamelMimePart *part;
@@ -98,7 +100,12 @@ struct _EMFormat {
struct _EMFormatPrivate *priv;
- struct _CamelMedium *message; /* the current message */
+ struct _CamelMimeMessage *message; /* the current message */
+
+ struct _CamelFolder *folder;
+ char *uid;
+
+ GString *part_id; /* current part id prefix, for identifying parts directly */
EDList header_list; /* if empty, then all */
@@ -130,7 +137,7 @@ struct _EMFormatClass {
const EMFormatHandler *(*find_handler)(EMFormat *, const char *mime_type);
/* start formatting a message */
- void (*format_clone)(EMFormat *, struct _CamelMedium *, EMFormat *);
+ void (*format_clone)(EMFormat *, struct _CamelFolder *, const char *uid, struct _CamelMimeMessage *, EMFormat *);
/* some internel error/inconsistency */
void (*format_error)(EMFormat *, struct _CamelStream *, const char *msg);
@@ -186,9 +193,14 @@ void em_format_push_level(EMFormat *emf);
void em_format_pull_level(EMFormat *emf);
/* clones inline state/view and format, or use to redraw */
-#define em_format_format_clone(emf, msg, src) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), (msg), (src))
+#define em_format_format_clone(emf, folder, uid, msg, src) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), (folder), (uid), (msg), (src))
/* formats a new message */
-#define em_format_format(emf, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), (msg), NULL)
+#define em_format_format(emf, folder, uid, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), (folder), (uid), (msg), NULL)
+#define em_format_redraw(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), \
+ ((EMFormat *)(emf))->folder, \
+ ((EMFormat *)(emf))->uid, \
+ ((EMFormat *)(emf))->message, \
+ (emf))
#define em_format_format_error(emf, stream, txt) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_error((emf), (stream), (txt))
#define em_format_format_attachment(emf, stream, msg, type, info) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment((emf), (stream), (msg), (type), (info))
#define em_format_format_message(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_message((emf), (stream), (msg))
diff --git a/mail/em-icon-stream.c b/mail/em-icon-stream.c
index ca0e7b64eb..c35026267c 100644
--- a/mail/em-icon-stream.c
+++ b/mail/em-icon-stream.c
@@ -34,8 +34,16 @@
#include <gtk/gtkimage.h>
#include "em-icon-stream.h"
+#include "e-util/e-msgport.h"
+
#define d(x)
+struct _emis_cache_node {
+ EMCacheNode node;
+
+ GdkPixbuf *pixbuf;
+};
+
static void em_icon_stream_class_init (EMIconStreamClass *klass);
static void em_icon_stream_init (CamelObject *object);
static void em_icon_stream_finalize (CamelObject *object);
@@ -45,6 +53,15 @@ static int emis_sync_close(CamelStream *stream);
static int emis_sync_flush(CamelStream *stream);
static EMSyncStreamClass *parent_class = NULL;
+static EMCache *emis_cache;
+
+static void
+emis_cache_free(void *data)
+{
+ struct _emis_cache_node *node = data;
+
+ g_object_unref(node->pixbuf);
+}
CamelType
em_icon_stream_get_type (void)
@@ -61,6 +78,8 @@ em_icon_stream_get_type (void)
NULL,
(CamelObjectInitFunc) em_icon_stream_init,
(CamelObjectFinalizeFunc) em_icon_stream_finalize);
+
+ emis_cache = em_cache_new(60, sizeof(struct _emis_cache_node), emis_cache_free);
}
return type;
@@ -97,6 +116,9 @@ emis_cleanup(EMIconStream *emis)
emis->destroy_id = 0;
}
+ g_free(emis->key);
+ emis->key = NULL;
+
emis->image = NULL;
emis->sync.cancel = TRUE;
}
@@ -137,6 +159,7 @@ emis_sync_close(CamelStream *stream)
EMIconStream *emis = (EMIconStream *)stream;
int width, height, ratio;
GdkPixbuf *pixbuf, *mini;
+ struct _emis_cache_node *node;
if (emis->loader == NULL)
return -1;
@@ -174,11 +197,16 @@ emis_sync_close(CamelStream *stream)
mini = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR);
#endif
gtk_image_set_from_pixbuf(emis->image, mini);
- g_object_unref(mini);
+ pixbuf = mini;
} else {
+ g_object_ref(pixbuf);
gtk_image_set_from_pixbuf(emis->image, pixbuf);
}
+ node = (struct _emis_cache_node *)em_cache_node_new(emis_cache, emis->key);
+ node->pixbuf = pixbuf;
+ em_cache_add(emis_cache, (EMCacheNode *)node);
+
g_object_unref(emis->loader);
emis->loader = NULL;
@@ -195,14 +223,40 @@ emis_image_destroy(struct _GtkImage *image, EMIconStream *emis)
}
CamelStream *
-em_icon_stream_new(GtkImage *image)
+em_icon_stream_new(GtkImage *image, const char *key)
{
EMIconStream *new;
-
+
new = EM_ICON_STREAM(camel_object_new(EM_ICON_STREAM_TYPE));
new->image = image;
new->destroy_id = g_signal_connect(image, "destroy", G_CALLBACK(emis_image_destroy), new);
new->loader = gdk_pixbuf_loader_new();
+ new->key = g_strdup(key);
return (CamelStream *)new;
}
+
+GdkPixbuf *
+em_icon_stream_get_image(const char *key)
+{
+ struct _emis_cache_node *node;
+ GdkPixbuf *pb = NULL;
+
+ /* forces the cache to be setup if not */
+ em_icon_stream_get_type();
+
+ node = (struct _emis_cache_node *)em_cache_lookup(emis_cache, key);
+ if (node) {
+ pb = node->pixbuf;
+ g_object_ref(pb);
+ em_cache_node_unref(emis_cache, (EMCacheNode *)node);
+ }
+
+ return pb;
+}
+
+void
+em_icon_stream_clear_cache(void)
+{
+ em_cache_clear(emis_cache);
+}
diff --git a/mail/em-icon-stream.h b/mail/em-icon-stream.h
index 3776732578..3b13c7c49f 100644
--- a/mail/em-icon-stream.h
+++ b/mail/em-icon-stream.h
@@ -45,6 +45,7 @@ typedef struct _EMIconStream {
guint destroy_id;
struct _GdkPixbufLoader *loader;
struct _GtkImage *image;
+ char *key;
} EMIconStream;
typedef struct {
@@ -53,7 +54,9 @@ typedef struct {
CamelType em_icon_stream_get_type (void);
-CamelStream *em_icon_stream_new(GtkImage *image);
+CamelStream *em_icon_stream_new(GtkImage *image, const char *key);
+struct _GdkPixbuf *em_icon_stream_get_image(const char *key);
+void em_icon_stream_clear_cache(void);
#ifdef __cplusplus
}
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 7a4c94b3b4..3740e47271 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -2372,7 +2372,7 @@ em_utils_message_to_html(CamelMimeMessage *message, const char *credits, guint32
camel_stream_mem_set_byte_array (mem, buf);
emfq = em_format_quote_new(credits, (CamelStream *)mem, flags);
- em_format_format((EMFormat *)emfq, (CamelMedium *)message);
+ em_format_format((EMFormat *)emfq, NULL, NULL, message);
g_object_unref (emfq);
camel_stream_write ((CamelStream *) mem, "", 1);