File: | ctk/ctkactiongroup.c |
Warning: | line 482, column 14 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * CTK - The GIMP Toolkit |
3 | * Copyright (C) 1998, 1999 Red Hat, Inc. |
4 | * All rights reserved. |
5 | * |
6 | * This Library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public License as |
8 | * published by the Free Software Foundation; either version 2 of the |
9 | * 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 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | /* |
21 | * Author: James Henstridge <james@daa.com.au> |
22 | * |
23 | * Modified by the CTK+ Team and others 2003. See the AUTHORS |
24 | * file for a list of people on the CTK+ Team. See the ChangeLog |
25 | * files for a list of changes. These files are distributed with |
26 | * CTK+ at ftp://ftp.ctk.org/pub/ctk/. |
27 | */ |
28 | |
29 | /** |
30 | * SECTION:ctkactiongroup |
31 | * @Short_description: A group of actions |
32 | * @Title: CtkActionGroup |
33 | * |
34 | * Actions are organised into groups. An action group is essentially a |
35 | * map from names to #CtkAction objects. |
36 | * |
37 | * All actions that would make sense to use in a particular context |
38 | * should be in a single group. Multiple action groups may be used for a |
39 | * particular user interface. In fact, it is expected that most nontrivial |
40 | * applications will make use of multiple groups. For example, in an |
41 | * application that can edit multiple documents, one group holding global |
42 | * actions (e.g. quit, about, new), and one group per document holding |
43 | * actions that act on that document (eg. save, cut/copy/paste, etc). Each |
44 | * window’s menus would be constructed from a combination of two action |
45 | * groups. |
46 | * |
47 | * ## Accelerators ## {#Action-Accel} |
48 | * |
49 | * Accelerators are handled by the CTK+ accelerator map. All actions are |
50 | * assigned an accelerator path (which normally has the form |
51 | * `<Actions>/group-name/action-name`) and a shortcut is associated with |
52 | * this accelerator path. All menuitems and toolitems take on this accelerator |
53 | * path. The CTK+ accelerator map code makes sure that the correct shortcut |
54 | * is displayed next to the menu item. |
55 | * |
56 | * # CtkActionGroup as CtkBuildable # {#CtkActionGroup-BUILDER-UI} |
57 | * |
58 | * The #CtkActionGroup implementation of the #CtkBuildable interface accepts |
59 | * #CtkAction objects as <child> elements in UI definitions. |
60 | * |
61 | * Note that it is probably more common to define actions and action groups |
62 | * in the code, since they are directly related to what the code can do. |
63 | * |
64 | * The CtkActionGroup implementation of the CtkBuildable interface supports |
65 | * a custom <accelerator> element, which has attributes named “key“ and |
66 | * “modifiers“ and allows to specify accelerators. This is similar to the |
67 | * <accelerator> element of #CtkWidget, the main difference is that |
68 | * it doesn’t allow you to specify a signal. |
69 | * |
70 | * ## A #CtkDialog UI definition fragment. ## |
71 | * |[ |
72 | * <object class="CtkActionGroup" id="actiongroup"> |
73 | * <child> |
74 | * <object class="CtkAction" id="About"> |
75 | * <property name="name">About</property> |
76 | * <property name="stock_id">ctk-about</property> |
77 | * <signal handler="about_activate" name="activate"/> |
78 | * </object> |
79 | * <accelerator key="F1" modifiers="CDK_CONTROL_MASK | CDK_SHIFT_MASK"/> |
80 | * </child> |
81 | * </object> |
82 | * ]| |
83 | * |
84 | */ |
85 | |
86 | #include "config.h" |
87 | #include <string.h> |
88 | |
89 | #include "ctkactiongroup.h" |
90 | #include "ctkbuildable.h" |
91 | #include "ctkiconfactory.h" |
92 | #include "ctkicontheme.h" |
93 | #include "ctkstock.h" |
94 | #include "ctktoggleaction.h" |
95 | #include "ctkradioaction.h" |
96 | #include "ctkaccelmap.h" |
97 | #include "ctkmarshalers.h" |
98 | #include "ctkbuilderprivate.h" |
99 | #include "ctkprivate.h" |
100 | #include "ctkintl.h" |
101 | |
102 | |
103 | struct _CtkActionGroupPrivate |
104 | { |
105 | gchar *name; |
106 | gboolean sensitive; |
107 | gboolean visible; |
108 | GHashTable *actions; |
109 | CtkAccelGroup *accel_group; |
110 | |
111 | CtkTranslateFunc translate_func; |
112 | gpointer translate_data; |
113 | GDestroyNotify translate_notify; |
114 | }; |
115 | |
116 | enum |
117 | { |
118 | CONNECT_PROXY, |
119 | DISCONNECT_PROXY, |
120 | PRE_ACTIVATE, |
121 | POST_ACTIVATE, |
122 | LAST_SIGNAL |
123 | }; |
124 | |
125 | enum |
126 | { |
127 | PROP_0, |
128 | PROP_NAME, |
129 | PROP_SENSITIVE, |
130 | PROP_VISIBLE, |
131 | PROP_ACCEL_GROUP |
132 | }; |
133 | |
134 | static void ctk_action_group_init (CtkActionGroup *self); |
135 | static void ctk_action_group_class_init (CtkActionGroupClass *class); |
136 | static void ctk_action_group_finalize (GObject *object); |
137 | static void ctk_action_group_set_property (GObject *object, |
138 | guint prop_id, |
139 | const GValue *value, |
140 | GParamSpec *pspec); |
141 | static void ctk_action_group_get_property (GObject *object, |
142 | guint prop_id, |
143 | GValue *value, |
144 | GParamSpec *pspec); |
145 | static CtkAction *ctk_action_group_real_get_action (CtkActionGroup *self, |
146 | const gchar *name); |
147 | |
148 | /* CtkBuildable */ |
149 | static void ctk_action_group_buildable_init (CtkBuildableIface *iface); |
150 | static void ctk_action_group_buildable_add_child (CtkBuildable *buildable, |
151 | CtkBuilder *builder, |
152 | GObject *child, |
153 | const gchar *type); |
154 | static void ctk_action_group_buildable_set_name (CtkBuildable *buildable, |
155 | const gchar *name); |
156 | static const gchar* ctk_action_group_buildable_get_name (CtkBuildable *buildable); |
157 | static gboolean ctk_action_group_buildable_custom_tag_start (CtkBuildable *buildable, |
158 | CtkBuilder *builder, |
159 | GObject *child, |
160 | const gchar *tagname, |
161 | GMarkupParser *parser, |
162 | gpointer *data); |
163 | static void ctk_action_group_buildable_custom_tag_end (CtkBuildable *buildable, |
164 | CtkBuilder *builder, |
165 | GObject *child, |
166 | const gchar *tagname, |
167 | gpointer *user_data); |
168 | |
169 | static guint action_group_signals[LAST_SIGNAL] = { 0 }; |
170 | |
171 | G_DEFINE_TYPE_WITH_CODE (CtkActionGroup, ctk_action_group, G_TYPE_OBJECT,static void ctk_action_group_init (CtkActionGroup *self); static void ctk_action_group_class_init (CtkActionGroupClass *klass ); static GType ctk_action_group_get_type_once (void); static gpointer ctk_action_group_parent_class = ((void*)0); static gint CtkActionGroup_private_offset; static void ctk_action_group_class_intern_init (gpointer klass) { ctk_action_group_parent_class = g_type_class_peek_parent (klass); if (CtkActionGroup_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkActionGroup_private_offset); ctk_action_group_class_init ((CtkActionGroupClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_action_group_get_instance_private (CtkActionGroup *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkActionGroup_private_offset)))); } GType ctk_action_group_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_action_group_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_action_group_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkActionGroup" ), sizeof (CtkActionGroupClass), (GClassInitFunc)(void (*)(void )) ctk_action_group_class_intern_init, sizeof (CtkActionGroup ), (GInstanceInitFunc)(void (*)(void)) ctk_action_group_init, (GTypeFlags) 0); { {{ CtkActionGroup_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkActionGroupPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_action_group_buildable_init, ((void*)0) , ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
172 | G_ADD_PRIVATE (CtkActionGroup)static void ctk_action_group_init (CtkActionGroup *self); static void ctk_action_group_class_init (CtkActionGroupClass *klass ); static GType ctk_action_group_get_type_once (void); static gpointer ctk_action_group_parent_class = ((void*)0); static gint CtkActionGroup_private_offset; static void ctk_action_group_class_intern_init (gpointer klass) { ctk_action_group_parent_class = g_type_class_peek_parent (klass); if (CtkActionGroup_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkActionGroup_private_offset); ctk_action_group_class_init ((CtkActionGroupClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_action_group_get_instance_private (CtkActionGroup *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkActionGroup_private_offset)))); } GType ctk_action_group_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_action_group_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_action_group_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkActionGroup" ), sizeof (CtkActionGroupClass), (GClassInitFunc)(void (*)(void )) ctk_action_group_class_intern_init, sizeof (CtkActionGroup ), (GInstanceInitFunc)(void (*)(void)) ctk_action_group_init, (GTypeFlags) 0); { {{ CtkActionGroup_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkActionGroupPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_action_group_buildable_init, ((void*)0) , ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
173 | G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_action_group_init (CtkActionGroup *self); static void ctk_action_group_class_init (CtkActionGroupClass *klass ); static GType ctk_action_group_get_type_once (void); static gpointer ctk_action_group_parent_class = ((void*)0); static gint CtkActionGroup_private_offset; static void ctk_action_group_class_intern_init (gpointer klass) { ctk_action_group_parent_class = g_type_class_peek_parent (klass); if (CtkActionGroup_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkActionGroup_private_offset); ctk_action_group_class_init ((CtkActionGroupClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_action_group_get_instance_private (CtkActionGroup *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkActionGroup_private_offset)))); } GType ctk_action_group_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_action_group_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_action_group_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkActionGroup" ), sizeof (CtkActionGroupClass), (GClassInitFunc)(void (*)(void )) ctk_action_group_class_intern_init, sizeof (CtkActionGroup ), (GInstanceInitFunc)(void (*)(void)) ctk_action_group_init, (GTypeFlags) 0); { {{ CtkActionGroup_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkActionGroupPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_action_group_buildable_init, ((void*)0) , ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
174 | ctk_action_group_buildable_init))static void ctk_action_group_init (CtkActionGroup *self); static void ctk_action_group_class_init (CtkActionGroupClass *klass ); static GType ctk_action_group_get_type_once (void); static gpointer ctk_action_group_parent_class = ((void*)0); static gint CtkActionGroup_private_offset; static void ctk_action_group_class_intern_init (gpointer klass) { ctk_action_group_parent_class = g_type_class_peek_parent (klass); if (CtkActionGroup_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkActionGroup_private_offset); ctk_action_group_class_init ((CtkActionGroupClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer ctk_action_group_get_instance_private (CtkActionGroup *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkActionGroup_private_offset)))); } GType ctk_action_group_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_action_group_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_action_group_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkActionGroup" ), sizeof (CtkActionGroupClass), (GClassInitFunc)(void (*)(void )) ctk_action_group_class_intern_init, sizeof (CtkActionGroup ), (GInstanceInitFunc)(void (*)(void)) ctk_action_group_init, (GTypeFlags) 0); { {{ CtkActionGroup_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkActionGroupPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_action_group_buildable_init, ((void*)0) , ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } |
175 | |
176 | static void |
177 | ctk_action_group_class_init (CtkActionGroupClass *klass) |
178 | { |
179 | GObjectClass *gobject_class; |
180 | |
181 | gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); |
182 | |
183 | gobject_class->finalize = ctk_action_group_finalize; |
184 | gobject_class->set_property = ctk_action_group_set_property; |
185 | gobject_class->get_property = ctk_action_group_get_property; |
186 | klass->get_action = ctk_action_group_real_get_action; |
187 | |
188 | /** |
189 | * CtkActionGroup:name: |
190 | * |
191 | * A name for the action. |
192 | */ |
193 | g_object_class_install_property (gobject_class, |
194 | PROP_NAME, |
195 | g_param_spec_string ("name", |
196 | P_("Name")g_dgettext("ctk30" "-properties","Name"), |
197 | P_("A name for the action group.")g_dgettext("ctk30" "-properties","A name for the action group." ), |
198 | NULL((void*)0), |
199 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY)); |
200 | /** |
201 | * CtkActionGroup:sensitive: |
202 | * |
203 | * Whether the action group is enabled. |
204 | */ |
205 | g_object_class_install_property (gobject_class, |
206 | PROP_SENSITIVE, |
207 | g_param_spec_boolean ("sensitive", |
208 | P_("Sensitive")g_dgettext("ctk30" "-properties","Sensitive"), |
209 | P_("Whether the action group is enabled.")g_dgettext("ctk30" "-properties","Whether the action group is enabled." ), |
210 | TRUE(!(0)), |
211 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
212 | /** |
213 | * CtkActionGroup:visible: |
214 | * |
215 | * Whether the action group is visible. |
216 | */ |
217 | g_object_class_install_property (gobject_class, |
218 | PROP_VISIBLE, |
219 | g_param_spec_boolean ("visible", |
220 | P_("Visible")g_dgettext("ctk30" "-properties","Visible"), |
221 | P_("Whether the action group is visible.")g_dgettext("ctk30" "-properties","Whether the action group is visible." ), |
222 | TRUE(!(0)), |
223 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
224 | /** |
225 | * CtkActionGroup:accel-group: |
226 | * |
227 | * The accelerator group the actions of this group should use. |
228 | */ |
229 | g_object_class_install_property (gobject_class, |
230 | PROP_ACCEL_GROUP, |
231 | g_param_spec_object ("accel-group", |
232 | P_("Accelerator Group")g_dgettext("ctk30" "-properties","Accelerator Group"), |
233 | P_("The accelerator group the actions of this group should use.")g_dgettext("ctk30" "-properties","The accelerator group the actions of this group should use." ), |
234 | CTK_TYPE_ACCEL_GROUP(ctk_accel_group_get_type ()), |
235 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
236 | |
237 | /** |
238 | * CtkActionGroup::connect-proxy: |
239 | * @action_group: the group |
240 | * @action: the action |
241 | * @proxy: the proxy |
242 | * |
243 | * The ::connect-proxy signal is emitted after connecting a proxy to |
244 | * an action in the group. Note that the proxy may have been connected |
245 | * to a different action before. |
246 | * |
247 | * This is intended for simple customizations for which a custom action |
248 | * class would be too clumsy, e.g. showing tooltips for menuitems in the |
249 | * statusbar. |
250 | * |
251 | * #CtkUIManager proxies the signal and provides global notification |
252 | * just before any action is connected to a proxy, which is probably more |
253 | * convenient to use. |
254 | * |
255 | * Since: 2.4 |
256 | */ |
257 | action_group_signals[CONNECT_PROXY] = |
258 | g_signal_new (I_("connect-proxy")g_intern_static_string ("connect-proxy"), |
259 | G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)), |
260 | 0, 0, NULL((void*)0), NULL((void*)0), |
261 | _ctk_marshal_VOID__OBJECT_OBJECT, |
262 | G_TYPE_NONE((GType) ((1) << (2))), 2, |
263 | CTK_TYPE_ACTION(ctk_action_get_type ()), CTK_TYPE_WIDGET(ctk_widget_get_type ())); |
264 | |
265 | /** |
266 | * CtkActionGroup::disconnect-proxy: |
267 | * @action_group: the group |
268 | * @action: the action |
269 | * @proxy: the proxy |
270 | * |
271 | * The ::disconnect-proxy signal is emitted after disconnecting a proxy |
272 | * from an action in the group. |
273 | * |
274 | * #CtkUIManager proxies the signal and provides global notification |
275 | * just before any action is connected to a proxy, which is probably more |
276 | * convenient to use. |
277 | * |
278 | * Since: 2.4 |
279 | */ |
280 | action_group_signals[DISCONNECT_PROXY] = |
281 | g_signal_new (I_("disconnect-proxy")g_intern_static_string ("disconnect-proxy"), |
282 | G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)), |
283 | 0, 0, NULL((void*)0), NULL((void*)0), |
284 | _ctk_marshal_VOID__OBJECT_OBJECT, |
285 | G_TYPE_NONE((GType) ((1) << (2))), 2, |
286 | CTK_TYPE_ACTION(ctk_action_get_type ()), CTK_TYPE_WIDGET(ctk_widget_get_type ())); |
287 | |
288 | /** |
289 | * CtkActionGroup::pre-activate: |
290 | * @action_group: the group |
291 | * @action: the action |
292 | * |
293 | * The ::pre-activate signal is emitted just before the @action in the |
294 | * @action_group is activated |
295 | * |
296 | * This is intended for #CtkUIManager to proxy the signal and provide global |
297 | * notification just before any action is activated. |
298 | * |
299 | * Since: 2.4 |
300 | */ |
301 | action_group_signals[PRE_ACTIVATE] = |
302 | g_signal_new (I_("pre-activate")g_intern_static_string ("pre-activate"), |
303 | G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)), |
304 | 0, 0, NULL((void*)0), NULL((void*)0), |
305 | NULL((void*)0), |
306 | G_TYPE_NONE((GType) ((1) << (2))), 1, |
307 | CTK_TYPE_ACTION(ctk_action_get_type ())); |
308 | |
309 | /** |
310 | * CtkActionGroup::post-activate: |
311 | * @action_group: the group |
312 | * @action: the action |
313 | * |
314 | * The ::post-activate signal is emitted just after the @action in the |
315 | * @action_group is activated |
316 | * |
317 | * This is intended for #CtkUIManager to proxy the signal and provide global |
318 | * notification just after any action is activated. |
319 | * |
320 | * Since: 2.4 |
321 | */ |
322 | action_group_signals[POST_ACTIVATE] = |
323 | g_signal_new (I_("post-activate")g_intern_static_string ("post-activate"), |
324 | G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)), |
325 | 0, 0, NULL((void*)0), NULL((void*)0), |
326 | NULL((void*)0), |
327 | G_TYPE_NONE((GType) ((1) << (2))), 1, |
328 | CTK_TYPE_ACTION(ctk_action_get_type ())); |
329 | } |
330 | |
331 | |
332 | static void |
333 | remove_action (CtkAction *action) |
334 | { |
335 | g_object_set (action, I_("action-group")g_intern_static_string ("action-group"), NULL((void*)0), NULL((void*)0)); |
336 | g_object_unref (action); |
337 | } |
338 | |
339 | static void |
340 | ctk_action_group_init (CtkActionGroup *action_group) |
341 | { |
342 | action_group->priv = ctk_action_group_get_instance_private (action_group); |
343 | action_group->priv->name = NULL((void*)0); |
344 | action_group->priv->sensitive = TRUE(!(0)); |
345 | action_group->priv->visible = TRUE(!(0)); |
346 | action_group->priv->actions = g_hash_table_new_full (g_str_hash, g_str_equal, |
347 | NULL((void*)0), |
348 | (GDestroyNotify) remove_action); |
349 | action_group->priv->translate_func = NULL((void*)0); |
350 | action_group->priv->translate_data = NULL((void*)0); |
351 | action_group->priv->translate_notify = NULL((void*)0); |
352 | } |
353 | |
354 | static void |
355 | ctk_action_group_buildable_init (CtkBuildableIface *iface) |
356 | { |
357 | iface->add_child = ctk_action_group_buildable_add_child; |
358 | iface->set_name = ctk_action_group_buildable_set_name; |
359 | iface->get_name = ctk_action_group_buildable_get_name; |
360 | iface->custom_tag_start = ctk_action_group_buildable_custom_tag_start; |
361 | iface->custom_tag_end = ctk_action_group_buildable_custom_tag_end; |
362 | } |
363 | |
364 | static void |
365 | ctk_action_group_buildable_add_child (CtkBuildable *buildable, |
366 | CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)), |
367 | GObject *child, |
368 | const gchar *type G_GNUC_UNUSED__attribute__ ((__unused__))) |
369 | { |
370 | ctk_action_group_add_action_with_accel (CTK_ACTION_GROUP (buildable)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((buildable)), ((ctk_action_group_get_type ())))))), |
371 | CTK_ACTION (child)((((CtkAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_action_get_type ())))))), NULL((void*)0)); |
372 | } |
373 | |
374 | static void |
375 | ctk_action_group_buildable_set_name (CtkBuildable *buildable, |
376 | const gchar *name) |
377 | { |
378 | CtkActionGroup *self = CTK_ACTION_GROUP (buildable)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((buildable)), ((ctk_action_group_get_type ())))))); |
379 | CtkActionGroupPrivate *private = self->priv; |
380 | |
381 | private->name = g_strdup (name)g_strdup_inline (name); |
382 | } |
383 | |
384 | static const gchar * |
385 | ctk_action_group_buildable_get_name (CtkBuildable *buildable) |
386 | { |
387 | CtkActionGroup *self = CTK_ACTION_GROUP (buildable)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((buildable)), ((ctk_action_group_get_type ())))))); |
388 | CtkActionGroupPrivate *private = self->priv; |
389 | |
390 | return private->name; |
391 | } |
392 | |
393 | typedef struct { |
394 | GObject *child; |
395 | guint key; |
396 | CdkModifierType modifiers; |
397 | } AcceleratorParserData; |
398 | |
399 | static void |
400 | accelerator_start_element (GMarkupParseContext *context G_GNUC_UNUSED__attribute__ ((__unused__)), |
401 | const gchar *element_name, |
402 | const gchar **names, |
403 | const gchar **values, |
404 | gpointer user_data, |
405 | GError **error) |
406 | { |
407 | gint i; |
408 | guint key = 0; |
409 | CdkModifierType modifiers = 0; |
410 | AcceleratorParserData *parser_data = (AcceleratorParserData*)user_data; |
411 | |
412 | if (strcmp (element_name, "accelerator") != 0) |
413 | g_warning ("Unknown <accelerator> tag: %s", element_name); |
414 | |
415 | for (i = 0; names[i]; i++) |
416 | { |
417 | if (strcmp (names[i], "key") == 0) |
418 | key = cdk_keyval_from_name (values[i]); |
419 | else if (strcmp (names[i], "modifiers") == 0) |
420 | { |
421 | if (!_ctk_builder_flags_from_string (CDK_TYPE_MODIFIER_TYPE(cdk_modifier_type_get_type ()), |
422 | NULL((void*)0), |
423 | values[i], |
424 | &modifiers, |
425 | error)) |
426 | return; |
427 | } |
428 | } |
429 | |
430 | if (key == 0) |
431 | { |
432 | g_warning ("<accelerator> requires a key attribute"); |
433 | return; |
434 | } |
435 | parser_data->key = key; |
436 | parser_data->modifiers = modifiers; |
437 | } |
438 | |
439 | static const GMarkupParser accelerator_parser = |
440 | { |
441 | .start_element = accelerator_start_element |
442 | }; |
443 | |
444 | static gboolean |
445 | ctk_action_group_buildable_custom_tag_start (CtkBuildable *buildable G_GNUC_UNUSED__attribute__ ((__unused__)), |
446 | CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)), |
447 | GObject *child, |
448 | const gchar *tagname, |
449 | GMarkupParser *parser, |
450 | gpointer *user_data) |
451 | { |
452 | AcceleratorParserData *parser_data; |
453 | |
454 | if (child && strcmp (tagname, "accelerator") == 0) |
455 | { |
456 | parser_data = g_slice_new0 (AcceleratorParserData)((AcceleratorParserData*) g_slice_alloc0 (sizeof (AcceleratorParserData ))); |
457 | parser_data->child = child; |
458 | *user_data = parser_data; |
459 | *parser = accelerator_parser; |
460 | |
461 | return TRUE(!(0)); |
462 | } |
463 | return FALSE(0); |
464 | } |
465 | |
466 | static void |
467 | ctk_action_group_buildable_custom_tag_end (CtkBuildable *buildable, |
468 | CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)), |
469 | GObject *child, |
470 | const gchar *tagname, |
471 | gpointer *user_data) |
472 | { |
473 | AcceleratorParserData *data; |
474 | |
475 | if (strcmp (tagname, "accelerator") == 0) |
476 | { |
477 | CtkActionGroup *action_group; |
478 | CtkActionGroupPrivate *private; |
479 | CtkAction *action; |
480 | gchar *accel_path; |
481 | |
482 | data = (AcceleratorParserData*)user_data; |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
483 | action_group = CTK_ACTION_GROUP (buildable)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((buildable)), ((ctk_action_group_get_type ())))))); |
484 | private = action_group->priv; |
485 | action = CTK_ACTION (child)((((CtkAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_action_get_type ())))))); |
486 | |
487 | accel_path = g_strconcat ("<Actions>/", |
488 | private->name, "/", |
489 | ctk_action_get_name (action), NULL((void*)0)); |
490 | |
491 | if (ctk_accel_map_lookup_entry (accel_path, NULL((void*)0))) |
492 | ctk_accel_map_change_entry (accel_path, data->key, data->modifiers, TRUE(!(0))); |
493 | else |
494 | ctk_accel_map_add_entry (accel_path, data->key, data->modifiers); |
495 | |
496 | ctk_action_set_accel_path (action, accel_path); |
497 | |
498 | g_free (accel_path); |
499 | g_slice_free (AcceleratorParserData, data)do { if (1) g_slice_free1 (sizeof (AcceleratorParserData), (data )); else (void) ((AcceleratorParserData*) 0 == (data)); } while (0); |
500 | } |
501 | } |
502 | |
503 | /** |
504 | * ctk_action_group_new: |
505 | * @name: the name of the action group. |
506 | * |
507 | * Creates a new #CtkActionGroup object. The name of the action group |
508 | * is used when associating [keybindings][Action-Accel] |
509 | * with the actions. |
510 | * |
511 | * Returns: the new #CtkActionGroup |
512 | * |
513 | * Since: 2.4 |
514 | */ |
515 | CtkActionGroup * |
516 | ctk_action_group_new (const gchar *name) |
517 | { |
518 | CtkActionGroup *self; |
519 | CtkActionGroupPrivate *private; |
520 | |
521 | self = g_object_new (CTK_TYPE_ACTION_GROUP(ctk_action_group_get_type ()), NULL((void*)0)); |
522 | private = self->priv; |
523 | private->name = g_strdup (name)g_strdup_inline (name); |
524 | |
525 | return self; |
526 | } |
527 | |
528 | static void |
529 | ctk_action_group_finalize (GObject *object) |
530 | { |
531 | CtkActionGroup *self = CTK_ACTION_GROUP (object)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_action_group_get_type ())))))); |
532 | |
533 | g_free (self->priv->name); |
534 | |
535 | g_hash_table_destroy (self->priv->actions); |
536 | |
537 | g_clear_object (&self->priv->accel_group)do { _Static_assert (sizeof *((&self->priv->accel_group )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&self->priv->accel_group))) _pp = ((&self-> priv->accel_group)); __typeof__ (*((&self->priv-> accel_group))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref ) (_ptr); } while (0); |
538 | |
539 | if (self->priv->translate_notify != NULL((void*)0)) |
540 | self->priv->translate_notify (self->priv->translate_data); |
541 | |
542 | G_OBJECT_CLASS (ctk_action_group_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_action_group_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); |
543 | } |
544 | |
545 | static void |
546 | ctk_action_group_set_property (GObject *object, |
547 | guint prop_id, |
548 | const GValue *value, |
549 | GParamSpec *pspec) |
550 | { |
551 | CtkActionGroup *self; |
552 | CtkActionGroupPrivate *private; |
553 | gchar *tmp; |
554 | |
555 | self = CTK_ACTION_GROUP (object)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_action_group_get_type ())))))); |
556 | private = self->priv; |
557 | |
558 | switch (prop_id) |
559 | { |
560 | case PROP_NAME: |
561 | tmp = private->name; |
562 | private->name = g_value_dup_string (value); |
563 | g_free (tmp); |
564 | break; |
565 | case PROP_SENSITIVE: |
566 | ctk_action_group_set_sensitive (self, g_value_get_boolean (value)); |
567 | break; |
568 | case PROP_VISIBLE: |
569 | ctk_action_group_set_visible (self, g_value_get_boolean (value)); |
570 | break; |
571 | case PROP_ACCEL_GROUP: |
572 | ctk_action_group_set_accel_group (self, g_value_get_object (value)); |
573 | break; |
574 | default: |
575 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkactiongroup.c", 575, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
576 | break; |
577 | } |
578 | } |
579 | |
580 | static void |
581 | ctk_action_group_get_property (GObject *object, |
582 | guint prop_id, |
583 | GValue *value, |
584 | GParamSpec *pspec) |
585 | { |
586 | CtkActionGroup *self; |
587 | CtkActionGroupPrivate *private; |
588 | |
589 | self = CTK_ACTION_GROUP (object)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_action_group_get_type ())))))); |
590 | private = self->priv; |
591 | |
592 | switch (prop_id) |
593 | { |
594 | case PROP_NAME: |
595 | g_value_set_string (value, private->name); |
596 | break; |
597 | case PROP_SENSITIVE: |
598 | g_value_set_boolean (value, private->sensitive); |
599 | break; |
600 | case PROP_VISIBLE: |
601 | g_value_set_boolean (value, private->visible); |
602 | break; |
603 | case PROP_ACCEL_GROUP: |
604 | g_value_set_object (value, private->accel_group); |
605 | break; |
606 | default: |
607 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkactiongroup.c", 607, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
608 | break; |
609 | } |
610 | } |
611 | |
612 | static CtkAction * |
613 | ctk_action_group_real_get_action (CtkActionGroup *self, |
614 | const gchar *action_name) |
615 | { |
616 | CtkActionGroupPrivate *private; |
617 | |
618 | private = self->priv; |
619 | |
620 | return g_hash_table_lookup (private->actions, action_name); |
621 | } |
622 | |
623 | /** |
624 | * ctk_action_group_get_name: |
625 | * @action_group: the action group |
626 | * |
627 | * Gets the name of the action group. |
628 | * |
629 | * Returns: the name of the action group. |
630 | * |
631 | * Since: 2.4 |
632 | */ |
633 | const gchar * |
634 | ctk_action_group_get_name (CtkActionGroup *action_group) |
635 | { |
636 | CtkActionGroupPrivate *private; |
637 | |
638 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return (((void*)0)); } } while (0); |
639 | |
640 | private = action_group->priv; |
641 | |
642 | return private->name; |
643 | } |
644 | |
645 | /** |
646 | * ctk_action_group_get_sensitive: |
647 | * @action_group: the action group |
648 | * |
649 | * Returns %TRUE if the group is sensitive. The constituent actions |
650 | * can only be logically sensitive (see ctk_action_is_sensitive()) if |
651 | * they are sensitive (see ctk_action_get_sensitive()) and their group |
652 | * is sensitive. |
653 | * |
654 | * Returns: %TRUE if the group is sensitive. |
655 | * |
656 | * Since: 2.4 |
657 | */ |
658 | gboolean |
659 | ctk_action_group_get_sensitive (CtkActionGroup *action_group) |
660 | { |
661 | CtkActionGroupPrivate *private; |
662 | |
663 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ((0)); } } while (0); |
664 | |
665 | private = action_group->priv; |
666 | |
667 | return private->sensitive; |
668 | } |
669 | |
670 | static void |
671 | cb_set_action_sensitivity (const gchar *name G_GNUC_UNUSED__attribute__ ((__unused__)), |
672 | CtkAction *action) |
673 | { |
674 | /* Minor optimization, the action_groups state only affects actions |
675 | * that are themselves sensitive */ |
676 | g_object_notify (G_OBJECT (action)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), (((GType) ((20) << (2)))))))), "sensitive"); |
677 | |
678 | } |
679 | |
680 | /** |
681 | * ctk_action_group_set_sensitive: |
682 | * @action_group: the action group |
683 | * @sensitive: new sensitivity |
684 | * |
685 | * Changes the sensitivity of @action_group |
686 | * |
687 | * Since: 2.4 |
688 | */ |
689 | void |
690 | ctk_action_group_set_sensitive (CtkActionGroup *action_group, |
691 | gboolean sensitive) |
692 | { |
693 | CtkActionGroupPrivate *private; |
694 | |
695 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
696 | |
697 | private = action_group->priv; |
698 | sensitive = sensitive != FALSE(0); |
699 | |
700 | if (private->sensitive != sensitive) |
701 | { |
702 | private->sensitive = sensitive; |
703 | g_hash_table_foreach (private->actions, |
704 | (GHFunc) cb_set_action_sensitivity, NULL((void*)0)); |
705 | |
706 | g_object_notify (G_OBJECT (action_group)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action_group)), (((GType) ((20) << (2)))))))), "sensitive"); |
707 | } |
708 | } |
709 | |
710 | /** |
711 | * ctk_action_group_get_visible: |
712 | * @action_group: the action group |
713 | * |
714 | * Returns %TRUE if the group is visible. The constituent actions |
715 | * can only be logically visible (see ctk_action_is_visible()) if |
716 | * they are visible (see ctk_action_get_visible()) and their group |
717 | * is visible. |
718 | * |
719 | * Returns: %TRUE if the group is visible. |
720 | * |
721 | * Since: 2.4 |
722 | */ |
723 | gboolean |
724 | ctk_action_group_get_visible (CtkActionGroup *action_group) |
725 | { |
726 | CtkActionGroupPrivate *private; |
727 | |
728 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ((0)); } } while (0); |
729 | |
730 | private = action_group->priv; |
731 | |
732 | return private->visible; |
733 | } |
734 | |
735 | /** |
736 | * ctk_action_group_get_accel_group: |
737 | * @action_group: a #CtkActionGroup |
738 | * |
739 | * Gets the accelerator group. |
740 | * |
741 | * Returns: (transfer none): the accelerator group associated with this action |
742 | * group or %NULL if there is none. |
743 | * |
744 | * Since: 3.6 |
745 | */ |
746 | CtkAccelGroup * |
747 | ctk_action_group_get_accel_group (CtkActionGroup *action_group) |
748 | { |
749 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ((0)); } } while (0); |
750 | |
751 | return action_group->priv->accel_group; |
752 | } |
753 | |
754 | static void |
755 | cb_set_action_visiblity (const gchar *name G_GNUC_UNUSED__attribute__ ((__unused__)), |
756 | CtkAction *action) |
757 | { |
758 | /* Minor optimization, the action_groups state only affects actions |
759 | * that are themselves visible */ |
760 | g_object_notify (G_OBJECT (action)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), (((GType) ((20) << (2)))))))), "visible"); |
761 | } |
762 | |
763 | /** |
764 | * ctk_action_group_set_visible: |
765 | * @action_group: the action group |
766 | * @visible: new visiblity |
767 | * |
768 | * Changes the visible of @action_group. |
769 | * |
770 | * Since: 2.4 |
771 | */ |
772 | void |
773 | ctk_action_group_set_visible (CtkActionGroup *action_group, |
774 | gboolean visible) |
775 | { |
776 | CtkActionGroupPrivate *private; |
777 | |
778 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
779 | |
780 | private = action_group->priv; |
781 | visible = visible != FALSE(0); |
782 | |
783 | if (private->visible != visible) |
784 | { |
785 | private->visible = visible; |
786 | g_hash_table_foreach (private->actions, |
787 | (GHFunc) cb_set_action_visiblity, NULL((void*)0)); |
788 | |
789 | g_object_notify (G_OBJECT (action_group)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action_group)), (((GType) ((20) << (2)))))))), "visible"); |
790 | } |
791 | } |
792 | |
793 | static void |
794 | ctk_action_group_accel_group_foreach (gpointer key G_GNUC_UNUSED__attribute__ ((__unused__)), |
795 | gpointer val, |
796 | gpointer data) |
797 | { |
798 | ctk_action_set_accel_group (val, data); |
799 | } |
800 | |
801 | /** |
802 | * ctk_action_group_set_accel_group: |
803 | * @action_group: a #CtkActionGroup |
804 | * @accel_group: (allow-none): a #CtkAccelGroup to set or %NULL |
805 | * |
806 | * Sets the accelerator group to be used by every action in this group. |
807 | * |
808 | * Since: 3.6 |
809 | */ |
810 | void |
811 | ctk_action_group_set_accel_group (CtkActionGroup *action_group, |
812 | CtkAccelGroup *accel_group) |
813 | { |
814 | CtkActionGroupPrivate *private; |
815 | |
816 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
817 | |
818 | private = action_group->priv; |
819 | |
820 | if (private->accel_group == accel_group) |
821 | return; |
822 | |
823 | g_clear_object (&private->accel_group)do { _Static_assert (sizeof *((&private->accel_group)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&private->accel_group))) _pp = ((&private-> accel_group)); __typeof__ (*((&private->accel_group))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) ( _ptr); } while (0); |
824 | |
825 | if (accel_group) |
826 | private->accel_group = g_object_ref (accel_group)((__typeof__ (accel_group)) (g_object_ref) (accel_group)); |
827 | |
828 | /* Set the new accel group on every action */ |
829 | g_hash_table_foreach (private->actions, |
830 | ctk_action_group_accel_group_foreach, |
831 | accel_group); |
832 | |
833 | g_object_notify (G_OBJECT (action_group)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action_group)), (((GType) ((20) << (2)))))))), "accel-group"); |
834 | } |
835 | |
836 | /** |
837 | * ctk_action_group_get_action: |
838 | * @action_group: the action group |
839 | * @action_name: the name of the action |
840 | * |
841 | * Looks up an action in the action group by name. |
842 | * |
843 | * Returns: (transfer none): the action, or %NULL if no action by that name exists |
844 | * |
845 | * Since: 2.4 |
846 | */ |
847 | CtkAction * |
848 | ctk_action_group_get_action (CtkActionGroup *action_group, |
849 | const gchar *action_name) |
850 | { |
851 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return (((void*)0)); } } while (0); |
852 | g_return_val_if_fail (CTK_ACTION_GROUP_GET_CLASS (action_group)->get_action != NULL, NULL)do { if ((((((CtkActionGroupClass*) (((GTypeInstance*) ((action_group )))->g_class))))->get_action != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_ACTION_GROUP_GET_CLASS (action_group)->get_action != NULL" ); return (((void*)0)); } } while (0); |
853 | |
854 | return CTK_ACTION_GROUP_GET_CLASS (action_group)((((CtkActionGroupClass*) (((GTypeInstance*) ((action_group)) )->g_class))))->get_action (action_group, |
855 | action_name); |
856 | } |
857 | |
858 | static gboolean |
859 | check_unique_action (CtkActionGroup *action_group, |
860 | const gchar *action_name) |
861 | { |
862 | if (ctk_action_group_get_action (action_group, action_name) != NULL((void*)0)) |
863 | { |
864 | CtkActionGroupPrivate *private; |
865 | |
866 | private = action_group->priv; |
867 | |
868 | g_warning ("Refusing to add non-unique action '%s' to action group '%s'", |
869 | action_name, |
870 | private->name); |
871 | return FALSE(0); |
872 | } |
873 | |
874 | return TRUE(!(0)); |
875 | } |
876 | |
877 | /** |
878 | * ctk_action_group_add_action: |
879 | * @action_group: the action group |
880 | * @action: an action |
881 | * |
882 | * Adds an action object to the action group. Note that this function |
883 | * does not set up the accel path of the action, which can lead to problems |
884 | * if a user tries to modify the accelerator of a menuitem associated with |
885 | * the action. Therefore you must either set the accel path yourself with |
886 | * ctk_action_set_accel_path(), or use |
887 | * `ctk_action_group_add_action_with_accel (..., NULL)`. |
888 | * |
889 | * Since: 2.4 |
890 | */ |
891 | void |
892 | ctk_action_group_add_action (CtkActionGroup *action_group, |
893 | CtkAction *action) |
894 | { |
895 | CtkActionGroupPrivate *private; |
896 | const gchar *name; |
897 | |
898 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
899 | g_return_if_fail (CTK_IS_ACTION (action))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action)); GType __t = ((ctk_action_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_ACTION (action)"); return; } } while (0); |
900 | |
901 | name = ctk_action_get_name (action); |
902 | g_return_if_fail (name != NULL)do { if ((name != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "name != NULL"); return; } } while (0); |
903 | |
904 | if (!check_unique_action (action_group, name)) |
905 | return; |
906 | |
907 | private = action_group->priv; |
908 | |
909 | g_hash_table_insert (private->actions, |
910 | (gpointer) name, |
911 | g_object_ref (action)((__typeof__ (action)) (g_object_ref) (action))); |
912 | g_object_set (action, I_("action-group")g_intern_static_string ("action-group"), action_group, NULL((void*)0)); |
913 | |
914 | if (private->accel_group) |
915 | ctk_action_set_accel_group (action, private->accel_group); |
916 | } |
917 | |
918 | /** |
919 | * ctk_action_group_add_action_with_accel: |
920 | * @action_group: the action group |
921 | * @action: the action to add |
922 | * @accelerator: (allow-none): the accelerator for the action, in |
923 | * the format understood by ctk_accelerator_parse(), or "" for no accelerator, or |
924 | * %NULL to use the stock accelerator |
925 | * |
926 | * Adds an action object to the action group and sets up the accelerator. |
927 | * |
928 | * If @accelerator is %NULL, attempts to use the accelerator associated |
929 | * with the stock_id of the action. |
930 | * |
931 | * Accel paths are set to `<Actions>/group-name/action-name`. |
932 | * |
933 | * Since: 2.4 |
934 | */ |
935 | void |
936 | ctk_action_group_add_action_with_accel (CtkActionGroup *action_group, |
937 | CtkAction *action, |
938 | const gchar *accelerator) |
939 | { |
940 | CtkActionGroupPrivate *private; |
941 | gchar *accel_path; |
942 | guint accel_key = 0; |
943 | CdkModifierType accel_mods; |
944 | const gchar *name; |
945 | |
946 | name = ctk_action_get_name (action); |
947 | if (!check_unique_action (action_group, name)) |
948 | return; |
949 | |
950 | private = action_group->priv; |
951 | accel_path = g_strconcat ("<Actions>/", |
952 | private->name, "/", name, NULL((void*)0)); |
953 | |
954 | if (accelerator) |
955 | { |
956 | if (accelerator[0] == 0) |
957 | accel_key = 0; |
958 | else |
959 | { |
960 | ctk_accelerator_parse (accelerator, &accel_key, &accel_mods); |
961 | if (accel_key == 0) |
962 | g_warning ("Unable to parse accelerator '%s' for action '%s'", |
963 | accelerator, name); |
964 | } |
965 | } |
966 | else |
967 | { |
968 | gchar *stock_id; |
969 | CtkStockItem stock_item; |
970 | |
971 | g_object_get (action, "stock-id", &stock_id, NULL((void*)0)); |
972 | |
973 | if (stock_id && ctk_stock_lookup (stock_id, &stock_item)) |
974 | { |
975 | accel_key = stock_item.keyval; |
976 | accel_mods = stock_item.modifier; |
977 | } |
978 | |
979 | g_free (stock_id); |
980 | } |
981 | |
982 | if (accel_key) |
983 | ctk_accel_map_add_entry (accel_path, accel_key, accel_mods); |
984 | |
985 | ctk_action_set_accel_path (action, accel_path); |
986 | ctk_action_group_add_action (action_group, action); |
987 | |
988 | g_free (accel_path); |
989 | } |
990 | |
991 | /** |
992 | * ctk_action_group_remove_action: |
993 | * @action_group: the action group |
994 | * @action: an action |
995 | * |
996 | * Removes an action object from the action group. |
997 | * |
998 | * Since: 2.4 |
999 | */ |
1000 | void |
1001 | ctk_action_group_remove_action (CtkActionGroup *action_group, |
1002 | CtkAction *action) |
1003 | { |
1004 | CtkActionGroupPrivate *private; |
1005 | const gchar *name; |
1006 | |
1007 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
1008 | g_return_if_fail (CTK_IS_ACTION (action))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action)); GType __t = ((ctk_action_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_ACTION (action)"); return; } } while (0); |
1009 | |
1010 | name = ctk_action_get_name (action); |
1011 | g_return_if_fail (name != NULL)do { if ((name != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "name != NULL"); return; } } while (0); |
1012 | |
1013 | private = action_group->priv; |
1014 | |
1015 | g_hash_table_remove (private->actions, name); |
1016 | } |
1017 | |
1018 | static void |
1019 | add_single_action (gpointer key G_GNUC_UNUSED__attribute__ ((__unused__)), |
1020 | gpointer value, |
1021 | gpointer user_data) |
1022 | { |
1023 | GList **list = user_data; |
1024 | |
1025 | *list = g_list_prepend (*list, value); |
1026 | } |
1027 | |
1028 | /** |
1029 | * ctk_action_group_list_actions: |
1030 | * @action_group: the action group |
1031 | * |
1032 | * Lists the actions in the action group. |
1033 | * |
1034 | * Returns: (element-type CtkAction) (transfer container): an allocated list of the action objects in the action group |
1035 | * |
1036 | * Since: 2.4 |
1037 | */ |
1038 | GList * |
1039 | ctk_action_group_list_actions (CtkActionGroup *action_group) |
1040 | { |
1041 | CtkActionGroupPrivate *private; |
1042 | GList *actions = NULL((void*)0); |
1043 | |
1044 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return (((void*)0)); } } while (0); |
1045 | |
1046 | private = action_group->priv; |
1047 | |
1048 | g_hash_table_foreach (private->actions, add_single_action, &actions); |
1049 | |
1050 | return g_list_reverse (actions); |
1051 | } |
1052 | |
1053 | |
1054 | /** |
1055 | * ctk_action_group_add_actions: (skip) |
1056 | * @action_group: the action group |
1057 | * @entries: (array length=n_entries): an array of action descriptions |
1058 | * @n_entries: the number of entries |
1059 | * @user_data: data to pass to the action callbacks |
1060 | * |
1061 | * This is a convenience function to create a number of actions and add them |
1062 | * to the action group. |
1063 | * |
1064 | * The “activate” signals of the actions are connected to the callbacks |
1065 | * and their accel paths are set to `<Actions>/group-name/action-name`. |
1066 | * |
1067 | * Since: 2.4 |
1068 | */ |
1069 | void |
1070 | ctk_action_group_add_actions (CtkActionGroup *action_group, |
1071 | const CtkActionEntry *entries, |
1072 | guint n_entries, |
1073 | gpointer user_data) |
1074 | { |
1075 | ctk_action_group_add_actions_full (action_group, |
1076 | entries, n_entries, |
1077 | user_data, NULL((void*)0)); |
1078 | } |
1079 | |
1080 | typedef struct _SharedData SharedData; |
1081 | |
1082 | struct _SharedData { |
1083 | guint ref_count; |
1084 | gpointer data; |
1085 | GDestroyNotify destroy; |
1086 | }; |
1087 | |
1088 | static void |
1089 | shared_data_unref (gpointer data) |
1090 | { |
1091 | SharedData *shared_data = (SharedData *)data; |
1092 | |
1093 | shared_data->ref_count--; |
1094 | if (shared_data->ref_count == 0) |
1095 | { |
1096 | if (shared_data->destroy) |
1097 | shared_data->destroy (shared_data->data); |
1098 | |
1099 | g_slice_free (SharedData, shared_data)do { if (1) g_slice_free1 (sizeof (SharedData), (shared_data) ); else (void) ((SharedData*) 0 == (shared_data)); } while (0 ); |
1100 | } |
1101 | } |
1102 | |
1103 | |
1104 | /** |
1105 | * ctk_action_group_add_actions_full: (skip) |
1106 | * @action_group: the action group |
1107 | * @entries: (array length=n_entries): an array of action descriptions |
1108 | * @n_entries: the number of entries |
1109 | * @user_data: data to pass to the action callbacks |
1110 | * @destroy: (nullable): destroy notification callback for @user_data |
1111 | * |
1112 | * This variant of ctk_action_group_add_actions() adds a #GDestroyNotify |
1113 | * callback for @user_data. |
1114 | * |
1115 | * Since: 2.4 |
1116 | */ |
1117 | void |
1118 | ctk_action_group_add_actions_full (CtkActionGroup *action_group, |
1119 | const CtkActionEntry *entries, |
1120 | guint n_entries, |
1121 | gpointer user_data, |
1122 | GDestroyNotify destroy) |
1123 | { |
1124 | |
1125 | /* Keep this in sync with the other |
1126 | * ctk_action_group_add_..._actions_full() functions. |
1127 | */ |
1128 | guint i; |
1129 | SharedData *shared_data; |
1130 | |
1131 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
1132 | |
1133 | shared_data = g_slice_new0 (SharedData)((SharedData*) g_slice_alloc0 (sizeof (SharedData))); |
1134 | shared_data->ref_count = 1; |
1135 | shared_data->data = user_data; |
1136 | shared_data->destroy = destroy; |
1137 | |
1138 | for (i = 0; i < n_entries; i++) |
1139 | { |
1140 | CtkAction *action; |
1141 | const gchar *label; |
1142 | const gchar *tooltip; |
1143 | |
1144 | if (!check_unique_action (action_group, entries[i].name)) |
1145 | continue; |
1146 | |
1147 | label = ctk_action_group_translate_string (action_group, entries[i].label); |
1148 | tooltip = ctk_action_group_translate_string (action_group, entries[i].tooltip); |
1149 | |
1150 | action = ctk_action_new (entries[i].name, |
1151 | label, |
1152 | tooltip, |
1153 | NULL((void*)0)); |
1154 | |
1155 | if (entries[i].stock_id) |
1156 | { |
1157 | g_object_set (action, "stock-id", entries[i].stock_id, NULL((void*)0)); |
1158 | if (ctk_icon_theme_has_icon (ctk_icon_theme_get_default (), |
1159 | entries[i].stock_id)) |
1160 | g_object_set (action, "icon-name", entries[i].stock_id, NULL((void*)0)); |
1161 | } |
1162 | |
1163 | if (entries[i].callback) |
1164 | { |
1165 | GClosure *closure; |
1166 | |
1167 | closure = g_cclosure_new (entries[i].callback, user_data, NULL((void*)0)); |
1168 | g_closure_add_finalize_notifier (closure, shared_data, |
1169 | (GClosureNotify)shared_data_unref); |
1170 | shared_data->ref_count++; |
1171 | |
1172 | g_signal_connect_closure (action, "activate", closure, FALSE(0)); |
1173 | } |
1174 | |
1175 | ctk_action_group_add_action_with_accel (action_group, |
1176 | action, |
1177 | entries[i].accelerator); |
1178 | g_object_unref (action); |
1179 | } |
1180 | |
1181 | shared_data_unref (shared_data); |
1182 | } |
1183 | |
1184 | /** |
1185 | * ctk_action_group_add_toggle_actions: (skip) |
1186 | * @action_group: the action group |
1187 | * @entries: (array length=n_entries): an array of toggle action descriptions |
1188 | * @n_entries: the number of entries |
1189 | * @user_data: data to pass to the action callbacks |
1190 | * |
1191 | * This is a convenience function to create a number of toggle actions and add them |
1192 | * to the action group. |
1193 | * |
1194 | * The “activate” signals of the actions are connected to the callbacks |
1195 | * and their accel paths are set to `<Actions>/group-name/action-name`. |
1196 | * |
1197 | * Since: 2.4 |
1198 | */ |
1199 | void |
1200 | ctk_action_group_add_toggle_actions (CtkActionGroup *action_group, |
1201 | const CtkToggleActionEntry *entries, |
1202 | guint n_entries, |
1203 | gpointer user_data) |
1204 | { |
1205 | ctk_action_group_add_toggle_actions_full (action_group, |
1206 | entries, n_entries, |
1207 | user_data, NULL((void*)0)); |
1208 | } |
1209 | |
1210 | |
1211 | /** |
1212 | * ctk_action_group_add_toggle_actions_full: (skip) |
1213 | * @action_group: the action group |
1214 | * @entries: (array length=n_entries): an array of toggle action descriptions |
1215 | * @n_entries: the number of entries |
1216 | * @user_data: data to pass to the action callbacks |
1217 | * @destroy: (nullable): destroy notification callback for @user_data |
1218 | * |
1219 | * This variant of ctk_action_group_add_toggle_actions() adds a |
1220 | * #GDestroyNotify callback for @user_data. |
1221 | * |
1222 | * Since: 2.4 |
1223 | */ |
1224 | void |
1225 | ctk_action_group_add_toggle_actions_full (CtkActionGroup *action_group, |
1226 | const CtkToggleActionEntry *entries, |
1227 | guint n_entries, |
1228 | gpointer user_data, |
1229 | GDestroyNotify destroy) |
1230 | { |
1231 | /* Keep this in sync with the other |
1232 | * ctk_action_group_add_..._actions_full() functions. |
1233 | */ |
1234 | guint i; |
1235 | SharedData *shared_data; |
1236 | |
1237 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
1238 | |
1239 | shared_data = g_slice_new0 (SharedData)((SharedData*) g_slice_alloc0 (sizeof (SharedData))); |
1240 | shared_data->ref_count = 1; |
1241 | shared_data->data = user_data; |
1242 | shared_data->destroy = destroy; |
1243 | |
1244 | for (i = 0; i < n_entries; i++) |
1245 | { |
1246 | CtkToggleAction *action; |
1247 | const gchar *label; |
1248 | const gchar *tooltip; |
1249 | |
1250 | if (!check_unique_action (action_group, entries[i].name)) |
1251 | continue; |
1252 | |
1253 | label = ctk_action_group_translate_string (action_group, entries[i].label); |
1254 | tooltip = ctk_action_group_translate_string (action_group, entries[i].tooltip); |
1255 | |
1256 | action = ctk_toggle_action_new (entries[i].name, |
1257 | label, |
1258 | tooltip, |
1259 | NULL((void*)0)); |
1260 | |
1261 | if (entries[i].stock_id) |
1262 | { |
1263 | if (ctk_icon_factory_lookup_default (entries[i].stock_id)) |
1264 | g_object_set (action, "stock-id", entries[i].stock_id, NULL((void*)0)); |
1265 | else |
1266 | g_object_set (action, "icon-name", entries[i].stock_id, NULL((void*)0)); |
1267 | } |
1268 | |
1269 | ctk_toggle_action_set_active (action, entries[i].is_active); |
1270 | |
1271 | if (entries[i].callback) |
1272 | { |
1273 | GClosure *closure; |
1274 | |
1275 | closure = g_cclosure_new (entries[i].callback, user_data, NULL((void*)0)); |
1276 | g_closure_add_finalize_notifier (closure, shared_data, |
1277 | (GClosureNotify)shared_data_unref); |
1278 | shared_data->ref_count++; |
1279 | |
1280 | g_signal_connect_closure (action, "activate", closure, FALSE(0)); |
1281 | } |
1282 | |
1283 | ctk_action_group_add_action_with_accel (action_group, |
1284 | CTK_ACTION (action)((((CtkAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((ctk_action_get_type ())))))), |
1285 | entries[i].accelerator); |
1286 | g_object_unref (action); |
1287 | } |
1288 | |
1289 | shared_data_unref (shared_data); |
1290 | } |
1291 | |
1292 | /** |
1293 | * ctk_action_group_add_radio_actions: (skip) |
1294 | * @action_group: the action group |
1295 | * @entries: (array length=n_entries): an array of radio action descriptions |
1296 | * @n_entries: the number of entries |
1297 | * @value: the value of the action to activate initially, or -1 if |
1298 | * no action should be activated |
1299 | * @on_change: the callback to connect to the changed signal |
1300 | * @user_data: data to pass to the action callbacks |
1301 | * |
1302 | * This is a convenience routine to create a group of radio actions and |
1303 | * add them to the action group. |
1304 | * |
1305 | * The “changed” signal of the first radio action is connected to the |
1306 | * @on_change callback and the accel paths of the actions are set to |
1307 | * `<Actions>/group-name/action-name`. |
1308 | * |
1309 | * Since: 2.4 |
1310 | **/ |
1311 | void |
1312 | ctk_action_group_add_radio_actions (CtkActionGroup *action_group, |
1313 | const CtkRadioActionEntry *entries, |
1314 | guint n_entries, |
1315 | gint value, |
1316 | GCallback on_change, |
1317 | gpointer user_data) |
1318 | { |
1319 | ctk_action_group_add_radio_actions_full (action_group, |
1320 | entries, n_entries, |
1321 | value, |
1322 | on_change, user_data, NULL((void*)0)); |
1323 | } |
1324 | |
1325 | /** |
1326 | * ctk_action_group_add_radio_actions_full: (skip) |
1327 | * @action_group: the action group |
1328 | * @entries: (array length=n_entries): an array of radio action descriptions |
1329 | * @n_entries: the number of entries |
1330 | * @value: the value of the action to activate initially, or -1 if |
1331 | * no action should be activated |
1332 | * @on_change: the callback to connect to the changed signal |
1333 | * @user_data: data to pass to the action callbacks |
1334 | * @destroy: destroy notification callback for @user_data |
1335 | * |
1336 | * This variant of ctk_action_group_add_radio_actions() adds a |
1337 | * #GDestroyNotify callback for @user_data. |
1338 | * |
1339 | * Since: 2.4 |
1340 | **/ |
1341 | void |
1342 | ctk_action_group_add_radio_actions_full (CtkActionGroup *action_group, |
1343 | const CtkRadioActionEntry *entries, |
1344 | guint n_entries, |
1345 | gint value, |
1346 | GCallback on_change, |
1347 | gpointer user_data, |
1348 | GDestroyNotify destroy) |
1349 | { |
1350 | /* Keep this in sync with the other |
1351 | * ctk_action_group_add_..._actions_full() functions. |
1352 | */ |
1353 | guint i; |
1354 | GSList *group = NULL((void*)0); |
1355 | CtkRadioAction *first_action = NULL((void*)0); |
1356 | |
1357 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
1358 | |
1359 | for (i = 0; i < n_entries; i++) |
1360 | { |
1361 | CtkRadioAction *action; |
1362 | const gchar *label; |
1363 | const gchar *tooltip; |
1364 | |
1365 | if (!check_unique_action (action_group, entries[i].name)) |
1366 | continue; |
1367 | |
1368 | label = ctk_action_group_translate_string (action_group, entries[i].label); |
1369 | tooltip = ctk_action_group_translate_string (action_group, entries[i].tooltip); |
1370 | |
1371 | action = ctk_radio_action_new (entries[i].name, |
1372 | label, |
1373 | tooltip, |
1374 | NULL((void*)0), |
1375 | entries[i].value); |
1376 | |
1377 | if (entries[i].stock_id) |
1378 | { |
1379 | if (ctk_icon_factory_lookup_default (entries[i].stock_id)) |
1380 | g_object_set (action, "stock-id", entries[i].stock_id, NULL((void*)0)); |
1381 | else |
1382 | g_object_set (action, "icon-name", entries[i].stock_id, NULL((void*)0)); |
1383 | } |
1384 | |
1385 | if (i == 0) |
1386 | first_action = action; |
1387 | |
1388 | ctk_radio_action_set_group (action, group); |
1389 | group = ctk_radio_action_get_group (action); |
1390 | |
1391 | if (value == entries[i].value) |
1392 | ctk_toggle_action_set_active (CTK_TOGGLE_ACTION (action)((((CtkToggleAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((ctk_toggle_action_get_type ())))))), TRUE(!(0))); |
1393 | |
1394 | ctk_action_group_add_action_with_accel (action_group, |
1395 | CTK_ACTION (action)((((CtkAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((ctk_action_get_type ())))))), |
1396 | entries[i].accelerator); |
1397 | g_object_unref (action); |
1398 | } |
1399 | |
1400 | if (on_change && first_action) |
1401 | g_signal_connect_data (first_action, "changed", |
1402 | on_change, user_data, |
1403 | (GClosureNotify)destroy, 0); |
1404 | } |
1405 | |
1406 | /** |
1407 | * ctk_action_group_set_translate_func: |
1408 | * @action_group: a #CtkActionGroup |
1409 | * @func: a #CtkTranslateFunc |
1410 | * @data: data to be passed to @func and @notify |
1411 | * @notify: a #GDestroyNotify function to be called when @action_group is |
1412 | * destroyed and when the translation function is changed again |
1413 | * |
1414 | * Sets a function to be used for translating the @label and @tooltip of |
1415 | * #CtkActionEntrys added by ctk_action_group_add_actions(). |
1416 | * |
1417 | * If you’re using gettext(), it is enough to set the translation domain |
1418 | * with ctk_action_group_set_translation_domain(). |
1419 | * |
1420 | * Since: 2.4 |
1421 | **/ |
1422 | void |
1423 | ctk_action_group_set_translate_func (CtkActionGroup *action_group, |
1424 | CtkTranslateFunc func, |
1425 | gpointer data, |
1426 | GDestroyNotify notify) |
1427 | { |
1428 | CtkActionGroupPrivate *private; |
1429 | |
1430 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
1431 | |
1432 | private = action_group->priv; |
1433 | |
1434 | if (private->translate_notify) |
1435 | private->translate_notify (private->translate_data); |
1436 | |
1437 | private->translate_func = func; |
1438 | private->translate_data = data; |
1439 | private->translate_notify = notify; |
1440 | } |
1441 | |
1442 | static gchar * |
1443 | dgettext_swapped (const gchar *msgid, |
1444 | const gchar *domainname) |
1445 | { |
1446 | /* Pass through g_dgettext if and only if msgid is nonempty. */ |
1447 | if (msgid && *msgid) |
1448 | return (gchar*) g_dgettext (domainname, msgid); |
1449 | else |
1450 | return (gchar*) msgid; |
1451 | } |
1452 | |
1453 | /** |
1454 | * ctk_action_group_set_translation_domain: |
1455 | * @action_group: a #CtkActionGroup |
1456 | * @domain: (allow-none): the translation domain to use for g_dgettext() |
1457 | * calls, or %NULL to use the domain set with textdomain() |
1458 | * |
1459 | * Sets the translation domain and uses g_dgettext() for translating the |
1460 | * @label and @tooltip of #CtkActionEntrys added by |
1461 | * ctk_action_group_add_actions(). |
1462 | * |
1463 | * If you’re not using gettext() for localization, see |
1464 | * ctk_action_group_set_translate_func(). |
1465 | * |
1466 | * Since: 2.4 |
1467 | **/ |
1468 | void |
1469 | ctk_action_group_set_translation_domain (CtkActionGroup *action_group, |
1470 | const gchar *domain) |
1471 | { |
1472 | g_return_if_fail (CTK_IS_ACTION_GROUP (action_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return ; } } while (0); |
1473 | |
1474 | ctk_action_group_set_translate_func (action_group, |
1475 | (CtkTranslateFunc)dgettext_swapped, |
1476 | g_strdup (domain)g_strdup_inline (domain), |
1477 | g_free); |
1478 | } |
1479 | |
1480 | |
1481 | /** |
1482 | * ctk_action_group_translate_string: |
1483 | * @action_group: a #CtkActionGroup |
1484 | * @string: a string |
1485 | * |
1486 | * Translates a string using the function set with |
1487 | * ctk_action_group_set_translate_func(). This |
1488 | * is mainly intended for language bindings. |
1489 | * |
1490 | * Returns: the translation of @string |
1491 | * |
1492 | * Since: 2.6 |
1493 | **/ |
1494 | const gchar * |
1495 | ctk_action_group_translate_string (CtkActionGroup *action_group, |
1496 | const gchar *string) |
1497 | { |
1498 | CtkActionGroupPrivate *private; |
1499 | CtkTranslateFunc translate_func; |
1500 | gpointer translate_data; |
1501 | |
1502 | g_return_val_if_fail (CTK_IS_ACTION_GROUP (action_group), string)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((action_group)); GType __t = ((ctk_action_group_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_ACTION_GROUP (action_group)"); return (string); } } while (0); |
1503 | |
1504 | if (string == NULL((void*)0)) |
1505 | return NULL((void*)0); |
1506 | |
1507 | private = action_group->priv; |
1508 | |
1509 | translate_func = private->translate_func; |
1510 | translate_data = private->translate_data; |
1511 | |
1512 | if (translate_func) |
1513 | return translate_func (string, translate_data); |
1514 | else |
1515 | return string; |
1516 | } |
1517 | |
1518 | /* Protected for use by CtkAction */ |
1519 | void |
1520 | _ctk_action_group_emit_connect_proxy (CtkActionGroup *action_group, |
1521 | CtkAction *action, |
1522 | CtkWidget *proxy) |
1523 | { |
1524 | g_signal_emit (action_group, action_group_signals[CONNECT_PROXY], 0, |
1525 | action, proxy); |
1526 | } |
1527 | |
1528 | void |
1529 | _ctk_action_group_emit_disconnect_proxy (CtkActionGroup *action_group, |
1530 | CtkAction *action, |
1531 | CtkWidget *proxy) |
1532 | { |
1533 | g_signal_emit (action_group, action_group_signals[DISCONNECT_PROXY], 0, |
1534 | action, proxy); |
1535 | } |
1536 | |
1537 | void |
1538 | _ctk_action_group_emit_pre_activate (CtkActionGroup *action_group, |
1539 | CtkAction *action) |
1540 | { |
1541 | g_signal_emit (action_group, action_group_signals[PRE_ACTIVATE], 0, action); |
1542 | } |
1543 | |
1544 | void |
1545 | _ctk_action_group_emit_post_activate (CtkActionGroup *action_group, |
1546 | CtkAction *action) |
1547 | { |
1548 | g_signal_emit (action_group, action_group_signals[POST_ACTIVATE], 0, action); |
1549 | } |