[gtk/wip/otte/listview] Redo the sorting in testlistview



commit 8833158176f72415ae2500dc399583eb6eede8c1
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jan 6 21:25:13 2019 -0500

    Redo the sorting in testlistview
    
    Sort the entire treelistmodel, not individual
    directories. This lets us change sort order and
    (almost) get working persistence for selection.

 tests/testlistview.c | 118 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 70 insertions(+), 48 deletions(-)
---
diff --git a/tests/testlistview.c b/tests/testlistview.c
index e3d3015925..ded00b854c 100644
--- a/tests/testlistview.c
+++ b/tests/testlistview.c
@@ -106,8 +106,6 @@ got_files (GObject      *enumerate,
                                       store);
 }
 
-static gboolean invert_sort;
-
 static int
 compare_files (gconstpointer first,
                gconstpointer second,
@@ -136,9 +134,6 @@ compare_files (gconstpointer first,
 
   result = strcasecmp (first_path, second_path);
 
-  if (invert_sort)
-    result = - result;
-
   g_free (first_path);
   g_free (second_path);
 
@@ -148,7 +143,6 @@ compare_files (gconstpointer first,
 static GListModel *
 create_list_model_for_directory (gpointer file)
 {
-  GtkSortListModel *sort;
   GListStore *store;
 
   if (g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) != G_FILE_TYPE_DIRECTORY)
@@ -160,11 +154,7 @@ create_list_model_for_directory (gpointer file)
   if (!start_enumerate (store))
     return NULL;
 
-  sort = gtk_sort_list_model_new (G_LIST_MODEL (store),
-                                  compare_files,
-                                  NULL, NULL);
-  g_object_unref (store);
-  return G_LIST_MODEL (sort);
+  return G_LIST_MODEL (store);
 }
 
 typedef struct _RowData RowData;
@@ -345,47 +335,75 @@ match_file (gpointer item, gpointer data)
   return result;
 }
 
+static gboolean invert_sort;
+
 static void
-resort_model (GListModel *model)
+toggle_sort (GtkButton *button, GtkSortListModel *sort)
 {
-  if (GTK_IS_SELECTION_MODEL (model))
-    {
-      resort_model (gtk_selection_model_get_model (GTK_SELECTION_MODEL (model)));
-    }
-  else if (GTK_IS_FILTER_LIST_MODEL (model))
-    {
-      resort_model (gtk_filter_list_model_get_model (GTK_FILTER_LIST_MODEL (model)));
-    }
-  else if (GTK_IS_SORT_LIST_MODEL (model))
-    {
-      gtk_sort_list_model_resort (GTK_SORT_LIST_MODEL (model));
-    }
-  else if (GTK_IS_TREE_LIST_MODEL (model))
-    {
-      int i;
+  invert_sort = !invert_sort;
 
-      resort_model (gtk_tree_list_model_get_model (GTK_TREE_LIST_MODEL (model)));
+  gtk_button_set_icon_name (button, invert_sort ? "view-sort-descending" : "view-sort-ascending");
 
-      for (i = 0; i < g_list_model_get_n_items (model); i++)
-        {
-          GtkTreeListRow *row;
-          row = gtk_tree_list_model_get_row (GTK_TREE_LIST_MODEL (model), i);
-          if (gtk_tree_list_row_get_expanded (row))
-            {
-              resort_model (gtk_tree_list_row_get_children (row));
-            }
-        }
-    }
+  gtk_sort_list_model_resort (sort);
 }
 
-static void
-toggle_sort (GtkButton *button, GtkListView *view)
+static int
+sort_tree (gconstpointer a, gconstpointer b, gpointer data)
 {
-  invert_sort = !invert_sort;
+  GtkTreeListRow *ra = (GtkTreeListRow *) a;
+  GtkTreeListRow *rb = (GtkTreeListRow *) b;
+  GtkTreeListRow *pa, *pb;
+  guint da, db;
+  int i;
+  GFile *ia, *ib;
+  int cmp = 0;
+
+  da = gtk_tree_list_row_get_depth (ra);
+  db = gtk_tree_list_row_get_depth (rb);
+
+  if (da > db)
+    for (i = 0; i < da - db; i++)
+      {
+        ra = gtk_tree_list_row_get_parent (ra);
+        if (ra) g_object_unref (ra);
+      }
+  if (db > da)
+    for (i = 0; i < db - da; i++)
+      {
+        rb = gtk_tree_list_row_get_parent (rb);
+        if (rb) g_object_unref (rb);
+      }
+
+  /* now ra and rb are ancestors of a and b at the same depth */
+
+  if (ra == rb)
+    return da - db;
+
+  pa = ra;
+  pb = rb;
+  do {
+    ra = pa;
+    rb = pb;
+    pa = gtk_tree_list_row_get_parent (ra);
+    pb = gtk_tree_list_row_get_parent (rb);
+    if (pa) g_object_unref (pa);
+    if (pb) g_object_unref (pb);
+  } while (pa != pb);
+
+  /* now ra and rb are ancestors of a and b that have a common parent */
+
+  ia = gtk_tree_list_row_get_item (ra);
+  ib = gtk_tree_list_row_get_item (rb);
+
+  cmp = compare_files (ia, ib, NULL);
+
+  g_object_unref (ia);
+  g_object_unref (ib);
 
-  gtk_button_set_icon_name (button, invert_sort ? "view-sort-descending" : "view-sort-ascending");
+  if (invert_sort)
+    cmp = -cmp;
 
-  resort_model (gtk_list_view_get_model (view));
+  return cmp;
 }
 
 int
@@ -396,13 +414,12 @@ main (int argc, char *argv[])
   GListModel *dirmodel;
   GtkTreeListModel *tree;
   GtkFilterListModel *filter;
+  GtkSortListModel *sort;
   GtkSelectionModel *selection;
   GFile *root;
 
   gtk_init ();
 
-  listview = gtk_list_view_new ();
-
   win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size (GTK_WINDOW (win), 400, 600);
   g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), win);
