[nautilus/wip/antoniof/new-list-view-continuation: 3/21] view-model: Use GSortListModel internally
- From: António Fernandes <antoniof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/antoniof/new-list-view-continuation: 3/21] view-model: Use GSortListModel internally
- Date: Tue, 31 May 2022 18:11:57 +0000 (UTC)
commit 24157d1bf80189e8409bdfd31ba232459ce01443
Author: António Fernandes <antoniof gnome org>
Date: Wed Apr 6 00:56:57 2022 +0100
view-model: Use GSortListModel internally
This is a required step in order to use GtkTreeListModel later.
GtkTreeListModel doesn't work well when its internal models get
resorted: it assumes the items are gone, not reordered, causing
the row objects to get destroyed and the view to lose track of
things.
This might not be as efficient, but we've got no other option
other than implementing a custom tree list model...
src/nautilus-view-model.c | 89 ++++++++++++++++++++---------------------------
src/nautilus-view-model.h | 1 +
2 files changed, 39 insertions(+), 51 deletions(-)
---
diff --git a/src/nautilus-view-model.c b/src/nautilus-view-model.c
index 2d4deee02..22794998c 100644
--- a/src/nautilus-view-model.c
+++ b/src/nautilus-view-model.c
@@ -8,9 +8,8 @@ struct _NautilusViewModel
GHashTable *map_files_to_model;
GListStore *internal_model;
+ GtkSortListModel *sort_model;
GtkMultiSelection *selection_model;
- GtkSorter *sorter;
- gulong sorter_changed_handler_id;
};
static GType
@@ -38,12 +37,12 @@ nautilus_view_model_get_item (GListModel *list,
{
NautilusViewModel *self = NAUTILUS_VIEW_MODEL (list);
- if (self->internal_model == NULL)
+ if (self->sort_model == NULL)
{
return NULL;
}
- return g_list_model_get_item (G_LIST_MODEL (self->internal_model), position);
+ return g_list_model_get_item (G_LIST_MODEL (self->sort_model), position);
}
static void
@@ -135,16 +134,15 @@ dispose (GObject *object)
self->selection_model = NULL;
}
- if (self->internal_model != NULL)
+ if (self->sort_model != NULL)
{
- g_signal_handlers_disconnect_by_func (self->internal_model,
+ g_signal_handlers_disconnect_by_func (self->sort_model,
g_list_model_items_changed,
self);
- g_object_unref (self->internal_model);
- self->internal_model = NULL;
+ g_object_unref (self->sort_model);
+ self->sort_model = NULL;
}
- g_clear_signal_handler (&self->sorter_changed_handler_id, self->sorter);
G_OBJECT_CLASS (nautilus_view_model_parent_class)->dispose (object);
}
@@ -157,7 +155,6 @@ finalize (GObject *object)
G_OBJECT_CLASS (nautilus_view_model_parent_class)->finalize (object);
g_hash_table_destroy (self->map_files_to_model);
- g_clear_object (&self->sorter);
}
static void
@@ -172,7 +169,7 @@ get_property (GObject *object,
{
case PROP_SORTER:
{
- g_value_set_object (value, self->sorter);
+ g_value_set_object (value, gtk_sort_list_model_get_sorter (self->sort_model));
}
break;
@@ -214,10 +211,11 @@ constructed (GObject *object)
G_OBJECT_CLASS (nautilus_view_model_parent_class)->constructed (object);
self->internal_model = g_list_store_new (NAUTILUS_TYPE_VIEW_ITEM_MODEL);
- self->selection_model = gtk_multi_selection_new (g_object_ref (G_LIST_MODEL (self->internal_model)));
+ self->sort_model = gtk_sort_list_model_new (g_object_ref (G_LIST_MODEL (self->internal_model)), NULL);
+ self->selection_model = gtk_multi_selection_new (g_object_ref (G_LIST_MODEL (self->sort_model)));
self->map_files_to_model = g_hash_table_new (NULL, NULL);
- g_signal_connect_swapped (self->internal_model, "items-changed",
+ g_signal_connect_swapped (self->sort_model, "items-changed",
G_CALLBACK (g_list_model_items_changed), self);
g_signal_connect_swapped (self->selection_model, "selection-changed",
G_CALLBACK (gtk_selection_model_selection_changed), self);
@@ -247,28 +245,6 @@ nautilus_view_model_init (NautilusViewModel *self)
{
}
-static gint
-compare_data_func (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- NautilusViewModel *self = NAUTILUS_VIEW_MODEL (user_data);
-
- g_return_val_if_fail (self->sorter != NULL, GTK_ORDERING_EQUAL);
-
- return gtk_sorter_compare (self->sorter, (gpointer) a, (gpointer) b);
-}
-
-static void
-on_sorter_changed (GtkSorter *sorter,
- GtkSorterChange change,
- gpointer user_data)
-{
- NautilusViewModel *self = NAUTILUS_VIEW_MODEL (user_data);
-
- g_list_store_sort (self->internal_model, compare_data_func, self);
-}
-
NautilusViewModel *
nautilus_view_model_new ()
{
@@ -279,14 +255,15 @@ void
nautilus_view_model_set_sorter (NautilusViewModel *self,
GtkSorter *sorter)
{
- g_clear_signal_handler (&self->sorter_changed_handler_id, self->sorter);
- g_set_object (&self->sorter, sorter);
- self->sorter_changed_handler_id = g_signal_connect (self->sorter,
- "changed",
- G_CALLBACK (on_sorter_changed),
- self);
-
- g_list_store_sort (self->internal_model, compare_data_func, self);
+ gtk_sort_list_model_set_sorter (self->sort_model, sorter);
+}
+
+void
+nautilus_view_model_sort (NautilusViewModel *self)
+{
+ /* Hack: Reset the sorter to trigger ressorting. */
+ gtk_sort_list_model_set_sorter (self->sort_model,
+ gtk_sort_list_model_get_sorter (self->sort_model));
}
GQueue *
@@ -363,7 +340,7 @@ nautilus_view_model_add_item (NautilusViewModel *self,
g_hash_table_insert (self->map_files_to_model,
nautilus_view_item_model_get_file (item),
item);
- g_list_store_insert_sorted (self->internal_model, item, compare_data_func, self);
+ g_list_store_append (self->internal_model, item);
}
void
@@ -389,19 +366,29 @@ nautilus_view_model_add_items (NautilusViewModel *self,
g_list_store_splice (self->internal_model,
g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
0, array, g_queue_get_length (items));
-
- g_list_store_sort (self->internal_model, compare_data_func, self);
}
guint
nautilus_view_model_get_index (NautilusViewModel *self,
NautilusViewItemModel *item)
{
- guint i = G_MAXUINT;
- gboolean found;
+ guint n_items;
+ guint i = 0;
+
+ n_items = g_list_model_get_n_items (G_LIST_MODEL (self->sort_model));
+ while (i < n_items)
+ {
+ g_autoptr (NautilusViewItemModel) item_i = NULL;
+
+ item_i = NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (G_LIST_MODEL (self->sort_model), i));
+ g_warn_if_fail (item_i != NULL);
- found = g_list_store_find (self->internal_model, item, &i);
- g_warn_if_fail (found);
+ if (item_i == item)
+ {
+ return i;
+ }
+ i++;
+ }
- return i;
+ return G_MAXUINT;
}
diff --git a/src/nautilus-view-model.h b/src/nautilus-view-model.h
index 1771cd6e2..2c294eff0 100644
--- a/src/nautilus-view-model.h
+++ b/src/nautilus-view-model.h
@@ -14,6 +14,7 @@ NautilusViewModel * nautilus_view_model_new (void);
void nautilus_view_model_set_sorter (NautilusViewModel *self,
GtkSorter *sorter);
+void nautilus_view_model_sort (NautilusViewModel *self);
NautilusViewItemModel * nautilus_view_model_get_item_from_file (NautilusViewModel *self,
NautilusFile *file);
GQueue * nautilus_view_model_get_items_from_files (NautilusViewModel *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]