[gtk+/filesystemmodel: 12/28] implement GtkTreeSortable in the filesystem model



commit a7c5df35f07c1a7519aec7c101153140933f9d80
Author: Benjamin Otte <otte gnome org>
Date:   Sun Jun 21 18:24:25 2009 +0200

    implement GtkTreeSortable in the filesystem model
    
    It only implements the interface, but doesn't do anything useful with it
    yet.
    Now that all features are cut, performance is fine. I only need to add
    the features back, most importantly:
    - sorting
    - displaying icons

 gtk/gtkfilechooserdefault.c |   95 ++++++++++--------------------
 gtk/gtkfilechooserprivate.h |    2 -
 gtk/gtkfilesystemmodel.c    |  140 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+), 66 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 8ee66da..fc8f889 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -872,14 +872,11 @@ store_selection_foreach (GtkTreeModel *model,
 			 gpointer      data)
 {
   GtkFileChooserDefault *impl;
-  GtkTreeIter child_iter;
   GFile *file;
 
   impl = GTK_FILE_CHOOSER_DEFAULT (data);
 
-  gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, iter);
-
-  file = _gtk_file_system_model_get_file (impl->browse_files_model, &child_iter);
+  file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (model), iter);
   pending_select_files_add (impl, file);
 }
 
@@ -943,9 +940,6 @@ gtk_file_chooser_default_finalize (GObject *object)
   if (impl->browse_files_model)
     g_object_unref (impl->browse_files_model);
 
-  if (impl->sort_model)
-    g_object_unref (impl->sort_model);
-
   search_clear_model (impl, FALSE);
   recent_clear_model (impl, FALSE);
 
@@ -5875,6 +5869,9 @@ set_sort_column (GtkFileChooserDefault *impl)
   GtkTreeSortable *sortable;
 
   sortable = GTK_TREE_SORTABLE (gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view)));
+  /* can happen when we're still populating the model */
+  if (sortable == NULL)
+    return;
 
   gtk_tree_sortable_set_sort_column_id (sortable,
                                         impl->sort_column,
@@ -6226,27 +6223,12 @@ load_set_model (GtkFileChooserDefault *impl)
   profile_start ("start", NULL);
 
   g_assert (impl->browse_files_model != NULL);
-  g_assert (impl->sort_model == NULL);
-
-  profile_msg ("    gtk_tree_model_sort_new_with_model start", NULL);
-  impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->browse_files_model));
-  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), MODEL_COL_NAME, name_sort_func, impl, NULL);
-  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), MODEL_COL_SIZE, size_sort_func, impl, NULL);
-  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), MODEL_COL_MTIME, mtime_sort_func, impl, NULL);
-  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->sort_model), NULL, NULL, NULL);
-  set_sort_column (impl);
-  impl->list_sort_ascending = TRUE;
-  profile_msg ("    gtk_tree_model_sort_new_with_model end", NULL);
-
-  g_signal_connect (impl->sort_model, "sort-column-changed",
-		    G_CALLBACK (list_sort_column_changed_cb), impl);
 
   profile_msg ("    gtk_tree_view_set_model start", NULL);
   gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
-			   GTK_TREE_MODEL (impl->sort_model));
+			   GTK_TREE_MODEL (impl->browse_files_model));
   gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view));
-  gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view),
-				   MODEL_COL_NAME);
+  set_sort_column (impl);
   profile_msg ("    gtk_tree_view_set_model end", NULL);
 
   profile_end ("end", NULL);
@@ -6312,12 +6294,12 @@ browse_files_select_first_row (GtkFileChooserDefault *impl)
   GtkTreeIter dummy_iter;
   GtkTreeModel *tree_model;
 
-  if (!impl->sort_model)
-    return;
-
   path = gtk_tree_path_new_from_indices (0, -1);
   tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view));
 
+  if (!tree_model)
+    return;
+
   /* If the list is empty, do nothing. */
   if (gtk_tree_model_get_iter (tree_model, &dummy_iter, path))
       gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, FALSE);
