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