[evolution-patches] 57972, mail, sensitivity of next/prev buttons, plus others




ok addresses the bug, fwiw (which i think is 'very little').  it could be expensive to calculate, so i'm not sure if its really worth it (e.g. you could end up scanning the full tree once, times the number of times it thinks it needs to update it, which is at least 2-3 times each time the cursor moves).

but also cleans up the api marginally, and fixes 'select next thread' so it works if sorting is turned on, rather than running off the raw unsorted model data.  Which i'm susprised has never been reported - i guess nobody much uses it anyway.  it seems rather pointless to me.

--
Michael Zucchi <notzed ximian com>
"born to die, live to work, it's all downhill from here"
Novell's Evolution and Free Software Developer
Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.3420
diff -u -3 -r1.3420 ChangeLog
--- mail/ChangeLog	26 Jul 2004 06:41:39 -0000	1.3420
+++ mail/ChangeLog	27 Jul 2004 08:17:35 -0000
@@ -1,3 +1,25 @@
+2004-07-27  Not Zed  <NotZed Ximian com>
+
+	** See #57972.
+
+	* message-list.c (search_func): removed.
+	(ml_search_path): new function to just search, not actually change
+	the cursor like e_tree_find does.
+	(message_list_can_select): new function, returns true if the
+	selection specified is possible without changing the selection.
+	(message_list_select): rewritten.
+	(select_path): helper to select a path in a way that 'works
+	reliably'.
+	(message_list_select_next_thread): rewritten to use the
+	table-adapter, so it properly handles arbitrary sorting.
+
+	* em-folder-view.c (em_folder_view_get_popup_target): setup
+	next/prev flags as appropriate.
+	(emfv_enable_map[]): setup next/prev flags.
+
+	* em-folder-view.h: added last and first message status bits to
+	folder view select mask.
+
 2004-07-22  Not Zed  <NotZed Ximian com>
 
 	* mail-component.c (impl_createControls): dont call
Index: mail/em-folder-view.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-folder-view.c,v
retrieving revision 1.83
diff -u -3 -r1.83 em-folder-view.c
--- mail/em-folder-view.c	26 Jul 2004 06:33:23 -0000	1.83
+++ mail/em-folder-view.c	27 Jul 2004 08:17:37 -0000
@@ -724,7 +724,7 @@
 				     CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN,
 				     CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);
 	if (uids->len == 1)
-		message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0, FALSE);
+		message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
 
 	message_list_free_uids(emfv->list, uids);
 }
@@ -739,7 +739,7 @@
 				     CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN,
 				     CAMEL_MESSAGE_JUNK_LEARN);
 	if (uids->len == 1)
-		message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0, FALSE);
+		message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
 
 	message_list_free_uids(emfv->list, uids);
 }
@@ -753,8 +753,8 @@
 	em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED);
 	
 	if (uids->len == 1) {
-		if (!message_list_select (emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0, FALSE) && emfv->hide_deleted)
-			message_list_select (emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0, FALSE);
+		if (!message_list_select (emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0) && emfv->hide_deleted)
+			message_list_select (emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
 	}
 	em_utils_uids_free(uids);
 }
@@ -1110,7 +1110,7 @@
 {
 	EMFolderView *emfv = data;
 
-	message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0, FALSE);
+	message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
 }
 
 static void
@@ -1118,7 +1118,7 @@
 {
 	EMFolderView *emfv = data;
 	
-	message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED, TRUE);
+	message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
 }
 
 static void
@@ -1126,7 +1126,7 @@
 {
 	EMFolderView *emfv = data;
 
-	message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN, TRUE);
+	message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
 }
 
 static void
@@ -1142,7 +1142,7 @@
 {
 	EMFolderView *emfv = data;
 
-	message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0, FALSE);
+	message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
 }
 
 static void
@@ -1150,7 +1150,7 @@
 {
 	EMFolderView *emfv = data;
 
-	message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED, TRUE);
+	message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
 }
 
 static void
@@ -1158,7 +1158,7 @@
 {
 	EMFolderView *emfv = data;
 
-	message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, CAMEL_MESSAGE_SEEN, TRUE);
+	message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
 }
 
 static void
@@ -1549,11 +1549,11 @@
 	{ "EditPaste",                EM_POPUP_SELECT_FOLDER },
 
 	/* FIXME: should these be single-selection? */
