Test runtime dir getter
[platform/upstream/glib.git] / gio / gactiongroup.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 #include "gactiongroup.h"
24 #include "gaction.h"
25 #include "gio-marshal.h"
26 #include "glibintl.h"
27
28 /**
29  * SECTION:gactiongroup
30  * @title: GActionGroup
31  * @short_description: A group of actions
32  *
33  * #GActionGroup represents a group of actions.
34  *
35  * Each action in the group has a unique name (which is a string).  All
36  * method calls, except g_action_group_list_actions() take the name of
37  * an action as an argument.
38  *
39  * The #GActionGroup API is meant to be the 'public' API to the action
40  * group.  The calls here are exactly the interaction that 'external
41  * forces' (eg: UI, incoming D-Bus messages, etc.) are supposed to have
42  * with actions.  'Internal' APIs (ie: ones meant only to be accessed by
43  * the action group implementation) are found on subclasses.  This is
44  * why you will find -- for example -- g_action_group_get_action_enabled()
45  * but not an equivalent <function>set()</function> call.
46  *
47  * Signals are emitted on the action group in response to state changes
48  * on individual actions.
49  **/
50
51 G_DEFINE_INTERFACE (GActionGroup, g_action_group, G_TYPE_OBJECT)
52
53 enum
54 {
55   SIGNAL_ACTION_ADDED,
56   SIGNAL_ACTION_REMOVED,
57   SIGNAL_ACTION_ENABLED_CHANGED,
58   SIGNAL_ACTION_STATE_CHANGED,
59   NR_SIGNALS
60 };
61
62 static guint g_action_group_signals[NR_SIGNALS];
63
64 static void
65 g_action_group_default_init (GActionGroupInterface *class)
66 {
67   /**
68    * GActionGroup::action-added:
69    * @action_group: the #GActionGroup that changed
70    * @action_name: the name of the action in @action_group
71    *
72    * Signals that a new action was just added to the group.
73    * This signal is emitted after the action has been added
74    * and is now visible.
75    *
76    * Since: 2.28
77    **/
78   g_action_group_signals[SIGNAL_ACTION_ADDED] =
79     g_signal_new (I_("action-added"),
80                   G_TYPE_ACTION_GROUP,
81                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
82                   G_STRUCT_OFFSET (GActionGroupInterface, action_added),
83                   NULL, NULL,
84                   g_cclosure_marshal_VOID__STRING,
85                   G_TYPE_NONE, 1,
86                   G_TYPE_STRING);
87
88   /**
89    * GActionGroup::action-removed:
90    * @action_group: the #GActionGroup that changed
91    * @action_name: the name of the action in @action_group
92    *
93    * Signals that an action is just about to be removed from the group.
94    * This signal is emitted before the action is removed, so the action
95    * is still visible and can be queried from the signal handler.
96    *
97    * Since: 2.28
98    **/
99   g_action_group_signals[SIGNAL_ACTION_REMOVED] =
100     g_signal_new (I_("action-removed"),
101                   G_TYPE_ACTION_GROUP,
102                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
103                   G_STRUCT_OFFSET (GActionGroupInterface, action_removed),
104                   NULL, NULL,
105                   g_cclosure_marshal_VOID__STRING,
106                   G_TYPE_NONE, 1,
107                   G_TYPE_STRING);
108
109
110   /**
111    * GActionGroup::action-enabled-changed:
112    * @action_group: the #GActionGroup that changed
113    * @action_name: the name of the action in @action_group
114    * @enabled: whether the action is enabled or not
115    *
116    * Signals that the enabled status of the named action has changed.
117    *
118    * Since: 2.28
119    **/
120   g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED] =
121     g_signal_new (I_("action-enabled-changed"),
122                   G_TYPE_ACTION_GROUP,
123                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
124                   G_STRUCT_OFFSET (GActionGroupInterface,
125                                    action_enabled_changed),
126                   NULL, NULL,
127                   _gio_marshal_VOID__STRING_BOOLEAN,
128                   G_TYPE_NONE, 2,
129                   G_TYPE_STRING,
130                   G_TYPE_BOOLEAN);
131
132   /**
133    * GActionGroup::action-state-changed:
134    * @action_group: the #GActionGroup that changed
135    * @action_name: the name of the action in @action_group
136    * @value: the new value of the state
137    *
138    * Signals that the state of the named action has changed.
139    *
140    * Since: 2.28
141    **/
142   g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED] =
143     g_signal_new (I_("action-state-changed"),
144                   G_TYPE_ACTION_GROUP,
145                   G_SIGNAL_RUN_LAST |
146                   G_SIGNAL_DETAILED |
147                   G_SIGNAL_MUST_COLLECT,
148                   G_STRUCT_OFFSET (GActionGroupInterface,
149                                    action_state_changed),
150                   NULL, NULL,
151                   _gio_marshal_VOID__STRING_VARIANT,
152                   G_TYPE_NONE, 2,
153                   G_TYPE_STRING,
154                   G_TYPE_VARIANT);
155 }
156
157 /**
158  * g_action_group_list_actions:
159  * @action_group: a #GActionGroup
160  *
161  * Lists the actions contained within @action_group.
162  *
163  * The caller is responsible for freeing the list with g_strfreev() when
164  * it is no longer required.
165  *
166  * Returns: (transfer full): a %NULL-terminated array of the names of the
167  * actions in the groupb
168  *
169  * Since: 2.28
170  **/
171 gchar **
172 g_action_group_list_actions (GActionGroup *action_group)
173 {
174   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
175
176   return G_ACTION_GROUP_GET_IFACE (action_group)
177     ->list_actions (action_group);
178 }
179
180 /**
181  * g_action_group_has_action:
182  * @action_group: a #GActionGroup
183  * @action_name: the name of the action to check for
184  *
185  * Checks if the named action exists within @action_group.
186  *
187  * Returns: whether the named action exists
188  *
189  * Since: 2.28
190  **/
191 gboolean
192 g_action_group_has_action (GActionGroup *action_group,
193                            const gchar  *action_name)
194 {
195   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
196
197   return G_ACTION_GROUP_GET_IFACE (action_group)
198     ->has_action (action_group, action_name);
199 }
200
201 /**
202  * g_action_group_get_action_parameter_type:
203  * @action_group: a #GActionGroup
204  * @action_name: the name of the action to query
205  *
206  * Queries the type of the parameter that must be given when activating
207  * the named action within @action_group.
208  *
209  * When activating the action using g_action_group_activate_action(),
210  * the #GVariant given to that function must be of the type returned
211  * by this function.
212  *
213  * In the case that this function returns %NULL, you must not give any
214  * #GVariant, but %NULL instead.
215  *
216  * The parameter type of a particular action will never change but it is
217  * possible for an action to be removed and for a new action to be added
218  * with the same name but a different parameter type.
219  *
220  * Return value: the parameter type
221  *
222  * Since: 2.28
223  **/
224 const GVariantType *
225 g_action_group_get_action_parameter_type (GActionGroup *action_group,
226                                           const gchar  *action_name)
227 {
228   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
229
230   return G_ACTION_GROUP_GET_IFACE (action_group)
231     ->get_action_parameter_type (action_group, action_name);
232 }
233
234 /**
235  * g_action_group_get_action_state_type:
236  * @action_group: a #GActionGroup
237  * @action_name: the name of the action to query
238  *
239  * Queries the type of the state of the named action within
240  * @action_group.
241  *
242  * If the action is stateful then this function returns the
243  * #GVariantType of the state.  All calls to
244  * g_action_group_change_action_state() must give a #GVariant of this
245  * type and g_action_group_get_action_state() will return a #GVariant
246  * of the same type.
247  *
248  * If the action is not stateful then this function will return %NULL.
249  * In that case, g_action_group_get_action_state() will return %NULL
250  * and you must not call g_action_group_change_action_state().
251  *
252  * The state type of a particular action will never change but it is
253  * possible for an action to be removed and for a new action to be added
254  * with the same name but a different state type.
255  *
256  * Returns: (transfer full): the state type, if the action is stateful
257  *
258  * Since: 2.28
259  **/
260 const GVariantType *
261 g_action_group_get_action_state_type (GActionGroup *action_group,
262                                       const gchar  *action_name)
263 {
264   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
265
266   return G_ACTION_GROUP_GET_IFACE (action_group)
267     ->get_action_state_type (action_group, action_name);
268 }
269
270 /**
271  * g_action_group_get_action_state_hint:
272  * @action_group: a #GActionGroup
273  * @action_name: the name of the action to query
274  *
275  * Requests a hint about the valid range of values for the state of the
276  * named action within @action_group.
277  *
278  * If %NULL is returned it either means that the action is not stateful
279  * or that there is no hint about the valid range of values for the
280  * state of the action.
281  *
282  * If a #GVariant array is returned then each item in the array is a
283  * possible value for the state.  If a #GVariant pair (ie: two-tuple) is
284  * returned then the tuple specifies the inclusive lower and upper bound
285  * of valid values for the state.
286  *
287  * In any case, the information is merely a hint.  It may be possible to
288  * have a state value outside of the hinted range and setting a value
289  * within the range may fail.
290  *
291  * The return value (if non-%NULL) should be freed with
292  * g_variant_unref() when it is no longer required.
293  *
294  * Return value: (transfer full): the state range hint
295  *
296  * Since: 2.28
297  **/
298 GVariant *
299 g_action_group_get_action_state_hint (GActionGroup *action_group,
300                                       const gchar  *action_name)
301 {
302   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
303
304   return G_ACTION_GROUP_GET_IFACE (action_group)
305     ->get_action_state_hint (action_group, action_name);
306 }
307
308 /**
309  * g_action_group_get_action_enabled:
310  * @action_group: a #GActionGroup
311  * @action_name: the name of the action to query
312  *
313  * Checks if the named action within @action_group is currently enabled.
314  *
315  * An action must be enabled in order to be activated or in order to
316  * have its state changed from outside callers.
317  *
318  * Return value: whether or not the action is currently enabled
319  *
320  * Since: 2.28
321  **/
322 gboolean
323 g_action_group_get_action_enabled (GActionGroup *action_group,
324                                    const gchar  *action_name)
325 {
326   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
327
328   return G_ACTION_GROUP_GET_IFACE (action_group)
329     ->get_action_enabled (action_group, action_name);
330 }
331
332 /**
333  * g_action_group_get_action_state:
334  * @action_group: a #GActionGroup
335  * @action_name: the name of the action to query
336  *
337  * Queries the current state of the named action within @action_group.
338  *
339  * If the action is not stateful then %NULL will be returned.  If the
340  * action is stateful then the type of the return value is the type
341  * given by g_action_group_get_action_state_type().
342  *
343  * The return value (if non-%NULL) should be freed with
344  * g_variant_unref() when it is no longer required.
345  *
346  * Return value: (allow-none): the current state of the action
347  *
348  * Since: 2.28
349  **/
350 GVariant *
351 g_action_group_get_action_state (GActionGroup *action_group,
352                                  const gchar  *action_name)
353 {
354   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
355
356   return G_ACTION_GROUP_GET_IFACE (action_group)
357     ->get_action_state (action_group, action_name);
358 }
359
360 /**
361  * g_action_group_change_action_state:
362  * @action_group: a #GActionGroup
363  * @action_name: the name of the action to request the change on
364  * @value: the new state
365  *
366  * Request for the state of the named action within @action_group to be
367  * changed to @value.
368  *
369  * The action must be stateful and @value must be of the correct type.
370  * See g_action_group_get_action_state_type().
371  *
372  * This call merely requests a change.  The action may refuse to change
373  * its state or may change its state to something other than @value.
374  * See g_action_group_get_action_state_hint().
375  *
376  * If the @value GVariant is floating, it is consumed.
377  *
378  * Since: 2.28
379  **/
380 void
381 g_action_group_change_action_state (GActionGroup *action_group,
382                                     const gchar  *action_name,
383                                     GVariant     *value)
384 {
385   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
386   g_return_if_fail (action_name != NULL);
387   g_return_if_fail (value != NULL);
388
389   G_ACTION_GROUP_GET_IFACE (action_group)
390     ->change_action_state (action_group, action_name, value);
391 }
392
393 /**
394  * g_action_group_activate_action:
395  * @action_group: a #GActionGroup
396  * @action_name: the name of the action to activate
397  * @parameter: (allow-none): parameters to the activation
398  *
399  * Activate the named action within @action_group.
400  *
401  * If the action is expecting a parameter, then the correct type of
402  * parameter must be given as @parameter.  If the action is expecting no
403  * parameters then @parameter must be %NULL.  See
404  * g_action_group_get_action_parameter_type().
405  *
406  * Since: 2.28
407  **/
408 void
409 g_action_group_activate_action (GActionGroup *action_group,
410                                 const gchar  *action_name,
411                                 GVariant     *parameter)
412 {
413   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
414   g_return_if_fail (action_name != NULL);
415
416   G_ACTION_GROUP_GET_IFACE (action_group)
417     ->activate_action (action_group, action_name, parameter);
418 }
419
420 /**
421  * g_action_group_action_added:
422  * @action_group: a #GActionGroup
423  * @action_name: the name of an action in the group
424  *
425  * Emits the #GActionGroup::action-added signal on @action_group.
426  *
427  * This function should only be called by #GActionGroup implementations.
428  *
429  * Since: 2.28
430  **/
431 void
432 g_action_group_action_added (GActionGroup *action_group,
433                              const gchar  *action_name)
434 {
435   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
436   g_return_if_fail (action_name != NULL);
437
438   g_signal_emit (action_group,
439                  g_action_group_signals[SIGNAL_ACTION_ADDED],
440                  g_quark_try_string (action_name),
441                  action_name);
442 }
443
444 /**
445  * g_action_group_action_removed:
446  * @action_group: a #GActionGroup
447  * @action_name: the name of an action in the group
448  *
449  * Emits the #GActionGroup::action-removed signal on @action_group.
450  *
451  * This function should only be called by #GActionGroup implementations.
452  *
453  * Since: 2.28
454  **/
455 void
456 g_action_group_action_removed (GActionGroup *action_group,
457                                const gchar  *action_name)
458 {
459   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
460   g_return_if_fail (action_name != NULL);
461
462   g_signal_emit (action_group,
463                  g_action_group_signals[SIGNAL_ACTION_REMOVED],
464                  g_quark_try_string (action_name),
465                  action_name);
466 }
467
468 /**
469  * g_action_group_action_enabled_changed:
470  * @action_group: a #GActionGroup
471  * @action_name: the name of an action in the group
472  * @enabled: whether or not the action is now enabled
473  *
474  * Emits the #GActionGroup::action-enabled-changed signal on @action_group.
475  *
476  * This function should only be called by #GActionGroup implementations.
477  *
478  * Since: 2.28
479  **/
480 void
481 g_action_group_action_enabled_changed (GActionGroup *action_group,
482                                        const gchar  *action_name,
483                                        gboolean      enabled)
484 {
485   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
486   g_return_if_fail (action_name != NULL);
487
488   enabled = !!enabled;
489
490   g_signal_emit (action_group,
491                  g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED],
492                  g_quark_try_string (action_name),
493                  action_name,
494                  enabled);
495 }
496
497 /**
498  * g_action_group_action_state_changed:
499  * @action_group: a #GActionGroup
500  * @action_name: the name of an action in the group
501  * @state: the new state of the named action
502  *
503  * Emits the #GActionGroup::action-state-changed signal on @action_group.
504  *
505  * This function should only be called by #GActionGroup implementations.
506  *
507  * Since: 2.28
508  **/
509 void
510 g_action_group_action_state_changed (GActionGroup *action_group,
511                                      const gchar  *action_name,
512                                      GVariant     *state)
513 {
514   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
515   g_return_if_fail (action_name != NULL);
516
517   g_signal_emit (action_group,
518                  g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED],
519                  g_quark_try_string (action_name),
520                  action_name,
521                  state);
522 }