mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 14:10:30 +00:00
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.
This commit is contained in:
parent
8ba7840528
commit
141aac1a60
@ -42,6 +42,7 @@ struct _GtkStringSorter
|
|||||||
GtkSorter parent_instance;
|
GtkSorter parent_instance;
|
||||||
|
|
||||||
gboolean ignore_case;
|
gboolean ignore_case;
|
||||||
|
GtkCollation collation;
|
||||||
|
|
||||||
GtkExpression *expression;
|
GtkExpression *expression;
|
||||||
};
|
};
|
||||||
@ -50,6 +51,7 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_EXPRESSION,
|
PROP_EXPRESSION,
|
||||||
PROP_IGNORE_CASE,
|
PROP_IGNORE_CASE,
|
||||||
|
PROP_COLLATION,
|
||||||
NUM_PROPERTIES
|
NUM_PROPERTIES
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,10 +62,13 @@ static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
|||||||
static char *
|
static char *
|
||||||
gtk_string_sorter_get_key (GtkExpression *expression,
|
gtk_string_sorter_get_key (GtkExpression *expression,
|
||||||
gboolean ignore_case,
|
gboolean ignore_case,
|
||||||
|
GtkCollation collation,
|
||||||
gpointer item1)
|
gpointer item1)
|
||||||
{
|
{
|
||||||
GValue value = G_VALUE_INIT;
|
GValue value = G_VALUE_INIT;
|
||||||
|
const char *string;
|
||||||
char *s;
|
char *s;
|
||||||
|
char *key;
|
||||||
|
|
||||||
if (expression == NULL)
|
if (expression == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -71,23 +76,35 @@ gtk_string_sorter_get_key (GtkExpression *expression,
|
|||||||
if (!gtk_expression_evaluate (expression, item1, &value))
|
if (!gtk_expression_evaluate (expression, item1, &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* If strings are NULL, order them before "". */
|
string = g_value_get_string (&value);
|
||||||
if (ignore_case)
|
|
||||||
{
|
|
||||||
char *t;
|
|
||||||
|
|
||||||
t = g_utf8_casefold (g_value_get_string (&value), -1);
|
if (ignore_case)
|
||||||
s = g_utf8_collate_key (t, -1);
|
s = g_utf8_casefold (string, -1);
|
||||||
g_free (t);
|
|
||||||
}
|
|
||||||
else
|
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);
|
g_value_unset (&value);
|
||||||
|
|
||||||
return s;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkOrdering
|
static GtkOrdering
|
||||||
@ -102,8 +119,8 @@ gtk_string_sorter_compare (GtkSorter *sorter,
|
|||||||
if (self->expression == NULL)
|
if (self->expression == NULL)
|
||||||
return GTK_ORDERING_EQUAL;
|
return GTK_ORDERING_EQUAL;
|
||||||
|
|
||||||
s1 = gtk_string_sorter_get_key (self->expression, self->ignore_case, item1);
|
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, item2);
|
s2 = gtk_string_sorter_get_key (self->expression, self->ignore_case, self->collation, item2);
|
||||||
|
|
||||||
result = gtk_ordering_from_cmpfunc (g_strcmp0 (s1, s2));
|
result = gtk_ordering_from_cmpfunc (g_strcmp0 (s1, s2));
|
||||||
|
|
||||||
@ -131,6 +148,7 @@ struct _GtkStringSortKeys
|
|||||||
|
|
||||||
GtkExpression *expression;
|
GtkExpression *expression;
|
||||||
gboolean ignore_case;
|
gboolean ignore_case;
|
||||||
|
GtkCollation collation;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -173,7 +191,7 @@ gtk_string_sort_keys_init_key (GtkSortKeys *keys,
|
|||||||
GtkStringSortKeys *self = (GtkStringSortKeys *) keys;
|
GtkStringSortKeys *self = (GtkStringSortKeys *) keys;
|
||||||
char **key = (char **) key_memory;
|
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
|
static void
|
||||||
@ -209,6 +227,7 @@ gtk_string_sort_keys_new (GtkStringSorter *self)
|
|||||||
|
|
||||||
result->expression = gtk_expression_ref (self->expression);
|
result->expression = gtk_expression_ref (self->expression);
|
||||||
result->ignore_case = self->ignore_case;
|
result->ignore_case = self->ignore_case;
|
||||||
|
result->collation = self->collation;
|
||||||
|
|
||||||
return (GtkSortKeys *) result;
|
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));
|
gtk_string_sorter_set_ignore_case (self, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_COLLATION:
|
||||||
|
gtk_string_sorter_set_collation (self, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_string_sorter_get_property (GObject *object,
|
gtk_string_sorter_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
@ -255,6 +278,10 @@ gtk_string_sorter_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, self->ignore_case);
|
g_value_set_boolean (value, self->ignore_case);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_COLLATION:
|
||||||
|
g_value_set_enum (value, self->collation);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
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)
|
* 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] =
|
properties[PROP_IGNORE_CASE] =
|
||||||
g_param_spec_boolean ("ignore-case", NULL, NULL,
|
g_param_spec_boolean ("ignore-case", NULL, NULL,
|
||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
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);
|
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -311,6 +351,7 @@ static void
|
|||||||
gtk_string_sorter_init (GtkStringSorter *self)
|
gtk_string_sorter_init (GtkStringSorter *self)
|
||||||
{
|
{
|
||||||
self->ignore_case = TRUE;
|
self->ignore_case = TRUE;
|
||||||
|
self->collation = GTK_COLLATION_UNICODE;
|
||||||
|
|
||||||
gtk_sorter_changed_with_keys (GTK_SORTER (self),
|
gtk_sorter_changed_with_keys (GTK_SORTER (self),
|
||||||
GTK_SORTER_CHANGE_DIFFERENT,
|
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]);
|
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]);
|
||||||
|
}
|
||||||
|
@ -47,6 +47,32 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
void gtk_string_sorter_set_ignore_case (GtkStringSorter *self,
|
void gtk_string_sorter_set_ignore_case (GtkStringSorter *self,
|
||||||
gboolean ignore_case);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_STRING_SORTER_H__ */
|
#endif /* __GTK_STRING_SORTER_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user