From: Jose Dapena Paz Date: Tue, 22 Jul 2008 15:52:01 +0000 (+0000) Subject: * src/modest-marshal.list: X-Git-Tag: git_migration_finished~1256 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=004e051469e80cc145ee2fb886682bd1ff07b213 * src/modest-marshal.list: * 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 --- diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index 7fa69d7..6bad4fe 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -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; } diff --git a/src/modest-marshal.list b/src/modest-marshal.list index 1d5587e..4ca7a82 100644 --- a/src/modest-marshal.list +++ b/src/modest-marshal.list @@ -10,3 +10,4 @@ VOID:STRING,POINTER,BOOL VOID:POINTER,INT BOOL:STRING BOOL:STRING,OBJECT +BOOL:ENUM,BOOL diff --git a/src/widgets/modest-gtkhtml-mime-part-view.c b/src/widgets/modest-gtkhtml-mime-part-view.c index 824021f..499e13e 100644 --- a/src/widgets/modest-gtkhtml-mime-part-view.c +++ b/src/widgets/modest-gtkhtml-mime-part-view.c @@ -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)); diff --git a/src/widgets/modest-gtkhtml-msg-view.c b/src/widgets/modest-gtkhtml-msg-view.c index 351cc75..3bacb9b 100644 --- a/src/widgets/modest-gtkhtml-msg-view.c +++ b/src/widgets/modest-gtkhtml-msg-view.c @@ -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) { diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index 4ef6619..1b52c1e 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -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); diff --git a/src/widgets/modest-msg-view-window.h b/src/widgets/modest-msg-view-window.h index 9b1bae7..1121687 100644 --- a/src/widgets/modest-msg-view-window.h +++ b/src/widgets/modest-msg-view-window.h @@ -34,6 +34,7 @@ #include #include #include +#include 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; /**