X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsimpleaction.c;h=610e2fa1dcddaa1a902db2ccc25a46be74a8dbe9;hb=c3842d1969feace4bfb12919be730e75e53877d9;hp=b87f80289b7a20a37ac19bb6c80e950ea3aed122;hpb=09429e2c820118918e6132d32884eb02203136d4;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gsimpleaction.c b/gio/gsimpleaction.c index b87f802..610e2fa 100644 --- a/gio/gsimpleaction.c +++ b/gio/gsimpleaction.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Authors: Ryan Lortie */ @@ -29,14 +27,15 @@ /** * SECTION:gsimpleaction * @title: GSimpleAction - * @short_description: A simple GSimpleAction + * @short_description: A simple GAction implementation + * @include: gio/gio.h * * A #GSimpleAction is the obvious simple implementation of the #GAction - * interface. This is the easiest way to create an action for purposes of + * interface. This is the easiest way to create an action for purposes of * adding it to a #GSimpleActionGroup. * * See also #GtkAction. - **/ + */ struct _GSimpleAction { GObject parent_instance; @@ -45,6 +44,7 @@ struct _GSimpleAction GVariantType *parameter_type; gboolean enabled; GVariant *state; + gboolean state_set_already; }; typedef GObjectClass GSimpleActionClass; @@ -144,6 +144,8 @@ g_simple_action_change_state (GAction *action, * property. Instead, they should call g_action_change_state() to * request the change. * + * If the @value GVariant is floating, it is consumed. + * * Since: 2.30 **/ void @@ -201,13 +203,78 @@ g_simple_action_activate (GAction *action, g_variant_ref_sink (parameter); if (simple->enabled) - g_signal_emit (simple, g_simple_action_signals[SIGNAL_ACTIVATE], 0, parameter); + { + /* If the user connected a signal handler then they are responsible + * for handling activation. + */ + if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, TRUE)) + g_signal_emit (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, parameter); + + /* If not, do some reasonable defaults for stateful actions. */ + else if (simple->state) + { + /* If we have no parameter and this is a boolean action, toggle. */ + if (parameter == NULL && g_variant_is_of_type (simple->state, G_VARIANT_TYPE_BOOLEAN)) + { + gboolean was_enabled = g_variant_get_boolean (simple->state); + g_simple_action_change_state (action, g_variant_new_boolean (!was_enabled)); + } + + /* else, if the parameter and state type are the same, do a change-state */ + else if (g_variant_is_of_type (simple->state, g_variant_get_type (parameter))) + g_simple_action_change_state (action, parameter); + } + } if (parameter != NULL) g_variant_unref (parameter); } static void +g_simple_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSimpleAction *action = G_SIMPLE_ACTION (object); + + switch (prop_id) + { + case PROP_NAME: + action->name = g_strdup (g_value_get_string (value)); + break; + + case PROP_PARAMETER_TYPE: + action->parameter_type = g_value_dup_boxed (value); + break; + + case PROP_ENABLED: + action->enabled = g_value_get_boolean (value); + break; + + case PROP_STATE: + /* The first time we see this (during construct) we should just + * take the state as it was handed to us. + * + * After that, we should make sure we go through the same checks + * as the C API. + */ + if (!action->state_set_already) + { + action->state = g_value_dup_variant (value); + action->state_set_already = TRUE; + } + else + g_simple_action_set_state (action, g_value_get_variant (value)); + + break; + + default: + g_assert_not_reached (); + } +} + +static void g_simple_action_get_property (GObject *object, guint prop_id, GValue *value, @@ -260,6 +327,7 @@ g_simple_action_finalize (GObject *object) void g_simple_action_init (GSimpleAction *simple) { + simple->enabled = TRUE; } void @@ -280,6 +348,7 @@ g_simple_action_class_init (GSimpleActionClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); + object_class->set_property = g_simple_action_set_property; object_class->get_property = g_simple_action_get_property; object_class->finalize = g_simple_action_finalize; @@ -293,6 +362,14 @@ g_simple_action_class_init (GSimpleActionClass *class) * @parameter will always be of the expected type. In the event that * an incorrect type was given, no signal will be emitted. * + * Since GLib 2.40, if no handler is connected to this signal then the + * default behaviour for boolean-stated actions with a %NULL parameter + * type is to toggle them via the #GSimpleAction::change-state signal. + * For stateful actions where the state type is equal to the parameter + * type, the default is to forward them directly to + * #GSimpleAction::change-state. This should allow almost all users + * of #GSimpleAction to connect only one handler or the other. + * * Since: 2.28 */ g_simple_action_signals[SIGNAL_ACTIVATE] = @@ -317,13 +394,12 @@ g_simple_action_class_init (GSimpleActionClass *class) * * If no handler is connected to this signal then the default * behaviour is to call g_simple_action_set_state() to set the state - * to the requested value. If you connect a signal handler then no - * default action is taken. If the state should change then you must + * to the requested value. If you connect a signal handler then no + * default action is taken. If the state should change then you must * call g_simple_action_set_state() from the handler. * - * - * Example 'change-state' handler - * + * An example of a 'change-state' handler: + * |[ * static void * change_volume_state (GSimpleAction *action, * GVariant *value, @@ -337,11 +413,10 @@ g_simple_action_class_init (GSimpleActionClass *class) * if (0 <= requested && requested <= 10) * g_simple_action_set_state (action, value); * } - * - * + * ]| * - * The handler need not set the state to the requested value. It - * could set it to any value at all, or take some other action. + * The handler need not set the state to the requested value. + * It could set it to any value at all, or take some other action. * * Since: 2.30 */ @@ -357,7 +432,7 @@ g_simple_action_class_init (GSimpleActionClass *class) /** * GSimpleAction:name: * - * The name of the action. This is mostly meaningful for identifying + * The name of the action. This is mostly meaningful for identifying * the action once it has been added to a #GSimpleActionGroup. * * Since: 2.28 @@ -367,7 +442,8 @@ g_simple_action_class_init (GSimpleActionClass *class) P_("Action Name"), P_("The name used to invoke the action"), NULL, - G_PARAM_READABLE | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); /** @@ -383,7 +459,8 @@ g_simple_action_class_init (GSimpleActionClass *class) P_("Parameter Type"), P_("The type of GVariant passed to activate()"), G_TYPE_VARIANT_TYPE, - G_PARAM_READABLE | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); /** @@ -401,7 +478,7 @@ g_simple_action_class_init (GSimpleActionClass *class) P_("Enabled"), P_("If the action can be activated"), TRUE, - G_PARAM_READABLE | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -433,7 +510,7 @@ g_simple_action_class_init (GSimpleActionClass *class) P_("The state the action is in"), G_VARIANT_TYPE_ANY, NULL, - G_PARAM_READABLE | + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); } @@ -483,19 +560,10 @@ GSimpleAction * g_simple_action_new (const gchar *name, const GVariantType *parameter_type) { - GSimpleAction *simple; - - g_return_val_if_fail (name != NULL, NULL); - - simple = g_object_new (G_TYPE_SIMPLE_ACTION, NULL); - simple->name = g_strdup (name); - - if (parameter_type) - simple->parameter_type = g_variant_type_copy (parameter_type); - - simple->enabled = TRUE; - - return simple; + return g_object_new (G_TYPE_SIMPLE_ACTION, + "name", name, + "parameter-type", parameter_type, + NULL); } /** @@ -520,20 +588,9 @@ g_simple_action_new_stateful (const gchar *name, const GVariantType *parameter_type, GVariant *state) { - GSimpleAction *simple; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (state != NULL, NULL); - - simple = g_object_new (G_TYPE_SIMPLE_ACTION, NULL); - simple->name = g_strdup (name); - - if (parameter_type) - simple->parameter_type = g_variant_type_copy (parameter_type); - - simple->state = g_variant_ref_sink (state); - - simple->enabled = TRUE; - - return simple; + return g_object_new (G_TYPE_SIMPLE_ACTION, + "name", name, + "parameter-type", parameter_type, + "state", state, + NULL); }