diff --git a/gio/gpropertyaction.c b/gio/gpropertyaction.c index 8c4a4952a..52cee4b73 100644 --- a/gio/gpropertyaction.c +++ b/gio/gpropertyaction.c @@ -93,6 +93,7 @@ struct _GPropertyAction gpointer object; GParamSpec *pspec; const GVariantType *state_type; + gboolean invert_boolean; }; /** @@ -118,9 +119,18 @@ enum PROP_STATE_TYPE, PROP_STATE, PROP_OBJECT, - PROP_PROPERTY_NAME + PROP_PROPERTY_NAME, + PROP_INVERT_BOOLEAN }; +static gboolean +g_property_action_get_invert_boolean (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + return paction->invert_boolean; +} + static const gchar * g_property_action_get_name (GAction *action) { @@ -165,6 +175,10 @@ g_property_action_set_state (GPropertyAction *paction, g_value_init (&value, paction->pspec->value_type); g_settings_get_mapping (&value, variant, NULL); + + if (paction->pspec->value_type == G_TYPE_BOOLEAN && paction->invert_boolean) + g_value_set_boolean (&value, !g_value_get_boolean (&value)); + g_object_set_property (paction->object, paction->pspec->name, &value); g_value_unset (&value); } @@ -189,6 +203,10 @@ g_property_action_get_state (GAction *action) g_value_init (&value, paction->pspec->value_type); g_object_get_property (paction->object, paction->pspec->name, &value); + + if (paction->pspec->value_type == G_TYPE_BOOLEAN && paction->invert_boolean) + g_value_set_boolean (&value, !g_value_get_boolean (&value)); + result = g_settings_set_mapping (&value, paction->state_type, NULL); g_value_unset (&value); @@ -316,6 +334,10 @@ g_property_action_set_property (GObject *object, g_property_action_set_property_name (paction, g_value_get_string (value)); break; + case PROP_INVERT_BOOLEAN: + paction->invert_boolean = g_value_get_boolean (value); + break; + default: g_assert_not_reached (); } @@ -351,6 +373,10 @@ g_property_action_get_property (GObject *object, g_value_take_variant (value, g_property_action_get_state (action)); break; + case PROP_INVERT_BOOLEAN: + g_value_set_boolean (value, g_property_action_get_invert_boolean (action)); + break; + default: g_assert_not_reached (); } @@ -515,6 +541,23 @@ g_property_action_class_init (GPropertyActionClass *class) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:invert-boolean: + * + * If %TRUE, the state of the action will be the negation of the + * property value, provided the property is boolean. + * + * Since: 2.46 + */ + g_object_class_install_property (object_class, PROP_INVERT_BOOLEAN, + g_param_spec_boolean ("invert-boolean", + P_("Invert boolean"), + P_("Whether to invert the value of a boolean property"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } /** diff --git a/gio/tests/actions.c b/gio/tests/actions.c index 35de47f4e..8b5339e4d 100644 --- a/gio/tests/actions.c +++ b/gio/tests/actions.c @@ -1050,6 +1050,16 @@ test_property_actions (void) g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); g_object_unref (action); + /* inverted */ + action = g_object_new (G_TYPE_PROPERTY_ACTION, + "name", "disable-proxy", + "object", client, + "property-name", "enable-proxy", + "invert-boolean", TRUE, + NULL); + g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); + g_object_unref (action); + /* enum... */ action = g_property_action_new ("type", client, "type"); g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); @@ -1062,6 +1072,7 @@ test_property_actions (void) ensure_state (group, "app-id", "'org.gtk.test'"); ensure_state (group, "keepalive", "uint32 0"); ensure_state (group, "tls", "false"); + ensure_state (group, "disable-proxy", "false"); ensure_state (group, "type", "'stream'"); verify_changed (NULL); @@ -1102,6 +1113,11 @@ test_property_actions (void) g_assert (g_socket_client_get_tls (client)); ensure_state (group, "tls", "true"); + g_action_group_change_action_state (G_ACTION_GROUP (group), "disable-proxy", g_variant_new ("b", TRUE)); + verify_changed ("disable-proxy:true"); + ensure_state (group, "disable-proxy", "true"); + g_assert (!g_socket_client_get_enable_proxy (client)); + /* test toggle true->false */ g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL); verify_changed ("tls:false"); @@ -1118,6 +1134,21 @@ test_property_actions (void) verify_changed ("tls:false"); ensure_state (group, "tls", "false"); + /* now do the same for the inverted action */ + g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL); + verify_changed ("disable-proxy:false"); + g_assert (g_socket_client_get_enable_proxy (client)); + ensure_state (group, "disable-proxy", "false"); + + g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL); + verify_changed ("disable-proxy:true"); + g_assert (!g_socket_client_get_enable_proxy (client)); + ensure_state (group, "disable-proxy", "true"); + + g_socket_client_set_enable_proxy (client, TRUE); + verify_changed ("disable-proxy:false"); + ensure_state (group, "disable-proxy", "false"); + /* enum tests */ g_action_group_change_action_state (G_ACTION_GROUP (group), "type", g_variant_new ("s", "datagram")); verify_changed ("type:'datagram'");