From: Matthias Clasen Date: Tue, 11 Oct 2022 16:57:09 +0000 (-0400) Subject: stringsorter: Add a collation property X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~9^2~185^2~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=141aac1a60f64bf8891d5531055cc297a91e8cc0;p=gtk4.git stringsorter: Add a collation property The new property lets us choose between Unicode collation, filename collation, and plain strcmp. This will be used in the filechooser. --- diff --git a/gtk/gtkstringsorter.c b/gtk/gtkstringsorter.c index 59d2d8737e..87f65da897 100644 --- a/gtk/gtkstringsorter.c +++ b/gtk/gtkstringsorter.c @@ -42,6 +42,7 @@ struct _GtkStringSorter GtkSorter parent_instance; gboolean ignore_case; + GtkCollation collation; GtkExpression *expression; }; @@ -50,6 +51,7 @@ enum { PROP_0, PROP_EXPRESSION, PROP_IGNORE_CASE, + PROP_COLLATION, NUM_PROPERTIES }; @@ -60,10 +62,13 @@ static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; static char * gtk_string_sorter_get_key (GtkExpression *expression, gboolean ignore_case, + GtkCollation collation, gpointer item1) { GValue value = G_VALUE_INIT; + const char *string; char *s; + char *key; if (expression == NULL) return NULL; @@ -71,23 +76,35 @@ gtk_string_sorter_get_key (GtkExpression *expression, if (!gtk_expression_evaluate (expression, item1, &value)) return NULL; - /* If strings are NULL, order them before "". */ - if (ignore_case) - { - char *t; + string = g_value_get_string (&value); - t = g_utf8_casefold (g_value_get_string (&value), -1); - s = g_utf8_collate_key (t, -1); - g_free (t); - } + if (ignore_case) + s = g_utf8_casefold (string, -1); else + s = (char *) string; + + switch (collation) { - s = g_utf8_collate_key (g_value_get_string (&value), -1); + case GTK_COLLATION_NONE: + key = s; + break; + case GTK_COLLATION_UNICODE: + key = g_utf8_collate_key (s, -1); + break; + case GTK_COLLATION_FILENAME: + key = g_utf8_collate_key_for_filename (s, -1); + break; + default: + g_assert_not_reached (); + break; } + if (s != string) + g_free (s); + g_value_unset (&value); - return s; + return key; } static GtkOrdering @@ -102,8 +119,8 @@ gtk_string_sorter_compare (GtkSorter *sorter, if (self->expression == NULL) return GTK_ORDERING_EQUAL; - s1 = gtk_string_sorter_get_key (self->expression, self->ignore_case, item1); - s2 = gtk_string_sorter_get_key (self->expression, self->ignore_case, item2); + s1 = gtk_string_sorter_get_key (self->expression, self->ignore_case, self->collation, item1); + s2 = gtk_string_sorter_get_key (self->expression, self->ignore_case, self->collation, item2); result = gtk_ordering_from_cmpfunc (g_strcmp0 (s1, s2)); @@ -131,6 +148,7 @@ struct _GtkStringSortKeys GtkExpression *expression; gboolean ignore_case; + GtkCollation collation; }; static void @@ -173,7 +191,7 @@ gtk_string_sort_keys_init_key (GtkSortKeys *keys, GtkStringSortKeys *self = (GtkStringSortKeys *) keys; char **key = (char **) key_memory; - *key = gtk_string_sorter_get_key (self->expression, self->ignore_case, item); + *key = gtk_string_sorter_get_key (self->expression, self->ignore_case, self->collation, item); } static void @@ -209,6 +227,7 @@ gtk_string_sort_keys_new (GtkStringSorter *self) result->expression = gtk_expression_ref (self->expression); result->ignore_case = self->ignore_case; + result->collation = self->collation; return (GtkSortKeys *) result; } @@ -231,13 +250,17 @@ gtk_string_sorter_set_property (GObject *object, gtk_string_sorter_set_ignore_case (self, g_value_get_boolean (value)); break; + case PROP_COLLATION: + gtk_string_sorter_set_collation (self, g_value_get_enum (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } -static void +static void gtk_string_sorter_get_property (GObject *object, guint prop_id, GValue *value, @@ -255,6 +278,10 @@ gtk_string_sorter_get_property (GObject *object, g_value_set_boolean (value, self->ignore_case); break; + case PROP_COLLATION: + g_value_set_enum (value, self->collation); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -296,13 +323,26 @@ gtk_string_sorter_class_init (GtkStringSorterClass *class) /** * GtkStringSorter:ignore-case: (attributes org.gtk.Property.get=gtk_string_sorter_get_ignore_case org.gtk.Property.set=gtk_string_sorter_set_ignore_case) * - * If matching is case sensitive. + * If sorting is case sensitive. */ properties[PROP_IGNORE_CASE] = g_param_spec_boolean ("ignore-case", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkStringSorter:collation: (attributes org.gtk.Property.get=gtk_string_sorter_get_collation org.gtk.Property.set=gtk_string_sorter_set_collation) + * + * The collation method to use for sorting. + * + * Since: 4.10 + */ + properties[PROP_COLLATION] = + g_param_spec_enum ("collationmode", NULL, NULL, + GTK_TYPE_COLLATION, + GTK_COLLATION_UNICODE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } @@ -311,6 +351,7 @@ static void gtk_string_sorter_init (GtkStringSorter *self) { self->ignore_case = TRUE; + self->collation = GTK_COLLATION_UNICODE; gtk_sorter_changed_with_keys (GTK_SORTER (self), GTK_SORTER_CHANGE_DIFFERENT, @@ -429,3 +470,48 @@ gtk_string_sorter_set_ignore_case (GtkStringSorter *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IGNORE_CASE]); } + +/** + * gtk_string_sorter_get_collation: (attributes org.gtk.Method.get_property=collation) + * @self: a `GtkStringSorter` + * + * Gets which collation method the sorter uses. + * + * Returns: The collation method + * + * Since: 4.10 + */ +GtkCollation +gtk_string_sorter_get_collation (GtkStringSorter *self) +{ + g_return_val_if_fail (GTK_IS_STRING_SORTER (self), GTK_COLLATION_UNICODE); + + return self->collation; +} + +/** + * gtk_string_sorter_set_collation: (attributes org.gtk.Method.set_property=collation) + * @self: a `GtkStringSorter` + * @collation: the collation method + * + * Sets the collation method to use for sorting. + * + * Since: 4.10 + */ +void +gtk_string_sorter_set_collation (GtkStringSorter *self, + GtkCollation collation) +{ + g_return_if_fail (GTK_IS_STRING_SORTER (self)); + + if (self->collation == collation) + return; + + self->collation = collation; + + gtk_sorter_changed_with_keys (GTK_SORTER (self), + GTK_SORTER_CHANGE_DIFFERENT, + gtk_string_sort_keys_new (self)); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLLATION]); +} diff --git a/gtk/gtkstringsorter.h b/gtk/gtkstringsorter.h index c340c6fa8d..ea61a47061 100644 --- a/gtk/gtkstringsorter.h +++ b/gtk/gtkstringsorter.h @@ -47,6 +47,32 @@ GDK_AVAILABLE_IN_ALL void gtk_string_sorter_set_ignore_case (GtkStringSorter *self, gboolean ignore_case); +/** + * GtkCollation: + * @GTK_COLLATION_NONE: Don't do any collation + * @GTK_COLLATION_UNICODE: Use [func@GLib.g_utf8_collate_key] + * @GTK_COLLATION_FILENAME: Use [func@GLib.g_utf8_collate_key_for_filename] + * + * Describes how a [class@Gtk.StringSorter] turns strings into sort keys to + * compare them. + * + * Note that the result of sorting will in general depend on the current locale + * unless the mode is @GTK_COLLATION_NONE. + */ +typedef enum +{ + GTK_COLLATION_NONE, + GTK_COLLATION_UNICODE, + GTK_COLLATION_FILENAME +} GtkCollation; + +GDK_AVAILABLE_IN_4_10 +void gtk_string_sorter_set_collation (GtkStringSorter *self, + GtkCollation collation); + +GDK_AVAILABLE_IN_4_10 +GtkCollation gtk_string_sorter_get_collation (GtkStringSorter *self); + G_END_DECLS #endif /* __GTK_STRING_SORTER_H__ */