diff options
Diffstat (limited to 'mail/em-format-html.c')
-rw-r--r-- | mail/em-format-html.c | 749 |
1 files changed, 388 insertions, 361 deletions
diff --git a/mail/em-format-html.c b/mail/em-format-html.c index bafb82ae36..6308947a26 100644 --- a/mail/em-format-html.c +++ b/mail/em-format-html.c @@ -135,12 +135,7 @@ static void efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh); static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); -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_source(EMFormat *, CamelStream *, CamelMimePart *); -static void efh_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const char *, const EMFormatHandler *); static void efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid); -static gboolean efh_busy(EMFormat *); static void efh_builtin_init(EMFormatHTMLClass *efhc); @@ -151,6 +146,230 @@ static CamelDataCache *emfh_http_cache; #define EMFH_HTTP_CACHE_PATH "http" +/* Sigh, this is so we have a cancellable, async rendering thread */ +struct _format_msg { + MailMsg base; + + EMFormatHTML *format; + EMFormat *format_source; + EMHTMLStream *estream; + CamelFolder *folder; + char *uid; + CamelMimeMessage *message; +}; + +static gchar * +efh_format_desc (struct _format_msg *m) +{ + return g_strdup(_("Formatting message")); +} + +static void +efh_format_exec (struct _format_msg *m) +{ + struct _EMFormatHTMLJob *job; + struct _EMFormatPURITree *puri_level; + int cancelled = FALSE; + CamelURL *base; + + if (m->format->html == NULL) + return; + + camel_stream_printf ( + (CamelStream *)m->estream, + "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" + "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n" + "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n", + e_color_to_value ( + &m->format->priv->colors[ + EM_FORMAT_HTML_COLOR_BODY]), + e_color_to_value ( + &m->format->priv->colors[ + EM_FORMAT_HTML_COLOR_HEADER])); + + /* <insert top-header stuff here> */ + + if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE) { + em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message); + } else { + const EMFormatHandler *handle; + + handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/prefix"); + if (handle) + handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle); + handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822"); + if (handle) + handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle); + handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/post-header-closure"); + if (handle && !((EMFormat *)m->format)->print) + handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle); + + } + + camel_stream_flush((CamelStream *)m->estream); + + puri_level = ((EMFormat *)m->format)->pending_uri_level; + base = ((EMFormat *)m->format)->base; + + do { + /* now dispatch any added tasks ... */ + g_mutex_lock(m->format->priv->lock); + while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) { + g_mutex_unlock(m->format->priv->lock); + + /* This is an implicit check to see if the gtkhtml has been destroyed */ + if (!cancelled) + cancelled = m->format->html == NULL; + + /* Now do an explicit check for user cancellation */ + if (!cancelled) + cancelled = camel_operation_cancel_check(NULL); + + /* call jobs even if cancelled, so they can clean up resources */ + ((EMFormat *)m->format)->pending_uri_level = job->puri_level; + if (job->base) + ((EMFormat *)m->format)->base = job->base; + job->callback(job, cancelled); + ((EMFormat *)m->format)->base = base; + + /* clean up the job */ + camel_object_unref(job->stream); + if (job->base) + camel_url_free(job->base); + g_free(job); + + g_mutex_lock(m->format->priv->lock); + } + g_mutex_unlock(m->format->priv->lock); + + if (m->estream) { + /* Closing this base stream can queue more jobs, so we need + to check the list again after we've finished */ + d(printf("out of jobs, closing root stream\n")); + camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n"); + camel_stream_close((CamelStream *)m->estream); + camel_object_unref(m->estream); + m->estream = NULL; + } + + /* e_dlist_empty is atomic and doesn't need locking */ + } while (!e_dlist_empty(&m->format->priv->pending_jobs)); + + d(printf("out of jobs, done\n")); + + ((EMFormat *)m->format)->pending_uri_level = puri_level; +} + +static void +efh_format_done (struct _format_msg *m) +{ + d(printf("formatting finished\n")); + + m->format->priv->format_id = -1; + m->format->priv->load_images_now = FALSE; + m->format->state = EM_FORMAT_HTML_STATE_NONE; + g_signal_emit_by_name(m->format, "complete"); +} + +static void +efh_format_free (struct _format_msg *m) +{ + d(printf("formatter freed\n")); + g_object_unref(m->format); + if (m->estream) { + 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) + g_object_unref(m->format_source); +} + +static MailMsgInfo efh_format_info = { + sizeof (struct _format_msg), + (MailMsgDescFunc) efh_format_desc, + (MailMsgExecFunc) efh_format_exec, + (MailMsgDoneFunc) efh_format_done, + (MailMsgFreeFunc) efh_format_free +}; + +static gboolean +efh_format_timeout(struct _format_msg *m) +{ + GtkHTMLStream *hstream; + EMFormatHTML *efh = m->format; + struct _EMFormatHTMLPrivate *p = efh->priv; + + if (m->format->html == NULL) { + mail_msg_unref(m); + return FALSE; + } + + d(printf("timeout called ...\n")); + if (p->format_id != -1) { + d(printf(" still waiting for cancellation to take effect, waiting ...\n")); + return TRUE; + } + + g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE); + + d(printf(" ready to go, firing off format thread\n")); + + /* call super-class to kick it off */ + EM_FORMAT_CLASS (parent_class)->format_clone ( + EM_FORMAT (efh), m->folder, m->uid, + m->message, m->format_source); + em_format_html_clear_pobject(m->format); + + /* FIXME: method off EMFormat? */ + if (((EMFormat *)efh)->valid) { + camel_cipher_validity_free(((EMFormat *)efh)->valid); + ((EMFormat *)efh)->valid = NULL; + ((EMFormat *)efh)->valid_parent = NULL; + } + + if (m->message == NULL) { + hstream = gtk_html_begin(efh->html); + gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK); + mail_msg_unref(m); + p->last_part = NULL; + } else { + efh->state = EM_FORMAT_HTML_STATE_RENDERING; + + if (p->last_part != m->message) { + hstream = gtk_html_begin (efh->html); + gtk_html_stream_printf (hstream, "<h5>%s</h5>", _("Formatting Message...")); + gtk_html_stream_close (hstream, GTK_HTML_STREAM_OK); + } + + hstream = NULL; + m->estream = (EMHTMLStream *)em_html_stream_new(efh->html, hstream); + + if (p->last_part == m->message) { + em_html_stream_set_flags (m->estream, + GTK_HTML_BEGIN_KEEP_SCROLL | GTK_HTML_BEGIN_KEEP_IMAGES + | GTK_HTML_BEGIN_BLOCK_UPDATES | GTK_HTML_BEGIN_BLOCK_IMAGES); + } else { + /* clear cache of inline-scanned text parts */ + g_hash_table_remove_all(p->text_inline_parts); + + p->last_part = m->message; + } + + efh->priv->format_id = m->base.seq; + mail_msg_unordered_push (m); + } + + efh->priv->format_timeout_id = 0; + efh->priv->format_timeout_msg = NULL; + + return FALSE; +} + static void efh_free_cache(struct _EMFormatHTMLCache *efhc) { @@ -371,6 +590,143 @@ efh_finalize (GObject *object) } static void +efh_format_clone (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *msg, + EMFormat *emfsource) +{ + EMFormatHTML *efh = EM_FORMAT_HTML (emf); + struct _format_msg *m; + + /* How to sub-class ? Might need to adjust api ... */ + + if (efh->html == NULL) + return; + + d(printf("efh_format called\n")); + if (efh->priv->format_timeout_id != 0) { + d(printf(" timeout for last still active, removing ...\n")); + g_source_remove(efh->priv->format_timeout_id); + efh->priv->format_timeout_id = 0; + mail_msg_unref(efh->priv->format_timeout_msg); + efh->priv->format_timeout_msg = NULL; + } + + if (emfsource != NULL) + g_object_ref (emfsource); + + if (folder != NULL) + camel_object_ref (folder); + + if (msg != NULL) + camel_object_ref (msg); + + m = mail_msg_new (&efh_format_info); + m->format = g_object_ref (emf); + m->format_source = emfsource; + m->folder = folder; + m->uid = g_strdup (uid); + m->message = msg; + + if (efh->priv->format_id == -1) { + d(printf(" idle, forcing format\n")); + efh_format_timeout (m); + } else { + d(printf(" still busy, cancelling and queuing wait\n")); + /* cancel and poll for completion */ + mail_msg_cancel (efh->priv->format_id); + efh->priv->format_timeout_msg = m; + efh->priv->format_timeout_id = g_timeout_add ( + 100, (GSourceFunc) efh_format_timeout, m); + } +} + +static void +efh_format_error (EMFormat *emf, + CamelStream *stream, + const gchar *txt) +{ + gchar *html; + + html = camel_text_to_html ( + txt, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | + CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); + camel_stream_printf ( + stream, "<em><font color=\"red\">%s</font></em><br>", html); + g_free (html); +} + +static void +efh_format_source (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part) +{ + CamelStreamFilter *filtered_stream; + CamelMimeFilter *filter; + CamelDataWrapper *dw = (CamelDataWrapper *) part; + + filtered_stream = camel_stream_filter_new_with_stream (stream); + + filter = camel_mime_filter_tohtml_new ( + CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | + CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES | + CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT, 0); + camel_stream_filter_add (filtered_stream, filter); + camel_object_unref (filter); + + camel_stream_write_string (stream, "<table><tr><td><tt>"); + em_format_format_text (emf, (CamelStream *) filtered_stream, dw); + camel_object_unref (filtered_stream); + + camel_stream_write_string(stream, "</tt></td></tr></table>"); +} + +static void +efh_format_attachment (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part, + const gchar *mime_type, + const EMFormatHandler *handle) +{ + char *text, *html; + + /* we display all inlined attachments only */ + + /* this could probably be cleaned up ... */ + camel_stream_write_string ( + stream, + "<table border=1 cellspacing=0 cellpadding=0><tr><td>" + "<table width=10 cellspacing=0 cellpadding=0>" + "<tr><td></td></tr></table></td>" + "<td><table width=3 cellspacing=0 cellpadding=0>" + "<tr><td></td></tr></table></td><td><font size=-1>\n"); + + /* output some info about it */ + text = em_format_describe_part(part, mime_type); + html = camel_text_to_html ( + text, ((EMFormatHTML *)emf)->text_html_flags & + CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); + camel_stream_write_string (stream, html); + g_free (html); + g_free (text); + + camel_stream_write_string (stream, "</font></td></tr><tr></table>"); + + if (handle && em_format_is_inline (emf, emf->part_id->str, part, handle)) + handle->handler (emf, stream, part, handle); +} + +static gboolean +efh_busy (EMFormat *emf) +{ + EMFormatHTMLPrivate *priv; + + priv = EM_FORMAT_HTML_GET_PRIVATE (emf); + + return (priv->format_id != -1); +} +static void efh_base_init (EMFormatHTMLClass *class) { efh_builtin_init (class); @@ -399,6 +755,8 @@ efh_class_init (EMFormatHTMLClass *class) format_class->format_secure = efh_format_secure; format_class->busy = efh_busy; + class->html_widget_type = GTK_TYPE_HTML; + g_object_class_install_property ( object_class, PROP_BODY_COLOR, @@ -516,8 +874,10 @@ efh_class_init (EMFormatHTMLClass *class) } static void -efh_init (EMFormatHTML *efh) +efh_init (EMFormatHTML *efh, + EMFormatHTMLClass *class) { + GtkHTML *html; GdkColor *color; efh->priv = EM_FORMAT_HTML_GET_PRIVATE (efh); @@ -531,32 +891,35 @@ efh_init (EMFormatHTML *efh) (GDestroyNotify) NULL, (GDestroyNotify) efh_free_cache); - efh->html = (GtkHTML *) gtk_html_new (); - g_object_ref_sink(efh->html); + html = g_object_new (class->html_widget_type, NULL); + efh->html = g_object_ref_sink (html); - gtk_html_set_blocking (efh->html, FALSE); - gtk_html_set_caret_first_focus_anchor (efh->html, EFM_MESSAGE_START_ANAME); + gtk_html_set_blocking (html, FALSE); + gtk_html_set_caret_first_focus_anchor (html, EFM_MESSAGE_START_ANAME); + gtk_html_set_default_content_type (html, "text/html; charset=utf-8"); + gtk_html_set_editable (html, FALSE); - gtk_html_set_default_content_type(efh->html, "text/html; charset=utf-8"); - gtk_html_set_editable(efh->html, FALSE); - - g_signal_connect(efh->html, "url_requested", G_CALLBACK(efh_url_requested), efh); - g_signal_connect(efh->html, "object_requested", G_CALLBACK(efh_object_requested), efh); + g_signal_connect ( + html, "url-requested", + G_CALLBACK (efh_url_requested), efh); + g_signal_connect ( + html, "object-requested", + G_CALLBACK (efh_object_requested), efh); color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_BODY]; - gdk_color_parse ("0xeeeeee", color); + gdk_color_parse ("#eeeeee", color); color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_CONTENT]; - gdk_color_parse ("0xffffff", color); + gdk_color_parse ("#ffffff", color); color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_FRAME]; - gdk_color_parse ("0x3f3f3f", color); + gdk_color_parse ("#3f3f3f", color); color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_HEADER]; - gdk_color_parse ("0xeeeeee", color); + gdk_color_parse ("#eeeeee", color); color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_TEXT]; - gdk_color_parse ("0x000000", color); + gdk_color_parse ("#000000", color); efh->text_html_flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | @@ -590,18 +953,13 @@ em_format_html_get_type (void) }; type = g_type_register_static ( - em_format_get_type(), "EMFormatHTML", &type_info, 0); + em_format_get_type(), "EMFormatHTML", + &type_info, G_TYPE_FLAG_ABSTRACT); } return type; } -EMFormatHTML * -em_format_html_new(void) -{ - return g_object_new (EM_TYPE_FORMAT_HTML, NULL); -} - void em_format_html_load_images (EMFormatHTML *efh) { @@ -688,7 +1046,7 @@ em_format_html_get_image_loading_policy (EMFormatHTML *efh) { g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), 0); - return efh->priv->image_loading_policy;; + return efh->priv->image_loading_policy; } void @@ -1711,284 +2069,6 @@ efh_builtin_init(EMFormatHTMLClass *efhc) /* ********************************************************************** */ -/* Sigh, this is so we have a cancellable, async rendering thread */ -struct _format_msg { - MailMsg base; - - EMFormatHTML *format; - EMFormat *format_source; - EMHTMLStream *estream; - CamelFolder *folder; - char *uid; - CamelMimeMessage *message; -}; - -static gchar * -efh_format_desc (struct _format_msg *m) -{ - return g_strdup(_("Formatting message")); -} - -static void -efh_format_exec (struct _format_msg *m) -{ - struct _EMFormatHTMLJob *job; - struct _EMFormatPURITree *puri_level; - int cancelled = FALSE; - CamelURL *base; - - if (m->format->html == NULL) - return; - - camel_stream_printf ( - (CamelStream *)m->estream, - "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" - "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n" - "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n", - e_color_to_value ( - &m->format->priv->colors[ - EM_FORMAT_HTML_COLOR_BODY]), - e_color_to_value ( - &m->format->priv->colors[ - EM_FORMAT_HTML_COLOR_HEADER])); - - /* <insert top-header stuff here> */ - - if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE) { - em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message); - } else { - const EMFormatHandler *handle; - - handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/prefix"); - if (handle) - handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle); - handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822"); - if (handle) - handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle); - handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/post-header-closure"); - if (handle && !((EMFormat *)m->format)->print) - handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle); - - } - - camel_stream_flush((CamelStream *)m->estream); - - puri_level = ((EMFormat *)m->format)->pending_uri_level; - base = ((EMFormat *)m->format)->base; - - do { - /* now dispatch any added tasks ... */ - g_mutex_lock(m->format->priv->lock); - while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) { - g_mutex_unlock(m->format->priv->lock); - - /* This is an implicit check to see if the gtkhtml has been destroyed */ - if (!cancelled) - cancelled = m->format->html == NULL; - - /* Now do an explicit check for user cancellation */ - if (!cancelled) - cancelled = camel_operation_cancel_check(NULL); - - /* call jobs even if cancelled, so they can clean up resources */ - ((EMFormat *)m->format)->pending_uri_level = job->puri_level; - if (job->base) - ((EMFormat *)m->format)->base = job->base; - job->callback(job, cancelled); - ((EMFormat *)m->format)->base = base; - - /* clean up the job */ - camel_object_unref(job->stream); - if (job->base) - camel_url_free(job->base); - g_free(job); - - g_mutex_lock(m->format->priv->lock); - } - g_mutex_unlock(m->format->priv->lock); - - if (m->estream) { - /* Closing this base stream can queue more jobs, so we need - to check the list again after we've finished */ - d(printf("out of jobs, closing root stream\n")); - camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n"); - camel_stream_close((CamelStream *)m->estream); - camel_object_unref(m->estream); - m->estream = NULL; - } - - /* e_dlist_empty is atomic and doesn't need locking */ - } while (!e_dlist_empty(&m->format->priv->pending_jobs)); - - d(printf("out of jobs, done\n")); - - ((EMFormat *)m->format)->pending_uri_level = puri_level; -} - -static void -efh_format_done (struct _format_msg *m) -{ - d(printf("formatting finished\n")); - - m->format->priv->format_id = -1; - m->format->priv->load_images_now = FALSE; - m->format->state = EM_FORMAT_HTML_STATE_NONE; - g_signal_emit_by_name(m->format, "complete"); -} - -static void -efh_format_free (struct _format_msg *m) -{ - d(printf("formatter freed\n")); - g_object_unref(m->format); - if (m->estream) { - 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) - g_object_unref(m->format_source); -} - -static MailMsgInfo efh_format_info = { - sizeof (struct _format_msg), - (MailMsgDescFunc) efh_format_desc, - (MailMsgExecFunc) efh_format_exec, - (MailMsgDoneFunc) efh_format_done, - (MailMsgFreeFunc) efh_format_free -}; - -static gboolean -efh_format_timeout(struct _format_msg *m) -{ - GtkHTMLStream *hstream; - EMFormatHTML *efh = m->format; - struct _EMFormatHTMLPrivate *p = efh->priv; - - if (m->format->html == NULL) { - mail_msg_unref(m); - return FALSE; - } - - d(printf("timeout called ...\n")); - if (p->format_id != -1) { - d(printf(" still waiting for cancellation to take effect, waiting ...\n")); - return TRUE; - } - - g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE); - - d(printf(" ready to go, firing off format thread\n")); - - /* call super-class to kick it off */ - EM_FORMAT_CLASS (parent_class)->format_clone ( - EM_FORMAT (efh), m->folder, m->uid, - m->message, m->format_source); - em_format_html_clear_pobject(m->format); - - /* FIXME: method off EMFormat? */ - if (((EMFormat *)efh)->valid) { - camel_cipher_validity_free(((EMFormat *)efh)->valid); - ((EMFormat *)efh)->valid = NULL; - ((EMFormat *)efh)->valid_parent = NULL; - } - - if (m->message == NULL) { - hstream = gtk_html_begin(efh->html); - gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK); - mail_msg_unref(m); - p->last_part = NULL; - } else { - efh->state = EM_FORMAT_HTML_STATE_RENDERING; - - if (p->last_part != m->message) { - hstream = gtk_html_begin (efh->html); - gtk_html_stream_printf (hstream, "<h5>%s</h5>", _("Formatting Message...")); - gtk_html_stream_close (hstream, GTK_HTML_STREAM_OK); - } - - hstream = NULL; - m->estream = (EMHTMLStream *)em_html_stream_new(efh->html, hstream); - - if (p->last_part == m->message) { - em_html_stream_set_flags (m->estream, - GTK_HTML_BEGIN_KEEP_SCROLL | GTK_HTML_BEGIN_KEEP_IMAGES - | GTK_HTML_BEGIN_BLOCK_UPDATES | GTK_HTML_BEGIN_BLOCK_IMAGES); - } else { - /* clear cache of inline-scanned text parts */ - g_hash_table_remove_all(p->text_inline_parts); - - p->last_part = m->message; - } - - efh->priv->format_id = m->base.seq; - mail_msg_unordered_push (m); - } - - efh->priv->format_timeout_id = 0; - efh->priv->format_timeout_msg = NULL; - - return FALSE; -} - -static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource) -{ - EMFormatHTML *efh = (EMFormatHTML *)emf; - struct _format_msg *m; - - /* How to sub-class ? Might need to adjust api ... */ - - if (efh->html == NULL) - return; - - d(printf("efh_format called\n")); - if (efh->priv->format_timeout_id != 0) { - d(printf(" timeout for last still active, removing ...\n")); - g_source_remove(efh->priv->format_timeout_id); - efh->priv->format_timeout_id = 0; - mail_msg_unref(efh->priv->format_timeout_msg); - efh->priv->format_timeout_msg = NULL; - } - - m = mail_msg_new(&efh_format_info); - m->format = (EMFormatHTML *)emf; - g_object_ref(emf); - m->format_source = emfsource; - if (emfsource) - g_object_ref(emfsource); - 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")); - efh_format_timeout(m); - } else { - d(printf(" still busy, cancelling and queuing wait\n")); - /* cancel and poll for completion */ - mail_msg_cancel(efh->priv->format_id); - efh->priv->format_timeout_msg = m; - efh->priv->format_timeout_id = g_timeout_add(100, (GSourceFunc)efh_format_timeout, m); - } -} - -static void efh_format_error(EMFormat *emf, CamelStream *stream, const char *txt) -{ - char *html; - - html = camel_text_to_html (txt, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL|CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); - camel_stream_printf(stream, "<em><font color=\"red\">%s</font></em><br>", html); - g_free(html); -} - static void efh_format_text_header (EMFormatHTML *emfh, CamelStream *stream, const char *label, const char *value, guint32 flags) { @@ -2563,7 +2643,8 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part) } } -static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) +static void +efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) { const EMFormatHandler *handle; @@ -2595,57 +2676,3 @@ static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart emf->valid = save; emf->valid_parent = save_parent; } - -static void efh_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part) -{ - CamelStreamFilter *filtered_stream; - CamelMimeFilter *html_filter; - CamelDataWrapper *dw = (CamelDataWrapper *)part; - - filtered_stream = camel_stream_filter_new_with_stream ((CamelStream *) stream); - html_filter = camel_mime_filter_tohtml_new (CAMEL_MIME_FILTER_TOHTML_CONVERT_NL - | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES - | CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT, 0); - camel_stream_filter_add(filtered_stream, html_filter); - camel_object_unref(html_filter); - - camel_stream_write_string((CamelStream *)stream, "<table><tr><td><tt>"); - em_format_format_text(emf, (CamelStream *)filtered_stream, dw); - camel_object_unref(filtered_stream); - - camel_stream_write_string(stream, "</tt></td></tr></table>"); -} - -static void -efh_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const char *mime_type, const EMFormatHandler *handle) -{ - char *text, *html; - - /* we display all inlined attachments only */ - - /* this could probably be cleaned up ... */ - camel_stream_write_string(stream, - "<table border=1 cellspacing=0 cellpadding=0><tr><td>" - "<table width=10 cellspacing=0 cellpadding=0>" - "<tr><td></td></tr></table></td>" - "<td><table width=3 cellspacing=0 cellpadding=0>" - "<tr><td></td></tr></table></td><td><font size=-1>\n"); - - /* output some info about it */ - text = em_format_describe_part(part, mime_type); - html = camel_text_to_html(text, ((EMFormatHTML *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); - camel_stream_write_string(stream, html); - g_free(html); - g_free(text); - - camel_stream_write_string(stream, "</font></td></tr><tr></table>"); - - if (handle && em_format_is_inline(emf, emf->part_id->str, part, handle)) - handle->handler(emf, stream, part, handle); -} - -static gboolean -efh_busy(EMFormat *emf) -{ - return (((EMFormatHTML *)emf)->priv->format_id != -1); -} |