-	{ "MailNext",                 EM_POPUP_SELECT_MANY },
+	{ "MailNext",                 EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_NEXT_MSG },
 	{ "MailNextFlagged",          EM_POPUP_SELECT_MANY },
 	{ "MailNextUnread",           EM_POPUP_SELECT_MANY },
 	{ "MailNextThread",           EM_POPUP_SELECT_MANY },
-	{ "MailPrevious",             EM_POPUP_SELECT_MANY },
+	{ "MailPrevious",             EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_PREV_MSG },
 	{ "MailPreviousFlagged",      EM_POPUP_SELECT_MANY },
 	{ "MailPreviousUnread",       EM_POPUP_SELECT_MANY },
 
@@ -1869,6 +1869,12 @@
 
 	if (message_list_hidden(emfv->list) != 0)
 		t->mask &= ~EM_FOLDER_VIEW_SELECT_HIDDEN;
+
+	if (message_list_can_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0))
+		t->mask &= ~EM_FOLDER_VIEW_SELECT_NEXT_MSG;
+
+	if (message_list_can_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0))
+		t->mask &= ~EM_FOLDER_VIEW_SELECT_PREV_MSG;
 
 	/* See bug #54770 */
 	if (!emfv->hide_deleted)
Index: mail/em-folder-view.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-folder-view.h,v
retrieving revision 1.12
diff -u -3 -r1.12 em-folder-view.h
--- mail/em-folder-view.h	10 May 2004 05:24:10 -0000	1.12
+++ mail/em-folder-view.h	27 Jul 2004 08:17:38 -0000
@@ -47,7 +47,9 @@
 enum {
 	EM_FOLDER_VIEW_SELECT_THREADED = EM_POPUP_SELECT_LAST,
 	EM_FOLDER_VIEW_SELECT_HIDDEN = EM_POPUP_SELECT_LAST<<1,
-	EM_FOLDER_VIEW_SELECT_LAST = EM_POPUP_SELECT_LAST<<2,
+	EM_FOLDER_VIEW_SELECT_NEXT_MSG = EM_POPUP_SELECT_LAST<<2,
+	EM_FOLDER_VIEW_SELECT_PREV_MSG = EM_POPUP_SELECT_LAST<<3,
+	EM_FOLDER_VIEW_SELECT_LAST = EM_POPUP_SELECT_LAST<<4,
 };
 
 struct _EMFolderViewEnable {
Index: mail/message-list.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/message-list.c,v
retrieving revision 1.395
diff -u -3 -r1.395 message-list.c
--- mail/message-list.c	23 Jul 2004 03:49:22 -0000	1.395
+++ mail/message-list.c	27 Jul 2004 08:17:40 -0000
@@ -461,32 +461,6 @@
 	return e_poolv_get (poolv, index);
 }
 
-struct search_func_data {
-	MessageList *message_list;
-	guint32 flags;
-	guint32 mask;
-	ETreePath path;
-};
-
-static gboolean
-search_func (ETreeModel *model, ETreePath path, struct search_func_data *data)
-{
-	CamelMessageInfo *info;
-
-	if (e_tree_model_node_is_root (data->message_list->model, path))
-		return FALSE;
-
-	info = get_message_info (data->message_list, path);
-	
-	if (info && (info->flags & data->mask) == data->flags) {
-		g_free(data->message_list->cursor_uid);
-		data->message_list->cursor_uid = NULL;
-		data->path = path;
-		return TRUE;
-	}
-	return FALSE;
-}
-
 static void
 clear_selection(MessageList *ml, struct _MLSelection *selection)
 {
@@ -502,6 +476,88 @@
 	selection->folder_uri = NULL;
 }
 
