diff options
author | Not Zed <NotZed@Ximian.com> | 2004-01-14 10:58:24 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2004-01-14 10:58:24 +0800 |
commit | df12f97f295e461187793034557ef9d8787ffa4b (patch) | |
tree | 06f0a69306c896b875b8ae2b5b1e3b78a7cb0dec | |
parent | b7d6b7be91f2348427d1900b011b069abd0fa40a (diff) | |
download | gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.tar gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.tar.gz gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.tar.bz2 gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.tar.lz gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.tar.xz gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.tar.zst gsoc2013-evolution-df12f97f295e461187793034557ef9d8787ffa4b.zip |
** See bug 51660.
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.
svn path=/trunk/; revision=24210
-rw-r--r-- | mail/ChangeLog | 56 | ||||
-rw-r--r-- | mail/em-folder-view.c | 12 | ||||
-rw-r--r-- | mail/em-format-html-display.c | 49 | ||||
-rw-r--r-- | mail/em-format-html-print.c | 6 | ||||
-rw-r--r-- | mail/em-format-html-print.h | 2 | ||||
-rw-r--r-- | mail/em-format-html-quote.c | 13 | ||||
-rw-r--r-- | mail/em-format-html.c | 79 | ||||
-rw-r--r-- | mail/em-format-quote.c | 10 | ||||
-rw-r--r-- | mail/em-format.c | 105 | ||||
-rw-r--r-- | mail/em-format.h | 20 | ||||
-rw-r--r-- | mail/em-icon-stream.c | 60 | ||||
-rw-r--r-- | mail/em-icon-stream.h | 5 | ||||
-rw-r--r-- | mail/em-utils.c | 2 |
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); |