diff options
author | Benjamin Otte <otte@redhat.com> | 2020-07-05 01:08:12 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2020-07-05 02:59:21 +0200 |
commit | 795d3122cc53897cbc25cbfc64a1e15e806f5ce2 (patch) | |
tree | d2137c3af64857c7ce6ced0bdbe1f01495b58703 /gtk/gtkmultiselection.c | |
parent | 508073072822b83dccf3bc5aa642f488c967de52 (diff) | |
download | gtk+-795d3122cc53897cbc25cbfc64a1e15e806f5ce2.tar.gz |
selectionmodels: Add set_model() support
Now that we don't care about item types anymore, we can make the child
models settable.
We try to retain the selection, even when the model changes.
Diffstat (limited to 'gtk/gtkmultiselection.c')
-rw-r--r-- | gtk/gtkmultiselection.c | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c index ad6d3857de..4dd93b5234 100644 --- a/gtk/gtkmultiselection.c +++ b/gtk/gtkmultiselection.c @@ -70,6 +70,9 @@ gtk_multi_selection_get_n_items (GListModel *list) { GtkMultiSelection *self = GTK_MULTI_SELECTION (list); + if (self->model == NULL) + return 0; + return g_list_model_get_n_items (self->model); } @@ -79,6 +82,9 @@ gtk_multi_selection_get_item (GListModel *list, { GtkMultiSelection *self = GTK_MULTI_SELECTION (list); + if (self->model == NULL) + return NULL; + return g_list_model_get_item (self->model, position); } @@ -172,7 +178,7 @@ gtk_multi_selection_set_selection (GtkSelectionModel *model, max = gtk_bitset_get_maximum (changes); /* sanity check */ - n_items = g_list_model_get_n_items (self->model); + n_items = self->model ? g_list_model_get_n_items (self->model) : 0; if (max >= n_items) { gtk_bitset_remove_range_closed (changes, n_items, max); @@ -289,12 +295,7 @@ gtk_multi_selection_set_property (GObject *object, switch (prop_id) { case PROP_MODEL: - self->model = g_value_dup_object (value); - g_warn_if_fail (self->model != NULL); - g_signal_connect (self->model, - "items-changed", - G_CALLBACK (gtk_multi_selection_items_changed_cb), - self); + gtk_multi_selection_set_model (self, g_value_get_object (value)); break; default: @@ -355,7 +356,7 @@ gtk_multi_selection_class_init (GtkMultiSelectionClass *klass) P_("Model"), P_("List managed by this selection"), G_TYPE_LIST_MODEL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, N_PROPS, properties); } @@ -400,3 +401,49 @@ gtk_multi_selection_get_model (GtkMultiSelection *self) return self->model; } + +/** + * gtk_multi_selection_set_model: + * @self: a #GtkMultiSelection + * @model: (allow-none): A #GListModel to wrap + * + * Sets the model that @self should wrap. If @model is %NULL, @self + * will be empty. + **/ +void +gtk_multi_selection_set_model (GtkMultiSelection *self, + GListModel *model) +{ + guint n_items_before; + + g_return_if_fail (GTK_IS_MULTI_SELECTION (self)); + g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model)); + + if (self->model == model) + return; + + n_items_before = self->model ? g_list_model_get_n_items (self->model) : 0; + gtk_multi_selection_clear_model (self); + + if (model) + { + self->model = g_object_ref (model); + g_signal_connect (self->model, + "items-changed", + G_CALLBACK (gtk_multi_selection_items_changed_cb), + self); + gtk_multi_selection_items_changed_cb (self->model, + 0, + n_items_before, + g_list_model_get_n_items (model), + self); + } + else + { + gtk_bitset_remove_all (self->selected); + g_hash_table_remove_all (self->items); + g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items_before, 0); + } + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]); +} |