2 * Copyright © 2010 Codethink Limited
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Authors: Ryan Lortie <desrt@desrt.ca>
24 #include "gsimpleaction.h"
25 #include "gactiongroup.h"
26 #include "gactionmap.h"
32 * @short_description: Interface for action containers
34 * The GActionMap interface is implemented by #GActionGroup
35 * implementations that operate by containing a number of
36 * named #GAction instances, such as #GSimpleActionGroup.
38 * One useful application of this interface is to map the
39 * names of actions from various action groups to unique,
40 * prefixed names (e.g. by prepending "app." or "win.").
41 * This is the motivation for the 'Map' part of the interface
45 G_DEFINE_INTERFACE (GActionMap, g_action_map, G_TYPE_ACTION_GROUP)
48 g_action_map_default_init (GActionMapInterface *iface)
53 * g_action_map_lookup_action:
54 * @action_map: a #GActionMap
55 * @action_name: the name of an action
57 * Looks up the action with the name @action_name in @action_map.
59 * If no such action exists, returns %NULL.
61 * Returns: (transfer none): a #GAction, or %NULL
66 g_action_map_lookup_action (GActionMap *action_map,
67 const gchar *action_name)
69 return G_ACTION_MAP_GET_IFACE (action_map)
70 ->lookup_action (action_map, action_name);
74 * g_action_map_add_action:
75 * @action_map: a #GActionMap
78 * Adds an action to the @action_map.
80 * If the action map already contains an action with the same name
81 * as @action then the old action is dropped from the action map.
83 * The action map takes its own reference on @action.
88 g_action_map_add_action (GActionMap *action_map,
91 return G_ACTION_MAP_GET_IFACE (action_map)
92 ->add_action (action_map, action);
96 * g_action_map_remove_action:
97 * @action_map: a #GActionMap
98 * @action_name: the name of the action
100 * Removes the named action from the action map.
102 * If no action of this name is in the map then nothing happens.
107 g_action_map_remove_action (GActionMap *action_map,
108 const gchar *action_name)
110 return G_ACTION_MAP_GET_IFACE (action_map)
111 ->remove_action (action_map, action_name);
116 * @name: the name of the action
117 * @activate: the callback to connect to the "activate" signal of the
119 * @parameter_type: the type of the parameter that must be passed to the
120 * activate function for this action, given as a single
121 * GVariant type string (or %NULL for no parameter)
122 * @state: the initial state for this action, given in GVariant text
123 * format. The state is parsed with no extra type information,
124 * so type tags must be added to the string if they are
126 * @change_state: the callback to connect to the "change-state" signal
129 * This struct defines a single action. It is for use with
130 * g_action_map_add_action_entries().
132 * The order of the items in the structure are intended to reflect
133 * frequency of use. It is permissible to use an incomplete initialiser
134 * in order to leave some of the later values as %NULL. All values
135 * after @name are optional. Additional optional fields may be added in
138 * See g_action_map_add_action_entries() for an example.
142 * g_action_map_add_action_entries:
143 * @action_map: a #GActionMap
144 * @entries: a pointer to the first item in an array of #GActionEntry
146 * @n_entries: the length of @entries, or -1 if @entries is %NULL-terminated
147 * @user_data: the user data for signal connections
149 * A convenience function for creating multiple #GSimpleAction instances
150 * and adding them to a #GActionMap.
152 * Each action is constructed as per one #GActionEntry.
155 * <title>Using g_action_map_add_action_entries()</title>
158 * activate_quit (GSimpleAction *simple,
159 * GVariant *parameter,
160 * gpointer user_data)
166 * activate_print_string (GSimpleAction *simple,
167 * GVariant *parameter,
168 * gpointer user_data)
170 * g_print ("%s\n", g_variant_get_string (parameter, NULL));
173 * static GActionGroup *
174 * create_action_group (void)
176 * const GActionEntry entries[] = {
177 * { "quit", activate_quit },
178 * { "print-string", activate_print_string, "s" }
180 * GSimpleActionGroup *group;
182 * group = g_simple_action_group_new ();
183 * g_action_map_add_action_entries (G_ACTION_MAP (group), entries, G_N_ELEMENTS (entries), NULL);
185 * return G_ACTION_GROUP (group);
193 g_action_map_add_action_entries (GActionMap *action_map,
194 const GActionEntry *entries,
200 g_return_if_fail (G_IS_ACTION_MAP (action_map));
201 g_return_if_fail (entries != NULL || n_entries == 0);
203 for (i = 0; n_entries == -1 ? entries[i].name != NULL : i < n_entries; i++)
205 const GActionEntry *entry = &entries[i];
206 const GVariantType *parameter_type;
207 GSimpleAction *action;
209 if (entry->parameter_type)
211 if (!g_variant_type_string_is_valid (entry->parameter_type))
213 g_critical ("g_simple_action_group_add_entries: the type "
214 "string '%s' given as the parameter type for "
215 "action '%s' is not a valid GVariant type "
216 "string. This action will not be added.",
217 entry->parameter_type, entry->name);
221 parameter_type = G_VARIANT_TYPE (entry->parameter_type);
224 parameter_type = NULL;
228 GError *error = NULL;
231 state = g_variant_parse (NULL, entry->state, NULL, NULL, &error);
234 g_critical ("g_simple_action_group_add_entries: GVariant could "
235 "not parse the state value given for action '%s' "
236 "('%s'): %s. This action will not be added.",
237 entry->name, entry->state, error->message);
238 g_error_free (error);
242 action = g_simple_action_new_stateful (entry->name,
246 g_variant_unref (state);
250 action = g_simple_action_new (entry->name,
254 if (entry->activate != NULL)
255 g_signal_connect (action, "activate",
256 G_CALLBACK (entry->activate), user_data);
258 if (entry->change_state != NULL)
259 g_signal_connect (action, "change-state",
260 G_CALLBACK (entry->change_state), user_data);
262 g_action_map_add_action (action_map, G_ACTION (action));
263 g_object_unref (action);