[balsa] Implement user-controlled image download



commit 051ed8c90e594da6321a1a1437409063667317b4
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Mon Jan 11 19:23:47 2010 -0500

    Implement user-controlled image download

 ChangeLog                    |   16 ++
 libbalsa/html.c              |  383 +++++++++++++++++++++++++++++++-----------
 libbalsa/html.h              |    5 +-
 src/balsa-mime-widget-text.c |   49 +++---
 4 files changed, 326 insertions(+), 127 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 70588a3..47d86aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2010-01-11  Peter Bloomfield
 
+	* libbalsa/html.h: new API for libbalsa_html_new.
+	* src/balsa-mime-widget-text.c (balsa_mime_widget_new_text),
+	(bm_widget_new_html): use it.
+	* libbalsa/html.c (lbh_get_body_content,
+	lbh_get_web_view, libbalsa_html_can_zoom,
+	libbalsa_html_zoom, libbalsa_html_can_select,
+	libbalsa_html_select_all, libbalsa_html_copy,
+	libbalsa_html_can_search, libbalsa_html_search_text,
+	libbalsa_html_get_selection_bounds): implement new API;
+	(lbh_info_bar_realize_cb, lbh_info_bar_widget,
+	lbh_resource_request_starting_cb, lbh_info_bar_response_cb,
+	libbalsa_html_new): prepend HTML message part with a GtkInfoBar
+	offering the option to download images.
+
+2010-01-11  Peter Bloomfield
+
 	* src/balsa-message.c (add_part), (balsa_message_can_select):
 	html widgets can select text.
 
diff --git a/libbalsa/html.c b/libbalsa/html.c
index 86bbd2f..53f712b 100644
--- a/libbalsa/html.c
+++ b/libbalsa/html.c
@@ -42,13 +42,39 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <glib/gi18n.h>
 
 #ifdef HAVE_GTKHTML
 
-/* We need the declaration of LibBalsaMessage, but including "message.h"
- * directly gets into some kind of circular #include problem, whereas
- * including it indirectly through "libbalsa.h" doesn't! */
-#include "libbalsa.h"
+/*
+ * Used by all HTML widgets
+ *
+ * returns -1 on error
+ * otherwise, caller must g_free buf
+ */
+static gssize
+lbh_get_body_content(LibBalsaMessageBody * body, gchar ** buf)
+{
+    gssize len;
+    GError *err = NULL;
+    LibBalsaHTMLType html_type;
+    gchar *content_type;
+
+    len = libbalsa_message_body_get_content(body, buf, &err);
+    if (len < 0) {
+        libbalsa_information(LIBBALSA_INFORMATION_ERROR,
+                             _("Could not get an HTML part: %s"),
+                             err ? err->message : "Unknown error");
+        g_error_free(err);
+        return len;
+    }
+
+    content_type = libbalsa_message_body_get_mime_type(body);
+    html_type = libbalsa_html_type(content_type);
+    g_free(content_type);
+
+    return libbalsa_html_filter(html_type, buf, len);
+}
 
 # if defined(HAVE_WEBKIT)
 
@@ -60,11 +86,15 @@
 #include <JavaScriptCore/JavaScript.h>
 
 typedef struct {
-    WebKitWebView        *web_view;
-    WebKitWebFrame       *frame;
+    LibBalsaMessageBody  *body;
     LibBalsaHtmlCallback  hover_cb;
     LibBalsaHtmlCallback  clicked_cb;
-    LibBalsaMessage      *message;
+    WebKitWebFrame       *frame;
+#if GTK_CHECK_VERSION(2, 18, 0)
+    gboolean              download_images;
+    GtkWidget            *info_bar_widget;
+#endif /* GTK_CHECK_VERSION(2, 18, 0) */
+    WebKitWebView        *web_view;
 } LibBalsaWebKitInfo;
 
 /*
@@ -142,17 +172,41 @@ lbh_resource_request_starting_cb(WebKitWebView         * web_view,
                                  gpointer                data)
 {
     const gchar *uri = webkit_network_request_get_uri(request);
+    LibBalsaWebKitInfo *info = data;
+
+    if (!g_ascii_strcasecmp(uri, "about:blank"))
+        return;
 
     if (g_ascii_strncasecmp(uri, "cid:", 4)) {
         /* Not a "cid:" request: disable loading. */