@@ -416,7 +433,6 @@ main (int argc, char *argv[])
   gtk_container_add (GTK_CONTAINER (hbox), search_entry);
   gtk_widget_set_hexpand (search_entry, TRUE);
   button = gtk_button_new_from_icon_name ("view-sort-ascending");
-  g_signal_connect (button, "clicked", G_CALLBACK (toggle_sort), listview);
   gtk_container_add (GTK_CONTAINER (hbox), button);
 
   sw = gtk_scrolled_window_new (NULL, NULL);
@@ -424,6 +440,8 @@ main (int argc, char *argv[])
   gtk_search_entry_set_key_capture_widget (GTK_SEARCH_ENTRY (search_entry), sw);
   gtk_container_add (GTK_CONTAINER (vbox), sw);
 
+  listview = gtk_list_view_new ();
+
   gtk_list_view_set_functions (GTK_LIST_VIEW (listview),
                                setup_widget,
                                NULL,
@@ -443,14 +461,18 @@ main (int argc, char *argv[])
   g_object_unref (dirmodel);
   g_object_unref (root);
 
-  filter = gtk_filter_list_model_new (G_LIST_MODEL (tree),
+  sort = gtk_sort_list_model_new (G_LIST_MODEL (tree), sort_tree, NULL, NULL);
+
+  g_signal_connect (button, "clicked", G_CALLBACK (toggle_sort), sort);
+
+  filter = gtk_filter_list_model_new (G_LIST_MODEL (sort),
                                       match_file,
                                       search_entry,
                                       NULL);
+                                  
   g_signal_connect_swapped (search_entry, "search-changed", G_CALLBACK (gtk_filter_list_model_refilter), 
filter);
   selection = GTK_SELECTION_MODEL (gtk_single_selection_new (G_LIST_MODEL (filter)));
 
-
   gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
 
   statusbar = gtk_statusbar_new ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]