+static ETreePath
+ml_search_forward(MessageList *ml, int start, int end, guint32 flags, guint32 mask)
+{
+	ETreePath path;
+	int row;
+	CamelMessageInfo *info;
+	ETreeTableAdapter *etta = e_tree_get_table_adapter(ml->tree);
+
+	for (row = start; row <= end; row ++) {
+		path = e_tree_table_adapter_node_at_row(etta, row);
+		if (path
+		    && (info = get_message_info(ml, path))
+		    && (info->flags & mask) == flags)
+			return path;
+	}
+
+	return NULL;
+}
+
+static ETreePath
+ml_search_backward(MessageList *ml, int start, int end, guint32 flags, guint32 mask)
+{
+	ETreePath path;
+	int row;
+	CamelMessageInfo *info;
+	ETreeTableAdapter *etta = e_tree_get_table_adapter(ml->tree);
+
+	for (row = start; row >= end; row --) {
+		path = e_tree_table_adapter_node_at_row(etta, row);
+		if (path
+		    && (info = get_message_info(ml, path))
+		    && (info->flags & mask) == flags)
+			return path;
+	}
+
+	return NULL;
+}
+
+static ETreePath
+ml_search_path(MessageList *ml, MessageListSelectDirection direction, guint32 flags, guint32 mask)
+{
+	ETreePath node;
+	int row, count;
+	ETreeTableAdapter *etta = e_tree_get_table_adapter(ml->tree);
+
+	if (ml->cursor_uid == NULL
+	    || (node = g_hash_table_lookup(ml->uid_nodemap, ml->cursor_uid)) == NULL)
+		return NULL;
+
+	row = e_tree_table_adapter_row_of_node(etta, node);
+	if (row == -1)
+		return NULL;
+	count = e_table_model_row_count((ETableModel *)etta);
+
+	if ((direction & MESSAGE_LIST_SELECT_DIRECTION) == MESSAGE_LIST_SELECT_NEXT)
+		node = ml_search_forward(ml, row + 1, count - 1, flags, mask);
+	else
+		node = ml_search_backward(ml, row-1, 0, flags, mask);
+
+	if (node == NULL && (direction & MESSAGE_LIST_SELECT_WRAP)) {
+		if ((direction & MESSAGE_LIST_SELECT_DIRECTION) == MESSAGE_LIST_SELECT_NEXT)
+			node = ml_search_forward(ml, 0, row, flags, mask);
+		else
+			node = ml_search_backward(ml, count-1, row, flags, mask);
+	}
+
+	return node;
+}
+
+static void
+select_path(MessageList *ml, ETreePath path)
+{
+	ETreeSelectionModel *etsm = (ETreeSelectionModel *)e_tree_get_selection_model(ml->tree);
+
+	g_free(ml->cursor_uid);
+	ml->cursor_uid = NULL;
+
+	e_tree_table_adapter_show_node(e_tree_get_table_adapter(ml->tree), path);
+	e_tree_set_cursor(ml->tree, path);
+	e_tree_selection_model_select_single_path(etsm, path);
+}
+
 /**
  * message_list_select:
  * @message_list: a MessageList
@@ -509,8 +565,6 @@
  * @direction: the direction to search in
  * @flags: a set of flag values
  * @mask: a mask for comparing against @flags
- * @wraparound: if %TRUE, go back to the beginning for 
- *     the next match if necessary.
  *
  * This moves the message list selection to a suitable row. @base_row
  * lists the first (model) row to try, but as a special case, model
@@ -518,43 +572,43 @@
  * what constitutes a suitable row. @direction is
  * %MESSAGE_LIST_SELECT_NEXT if it should find the next matching
  * message, or %MESSAGE_LIST_SELECT_PREVIOUS if it should find the
- * previous. If no suitable row is found, the selection will be
+ * previous. %MESSAGE_LIST_SELECT_WRAP is an option bit which specifies the
+ * search should wrap.
+ *
+ * If no suitable row is found, the selection will be
  * unchanged.
  *
  * Returns %TRUE if a new message has been selected or %FALSE otherwise.
  **/
 gboolean
