X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fwidgets%2Fmodest-gtkhtml-msg-view.c;h=8f8b2cef8de7ea3c29226831fae80334c11495d3;hp=469d6d76ac5884c275419d830480ded45037ef1b;hb=38454a69440197510b16c5a5444e19f234c91690;hpb=c6037f8b815e98c569716ab2189b67a5f4de886b diff --git a/src/widgets/modest-gtkhtml-msg-view.c b/src/widgets/modest-gtkhtml-msg-view.c index 469d6d7..8f8b2ce 100644 --- a/src/widgets/modest-gtkhtml-msg-view.c +++ b/src/widgets/modest-gtkhtml-msg-view.c @@ -41,11 +41,9 @@ #include #include #include -#ifdef MODEST_TOOLKIT_HILDON2 #include +#ifdef MODEST_TOOLKIT_HILDON2 #include -#else -#include #endif #include #include @@ -54,12 +52,8 @@ #include #include #include - -/* FIXNE: we should have no maemo-deps in widgets/ */ -#ifndef MODEST_TOOLKIT_GTK -#include "maemo/modest-hildon-includes.h" -#endif /*!MODEST_TOOLKIT_GTK*/ - +#include +#include /* 'private'/'protected' functions */ static void modest_gtkhtml_msg_view_class_init (ModestGtkhtmlMsgViewClass *klass); @@ -86,6 +80,7 @@ static gboolean on_activate_link (GtkWidget *widget, const gchar *uri, ModestGtk static gboolean on_fetch_url (GtkWidget *widget, const gchar *uri, TnyStream *stream, ModestGtkhtmlMsgView *msg_view); static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestGtkhtmlMsgView *msg_view); +static void on_limit_error (GtkWidget *widget, ModestGtkhtmlMsgView *msg_view); #ifdef MAEMO_CHANGES static void on_tap_and_hold (GtkWidget *widget, gpointer userdata); @@ -172,6 +167,7 @@ static gboolean modest_msg_view_search_default (ModestISearchView *self, const g static gboolean modest_msg_view_search_next (ModestISearchView *self); static gboolean modest_msg_view_search_next_default (ModestISearchView *self); /* ModestMsgView implementation */ +static void modest_gtkhtml_msg_view_set_msg_with_other_body (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body); static GtkAdjustment *modest_gtkhtml_msg_view_get_vadjustment (ModestMsgView *self); static GtkAdjustment *modest_gtkhtml_msg_view_get_hadjustment (ModestMsgView *self); static void modest_gtkhtml_msg_view_set_vadjustment (ModestMsgView *self, GtkAdjustment *vadj); @@ -185,7 +181,9 @@ static TnyList *modest_gtkhtml_msg_view_get_attachments (ModestMsgView *self); static void modest_gtkhtml_msg_view_grab_focus (ModestMsgView *self); static void modest_gtkhtml_msg_view_remove_attachment (ModestMsgView *view, TnyMimePart *attachment); static void modest_gtkhtml_msg_view_request_fetch_images (ModestMsgView *view); +static void modest_gtkhtml_msg_view_set_branding (ModestMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); static gboolean modest_gtkhtml_msg_view_has_blocked_external_images (ModestMsgView *view); +static void modest_gtkhtml_msg_view_set_msg_with_other_body_default (ModestMsgView *view, TnyMsg *msg, TnyMimePart *part); static GtkAdjustment *modest_gtkhtml_msg_view_get_vadjustment_default (ModestMsgView *self); static GtkAdjustment *modest_gtkhtml_msg_view_get_hadjustment_default (ModestMsgView *self); static void modest_gtkhtml_msg_view_set_vadjustment_default (ModestMsgView *self, GtkAdjustment *vadj); @@ -200,11 +198,12 @@ static void modest_gtkhtml_msg_view_grab_focus_default (ModestMsgView *self); static void modest_gtkhtml_msg_view_remove_attachment_default (ModestMsgView *view, TnyMimePart *attachment); static gboolean modest_gtkhtml_msg_view_has_blocked_external_images_default (ModestMsgView *view); static void modest_gtkhtml_msg_view_request_fetch_images_default (ModestMsgView *view); +static void modest_gtkhtml_msg_view_set_branding_default (ModestMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); /* internal api */ static void set_header (ModestGtkhtmlMsgView *self, TnyHeader *header); static TnyMsg *get_message (ModestGtkhtmlMsgView *self); -static void set_message (ModestGtkhtmlMsgView *self, TnyMsg *tny_msg); +static void set_message (ModestGtkhtmlMsgView *self, TnyMsg *tny_msg, TnyMimePart *other_body); static gboolean is_empty (ModestGtkhtmlMsgView *self); static void set_zoom (ModestGtkhtmlMsgView *self, gdouble zoom); static gdouble get_zoom (ModestGtkhtmlMsgView *self); @@ -223,7 +222,9 @@ static TnyList *get_attachments (ModestGtkhtmlMsgView *self); static void grab_focus (ModestGtkhtmlMsgView *self); static void remove_attachment (ModestGtkhtmlMsgView *view, TnyMimePart *attachment); static void request_fetch_images (ModestGtkhtmlMsgView *view); +static void set_branding (ModestGtkhtmlMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); static gboolean has_blocked_external_images (ModestGtkhtmlMsgView *view); +static void set_calendar (ModestGtkhtmlMsgView *self, TnyHeader *header, TnyMsg *msg); /* list properties */ enum { @@ -238,16 +239,23 @@ struct _ModestGtkhtmlMsgViewPrivate { GtkWidget *body_view; GtkWidget *mail_header_view; GtkWidget *attachments_view; - GtkWidget *priority_icon; TnyMsg *msg; /* embedded elements */ GtkWidget *headers_box; - GtkWidget *priority_box; GtkWidget *html_scroll; GtkWidget *attachments_box; +#ifdef MODEST_TOOLKIT_HILDON2 + GtkWidget *priority_box; + GtkWidget *priority_icon; +#endif + GtkWidget *calendar_box; + GtkWidget *calendar_icon; + GtkWidget *calendar_actions_box; + GtkWidget *calendar_actions_container; + /* internal adjustments for set_scroll_adjustments */ GtkAdjustment *hadj; GtkAdjustment *vadj; @@ -261,11 +269,18 @@ struct _ModestGtkhtmlMsgViewPrivate { /* id handler for dragged scroll */ guint idle_motion_id; + /* idle changes count */ + gint idle_changes_count; + guint idle_readjust_scroll_id; + guint idle_resize_children_id; + /* zoom */ gdouble current_zoom; /* link click management */ gchar *last_url; + + gboolean has_blocked_bs_images; }; #define MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ @@ -414,6 +429,7 @@ modest_gtkhtml_msg_view_class_init (ModestGtkhtmlMsgViewClass *klass) klass->zoom_plus_func = modest_msg_view_zoom_plus_default; klass->search_func = modest_msg_view_search_default; klass->search_next_func = modest_msg_view_search_next_default; + klass->set_msg_with_other_body_func = modest_gtkhtml_msg_view_set_msg_with_other_body_default; klass->get_vadjustment_func = modest_gtkhtml_msg_view_get_vadjustment_default; klass->get_hadjustment_func = modest_gtkhtml_msg_view_get_hadjustment_default; klass->set_vadjustment_func = modest_gtkhtml_msg_view_set_vadjustment_default; @@ -427,6 +443,7 @@ modest_gtkhtml_msg_view_class_init (ModestGtkhtmlMsgViewClass *klass) klass->grab_focus_func = modest_gtkhtml_msg_view_grab_focus_default; klass->remove_attachment_func = modest_gtkhtml_msg_view_remove_attachment_default; klass->request_fetch_images_func = modest_gtkhtml_msg_view_request_fetch_images_default; + klass->set_branding_func = modest_gtkhtml_msg_view_set_branding_default; klass->has_blocked_external_images_func = modest_gtkhtml_msg_view_has_blocked_external_images_default; g_type_class_add_private (gobject_class, sizeof(ModestGtkhtmlMsgViewPrivate)); @@ -586,6 +603,8 @@ set_hadjustment_values (ModestGtkhtmlMsgView *self, { GtkAllocation view_allocation; GtkAdjustment *hadj = get_hadjustment (self); + gint full_width = 0; + ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); get_view_allocation (self, &view_allocation); hadj->page_size = view_allocation.width; @@ -595,11 +614,20 @@ set_hadjustment_values (ModestGtkhtmlMsgView *self, hadj->lower = 0; hadj->upper = view_allocation.width; + /* Get the real width of the embedded html */ + if (priv->html_scroll && GTK_WIDGET_VISIBLE(priv->html_scroll)) { + GtkAdjustment *html_hadj; + html_hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + full_width += html_hadj->upper; + } + + hadj->upper = MAX (view_allocation.width, full_width); + reclamp_adjustment (hadj, value_changed); } -static void +static void set_vadjustment_values (ModestGtkhtmlMsgView *self, gboolean *value_changed) { @@ -886,6 +914,12 @@ size_allocate (GtkWidget *widget, allocation->height != widget->allocation.height)) gdk_window_invalidate_rect (widget->window, NULL, FALSE); + if (priv->idle_readjust_scroll_id == 0 && priv->idle_changes_count < 5 && widget->allocation.width != allocation->width) { + g_object_ref (self); + priv->idle_readjust_scroll_id = g_idle_add ((GSourceFunc) idle_readjust_scroll, self); + priv->idle_changes_count ++; + } + widget->allocation = *allocation; set_hadjustment_values (self, &hadj_value_changed); set_vadjustment_values (self, &vadj_value_changed); @@ -903,9 +937,14 @@ size_allocate (GtkWidget *widget, html_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); html_allocation.x = 0; - html_allocation.y = headers_allocation.height; + html_allocation.y = MAX (0, headers_allocation.height - priv->vadj->value); html_allocation.width = view_allocation.width; - html_allocation.height = MAX ((gint) html_vadj->upper, (gint)(priv->vadj->upper - headers_allocation.height)); + if (html_vadj->upper < allocation->height) { + html_allocation.height = MAX (html_vadj->upper, allocation->height - headers_allocation.height); + } else { + html_allocation.height = allocation->height; + } + /* html_allocation.height = MAX ((gint) html_vadj->upper, (gint)(priv->vadj->upper - headers_allocation.height)); */ if (GTK_WIDGET_REALIZED (widget)) { gdk_window_move_resize (widget->window, @@ -926,7 +965,7 @@ size_allocate (GtkWidget *widget, headers_allocation.height); gdk_window_move_resize (priv->html_window, (gint) (- priv->hadj->value), - (gint) (html_allocation.y - priv->vadj->value), + (gint) html_allocation.y, (gint) priv->hadj->upper, html_allocation.height); } @@ -938,8 +977,11 @@ size_allocate (GtkWidget *widget, html_allocation.x = 0; html_allocation.y = 0; html_allocation.width = (gint) priv->hadj->upper; - html_allocation.height = (gint) priv->vadj->upper - headers_allocation.height; gtk_widget_size_allocate (priv->html_scroll, &html_allocation); + if (html_vadj->page_size != html_allocation.height) { + html_vadj->page_size = html_allocation.height; + gtk_adjustment_changed (html_vadj); + } } gtk_adjustment_changed (priv->hadj); gtk_adjustment_changed (priv->vadj); @@ -988,9 +1030,15 @@ adjustment_value_changed (GtkAdjustment *adj, gpointer data) if (priv->html_scroll && GTK_WIDGET_VISIBLE (priv->html_scroll)) { gint old_x, old_y; gint new_x, new_y; + gint new_internal_vvalue; gdk_window_get_position (priv->html_window, &old_x, &old_y); new_x = -hadj->value; - new_y = headers_offset - vadj->value; + + new_internal_vvalue = MAX (0, vadj->value - headers_offset); + gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)), + new_internal_vvalue); + + new_y = MAX (0, headers_offset - vadj->value); if (new_x != old_x || new_y != old_y) { gdk_window_move (priv->html_window, new_x, new_y); @@ -1001,6 +1049,18 @@ adjustment_value_changed (GtkAdjustment *adj, gpointer data) } } +static gboolean +resize_children_idle (GtkContainer *cont) +{ + ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (cont); + if (GTK_WIDGET_DRAWABLE (cont)) { + gtk_container_resize_children (cont); + } + priv->idle_resize_children_id = 0; + + return FALSE; +} + static void html_adjustment_changed (GtkAdjustment *adj, gpointer userdata) @@ -1014,19 +1074,25 @@ html_adjustment_changed (GtkAdjustment *adj, g_signal_stop_emission_by_name (G_OBJECT (adj), "changed"); priv->html_scroll->requisition.height = html_vadj->upper; - if (html_vadj->upper == priv->html_scroll->allocation.height) + if ((priv->vadj != NULL && (html_vadj->upper == (priv->vadj->upper - GTK_WIDGET (priv->headers_box)->allocation.height))) + && html_vadj->page_size == priv->html_scroll->allocation.height) return; - priv->html_scroll->allocation.height = html_vadj->upper; set_vadjustment_values (self, &vadj_changed); - new_height = MAX ((gint) html_vadj->upper, (gint) (priv->vadj->upper - priv->headers_box->allocation.height)); + if (html_vadj->upper < GTK_WIDGET (self)->allocation.height) { + new_height = MAX (html_vadj->upper, + GTK_WIDGET (self)->allocation.height - GTK_WIDGET(priv->headers_box)->allocation.height); + } else { + new_height = GTK_WIDGET (self)->allocation.height; + } gtk_adjustment_changed (priv->vadj); if (GTK_WIDGET_DRAWABLE (priv->html_scroll)) { gdk_window_resize (priv->html_window, (gint) priv->hadj->upper, (gint) new_height); gdk_window_process_updates (priv->view_window, TRUE); - gtk_container_resize_children (GTK_CONTAINER (self)); + if (priv->idle_resize_children_id == 0) + priv->idle_resize_children_id = gdk_threads_add_idle ((GSourceFunc) resize_children_idle, self); } } @@ -1034,27 +1100,42 @@ html_adjustment_changed (GtkAdjustment *adj, gboolean idle_readjust_scroll (ModestGtkhtmlMsgView *self) { + ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); /* We're out the main lock */ gdk_threads_enter (); if (GTK_WIDGET_DRAWABLE (self)) { - ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); GtkAdjustment *html_vadj; + GtkAdjustment *html_hadj; + html_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); - html_vadj->page_size = html_vadj->upper; - gtk_adjustment_changed (html_vadj); - gtk_widget_queue_resize (GTK_WIDGET (self)); - gtk_widget_queue_draw (GTK_WIDGET (self)); + html_vadj->upper = 0; + html_vadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_vadj), "changed"); + + html_hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_hadj->upper = 0; + html_hadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_hadj), "changed"); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); + gtk_widget_queue_draw (GTK_WIDGET (priv->body_view)); /* Just another hack for making readjust really work. This forces an update * of the scroll, and then, make the scroll really update properly the * the size and not corrupt scrollable area */ gtk_adjustment_set_value (priv->vadj, 1.0); gtk_adjustment_set_value (priv->vadj, 0.0); + } + priv->idle_readjust_scroll_id = 0; g_object_unref (G_OBJECT (self)); + gdk_threads_leave (); return FALSE; @@ -1065,7 +1146,9 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) { ModestGtkhtmlMsgViewPrivate *priv; GtkAdjustment *html_vadj; +#ifndef MODEST_TOOLKIT_HILDON2 GtkWidget *separator; +#endif GTK_WIDGET_UNSET_FLAGS (obj, GTK_NO_WINDOW); gtk_widget_set_redraw_on_allocate (GTK_WIDGET (obj), TRUE); @@ -1074,6 +1157,11 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE(obj); + priv->has_blocked_bs_images = FALSE; + + priv->idle_changes_count = 0; + priv->idle_readjust_scroll_id = 0; + priv->idle_resize_children_id = 0; priv->current_zoom = 1.0; priv->hadj = NULL; @@ -1094,11 +1182,7 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) priv->msg = NULL; priv->body_view = GTK_WIDGET (g_object_new (MODEST_TYPE_GTKHTML_MIME_PART_VIEW, NULL)); -#ifdef MODEST_TOOLKIT_HILDON2 - priv->mail_header_view = GTK_WIDGET(modest_compact_mail_header_view_new ()); -#else - priv->mail_header_view = GTK_WIDGET(modest_expander_mail_header_view_new (TRUE)); -#endif + priv->mail_header_view = GTK_WIDGET (modest_compact_mail_header_view_new ()); gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); priv->attachments_view = GTK_WIDGET(modest_attachments_view_new (NULL)); #ifdef MODEST_TOOLKIT_HILDON2 @@ -1115,6 +1199,8 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) G_CALLBACK(on_fetch_url), obj); g_signal_connect (G_OBJECT(priv->body_view), "link_hover", G_CALLBACK(on_link_hover), obj); + g_signal_connect (G_OBJECT(priv->body_view), "limit_error", + G_CALLBACK(on_limit_error), obj); #ifdef MAEMO_CHANGES g_signal_connect (G_OBJECT(priv->body_view), "motion-notify-event", G_CALLBACK (motion_notify_event), obj); @@ -1138,13 +1224,14 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) G_CALLBACK (html_adjustment_changed), obj); gtk_widget_push_composite_child (); - priv->headers_box = gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT); + priv->headers_box = gtk_vbox_new (FALSE, 0); gtk_widget_set_composite_name (priv->headers_box, "headers"); gtk_widget_pop_composite_child (); if (priv->mail_header_view) gtk_box_pack_start (GTK_BOX(priv->headers_box), priv->mail_header_view, FALSE, FALSE, 0); - + +#ifdef MODEST_TOOLKIT_HILDON2 priv->priority_icon = gtk_image_new (); gtk_misc_set_alignment (GTK_MISC (priv->priority_icon), 0.0, 0.5); if (priv->priority_icon) { @@ -1156,6 +1243,20 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) gtk_widget_hide_all (priv->priority_box); } +#endif + priv->calendar_actions_box = NULL; + priv->calendar_icon = gtk_image_new (); + gtk_image_set_from_icon_name (GTK_IMAGE (priv->calendar_icon), MODEST_HEADER_ICON_CALENDAR, GTK_ICON_SIZE_MENU); + gtk_misc_set_alignment (GTK_MISC (priv->calendar_icon), 0.0, 0.5); + if (priv->calendar_icon) { + priv->calendar_box = (GtkWidget *) + modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), + _("mail_fi_invitation"), + priv->calendar_icon, + FALSE, FALSE); + + gtk_widget_hide_all (priv->calendar_box); + } if (priv->attachments_view) { #ifndef MODEST_TOOLKIT_HILDON2 @@ -1173,8 +1274,16 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj) g_free (att_label); } + priv->calendar_actions_container = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (priv->headers_box), priv->calendar_actions_container, FALSE, FALSE, 0); + gtk_widget_hide (priv->calendar_actions_container); + gtk_widget_hide_all (priv->calendar_actions_container); + gtk_widget_set_no_show_all (priv->calendar_actions_container, TRUE); + +#ifndef MODEST_TOOLKIT_HILDON2 separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX(priv->headers_box), separator, FALSE, FALSE, 0); +#endif gtk_widget_set_parent (priv->headers_box, GTK_WIDGET (obj)); @@ -1202,6 +1311,16 @@ modest_gtkhtml_msg_view_finalize (GObject *obj) priv->msg = NULL; } + if (priv->idle_resize_children_id > 0) { + g_source_remove (priv->idle_resize_children_id); + priv->idle_resize_children_id = 0; + } + + if (priv->idle_readjust_scroll_id > 0) { + g_source_remove (priv->idle_readjust_scroll_id); + priv->idle_readjust_scroll_id = 0; + } + if (priv->idle_motion_id > 0) { g_source_remove (priv->idle_motion_id); priv->idle_motion_id = 0; @@ -1347,8 +1466,7 @@ set_hadjustment (ModestGtkhtmlMsgView *self, GtkAdjustment *hadj) if (!hadj) hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0,0.0,0.0,0.0,0.0,0.0)); disconnect_hadjustment (self); - g_object_ref (G_OBJECT (hadj)); - gtk_object_sink (GTK_OBJECT (hadj)); + g_object_ref_sink (G_OBJECT (hadj)); priv->hadj = hadj; set_hadjustment_values (self, &value_changed); @@ -1376,8 +1494,7 @@ set_vadjustment (ModestGtkhtmlMsgView *self, GtkAdjustment *vadj) if (!vadj) vadj = (GtkAdjustment *) gtk_adjustment_new (0.0,0.0,0.0,0.0,0.0,0.0); disconnect_vadjustment (self); - g_object_ref (G_OBJECT (vadj)); - gtk_object_sink (GTK_OBJECT (vadj)); + g_object_ref_sink (G_OBJECT (vadj)); priv->vadj = vadj; set_vadjustment_values (self, &value_changed); @@ -1491,6 +1608,7 @@ request_fetch_images (ModestGtkhtmlMsgView *self) /* The message could have not been downloaded yet */ if (priv->msg) { modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), TRUE); + priv->has_blocked_bs_images = FALSE; part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (priv->body_view)); if (part) { tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (priv->body_view), part); @@ -1500,12 +1618,21 @@ request_fetch_images (ModestGtkhtmlMsgView *self) } } +static void +set_branding (ModestGtkhtmlMsgView *self, const gchar *brand_name, const GdkPixbuf *brand_icon) +{ + ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); + + modest_mail_header_view_set_branding (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), brand_name, brand_icon); +} + static gboolean has_blocked_external_images (ModestGtkhtmlMsgView *self) { ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); - return (modest_mime_part_view_has_external_images (MODEST_MIME_PART_VIEW (priv->body_view)) && + return ((modest_mime_part_view_has_external_images (MODEST_MIME_PART_VIEW (priv->body_view)) || + (priv->has_blocked_bs_images)) && !modest_mime_part_view_get_view_images (MODEST_MIME_PART_VIEW (priv->body_view))); } @@ -1535,7 +1662,28 @@ on_link_hover (GtkWidget *widget, const gchar *uri, ModestGtkhtmlMsgView *self) return result; } +static void +on_limit_error (GtkWidget *widget, ModestGtkhtmlMsgView *msg_view) +{ + g_signal_emit_by_name (G_OBJECT (msg_view), "limit-error"); +} + +static gboolean +part_cids_equal (const gchar *part_cid1, + const gchar *part_cid2) +{ + if (g_strcmp0 (part_cid1, part_cid2) == 0) + return TRUE; + + if (part_cid2 && part_cid2[0] == '<') { + const gchar *end; + end = g_strrstr_len (part_cid2, -1, ">"); + if (end && strncmp (part_cid2 + 1, part_cid1, end - part_cid2 - 1) == 0) + return TRUE; + } + return FALSE; +} static TnyMimePart * find_cid_image (TnyMsg *msg, const gchar *cid) @@ -1564,8 +1712,8 @@ find_cid_image (TnyMsg *msg, const gchar *cid) */ if (!part_cid) part_cid = tny_mime_part_get_content_location (part); - - if (part_cid && strcmp (cid, part_cid) == 0) + + if (part_cids_equal (cid, part_cid)) break; if (tny_mime_part_content_type_is (part, "multipart/related")) { @@ -1579,9 +1727,10 @@ find_cid_image (TnyMsg *msg, const gchar *cid) while (!tny_iterator_is_done (related_iter)) { related_part = TNY_MIME_PART (tny_iterator_get_current (related_iter)); part_cid = tny_mime_part_get_content_id (related_part); - if (part_cid && strcmp (cid, part_cid) == 0) { + + if (part_cids_equal (cid, part_cid)) break; - } + g_object_unref (related_part); related_part = NULL; tny_iterator_next (related_iter); @@ -1608,6 +1757,11 @@ find_cid_image (TnyMsg *msg, const gchar *cid) return part; } +static void +fetch_url_decode_to_stream_cb (TnyMimePart *self, gboolean cancelled, TnyStream *stream, GError *err, gpointer user_data) +{ + tny_stream_close (stream); +} static gboolean on_fetch_url (GtkWidget *widget, const gchar *uri, @@ -1648,35 +1802,37 @@ on_fetch_url (GtkWidget *widget, const gchar *uri, } else { return FALSE; } + } else if (TNY_IS_CAMEL_BS_MIME_PART (part) && + !tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))){ + if (!modest_mime_part_view_get_view_images (MODEST_MIME_PART_VIEW (priv->body_view)) || + !tny_device_is_online (modest_runtime_get_device ())) { + priv->has_blocked_bs_images = TRUE; + tny_stream_close (stream); + return TRUE; + } } - tny_mime_part_decode_to_stream ((TnyMimePart*)part, stream, NULL); - tny_stream_close (stream); + tny_mime_part_decode_to_stream_async ((TnyMimePart*)part, stream, fetch_url_decode_to_stream_cb, NULL, NULL); g_object_unref (G_OBJECT(part)); return TRUE; } static void -set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg) +set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg, TnyMimePart *other_body) { TnyMimePart *body; ModestGtkhtmlMsgViewPrivate *priv; TnyHeader *header; - GtkAdjustment *html_vadj; + GtkAdjustment *html_vadj, *html_hadj; g_return_if_fail (self); priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE(self); + priv->has_blocked_bs_images = FALSE; modest_mail_header_view_set_loading (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), FALSE); gtk_widget_set_no_show_all (priv->mail_header_view, FALSE); modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), FALSE); - html_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); - html_vadj->upper = 0; - html_vadj->page_size = 0; - g_signal_emit_by_name (G_OBJECT (html_vadj), "changed"); - - if (msg != priv->msg) { if (priv->msg) g_object_unref (G_OBJECT(priv->msg)); @@ -1690,9 +1846,31 @@ set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg) modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL); gtk_widget_hide_all (priv->mail_header_view); gtk_widget_hide_all (priv->attachments_box); +#ifdef MODEST_TOOKIT_HILDON2 gtk_widget_hide_all (priv->priority_box); +#endif + gtk_widget_hide_all (priv->calendar_box); + gtk_widget_hide (priv->calendar_actions_container); + gtk_widget_hide_all (priv->calendar_actions_container); gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view)); + + html_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_vadj->upper = 0; + html_vadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_vadj), "changed"); + + html_hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_hadj->upper = 0; + html_hadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_hadj), "changed"); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + priv->idle_changes_count = 0; + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); + gtk_widget_queue_resize (GTK_WIDGET(self)); gtk_widget_queue_draw (GTK_WIDGET(self)); return; @@ -1702,12 +1880,17 @@ set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg) tny_header_view_set_header (TNY_HEADER_VIEW (priv->mail_header_view), header); g_object_unref (header); - modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW(priv->attachments_view), - msg); + modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), + other_body?NULL:msg); modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), tny_msg_get_allow_external_images (msg)); - body = modest_tny_msg_find_body_part (msg, TRUE); + if (other_body) { + body = other_body; + g_object_ref (body); + } else { + body = modest_tny_msg_find_body_part (msg, TRUE); + } if (body) { ModestAttachmentsView *widget; @@ -1723,11 +1906,15 @@ set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg) children = gtk_container_get_children (GTK_CONTAINER (priv->attachments_box)); label = GTK_LABEL (children->data); gtk_widget_show_all (priv->attachments_box); +#ifdef MODEST_TOOLKIT_HILDON2 if (modest_attachments_view_get_num_attachments (widget) > 1) { text = _("mail_va_attachments"); } else { text = _("mail_va_attachment"); } +#else + text = _("mail_va_attachment"); +#endif gtk_label_set_text (label, text); } else { gtk_widget_hide_all (priv->attachments_box); @@ -1739,14 +1926,40 @@ set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg) /* Refresh priority */ set_priority (self, tny_header_get_flags (header)); + set_calendar (self, header, msg); gtk_widget_show (priv->body_view); +#ifdef MODEST_TOOLKIT_HILDON2 gtk_widget_set_no_show_all (priv->priority_box, TRUE); +#endif + gtk_widget_set_no_show_all (priv->calendar_box, TRUE); + gtk_widget_set_no_show_all (priv->calendar_actions_container, TRUE); gtk_widget_set_no_show_all (priv->attachments_box, TRUE); gtk_widget_show_all (priv->mail_header_view); gtk_widget_set_no_show_all (priv->attachments_box, FALSE); +#ifdef MODEST_TOOLKIT_HILDON2 gtk_widget_set_no_show_all (priv->priority_box, FALSE); +#endif + gtk_widget_set_no_show_all (priv->calendar_box, FALSE); + gtk_widget_set_no_show_all (priv->calendar_actions_container, FALSE); gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); + + html_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_vadj->upper = 0; + html_vadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_vadj), "changed"); + + html_hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_hadj->upper = 0; + html_hadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_hadj), "changed"); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + priv->idle_changes_count = 0; + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); + gtk_widget_queue_resize (GTK_WIDGET(self)); gtk_widget_queue_draw (GTK_WIDGET(self)); @@ -1760,24 +1973,27 @@ set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg) /* This is a hack to force reallocation of scroll after drawing all the stuff. This * makes the html view get the proper and expected size and prevent being able to scroll * the buffer when it shouldn't be scrollable */ - g_object_ref (self); - g_timeout_add (250, (GSourceFunc) idle_readjust_scroll, self); + if (priv->idle_readjust_scroll_id == 0) { + g_object_ref (self); + priv->idle_readjust_scroll_id = g_idle_add ((GSourceFunc) idle_readjust_scroll, self); + } } static void set_header (ModestGtkhtmlMsgView *self, TnyHeader *header) { ModestGtkhtmlMsgViewPrivate *priv; - GtkAdjustment *html_vadj; + GtkAdjustment *html_vadj, *html_hadj; g_return_if_fail (self); if (header == NULL) { - set_message (self, NULL); + set_message (self, NULL, NULL); return; } priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE(self); + priv->has_blocked_bs_images = FALSE; modest_mail_header_view_set_loading (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), TRUE); gtk_widget_set_no_show_all (priv->mail_header_view, FALSE); modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), FALSE); @@ -1787,6 +2003,15 @@ set_header (ModestGtkhtmlMsgView *self, TnyHeader *header) html_vadj->page_size = 0; g_signal_emit_by_name (G_OBJECT (html_vadj), "changed"); + html_hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_hadj->upper = 0; + html_hadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_hadj), "changed"); + + priv->idle_changes_count = 0; + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); if (priv->msg) { g_object_unref (G_OBJECT(priv->msg)); @@ -1797,9 +2022,15 @@ set_header (ModestGtkhtmlMsgView *self, TnyHeader *header) modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL); gtk_widget_show_all (priv->mail_header_view); gtk_widget_hide_all (priv->attachments_box); +#ifdef MODEST_TOOLKIT_HILDON2 gtk_widget_hide_all (priv->priority_box); +#endif + gtk_widget_hide_all (priv->calendar_box); + gtk_widget_hide (priv->calendar_actions_container); + gtk_widget_hide_all (priv->calendar_actions_container); gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view)); + priv->idle_changes_count = 0; gtk_widget_queue_resize (GTK_WIDGET(self)); gtk_widget_queue_draw (GTK_WIDGET(self)); } @@ -1832,12 +2063,27 @@ static void set_zoom (ModestGtkhtmlMsgView *self, gdouble zoom) { ModestGtkhtmlMsgViewPrivate *priv; + GtkAdjustment *html_vadj, *html_hadj; g_return_if_fail (MODEST_IS_GTKHTML_MSG_VIEW (self)); priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); modest_zoomable_set_zoom (MODEST_ZOOMABLE(priv->body_view), zoom); + html_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_vadj->upper = 0; + html_vadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_vadj), "changed"); + + html_hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->html_scroll)); + html_hadj->upper = 0; + html_hadj->page_size = 0; + g_signal_emit_by_name (G_OBJECT (html_hadj), "changed"); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + priv->idle_changes_count = 0; gtk_widget_queue_resize (priv->body_view); } @@ -1868,15 +2114,17 @@ static void set_priority (ModestGtkhtmlMsgView *self, TnyHeaderFlags flags) { ModestGtkhtmlMsgViewPrivate *priv; - TnyHeaderFlags priority_flags; - gboolean show_priority = FALSE; g_return_if_fail (MODEST_IS_GTKHTML_MSG_VIEW (self)); priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); modest_mail_header_view_set_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), flags); - priority_flags = flags & TNY_HEADER_FLAG_PRIORITY_MASK; +#ifdef MODEST_TOOLKIT_HILDON2 + gboolean show_priority = FALSE; + TnyHeaderFlags priority_flags; + + priority_flags = flags & TNY_HEADER_FLAG_PRIORITY_MASK; if (priority_flags == TNY_HEADER_FLAG_HIGH_PRIORITY) { show_priority = TRUE; gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), MODEST_HEADER_ICON_HIGH, GTK_ICON_SIZE_MENU); @@ -1885,7 +2133,6 @@ set_priority (ModestGtkhtmlMsgView *self, TnyHeaderFlags flags) gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), MODEST_HEADER_ICON_LOW, GTK_ICON_SIZE_MENU); } -#ifdef MODEST_TOOLKIT_HILDON2 if (show_priority && MODEST_IS_COMPACT_MAIL_HEADER_VIEW (priv->mail_header_view)) { gtk_widget_show_all (priv->priority_box); } else { @@ -2051,7 +2298,7 @@ modest_msg_view_clear_header (TnyHeaderView *self) static void modest_msg_view_clear_header_default (TnyHeaderView *self) { - set_message (MODEST_GTKHTML_MSG_VIEW (self), NULL); + set_message (MODEST_GTKHTML_MSG_VIEW (self), NULL, NULL); } /* TNY MSG IMPLEMENTATION */ @@ -2121,7 +2368,7 @@ modest_msg_view_clear (TnyMsgView *self) static void modest_msg_view_clear_default (TnyMsgView *self) { - set_message (MODEST_GTKHTML_MSG_VIEW (self), NULL); + set_message (MODEST_GTKHTML_MSG_VIEW (self), NULL, NULL); } static TnyMimePartView* @@ -2191,7 +2438,7 @@ modest_msg_view_mp_set_part_default (TnyMimePartView *self, { g_return_if_fail ((part == NULL) || TNY_IS_MSG (part)); - set_message (MODEST_GTKHTML_MSG_VIEW (self), TNY_MSG (part)); + set_message (MODEST_GTKHTML_MSG_VIEW (self), TNY_MSG (part), NULL); } static void @@ -2330,6 +2577,7 @@ modest_msg_view_init (gpointer g, gpointer iface_data) { ModestMsgViewIface *klass = (ModestMsgViewIface *)g; + klass->set_msg_with_other_body_func = modest_gtkhtml_msg_view_set_msg_with_other_body; klass->get_vadjustment_func = modest_gtkhtml_msg_view_get_vadjustment; klass->get_hadjustment_func = modest_gtkhtml_msg_view_get_hadjustment; klass->set_vadjustment_func = modest_gtkhtml_msg_view_set_vadjustment; @@ -2343,11 +2591,24 @@ modest_msg_view_init (gpointer g, gpointer iface_data) klass->grab_focus_func = modest_gtkhtml_msg_view_grab_focus; klass->remove_attachment_func = modest_gtkhtml_msg_view_remove_attachment; klass->request_fetch_images_func = modest_gtkhtml_msg_view_request_fetch_images; + klass->set_branding_func = modest_gtkhtml_msg_view_set_branding; klass->has_blocked_external_images_func = modest_gtkhtml_msg_view_has_blocked_external_images; return; } +static void +modest_gtkhtml_msg_view_set_msg_with_other_body (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body) +{ + MODEST_GTKHTML_MSG_VIEW_GET_CLASS (self)->set_msg_with_other_body_func (self, msg, other_body); +} + +static void +modest_gtkhtml_msg_view_set_msg_with_other_body_default (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body) +{ + set_message (MODEST_GTKHTML_MSG_VIEW (self), msg, other_body); +} + static GtkAdjustment* modest_gtkhtml_msg_view_get_vadjustment (ModestMsgView *self) { @@ -2504,6 +2765,18 @@ modest_gtkhtml_msg_view_request_fetch_images_default (ModestMsgView *self) request_fetch_images (MODEST_GTKHTML_MSG_VIEW (self)); } +static void +modest_gtkhtml_msg_view_set_branding (ModestMsgView *self, const gchar *brand_name, const GdkPixbuf *brand_icon) +{ + MODEST_GTKHTML_MSG_VIEW_GET_CLASS (self)->set_branding_func (self, brand_name, brand_icon); +} + +static void +modest_gtkhtml_msg_view_set_branding_default (ModestMsgView *self, const gchar *brand_name, const GdkPixbuf *brand_icon) +{ + set_branding (MODEST_GTKHTML_MSG_VIEW (self), brand_name, brand_icon); +} + static gboolean modest_gtkhtml_msg_view_has_blocked_external_images (ModestMsgView *self) { @@ -2515,3 +2788,48 @@ modest_gtkhtml_msg_view_has_blocked_external_images_default (ModestMsgView *self { return has_blocked_external_images (MODEST_GTKHTML_MSG_VIEW (self)); } + +static void +set_calendar (ModestGtkhtmlMsgView *self, TnyHeader *header, TnyMsg *msg) +{ + ModestGtkhtmlMsgViewPrivate *priv; + TnyMimePart *calendar_part; + + g_return_if_fail (MODEST_IS_GTKHTML_MSG_VIEW (self)); + priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self); + + gtk_widget_hide (priv->calendar_actions_container); + gtk_widget_hide_all (priv->calendar_actions_container); + if (priv->calendar_actions_box) { + gtk_widget_destroy (priv->calendar_actions_box); + priv->calendar_actions_box = NULL; + } + + calendar_part = modest_tny_msg_find_calendar (TNY_MSG (msg)); + + if (calendar_part) { + gboolean retval = FALSE; + priv->calendar_actions_box = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (priv->calendar_actions_container), priv->calendar_actions_box, FALSE, FALSE, 0); + g_signal_emit_by_name (G_OBJECT (self), "handle-calendar", calendar_part, priv->calendar_actions_box, &retval); + if (retval) { + gtk_widget_show (priv->calendar_actions_container); + gtk_widget_show_all (priv->calendar_actions_container); + gtk_widget_show (priv->calendar_actions_box); + gtk_widget_show_all (priv->calendar_actions_box); + } else { + gtk_widget_hide (priv->calendar_actions_container); + gtk_widget_hide_all (priv->calendar_actions_container); + gtk_widget_hide (priv->calendar_actions_box); + gtk_widget_hide_all (priv->calendar_actions_box); + } + gtk_widget_show_all (priv->calendar_box); + g_object_unref (calendar_part); + } else { + gtk_widget_hide_all (priv->calendar_box); + gtk_widget_hide (priv->calendar_actions_container); + gtk_widget_hide_all (priv->calendar_actions_container); + if (priv->calendar_actions_box) + gtk_widget_hide (priv->calendar_actions_box); + } +}