(root)/
glib-2.79.0/
gio/
gactiongroup.c
       1  /*
       2   * Copyright © 2010 Codethink Limited
       3   *
       4   * SPDX-License-Identifier: LGPL-2.1-or-later
       5   *
       6   * This library is free software; you can redistribute it and/or
       7   * modify it under the terms of the GNU Lesser General Public
       8   * License as published by the Free Software Foundation; either
       9   * version 2.1 of the License, or (at your option) any later version.
      10   *
      11   * This library is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14   * Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General
      17   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18   *
      19   * Authors: Ryan Lortie <desrt@desrt.ca>
      20   */
      21  
      22  #include "config.h"
      23  #include "gactiongroup.h"
      24  #include "gaction.h"
      25  #include "glibintl.h"
      26  #include "gmarshal-internal.h"
      27  
      28  /**
      29   * GActionGroup:
      30   *
      31   * `GActionGroup` represents a group of actions.
      32   *
      33   * Actions can be used to expose functionality in a structured way, either
      34   * from one part of a program to another, or to the outside world. Action
      35   * groups are often used together with a `GMenuModel` that provides additional
      36   * representation data for displaying the actions to the user, e.g. in a menu.
      37   *
      38   * The main way to interact with the actions in a `GActionGroup` is to
      39   * activate them with [method@Gio.ActionGroup.activate_action]. Activating an
      40   * action may require a `GVariant` parameter. The required type of the
      41   * parameter can be inquired with [method@Gio.ActionGroup.get_action_parameter_type].
      42   * Actions may be disabled, see [method@Gio.ActionGroup.get_action_enabled].
      43   * Activating a disabled action has no effect.
      44   *
      45   * Actions may optionally have a state in the form of a #GVariant. The current
      46   * state of an action can be inquired with [method@Gio.ActionGroup.get_action_state].
      47   * Activating a stateful action may change its state, but it is also possible to
      48   * set the state by calling [method@Gio.ActionGroup.change_action_state].
      49   *
      50   * As typical example, consider a text editing application which has an
      51   * option to change the current font to 'bold'. A good way to represent
      52   * this would be a stateful action, with a boolean state. Activating the
      53   * action would toggle the state.
      54   *
      55   * Each action in the group has a unique name (which is a string).  All
      56   * method calls, except [method@Gio.ActionGroup.list_actions] take the name of
      57   * an action as an argument.
      58   *
      59   * The `GActionGroup` API is meant to be the 'public' API to the action
      60   * group. The calls here are exactly the interaction that 'external
      61   * forces' (eg: UI, incoming D-Bus messages, etc.) are supposed to have
      62   * with actions. 'Internal' APIs (ie: ones meant only to be accessed by
      63   * the action group implementation) are found on subclasses. This is
      64   * why you will find - for example - [method@Gio.ActionGroup.get_action_enabled]
      65   * but not an equivalent set() call.
      66   *
      67   * Signals are emitted on the action group in response to state changes
      68   * on individual actions.
      69   *
      70   * Implementations of `GActionGroup` should provide implementations for
      71   * the virtual functions [method@Gio.ActionGroup.list_actions] and
      72   * [method@Gio.ActionGroup.query_action]. The other virtual functions should
      73   * not be implemented - their "wrappers" are actually implemented with
      74   * calls to [method@Gio.ActionGroup.query_action].
      75   */
      76  
      77  /**
      78   * GActionGroupInterface:
      79   * @has_action: the virtual function pointer for g_action_group_has_action()
      80   * @list_actions: the virtual function pointer for g_action_group_list_actions()
      81   * @get_action_parameter_type: the virtual function pointer for g_action_group_get_action_parameter_type()
      82   * @get_action_state_type: the virtual function pointer for g_action_group_get_action_state_type()
      83   * @get_action_state_hint: the virtual function pointer for g_action_group_get_action_state_hint()
      84   * @get_action_enabled: the virtual function pointer for g_action_group_get_action_enabled()
      85   * @get_action_state: the virtual function pointer for g_action_group_get_action_state()
      86   * @change_action_state: the virtual function pointer for g_action_group_change_action_state()
      87   * @activate_action: the virtual function pointer for g_action_group_activate_action()
      88   * @action_added: the class closure for the #GActionGroup::action-added signal
      89   * @action_removed: the class closure for the #GActionGroup::action-removed signal
      90   * @action_enabled_changed: the class closure for the #GActionGroup::action-enabled-changed signal
      91   * @action_state_changed: the class closure for the #GActionGroup::action-enabled-changed signal
      92   * @query_action: the virtual function pointer for g_action_group_query_action()
      93   *
      94   * The virtual function table for #GActionGroup.
      95   *
      96   * Since: 2.28
      97   **/
      98  
      99  G_DEFINE_INTERFACE (GActionGroup, g_action_group, G_TYPE_OBJECT)
     100  
     101  enum
     102  {
     103    SIGNAL_ACTION_ADDED,
     104    SIGNAL_ACTION_REMOVED,
     105    SIGNAL_ACTION_ENABLED_CHANGED,
     106    SIGNAL_ACTION_STATE_CHANGED,
     107    NR_SIGNALS
     108  };
     109  
     110  static guint g_action_group_signals[NR_SIGNALS];
     111  
     112  static gboolean
     113  g_action_group_real_has_action (GActionGroup *action_group,
     114                                  const gchar  *action_name)
     115  {
     116    return g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, NULL);
     117  }
     118  
     119  static gboolean
     120  g_action_group_real_get_action_enabled (GActionGroup *action_group,
     121                                          const gchar  *action_name)
     122  {
     123    gboolean enabled;
     124  
     125    if (!g_action_group_query_action (action_group, action_name, &enabled, NULL, NULL, NULL, NULL))
     126      return FALSE;
     127  
     128    return enabled;
     129  }
     130  
     131  static const GVariantType *
     132  g_action_group_real_get_action_parameter_type (GActionGroup *action_group,
     133                                                 const gchar  *action_name)
     134  {
     135    const GVariantType *type;
     136  
     137    if (!g_action_group_query_action (action_group, action_name, NULL, &type, NULL, NULL, NULL))
     138      return NULL;
     139  
     140    return type;
     141  }
     142  
     143  static const GVariantType *
     144  g_action_group_real_get_action_state_type (GActionGroup *action_group,
     145                                             const gchar  *action_name)
     146  {
     147    const GVariantType *type;
     148  
     149    if (!g_action_group_query_action (action_group, action_name, NULL, NULL, &type, NULL, NULL))
     150      return NULL;
     151  
     152    return type;
     153  }
     154  
     155  static GVariant *
     156  g_action_group_real_get_action_state_hint (GActionGroup *action_group,
     157                                             const gchar  *action_name)
     158  {
     159    GVariant *hint;
     160  
     161    if (!g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, &hint, NULL))
     162      return NULL;
     163  
     164    return hint;
     165  }
     166  
     167  static GVariant *
     168  g_action_group_real_get_action_state (GActionGroup *action_group,
     169                                        const gchar  *action_name)
     170  {
     171    GVariant *state;
     172  
     173    if (!g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, &state))
     174      return NULL;
     175  
     176    return state;
     177  }
     178  
     179  static gboolean
     180  g_action_group_real_query_action (GActionGroup        *action_group,
     181                                    const gchar         *action_name,
     182                                    gboolean            *enabled,
     183                                    const GVariantType **parameter_type,
     184                                    const GVariantType **state_type,
     185                                    GVariant           **state_hint,
     186                                    GVariant           **state)
     187  {
     188    GActionGroupInterface *iface = G_ACTION_GROUP_GET_IFACE (action_group);
     189  
     190    /* we expect implementations to override this method, but we also
     191     * allow for implementations that existed before this method was
     192     * introduced to override the individual accessors instead.
     193     *
     194     * detect the case that neither has happened and report it.
     195     */
     196    if G_UNLIKELY (iface->has_action == g_action_group_real_has_action ||
     197                   iface->get_action_enabled == g_action_group_real_get_action_enabled ||
     198                   iface->get_action_parameter_type == g_action_group_real_get_action_parameter_type ||
     199                   iface->get_action_state_type == g_action_group_real_get_action_state_type ||
     200                   iface->get_action_state_hint == g_action_group_real_get_action_state_hint ||
     201                   iface->get_action_state == g_action_group_real_get_action_state)
     202      {
     203        g_critical ("Class '%s' implements GActionGroup interface without overriding "
     204                    "query_action() method -- bailing out to avoid infinite recursion.",
     205                    G_OBJECT_TYPE_NAME (action_group));
     206        return FALSE;
     207      }
     208  
     209    if (!(* iface->has_action) (action_group, action_name))
     210      return FALSE;
     211  
     212    if (enabled != NULL)
     213      *enabled = (* iface->get_action_enabled) (action_group, action_name);
     214  
     215    if (parameter_type != NULL)
     216      *parameter_type = (* iface->get_action_parameter_type) (action_group, action_name);
     217  
     218    if (state_type != NULL)
     219      *state_type = (* iface->get_action_state_type) (action_group, action_name);
     220  
     221    if (state_hint != NULL)
     222      *state_hint = (* iface->get_action_state_hint) (action_group, action_name);
     223  
     224    if (state != NULL)
     225      *state = (* iface->get_action_state) (action_group, action_name);
     226  
     227    return TRUE;
     228  }
     229  
     230  static void
     231  g_action_group_default_init (GActionGroupInterface *iface)
     232  {
     233    iface->has_action = g_action_group_real_has_action;
     234    iface->get_action_enabled = g_action_group_real_get_action_enabled;
     235    iface->get_action_parameter_type = g_action_group_real_get_action_parameter_type;
     236    iface->get_action_state_type = g_action_group_real_get_action_state_type;
     237    iface->get_action_state_hint = g_action_group_real_get_action_state_hint;
     238    iface->get_action_state = g_action_group_real_get_action_state;
     239    iface->query_action = g_action_group_real_query_action;
     240  
     241    /**
     242     * GActionGroup::action-added:
     243     * @action_group: the #GActionGroup that changed
     244     * @action_name: the name of the action in @action_group
     245     *
     246     * Signals that a new action was just added to the group.
     247     * This signal is emitted after the action has been added
     248     * and is now visible.
     249     *
     250     * Since: 2.28
     251     **/
     252    g_action_group_signals[SIGNAL_ACTION_ADDED] =
     253      g_signal_new (I_("action-added"),
     254                    G_TYPE_ACTION_GROUP,
     255                    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
     256                    G_STRUCT_OFFSET (GActionGroupInterface, action_added),
     257                    NULL, NULL,
     258                    NULL,
     259                    G_TYPE_NONE, 1,
     260                    G_TYPE_STRING);
     261  
     262    /**
     263     * GActionGroup::action-removed:
     264     * @action_group: the #GActionGroup that changed
     265     * @action_name: the name of the action in @action_group
     266     *
     267     * Signals that an action is just about to be removed from the group.
     268     * This signal is emitted before the action is removed, so the action
     269     * is still visible and can be queried from the signal handler.
     270     *
     271     * Since: 2.28
     272     **/
     273    g_action_group_signals[SIGNAL_ACTION_REMOVED] =
     274      g_signal_new (I_("action-removed"),
     275                    G_TYPE_ACTION_GROUP,
     276                    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
     277                    G_STRUCT_OFFSET (GActionGroupInterface, action_removed),
     278                    NULL, NULL,
     279                    NULL,
     280                    G_TYPE_NONE, 1,
     281                    G_TYPE_STRING);
     282  
     283  
     284    /**
     285     * GActionGroup::action-enabled-changed:
     286     * @action_group: the #GActionGroup that changed
     287     * @action_name: the name of the action in @action_group
     288     * @enabled: whether the action is enabled or not
     289     *
     290     * Signals that the enabled status of the named action has changed.
     291     *
     292     * Since: 2.28
     293     **/
     294    g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED] =
     295      g_signal_new (I_("action-enabled-changed"),
     296                    G_TYPE_ACTION_GROUP,
     297                    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
     298                    G_STRUCT_OFFSET (GActionGroupInterface,
     299                                     action_enabled_changed),
     300                    NULL, NULL,
     301                    _g_cclosure_marshal_VOID__STRING_BOOLEAN,
     302                    G_TYPE_NONE, 2,
     303                    G_TYPE_STRING,
     304                    G_TYPE_BOOLEAN);
     305    g_signal_set_va_marshaller (g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED],
     306                                G_TYPE_FROM_INTERFACE (iface),
     307                                _g_cclosure_marshal_VOID__STRING_BOOLEANv);
     308  
     309    /**
     310     * GActionGroup::action-state-changed:
     311     * @action_group: the #GActionGroup that changed
     312     * @action_name: the name of the action in @action_group
     313     * @value: the new value of the state
     314     *
     315     * Signals that the state of the named action has changed.
     316     *
     317     * Since: 2.28
     318     **/
     319    g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED] =
     320      g_signal_new (I_("action-state-changed"),
     321                    G_TYPE_ACTION_GROUP,
     322                    G_SIGNAL_RUN_LAST |
     323                    G_SIGNAL_DETAILED |
     324                    G_SIGNAL_MUST_COLLECT,
     325                    G_STRUCT_OFFSET (GActionGroupInterface,
     326                                     action_state_changed),
     327                    NULL, NULL,
     328                    _g_cclosure_marshal_VOID__STRING_VARIANT,
     329                    G_TYPE_NONE, 2,
     330                    G_TYPE_STRING,
     331                    G_TYPE_VARIANT);
     332    g_signal_set_va_marshaller (g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED],
     333                                G_TYPE_FROM_INTERFACE (iface),
     334                                _g_cclosure_marshal_VOID__STRING_VARIANTv);
     335  }
     336  
     337  /**
     338   * g_action_group_list_actions:
     339   * @action_group: a #GActionGroup
     340   *
     341   * Lists the actions contained within @action_group.
     342   *
     343   * The caller is responsible for freeing the list with g_strfreev() when
     344   * it is no longer required.
     345   *
     346   * Returns: (transfer full): a %NULL-terminated array of the names of the
     347   * actions in the group
     348   *
     349   * Since: 2.28
     350   **/
     351  gchar **
     352  g_action_group_list_actions (GActionGroup *action_group)
     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      ->list_actions (action_group);
     358  }
     359  
     360  /**
     361   * g_action_group_has_action:
     362   * @action_group: a #GActionGroup
     363   * @action_name: the name of the action to check for
     364   *
     365   * Checks if the named action exists within @action_group.
     366   *
     367   * Returns: whether the named action exists
     368   *
     369   * Since: 2.28
     370   **/
     371  gboolean
     372  g_action_group_has_action (GActionGroup *action_group,
     373                             const gchar  *action_name)
     374  {
     375    g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
     376  
     377    return G_ACTION_GROUP_GET_IFACE (action_group)
     378      ->has_action (action_group, action_name);
     379  }
     380  
     381  /**
     382   * g_action_group_get_action_parameter_type:
     383   * @action_group: a #GActionGroup
     384   * @action_name: the name of the action to query
     385   *
     386   * Queries the type of the parameter that must be given when activating
     387   * the named action within @action_group.
     388   *
     389   * When activating the action using g_action_group_activate_action(),
     390   * the #GVariant given to that function must be of the type returned
     391   * by this function.
     392   *
     393   * In the case that this function returns %NULL, you must not give any
     394   * #GVariant, but %NULL instead.
     395   *
     396   * The parameter type of a particular action will never change but it is
     397   * possible for an action to be removed and for a new action to be added
     398   * with the same name but a different parameter type.
     399   *
     400   * Returns: (nullable): the parameter type
     401   *
     402   * Since: 2.28
     403   **/
     404  const GVariantType *
     405  g_action_group_get_action_parameter_type (GActionGroup *action_group,
     406                                            const gchar  *action_name)
     407  {
     408    g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
     409  
     410    return G_ACTION_GROUP_GET_IFACE (action_group)
     411      ->get_action_parameter_type (action_group, action_name);
     412  }
     413  
     414  /**
     415   * g_action_group_get_action_state_type:
     416   * @action_group: a #GActionGroup
     417   * @action_name: the name of the action to query
     418   *
     419   * Queries the type of the state of the named action within
     420   * @action_group.
     421   *
     422   * If the action is stateful then this function returns the
     423   * #GVariantType of the state.  All calls to
     424   * g_action_group_change_action_state() must give a #GVariant of this
     425   * type and g_action_group_get_action_state() will return a #GVariant
     426   * of the same type.
     427   *
     428   * If the action is not stateful then this function will return %NULL.
     429   * In that case, g_action_group_get_action_state() will return %NULL
     430   * and you must not call g_action_group_change_action_state().
     431   *
     432   * The state type of a particular action will never change but it is
     433   * possible for an action to be removed and for a new action to be added
     434   * with the same name but a different state type.
     435   *
     436   * Returns: (nullable): the state type, if the action is stateful
     437   *
     438   * Since: 2.28
     439   **/
     440  const GVariantType *
     441  g_action_group_get_action_state_type (GActionGroup *action_group,
     442                                        const gchar  *action_name)
     443  {
     444    g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
     445  
     446    return G_ACTION_GROUP_GET_IFACE (action_group)
     447      ->get_action_state_type (action_group, action_name);
     448  }
     449  
     450  /**
     451   * g_action_group_get_action_state_hint:
     452   * @action_group: a #GActionGroup
     453   * @action_name: the name of the action to query
     454   *
     455   * Requests a hint about the valid range of values for the state of the
     456   * named action within @action_group.
     457   *
     458   * If %NULL is returned it either means that the action is not stateful
     459   * or that there is no hint about the valid range of values for the
     460   * state of the action.
     461   *
     462   * If a #GVariant array is returned then each item in the array is a
     463   * possible value for the state.  If a #GVariant pair (ie: two-tuple) is
     464   * returned then the tuple specifies the inclusive lower and upper bound
     465   * of valid values for the state.
     466   *
     467   * In any case, the information is merely a hint.  It may be possible to
     468   * have a state value outside of the hinted range and setting a value
     469   * within the range may fail.
     470   *
     471   * The return value (if non-%NULL) should be freed with
     472   * g_variant_unref() when it is no longer required.
     473   *
     474   * Returns: (nullable) (transfer full): the state range hint
     475   *
     476   * Since: 2.28
     477   **/
     478  GVariant *
     479  g_action_group_get_action_state_hint (GActionGroup *action_group,
     480                                        const gchar  *action_name)
     481  {
     482    g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
     483  
     484    return G_ACTION_GROUP_GET_IFACE (action_group)
     485      ->get_action_state_hint (action_group, action_name);
     486  }
     487  
     488  /**
     489   * g_action_group_get_action_enabled:
     490   * @action_group: a #GActionGroup
     491   * @action_name: the name of the action to query
     492   *
     493   * Checks if the named action within @action_group is currently enabled.
     494   *
     495   * An action must be enabled in order to be activated or in order to
     496   * have its state changed from outside callers.
     497   *
     498   * Returns: whether or not the action is currently enabled
     499   *
     500   * Since: 2.28
     501   **/
     502  gboolean
     503  g_action_group_get_action_enabled (GActionGroup *action_group,
     504                                     const gchar  *action_name)
     505  {
     506    g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
     507  
     508    return G_ACTION_GROUP_GET_IFACE (action_group)
     509      ->get_action_enabled (action_group, action_name);
     510  }
     511  
     512  /**
     513   * g_action_group_get_action_state:
     514   * @action_group: a #GActionGroup
     515   * @action_name: the name of the action to query
     516   *
     517   * Queries the current state of the named action within @action_group.
     518   *
     519   * If the action is not stateful then %NULL will be returned.  If the
     520   * action is stateful then the type of the return value is the type
     521   * given by g_action_group_get_action_state_type().
     522   *
     523   * The return value (if non-%NULL) should be freed with
     524   * g_variant_unref() when it is no longer required.
     525   *
     526   * Returns: (nullable) (transfer full): the current state of the action
     527   *
     528   * Since: 2.28
     529   **/
     530  GVariant *
     531  g_action_group_get_action_state (GActionGroup *action_group,
     532                                   const gchar  *action_name)
     533  {
     534    g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
     535  
     536    return G_ACTION_GROUP_GET_IFACE (action_group)
     537      ->get_action_state (action_group, action_name);
     538  }
     539  
     540  /**
     541   * g_action_group_change_action_state:
     542   * @action_group: a #GActionGroup
     543   * @action_name: the name of the action to request the change on
     544   * @value: the new state
     545   *
     546   * Request for the state of the named action within @action_group to be
     547   * changed to @value.
     548   *
     549   * The action must be stateful and @value must be of the correct type.
     550   * See g_action_group_get_action_state_type().
     551   *
     552   * This call merely requests a change.  The action may refuse to change
     553   * its state or may change its state to something other than @value.
     554   * See g_action_group_get_action_state_hint().
     555   *
     556   * If the @value GVariant is floating, it is consumed.
     557   *
     558   * Since: 2.28
     559   **/
     560  void
     561  g_action_group_change_action_state (GActionGroup *action_group,
     562                                      const gchar  *action_name,
     563                                      GVariant     *value)
     564  {
     565    g_return_if_fail (G_IS_ACTION_GROUP (action_group));
     566    g_return_if_fail (action_name != NULL);
     567    g_return_if_fail (value != NULL);
     568  
     569    G_ACTION_GROUP_GET_IFACE (action_group)
     570      ->change_action_state (action_group, action_name, value);
     571  }
     572  
     573  /**
     574   * g_action_group_activate_action:
     575   * @action_group: a #GActionGroup
     576   * @action_name: the name of the action to activate
     577   * @parameter: (nullable): parameters to the activation
     578   *
     579   * Activate the named action within @action_group.
     580   *
     581   * If the action is expecting a parameter, then the correct type of
     582   * parameter must be given as @parameter.  If the action is expecting no
     583   * parameters then @parameter must be %NULL.  See
     584   * g_action_group_get_action_parameter_type().
     585   *
     586   * If the #GActionGroup implementation supports asynchronous remote
     587   * activation over D-Bus, this call may return before the relevant
     588   * D-Bus traffic has been sent, or any replies have been received. In
     589   * order to block on such asynchronous activation calls,
     590   * g_dbus_connection_flush() should be called prior to the code, which
     591   * depends on the result of the action activation. Without flushing
     592   * the D-Bus connection, there is no guarantee that the action would
     593   * have been activated.
     594   *
     595   * The following code which runs in a remote app instance, shows an
     596   * example of a "quit" action being activated on the primary app
     597   * instance over D-Bus. Here g_dbus_connection_flush() is called
     598   * before `exit()`. Without g_dbus_connection_flush(), the "quit" action
     599   * may fail to be activated on the primary instance.
     600   *
     601   * |[<!-- language="C" -->
     602   * // call "quit" action on primary instance
     603   * g_action_group_activate_action (G_ACTION_GROUP (app), "quit", NULL);
     604   *
     605   * // make sure the action is activated now
     606   * g_dbus_connection_flush (...);
     607   *
     608   * g_debug ("application has been terminated. exiting.");
     609   *
     610   * exit (0);
     611   * ]|
     612   *
     613   * Since: 2.28
     614   **/
     615  void
     616  g_action_group_activate_action (GActionGroup *action_group,
     617                                  const gchar  *action_name,
     618                                  GVariant     *parameter)
     619  {
     620    g_return_if_fail (G_IS_ACTION_GROUP (action_group));
     621    g_return_if_fail (action_name != NULL);
     622  
     623    G_ACTION_GROUP_GET_IFACE (action_group)
     624      ->activate_action (action_group, action_name, parameter);
     625  }
     626  
     627  /**
     628   * g_action_group_action_added:
     629   * @action_group: a #GActionGroup
     630   * @action_name: the name of an action in the group
     631   *
     632   * Emits the #GActionGroup::action-added signal on @action_group.
     633   *
     634   * This function should only be called by #GActionGroup implementations.
     635   *
     636   * Since: 2.28
     637   **/
     638  void
     639  g_action_group_action_added (GActionGroup *action_group,
     640                               const gchar  *action_name)
     641  {
     642    g_return_if_fail (G_IS_ACTION_GROUP (action_group));
     643    g_return_if_fail (action_name != NULL);
     644  
     645    g_signal_emit (action_group,
     646                   g_action_group_signals[SIGNAL_ACTION_ADDED],
     647                   g_quark_try_string (action_name),
     648                   action_name);
     649  }
     650  
     651  /**
     652   * g_action_group_action_removed:
     653   * @action_group: a #GActionGroup
     654   * @action_name: the name of an action in the group
     655   *
     656   * Emits the #GActionGroup::action-removed signal on @action_group.
     657   *
     658   * This function should only be called by #GActionGroup implementations.
     659   *
     660   * Since: 2.28
     661   **/
     662  void
     663  g_action_group_action_removed (GActionGroup *action_group,
     664                                 const gchar  *action_name)
     665  {
     666    g_return_if_fail (G_IS_ACTION_GROUP (action_group));
     667    g_return_if_fail (action_name != NULL);
     668  
     669    g_signal_emit (action_group,
     670                   g_action_group_signals[SIGNAL_ACTION_REMOVED],
     671                   g_quark_try_string (action_name),
     672                   action_name);
     673  }
     674  
     675  /**
     676   * g_action_group_action_enabled_changed:
     677   * @action_group: a #GActionGroup
     678   * @action_name: the name of an action in the group
     679   * @enabled: whether or not the action is now enabled
     680   *
     681   * Emits the #GActionGroup::action-enabled-changed signal on @action_group.
     682   *
     683   * This function should only be called by #GActionGroup implementations.
     684   *
     685   * Since: 2.28
     686   **/
     687  void
     688  g_action_group_action_enabled_changed (GActionGroup *action_group,
     689                                         const gchar  *action_name,
     690                                         gboolean      enabled)
     691  {
     692    g_return_if_fail (G_IS_ACTION_GROUP (action_group));
     693    g_return_if_fail (action_name != NULL);
     694  
     695    enabled = !!enabled;
     696  
     697    g_signal_emit (action_group,
     698                   g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED],
     699                   g_quark_try_string (action_name),
     700                   action_name,
     701                   enabled);
     702  }
     703  
     704  /**
     705   * g_action_group_action_state_changed:
     706   * @action_group: a #GActionGroup
     707   * @action_name: the name of an action in the group
     708   * @state: the new state of the named action
     709   *
     710   * Emits the #GActionGroup::action-state-changed signal on @action_group.
     711   *
     712   * This function should only be called by #GActionGroup implementations.
     713   *
     714   * Since: 2.28
     715   **/
     716  void
     717  g_action_group_action_state_changed (GActionGroup *action_group,
     718                                       const gchar  *action_name,
     719                                       GVariant     *state)
     720  {
     721    g_return_if_fail (G_IS_ACTION_GROUP (action_group));
     722    g_return_if_fail (action_name != NULL);
     723  
     724    g_signal_emit (action_group,
     725                   g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED],
     726                   g_quark_try_string (action_name),
     727                   action_name,
     728                   state);
     729  }
     730  
     731  /**
     732   * g_action_group_query_action:
     733   * @action_group: a #GActionGroup
     734   * @action_name: the name of an action in the group
     735   * @enabled: (out): if the action is presently enabled
     736   * @parameter_type: (out) (transfer none) (optional): the parameter type, or %NULL if none needed
     737   * @state_type: (out) (transfer none) (optional): the state type, or %NULL if stateless
     738   * @state_hint: (out) (optional): the state hint, or %NULL if none
     739   * @state: (out) (optional): the current state, or %NULL if stateless
     740   *
     741   * Queries all aspects of the named action within an @action_group.
     742   *
     743   * This function acquires the information available from
     744   * g_action_group_has_action(), g_action_group_get_action_enabled(),
     745   * g_action_group_get_action_parameter_type(),
     746   * g_action_group_get_action_state_type(),
     747   * g_action_group_get_action_state_hint() and
     748   * g_action_group_get_action_state() with a single function call.
     749   *
     750   * This provides two main benefits.
     751   *
     752   * The first is the improvement in efficiency that comes with not having
     753   * to perform repeated lookups of the action in order to discover
     754   * different things about it.  The second is that implementing
     755   * #GActionGroup can now be done by only overriding this one virtual
     756   * function.
     757   *
     758   * The interface provides a default implementation of this function that
     759   * calls the individual functions, as required, to fetch the
     760   * information.  The interface also provides default implementations of
     761   * those functions that call this function.  All implementations,
     762   * therefore, must override either this function or all of the others.
     763   *
     764   * If the action exists, %TRUE is returned and any of the requested
     765   * fields (as indicated by having a non-%NULL reference passed in) are
     766   * filled.  If the action doesn't exist, %FALSE is returned and the
     767   * fields may or may not have been modified.
     768   *
     769   * Returns: %TRUE if the action exists, else %FALSE
     770   *
     771   * Since: 2.32
     772   **/
     773  gboolean
     774  g_action_group_query_action (GActionGroup        *action_group,
     775                               const gchar         *action_name,
     776                               gboolean            *enabled,
     777                               const GVariantType **parameter_type,
     778                               const GVariantType **state_type,
     779                               GVariant           **state_hint,
     780                               GVariant           **state)
     781  {
     782    return G_ACTION_GROUP_GET_IFACE (action_group)
     783      ->query_action (action_group, action_name, enabled, parameter_type, state_type, state_hint, state);
     784  }