LCOV - code coverage report
Current view: top level - gio - gactionmap.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 100.0 % 44 44
Test Date: 2024-11-26 05:23:01 Functions: 100.0 % 7 7
Branches: - 0 0

             Branch data     Line data    Source code
       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                 :             : 
      24                 :             : #include "gsimpleaction.h"
      25                 :             : #include "gactionmap.h"
      26                 :             : #include "gaction.h"
      27                 :             : 
      28                 :             : /**
      29                 :             :  * GActionMap:
      30                 :             :  *
      31                 :             :  * `GActionMap` is an interface for action containers.
      32                 :             :  *
      33                 :             :  * The `GActionMap` interface is implemented by [iface@Gio.ActionGroup]
      34                 :             :  * implementations that operate by containing a number of named
      35                 :             :  * [iface@Gio.Action] instances, such as [class@Gio.SimpleActionGroup].
      36                 :             :  *
      37                 :             :  * One useful application of this interface is to map the
      38                 :             :  * names of actions from various action groups to unique,
      39                 :             :  * prefixed names (e.g. by prepending "app." or "win.").
      40                 :             :  * This is the motivation for the ‘Map’ part of the interface
      41                 :             :  * name.
      42                 :             :  *
      43                 :             :  * Since: 2.32
      44                 :             :  */
      45                 :             : 
      46                 :             : /**
      47                 :             :  * GActionMapInterface:
      48                 :             :  * @lookup_action: the virtual function pointer for
      49                 :             :  *   [method@Gio.ActionMap.lookup_action]
      50                 :             :  * @add_action: the virtual function pointer for
      51                 :             :  *   [method@Gio.ActionMap.add_action]
      52                 :             :  * @remove_action: the virtual function pointer for
      53                 :             :  *   [method@Gio.ActionMap.remove_action]
      54                 :             :  *
      55                 :             :  * The virtual function table for [iface@Gio.ActionMap].
      56                 :             :  *
      57                 :             :  * Since: 2.32
      58                 :             :  **/
      59                 :             : 
      60                 :      200406 : G_DEFINE_INTERFACE (GActionMap, g_action_map, G_TYPE_OBJECT)
      61                 :             : 
      62                 :             : static void
      63                 :          13 : g_action_map_default_init (GActionMapInterface *iface)
      64                 :             : {
      65                 :          13 : }
      66                 :             : 
      67                 :             : /**
      68                 :             :  * g_action_map_lookup_action:
      69                 :             :  * @action_map: an action map
      70                 :             :  * @action_name: the name of an action
      71                 :             :  *
      72                 :             :  * Looks up the action with the name @action_name in @action_map.
      73                 :             :  *
      74                 :             :  * If no such action exists, returns `NULL`.
      75                 :             :  *
      76                 :             :  * Returns: (nullable) (transfer none): a [iface@Gio.Action]
      77                 :             :  *
      78                 :             :  * Since: 2.32
      79                 :             :  */
      80                 :             : GAction *
      81                 :      100007 : g_action_map_lookup_action (GActionMap  *action_map,
      82                 :             :                             const gchar *action_name)
      83                 :             : {
      84                 :      100007 :   return G_ACTION_MAP_GET_IFACE (action_map)
      85                 :      100007 :     ->lookup_action (action_map, action_name);
      86                 :             : }
      87                 :             : 
      88                 :             : /**
      89                 :             :  * g_action_map_add_action:
      90                 :             :  * @action_map: an action map
      91                 :             :  * @action: a [iface@Gio.Action]
      92                 :             :  *
      93                 :             :  * Adds an action to the @action_map.
      94                 :             :  *
      95                 :             :  * If the action map already contains an action with the same name
      96                 :             :  * as @action then the old action is dropped from the action map.
      97                 :             :  *
      98                 :             :  * The action map takes its own reference on @action.
      99                 :             :  *
     100                 :             :  * Since: 2.32
     101                 :             :  */
     102                 :             : void
     103                 :         161 : g_action_map_add_action (GActionMap *action_map,
     104                 :             :                          GAction    *action)
     105                 :             : {
     106                 :         161 :   G_ACTION_MAP_GET_IFACE (action_map)->add_action (action_map, action);
     107                 :         161 : }
     108                 :             : 
     109                 :             : /**
     110                 :             :  * g_action_map_remove_action:
     111                 :             :  * @action_map: an action map
     112                 :             :  * @action_name: the name of the action
     113                 :             :  *
     114                 :             :  * Removes the named action from the action map.
     115                 :             :  *
     116                 :             :  * If no action of this name is in the map then nothing happens.
     117                 :             :  *
     118                 :             :  * Since: 2.32
     119                 :             :  */
     120                 :             : void
     121                 :          10 : g_action_map_remove_action (GActionMap  *action_map,
     122                 :             :                             const gchar *action_name)
     123                 :             : {
     124                 :          10 :   G_ACTION_MAP_GET_IFACE (action_map)->remove_action (action_map, action_name);
     125                 :          10 : }
     126                 :             : 
     127                 :             : /**
     128                 :             :  * GActionEntry:
     129                 :             :  * @name: the name of the action
     130                 :             :  * @activate: the callback to connect to the "activate" signal of the action.
     131                 :             :  *   Since GLib 2.40, this can be `NULL` for stateful actions, in which case
     132                 :             :  *   the default handler is used. For boolean-stated actions with no
     133                 :             :  *   parameter, this is a toggle. For other state types (and parameter type
     134                 :             :  *   equal to the state type) this will be a function that just calls
     135                 :             :  *   @change_state (which you should provide).
     136                 :             :  * @parameter_type: the type of the parameter that must be passed to the
     137                 :             :  *   activate function for this action, given as a single GVariant type string
     138                 :             :  *   (or `NULL` for no parameter)
     139                 :             :  * @state: the initial state for this action, given in
     140                 :             :  *   [GVariant text format](gvariant-text-format.html).  The state is parsed
     141                 :             :  *   with no extra type information, so type tags must be added to the string
     142                 :             :  *   if they are necessary.  Stateless actions should give `NULL` here.
     143                 :             :  * @change_state: the callback to connect to the "change-state" signal of the
     144                 :             :  *   action.  All stateful actions should provide a handler here; stateless
     145                 :             :  *   actions should not.
     146                 :             :  *
     147                 :             :  * This struct defines a single action.  It is for use with
     148                 :             :  * [method@Gio.ActionMap.add_action_entries].
     149                 :             :  *
     150                 :             :  * The order of the items in the structure are intended to reflect
     151                 :             :  * frequency of use.  It is permissible to use an incomplete initialiser
     152                 :             :  * in order to leave some of the later values as `NULL`.  All values
     153                 :             :  * after @name are optional.  Additional optional fields may be added in
     154                 :             :  * the future.
     155                 :             :  *
     156                 :             :  * See [method@Gio.ActionMap.add_action_entries] for an example.
     157                 :             :  **/
     158                 :             : 
     159                 :             : /**
     160                 :             :  * g_action_map_add_action_entries:
     161                 :             :  * @action_map: an action map
     162                 :             :  * @entries: (array length=n_entries) (element-type GActionEntry): a pointer to
     163                 :             :  *   the first item in an array of [struct@Gio.ActionEntry] structs
     164                 :             :  * @n_entries: the length of @entries, or -1 if @entries is `NULL`-terminated
     165                 :             :  * @user_data: the user data for signal connections
     166                 :             :  *
     167                 :             :  * A convenience function for creating multiple [class@Gio.SimpleAction]
     168                 :             :  * instances and adding them to a [iface@Gio.ActionMap].
     169                 :             :  *
     170                 :             :  * Each action is constructed as per one [struct@Gio.ActionEntry].
     171                 :             :  *
     172                 :             :  * ```c
     173                 :             :  * static void
     174                 :             :  * activate_quit (GSimpleAction *simple,
     175                 :             :  *                GVariant      *parameter,
     176                 :             :  *                gpointer       user_data)
     177                 :             :  * {
     178                 :             :  *   exit (0);
     179                 :             :  * }
     180                 :             :  *
     181                 :             :  * static void
     182                 :             :  * activate_print_string (GSimpleAction *simple,
     183                 :             :  *                        GVariant      *parameter,
     184                 :             :  *                        gpointer       user_data)
     185                 :             :  * {
     186                 :             :  *   g_print ("%s\n", g_variant_get_string (parameter, NULL));
     187                 :             :  * }
     188                 :             :  *
     189                 :             :  * static GActionGroup *
     190                 :             :  * create_action_group (void)
     191                 :             :  * {
     192                 :             :  *   const GActionEntry entries[] = {
     193                 :             :  *     { "quit",         activate_quit              },
     194                 :             :  *     { "print-string", activate_print_string, "s" }
     195                 :             :  *   };
     196                 :             :  *   GSimpleActionGroup *group;
     197                 :             :  *
     198                 :             :  *   group = g_simple_action_group_new ();
     199                 :             :  *   g_action_map_add_action_entries (G_ACTION_MAP (group), entries, G_N_ELEMENTS (entries), NULL);
     200                 :             :  *
     201                 :             :  *   return G_ACTION_GROUP (group);
     202                 :             :  * }
     203                 :             :  * ```
     204                 :             :  *
     205                 :             :  * Since: 2.32
     206                 :             :  */
     207                 :             : void
     208                 :          30 : g_action_map_add_action_entries (GActionMap         *action_map,
     209                 :             :                                  const GActionEntry *entries,
     210                 :             :                                  gint                n_entries,
     211                 :             :                                  gpointer            user_data)
     212                 :             : {
     213                 :          30 :   g_return_if_fail (G_IS_ACTION_MAP (action_map));
     214                 :          30 :   g_return_if_fail (entries != NULL || n_entries == 0);
     215                 :             : 
     216                 :         125 :   for (int i = 0; n_entries < 0 ? entries[i].name != NULL : i < n_entries; i++)
     217                 :             :     {
     218                 :          96 :       const GActionEntry *entry = &entries[i];
     219                 :             :       const GVariantType *parameter_type;
     220                 :             :       GSimpleAction *action;
     221                 :             : 
     222                 :          96 :       if (entry->parameter_type)
     223                 :             :         {
     224                 :          42 :           if (!g_variant_type_string_is_valid (entry->parameter_type))
     225                 :             :             {
     226                 :           1 :               g_critical ("g_action_map_add_entries: the type "
     227                 :             :                           "string '%s' given as the parameter type for "
     228                 :             :                           "action '%s' is not a valid GVariant type "
     229                 :             :                           "string.  This action will not be added.",
     230                 :             :                           entry->parameter_type, entry->name);
     231                 :           1 :               return;
     232                 :             :             }
     233                 :             : 
     234                 :          41 :           parameter_type = G_VARIANT_TYPE (entry->parameter_type);
     235                 :             :         }
     236                 :             :       else
     237                 :          54 :         parameter_type = NULL;
     238                 :             : 
     239                 :          95 :       if (entry->state)
     240                 :             :         {
     241                 :          20 :           GError *error = NULL;
     242                 :             :           GVariant *state;
     243                 :             : 
     244                 :          20 :           state = g_variant_parse (NULL, entry->state, NULL, NULL, &error);
     245                 :          20 :           if (state == NULL)
     246                 :             :             {
     247                 :           1 :               g_critical ("g_action_map_add_entries: GVariant could "
     248                 :             :                           "not parse the state value given for action '%s' "
     249                 :             :                           "('%s'): %s.  This action will not be added.",
     250                 :             :                           entry->name, entry->state, error->message);
     251                 :           1 :               g_error_free (error);
     252                 :           1 :               continue;
     253                 :             :             }
     254                 :             : 
     255                 :          19 :           action = g_simple_action_new_stateful (entry->name,
     256                 :             :                                                  parameter_type,
     257                 :             :                                                  state);
     258                 :             : 
     259                 :          19 :           g_variant_unref (state);
     260                 :             :         }
     261                 :             :       else
     262                 :             :         {
     263                 :          75 :           action = g_simple_action_new (entry->name,
     264                 :             :                                         parameter_type);
     265                 :             :         }
     266                 :             : 
     267                 :          94 :       if (entry->activate != NULL)
     268                 :          92 :         g_signal_connect (action, "activate",
     269                 :             :                           G_CALLBACK (entry->activate), user_data);
     270                 :             : 
     271                 :          94 :       if (entry->change_state != NULL)
     272                 :           1 :         g_signal_connect (action, "change-state",
     273                 :             :                           G_CALLBACK (entry->change_state), user_data);
     274                 :             : 
     275                 :          94 :       g_action_map_add_action (action_map, G_ACTION (action));
     276                 :          94 :       g_object_unref (action);
     277                 :             :     }
     278                 :             : }
     279                 :             : 
     280                 :             : /**
     281                 :             :  * g_action_map_remove_action_entries:
     282                 :             :  * @action_map: The [iface@Gio.ActionMap]
     283                 :             :  * @entries: (array length=n_entries) (element-type GActionEntry): a pointer to
     284                 :             :  *   the first item in an array of [struct@Gio.ActionEntry] structs
     285                 :             :  * @n_entries: the length of @entries, or -1 if @entries is `NULL`-terminated
     286                 :             :  *
     287                 :             :  * Remove actions from a [iface@Gio.ActionMap]. This is meant as the reverse of
     288                 :             :  * [method@Gio.ActionMap.add_action_entries].
     289                 :             :  *
     290                 :             :  *
     291                 :             :  * ```c
     292                 :             :  * static const GActionEntry entries[] = {
     293                 :             :  *     { "quit",         activate_quit              },
     294                 :             :  *     { "print-string", activate_print_string, "s" }
     295                 :             :  * };
     296                 :             :  *
     297                 :             :  * void
     298                 :             :  * add_actions (GActionMap *map)
     299                 :             :  * {
     300                 :             :  *   g_action_map_add_action_entries (map, entries, G_N_ELEMENTS (entries), NULL);
     301                 :             :  * }
     302                 :             :  *
     303                 :             :  * void
     304                 :             :  * remove_actions (GActionMap *map)
     305                 :             :  * {
     306                 :             :  *   g_action_map_remove_action_entries (map, entries, G_N_ELEMENTS (entries));
     307                 :             :  * }
     308                 :             :  * ```
     309                 :             :  *
     310                 :             :  * Since: 2.78
     311                 :             :  */
     312                 :             : void
     313                 :           2 : g_action_map_remove_action_entries (GActionMap         *action_map,
     314                 :             :                                     const GActionEntry  entries[],
     315                 :             :                                     gint                n_entries)
     316                 :             : {
     317                 :           2 :   g_return_if_fail (G_IS_ACTION_MAP (action_map));
     318                 :           2 :   g_return_if_fail (entries != NULL || n_entries == 0);
     319                 :             : 
     320                 :           8 :   for (int i = 0; n_entries < 0 ? entries[i].name != NULL : i < n_entries; i++)
     321                 :           6 :     g_action_map_remove_action (action_map, entries[i].name);
     322                 :             : }
        

Generated by: LCOV version 2.0-1