-message_list_select (MessageList               *message_list,
-		     MessageListSelectDirection direction,
-		     guint32                    flags,
-		     guint32                    mask,
-		     gboolean                   wraparound)
+message_list_select(MessageList *ml, MessageListSelectDirection direction, guint32 flags, guint32 mask)
 {
-	struct search_func_data data;
-	ETreeFindNextParams params = 0;
-	
-	data.message_list = message_list;
-	data.flags = flags;
-	data.mask = mask;
-	data.path = NULL;
-
-	if (direction == MESSAGE_LIST_SELECT_NEXT)
-		params |= E_TREE_FIND_NEXT_FORWARD;
-	else
-		params |= E_TREE_FIND_NEXT_BACKWARD;
-	
-	if (wraparound)
-		params |= E_TREE_FIND_NEXT_WRAP;
-	
-	if (e_tree_find_next (message_list->tree, params, (ETreePathFunc) search_func, &data)) {
-		ETreeSelectionModel *etsm = (ETreeSelectionModel *)e_tree_get_selection_model (message_list->tree);
+	ETreePath path;
 
-		e_tree_selection_model_select_single_path(etsm, data.path);
+	path = ml_search_path(ml, direction, flags, mask);
+	if (path) {
+		select_path(ml, path);
 		return TRUE;
 	} else
 		return FALSE;
 }
 
+/**
+ * message_list_can_select:
+ * @ml: 
+ * @direction: 
+ * @flags: 
+ * @mask: 
+ * 
+ * Returns true if the selection specified is possible with the current view.
+ * 
+ * Return value: 
+ **/
+gboolean
+message_list_can_select(MessageList *ml, MessageListSelectDirection direction, guint32 flags, guint32 mask)
+{
+	return ml_search_path(ml, direction, flags, mask) != NULL;
+}
 
 /**
  * message_list_select_uid:
@@ -591,39 +645,32 @@
 	}
 }
 
-
 void
-message_list_select_next_thread (MessageList *message_list)
+message_list_select_next_thread (MessageList *ml)
 {
-	ETreePath node, last;
-	
-	if (!message_list->cursor_uid)
+	ETreePath node;
+	ETreeTableAdapter *etta = e_tree_get_table_adapter(ml->tree);
+	int i, count, row;
+
+	if (!ml->cursor_uid
+	    || (node = g_hash_table_lookup(ml->uid_nodemap, ml->cursor_uid)) == NULL)
 		return;
-	
-	/* get the thread parent node */
-	last = node = g_hash_table_lookup (message_list->uid_nodemap, message_list->cursor_uid);
-	while (!e_tree_model_node_is_root (message_list->model, node)) {
-		last = node;
-		node = e_tree_model_node_get_parent (message_list->model, node);
-	}
-	
-	/* get the next toplevel node */
-	node = e_tree_model_node_get_next (message_list->model, last);
-	
-	if (node) {
-		CamelMessageInfo *info;
-		
-		info = get_message_info (message_list, node);
-		e_tree_set_cursor (message_list->tree, node);
-		
-		g_free (message_list->cursor_uid);
-		message_list->cursor_uid = g_strdup (camel_message_info_uid (info));
-		
-		g_signal_emit (GTK_OBJECT (message_list), message_list_signals[MESSAGE_SELECTED], 0,
-			       camel_message_info_uid (info));
+
+	row = e_tree_table_adapter_row_of_node(etta, node);
+	if (row == -1)
+		return;
+	count = e_table_model_row_count((ETableModel *)etta);
+
+	/* find the next node which has a root parent (i.e. toplevel node) */
+	for (i=row+1;i<count-1;i++) {
+		node = e_tree_table_adapter_node_at_row(etta, i);
+		if (node
+		    && e_tree_model_node_is_root(ml->model, e_tree_model_node_get_parent(ml->model, node))) {
+			select_path(ml, node);
+			return;
+		}
 	}
 }
-
 
 /**
  * message_list_select_all:
Index: mail/message-list.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/message-list.h,v
retrieving revision 1.84
diff -u -3 -r1.84 message-list.h
--- mail/message-list.h	21 May 2004 09:10:00 -0000	1.84
+++ mail/message-list.h	27 Jul 2004 08:17:40 -0000
@@ -165,8 +165,10 @@
 					gpointer user_data);
 
 typedef enum {
-	MESSAGE_LIST_SELECT_NEXT = 1,
-	MESSAGE_LIST_SELECT_PREVIOUS = -1
+	MESSAGE_LIST_SELECT_NEXT = 0,
+	MESSAGE_LIST_SELECT_PREVIOUS = 1,
+	MESSAGE_LIST_SELECT_DIRECTION = 1, /* direction mask */
+	MESSAGE_LIST_SELECT_WRAP = 1<<1, /* option bit */
 } MessageListSelectDirection;
 
 GtkType        message_list_get_type   (void);
@@ -188,8 +190,8 @@
 gboolean       message_list_select     (MessageList *message_list,
 					MessageListSelectDirection direction,
 					guint32 flags,
-					guint32 mask,
-					gboolean wraparound);
+					guint32 mask);
+gboolean message_list_can_select(MessageList *ml, MessageListSelectDirection direction, guint32 flags, guint32 mask);
 
 void           message_list_select_uid (MessageList *message_list,
 					const char *uid);


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