[anjal] Move focus to the first unread message on the thread



commit 5c4e966a018eba186fdd540290aff670993457bb
Author: Srinivasa Ragavan <sragavan novell com>
Date:   Thu Mar 26 14:02:50 2009 +0530

    Move focus to the first unread message on the thread
---
 src/mail-conv-view.c    |   54 ++++++++++++++++++++++++++++++++++++++++++++--
 src/mail-message-view.c |   18 +++++++++++++++
 src/mail-message-view.h |    5 +++-
 3 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/src/mail-conv-view.c b/src/mail-conv-view.c
index f9f699e..384e2a7 100644
--- a/src/mail-conv-view.c
+++ b/src/mail-conv-view.c
@@ -42,6 +42,7 @@ struct  _MailConvViewPrivate {
 	GtkWidget *viewport;
 	GList *child;
 	GList  *selected_child;
+	gboolean once;
 };
 
 static void
@@ -49,6 +50,7 @@ mail_conv_view_init (MailConvView  *shell)
 {
 	shell->priv = g_new0(MailConvViewPrivate, 1);
 	shell->type = -1;
+	shell->priv->once = FALSE;
 }
 
 static void
@@ -202,6 +204,38 @@ mcv_sh_color_expose (GtkWidget *w, GdkEventExpose *event, const char *color)
 }
 
 static void
