c3748a902f109290493ca58f370bacc065998892
[platform/upstream/glib.git] / gio / gaction.c
1 /*
2  * Copyright © 2010 Codethink Limited
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at 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, see <http://www.gnu.org/licenses/>.
16  *
17  * Authors: Ryan Lortie <desrt@desrt.ca>
18  */
19
20 #include "config.h"
21 #include "gaction.h"
22 #include "glibintl.h"
23
24 #include <string.h>
25
26 G_DEFINE_INTERFACE (GAction, g_action, G_TYPE_OBJECT)
27
28 /**
29  * SECTION:gaction
30  * @title: GAction
31  * @short_description: An action interface
32  * @include: gio/gio.h
33  *
34  * #GAction represents a single named action.
35  *
36  * The main interface to an action is that it can be activated with
37  * g_action_activate().  This results in the 'activate' signal being
38  * emitted.  An activation has a #GVariant parameter (which may be
39  * %NULL).  The correct type for the parameter is determined by a static
40  * parameter type (which is given at construction time).
41  *
42  * An action may optionally have a state, in which case the state may be
43  * set with g_action_change_state().  This call takes a #GVariant.  The
44  * correct type for the state is determined by a static state type
45  * (which is given at construction time).
46  *
47  * The state may have a hint associated with it, specifying its valid
48  * range.
49  *
50  * #GAction is merely the interface to the concept of an action, as
51  * described above.  Various implementations of actions exist, including
52  * #GSimpleAction.
53  *
54  * In all cases, the implementing class is responsible for storing the
55  * name of the action, the parameter type, the enabled state, the
56  * optional state type and the state and emitting the appropriate
57  * signals when these change.  The implementor is responsible for filtering
58  * calls to g_action_activate() and g_action_change_state() for type
59  * safety and for the state being enabled.
60  *
61  * Probably the only useful thing to do with a #GAction is to put it
62  * inside of a #GSimpleActionGroup.
63  **/
64
65 /**
66  * GAction:
67  *
68  * #GAction is an opaque data structure and can only be accessed
69  * using the following functions.
70  **/
71
72 /**
73  * GActionInterface:
74  * @get_name: the virtual function pointer for g_action_get_name()
75  * @get_parameter_type: the virtual function pointer for g_action_get_parameter_type()
76  * @get_state_type: the virtual function pointer for g_action_get_state_type()
77  * @get_state_hint: the virtual function pointer for g_action_get_state_hint()
78  * @get_enabled: the virtual function pointer for g_action_get_enabled()
79  * @get_state: the virtual function pointer for g_action_get_state()
80  * @change_state: the virtual function pointer for g_action_change_state()
81  * @activate: the virtual function pointer for g_action_activate().  Note that #GAction does not have an
82  *            'activate' signal but that implementations of it may have one.
83  *
84  * The virtual function table for #GAction.
85  *
86  * Since: 2.28
87  */
88
89 void
90 g_action_default_init (GActionInterface *iface)
91 {
92   /**
93    * GAction:name:
94    *
95    * The name of the action.  This is mostly meaningful for identifying
96    * the action once it has been added to a #GActionGroup. It is immutable.
97    *
98    * Since: 2.28
99    **/
100   g_object_interface_install_property (iface,
101                                        g_param_spec_string ("name",
102                                                             P_("Action Name"),
103                                                             P_("The name used to invoke the action"),
104                                                             NULL,
105                                                             G_PARAM_READABLE |
106                                                             G_PARAM_STATIC_STRINGS));
107
108   /**
109    * GAction:parameter-type:
110    *
111    * The type of the parameter that must be given when activating the
112    * action. This is immutable, and may be %NULL if no parameter is needed when
113    * activating the action.
114    *
115    * Since: 2.28
116    **/
117   g_object_interface_install_property (iface,
118                                        g_param_spec_boxed ("parameter-type",
119                                                            P_("Parameter Type"),
120                                                            P_("The type of GVariant passed to activate()"),
121                                                            G_TYPE_VARIANT_TYPE,
122                                                            G_PARAM_READABLE |
123                                                            G_PARAM_STATIC_STRINGS));
124
125   /**
126    * GAction:enabled:
127    *
128    * If @action is currently enabled.
129    *
130    * If the action is disabled then calls to g_action_activate() and
131    * g_action_change_state() have no effect.
132    *
133    * Since: 2.28
134    **/
135   g_object_interface_install_property (iface,
136                                        g_param_spec_boolean ("enabled",
137                                                              P_("Enabled"),
138                                                              P_("If the action can be activated"),
139                                                              TRUE,
140                                                              G_PARAM_READABLE |
141                                                              G_PARAM_STATIC_STRINGS));
142
143   /**
144    * GAction:state-type:
145    *
146    * The #GVariantType of the state that the action has, or %NULL if the
147    * action is stateless. This is immutable.
148    *
149    * Since: 2.28
150    **/
151   g_object_interface_install_property (iface,
152                                        g_param_spec_boxed ("state-type",
153                                                            P_("State Type"),
154                                                            P_("The type of the state kept by the action"),
155                                                            G_TYPE_VARIANT_TYPE,
156                                                            G_PARAM_READABLE |
157                                                            G_PARAM_STATIC_STRINGS));
158
159   /**
160    * GAction:state:
161    *
162    * The state of the action, or %NULL if the action is stateless.
163    *
164    * Since: 2.28
165    **/
166   g_object_interface_install_property (iface,
167                                        g_param_spec_variant ("state",
168                                                              P_("State"),
169                                                              P_("The state the action is in"),
170                                                              G_VARIANT_TYPE_ANY,
171                                                              NULL,
172                                                              G_PARAM_READABLE |
173                                                              G_PARAM_STATIC_STRINGS));
174 }
175
176 /**
177  * g_action_change_state:
178  * @action: a #GAction
179  * @value: the new state
180  *
181  * Request for the state of @action to be changed to @value.
182  *
183  * The action must be stateful and @value must be of the correct type.
184  * See g_action_get_state_type().
185  *
186  * This call merely requests a change.  The action may refuse to change
187  * its state or may change its state to something other than @value.
188  * See g_action_get_state_hint().
189  *
190  * If the @value GVariant is floating, it is consumed.
191  *
192  * Since: 2.30
193  **/
194 void
195 g_action_change_state (GAction  *action,
196                        GVariant *value)
197 {
198   const GVariantType *state_type;
199
200   g_return_if_fail (G_IS_ACTION (action));
201   g_return_if_fail (value != NULL);
202   state_type = g_action_get_state_type (action);
203   g_return_if_fail (state_type != NULL);
204   g_return_if_fail (g_variant_is_of_type (value, state_type));
205
206   g_variant_ref_sink (value);
207
208   G_ACTION_GET_IFACE (action)
209     ->change_state (action, value);
210
211   g_variant_unref (value);
212 }
213
214 /**
215  * g_action_get_state:
216  * @action: a #GAction
217  *
218  * Queries the current state of @action.
219  *
220  * If the action is not stateful then %NULL will be returned.  If the
221  * action is stateful then the type of the return value is the type
222  * given by g_action_get_state_type().
223  *
224  * The return value (if non-%NULL) should be freed with
225  * g_variant_unref() when it is no longer required.
226  *
227  * Returns: (transfer full): the current state of the action
228  *
229  * Since: 2.28
230  **/
231 GVariant *
232 g_action_get_state (GAction *action)
233 {
234   g_return_val_if_fail (G_IS_ACTION (action), NULL);
235
236   return G_ACTION_GET_IFACE (action)
237     ->get_state (action);
238 }
239
240 /**
241  * g_action_get_name:
242  * @action: a #GAction
243  *
244  * Queries the name of @action.
245  *
246  * Returns: the name of the action
247  *
248  * Since: 2.28
249  **/
250 const gchar *
251 g_action_get_name (GAction *action)
252 {
253   g_return_val_if_fail (G_IS_ACTION (action), NULL);
254
255   return G_ACTION_GET_IFACE (action)
256     ->get_name (action);
257 }
258
259 /**
260  * g_action_get_parameter_type:
261  * @action: a #GAction
262  *
263  * Queries the type of the parameter that must be given when activating
264  * @action.
265  *
266  * When activating the action using g_action_activate(), the #GVariant
267  * given to that function must be of the type returned by this function.
268  *
269  * In the case that this function returns %NULL, you must not give any
270  * #GVariant, but %NULL instead.
271  *
272  * Returns: (nullable): the parameter type
273  *
274  * Since: 2.28
275  **/
276 const GVariantType *
277 g_action_get_parameter_type (GAction *action)
278 {
279   g_return_val_if_fail (G_IS_ACTION (action), NULL);
280
281   return G_ACTION_GET_IFACE (action)
282     ->get_parameter_type (action);
283 }
284
285 /**
286  * g_action_get_state_type:
287  * @action: a #GAction
288  *
289  * Queries the type of the state of @action.
290  *
291  * If the action is stateful (e.g. created with
292  * g_simple_action_new_stateful()) then this function returns the
293  * #GVariantType of the state.  This is the type of the initial value
294  * given as the state. All calls to g_action_change_state() must give a
295  * #GVariant of this type and g_action_get_state() will return a
296  * #GVariant of the same type.
297  *
298  * If the action is not stateful (e.g. created with g_simple_action_new())
299  * then this function will return %NULL. In that case, g_action_get_state()
300  * will return %NULL and you must not call g_action_change_state().
301  *
302  * Returns: (nullable): the state type, if the action is stateful
303  *
304  * Since: 2.28
305  **/
306 const GVariantType *
307 g_action_get_state_type (GAction *action)
308 {
309   g_return_val_if_fail (G_IS_ACTION (action), NULL);
310
311   return G_ACTION_GET_IFACE (action)
312     ->get_state_type (action);
313 }
314
315 /**
316  * g_action_get_state_hint:
317  * @action: a #GAction
318  *
319  * Requests a hint about the valid range of values for the state of
320  * @action.
321  *
322  * If %NULL is returned it either means that the action is not stateful
323  * or that there is no hint about the valid range of values for the
324  * state of the action.
325  *
326  * If a #GVariant array is returned then each item in the array is a
327  * possible value for the state.  If a #GVariant pair (ie: two-tuple) is
328  * returned then the tuple specifies the inclusive lower and upper bound
329  * of valid values for the state.
330  *
331  * In any case, the information is merely a hint.  It may be possible to
332  * have a state value outside of the hinted range and setting a value
333  * within the range may fail.
334  *
335  * The return value (if non-%NULL) should be freed with
336  * g_variant_unref() when it is no longer required.
337  *
338  * Returns: (nullable) (transfer full): the state range hint
339  *
340  * Since: 2.28
341  **/
342 GVariant *
343 g_action_get_state_hint (GAction *action)
344 {
345   g_return_val_if_fail (G_IS_ACTION (action), NULL);
346
347   return G_ACTION_GET_IFACE (action)
348     ->get_state_hint (action);
349 }
350
351 /**
352  * g_action_get_enabled:
353  * @action: a #GAction
354  *
355  * Checks if @action is currently enabled.
356  *
357  * An action must be enabled in order to be activated or in order to
358  * have its state changed from outside callers.
359  *
360  * Returns: whether the action is enabled
361  *
362  * Since: 2.28
363  **/
364 gboolean
365 g_action_get_enabled (GAction *action)
366 {
367   g_return_val_if_fail (G_IS_ACTION (action), FALSE);
368
369   return G_ACTION_GET_IFACE (action)
370     ->get_enabled (action);
371 }
372
373 /**
374  * g_action_activate:
375  * @action: a #GAction
376  * @parameter: (nullable): the parameter to the activation
377  *
378  * Activates the action.
379  *
380  * @parameter must be the correct type of parameter for the action (ie:
381  * the parameter type given at construction time).  If the parameter
382  * type was %NULL then @parameter must also be %NULL.
383  *
384  * If the @parameter GVariant is floating, it is consumed.
385  *
386  * Since: 2.28
387  **/
388 void
389 g_action_activate (GAction  *action,
390                    GVariant *parameter)
391 {
392   g_return_if_fail (G_IS_ACTION (action));
393
394   if (parameter != NULL)
395     g_variant_ref_sink (parameter);
396
397   G_ACTION_GET_IFACE (action)
398     ->activate (action, parameter);
399
400   if (parameter != NULL)
401     g_variant_unref (parameter);
402 }
403
404 /**
405  * g_action_name_is_valid:
406  * @action_name: a potential action name
407  *
408  * Checks if @action_name is valid.
409  *
410  * @action_name is valid if it consists only of alphanumeric characters,
411  * plus '-' and '.'.  The empty string is not a valid action name.
412  *
413  * It is an error to call this function with a non-utf8 @action_name.
414  * @action_name must not be %NULL.
415  *
416  * Returns: %TRUE if @action_name is valid
417  *
418  * Since: 2.38
419  **/
420 gboolean
421 g_action_name_is_valid (const gchar *action_name)
422 {
423   gchar c;
424   gint i;
425
426   g_return_val_if_fail (action_name != NULL, FALSE);
427
428   for (i = 0; (c = action_name[i]); i++)
429     if (!g_ascii_isalnum (c) && c != '.' && c != '-')
430       return FALSE;
431
432   return i > 0;
433 }
434
435 /**
436  * g_action_parse_detailed_name:
437  * @detailed_name: a detailed action name
438  * @action_name: (out): the action name
439  * @target_value: (out): the target value, or %NULL for no target
440  * @error: a pointer to a %NULL #GError, or %NULL
441  *
442  * Parses a detailed action name into its separate name and target
443  * components.
444  *
445  * Detailed action names can have three formats.
446  *
447  * The first format is used to represent an action name with no target
448  * value and consists of just an action name containing no whitespace
449  * nor the characters ':', '(' or ')'.  For example: "app.action".
450  *
451  * The second format is used to represent an action with a target value
452  * that is a non-empty string consisting only of alphanumerics, plus '-'
453  * and '.'.  In that case, the action name and target value are
454  * separated by a double colon ("::").  For example:
455  * "app.action::target".
456  *
457  * The third format is used to represent an action with any type of
458  * target value, including strings.  The target value follows the action
459  * name, surrounded in parens.  For example: "app.action(42)".  The
460  * target value is parsed using g_variant_parse().  If a tuple-typed
461  * value is desired, it must be specified in the same way, resulting in
462  * two sets of parens, for example: "app.action((1,2,3))".  A string
463  * target can be specified this way as well: "app.action('target')".
464  * For strings, this third format must be used if * target value is
465  * empty or contains characters other than alphanumerics, '-' and '.'.
466  *
467  * Returns: %TRUE if successful, else %FALSE with @error set
468  *
469  * Since: 2.38
470  **/
471 gboolean
472 g_action_parse_detailed_name (const gchar  *detailed_name,
473                               gchar       **action_name,
474                               GVariant    **target_value,
475                               GError      **error)
476 {
477   const gchar *target;
478   gsize target_len;
479   gsize base_len;
480
481   /* For historical (compatibility) reasons, this function accepts some
482    * cases of invalid action names as long as they don't interfere with
483    * the separation of the action from the target value.
484    *
485    * We decide which format we have based on which we see first between
486    * '::' '(' and '\0'.
487    */
488
489   if (*detailed_name == '\0' || *detailed_name == ' ')
490     goto bad_fmt;
491
492   base_len = strcspn (detailed_name, ": ()");
493   target = detailed_name + base_len;
494   target_len = strlen (target);
495
496   switch (target[0])
497     {
498     case ' ':
499     case ')':
500       goto bad_fmt;
501
502     case ':':
503       if (target[1] != ':')
504         goto bad_fmt;
505
506       *target_value = g_variant_ref_sink (g_variant_new_string (target + 2));
507       break;
508
509     case '(':
510       {
511         if (target[target_len - 1] != ')')
512           goto bad_fmt;
513
514         *target_value = g_variant_parse (NULL, target + 1, target + target_len - 1, NULL, error);
515         if (*target_value == NULL)
516           goto bad_fmt;
517       }
518       break;
519
520     case '\0':
521       *target_value = NULL;
522       break;
523     }
524
525   *action_name = g_strndup (detailed_name, base_len);
526
527   return TRUE;
528
529 bad_fmt:
530   if (error)
531     {
532       if (*error == NULL)
533         g_set_error (error, G_VARIANT_PARSE_ERROR, G_VARIANT_PARSE_ERROR_FAILED,
534                      "Detailed action name '%s' has invalid format", detailed_name);
535       else
536         g_prefix_error (error, "Detailed action name '%s' has invalid format: ", detailed_name);
537     }
538
539   return FALSE;
540 }
541
542 /**
543  * g_action_print_detailed_name:
544  * @action_name: a valid action name
545  * @target_value: (nullable): a #GVariant target value, or %NULL
546  *
547  * Formats a detailed action name from @action_name and @target_value.
548  *
549  * It is an error to call this function with an invalid action name.
550  *
551  * This function is the opposite of g_action_parse_detailed_name().
552  * It will produce a string that can be parsed back to the @action_name
553  * and @target_value by that function.
554  *
555  * See that function for the types of strings that will be printed by
556  * this function.
557  *
558  * Returns: a detailed format string
559  *
560  * Since: 2.38
561  **/
562 gchar *
563 g_action_print_detailed_name (const gchar *action_name,
564                               GVariant    *target_value)
565 {
566   g_return_val_if_fail (g_action_name_is_valid (action_name), NULL);
567
568   if (target_value == NULL)
569     return g_strdup (action_name);
570
571   if (g_variant_is_of_type (target_value, G_VARIANT_TYPE_STRING))
572     {
573       const gchar *str = g_variant_get_string (target_value, NULL);
574
575       if (g_action_name_is_valid (str))
576         return g_strconcat (action_name, "::", str, NULL);
577     }
578
579   {
580     GString *result = g_string_new (action_name);
581     g_string_append_c (result, '(');
582     g_variant_print_string (target_value, result, TRUE);
583     g_string_append_c (result, ')');
584
585     return g_string_free (result, FALSE);
586   }
587 }