* src/modest-marshal.list:
authorJose Dapena Paz <jdapena@igalia.com>
Tue, 22 Jul 2008 15:52:01 +0000 (15:52 +0000)
committerJose Dapena Paz <jdapena@igalia.com>
Tue, 22 Jul 2008 15:52:01 +0000 (15:52 +0000)
        * Add a new marshaller.
* src/widgets/modest-gtkhtml-msg-view.c:
        * Implement autoscroll on selection grab, so that moving
          finger/stylus to borders scroll and enable user to select more
          than what she sees (fixes NB#86800).
* src/widgets/modest-gtkhtml-mime-part-view.c:
        * Disable keyboard bindings that we manage really at window
          level.
* src/widgets/modest-msg-view-window.h:
        * New scroll child signal.
* src/maemo/modest-msg-view-window.c:
        * Implement keyboard scroll using binding sets, to enable
          properly "press-and-hold" continuous scroll as user would
          expect (fixes NB#86757).
* src/widgets/modest-header-view.c:
        * Remove some debugging messages.

pmo-trunk-r5098

src/maemo/modest-msg-view-window.c
src/modest-marshal.list
src/widgets/modest-gtkhtml-mime-part-view.c
src/widgets/modest-gtkhtml-msg-view.c
src/widgets/modest-header-view.c
src/widgets/modest-msg-view-window.h

index 7fa69d7..6bad4fe 100644 (file)
@@ -160,9 +160,15 @@ static gboolean on_fetch_image (ModestMsgView *msgview,
                                TnyStream *stream,
                                ModestMsgViewWindow *window);
 
+static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
+                                                    GtkScrollType scroll_type,
+                                                    gboolean horizontal,
+                                                    gpointer userdata);
+
 /* list my signals */
 enum {
        MSG_CHANGED_SIGNAL,
+       SCROLL_CHILD_SIGNAL,
        LAST_SIGNAL
 };
 
@@ -309,11 +315,43 @@ restore_settings (ModestMsgViewWindow *self)
                                      MODEST_CONF_MSG_VIEW_WINDOW_KEY);
 }
 
+static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
+                                                    GtkScrollType scroll_type,
+                                                    gboolean horizontal,
+                                                    gpointer userdata)
+{
+       ModestMsgViewWindowPrivate *priv;
+       gboolean return_value;
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
+       g_signal_emit_by_name (priv->main_scroll, "scroll-child", scroll_type, horizontal, &return_value);
+       return return_value;
+}
+
+static void
+add_scroll_binding (GtkBindingSet *binding_set,
+                   guint keyval,
+                   GtkScrollType scroll)
+{
+       guint keypad_keyval = keyval - GDK_Left + GDK_KP_Left;
+       
+       gtk_binding_entry_add_signal (binding_set, keyval, 0,
+                                     "scroll_child", 2,
+                                     GTK_TYPE_SCROLL_TYPE, scroll,
+                                     G_TYPE_BOOLEAN, FALSE);
+       gtk_binding_entry_add_signal (binding_set, keypad_keyval, 0,
+                                     "scroll_child", 2,
+                                     GTK_TYPE_SCROLL_TYPE, scroll,
+                                     G_TYPE_BOOLEAN, FALSE);
+}
+
 static void
 modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass)
 {
        GObjectClass *gobject_class;
        ModestWindowClass *modest_window_class;
+       GtkBindingSet *binding_set;
+
        gobject_class = (GObjectClass*) klass;
        modest_window_class = (ModestWindowClass *) klass;
 
@@ -327,10 +365,10 @@ modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass)
        modest_window_class->show_toolbar_func = modest_msg_view_window_show_toolbar;
        modest_window_class->disconnect_signals_func = modest_msg_view_window_disconnect_signals;
 
-       g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate));
-
        modest_window_class->save_state_func = save_state;
 
+       klass->scroll_child = modest_msg_view_window_scroll_child;
+
        signals[MSG_CHANGED_SIGNAL] =
                g_signal_new ("msg-changed",
                              G_TYPE_FROM_CLASS (gobject_class),
@@ -339,6 +377,26 @@ modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass)
                              NULL, NULL,
                              modest_marshal_VOID__POINTER_POINTER,
                              G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
