File: | tests/testgmenu.c |
Warning: | line 247, column 41 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 | /* testgmenu.c |
2 | * Copyright (C) 2011 Red Hat, Inc. |
3 | * Written by Matthias Clasen |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #include <stdlib.h> |
20 | #include <string.h> |
21 | #include <gio/gio.h> |
22 | #include <ctk/ctk.h> |
23 | |
24 | /* TODO |
25 | * |
26 | * - Labeled sections |
27 | * |
28 | * - Focus changes. Verify that stopping subscriptions works. |
29 | * |
30 | * - Other attributes. What about icons ? |
31 | */ |
32 | |
33 | /* The example menu {{{1 */ |
34 | |
35 | static const gchar menu_markup[] = |
36 | "<interface>\n" |
37 | "<menu id='edit-menu'>\n" |
38 | " <section>\n" |
39 | " <item>\n" |
40 | " <attribute name='action'>actions.undo</attribute>\n" |
41 | " <attribute name='label' translatable='yes' context='Stock label'>_Undo</attribute>\n" |
42 | " </item>\n" |
43 | " <item>\n" |
44 | " <attribute name='label' translatable='yes'>Redo</attribute>\n" |
45 | " <attribute name='action'>actions.redo</attribute>\n" |
46 | " </item>\n" |
47 | " </section>\n" |
48 | " <section/>\n" |
49 | " <section>\n" |
50 | " <attribute name='label' translatable='yes'>Copy & Paste</attribute>\n" |
51 | " <item>\n" |
52 | " <attribute name='label' translatable='yes'>Cut</attribute>\n" |
53 | " <attribute name='action'>actions.cut</attribute>\n" |
54 | " </item>\n" |
55 | " <item>\n" |
56 | " <attribute name='label' translatable='yes'>Copy</attribute>\n" |
57 | " <attribute name='action'>actions.copy</attribute>\n" |
58 | " </item>\n" |
59 | " <item>\n" |
60 | " <attribute name='label' translatable='yes'>Paste</attribute>\n" |
61 | " <attribute name='action'>actions.paste</attribute>\n" |
62 | " </item>\n" |
63 | " </section>\n" |
64 | " <section>\n" |
65 | " <item>\n" |
66 | " <attribute name='label' translatable='yes'>Bold</attribute>\n" |
67 | " <attribute name='action'>actions.bold</attribute>\n" |
68 | " </item>\n" |
69 | " <section id=\"size-placeholder\">\n" |
70 | " <attribute name=\"label\">Size</attribute>" |
71 | " </section>\n" |
72 | " <submenu>\n" |
73 | " <attribute name='label' translatable='yes'>Language</attribute>\n" |
74 | " <item>\n" |
75 | " <attribute name='label' translatable='yes'>Latin</attribute>\n" |
76 | " <attribute name='action'>actions.lang</attribute>\n" |
77 | " <attribute name='target'>latin</attribute>\n" |
78 | " </item>\n" |
79 | " <item>\n" |
80 | " <attribute name='label' translatable='yes'>Greek</attribute>\n" |
81 | " <attribute name='action'>actions.lang</attribute>\n" |
82 | " <attribute name='target'>greek</attribute>\n" |
83 | " </item>\n" |
84 | " <item>\n" |
85 | " <attribute name='label' translatable='yes'>Urdu</attribute>\n" |
86 | " <attribute name='action'>actions.lang</attribute>\n" |
87 | " <attribute name='target'>urdu</attribute>\n" |
88 | " </item>\n" |
89 | " </submenu>\n" |
90 | " </section>\n" |
91 | "</menu>\n" |
92 | "</interface>\n"; |
93 | |
94 | static GMenuModel * |
95 | get_model (void) |
96 | { |
97 | GError *error = NULL((void*)0); |
98 | CtkBuilder *builder; |
99 | GMenuModel *menu, *section; |
100 | float i; |
101 | |
102 | builder = ctk_builder_new (); |
103 | ctk_builder_add_from_string (builder, menu_markup, -1, &error); |
104 | g_assert_no_error (error)do { if (error) g_assertion_message_error (((gchar*) 0), "testgmenu.c" , 104, ((const char*) (__func__)), "error", error, 0, 0); } while (0); |
105 | |
106 | menu = G_MENU_MODEL (g_object_ref (ctk_builder_get_object (builder, "edit-menu")))((((GMenuModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((((__typeof__ (ctk_builder_get_object (builder, "edit-menu" ))) (g_object_ref) (ctk_builder_get_object (builder, "edit-menu" ))))), ((g_menu_model_get_type ())))))); |
107 | |
108 | section = G_MENU_MODEL (g_object_ref (ctk_builder_get_object (builder, "size-placeholder")))((((GMenuModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((((__typeof__ (ctk_builder_get_object (builder, "size-placeholder" ))) (g_object_ref) (ctk_builder_get_object (builder, "size-placeholder" ))))), ((g_menu_model_get_type ())))))); |
109 | g_object_unref (builder); |
110 | |
111 | for (i = 0.5; i <= 2.0; i += 0.5) |
112 | { |
113 | GMenuItem *item; |
114 | char *target; |
115 | char *label; |
116 | |
117 | target = g_strdup_printf ("actions.size::%.1f", i); |
118 | label = g_strdup_printf ("x %.1f", i); |
119 | item = g_menu_item_new (label, target); |
120 | g_menu_append_item (G_MENU (section)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((section)), ((g_menu_get_type ())))))), item); |
121 | g_free (label); |
122 | g_free (target); |
123 | } |
124 | |
125 | return menu; |
126 | } |
127 | |
128 | /* The example actions {{{1 */ |
129 | |
130 | static void |
131 | activate_action (GSimpleAction *action, |
132 | GVariant *parameter G_GNUC_UNUSED__attribute__ ((__unused__)), |
133 | gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
134 | { |
135 | g_print ("Action %s activated\n", g_action_get_name (G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ())))))))); |
136 | } |
137 | |
138 | static void |
139 | activate_toggle (GSimpleAction *action, |
140 | GVariant *parameter G_GNUC_UNUSED__attribute__ ((__unused__)), |
141 | gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
142 | { |
143 | GVariant *old_state, *new_state; |
144 | |
145 | old_state = g_action_get_state (G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))); |
146 | new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state)); |
147 | |
148 | g_print ("Toggle action %s activated, state changes from %d to %d\n", |
149 | g_action_get_name (G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))), |
150 | g_variant_get_boolean (old_state), |
151 | g_variant_get_boolean (new_state)); |
152 | |
153 | g_simple_action_set_state (action, new_state); |
154 | g_variant_unref (old_state); |
155 | } |
156 | |
157 | static void |
158 | activate_radio (GSimpleAction *action, |
159 | GVariant *parameter, |
160 | gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
161 | { |
162 | GVariant *old_state, *new_state; |
163 | |
164 | old_state = g_action_get_state (G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))); |
165 | new_state = g_variant_new_string (g_variant_get_string (parameter, NULL((void*)0))); |
166 | |
167 | g_print ("Radio action %s activated, state changes from %s to %s\n", |
168 | g_action_get_name (G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))), |
169 | g_variant_get_string (old_state, NULL((void*)0)), |
170 | g_variant_get_string (new_state, NULL((void*)0))); |
171 | |
172 | g_simple_action_set_state (action, new_state); |
173 | g_variant_unref (old_state); |
174 | } |
175 | |
176 | static GActionEntry actions[] = { |
177 | { .name = "undo", .activate = activate_action }, |
178 | { .name = "redo", .activate = activate_action }, |
179 | { .name = "cut", .activate = activate_action }, |
180 | { .name = "copy", .activate = activate_action }, |
181 | { .name = "paste", .activate = activate_action }, |
182 | { .name = "bold", .activate = activate_toggle, .state = "true" }, |
183 | { .name = "lang", .activate = activate_radio, .parameter_type = "s", .state = "'latin'" }, |
184 | }; |
185 | |
186 | static GActionGroup * |
187 | get_group (void) |
188 | { |
189 | GSimpleActionGroup *group; |
190 | |
191 | group = g_simple_action_group_new (); |
192 | |
193 | g_action_map_add_action_entries (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), actions, G_N_ELEMENTS (actions)(sizeof (actions) / sizeof ((actions)[0])), NULL((void*)0)); |
194 | |
195 | return G_ACTION_GROUP (group)((((GActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_group_get_type ())))))); |
196 | } |
197 | |
198 | /* The action treeview {{{1 */ |
199 | |
200 | static void |
201 | enabled_cell_func (CtkTreeViewColumn *column G_GNUC_UNUSED__attribute__ ((__unused__)), |
202 | CtkCellRenderer *cell, |
203 | CtkTreeModel *model, |
204 | CtkTreeIter *iter, |
205 | gpointer data) |
206 | { |
207 | GActionGroup *group = data; |
208 | gchar *name; |
209 | gboolean enabled; |
210 | |
211 | ctk_tree_model_get (model, iter, 0, &name, -1); |
212 | enabled = g_action_group_get_action_enabled (group, name); |
213 | g_free (name); |
214 | |
215 | ctk_cell_renderer_toggle_set_active (CTK_CELL_RENDERER_TOGGLE (cell)((((CtkCellRendererToggle*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((cell)), ((ctk_cell_renderer_toggle_get_type ())))))), enabled); |
216 | } |
217 | |
218 | static void |
219 | state_cell_func (CtkTreeViewColumn *column G_GNUC_UNUSED__attribute__ ((__unused__)), |
220 | CtkCellRenderer *cell, |
221 | CtkTreeModel *model, |
222 | CtkTreeIter *iter, |
223 | gpointer data) |
224 | { |
225 | GActionGroup *group = data; |
226 | gchar *name; |
227 | GVariant *state; |
228 | |
229 | ctk_tree_model_get (model, iter, 0, &name, -1); |
230 | state = g_action_group_get_action_state (group, name); |
231 | g_free (name); |
232 | |
233 | ctk_cell_renderer_set_visible (cell, FALSE(0)); |
234 | g_object_set (cell, "mode", CTK_CELL_RENDERER_MODE_INERT, NULL((void*)0)); |
235 | |
236 | if (state == NULL((void*)0)) |
237 | return; |
238 | |
239 | if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")) && |
240 | CTK_IS_CELL_RENDERER_TOGGLE (cell)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cell)); GType __t = ((ctk_cell_renderer_toggle_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; } ))))) |
241 | { |
242 | ctk_cell_renderer_set_visible (cell, TRUE(!(0))); |
243 | g_object_set (cell, "mode", CTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL((void*)0)); |
244 | ctk_cell_renderer_toggle_set_active (CTK_CELL_RENDERER_TOGGLE (cell)((((CtkCellRendererToggle*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((cell)), ((ctk_cell_renderer_toggle_get_type ())))))), |
245 | g_variant_get_boolean (state)); |
246 | } |
247 | else if (g_variant_is_of_type (state, G_VARIANT_TYPE_STRING((const GVariantType *) "s")) && |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
248 | CTK_IS_CELL_RENDERER_COMBO (cell)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cell)); GType __t = ((ctk_cell_renderer_combo_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; } ))))) |
249 | { |
250 | ctk_cell_renderer_set_visible (cell, TRUE(!(0))); |
251 | g_object_set (cell, "mode", CTK_CELL_RENDERER_MODE_EDITABLE, NULL((void*)0)); |
252 | g_object_set (cell, "text", g_variant_get_string (state, NULL((void*)0)), NULL((void*)0)); |
253 | } |
254 | |
255 | g_variant_unref (state); |
256 | } |
257 | |
258 | static void |
259 | enabled_cell_toggled (CtkCellRendererToggle *cell G_GNUC_UNUSED__attribute__ ((__unused__)), |
260 | const gchar *path_str, |
261 | CtkTreeModel *model) |
262 | { |
263 | GActionGroup *group; |
264 | GAction *action; |
265 | gchar *name; |
266 | CtkTreePath *path; |
267 | CtkTreeIter iter; |
268 | gboolean enabled; |
269 | |
270 | group = g_object_get_data (G_OBJECT (model)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), (((GType) ((20) << (2)))))))), "group"); |
271 | path = ctk_tree_path_new_from_string (path_str); |
272 | ctk_tree_model_get_iter (model, &iter, path); |
273 | ctk_tree_model_get (model, &iter, 0, &name, -1); |
274 | |
275 | enabled = g_action_group_get_action_enabled (group, name); |
276 | action = g_action_map_lookup_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), name); |
277 | g_simple_action_set_enabled (G_SIMPLE_ACTION (action)((((GSimpleAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_simple_action_get_type ())))))), !enabled); |
278 | |
279 | ctk_tree_model_row_changed (model, path, &iter); |
280 | |
281 | g_free (name); |
282 | ctk_tree_path_free (path); |
283 | } |
284 | |
285 | static void |
286 | state_cell_toggled (CtkCellRendererToggle *cell G_GNUC_UNUSED__attribute__ ((__unused__)), |
287 | const gchar *path_str, |
288 | CtkTreeModel *model) |
289 | { |
290 | GActionGroup *group; |
291 | GAction *action; |
292 | gchar *name; |
293 | CtkTreePath *path; |
294 | CtkTreeIter iter; |
295 | GVariant *state; |
296 | |
297 | group = g_object_get_data (G_OBJECT (model)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), (((GType) ((20) << (2)))))))), "group"); |
298 | path = ctk_tree_path_new_from_string (path_str); |
299 | ctk_tree_model_get_iter (model, &iter, path); |
300 | ctk_tree_model_get (model, &iter, 0, &name, -1); |
301 | |
302 | state = g_action_group_get_action_state (group, name); |
303 | action = g_action_map_lookup_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), name); |
304 | if (state && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b"))) |
305 | { |
306 | gboolean b; |
307 | |
308 | b = g_variant_get_boolean (state); |
309 | g_simple_action_set_state (G_SIMPLE_ACTION (action)((((GSimpleAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_simple_action_get_type ())))))), g_variant_new_boolean (!b)); |
310 | } |
311 | else |
312 | { |
313 | /* nothing to do */ |
314 | } |
315 | |
316 | ctk_tree_model_row_changed (model, path, &iter); |
317 | |
318 | g_free (name); |
319 | ctk_tree_path_free (path); |
320 | if (state) |
321 | g_variant_unref (state); |
322 | } |
323 | |
324 | static void |
325 | state_cell_edited (CtkCellRendererCombo *cell G_GNUC_UNUSED__attribute__ ((__unused__)), |
326 | const gchar *path_str, |
327 | const gchar *new_text, |
328 | CtkTreeModel *model) |
329 | { |
330 | GActionGroup *group; |
331 | GAction *action; |
332 | gchar *name; |
333 | CtkTreePath *path; |
334 | CtkTreeIter iter; |
335 | |
336 | group = g_object_get_data (G_OBJECT (model)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), (((GType) ((20) << (2)))))))), "group"); |
337 | path = ctk_tree_path_new_from_string (path_str); |
338 | ctk_tree_model_get_iter (model, &iter, path); |
339 | ctk_tree_model_get (model, &iter, 0, &name, -1); |
340 | action = g_action_map_lookup_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), name); |
341 | g_simple_action_set_state (G_SIMPLE_ACTION (action)((((GSimpleAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_simple_action_get_type ())))))), g_variant_new_string (new_text)); |
342 | |
343 | ctk_tree_model_row_changed (model, path, &iter); |
344 | |
345 | g_free (name); |
346 | ctk_tree_path_free (path); |
347 | } |
348 | |
349 | static CtkWidget * |
350 | create_action_treeview (GActionGroup *group) |
351 | { |
352 | CtkWidget *tv; |
353 | CtkListStore *store; |
354 | CtkListStore *values; |
355 | CtkTreeIter iter; |
356 | CtkTreeViewColumn *column; |
357 | CtkCellRenderer *cell; |
358 | gchar **actions; |
359 | gint i; |
360 | |
361 | store = ctk_list_store_new (2, G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_STRING((GType) ((16) << (2)))); |
362 | actions = g_action_group_list_actions (group); |
363 | for (i = 0; actions[i]; i++) |
364 | { |
365 | ctk_list_store_append (store, &iter); |
366 | ctk_list_store_set (store, &iter, 0, actions[i], -1); |
367 | } |
368 | g_strfreev (actions); |
369 | g_object_set_data (G_OBJECT (store)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((store)), (((GType) ((20) << (2)))))))), "group", group); |
370 | |
371 | tv = ctk_tree_view_new (); |
372 | |
373 | g_signal_connect_swapped (group, "action-enabled-changed",g_signal_connect_data ((group), ("action-enabled-changed"), ( ((GCallback) (ctk_widget_queue_draw))), (tv), ((void*)0), G_CONNECT_SWAPPED ) |
374 | G_CALLBACK (ctk_widget_queue_draw), tv)g_signal_connect_data ((group), ("action-enabled-changed"), ( ((GCallback) (ctk_widget_queue_draw))), (tv), ((void*)0), G_CONNECT_SWAPPED ); |
375 | g_signal_connect_swapped (group, "action-state-changed",g_signal_connect_data ((group), ("action-state-changed"), ((( GCallback) (ctk_widget_queue_draw))), (tv), ((void*)0), G_CONNECT_SWAPPED ) |
376 | G_CALLBACK (ctk_widget_queue_draw), tv)g_signal_connect_data ((group), ("action-state-changed"), ((( GCallback) (ctk_widget_queue_draw))), (tv), ((void*)0), G_CONNECT_SWAPPED ); |
377 | |
378 | ctk_tree_view_set_model (CTK_TREE_VIEW (tv)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tv)), ((ctk_tree_view_get_type ())))))), CTK_TREE_MODEL (store)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((store)), ((ctk_tree_model_get_type ()))))))); |
379 | |
380 | cell = ctk_cell_renderer_text_new (); |
381 | column = ctk_tree_view_column_new_with_attributes ("Action", cell, |
382 | "text", 0, |
383 | NULL((void*)0)); |
384 | ctk_tree_view_append_column (CTK_TREE_VIEW (tv)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tv)), ((ctk_tree_view_get_type ())))))), column); |
385 | |
386 | column = ctk_tree_view_column_new (); |
387 | ctk_tree_view_column_set_title (column, "Enabled"); |
388 | cell = ctk_cell_renderer_toggle_new (); |
389 | ctk_tree_view_column_pack_start (column, cell, FALSE(0)); |
390 | ctk_tree_view_column_set_cell_data_func (column, cell, enabled_cell_func, group, NULL((void*)0)); |
391 | g_signal_connect (cell, "toggled", G_CALLBACK (enabled_cell_toggled), store)g_signal_connect_data ((cell), ("toggled"), (((GCallback) (enabled_cell_toggled ))), (store), ((void*)0), (GConnectFlags) 0); |
392 | ctk_tree_view_append_column (CTK_TREE_VIEW (tv)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tv)), ((ctk_tree_view_get_type ())))))), column); |
393 | |
394 | column = ctk_tree_view_column_new (); |
395 | ctk_tree_view_column_set_title (column, "State"); |
396 | cell = ctk_cell_renderer_toggle_new (); |
397 | ctk_tree_view_column_pack_start (column, cell, FALSE(0)); |
398 | ctk_tree_view_column_set_cell_data_func (column, cell, state_cell_func, group, NULL((void*)0)); |
399 | g_signal_connect (cell, "toggled", G_CALLBACK (state_cell_toggled), store)g_signal_connect_data ((cell), ("toggled"), (((GCallback) (state_cell_toggled ))), (store), ((void*)0), (GConnectFlags) 0); |
400 | cell = ctk_cell_renderer_combo_new (); |
401 | values = ctk_list_store_new (1, G_TYPE_STRING((GType) ((16) << (2)))); |
402 | ctk_list_store_append (values, &iter); |
403 | ctk_list_store_set (values, &iter, 0, "latin", -1); |
404 | ctk_list_store_append (values, &iter); |
405 | ctk_list_store_set (values, &iter, 0, "greek", -1); |
406 | ctk_list_store_append (values, &iter); |
407 | ctk_list_store_set (values, &iter, 0, "urdu", -1); |
408 | ctk_list_store_append (values, &iter); |
409 | ctk_list_store_set (values, &iter, 0, "sumerian", -1); |
410 | g_object_set (cell, |
411 | "has-entry", FALSE(0), |
412 | "model", values, |
413 | "text-column", 0, |
414 | "editable", TRUE(!(0)), |
415 | NULL((void*)0)); |
416 | ctk_tree_view_column_pack_start (column, cell, FALSE(0)); |
417 | ctk_tree_view_column_set_cell_data_func (column, cell, state_cell_func, group, NULL((void*)0)); |
418 | g_signal_connect (cell, "edited", G_CALLBACK (state_cell_edited), store)g_signal_connect_data ((cell), ("edited"), (((GCallback) (state_cell_edited ))), (store), ((void*)0), (GConnectFlags) 0); |
419 | ctk_tree_view_append_column (CTK_TREE_VIEW (tv)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tv)), ((ctk_tree_view_get_type ())))))), column); |
420 | |
421 | return tv; |
422 | } |
423 | |
424 | /* Dynamic menu changes {{{1 */ |
425 | |
426 | static void |
427 | toggle_sumerian (CtkToggleButton *button, |
428 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) |
429 | { |
430 | GMenuModel *model; |
431 | gboolean adding; |
432 | GMenuModel *m; |
433 | |
434 | model = g_object_get_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "model"); |
435 | |
436 | adding = ctk_toggle_button_get_active (button); |
437 | |
438 | m = g_menu_model_get_item_link (model, g_menu_model_get_n_items (model) - 1, G_MENU_LINK_SECTION"section"); |
439 | m = g_menu_model_get_item_link (m, g_menu_model_get_n_items (m) - 1, G_MENU_LINK_SUBMENU"submenu"); |
440 | if (adding) |
441 | g_menu_append (G_MENU (m)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((m)), ((g_menu_get_type ())))))), "Sumerian", "lang::sumerian"); |
442 | else |
443 | g_menu_remove (G_MENU (m)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((m)), ((g_menu_get_type ())))))), g_menu_model_get_n_items (m) - 1); |
444 | } |
445 | |
446 | static void |
447 | action_list_add (CtkTreeModel *store, |
448 | const gchar *action) |
449 | { |
450 | CtkTreeIter iter; |
451 | |
452 | ctk_list_store_append (CTK_LIST_STORE (store)((((CtkListStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((store)), ((ctk_list_store_get_type ())))))), &iter); |
453 | ctk_list_store_set (CTK_LIST_STORE (store)((((CtkListStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((store)), ((ctk_list_store_get_type ())))))), &iter, 0, action, -1); |
454 | } |
455 | |
456 | static void |
457 | action_list_remove (CtkTreeModel *store, |
458 | const gchar *action) |
459 | { |
460 | CtkTreeIter iter; |
461 | gchar *text; |
462 | |
463 | ctk_tree_model_get_iter_first (store, &iter); |
464 | do { |
465 | ctk_tree_model_get (store, &iter, 0, &text, -1); |
466 | if (g_strcmp0 (action, text) == 0) |
467 | { |
468 | g_free (text); |
469 | ctk_list_store_remove (CTK_LIST_STORE (store)((((CtkListStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((store)), ((ctk_list_store_get_type ())))))), &iter); |
470 | break; |
471 | } |
472 | g_free (text); |
473 | } while (ctk_tree_model_iter_next (store, &iter)); |
474 | } |
475 | |
476 | static void |
477 | toggle_italic (CtkToggleButton *button, gpointer data) |
478 | { |
479 | GMenuModel *model; |
480 | GActionGroup *group; |
481 | gboolean adding; |
482 | GMenuModel *m; |
483 | CtkTreeView *tv = data; |
484 | CtkTreeModel *store; |
485 | |
486 | model = g_object_get_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "model"); |
487 | group = g_object_get_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "group"); |
488 | |
489 | store = ctk_tree_view_get_model (tv); |
490 | |
491 | adding = ctk_toggle_button_get_active (button); |
492 | |
493 | m = g_menu_model_get_item_link (model, g_menu_model_get_n_items (model) - 1, G_MENU_LINK_SECTION"section"); |
494 | if (adding) |
495 | { |
496 | GSimpleAction *action; |
497 | |
498 | action = g_simple_action_new_stateful ("italic", NULL((void*)0), g_variant_new_boolean (FALSE(0))); |
499 | g_action_map_add_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))); |
500 | g_signal_connect (action, "activate", G_CALLBACK (activate_toggle), NULL)g_signal_connect_data ((action), ("activate"), (((GCallback) ( activate_toggle))), (((void*)0)), ((void*)0), (GConnectFlags) 0); |
501 | g_object_unref (action); |
502 | action_list_add (store, "italic"); |
503 | g_menu_insert (G_MENU (m)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((m)), ((g_menu_get_type ())))))), 1, "Italic", "italic"); |
504 | } |
505 | else |
506 | { |
507 | g_action_map_remove_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), "italic"); |
508 | action_list_remove (store, "italic"); |
509 | g_menu_remove (G_MENU (m)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((m)), ((g_menu_get_type ())))))), 1); |
510 | } |
511 | } |
512 | |
513 | static void |
514 | toggle_speed (CtkToggleButton *button, gpointer data) |
515 | { |
516 | GMenuModel *model; |
517 | GActionGroup *group; |
518 | gboolean adding; |
519 | GMenuModel *m; |
520 | CtkTreeView *tv = data; |
521 | CtkTreeModel *store; |
522 | |
523 | model = g_object_get_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "model"); |
524 | group = g_object_get_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "group"); |
525 | |
526 | store = ctk_tree_view_get_model (tv); |
527 | |
528 | adding = ctk_toggle_button_get_active (button); |
529 | |
530 | m = g_menu_model_get_item_link (model, 1, G_MENU_LINK_SECTION"section"); |
531 | if (adding) |
532 | { |
533 | GSimpleAction *action; |
534 | GMenu *submenu; |
535 | |
536 | action = g_simple_action_new ("faster", NULL((void*)0)); |
537 | g_action_map_add_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))); |
538 | g_signal_connect (action, "activate", G_CALLBACK (activate_action), NULL)g_signal_connect_data ((action), ("activate"), (((GCallback) ( activate_action))), (((void*)0)), ((void*)0), (GConnectFlags) 0); |
539 | g_object_unref (action); |
540 | |
541 | action = g_simple_action_new ("slower", NULL((void*)0)); |
542 | g_action_map_add_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((action)), ((g_action_get_type ()))))))); |
543 | g_signal_connect (action, "activate", G_CALLBACK (activate_action), NULL)g_signal_connect_data ((action), ("activate"), (((GCallback) ( activate_action))), (((void*)0)), ((void*)0), (GConnectFlags) 0); |
544 | g_object_unref (action); |
545 | |
546 | action_list_add (store, "faster"); |
547 | action_list_add (store, "slower"); |
548 | |
549 | submenu = g_menu_new (); |
550 | g_menu_append (submenu, "Faster", "faster"); |
551 | g_menu_append (submenu, "Slower", "slower"); |
552 | g_menu_append_submenu (G_MENU (m)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((m)), ((g_menu_get_type ())))))), "Speed", G_MENU_MODEL (submenu)((((GMenuModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((submenu)), ((g_menu_model_get_type ()))))))); |
553 | } |
554 | else |
555 | { |
556 | g_action_map_remove_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), "faster"); |
557 | g_action_map_remove_action (G_ACTION_MAP (group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((group)), ((g_action_map_get_type ())))))), "slower"); |
558 | |
559 | action_list_remove (store, "faster"); |
560 | action_list_remove (store, "slower"); |
561 | |
562 | g_menu_remove (G_MENU (m)((((GMenu*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((m)), ((g_menu_get_type ())))))), g_menu_model_get_n_items (m) - 1); |
563 | } |
564 | } |
565 | static CtkWidget * |
566 | create_add_remove_buttons (GActionGroup *group, |
567 | GMenuModel *model, |
568 | CtkWidget *treeview) |
569 | { |
570 | CtkWidget *box; |
571 | CtkWidget *button; |
572 | |
573 | box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6); |
574 | |
575 | button = ctk_check_button_new_with_label ("Add Italic"); |
576 | ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), button); |
577 | |
578 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "group", group); |
579 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "model", model); |
580 | |
581 | g_signal_connect (button, "toggled",g_signal_connect_data ((button), ("toggled"), (((GCallback) ( toggle_italic))), (treeview), ((void*)0), (GConnectFlags) 0) |
582 | G_CALLBACK (toggle_italic), treeview)g_signal_connect_data ((button), ("toggled"), (((GCallback) ( toggle_italic))), (treeview), ((void*)0), (GConnectFlags) 0); |
583 | |
584 | button = ctk_check_button_new_with_label ("Add Sumerian"); |
585 | ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), button); |
586 | |
587 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "group", group); |
588 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "model", model); |
589 | |
590 | g_signal_connect (button, "toggled",g_signal_connect_data ((button), ("toggled"), (((GCallback) ( toggle_sumerian))), (((void*)0)), ((void*)0), (GConnectFlags) 0) |
591 | G_CALLBACK (toggle_sumerian), NULL)g_signal_connect_data ((button), ("toggled"), (((GCallback) ( toggle_sumerian))), (((void*)0)), ((void*)0), (GConnectFlags) 0); |
592 | |
593 | button = ctk_check_button_new_with_label ("Add Speed"); |
594 | ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), button); |
595 | |
596 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "group", group); |
597 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "model", model); |
598 | |
599 | g_signal_connect (button, "toggled",g_signal_connect_data ((button), ("toggled"), (((GCallback) ( toggle_speed))), (treeview), ((void*)0), (GConnectFlags) 0) |
600 | G_CALLBACK (toggle_speed), treeview)g_signal_connect_data ((button), ("toggled"), (((GCallback) ( toggle_speed))), (treeview), ((void*)0), (GConnectFlags) 0); |
601 | return box; |
602 | } |
603 | |
604 | /* main {{{1 */ |
605 | |
606 | #define BUS_NAME"org.ctk.TestMenus" "org.ctk.TestMenus" |
607 | #define OBJ_PATH"/org/ctk/TestMenus" "/org/ctk/TestMenus" |
608 | |
609 | static gboolean |
610 | on_delete_event (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
611 | CdkEvent *event G_GNUC_UNUSED__attribute__ ((__unused__)), |
612 | gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
613 | { |
614 | ctk_main_quit (); |
615 | return TRUE(!(0)); |
616 | } |
617 | |
618 | int |
619 | main (int argc, char *argv[]) |
620 | { |
621 | CtkWidget *window; |
622 | CtkWidget *box; |
623 | GMenuModel *model; |
624 | GActionGroup *group; |
625 | GDBusConnection *bus; |
626 | GError *error = NULL((void*)0); |
627 | gboolean do_export = FALSE(0); |
628 | gboolean do_import = FALSE(0); |
629 | GOptionEntry entries[] = { |
630 | { "export", 0, 0, G_OPTION_ARG_NONE, &do_export, "Export actions and menus over D-Bus", NULL((void*)0) }, |
631 | { "import", 0, 0, G_OPTION_ARG_NONE, &do_import, "Use exported actions and menus", NULL((void*)0) }, |
632 | { NULL((void*)0), } |
633 | }; |
634 | |
635 | ctk_init_with_args (&argc, &argv, NULL((void*)0), entries, NULL((void*)0), NULL((void*)0)); |
636 | |
637 | if (do_export && do_import) |
638 | { |
639 | g_error ("can't have it both ways\n"); |
640 | exit (1); |
641 | } |
642 | |
643 | window = ctk_window_new (CTK_WINDOW_TOPLEVEL); |
644 | g_signal_connect (window, "delete-event", G_CALLBACK(on_delete_event), NULL)g_signal_connect_data ((window), ("delete-event"), (((GCallback ) (on_delete_event))), (((void*)0)), ((void*)0), (GConnectFlags ) 0); |
645 | box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6); |
646 | ctk_container_add (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((window)), ((ctk_container_get_type ())))))), box); |
647 | |
648 | bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL((void*)0), NULL((void*)0)); |
649 | |
650 | if (do_import) |
651 | { |
652 | g_print ("Getting menus from the bus...\n"); |
653 | model = (GMenuModel*)g_dbus_menu_model_get (bus, BUS_NAME"org.ctk.TestMenus", OBJ_PATH"/org/ctk/TestMenus"); |
654 | g_print ("Getting actions from the bus...\n"); |
655 | group = (GActionGroup*)g_dbus_action_group_get (bus, BUS_NAME"org.ctk.TestMenus", OBJ_PATH"/org/ctk/TestMenus"); |
656 | } |
657 | else |
658 | { |
659 | CtkWidget *tv; |
660 | CtkWidget *buttons; |
661 | |
662 | group = get_group (); |
663 | model = get_model (); |
664 | |
665 | tv = create_action_treeview (group); |
666 | ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), tv); |
667 | buttons = create_add_remove_buttons (group, model, tv); |
668 | ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), buttons); |
669 | } |
670 | |
671 | if (do_export) |
672 | { |
673 | g_print ("Exporting menus on the bus...\n"); |
674 | if (!g_dbus_connection_export_menu_model (bus, OBJ_PATH"/org/ctk/TestMenus", model, &error)) |
675 | { |
676 | g_warning ("Menu export failed: %s", error->message); |
677 | exit (1); |
678 | } |
679 | g_print ("Exporting actions on the bus...\n"); |
680 | if (!g_dbus_connection_export_action_group (bus, OBJ_PATH"/org/ctk/TestMenus", group, &error)) |
681 | { |
682 | g_warning ("Action export failed: %s", error->message); |
683 | exit (1); |
684 | } |
685 | g_bus_own_name_on_connection (bus, BUS_NAME"org.ctk.TestMenus", 0, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
686 | } |
687 | else |
688 | { |
689 | CtkWidget *button; |
690 | |
691 | button = ctk_menu_button_new (); |
692 | ctk_button_set_label (CTK_BUTTON (button)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_button_get_type ())))))), "Click here"); |
693 | ctk_menu_button_set_use_popover (CTK_MENU_BUTTON (button)((((CtkMenuButton*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_menu_button_get_type ())))))), TRUE(!(0))); |
694 | ctk_menu_button_set_menu_model (CTK_MENU_BUTTON (button)((((CtkMenuButton*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_menu_button_get_type ())))))), model); |
695 | ctk_widget_insert_action_group (button, "actions", group); |
696 | ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), button); |
697 | } |
698 | |
699 | ctk_widget_show_all (window); |
700 | |
701 | ctk_main (); |
702 | |
703 | return 0; |
704 | } |
705 | |
706 | /* Epilogue {{{1 */ |
707 | /* vim:set foldmethod=marker: */ |