GSimpleAction: fix mistake in last commit
[platform/upstream/glib.git] / gio / gsimpleaction.c
1 /*
2  * Copyright © 2010 Codethink Limited
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published
6  * by the Free Software Foundation; either version 2 of the licence or (at
7  * your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 #include "config.h"
23
24 #include "gsimpleaction.h"
25
26 #include "gaction.h"
27 #include "glibintl.h"
28
29 /**
30  * SECTION:gsimpleaction
31  * @title: GSimpleAction
32  * @short_description: A simple GAction implementation
33  * @include: gio/gio.h
34  *
35  * A #GSimpleAction is the obvious simple implementation of the #GAction
36  * interface. This is the easiest way to create an action for purposes of
37  * adding it to a #GSimpleActionGroup.
38  *
39  * See also #GtkAction.
40  */
41 struct _GSimpleAction
42 {
43   GObject       parent_instance;
44
45   gchar        *name;
46   GVariantType *parameter_type;
47   gboolean      enabled;
48   GVariant     *state;
49   gboolean      state_set_already;
50 };
51
52 typedef GObjectClass GSimpleActionClass;
53
54 static void g_simple_action_iface_init (GActionInterface *iface);
55 G_DEFINE_TYPE_WITH_CODE (GSimpleAction, g_simple_action, G_TYPE_OBJECT,
56   G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_simple_action_iface_init))
57
58 enum
59 {
60   PROP_NONE,
61   PROP_NAME,
62   PROP_PARAMETER_TYPE,
63   PROP_ENABLED,
64   PROP_STATE_TYPE,
65   PROP_STATE
66 };
67
68 enum
69 {
70   SIGNAL_CHANGE_STATE,
71   SIGNAL_ACTIVATE,
72   NR_SIGNALS
73 };
74
75 static guint g_simple_action_signals[NR_SIGNALS];
76
77 static const gchar *
78 g_simple_action_get_name (GAction *action)
79 {
80   GSimpleAction *simple = G_SIMPLE_ACTION (action);
81
82   return simple->name;
83 }
84
85 static const GVariantType *
86 g_simple_action_get_parameter_type (GAction *action)
87 {
88   GSimpleAction *simple = G_SIMPLE_ACTION (action);
89
90   return simple->parameter_type;
91 }
92
93 static const GVariantType *
94 g_simple_action_get_state_type (GAction *action)
95 {
96   GSimpleAction *simple = G_SIMPLE_ACTION (action);
97
98   if (simple->state != NULL)
99     return g_variant_get_type (simple->state);
100   else
101     return NULL;
102 }
103
104 static GVariant *
105 g_simple_action_get_state_hint (GAction *action)
106 {
107   return NULL;
108 }
109
110 static gboolean
111 g_simple_action_get_enabled (GAction *action)
112 {
113   GSimpleAction *simple = G_SIMPLE_ACTION (action);
114
115   return simple->enabled;
116 }
117
118 static void
119 g_simple_action_change_state (GAction  *action,
120                               GVariant *value)
121 {
122   GSimpleAction *simple = G_SIMPLE_ACTION (action);
123
124   /* If the user connected a signal handler then they are responsible
125    * for handling state changes.
126    */
127   if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, TRUE))
128     g_signal_emit (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, value);
129
130   /* If not, then the default behaviour is to just set the state. */
131   else
132     g_simple_action_set_state (simple, value);
133 }
134
135 /**
136  * g_simple_action_set_state:
137  * @simple: a #GSimpleAction
138  * @value: the new #GVariant for the state
139  *
140  * Sets the state of the action.
141  *
142  * This directly updates the 'state' property to the given value.
143  *
144  * This should only be called by the implementor of the action.  Users
145  * of the action should not attempt to directly modify the 'state'
146  * property.  Instead, they should call g_action_change_state() to
147  * request the change.
148  *
149  * If the @value GVariant is floating, it is consumed.
150  *
151  * Since: 2.30
152  **/
153 void
154 g_simple_action_set_state (GSimpleAction *simple,
155                            GVariant      *value)
156 {
157   g_return_if_fail (G_IS_SIMPLE_ACTION (simple));
158   g_return_if_fail (value != NULL);
159
160   {
161     const GVariantType *state_type;
162
163     state_type = simple->state ?
164                    g_variant_get_type (simple->state) : NULL;
165     g_return_if_fail (state_type != NULL);
166     g_return_if_fail (g_variant_is_of_type (value, state_type));
167   }
168
169   g_variant_ref_sink (value);
170
171   if (!simple->state || !g_variant_equal (simple->state, value))
172     {
173       if (simple->state)
174         g_variant_unref (simple->state);
175
176       simple->state = g_variant_ref (value);
177
178       g_object_notify (G_OBJECT (simple), "state");
179     }
180
181   g_variant_unref (value);
182 }
183
184 static GVariant *
185 g_simple_action_get_state (GAction *action)
186 {
187   GSimpleAction *simple = G_SIMPLE_ACTION (action);
188
189   return simple->state ? g_variant_ref (simple->state) : NULL;
190 }
191
192 static void
193 g_simple_action_activate (GAction  *action,
194                           GVariant *parameter)
195 {
196   GSimpleAction *simple = G_SIMPLE_ACTION (action);
197
198   g_return_if_fail (simple->parameter_type == NULL ?
199                       parameter == NULL :
200                     (parameter != NULL &&
201                      g_variant_is_of_type (parameter,
202                                            simple->parameter_type)));
203
204   if (parameter != NULL)
205     g_variant_ref_sink (parameter);
206
207   if (simple->enabled)
208     {
209       /* If the user connected a signal handler then they are responsible
210        * for handling activation.
211        */
212       if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, TRUE))
213         g_signal_emit (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, parameter);
214
215       /* If not, do some reasonable defaults for stateful actions. */
216       else if (simple->state)
217         {
218           /* If we have no parameter and this is a boolean action, toggle. */
219           if (parameter == NULL && g_variant_is_of_type (simple->state, G_VARIANT_TYPE_BOOLEAN))
220             {
221               gboolean was_enabled = g_variant_get_boolean (simple->state);
222               g_simple_action_change_state (action, g_variant_new_boolean (!was_enabled));
223             }
224
225           /* else, if the parameter and state type are the same, do a change-state */
226           else if (g_variant_is_of_type (simple->state, g_variant_get_type (parameter)))
227             g_simple_action_change_state (action, parameter);
228         }
229     }
230
231   if (parameter != NULL)
232     g_variant_unref (parameter);
233 }
234
235 static void
236 g_simple_action_set_property (GObject    *object,
237                               guint       prop_id,
238                               const GValue     *value,
239                               GParamSpec *pspec)
240 {
241   GSimpleAction *action = G_SIMPLE_ACTION (object);
242
243   switch (prop_id)
244     {
245     case PROP_NAME:
246       action->name = g_strdup (g_value_get_string (value));
247       break;
248
249     case PROP_PARAMETER_TYPE:
250       action->parameter_type = g_value_dup_boxed (value);
251       break;
252
253     case PROP_ENABLED:
254       action->enabled = g_value_get_boolean (value);
255       break;
256
257     case PROP_STATE:
258       /* The first time we see this (during construct) we should just
259        * take the state as it was handed to us.
260        *
261        * After that, we should make sure we go through the same checks
262        * as the C API.
263        */
264       if (!action->state_set_already)
265         {
266           action->state = g_value_dup_variant (value);
267           action->state_set_already = TRUE;
268         }
269       else
270         g_simple_action_set_state (action, g_value_get_variant (value));
271
272       break;
273
274     default:
275       g_assert_not_reached ();
276     }
277 }
278
279 static void
280 g_simple_action_get_property (GObject    *object,
281                               guint       prop_id,
282                               GValue     *value,
283                               GParamSpec *pspec)
284 {
285   GAction *action = G_ACTION (object);
286
287   switch (prop_id)
288     {
289     case PROP_NAME:
290       g_value_set_string (value, g_simple_action_get_name (action));
291       break;
292
293     case PROP_PARAMETER_TYPE:
294       g_value_set_boxed (value, g_simple_action_get_parameter_type (action));
295       break;
296
297     case PROP_ENABLED:
298       g_value_set_boolean (value, g_simple_action_get_enabled (action));
299       break;
300
301     case PROP_STATE_TYPE:
302       g_value_set_boxed (value, g_simple_action_get_state_type (action));
303       break;
304
305     case PROP_STATE:
306       g_value_take_variant (value, g_simple_action_get_state (action));
307       break;
308
309     default:
310       g_assert_not_reached ();
311     }
312 }
313
314 static void
315 g_simple_action_finalize (GObject *object)
316 {
317   GSimpleAction *simple = G_SIMPLE_ACTION (object);
318
319   g_free (simple->name);
320   if (simple->parameter_type)
321     g_variant_type_free (simple->parameter_type);
322   if (simple->state)
323     g_variant_unref (simple->state);
324
325   G_OBJECT_CLASS (g_simple_action_parent_class)
326     ->finalize (object);
327 }
328
329 void
330 g_simple_action_init (GSimpleAction *simple)
331 {
332   simple->enabled = TRUE;
333 }
334
335 void
336 g_simple_action_iface_init (GActionInterface *iface)
337 {
338   iface->get_name = g_simple_action_get_name;
339   iface->get_parameter_type = g_simple_action_get_parameter_type;
340   iface->get_state_type = g_simple_action_get_state_type;
341   iface->get_state_hint = g_simple_action_get_state_hint;
342   iface->get_enabled = g_simple_action_get_enabled;
343   iface->get_state = g_simple_action_get_state;
344   iface->change_state = g_simple_action_change_state;
345   iface->activate = g_simple_action_activate;
346 }
347
348 void
349 g_simple_action_class_init (GSimpleActionClass *class)
350 {
351   GObjectClass *object_class = G_OBJECT_CLASS (class);
352
353   object_class->set_property = g_simple_action_set_property;
354   object_class->get_property = g_simple_action_get_property;
355   object_class->finalize = g_simple_action_finalize;
356
357   /**
358    * GSimpleAction::activate:
359    * @simple: the #GSimpleAction
360    * @parameter: (allow-none): the parameter to the activation
361    *
362    * Indicates that the action was just activated.
363    *
364    * @parameter will always be of the expected type.  In the event that
365    * an incorrect type was given, no signal will be emitted.
366    *
367    * Since GLib 2.40, if no handler is connected to this signal then the
368    * default behaviour for boolean-stated actions with a %NULL parameter
369    * type is to toggle them via the #GSimpleAction::change-state signal.
370    * For stateful actions where the state type is equal to the parameter
371    * type, the default is to forward them directly to
372    * #GSimpleAction::change-state.  This should allow almost all users
373    * of #GSimpleAction to connect only one handler or the other.
374    *
375    * Since: 2.28
376    */
377   g_simple_action_signals[SIGNAL_ACTIVATE] =
378     g_signal_new (I_("activate"),
379                   G_TYPE_SIMPLE_ACTION,
380                   G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
381                   0, NULL, NULL,
382                   g_cclosure_marshal_VOID__VARIANT,
383                   G_TYPE_NONE, 1,
384                   G_TYPE_VARIANT);
385
386   /**
387    * GSimpleAction::change-state:
388    * @simple: the #GSimpleAction
389    * @value: (allow-none): the requested value for the state
390    *
391    * Indicates that the action just received a request to change its
392    * state.
393    *
394    * @value will always be of the correct state type.  In the event that
395    * an incorrect type was given, no signal will be emitted.
396    *
397    * If no handler is connected to this signal then the default
398    * behaviour is to call g_simple_action_set_state() to set the state
399    * to the requested value.  If you connect a signal handler then no
400    * default action is taken.  If the state should change then you must
401    * call g_simple_action_set_state() from the handler.
402    *
403    * <example>
404    * <title>Example 'change-state' handler</title>
405    * <programlisting>
406    * static void
407    * change_volume_state (GSimpleAction *action,
408    *                      GVariant      *value,
409    *                      gpointer       user_data)
410    * {
411    *   gint requested;
412    *
413    *   requested = g_variant_get_int32 (value);
414    *
415    *   // Volume only goes from 0 to 10
416    *   if (0 <= requested && requested <= 10)
417    *     g_simple_action_set_state (action, value);
418    * }
419    * </programlisting>
420    * </example>
421    *
422    * The handler need not set the state to the requested value.  It
423    * could set it to any value at all, or take some other action.
424    *
425    * Since: 2.30
426    */
427   g_simple_action_signals[SIGNAL_CHANGE_STATE] =
428     g_signal_new (I_("change-state"),
429                   G_TYPE_SIMPLE_ACTION,
430                   G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
431                   0, NULL, NULL,
432                   g_cclosure_marshal_VOID__VARIANT,
433                   G_TYPE_NONE, 1,
434                   G_TYPE_VARIANT);
435
436   /**
437    * GSimpleAction:name:
438    *
439    * The name of the action.  This is mostly meaningful for identifying
440    * the action once it has been added to a #GSimpleActionGroup.
441    *
442    * Since: 2.28
443    **/
444   g_object_class_install_property (object_class, PROP_NAME,
445                                    g_param_spec_string ("name",
446                                                         P_("Action Name"),
447                                                         P_("The name used to invoke the action"),
448                                                         NULL,
449                                                         G_PARAM_READWRITE |
450                                                         G_PARAM_CONSTRUCT_ONLY |
451                                                         G_PARAM_STATIC_STRINGS));
452
453   /**
454    * GSimpleAction:parameter-type:
455    *
456    * The type of the parameter that must be given when activating the
457    * action.
458    *
459    * Since: 2.28
460    **/
461   g_object_class_install_property (object_class, PROP_PARAMETER_TYPE,
462                                    g_param_spec_boxed ("parameter-type",
463                                                        P_("Parameter Type"),
464                                                        P_("The type of GVariant passed to activate()"),
465                                                        G_TYPE_VARIANT_TYPE,
466                                                        G_PARAM_READWRITE |
467                                                        G_PARAM_CONSTRUCT_ONLY |
468                                                        G_PARAM_STATIC_STRINGS));
469
470   /**
471    * GSimpleAction:enabled:
472    *
473    * If @action is currently enabled.
474    *
475    * If the action is disabled then calls to g_action_activate() and
476    * g_action_change_state() have no effect.
477    *
478    * Since: 2.28
479    **/
480   g_object_class_install_property (object_class, PROP_ENABLED,
481                                    g_param_spec_boolean ("enabled",
482                                                          P_("Enabled"),
483                                                          P_("If the action can be activated"),
484                                                          TRUE,
485                                                          G_PARAM_READWRITE |
486                                                          G_PARAM_STATIC_STRINGS));
487
488   /**
489    * GSimpleAction:state-type:
490    *
491    * The #GVariantType of the state that the action has, or %NULL if the
492    * action is stateless.
493    *
494    * Since: 2.28
495    **/
496   g_object_class_install_property (object_class, PROP_STATE_TYPE,
497                                    g_param_spec_boxed ("state-type",
498                                                        P_("State Type"),
499                                                        P_("The type of the state kept by the action"),
500                                                        G_TYPE_VARIANT_TYPE,
501                                                        G_PARAM_READABLE |
502                                                        G_PARAM_STATIC_STRINGS));
503
504   /**
505    * GSimpleAction:state:
506    *
507    * The state of the action, or %NULL if the action is stateless.
508    *
509    * Since: 2.28
510    **/
511   g_object_class_install_property (object_class, PROP_STATE,
512                                    g_param_spec_variant ("state",
513                                                          P_("State"),
514                                                          P_("The state the action is in"),
515                                                          G_VARIANT_TYPE_ANY,
516                                                          NULL,
517                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
518                                                          G_PARAM_STATIC_STRINGS));
519 }
520
521 /**
522  * g_simple_action_set_enabled:
523  * @simple: a #GSimpleAction
524  * @enabled: whether the action is enabled
525  *
526  * Sets the action as enabled or not.
527  *
528  * An action must be enabled in order to be activated or in order to
529  * have its state changed from outside callers.
530  *
531  * This should only be called by the implementor of the action.  Users
532  * of the action should not attempt to modify its enabled flag.
533  *
534  * Since: 2.28
535  **/
536 void
537 g_simple_action_set_enabled (GSimpleAction *simple,
538                              gboolean       enabled)
539 {
540   g_return_if_fail (G_IS_SIMPLE_ACTION (simple));
541
542   enabled = !!enabled;
543
544   if (simple->enabled != enabled)
545     {
546       simple->enabled = enabled;
547       g_object_notify (G_OBJECT (simple), "enabled");
548     }
549 }
550 /**
551  * g_simple_action_new:
552  * @name: the name of the action
553  * @parameter_type: (allow-none): the type of parameter to the activate function
554  *
555  * Creates a new action.
556  *
557  * The created action is stateless.  See g_simple_action_new_stateful().
558  *
559  * Returns: a new #GSimpleAction
560  *
561  * Since: 2.28
562  **/
563 GSimpleAction *
564 g_simple_action_new (const gchar        *name,
565                      const GVariantType *parameter_type)
566 {
567   return g_object_new (G_TYPE_SIMPLE_ACTION,
568                        "name", name,
569                        "parameter-type", parameter_type,
570                        NULL);
571 }
572
573 /**
574  * g_simple_action_new_stateful:
575  * @name: the name of the action
576  * @parameter_type: (allow-none): the type of the parameter to the activate function
577  * @state: the initial state of the action
578  *
579  * Creates a new stateful action.
580  *
581  * @state is the initial state of the action.  All future state values
582  * must have the same #GVariantType as the initial state.
583  *
584  * If the @state GVariant is floating, it is consumed.
585  *
586  * Returns: a new #GSimpleAction
587  *
588  * Since: 2.28
589  **/
590 GSimpleAction *
591 g_simple_action_new_stateful (const gchar        *name,
592                               const GVariantType *parameter_type,
593                               GVariant           *state)
594 {
595   return g_object_new (G_TYPE_SIMPLE_ACTION,
596                        "name", name,
597                        "parameter-type", parameter_type,
598                        "state", state,
599                        NULL);
600 }