File: | ctk/ctkactionable.c |
Warning: | line 78, column 27 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 | * Copyright © 2012 Canonical Limited |
3 | * |
4 | * This library is free software: you can redistribute it and/or modify |
5 | * it under the terms of the GNU Lesser General Public License as |
6 | * published by the Free Software Foundation; either version 2 of the |
7 | * licence or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, but |
10 | * 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. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | * Authors: Ryan Lortie <desrt@desrt.ca> |
18 | */ |
19 | |
20 | #include "config.h" |
21 | |
22 | #include "ctkactionable.h" |
23 | |
24 | #include "ctkwidget.h" |
25 | #include "ctkintl.h" |
26 | |
27 | /** |
28 | * SECTION:ctkactionable |
29 | * @title: CtkActionable |
30 | * @short_description: An interface for widgets that can be associated |
31 | * with actions |
32 | * |
33 | * This interface provides a convenient way of associating widgets with |
34 | * actions on a #CtkApplicationWindow or #CtkApplication. |
35 | * |
36 | * It primarily consists of two properties: #CtkActionable:action-name |
37 | * and #CtkActionable:action-target. There are also some convenience APIs |
38 | * for setting these properties. |
39 | * |
40 | * The action will be looked up in action groups that are found among |
41 | * the widgets ancestors. Most commonly, these will be the actions with |
42 | * the “win.” or “app.” prefix that are associated with the #CtkApplicationWindow |
43 | * or #CtkApplication, but other action groups that are added with |
44 | * ctk_widget_insert_action_group() will be consulted as well. |
45 | * |
46 | * Since: 3.4 |
47 | **/ |
48 | |
49 | /** |
50 | * CtkActionable: |
51 | * |
52 | * An opaque pointer type. |
53 | **/ |
54 | |
55 | /** |
56 | * CtkActionableInterface: |
57 | * @get_action_name: virtual function for ctk_actionable_get_action_name() |
58 | * @set_action_name: virtual function for ctk_actionable_set_action_name() |
59 | * @get_action_target_value: virtual function for ctk_actionable_get_action_target_value() |
60 | * @set_action_target_value: virtual function for ctk_actionable_set_action_target_value() |
61 | * |
62 | * The interface vtable for #CtkActionable. |
63 | **/ |
64 | |
65 | G_DEFINE_INTERFACE (CtkActionable, ctk_actionable, CTK_TYPE_WIDGET)static void ctk_actionable_default_init (CtkActionableInterface *klass); GType ctk_actionable_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 = g_type_register_static_simple (((GType) ((2) << (2)) ), g_intern_static_string ("CtkActionable"), sizeof (CtkActionableInterface ), (GClassInitFunc)(void (*)(void)) ctk_actionable_default_init , 0, (GInstanceInitFunc)((void*)0), (GTypeFlags) 0); if ((ctk_widget_get_type ()) != ((GType) ((0) << (2)))) g_type_interface_add_prerequisite (g_define_type_id, (ctk_widget_get_type ())); { {;;} } (__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 ; } |
66 | |
67 | static void |
68 | ctk_actionable_default_init (CtkActionableInterface *iface) |
69 | { |
70 | g_object_interface_install_property (iface, |
71 | g_param_spec_string ("action-name", P_("Action name")g_dgettext("ctk30" "-properties","Action name"), |
72 | P_("The name of the associated action, like 'app.quit'")g_dgettext("ctk30" "-properties","The name of the associated action, like 'app.quit'" ), |
73 | NULL((void*)0), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB ))); |
74 | |
75 | g_object_interface_install_property (iface, |
76 | g_param_spec_variant ("action-target", P_("Action target value")g_dgettext("ctk30" "-properties","Action target value"), |
77 | P_("The parameter for action invocations")g_dgettext("ctk30" "-properties","The parameter for action invocations" ), |
78 | G_VARIANT_TYPE_ANY((const GVariantType *) "*"), NULL((void*)0), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB ))); |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
79 | } |
80 | |
81 | /** |
82 | * ctk_actionable_get_action_name: |
83 | * @actionable: a #CtkActionable widget |
84 | * |
85 | * Gets the action name for @actionable. |
86 | * |
87 | * See ctk_actionable_set_action_name() for more information. |
88 | * |
89 | * Returns: (nullable): the action name, or %NULL if none is set |
90 | * |
91 | * Since: 3.4 |
92 | **/ |
93 | const gchar * |
94 | ctk_actionable_get_action_name (CtkActionable *actionable) |
95 | { |
96 | g_return_val_if_fail (CTK_IS_ACTIONABLE (actionable), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((actionable)); GType __t = ((ctk_actionable_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_ACTIONABLE (actionable)"); return ((( void*)0)); } } while (0); |
97 | |
98 | return CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance *) ((actionable)))->g_class, ((ctk_actionable_get_type ()) ))))) |
99 | ->get_action_name (actionable); |
100 | } |
101 | |
102 | /** |
103 | * ctk_actionable_set_action_name: |
104 | * @actionable: a #CtkActionable widget |
105 | * @action_name: (nullable): an action name, or %NULL |
106 | * |
107 | * Specifies the name of the action with which this widget should be |
108 | * associated. If @action_name is %NULL then the widget will be |
109 | * unassociated from any previous action. |
110 | * |
111 | * Usually this function is used when the widget is located (or will be |
112 | * located) within the hierarchy of a #CtkApplicationWindow. |
113 | * |
114 | * Names are of the form “win.save” or “app.quit” for actions on the |
115 | * containing #CtkApplicationWindow or its associated #CtkApplication, |
116 | * respectively. This is the same form used for actions in the #GMenu |
117 | * associated with the window. |
118 | * |
119 | * Since: 3.4 |
120 | **/ |
121 | void |
122 | ctk_actionable_set_action_name (CtkActionable *actionable, |
123 | const gchar *action_name) |
124 | { |
125 | g_return_if_fail (CTK_IS_ACTIONABLE (actionable))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((actionable)); GType __t = ((ctk_actionable_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_ACTIONABLE (actionable)"); return; } } while (0); |
126 | |
127 | CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance *) ((actionable)))->g_class, ((ctk_actionable_get_type ()) ))))) |
128 | ->set_action_name (actionable, action_name); |
129 | } |
130 | |
131 | /** |
132 | * ctk_actionable_get_action_target_value: |
133 | * @actionable: a #CtkActionable widget |
134 | * |
135 | * Gets the current target value of @actionable. |
136 | * |
137 | * See ctk_actionable_set_action_target_value() for more information. |
138 | * |
139 | * Returns: (transfer none): the current target value |
140 | * |
141 | * Since: 3.4 |
142 | **/ |
143 | GVariant * |
144 | ctk_actionable_get_action_target_value (CtkActionable *actionable) |
145 | { |
146 | g_return_val_if_fail (CTK_IS_ACTIONABLE (actionable), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((actionable)); GType __t = ((ctk_actionable_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_ACTIONABLE (actionable)"); return ((( void*)0)); } } while (0); |
147 | |
148 | return CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance *) ((actionable)))->g_class, ((ctk_actionable_get_type ()) ))))) |
149 | ->get_action_target_value (actionable); |
150 | } |
151 | |
152 | /** |
153 | * ctk_actionable_set_action_target_value: |
154 | * @actionable: a #CtkActionable widget |
155 | * @target_value: (nullable): a #GVariant to set as the target value, or %NULL |
156 | * |
157 | * Sets the target value of an actionable widget. |
158 | * |
159 | * If @target_value is %NULL then the target value is unset. |
160 | * |
161 | * The target value has two purposes. First, it is used as the |
162 | * parameter to activation of the action associated with the |
163 | * #CtkActionable widget. Second, it is used to determine if the widget |
164 | * should be rendered as “active” — the widget is active if the state |
165 | * is equal to the given target. |
166 | * |
167 | * Consider the example of associating a set of buttons with a #GAction |
168 | * with string state in a typical “radio button” situation. Each button |
169 | * will be associated with the same action, but with a different target |
170 | * value for that action. Clicking on a particular button will activate |
171 | * the action with the target of that button, which will typically cause |
172 | * the action’s state to change to that value. Since the action’s state |
173 | * is now equal to the target value of the button, the button will now |
174 | * be rendered as active (and the other buttons, with different targets, |
175 | * rendered inactive). |
176 | * |
177 | * Since: 3.4 |
178 | **/ |
179 | void |
180 | ctk_actionable_set_action_target_value (CtkActionable *actionable, |
181 | GVariant *target_value) |
182 | { |
183 | g_return_if_fail (CTK_IS_ACTIONABLE (actionable))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((actionable)); GType __t = ((ctk_actionable_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_ACTIONABLE (actionable)"); return; } } while (0); |
184 | |
185 | CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance *) ((actionable)))->g_class, ((ctk_actionable_get_type ()) ))))) |
186 | ->set_action_target_value (actionable, target_value); |
187 | } |
188 | |
189 | /** |
190 | * ctk_actionable_set_action_target: |
191 | * @actionable: a #CtkActionable widget |
192 | * @format_string: a GVariant format string |
193 | * @...: arguments appropriate for @format_string |
194 | * |
195 | * Sets the target of an actionable widget. |
196 | * |
197 | * This is a convenience function that calls g_variant_new() for |
198 | * @format_string and uses the result to call |
199 | * ctk_actionable_set_action_target_value(). |
200 | * |
201 | * If you are setting a string-valued target and want to set the action |
202 | * name at the same time, you can use |
203 | * ctk_actionable_set_detailed_action_name (). |
204 | * |
205 | * Since: 3.4 |
206 | **/ |
207 | void |
208 | ctk_actionable_set_action_target (CtkActionable *actionable, |
209 | const gchar *format_string, |
210 | ...) |
211 | { |
212 | va_list ap; |
213 | |
214 | va_start (ap, format_string)__builtin_va_start(ap, format_string); |
215 | ctk_actionable_set_action_target_value (actionable, g_variant_new_va (format_string, NULL((void*)0), &ap)); |
216 | va_end (ap)__builtin_va_end(ap); |
217 | } |
218 | |
219 | /** |
220 | * ctk_actionable_set_detailed_action_name: |
221 | * @actionable: a #CtkActionable widget |
222 | * @detailed_action_name: the detailed action name |
223 | * |
224 | * Sets the action-name and associated string target value of an |
225 | * actionable widget. |
226 | * |
227 | * @detailed_action_name is a string in the format accepted by |
228 | * g_action_parse_detailed_name(). |
229 | * |
230 | * (Note that prior to version 3.22.25, |
231 | * this function is only usable for actions with a simple "s" target, and |
232 | * @detailed_action_name must be of the form `"action::target"` where |
233 | * `action` is the action name and `target` is the string to use |
234 | * as the target.) |
235 | * |
236 | * Since: 3.4 |
237 | **/ |
238 | void |
239 | ctk_actionable_set_detailed_action_name (CtkActionable *actionable, |
240 | const gchar *detailed_action_name) |
241 | { |
242 | GError *error = NULL((void*)0); |
243 | GVariant *target; |
244 | gchar *name; |
245 | |
246 | if (detailed_action_name == NULL((void*)0)) |
247 | { |
248 | ctk_actionable_set_action_name (actionable, NULL((void*)0)); |
249 | ctk_actionable_set_action_target_value (actionable, NULL((void*)0)); |
250 | return; |
251 | } |
252 | |
253 | if (!g_action_parse_detailed_name (detailed_action_name, &name, &target, &error)) |
254 | g_error ("ctk_actionable_set_detailed_action_name: %s", error->message); |
255 | |
256 | ctk_actionable_set_action_name (actionable, name); |
257 | ctk_actionable_set_action_target_value (actionable, target); |
258 | |
259 | if (target) |
260 | g_variant_unref (target); |
261 | g_free (name); |
262 | } |
263 |