+#if GTK_CHECK_VERSION(2, 18, 0)
+        static GHashTable *cache = NULL;
+
+        if (!cache)
+            cache = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                          g_free, NULL);
+
+        if (!g_hash_table_lookup(cache, uri)) {
+            if (info->download_images) {
+                g_hash_table_insert(cache, g_strdup(uri),
+                                    GINT_TO_POINTER(TRUE));
+            } else {
+                webkit_network_request_set_uri(request, "about:blank");
+                gtk_widget_show_all(info->info_bar_widget);
+                gtk_info_bar_set_default_response(GTK_INFO_BAR
+                                                  (info->info_bar_widget),
+                                                  GTK_RESPONSE_CLOSE);
+            }
+        }
+#else  /* GTK_CHECK_VERSION(2, 18, 0) */
         webkit_network_request_set_uri(request, "about:blank");
+#endif /* GTK_CHECK_VERSION(2, 18, 0) */
     } else {
-        LibBalsaWebKitInfo *info = data;
         LibBalsaMessageBody *body;
 
         /* Replace "cid:" request with a "file:" request. */
         if ((body =
-             libbalsa_message_get_part_by_id(info->message, uri + 4))
+             libbalsa_message_get_part_by_id(info->body->message, uri + 4))
             && libbalsa_message_body_save_temporary(body, NULL)) {
             gchar *file_uri =
                 g_strconcat("file://", body->temp_filename, NULL);
@@ -234,69 +288,162 @@ lbh_create_web_view_cb(WebKitWebView  * web_view,
     return WEBKIT_WEB_VIEW(widget);
 }
 
+#if GTK_CHECK_VERSION(2, 18, 0)
+/*
+ * Make the GtkInfoBar for asking about downloading images
+ */
+
+static void
+lbh_info_bar_response_cb(GtkInfoBar * info_bar,
+                         gint response_id, gpointer user_data)
+{
+    LibBalsaWebKitInfo *info = user_data;
+
+    if (response_id == GTK_RESPONSE_OK) {
+        gchar *text;
+
+        if (lbh_get_body_content(info->body, &text) >= 0) {
+            info->download_images = TRUE;
+            webkit_web_view_reload_bypass_cache(info->web_view);
+            webkit_web_view_load_string(info->web_view, text, "text/html",
+                                        libbalsa_message_body_charset
+                                        (info->body), NULL);
+            g_free(text);
+        }
+    }
+
+    gtk_widget_destroy(GTK_WIDGET(info_bar));
+}
+
+static void
+lbh_info_bar_realize_cb(GtkWidget * info_bar,
+                        GtkWidget * text_view)
+{
+    GtkStyle *style = gtk_style_copy(gtk_widget_get_style(info_bar));
+
+    style->base[GTK_STATE_NORMAL] = style->bg[GTK_STATE_NORMAL];
+    gtk_widget_set_style(text_view, style);
+    g_object_unref(style);
+    gtk_widget_hide(info_bar);
+}
+
+static GtkWidget *
+lbh_info_bar_widget(GtkWidget * widget, LibBalsaWebKitInfo * info)
+{
+    GtkWidget *info_bar_widget;
+    GtkInfoBar *info_bar;
+    GtkWidget *text_view_widget;
+    GtkTextView *text_view;
+    GtkWidget *content_area;
+    gchar *text = _("This message part contains images "
+                    "from a remote server. "
+                    "To protect your privacy, "
+                    "Balsa has not downloaded them. "
+                    "You may choose to download them "
+                    "if you trust the server.");
+
+    info_bar_widget =
+        gtk_info_bar_new_with_buttons(_("_Download images"), GTK_RESPONSE_OK,
+                                      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+                                      NULL);
+
+    info_bar = GTK_INFO_BAR(info_bar_widget);
+    gtk_info_bar_set_message_type(info_bar, GTK_MESSAGE_QUESTION);
+    g_signal_connect(info_bar, "response",
+                     G_CALLBACK(lbh_info_bar_response_cb), info);
+
+    text_view_widget = gtk_text_view_new();
+    g_signal_connect(info_bar_widget, "realize",
+                     G_CALLBACK(lbh_info_bar_realize_cb), text_view_widget);
+
+    content_area = gtk_info_bar_get_content_area(info_bar);
+    gtk_container_add(GTK_CONTAINER(content_area), text_view_widget);
+
+    text_view = GTK_TEXT_VIEW(text_view_widget);
+    gtk_text_view_set_wrap_mode(text_view, GTK_WRAP_WORD_CHAR);
+    gtk_text_view_set_editable(text_view, FALSE);
+    gtk_text_buffer_set_text(gtk_text_view_get_buffer(text_view),
+                             text, -1);
+
+    return info_bar_widget;
+}
+#endif /* GTK_CHECK_VERSION(2, 18, 0) */
+
 /* Create a new WebKitWebView widget:
  * text			the HTML source;
  * len			length of text;
- * charset		ignored;
- * message 		the LibBalsaMessage from which to extract any
- *			HTML objects (by url); ignored if NULL;
+ * body 		LibBalsaMessageBody that belongs to the
+ *                      LibBalsaMessage from which to extract any
+ *			HTML objects (by url);
  * hover_cb             callback for link-hover signal;
- * clicked_cb	        callback for the "link-clicked" signal; ignored
- *			if NULL.
+ * clicked_cb	        callback for the "link-clicked" signal;
  */
 
 GtkWidget *
-libbalsa_html_new(const gchar        * text,
-                  size_t               len,
-                  const gchar        * charset,
-                  gpointer             msg,
-                  LibBalsaHtmlCallback hover_cb,
-                  LibBalsaHtmlCallback clicked_cb)
-{
-    LibBalsaMessage *message = LIBBALSA_MESSAGE(msg);
+libbalsa_html_new(LibBalsaMessageBody * body,
+                  LibBalsaHtmlCallback  hover_cb,
+                  LibBalsaHtmlCallback  clicked_cb)
+{
+    gchar *text;
+    gssize len;
+    GtkWidget *vbox;
     GtkWidget *widget;
     WebKitWebView *web_view;
     LibBalsaWebKitInfo *info;
 
+    len = lbh_get_body_content(body, &text);
+    if (len < 0)
+        return NULL;
+
+    vbox = gtk_vbox_new(FALSE, 0);
+
     widget = webkit_web_view_new();
 
     info = g_new(LibBalsaWebKitInfo, 1);
+    info->body            = body;
+    info->hover_cb        = hover_cb;
+    info->clicked_cb      = clicked_cb;
+    info->frame           = NULL;
+#if GTK_CHECK_VERSION(2, 18, 0)
+    info->download_images = FALSE;
+    info->info_bar_widget = lbh_info_bar_widget(widget, info);
+
+    gtk_box_pack_start(GTK_BOX(vbox), info->info_bar_widget,
+                       FALSE, FALSE, 0);
+#endif /* GTK_CHECK_VERSION(2, 18, 0) */
+    gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 0);
+
     info->web_view = web_view = WEBKIT_WEB_VIEW(widget);
-    info->frame = NULL;
-    g_object_weak_ref(G_OBJECT(web_view), (GWeakNotify) g_free, info);
+    g_object_set_data(G_OBJECT(vbox), "libbalsa-html-web-view", web_view);
+    g_object_set_data_full(G_OBJECT(web_view), "libbalsa-html-info", info,
+                           g_free);
 
     g_object_set(webkit_web_view_get_settings(web_view),
                  "enable-scripts",   FALSE,
                  "enable-plugins",   FALSE,
                  NULL);
 
-    info->hover_cb = hover_cb;
     g_signal_connect(web_view, "hovering-over-link",
                      G_CALLBACK(lbh_hovering_over_link_cb), info);
-
-    info->clicked_cb = clicked_cb;
     g_signal_connect(web_view, "navigation-policy-decision-requested",
                      G_CALLBACK
                      (lbh_navigation_policy_decision_requested_cb), info);
-    info->message = message;
     g_signal_connect(web_view, "resource-request-starting",
                      G_CALLBACK(lbh_resource_request_starting_cb), info);
     g_signal_connect(web_view, "new-window-policy-decision-requested",
-                     G_CALLBACK(lbh_new_window_policy_decision_requested_cb), info);
+                     G_CALLBACK(lbh_new_window_policy_decision_requested_cb),
+                     info);
     g_signal_connect(web_view, "create-web-view",
                      G_CALLBACK(lbh_create_web_view_cb), info);
 
     g_signal_connect(web_view, "notify::progress",
                      G_CALLBACK(gtk_widget_queue_resize), NULL);
 
-#if WEBKIT_CHECK_VERSION(1, 1, 18)
-    webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
-#endif                          /* WEBKIT_CHECK_VERSION(1, 1, 18) */
-
-    webkit_web_view_load_string(web_view, text, "text/html", charset,
-                                NULL);
+    webkit_web_view_load_string(web_view, text, "text/html",
+                                libbalsa_message_body_charset(body), NULL);
+    g_free(text);
 
-    return widget;
+    return vbox;
 }
 
 void