@@ -6419,7 +6401,7 @@ show_and_select_files_finished_loading (GtkFolder *folder,
   for (l = data->files; l; l = l->next)
     {
       GtkTreeSelection *selection;
-      GtkTreeIter iter, sorted_iter;
+      GtkTreeIter iter;
 
       if (!_gtk_file_system_model_get_iter_for_file (data->impl->browse_files_model, 
                                                      &iter,
@@ -6427,8 +6409,7 @@ show_and_select_files_finished_loading (GtkFolder *folder,
         continue;
       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->impl->browse_files_tree_view));
 
-      gtk_tree_model_sort_convert_child_iter_to_iter (data->impl->sort_model, &sorted_iter, &iter);
-      gtk_tree_selection_select_iter (selection, &sorted_iter);
+      gtk_tree_selection_select_iter (selection, &iter);
     }
 
   browse_files_center_selected_row (data->impl);
@@ -6515,7 +6496,6 @@ pending_select_files_process (GtkFileChooserDefault *impl)
 {
   g_assert (impl->load_state == LOAD_FINISHED);
   g_assert (impl->browse_files_model != NULL);
-  g_assert (impl->sort_model != NULL);
 
   if (impl->pending_select_files)
     {
@@ -6590,12 +6570,6 @@ stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
       impl->browse_files_model = NULL;
     }
 
-  if (impl->sort_model)
-    {
-      g_object_unref (impl->sort_model);
-      impl->sort_model = NULL;
-    }
-  
   gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
 }
 
@@ -6797,13 +6771,24 @@ set_list_model (GtkFileChooserDefault *impl,
                                                          G_TYPE_STRING,
                                                          G_TYPE_STRING,
                                                          PANGO_TYPE_ELLIPSIZE_MODE);
+
+  _gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden);
+
+  profile_msg ("    set sort function", NULL);
+  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->browse_files_model), MODEL_COL_NAME, name_sort_func, impl, NULL);
+  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->browse_files_model), MODEL_COL_SIZE, size_sort_func, impl, NULL);
+  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->browse_files_model), MODEL_COL_MTIME, mtime_sort_func, impl, NULL);
+  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->browse_files_model), NULL, NULL, NULL);
+  set_sort_column (impl);
+  impl->list_sort_ascending = TRUE;
+  g_signal_connect (impl->browse_files_model, "sort-column-changed",
+		    G_CALLBACK (list_sort_column_changed_cb), impl);
+
   load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */
 
   g_signal_connect (impl->browse_files_model, "finished-loading",
 		    G_CALLBACK (browse_files_model_finished_loading_cb), impl);
 
-  _gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden);
-
   install_list_model_filter (impl);
 
   profile_end ("end", NULL);
