[gtk/filename-sorter] stringsorter: Add a collate-mode property
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/filename-sorter] stringsorter: Add a collate-mode property
- Date: Tue, 11 Oct 2022 16:58:20 +0000 (UTC)
commit 18b21a4fc3845bbbb5d18cea2efe7874a20ed98e
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Oct 11 12:57:09 2022 -0400
stringsorter: Add a collate-mode property
This lets us change between locale collation,
filename collation, and plain strcmp.
gtk/gtkstringsorter.c | 120 ++++++++++++++++++++++++++++++++++++++++++--------
gtk/gtkstringsorter.h | 25 +++++++++++
2 files changed, 127 insertions(+), 18 deletions(-)
---
diff --git a/gtk/gtkstringsorter.c b/gtk/gtkstringsorter.c
index 59d2d8737e..3c7c52f30f 100644
--- a/gtk/gtkstringsorter.c
+++ b/gtk/gtkstringsorter.c
@@ -42,6 +42,7 @@ struct _GtkStringSorter
GtkSorter parent_instance;
gboolean ignore_case;
+ GtkCollateMode collate_mode;
GtkExpression *expression;
};
@@ -50,6 +51,7 @@ enum {
PROP_0,
PROP_EXPRESSION,
PROP_IGNORE_CASE,
+ PROP_COLLATE_MODE,
NUM_PROPERTIES
};
@@ -58,12 +60,15 @@ G_DEFINE_TYPE (GtkStringSorter, gtk_string_sorter, GTK_TYPE_SORTER)
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static char *
-gtk_string_sorter_get_key (GtkExpression *expression,
- gboolean ignore_case,
- gpointer item1)
+gtk_string_sorter_get_key (GtkExpression *expression,
+ gboolean ignore_case,
+ GtkCollateMode collate_mode,
+ 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 (collate_mode)
{
- s = g_utf8_collate_key (g_value_get_string (&value), -1);
+ case GTK_COLLATE_MODE_NONE:
+ key = s;
+ break;
+ case GTK_COLLATE_MODE_LOCALE:
+ key = g_utf8_collate_key (s, -1);
+ break;
+ case GTK_COLLATE_MODE_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->collate_mode, item1);
+ s2 = gtk_string_sorter_get_key (self->expression, self->ignore_case, self->collate_mode, item2);
result = gtk_ordering_from_cmpfunc (g_strcmp0 (s1, s2));
@@ -131,6 +148,7 @@ struct _GtkStringSortKeys
GtkExpression *expression;
gboolean ignore_case;
+ GtkCollateMode collate_mode;
};
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->collate_mode, 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->collate_mode = self->collate_mode;
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_COLLATE_MODE:
+ gtk_string_sorter_set_collate_mode (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_COLLATE_MODE:
+ g_value_set_enum (value, self->collate_mode);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -296,13 +323,24 @@ 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:collate-mode: (attributes org.gtk.Property.get=gtk_string_sorter_get_collate_mode
org.gtk.Property.set=gtk_string_sorter_set_collate_mode)
+ *
+ * The collation mode to use for sorting.
+ */
+ properties[PROP_COLLATE_MODE] =
+ g_param_spec_enum ("collate-mode", NULL, NULL,
+ GTK_TYPE_COLLATE_MODE,
+ GTK_COLLATE_MODE_LOCALE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
@@ -311,6 +349,7 @@ static void
gtk_string_sorter_init (GtkStringSorter *self)
{
self->ignore_case = TRUE;
+ self->collate_mode = GTK_COLLATE_MODE_LOCALE;
gtk_sorter_changed_with_keys (GTK_SORTER (self),
GTK_SORTER_CHANGE_DIFFERENT,
@@ -429,3 +468,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_collate_mode: (attributes org.gtk.Method.get_property=collate-mode)
+ * @self: a `GtkStringSorter`
+ *
+ * Gets which collation mode the sorter uses.
+ *
+ * Returns: The collation mode
+ *
+ * Since: 4.10
+ */
+GtkCollateMode
+gtk_string_sorter_get_collate_mode (GtkStringSorter *self)
+{
+ g_return_val_if_fail (GTK_IS_STRING_SORTER (self), GTK_COLLATE_MODE_LOCALE);
+
+ return self->collate_mode;
+}
+
+/**
+ * gtk_string_sorter_set_collate_mode: (attributes org.gtk.Method.set_property=collate-mode)
+ * @self: a `GtkStringSorter`
+ * @collate_mode: the collation mode
+ *
+ * Sets the collation mode to use for sorting.
+ *
+ * Since: 4.10
+ */
+void
+gtk_string_sorter_set_collate_mode (GtkStringSorter *self,
+ GtkCollateMode collate_mode)
+{
+ g_return_if_fail (GTK_IS_STRING_SORTER (self));
+
+ if (self->collate_mode == collate_mode)
+ return;
+
+ self->collate_mode = collate_mode;
+
+ 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_COLLATE_MODE]);
+}
diff --git a/gtk/gtkstringsorter.h b/gtk/gtkstringsorter.h
index c340c6fa8d..0bdfb3a042 100644
--- a/gtk/gtkstringsorter.h
+++ b/gtk/gtkstringsorter.h
@@ -47,6 +47,31 @@ GDK_AVAILABLE_IN_ALL
void gtk_string_sorter_set_ignore_case (GtkStringSorter *self,
gboolean ignore_case);
+/**
+ * GtkCollateMode:
+ * @GTK_COLLATE_MODE_NONE: Don't do any collation
+ * @GTK_COLLATE_MODE_LOCALE: Use [func@GLib.g_utf8_collate_key]
+ * @GTK_COLLATE_MODE_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_COLLATE_MODE_NONE.
+ */
+typedef enum
+{
+ GTK_COLLATE_MODE_NONE,
+ GTK_COLLATE_MODE_LOCALE,
+ GTK_COLLATE_MODE_FILENAME
+} GtkCollateMode;
+
+GDK_AVAILABLE_IN_4_10
+void gtk_string_sorter_set_collate_mode (GtkStringSorter *self,
+ GtkCollateMode collate_mode);
+GDK_AVAILABLE_IN_4_10
+GtkCollateMode gtk_string_sorter_get_collate_mode (GtkStringSorter *self);
+
G_END_DECLS
#endif /* __GTK_STRING_SORTER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]