[gtk+/filesystemmodel: 4/28] file system model improvements, step 2
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/filesystemmodel: 4/28] file system model improvements, step 2
- Date: Tue, 23 Jun 2009 16:17:11 -0400 (EDT)
commit 8ba104089216bca253ab984a6c7faab49045bf45
Author: Benjamin Otte <otte gnome org>
Date: Thu Jun 18 17:03:07 2009 +0200
file system model improvements, step 2
make columns managed by the creator of the model, so any number of nodes
can be added as needed. Values are filled on demand using a function
given when creating the model.
The reason for this API change is to make the code more similar to
GtkListStore. This should allow simplifying the code in gtkfilechooser.c
where these two models are used interchangably.
gtk/gtkfilechooserdefault.c | 31 +++++++-
gtk/gtkfilesystemmodel.c | 181 +++++++++++++++++++++++++++++--------------
gtk/gtkfilesystemmodel.h | 16 +++--
3 files changed, 160 insertions(+), 68 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 6ee285d..0895bd6 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -191,6 +191,12 @@ typedef enum {
SHORTCUT_TYPE_RECENT
} ShortcutType;
+enum {
+ BROWSE_MODEL_COL_INFO,
+ BROWSE_MODEL_COL_DISPLAY_NAME,
+ BROWSE_MODEL_COL_NUM_COLUMNS
+};
+
/* Column numbers for the search model.
* Keep this in sync with search_setup_model()
*/
@@ -6438,7 +6444,7 @@ load_set_model (GtkFileChooserDefault *impl)
GTK_TREE_MODEL (impl->sort_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),
- GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME);
+ BROWSE_MODEL_COL_DISPLAY_NAME);
profile_msg (" gtk_tree_view_set_model end", NULL);
profile_end ("end", NULL);
@@ -6791,6 +6797,22 @@ stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
}
+static void
+file_system_model_set (GtkFileSystemModel *model,
+ GFile *file,
+ GFileInfo *info,
+ GValue *values,
+ gpointer unused)
+{
+ g_value_set_object (&values[0], info);
+
+ if (info == NULL)
+ g_value_set_static_string (&values[1], "");
+ else
+ g_value_set_string (&values[1], g_file_info_get_display_name (info));
+
+}
+
/* Gets rid of the old list model and creates a new one for the current folder */
static gboolean
set_list_model (GtkFileChooserDefault *impl,
@@ -6808,7 +6830,12 @@ set_list_model (GtkFileChooserDefault *impl,
impl->browse_files_model = _gtk_file_system_model_new (impl->current_folder,
"standard::name,standard::type,standard::display-name,"
"standard::is-hidden,standard::is-backup",
- "standard,time,thumbnail");
+ "standard,time,thumbnail",
+ file_system_model_set,
+ NULL,
+ BROWSE_MODEL_COL_NUM_COLUMNS,
+ G_TYPE_FILE_INFO,
+ G_TYPE_STRING);
load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */
g_signal_connect (impl->browse_files_model, "finished-loading",
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index c947dc1..c8bee02 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -27,6 +27,7 @@
#include "gtkintl.h"
#include "gtkmarshalers.h"
+#include "gtktreedatalist.h"
#include "gtktreednd.h"
#include "gtktreemodel.h"
#include "gtkalias.h"
@@ -52,6 +53,9 @@ struct _FileModelNode
guint index; /* 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 */
+
+ GValue values[1]; /* actually n_columns values */
};
struct _GtkFileSystemModel
@@ -65,6 +69,11 @@ struct _GtkFileSystemModel
GCancellable * cancellable; /* cancellable in use for all operations - cancelled on dispose */
GArray * files; /* array of FileModelNode containing all our files */
+ guint n_columns; /* number of columns */
+ GType * column_types; /* types of each column */
+ GtkFileSystemModelSet set_func; /* function to call to fill in values in columns */
+ gpointer set_data; /* data to pass to set_func */
+
GtkFileSystemModelFilter filter_func; /* filter to use for deciding which nodes are visible */
gpointer filter_data; /* data to pass to filter_func */
@@ -103,8 +112,30 @@ struct _GtkFileSystemModelClass
/*** FileModelNode ***/
-#define get_node(_model, _index) (&g_array_index ((_model)->files, FileModelNode, (_index)))
-#define gtk_tree_path_new_from_node(_model, _index) gtk_tree_path_new_from_indices (get_node ((_model), (_index))->index, -1)
+#define NODE_SIZE(_model) (sizeof (FileModelNode) + sizeof (GValue) * (MAX ((model)->n_columns, 1) - 1))
+#define get_node(_model, _index) ((FileModelNode *) (((guint8 *) (_model)->files->data) + (_index) * NODE_SIZE (_model)))
+
+static GtkTreePath *
+gtk_tree_path_new_from_node (GtkFileSystemModel *model, guint id)
+{
+ FileModelNode *node = get_node (model, id);
+
+ g_assert (node->index < model->files->len);
+
+ return gtk_tree_path_new_from_indices (node->index, -1);
+}
+
+static void
+node_ensure_values_set (GtkFileSystemModel *model, guint id)
+{
+ FileModelNode *node = get_node (model, id);
+
+ if (node->values_set)
+ return;
+
+ model->set_func (model, node->file, node->info, node->values, model->set_data);
+ node->values_set = TRUE;
+}
static void
node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible)
@@ -186,23 +217,20 @@ gtk_file_system_model_get_flags (GtkTreeModel *tree_model)
static gint
gtk_file_system_model_get_n_columns (GtkTreeModel *tree_model)
{
- return GTK_FILE_SYSTEM_MODEL_N_COLUMNS;
+ GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (tree_model);
+
+ return model->n_columns;
}
static GType
gtk_file_system_model_get_column_type (GtkTreeModel *tree_model,
gint i)
{
- switch (i)
- {
- case GTK_FILE_SYSTEM_MODEL_INFO:
- return G_TYPE_FILE_INFO;
- case GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME:
- return G_TYPE_STRING;
- default:
- g_assert_not_reached ();
- return G_TYPE_NONE;
- }
+ GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (tree_model);
+
+ g_return_val_if_fail (i >= 0 && (guint) i < model->n_columns, G_TYPE_NONE);
+
+ return model->column_types[i];
}
static int
@@ -220,7 +248,8 @@ gtk_file_system_model_iter_nth_child (GtkTreeModel *tree_model,
gint n)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (tree_model);
- FileModelNode *node, *first;
+ char *node;
+ guint id;
g_return_val_if_fail (n >= 0, FALSE);
@@ -230,16 +259,16 @@ gtk_file_system_model_iter_nth_child (GtkTreeModel *tree_model,
node = bsearch (GUINT_TO_POINTER ((guint) n),
model->files->data,
model->files->len,
- sizeof (FileModelNode),
+ NODE_SIZE (model),
compare_indices);
if (node == NULL)
return FALSE;
- first = get_node (model, 0);
- while (node >= first && !node->visible)
- node--;
+ id = (node - model->files->data) / NODE_SIZE (model);
+ while (!get_node (model, id)->visible)
+ id--;
- ITER_INIT_FROM_INDEX (model, iter, (guint) (node - get_node (model, 0)));
+ ITER_INIT_FROM_INDEX (model, iter, id);
return TRUE;
}
@@ -270,36 +299,23 @@ gtk_file_system_model_get_path (GtkTreeModel *tree_model,
static void
gtk_file_system_model_get_value (GtkTreeModel *tree_model,
GtkTreeIter *iter,
- gint column,
+ gint i_can_has_uint,
GValue *value)
{
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (tree_model);
FileModelNode *node;
+ guint column = i_can_has_uint;
+ g_return_if_fail (column < model->n_columns);
g_return_if_fail (ITER_IS_VALID (model, iter));
node = get_node (model, ITER_INDEX (iter));
g_assert (node->visible);
- switch (column)
- {
- case GTK_FILE_SYSTEM_MODEL_INFO:
- g_value_init (value, G_TYPE_FILE_INFO);
- g_value_set_object (value, node->info);
- break;
- case GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME:
- {
- g_value_init (value, G_TYPE_STRING);
-
- if (node->info == NULL)
- g_value_set_static_string (value, "");
- else
- g_value_set_string (value, g_file_info_get_display_name (node->info));
- }
- break;
- default:
- g_assert_not_reached ();
- }
+ node_ensure_values_set (model, ITER_INDEX (iter));
+
+ g_value_init (value, model->column_types[column]);
+ g_value_copy (&node->values[column], value);
}
static gboolean
@@ -513,25 +529,31 @@ _gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
/* NB: takes ownership of file and info */
static void
-gtk_file_system_model_add_node (GtkFileSystemModel *model,
- FileModelNode * node)
+gtk_file_system_model_add_node (GtkFileSystemModel *model, GFile *file, GFileInfo *info)
{
- g_assert (!node->visible); /* must be made visible later */
- g_assert (model->files->len > 0);
+ FileModelNode *node = g_slice_alloc0 (NODE_SIZE (model));
+ guint i;
- node->index = get_node (model, model->files->len - 1)->index;
+ node->file = file;
+ node->info = info;
+
+ if (model->files->len > 0)
+ node->index = get_node (model, model->files->len - 1)->index;
+ else
+ node->index = -1;
+
+ for (i = 0; i < model->n_columns; i++)
+ {
+ g_value_init (&node->values[i], model->column_types[i]);
+ }
g_array_append_vals (model->files, node, 1);
+ g_slice_free1 (NODE_SIZE (model), node);
}
static void
_gtk_file_system_model_init (GtkFileSystemModel *model)
{
- FileModelNode node = { NULL, NULL, -1, FALSE };
-
- model->files = g_array_new (FALSE, FALSE, sizeof (FileModelNode));
- g_array_append_val (model->files, node);
-
model->show_files = TRUE;
model->show_folders = TRUE;
model->show_hidden = FALSE;
@@ -561,21 +583,20 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
for (walk = files; walk; walk = walk->next)
{
- FileModelNode node;
const char *name;
+ GFileInfo *info;
+ GFile *file;
- node.info = walk->data;
- name = g_file_info_get_name (node.info);
+ info = walk->data;
+ name = g_file_info_get_name (info);
if (name == NULL)
{
/* Shouldn't happen, but the APIs allow it */
- g_object_unref (node.info);
+ g_object_unref (info);
continue;
}
- node.file = g_file_get_child (model->dir, name);
- /* set as invisible, because node_should_be_visible() requires it being added already */
- node.visible = FALSE;
- gtk_file_system_model_add_node (model, &node);
+ 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));
}
@@ -635,6 +656,35 @@ gtk_file_system_model_got_enumerator (GObject *dir, GAsyncResult *res, gpointer
gdk_threads_leave ();
}
+static void
+gtk_file_system_model_set_n_columns (GtkFileSystemModel *model,
+ gint n_columns,
+ va_list args)
+{
+ guint i;
+
+ g_assert (model->files == NULL);
+
+ model->n_columns = n_columns;
+ model->column_types = g_slice_alloc0 (sizeof (GType) * n_columns);
+
+ for (i = 0; i < (guint) n_columns; i++)
+ {
+ GType type = va_arg (args, GType);
+ if (! _gtk_tree_data_list_check_type (type))
+ {
+ g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (type));
+ continue;
+ }
+
+ model->column_types[i] = type;
+ }
+
+ model->files = g_array_new (FALSE, FALSE, NODE_SIZE (model));
+ /* add editable node at start */
+ gtk_file_system_model_add_node (model, NULL, NULL);
+}
+
/**
* _gtk_file_system_model_new:
* @directory: the directory to show.
@@ -659,11 +709,16 @@ gtk_file_system_model_got_enumerator (GObject *dir, GAsyncResult *res, gpointer
* was an error.
**/
GtkFileSystemModel *
-_gtk_file_system_model_new (GFile * dir,
- const gchar *attributes,
- const gchar *full_attributes)
+_gtk_file_system_model_new (GFile * dir,
+ const gchar * attributes,
+ const gchar * full_attributes,
+ GtkFileSystemModelSet set_func,
+ gpointer set_data,
+ guint n_columns,
+ ...)
{
GtkFileSystemModel *model;
+ va_list args;
g_return_val_if_fail (G_IS_FILE (dir), NULL);
@@ -671,6 +726,12 @@ _gtk_file_system_model_new (GFile * dir,
model->dir = g_object_ref (dir);
model->attributes = g_strdup (attributes);
model->full_attributes = g_strdup (full_attributes);
+ model->set_func = set_func;
+ model->set_data = set_data;
+
+ va_start (args, n_columns);
+ gtk_file_system_model_set_n_columns (model, n_columns, args);
+ va_end (args);
g_object_ref (model);
g_file_enumerate_children_async (dir,
diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h
index f9e608d..dabd6a5 100644
--- a/gtk/gtkfilesystemmodel.h
+++ b/gtk/gtkfilesystemmodel.h
@@ -34,15 +34,19 @@ typedef struct _GtkFileSystemModel GtkFileSystemModel;
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
-typedef enum {
- GTK_FILE_SYSTEM_MODEL_INFO,
- GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME,
- GTK_FILE_SYSTEM_MODEL_N_COLUMNS
-} GtkFileSystemModelColumns;
+typedef void (*GtkFileSystemModelSet) (GtkFileSystemModel *model,
+ GFile *file,
+ GFileInfo *info,
+ GValue *values,
+ gpointer user_data);
GtkFileSystemModel *_gtk_file_system_model_new (GFile * dir,
const gchar * attributes,
- const gchar * full_attributes);
+ const gchar * full_attributes,
+ GtkFileSystemModelSet set_func,
+ gpointer set_data,
+ guint n_columns,
+ ...);
GFileInfo * _gtk_file_system_model_get_info (GtkFileSystemModel *model,
GtkTreeIter *iter);
gboolean _gtk_file_system_model_get_iter_for_file(GtkFileSystemModel *model,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]