* Changes in the autotools stuff affecting a lot of platform dependent
[modest] / src / widgets / modest-gtkhtml-msg-view.c
index b752eb5..75c5526 100644 (file)
 #include <widgets/modest-gtkhtml-mime-part-view.h>
 #include <widgets/modest-gtkhtml-msg-view.h>
 #include <widgets/modest-isearch-view.h>
+#include <widgets/modest-ui-constants.h>
 
 /* FIXNE: we should have no maemo-deps in widgets/ */
-#ifdef MODEST_PLATFORM_MAEMO
+#ifndef MODEST_TOOLKIT_GTK
 #include "maemo/modest-hildon-includes.h"
-#endif /*MODEST_PLATFORM_MAEMO*/
+#endif /*!MODEST_TOOLKIT_GTK*/
 
 
 /* 'private'/'protected' functions */
@@ -81,6 +82,7 @@ static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestGtkhtm
 
 #ifdef MAEMO_CHANGES
 static void     on_tap_and_hold (GtkWidget *widget, gpointer userdata); 
+static gboolean on_tap_and_hold_query (GtkWidget *widget, GdkEvent *event, gpointer userdata); 
 #endif /*MAEMO_CHANGES*/
 
 
@@ -107,6 +109,15 @@ static gboolean motion_notify_event (GtkWidget *widget,
                                     gpointer userdata);
 #endif
 
+static gboolean 
+button_press_event (GtkWidget *widget,
+                   GdkEventButton *event,
+                   gpointer userdata);
+static gboolean 
+button_release_event (GtkWidget *widget,
+                     GdkEventButton *event,
+                     gpointer userdata);
+
 /* GtkContainer methods */
 static void forall (GtkContainer *container, gboolean include_internals,
                    GtkCallback callback, gpointer userdata);
@@ -227,6 +238,9 @@ struct _ModestGtkhtmlMsgViewPrivate {
        GdkWindow *headers_window;
        GdkWindow *html_window;
 
+       /* id handler for dragged scroll */
+       guint idle_motion_id;
+
        /* zoom */
        gdouble current_zoom;
 
@@ -1033,6 +1047,8 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj)
        priv->headers_window = NULL;
        priv->html_window = NULL;
 
+       priv->idle_motion_id = 0;
+
        gtk_widget_push_composite_child ();
        priv->html_scroll = gtk_scrolled_window_new (NULL, NULL);
        gtk_widget_set_composite_name (priv->html_scroll, "contents");
@@ -1043,7 +1059,7 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj)
 
        priv->body_view                 = GTK_WIDGET (g_object_new (MODEST_TYPE_GTKHTML_MIME_PART_VIEW, NULL));
        priv->mail_header_view        = GTK_WIDGET(modest_mail_header_view_new (TRUE));
-       priv->view_images_button = gtk_button_new_with_label (_("TODO: view images"));
+       priv->view_images_button = gtk_button_new_with_label (_("mail_bd_external_images"));
        gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
        gtk_widget_set_no_show_all (priv->view_images_button, TRUE);
        priv->attachments_view        = GTK_WIDGET(modest_attachments_view_new (NULL));
@@ -1058,6 +1074,10 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj)
        g_signal_connect (G_OBJECT(priv->body_view), "motion-notify-event",
                          G_CALLBACK (motion_notify_event), obj);
 #endif
+       g_signal_connect (G_OBJECT (priv->body_view), "button-press-event",
+                         G_CALLBACK (button_press_event), obj);
+       g_signal_connect (G_OBJECT (priv->body_view), "button-release-event",
+                         G_CALLBACK (button_release_event), obj);
 
        g_signal_connect (G_OBJECT (priv->mail_header_view), "recpt-activated", 
                          G_CALLBACK (on_recpt_activated), obj);
@@ -1074,14 +1094,18 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj)
                          G_CALLBACK (html_adjustment_changed), obj);
 
        gtk_widget_push_composite_child ();
-       priv->headers_box = gtk_vbox_new (0, FALSE);
+       priv->headers_box = gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT);
        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);
        if (priv->view_images_button) {
-               gtk_box_pack_start (GTK_BOX (priv->headers_box), priv->view_images_button, FALSE, FALSE, 0);
+               GtkWidget *hbuttonbox;
+               
+               hbuttonbox = gtk_hbutton_box_new ();
+               gtk_container_add (GTK_CONTAINER (hbuttonbox), priv->view_images_button);
+               gtk_box_pack_start (GTK_BOX (priv->headers_box), hbuttonbox, FALSE, FALSE, 0);
                gtk_widget_hide (priv->view_images_button);
        }
        
@@ -1108,6 +1132,7 @@ modest_gtkhtml_msg_view_init (ModestGtkhtmlMsgView *obj)
 #ifdef MAEMO_CHANGES
                gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->body_view), NULL, NULL, 0);
                g_signal_connect (G_OBJECT (priv->body_view), "tap-and-hold", G_CALLBACK (on_tap_and_hold), obj);
+               g_signal_connect (G_OBJECT (priv->body_view), "tap-and-hold-query", G_CALLBACK (on_tap_and_hold_query), obj);
 #endif
        }
        
@@ -1124,6 +1149,11 @@ modest_gtkhtml_msg_view_finalize (GObject *obj)
                g_object_unref (G_OBJECT(priv->msg));
                priv->msg = NULL;
        }