@@ -307,13 +454,24 @@ libbalsa_html_to_string(gchar ** text, size_t len)
              * it to an empty string. */
 }
 
+static gboolean
+lbh_get_web_view(GtkWidget * widget, WebKitWebView ** web_view)
+{
+    *web_view =
+        g_object_get_data(G_OBJECT(widget), "libbalsa-html-web-view");
+
+    return *web_view && WEBKIT_IS_WEB_VIEW(*web_view);
+}
+
 /*
  * Does the widget support zoom?
  */
 gboolean
 libbalsa_html_can_zoom(GtkWidget * widget)
 {
-    return WEBKIT_IS_WEB_VIEW(widget);
+    WebKitWebView *web_view;
+
+    return lbh_get_web_view(widget, &web_view);
 }
 
 /*
@@ -322,18 +480,22 @@ libbalsa_html_can_zoom(GtkWidget * widget)
 void
 libbalsa_html_zoom(GtkWidget * widget, gint in_out)
 {
-    switch (in_out) {
-    case +1:
-	webkit_web_view_zoom_in(WEBKIT_WEB_VIEW(widget));
-	break;
-    case -1:
-	webkit_web_view_zoom_out(WEBKIT_WEB_VIEW(widget));
-	break;
-    case 0:
-	webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(widget), 1.0);
-	break;
-    default:
-	break;
+    WebKitWebView *web_view;
+
+    if (lbh_get_web_view(widget, &web_view)) {
+        switch (in_out) {
+        case +1:
+            webkit_web_view_zoom_in(web_view);
+            break;
+        case -1:
+            webkit_web_view_zoom_out(web_view);
+            break;
+        case 0:
+            webkit_web_view_set_zoom_level(web_view, 1.0);
+            break;
+        default:
+            break;
+        }
     }
 }
 
@@ -343,7 +505,9 @@ libbalsa_html_zoom(GtkWidget * widget, gint in_out)
 gboolean
 libbalsa_html_can_select(GtkWidget * widget)
 {
-    return WEBKIT_IS_WEB_VIEW(widget);
+    WebKitWebView *web_view;
+
+    return lbh_get_web_view(widget, &web_view);
 }
 
 /*
@@ -352,7 +516,10 @@ libbalsa_html_can_select(GtkWidget * widget)
 void
 libbalsa_html_select_all(GtkWidget * widget)
 {
-    webkit_web_view_select_all(WEBKIT_WEB_VIEW(widget));
+    WebKitWebView *web_view;
+
+    if (lbh_get_web_view(widget, &web_view))
+        webkit_web_view_select_all(web_view);
 }
 
 /*
@@ -361,7 +528,10 @@ libbalsa_html_select_all(GtkWidget * widget)
 void
 libbalsa_html_copy(GtkWidget * widget)
 {
-    webkit_web_view_copy_clipboard(WEBKIT_WEB_VIEW(widget));
+    WebKitWebView *web_view;
+
+    if (lbh_get_web_view(widget, &web_view))
+        webkit_web_view_copy_clipboard(web_view);
 }
 
 /*
@@ -370,7 +540,9 @@ libbalsa_html_copy(GtkWidget * widget)
 gboolean
 libbalsa_html_can_search(GtkWidget * widget)
 {
-    return WEBKIT_IS_WEB_VIEW(widget);
+    WebKitWebView *web_view;
+
+    return lbh_get_web_view(widget, &web_view);
 }
 
 /*
@@ -420,18 +592,22 @@ libbalsa_html_search_text(GtkWidget   * widget,
                           gboolean      find_forward,
                           gboolean      wrap)
 {
-    WebKitWebView *web_view = WEBKIT_WEB_VIEW(widget);
+    WebKitWebView *web_view;
+
+    if (!lbh_get_web_view(widget, &web_view))
+        return FALSE;
 
     if (!*text) {
-        lbh_js_run_script(lbh_js_get_global_context(web_view),
-                          "window.getSelection().removeAllRanges()");
+        gchar script[] = "window.getSelection().removeAllRanges()";
+
+        lbh_js_run_script(lbh_js_get_global_context(web_view), script);
+
         return TRUE;
     }
 
     return webkit_web_view_search_text(web_view, text,
                                        FALSE,    /* case-insensitive */
                                        find_forward, wrap);
