From 032096185501894e9e0060bccc758d26372061e2 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 5 Sep 2001 22:13:05 +0000 Subject: This patch should avoid flashing when loading images into mail view, credits go to Dan, Larry and me ;) (fixes ximian #6680) 2001-09-06 Radek Doulik * everywhere updated for new mail_content_loaded definition (prototype) 2001-09-05 Radek Doulik * mail-display.c (mail_display_redisplay): increase redisplay_counter (try_part_urls): new helper function (try_data_urls): ditto (load_content_loaded): if it has stream handle available and if it's still valid, it writes to this stream instead of redisplaying, uses try_part_urls and try_data_urls * mail-display.h: added redisplay_counter to MailDisplay, I use it in load_content_loaded to be sure that there wasn't any redisplay and that remembered handle is still valid * mail-display.c (on_url_requested): don't end stream with error if part is not loaded yet (on_url_requested): don't end stream in cases when we are going to load image using http (stream_write_or_redisplay_when_loaded): new helper function, which is extracted from mail_display_redisplay_when_loaded. it's extended to handle gtkhtml stream writting (mail_display_redisplay_when_loaded): use stream_write_or_redisplay_when_loaded (mail_display_stream_write_when_loaded): new function, uses stream_write_or_redisplay_when_loaded struct _load_content_msg: added handle, url and redisplay_counter fields * mail-format.c (mail_content_loaded): added redisplay, url and handle parameter for case when we are loading image content and want it write to stream instead of redisplaying svn path=/trunk/; revision=12633 --- mail/ChangeLog | 37 ++++++++++++ mail/mail-display.c | 166 ++++++++++++++++++++++++++++++++++++++++++--------- mail/mail-display.h | 7 +++ mail/mail-format.c | 11 ++-- mail/mail-identify.c | 2 +- mail/mail.h | 6 +- 6 files changed, 196 insertions(+), 33 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 573d06fd1a..523ff74dac 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,40 @@ +2001-09-06 Radek Doulik + + * everywhere updated for new mail_content_loaded definition + (prototype) + +2001-09-05 Radek Doulik + + * mail-display.c (mail_display_redisplay): increase + redisplay_counter + (try_part_urls): new helper function + (try_data_urls): ditto + (load_content_loaded): if it has stream handle available and if + it's still valid, it writes to this stream instead of + redisplaying, uses try_part_urls and try_data_urls + + * mail-display.h: added redisplay_counter to MailDisplay, I use + it in load_content_loaded to be sure that there wasn't any + redisplay and that remembered handle is still valid + + * mail-display.c (on_url_requested): don't end stream with error + if part is not loaded yet + (on_url_requested): don't end stream in cases when we are going to + load image using http + (stream_write_or_redisplay_when_loaded): new helper function, + which is extracted from mail_display_redisplay_when_loaded. it's + extended to handle gtkhtml stream writting + (mail_display_redisplay_when_loaded): use + stream_write_or_redisplay_when_loaded + (mail_display_stream_write_when_loaded): new function, uses + stream_write_or_redisplay_when_loaded + struct _load_content_msg: added handle, url and redisplay_counter + fields + + * mail-format.c (mail_content_loaded): added redisplay, url and + handle parameter for case when we are loading image content and + want it write to stream instead of redisplaying + 2001-09-05 Ettore Perazzoli * message-browser.c (message_browser_new): s/Evolution/Ximian diff --git a/mail/mail-display.c b/mail/mail-display.c index 75bc012a00..11bce0adc8 100644 --- a/mail/mail-display.c +++ b/mail/mail-display.c @@ -705,7 +705,7 @@ save_url (MailDisplay *md, const char *url) g_return_val_if_fail (CAMEL_IS_MIME_PART (part), NULL); data = camel_medium_get_content_object ((CamelMedium *)part); - if (!mail_content_loaded (data, md)) { + if (!mail_content_loaded (data, md, TRUE, NULL, NULL)) { return NULL; } @@ -984,14 +984,15 @@ on_url_requested (GtkHTML *html, const char *url, GtkHTMLStream *handle, g_return_if_fail (CAMEL_IS_MEDIUM (medium)); data = camel_medium_get_content_object (medium); - if (!mail_content_loaded (data, md)) { - gtk_html_end (html, handle, GTK_HTML_STREAM_ERROR); + if (!mail_content_loaded (data, md, FALSE, url, handle)) return; - } ba = g_byte_array_new (); stream_mem = camel_stream_mem_new_with_byte_array (ba); camel_data_wrapper_write_to_stream (data, stream_mem); + /* printf ("-- begin --\n"); + printf (ba->data); + printf ("-- end --\n"); */ gtk_html_write (html, handle, ba->data, ba->len); camel_object_unref (CAMEL_OBJECT (stream_mem)); @@ -1005,8 +1006,12 @@ on_url_requested (GtkHTML *html, const char *url, GtkHTMLStream *handle, /* See if it's some piece of cached data */ ba = g_hash_table_lookup (urls, url); if (ba) { - if (ba->len) + if (ba->len) { gtk_html_write (html, handle, ba->data, ba->len); + /* printf ("-- begin --\n"); + printf (ba->data); + printf ("-- end --\n"); */ + } gtk_html_end (html, handle, GTK_HTML_STREAM_OK); return; } @@ -1017,8 +1022,8 @@ on_url_requested (GtkHTML *html, const char *url, GtkHTMLStream *handle, g_datalist_get_data (md->data, "load_images")) { ba = g_byte_array_new (); g_hash_table_insert (urls, g_strdup (url), ba); - mail_display_redisplay_when_loaded (md, ba, load_http, - g_strdup (url)); + mail_display_stream_write_when_loaded (md, ba, url, load_http, handle, + g_strdup (url)); } else if (mail_config_get_http_mode () == MAIL_CONFIG_HTTP_SOMETIMES && !g_datalist_get_data (md->data, "checking_from")) { const CamelInternetAddress *from = camel_mime_message_get_from (md->current_message); @@ -1028,16 +1033,20 @@ on_url_requested (GtkHTML *html, const char *url, GtkHTMLStream *handle, GINT_TO_POINTER (1)); if (camel_internet_address_get (from, 0, &name, &addr)) e_book_query_address_locally (addr, ebook_callback, md); + else + gtk_html_end (html, handle, GTK_HTML_STREAM_ERROR); } } - - gtk_html_end (html, handle, GTK_HTML_STREAM_ERROR); } struct _load_content_msg { struct _mail_msg msg; MailDisplay *display; + + GtkHTMLStream *handle; + gint redisplay_counter; + gchar *url; CamelMimeMessage *message; void (*callback)(MailDisplay *, gpointer); gpointer data; @@ -1057,13 +1066,85 @@ load_content_load (struct _mail_msg *mm) m->callback (m->display, m->data); } +static gboolean +try_part_urls (struct _load_content_msg *m) +{ + GHashTable *urls; + CamelMedium *medium; + GByteArray *ba; + + urls = g_datalist_get_data (m->display->data, "part_urls"); + g_return_val_if_fail (urls != NULL, FALSE); + + /* See if it refers to a MIME part (cid: or http:) */ + medium = g_hash_table_lookup (urls, m->url); + if (medium) { + CamelDataWrapper *data; + CamelStream *stream_mem; + + g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), FALSE); + + data = camel_medium_get_content_object (medium); + if (!mail_content_loaded (data, m->display, FALSE, m->url, m->handle)) { + g_warning ("This code should not be reached\n"); + return TRUE; + } + + ba = g_byte_array_new (); + stream_mem = camel_stream_mem_new_with_byte_array (ba); + camel_data_wrapper_write_to_stream (data, stream_mem); + /* printf ("-- begin --\n"); + printf (ba->data); + printf ("-- end --\n"); */ + gtk_html_write (m->display->html, m->handle, ba->data, ba->len); + camel_object_unref (CAMEL_OBJECT (stream_mem)); + + gtk_html_end (m->display->html, m->handle, GTK_HTML_STREAM_OK); + return TRUE; + } + + return FALSE; +} + +static gboolean +try_data_urls (struct _load_content_msg *m) +{ + GHashTable *urls; + GByteArray *ba; + + urls = g_datalist_get_data (m->display->data, "data_urls"); + ba = g_hash_table_lookup (urls, m->url); + + printf ("url: %s data: %p len: %d\n", m->url, ba, ba ? ba->len : -1); + if (ba) { + if (ba->len) { + printf ("writing ...\n"); + gtk_html_write (m->display->html, m->handle, ba->data, ba->len); + } + gtk_html_end (m->display->html, m->handle, GTK_HTML_STREAM_OK); + return TRUE; + } + + return FALSE; +} + static void load_content_loaded (struct _mail_msg *mm) { struct _load_content_msg *m = (struct _load_content_msg *)mm; - if (m->display->current_message == m->message) - mail_display_queue_redisplay (m->display); + if (m->display->current_message == m->message) { + if (m->handle) { + printf ("handle: %p orig: %d actual: %d\n", m->handle, + m->redisplay_counter, + m->display->redisplay_counter); + if (m->redisplay_counter == m->display->redisplay_counter) { + if (!try_part_urls (m) && !try_data_urls (m)) + gtk_html_end (m->display->html, m->handle, GTK_HTML_STREAM_ERROR); + } + } else + mail_display_redisplay (m->display, FALSE); + } } static void @@ -1071,6 +1152,7 @@ load_content_free (struct _mail_msg *mm) { struct _load_content_msg *m = (struct _load_content_msg *)mm; + g_free (m->url); gtk_object_unref (GTK_OBJECT (m->display)); camel_object_unref (CAMEL_OBJECT (m->message)); } @@ -1082,11 +1164,13 @@ static struct _mail_msg_op load_content_op = { load_content_free, }; -void -mail_display_redisplay_when_loaded (MailDisplay *md, - gconstpointer key, - void (*callback)(MailDisplay *, gpointer), - gpointer data) +static void +stream_write_or_redisplay_when_loaded (MailDisplay *md, + gconstpointer key, + const gchar *url, + void (*callback)(MailDisplay *, gpointer), + GtkHTMLStream *handle, + gpointer data) { struct _load_content_msg *m; GHashTable *loading; @@ -1104,6 +1188,9 @@ mail_display_redisplay_when_loaded (MailDisplay *md, m = mail_msg_new (&load_content_op, NULL, sizeof (*m)); m->display = md; + m->handle = handle; + m->url = g_strdup (url); + m->redisplay_counter = md->redisplay_counter; gtk_object_ref (GTK_OBJECT (m->display)); m->message = md->current_message; camel_object_ref (CAMEL_OBJECT (m->message)); @@ -1114,6 +1201,26 @@ mail_display_redisplay_when_loaded (MailDisplay *md, return; } +void +mail_display_stream_write_when_loaded (MailDisplay *md, + gconstpointer key, + const gchar *url, + void (*callback)(MailDisplay *, gpointer), + GtkHTMLStream *handle, + gpointer data) +{ + stream_write_or_redisplay_when_loaded (md, key, url, callback, handle, data); +} + +void +mail_display_redisplay_when_loaded (MailDisplay *md, + gconstpointer key, + void (*callback)(MailDisplay *, gpointer), + gpointer data) +{ + stream_write_or_redisplay_when_loaded (md, key, NULL, callback, NULL, data); +} + void mail_html_write (GtkHTML *html, GtkHTMLStream *stream, const char *format, ...) @@ -1125,6 +1232,7 @@ mail_html_write (GtkHTML *html, GtkHTMLStream *stream, buf = g_strdup_vprintf (format, ap); va_end (ap); gtk_html_write (html, stream, buf, strlen (buf)); + /* printf (buf); */ g_free (buf); } @@ -1191,6 +1299,9 @@ void mail_display_redisplay (MailDisplay *md, gboolean unscroll) { md->last_active = NULL; + md->redisplay_counter ++; + /* printf ("md %p redisplay %d\n", md, md->redisplay_counter); */ + md->stream = gtk_html_begin (GTK_HTML (md->html)); if (!unscroll) { /* This is a hack until there's a clean way to do this. */ @@ -1266,19 +1377,20 @@ mail_display_init (GtkObject *object) { MailDisplay *mail_display = MAIL_DISPLAY (object); - mail_display->current_message = NULL; - mail_display->scroll = NULL; - mail_display->html = NULL; - mail_display->stream = NULL; - mail_display->last_active = NULL; - mail_display->idle_id = 0; - mail_display->selection = NULL; - mail_display->current_message = NULL; - mail_display->data = NULL; + mail_display->current_message = NULL; + mail_display->scroll = NULL; + mail_display->html = NULL; + mail_display->redisplay_counter = 0; + mail_display->stream = NULL; + mail_display->last_active = NULL; + mail_display->idle_id = 0; + mail_display->selection = NULL; + mail_display->current_message = NULL; + mail_display->data = NULL; - mail_display->invisible = gtk_invisible_new (); + mail_display->invisible = gtk_invisible_new (); - mail_display->display_style = mail_config_get_message_display_style (); + mail_display->display_style = mail_config_get_message_display_style (); } static void diff --git a/mail/mail-display.h b/mail/mail-display.h index b08fa12927..5a6b76c257 100644 --- a/mail/mail-display.h +++ b/mail/mail-display.h @@ -27,6 +27,7 @@ struct _MailDisplay { EScrollFrame *scroll; GtkHTML *html; GtkHTMLStream *stream; + gint redisplay_counter; gpointer last_active; guint idle_id; @@ -55,6 +56,12 @@ void mail_display_redisplay_when_loaded (MailDisplay *md, gconstpointer key, void (*callback)(MailDisplay *, gpointer), gpointer data); +void mail_display_stream_write_when_loaded (MailDisplay *md, + gconstpointer key, + const gchar *url, + void (*callback)(MailDisplay *, gpointer), + GtkHTMLStream *handle, + gpointer data); void mail_display_set_message (MailDisplay *mail_display, CamelMedium *medium); diff --git a/mail/mail-format.c b/mail/mail-format.c index aaf8ec84f6..27f4506ad6 100644 --- a/mail/mail-format.c +++ b/mail/mail-format.c @@ -676,7 +676,7 @@ format_mime_part (CamelMimePart *part, MailDisplay *md) mesg = e_utf8_from_locale_string (_("Could not parse MIME message. Displaying as source.")); mail_error_write (md->html, md->stream, "%s", mesg); g_free (mesg); - if (mail_content_loaded (wrapper, md)) + if (mail_content_loaded (wrapper, md, TRUE, NULL, NULL)) handle_text_plain (part, "text/plain", md); return TRUE; } @@ -712,7 +712,7 @@ format_mime_part (CamelMimePart *part, MailDisplay *md) attachment_header (part, mime_type, md); if (handler && handler->builtin && inline_flags & I_DISPLAYED && - mail_content_loaded (wrapper, md)) + mail_content_loaded (wrapper, md, TRUE, NULL, NULL)) output = (*handler->builtin) (part, mime_type, md); else output = TRUE; @@ -990,13 +990,16 @@ load_offline_content (MailDisplay *md, gpointer data) } gboolean -mail_content_loaded (CamelDataWrapper *wrapper, MailDisplay *md) +mail_content_loaded (CamelDataWrapper *wrapper, MailDisplay *md, gboolean redisplay, const gchar *url, GtkHTMLStream *handle) { if (!camel_data_wrapper_is_offline (wrapper)) return TRUE; camel_object_ref (CAMEL_OBJECT (wrapper)); - mail_display_redisplay_when_loaded (md, wrapper, load_offline_content, wrapper); + if (redisplay) + mail_display_redisplay_when_loaded (md, wrapper, load_offline_content, wrapper); + else + mail_display_stream_write_when_loaded (md, wrapper, url, load_offline_content, handle, wrapper); return FALSE; } diff --git a/mail/mail-identify.c b/mail/mail-identify.c index 7742da0379..e3a0eefb14 100644 --- a/mail/mail-identify.c +++ b/mail/mail-identify.c @@ -95,7 +95,7 @@ mail_identify_mime_part (CamelMimePart *part, MailDisplay *md) * just to identify the MIME type. */ if (camel_data_wrapper_is_offline (data)) - mail_content_loaded (data, md); + mail_content_loaded (data, md, TRUE, NULL, NULL); return NULL; } diff --git a/mail/mail.h b/mail/mail.h index 509d5647d0..b8f96739b1 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -40,7 +40,11 @@ void mail_format_mime_message (CamelMimeMessage *mime_message, MailDisplay *md); void mail_format_raw_message (CamelMimeMessage *mime_message, MailDisplay *md); -gboolean mail_content_loaded (CamelDataWrapper *wrapper, MailDisplay *display); +gboolean mail_content_loaded (CamelDataWrapper *wrapper, + MailDisplay *display, + gboolean redisplay, + const gchar *url, + GtkHTMLStream *handle); typedef gboolean (*MailMimeHandlerFn) (CamelMimePart *part, const char *mime_type, -- cgit v1.2.3