+
+       signals[SCROLL_CHILD_SIGNAL] =
+               g_signal_new ("scroll-child",
+                             G_TYPE_FROM_CLASS (gobject_class),
+                             G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                             G_STRUCT_OFFSET (ModestMsgViewWindowClass, scroll_child),
+                             NULL, NULL,
+                             modest_marshal_BOOLEAN__ENUM_BOOLEAN,
+                             G_TYPE_BOOLEAN, 2, GTK_TYPE_SCROLL_TYPE, G_TYPE_BOOLEAN);
+
+       binding_set = gtk_binding_set_by_class (klass);
+       add_scroll_binding (binding_set, GDK_Up, GTK_SCROLL_STEP_UP);
+       add_scroll_binding (binding_set, GDK_Down, GTK_SCROLL_STEP_DOWN);
+       add_scroll_binding (binding_set, GDK_Page_Up, GTK_SCROLL_PAGE_UP);
+       add_scroll_binding (binding_set, GDK_Page_Down, GTK_SCROLL_PAGE_DOWN);
+       add_scroll_binding (binding_set, GDK_Home, GTK_SCROLL_START);
+       add_scroll_binding (binding_set, GDK_End, GTK_SCROLL_END);
+
+       g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate));
+
 }
 
 static void modest_header_view_observer_init(
@@ -1576,10 +1634,10 @@ modest_msg_view_window_key_event (GtkWidget *window,
            event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down ||
            event->keyval == GDK_Home || event->keyval == GDK_KP_Home ||
            event->keyval == GDK_End || event->keyval == GDK_KP_End) {
-               ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
-               gboolean return_value;
+               /* ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); */
+               /* gboolean return_value; */
 
-               if (event->type == GDK_KEY_RELEASE) {
+               if (event->type == GDK_KEY_PRESS) {
                        GtkScrollType scroll_type;
                        
                        switch (event->keyval) {
@@ -1604,9 +1662,9 @@ modest_msg_view_window_key_event (GtkWidget *window,
                        default: scroll_type = GTK_SCROLL_NONE;
                        }
                        
-                       g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", 
-                                              scroll_type, FALSE, &return_value);
-                       return TRUE;
+                       /* g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child",  */
+                       /*                     scroll_type, FALSE, &return_value); */
+                       return FALSE;
                } else {
                        return FALSE;
                }
index 1d5587e..4ca7a82 100644 (file)
@@ -10,3 +10,4 @@ VOID:STRING,POINTER,BOOL
 VOID:POINTER,INT
 BOOL:STRING
 BOOL:STRING,OBJECT
+BOOL:ENUM,BOOL
index 824021f..499e13e 100644 (file)
@@ -202,6 +202,8 @@ static void
 modest_gtkhtml_mime_part_view_class_init (ModestGtkhtmlMimePartViewClass *klass)
 {
        GObjectClass *gobject_class;
+       GtkBindingSet *binding_set;
+
        gobject_class = (GObjectClass*) klass;
 
        parent_class            = g_type_class_peek_parent (klass);
@@ -222,6 +224,20 @@ modest_gtkhtml_mime_part_view_class_init (ModestGtkhtmlMimePartViewClass *klass)
        klass->search_func = modest_gtkhtml_mime_part_view_search_default;
        klass->search_next_func = modest_gtkhtml_mime_part_view_search_next_default;
        klass->get_selection_area_func = modest_gtkhtml_mime_part_view_get_selection_area_default;
+
+       binding_set = gtk_binding_set_by_class (klass);
+       gtk_binding_entry_skip (binding_set, GDK_Down, 0);
+       gtk_binding_entry_skip (binding_set, GDK_Up, 0);
+       gtk_binding_entry_skip (binding_set, GDK_KP_Up, 0);
+       gtk_binding_entry_skip (binding_set, GDK_KP_Down, 0);
+       gtk_binding_entry_skip (binding_set, GDK_Page_Down, 0);
+       gtk_binding_entry_skip (binding_set, GDK_Page_Up, 0);
+       gtk_binding_entry_skip (binding_set, GDK_KP_Page_Up, 0);
+       gtk_binding_entry_skip (binding_set, GDK_KP_Page_Down, 0);
+       gtk_binding_entry_skip (binding_set, GDK_Home, 0);
+       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));
 
index 351cc75..3bacb9b 100644 (file)
@@ -109,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);
@@ -229,6 +238,9 @@ struct _ModestGtkhtmlMsgViewPrivate {
        GdkWindow *headers_window;
        GdkWindow *html_window;
 
+       /* id handler for dragged scroll */
+       guint idle_motion_id;
+
        /* zoom */
        gdouble current_zoom;
 
@@ -1035,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");
@@ -1060,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);
@@ -1131,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 */
@@ -1179,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)
 {
index 4ef6619..1b52c1e 100644 (file)
@@ -978,13 +978,11 @@ modest_header_view_on_expose_event(GtkTreeView *header_view,
                        GtkTreePath * last_path;
                        if (gtk_tree_selection_count_selected_rows (sel) != 1) {
                                moved_selection = TRUE;
-                               g_message ("MULTISELECTION %d -> MOVED", gtk_tree_selection_count_selected_rows (sel));
                        } else {
                                GList *rows;
 
                                rows = gtk_tree_selection_get_selected_rows (sel, NULL);
                                last_path = gtk_tree_row_reference_get_path (priv->autoselect_reference);
-                               g_message ("SELECTION PATH %s LAST PATH %s", gtk_tree_path_to_string (rows->data), gtk_tree_path_to_string (last_path));
                                if (gtk_tree_path_compare (last_path, (GtkTreePath *) rows->data) != 0)
                                        moved_selection = TRUE;
                                g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
@@ -999,7 +997,6 @@ modest_header_view_on_expose_event(GtkTreeView *header_view,
                                        GtkTreePath *current_path;
                                        current_path = gtk_tree_model_get_path (model, &tree_iter);
                                        last_path = gtk_tree_row_reference_get_path (priv->autoselect_reference);
-                                       g_message ("CURRENT PATH %s LAST PATH %s", gtk_tree_path_to_string (current_path), gtk_tree_path_to_string (last_path));
                                        if (gtk_tree_path_compare (current_path, last_path) != 0) {
                                                g_object_set(header_view, "can-focus", FALSE, NULL);
                                                gtk_tree_selection_unselect_all (sel);
index 9b1bae7..1121687 100644 (file)
@@ -34,6 +34,7 @@
 #include <tny-folder.h>
 #include <widgets/modest-window.h>
 #include <gtk/gtktreemodel.h>
+#include <gtk/gtkenums.h>
 
 G_BEGIN_DECLS
 
@@ -57,6 +58,11 @@ typedef struct {
                             GtkTreeModel *model,
                             GtkTreeRowReference *row_reference, 
                             gpointer user_data);
+
+       gboolean (*scroll_child) (ModestMsgViewWindow *self,
+                                  GtkScrollType scroll_type,
+                                  gboolean horizontal,
+                                  gpointer userdata);
 } ModestMsgViewWindowClass;
 
 /**