From 2c1b4e7a83214494654aeb6bf99f71a1d50208fd Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 17 Nov 2022 12:16:27 +0000 Subject: [PATCH 1/5] as-review: Add a typedef for property enums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows `-Wswitch-enum` to catch unhandled properties in the `get_property()` and `set_property()` vfuncs. It doesn’t catch any bugs in practice at the moment, but is best practice. Signed-off-by: Philip Withnall --- src/as-review.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/as-review.c b/src/as-review.c index c2c25a3d..b6574b5a 100644 --- a/src/as-review.c +++ b/src/as-review.c @@ -52,9 +52,8 @@ typedef struct GHashTable *metadata; /* GRefString : GRefString */ } AsReviewPrivate; -enum { - PROP_0, - PROP_ID, +typedef enum { + PROP_ID = 1, PROP_SUMMARY, PROP_DESCRIPTION, PROP_LOCALE, @@ -64,8 +63,7 @@ enum { PROP_REVIEWER_NAME, PROP_DATE, PROP_FLAGS, - PROP_LAST -}; +} AsReviewProperty; G_DEFINE_TYPE_WITH_PRIVATE (AsReview, as_review, G_TYPE_OBJECT) @@ -108,7 +106,7 @@ as_review_get_property (GObject *object, guint prop_id, AsReview *review = AS_REVIEW (object); AsReviewPrivate *priv = GET_PRIVATE (review); - switch (prop_id) { + switch ((AsReviewProperty) prop_id) { case PROP_ID: g_value_set_string (value, priv->id); break; @@ -151,7 +149,7 @@ as_review_set_property (GObject *object, guint prop_id, { AsReview *review = AS_REVIEW (object); - switch (prop_id) { + switch ((AsReviewProperty) prop_id) { case PROP_ID: as_review_set_id (review, g_value_get_string (value)); break; From 53b12c54a27ce2254fa603c8494dcbbcd4997cf5 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 17 Nov 2022 12:19:20 +0000 Subject: [PATCH 2/5] as-review: Install properties at once rather than individually This will marginally speed up class initialisation, as all the locks for adding pspecs to the `GObjectClass` will only have to be taken once, rather than N times. It also means we have a handy indexed `GParamSpec*` array ready to use in the following commit. Signed-off-by: Philip Withnall --- src/as-review.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/as-review.c b/src/as-review.c index b6574b5a..c533925c 100644 --- a/src/as-review.c +++ b/src/as-review.c @@ -65,6 +65,8 @@ typedef enum { PROP_FLAGS, } AsReviewProperty; +GParamSpec *pspecs[PROP_FLAGS + 1] = { NULL, }; + G_DEFINE_TYPE_WITH_PRIVATE (AsReview, as_review, G_TYPE_OBJECT) #define GET_PRIVATE(o) (as_review_get_instance_private (o)) @@ -189,7 +191,6 @@ as_review_set_property (GObject *object, guint prop_id, static void as_review_class_init (AsReviewClass *klass) { - GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = as_review_finalize; object_class->get_property = as_review_get_property; @@ -200,102 +201,104 @@ as_review_class_init (AsReviewClass *klass) * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("id", NULL, NULL, + pspecs[PROP_ID] = + g_param_spec_string ("id", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_ID, pspec); /** * AsReview:summary: * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("summary", NULL, NULL, + pspecs[PROP_SUMMARY] = + g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_SUMMARY, pspec); /** * AsReview:description: * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("description", NULL, NULL, + pspecs[PROP_DESCRIPTION] = + g_param_spec_string ("description", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec); /** * AsReview:locale: * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("locale", NULL, NULL, + pspecs[PROP_LOCALE] = + g_param_spec_string ("locale", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_LOCALE, pspec); /** * AsReview:rating: * * Since: 0.14.0 **/ - pspec = g_param_spec_int ("rating", NULL, NULL, + pspecs[PROP_RATING] = + g_param_spec_int ("rating", NULL, NULL, -1, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_RATING, pspec); /** * AsReview:flags: * * Since: 0.14.0 **/ - pspec = g_param_spec_uint64 ("flags", NULL, NULL, + pspecs[PROP_FLAGS] = + g_param_spec_uint64 ("flags", NULL, NULL, AS_REVIEW_FLAG_NONE, AS_REVIEW_FLAG_LAST, AS_REVIEW_FLAG_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_FLAGS, pspec); /** * AsReview:version: * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("version", NULL, NULL, + pspecs[PROP_VERSION] = + g_param_spec_string ("version", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_VERSION, pspec); /** * AsReview:reviewer-id: * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("reviewer-id", NULL, NULL, + pspecs[PROP_REVIEWER_ID] = + g_param_spec_string ("reviewer-id", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_REVIEWER_ID, pspec); /** * AsReview:reviewer-name: * * Since: 0.14.0 **/ - pspec = g_param_spec_string ("reviewer-name", NULL, NULL, + pspecs[PROP_REVIEWER_NAME] = + g_param_spec_string ("reviewer-name", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_REVIEWER_NAME, pspec); /** * AsReview:date: * * Since: 0.14.0 **/ - pspec = g_param_spec_object ("date", NULL, NULL, + pspecs[PROP_DATE] = + g_param_spec_object ("date", NULL, NULL, AS_TYPE_REVIEW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_DATE, pspec); + + g_object_class_install_properties (object_class, G_N_ELEMENTS (pspecs), pspecs); } /** From c1191bbaeab3bd14f307abdd1e924658861372ba Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 17 Nov 2022 12:23:56 +0000 Subject: [PATCH 3/5] as-review: Specify G_PARAM_STATIC_STRINGS for properties If these properties ever get names or descriptions added, this will avoid them being `strdup()`ed pointlessly by GObject. Since none of the properties currently have any strings set, this is currently a no-op. Signed-off-by: Philip Withnall --- src/as-review.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/as-review.c b/src/as-review.c index c533925c..5b35e290 100644 --- a/src/as-review.c +++ b/src/as-review.c @@ -204,7 +204,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_ID] = g_param_spec_string ("id", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:summary: @@ -214,7 +214,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_SUMMARY] = g_param_spec_string ("summary", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:description: @@ -224,7 +224,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_DESCRIPTION] = g_param_spec_string ("description", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:locale: @@ -234,7 +234,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_LOCALE] = g_param_spec_string ("locale", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:rating: @@ -244,7 +244,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_RATING] = g_param_spec_int ("rating", NULL, NULL, -1, 100, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:flags: @@ -256,7 +256,7 @@ as_review_class_init (AsReviewClass *klass) AS_REVIEW_FLAG_NONE, AS_REVIEW_FLAG_LAST, AS_REVIEW_FLAG_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:version: @@ -266,7 +266,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_VERSION] = g_param_spec_string ("version", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:reviewer-id: @@ -276,7 +276,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_REVIEWER_ID] = g_param_spec_string ("reviewer-id", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:reviewer-name: @@ -286,7 +286,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_REVIEWER_NAME] = g_param_spec_string ("reviewer-name", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * AsReview:date: @@ -296,7 +296,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_DATE] = g_param_spec_object ("date", NULL, NULL, AS_TYPE_REVIEW, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, G_N_ELEMENTS (pspecs), pspecs); } From ac968a1ad3e6cca60d9f7ddc1a2498a69c6319d1 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 17 Nov 2022 12:21:32 +0000 Subject: [PATCH 4/5] as-review: Emit GObject::notify on property value changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is best practice for GObjects, as it allows binding things together (particularly UI widgets) to update themselves when the properties of the object they represent are updated. In particular, this will eventually let us bind review property updates in gnome-software to the `GsReviewRow` widget so that it updates automatically when a review is upvoted/downvoted/etc. See https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1545. The `G_PARAM_EXPLICIT_NOTIFY` flag now needs to be passed to the pspecs so that `g_object_set_property()` doesn’t implicitly emit the `GObject::notify` signal when it’s called. That would result in a duplicate signal emission. Unfortunately we can’t rely on this implicit behaviour because C code is more likely to call `as_review_set_*()` directly, which doesn’t use the implicit behaviour. Hence `G_PARAM_EXPLICIT_NOTIFY`. Where possible, the `as_review_set_*()` methods have been changed to return early if the new value is the same as the old one, to avoid an unnecessary `GObject::notify` emission. Where functions from `as-utils.c` have been used, though, that’s not straightforward, so there is still currently an unnecessary signal emission. That’s not a great problem, as consumers of the signal must be able to accept spurious emissions of it. Signed-off-by: Philip Withnall --- src/as-review.c | 57 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/as-review.c b/src/as-review.c index 5b35e290..8d2b6ba2 100644 --- a/src/as-review.c +++ b/src/as-review.c @@ -204,7 +204,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_ID] = g_param_spec_string ("id", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:summary: @@ -214,7 +214,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_SUMMARY] = g_param_spec_string ("summary", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:description: @@ -224,7 +224,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_DESCRIPTION] = g_param_spec_string ("description", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:locale: @@ -234,7 +234,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_LOCALE] = g_param_spec_string ("locale", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:rating: @@ -244,7 +244,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_RATING] = g_param_spec_int ("rating", NULL, NULL, -1, 100, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:flags: @@ -256,7 +256,7 @@ as_review_class_init (AsReviewClass *klass) AS_REVIEW_FLAG_NONE, AS_REVIEW_FLAG_LAST, AS_REVIEW_FLAG_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:version: @@ -266,7 +266,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_VERSION] = g_param_spec_string ("version", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:reviewer-id: @@ -276,7 +276,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_REVIEWER_ID] = g_param_spec_string ("reviewer-id", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:reviewer-name: @@ -286,7 +286,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_REVIEWER_NAME] = g_param_spec_string ("reviewer-name", NULL, NULL, NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); /** * AsReview:date: @@ -296,7 +296,7 @@ as_review_class_init (AsReviewClass *klass) pspecs[PROP_DATE] = g_param_spec_object ("date", NULL, NULL, AS_TYPE_REVIEW, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); g_object_class_install_properties (object_class, G_N_ELEMENTS (pspecs), pspecs); } @@ -389,6 +389,7 @@ as_review_set_id (AsReview *review, const gchar *id) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->id, id); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_ID]); } /** @@ -406,6 +407,7 @@ as_review_set_summary (AsReview *review, const gchar *summary) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->summary, summary); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_SUMMARY]); } /** @@ -441,6 +443,7 @@ as_review_set_description (AsReview *review, const gchar *description) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->description, description); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_DESCRIPTION]); } /** @@ -476,6 +479,7 @@ as_review_set_locale (AsReview *review, const gchar *locale) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->locale, locale); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_LOCALE]); } /** @@ -510,7 +514,11 @@ as_review_set_rating (AsReview *review, gint rating) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - priv->rating = rating; + + if (priv->rating != rating) { + priv->rating = rating; + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_RATING]); + } } /** @@ -547,7 +555,11 @@ as_review_set_flags (AsReview *review, AsReviewFlags flags) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - priv->flags = flags; + + if (priv->flags != flags) { + priv->flags = flags; + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_FLAGS]); + } } /** @@ -564,7 +576,11 @@ as_review_add_flags (AsReview *review, AsReviewFlags flags) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - priv->flags |= flags; + + if ((priv->flags & flags) != flags) { + priv->flags |= flags; + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_FLAGS]); + } } /** @@ -618,6 +634,7 @@ as_review_set_reviewer_id (AsReview *review, const gchar *reviewer_id) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->reviewer_id, reviewer_id); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_REVIEWER_ID]); } /** @@ -635,6 +652,7 @@ as_review_set_reviewer_name (AsReview *review, const gchar *reviewer_name) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->reviewer_name, reviewer_name); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_REVIEWER_NAME]); } /** @@ -652,6 +670,7 @@ as_review_set_version (AsReview *review, const gchar *version) AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); as_ref_string_assign_safe (&priv->version, version); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_VERSION]); } /** @@ -704,9 +723,15 @@ as_review_set_date (AsReview *review, GDateTime *date) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); + + if ((date == NULL && priv->date == NULL) || + (date != NULL && priv->date != NULL && g_date_time_equal (date, priv->date))) + return; + g_clear_pointer (&priv->date, g_date_time_unref); if (date != NULL) priv->date = g_date_time_ref (date); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_DATE]); } /** @@ -839,22 +864,28 @@ as_review_load_from_xml (AsReview *review, AsContext *ctx, xmlNode *node, GError } else if (g_strcmp0 ((gchar*) iter->name, "summary") == 0) { as_ref_string_assign_transfer (&priv->summary, as_xml_get_node_value_refstr (iter)); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_SUMMARY]); } else if (g_strcmp0 ((gchar*) iter->name, "description") == 0) { g_autofree gchar *desc = as_xml_dump_node_children (iter); as_ref_string_assign_transfer (&priv->description, g_ref_string_new_intern (desc)); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_DESCRIPTION]); } else if (g_strcmp0 ((gchar*) iter->name, "version") == 0) { as_ref_string_assign_transfer (&priv->version, as_xml_get_node_value_refstr (iter)); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_VERSION]); } else if (g_strcmp0 ((gchar*) iter->name, "reviewer_id") == 0) { as_ref_string_assign_transfer (&priv->reviewer_id, as_xml_get_node_value_refstr (iter)); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_REVIEWER_ID]); } else if (g_strcmp0 ((gchar*) iter->name, "reviewer_name") == 0) { as_ref_string_assign_transfer (&priv->reviewer_name, as_xml_get_node_value_refstr (iter)); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_REVIEWER_NAME]); } else if (g_strcmp0 ((gchar*) iter->name, "lang") == 0) { as_ref_string_assign_transfer (&priv->locale, as_xml_get_node_value_refstr (iter)); + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_LOCALE]); } else if (g_strcmp0 ((gchar*) iter->name, "metadata") == 0) { as_xml_parse_custom_node (iter, priv->metadata); From e7906a6a59fc58f35ee2b061688f3d1cf532e03c Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 17 Nov 2022 12:27:26 +0000 Subject: [PATCH 5/5] as-review: Add missing property for as_review_{get,set}_priority() This allows property change notifications for it, property bindings to it, and for it to be correctly exposed as a property in language bindings. Signed-off-by: Philip Withnall --- src/as-review.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/as-review.c b/src/as-review.c index 8d2b6ba2..7de59615 100644 --- a/src/as-review.c +++ b/src/as-review.c @@ -57,6 +57,7 @@ typedef enum { PROP_SUMMARY, PROP_DESCRIPTION, PROP_LOCALE, + PROP_PRIORITY, PROP_RATING, PROP_VERSION, PROP_REVIEWER_ID, @@ -121,6 +122,9 @@ as_review_get_property (GObject *object, guint prop_id, case PROP_LOCALE: g_value_set_string (value, priv->locale); break; + case PROP_PRIORITY: + g_value_set_int (value, priv->priority); + break; case PROP_RATING: g_value_set_int (value, priv->rating); break; @@ -164,6 +168,9 @@ as_review_set_property (GObject *object, guint prop_id, case PROP_LOCALE: as_review_set_locale (review, g_value_get_string (value)); break; + case PROP_PRIORITY: + as_review_set_priority (review, g_value_get_int (value)); + break; case PROP_RATING: as_review_set_rating (review, g_value_get_int (value)); break; @@ -236,6 +243,19 @@ as_review_class_init (AsReviewClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + /** + * AsReview:priority: + * + * The priority for the review, where positive numbers indicate + * a better review for the specific user. + * + * Since: 0.15.6 + */ + pspecs[PROP_PRIORITY] = + g_param_spec_int ("priority", NULL, NULL, + G_MININT, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + /** * AsReview:rating: * @@ -335,7 +355,11 @@ as_review_set_priority (AsReview *review, gint priority) { AsReviewPrivate *priv = GET_PRIVATE (review); g_return_if_fail (AS_IS_REVIEW (review)); - priv->priority = priority; + + if (priv->priority != priority) { + priv->priority = priority; + g_object_notify_by_pspec (G_OBJECT (review), pspecs[PROP_PRIORITY]); + } } /**