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