Coverage Report

Created: 2025-07-18 06:10

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