+mcv_adjust_scroll(MailConvView *mcv, MailMessageView *mmv)
+{
+	int x, y, height, ret;
+	GtkAdjustment *adj = gtk_viewport_get_vadjustment(mcv->priv->viewport);
+
+	ret = gtk_widget_translate_coordinates (mcv->priv->selected_child->data, mcv->child_box, 0, 0, &x, &y);
+	height = ((GtkContainer *)mcv->child_box)->focus_child->allocation.height;
+	gtk_adjustment_clamp_page (adj, y + height, y+height+gtk_adjustment_get_page_increment(adj));
+}
+
+static void
+mcv_scroll_to_mmv (MailMessageView *mmv, MailConvView *mcv)
+{
+	mcv_adjust_scroll (mcv, mmv);
+	g_signal_handlers_disconnect_by_func(mmv, mcv_scroll_to_mmv, mcv);
+}
+
+static int
+mcv_sh_focus_expose (GtkWidget *w, GdkEventExpose *event, MailConvView *mcv)
+{
+	int x, y, height, ret;
+	GtkAdjustment *adj = gtk_viewport_get_vadjustment(mcv->priv->viewport);
+
+	if (!mcv->priv->once) {
+		mcv->priv->once = TRUE;
+		ret = gtk_widget_translate_coordinates (mcv->priv->selected_child->data, mcv->child_box, 0, 0, &x, &y);
+		height = ((GtkContainer *)mcv->child_box)->focus_child->allocation.height;
+		gtk_adjustment_clamp_page (adj, y, y+height);
+	}
+}
+
+static void
 mcv_message_selected (MailMessageView *mmv, MailConvView *mcv)
 {
 	GtkWidget *focus = mail_message_view_get_focus_widget (mmv);
@@ -279,13 +313,15 @@ mail_conv_view_set_thread (MailConvView *mcv, CamelFolder *folder, GPtrArray *ar
 	int i;
 	GList *focus = NULL;
 	extern char *scolor_bg_norm;
-		 
+	GtkWidget *unread = NULL, *unread_parent;
+
 	if (mcv->child_box) {
 		tmp = mcv->child_box;
 		gtk_widget_hide (tmp);
 		gtk_container_remove (mcv->priv->viewport, tmp);
 	}
 	mcv->child_box = gtk_vbox_new (FALSE, 0);
+	mcv->priv->once = FALSE;
 	gtk_container_set_focus_vadjustment (mcv->child_box, gtk_viewport_get_vadjustment (mcv->priv->viewport));
 	gtk_widget_show (mcv->child_box);
 	g_signal_connect (mcv->child_box, "expose-event",
@@ -300,11 +336,16 @@ mail_conv_view_set_thread (MailConvView *mcv, CamelFolder *folder, GPtrArray *ar
 		child = mail_message_view_new ();
 		gtk_box_pack_start (mcv->child_box, child, FALSE, FALSE, 4);
 		gtk_widget_show (child);
-
+		
 		mail_message_view_set_message (child, folder, array->pdata[i]);
 		g_signal_connect (child, "message-selected", G_CALLBACK(mcv_message_selected), mcv);
 		g_signal_connect (child, "message-removed", G_CALLBACK(mcv_message_removed), mcv);
 		focus = g_list_prepend (focus, mail_message_view_get_focus_widget(child));
+		if (!unread) {
+			if (mail_message_view_get_unread (child))
+				unread = mail_message_view_get_focus_widget(child);
+				g_signal_connect (child, "message-loaded", G_CALLBACK(mcv_scroll_to_mmv), mcv);
+		}
 	}
 
 	focus = g_list_reverse (focus);
@@ -312,7 +353,14 @@ mail_conv_view_set_thread (MailConvView *mcv, CamelFolder *folder, GPtrArray *ar
 
 	/* Select first child by default */
 	mcv->priv->selected_child = focus;
-	gtk_widget_grab_focus (mcv->priv->child->data);
+	if (unread) {
+		g_signal_connect (mcv->child_box, "expose-event",
+					  G_CALLBACK (mcv_sh_focus_expose),
+					  mcv);
+		mcv->priv->selected_child = g_list_find (focus, unread);
+		gtk_widget_grab_focus (unread);
+	} else				
+		gtk_widget_grab_focus (mcv->priv->child->data);
 	
 }
 
diff --git a/src/mail-message-view.c b/src/mail-message-view.c
index caf1e90..61c4e08 100644
--- a/src/mail-message-view.c
+++ b/src/mail-message-view.c
@@ -56,6 +56,7 @@ G_DEFINE_TYPE (MailMessageView, mail_message_view, GTK_TYPE_VBOX)
 enum {
 	MESSAGE_SELECTED,
 	MESSAGE_REMOVED,
+	MESSAGE_LOADED,
 	LAST_SIGNAL
 };
 
@@ -113,6 +114,15 @@ mail_message_view_class_init (MailMessageViewClass *klass)
 			      NULL, NULL,
 			      g_cclosure_marshal_VOID__VOID,
 			     G_TYPE_NONE, 0);
+	signals[MESSAGE_LOADED] =
+		g_signal_new ("message-loaded",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (MailMessageViewClass , message_loaded),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			     G_TYPE_NONE, 0);
+
 }
 
 static void
@@ -363,6 +373,8 @@ mmv_finished (WebKitWebView  *webkitwebview, WebKitWebFrame *arg1, gpointer user
 
 	/* Connect on expose, and mark mail as read on expose, when the mail is actually seen */
 	g_signal_connect (webkitwebview, "expose-event" , mark_mail_read, mmview);
+	g_signal_emit (mmview, signals[MESSAGE_LOADED], 0);
+
 }
 
 static void
@@ -885,3 +897,9 @@ mail_message_view_get_focus_widget (MailMessageView *mmv)
 {
 	return mmv->priv->focus;
 };
+
+gboolean
+mail_message_view_get_unread(MailMessageView *mmv)
+{
+	return !(camel_message_info_flags(mmv->priv->info) & CAMEL_MESSAGE_SEEN);
+}
diff --git a/src/mail-message-view.h b/src/mail-message-view.h
index de030ef..47c23a2 100644
--- a/src/mail-message-view.h
+++ b/src/mail-message-view.h
@@ -59,11 +59,14 @@ typedef struct _MailMessageViewClass {
 	GtkVBoxClass parent_class;
 
 	void (*message_selected) (MailMessageView *);
-	 void (*message_removed) (MailMessageView *);
+	void (*message_removed) (MailMessageView *);
+	void (*message_loaded) (MailMessageView *);
+
 } MailMessageViewClass;
 
 MailMessageView * mail_message_view_new (void);
 void mail_message_view_set_message (MailMessageView *mmview, struct _CamelFolder *folder, const char *uid);
 GtkWidget * mail_message_view_create_webview (MailMessageView *mmv, GtkWidget *box);
 GtkWidget * mail_message_view_get_focus_widget (MailMessageView *mmv);
+gboolean mail_message_view_get_unread (MailMessageView *mmv);
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]