Blame SOURCES/evolution-3.8.5-message-list-select-with-collapsed-threads.patch

7c6d83
diff -up evolution-3.8.5/e-util/e-table-item.c.message-list-select-with-collapsed-threads evolution-3.8.5/e-util/e-table-item.c
7c6d83
--- evolution-3.8.5/e-util/e-table-item.c.message-list-select-with-collapsed-threads	2014-08-25 19:05:29.946290850 +0200
7c6d83
+++ evolution-3.8.5/e-util/e-table-item.c	2014-08-25 19:05:29.995290548 +0200
7c6d83
@@ -1179,6 +1179,24 @@ eti_unfreeze (ETableItem *eti)
7c6d83
 	}
7c6d83
 }
7c6d83
 
7c6d83
+void
7c6d83
+e_table_item_freeze (ETableItem *eti)
7c6d83
+{
7c6d83
+	if (!eti)
7c6d83
+		return;
7c6d83
+
7c6d83
+	eti_freeze (eti);
7c6d83
+}
7c6d83
+
7c6d83
+void
7c6d83
+e_table_item_thaw (ETableItem *eti)
7c6d83
+{
7c6d83
+	if (!eti)
7c6d83
+		return;
7c6d83
+
7c6d83
+	eti_unfreeze (eti);
7c6d83
+}
7c6d83
+
7c6d83
 /*
7c6d83
  * Callback routine: invoked before the ETableModel suffers a change
7c6d83
  */