+
+       if (priv->idle_motion_id > 0) {
+               g_source_remove (priv->idle_motion_id);
+               priv->idle_motion_id = 0;
+       }
        
        /* we cannot disconnect sigs, because priv->body_view is
         * already dead */
@@ -1172,11 +1202,63 @@ motion_notify_event (GtkWidget *widget,
                        value = priv->vadj->upper - priv->vadj->page_size;
                gtk_adjustment_set_value (priv->vadj, value);
                
-       }
+       } 
        return FALSE;
 }
 #endif
 
+static gboolean
+idle_motion (gpointer userdata)
+{
+       ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (userdata);
+       if (GTK_HTML (priv->body_view)->in_selection_drag) {
+               gdouble offset;
+               GtkAdjustment *adj;
+               gint gdk_y;
+               gdk_window_get_pointer (gtk_widget_get_parent_window (priv->body_view), NULL, &gdk_y, NULL);
+               offset= (gdouble) (priv->headers_box->requisition.height + gdk_y);
+               adj = GTK_ADJUSTMENT (priv->vadj);
+               if (offset < adj->value + adj->step_increment) {
+                       gtk_adjustment_set_value (adj, MAX (offset + adj->page_increment - adj->page_size, 0.0));
+               } else if (offset > adj->value + adj->page_increment) {
+                       gtk_adjustment_set_value (adj, MIN (offset - adj->page_increment, adj->upper - adj->page_size));
+               }
+               gtk_widget_queue_resize (userdata);
+       }
+       return TRUE;
+}
+
+static gboolean 
+button_press_event (GtkWidget *widget,
+                   GdkEventButton *event,
+                   gpointer userdata)
+{
+       ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (userdata);
+
+       if (priv->idle_motion_id == 0) {
+               priv->idle_motion_id = g_timeout_add (200, idle_motion, userdata);
+       }
+       return FALSE;
+}
+
+static gboolean 
+button_release_event (GtkWidget *widget,
+                     GdkEventButton *event,
+                     gpointer userdata)
+{
+       ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (userdata);
+
+       if (priv->idle_motion_id > 0) {
+               gint gdk_y;
+               g_source_remove (priv->idle_motion_id);
+               
+               priv->idle_motion_id = 0;;
+               gdk_window_get_pointer (gtk_widget_get_parent_window (priv->body_view), NULL, &gdk_y, NULL);
+               event->y = (gdouble) gdk_y;
+       }
+       return FALSE;
+}
+
 static GtkAdjustment *
 get_vadjustment (ModestGtkhtmlMsgView *self)
 {
@@ -1312,6 +1394,18 @@ on_tap_and_hold (GtkWidget *widget,
 
        g_signal_emit_by_name (G_OBJECT (self), "link-contextual", priv->last_url);
 }
+
+static gboolean
+on_tap_and_hold_query (GtkWidget *widget,
+                      GdkEvent *event,
+                      gpointer data)
+{
+       ModestGtkhtmlMsgView *self = (ModestGtkhtmlMsgView *) data;
+       ModestGtkhtmlMsgViewPrivate *priv = MODEST_GTKHTML_MSG_VIEW_GET_PRIVATE (self);
+
+       /* Don't show the tap and hold animation if no url below */
+       return (priv->last_url == NULL);
+}
 #endif
 
 static void
@@ -1473,30 +1567,13 @@ on_fetch_url (GtkWidget *widget, const gchar *uri,
        part = find_cid_image (priv->msg, my_uri);
 
        if (!part) {
-               GtkIconTheme *current_theme;
-               GtkIconInfo *icon_info;
-
                if (g_str_has_prefix (uri, "http:")) {
                        if (modest_mime_part_view_get_view_images (MODEST_MIME_PART_VIEW (priv->body_view))) {
                                gboolean result = FALSE;
                                g_signal_emit_by_name (self, "fetch-image", uri, stream, &result);
                                return result;
                        } else {
-                               current_theme = gtk_icon_theme_get_default ();
-                               icon_info = gtk_icon_theme_lookup_icon (current_theme, "qgn_indi_messagin_nullcmas", 26,
-                                                                       GTK_ICON_LOOKUP_NO_SVG);
-                               if (icon_info != NULL) {
-                                       const gchar *filename;
-                                       TnyStream *vfs_stream;
-                                       GnomeVFSHandle *handle;
-                                       filename = gtk_icon_info_get_filename (icon_info);
-                                       gnome_vfs_open (&handle, filename, GNOME_VFS_OPEN_READ);
-                                       vfs_stream = tny_vfs_stream_new (handle);
-                                       while (tny_stream_write_to_stream (vfs_stream, stream) > 0);
-                                       tny_stream_close (vfs_stream);
-                                       g_object_unref (vfs_stream);
-                                       gtk_icon_info_free (icon_info);
-                               }
+                               /* we return immediately to get a "image not found" icon */
                                tny_stream_close (stream);
                                return TRUE;
                        }
@@ -1563,6 +1640,7 @@ set_message (ModestGtkhtmlMsgView *self, TnyMsg *msg)
        body = modest_tny_msg_find_body_part (msg, TRUE);
        if (body) {
                tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (priv->body_view), body);
+               g_object_unref (body);
 
                if(modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view))) {
                        gtk_widget_show_all (priv->attachments_box);