Modified webpage: now tinymail repository is in gitorious.
[modest] / src / widgets / modest-gtkhtml-mime-part-view.c
index 22b9ec5..37b97bc 100644 (file)
@@ -101,7 +101,7 @@ static gboolean modest_gtkhtml_mime_part_view_get_selection_area_default (Modest
 
 /* internal api */
 static TnyMimePart  *get_part   (ModestGtkhtmlMimePartView *self);
-static void          set_html_part   (ModestGtkhtmlMimePartView *self, TnyMimePart *part);
+static void          set_html_part   (ModestGtkhtmlMimePartView *self, TnyMimePart *part, const gchar *encoding);
 static void          set_text_part   (ModestGtkhtmlMimePartView *self, TnyMimePart *part);
 static void          set_empty_part  (ModestGtkhtmlMimePartView *self);
 static void          set_part   (ModestGtkhtmlMimePartView *self, TnyMimePart *part);
@@ -133,6 +133,7 @@ struct _ModestGtkhtmlMimePartViewPrivate {
 
 enum {
        STOP_STREAMS_SIGNAL,
+       LIMIT_ERROR_SIGNAL,
        LAST_SIGNAL
 };
 
@@ -251,7 +252,7 @@ modest_gtkhtml_mime_part_view_class_init (ModestGtkhtmlMimePartViewClass *klass)
        gtk_binding_entry_skip (binding_set, GDK_End, 0);
        gtk_binding_entry_skip (binding_set, GDK_KP_Home, 0);
        gtk_binding_entry_skip (binding_set, GDK_KP_End, 0);
-       
+
        g_type_class_add_private (gobject_class, sizeof(ModestGtkhtmlMimePartViewPrivate));
 
        signals[STOP_STREAMS_SIGNAL] = 
@@ -263,9 +264,18 @@ modest_gtkhtml_mime_part_view_class_init (ModestGtkhtmlMimePartViewClass *klass)
                              g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
 
+       signals[LIMIT_ERROR_SIGNAL] = 
+               g_signal_new ("limit-error",
+                             G_TYPE_FROM_CLASS (gobject_class),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (ModestGtkhtmlMimePartViewClass,limit_error),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
+
 }
 
-static void    
+static void
 modest_gtkhtml_mime_part_view_init (ModestGtkhtmlMimePartView *self)
 {
        ModestGtkhtmlMimePartViewPrivate *priv = MODEST_GTKHTML_MIME_PART_VIEW_GET_PRIVATE (self);
@@ -277,7 +287,6 @@ modest_gtkhtml_mime_part_view_init (ModestGtkhtmlMimePartView *self)
        gtk_html_set_caret_mode      (GTK_HTML(self), FALSE);
        gtk_html_set_blocking        (GTK_HTML(self), TRUE);
        gtk_html_set_images_blocking (GTK_HTML(self), TRUE);
-       gtk_container_set_border_width (GTK_CONTAINER (self), MODEST_MARGIN_DEFAULT);
 
 #ifdef MODEST_TOOLKIT_HILDON2
 #ifdef HAVE_GTK_HTML_SET_MAX_IMAGE_SIZE
@@ -285,6 +294,17 @@ modest_gtkhtml_mime_part_view_init (ModestGtkhtmlMimePartView *self)
           maximum height of 2 times the full size of the window. Should be enough */
        gtk_html_set_max_image_size (GTK_HTML (self), 720, 880);
 #endif
+#ifdef HAVE_GTK_HTML_SET_ALLOW_DND
+       gtk_html_set_allow_dnd       (GTK_HTML(self), FALSE);
+#endif
+#ifdef HAVE_GTK_HTML_SET_WORD_CHAR_WRAPPING
+       gtk_html_set_word_char_wrapping (GTK_HTML (self), TRUE);
+#endif
+#endif
+
+#ifdef HAVE_GTK_HTML_SET_DEFAULT_ENGINE
+       /* Enable Content type handling */
+       gtk_html_set_default_engine (GTK_HTML (self), TRUE);
 #endif
 
        gdk_color_parse ("#fff", &base);
@@ -408,12 +428,6 @@ on_url (GtkWidget *widget, const gchar *uri, ModestGtkhtmlMimePartView *self)
        return result;
 }
 
-typedef struct {
-       gpointer buffer;
-       GtkHTML *html;
-       GtkHTMLStream *stream;
-} ImageFetcherInfo;
-
 static gboolean
 on_url_requested (GtkWidget *widget, const gchar *uri, GtkHTMLStream *stream, 
                  ModestGtkhtmlMimePartView *self)
@@ -443,36 +457,47 @@ decode_to_stream_cb (TnyMimePart *self,
                     GError *err,
                     gpointer user_data)
 {
-       gboolean is_text = GPOINTER_TO_INT (user_data);
+       ModestGtkhtmlMimePartView *view = (ModestGtkhtmlMimePartView *) user_data;
 
-       if (is_text) {
+       if (MODEST_IS_STREAM_TEXT_TO_HTML (stream)) {
                if (tny_stream_write (stream, "\n", 1) == -1) {
                        g_warning ("failed to write CR in %s", __FUNCTION__);
                }
+               if (modest_stream_text_to_html_limit_reached (MODEST_STREAM_TEXT_TO_HTML (stream))) {
+                       g_signal_emit (G_OBJECT (view), signals[LIMIT_ERROR_SIGNAL], 0);
+               }
                tny_stream_reset (stream);
+       } else {
+               if (modest_tny_stream_gtkhtml_limit_reached (MODEST_TNY_STREAM_GTKHTML (stream))) {
+                       g_signal_emit (G_OBJECT (view), signals[LIMIT_ERROR_SIGNAL], 0);
+               }
        }
        tny_stream_close (stream);
 }
 
 static void
-set_html_part (ModestGtkhtmlMimePartView *self, TnyMimePart *part)
+set_html_part (ModestGtkhtmlMimePartView *self, TnyMimePart *part, const gchar *encoding)
 {
        GtkHTMLStream *gtkhtml_stream;
        TnyStream *tny_stream;
+       gchar *content_type;
 
        g_return_if_fail (self);
        g_return_if_fail (part);
 
        g_signal_emit (G_OBJECT (self), signals[STOP_STREAMS_SIGNAL], 0);
 
-       gtkhtml_stream = gtk_html_begin(GTK_HTML(self));
+       content_type = g_strdup_printf ("text/html; charset=%s", encoding);
+       gtkhtml_stream = gtk_html_begin_full(GTK_HTML(self), NULL, content_type, 0);
+       g_free (content_type);
 
        tny_stream     = TNY_STREAM(modest_tny_stream_gtkhtml_new (gtkhtml_stream, GTK_HTML (self)));
+       modest_tny_stream_gtkhtml_set_max_size (MODEST_TNY_STREAM_GTKHTML (tny_stream), 128*1024);
        tny_stream_reset (tny_stream);
 
        tny_mime_part_decode_to_stream_async (TNY_MIME_PART (part),
                                              tny_stream, decode_to_stream_cb,
-                                             NULL, GINT_TO_POINTER (FALSE));
+                                             NULL, self);
        g_object_unref (tny_stream);
 }
 
@@ -489,15 +514,18 @@ set_text_part (ModestGtkhtmlMimePartView *self, TnyMimePart *part)
 
        gtkhtml_stream = gtk_html_begin(GTK_HTML(self));
        tny_stream =  TNY_STREAM(modest_tny_stream_gtkhtml_new (gtkhtml_stream, GTK_HTML (self)));
+       modest_tny_stream_gtkhtml_set_max_size (MODEST_TNY_STREAM_GTKHTML (tny_stream), 128*1024);
        text_to_html_stream = TNY_STREAM (modest_stream_text_to_html_new (tny_stream));
        modest_stream_text_to_html_set_linkify_limit (MODEST_STREAM_TEXT_TO_HTML (text_to_html_stream),
                                                      64*1024);
        modest_stream_text_to_html_set_full_limit (MODEST_STREAM_TEXT_TO_HTML (text_to_html_stream),
-                                                  640*1024);
+                                                  128*1024);
+       modest_stream_text_to_html_set_line_limit (MODEST_STREAM_TEXT_TO_HTML (text_to_html_stream),
+                                                  1024);
 
        tny_mime_part_decode_to_stream_async (TNY_MIME_PART (part),
                                              text_to_html_stream, decode_to_stream_cb,
-                                             NULL, GINT_TO_POINTER (TRUE));
+                                             NULL, self);
 
        g_object_unref (G_OBJECT(text_to_html_stream));
        g_object_unref (G_OBJECT(tny_stream));