@@ -6883,18 +6868,12 @@ update_chooser_entry (GtkFileChooserDefault *impl)
     }
   else if (closure.num_selected == 1)
     {
-      GtkTreeIter child_iter;
-      
       if (impl->operation_mode == OPERATION_MODE_BROWSE)
         {
           GFileInfo *info;
           gboolean change_entry;
 
-          gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
-                                                          &child_iter,
-                                                          &closure.first_selected_iter);
-
-          info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
+          info = _gtk_file_system_model_get_info (impl->browse_files_model, &closure.first_selected_iter);
 
           /* If the cursor moved to the row of the newly created folder, 
            * retrieving info will return NULL.
@@ -7363,7 +7342,7 @@ gtk_file_chooser_default_unselect_file (GtkFileChooser *chooser,
 {
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
   GtkTreeView *tree_view = GTK_TREE_VIEW (impl->browse_files_tree_view);
-  GtkTreeIter iter, sorted_iter;
+  GtkTreeIter iter;
 
   if (!impl->browse_files_model)
     return;
@@ -7373,11 +7352,8 @@ gtk_file_chooser_default_unselect_file (GtkFileChooser *chooser,
                                                  file))
     return;
 
-  gtk_tree_model_sort_convert_child_iter_to_iter (impl->sort_model,
-                                                  &sorted_iter,
-                                                  &iter);
   gtk_tree_selection_unselect_iter (gtk_tree_view_get_selection (tree_view),
-                                    &sorted_iter);
+                                    &iter);
 }
 
 static gboolean
@@ -7421,7 +7397,7 @@ gtk_file_chooser_default_select_all (GtkFileChooser *chooser)
     }
 
   if (impl->select_multiple)
-    gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model), 
+    gtk_tree_model_foreach (GTK_TREE_MODEL (impl->browse_files_model), 
 			    maybe_select, impl);
 }
 
@@ -7537,13 +7513,11 @@ get_files_foreach (GtkTreeModel *model,
   struct get_files_closure *info;
   GFile *file;
   GtkFileSystemModel *fs_model;
-  GtkTreeIter sel_iter;
 
   info = data;
   fs_model = info->impl->browse_files_model;
-  gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter);
 
-  file = _gtk_file_system_model_get_file (fs_model, &sel_iter);
+  file = _gtk_file_system_model_get_file (fs_model, iter);
   if (!file)
     return; /* We are on the editable row */
 
@@ -8089,13 +8063,10 @@ switch_folder_foreach_cb (GtkTreeModel      *model,
 			  gpointer           data)
 {
   struct switch_folder_closure *closure;
-  GtkTreeIter child_iter;
 
   closure = data;
 
-  gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
-
-  closure->file = _gtk_file_system_model_get_file (closure->impl->browse_files_model, &child_iter);
+  closure->file = _gtk_file_system_model_get_file (closure->impl->browse_files_model, iter);
   closure->num_selected++;
 }
 
@@ -8143,11 +8114,7 @@ get_selected_file_info_from_file_list (GtkFileChooserDefault *impl,
 
   *had_selection = TRUE;
 
-  gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
-						  &child_iter,
-						  &iter);
-
-  info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
+  info = _gtk_file_system_model_get_info (impl->browse_files_model, &iter);
   return info;
 }
 
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index d657f62..ecca984 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -232,8 +232,6 @@ struct _GtkFileChooserDefault
    */
   GtkTreeModel *shortcuts_combo_filter_model;
 
-  GtkTreeModelSort *sort_model;
-
   /* Handles */
   GSList *loading_shortcuts;
   GSList *reload_icon_cancellables;
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index bccb826..0e014e8 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -78,6 +78,13 @@ struct _GtkFileSystemModel
   GtkFileSystemModelFilter filter_func; /* filter to use for deciding which nodes are visible */
   gpointer              filter_data;    /* data to pass to filter_func */
 
+  int                   sort_column_id; /* current sorting column */
+  GtkSortType           sort_order;     /* current sorting order */
+  GList *               sort_list;      /* list of sorting functions */
+  GtkTreeIterCompareFunc default_sort_func; /* default sort function */
+  gpointer              default_sort_data; /* data to pass to default sort func */
+  GDestroyNotify        default_sort_destroy; /* function to call to destroy default_sort_data */
+
   guint                 show_hidden :1; /* whether to show hidden files */
   guint                 show_folders :1;/* whether to show folders */
   guint                 show_files :1;  /* whether to show files */
@@ -448,6 +455,131 @@ gtk_file_system_model_iface_init (GtkTreeModelIface *iface)
   iface->unref_node =      gtk_file_system_model_unref_node;
 }
 
