[gtk+/filesystemmodel: 12/28] implement GtkTreeSortable in the filesystem model
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/filesystemmodel: 12/28] implement GtkTreeSortable in the filesystem model
- Date: Tue, 23 Jun 2009 16:17:51 -0400 (EDT)
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]