7c6d83
diff -up evolution-3.8.5/e-util/e-table-item.h.message-list-select-with-collapsed-threads evolution-3.8.5/e-util/e-table-item.h
7c6d83
--- evolution-3.8.5/e-util/e-table-item.h.message-list-select-with-collapsed-threads	2013-08-03 15:22:52.000000000 +0200
7c6d83
+++ evolution-3.8.5/e-util/e-table-item.h	2014-08-25 19:05:29.995290548 +0200
7c6d83
@@ -260,6 +260,9 @@ gboolean	e_table_item_is_editing		(ETabl
7c6d83
 
7c6d83
 void		e_table_item_cursor_scrolled	(ETableItem *eti);
7c6d83
 
7c6d83
+void		e_table_item_freeze		(ETableItem *eti);
7c6d83
+void		e_table_item_thaw		(ETableItem *eti);
7c6d83
+
7c6d83
 G_END_DECLS
7c6d83
 
7c6d83
 #endif /* _E_TABLE_ITEM_H_ */
7c6d83
diff -up evolution-3.8.5/mail/message-list.c.message-list-select-with-collapsed-threads evolution-3.8.5/mail/message-list.c
7c6d83
--- evolution-3.8.5/mail/message-list.c.message-list-select-with-collapsed-threads	2014-08-25 19:05:29.959290770 +0200
7c6d83
+++ evolution-3.8.5/mail/message-list.c	2014-08-25 19:05:29.996290542 +0200
7c6d83
@@ -3224,10 +3224,6 @@ build_tree (MessageList *ml,
7c6d83
 #ifndef BROKEN_ETREE
7c6d83
 	ETreePath *top;
7c6d83
 #endif
7c6d83
-	gchar *saveuid = NULL;
7c6d83
-#ifdef BROKEN_ETREE
7c6d83
-	GPtrArray *selected;
7c6d83
-#endif
7c6d83
 #ifdef TIMEIT
7c6d83
 	struct timeval start, end;
7c6d83
 	gulong diff;
7c6d83
@@ -3247,35 +3243,19 @@ build_tree (MessageList *ml,
7c6d83
 		ml->tree_root =	e_tree_memory_node_insert (E_TREE_MEMORY (etm), NULL, 0, NULL);
7c6d83
 	}
7c6d83
 
7c6d83
-	if (ml->cursor_uid)
7c6d83
-		saveuid = find_next_selectable (ml);
7c6d83
-
7c6d83
 #ifndef BROKEN_ETREE
7c6d83
 	top = e_tree_model_node_get_first_child (etm, ml->tree_root);
7c6d83
 	if (top == NULL || changes == NULL) {
7c6d83
-#else
7c6d83
-		selected = message_list_get_selected (ml);
7c6d83
 #endif
7c6d83
+		if (table_item)
7c6d83
+			e_table_item_freeze (table_item);
7c6d83
+
7c6d83
 		e_tree_memory_freeze (E_TREE_MEMORY (etm));
7c6d83
 		clear_tree (ml, FALSE);
7c6d83
 
7c6d83
 		build_subtree (ml, ml->tree_root, thread->tree, &row;;
7c6d83
 
7c6d83
-		if (!can_scroll_to_cursor && table_item)
7c6d83
-			table_item->queue_show_cursor = FALSE;
7c6d83
-
7c6d83
-		e_tree_memory_thaw (E_TREE_MEMORY (etm));
7c6d83
 #ifdef BROKEN_ETREE
7c6d83
-
7c6d83
-		/* it's required to thaw & freeze, to propagate changes */
7c6d83
-		e_tree_memory_freeze (E_TREE_MEMORY (etm));
7c6d83
-
7c6d83
-		message_list_set_selected (ml, selected);
7c6d83
-		em_utils_uids_free (selected);
7c6d83
-
7c6d83
-		if (!can_scroll_to_cursor && table_item)
7c6d83
-			table_item->queue_show_cursor = FALSE;
7c6d83
-
7c6d83
 		e_tree_memory_thaw (E_TREE_MEMORY (etm));
7c6d83
 #else
7c6d83
 	} else {
7c6d83
@@ -3286,42 +3266,13 @@ build_tree (MessageList *ml,
7c6d83
 		tree_equal (ml->model, top, thread->tree);
7c6d83
 	}
7c6d83
 #endif
7c6d83
-	if (!saveuid && ml->cursor_uid && g_hash_table_lookup (ml->uid_nodemap, ml->cursor_uid)) {
7c6d83
-		/* this makes sure a visible node is selected, like when
7c6d83
-		 * collapsing all nodes and a children had been selected
7c6d83
-		*/
7c6d83
-		saveuid = g_strdup (ml->cursor_uid);
7c6d83
-	}
7c6d83
-
7c6d83
-	if (saveuid) {
7c6d83
-		ETreePath node = g_hash_table_lookup (ml->uid_nodemap, saveuid);
7c6d83
-		if (node == NULL) {
7c6d83
-			g_free (ml->cursor_uid);
7c6d83
-			ml->cursor_uid = NULL;
7c6d83
-			g_signal_emit (ml, message_list_signals[MESSAGE_SELECTED], 0, NULL);
7c6d83
-		} else {
7c6d83
-			ETree *tree = E_TREE (ml);
7c6d83
-			ETreePath parent = node;
7c6d83
-
7c6d83
-			while (parent = e_tree_model_node_get_parent (etm, parent), parent) {
7c6d83
-				if (!e_tree_node_is_expanded (tree, parent))
7c6d83
-					node = parent;
7c6d83
-			}
7c6d83
-
7c6d83
-			e_tree_memory_freeze (E_TREE_MEMORY (etm));
7c6d83
 
7c6d83
-			e_tree_set_cursor (E_TREE (ml), node);
7c6d83
-
7c6d83
-			if (!can_scroll_to_cursor && table_item)
7c6d83
-				table_item->queue_show_cursor = FALSE;
7c6d83
-
7c6d83
-			e_tree_memory_thaw (E_TREE_MEMORY (etm));
7c6d83
-		}
7c6d83
-		g_free (saveuid);
7c6d83
-	} else if (ml->cursor_uid && !g_hash_table_lookup (ml->uid_nodemap, ml->cursor_uid)) {
7c6d83
-		g_free (ml->cursor_uid);
7c6d83
-		ml->cursor_uid = NULL;
7c6d83
-		g_signal_emit (ml, message_list_signals[MESSAGE_SELECTED], 0, NULL);
7c6d83
+	if (table_item) {
7c6d83
+		/* Show the cursor unless we're responding to a
7c6d83
+		 * "folder-changed" signal from our CamelFolder. */
7c6d83
+		if (!can_scroll_to_cursor)
7c6d83
+			table_item->queue_show_cursor = FALSE;
7c6d83
+		e_table_item_thaw (table_item);
7c6d83
 	}
7c6d83
 
7c6d83
 #ifdef TIMEIT
7c6d83
@@ -4863,6 +4814,9 @@ regen_list_done (struct _regen_list_msg
7c6d83
 	searching = m->ml->search && *m->ml->search;
7c6d83
 
7c6d83
 	if (m->dotree) {
7c6d83
+		ETableItem *table_item = e_tree_get_item (E_TREE (m->ml));
7c6d83
+		GPtrArray *selected;
7c6d83
+		gchar *saveuid = NULL;
7c6d83
 		gboolean forcing_expand_state = m->ml->expand_all || m->ml->collapse_all;
7c6d83
 
7c6d83
 		if (m->ml->just_set_folder) {
7c6d83
@@ -4877,6 +4831,11 @@ regen_list_done (struct _regen_list_msg
7c6d83
 		if (forcing_expand_state || searching)
7c6d83
 			e_tree_force_expanded_state (tree, (m->ml->expand_all || searching) ? 1 : -1);
7c6d83
 
7c6d83
+		if (m->ml->cursor_uid != NULL)
7c6d83
+			saveuid = find_next_selectable (m->ml);
7c6d83
+
7c6d83
+		selected = message_list_get_selected (m->ml);
7c6d83
+
7c6d83
 		build_tree (m->ml, m->tree, m->changes, m->scroll_to_cursor);
7c6d83
 		if (m->ml->thread_tree)
7c6d83
 			camel_folder_thread_messages_unref (m->ml->thread_tree);
7c6d83
@@ -4893,6 +4852,67 @@ regen_list_done (struct _regen_list_msg
7c6d83
 
7c6d83
 		m->ml->expand_all = 0;
7c6d83
 		m->ml->collapse_all = 0;
7c6d83
+
7c6d83
+		/* restore cursor position only after the expand state is restored,
7c6d83
+		   thus the row numbers will actually match their real rows in UI */
7c6d83
+
7c6d83
+		e_table_item_freeze (table_item);
7c6d83
+
7c6d83
+		message_list_set_selected (m->ml, selected);
7c6d83
+		g_ptr_array_unref (selected);
7c6d83
+
7c6d83
+		/* Show the cursor unless we're responding to a
7c6d83
+		 * "folder-changed" signal from our CamelFolder. */
7c6d83
+		if (!m->scroll_to_cursor && table_item != NULL)
7c6d83
+			table_item->queue_show_cursor = FALSE;
7c6d83
+
7c6d83
+		e_table_item_thaw (table_item);
7c6d83
+
7c6d83
+		if (!saveuid && m->ml->cursor_uid && g_hash_table_lookup (m->ml->uid_nodemap, m->ml->cursor_uid)) {
7c6d83
+			/* this makes sure a visible node is selected, like when
7c6d83
+			 * collapsing all nodes and a children had been selected
7c6d83
+			*/
7c6d83
+			saveuid = g_strdup (m->ml->cursor_uid);
7c6d83
+		}
7c6d83
+
7c6d83
+		if (saveuid) {
7c6d83
+			ETreePath node;
7c6d83
+
7c6d83
+			node = g_hash_table_lookup (m->ml->uid_nodemap, saveuid);
7c6d83
+			if (node == NULL) {
7c6d83
+				g_free (m->ml->cursor_uid);
7c6d83
+				m->ml->cursor_uid = NULL;
7c6d83
+				g_signal_emit (m->ml, message_list_signals[MESSAGE_SELECTED], 0, NULL);
7c6d83
+
7c6d83
+			} else {
7c6d83
+				ETree *tree = E_TREE (m->ml);
7c6d83
+				ETreeModel *etm = m->ml->model;
7c6d83
+				ETreePath parent = node;
7c6d83
+
7c6d83
+				while (parent = e_tree_model_node_get_parent (etm, parent), parent) {
7c6d83
+					if (!e_tree_node_is_expanded (tree, parent))
7c6d83
+						node = parent;
7c6d83
+				}
7c6d83
+
7c6d83
+				e_table_item_freeze (table_item);
7c6d83
+
7c6d83
+				e_tree_set_cursor (E_TREE (m->ml), node);
7c6d83
+
7c6d83
+				/* Show the cursor unless we're responding to a
7c6d83
+				 * "folder-changed" signal from our CamelFolder. */
7c6d83
+				if (!m->scroll_to_cursor && table_item != NULL)
7c6d83
+					table_item->queue_show_cursor = FALSE;
7c6d83
+
7c6d83
+				e_table_item_thaw (table_item);
7c6d83
+			}
7c6d83
+			g_free (saveuid);
7c6d83
+		} else if (m->ml->cursor_uid && !g_hash_table_lookup (m->ml->uid_nodemap, m->ml->cursor_uid)) {
7c6d83
+			g_free (m->ml->cursor_uid);
7c6d83
+			m->ml->cursor_uid = NULL;
7c6d83
+			g_signal_emit (
7c6d83
+				m->ml,
7c6d83
+				message_list_signals[MESSAGE_SELECTED], 0, NULL);
7c6d83
+		}
7c6d83
 	} else
7c6d83
 		build_flat (m->ml, m->summary, m->changes);
7c6d83