summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2020-06-01 21:07:53 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2020-06-01 21:07:53 +0100
commitebaa96c0fadf4081fc772a01b76b3821b138eee4 (patch)
tree16d56d5c0dbca38aa782f2bcdb0fc548263eb64b
parentfb3d08c651d5aa71df5022a2af9237b9e14056d4 (diff)
downloadgtk+-ebaa96c0fadf4081fc772a01b76b3821b138eee4.tar.gz
Turn GtkExpression into a GTypeInstance
Since it's a type with sub-classes, we need to use GTypeInstance (at the very least), otherwise we won't be able to address each sub-class as such. This is similar to how GskRenderNode and GdkEvent are handled, with the added difficulty that GtkExpression is meant to be used in properties, in order to be deserialised by GtkBuilder. This requires adding a GParamSpec sub-class that we can match on from within GtkBuilder, alongside some convenience API for storing a GtkExpression inside a GValue.
-rw-r--r--gtk/gtkbuilder.c6
-rw-r--r--gtk/gtkdropdown.c15
-rw-r--r--gtk/gtkexpression.c738
-rw-r--r--gtk/gtkexpression.h74
-rw-r--r--gtk/gtknumericsorter.c29
-rw-r--r--gtk/gtkstringfilter.c17
-rw-r--r--gtk/gtkstringsorter.c17
7 files changed, 753 insertions, 143 deletions
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 385b78db65..187d95720d 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -534,11 +534,9 @@ gtk_builder_get_parameters (GtkBuilder *builder,
g_value_init (&property_value, G_PARAM_SPEC_VALUE_TYPE (prop->pspec));
if (G_PARAM_SPEC_VALUE_TYPE (prop->pspec) == GTK_TYPE_EXPRESSION)
- g_value_set_boxed (&property_value, prop->value);
+ gtk_value_set_expression (&property_value, prop->value);
else
- {
- g_assert_not_reached();
- }
+ g_assert_not_reached ();
}
else if (prop->bound && (!prop->text || prop->text->len == 0))
{
diff --git a/gtk/gtkdropdown.c b/gtk/gtkdropdown.c
index 4759186a49..c4f3e37f19 100644
--- a/gtk/gtkdropdown.c
+++ b/gtk/gtkdropdown.c
@@ -315,7 +315,7 @@ gtk_drop_down_get_property (GObject *object,
break;
case PROP_EXPRESSION:
- g_value_set_boxed (value, self->expression);
+ gtk_value_set_expression (value, self->expression);
break;
default:
@@ -355,7 +355,7 @@ gtk_drop_down_set_property (GObject *object,
break;
case PROP_EXPRESSION:
- gtk_drop_down_set_expression (self, g_value_get_boxed (value));
+ gtk_drop_down_set_expression (self, gtk_value_get_expression (value));
break;
default:
@@ -497,7 +497,7 @@ gtk_drop_down_class_init (GtkDropDownClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
- * GtkDropDown:expression:
+ * GtkDropDown:expression: (type GtkExpression)
*
* An expression to evaluate to obtain strings to match against the search
* term (see #GtkDropDown:enable-search). If #GtkDropDown:factory is not set,
@@ -505,11 +505,10 @@ gtk_drop_down_class_init (GtkDropDownClass *klass)
* default factory.
*/
properties[PROP_EXPRESSION] =
- g_param_spec_boxed ("expression",
- P_("Expression"),
- P_("Expression to determine strings to search for"),
- GTK_TYPE_EXPRESSION,
- G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ gtk_param_spec_expression ("expression",
+ P_("Expression"),
+ P_("Expression to determine strings to search for"),
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c
index 394bdd42e9..2fcf29c83b 100644
--- a/gtk/gtkexpression.c
+++ b/gtk/gtkexpression.c
@@ -30,7 +30,7 @@
*
* GtkExpression provides a way to describe references to #GValues.
*
- * An expression needs to be `evaluated` to obtain the value that it currently refers
+ * An expression needs to be "evaluated" to obtain the value that it currently refers
* to. An evaluation always happens in the context of a current object called `this`
* (it mirrors the behavior of object-oriented languages), which may or may not
* influence the result of the evaluation. Use gtk_expression_evaluate() for
@@ -43,7 +43,7 @@
*
* By default, expressions are not paying attention to changes and evaluation is
* just a snapshot of the current state at a given time. To get informed about
- * changes, an expression needs to be `watched` via a #GtkExpressionWatch, which
+ * changes, an expression needs to be "watched" via a #GtkExpressionWatch, which
* will cause a callback to be called whenever the value of the expression may
* have changed. gtk_expression_watch() starts watching an expression, and
* gtk_expression_watch_unwatch() stops.
@@ -89,33 +89,54 @@
* </closure>
* ]|
*/
+
+
+/**
+ * GtkExpression: (ref-func gtk_expression_ref) (unref-func gtk_expression_unref) (set-value-func gtk_value_set_expression) (get-value-func gtk_value_get_expression)
+ *
+ * The `GtkExpression` structure contains only private data.
+ */
+
typedef struct _GtkExpressionClass GtkExpressionClass;
+typedef struct _GtkExpressionSubWatch GtkExpressionSubWatch;
+typedef struct _GtkExpressionTypeInfo GtkExpressionTypeInfo;
struct _GtkExpression
{
- const GtkExpressionClass *expression_class;
+ GTypeInstance parent_instance;
+
+ gatomicrefcount ref_count;
+
GType value_type;
GtkExpression *owner;
};
-typedef struct _GtkExpressionSubWatch GtkExpressionSubWatch;
-
-struct _GtkExpressionWatch
+struct _GtkExpressionClass
{
- GtkExpression *expression;
- GObject *this;
- GDestroyNotify user_destroy;
- GtkExpressionNotify notify;
- gpointer user_data;
- guchar sub[0];
+ GTypeClass parent_class;
+
+ void (* finalize) (GtkExpression *expr);
+ gboolean (* is_static) (GtkExpression *expr);
+ gboolean (* evaluate) (GtkExpression *expr,
+ gpointer this,
+ GValue *value);
+
+ gsize (* watch_size) (GtkExpression *expr);
+ void (* watch) (GtkExpression *self,
+ GtkExpressionSubWatch *watch,
+ gpointer this_,
+ GtkExpressionNotify notify,
+ gpointer user_data);
+ void (* unwatch) (GtkExpression *self,
+ GtkExpressionSubWatch *watch);
};
-struct _GtkExpressionClass
+struct _GtkExpressionTypeInfo
{
- gsize struct_size;
- const char *type_name;
+ gsize instance_size;
+ void (* instance_init) (GtkExpression *expr);
void (* finalize) (GtkExpression *expr);
gboolean (* is_static) (GtkExpression *expr);
gboolean (* evaluate) (GtkExpression *expr,
@@ -132,64 +153,500 @@ struct _GtkExpressionClass
GtkExpressionSubWatch *watch);
};
+struct _GtkExpressionWatch
+{
+ GtkExpression *expression;
+ GObject *this;
+ GDestroyNotify user_destroy;
+ GtkExpressionNotify notify;
+ gpointer user_data;
+ guchar sub[0];
+};
+
+#define GTK_EXPRESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_EXPRESSION, GtkExpressionClass))
+
+/*< private >
+ * GTK_DEFINE_EXPRESSION_TYPE:
+ * @TypeName: the type name, in camel case
+ * @type_name: the type name, in snake case
+ * @type_info: the address of the #GtkExpressionTypeInfo for the expression type
+ *
+ * Registers a new #GtkExpression subclass with the given @TypeName and @type_info.
+ *
+ * Similarly to %G_DEFINE_TYPE, this macro will generate a `get_type()`
+ * function that registers the event type.
+ *
+ * You can specify code to be run after the type registration; the #GType of
+ * the event is available in the `gtk_define_expression_type_id` variable.
+ */
+#define GTK_DEFINE_EXPRESSION_TYPE(TypeName, type_name, type_info) \
+GType \
+type_name ## _get_type (void) \
+{ \
+ static volatile gsize gtk_define_expression_type_id__volatile; \
+ if (g_once_init_enter (&gtk_define_expression_type_id__volatile)) \
+ { \
+ GType gtk_define_expression_type_id = \
+ gtk_expression_type_register_static (g_intern_static_string (#TypeName), type_info); \
+ g_once_init_leave (&gtk_define_expression_type_id__volatile, gtk_define_expression_type_id); \
+ } \
+ return gtk_define_expression_type_id__volatile; \
+}
+
+#define GTK_EXPRESSION_SUPER(expr) \
+ ((GtkExpressionClass *) g_type_class_peek (g_type_parent (G_TYPE_FROM_INSTANCE (expr))))
+
+/* {{{ GtkExpression internals */
+
+static void
+value_expression_init (GValue *value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+static void
+value_expression_free_value (GValue *value)
+{
+ if (value->data[0].v_pointer != NULL)
+ gtk_expression_unref (value->data[0].v_pointer);
+}
+
+static void
+value_expression_copy_value (const GValue *src,
+ GValue *dst)
+{
+ if (src->data[0].v_pointer != NULL)
+ dst->data[0].v_pointer = gtk_expression_ref (src->data[0].v_pointer);
+ else
+ dst->data[0].v_pointer = NULL;
+}
+
+static gpointer
+value_expression_peek_pointer (const GValue *value)
+{
+ return value->data[0].v_pointer;
+}
+
+static char *
+value_expression_collect_value (GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ GtkExpression *expression = collect_values[0].v_pointer;
+
+ if (expression == NULL)
+ {
+ value->data[0].v_pointer = NULL;
+ return NULL;
+ }
+
+ if (expression->parent_instance.g_class == NULL)
+ return g_strconcat ("invalid unclassed GtkExpression pointer for "
+ "value type '",
+ G_VALUE_TYPE_NAME (value),
+ "'",
+ NULL);
+
+ value->data[0].v_pointer = gtk_expression_ref (expression);
+
+ return NULL;
+}
+
+static gchar *
+value_expression_lcopy_value (const GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ GtkExpression **expression_p = collect_values[0].v_pointer;
+
+ if (expression_p == NULL)
+ return g_strconcat ("value location for '",
+ G_VALUE_TYPE_NAME (value),
+ "' passed as NULL",
+ NULL);
+
+ if (value->data[0].v_pointer == NULL)
+ *expression_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *expression_p = value->data[0].v_pointer;
+ else
+ *expression_p = gtk_expression_ref (value->data[0].v_pointer);
+
+ return NULL;
+}
+
/**
- * GtkExpression: (ref-func gtk_expression_ref) (unref-func gtk_expression_unref)
+ * gtk_value_set_expression:
+ * @value: a #GValue initialized with type %GTK_TYPE_EXPRESSION
+ * @expression: a #GtkExpression
*
- * The `GtkExpression` structure contains only private data.
+ * Stores the given #GtkExpression inside @value.
+ *
+ * The #GValue will acquire a reference to the @expression.
*/
+void
+gtk_value_set_expression (GValue *value,
+ GtkExpression *expression)
+{
+ g_return_if_fail (G_VALUE_HOLDS (value, GTK_TYPE_EXPRESSION));
-G_DEFINE_BOXED_TYPE (GtkExpression, gtk_expression,
- gtk_expression_ref,
- gtk_expression_unref)
+ GtkExpression *old_expression = value->data[0].v_pointer;
-/*< private >
- * gtk_expression_alloc:
- * @expression_class: class structure for this expression
- * @value_type: the type of the value returned by this expression
+ if (expression != NULL)
+ {
+ g_return_if_fail (GTK_IS_EXPRESSION (expression));
+
+ value->data[0].v_pointer = gtk_expression_ref (expression);
+ }
+ else
+ {
+ value->data[0].v_pointer = NULL;
+ }
+
+ if (old_expression != NULL)
+ gtk_expression_unref (old_expression);
+}
+
+/**
+ * gtk_value_take_expression:
+ * @value: a #GValue initialized with type %GTK_TYPE_EXPRESSION
+ * @expression: (transfer full) (nullable): a #GtkExpression
*
- * Returns: (transfer full): the newly created #GtkExpression
+ * Stores the given #GtkExpression inside @value.
+ *
+ * This function transfers the ownership of the @expression to the #GValue.
*/
-static gpointer
-gtk_expression_alloc (const GtkExpressionClass *expression_class,
- GType value_type)
+void
+gtk_value_take_expression (GValue *value,
+ GtkExpression *expression)
{
- GtkExpression *self;
+ g_return_if_fail (G_VALUE_HOLDS (value, GTK_TYPE_EXPRESSION));
- g_return_val_if_fail (expression_class != NULL, NULL);
+ GtkExpression *old_expression = value->data[0].v_pointer;
- self = g_atomic_rc_box_alloc0 (expression_class->struct_size);
+ if (expression != NULL)
+ {
+ g_return_if_fail (GTK_IS_EXPRESSION (expression));
- self->expression_class = expression_class;
- self->value_type = value_type;
+ value->data[0].v_pointer = expression;
+ }
+ else
+ {
+ value->data[0].v_pointer = NULL;
+ }
- return self;
+ if (old_expression != NULL)
+ gtk_expression_unref (old_expression);
+}
+
+/**
+ * gtk_value_get_expression:
+ * @value: a #GValue initialized with type %GTK_TYPE_EXPRESSION
+ *
+ * Retrieves the #GtkExpression stored inside the given @value.
+ *
+ * Returns: (transfer none) (nullable): a #GtkExpression
+ */
+GtkExpression *
+gtk_value_get_expression (const GValue *value)
+{
+ g_return_val_if_fail (G_VALUE_HOLDS (value, GTK_TYPE_EXPRESSION), NULL);
+
+ return value->data[0].v_pointer;
+}
+
+/**
+ * gtk_value_dup_expression:
+ * @value: a #GValue initialized with type %GTK_TYPE_EXPRESSION
+ *
+ * Retrieves the #GtkExpression stored inside the given @value, and acquires
+ * a reference to it.
+ *
+ * Returns: (transfer full) (nullable): a #GtkExpression
+ */
+GtkExpression *
+gtk_value_dup_expression (const GValue *value)
+{
+ g_return_val_if_fail (G_VALUE_HOLDS (value, GTK_TYPE_EXPRESSION), NULL);
+
+ if (value->data[0].v_pointer == NULL)
+ return NULL;
+
+ GtkExpression *expression = value->data[0].v_pointer;
+
+ return gtk_expression_ref (expression);
+}
+
+static void
+param_expression_init (GParamSpec *pspec)
+{
+}
+
+static void
+param_expression_set_default (GParamSpec *pspec,
+ GValue *value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+static gboolean
+param_expression_validate (GParamSpec *pspec,
+ GValue *value)
+{
+ GtkParamSpecExpression *espec = GTK_PARAM_SPEC_EXPRESSION (pspec);
+ GtkExpression *expr = value->data[0].v_pointer;
+ guint changed = 0;
+
+ if (expr != NULL &&
+ !g_value_type_compatible (G_TYPE_FROM_INSTANCE (expr), G_PARAM_SPEC_VALUE_TYPE (espec)))
+ {
+ gtk_expression_unref (expr);
+ value->data[0].v_pointer = NULL;
+ changed++;
+ }
+
+ return changed;
+}
+
+static gint
+param_expression_values_cmp (GParamSpec *pspec,
+ const GValue *value1,
+ const GValue *value2)
+{
+ guint8 *p1 = value1->data[0].v_pointer;
+ guint8 *p2 = value2->data[0].v_pointer;
+
+ return p1 < p2 ? -1 : p1 > p2;
+}
+
+GType
+gtk_param_expression_get_type (void)
+{
+ static volatile gsize param_expression_type__volatile;
+
+ if (g_once_init_enter (&param_expression_type__volatile))
+ {
+ const GParamSpecTypeInfo pspec_info = {
+ sizeof (GtkParamSpecExpression),
+ 16,
+ param_expression_init,
+ GTK_TYPE_EXPRESSION,
+ NULL,
+ param_expression_set_default,
+ param_expression_validate,
+ param_expression_values_cmp,
+ };
+
+ GType param_expression_type =
+ g_param_type_register_static (g_intern_static_string ("GtkParamSpecExpression"),
+ &pspec_info);
+
+ g_once_init_leave (&param_expression_type__volatile, param_expression_type);
+ }
+
+ return param_expression_type__volatile;
+}
+
+/**
+ * gtk_param_spec_expression:
+ * @name: canonical name of the property
+ * @nick: a user-readable name for the property
+ * @blurb: a user-readable description of the property
+ * @flags: flags for the property
+ *
+ * Creates a new #GParamSpec instance for a property holding a #GtkExpression.
+ *
+ * See g_param_spec_internal() for details on the property strings.
+ *
+ * Returns: (transfer full): a newly created property specification
+ */
+GParamSpec *
+gtk_param_spec_expression (const char *name,
+ const char *nick,
+ const char *blurb,
+ GParamFlags flags)
+{
+ GParamSpec *pspec = g_param_spec_internal (GTK_TYPE_PARAM_SPEC_EXPRESSION,
+ name, nick, blurb,
+ flags);
+
+ pspec->value_type = GTK_TYPE_EXPRESSION;
+
+ return pspec;
+}
+
+/* }}} */
+
+/* {{{ GtkExpression internals */
+
+static void
+gtk_expression_real_finalize (GtkExpression *self)
+{
+ g_type_free_instance ((GTypeInstance *) self);
}
static gsize
-gtk_expression_watch_size_static (GtkExpression *self)
+gtk_expression_real_watch_size (GtkExpression *self)
{
return 0;
}
static void
-gtk_expression_watch_static (GtkExpression *self,
- GtkExpressionSubWatch *watch,
- gpointer this_,
- GtkExpressionNotify notify,
- gpointer user_data)
+gtk_expression_real_watch (GtkExpression *self,
+ GtkExpressionSubWatch *watch,
+ gpointer this_,
+ GtkExpressionNotify notify,
+ gpointer user_data)
{
}
static void
-gtk_expression_unwatch_static (GtkExpression *self,
- GtkExpressionSubWatch *watch)
+gtk_expression_real_unwatch (GtkExpression *self,
+ GtkExpressionSubWatch *watch)
{
}
static gsize
gtk_expression_watch_size (GtkExpression *self)
{
- return self->expression_class->watch_size (self);
+ return GTK_EXPRESSION_GET_CLASS (self)->watch_size (self);
+}
+
+static void
+gtk_expression_class_init (GtkExpressionClass *klass)
+{
+ klass->finalize = gtk_expression_real_finalize;
+ klass->watch_size = gtk_expression_real_watch_size;
+ klass->watch = gtk_expression_real_watch;
+ klass->unwatch = gtk_expression_real_unwatch;
+}
+
+static void
+gtk_expression_init (GtkExpression *self)
+{
+ g_atomic_ref_count_init (&self->ref_count);
+}
+
+GType
+gtk_expression_get_type (void)
+{
+ static volatile gsize expression_type__volatile;
+
+ if (g_once_init_enter (&expression_type__volatile))
+ {
+ static const GTypeFundamentalInfo finfo = {
+ (G_TYPE_FLAG_CLASSED |
+ G_TYPE_FLAG_INSTANTIATABLE |
+ G_TYPE_FLAG_DERIVABLE |
+ G_TYPE_FLAG_DEEP_DERIVABLE),
+ };
+
+ static const GTypeValueTable value_table = {
+ value_expression_init,
+ value_expression_free_value,
+ value_expression_copy_value,
+ value_expression_peek_pointer,
+ "p",
+ value_expression_collect_value,
+ "p",
+ value_expression_lcopy_value,
+ };
+
+ const GTypeInfo event_info = {
+ /* Class */
+ sizeof (GtkExpressionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_expression_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+
+ /* Instance */
+ sizeof (GtkExpression),
+ 0,
+ (GInstanceInitFunc) gtk_expression_init,
+
+ /* GValue */
+ &value_table,
+ };
+
+ GType expression_type =
+ g_type_register_fundamental (g_type_fundamental_next (),
+ g_intern_static_string ("GtkExpression"),
+ &event_info, &finfo,
+ G_TYPE_FLAG_ABSTRACT);
+
+ g_once_init_leave (&expression_type__volatile, expression_type);
+ }
+
+ return expression_type__volatile;
+}
+
+static void
+gtk_expression_generic_class_init (gpointer g_class,
+ gpointer class_data)
+{
+ GtkExpressionTypeInfo *info = class_data;
+ GtkExpressionClass *expression_class = g_class;
+
+ /* Mandatory */
+ expression_class->is_static = info->is_static;
+ expression_class->evaluate = info->evaluate;
+
+ /* Optional */
+ if (info->finalize != NULL)
+ expression_class->finalize = info->finalize;
+ if (info->watch_size != NULL)
+ expression_class->watch_size = info->watch_size;
+ if (info->watch != NULL)
+ expression_class->watch = info->watch;
+ if (info->unwatch != NULL)
+ expression_class->unwatch = info->unwatch;
+
+ g_free (info);
+}
+
+static GType
+gtk_expression_type_register_static (const char *type_name,
+ const GtkExpressionTypeInfo *type_info)
+{
+ GTypeInfo info;
+
+ info.class_size = sizeof (GtkExpressionClass);
+ info.base_init = NULL;
+ info.base_finalize = NULL;
+ info.class_init = gtk_expression_generic_class_init;
+ info.class_finalize = NULL;
+ info.class_data = g_memdup (type_info, sizeof (GtkExpressionTypeInfo));
+
+ info.instance_size = type_info->instance_size;
+ info.n_preallocs = 0;
+ info.instance_init = (GInstanceInitFunc) type_info->instance_init;
+ info.value_table = NULL;
+
+ return g_type_register_static (GTK_TYPE_EXPRESSION, type_name, &info, 0);
+}
+
+/*< private >
+ * gtk_expression_alloc:
+ * @expression_type: the type of expression to create
+ * @value_type: the type of the value returned by this expression
+ *
+ * Returns: (transfer full): the newly created #GtkExpression
+ */
+static gpointer
+gtk_expression_alloc (GType expression_type,
+ GType value_type)
+{
+ GtkExpression *self;
+
+ self = (GtkExpression *) g_type_create_instance (expression_type);
+
+ self->value_type = value_type;
+
+ return self;
}
static void
@@ -199,17 +656,19 @@ gtk_expression_subwatch_init (GtkExpression *self,
GtkExpressionNotify notify,
gpointer user_data)
{
- self->expression_class->watch (self, watch, this, notify, user_data);
+ GTK_EXPRESSION_GET_CLASS (self)->watch (self, watch, this, notify, user_data);
}
static void
gtk_expression_subwatch_finish (GtkExpression *self,
GtkExpressionSubWatch *watch)
{
- self->expression_class->unwatch (self, watch);
+ GTK_EXPRESSION_GET_CLASS (self)->unwatch (self, watch);
}
-/*** CONSTANT ***/
+/* }}} */
+
+/* {{{ GtkConstantExpression */
typedef struct _GtkConstantExpression GtkConstantExpression;
@@ -226,6 +685,8 @@ gtk_constant_expression_finalize (GtkExpression *expr)
GtkConstantExpression *self = (GtkConstantExpression *) expr;
g_value_unset (&self->value);
+
+ GTK_EXPRESSION_SUPER (expr)->finalize (expr);
}
static gboolean
@@ -246,18 +707,22 @@ gtk_constant_expression_evaluate (GtkExpression *expr,
return TRUE;
}
-static const GtkExpressionClass GTK_CONSTANT_EXPRESSION_CLASS =
+static const GtkExpressionTypeInfo gtk_constant_expression_info =
{
sizeof (GtkConstantExpression),
- "GtkConstantExpression",
+ NULL,
gtk_constant_expression_finalize,
gtk_constant_expression_is_static,
gtk_constant_expression_evaluate,
- gtk_expression_watch_size_static,
- gtk_expression_watch_static,
- gtk_expression_unwatch_static
+ NULL,
+ NULL,
+ NULL,
};
+GTK_DEFINE_EXPRESSION_TYPE (GtkConstantExpression,
+ gtk_constant_expression,
+ &gtk_constant_expression_info)
+
/**
* gtk_constant_expression_new:
* @value_type: The type of the object
@@ -310,19 +775,23 @@ gtk_constant_expression_new (GType value_type,
GtkExpression *
gtk_constant_expression_new_for_value (const GValue *value)
{
- GtkConstantExpression *result;
+ GtkExpression *result;
+ GtkConstantExpression *self;
g_return_val_if_fail (G_IS_VALUE (value), NULL);
- result = gtk_expression_alloc (&GTK_CONSTANT_EXPRESSION_CLASS, G_VALUE_TYPE (value));
+ result = gtk_expression_alloc (GTK_TYPE_CONSTANT_EXPRESSION, G_VALUE_TYPE (value));
+ self = (GtkConstantExpression *) result;
- g_value_init (&result->value, G_VALUE_TYPE (value));
- g_value_copy (value, &result->value);
+ g_value_init (&self->value, G_VALUE_TYPE (value));
+ g_value_copy (value, &self->value);
- return (GtkExpression *) result;
+ return result;
}
-/*** OBJECT ***/
+/* }}} */
+
+/* {{{ GtkObjectExpression */
typedef struct _GtkObjectExpression GtkObjectExpression;
typedef struct _GtkObjectExpressionWatch GtkObjectExpressionWatch;
@@ -367,6 +836,8 @@ gtk_object_expression_finalize (GtkExpression *expr)
g_object_weak_unref (self->object, gtk_object_expression_weak_ref_cb, self);
g_assert (self->watches == NULL);
+
+ GTK_EXPRESSION_SUPER (expr)->finalize (expr);
}
static gboolean
@@ -420,10 +891,10 @@ gtk_object_expression_unwatch (GtkExpression *expr,
self->watches = g_slist_remove (self->watches, watch);
}
-static const GtkExpressionClass GTK_OBJECT_EXPRESSION_CLASS =
+static const GtkExpressionTypeInfo gtk_object_expression_info =
{
sizeof (GtkObjectExpression),
- "GtkObjectExpression",
+ NULL,
gtk_object_expression_finalize,
gtk_object_expression_is_static,
gtk_object_expression_evaluate,
@@ -432,6 +903,10 @@ static const GtkExpressionClass GTK_OBJECT_EXPRESSION_CLASS =
gtk_object_expression_unwatch
};
+GTK_DEFINE_EXPRESSION_TYPE (GtkObjectExpression,
+ gtk_object_expression,
+ &gtk_object_expression_info)
+
/**
* gtk_object_expression_new:
* @object: (transfer none): object to watch
@@ -447,19 +922,23 @@ static const GtkExpressionClass GTK_OBJECT_EXPRESSION_CLASS =
GtkExpression *
gtk_object_expression_new (GObject *object)
{
- GtkObjectExpression *result;
+ GtkExpression *result;
+ GtkObjectExpression *self;
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
- result = gtk_expression_alloc (&GTK_OBJECT_EXPRESSION_CLASS, G_OBJECT_TYPE (object));
+ result = gtk_expression_alloc (GTK_TYPE_OBJECT_EXPRESSION, G_OBJECT_TYPE (object));
+ self = (GtkObjectExpression *) result;
- result->object = object;
- g_object_weak_ref (object, gtk_object_expression_weak_ref_cb, result);
+ self->object = object;
+ g_object_weak_ref (object, gtk_object_expression_weak_ref_cb, self);
- return (GtkExpression *) result;
+ return result;
}
-/*** PROPERTY ***/
+/* }}} */
+
+/* {{{ GtkPropertyExpression */
typedef struct _GtkPropertyExpression GtkPropertyExpression;
@@ -478,6 +957,8 @@ gtk_property_expression_finalize (GtkExpression *expr)
GtkPropertyExpression *self = (GtkPropertyExpression *) expr;
g_clear_pointer (&self->expr, gtk_expression_unref);
+
+ GTK_EXPRESSION_SUPER (expr)->finalize (expr);
}
static gboolean
@@ -657,10 +1138,10 @@ gtk_property_expression_unwatch (GtkExpression *expr,
gtk_expression_subwatch_finish (self->expr, (GtkExpressionSubWatch *) pwatch->sub);
}
-static const GtkExpressionClass GTK_PROPERTY_EXPRESSION_CLASS =
+static const GtkExpressionTypeInfo gtk_property_expression_info =
{
sizeof (GtkPropertyExpression),
- "GtkPropertyExpression",
+ NULL,
gtk_property_expression_finalize,
gtk_property_expression_is_static,
gtk_property_expression_evaluate,
@@ -669,6 +1150,10 @@ static const GtkExpressionClass GTK_PROPERTY_EXPRESSION_CLASS =
gtk_property_expression_unwatch
};
+GTK_DEFINE_EXPRESSION_TYPE (GtkPropertyExpression,
+ gtk_property_expression,
+ &gtk_property_expression_info)
+
/**
* gtk_property_expression_new:
* @this_type: The type to expect for the this type
@@ -744,17 +1229,21 @@ GtkExpression *
gtk_property_expression_new_for_pspec (GtkExpression *expression,
GParamSpec *pspec)
{
- GtkPropertyExpression *result;
+ GtkExpression *result;
+ GtkPropertyExpression *self;
- result = gtk_expression_alloc (&GTK_PROPERTY_EXPRESSION_CLASS, pspec->value_type);
+ result = gtk_expression_alloc (GTK_TYPE_PROPERTY_EXPRESSION, pspec->value_type);
+ self = (GtkPropertyExpression *) result;
- result->pspec = pspec;
- result->expr = expression;
+ self->pspec = pspec;
+ self->expr = expression;
- return (GtkExpression *) result;
+ return result;
}
-/*** CLOSURE ***/
+/* }}} */
+
+/* {{{ GtkClosureExpression */
typedef struct _GtkClosureExpression GtkClosureExpression;
@@ -780,6 +1269,8 @@ gtk_closure_expression_finalize (GtkExpression *expr)
g_free (self->params);
g_closure_unref (self->closure);
+
+ GTK_EXPRESSION_SUPER (expr)->finalize (expr);
}
static gboolean
@@ -925,10 +1416,10 @@ gtk_closure_expression_unwatch (GtkExpression *expr,
}
}
-static const GtkExpressionClass GTK_CLOSURE_EXPRESSION_CLASS =
+static const GtkExpressionTypeInfo gtk_closure_expression_info =
{
sizeof (GtkClosureExpression),
- "GtkClosureExpression",
+ NULL,
gtk_closure_expression_finalize,
gtk_closure_expression_is_static,
gtk_closure_expression_evaluate,
@@ -937,6 +1428,10 @@ static const GtkExpressionClass GTK_CLOSURE_EXPRESSION_CLASS =
gtk_closure_expression_unwatch
};
+GTK_DEFINE_EXPRESSION_TYPE (GtkClosureExpression,
+ gtk_closure_expression,
+ &gtk_closure_expression_info)
+
/**
* gtk_closure_expression_new:
* @value_type: the type of the value that this expression evaluates to
@@ -956,27 +1451,56 @@ gtk_closure_expression_new (GType value_type,
guint n_params,
GtkExpression **params)
{
- GtkClosureExpression *result;
+ GtkExpression *result;
+ GtkClosureExpression *self;
guint i;
g_return_val_if_fail (closure != NULL, NULL);
g_return_val_if_fail (n_params == 0 || params != NULL, NULL);
- result = gtk_expression_alloc (&GTK_CLOSURE_EXPRESSION_CLASS, value_type);
+ result = gtk_expression_alloc (GTK_TYPE_CLOSURE_EXPRESSION, value_type);
+ self = (GtkClosureExpression *) result;
- result->closure = g_closure_ref (closure);
+ self->closure = g_closure_ref (closure);
g_closure_sink (closure);
if (G_CLOSURE_NEEDS_MARSHAL (closure))
g_closure_set_marshal (closure, g_cclosure_marshal_generic);
- result->n_params = n_params;
- result->params = g_new (GtkExpression *, n_params);
+ self->n_params = n_params;
+ self->params = g_new (GtkExpression *, n_params);
for (i = 0; i < n_params; i++)
- result->params[i] = params[i];
+ self->params[i] = params[i];
- return (GtkExpression *) result;
+ return result;
}
+/* }}} */
+
+/* {{{ GtkCClosureExpression */
+
+typedef struct _GtkCClosureExpression GtkCClosureExpression;
+
+struct _GtkCClosureExpression
+{
+ GtkClosureExpression parent;
+};
+
+static const GtkExpressionTypeInfo gtk_cclosure_expression_info =
+{
+ sizeof (GtkClosureExpression),
+ NULL,
+ gtk_closure_expression_finalize,
+ gtk_closure_expression_is_static,
+ gtk_closure_expression_evaluate,
+ gtk_closure_expression_watch_size,
+ gtk_closure_expression_watch,
+ gtk_closure_expression_unwatch
+};
+
+GTK_DEFINE_EXPRESSION_TYPE (GtkCClosureExpression,
+ gtk_cclosure_expression,
+ &gtk_cclosure_expression_info)
+
/**
* gtk_cclosure_expression_new:
* @value_type: the type of the value that this expression evaluates to
@@ -1002,23 +1526,38 @@ gtk_cclosure_expression_new (GType value_type,
gpointer user_data,
GClosureNotify user_destroy)
{
+ GtkExpression *result;
+ GtkClosureExpression *self;
GClosure *closure;
+ guint i;
+
+ g_return_val_if_fail (callback_func != NULL, NULL);
+ g_return_val_if_fail (n_params == 0 || params != NULL, NULL);
+
+ result = gtk_expression_alloc (GTK_TYPE_CCLOSURE_EXPRESSION, value_type);
+ self = (GtkClosureExpression *) result;
closure = g_cclosure_new (callback_func, user_data, user_destroy);
if (marshal)
g_closure_set_marshal (closure, marshal);
- return gtk_closure_expression_new (value_type, closure, n_params, params);
-}
+ self->closure = g_closure_ref (closure);
+ g_closure_sink (closure);
+ if (G_CLOSURE_NEEDS_MARSHAL (closure))
+ g_closure_set_marshal (closure, g_cclosure_marshal_generic);
-/*** PUBLIC API ***/
+ self->n_params = n_params;
+ self->params = g_new (GtkExpression *, n_params);
+ for (i = 0; i < n_params; i++)
+ self->params[i] = params[i];
-static void
-gtk_expression_finalize (GtkExpression *self)
-{
- self->expression_class->finalize (self);
+ return result;
}
+/* }}} */
+
+/* {{{ GtkExpression public API */
+
/**
* gtk_expression_ref:
* @self: (allow-none): a #GtkExpression
@@ -1030,7 +1569,11 @@ gtk_expression_finalize (GtkExpression *self)
GtkExpression *
gtk_expression_ref (GtkExpression *self)
{
- return g_atomic_rc_box_acquire (self);
+ g_return_val_if_fail (GTK_IS_EXPRESSION (self), NULL);
+
+ g_atomic_ref_count_inc (&self->ref_count);
+
+ return self;
}
/**
@@ -1045,7 +1588,10 @@ gtk_expression_ref (GtkExpression *self)
void
gtk_expression_unref (GtkExpression *self)
{
- g_atomic_rc_box_release_full (self, (GDestroyNotify) gtk_expression_finalize);
+ g_return_if_fail (GTK_IS_EXPRESSION (self));
+
+ if (g_atomic_ref_count_dec (&self->ref_count))
+ GTK_EXPRESSION_GET_CLASS (self)->finalize (self);
}
/**
@@ -1091,7 +1637,7 @@ gtk_expression_evaluate (GtkExpression *self,
g_return_val_if_fail (this_ == NULL || G_IS_OBJECT (this_), FALSE);
g_return_val_if_fail (value != NULL, FALSE);
- return self->expression_class->evaluate (self, this_, value);
+ return GTK_EXPRESSION_GET_CLASS (self)->evaluate (self, this_, value);
}
/**
@@ -1111,7 +1657,9 @@ gtk_expression_evaluate (GtkExpression *self,
gboolean
gtk_expression_is_static (GtkExpression *self)
{
- return self->expression_class->is_static (self);
+ g_return_val_if_fail (GTK_IS_EXPRESSION (self), FALSE);
+
+ return GTK_EXPRESSION_GET_CLASS (self)->is_static (self);
}
static gboolean
@@ -1146,7 +1694,7 @@ gtk_expression_watch_cb (gpointer data)
/**
* gtk_expression_watch:
* @self: a #GtkExpression
- * @this_: (transfer none) (type GObject) (nullable): the this argument to
+ * @this_: (transfer none) (type GObject) (nullable): the `this` argument to
* watch
* @notify: (closure user_data): callback to invoke when the
* expression changes
@@ -1445,3 +1993,5 @@ gtk_expression_bind (GtkExpression *self,
return bind->watch;
}
+
+/* }}} */
diff --git a/gtk/gtkexpression.h b/gtk/gtkexpression.h
index 9705dae18f..44bebf75bb 100644
--- a/gtk/gtkexpression.h
+++ b/gtk/gtkexpression.h
@@ -25,6 +25,10 @@
G_BEGIN_DECLS
+#define GTK_TYPE_EXPRESSION (gtk_expression_get_type ())
+#define GTK_IS_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_EXPRESSION))
+#define GTK_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_EXPRESSION, GtkExpression))
+
typedef struct _GtkExpression GtkExpression;
typedef struct _GtkExpressionWatch GtkExpressionWatch;
@@ -37,10 +41,6 @@ typedef struct _GtkExpressionWatch GtkExpressionWatch;
*/
typedef void (* GtkExpressionNotify) (gpointer user_data);
-#define GTK_IS_EXPRESSION(expr) ((expr) != NULL)
-
-#define GTK_TYPE_EXPRESSION (gtk_expression_get_type ())
-
GDK_AVAILABLE_IN_ALL
GType gtk_expression_get_type (void) G_GNUC_CONST;
@@ -79,6 +79,12 @@ gboolean gtk_expression_watch_evaluate (GtkExpressionWa
GDK_AVAILABLE_IN_ALL
void gtk_expression_watch_unwatch (GtkExpressionWatch *watch);
+#define GTK_TYPE_PROPERTY_EXPRESSION (gtk_property_expression_get_type())
+typedef struct _GtkPropertyExpression GtkPropertyExpression;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_property_expression_get_type (void) G_GNUC_CONST;
+
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_property_expression_new (GType this_type,
GtkExpression *expression,
@@ -86,18 +92,46 @@ GtkExpression * gtk_property_expression_new (GType
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_property_expression_new_for_pspec (GtkExpression *expression,
GParamSpec *pspec);
+
+#define GTK_TYPE_CONSTANT_EXPRESSION (gtk_constant_expression_get_type())
+typedef struct _GtkConstantExpression GtkConstantExpression;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_constant_expression_get_type (void) G_GNUC_CONST;
+
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_constant_expression_new (GType value_type,
...);
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_constant_expression_new_for_value (const GValue *value);
+
+#define GTK_TYPE_OBJECT_EXPRESSION (gtk_object_expression_get_type())
+typedef struct _GtkObjectExpression GtkObjectExpression;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_object_expression_get_type (void) G_GNUC_CONST;
+
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_object_expression_new (GObject *object);
+
+#define GTK_TYPE_CLOSURE_EXPRESSION (gtk_closure_expression_get_type())
+typedef struct _GtkClosureExpression GtkClosureExpression;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_closure_expression_get_type (void) G_GNUC_CONST;
+
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_closure_expression_new (GType value_type,
GClosure *closure,
guint n_params,
GtkExpression **params);
+
+#define GTK_TYPE_CCLOSURE_EXPRESSION (gtk_cclosure_expression_get_type())
+typedef struct _GtkCClosureExpression GtkCClosureExpression;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_cclosure_expression_get_type (void) G_GNUC_CONST;
+
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_cclosure_expression_new (GType value_type,
GClosureMarshal marshal,
@@ -107,6 +141,38 @@ GtkExpression * gtk_cclosure_expression_new (GType
gpointer user_data,
GClosureNotify user_destroy);
+/* GObject integration, so we can use GtkBuilder */
+
+#define GTK_VALUE_HOLDS_EXPRESSION(value) (G_VALUE_HOLDS ((value), GTK_TYPE_EXPRESSION))
+
+GDK_AVAILABLE_IN_ALL
+void gtk_value_set_expression (GValue *value,
+ GtkExpression *expression);
+GDK_AVAILABLE_IN_ALL
+void gtk_value_take_expression (GValue *value,
+ GtkExpression *expression);
+GDK_AVAILABLE_IN_ALL
+GtkExpression * gtk_value_get_expression (const GValue *value);
+GDK_AVAILABLE_IN_ALL
+GtkExpression * gtk_value_dup_expression (const GValue *value);
+
+#define GTK_TYPE_PARAM_SPEC_EXPRESSION (gtk_param_expression_get_type())
+#define GTK_PARAM_SPEC_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PARAM_SPEC_EXPRESSION, GtkParamSpecExpression))
+#define GTK_IS_PARAM_SPEC_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PARAM_SPEC_EXPRESSION))
+
+typedef struct {
+ /*< private >*/
+ GParamSpec parent_instance;
+} GtkParamSpecExpression;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_param_expression_get_type (void) G_GNUC_CONST;
+GDK_AVAILABLE_IN_ALL
+GParamSpec * gtk_param_spec_expression (const char *name,
+ const char *nick,
+ const char *blurb,
+ GParamFlags flags);
+
G_END_DECLS
#endif /* __GTK_EXPRESSION_H__ */
diff --git a/gtk/gtknumericsorter.c b/gtk/gtknumericsorter.c
index eac561241b..94ca187d6e 100644
--- a/gtk/gtknumericsorter.c
+++ b/gtk/gtknumericsorter.c
@@ -212,7 +212,7 @@ gtk_numeric_sorter_set_property (GObject *object,
switch (prop_id)
{
case PROP_EXPRESSION:
- gtk_numeric_sorter_set_expression (self, g_value_get_boxed (value));
+ gtk_numeric_sorter_set_expression (self, gtk_value_get_expression (value));
break;
case PROP_SORT_ORDER:
@@ -236,7 +236,7 @@ gtk_numeric_sorter_get_property (GObject *object,
switch (prop_id)
{
case PROP_EXPRESSION:
- g_value_set_boxed (value, self->expression);
+ gtk_value_set_expression (value, self->expression);
break;
case PROP_SORT_ORDER:
@@ -273,16 +273,15 @@ gtk_numeric_sorter_class_init (GtkNumericSorterClass *class)
object_class->dispose = gtk_numeric_sorter_dispose;
/**
- * GtkNumericSorter:expression:
+ * GtkNumericSorter:expression: (type GtkExpression)
*
* The expression to evalute on items to get a number to compare with
*/
properties[PROP_EXPRESSION] =
- g_param_spec_boxed ("expression",
- P_("Expression"),
- P_("Expression to compare with"),
- GTK_TYPE_EXPRESSION,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ gtk_param_spec_expression ("expression",
+ P_("Expression"),
+ P_("Expression to compare with"),
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkNumericSorter:sort-order:
@@ -290,12 +289,12 @@ gtk_numeric_sorter_class_init (GtkNumericSorterClass *class)
* Whether the sorter will sort smaller numbers first
*/
properties[PROP_SORT_ORDER] =
- g_param_spec_enum ("sort-order",
- P_("Sort order"),
- P_("Whether to sort smaller numbers first"),
- GTK_TYPE_SORT_TYPE,
- GTK_SORT_ASCENDING,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ g_param_spec_enum ("sort-order",
+ P_("Sort order"),
+ P_("Whether to sort smaller numbers first"),
+ GTK_TYPE_SORT_TYPE,
+ GTK_SORT_ASCENDING,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
@@ -338,7 +337,7 @@ gtk_numeric_sorter_new (GtkExpression *expression)
*
* Gets the expression that is evaluated to obtain numbers from items.
*
- * Returns: (nullable): a #GtkExpression, or %NULL
+ * Returns: (transfer none) (nullable): a #GtkExpression, or %NULL
*/
GtkExpression *
gtk_numeric_sorter_get_expression (GtkNumericSorter *self)
diff --git a/gtk/gtkstringfilter.c b/gtk/gtkstringfilter.c
index ff409be8d0..f998cbd662 100644
--- a/gtk/gtkstringfilter.c
+++ b/gtk/gtkstringfilter.c
@@ -164,7 +164,7 @@ gtk_string_filter_set_property (GObject *object,
switch (prop_id)
{
case PROP_EXPRESSION:
- gtk_string_filter_set_expression (self, g_value_get_boxed (value));
+ gtk_string_filter_set_expression (self, gtk_value_get_expression (value));
break;
case PROP_IGNORE_CASE:
@@ -196,7 +196,7 @@ gtk_string_filter_get_property (GObject *object,
switch (prop_id)
{
case PROP_EXPRESSION:
- g_value_set_boxed (value, self->expression);
+ gtk_value_set_expression (value, self->expression);
break;
case PROP_IGNORE_CASE:
@@ -243,16 +243,15 @@ gtk_string_filter_class_init (GtkStringFilterClass *class)
object_class->dispose = gtk_string_filter_dispose;
/**
- * GtkStringFilter:expression:
+ * GtkStringFilter:expression: (type GtkExpression)
*
* The expression to evalute on item to get a string to compare with
*/
properties[PROP_EXPRESSION] =
- g_param_spec_boxed ("expression",
- P_("Expression"),
- P_("Expression to compare with"),
- GTK_TYPE_EXPRESSION,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ gtk_param_spec_expression ("expression",
+ P_("Expression"),
+ P_("Expression to compare with"),
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkStringFilter:ignore-case:
@@ -382,7 +381,7 @@ gtk_string_filter_set_search (GtkStringFilter *self,
* Gets the expression that the string filter uses to
* obtain strings from items.
*
- * Returns: a #GtkExpression
+ * Returns: (transfer none): a #GtkExpression
*/
GtkExpression *
gtk_string_filter_get_expression (GtkStringFilter *self)
diff --git a/gtk/gtkstringsorter.c b/gtk/gtkstringsorter.c
index 5fcc63c566..8ca9fce725 100644
--- a/gtk/gtkstringsorter.c
+++ b/gtk/gtkstringsorter.c
@@ -148,7 +148,7 @@ gtk_string_sorter_set_property (GObject *object,
switch (prop_id)
{
case PROP_EXPRESSION:
- gtk_string_sorter_set_expression (self, g_value_get_boxed (value));
+ gtk_string_sorter_set_expression (self, gtk_value_get_expression (value));
break;
case PROP_IGNORE_CASE:
@@ -172,7 +172,7 @@ gtk_string_sorter_get_property (GObject *object,
switch (prop_id)
{
case PROP_EXPRESSION:
- g_value_set_boxed (value, self->expression);
+ gtk_value_set_expression (value, self->expression);
break;
case PROP_IGNORE_CASE:
@@ -209,16 +209,15 @@ gtk_string_sorter_class_init (GtkStringSorterClass *class)
object_class->dispose = gtk_string_sorter_dispose;
/**
- * GtkStringSorter:expression:
+ * GtkStringSorter:expression: (type GtkExpression)
*
* The expression to evalute on item to get a string to compare with
*/
properties[PROP_EXPRESSION] =
- g_param_spec_boxed ("expression",
- P_("Expression"),
- P_("Expression to compare with"),
- GTK_TYPE_EXPRESSION,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ gtk_param_spec_expression ("expression",
+ P_("Expression"),
+ P_("Expression to compare with"),
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkStringSorter:ignore-case:
@@ -274,7 +273,7 @@ gtk_string_sorter_new (GtkExpression *expression)
*
* Gets the expression that is evaluated to obtain strings from items.
*
- * Returns: (nullable): a #GtkExpression, or %NULL
+ * Returns: (transfer none) (nullable): a #GtkExpression, or %NULL
*/
GtkExpression *
gtk_string_sorter_get_expression (GtkStringSorter *self)