Index: mail/message-list.h
===================================================================
--- mail/message-list.h	(revision 34412)
+++ mail/message-list.h	(working copy)
@@ -132,7 +132,6 @@
 	guint frozen:16;
 
 	/* Where the ETree cursor is. */
-	int cursor_row;
 	char *cursor_uid;
 
 	/* Row-selection and seen-marking timers */
Index: mail/ChangeLog
===================================================================
--- mail/ChangeLog	(revision 34412)
+++ mail/ChangeLog	(working copy)
@@ -1,3 +1,20 @@
+2007-10-23  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #335931
+
+	* message-list.c: (struct _regen_list_msg): New member last_row.
+	* message-list.c: (regen_list_regen): Store last_row for later use.
+	* message-list.c: (regen_list_regened): Restore row based on last_row
+	when no uid was selected before.
+	* message-list.c: (mail_regen_list): Init new last_row member.
+	* em-folder-view.c: (emfv_select_next_message): New helper function
+	to select messages in list.
+	* em-folder-view.c: (emfv_popup_mark_junk), (emfv_popup_mark_nojunk),
+	(emfv_popup_delete): Using new helper function, so get same behavior.
+
+	* message-list.h: (struct _MessageList):
+	* message-list.c: (on_cursor_activated_cmd): Removed cursor_row member.
+
 2007-10-23  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #271734
Index: mail/em-folder-view.c
===================================================================
--- mail/em-folder-view.c	(revision 34412)
+++ mail/em-folder-view.c	(working copy)
@@ -1006,6 +1006,15 @@
 }
 
 static void
+emfv_select_next_message (EMFolderView *emfv, int count, gboolean always_can_previous)
+{
+	if (emfv && count == 1) {
+		if (!message_list_select (emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0) && (emfv->hide_deleted || always_can_previous))
+			message_list_select (emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
+	}
+}
+
+static void
 emfv_popup_mark_junk (EPopup *ep, EPopupItem *pitem, void *data)
 {
 	EMFolderView *emfv = data;
@@ -1014,8 +1023,8 @@
 	count = em_folder_view_mark_selected(emfv,
 					     CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN,
 					     CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);
-	if (count == 1)
-		message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
+
+	emfv_select_next_message (emfv, count, TRUE);
 }
 
 static void
@@ -1027,8 +1036,8 @@
 	count = em_folder_view_mark_selected(emfv,
 					     CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN,
 					     CAMEL_MESSAGE_JUNK_LEARN);
-	if (count == 1)
-		message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
+
+	emfv_select_next_message (emfv, count, TRUE);
 }
 
 static void
@@ -1062,10 +1071,7 @@
 	message_list_free_uids(emfv->list, uids);
 	camel_folder_thaw(emfv->folder);
 
-	if (count == 1) {
-		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);
-	}
+	emfv_select_next_message (emfv, count, FALSE);
 }
 
 static void
Index: mail/message-list.c
===================================================================
--- mail/message-list.c	(revision 34412)
+++ mail/message-list.c	(working copy)
@@ -3231,7 +3231,6 @@
 	    || (message_list->cursor_uid != NULL && new_uid != NULL && !strcmp (message_list->cursor_uid, new_uid)))
 		return;
 	
-	message_list->cursor_row = row;
 	g_free (message_list->cursor_uid);
 	message_list->cursor_uid = g_strdup (new_uid);
 	
@@ -3724,6 +3723,8 @@
 
 	CamelFolder *folder;
 	GPtrArray *summary;
+
+	int last_row; /* last selected (cursor) row */
 };
 
 /*
@@ -3748,11 +3749,16 @@
 	struct _regen_list_msg *m = (struct _regen_list_msg *)mm;
 	GPtrArray *uids, *uidnew, *showuids, *searchuids = NULL;
 	CamelMessageInfo *info;
+	ETreePath cursor;
 	int i;
 	
 	if (m->folder != m->ml->folder)
 		return;
 
+	cursor = e_tree_get_cursor (m->ml->tree);
+	if (cursor)
+		m->last_row = e_tree_table_adapter_row_of_node (e_tree_get_table_adapter (m->ml->tree), cursor);
+	
 	e_profile_event_emit("list.getuids", m->folder->full_name, 0);
 
 	/* if we have hidedeleted on, use a search to find it out, merge with existing search if set */
@@ -3838,10 +3844,22 @@
 		
 		/* first, hide matches */
 		if (m->ml->hidden) {
+			int subtr = 0;
+
 			for (i = 0; i < uids->len; i++) {
 				if (g_hash_table_lookup (m->ml->hidden, uids->pdata[i]) == 0)
 					g_ptr_array_add (uidnew, uids->pdata[i]);
+				else if (m->last_row >= 0) {
+					/* if we are going to hide message above last selected row, then we should
+					   decrease our last row number, to put cursor on a proper place. */
+					ETreePath node = g_hash_table_lookup (m->ml->uid_nodemap, (const char *) uids->pdata[i]);
+
+					if (node && m->last_row > e_tree_table_adapter_row_of_node (e_tree_get_table_adapter (m->ml->tree), node))
+						subtr ++;
+				}
 			}
+
+			m->last_row -= subtr;
 		}
 		
 		/* then calculate the subrange visible and chop it out */
@@ -3960,6 +3978,19 @@
 		m->ml->pending_select_uid = NULL;
 		message_list_select_uid(m->ml, uid);
 		g_free(uid);
+	} else if (m->ml->regen == NULL && m->ml->cursor_uid == NULL && m->last_row != -1) {
+		ETreeTableAdapter *etta = e_tree_get_table_adapter (m->ml->tree);
+
+		if (m->last_row >= e_table_model_row_count (E_TABLE_MODEL (etta)))
+			m->last_row = e_table_model_row_count (E_TABLE_MODEL (etta)) - 1;
+		
+		if (m->last_row >= 0) {
+			ETreePath path;
+
+			path = e_tree_table_adapter_node_at_row (etta, m->last_row);
+			if (path)
+				select_path (m->ml, path);
+		}
 	}
 
 	g_signal_emit (m->ml, message_list_signals[MESSAGE_LIST_BUILT], 0);
@@ -4085,6 +4116,7 @@
 	g_object_ref(ml);
 	m->folder = ml->folder;
 	camel_object_ref(m->folder);
+	m->last_row = -1;
 
 	if ((!m->hidedel || !m->dotree) && ml->thread_tree) {
 		camel_folder_thread_messages_unref(ml->thread_tree);
