changeset 93:f1c8f8632e23

Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net> * view_file_list.c: Fix slow re-sort when updating list by clearing the list and adding items in the new order instead of simply moving them. Fixes bug #1451200.
author gqview
date Thu, 02 Nov 2006 19:45:18 +0000
parents 3c0eeb66ce1b
children 50dc5a14d37b
files ChangeLog src/view_file_list.c
diffstat 2 files changed, 104 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Nov 02 11:50:51 2006 +0000
+++ b/ChangeLog	Thu Nov 02 19:45:18 2006 +0000
@@ -1,3 +1,9 @@
+Thu Nov  2 14:38:54 2006  John Ellis  <johne@verizon.net>
+
+	* view_file_list.c: Fix slow re-sort when updating list by clearing the
+	list and adding items in the new order instead of simply moving them.
+	Fixes bug #1451200.
+
 Thu Nov  2 06:46:14 2006  John Ellis  <johne@verizon.net>
 
 	* po/eo.po: Add Esperanto translation,
--- a/src/view_file_list.c	Thu Nov 02 11:50:51 2006 +0000
+++ b/src/view_file_list.c	Thu Nov 02 19:45:18 2006 +0000
@@ -734,10 +734,23 @@
  *-----------------------------------------------------------------------------
  */
 
+static gboolean vflist_dummy_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath,
+				        gboolean path_currently_selected, gpointer data)
+{
+	return TRUE;
+}
+
 void vflist_sort_set(ViewFileList *vfl, SortType type, gint ascend)
 {
+	GtkTreeModel *model;
 	GtkListStore *store;
 	GList *work;
+	GtkTreeSelection *selection;
+	GtkTreePath *tpath;
+	GtkTreeIter iter;
+	GList *select_list;
+	FileData *cursor_fd = NULL;
+	gint single_select;
 
 	if (vfl->sort_method == type && vfl->sort_ascend == ascend) return;
 
@@ -748,9 +761,12 @@
 
 	vfl->list = filelist_sort(vfl->list, vfl->sort_method, vfl->sort_ascend);
 
+	/* now reorder the treeview, maintaining current selection */
+
+#if 0
+	/* this is simpler, but much slower */
 	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)));
 
-	/* reorder the treeview, maintaining current selection */
 	work = g_list_last(vfl->list);
 	while (work)
 		{
@@ -765,6 +781,87 @@
 
 		work = work->prev;
 		}
+#endif
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview));
+
+	gtk_tree_selection_set_select_function(selection, vflist_dummy_select_cb, vfl, NULL);
+
+	select_list = gtk_tree_selection_get_selected_rows(selection, &model);
+	work = select_list;
+	while (work)
+		{
+		FileData *fd;
+
+		tpath = work->data;
+		gtk_tree_model_get_iter(model, &iter, tpath);
+		gtk_tree_model_get(model, &iter, FILE_COLUMN_POINTER, &fd, -1);
+		gtk_tree_path_free(tpath);
+
+		work->data = fd;
+		work = work->next;
+		}
+
+	select_list = filelist_sort(select_list, vfl->sort_method, vfl->sort_ascend);
+
+	gtk_tree_view_get_cursor(GTK_TREE_VIEW(vfl->listview), &tpath, NULL);
+	if (tpath)
+		{
+		if (gtk_tree_model_get_iter(model, &iter, tpath))
+			{
+			gtk_tree_model_get(model, &iter, FILE_COLUMN_POINTER, &cursor_fd, -1);
+			}
+		gtk_tree_path_free(tpath);
+		}
+
+	single_select = (select_list && !select_list->next);
+	if (single_select) cursor_fd = select_list->data;
+
+	store = GTK_LIST_STORE(model);
+	gtk_list_store_clear(store);
+
+	work = vfl->list;
+	while (work)
+		{
+		FileData *fd;
+		gchar *size;
+
+		fd = work->data;
+		size = text_from_size(fd->size);
+		gtk_list_store_append(store, &iter);
+		gtk_list_store_set(store, &iter, FILE_COLUMN_POINTER, fd,
+						 FILE_COLUMN_THUMB, (vfl->thumbs_enabled) ? fd->pixbuf : NULL,
+						 FILE_COLUMN_NAME, fd->name,
+						 FILE_COLUMN_SIZE, size,
+						 FILE_COLUMN_DATE, text_from_time(fd->date),
+						 FILE_COLUMN_COLOR, FALSE, -1);
+		g_free(size);
+
+		if (select_list && select_list->data == fd)
+			{
+			select_list = g_list_remove(select_list, fd);
+			gtk_tree_selection_select_iter(selection, &iter);
+			}
+
+		work = work->next;
+		}
+
+	g_list_free(select_list);
+
+	if (cursor_fd &&
+	    vflist_find_row(vfl, cursor_fd, &iter) >= 0)
+		{
+		if (single_select)
+			{
+			vflist_move_cursor(vfl, &iter);
+			}
+		else
+			{
+			tree_view_row_make_visible(GTK_TREE_VIEW(vfl->listview), &iter, TRUE);
+			}
+		}
+
+	gtk_tree_selection_set_select_function(selection, vflist_select_cb, vfl, NULL);
 }
 
 /*