[gtk/wip/otte/sortlistmodel: 8/33] stringsorter: Implement GtkSortKeys
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/sortlistmodel: 8/33] stringsorter: Implement GtkSortKeys
- Date: Wed, 22 Jul 2020 01:23:23 +0000 (UTC)
commit 61cdbebf6a919604caf5bf79218e3e689802ab5a
Author: Benjamin Otte <otte redhat com>
Date: Wed Jul 15 20:28:45 2020 +0200
stringsorter: Implement GtkSortKeys
gtk/gtkstringsorter.c | 188 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 137 insertions(+), 51 deletions(-)
---
diff --git a/gtk/gtkstringsorter.c b/gtk/gtkstringsorter.c
index 2879faf140..24244162a9 100644
--- a/gtk/gtkstringsorter.c
+++ b/gtk/gtkstringsorter.c
@@ -22,6 +22,7 @@
#include "gtkstringsorter.h"
#include "gtkintl.h"
+#include "gtksorterprivate.h"
#include "gtktypebuiltins.h"
/**
@@ -58,70 +59,58 @@ G_DEFINE_TYPE (GtkStringSorter, gtk_string_sorter, GTK_TYPE_SORTER)
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
-static GtkOrdering
-gtk_string_sorter_compare (GtkSorter *sorter,
- gpointer item1,
- gpointer item2)
+static char *
+gtk_string_sorter_get_key (GtkExpression *expression,
+ gboolean ignore_case,
+ gpointer item1)
{
- GtkStringSorter *self = GTK_STRING_SORTER (sorter);
- GValue value1 = G_VALUE_INIT;
- GValue value2 = G_VALUE_INIT;
- const char *s1, *s2;
- gboolean res1, res2;
- GtkOrdering result;
+ GValue value = G_VALUE_INIT;
+ char *s;
- if (self->expression == NULL)
- return GTK_ORDERING_EQUAL;
+ if (expression == NULL)
+ return NULL;
- res1 = gtk_expression_evaluate (self->expression, item1, &value1);
- res2 = gtk_expression_evaluate (self->expression, item2, &value2);
+ if (!gtk_expression_evaluate (expression, item1, &value))
+ return NULL;
- /* If items don't evaluate, order them at the end, so they aren't
- * in the way. */
- if (!res1)
+ /* If strings are NULL, order them before "". */
+ if (ignore_case)
{
- result = res2 ? GTK_ORDERING_LARGER : GTK_ORDERING_EQUAL;
- goto out;
+ char *t;
+
+ t = g_utf8_casefold (g_value_get_string (&value), -1);
+ s = g_utf8_collate_key (t, -1);
+ g_free (t);
}
- else if (!res2)
+ else
{
- result = GTK_ORDERING_SMALLER;
- goto out;
+ s = g_utf8_collate_key (g_value_get_string (&value), -1);
}
- s1 = g_value_get_string (&value1);
- s2 = g_value_get_string (&value2);
+ g_value_unset (&value);
- /* If strings are NULL, order them before "". */
- if (s1 == NULL)
- {
- result = s2 == NULL ? GTK_ORDERING_EQUAL : GTK_ORDERING_SMALLER;
- goto out;
- }
- else if (s2 == NULL)
- {
- result = GTK_ORDERING_LARGER;
- goto out;
- }
+ return s;
+}
- if (self->ignore_case)
- {
- char *t1, *t2;
+static GtkOrdering
+gtk_string_sorter_compare (GtkSorter *sorter,
+ gpointer item1,
+ gpointer item2)
+{
+ GtkStringSorter *self = GTK_STRING_SORTER (sorter);
+ char *s1, *s2;
+ GtkOrdering result;
- t1 = g_utf8_casefold (s1, -1);
- t2 = g_utf8_casefold (s2, -1);
+ if (self->expression == NULL)
+ return GTK_ORDERING_EQUAL;
- result = gtk_ordering_from_cmpfunc (g_utf8_collate (t1, t2));
+ s1 = gtk_string_sorter_get_key (self->expression, self->ignore_case, item1);
+ s2 = gtk_string_sorter_get_key (self->expression, self->ignore_case, item2);
- g_free (t1);
- g_free (t2);
- }
- else
- result = gtk_ordering_from_cmpfunc (g_utf8_collate (s1, s2));
+ result = gtk_ordering_from_cmpfunc (g_strcmp0 (s1, s2));
-out:
- g_value_unset (&value1);
- g_value_unset (&value2);
+ g_free (s1);
+ g_free (s2);
return result;
}
@@ -137,6 +126,95 @@ gtk_string_sorter_get_order (GtkSorter *sorter)
return GTK_SORTER_ORDER_PARTIAL;
}
+typedef struct _GtkStringSortKeys GtkStringSortKeys;
+struct _GtkStringSortKeys
+{
+ GtkSortKeys keys;
+
+ GtkExpression *expression;
+ gboolean ignore_case;
+};
+
+static void
+gtk_string_sort_keys_free (GtkSortKeys *keys)
+{
+ GtkStringSortKeys *self = (GtkStringSortKeys *) keys;
+
+ gtk_expression_unref (self->expression);
+ g_slice_free (GtkStringSortKeys, self);
+}
+
+static int
+gtk_string_sort_keys_compare (gconstpointer a,
+ gconstpointer b,
+ gpointer unused)
+{
+ const char *sa = *(const char **) a;
+ const char *sb = *(const char **) b;
+
+ if (sa == NULL)
+ return sb == NULL ? GTK_ORDERING_EQUAL : GTK_ORDERING_LARGER;
+ else if (sb == NULL)
+ return GTK_ORDERING_SMALLER;
+
+ return gtk_ordering_from_cmpfunc (strcmp (sa, sb));
+}
+
+static gboolean
+gtk_string_sort_keys_is_compatible (GtkSortKeys *keys,
+ GtkSortKeys *other)
+{
+ return FALSE;
+}
+
+static void
+gtk_string_sort_keys_init_key (GtkSortKeys *keys,
+ gpointer item,
+ gpointer key_memory)
+{
+ GtkStringSortKeys *self = (GtkStringSortKeys *) keys;
+ char **key = (char **) key_memory;
+
+ *key = gtk_string_sorter_get_key (self->expression, self->ignore_case, item);
+}
+
+static void
+gtk_string_sort_keys_clear_key (GtkSortKeys *keys,
+ gpointer key_memory)
+{
+ char **key = (char **) key_memory;
+
+ g_free (*key);
+}
+
+static const GtkSortKeysClass GTK_STRING_SORT_KEYS_CLASS =
+{
+ gtk_string_sort_keys_free,
+ gtk_string_sort_keys_compare,
+ gtk_string_sort_keys_is_compatible,
+ gtk_string_sort_keys_init_key,
+ gtk_string_sort_keys_clear_key,
+};
+
+static GtkSortKeys *
+gtk_string_sort_keys_new (GtkStringSorter *self)
+{
+ GtkStringSortKeys *result;
+
+ if (self->expression == NULL)
+ return gtk_sort_keys_new_equal ();
+
+ result = gtk_sort_keys_new (GtkStringSortKeys,
+ >K_STRING_SORT_KEYS_CLASS,
+ sizeof (char *),
+ sizeof (char *));
+
+ result->expression = gtk_expression_ref (self->expression);
+ result->ignore_case = self->ignore_case;
+
+ return (GtkSortKeys *) result;
+}
+
static void
gtk_string_sorter_set_property (GObject *object,
guint prop_id,
@@ -239,6 +317,10 @@ static void
gtk_string_sorter_init (GtkStringSorter *self)
{
self->ignore_case = TRUE;
+
+ gtk_sorter_changed_with_keys (GTK_SORTER (self),
+ GTK_SORTER_CHANGE_DIFFERENT,
+ gtk_string_sort_keys_new (self));
}
/**
@@ -306,7 +388,9 @@ gtk_string_sorter_set_expression (GtkStringSorter *self,
if (expression)
self->expression = gtk_expression_ref (expression);
- gtk_sorter_changed (GTK_SORTER (self), GTK_SORTER_CHANGE_DIFFERENT);
+ 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_EXPRESSION]);
}
@@ -345,7 +429,9 @@ gtk_string_sorter_set_ignore_case (GtkStringSorter *self,
self->ignore_case = ignore_case;
- gtk_sorter_changed (GTK_SORTER (self), ignore_case ? GTK_SORTER_CHANGE_LESS_STRICT :
GTK_SORTER_CHANGE_MORE_STRICT);
+ gtk_sorter_changed_with_keys (GTK_SORTER (self),
+ ignore_case ? GTK_SORTER_CHANGE_LESS_STRICT : GTK_SORTER_CHANGE_MORE_STRICT,
+ gtk_string_sort_keys_new (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IGNORE_CASE]);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]