[gtk/gbsneto/filechooser-column-view: 9/47] filesystemmodel: Implement GListModel
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gbsneto/filechooser-column-view: 9/47] filesystemmodel: Implement GListModel
- Date: Mon, 10 Oct 2022 16:34:46 +0000 (UTC)
commit c7385c87e120124aa942ab710ea72718f8fd46e3
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Oct 7 16:52:56 2022 -0300
filesystemmodel: Implement GListModel
This is a trivial implementation of the GListModel interface. It
does not do anything fancy, like filtering out hidden files, nor
sorting.
The purpose of this minimal implementation is to bootstrap the
initial work to port GtkFileChooserWidget to GtkColumnView.
gtk/gtkfilesystemmodel.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkfilesystemmodel.h | 12 ++++
2 files changed, 156 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index d22acb5dcb..309cbd0267 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -137,6 +137,7 @@ struct _FileModelNode
{
GFile * file; /* file represented by this node or NULL for editable */
GFileInfo * info; /* info for this file or NULL if unknown */
+ GtkFileSystemItem * item; /* item for the GListModel implementation */
guint row; /* if valid (see model->n_valid_indexes), visible nodes before and
including
* this one - see the "Structure" comment above.
@@ -947,6 +948,116 @@ drag_source_iface_init (GtkTreeDragSourceIface *iface)
iface->drag_data_delete = NULL;
}
+/*** GListModel ***/
+
+struct _GtkFileSystemItem {
+ GObject parent;
+
+ FileModelNode *node; /* unonwned */
+};
+
+typedef struct _GtkFileSystemItemClass
+{
+ GObjectClass parent_class;
+} GtkFileSystemItemClass;
+
+G_DEFINE_TYPE (GtkFileSystemItem, _gtk_file_system_item, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_FILE,
+ PROP_FILE_INFO,
+ N_PROPS,
+};
+
+static GParamSpec *item_properties[N_PROPS] = { NULL, };
+
+static void
+_gtk_file_system_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkFileSystemItem *self = GTK_FILE_SYSTEM_ITEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_FILE:
+ g_value_set_object (value, self->node->file);
+ break;
+
+ case PROP_FILE_INFO:
+ g_value_set_object (value, self->node->info);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+_gtk_file_system_item_class_init (GtkFileSystemItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = _gtk_file_system_item_get_property;
+
+ item_properties[PROP_FILE] =
+ g_param_spec_object ("file", NULL, NULL,
+ G_TYPE_FILE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ item_properties[PROP_FILE_INFO] =
+ g_param_spec_object ("file-info", NULL, NULL,
+ G_TYPE_FILE_INFO,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPS, item_properties);
+}
+
+static void
+_gtk_file_system_item_init (GtkFileSystemItem *self)
+{
+}
+
+static GType
+list_model_get_item_type (GListModel *list_model)
+{
+ return GTK_TYPE_FILE_SYSTEM_ITEM;
+}
+
+static guint
+list_model_get_n_items (GListModel *list_model)
+{
+ GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (list_model);
+
+ return model->files->len - 1;
+}
+
+static gpointer
+list_model_get_item (GListModel *list_model,
+ guint position)
+{
+ GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (list_model);
+ FileModelNode *node;
+
+ /* The first items of GtkFileSystemModel is not really a file,
+ * so ignore it. */
+ if (position + 1 >= model->files->len)
+ return NULL;
+
+ node = get_node (model, position + 1);
+ return g_object_ref (node->item);
+}
+
+static void
+g_list_model_iface_init (GListModelInterface *iface)
+{
+ iface->get_item_type = list_model_get_item_type;
+ iface->get_n_items = list_model_get_n_items;
+ iface->get_item = list_model_get_item;
+}
+
/*** GtkFileSystemModel ***/
/* Signal IDs */
@@ -965,7 +1076,9 @@ G_DEFINE_TYPE_WITH_CODE (GtkFileSystemModel, _gtk_file_system_model, G_TYPE_OBJE
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))
+ drag_source_iface_init)
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
+ g_list_model_iface_init))
static void
gtk_file_system_model_dispose (GObject *object)
@@ -997,6 +1110,7 @@ gtk_file_system_model_finalize (GObject *object)
int v;
FileModelNode *node = get_node (model, i);
+ g_clear_object (&node->item);
g_clear_object (&node->file);
g_clear_object (&node->info);
@@ -1798,6 +1912,7 @@ add_file (GtkFileSystemModel *model,
GFileInfo *info)
{
FileModelNode *node;
+ guint position;
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
g_return_if_fail (G_IS_FILE (file));
@@ -1812,10 +1927,23 @@ add_file (GtkFileSystemModel *model,
g_array_append_vals (model->files, node, 1);
g_slice_free1 (model->node_size, node);
+ position = model->files->len - 1;
+
+ /* 'node' is now invalid, fetch the actual node from the array - this
+ * will all go away when we finish the transition to GtkColumnView
+ * and drop the GtkTreeModel code.
+ */
+ node = get_node (model, position);
+ node->item = g_object_new (GTK_TYPE_FILE_SYSTEM_ITEM, NULL);
+ node->item->node = node;
+
if (!model->frozen)
node_compute_visibility_and_filters (model, model->files->len -1);
gtk_file_system_model_sort_node (model, model->files->len -1);
+
+ /* Ignore the first item */
+ g_list_model_items_changed (G_LIST_MODEL (model), position - 1, 0, 1);
}
/**
@@ -1849,6 +1977,8 @@ remove_file (GtkFileSystemModel *model,
node_invalidate_index (model, id);
+ g_clear_object (&node->item);
+
g_hash_table_remove (model->file_lookup, file);
g_object_unref (node->file);
adjust_file_lookup (model, id, -1);
@@ -1862,6 +1992,8 @@ remove_file (GtkFileSystemModel *model,
if (was_visible)
emit_row_deleted_for_row (model, row);
+
+ g_list_model_items_changed (G_LIST_MODEL (model), id - 1, 1, 0);
}
/**
@@ -2137,3 +2269,14 @@ _gtk_file_system_model_get_directory (GtkFileSystemModel *model)
return model->dir;
}
+GFile *
+_gtk_file_system_item_get_file (GtkFileSystemItem *item)
+{
+ return item->node->file;
+}
+
+GFileInfo *
+_gtk_file_system_item_get_file_info (GtkFileSystemItem *item)
+{
+ return item->node->info;
+}
diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h
index 05383a7328..475c8bb6ec 100644
--- a/gtk/gtkfilesystemmodel.h
+++ b/gtk/gtkfilesystemmodel.h
@@ -33,6 +33,14 @@ typedef struct _GtkFileSystemModel GtkFileSystemModel;
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
+#define GTK_TYPE_FILE_SYSTEM_ITEM (_gtk_file_system_item_get_type ())
+#define GTK_FILE_SYSTEM_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_SYSTEM_ITEM,
GtkFileSystemItem))
+#define GTK_IS_FILE_SYSTEM_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_SYSTEM_ITEM))
+
+typedef struct _GtkFileSystemItem GtkFileSystemItem;
+
+GType _gtk_file_system_item_get_type (void) G_GNUC_CONST;
+
typedef gboolean (*GtkFileSystemModelGetValue) (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info,
@@ -94,6 +102,10 @@ void _gtk_file_system_model_clear_cache (GtkFileSystemModel
void _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
GtkFileFilter *filter);
+GFile * _gtk_file_system_item_get_file (GtkFileSystemItem *item);
+
+GFileInfo * _gtk_file_system_item_get_file_info (GtkFileSystemItem *item);
+
G_END_DECLS
#endif /* __GTK_FILE_SYSTEM_MODEL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]