From b03069bdf610c3d46ac7594250f7a9f1eaaae1b0 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 26 Jun 2020 14:05:02 +0200 Subject: [PATCH 01/13] a11y: Remove double initialization of variables --- gtk/a11y/gtkcellaccessible.c | 1 - gtk/a11y/gtkpasswordentryaccessible.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/gtk/a11y/gtkcellaccessible.c b/gtk/a11y/gtkcellaccessible.c index 239032331e..e55144ba02 100644 --- a/gtk/a11y/gtkcellaccessible.c +++ b/gtk/a11y/gtkcellaccessible.c @@ -295,7 +295,6 @@ gtk_cell_accessible_action_do_action (AtkAction *action, GtkCellAccessible *cell = GTK_CELL_ACCESSIBLE (action); GtkCellAccessibleParent *parent; - cell = GTK_CELL_ACCESSIBLE (action); if (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell)) == NULL) return FALSE; diff --git a/gtk/a11y/gtkpasswordentryaccessible.c b/gtk/a11y/gtkpasswordentryaccessible.c index d071e049e0..3b3236767f 100644 --- a/gtk/a11y/gtkpasswordentryaccessible.c +++ b/gtk/a11y/gtkpasswordentryaccessible.c @@ -65,7 +65,7 @@ static gunichar gtk_password_entry_accessible_get_character_at_offset (AtkText *atk_text, gint offset) { - GtkText *text = get_text_widget (GTK_ACCESSIBLE (atk_text)); + GtkText *text; char *contents, *index; gunichar result; From b75db7d1c64914818f389347f76e1953192597b0 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 27 Jun 2020 06:29:58 +0200 Subject: [PATCH 02/13] stringfilter: Don't crash if the expression returns "" --- gtk/gtkstringfilter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtk/gtkstringfilter.c b/gtk/gtkstringfilter.c index ada86ea401..3fa924e9c3 100644 --- a/gtk/gtkstringfilter.c +++ b/gtk/gtkstringfilter.c @@ -110,9 +110,9 @@ gtk_string_filter_match (GtkFilter *filter, !gtk_expression_evaluate (self->expression, item, &value)) return FALSE; s = g_value_get_string (&value); - if (s == NULL) - return FALSE; prepared = gtk_string_filter_prepare (self, s); + if (prepared == NULL) + return FALSE; switch (self->match_mode) { From f75a3a0e95b31c84f41acc741d6dfb2028dbe6a2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 27 Jun 2020 06:31:18 +0200 Subject: [PATCH 03/13] stringlist: Take a const char const * argument Sucks that we need to cast a char**, but otherwise we need to cast {"foo", "bar", "baz" } arrays. --- gtk/gtkdropdown.c | 2 +- gtk/gtkstringlist.c | 2 +- gtk/gtkstringlist.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gtk/gtkdropdown.c b/gtk/gtkdropdown.c index 721493dd3f..70e45c2712 100644 --- a/gtk/gtkdropdown.c +++ b/gtk/gtkdropdown.c @@ -943,7 +943,7 @@ gtk_drop_down_set_from_strings (GtkDropDown *self, set_default_factory (self); - model = G_LIST_MODEL (gtk_string_list_new ((const char **)texts)); + model = G_LIST_MODEL (gtk_string_list_new (texts)); gtk_drop_down_set_model (self, model); g_object_unref (model); } diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index d4f90c6781..61e8847d6d 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -432,7 +432,7 @@ gtk_string_list_init (GtkStringList *self) * Returns: a new #GtkStringList */ GtkStringList * -gtk_string_list_new (const char **strings) +gtk_string_list_new (const char * const *strings) { GtkStringList *self; guint i; diff --git a/gtk/gtkstringlist.h b/gtk/gtkstringlist.h index 31c788312a..0a29612ef8 100644 --- a/gtk/gtkstringlist.h +++ b/gtk/gtkstringlist.h @@ -45,7 +45,7 @@ GDK_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (GtkStringList, gtk_string_list, GTK, STRING_LIST, GObject) GDK_AVAILABLE_IN_ALL -GtkStringList * gtk_string_list_new (const char **strings); +GtkStringList * gtk_string_list_new (const char * const *strings); GDK_AVAILABLE_IN_ALL void gtk_string_list_append (GtkStringList *self, From 508073072822b83dccf3bc5aa642f488c967de52 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 4 Jul 2020 21:47:48 +0200 Subject: [PATCH 04/13] listmodels: Stop respecting item-type Simplify all view model APIs and always return G_TYPE_OBJECT as the item-type for every model. It turns out nobody uses item-type anyway. So instead of adding lots of APIs, forcing people to think about it and trying to figure out how to handle filter or map models that modify item types, just having an easy life is a better approach. All the models need to be able to deal with any type of object going through anyway. --- demos/constraint-editor/constraint-view.c | 2 +- docs/reference/gtk/gtk4-sections.txt | 3 -- gtk/gtkcustompaperunixdialog.c | 2 +- gtk/gtkfilterlistmodel.c | 52 ++------------------- gtk/gtkfilterlistmodel.h | 2 - gtk/gtkflattenlistmodel.c | 46 +++---------------- gtk/gtkflattenlistmodel.h | 3 +- gtk/gtkfontchooserwidget.c | 2 +- gtk/gtkmaplistmodel.c | 37 +-------------- gtk/gtkmaplistmodel.h | 3 +- gtk/gtkmultiselection.c | 4 +- gtk/gtknoselection.c | 4 +- gtk/gtkpagesetupunixdialog.c | 4 +- gtk/gtkprintunixdialog.c | 4 +- gtk/gtkshortcutcontroller.c | 20 ++++----- gtk/gtkshortcutmanager.c | 4 +- gtk/gtksingleselection.c | 4 +- gtk/gtkslicelistmodel.c | 50 ++------------------- gtk/gtkslicelistmodel.h | 2 - gtk/gtksortlistmodel.c | 55 ++--------------------- gtk/gtksortlistmodel.h | 3 -- gtk/gtktreelistmodel.c | 12 +---- gtk/inspector/controllers.c | 4 +- gtk/inspector/object-tree.c | 14 +++--- testsuite/gtk/expression.c | 2 +- testsuite/gtk/flattenlistmodel.c | 2 +- testsuite/gtk/maplistmodel.c | 2 +- testsuite/gtk/slicelistmodel.c | 6 +-- testsuite/gtk/sortlistmodel.c | 2 +- 29 files changed, 56 insertions(+), 294 deletions(-) diff --git a/demos/constraint-editor/constraint-view.c b/demos/constraint-editor/constraint-view.c index 76b4acd848..c9d08acab8 100644 --- a/demos/constraint-editor/constraint-view.c +++ b/demos/constraint-editor/constraint-view.c @@ -188,7 +188,7 @@ constraint_view_init (ConstraintView *self) g_list_store_append (list, children); g_list_store_append (list, guides); g_list_store_append (list, constraints); - self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list))); + self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list))); g_object_unref (children); g_object_unref (guides); g_object_unref (constraints); diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 208151976c..15bdac5bc3 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -1539,7 +1539,6 @@ gtk_custom_filter_get_type GtkFilterListModel GtkFilterListModel gtk_filter_list_model_new -gtk_filter_list_model_new_for_type gtk_filter_list_model_set_model gtk_filter_list_model_get_model gtk_filter_list_model_set_filter @@ -2698,7 +2697,6 @@ gtk_size_group_get_type GtkSliceListModel GtkSliceListModel gtk_slice_list_model_new -gtk_slice_list_model_new_for_type gtk_slice_list_model_set_model gtk_slice_list_model_get_model gtk_slice_list_model_set_offset @@ -2830,7 +2828,6 @@ gtk_tree_list_row_sorter_get_type GtkSortListModel GtkSortListModel gtk_sort_list_model_new -gtk_sort_list_model_new_for_type gtk_sort_list_model_set_sorter gtk_sort_list_model_get_sorter gtk_sort_list_model_set_model diff --git a/gtk/gtkcustompaperunixdialog.c b/gtk/gtkcustompaperunixdialog.c index 608a637c88..75e471689c 100644 --- a/gtk/gtkcustompaperunixdialog.c +++ b/gtk/gtkcustompaperunixdialog.c @@ -321,7 +321,7 @@ gtk_custom_paper_unix_dialog_init (GtkCustomPaperUnixDialog *dialog) g_list_store_append (printer_list_list, printer_list); g_object_unref (printer_list); - full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list))); + full_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (printer_list_list))); g_object_unref (printer_list_list); filter = gtk_custom_filter_new (match_func, NULL, NULL); diff --git a/gtk/gtkfilterlistmodel.c b/gtk/gtkfilterlistmodel.c index af29154fcb..12a456ca8a 100644 --- a/gtk/gtkfilterlistmodel.c +++ b/gtk/gtkfilterlistmodel.c @@ -40,7 +40,6 @@ enum { PROP_0, PROP_FILTER, - PROP_ITEM_TYPE, PROP_MODEL, NUM_PROPERTIES }; @@ -63,7 +62,6 @@ struct _GtkFilterListModel { GObject parent_instance; - GType item_type; GListModel *model; GtkFilter *filter; GtkFilterMatch strictness; @@ -194,9 +192,7 @@ gtk_filter_list_model_get_nth (GtkRbTree *tree, static GType gtk_filter_list_model_get_item_type (GListModel *list) { - GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list); - - return self->item_type; + return G_TYPE_OBJECT; } static guint @@ -364,10 +360,6 @@ gtk_filter_list_model_set_property (GObject *object, gtk_filter_list_model_set_filter (self, g_value_get_object (value)); break; - case PROP_ITEM_TYPE: - self->item_type = g_value_get_gtype (value); - break; - case PROP_MODEL: gtk_filter_list_model_set_model (self, g_value_get_object (value)); break; @@ -392,10 +384,6 @@ gtk_filter_list_model_get_property (GObject *object, g_value_set_object (value, self->filter); break; - case PROP_ITEM_TYPE: - g_value_set_gtype (value, self->item_type); - break; - case PROP_MODEL: g_value_set_object (value, self->model); break; @@ -662,18 +650,6 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class) GTK_TYPE_FILTER, GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); - /** - * GtkFilterListModel:item-type: - * - * The #GType for elements of this object - */ - properties[PROP_ITEM_TYPE] = - g_param_spec_gtype ("item-type", - P_("Item type"), - P_("The type of elements of this object"), - G_TYPE_OBJECT, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY); - /** * GtkFilterListModel:model: * @@ -697,7 +673,7 @@ gtk_filter_list_model_init (GtkFilterListModel *self) /** * gtk_filter_list_model_new: - * @model: the model to sort + * @model: (allow-none): the model to sort * @filter: (allow-none): filter or %NULL to not filter items * * Creates a new #GtkFilterListModel that will filter @model using the given @@ -711,10 +687,10 @@ gtk_filter_list_model_new (GListModel *model, { GtkFilterListModel *result; - g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL); + g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL); + g_return_val_if_fail (filter == NULL || GTK_IS_FILTER (filter), NULL); result = g_object_new (GTK_TYPE_FILTER_LIST_MODEL, - "item-type", g_list_model_get_item_type (model), "model", model, "filter", filter, NULL); @@ -722,26 +698,6 @@ gtk_filter_list_model_new (GListModel *model, return result; } -/** - * gtk_filter_list_model_new_for_type: - * @item_type: the type of the items that will be returned - * - * Creates a new empty filter list model set up to return items of type @item_type. - * It is up to the application to set a proper filter and model to ensure - * the item type is matched. - * - * Returns: a new #GtkFilterListModel - **/ -GtkFilterListModel * -gtk_filter_list_model_new_for_type (GType item_type) -{ - g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL); - - return g_object_new (GTK_TYPE_FILTER_LIST_MODEL, - "item-type", item_type, - NULL); -} - /** * gtk_filter_list_model_set_filter: * @self: a #GtkFilterListModel diff --git a/gtk/gtkfilterlistmodel.h b/gtk/gtkfilterlistmodel.h index fcb8dfab5c..c496f302c5 100644 --- a/gtk/gtkfilterlistmodel.h +++ b/gtk/gtkfilterlistmodel.h @@ -39,8 +39,6 @@ G_DECLARE_FINAL_TYPE (GtkFilterListModel, gtk_filter_list_model, GTK, FILTER_LIS GDK_AVAILABLE_IN_ALL GtkFilterListModel * gtk_filter_list_model_new (GListModel *model, GtkFilter *filter); -GDK_AVAILABLE_IN_ALL -GtkFilterListModel * gtk_filter_list_model_new_for_type (GType item_type); GDK_AVAILABLE_IN_ALL void gtk_filter_list_model_set_filter (GtkFilterListModel *self, diff --git a/gtk/gtkflattenlistmodel.c b/gtk/gtkflattenlistmodel.c index 78ea061a53..fe681b265e 100644 --- a/gtk/gtkflattenlistmodel.c +++ b/gtk/gtkflattenlistmodel.c @@ -40,7 +40,6 @@ enum { PROP_0, - PROP_ITEM_TYPE, PROP_MODEL, NUM_PROPERTIES }; @@ -64,7 +63,6 @@ struct _GtkFlattenListModel { GObject parent_instance; - GType item_type; GListModel *model; GtkRbTree *items; /* NULL if model == NULL */ }; @@ -157,9 +155,7 @@ gtk_flatten_list_model_get_nth_model (GtkRbTree *tree, static GType gtk_flatten_list_model_get_item_type (GListModel *list) { - GtkFlattenListModel *self = GTK_FLATTEN_LIST_MODEL (list); - - return self->item_type; + return G_TYPE_OBJECT; } static guint @@ -299,7 +295,6 @@ gtk_flatten_list_model_add_items (GtkFlattenListModel *self, { node = gtk_rb_tree_insert_before (self->items, after); node->model = g_list_model_get_item (self->model, position + i); - g_warn_if_fail (g_type_is_a (g_list_model_get_item_type (node->model), self->item_type)); g_signal_connect (node->model, "items-changed", G_CALLBACK (gtk_flatten_list_model_items_changed_cb), @@ -321,10 +316,6 @@ gtk_flatten_list_model_set_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - self->item_type = g_value_get_gtype (value); - break; - case PROP_MODEL: gtk_flatten_list_model_set_model (self, g_value_get_object (value)); break; @@ -345,10 +336,6 @@ gtk_flatten_list_model_get_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - g_value_set_gtype (value, self->item_type); - break; - case PROP_MODEL: g_value_set_object (value, self->model); break; @@ -416,18 +403,6 @@ gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class) gobject_class->get_property = gtk_flatten_list_model_get_property; gobject_class->dispose = gtk_flatten_list_model_dispose; - /** - * GtkFlattenListModel:item-type: - * - * The #GType for elements of this object - */ - properties[PROP_ITEM_TYPE] = - g_param_spec_gtype ("item-type", - P_("Item type"), - P_("The type of elements of this object"), - G_TYPE_OBJECT, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY); - /** * GtkFlattenListModel:model: * @@ -450,26 +425,20 @@ gtk_flatten_list_model_init (GtkFlattenListModel *self) /** * gtk_flatten_list_model_new: - * @item_type: The type of items in the to-be-flattened models - * @model: (nullable) (transfer none): the item to be flattened + * @model: (nullable) (transfer none): the model to be flattened * - * Creates a new #GtkFlattenListModel that flattens @list. The - * models returned by @model must conform to the given @item_type, - * either by having an identical type or a subtype. + * Creates a new #GtkFlattenListModel that flattens @list. * * Returns: a new #GtkFlattenListModel **/ GtkFlattenListModel * -gtk_flatten_list_model_new (GType item_type, - GListModel *model) +gtk_flatten_list_model_new (GListModel *model) { GtkFlattenListModel *result; - g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL); g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL); result = g_object_new (GTK_TYPE_FLATTEN_LIST_MODEL, - "item-type", item_type, "model", model, NULL); @@ -481,8 +450,7 @@ gtk_flatten_list_model_new (GType item_type, * @self: a #GtkFlattenListModel * @model: (nullable) (transfer none): the new model or %NULL * - * Sets a new model to be flattened. The model must contain items of - * #GListModel that conform to the item type of @self. + * Sets a new model to be flattened. **/ void gtk_flatten_list_model_set_model (GtkFlattenListModel *self, @@ -492,10 +460,6 @@ gtk_flatten_list_model_set_model (GtkFlattenListModel *self, g_return_if_fail (GTK_IS_FLATTEN_LIST_MODEL (self)); g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model)); - if (model) - { - g_return_if_fail (g_type_is_a (g_list_model_get_item_type (model), G_TYPE_LIST_MODEL)); - } if (self->model == model) return; diff --git a/gtk/gtkflattenlistmodel.h b/gtk/gtkflattenlistmodel.h index ec1eaaa84e..c934674ff3 100644 --- a/gtk/gtkflattenlistmodel.h +++ b/gtk/gtkflattenlistmodel.h @@ -36,8 +36,7 @@ GDK_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (GtkFlattenListModel, gtk_flatten_list_model, GTK, FLATTEN_LIST_MODEL, GObject) GDK_AVAILABLE_IN_ALL -GtkFlattenListModel * gtk_flatten_list_model_new (GType item_type, - GListModel *model); +GtkFlattenListModel * gtk_flatten_list_model_new (GListModel *model); GDK_AVAILABLE_IN_ALL void gtk_flatten_list_model_set_model (GtkFlattenListModel *self, diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c index 1d4cd53aa8..42101f29d3 100644 --- a/gtk/gtkfontchooserwidget.c +++ b/gtk/gtkfontchooserwidget.c @@ -784,7 +784,7 @@ update_fontlist (GtkFontChooserWidget *self) if ((self->level & GTK_FONT_CHOOSER_LEVEL_STYLE) == 0) model = g_object_ref (G_LIST_MODEL (fontmap)); else - model = G_LIST_MODEL (gtk_flatten_list_model_new (PANGO_TYPE_FONT_FACE, G_LIST_MODEL (fontmap))); + model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (fontmap))); gtk_filter_list_model_set_model (self->filter_model, model); g_object_unref (model); } diff --git a/gtk/gtkmaplistmodel.c b/gtk/gtkmaplistmodel.c index b77906fcc9..ea43269c07 100644 --- a/gtk/gtkmaplistmodel.c +++ b/gtk/gtkmaplistmodel.c @@ -63,7 +63,6 @@ enum { PROP_0, PROP_HAS_MAP, - PROP_ITEM_TYPE, PROP_MODEL, NUM_PROPERTIES }; @@ -86,7 +85,6 @@ struct _GtkMapListModel { GObject parent_instance; - GType item_type; GListModel *model; GtkMapListModelMapFunc map_func; gpointer user_data; @@ -145,9 +143,7 @@ gtk_map_list_model_get_nth (GtkRbTree *tree, static GType gtk_map_list_model_get_item_type (GListModel *list) { - GtkMapListModel *self = GTK_MAP_LIST_MODEL (list); - - return self->item_type; + return G_TYPE_OBJECT; } static guint @@ -199,11 +195,6 @@ gtk_map_list_model_get_item (GListModel *list, } node->item = self->map_func (g_list_model_get_item (self->model, position), self->user_data); - if (!G_TYPE_CHECK_INSTANCE_TYPE (node->item, self->item_type)) - { - g_critical ("Map function returned a %s, but it is not a subtype of the model's type %s", - G_OBJECT_TYPE_NAME (node->item), g_type_name (self->item_type)); - } g_object_add_weak_pointer (node->item, &node->item); return node->item; @@ -293,10 +284,6 @@ gtk_map_list_model_set_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - self->item_type = g_value_get_gtype (value); - break; - case PROP_MODEL: gtk_map_list_model_set_model (self, g_value_get_object (value)); break; @@ -321,10 +308,6 @@ gtk_map_list_model_get_property (GObject *object, g_value_set_boolean (value, self->items != NULL); break; - case PROP_ITEM_TYPE: - g_value_set_gtype (value, self->item_type); - break; - case PROP_MODEL: g_value_set_object (value, self->model); break; @@ -382,18 +365,6 @@ gtk_map_list_model_class_init (GtkMapListModelClass *class) FALSE, GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY); - /** - * GtkMapListModel:item-type: - * - * The #GType for elements of this object - */ - properties[PROP_ITEM_TYPE] = - g_param_spec_gtype ("item-type", - P_("Item type"), - P_("The type of elements of this object"), - G_TYPE_OBJECT, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY); - /** * GtkMapListModel:model: * @@ -441,7 +412,6 @@ gtk_map_list_model_augment (GtkRbTree *map, /** * gtk_map_list_model_new: - * @item_type: the #GType to use as the model's item type * @model: (allow-none): The model to map or %NULL for none * @map_func: (allow-none): map function or %NULL to not map items * @user_data: (closure): user data passed to @map_func @@ -452,19 +422,16 @@ gtk_map_list_model_augment (GtkRbTree *map, * Returns: a new #GtkMapListModel **/ GtkMapListModel * -gtk_map_list_model_new (GType item_type, - GListModel *model, +gtk_map_list_model_new (GListModel *model, GtkMapListModelMapFunc map_func, gpointer user_data, GDestroyNotify user_destroy) { GtkMapListModel *result; - g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL); g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL); result = g_object_new (GTK_TYPE_MAP_LIST_MODEL, - "item-type", item_type, "model", model, NULL); diff --git a/gtk/gtkmaplistmodel.h b/gtk/gtkmaplistmodel.h index f0ddcc9524..85a39823ab 100644 --- a/gtk/gtkmaplistmodel.h +++ b/gtk/gtkmaplistmodel.h @@ -53,8 +53,7 @@ G_DECLARE_FINAL_TYPE (GtkMapListModel, gtk_map_list_model, GTK, MAP_LIST_MODEL, typedef gpointer (* GtkMapListModelMapFunc) (gpointer item, gpointer user_data); GDK_AVAILABLE_IN_ALL -GtkMapListModel * gtk_map_list_model_new (GType item_type, - GListModel *model, +GtkMapListModel * gtk_map_list_model_new (GListModel *model, GtkMapListModelMapFunc map_func, gpointer user_data, GDestroyNotify user_destroy); diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c index e8bd0759ef..ad6d3857de 100644 --- a/gtk/gtkmultiselection.c +++ b/gtk/gtkmultiselection.c @@ -62,9 +62,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, }; static GType gtk_multi_selection_get_item_type (GListModel *list) { - GtkMultiSelection *self = GTK_MULTI_SELECTION (list); - - return g_list_model_get_item_type (self->model); + return G_TYPE_OBJECT; } static guint diff --git a/gtk/gtknoselection.c b/gtk/gtknoselection.c index 72ace9a5a5..652b148735 100644 --- a/gtk/gtknoselection.c +++ b/gtk/gtknoselection.c @@ -60,9 +60,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, }; static GType gtk_no_selection_get_item_type (GListModel *list) { - GtkNoSelection *self = GTK_NO_SELECTION (list); - - return g_list_model_get_item_type (self->model); + return G_TYPE_OBJECT; } static guint diff --git a/gtk/gtkpagesetupunixdialog.c b/gtk/gtkpagesetupunixdialog.c index 5e2679affd..2e353c0033 100644 --- a/gtk/gtkpagesetupunixdialog.c +++ b/gtk/gtkpagesetupunixdialog.c @@ -306,7 +306,7 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) g_list_store_append (store, dialog->page_setup_list); g_list_store_append (store, dialog->custom_paper_list); g_list_store_append (store, dialog->manage_papers_list); - paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store))); + paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (store))); gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list); g_object_unref (store); g_object_unref (paper_size_list); @@ -321,7 +321,7 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) g_list_store_append (printer_list_list, printer_list); g_object_unref (printer_list); - full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list))); + full_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (printer_list_list))); filter = gtk_custom_filter_new (match_func, NULL, NULL); dialog->printer_list = G_LIST_MODEL (gtk_filter_list_model_new (full_list, filter)); diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c index 37a9e58e6f..dab4548b49 100644 --- a/gtk/gtkprintunixdialog.c +++ b/gtk/gtkprintunixdialog.c @@ -806,7 +806,7 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) g_list_store_append (store, dialog->page_setup_list); g_list_store_append (store, dialog->custom_paper_list); g_list_store_append (store, dialog->manage_papers_list); - paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store))); + paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (store))); gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list); g_object_unref (store); g_object_unref (paper_size_list); @@ -1056,7 +1056,7 @@ load_print_backends (GtkPrintUnixDialog *dialog) g_list_store_append (lists, gtk_print_backend_get_printers (backend)); } - model = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (lists))); + model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (lists))); g_object_unref (lists); diff --git a/gtk/gtkshortcutcontroller.c b/gtk/gtkshortcutcontroller.c index 19c3d793dd..1b995f5098 100644 --- a/gtk/gtkshortcutcontroller.c +++ b/gtk/gtkshortcutcontroller.c @@ -110,7 +110,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, }; static GType gtk_shortcut_controller_list_model_get_item_type (GListModel *list) { - return GTK_TYPE_SHORTCUT; + return G_TYPE_OBJECT; } static guint @@ -198,12 +198,6 @@ gtk_shortcut_controller_set_property (GObject *object, case PROP_MODEL: { GListModel *model = g_value_get_object (value); - if (model && g_list_model_get_item_type (model) != GTK_TYPE_SHORTCUT) - { - g_warning ("Setting a model with type '%s' on a shortcut controller that requires 'GtkShortcut'", - g_type_name (g_list_model_get_item_type (model))); - model = NULL; - } if (model == NULL) { self->shortcuts = G_LIST_MODEL (g_list_store_new (GTK_TYPE_SHORTCUT)); @@ -309,6 +303,11 @@ gtk_shortcut_controller_run_controllers (GtkEventController *controller, index = (self->last_activated + 1 + i) % g_list_model_get_n_items (self->shortcuts); shortcut = g_list_model_get_item (self->shortcuts, index); + if (!GTK_IS_SHORTCUT (shortcut)) + { + g_object_unref (shortcut); + continue; + } switch (gtk_shortcut_trigger_trigger (gtk_shortcut_get_trigger (shortcut), event, enable_mnemonics)) { @@ -484,7 +483,8 @@ gtk_shortcut_controller_set_widget (GtkEventController *controller, for (i = 0, p = g_list_model_get_n_items (G_LIST_MODEL (controller)); i < p; i++) { GtkShortcut *shortcut = g_list_model_get_item (G_LIST_MODEL (controller), i); - update_accel (shortcut, widget, TRUE); + if (GTK_IS_SHORTCUT (shortcut)) + update_accel (shortcut, widget, TRUE); g_object_unref (shortcut); } @@ -506,7 +506,8 @@ gtk_shortcut_controller_unset_widget (GtkEventController *controller) for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (controller)); i++) { GtkShortcut *shortcut = g_list_model_get_item (G_LIST_MODEL (controller), i); - update_accel (shortcut, widget, FALSE); + if (GTK_IS_SHORTCUT (shortcut)) + update_accel (shortcut, widget, FALSE); g_object_unref (shortcut); } #endif @@ -697,7 +698,6 @@ GtkEventController * gtk_shortcut_controller_new_for_model (GListModel *model) { g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL); - g_return_val_if_fail (g_list_model_get_item_type (model) == GTK_TYPE_SHORTCUT, NULL); return g_object_new (GTK_TYPE_SHORTCUT_CONTROLLER, "model", model, diff --git a/gtk/gtkshortcutmanager.c b/gtk/gtkshortcutmanager.c index 9aa3577703..a6f2559b1d 100644 --- a/gtk/gtkshortcutmanager.c +++ b/gtk/gtkshortcutmanager.c @@ -49,7 +49,7 @@ gtk_shortcut_manager_create_controllers (GtkWidget *widget) GtkEventController *controller; store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER); - model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store)); + model = gtk_flatten_list_model_new (G_LIST_MODEL (store)); g_object_unref (store); g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-bubble", model, g_object_unref); controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model)); @@ -57,7 +57,7 @@ gtk_shortcut_manager_create_controllers (GtkWidget *widget) gtk_widget_add_controller (widget, controller); store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER); - model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store)); + model = gtk_flatten_list_model_new (G_LIST_MODEL (store)); g_object_unref (store); g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-capture", model, g_object_unref); controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model)); diff --git a/gtk/gtksingleselection.c b/gtk/gtksingleselection.c index bd35aed782..70f0beab27 100644 --- a/gtk/gtksingleselection.c +++ b/gtk/gtksingleselection.c @@ -72,9 +72,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, }; static GType gtk_single_selection_get_item_type (GListModel *list) { - GtkSingleSelection *self = GTK_SINGLE_SELECTION (list); - - return g_list_model_get_item_type (self->model); + return G_TYPE_OBJECT; } static guint diff --git a/gtk/gtkslicelistmodel.c b/gtk/gtkslicelistmodel.c index d002252fff..8d0273c037 100644 --- a/gtk/gtkslicelistmodel.c +++ b/gtk/gtkslicelistmodel.c @@ -41,7 +41,6 @@ enum { PROP_0, - PROP_ITEM_TYPE, PROP_MODEL, PROP_OFFSET, PROP_SIZE, @@ -52,7 +51,6 @@ struct _GtkSliceListModel { GObject parent_instance; - GType item_type; GListModel *model; guint offset; guint size; @@ -70,9 +68,7 @@ static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; static GType gtk_slice_list_model_get_item_type (GListModel *list) { - GtkSliceListModel *self = GTK_SLICE_LIST_MODEL (list); - - return self->item_type; + return G_TYPE_OBJECT; } static guint @@ -182,10 +178,6 @@ gtk_slice_list_model_set_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - self->item_type = g_value_get_gtype (value); - break; - case PROP_MODEL: gtk_slice_list_model_set_model (self, g_value_get_object (value)); break; @@ -214,10 +206,6 @@ gtk_slice_list_model_get_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - g_value_set_gtype (value, self->item_type); - break; - case PROP_MODEL: g_value_set_object (value, self->model); break; @@ -265,18 +253,6 @@ gtk_slice_list_model_class_init (GtkSliceListModelClass *class) gobject_class->get_property = gtk_slice_list_model_get_property; gobject_class->dispose = gtk_slice_list_model_dispose; - /** - * GtkSliceListModel:item-type: - * - * The #GType for elements of this object - */ - properties[PROP_ITEM_TYPE] = - g_param_spec_gtype ("item-type", - P_("Item type"), - P_("The type of elements of this object"), - G_TYPE_OBJECT, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY); - /** * GtkSliceListModel:model: * @@ -324,7 +300,7 @@ gtk_slice_list_model_init (GtkSliceListModel *self) /** * gtk_slice_list_model_new: - * @model: (transfer none): The model to use + * @model: (transfer none) (allow-none): The model to use * @offset: the offset of the slice * @size: maximum size of the slice * @@ -338,35 +314,15 @@ gtk_slice_list_model_new (GListModel *model, guint offset, guint size) { - g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL); + g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL); return g_object_new (GTK_TYPE_SLICE_LIST_MODEL, - "item-type", g_list_model_get_item_type (model), "model", model, "offset", offset, "size", size, NULL); } -/** - * gtk_slice_list_model_new_for_type: - * @item_type: the type of items - * - * Creates a new empty #GtkSliceListModel for the given @item_type that - * can be set up later. - * - * Returns: a new empty #GtkSliceListModel - **/ -GtkSliceListModel * -gtk_slice_list_model_new_for_type (GType item_type) -{ - g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL); - - return g_object_new (GTK_TYPE_SLICE_LIST_MODEL, - "item-type", item_type, - NULL); -} - /** * gtk_slice_list_model_set_model: * @self: a #GtkSliceListModel diff --git a/gtk/gtkslicelistmodel.h b/gtk/gtkslicelistmodel.h index 837e67ef7a..d1b0cd8edc 100644 --- a/gtk/gtkslicelistmodel.h +++ b/gtk/gtkslicelistmodel.h @@ -40,8 +40,6 @@ GDK_AVAILABLE_IN_ALL GtkSliceListModel * gtk_slice_list_model_new (GListModel *model, guint offset, guint size); -GDK_AVAILABLE_IN_ALL -GtkSliceListModel * gtk_slice_list_model_new_for_type (GType item_type); GDK_AVAILABLE_IN_ALL void gtk_slice_list_model_set_model (GtkSliceListModel *self, diff --git a/gtk/gtksortlistmodel.c b/gtk/gtksortlistmodel.c index 0406d1e86f..06e1c6f3b2 100644 --- a/gtk/gtksortlistmodel.c +++ b/gtk/gtksortlistmodel.c @@ -42,7 +42,6 @@ enum { PROP_0, - PROP_ITEM_TYPE, PROP_MODEL, PROP_SORTER, NUM_PROPERTIES @@ -54,7 +53,6 @@ struct _GtkSortListModel { GObject parent_instance; - GType item_type; GListModel *model; GtkSorter *sorter; @@ -89,9 +87,7 @@ gtk_sort_list_entry_free (gpointer data) static GType gtk_sort_list_model_get_item_type (GListModel *list) { - GtkSortListModel *self = GTK_SORT_LIST_MODEL (list); - - return self->item_type; + return G_TYPE_OBJECT; } static guint @@ -262,10 +258,6 @@ gtk_sort_list_model_set_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - self->item_type = g_value_get_gtype (value); - break; - case PROP_MODEL: gtk_sort_list_model_set_model (self, g_value_get_object (value)); break; @@ -290,10 +282,6 @@ gtk_sort_list_model_get_property (GObject *object, switch (prop_id) { - case PROP_ITEM_TYPE: - g_value_set_gtype (value, self->item_type); - break; - case PROP_MODEL: g_value_set_object (value, self->model); break; @@ -405,18 +393,6 @@ gtk_sort_list_model_class_init (GtkSortListModelClass *class) GTK_TYPE_SORTER, GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); - /** - * GtkSortListModel:item-type: - * - * The #GType for items of this model - */ - properties[PROP_ITEM_TYPE] = - g_param_spec_gtype ("item-type", - P_("Item type"), - P_("The type of items of this list"), - G_TYPE_OBJECT, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY); - /** * GtkSortListModel:model: * @@ -439,7 +415,7 @@ gtk_sort_list_model_init (GtkSortListModel *self) /** * gtk_sort_list_model_new: - * @model: the model to sort + * @model: (allow-none): the model to sort * @sorter: (allow-none): the #GtkSorter to sort @model with * * Creates a new sort list model that uses the @sorter to sort @model. @@ -452,11 +428,10 @@ gtk_sort_list_model_new (GListModel *model, { GtkSortListModel *result; - g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL); + g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL); g_return_val_if_fail (sorter == NULL || GTK_IS_SORTER (sorter), NULL); result = g_object_new (GTK_TYPE_SORT_LIST_MODEL, - "item-type", g_list_model_get_item_type (model), "model", model, "sorter", sorter, NULL); @@ -464,26 +439,6 @@ gtk_sort_list_model_new (GListModel *model, return result; } -/** - * gtk_sort_list_model_new_for_type: - * @item_type: the type of the items that will be returned - * - * Creates a new empty sort list model set up to return items of type @item_type. - * It is up to the application to set a proper sort function and model to ensure - * the item type is matched. - * - * Returns: a new #GtkSortListModel - **/ -GtkSortListModel * -gtk_sort_list_model_new_for_type (GType item_type) -{ - g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL); - - return g_object_new (GTK_TYPE_SORT_LIST_MODEL, - "item-type", item_type, - NULL); -} - /** * gtk_sort_list_model_set_model: * @self: a #GtkSortListModel @@ -500,10 +455,6 @@ gtk_sort_list_model_set_model (GtkSortListModel *self, g_return_if_fail (GTK_IS_SORT_LIST_MODEL (self)); g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model)); - if (model) - { - g_return_if_fail (g_type_is_a (g_list_model_get_item_type (model), self->item_type)); - } if (self->model == model) return; diff --git a/gtk/gtksortlistmodel.h b/gtk/gtksortlistmodel.h index 3e009502e2..b78029af2f 100644 --- a/gtk/gtksortlistmodel.h +++ b/gtk/gtksortlistmodel.h @@ -40,9 +40,6 @@ G_DECLARE_FINAL_TYPE (GtkSortListModel, gtk_sort_list_model, GTK, SORT_LIST_MODE GDK_AVAILABLE_IN_ALL GtkSortListModel * gtk_sort_list_model_new (GListModel *model, GtkSorter *sorter); -GDK_AVAILABLE_IN_ALL -GtkSortListModel * gtk_sort_list_model_new_for_type (GType item_type); - GDK_AVAILABLE_IN_ALL void gtk_sort_list_model_set_sorter (GtkSortListModel *self, GtkSorter *sorter); diff --git a/gtk/gtktreelistmodel.c b/gtk/gtktreelistmodel.c index 246d9f2eb7..4311acb9d3 100644 --- a/gtk/gtktreelistmodel.c +++ b/gtk/gtktreelistmodel.c @@ -533,16 +533,6 @@ gtk_tree_list_model_expand_node (GtkTreeListModel *self, if (model == NULL) return 0; - if (!g_type_is_a (g_list_model_get_item_type (model), g_list_model_get_item_type (self->root_node.model))) - { - g_critical ("The GtkTreeListModelCreateModelFunc for %p returned a model with item type \"%s\" " - "but \"%s\" is required.", - self, - g_type_name (g_list_model_get_item_type (model)), - g_type_name (g_list_model_get_item_type (self->root_node.model))); - return 0; - } - gtk_tree_list_model_init_node (self, node, model); tree_node_mark_dirty (node); @@ -576,7 +566,7 @@ gtk_tree_list_model_get_item_type (GListModel *list) GtkTreeListModel *self = GTK_TREE_LIST_MODEL (list); if (self->passthrough) - return g_list_model_get_item_type (self->root_node.model); + return G_TYPE_OBJECT; else return GTK_TYPE_TREE_LIST_ROW; } diff --git a/gtk/inspector/controllers.c b/gtk/inspector/controllers.c index d20bef493b..0eae1caafd 100644 --- a/gtk/inspector/controllers.c +++ b/gtk/inspector/controllers.c @@ -245,10 +245,10 @@ gtk_inspector_controllers_set_object (GtkInspectorControllers *self, self->model = gtk_property_lookup_list_model_new (GTK_TYPE_WIDGET, "parent"); gtk_property_lookup_list_model_set_object (self->model, object); - map_model = gtk_map_list_model_new (G_TYPE_LIST_MODEL, G_LIST_MODEL (self->model), map_to_controllers, NULL, NULL); + map_model = gtk_map_list_model_new (G_LIST_MODEL (self->model), map_to_controllers, NULL, NULL); g_object_unref (self->model); - flatten_model = gtk_flatten_list_model_new (GTK_TYPE_EVENT_CONTROLLER, G_LIST_MODEL (map_model)); + flatten_model = gtk_flatten_list_model_new (G_LIST_MODEL (map_model)); sorter = gtk_custom_sorter_new (compare_controllers, NULL, NULL); sort_model = gtk_sort_list_model_new (G_LIST_MODEL (flatten_model), sorter); diff --git a/gtk/inspector/object-tree.c b/gtk/inspector/object-tree.c index add6da624c..44d8cf0fc3 100644 --- a/gtk/inspector/object-tree.c +++ b/gtk/inspector/object-tree.c @@ -130,7 +130,7 @@ object_tree_widget_get_children (GObject *object) g_list_store_append (list, sublist); g_object_unref (sublist); - flatten = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)); + flatten = gtk_flatten_list_model_new (G_LIST_MODEL (list)); g_object_unref (list); return G_LIST_MODEL (flatten); @@ -225,7 +225,7 @@ list_model_for_properties (GObject *object, g_object_unref (tmp); } - result = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (concat))); + result = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (concat))); g_object_unref (concat); return result; } @@ -330,7 +330,7 @@ object_tree_tree_view_get_children (GObject *object) g_object_unref (selection); g_list_store_append (result_list, columns); g_object_unref (columns); - result = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (result_list)); + result = gtk_flatten_list_model_new (G_LIST_MODEL (result_list)); g_object_unref (result_list); return G_LIST_MODEL (result); @@ -353,7 +353,7 @@ object_tree_column_view_get_children (GObject *object) g_list_store_append (result_list, sublist); g_object_unref (sublist); - result = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (result_list)); + result = gtk_flatten_list_model_new (G_LIST_MODEL (result_list)); g_object_unref (result_list); return G_LIST_MODEL (result); @@ -640,7 +640,7 @@ object_get_children (GObject *object) if (result_list) { - result = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (result_list))); + result = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (result_list))); g_object_unref (result_list); } @@ -1179,7 +1179,7 @@ create_root_model (GdkDisplay *display) g_list_store_append (list, special); g_object_unref (special); - filter = gtk_filter_list_model_new_for_type (G_TYPE_OBJECT); + filter = gtk_filter_list_model_new (NULL, NULL); custom_filter = gtk_custom_filter_new (toplevel_filter_func, display, NULL); gtk_filter_list_model_set_filter (filter, custom_filter); @@ -1187,7 +1187,7 @@ create_root_model (GdkDisplay *display) g_list_store_append (list, filter); g_object_unref (filter); - flatten = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)); + flatten = gtk_flatten_list_model_new (G_LIST_MODEL (list)); g_object_unref (list); return G_LIST_MODEL (flatten); } diff --git a/testsuite/gtk/expression.c b/testsuite/gtk/expression.c index d8c75e527b..08b6e4d97d 100644 --- a/testsuite/gtk/expression.c +++ b/testsuite/gtk/expression.c @@ -492,7 +492,7 @@ test_bind_child (void) "filter"); filter = gtk_string_filter_new (); - child = gtk_filter_list_model_new_for_type (G_TYPE_OBJECT); + child = gtk_filter_list_model_new (NULL, NULL); gtk_filter_list_model_set_filter (child, filter); target = gtk_filter_list_model_new (G_LIST_MODEL (child), NULL); g_object_unref (child); diff --git a/testsuite/gtk/flattenlistmodel.c b/testsuite/gtk/flattenlistmodel.c index dd56e37464..12fc279d18 100644 --- a/testsuite/gtk/flattenlistmodel.c +++ b/testsuite/gtk/flattenlistmodel.c @@ -210,7 +210,7 @@ new_model (GListStore *store) GtkFlattenListModel *result; GString *changes; - result = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (store)); + result = gtk_flatten_list_model_new (G_LIST_MODEL (store)); changes = g_string_new (""); g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes); g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes); diff --git a/testsuite/gtk/maplistmodel.c b/testsuite/gtk/maplistmodel.c index 5b6af7b5e4..94a437f842 100644 --- a/testsuite/gtk/maplistmodel.c +++ b/testsuite/gtk/maplistmodel.c @@ -196,7 +196,7 @@ new_model (GListStore *store) GtkMapListModel *result; GString *changes; - result = gtk_map_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (store), map_multiply, GUINT_TO_POINTER (2), NULL); + result = gtk_map_list_model_new (G_LIST_MODEL (store), map_multiply, GUINT_TO_POINTER (2), NULL); changes = g_string_new (""); g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes); g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes); diff --git a/testsuite/gtk/slicelistmodel.c b/testsuite/gtk/slicelistmodel.c index c3ae685c59..631444182f 100644 --- a/testsuite/gtk/slicelistmodel.c +++ b/testsuite/gtk/slicelistmodel.c @@ -191,11 +191,7 @@ new_model (GListStore *store, guint offset, guint size) GtkSliceListModel *result; GString *changes; - result = gtk_slice_list_model_new_for_type (G_TYPE_OBJECT); - if (store) - gtk_slice_list_model_set_model (result, G_LIST_MODEL (store)); - gtk_slice_list_model_set_offset (result, offset); - gtk_slice_list_model_set_size (result, size); + result = gtk_slice_list_model_new (G_LIST_MODEL (store), offset, size); changes = g_string_new (""); g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes); diff --git a/testsuite/gtk/sortlistmodel.c b/testsuite/gtk/sortlistmodel.c index e0ed7e37df..e7a3004d9d 100644 --- a/testsuite/gtk/sortlistmodel.c +++ b/testsuite/gtk/sortlistmodel.c @@ -203,7 +203,7 @@ new_model (gpointer model) g_object_unref (sorter); } else - result = gtk_sort_list_model_new_for_type (G_TYPE_OBJECT); + result = gtk_sort_list_model_new (NULL, NULL); changes = g_string_new (""); g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes); From 795d3122cc53897cbc25cbfc64a1e15e806f5ce2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 5 Jul 2020 01:08:12 +0200 Subject: [PATCH 05/13] 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. --- docs/reference/gtk/gtk4-sections.txt | 3 ++ gtk/gtkmultiselection.c | 63 ++++++++++++++++++++---- gtk/gtkmultiselection.h | 3 ++ gtk/gtknoselection.c | 58 +++++++++++++++++++---- gtk/gtknoselection.h | 3 ++ gtk/gtksingleselection.c | 71 +++++++++++++++++++++++++--- gtk/gtksingleselection.h | 23 +++++---- testsuite/gtk/multiselection.c | 54 +++++++++++++++++++++ testsuite/gtk/singleselection.c | 52 ++++++++++++++++++++ 9 files changed, 296 insertions(+), 34 deletions(-) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 15bdac5bc3..b02457dca8 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -422,6 +422,7 @@ gtk_selection_model_get_type GtkNoSelection gtk_no_selection_new gtk_no_selection_get_model +gtk_no_selection_set_model gtk_no_selection_get_type @@ -433,6 +434,7 @@ GtkSingleSelection GTK_INVALID_LIST_POSITION gtk_single_selection_new gtk_single_selection_get_model +gtk_single_selection_set_model gtk_single_selection_get_selected gtk_single_selection_set_selected gtk_single_selection_get_selected_item @@ -450,6 +452,7 @@ gtk_single_selection_get_type GtkMultiSelection gtk_multi_selection_new gtk_multi_selection_get_model +gtk_multi_selection_set_model gtk_multi_selection_get_type 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]); +} diff --git a/gtk/gtkmultiselection.h b/gtk/gtkmultiselection.h index 92074683c0..69c8a69028 100644 --- a/gtk/gtkmultiselection.h +++ b/gtk/gtkmultiselection.h @@ -35,6 +35,9 @@ GListModel * gtk_multi_selection_new (GListModel *mo GDK_AVAILABLE_IN_ALL GListModel * gtk_multi_selection_get_model (GtkMultiSelection *self); +GDK_AVAILABLE_IN_ALL +void gtk_multi_selection_set_model (GtkMultiSelection *self, + GListModel *model); G_END_DECLS diff --git a/gtk/gtknoselection.c b/gtk/gtknoselection.c index 652b148735..8027d003b2 100644 --- a/gtk/gtknoselection.c +++ b/gtk/gtknoselection.c @@ -68,15 +68,21 @@ gtk_no_selection_get_n_items (GListModel *list) { GtkNoSelection *self = GTK_NO_SELECTION (list); + if (self->model == NULL) + return 0; + return g_list_model_get_n_items (self->model); } static gpointer gtk_no_selection_get_item (GListModel *list, - guint position) + guint position) { GtkNoSelection *self = GTK_NO_SELECTION (list); + if (self->model == NULL) + return NULL; + return g_list_model_get_item (self->model, position); } @@ -130,9 +136,9 @@ gtk_no_selection_clear_model (GtkNoSelection *self) static void gtk_no_selection_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GtkNoSelection *self = GTK_NO_SELECTION (object); @@ -140,10 +146,7 @@ gtk_no_selection_set_property (GObject *object, switch (prop_id) { case PROP_MODEL: - gtk_no_selection_clear_model (self); - self->model = g_value_dup_object (value); - g_signal_connect_swapped (self->model, "items-changed", - G_CALLBACK (g_list_model_items_changed), self); + gtk_no_selection_set_model (self, g_value_get_object (value)); break; default: @@ -201,7 +204,7 @@ gtk_no_selection_class_init (GtkNoSelectionClass *klass) P_("The model"), P_("The model being managed"), G_TYPE_LIST_MODEL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, N_PROPS, properties); } @@ -245,3 +248,40 @@ gtk_no_selection_get_model (GtkNoSelection *self) return self->model; } +/** + * gtk_no_selection_set_model: + * @self: a #GtkNoSelection + * @model: (allow-none): A #GListModel to wrap + * + * Sets the model that @self should wrap. If @model is %NULL, this + * model will be empty. + **/ +void +gtk_no_selection_set_model (GtkNoSelection *self, + GListModel *model) +{ + guint n_items_before; + + g_return_if_fail (GTK_IS_NO_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_no_selection_clear_model (self); + + if (model) + { + self->model = g_object_ref (model); + g_signal_connect_swapped (self->model, "items-changed", + G_CALLBACK (g_list_model_items_changed), self); + } + + g_list_model_items_changed (G_LIST_MODEL (self), + 0, + n_items_before, + model ? g_list_model_get_n_items (self->model) : 0); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]); +} diff --git a/gtk/gtknoselection.h b/gtk/gtknoselection.h index e6341df409..09f027c9d9 100644 --- a/gtk/gtknoselection.h +++ b/gtk/gtknoselection.h @@ -34,6 +34,9 @@ GtkNoSelection * gtk_no_selection_new (GListModel GDK_AVAILABLE_IN_ALL GListModel * gtk_no_selection_get_model (GtkNoSelection *self); +GDK_AVAILABLE_IN_ALL +void gtk_no_selection_set_model (GtkNoSelection *self, + GListModel *model); G_END_DECLS diff --git a/gtk/gtksingleselection.c b/gtk/gtksingleselection.c index 70f0beab27..209f6524e8 100644 --- a/gtk/gtksingleselection.c +++ b/gtk/gtksingleselection.c @@ -80,6 +80,9 @@ gtk_single_selection_get_n_items (GListModel *list) { GtkSingleSelection *self = GTK_SINGLE_SELECTION (list); + if (self->model == NULL) + return 0; + return g_list_model_get_n_items (self->model); } @@ -89,6 +92,9 @@ gtk_single_selection_get_item (GListModel *list, { GtkSingleSelection *self = GTK_SINGLE_SELECTION (list); + if (self->model == NULL) + return NULL; + return g_list_model_get_item (self->model, position); } @@ -305,12 +311,7 @@ gtk_single_selection_set_property (GObject *object, break; case PROP_MODEL: - gtk_single_selection_clear_model (self); - self->model = g_value_dup_object (value); - g_signal_connect (self->model, "items-changed", - G_CALLBACK (gtk_single_selection_items_changed_cb), self); - if (self->autoselect) - gtk_single_selection_set_selected (self, 0); + gtk_single_selection_set_model (self, g_value_get_object (value)); break; case PROP_SELECTED: @@ -438,7 +439,7 @@ gtk_single_selection_class_init (GtkSingleSelectionClass *klass) P_("The model"), P_("The model being managed"), G_TYPE_LIST_MODEL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, N_PROPS, properties); } @@ -484,6 +485,62 @@ gtk_single_selection_get_model (GtkSingleSelection *self) return self->model; } +/** + * gtk_single_selection_set_model: + * @self: a #GtkSingleSelection + * @model: (allow-none): A #GListModel to wrap + * + * Sets the model that @self should wrap. If @model is %NULL, @self + * will be empty. + **/ +void +gtk_single_selection_set_model (GtkSingleSelection *self, + GListModel *model) +{ + guint n_items_before; + + g_return_if_fail (GTK_IS_SINGLE_SELECTION (self)); + g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model)); + + if (self->model == model) + return; + + g_object_freeze_notify (G_OBJECT (self)); + + n_items_before = self->model ? g_list_model_get_n_items (self->model) : 0; + gtk_single_selection_clear_model (self); + + if (model) + { + self->model = g_object_ref (model); + g_signal_connect (self->model, "items-changed", + G_CALLBACK (gtk_single_selection_items_changed_cb), self); + gtk_single_selection_items_changed_cb (self->model, + 0, + n_items_before, + g_list_model_get_n_items (model), + self); + } + else + { + if (self->selected != GTK_INVALID_LIST_POSITION) + { + self->selected = GTK_INVALID_LIST_POSITION; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]); + } + if (self->selected_item) + { + g_clear_object (&self->selected_item); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]); + } + 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]); + + g_object_thaw_notify (G_OBJECT (self)); +} + /** * gtk_single_selection_get_selected: * @self: a #GtkSingleSelection diff --git a/gtk/gtksingleselection.h b/gtk/gtksingleselection.h index f9bbcae9e9..edfb1fe5c1 100644 --- a/gtk/gtksingleselection.h +++ b/gtk/gtksingleselection.h @@ -35,22 +35,25 @@ GtkSingleSelection * gtk_single_selection_new (GListModel GDK_AVAILABLE_IN_ALL GListModel * gtk_single_selection_get_model (GtkSingleSelection *self); GDK_AVAILABLE_IN_ALL -guint gtk_single_selection_get_selected (GtkSingleSelection *self); +void gtk_single_selection_set_model (GtkSingleSelection *self, + GListModel *model); GDK_AVAILABLE_IN_ALL -void gtk_single_selection_set_selected (GtkSingleSelection *self, - guint position); +guint gtk_single_selection_get_selected (GtkSingleSelection *self); GDK_AVAILABLE_IN_ALL -gpointer gtk_single_selection_get_selected_item (GtkSingleSelection *self); +void gtk_single_selection_set_selected (GtkSingleSelection *self, + guint position); GDK_AVAILABLE_IN_ALL -gboolean gtk_single_selection_get_autoselect (GtkSingleSelection *self); +gpointer gtk_single_selection_get_selected_item (GtkSingleSelection *self); GDK_AVAILABLE_IN_ALL -void gtk_single_selection_set_autoselect (GtkSingleSelection *self, - gboolean autoselect); +gboolean gtk_single_selection_get_autoselect (GtkSingleSelection *self); GDK_AVAILABLE_IN_ALL -gboolean gtk_single_selection_get_can_unselect (GtkSingleSelection *self); +void gtk_single_selection_set_autoselect (GtkSingleSelection *self, + gboolean autoselect); GDK_AVAILABLE_IN_ALL -void gtk_single_selection_set_can_unselect (GtkSingleSelection *self, - gboolean can_unselect); +gboolean gtk_single_selection_get_can_unselect (GtkSingleSelection *self); +GDK_AVAILABLE_IN_ALL +void gtk_single_selection_set_can_unselect (GtkSingleSelection *self, + gboolean can_unselect); G_END_DECLS diff --git a/testsuite/gtk/multiselection.c b/testsuite/gtk/multiselection.c index 1fd32bce71..970a6c4a6a 100644 --- a/testsuite/gtk/multiselection.c +++ b/testsuite/gtk/multiselection.c @@ -613,6 +613,59 @@ test_selection_filter (void) g_object_unref (store); g_object_unref (selection); } + +static void +test_set_model (void) +{ + GtkSelectionModel *selection; + GListStore *store; + GListModel *m1, *m2; + gboolean ret; + + store = new_store (1, 5, 1); + m1 = G_LIST_MODEL (store); + m2 = G_LIST_MODEL (gtk_slice_list_model_new (m1, 0, 3)); + selection = new_model (store); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + ret = gtk_selection_model_select_range (selection, 1, 3, FALSE); + g_assert_true (ret); + assert_selection (selection, "2 3 4"); + assert_selection_changes (selection, "1:3"); + + /* we retain the selected item across model changes */ + gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), m2); + assert_changes (selection, "0-5+3"); + assert_selection (selection, "2 3"); + assert_selection_changes (selection, ""); + + gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), NULL); + assert_changes (selection, "0-3"); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), m2); + assert_changes (selection, "0+3"); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + ret = gtk_selection_model_select_all (selection); + g_assert_true (ret); + assert_selection (selection, "1 2 3"); + assert_selection_changes (selection, "0:3"); + + /* we retain no selected item across model changes */ + gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), m1); + assert_changes (selection, "0-3+5"); + assert_selection (selection, "1 2 3"); + assert_selection_changes (selection, ""); + + g_object_unref (m2); + g_object_unref (m1); + g_object_unref (selection); +} + int main (int argc, char *argv[]) { @@ -633,6 +686,7 @@ main (int argc, char *argv[]) g_test_add_func ("/multiselection/readd", test_readd); g_test_add_func ("/multiselection/set_selection", test_set_selection); g_test_add_func ("/multiselection/selection-filter", test_selection_filter); + g_test_add_func ("/multiselection/set-model", test_set_model); return g_test_run (); } diff --git a/testsuite/gtk/singleselection.c b/testsuite/gtk/singleselection.c index 81b96e90d0..90356345da 100644 --- a/testsuite/gtk/singleselection.c +++ b/testsuite/gtk/singleselection.c @@ -644,6 +644,57 @@ test_query_range (void) g_object_unref (selection); } +static void +test_set_model (void) +{ + GtkSelectionModel *selection; + GListStore *store; + GListModel *m1, *m2; + + store = new_store (1, 5, 1); + m1 = G_LIST_MODEL (store); + m2 = G_LIST_MODEL (gtk_slice_list_model_new (m1, 0, 3)); + selection = new_model (store, TRUE, TRUE); + assert_selection (selection, "1"); + assert_selection_changes (selection, ""); + + /* we retain the selected item across model changes */ + gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m2); + assert_changes (selection, "0-5+3"); + assert_selection (selection, "1"); + assert_selection_changes (selection, ""); + + gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), NULL); + assert_changes (selection, "0-3"); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + gtk_single_selection_set_autoselect (GTK_SINGLE_SELECTION (selection), FALSE); + gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m2); + assert_changes (selection, "0+3"); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + /* we retain no selected item across model changes */ + gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m1); + assert_changes (selection, "0-3+5"); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (selection), 4); + assert_selection (selection, "5"); + assert_selection_changes (selection, "4:1"); + + gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m2); + assert_changes (selection, "0-5+3"); + assert_selection (selection, ""); + assert_selection_changes (selection, ""); + + g_object_unref (m2); + g_object_unref (m1); + g_object_unref (selection); +} + int main (int argc, char *argv[]) { @@ -662,6 +713,7 @@ main (int argc, char *argv[]) g_test_add_func ("/singleselection/persistence", test_persistence); g_test_add_func ("/singleselection/query-range", test_query_range); g_test_add_func ("/singleselection/changes", test_changes); + g_test_add_func ("/singleselection/set-model", test_set_model); return g_test_run (); } From 6f2f828bcebe49f8b1e56049016b08195fda0e32 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 00:44:00 +0200 Subject: [PATCH 06/13] tests: Make testlistview be a list again The grid conversion was for testing and should never have been committed. --- tests/testlistview.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testlistview.c b/tests/testlistview.c index a230c50ed0..6e82bdff9b 100644 --- a/tests/testlistview.c +++ b/tests/testlistview.c @@ -621,7 +621,7 @@ main (int argc, char *argv[]) factory = gtk_signal_list_item_factory_new (); g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL); - listview = gtk_grid_view_new_with_factory (factory); + listview = gtk_list_view_new_with_factory (factory); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview); if (argc > 1) @@ -645,7 +645,7 @@ main (int argc, char *argv[]) selectionmodel = file_info_selection_new (G_LIST_MODEL (filter)); g_object_unref (filter); - gtk_grid_view_set_model (GTK_GRID_VIEW (listview), G_LIST_MODEL (selectionmodel)); + gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selectionmodel)); statusbar = gtk_statusbar_new (); gtk_widget_add_tick_callback (statusbar, (GtkTickCallback) update_statusbar, NULL, NULL); From 6099fbafc16f8d7aa5da06671d3e893fc7a48426 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 03:29:22 +0200 Subject: [PATCH 07/13] bitset: Add gtk_bitset_new_range() It's a common use. --- docs/reference/gtk/gtk4-sections.txt | 1 + gtk/gtkbitset.c | 24 +++++++++++++++++++++++- gtk/gtkbitset.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index b02457dca8..437092116c 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -348,6 +348,7 @@ GtkBitset gtk_bitset_ref gtk_bitset_unref gtk_bitset_new_empty +gtk_bitset_new_range gtk_bitset_copy gtk_bitset_contains diff --git a/gtk/gtkbitset.c b/gtk/gtkbitset.c index c69efd0cf7..27cdf1ba63 100644 --- a/gtk/gtkbitset.c +++ b/gtk/gtkbitset.c @@ -268,7 +268,7 @@ gtk_bitset_get_nth (const GtkBitset *self, * * Creates a new empty bitset. * - * Returns: A new empty bitset. + * Returns: A new empty bitset **/ GtkBitset * gtk_bitset_new_empty (void) @@ -284,6 +284,28 @@ gtk_bitset_new_empty (void) return self; } +/** + * gtk_bitset_new_range: + * @start: first value to add + * @n_items: number of consecutive values to add + * + * Creates a bitset with the given range set. + * + * Returns: A new bitset + **/ +GtkBitset * +gtk_bitset_new_range (guint start, + guint n_items) +{ + GtkBitset *self; + + self = gtk_bitset_new_empty (); + + gtk_bitset_add_range (self, start, n_items); + + return self; +} + /** * gtk_bitset_copy: * @self: a #GtkBitset diff --git a/gtk/gtkbitset.h b/gtk/gtkbitset.h index 1fcbf6faeb..be0ca58f3b 100644 --- a/gtk/gtkbitset.h +++ b/gtk/gtkbitset.h @@ -65,6 +65,9 @@ GDK_AVAILABLE_IN_ALL GtkBitset * gtk_bitset_new_empty (void); GDK_AVAILABLE_IN_ALL GtkBitset * gtk_bitset_copy (const GtkBitset *self); +GDK_AVAILABLE_IN_ALL +GtkBitset * gtk_bitset_new_range (guint start, + guint n_items); GDK_AVAILABLE_IN_ALL void gtk_bitset_remove_all (GtkBitset *self); From fb14f50ec1a8fe9b9024efdc12922ea176b512d7 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 00:35:25 +0200 Subject: [PATCH 08/13] stringlist: Make property not construct-only Massively speeds up creation of long stringlists. --- gtk/gtkstringlist.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index 61e8847d6d..2b43f70e5d 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -138,8 +138,7 @@ gtk_string_object_class_init (GtkStringObjectClass *class) pspec = g_param_spec_string ("string", "String", "String", NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_STRING, pspec); @@ -149,7 +148,12 @@ gtk_string_object_class_init (GtkStringObjectClass *class) static GtkStringObject * gtk_string_object_new (const char *string) { - return g_object_new (GTK_TYPE_STRING_OBJECT, "string", string, NULL); + GtkStringObject *result; + + result = g_object_new (GTK_TYPE_STRING_OBJECT, NULL); + result->string = g_strdup (string); + + return result; } static GtkStringObject * From a979daa8ea98e15e6c88f171707c187793c23b14 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 19:35:04 +0200 Subject: [PATCH 09/13] stringlist: Make one constructor call the other Simplifies code. --- gtk/gtkstringlist.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index 2b43f70e5d..70290fe24f 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -145,17 +145,6 @@ gtk_string_object_class_init (GtkStringObjectClass *class) } -static GtkStringObject * -gtk_string_object_new (const char *string) -{ - GtkStringObject *result; - - result = g_object_new (GTK_TYPE_STRING_OBJECT, NULL); - result->string = g_strdup (string); - - return result; -} - static GtkStringObject * gtk_string_object_new_take (char *string) { @@ -167,6 +156,12 @@ gtk_string_object_new_take (char *string) return obj; } +static GtkStringObject * +gtk_string_object_new (const char *string) +{ + return gtk_string_object_new_take (g_strdup (string)); +} + /** * gtk_string_object_get_string: * @self: a #GtkStringObject From 67cbb2a7d384d40f886f2211ff21afd9836d9ae4 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 19:35:43 +0200 Subject: [PATCH 10/13] stringlist: Clarify docs for gtk_string_list_get_string() Make sure it's obvious that it behaves like g_list_model_get_item() and returns NULL for pos >= n_items. --- gtk/gtkstringlist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index 70290fe24f..e58a0fe6b6 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -588,8 +588,8 @@ gtk_string_list_remove (GtkStringList *self, * @self: a #GtkStringList * @position: the position to get the string for * - * Gets the string that is at @position in @self. @position - * must be smaller than the current length of the list. + * Gets the string that is at @position in @self. If @self + * does not contain @position items, %NULL is returned. * * This function returns the const char *. To get the * object wrapping it, use g_list_model_get_item(). From c4e4de36f60881a8f29287dc612f2a8e055d12e3 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 19:36:51 +0200 Subject: [PATCH 11/13] stringlist: Remove n_additions argument from gtk_string_list_splice() char ** arrays are null-terminated everywhere, so make sure they are in splice(), too. Also fix the argument to be a const char * const * like in the constructor. --- gtk/gtkstringlist.c | 31 +++++++++++++++---------------- gtk/gtkstringlist.h | 27 +++++++++++++-------------- testsuite/gtk/stringlist.c | 2 +- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index e58a0fe6b6..a3e2af5f68 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -449,11 +449,10 @@ gtk_string_list_new (const char * const *strings) * @self: a #GtkStringList * @position: the position at which to make the change * @n_removals: the number of strings to remove - * @additions: (array length=n_additions): the strings to add - * @n_additions: the number of items to add + * @additions: (array zero-terminated=1) (nullable): The strings to add * - * Changes @self by removing @n_removals strings and adding @n_additions - * strings to it. + * Changes @self by removing @n_removals strings and adding @additions + * to it. * * This function is more efficient than gtk_string_list_insert() and * gtk_string_list_remove(), because it only emits @@ -466,14 +465,13 @@ gtk_string_list_new (const char * const *strings) * of the list at the time this function is called). */ void -gtk_string_list_splice (GtkStringList *self, - guint position, - guint n_removals, - const char **additions, - guint n_additions) +gtk_string_list_splice (GtkStringList *self, + guint position, + guint n_removals, + const char * const *additions) { GSequenceIter *it; - guint n_items; + guint add, n_items; g_return_if_fail (GTK_IS_STRING_LIST (self)); g_return_if_fail (position + n_removals >= position); /* overflow */ @@ -493,17 +491,18 @@ gtk_string_list_splice (GtkStringList *self, it = end; } - if (n_additions) + if (additions) { - gint i; - - for (i = 0; i < n_additions; i++) + for (add = 0; additions[add]; add++) { - g_sequence_insert_before (it, gtk_string_object_new (additions[i])); + g_sequence_insert_before (it, gtk_string_object_new (additions[add])); } } + else + add = 0; - g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, n_additions); + if (n_removals || add) + g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, add); } /** diff --git a/gtk/gtkstringlist.h b/gtk/gtkstringlist.h index 0a29612ef8..17be87864b 100644 --- a/gtk/gtkstringlist.h +++ b/gtk/gtkstringlist.h @@ -45,30 +45,29 @@ GDK_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (GtkStringList, gtk_string_list, GTK, STRING_LIST, GObject) GDK_AVAILABLE_IN_ALL -GtkStringList * gtk_string_list_new (const char * const *strings); +GtkStringList * gtk_string_list_new (const char * const *strings); GDK_AVAILABLE_IN_ALL -void gtk_string_list_append (GtkStringList *self, - const char *string); +void gtk_string_list_append (GtkStringList *self, + const char *string); GDK_AVAILABLE_IN_ALL -void gtk_string_list_take (GtkStringList *self, - char *string); +void gtk_string_list_take (GtkStringList *self, + char *string); GDK_AVAILABLE_IN_ALL -void gtk_string_list_remove (GtkStringList *self, - guint position); +void gtk_string_list_remove (GtkStringList *self, + guint position); GDK_AVAILABLE_IN_ALL -void gtk_string_list_splice (GtkStringList *self, - guint position, - guint n_removals, - const char **additions, - guint n_additions); +void gtk_string_list_splice (GtkStringList *self, + guint position, + guint n_removals, + const char * const *additions); GDK_AVAILABLE_IN_ALL -const char * gtk_string_list_get_string (GtkStringList *self, - guint position); +const char * gtk_string_list_get_string (GtkStringList *self, + guint position); G_END_DECLS diff --git a/testsuite/gtk/stringlist.c b/testsuite/gtk/stringlist.c index 5b6256f93f..12169be13e 100644 --- a/testsuite/gtk/stringlist.c +++ b/testsuite/gtk/stringlist.c @@ -184,7 +184,7 @@ test_splice (void) assert_model (list, "a b c d e"); - gtk_string_list_splice (list, 2, 2, (const char *[]){ "x", "y", "z" }, 3); + gtk_string_list_splice (list, 2, 2, (const char *[]){ "x", "y", "z", NULL }); assert_model (list, "a b x y z e"); assert_changes (list, "2-2+3"); From f6c2c2edbd3fc86fa5d6e6c31a10084de4d46df7 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jun 2020 23:31:02 +0200 Subject: [PATCH 12/13] stringlist: Call splice() for adding items after construction This has the benefit of actually allowing NULL to be passed. --- gtk/gtkstringlist.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index a3e2af5f68..608081d500 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -434,12 +434,10 @@ GtkStringList * gtk_string_list_new (const char * const *strings) { GtkStringList *self; - guint i; self = g_object_new (GTK_TYPE_STRING_LIST, NULL); - for (i = 0; strings[i]; i++) - g_sequence_append (self->items, gtk_string_object_new (strings[i])); + gtk_string_list_splice (self, 0, 0, strings); return self; } From 1dbb8df95f4732342c3ae279adea98da13238452 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 4 Jul 2020 17:02:44 +0200 Subject: [PATCH 13/13] stringlist: Export gtk_string_object_new() There are various use cases where it makes sense to construct these - from our internal testing to using them in flatten- or mapmodels. --- docs/reference/gtk/gtk4-sections.txt | 2 ++ gtk/gtkstringlist.c | 10 +++++++++- gtk/gtkstringlist.h | 4 +++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 437092116c..c6da63ac74 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -7611,7 +7611,9 @@ gtk_string_list_take gtk_string_list_remove gtk_string_list_splice gtk_string_list_get_string + GtkStringObject +gtk_string_object_new gtk_string_object_get_string diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index 608081d500..2555e1f8f3 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -156,7 +156,15 @@ gtk_string_object_new_take (char *string) return obj; } -static GtkStringObject * +/** + * gtk_string_object_new: + * @string: (non-nullable): The string to wrap + * + * Wraps a string in an object for use with #GListModel + * + * Returns: a new #GtkStringObject + **/ +GtkStringObject * gtk_string_object_new (const char *string) { return gtk_string_object_new_take (g_strdup (string)); diff --git a/gtk/gtkstringlist.h b/gtk/gtkstringlist.h index 17be87864b..c426a91542 100644 --- a/gtk/gtkstringlist.h +++ b/gtk/gtkstringlist.h @@ -37,7 +37,9 @@ GDK_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (GtkStringObject, gtk_string_object, GTK, STRING_OBJECT, GObject) GDK_AVAILABLE_IN_ALL -const char * gtk_string_object_get_string (GtkStringObject *self); +GtkStringObject * gtk_string_object_new (const char *string); +GDK_AVAILABLE_IN_ALL +const char * gtk_string_object_get_string (GtkStringObject *self); #define GTK_TYPE_STRING_LIST (gtk_string_list_get_type ())