2 * Copyright © 2010 Codethink Limited
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.
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.
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.
19 * Authors: Ryan Lortie <desrt@desrt.ca>
23 #include "gactiongroup.h"
25 #include "gio-marshal.h"
29 * SECTION:gactiongroup
30 * @title: GActionGroup
31 * @short_description: a group of actions
33 * #GActionGroup represents a group of actions.
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.
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_enabled() but
45 * not an equivalent <function>set()</function> call.
47 * Signals are emitted on the action group in response to state changes
48 * on individual actions.
51 G_DEFINE_ABSTRACT_TYPE (GActionGroup, g_action_group, G_TYPE_OBJECT)
56 SIGNAL_ACTION_REMOVED,
57 SIGNAL_ACTION_ENABLED_CHANGED,
58 SIGNAL_ACTION_STATE_CHANGED,
62 static guint g_action_group_signals[NR_SIGNALS];
65 g_action_group_init (GActionGroup *action_group)
70 g_action_group_class_init (GActionGroupClass *class)
73 * GActionGroup::action-added:
74 * @action_group: the #GActionGroup that changed
75 * @action_name: the name of the action in @action_group
77 * Signals that a new action was just added to the group. This signal
78 * is emitted after the action has been added and is now visible.
82 g_action_group_signals[SIGNAL_ACTION_ADDED] =
83 g_signal_new (I_("action-added"),
85 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
86 G_STRUCT_OFFSET (GActionGroupClass, action_added),
88 g_cclosure_marshal_VOID__STRING,
93 * GActionGroup::action-removed:
94 * @action_group: the #GActionGroup that changed
95 * @action_name: the name of the action in @action_group
97 * Signals that an action is just about to be removed from the group.
98 * This signal is emitted before the action is removed, so the action
99 * is still visible and can be queried from the signal handler.
103 g_action_group_signals[SIGNAL_ACTION_REMOVED] =
104 g_signal_new (I_("action-removed"),
106 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
107 G_STRUCT_OFFSET (GActionGroupClass, action_removed),
109 g_cclosure_marshal_VOID__STRING,
115 * GActionGroup::action-enabled-changed:
116 * @action_group: the #GActionGroup that changed
117 * @action_name: the name of the action in @action_group
118 * @enabled: whether the action is enabled or not
120 * Signals that the enabled status of the named action has changed.
124 g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED] =
125 g_signal_new (I_("action-enabled-changed"),
127 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
128 G_STRUCT_OFFSET (GActionGroupClass, action_enabled_changed),
130 _gio_marshal_VOID__STRING_BOOLEAN,
136 * GActionGroup::action-state-changed:
137 * @action_group: the #GActionGroup that changed
138 * @action_name: the name of the action in @action_group
139 * @value: the new value of the state
141 * Signals that the state of the named action has changed.
145 g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED] =
146 g_signal_new (I_("action-state-changed"),
148 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
149 G_STRUCT_OFFSET (GActionGroupClass, action_state_changed),
151 _gio_marshal_VOID__STRING_VARIANT,
158 * g_action_group_list_actions:
159 * @action_group: a #GActionGroup
161 * Lists the actions contained within @action_group.
163 * The caller is responsible for freeing the list with g_strfreev() when
164 * it is no longer required.
166 * Returns: a %NULL-terminated array of the names of the actions in the group
171 g_action_group_list_actions (GActionGroup *action_group)
173 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
175 return G_ACTION_GROUP_GET_CLASS (action_group)->list_actions (action_group);
179 * g_action_group_has_action:
180 * @action_group: a #GActionGroup
181 * @action_name: the name of the action to check for
183 * Checks if the named action exists within @action_group.
185 * Returns: whether the named action exists
190 g_action_group_has_action (GActionGroup *action_group,
191 const gchar *action_name)
193 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
195 return G_ACTION_GROUP_GET_CLASS (action_group)->has_action (action_group, action_name);
199 * g_action_group_get_parameter_type:
200 * @action_group: a #GActionGroup
201 * @action_name: the name of the action to query
203 * Queries the type of the parameter that must be given when activating
204 * the named action within @action_group.
206 * When activating the action using g_action_group_activate(), the
207 * #GVariant given to that function must be of the type returned by this
210 * In the case that this function returns %NULL, you must not give any
211 * #GVariant, but %NULL instead.
213 * The parameter type of a particular action will never change but it is
214 * possible for an action to be removed and for a new action to be added
215 * with the same name but a different parameter type.
217 * Return value: the parameter type
222 g_action_group_get_parameter_type (GActionGroup *action_group,
223 const gchar *action_name)
225 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
227 return G_ACTION_GROUP_GET_CLASS (action_group)->get_parameter_type (action_group, action_name);
231 * g_action_group_get_state_type:
232 * @action_group: a #GActionGroup
233 * @action_name: the name of the action to query
235 * Queries the type of the state of the named action within
238 * If the action is stateful then this function returns the
239 * #GVariantType of the state. All calls to g_action_group_set_state()
240 * must give a #GVariant of this type and g_action_group_get_state()
241 * will return a #GVariant of the same type.
243 * If the action is not stateful then this function will return %NULL.
244 * In that case, g_action_group_get_state() will return %NULL and you
245 * must not call g_action_group_set_state().
247 * The state type of a particular action will never change but it is
248 * possible for an action to be removed and for a new action to be added
249 * with the same name but a different state type.
251 * Returns: (allow-none): the state type, if the action is stateful
256 g_action_group_get_state_type (GActionGroup *action_group,
257 const gchar *action_name)
259 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
261 return G_ACTION_GROUP_GET_CLASS (action_group)->get_state_type (action_group, action_name);
265 * g_action_group_get_state_hint:
266 * @action_group: a #GActionGroup
267 * @action_name: the name of the action to query
269 * Requests a hint about the valid range of values for the state of the
270 * named action within @action_group.
272 * If %NULL is returned it either means that the action is not stateful
273 * or that there is no hint about the valid range of values for the
274 * state of the action.
276 * If a #GVariant array is returned then each item in the array is a
277 * possible value for the state. If a #GVariant pair (ie: two-tuple) is
278 * returned then the tuple specifies the inclusive lower and upper bound
279 * of valid values for the state.
281 * In any case, the information is merely a hint. It may be possible to
282 * have a state value outside of the hinted range and setting a value
283 * within the range may fail.
285 * The return value (if non-%NULL) should be freed with
286 * g_variant_unref() when it is no longer required.
288 * Return value: the state range hint
293 g_action_group_get_state_hint (GActionGroup *action_group,
294 const gchar *action_name)
296 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
298 return G_ACTION_GROUP_GET_CLASS (action_group)->get_state_hint (action_group, action_name);
302 * g_action_group_get_enabled:
303 * @action_group: a #GActionGroup
304 * @action_name: the name of the action to query
306 * Checks if the named action within @action_group is currently enabled.
308 * An action must be enabled in order to be activated or in order to
309 * have its state changed from outside callers.
311 * Return value: whether or not the action is currently enabled
316 g_action_group_get_enabled (GActionGroup *action_group,
317 const gchar *action_name)
319 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
321 return G_ACTION_GROUP_GET_CLASS (action_group)->get_enabled (action_group, action_name);
325 * g_action_group_get_state:
326 * @action_group: a #GActionGroup
327 * @action_name: the name of the action to query
329 * Queries the current state of the named action within @action_group.
331 * If the action is not stateful then %NULL will be returned. If the
332 * action is stateful then the type of the return value is the type
333 * given by g_action_group_get_state_type().
335 * The return value (if non-%NULL) should be freed with
336 * g_variant_unref() when it is no longer required.
338 * Return value: the current state of the action
343 g_action_group_get_state (GActionGroup *action_group,
344 const gchar *action_name)
346 g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
348 return G_ACTION_GROUP_GET_CLASS (action_group)->get_state (action_group, action_name);
352 * g_action_group_set_state:
353 * @action_group: a #GActionGroup
354 * @action_name: the name of the action to request the change on
355 * @value: the new state
357 * Request for the state of the named action within @action_group to be
360 * The action must be stateful and @value must be of the correct type.
361 * See g_action_group_get_state_type().
363 * This call merely requests a change. The action may refuse to change
364 * its state or may change its state to something other than @value.
365 * See g_action_group_get_state_hint().
367 * If the @value GVariant is floating, it is consumed.
372 g_action_group_set_state (GActionGroup *action_group,
373 const gchar *action_name,
376 g_return_if_fail (G_IS_ACTION_GROUP (action_group));
377 g_return_if_fail (action_name != NULL);
378 g_return_if_fail (value != NULL);
380 G_ACTION_GROUP_GET_CLASS (action_group)->set_state (action_group, action_name, value);
384 * g_action_group_activate:
385 * @action_group: a #GActionGroup
386 * @action_name: the name of the action to activate
387 * @parameter: (allow-none): parameters to the activation
389 * Activate the named action within @action_group.
391 * If the action is expecting a parameter, then the correct type of
392 * parameter must be given as @parameter. If the action is expecting no
393 * parameters then @parameter must be %NULL. See
394 * g_action_group_get_parameter_type().
399 g_action_group_activate (GActionGroup *action_group,
400 const gchar *action_name,
403 g_return_if_fail (G_IS_ACTION_GROUP (action_group));
404 g_return_if_fail (action_name != NULL);
406 G_ACTION_GROUP_GET_CLASS (action_group)->activate (action_group, action_name, parameter);
410 * g_action_group_action_added:
411 * @action_group: a #GActionGroup
412 * @action_name: the name of an action in the group
414 * Emits the #GActionGroup::action-added signal on @action_group.
416 * This function should only be called by #GActionGroup implementations.
421 g_action_group_action_added (GActionGroup *action_group,
422 const gchar *action_name)
424 g_return_if_fail (G_IS_ACTION_GROUP (action_group));
425 g_return_if_fail (action_name != NULL);
427 g_signal_emit (action_group,
428 g_action_group_signals[SIGNAL_ACTION_ADDED],
429 g_quark_try_string (action_name),
434 * g_action_group_action_removed:
435 * @action_group: a #GActionGroup
436 * @action_name: the name of an action in the group
438 * Emits the #GActionGroup::action-removed signal on @action_group.
440 * This function should only be called by #GActionGroup implementations.
445 g_action_group_action_removed (GActionGroup *action_group,
446 const gchar *action_name)
448 g_return_if_fail (G_IS_ACTION_GROUP (action_group));
449 g_return_if_fail (action_name != NULL);
451 g_signal_emit (action_group,
452 g_action_group_signals[SIGNAL_ACTION_REMOVED],
453 g_quark_try_string (action_name),
458 * g_action_group_action_enabled_changed:
459 * @action_group: a #GActionGroup
460 * @action_name: the name of an action in the group
461 * @enabled: whether or not the action is now enabled
463 * Emits the #GActionGroup::action-enabled-changed signal on @action_group.
465 * This function should only be called by #GActionGroup implementations.
470 g_action_group_action_enabled_changed (GActionGroup *action_group,
471 const gchar *action_name,
474 g_return_if_fail (G_IS_ACTION_GROUP (action_group));
475 g_return_if_fail (action_name != NULL);
479 g_signal_emit (action_group,
480 g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED],
481 g_quark_try_string (action_name),
487 * g_action_group_action_state_changed:
488 * @action_group: a #GActionGroup
489 * @action_name: the name of an action in the group
490 * @state: the new state of the named action
492 * Emits the #GActionGroup::action-state-changed signal on @action_group.
494 * This function should only be called by #GActionGroup implementations.
499 g_action_group_action_state_changed (GActionGroup *action_group,
500 const gchar *action_name,
503 g_return_if_fail (G_IS_ACTION_GROUP (action_group));
504 g_return_if_fail (action_name != NULL);
506 g_signal_emit (action_group,
507 g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED],
508 g_quark_try_string (action_name),