[gtk+/filesystemmodel: 13/28] add the ability to freeze the model, to bundle updates for performance
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/filesystemmodel: 13/28] add the ability to freeze the model, to bundle updates for performance
- Date: Tue, 23 Jun 2009 16:17:57 -0400 (EDT)
commit 77d301493a9698405e1701e43be23bf618148f99
Author: Benjamin Otte <otte gnome org>
Date: Sun Jun 21 20:01:59 2009 +0200
add the ability to freeze the model, to bundle updates for performance
gtk/gtkfilesystemmodel.c | 101 +++++++++++++++++++++++++++++++++++++++++++---
gtk/gtkfilesystemmodel.h | 2 +
2 files changed, 97 insertions(+), 6 deletions(-)
---
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index 0e014e8..8e640f9 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -53,7 +53,7 @@ struct _FileModelNode
guint index; /* if valid, index in path - aka visible nodes before this one */
guint visible :1; /* if the file is currently visible */
- guint values_set :1; /* true if the set function has been called on this node */
+ guint frozen_add :1; /* true if the model was frozen and the entry has not been added yet */
GValue values[1]; /* actually n_columns values */
};
@@ -85,6 +85,11 @@ struct _GtkFileSystemModel
gpointer default_sort_data; /* data to pass to default sort func */
GDestroyNotify default_sort_destroy; /* function to call to destroy default_sort_data */
+ guint frozen; /* number of times we're frozen */
+
+ gboolean filter_on_thaw :1;/* set when filtering needs to happen upon thawing */
+ gboolean sort_on_thaw :1;/* set when sorting needs to happen upon thawing */
+
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 */
@@ -179,7 +184,8 @@ node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible)
GtkTreePath *path;
GtkTreeIter iter;
- if (node->visible == visible)
+ if (node->visible == visible ||
+ node->frozen_add)
return;
if (visible)
@@ -343,7 +349,7 @@ gtk_file_system_model_get_value (GtkTreeModel *tree_model,
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (tree_model);
FileModelNode *node;
- g_return_if_fail (column < model->n_columns);
+ g_return_if_fail ((guint) column < model->n_columns);
g_return_if_fail (ITER_IS_VALID (model, iter));
node = get_node (model, ITER_INDEX (iter));
@@ -460,7 +466,15 @@ gtk_file_system_model_iface_init (GtkTreeModelIface *iface)
static void
gtk_file_system_model_sort (GtkFileSystemModel *model)
{
+ if (model->frozen)
+ {
+ model->sort_on_thaw = TRUE;
+ return;
+ }
+
g_warning ("sort not implemented");
+
+ model->sort_on_thaw = FALSE;
}
static gboolean
@@ -712,9 +726,14 @@ gtk_file_system_model_add_node (GtkFileSystemModel *model, GFile *file, GFileInf
node->file = file;
node->info = info;
+ node->frozen_add = model->frozen ? TRUE : FALSE;
g_array_append_vals (model->files, node, 1);
g_slice_free1 (NODE_SIZE (model), node);
+
+ if (!model->frozen)
+ node_set_visible (model, model->files->len -1,
+ node_should_be_visible (model, model->files->len - 1));
}
static void
@@ -747,6 +766,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
files = g_file_enumerator_next_files_finish (enumerator, res, &error);
+ _gtk_file_system_model_freeze_updates (model);
for (walk = files; walk; walk = walk->next)
{
const char *name;
@@ -763,10 +783,9 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
}
file = g_file_get_child (model->dir, name);
gtk_file_system_model_add_node (model, file, info);
- node_set_visible (model, model->files->len - 1,
- node_should_be_visible (model, model->files->len - 1));
}
g_list_free (files);
+ _gtk_file_system_model_thaw_updates (model);
if (files == NULL)
{
@@ -923,11 +942,22 @@ gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
{
guint i;
- /* don't change the editable */
+ if (model->frozen)
+ {
+ model->filter_on_thaw = TRUE;
+ return;
+ }
+
+ _gtk_file_system_model_freeze_updates (model);
+
+ /* start at index 1, don't change the editable */
for (i = 1; i < model->files->len; i++)
{
node_set_visible (model, i, node_should_be_visible (model, i));
}
+
+ model->filter_on_thaw = FALSE;
+ _gtk_file_system_model_thaw_updates (model);
}
/**
@@ -1146,3 +1176,62 @@ _gtk_file_system_model_remove_editable (GtkFileSystemModel *model)
node_set_visible (model, 0, FALSE);
}
+/**
+ * _gtk_file_system_model_freeze_updates:
+ * @model: a #GtkFileSystemModel
+ *
+ * Freezes most updates on the model, so that performing multiple
+ * operations on the files in the model do not cause any events.
+ * Use _gtk_file_system_model_thaw_updates() to resume proper
+ * operations. It is fine to call this function multiple times as
+ * long as freeze and thaw calls are balanced.
+ **/
+void
+_gtk_file_system_model_freeze_updates (GtkFileSystemModel *model)
+{
+ g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
+
+ model->frozen++;
+}
+
+/**
+ * _gtk_file_system_model_thaw_updates:
+ * @model: a #GtkFileSystemModel
+ *
+ * Undoes the effect of a previous call to
+ * _gtk_file_system_model_freeze_updates()
+ **/
+void
+_gtk_file_system_model_thaw_updates (GtkFileSystemModel *model)
+{
+ gboolean stuff_added;
+
+ g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
+ g_return_if_fail (model->frozen > 0);
+
+ model->frozen--;
+ if (model->frozen > 0)
+ return;
+
+ stuff_added = get_node (model, model->files->len - 1)->frozen_add;
+
+ if (model->filter_on_thaw)
+ gtk_file_system_model_refilter_all (model);
+ if (model->sort_on_thaw)
+ gtk_file_system_model_sort (model);
+ if (stuff_added)
+ {
+ guint i;
+
+ for (i = 0; i < model->files->len; i++)
+ {
+ FileModelNode *node = get_node (model, i);
+
+ if (!node->frozen_add)
+ continue;
+ node->frozen_add = FALSE;
+ node_set_visible (model, i, node_should_be_visible (model, i));
+ }
+ }
+}
+
diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h
index 89c6f6a..7df9077 100644
--- a/gtk/gtkfilesystemmodel.h
+++ b/gtk/gtkfilesystemmodel.h
@@ -61,6 +61,8 @@ void _gtk_file_system_model_set_show_folders (GtkFileSystemModel
gboolean show_folders);
void _gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
gboolean show_files);
+void _gtk_file_system_model_freeze_updates (GtkFileSystemModel *model);
+void _gtk_file_system_model_thaw_updates (GtkFileSystemModel *model);
typedef gboolean (*GtkFileSystemModelFilter) (GtkFileSystemModel *model,
GFile *file,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]