+/*** GtkTreeSortable ***/
+
+static void
+gtk_file_system_model_sort (GtkFileSystemModel *model)
+{
+  g_warning ("sort not implemented");
+}
+
+static gboolean
+gtk_file_system_model_get_sort_column_id (GtkTreeSortable  *sortable,
+                                          gint             *sort_column_id,
+                                          GtkSortType      *order)
+{
+  GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (sortable);
+
+  if (sort_column_id)
+    *sort_column_id = model->sort_column_id;
+  if (order)
+    *order = model->sort_order;
+
+  if (model->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
+      model->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+gtk_file_system_model_set_sort_column_id (GtkTreeSortable  *sortable,
+                                          gint              sort_column_id,
+                                          GtkSortType       order)
+{
+  GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (sortable);
+
+  if ((model->sort_column_id == sort_column_id) &&
+      (model->sort_order == order))
+    return;
+
+  if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
+    {
+      if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
+	{
+	  GtkTreeDataSortHeader *header = NULL;
+
+	  header = _gtk_tree_data_list_get_header (model->sort_list, 
+						   sort_column_id);
+
+	  /* We want to make sure that we have a function */
+	  g_return_if_fail (header != NULL);
+	  g_return_if_fail (header->func != NULL);
+	}
+      else
+	{
+	  g_return_if_fail (model->default_sort_func != NULL);
+	}
+    }
+
+
+  model->sort_column_id = sort_column_id;
+  model->sort_order = order;
+
+  gtk_tree_sortable_sort_column_changed (sortable);
+
+  gtk_file_system_model_sort (model);
+}
+
+static void
+gtk_file_system_model_set_sort_func (GtkTreeSortable        *sortable,
+                                     gint                    sort_column_id,
+                                     GtkTreeIterCompareFunc  func,
+                                     gpointer                data,
+                                     GDestroyNotify          destroy)
+{
+  GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (sortable);
+
+  model->sort_list = _gtk_tree_data_list_set_header (model->sort_list, 
+                                                     sort_column_id, 
+                                                     func, data, destroy);
+
+  if (model->sort_column_id == sort_column_id)
+    gtk_file_system_model_sort (model);
+}
+
+static void
+gtk_file_system_model_set_default_sort_func (GtkTreeSortable        *sortable,
+                                             GtkTreeIterCompareFunc  func,
+                                             gpointer                data,
+                                             GDestroyNotify          destroy)
+{
+  GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (sortable);
+
+  if (model->default_sort_destroy)
+    {
+      GDestroyNotify d = model->default_sort_destroy;
+
+      model->default_sort_destroy = NULL;
+      d (model->default_sort_data);
+    }
+
+  model->default_sort_func = func;
+  model->default_sort_data = data;
+  model->default_sort_destroy = destroy;
+
+  if (model->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
+    gtk_file_system_model_sort (model);
+}
+
+static gboolean
+gtk_file_system_model_has_default_sort_func (GtkTreeSortable *sortable)
+{
+  GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (sortable);
+
+  return (model->default_sort_func != NULL);
+}
+
+static void
+gtk_file_system_model_sortable_init (GtkTreeSortableIface *iface)
+{
+  iface->get_sort_column_id = gtk_file_system_model_get_sort_column_id;
+  iface->set_sort_column_id = gtk_file_system_model_set_sort_column_id;
+  iface->set_sort_func = gtk_file_system_model_set_sort_func;
+  iface->set_default_sort_func = gtk_file_system_model_set_default_sort_func;
+  iface->has_default_sort_func = gtk_file_system_model_has_default_sort_func;
+}
+
 /*** GtkTreeDragSource ***/
 
 static gboolean
@@ -511,6 +643,8 @@ static guint file_system_model_signals[LAST_SIGNAL] = { 0 };
 G_DEFINE_TYPE_WITH_CODE (GtkFileSystemModel, _gtk_file_system_model, G_TYPE_OBJECT,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
 						gtk_file_system_model_iface_init)
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
+						gtk_file_system_model_sortable_init)
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
 						drag_source_iface_init))
 
@@ -545,6 +679,10 @@ gtk_file_system_model_finalize (GObject *object)
   g_free (model->attributes);
   g_object_unref (model->dir);
 
+  _gtk_tree_data_list_header_free (model->sort_list);
+  if (model->default_sort_destroy)
+    model->default_sort_destroy (model->default_sort_data);
+
   G_OBJECT_CLASS (_gtk_file_system_model_parent_class)->finalize (object);
 }
 
@@ -708,6 +846,8 @@ gtk_file_system_model_set_n_columns (GtkFileSystemModel *model,
       model->column_types[i] = type;
     }
 
+  model->sort_list = _gtk_tree_data_list_header_new (n_columns, model->column_types);
+
   model->files = g_array_new (FALSE, FALSE, NODE_SIZE (model));
   /* add editable node at start */
   gtk_file_system_model_add_node (model, NULL, NULL);



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