-    return FALSE;
 }
 
 /*
@@ -443,22 +619,30 @@ void
 libbalsa_html_get_selection_bounds(GtkWidget    * widget,
                                    GdkRectangle * selection_bounds)
 {
-    WebKitWebView *web_view = WEBKIT_WEB_VIEW(widget);
+    WebKitWebView *web_view;
     JSGlobalContextRef ctx;
     gchar script[] =
         "window.getSelection().getRangeAt(0).getBoundingClientRect()";
     JSValueRef value;
 
+    if (!lbh_get_web_view(widget, &web_view))
+        return;
+
     ctx = lbh_js_get_global_context(web_view);
     value = lbh_js_run_script(ctx, script);
 
     if (JSValueIsObject(ctx, value)) {
         JSObjectRef object = JSValueToObject(ctx, value, NULL);
+        gint x, y;
+
+        x = lbh_js_object_get_property(ctx, object, "left");
+        y = lbh_js_object_get_property(ctx, object, "top");
+
+        gtk_widget_translate_coordinates(GTK_WIDGET(web_view), widget,
+                                         x, y,
+                                         &selection_bounds->x,
+                                         &selection_bounds->y);
 
-        selection_bounds->x =
-            lbh_js_object_get_property(ctx, object, "left");
-        selection_bounds->y =
-            lbh_js_object_get_property(ctx, object, "top");
         selection_bounds->width =
             lbh_js_object_get_property(ctx, object, "width");
         selection_bounds->height =
@@ -552,10 +736,6 @@ libbalsa_html_write_mime_stream(GtkHTMLStream * stream,
  * charset		source charset, or NULL;
  * export_string 	if we want the text exported as text/plain, a
  * 			GString to receive it; otherwise NULL;
- * message 		the LibBalsaMessage from which to extract any
- *			HTML objects (by url); ignored if NULL;
- * link_clicked_cb	callback for the "link-clicked" signal; ignored
- *			if NULL.
  */
 static GtkWidget *
 lbh_new(const gchar * text, size_t len,
@@ -608,23 +788,29 @@ lbh_new(const gchar * text, size_t len,
 /* Create a new HtmlView widget:
  * text			the HTML source;
  * len			length of text;
- * charset		source charset, or NULL;
- * message 		the LibBalsaMessage from which to extract any
- *			HTML objects (by url); ignored if NULL;
- * link_clicked_cb	callback for the "link-clicked" signal; ignored
- *			if NULL.
+ * body 		LibBalsaMessageBody that belongs to the
+ *                      LibBalsaMessage from which to extract any
+ *			HTML objects (by url);
+ * hover_cb             callback for the "on-url" signal;
+ * link_clicked_cb	callback for the "link-clicked" signal;
  */
 GtkWidget *
-libbalsa_html_new(const gchar * text, size_t len,
-                  const gchar * charset,
-                  gpointer message,
-                  LibBalsaHtmlCallback hover_cb,
-                  LibBalsaHtmlCallback clicked_cb)
+libbalsa_html_new(LibBalsaMessageBody * body,
+                  LibBalsaHtmlCallback  hover_cb,
+                  LibBalsaHtmlCallback  clicked_cb)
 {
+    gssize len;
+    gchar *text;
     GtkWidget *widget;
     LibBalsaHTMLInfo *info;
 
-    widget = lbh_new(text, len, charset, NULL);
+    len = lbh_get_body_content(body, &text);
+    if (len < 0)
+        return NULL;
+
+    widget = lbh_new(text, len, libbalsa_message_body_charset(body), NULL);
+    g_free(text);
+
     info = g_new(LibBalsaHTMLInfo, 1);
     g_object_weak_ref(G_OBJECT(widget), (GWeakNotify) g_free, info);
 
@@ -637,7 +823,8 @@ libbalsa_html_new(const gchar * text, size_t len,
                      G_CALLBACK(lbh_navigation_requested_cb), info);
 
     g_signal_connect(widget, "url-requested",
-                     G_CALLBACK(libbalsa_html_url_requested), message);
+                     G_CALLBACK(libbalsa_html_url_requested),
+                     body->message);
 
     g_signal_connect(widget, "size-request",
                      G_CALLBACK(lbh_size_request_cb), info);
@@ -743,36 +930,39 @@ libbalsa_html_write_mime_stream(HtmlStream * stream,
 /* Create a new HtmlView widget:
  * text			the HTML source;
  * len			length of text;
- * charset		ignored;
- * message 		the LibBalsaMessage from which to extract any
- *			HTML objects (by url); ignored if NULL;
- * link_clicked_cb	callback for the "link-clicked" signal; ignored
- *			if NULL.
+ * body        		LibBalsaMessageBody that belongs to the
+ *                      LibBalsaMessage from which to extract any
+ *                      HTML objects (by url);
+ * hover_cb             callback for the "on-url" signal;
+ * link_clicked_cb	callback for the "link-clicked" signal;
  */
 
 GtkWidget *
-libbalsa_html_new(const gchar * text, size_t len,
-		  const gchar * charset,
-		  gpointer message,
-                  LibBalsaHtmlCallback hover_cb,
-                  LibBalsaHtmlCallback link_clicked_cb)
+libbalsa_html_new(LibBalsaMessageBody  * body,
+                  LibBalsaHtmlCallback   hover_cb,
+                  LibBalsaHtmlCallback   link_clicked_cb)
 {
-    GtkWidget *html;
-    LibBalsaHTMLInfo *info;
     HtmlDocument *document;
+    LibBalsaHTMLInfo *info;
+    GtkWidget *html;
+    gssize len;
+    gchar *text;
+
+    len = lbh_get_body_content(body, &text);
+    if (len < 0)
+        return NULL;
 
     document = html_document_new();
     info = g_new(LibBalsaHTMLInfo, 1);
     g_object_weak_ref(G_OBJECT(document), (GWeakNotify) g_free, info);
 
-    if (message)
-	g_signal_connect(document, "request-url",
-			 G_CALLBACK(libbalsa_html_url_requested), message);
+    g_signal_connect(document, "request-url",
+                     G_CALLBACK(libbalsa_html_url_requested),
+                     body->message);
 
     info->clicked_cb = link_clicked_cb;
-    if (link_clicked_cb)
-        g_signal_connect(document, "link-clicked",
-                         G_CALLBACK(lbh_navigation_requested_cb), info);
+    g_signal_connect(document, "link-clicked",
+                     G_CALLBACK(lbh_navigation_requested_cb), info);
 
     /* We need to first set_document and then do *_stream() operations
      * or gtkhtml2 will crash. */
@@ -788,6 +978,7 @@ libbalsa_html_new(const gchar * text, size_t len,
 
     html_document_open_stream(document, "text/html");
     html_document_write_stream(document, text, len);
+    g_free(text);
     html_document_close_stream(document);
 
     return html;
diff --git a/libbalsa/html.h b/libbalsa/html.h
index 23125ef..03dca38 100644
--- a/libbalsa/html.h
+++ b/libbalsa/html.h
@@ -33,6 +33,7 @@
 # endif
 
 #  include <gtk/gtk.h>
+#include "libbalsa.h"
 
 /* We need this enum even if we're not using GtkHtml. */
 typedef enum {
@@ -46,9 +47,7 @@ typedef enum {
 
 typedef void (*LibBalsaHtmlCallback) (const gchar * uri);
 
-GtkWidget *libbalsa_html_new(const gchar * text, size_t len,
-			     const gchar * charset,
-			     gpointer message,
+GtkWidget *libbalsa_html_new(LibBalsaMessageBody * body,
                              LibBalsaHtmlCallback hover_cb,
                              LibBalsaHtmlCallback clicked_cb);
 void libbalsa_html_to_string(gchar ** text, size_t len);
diff --git a/src/balsa-mime-widget-text.c b/src/balsa-mime-widget-text.c
index 9ea642c..080624b 100644
--- a/src/balsa-mime-widget-text.c
+++ b/src/balsa-mime-widget-text.c
@@ -56,8 +56,9 @@ static void text_view_populate_popup(GtkTextView *textview, GtkMenu *menu,
 				     LibBalsaMessageBody * mime_body);
 
 #ifdef HAVE_GTKHTML
-static BalsaMimeWidget * bm_widget_new_html(BalsaMessage * bm, LibBalsaMessageBody * mime_body,
-					    gchar * ptr, size_t len);
+static BalsaMimeWidget *bm_widget_new_html(BalsaMessage * bm,
+                                           LibBalsaMessageBody *
+                                           mime_body);
 #endif
 static BalsaMimeWidget * bm_widget_new_vcard(BalsaMessage * bm,
                                              LibBalsaMessageBody * mime_body,
@@ -149,37 +150,33 @@ balsa_mime_widget_new_text(BalsaMessage * bm, LibBalsaMessageBody * mime_body,
     g_return_val_if_fail(mime_body != NULL, NULL);
     g_return_val_if_fail(content_type != NULL, NULL);
 
-    is_text_plain = !g_ascii_strcasecmp(content_type, "text/plain");
-    alloced = libbalsa_message_body_get_content(mime_body, &ptr, &err);
-    if (alloced < 0) {
-        balsa_information(LIBBALSA_INFORMATION_ERROR,
-                          _("Could not save a text part: %s"),
-                          err ? err->message : "Unknown error");
-        g_clear_error(&err);
-        return NULL;
-    }
-
     /* handle HTML if possible */
     html_type = libbalsa_html_type(content_type);
     if (html_type) {
-#ifdef HAVE_GTKHTML
-        BalsaMimeWidget *html_widget;
+        BalsaMimeWidget *html_widget = NULL;
 
-	alloced = libbalsa_html_filter(html_type, &ptr, alloced);
+#ifdef HAVE_GTKHTML
 	/* Force vertical scrollbar while we render the html, otherwise
 	 * the widget will make itself too wide to accept one, forcing
 	 * otherwise unnecessary horizontal scrolling. */
         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(bm->scroll),
                                        GTK_POLICY_AUTOMATIC,
                                        GTK_POLICY_ALWAYS);
-        html_widget = bm_widget_new_html(bm, mime_body, ptr, alloced);
-        g_free(ptr);
+        html_widget = bm_widget_new_html(bm, mime_body);
+#endif
         return html_widget;
-#else
-	g_free(ptr);
+    }
+
+    is_text_plain = !g_ascii_strcasecmp(content_type, "text/plain");
+    alloced = libbalsa_message_body_get_content(mime_body, &ptr, &err);
+    if (alloced < 0) {
+        balsa_information(LIBBALSA_INFORMATION_ERROR,
+                          _("Could not save a text part: %s"),
+                          err ? err->message : "Unknown error");
+        g_clear_error(&err);
         return NULL;
-#endif
     }
+
     if(g_ascii_strcasecmp(content_type, "text/x-vcard") == 0 ||
        g_ascii_strcasecmp(content_type, "text/directory") == 0) {
         mw = bm_widget_new_vcard(bm, mime_body, ptr, alloced);
@@ -1215,18 +1212,14 @@ balsa_gtk_html_button_press_cb(GtkWidget * html, GdkEventButton * event,
 }
 
 BalsaMimeWidget *
-bm_widget_new_html(BalsaMessage * bm, LibBalsaMessageBody * mime_body, gchar * ptr, size_t len)
+bm_widget_new_html(BalsaMessage * bm, LibBalsaMessageBody * mime_body)
 {
     BalsaMimeWidget *mw = g_object_new(BALSA_TYPE_MIME_WIDGET, NULL);
 
     mw->widget =
-        libbalsa_html_new(ptr, len,
-			  libbalsa_message_body_charset(mime_body),
-			  bm->message,
-                          (LibBalsaHtmlCallback)
-                          bm_widget_on_url,
-                          (LibBalsaHtmlCallback)
-                          handle_url);
+        libbalsa_html_new(mime_body,
+                          (LibBalsaHtmlCallback) bm_widget_on_url,
+                          (LibBalsaHtmlCallback) handle_url);
     g_object_set_data(G_OBJECT(mw->widget), "mime-body", mime_body);
 
     g_signal_connect(G_OBJECT(mw->widget), "button-press-event",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]