[evolution-patches] 57972, mail, sensitivity of next/prev buttons, plus others
- From: Not Zed <notzed ximian com>
- To: evolution-patches lists ximian com
- Subject: [evolution-patches] 57972, mail, sensitivity of next/prev buttons, plus others
- Date: Tue, 27 Jul 2004 08:20:35 +0000
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.
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]