@@ -516,6 +544,9 @@ static void
 set_part (ModestGtkhtmlMimePartView *self, TnyMimePart *part)
 {
        ModestGtkhtmlMimePartViewPrivate *priv;
+       gchar *header_content_type, *header_content_type_lower;
+       const gchar *tmp;
+       gchar *charset = NULL;
 
        g_return_if_fail (self);
        
@@ -535,23 +566,39 @@ set_part (ModestGtkhtmlMimePartView *self, TnyMimePart *part)
                return;
        }
 
+       header_content_type = modest_tny_mime_part_get_header_value (part, "Content-Type");
+       if (header_content_type) {
+               header_content_type = g_strstrip (header_content_type);
+               header_content_type_lower = g_ascii_strdown (header_content_type, -1);
+       } else {
+               header_content_type_lower = NULL;
+       }
+
+       if (header_content_type_lower) {
+               tmp = strstr (header_content_type_lower, "charset=");
+               if (tmp) {
+                       const gchar *tmp2;
+                       tmp = tmp + strlen ("charset=");
+                       
+                       tmp2 = strstr (tmp, ";");
+                       if (tmp2) {
+                               charset = g_strndup (tmp, tmp2-tmp);
+                       } else {
+                               charset = g_strdup (tmp);
+                       }
+               }
+       }
+
        if (tny_mime_part_content_type_is (part, "text/html")) {
-               set_html_part (self, part);
+               set_html_part (self, part, charset);
        } else {
                if (tny_mime_part_content_type_is (part, "message/rfc822")) {
-                       gchar *header_content_type, *header_content_type_lower;
-                       header_content_type = modest_tny_mime_part_get_header_value (part, "Content-Type");
                        if (header_content_type) {
-                               header_content_type = g_strstrip (header_content_type);
-                               header_content_type_lower = g_ascii_strdown (header_content_type, -1);
-
-                               if (!g_ascii_strcasecmp (header_content_type_lower, "text/html"))
-                                       set_html_part (self, part);
+                               if (g_str_has_prefix (header_content_type_lower, "text/html"))
+                                       set_html_part (self, part, charset);
                                else 
                                        set_text_part (self, part);
 
-                               g_free (header_content_type_lower);
-                               g_free (header_content_type);
                        } else {
                                set_text_part (self, part);
                        }
@@ -559,6 +606,8 @@ set_part (ModestGtkhtmlMimePartView *self, TnyMimePart *part)
                        set_text_part (self, part);
                }
        }
+       g_free (header_content_type_lower);
+       g_free (header_content_type);
 
 }