Bug Summary

File:ctk/ctkuimanager.c
Warning:line 718, column 7
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkuimanager.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172241-43638-1 -x c ctkuimanager.c
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#include "config.h"
30
31#include <string.h>
32#include "ctkaccellabel.h"
33#include "ctkactivatable.h"
34#include "ctkbuildable.h"
35#include "ctkimagemenuitem.h"
36#include "ctkintl.h"
37#include "ctkmarshalers.h"
38#include "ctkmenu.h"
39#include "ctkmenushellprivate.h"
40#include "ctkmenubar.h"
41#include "ctkmenutoolbutton.h"
42#include "ctkseparatormenuitem.h"
43#include "ctkseparatortoolitem.h"
44#include "ctktoolbar.h"
45#include "ctkwindow.h"
46#include "ctkprivate.h"
47
48#include "ctkuimanager.h"
49#include "ctktearoffmenuitem.h"
50
51/**
52 * SECTION:ctkuimanager
53 * @Short_description: Constructing menus and toolbars from an XML description
54 * @Title: CtkUIManager
55 * @See_also: #CtkBuilder
56 *
57 * A #CtkUIManager constructs a user interface (menus and toolbars) from
58 * one or more UI definitions, which reference actions from one or more
59 * action groups.
60 *
61 * # UI Definitions # {#XML-UI}
62 *
63 * The UI definitions are specified in an XML format which can be
64 * roughly described by the following DTD.
65 *
66 * > Do not confuse the CtkUIManager UI Definitions described here with
67 * > the similarly named [CtkBuilder UI Definitions][BUILDER-UI].
68 *
69 * |[
70 * <!ELEMENT ui (menubar|toolbar|popup|accelerator)* >
71 * <!ELEMENT menubar (menuitem|separator|placeholder|menu)* >
72 * <!ELEMENT menu (menuitem|separator|placeholder|menu)* >
73 * <!ELEMENT popup (menuitem|separator|placeholder|menu)* >
74 * <!ELEMENT toolbar (toolitem|separator|placeholder)* >
75 * <!ELEMENT placeholder (menuitem|toolitem|separator|placeholder|menu)* >
76 * <!ELEMENT menuitem EMPTY >
77 * <!ELEMENT toolitem (menu?) >
78 * <!ELEMENT separator EMPTY >
79 * <!ELEMENT accelerator EMPTY >
80 * <!ATTLIST menubar name #IMPLIED
81 * action #IMPLIED >
82 * <!ATTLIST toolbar name #IMPLIED
83 * action #IMPLIED >
84 * <!ATTLIST popup name #IMPLIED
85 * action #IMPLIED
86 * accelerators (true|false) #IMPLIED >
87 * <!ATTLIST placeholder name #IMPLIED
88 * action #IMPLIED >
89 * <!ATTLIST separator name #IMPLIED
90 * action #IMPLIED
91 * expand (true|false) #IMPLIED >
92 * <!ATTLIST menu name #IMPLIED
93 * action #REQUIRED
94 * position (top|bot) #IMPLIED >
95 * <!ATTLIST menuitem name #IMPLIED
96 * action #REQUIRED
97 * position (top|bot) #IMPLIED
98 * always-show-image (true|false) #IMPLIED >
99 * <!ATTLIST toolitem name #IMPLIED
100 * action #REQUIRED
101 * position (top|bot) #IMPLIED >
102 * <!ATTLIST accelerator name #IMPLIED
103 * action #REQUIRED >
104 * ]|
105 *
106 * There are some additional restrictions beyond those specified in the
107 * DTD, e.g. every toolitem must have a toolbar in its anchestry and
108 * every menuitem must have a menubar or popup in its anchestry. Since
109 * a #GMarkupParser is used to parse the UI description, it must not only
110 * be valid XML, but valid markup.
111 *
112 * If a name is not specified, it defaults to the action. If an action is
113 * not specified either, the element name is used. The name and action
114 * attributes must not contain “/” characters after parsing (since that
115 * would mess up path lookup) and must be usable as XML attributes when
116 * enclosed in doublequotes, thus they must not “"” characters or references
117 * to the &quot; entity.
118 *
119 * # A UI definition #
120 *
121 * |[
122 * <ui>
123 * <menubar>
124 * <menu name="FileMenu" action="FileMenuAction">
125 * <menuitem name="New" action="New2Action" />
126 * <placeholder name="FileMenuAdditions" />
127 * </menu>
128 * <menu name="JustifyMenu" action="JustifyMenuAction">
129 * <menuitem name="Left" action="justify-left"/>
130 * <menuitem name="Centre" action="justify-center"/>
131 * <menuitem name="Right" action="justify-right"/>
132 * <menuitem name="Fill" action="justify-fill"/>
133 * </menu>
134 * </menubar>
135 * <toolbar action="toolbar1">
136 * <placeholder name="JustifyToolItems">
137 * <separator/>
138 * <toolitem name="Left" action="justify-left"/>
139 * <toolitem name="Centre" action="justify-center"/>
140 * <toolitem name="Right" action="justify-right"/>
141 * <toolitem name="Fill" action="justify-fill"/>
142 * <separator/>
143 * </placeholder>
144 * </toolbar>
145 * </ui>
146 * ]|
147 *
148 * The constructed widget hierarchy is very similar to the element tree
149 * of the XML, with the exception that placeholders are merged into their
150 * parents. The correspondence of XML elements to widgets should be
151 * almost obvious:
152 *
153 * - menubar
154 *
155 * a #CtkMenuBar
156 *
157 * - toolbar
158 *
159 * a #CtkToolbar
160 *
161 * - popup
162 *
163 * a toplevel #CtkMenu
164 *
165 * - menu
166 *
167 * a #CtkMenu attached to a menuitem
168 *
169 * - menuitem
170 *
171 * a #CtkMenuItem subclass, the exact type depends on the action
172 *
173 * - toolitem
174 *
175 * a #CtkToolItem subclass, the exact type depends on the
176 * action. Note that toolitem elements may contain a menu element,
177 * but only if their associated action specifies a
178 * #CtkMenuToolButton as proxy.
179 *
180 * - separator
181 *
182 * a #CtkSeparatorMenuItem or #CtkSeparatorToolItem
183 *
184 * - accelerator
185 *
186 * a keyboard accelerator
187 *
188 * The “position” attribute determines where a constructed widget is positioned
189 * wrt. to its siblings in the partially constructed tree. If it is
190 * “top”, the widget is prepended, otherwise it is appended.
191 *
192 * # UI Merging # {#UI-Merging}
193 *
194 * The most remarkable feature of #CtkUIManager is that it can overlay a set
195 * of menuitems and toolitems over another one, and demerge them later.
196 *
197 * Merging is done based on the names of the XML elements. Each element is
198 * identified by a path which consists of the names of its anchestors, separated
199 * by slashes. For example, the menuitem named “Left” in the example above
200 * has the path `/ui/menubar/JustifyMenu/Left` and the
201 * toolitem with the same name has path
202 * `/ui/toolbar1/JustifyToolItems/Left`.
203 *
204 * # Accelerators #
205 *
206 * Every action has an accelerator path. Accelerators are installed together
207 * with menuitem proxies, but they can also be explicitly added with
208 * <accelerator> elements in the UI definition. This makes it possible to
209 * have accelerators for actions even if they have no visible proxies.
210 *
211 * # Smart Separators # {#Smart-Separators}
212 *
213 * The separators created by #CtkUIManager are “smart”, i.e. they do not show up
214 * in the UI unless they end up between two visible menu or tool items. Separators
215 * which are located at the very beginning or end of the menu or toolbar
216 * containing them, or multiple separators next to each other, are hidden. This
217 * is a useful feature, since the merging of UI elements from multiple sources
218 * can make it hard or impossible to determine in advance whether a separator
219 * will end up in such an unfortunate position.
220 *
221 * For separators in toolbars, you can set `expand="true"` to
222 * turn them from a small, visible separator to an expanding, invisible one.
223 * Toolitems following an expanding separator are effectively right-aligned.
224 *
225 * # Empty Menus
226 *
227 * Submenus pose similar problems to separators inconnection with merging. It is
228 * impossible to know in advance whether they will end up empty after merging.
229 * #CtkUIManager offers two ways to treat empty submenus:
230 *
231 * - make them disappear by hiding the menu item they’re attached to
232 *
233 * - add an insensitive “Empty” item
234 *
235 * The behaviour is chosen based on the “hide_if_empty” property of the action
236 * to which the submenu is associated.
237 *
238 * # CtkUIManager as CtkBuildable # {#CtkUIManager-BUILDER-UI}
239 *
240 * The CtkUIManager implementation of the CtkBuildable interface accepts
241 * CtkActionGroup objects as <child> elements in UI definitions.
242 *
243 * A CtkUIManager UI definition as described above can be embedded in
244 * an CtkUIManager <object> element in a CtkBuilder UI definition.
245 *
246 * The widgets that are constructed by a CtkUIManager can be embedded in
247 * other parts of the constructed user interface with the help of the
248 * “constructor” attribute. See the example below.
249 *
250 * ## An embedded CtkUIManager UI definition
251 *
252 * |[
253 * <object class="CtkUIManager" id="uiman">
254 * <child>
255 * <object class="CtkActionGroup" id="actiongroup">
256 * <child>
257 * <object class="CtkAction" id="file">
258 * <property name="label">_File</property>
259 * </object>
260 * </child>
261 * </object>
262 * </child>
263 * <ui>
264 * <menubar name="menubar1">
265 * <menu action="file">
266 * </menu>
267 * </menubar>
268 * </ui>
269 * </object>
270 * <object class="CtkWindow" id="main-window">
271 * <child>
272 * <object class="CtkMenuBar" id="menubar1" constructor="uiman"/>
273 * </child>
274 * </object>
275 * ]|
276 */
277
278typedef enum
279{
280 NODE_TYPE_UNDECIDED,
281 NODE_TYPE_ROOT,
282 NODE_TYPE_MENUBAR,
283 NODE_TYPE_MENU,
284 NODE_TYPE_TOOLBAR,
285 NODE_TYPE_MENU_PLACEHOLDER,
286 NODE_TYPE_TOOLBAR_PLACEHOLDER,
287 NODE_TYPE_POPUP,
288 NODE_TYPE_MENUITEM,
289 NODE_TYPE_TOOLITEM,
290 NODE_TYPE_SEPARATOR,
291 NODE_TYPE_ACCELERATOR
292} NodeType;
293
294typedef struct _Node Node;
295
296struct _Node {
297 NodeType type;
298
299 gchar *name;
300
301 GQuark action_name;
302 CtkAction *action;
303 CtkWidget *proxy;
304 CtkWidget *extra; /* second separator for placeholders */
305
306 GList *uifiles;
307
308 guint dirty : 1;
309 guint expand : 1; /* used for separators */
310 guint popup_accels : 1;
311 guint always_show_image_set : 1; /* used for menu items */
312 guint always_show_image : 1; /* used for menu items */
313};
314
315
316struct _CtkUIManagerPrivate
317{
318 CtkAccelGroup *accel_group;
319
320 GNode *root_node;
321 GList *action_groups;
322
323 guint last_merge_id;
324
325 guint update_tag;
326
327 gboolean add_tearoffs;
328};
329
330#define NODE_INFO(node)((Node *)node->data) ((Node *)node->data)
331
332typedef struct _NodeUIReference NodeUIReference;
333
334struct _NodeUIReference
335{
336 guint merge_id;
337 GQuark action_quark;
338};
339
340static void ctk_ui_manager_finalize (GObject *object);
341static void ctk_ui_manager_set_property (GObject *object,
342 guint prop_id,
343 const GValue *value,
344 GParamSpec *pspec);
345static void ctk_ui_manager_get_property (GObject *object,
346 guint prop_id,
347 GValue *value,
348 GParamSpec *pspec);
349static CtkWidget * ctk_ui_manager_real_get_widget (CtkUIManager *manager,
350 const gchar *path);
351static CtkAction * ctk_ui_manager_real_get_action (CtkUIManager *manager,
352 const gchar *path);
353static void queue_update (CtkUIManager *manager);
354static void dirty_all_nodes (CtkUIManager *manager);
355static void mark_node_dirty (GNode *node);
356static GNode * get_child_node (CtkUIManager *manager,
357 GNode *parent,
358 GNode *sibling,
359 const gchar *childname,
360 gint childname_length,
361 NodeType node_type,
362 gboolean create,
363 gboolean top);
364static GNode * get_node (CtkUIManager *manager,
365 const gchar *path,
366 NodeType node_type,
367 gboolean create);
368static gboolean free_node (GNode *node);
369static void node_prepend_ui_reference (GNode *node,
370 guint merge_id,
371 GQuark action_quark);
372static void node_remove_ui_reference (GNode *node,
373 guint merge_id);
374
375/* CtkBuildable */
376static void ctk_ui_manager_buildable_init (CtkBuildableIface *iface);
377static void ctk_ui_manager_buildable_add_child (CtkBuildable *buildable,
378 CtkBuilder *builder,
379 GObject *child,
380 const gchar *type);
381static GObject* ctk_ui_manager_buildable_construct_child (CtkBuildable *buildable,
382 CtkBuilder *builder,
383 const gchar *name);
384static gboolean ctk_ui_manager_buildable_custom_tag_start (CtkBuildable *buildable,
385 CtkBuilder *builder,
386 GObject *child,
387 const gchar *tagname,
388 GMarkupParser *parser,
389 gpointer *data);
390static void ctk_ui_manager_buildable_custom_tag_end (CtkBuildable *buildable,
391 CtkBuilder *builder,
392 GObject *child,
393 const gchar *tagname,
394 gpointer *data);
395static void ctk_ui_manager_do_set_add_tearoffs (CtkUIManager *manager,
396 gboolean add_tearoffs);
397
398
399
400enum
401{
402 ADD_WIDGET,
403 ACTIONS_CHANGED,
404 CONNECT_PROXY,
405 DISCONNECT_PROXY,
406 PRE_ACTIVATE,
407 POST_ACTIVATE,
408 LAST_SIGNAL
409};
410
411enum
412{
413 PROP_0,
414 PROP_ADD_TEAROFFS,
415 PROP_UI
416};
417
418static guint ui_manager_signals[LAST_SIGNAL] = { 0 };
419
420G_DEFINE_TYPE_WITH_CODE (CtkUIManager, ctk_ui_manager, G_TYPE_OBJECT,static void ctk_ui_manager_init (CtkUIManager *self); static void
ctk_ui_manager_class_init (CtkUIManagerClass *klass); static
GType ctk_ui_manager_get_type_once (void); static gpointer ctk_ui_manager_parent_class
= ((void*)0); static gint CtkUIManager_private_offset; static
void ctk_ui_manager_class_intern_init (gpointer klass) { ctk_ui_manager_parent_class
= g_type_class_peek_parent (klass); if (CtkUIManager_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkUIManager_private_offset
); ctk_ui_manager_class_init ((CtkUIManagerClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_ui_manager_get_instance_private
(CtkUIManager *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkUIManager_private_offset)))); } GType ctk_ui_manager_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_ui_manager_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_ui_manager_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CtkUIManager"
), sizeof (CtkUIManagerClass), (GClassInitFunc)(void (*)(void
)) ctk_ui_manager_class_intern_init, sizeof (CtkUIManager), (
GInstanceInitFunc)(void (*)(void)) ctk_ui_manager_init, (GTypeFlags
) 0); { {{ CtkUIManager_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkUIManagerPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_ui_manager_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
; }
421 G_ADD_PRIVATE (CtkUIManager)static void ctk_ui_manager_init (CtkUIManager *self); static void
ctk_ui_manager_class_init (CtkUIManagerClass *klass); static
GType ctk_ui_manager_get_type_once (void); static gpointer ctk_ui_manager_parent_class
= ((void*)0); static gint CtkUIManager_private_offset; static
void ctk_ui_manager_class_intern_init (gpointer klass) { ctk_ui_manager_parent_class
= g_type_class_peek_parent (klass); if (CtkUIManager_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkUIManager_private_offset
); ctk_ui_manager_class_init ((CtkUIManagerClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_ui_manager_get_instance_private
(CtkUIManager *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkUIManager_private_offset)))); } GType ctk_ui_manager_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_ui_manager_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_ui_manager_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CtkUIManager"
), sizeof (CtkUIManagerClass), (GClassInitFunc)(void (*)(void
)) ctk_ui_manager_class_intern_init, sizeof (CtkUIManager), (
GInstanceInitFunc)(void (*)(void)) ctk_ui_manager_init, (GTypeFlags
) 0); { {{ CtkUIManager_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkUIManagerPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_ui_manager_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
; }
422 G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_ui_manager_init (CtkUIManager *self); static void
ctk_ui_manager_class_init (CtkUIManagerClass *klass); static
GType ctk_ui_manager_get_type_once (void); static gpointer ctk_ui_manager_parent_class
= ((void*)0); static gint CtkUIManager_private_offset; static
void ctk_ui_manager_class_intern_init (gpointer klass) { ctk_ui_manager_parent_class
= g_type_class_peek_parent (klass); if (CtkUIManager_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkUIManager_private_offset
); ctk_ui_manager_class_init ((CtkUIManagerClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_ui_manager_get_instance_private
(CtkUIManager *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkUIManager_private_offset)))); } GType ctk_ui_manager_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_ui_manager_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_ui_manager_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CtkUIManager"
), sizeof (CtkUIManagerClass), (GClassInitFunc)(void (*)(void
)) ctk_ui_manager_class_intern_init, sizeof (CtkUIManager), (
GInstanceInitFunc)(void (*)(void)) ctk_ui_manager_init, (GTypeFlags
) 0); { {{ CtkUIManager_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkUIManagerPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_ui_manager_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
; }
423 ctk_ui_manager_buildable_init))static void ctk_ui_manager_init (CtkUIManager *self); static void
ctk_ui_manager_class_init (CtkUIManagerClass *klass); static
GType ctk_ui_manager_get_type_once (void); static gpointer ctk_ui_manager_parent_class
= ((void*)0); static gint CtkUIManager_private_offset; static
void ctk_ui_manager_class_intern_init (gpointer klass) { ctk_ui_manager_parent_class
= g_type_class_peek_parent (klass); if (CtkUIManager_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkUIManager_private_offset
); ctk_ui_manager_class_init ((CtkUIManagerClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_ui_manager_get_instance_private
(CtkUIManager *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkUIManager_private_offset)))); } GType ctk_ui_manager_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_ui_manager_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_ui_manager_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CtkUIManager"
), sizeof (CtkUIManagerClass), (GClassInitFunc)(void (*)(void
)) ctk_ui_manager_class_intern_init, sizeof (CtkUIManager), (
GInstanceInitFunc)(void (*)(void)) ctk_ui_manager_init, (GTypeFlags
) 0); { {{ CtkUIManager_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkUIManagerPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_ui_manager_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
; }
424
425static void
426ctk_ui_manager_class_init (CtkUIManagerClass *klass)
427{
428 GObjectClass *gobject_class;
429
430 gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
431
432 gobject_class->finalize = ctk_ui_manager_finalize;
433 gobject_class->set_property = ctk_ui_manager_set_property;
434 gobject_class->get_property = ctk_ui_manager_get_property;
435 klass->get_widget = ctk_ui_manager_real_get_widget;
436 klass->get_action = ctk_ui_manager_real_get_action;
437
438 /**
439 * CtkUIManager:add-tearoffs:
440 *
441 * The "add-tearoffs" property controls whether generated menus
442 * have tearoff menu items.
443 *
444 * Note that this only affects regular menus. Generated popup
445 * menus never have tearoff menu items.
446 *
447 * Since: 2.4
448 */
449 g_object_class_install_property (gobject_class,
450 PROP_ADD_TEAROFFS,
451 g_param_spec_boolean ("add-tearoffs",
452 P_("Add tearoffs to menus")g_dgettext("ctk30" "-properties","Add tearoffs to menus"),
453 P_("Whether tearoff menu items should be added to menus")g_dgettext("ctk30" "-properties","Whether tearoff menu items should be added to menus"
)
,
454 FALSE(0),
455 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
456
457 g_object_class_install_property (gobject_class,
458 PROP_UI,
459 g_param_spec_string ("ui",
460 P_("Merged UI definition")g_dgettext("ctk30" "-properties","Merged UI definition"),
461 P_("An XML string describing the merged UI")g_dgettext("ctk30" "-properties","An XML string describing the merged UI"
)
,
462 "<ui>\n</ui>\n",
463 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
464
465
466 /**
467 * CtkUIManager::add-widget:
468 * @manager: a #CtkUIManager
469 * @widget: the added widget
470 *
471 * The ::add-widget signal is emitted for each generated menubar and toolbar.
472 * It is not emitted for generated popup menus, which can be obtained by
473 * ctk_ui_manager_get_widget().
474 *
475 * Since: 2.4
476 */
477 ui_manager_signals[ADD_WIDGET] =
478 g_signal_new (I_("add-widget")g_intern_static_string ("add-widget"),
479 G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)),
480 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
481 G_STRUCT_OFFSET (CtkUIManagerClass, add_widget)((glong) __builtin_offsetof(CtkUIManagerClass, add_widget)),
482 NULL((void*)0), NULL((void*)0),
483 NULL((void*)0),
484 G_TYPE_NONE((GType) ((1) << (2))), 1,
485 CTK_TYPE_WIDGET(ctk_widget_get_type ()));
486
487 /**
488 * CtkUIManager::actions-changed:
489 * @manager: a #CtkUIManager
490 *
491 * The ::actions-changed signal is emitted whenever the set of actions
492 * changes.
493 *
494 * Since: 2.4
495 */
496 ui_manager_signals[ACTIONS_CHANGED] =
497 g_signal_new (I_("actions-changed")g_intern_static_string ("actions-changed"),
498 G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)),
499 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
500 G_STRUCT_OFFSET (CtkUIManagerClass, actions_changed)((glong) __builtin_offsetof(CtkUIManagerClass, actions_changed
))
,
501 NULL((void*)0), NULL((void*)0),
502 NULL((void*)0),
503 G_TYPE_NONE((GType) ((1) << (2))), 0);
504
505 /**
506 * CtkUIManager::connect-proxy:
507 * @manager: the ui manager
508 * @action: the action
509 * @proxy: the proxy
510 *
511 * The ::connect-proxy signal is emitted after connecting a proxy to
512 * an action in the group.
513 *
514 * This is intended for simple customizations for which a custom action
515 * class would be too clumsy, e.g. showing tooltips for menuitems in the
516 * statusbar.
517 *
518 * Since: 2.4
519 */
520 ui_manager_signals[CONNECT_PROXY] =
521 g_signal_new (I_("connect-proxy")g_intern_static_string ("connect-proxy"),
522 G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)),
523 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
524 G_STRUCT_OFFSET (CtkUIManagerClass, connect_proxy)((glong) __builtin_offsetof(CtkUIManagerClass, connect_proxy)
)
,
525 NULL((void*)0), NULL((void*)0),
526 _ctk_marshal_VOID__OBJECT_OBJECT,
527 G_TYPE_NONE((GType) ((1) << (2))), 2,
528 CTK_TYPE_ACTION(ctk_action_get_type ()),
529 CTK_TYPE_WIDGET(ctk_widget_get_type ()));
530
531 /**
532 * CtkUIManager::disconnect-proxy:
533 * @manager: the ui manager
534 * @action: the action
535 * @proxy: the proxy
536 *
537 * The ::disconnect-proxy signal is emitted after disconnecting a proxy
538 * from an action in the group.
539 *
540 * Since: 2.4
541 */
542 ui_manager_signals[DISCONNECT_PROXY] =
543 g_signal_new (I_("disconnect-proxy")g_intern_static_string ("disconnect-proxy"),
544 G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)),
545 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
546 G_STRUCT_OFFSET (CtkUIManagerClass, disconnect_proxy)((glong) __builtin_offsetof(CtkUIManagerClass, disconnect_proxy
))
,
547 NULL((void*)0), NULL((void*)0),
548 _ctk_marshal_VOID__OBJECT_OBJECT,
549 G_TYPE_NONE((GType) ((1) << (2))), 2,
550 CTK_TYPE_ACTION(ctk_action_get_type ()),
551 CTK_TYPE_WIDGET(ctk_widget_get_type ()));
552
553 /**
554 * CtkUIManager::pre-activate:
555 * @manager: the ui manager
556 * @action: the action
557 *
558 * The ::pre-activate signal is emitted just before the @action
559 * is activated.
560 *
561 * This is intended for applications to get notification
562 * just before any action is activated.
563 *
564 * Since: 2.4
565 */
566 ui_manager_signals[PRE_ACTIVATE] =
567 g_signal_new (I_("pre-activate")g_intern_static_string ("pre-activate"),
568 G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)),
569 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
570 G_STRUCT_OFFSET (CtkUIManagerClass, pre_activate)((glong) __builtin_offsetof(CtkUIManagerClass, pre_activate)),
571 NULL((void*)0), NULL((void*)0),
572 NULL((void*)0),
573 G_TYPE_NONE((GType) ((1) << (2))), 1,
574 CTK_TYPE_ACTION(ctk_action_get_type ()));
575
576 /**
577 * CtkUIManager::post-activate:
578 * @manager: the ui manager
579 * @action: the action
580 *
581 * The ::post-activate signal is emitted just after the @action
582 * is activated.
583 *
584 * This is intended for applications to get notification
585 * just after any action is activated.
586 *
587 * Since: 2.4
588 */
589 ui_manager_signals[POST_ACTIVATE] =
590 g_signal_new (I_("post-activate")g_intern_static_string ("post-activate"),
591 G_OBJECT_CLASS_TYPE (klass)((((GTypeClass*) (klass))->g_type)),
592 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
593 G_STRUCT_OFFSET (CtkUIManagerClass, post_activate)((glong) __builtin_offsetof(CtkUIManagerClass, post_activate)
)
,
594 NULL((void*)0), NULL((void*)0),
595 NULL((void*)0),
596 G_TYPE_NONE((GType) ((1) << (2))), 1,
597 CTK_TYPE_ACTION(ctk_action_get_type ()));
598
599 klass->add_widget = NULL((void*)0);
600 klass->actions_changed = NULL((void*)0);
601 klass->connect_proxy = NULL((void*)0);
602 klass->disconnect_proxy = NULL((void*)0);
603 klass->pre_activate = NULL((void*)0);
604 klass->post_activate = NULL((void*)0);
605}
606
607static void
608ctk_ui_manager_init (CtkUIManager *manager)
609{
610 guint merge_id;
611 GNode *node;
612
613 manager->private_data = ctk_ui_manager_get_instance_private (manager);
614
615 manager->private_data->accel_group = ctk_accel_group_new ();
616
617 manager->private_data->root_node = NULL((void*)0);
618 manager->private_data->action_groups = NULL((void*)0);
619
620 manager->private_data->last_merge_id = 0;
621 manager->private_data->add_tearoffs = FALSE(0);
622
623 merge_id = ctk_ui_manager_new_merge_id (manager);
624 node = get_child_node (manager, NULL((void*)0), NULL((void*)0), "ui", 2,
625 NODE_TYPE_ROOT, TRUE(!(0)), FALSE(0));
626 node_prepend_ui_reference (node, merge_id, 0);
627}
628
629static void
630ctk_ui_manager_finalize (GObject *object)
631{
632 CtkUIManager *manager = CTK_UI_MANAGER (object)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_ui_manager_get_type ()))))))
;
633
634 if (manager->private_data->update_tag != 0)
635 {
636 g_source_remove (manager->private_data->update_tag);
637 manager->private_data->update_tag = 0;
638 }
639
640 g_node_traverse (manager->private_data->root_node,
641 G_POST_ORDER, G_TRAVERSE_ALL, -1,
642 (GNodeTraverseFunc)free_node, NULL((void*)0));
643 g_node_destroy (manager->private_data->root_node);
644 manager->private_data->root_node = NULL((void*)0);
645
646 g_list_free_full (manager->private_data->action_groups, g_object_unref);
647 manager->private_data->action_groups = NULL((void*)0);
648
649 g_object_unref (manager->private_data->accel_group);
650 manager->private_data->accel_group = NULL((void*)0);
651
652 G_OBJECT_CLASS (ctk_ui_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_ui_manager_parent_class)), (((GType) ((20) << (
2))))))))
->finalize (object);
653}
654
655static void
656ctk_ui_manager_buildable_init (CtkBuildableIface *iface)
657{
658 iface->add_child = ctk_ui_manager_buildable_add_child;
659 iface->construct_child = ctk_ui_manager_buildable_construct_child;
660 iface->custom_tag_start = ctk_ui_manager_buildable_custom_tag_start;
661 iface->custom_tag_end = ctk_ui_manager_buildable_custom_tag_end;
662}
663
664static void
665ctk_ui_manager_buildable_add_child (CtkBuildable *buildable,
666 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
667 GObject *child,
668 const gchar *type G_GNUC_UNUSED__attribute__ ((__unused__)))
669{
670 CtkUIManager *manager = CTK_UI_MANAGER (buildable)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_ui_manager_get_type ()))))))
;
671 guint pos;
672
673 g_return_if_fail (CTK_IS_ACTION_GROUP (child))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((child)); 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 (child)"); return; } } while (0)
;
674
675 pos = g_list_length (manager->private_data->action_groups);
676
677 ctk_ui_manager_insert_action_group (manager,
678 CTK_ACTION_GROUP (child)((((CtkActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_action_group_get_type ()))))))
,
679 pos);
680}
681
682static void
683child_hierarchy_changed_cb (CtkWidget *widget,
684 CtkWidget *unused G_GNUC_UNUSED__attribute__ ((__unused__)),
685 CtkUIManager *uimgr)
686{
687 CtkWidget *toplevel;
688 CtkAccelGroup *group;
689 GSList *groups;
690
691 toplevel = ctk_widget_get_toplevel (widget);
692 if (!toplevel || !CTK_IS_WINDOW (toplevel)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(toplevel)); GType __t = ((ctk_window_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; }))))
)
693 return;
694
695 group = ctk_ui_manager_get_accel_group (uimgr);
696 groups = ctk_accel_groups_from_object (G_OBJECT (toplevel)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), (((GType) ((20) << (2))))))))
);
697 if (g_slist_find (groups, group) == NULL((void*)0))
698 ctk_window_add_accel_group (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_window_get_type ()))))))
, group);
699
700 g_signal_handlers_disconnect_by_func (widget,g_signal_handlers_disconnect_matched ((widget), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (child_hierarchy_changed_cb), (uimgr))
701 child_hierarchy_changed_cb,g_signal_handlers_disconnect_matched ((widget), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (child_hierarchy_changed_cb), (uimgr))
702 uimgr)g_signal_handlers_disconnect_matched ((widget), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (child_hierarchy_changed_cb), (uimgr))
;
703}
704
705static GObject *
706ctk_ui_manager_buildable_construct_child (CtkBuildable *buildable,
707 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
708 const gchar *id)
709{
710 CtkWidget *widget;
711 char *name;
712
713 name = g_strdup_printf ("ui/%s", id);
714 widget = ctk_ui_manager_get_widget (CTK_UI_MANAGER (buildable)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_ui_manager_get_type ()))))))
, name);
715 if (!widget)
716 {
717 g_error ("Unknown ui manager child: %s", name);
718 g_free (name);
This statement is never executed
719 return NULL((void*)0);
720 }
721 g_free (name);
722
723 g_signal_connect (widget, "hierarchy-changed",g_signal_connect_data ((widget), ("hierarchy-changed"), (((GCallback
) (child_hierarchy_changed_cb))), (((((CtkUIManager*) (void *
) g_type_check_instance_cast ((GTypeInstance*) ((buildable)),
((ctk_ui_manager_get_type ()))))))), ((void*)0), (GConnectFlags
) 0)
724 G_CALLBACK (child_hierarchy_changed_cb),g_signal_connect_data ((widget), ("hierarchy-changed"), (((GCallback
) (child_hierarchy_changed_cb))), (((((CtkUIManager*) (void *
) g_type_check_instance_cast ((GTypeInstance*) ((buildable)),
((ctk_ui_manager_get_type ()))))))), ((void*)0), (GConnectFlags
) 0)
725 CTK_UI_MANAGER (buildable))g_signal_connect_data ((widget), ("hierarchy-changed"), (((GCallback
) (child_hierarchy_changed_cb))), (((((CtkUIManager*) (void *
) g_type_check_instance_cast ((GTypeInstance*) ((buildable)),
((ctk_ui_manager_get_type ()))))))), ((void*)0), (GConnectFlags
) 0)
;
726 return G_OBJECT (g_object_ref (widget))((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((((__typeof__ (widget)) (g_object_ref) (widget)))), (((GType
) ((20) << (2))))))))
;
727}
728
729static void
730ctk_ui_manager_set_property (GObject *object,
731 guint prop_id,
732 const GValue *value,
733 GParamSpec *pspec)
734{
735 CtkUIManager *manager = CTK_UI_MANAGER (object)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_ui_manager_get_type ()))))))
;
736
737 switch (prop_id)
738 {
739 case PROP_ADD_TEAROFFS:
740 ctk_ui_manager_do_set_add_tearoffs (manager, g_value_get_boolean (value));
741 break;
742 default:
743 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'"
, "ctkuimanager.c", 743, ("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)
;
744 break;
745 }
746}
747
748static void
749ctk_ui_manager_get_property (GObject *object,
750 guint prop_id,
751 GValue *value,
752 GParamSpec *pspec)
753{
754 CtkUIManager *manager = CTK_UI_MANAGER (object)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_ui_manager_get_type ()))))))
;
755
756 switch (prop_id)
757 {
758 case PROP_ADD_TEAROFFS:
759 g_value_set_boolean (value, manager->private_data->add_tearoffs);
760 break;
761 case PROP_UI:
762 g_value_take_string (value, ctk_ui_manager_get_ui (manager));
763 break;
764 default:
765 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'"
, "ctkuimanager.c", 765, ("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)
;
766 break;
767 }
768}
769
770static CtkWidget *
771ctk_ui_manager_real_get_widget (CtkUIManager *manager,
772 const gchar *path)
773{
774 GNode *node;
775
776 /* ensure that there are no pending updates before we get the
777 * widget */
778 ctk_ui_manager_ensure_update (manager);
779
780 node = get_node (manager, path, NODE_TYPE_UNDECIDED, FALSE(0));
781
782 if (node == NULL((void*)0))
783 return NULL((void*)0);
784
785 return NODE_INFO (node)((Node *)node->data)->proxy;
786}
787
788static CtkAction *
789ctk_ui_manager_real_get_action (CtkUIManager *manager,
790 const gchar *path)
791{
792 GNode *node;
793
794 /* ensure that there are no pending updates before we get
795 * the action */
796 ctk_ui_manager_ensure_update (manager);
797
798 node = get_node (manager, path, NODE_TYPE_UNDECIDED, FALSE(0));
799
800 if (node == NULL((void*)0))
801 return NULL((void*)0);
802
803 return NODE_INFO (node)((Node *)node->data)->action;
804}
805
806
807/**
808 * ctk_ui_manager_new:
809 *
810 * Creates a new ui manager object.
811 *
812 * Returns: a new ui manager object.
813 *
814 * Since: 2.4
815 **/
816CtkUIManager*
817ctk_ui_manager_new (void)
818{
819 return g_object_new (CTK_TYPE_UI_MANAGER(ctk_ui_manager_get_type ()), NULL((void*)0));
820}
821
822
823/**
824 * ctk_ui_manager_get_add_tearoffs:
825 * @manager: a #CtkUIManager
826 *
827 * Returns whether menus generated by this #CtkUIManager
828 * will have tearoff menu items.
829 *
830 * Returns: whether tearoff menu items are added
831 *
832 * Since: 2.4
833 **/
834gboolean
835ctk_ui_manager_get_add_tearoffs (CtkUIManager *manager)
836{
837 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return ((0)); } } while (
0)
;
838
839 return manager->private_data->add_tearoffs;
840}
841
842
843/**
844 * ctk_ui_manager_set_add_tearoffs:
845 * @manager: a #CtkUIManager
846 * @add_tearoffs: whether tearoff menu items are added
847 *
848 * Sets the “add_tearoffs” property, which controls whether menus
849 * generated by this #CtkUIManager will have tearoff menu items.
850 *
851 * Note that this only affects regular menus. Generated popup
852 * menus never have tearoff menu items.
853 *
854 * Since: 2.4
855 **/
856void
857ctk_ui_manager_set_add_tearoffs (CtkUIManager *manager,
858 gboolean add_tearoffs)
859{
860 g_return_if_fail (CTK_IS_UI_MANAGER (manager))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return; } } while (0)
;
861
862 ctk_ui_manager_do_set_add_tearoffs (manager, add_tearoffs);
863}
864
865static void
866ctk_ui_manager_do_set_add_tearoffs (CtkUIManager *manager,
867 gboolean add_tearoffs)
868{
869 add_tearoffs = add_tearoffs != FALSE(0);
870
871 if (add_tearoffs != manager->private_data->add_tearoffs)
872 {
873 manager->private_data->add_tearoffs = add_tearoffs;
874
875 dirty_all_nodes (manager);
876
877 g_object_notify (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
, "add-tearoffs");
878 }
879}
880
881static void
882cb_proxy_connect_proxy (CtkActionGroup *group G_GNUC_UNUSED__attribute__ ((__unused__)),
883 CtkAction *action,
884 CtkWidget *proxy,
885 CtkUIManager *manager)
886{
887 g_signal_emit (manager, ui_manager_signals[CONNECT_PROXY], 0, action, proxy);
888}
889
890static void
891cb_proxy_disconnect_proxy (CtkActionGroup *group G_GNUC_UNUSED__attribute__ ((__unused__)),
892 CtkAction *action,
893 CtkWidget *proxy,
894 CtkUIManager *manager)
895{
896 g_signal_emit (manager, ui_manager_signals[DISCONNECT_PROXY], 0, action, proxy);
897}
898
899static void
900cb_proxy_pre_activate (CtkActionGroup *group G_GNUC_UNUSED__attribute__ ((__unused__)),
901 CtkAction *action,
902 CtkUIManager *manager)
903{
904 g_signal_emit (manager, ui_manager_signals[PRE_ACTIVATE], 0, action);
905}
906
907static void
908cb_proxy_post_activate (CtkActionGroup *group G_GNUC_UNUSED__attribute__ ((__unused__)),
909 CtkAction *action,
910 CtkUIManager *manager)
911{
912 g_signal_emit (manager, ui_manager_signals[POST_ACTIVATE], 0, action);
913}
914
915/**
916 * ctk_ui_manager_insert_action_group:
917 * @manager: a #CtkUIManager object
918 * @action_group: the action group to be inserted
919 * @pos: the position at which the group will be inserted.
920 *
921 * Inserts an action group into the list of action groups associated
922 * with @manager. Actions in earlier groups hide actions with the same
923 * name in later groups.
924 *
925 * If @pos is larger than the number of action groups in @manager, or
926 * negative, @action_group will be inserted at the end of the internal
927 * list.
928 *
929 * Since: 2.4
930 **/
931void
932ctk_ui_manager_insert_action_group (CtkUIManager *manager,
933 CtkActionGroup *action_group,
934 gint pos)
935{
936#ifdef G_ENABLE_DEBUG1
937 GList *l;
938 const char *group_name;
939#endif
940
941 g_return_if_fail (CTK_IS_UI_MANAGER (manager))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return; } } while (0)
;
942 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)
;
943 g_return_if_fail (g_list_find (manager->private_data->action_groups,do { if ((g_list_find (manager->private_data->action_groups
, action_group) == ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "g_list_find (manager->private_data->action_groups, action_group) == NULL"
); return; } } while (0)
944 action_group) == NULL)do { if ((g_list_find (manager->private_data->action_groups
, action_group) == ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "g_list_find (manager->private_data->action_groups, action_group) == NULL"
); return; } } while (0)
;
945
946#ifdef G_ENABLE_DEBUG1
947 group_name = ctk_action_group_get_name (action_group);
948
949 for (l = manager->private_data->action_groups; l; l = l->next)
950 {
951 CtkActionGroup *group = l->data;
952
953 if (strcmp (ctk_action_group_get_name (group), group_name) == 0)
954 {
955 g_warning ("Inserting action group '%s' into UI manager which "
956 "already has a group with this name", group_name);
957 break;
958 }
959 }
960#endif /* G_ENABLE_DEBUG */
961
962 g_object_ref (action_group)((__typeof__ (action_group)) (g_object_ref) (action_group));
963 manager->private_data->action_groups =
964 g_list_insert (manager->private_data->action_groups, action_group, pos);
965 g_object_connect (action_group,
966 "object-signal::connect-proxy", G_CALLBACK (cb_proxy_connect_proxy)((GCallback) (cb_proxy_connect_proxy)), manager,
967 "object-signal::disconnect-proxy", G_CALLBACK (cb_proxy_disconnect_proxy)((GCallback) (cb_proxy_disconnect_proxy)), manager,
968 "object-signal::pre-activate", G_CALLBACK (cb_proxy_pre_activate)((GCallback) (cb_proxy_pre_activate)), manager,
969 "object-signal::post-activate", G_CALLBACK (cb_proxy_post_activate)((GCallback) (cb_proxy_post_activate)), manager,
970 NULL((void*)0));
971
972 /* dirty all nodes, as action bindings may change */
973 dirty_all_nodes (manager);
974
975 g_signal_emit (manager, ui_manager_signals[ACTIONS_CHANGED], 0);
976}
977
978/**
979 * ctk_ui_manager_remove_action_group:
980 * @manager: a #CtkUIManager object
981 * @action_group: the action group to be removed
982 *
983 * Removes an action group from the list of action groups associated
984 * with @manager.
985 *
986 * Since: 2.4
987 **/
988void
989ctk_ui_manager_remove_action_group (CtkUIManager *manager,
990 CtkActionGroup *action_group)
991{
992 g_return_if_fail (CTK_IS_UI_MANAGER (manager))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return; } } while (0)
;
993 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)
;
994 g_return_if_fail (g_list_find (manager->private_data->action_groups,do { if ((g_list_find (manager->private_data->action_groups
, action_group) != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "g_list_find (manager->private_data->action_groups, action_group) != NULL"
); return; } } while (0)
995 action_group) != NULL)do { if ((g_list_find (manager->private_data->action_groups
, action_group) != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "g_list_find (manager->private_data->action_groups, action_group) != NULL"
); return; } } while (0)
;
996
997 manager->private_data->action_groups =
998 g_list_remove (manager->private_data->action_groups, action_group);
999
1000 g_object_disconnect (action_group,
1001 "any-signal::connect-proxy", G_CALLBACK (cb_proxy_connect_proxy)((GCallback) (cb_proxy_connect_proxy)), manager,
1002 "any-signal::disconnect-proxy", G_CALLBACK (cb_proxy_disconnect_proxy)((GCallback) (cb_proxy_disconnect_proxy)), manager,
1003 "any-signal::pre-activate", G_CALLBACK (cb_proxy_pre_activate)((GCallback) (cb_proxy_pre_activate)), manager,
1004 "any-signal::post-activate", G_CALLBACK (cb_proxy_post_activate)((GCallback) (cb_proxy_post_activate)), manager,
1005 NULL((void*)0));
1006 g_object_unref (action_group);
1007
1008 /* dirty all nodes, as action bindings may change */
1009 dirty_all_nodes (manager);
1010
1011 g_signal_emit (manager, ui_manager_signals[ACTIONS_CHANGED], 0);
1012}
1013
1014/**
1015 * ctk_ui_manager_get_action_groups:
1016 * @manager: a #CtkUIManager object
1017 *
1018 * Returns the list of action groups associated with @manager.
1019 *
1020 * Returns: (element-type CtkActionGroup) (transfer none): a #GList of
1021 * action groups. The list is owned by CTK+
1022 * and should not be modified.
1023 *
1024 * Since: 2.4
1025 **/
1026GList *
1027ctk_ui_manager_get_action_groups (CtkUIManager *manager)
1028{
1029 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (((void*)0)); } } while
(0)
;
1030
1031 return manager->private_data->action_groups;
1032}
1033
1034/**
1035 * ctk_ui_manager_get_accel_group:
1036 * @manager: a #CtkUIManager object
1037 *
1038 * Returns the #CtkAccelGroup associated with @manager.
1039 *
1040 * Returns: (transfer none): the #CtkAccelGroup.
1041 *
1042 * Since: 2.4
1043 **/
1044CtkAccelGroup *
1045ctk_ui_manager_get_accel_group (CtkUIManager *manager)
1046{
1047 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (((void*)0)); } } while
(0)
;
1048
1049 return manager->private_data->accel_group;
1050}
1051
1052/**
1053 * ctk_ui_manager_get_widget:
1054 * @manager: a #CtkUIManager
1055 * @path: a path
1056 *
1057 * Looks up a widget by following a path.
1058 * The path consists of the names specified in the XML description of the UI.
1059 * separated by “/”. Elements which don’t have a name or action attribute in
1060 * the XML (e.g. <popup>) can be addressed by their XML element name
1061 * (e.g. "popup"). The root element ("/ui") can be omitted in the path.
1062 *
1063 * Note that the widget found by following a path that ends in a <menu>;
1064 * element is the menuitem to which the menu is attached, not the menu it
1065 * manages.
1066 *
1067 * Also note that the widgets constructed by a ui manager are not tied to
1068 * the lifecycle of the ui manager. If you add the widgets returned by this
1069 * function to some container or explicitly ref them, they will survive the
1070 * destruction of the ui manager.
1071 *
1072 * Returns: (transfer none): the widget found by following the path,
1073 * or %NULL if no widget was found
1074 *
1075 * Since: 2.4
1076 **/
1077CtkWidget *
1078ctk_ui_manager_get_widget (CtkUIManager *manager,
1079 const gchar *path)
1080{
1081 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (((void*)0)); } } while
(0)
;
1082 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
1083
1084 return CTK_UI_MANAGER_GET_CLASS (manager)((((CtkUIManagerClass*) (((GTypeInstance*) ((manager)))->g_class
))))
->get_widget (manager, path);
1085}
1086
1087typedef struct {
1088 CtkUIManagerItemType types;
1089 GSList *list;
1090} ToplevelData;
1091
1092static void
1093collect_toplevels (GNode *node,
1094 gpointer user_data)
1095{
1096 ToplevelData *data = user_data;
1097
1098 if (NODE_INFO (node)((Node *)node->data)->proxy)
1099 {
1100 switch (NODE_INFO (node)((Node *)node->data)->type)
1101 {
1102 case NODE_TYPE_MENUBAR:
1103 if (data->types & CTK_UI_MANAGER_MENUBAR)
1104 data->list = g_slist_prepend (data->list, NODE_INFO (node)((Node *)node->data)->proxy);
1105 break;
1106 case NODE_TYPE_TOOLBAR:
1107 if (data->types & CTK_UI_MANAGER_TOOLBAR)
1108 data->list = g_slist_prepend (data->list, NODE_INFO (node)((Node *)node->data)->proxy);
1109 break;
1110 case NODE_TYPE_POPUP:
1111 if (data->types & CTK_UI_MANAGER_POPUP)
1112 data->list = g_slist_prepend (data->list, NODE_INFO (node)((Node *)node->data)->proxy);
1113 break;
1114 default: ;
1115 }
1116 }
1117}
1118
1119/**
1120 * ctk_ui_manager_get_toplevels:
1121 * @manager: a #CtkUIManager
1122 * @types: specifies the types of toplevel widgets to include. Allowed
1123 * types are #CTK_UI_MANAGER_MENUBAR, #CTK_UI_MANAGER_TOOLBAR and
1124 * #CTK_UI_MANAGER_POPUP.
1125 *
1126 * Obtains a list of all toplevel widgets of the requested types.
1127 *
1128 * Returns: (element-type CtkWidget) (transfer container): a newly-allocated #GSList of
1129 * all toplevel widgets of the requested types. Free the returned list with g_slist_free().
1130 *
1131 * Since: 2.4
1132 **/
1133GSList *
1134ctk_ui_manager_get_toplevels (CtkUIManager *manager,
1135 CtkUIManagerItemType types)
1136{
1137 ToplevelData data;
1138
1139 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (((void*)0)); } } while
(0)
;
1140 g_return_val_if_fail ((~(CTK_UI_MANAGER_MENUBAR |do { if (((~(CTK_UI_MANAGER_MENUBAR | CTK_UI_MANAGER_TOOLBAR |
CTK_UI_MANAGER_POPUP) & types) == 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "(~(CTK_UI_MANAGER_MENUBAR | CTK_UI_MANAGER_TOOLBAR | CTK_UI_MANAGER_POPUP) & types) == 0"
); return (((void*)0)); } } while (0)
1141 CTK_UI_MANAGER_TOOLBAR |do { if (((~(CTK_UI_MANAGER_MENUBAR | CTK_UI_MANAGER_TOOLBAR |
CTK_UI_MANAGER_POPUP) & types) == 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "(~(CTK_UI_MANAGER_MENUBAR | CTK_UI_MANAGER_TOOLBAR | CTK_UI_MANAGER_POPUP) & types) == 0"
); return (((void*)0)); } } while (0)
1142 CTK_UI_MANAGER_POPUP) & types) == 0, NULL)do { if (((~(CTK_UI_MANAGER_MENUBAR | CTK_UI_MANAGER_TOOLBAR |
CTK_UI_MANAGER_POPUP) & types) == 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "(~(CTK_UI_MANAGER_MENUBAR | CTK_UI_MANAGER_TOOLBAR | CTK_UI_MANAGER_POPUP) & types) == 0"
); return (((void*)0)); } } while (0)
;
1143
1144
1145 data.types = types;
1146 data.list = NULL((void*)0);
1147
1148 g_node_children_foreach (manager->private_data->root_node,
1149 G_TRAVERSE_ALL,
1150 collect_toplevels, &data);
1151
1152 return data.list;
1153}
1154
1155
1156/**
1157 * ctk_ui_manager_get_action:
1158 * @manager: a #CtkUIManager
1159 * @path: a path
1160 *
1161 * Looks up an action by following a path. See ctk_ui_manager_get_widget()
1162 * for more information about paths.
1163 *
1164 * Returns: (transfer none): the action whose proxy widget is found by following the path,
1165 * or %NULL if no widget was found.
1166 *
1167 * Since: 2.4
1168 **/
1169CtkAction *
1170ctk_ui_manager_get_action (CtkUIManager *manager,
1171 const gchar *path)
1172{
1173 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (((void*)0)); } } while
(0)
;
1174 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
1175
1176 return CTK_UI_MANAGER_GET_CLASS (manager)((((CtkUIManagerClass*) (((GTypeInstance*) ((manager)))->g_class
))))
->get_action (manager, path);
1177}
1178
1179static gboolean
1180node_is_dead (GNode *node)
1181{
1182 GNode *child;
1183
1184 if (NODE_INFO (node)((Node *)node->data)->uifiles != NULL((void*)0))
1185 return FALSE(0);
1186
1187 for (child = node->children; child != NULL((void*)0); child = child->next)
1188 {
1189 if (!node_is_dead (child))
1190 return FALSE(0);
1191 }
1192
1193 return TRUE(!(0));
1194}
1195
1196static GNode *
1197get_child_node (CtkUIManager *manager,
1198 GNode *parent,
1199 GNode *sibling,
1200 const gchar *childname,
1201 gint childname_length,
1202 NodeType node_type,
1203 gboolean create,
1204 gboolean top)
1205{
1206 GNode *child = NULL((void*)0);
1207
1208 if (parent)
1209 {
1210 if (childname)
1211 {
1212 for (child = parent->children; child != NULL((void*)0); child = child->next)
1213 {
1214 if (NODE_INFO (child)((Node *)child->data)->name &&
1215 strlen (NODE_INFO (child)((Node *)child->data)->name) == childname_length &&
1216 !strncmp (NODE_INFO (child)((Node *)child->data)->name, childname, childname_length))
1217 {
1218 /* if undecided about node type, set it */
1219 if (NODE_INFO (child)((Node *)child->data)->type == NODE_TYPE_UNDECIDED)
1220 NODE_INFO (child)((Node *)child->data)->type = node_type;
1221
1222 /* warn about type mismatch */
1223 if (NODE_INFO (child)((Node *)child->data)->type != NODE_TYPE_UNDECIDED &&
1224 node_type != NODE_TYPE_UNDECIDED &&
1225 NODE_INFO (child)((Node *)child->data)->type != node_type)
1226 g_warning ("node type doesn't match %d (%s is type %d)",
1227 node_type,
1228 NODE_INFO (child)((Node *)child->data)->name,
1229 NODE_INFO (child)((Node *)child->data)->type);
1230
1231 if (node_is_dead (child))
1232 {
1233 /* This node was removed but is still dirty so
1234 * it is still in the tree. We want to treat this
1235 * as if it didn't exist, which means we move it
1236 * to the position it would have been created at.
1237 */
1238 g_node_unlink (child);
1239 goto insert_child;
1240 }
1241
1242 return child;
1243 }
1244 }
1245 }
1246 if (!child && create)
1247 {
1248 Node *mnode;
1249
1250 mnode = g_slice_new0 (Node)((Node*) g_slice_alloc0 (sizeof (Node)));
1251 mnode->type = node_type;
1252 mnode->name = g_strndup (childname, childname_length);
1253
1254 child = g_node_new (mnode);
1255 insert_child:
1256 if (sibling)
1257 {
1258 if (top)
1259 g_node_insert_before (parent, sibling, child);
1260 else
1261 g_node_insert_after (parent, sibling, child);
1262 }
1263 else
1264 {
1265 if (top)
1266 g_node_prepend (parent, child);
1267 else
1268 g_node_append (parent, child)g_node_insert_before ((parent), ((void*)0), (child));
1269 }
1270
1271 mark_node_dirty (child);
1272 }
1273 }
1274 else
1275 {
1276 /* handle root node */
1277 if (manager->private_data->root_node)
1278 {
1279 child = manager->private_data->root_node;
1280 if (strncmp (NODE_INFO (child)((Node *)child->data)->name, childname, childname_length) != 0)
1281 g_warning ("root node name '%s' doesn't match '%s'",
1282 childname, NODE_INFO (child)((Node *)child->data)->name);
1283 if (NODE_INFO (child)((Node *)child->data)->type != NODE_TYPE_ROOT)
1284 g_warning ("base element must be of type ROOT");
1285 }
1286 else if (create)
1287 {
1288 Node *mnode;
1289
1290 mnode = g_slice_new0 (Node)((Node*) g_slice_alloc0 (sizeof (Node)));
1291 mnode->type = node_type;
1292 mnode->name = g_strndup (childname, childname_length);
1293 mnode->dirty = TRUE(!(0));
1294
1295 child = manager->private_data->root_node = g_node_new (mnode);
1296 }
1297 }
1298
1299 return child;
1300}
1301
1302static GNode *
1303get_node (CtkUIManager *manager,
1304 const gchar *path,
1305 NodeType node_type,
1306 gboolean create)
1307{
1308 const gchar *pos, *end;
1309 GNode *parent, *node;
1310
1311 if (strncmp ("/ui", path, 3) == 0)
1312 path += 3;
1313
1314 end = path + strlen (path);
1315 pos = path;
1316 parent = node = NULL((void*)0);
1317 while (pos < end)
1318 {
1319 const gchar *slash;
1320 gsize length;
1321
1322 slash = strchr (pos, '/');
1323 if (slash)
1324 length = slash - pos;
1325 else
1326 length = strlen (pos);
1327
1328 node = get_child_node (manager, parent, NULL((void*)0), pos, length, NODE_TYPE_UNDECIDED,
1329 create, FALSE(0));
1330 if (!node)
1331 return NULL((void*)0);
1332
1333 pos += length + 1; /* move past the node name and the slash too */
1334 parent = node;
1335 }
1336
1337 if (node != NULL((void*)0) && NODE_INFO (node)((Node *)node->data)->type == NODE_TYPE_UNDECIDED)
1338 NODE_INFO (node)((Node *)node->data)->type = node_type;
1339
1340 return node;
1341}
1342
1343static void
1344node_ui_reference_free (gpointer data)
1345{
1346 g_slice_free (NodeUIReference, data)do { if (1) g_slice_free1 (sizeof (NodeUIReference), (data));
else (void) ((NodeUIReference*) 0 == (data)); } while (0)
;
1347}
1348
1349static gboolean
1350free_node (GNode *node)
1351{
1352 Node *info = NODE_INFO (node)((Node *)node->data);
1353
1354 g_list_free_full (info->uifiles, node_ui_reference_free);
1355 info->uifiles = NULL((void*)0);
1356
1357 g_clear_object (&info->action)do { _Static_assert (sizeof *((&info->action)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&info->action))) _pp = ((&info->action)); __typeof__
(*((&info->action))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
1358 g_clear_object (&info->proxy)do { _Static_assert (sizeof *((&info->proxy)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&info->proxy))) _pp = ((&info->proxy)); __typeof__
(*((&info->proxy))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
1359 g_clear_object (&info->extra)do { _Static_assert (sizeof *((&info->extra)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&info->extra))) _pp = ((&info->extra)); __typeof__
(*((&info->extra))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
1360 g_clear_pointer (&info->name, g_free)do { _Static_assert (sizeof *(&info->name) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ ((&
info->name)) _pp = (&info->name); __typeof__ (*(&
info->name)) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_free
) (_ptr); } while (0)
;
1361 g_slice_free (Node, info)do { if (1) g_slice_free1 (sizeof (Node), (info)); else (void
) ((Node*) 0 == (info)); } while (0)
;
1362 node->data = NULL((void*)0);
1363
1364 return FALSE(0);
1365}
1366
1367/**
1368 * ctk_ui_manager_new_merge_id:
1369 * @manager: a #CtkUIManager
1370 *
1371 * Returns an unused merge id, suitable for use with
1372 * ctk_ui_manager_add_ui().
1373 *
1374 * Returns: an unused merge id.
1375 *
1376 * Since: 2.4
1377 **/
1378guint
1379ctk_ui_manager_new_merge_id (CtkUIManager *manager)
1380{
1381 manager->private_data->last_merge_id++;
1382
1383 return manager->private_data->last_merge_id;
1384}
1385
1386static void
1387node_prepend_ui_reference (GNode *gnode,
1388 guint merge_id,
1389 GQuark action_quark)
1390{
1391 Node *node = NODE_INFO (gnode)((Node *)gnode->data);
1392 NodeUIReference *reference = NULL((void*)0);
1393
1394 if (node->uifiles &&
1395 ((NodeUIReference *)node->uifiles->data)->merge_id == merge_id)
1396 reference = node->uifiles->data;
1397 else
1398 {
1399 reference = g_slice_new (NodeUIReference)((NodeUIReference*) g_slice_alloc (sizeof (NodeUIReference)));
1400 node->uifiles = g_list_prepend (node->uifiles, reference);
1401 }
1402
1403 reference->merge_id = merge_id;
1404 reference->action_quark = action_quark;
1405
1406 mark_node_dirty (gnode);
1407}
1408
1409static void
1410node_remove_ui_reference (GNode *gnode,
1411 guint merge_id)
1412{
1413 Node *node = NODE_INFO (gnode)((Node *)gnode->data);
1414 GList *p;
1415
1416 for (p = node->uifiles; p != NULL((void*)0); p = p->next)
1417 {
1418 NodeUIReference *reference = p->data;
1419
1420 if (reference->merge_id == merge_id)
1421 {
1422 if (p == node->uifiles)
1423 mark_node_dirty (gnode);
1424 node->uifiles = g_list_delete_link (node->uifiles, p);
1425 g_slice_free (NodeUIReference, reference)do { if (1) g_slice_free1 (sizeof (NodeUIReference), (reference
)); else (void) ((NodeUIReference*) 0 == (reference)); } while
(0)
;
1426
1427 break;
1428 }
1429 }
1430}
1431
1432/* -------------------- The UI file parser -------------------- */
1433
1434typedef enum
1435{
1436 STATE_START,
1437 STATE_ROOT,
1438 STATE_MENU,
1439 STATE_TOOLBAR,
1440 STATE_MENUITEM,
1441 STATE_TOOLITEM,
1442 STATE_ACCELERATOR,
1443 STATE_END
1444} ParseState;
1445
1446typedef struct _ParseContext ParseContext;
1447struct _ParseContext
1448{
1449 ParseState state;
1450 ParseState prev_state;
1451
1452 CtkUIManager *manager;
1453
1454 GNode *current;
1455
1456 guint merge_id;
1457};
1458
1459static void
1460start_element_handler (GMarkupParseContext *context,
1461 const gchar *element_name,
1462 const gchar **attribute_names,
1463 const gchar **attribute_values,
1464 gpointer user_data,
1465 GError **error)
1466{
1467 ParseContext *ctx = user_data;
1468 CtkUIManager *manager = ctx->manager;
1469
1470 gint i;
1471 const gchar *node_name;
1472 const gchar *action;
1473 GQuark action_quark;
1474 gboolean top;
1475 gboolean expand = FALSE(0);
1476 gboolean accelerators = FALSE(0);
1477 gboolean always_show_image_set = FALSE(0), always_show_image = FALSE(0);
1478
1479 gboolean raise_error = TRUE(!(0));
1480
1481 node_name = NULL((void*)0);
1482 action = NULL((void*)0);
1483 action_quark = 0;
1484 top = FALSE(0);
1485
1486 for (i = 0; attribute_names[i] != NULL((void*)0); i++)
1487 {
1488 if (!strcmp (attribute_names[i], "name"))
1489 {
1490 node_name = attribute_values[i];
1491 }
1492 else if (!strcmp (attribute_names[i], "action"))
1493 {
1494 action = attribute_values[i];
1495 action_quark = g_quark_from_string (attribute_values[i]);
1496 }
1497 else if (!strcmp (attribute_names[i], "position"))
1498 {
1499 top = !strcmp (attribute_values[i], "top");
1500 }
1501 else if (!strcmp (attribute_names[i], "expand"))
1502 {
1503 expand = !strcmp (attribute_values[i], "true");
1504 }
1505 else if (!strcmp (attribute_names[i], "accelerators"))
1506 {
1507 accelerators = !strcmp (attribute_values[i], "true");
1508 }
1509 else if (!strcmp (attribute_names[i], "always-show-image"))
1510 {
1511 always_show_image_set = TRUE(!(0));
1512 always_show_image = !strcmp (attribute_values[i], "true");
1513 }
1514 /* else silently skip unknown attributes to be compatible with
1515 * future additional attributes.
1516 */
1517 }
1518
1519 /* Work out a name for this node. Either the name attribute, or
1520 * the action, or the element name */
1521 if (node_name == NULL((void*)0))
1522 {
1523 if (action != NULL((void*)0))
1524 node_name = action;
1525 else
1526 node_name = element_name;
1527 }
1528
1529 switch (element_name[0])
1530 {
1531 case 'a':
1532 if (ctx->state == STATE_ROOT && !strcmp (element_name, "accelerator"))
1533 {
1534 ctx->state = STATE_ACCELERATOR;
1535 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1536 node_name, strlen (node_name),
1537 NODE_TYPE_ACCELERATOR,
1538 TRUE(!(0)), FALSE(0));
1539 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name == 0)
1540 NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name = action_quark;
1541
1542 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1543
1544 raise_error = FALSE(0);
1545 }
1546 break;
1547 case 'u':
1548 if (ctx->state == STATE_START && !strcmp (element_name, "ui"))
1549 {
1550 ctx->state = STATE_ROOT;
1551 ctx->current = manager->private_data->root_node;
1552 raise_error = FALSE(0);
1553
1554 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1555 }
1556 break;
1557 case 'm':
1558 if (ctx->state == STATE_ROOT && !strcmp (element_name, "menubar"))
1559 {
1560 ctx->state = STATE_MENU;
1561 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1562 node_name, strlen (node_name),
1563 NODE_TYPE_MENUBAR,
1564 TRUE(!(0)), FALSE(0));
1565 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name == 0)
1566 NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name = action_quark;
1567
1568 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1569 mark_node_dirty (ctx->current);
1570
1571 raise_error = FALSE(0);
1572 }
1573 else if (ctx->state == STATE_MENU && !strcmp (element_name, "menu"))
1574 {
1575 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1576 node_name, strlen (node_name),
1577 NODE_TYPE_MENU,
1578 TRUE(!(0)), top);
1579 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name == 0)
1580 NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name = action_quark;
1581
1582 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1583
1584 raise_error = FALSE(0);
1585 }
1586 else if (ctx->state == STATE_TOOLITEM && !strcmp (element_name, "menu"))
1587 {
1588 ctx->state = STATE_MENU;
1589
1590 ctx->current = get_child_node (manager, g_node_last_child (ctx->current), NULL((void*)0),
1591 node_name, strlen (node_name),
1592 NODE_TYPE_MENU,
1593 TRUE(!(0)), top);
1594 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name == 0)
1595 NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name = action_quark;
1596
1597 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1598
1599 raise_error = FALSE(0);
1600 }
1601 else if (ctx->state == STATE_MENU && !strcmp (element_name, "menuitem"))
1602 {
1603 GNode *node;
1604
1605 ctx->state = STATE_MENUITEM;
1606 node = get_child_node (manager, ctx->current, NULL((void*)0),
1607 node_name, strlen (node_name),
1608 NODE_TYPE_MENUITEM,
1609 TRUE(!(0)), top);
1610 if (NODE_INFO (node)((Node *)node->data)->action_name == 0)
1611 NODE_INFO (node)((Node *)node->data)->action_name = action_quark;
1612
1613 NODE_INFO (node)((Node *)node->data)->always_show_image_set = always_show_image_set;
1614 NODE_INFO (node)((Node *)node->data)->always_show_image = always_show_image;
1615
1616 node_prepend_ui_reference (node, ctx->merge_id, action_quark);
1617
1618 raise_error = FALSE(0);
1619 }
1620 break;
1621 case 'p':
1622 if (ctx->state == STATE_ROOT && !strcmp (element_name, "popup"))
1623 {
1624 ctx->state = STATE_MENU;
1625 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1626 node_name, strlen (node_name),
1627 NODE_TYPE_POPUP,
1628 TRUE(!(0)), FALSE(0));
1629
1630 NODE_INFO (ctx->current)((Node *)ctx->current->data)->popup_accels = accelerators;
1631
1632 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name == 0)
1633 NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name = action_quark;
1634
1635 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1636
1637 raise_error = FALSE(0);
1638 }
1639 else if ((ctx->state == STATE_MENU || ctx->state == STATE_TOOLBAR) &&
1640 !strcmp (element_name, "placeholder"))
1641 {
1642 if (ctx->state == STATE_TOOLBAR)
1643 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1644 node_name, strlen (node_name),
1645 NODE_TYPE_TOOLBAR_PLACEHOLDER,
1646 TRUE(!(0)), top);
1647 else
1648 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1649 node_name, strlen (node_name),
1650 NODE_TYPE_MENU_PLACEHOLDER,
1651 TRUE(!(0)), top);
1652
1653 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1654
1655 raise_error = FALSE(0);
1656 }
1657 break;
1658 case 's':
1659 if ((ctx->state == STATE_MENU || ctx->state == STATE_TOOLBAR) &&
1660 !strcmp (element_name, "separator"))
1661 {
1662 GNode *node;
1663 gint length;
1664
1665 if (ctx->state == STATE_TOOLBAR)
1666 ctx->state = STATE_TOOLITEM;
1667 else
1668 ctx->state = STATE_MENUITEM;
1669 if (!strcmp (node_name, "separator"))
1670 {
1671 node_name = NULL((void*)0);
1672 length = 0;
1673 }
1674 else
1675 length = strlen (node_name);
1676 node = get_child_node (manager, ctx->current, NULL((void*)0),
1677 node_name, length,
1678 NODE_TYPE_SEPARATOR,
1679 TRUE(!(0)), top);
1680
1681 NODE_INFO (node)((Node *)node->data)->expand = expand;
1682
1683 if (NODE_INFO (node)((Node *)node->data)->action_name == 0)
1684 NODE_INFO (node)((Node *)node->data)->action_name = action_quark;
1685
1686 node_prepend_ui_reference (node, ctx->merge_id, action_quark);
1687
1688 raise_error = FALSE(0);
1689 }
1690 break;
1691 case 't':
1692 if (ctx->state == STATE_ROOT && !strcmp (element_name, "toolbar"))
1693 {
1694 ctx->state = STATE_TOOLBAR;
1695 ctx->current = get_child_node (manager, ctx->current, NULL((void*)0),
1696 node_name, strlen (node_name),
1697 NODE_TYPE_TOOLBAR,
1698 TRUE(!(0)), FALSE(0));
1699 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name == 0)
1700 NODE_INFO (ctx->current)((Node *)ctx->current->data)->action_name = action_quark;
1701
1702 node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
1703
1704 raise_error = FALSE(0);
1705 }
1706 else if (ctx->state == STATE_TOOLBAR && !strcmp (element_name, "toolitem"))
1707 {
1708 GNode *node;
1709
1710 ctx->state = STATE_TOOLITEM;
1711 node = get_child_node (manager, ctx->current, NULL((void*)0),
1712 node_name, strlen (node_name),
1713 NODE_TYPE_TOOLITEM,
1714 TRUE(!(0)), top);
1715 if (NODE_INFO (node)((Node *)node->data)->action_name == 0)
1716 NODE_INFO (node)((Node *)node->data)->action_name = action_quark;
1717
1718 node_prepend_ui_reference (node, ctx->merge_id, action_quark);
1719
1720 raise_error = FALSE(0);
1721 }
1722 break;
1723 default:
1724 break;
1725 }
1726 if (raise_error)
1727 {
1728 gint line_number, char_number;
1729
1730 g_markup_parse_context_get_position (context,
1731 &line_number, &char_number);
1732 g_set_error (error,
1733 G_MARKUP_ERRORg_markup_error_quark (),
1734 G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1735 _("Unexpected start tag '%s' on line %d char %d")((char *) g_dgettext ("ctk30", "Unexpected start tag '%s' on line %d char %d"
))
,
1736 element_name,
1737 line_number, char_number);
1738 }
1739}
1740
1741static void
1742end_element_handler (GMarkupParseContext *context G_GNUC_UNUSED__attribute__ ((__unused__)),
1743 const gchar *element_name G_GNUC_UNUSED__attribute__ ((__unused__)),
1744 gpointer user_data,
1745 GError **error G_GNUC_UNUSED__attribute__ ((__unused__)))
1746{
1747 ParseContext *ctx = user_data;
1748
1749 switch (ctx->state)
1750 {
1751 case STATE_START:
1752 case STATE_END:
1753 /* no need to GError here, GMarkup already catches this */
1754 break;
1755 case STATE_ROOT:
1756 ctx->current = NULL((void*)0);
1757 ctx->state = STATE_END;
1758 break;
1759 case STATE_MENU:
1760 case STATE_TOOLBAR:
1761 case STATE_ACCELERATOR:
1762 ctx->current = ctx->current->parent;
1763 if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->type == NODE_TYPE_ROOT)
1764 ctx->state = STATE_ROOT;
1765 else if (NODE_INFO (ctx->current)((Node *)ctx->current->data)->type == NODE_TYPE_TOOLITEM)
1766 {
1767 ctx->current = ctx->current->parent;
1768 ctx->state = STATE_TOOLITEM;
1769 }
1770 /* else, stay in same state */
1771 break;
1772 case STATE_MENUITEM:
1773 ctx->state = STATE_MENU;
1774 break;
1775 case STATE_TOOLITEM:
1776 ctx->state = STATE_TOOLBAR;
1777 break;
1778 }
1779}
1780
1781static void
1782cleanup (GMarkupParseContext *context G_GNUC_UNUSED__attribute__ ((__unused__)),
1783 GError *error G_GNUC_UNUSED__attribute__ ((__unused__)),
1784 gpointer user_data)
1785{
1786 ParseContext *ctx = user_data;
1787
1788 ctx->current = NULL((void*)0);
1789 /* should also walk through the tree and get rid of nodes related to
1790 * this UI file's tag */
1791
1792 ctk_ui_manager_remove_ui (ctx->manager, ctx->merge_id);
1793}
1794
1795static gboolean
1796xml_isspace (char c)
1797{
1798 return c == ' ' || c == '\t' || c == '\n' || c == '\r';
1799}
1800
1801static void
1802text_handler (GMarkupParseContext *context,
1803 const gchar *text,
1804 gsize text_len,
1805 gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__)),
1806 GError **error)
1807{
1808 const gchar *p;
1809 const gchar *end;
1810
1811 p = text;
1812 end = text + text_len;
1813 while (p != end && xml_isspace (*p))
1814 ++p;
1815
1816 if (p != end)
1817 {
1818 gint line_number, char_number;
1819
1820 g_markup_parse_context_get_position (context,
1821 &line_number, &char_number);
1822 g_set_error (error,
1823 G_MARKUP_ERRORg_markup_error_quark (),
1824 G_MARKUP_ERROR_INVALID_CONTENT,
1825 _("Unexpected character data on line %d char %d")((char *) g_dgettext ("ctk30", "Unexpected character data on line %d char %d"
))
,
1826 line_number, char_number);
1827 }
1828}
1829
1830
1831static const GMarkupParser ui_parser = {
1832 start_element_handler,
1833 end_element_handler,
1834 text_handler,
1835 NULL((void*)0),
1836 cleanup
1837};
1838
1839static guint
1840add_ui_from_string (CtkUIManager *manager,
1841 const gchar *buffer,
1842 gssize length,
1843 gboolean needs_root,
1844 GError **error)
1845{
1846 ParseContext ctx = { 0 };
1847 GMarkupParseContext *context;
1848
1849 ctx.state = STATE_START;
1850 ctx.manager = manager;
1851 ctx.current = NULL((void*)0);
1852 ctx.merge_id = ctk_ui_manager_new_merge_id (manager);
1853
1854 context = g_markup_parse_context_new (&ui_parser, 0, &ctx, NULL((void*)0));
1855
1856 if (needs_root)
1857 if (!g_markup_parse_context_parse (context, "<ui>", -1, error))
1858 goto out;
1859
1860 if (!g_markup_parse_context_parse (context, buffer, length, error))
1861 goto out;
1862
1863 if (needs_root)
1864 if (!g_markup_parse_context_parse (context, "</ui>", -1, error))
1865 goto out;
1866
1867 if (!g_markup_parse_context_end_parse (context, error))
1868 goto out;
1869
1870 g_markup_parse_context_free (context);
1871
1872 queue_update (manager);
1873
1874 g_object_notify (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
, "ui");
1875
1876 return ctx.merge_id;
1877
1878 out:
1879
1880 g_markup_parse_context_free (context);
1881
1882 return 0;
1883}
1884
1885/**
1886 * ctk_ui_manager_add_ui_from_string:
1887 * @manager: a #CtkUIManager object
1888 * @buffer: the string to parse
1889 * @length: the length of @buffer (may be -1 if @buffer is nul-terminated)
1890 * @error: return location for an error
1891 *
1892 * Parses a string containing a [UI definition][XML-UI] and merges it with
1893 * the current contents of @manager. An enclosing <ui> element is added if
1894 * it is missing.
1895 *
1896 * Returns: The merge id for the merged UI. The merge id can be used
1897 * to unmerge the UI with ctk_ui_manager_remove_ui(). If an error occurred,
1898 * the return value is 0.
1899 *
1900 * Since: 2.4
1901 **/
1902guint
1903ctk_ui_manager_add_ui_from_string (CtkUIManager *manager,
1904 const gchar *buffer,
1905 gssize length,
1906 GError **error)
1907{
1908 gboolean needs_root = TRUE(!(0));
1909 const gchar *p;
1910 const gchar *end;
1911
1912 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (0); } } while (0)
;
1913 g_return_val_if_fail (buffer != NULL, 0)do { if ((buffer != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "buffer != NULL"); return
(0); } } while (0)
;
1914
1915 if (length < 0)
1916 length = strlen (buffer);
1917
1918 p = buffer;
1919 end = buffer + length;
1920 while (p != end && xml_isspace (*p))
1921 ++p;
1922
1923 if (end - p >= 4 && strncmp (p, "<ui>", 4) == 0)
1924 needs_root = FALSE(0);
1925
1926 return add_ui_from_string (manager, buffer, length, needs_root, error);
1927}
1928
1929/**
1930 * ctk_ui_manager_add_ui_from_file:
1931 * @manager: a #CtkUIManager object
1932 * @filename: (type filename): the name of the file to parse
1933 * @error: return location for an error
1934 *
1935 * Parses a file containing a [UI definition][XML-UI] and
1936 * merges it with the current contents of @manager.
1937 *
1938 * Returns: The merge id for the merged UI. The merge id can be used
1939 * to unmerge the UI with ctk_ui_manager_remove_ui(). If an error occurred,
1940 * the return value is 0.
1941 *
1942 * Since: 2.4
1943 **/
1944guint
1945ctk_ui_manager_add_ui_from_file (CtkUIManager *manager,
1946 const gchar *filename,
1947 GError **error)
1948{
1949 gchar *buffer;
1950 gsize length;
1951 guint res;
1952
1953 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (0); } } while (0)
;
1954
1955 if (!g_file_get_contents (filename, &buffer, &length, error))
1956 return 0;
1957
1958 res = add_ui_from_string (manager, buffer, length, FALSE(0), error);
1959 g_free (buffer);
1960
1961 return res;
1962}
1963
1964/**
1965 * ctk_ui_manager_add_ui_from_resource:
1966 * @manager: a #CtkUIManager object
1967 * @resource_path: the resource path of the file to parse
1968 * @error: return location for an error
1969 *
1970 * Parses a resource file containing a [UI definition][XML-UI] and
1971 * merges it with the current contents of @manager.
1972 *
1973 * Returns: The merge id for the merged UI. The merge id can be used
1974 * to unmerge the UI with ctk_ui_manager_remove_ui(). If an error occurred,
1975 * the return value is 0.
1976 *
1977 * Since: 3.4
1978 **/
1979guint
1980ctk_ui_manager_add_ui_from_resource (CtkUIManager *manager,
1981 const gchar *resource_path,
1982 GError **error)
1983{
1984 GBytes *data;
1985 guint res;
1986
1987 g_return_val_if_fail (CTK_IS_UI_MANAGER (manager), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return (0); } } while (0)
;
1988
1989 data = g_resources_lookup_data (resource_path, 0, error);
1990 if (data == NULL((void*)0))
1991 return 0;
1992
1993 res = add_ui_from_string (manager, g_bytes_get_data (data, NULL((void*)0)), g_bytes_get_size (data), FALSE(0), error);
1994 g_bytes_unref (data);
1995
1996 return res;
1997}
1998
1999/**
2000 * ctk_ui_manager_add_ui:
2001 * @manager: a #CtkUIManager
2002 * @merge_id: the merge id for the merged UI, see ctk_ui_manager_new_merge_id()
2003 * @path: a path
2004 * @name: the name for the added UI element
2005 * @action: (allow-none): the name of the action to be proxied, or %NULL to add a separator
2006 * @type: the type of UI element to add.
2007 * @top: if %TRUE, the UI element is added before its siblings, otherwise it
2008 * is added after its siblings.
2009 *
2010 * Adds a UI element to the current contents of @manager.
2011 *
2012 * If @type is %CTK_UI_MANAGER_AUTO, CTK+ inserts a menuitem, toolitem or
2013 * separator if such an element can be inserted at the place determined by
2014 * @path. Otherwise @type must indicate an element that can be inserted at
2015 * the place determined by @path.
2016 *
2017 * If @path points to a menuitem or toolitem, the new element will be inserted
2018 * before or after this item, depending on @top.
2019 *
2020 * Since: 2.4
2021 **/
2022void
2023ctk_ui_manager_add_ui (CtkUIManager *manager,
2024 guint merge_id,
2025 const gchar *path,
2026 const gchar *name,
2027 const gchar *action,
2028 CtkUIManagerItemType type,
2029 gboolean top)
2030{
2031 GNode *node;
2032 GNode *sibling;
2033 GNode *child;
2034 NodeType node_type;
2035 GQuark action_quark = 0;
2036
2037 g_return_if_fail (CTK_IS_UI_MANAGER (manager))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return; } } while (0)
;
2038 g_return_if_fail (merge_id > 0)do { if ((merge_id > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "merge_id > 0"); return
; } } while (0)
;
2039 g_return_if_fail (name != NULL || type == CTK_UI_MANAGER_SEPARATOR)do { if ((name != ((void*)0) || type == CTK_UI_MANAGER_SEPARATOR
)) { } else { g_return_if_fail_warning ("Ctk", ((const char*)
(__func__)), "name != NULL || type == CTK_UI_MANAGER_SEPARATOR"
); return; } } while (0)
;
2040
2041 node = get_node (manager, path, NODE_TYPE_UNDECIDED, FALSE(0));
2042 sibling = NULL((void*)0);
2043
2044 if (node == NULL((void*)0))
2045 return;
2046
2047 node_type = NODE_TYPE_UNDECIDED;
2048
2049 reswitch:
2050 switch (NODE_INFO (node)((Node *)node->data)->type)
2051 {
2052 case NODE_TYPE_SEPARATOR:
2053 case NODE_TYPE_MENUITEM:
2054 case NODE_TYPE_TOOLITEM:
2055 sibling = node;
2056 node = node->parent;
2057 goto reswitch;
2058 case NODE_TYPE_MENUBAR:
2059 case NODE_TYPE_MENU:
2060 case NODE_TYPE_POPUP:
2061 case NODE_TYPE_MENU_PLACEHOLDER:
2062 switch (type)
2063 {
2064 case CTK_UI_MANAGER_AUTO:
2065 if (action != NULL((void*)0))
2066 node_type = NODE_TYPE_MENUITEM;
2067 else
2068 node_type = NODE_TYPE_SEPARATOR;
2069 break;
2070 case CTK_UI_MANAGER_MENU:
2071 node_type = NODE_TYPE_MENU;
2072 break;
2073 case CTK_UI_MANAGER_MENUITEM:
2074 node_type = NODE_TYPE_MENUITEM;
2075 break;
2076 case CTK_UI_MANAGER_SEPARATOR:
2077 node_type = NODE_TYPE_SEPARATOR;
2078 break;
2079 case CTK_UI_MANAGER_PLACEHOLDER:
2080 node_type = NODE_TYPE_MENU_PLACEHOLDER;
2081 break;
2082 default: ;
2083 /* do nothing */
2084 }
2085 break;
2086 case NODE_TYPE_TOOLBAR:
2087 case NODE_TYPE_TOOLBAR_PLACEHOLDER:
2088 switch (type)
2089 {
2090 case CTK_UI_MANAGER_AUTO:
2091 if (action != NULL((void*)0))
2092 node_type = NODE_TYPE_TOOLITEM;
2093 else
2094 node_type = NODE_TYPE_SEPARATOR;
2095 break;
2096 case CTK_UI_MANAGER_TOOLITEM:
2097 node_type = NODE_TYPE_TOOLITEM;
2098 break;
2099 case CTK_UI_MANAGER_SEPARATOR:
2100 node_type = NODE_TYPE_SEPARATOR;
2101 break;
2102 case CTK_UI_MANAGER_PLACEHOLDER:
2103 node_type = NODE_TYPE_TOOLBAR_PLACEHOLDER;
2104 break;
2105 default: ;
2106 /* do nothing */
2107 }
2108 break;
2109 case NODE_TYPE_ROOT:
2110 switch (type)
2111 {
2112 case CTK_UI_MANAGER_MENUBAR:
2113 node_type = NODE_TYPE_MENUBAR;
2114 break;
2115 case CTK_UI_MANAGER_TOOLBAR:
2116 node_type = NODE_TYPE_TOOLBAR;
2117 break;
2118 case CTK_UI_MANAGER_POPUP:
2119 case CTK_UI_MANAGER_POPUP_WITH_ACCELS:
2120 node_type = NODE_TYPE_POPUP;
2121 break;
2122 case CTK_UI_MANAGER_ACCELERATOR:
2123 node_type = NODE_TYPE_ACCELERATOR;
2124 break;
2125 default: ;
2126 /* do nothing */
2127 }
2128 break;
2129 default: ;
2130 /* do nothing */
2131 }
2132
2133 if (node_type == NODE_TYPE_UNDECIDED)
2134 {
2135 g_warning ("item type %d not suitable for adding at '%s'", type, path);
2136 return;
2137 }
2138
2139 child = get_child_node (manager, node, sibling,
2140 name, name ? strlen (name) : 0,
2141 node_type, TRUE(!(0)), top);
2142
2143 if (type == CTK_UI_MANAGER_POPUP_WITH_ACCELS)
2144 NODE_INFO (child)((Node *)child->data)->popup_accels = TRUE(!(0));
2145
2146 if (action != NULL((void*)0))
2147 action_quark = g_quark_from_string (action);
2148
2149 node_prepend_ui_reference (child, merge_id, action_quark);
2150
2151 if (NODE_INFO (child)((Node *)child->data)->action_name == 0)
2152 NODE_INFO (child)((Node *)child->data)->action_name = action_quark;
2153
2154 queue_update (manager);
2155
2156 g_object_notify (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
, "ui");
2157}
2158
2159static gboolean
2160remove_ui (GNode *node,
2161 gpointer user_data)
2162{
2163 guint merge_id = GPOINTER_TO_UINT (user_data)((guint) (gulong) (user_data));
2164
2165 node_remove_ui_reference (node, merge_id);
2166
2167 return FALSE(0); /* continue */
2168}
2169
2170/**
2171 * ctk_ui_manager_remove_ui:
2172 * @manager: a #CtkUIManager object
2173 * @merge_id: a merge id as returned by ctk_ui_manager_add_ui_from_string()
2174 *
2175 * Unmerges the part of @manager's content identified by @merge_id.
2176 *
2177 * Since: 2.4
2178 **/
2179void
2180ctk_ui_manager_remove_ui (CtkUIManager *manager,
2181 guint merge_id)
2182{
2183 g_return_if_fail (CTK_IS_UI_MANAGER (manager))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((manager)); GType __t = ((ctk_ui_manager_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_UI_MANAGER (manager)"); return; } } while (0)
;
2184
2185 g_node_traverse (manager->private_data->root_node,
2186 G_POST_ORDER, G_TRAVERSE_ALL, -1,
2187 remove_ui, GUINT_TO_POINTER (merge_id)((gpointer) (gulong) (merge_id)));
2188
2189 queue_update (manager);
2190
2191 g_object_notify (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
, "ui");
2192}
2193
2194/* -------------------- Updates -------------------- */
2195
2196
2197static CtkAction *
2198get_action_by_name (CtkUIManager *merge,
2199 const gchar *action_name)
2200{
2201 GList *tmp;
2202
2203 if (!action_name)
2204 return NULL((void*)0);
2205
2206 /* lookup name */
2207 for (tmp = merge->private_data->action_groups; tmp != NULL((void*)0); tmp = tmp->next)
2208 {
2209 CtkActionGroup *action_group = tmp->data;
2210 CtkAction *action;
2211
2212 action = ctk_action_group_get_action (action_group, action_name);
2213
2214 if (action)
2215 return action;
2216 }
2217
2218 return NULL((void*)0);
2219}
2220
2221static gboolean
2222find_menu_position (GNode *node,
2223 CtkWidget **menushell_p,
2224 gint *pos_p)
2225{
2226 CtkWidget *menushell;
2227 gint pos = 0;
2228
2229 g_return_val_if_fail (node != NULL, FALSE)do { if ((node != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "node != NULL"); return (
(0)); } } while (0)
;
2230 g_return_val_if_fail (NODE_INFO (node)->type == NODE_TYPE_MENU ||do { if ((((Node *)node->data)->type == NODE_TYPE_MENU ||
((Node *)node->data)->type == NODE_TYPE_POPUP || ((Node
*)node->data)->type == NODE_TYPE_MENU_PLACEHOLDER || (
(Node *)node->data)->type == NODE_TYPE_MENUITEM || ((Node
*)node->data)->type == NODE_TYPE_SEPARATOR)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"NODE_INFO (node)->type == NODE_TYPE_MENU || NODE_INFO (node)->type == NODE_TYPE_POPUP || NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_MENUITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2231 NODE_INFO (node)->type == NODE_TYPE_POPUP ||do { if ((((Node *)node->data)->type == NODE_TYPE_MENU ||
((Node *)node->data)->type == NODE_TYPE_POPUP || ((Node
*)node->data)->type == NODE_TYPE_MENU_PLACEHOLDER || (
(Node *)node->data)->type == NODE_TYPE_MENUITEM || ((Node
*)node->data)->type == NODE_TYPE_SEPARATOR)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"NODE_INFO (node)->type == NODE_TYPE_MENU || NODE_INFO (node)->type == NODE_TYPE_POPUP || NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_MENUITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2232 NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER ||do { if ((((Node *)node->data)->type == NODE_TYPE_MENU ||
((Node *)node->data)->type == NODE_TYPE_POPUP || ((Node
*)node->data)->type == NODE_TYPE_MENU_PLACEHOLDER || (
(Node *)node->data)->type == NODE_TYPE_MENUITEM || ((Node
*)node->data)->type == NODE_TYPE_SEPARATOR)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"NODE_INFO (node)->type == NODE_TYPE_MENU || NODE_INFO (node)->type == NODE_TYPE_POPUP || NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_MENUITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2233 NODE_INFO (node)->type == NODE_TYPE_MENUITEM ||do { if ((((Node *)node->data)->type == NODE_TYPE_MENU ||
((Node *)node->data)->type == NODE_TYPE_POPUP || ((Node
*)node->data)->type == NODE_TYPE_MENU_PLACEHOLDER || (
(Node *)node->data)->type == NODE_TYPE_MENUITEM || ((Node
*)node->data)->type == NODE_TYPE_SEPARATOR)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"NODE_INFO (node)->type == NODE_TYPE_MENU || NODE_INFO (node)->type == NODE_TYPE_POPUP || NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_MENUITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2234 NODE_INFO (node)->type == NODE_TYPE_SEPARATOR,do { if ((((Node *)node->data)->type == NODE_TYPE_MENU ||
((Node *)node->data)->type == NODE_TYPE_POPUP || ((Node
*)node->data)->type == NODE_TYPE_MENU_PLACEHOLDER || (
(Node *)node->data)->type == NODE_TYPE_MENUITEM || ((Node
*)node->data)->type == NODE_TYPE_SEPARATOR)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"NODE_INFO (node)->type == NODE_TYPE_MENU || NODE_INFO (node)->type == NODE_TYPE_POPUP || NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_MENUITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2235 FALSE)do { if ((((Node *)node->data)->type == NODE_TYPE_MENU ||
((Node *)node->data)->type == NODE_TYPE_POPUP || ((Node
*)node->data)->type == NODE_TYPE_MENU_PLACEHOLDER || (
(Node *)node->data)->type == NODE_TYPE_MENUITEM || ((Node
*)node->data)->type == NODE_TYPE_SEPARATOR)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"NODE_INFO (node)->type == NODE_TYPE_MENU || NODE_INFO (node)->type == NODE_TYPE_POPUP || NODE_INFO (node)->type == NODE_TYPE_MENU_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_MENUITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
;
2236
2237 /* first sibling -- look at parent */
2238 if (node->prev == NULL((void*)0))
2239 {
2240 GNode *parent;
2241 GList *siblings;
2242
2243 parent = node->parent;
2244 switch (NODE_INFO (parent)((Node *)parent->data)->type)
2245 {
2246 case NODE_TYPE_MENUBAR:
2247 case NODE_TYPE_POPUP:
2248 menushell = NODE_INFO (parent)((Node *)parent->data)->proxy;
2249 pos = 0;
2250 break;
2251 case NODE_TYPE_MENU:
2252 menushell = NODE_INFO (parent)((Node *)parent->data)->proxy;
2253 if (CTK_IS_MENU_ITEM (menushell)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(menushell)); GType __t = ((ctk_menu_item_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; }))))
)
2254 menushell = ctk_menu_item_get_submenu (CTK_MENU_ITEM (menushell)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_item_get_type ()))))))
);
2255 siblings = ctk_container_get_children (CTK_CONTAINER (menushell)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_container_get_type ()))))))
);
2256
2257 if (siblings != NULL((void*)0) && CTK_IS_TEAROFF_MENU_ITEM (siblings->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(siblings->data)); GType __t = ((ctk_tearoff_menu_item_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; }))))
)
2258 pos = 1;
2259 else
2260 pos = 0;
2261
2262 g_list_free (siblings);
2263 break;
2264 case NODE_TYPE_MENU_PLACEHOLDER:
2265 menushell = ctk_widget_get_parent (NODE_INFO (parent)((Node *)parent->data)->proxy);
2266 g_return_val_if_fail (CTK_IS_MENU_SHELL (menushell), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menushell)); GType __t = ((ctk_menu_shell_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_MENU_SHELL (menushell)"); return ((0)
); } } while (0)
;
2267 pos = g_list_index (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
->priv->children,
2268 NODE_INFO (parent)((Node *)parent->data)->proxy) + 1;
2269 break;
2270 default:
2271 g_warning ("%s: bad parent node type %d", G_STRLOC"ctkuimanager.c" ":" "2271",
2272 NODE_INFO (parent)((Node *)parent->data)->type);
2273 return FALSE(0);
2274 }
2275 }
2276 else
2277 {
2278 CtkWidget *prev_child;
2279 GNode *sibling;
2280
2281 sibling = node->prev;
2282 if (NODE_INFO (sibling)((Node *)sibling->data)->type == NODE_TYPE_MENU_PLACEHOLDER)
2283 prev_child = NODE_INFO (sibling)((Node *)sibling->data)->extra; /* second Separator */
2284 else
2285 prev_child = NODE_INFO (sibling)((Node *)sibling->data)->proxy;
2286
2287 if (!CTK_IS_WIDGET (prev_child)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(prev_child)); GType __t = ((ctk_widget_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; }))))
)
2288 return FALSE(0);
2289
2290 menushell = ctk_widget_get_parent (prev_child);
2291 if (!CTK_IS_MENU_SHELL (menushell)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(menushell)); GType __t = ((ctk_menu_shell_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; }))))
)
2292 return FALSE(0);
2293
2294 pos = g_list_index (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
->priv->children, prev_child) + 1;
2295 }
2296
2297 if (menushell_p)
2298 *menushell_p = menushell;
2299 if (pos_p)
2300 *pos_p = pos;
2301
2302 return TRUE(!(0));
2303}
2304
2305static gboolean
2306find_toolbar_position (GNode *node,
2307 CtkWidget **toolbar_p,
2308 gint *pos_p)
2309{
2310 CtkWidget *toolbar;
2311 gint pos;
2312
2313 g_return_val_if_fail (node != NULL, FALSE)do { if ((node != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "node != NULL"); return (
(0)); } } while (0)
;
2314 g_return_val_if_fail (NODE_INFO (node)->type == NODE_TYPE_TOOLBAR ||do { if ((((Node *)node->data)->type == NODE_TYPE_TOOLBAR
|| ((Node *)node->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER
|| ((Node *)node->data)->type == NODE_TYPE_TOOLITEM ||
((Node *)node->data)->type == NODE_TYPE_SEPARATOR)) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "NODE_INFO (node)->type == NODE_TYPE_TOOLBAR || NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_TOOLITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2315 NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER ||do { if ((((Node *)node->data)->type == NODE_TYPE_TOOLBAR
|| ((Node *)node->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER
|| ((Node *)node->data)->type == NODE_TYPE_TOOLITEM ||
((Node *)node->data)->type == NODE_TYPE_SEPARATOR)) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "NODE_INFO (node)->type == NODE_TYPE_TOOLBAR || NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_TOOLITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2316 NODE_INFO (node)->type == NODE_TYPE_TOOLITEM ||do { if ((((Node *)node->data)->type == NODE_TYPE_TOOLBAR
|| ((Node *)node->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER
|| ((Node *)node->data)->type == NODE_TYPE_TOOLITEM ||
((Node *)node->data)->type == NODE_TYPE_SEPARATOR)) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "NODE_INFO (node)->type == NODE_TYPE_TOOLBAR || NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_TOOLITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2317 NODE_INFO (node)->type == NODE_TYPE_SEPARATOR,do { if ((((Node *)node->data)->type == NODE_TYPE_TOOLBAR
|| ((Node *)node->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER
|| ((Node *)node->data)->type == NODE_TYPE_TOOLITEM ||
((Node *)node->data)->type == NODE_TYPE_SEPARATOR)) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "NODE_INFO (node)->type == NODE_TYPE_TOOLBAR || NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_TOOLITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
2318 FALSE)do { if ((((Node *)node->data)->type == NODE_TYPE_TOOLBAR
|| ((Node *)node->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER
|| ((Node *)node->data)->type == NODE_TYPE_TOOLITEM ||
((Node *)node->data)->type == NODE_TYPE_SEPARATOR)) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "NODE_INFO (node)->type == NODE_TYPE_TOOLBAR || NODE_INFO (node)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER || NODE_INFO (node)->type == NODE_TYPE_TOOLITEM || NODE_INFO (node)->type == NODE_TYPE_SEPARATOR"
); return ((0)); } } while (0)
;
2319
2320 /* first sibling -- look at parent */
2321 if (node->prev == NULL((void*)0))
2322 {
2323 GNode *parent;
2324
2325 parent = node->parent;
2326 switch (NODE_INFO (parent)((Node *)parent->data)->type)
2327 {
2328 case NODE_TYPE_TOOLBAR:
2329 toolbar = NODE_INFO (parent)((Node *)parent->data)->proxy;
2330 pos = 0;
2331 break;
2332 case NODE_TYPE_TOOLBAR_PLACEHOLDER:
2333 toolbar = ctk_widget_get_parent (NODE_INFO (parent)((Node *)parent->data)->proxy);
2334 g_return_val_if_fail (CTK_IS_TOOLBAR (toolbar), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((toolbar)); GType __t = ((ctk_toolbar_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_TOOLBAR (toolbar)"); return ((0)); } } while (0)
;
2335 pos = ctk_toolbar_get_item_index (CTK_TOOLBAR (toolbar)((((CtkToolbar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_toolbar_get_type ()))))))
,
2336 CTK_TOOL_ITEM (NODE_INFO (parent)->proxy)((((CtkToolItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((((Node *)parent->data)->proxy)), ((ctk_tool_item_get_type
()))))))
) + 1;
2337 break;
2338 default:
2339 g_warning ("%s: bad parent node type %d", G_STRLOC"ctkuimanager.c" ":" "2339",
2340 NODE_INFO (parent)((Node *)parent->data)->type);
2341 return FALSE(0);
2342 }
2343 }
2344 else
2345 {
2346 CtkWidget *prev_child;
2347 GNode *sibling;
2348
2349 sibling = node->prev;
2350 if (NODE_INFO (sibling)((Node *)sibling->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER)
2351 prev_child = NODE_INFO (sibling)((Node *)sibling->data)->extra; /* second Separator */
2352 else
2353 prev_child = NODE_INFO (sibling)((Node *)sibling->data)->proxy;
2354
2355 if (!CTK_IS_WIDGET (prev_child)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(prev_child)); GType __t = ((ctk_widget_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; }))))
)
2356 return FALSE(0);
2357
2358 toolbar = ctk_widget_get_parent (prev_child);
2359 if (!CTK_IS_TOOLBAR (toolbar)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(toolbar)); GType __t = ((ctk_toolbar_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; }))))
)
2360 return FALSE(0);
2361
2362 pos = ctk_toolbar_get_item_index (CTK_TOOLBAR (toolbar)((((CtkToolbar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_toolbar_get_type ()))))))
,
2363 CTK_TOOL_ITEM (prev_child)((((CtkToolItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((prev_child)), ((ctk_tool_item_get_type ()))))))
) + 1;
2364 }
2365
2366 if (toolbar_p)
2367 *toolbar_p = toolbar;
2368 if (pos_p)
2369 *pos_p = pos;
2370
2371 return TRUE(!(0));
2372}
2373
2374enum {
2375 SEPARATOR_MODE_SMART,
2376 SEPARATOR_MODE_VISIBLE,
2377 SEPARATOR_MODE_HIDDEN
2378};
2379
2380static void
2381update_smart_separators (CtkWidget *proxy)
2382{
2383 CtkWidget *parent = NULL((void*)0);
2384
2385 if (CTK_IS_MENU (proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(proxy)); GType __t = ((ctk_menu_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; }))))
|| CTK_IS_TOOLBAR (proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(proxy)); GType __t = ((ctk_toolbar_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; }))))
)
2386 parent = proxy;
2387 else if (CTK_IS_MENU_ITEM (proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(proxy)); GType __t = ((ctk_menu_item_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; }))))
|| CTK_IS_TOOL_ITEM (proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(proxy)); GType __t = ((ctk_tool_item_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; }))))
)
2388 parent = ctk_widget_get_parent (proxy);
2389
2390 if (parent)
2391 {
2392 gboolean visible;
2393 gboolean empty;
2394 GList *children, *cur, *last;
2395 CtkWidget *filler;
2396
2397 children = ctk_container_get_children (CTK_CONTAINER (parent)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_container_get_type ()))))))
);
2398
2399 visible = FALSE(0);
2400 last = NULL((void*)0);
2401 empty = TRUE(!(0));
2402 filler = NULL((void*)0);
2403
2404 cur = children;
2405 while (cur)
2406 {
2407 if (g_object_get_data (cur->data, "ctk-empty-menu-item"))
2408 {
2409 filler = cur->data;
2410 }
2411 else if (CTK_IS_SEPARATOR_MENU_ITEM (cur->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cur->data)); GType __t = ((ctk_separator_menu_item_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; }))))
||
2412 CTK_IS_SEPARATOR_TOOL_ITEM (cur->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cur->data)); GType __t = ((ctk_separator_tool_item_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; }))))
)
2413 {
2414 gint mode =
2415 GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cur->data),((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((cur->data)), (((GType) ((20) <<
(2)))))))), "ctk-separator-mode")))
2416 "ctk-separator-mode"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((cur->data)), (((GType) ((20) <<
(2)))))))), "ctk-separator-mode")))
;
2417 switch (mode)
2418 {
2419 case SEPARATOR_MODE_VISIBLE:
2420 ctk_widget_show (CTK_WIDGET (cur->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cur->data)), ((ctk_widget_get_type ()))))))
);
2421 last = NULL((void*)0);
2422 visible = FALSE(0);
2423 break;
2424 case SEPARATOR_MODE_HIDDEN:
2425 ctk_widget_hide (CTK_WIDGET (cur->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cur->data)), ((ctk_widget_get_type ()))))))
);
2426 break;
2427 case SEPARATOR_MODE_SMART:
2428 if (visible)
2429 {
2430 ctk_widget_show (CTK_WIDGET (cur->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cur->data)), ((ctk_widget_get_type ()))))))
);
2431 last = cur;
2432 visible = FALSE(0);
2433 }
2434 else
2435 ctk_widget_hide (CTK_WIDGET (cur->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cur->data)), ((ctk_widget_get_type ()))))))
);
2436 break;
2437 }
2438 }
2439 else if (ctk_widget_get_visible (cur->data))
2440 {
2441 last = NULL((void*)0);
2442
2443 if (CTK_IS_TEAROFF_MENU_ITEM (cur->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cur->data)); GType __t = ((ctk_tearoff_menu_item_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; }))))
|| cur->data == filler)
2444 visible = FALSE(0);
2445 else
2446 {
2447 visible = TRUE(!(0));
2448 empty = FALSE(0);
2449 }
2450
2451 }
2452
2453 cur = cur->next;
2454 }
2455
2456 if (last)
2457 ctk_widget_hide (CTK_WIDGET (last->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((last->data)), ((ctk_widget_get_type ()))))))
);
2458
2459 if (CTK_IS_MENU (parent)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(parent)); GType __t = ((ctk_menu_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; }))))
)
2460 {
2461 CtkWidget *item;
2462
2463 item = ctk_menu_get_attach_widget (CTK_MENU (parent)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_menu_get_type ()))))))
);
2464 if (CTK_IS_MENU_ITEM (item)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(item)); GType __t = ((ctk_menu_item_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; }))))
)
2465 _ctk_action_sync_menu_visible (NULL((void*)0), item, empty);
2466 if (CTK_IS_WIDGET (filler)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(filler)); GType __t = ((ctk_widget_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; }))))
)
2467 {
2468 if (empty)
2469 ctk_widget_show (filler);
2470 else
2471 ctk_widget_hide (filler);
2472 }
2473 }
2474
2475 g_list_free (children);
2476 }
2477}
2478
2479static void
2480update_node (CtkUIManager *manager,
2481 GNode *node,
2482 gboolean in_popup,
2483 gboolean popup_accels)
2484{
2485 Node *info;
2486 GNode *child;
2487 CtkAction *action;
2488 const gchar *action_name;
2489 NodeUIReference *ref;
2490
2491 g_return_if_fail (node != NULL)do { if ((node != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "node != NULL"); return;
} } while (0)
;
2492 g_return_if_fail (NODE_INFO (node) != NULL)do { if ((((Node *)node->data) != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "NODE_INFO (node) != NULL"
); return; } } while (0)
;
2493
2494 info = NODE_INFO (node)((Node *)node->data);
2495
2496 if (!info->dirty)
2497 return;
2498
2499 if (info->type == NODE_TYPE_POPUP)
2500 {
2501 in_popup = TRUE(!(0));
2502 popup_accels = info->popup_accels;
2503 }
2504
2505 if (info->uifiles == NULL((void*)0)) {
2506 /* We may need to remove this node.
2507 * This must be done in post order
2508 */
2509 goto recurse_children;
2510 }
2511
2512 ref = info->uifiles->data;
2513 action_name = g_quark_to_string (ref->action_quark);
2514 action = get_action_by_name (manager, action_name);
2515
2516 info->dirty = FALSE(0);
2517
2518 /* Check if the node doesn't have an action and must have an action */
2519 if (action == NULL((void*)0) &&
2520 info->type != NODE_TYPE_ROOT &&
2521 info->type != NODE_TYPE_MENUBAR &&
2522 info->type != NODE_TYPE_TOOLBAR &&
2523 info->type != NODE_TYPE_POPUP &&
2524 info->type != NODE_TYPE_SEPARATOR &&
2525 info->type != NODE_TYPE_MENU_PLACEHOLDER &&
2526 info->type != NODE_TYPE_TOOLBAR_PLACEHOLDER)
2527 {
2528 g_warning ("%s: missing action %s", info->name, action_name);
2529
2530 return;
2531 }
2532
2533 if (action)
2534 ctk_action_set_accel_group (action, manager->private_data->accel_group);
2535
2536 /* If the widget already has a proxy and the action hasn't changed, then
2537 * we only have to update the tearoff menu items.
2538 */
2539 if (info->proxy != NULL((void*)0) && action == info->action)
2540 {
2541 if (info->type == NODE_TYPE_MENU)
2542 {
2543 CtkWidget *menu;
2544 GList *siblings;
2545
2546 if (CTK_IS_MENU (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_menu_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; }))))
)
2547 menu = info->proxy;
2548 else
2549 menu = ctk_menu_item_get_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
);
2550 siblings = ctk_container_get_children (CTK_CONTAINER (menu)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_container_get_type ()))))))
);
2551
2552 if (siblings != NULL((void*)0) && CTK_IS_TEAROFF_MENU_ITEM (siblings->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(siblings->data)); GType __t = ((ctk_tearoff_menu_item_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; }))))
)
2553 {
2554 if (manager->private_data->add_tearoffs && !in_popup)
2555 ctk_widget_show (CTK_WIDGET (siblings->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((siblings->data)), ((ctk_widget_get_type ()))))))
);
2556 else
2557 ctk_widget_hide (CTK_WIDGET (siblings->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((siblings->data)), ((ctk_widget_get_type ()))))))
);
2558 }
2559
2560 g_list_free (siblings);
2561 }
2562
2563 goto recurse_children;
2564 }
2565
2566 switch (info->type)
2567 {
2568 case NODE_TYPE_MENUBAR:
2569 if (info->proxy == NULL((void*)0))
2570 {
2571 info->proxy = ctk_menu_bar_new ();
2572 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2573 ctk_widget_set_name (info->proxy, info->name);
2574 ctk_widget_show (info->proxy);
2575 g_signal_emit (manager, ui_manager_signals[ADD_WIDGET], 0, info->proxy);
2576 }
2577 break;
2578 case NODE_TYPE_POPUP:
2579 if (info->proxy == NULL((void*)0))
2580 {
2581 info->proxy = ctk_menu_new ();
2582 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2583 }
2584 ctk_widget_set_name (info->proxy, info->name);
2585 break;
2586 case NODE_TYPE_MENU:
2587 {
2588 CtkWidget *prev_submenu = NULL((void*)0);
2589 CtkWidget *menu = NULL((void*)0);
2590 GList *siblings;
2591
2592 /* remove the proxy if it is of the wrong type ... */
2593 if (info->proxy &&
2594 G_OBJECT_TYPE (info->proxy)(((((GTypeClass*) (((GTypeInstance*) (info->proxy))->g_class
))->g_type)))
!= CTK_ACTION_GET_CLASS (action)((((CtkActionClass*) (((GTypeInstance*) ((action)))->g_class
))))
->menu_item_type)
2595 {
2596 if (CTK_IS_MENU_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_menu_item_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; }
))))
)
2597 {
2598 prev_submenu = ctk_menu_item_get_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
);
2599 if (prev_submenu)
2600 {
2601 g_object_ref (prev_submenu)((__typeof__ (prev_submenu)) (g_object_ref) (prev_submenu));
2602 ctk_menu_item_set_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
, NULL((void*)0));
2603 }
2604 }
2605
2606 ctk_activatable_set_related_action (CTK_ACTIVATABLE (info->proxy)((((CtkActivatable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_activatable_get_type ()))))))
, NULL((void*)0));
2607 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2608 info->proxy);
2609 g_object_unref (info->proxy);
2610 info->proxy = NULL((void*)0);
2611 }
2612
2613 /* create proxy if needed ... */
2614 if (info->proxy == NULL((void*)0))
2615 {
2616 /* ... if the action already provides a menu, then use
2617 * that menu instead of creating an empty one
2618 */
2619 if ((NODE_INFO (node->parent)((Node *)node->parent->data)->type == NODE_TYPE_TOOLITEM ||
2620 NODE_INFO (node->parent)((Node *)node->parent->data)->type == NODE_TYPE_MENUITEM) &&
2621 CTK_ACTION_GET_CLASS (action)((((CtkActionClass*) (((GTypeInstance*) ((action)))->g_class
))))
->create_menu)
2622 {
2623 menu = ctk_action_create_menu (action);
2624 }
2625
2626 if (!menu)
2627 {
2628 CtkWidget *tearoff;
2629 CtkWidget *filler;
2630
2631 menu = ctk_menu_new ();
2632 ctk_widget_set_name (menu, info->name);
2633
2634 tearoff = ctk_tearoff_menu_item_new ();
2635
2636 ctk_widget_set_no_show_all (tearoff, TRUE(!(0)));
2637 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, tearoff);
2638 filler = ctk_menu_item_new_with_label (_("Empty")((char *) g_dgettext ("ctk30", "Empty")));
2639 g_object_set_data (G_OBJECT (filler)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((filler)), (((GType) ((20) << (2))))))))
,
2640 I_("ctk-empty-menu-item")g_intern_static_string ("ctk-empty-menu-item"),
2641 GINT_TO_POINTER (TRUE)((gpointer) (glong) ((!(0)))));
2642 ctk_widget_set_sensitive (filler, FALSE(0));
2643 ctk_widget_set_no_show_all (filler, TRUE(!(0)));
2644 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, filler);
2645 }
2646
2647 if (NODE_INFO (node->parent)((Node *)node->parent->data)->type == NODE_TYPE_TOOLITEM)
2648 {
2649 info->proxy = menu;
2650 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2651 ctk_menu_tool_button_set_menu (CTK_MENU_TOOL_BUTTON (NODE_INFO (node->parent)->proxy)((((CtkMenuToolButton*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((Node *)node->parent->data)->proxy
)), ((ctk_menu_tool_button_get_type ()))))))
,
2652 menu);
2653 }
2654 else
2655 {
2656 CtkWidget *menushell;
2657 gint pos;
2658
2659 if (find_menu_position (node, &menushell, &pos))
2660 {
2661 info->proxy = ctk_action_create_menu_item (action);
2662 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2663 g_signal_connect (info->proxy, "notify::visible",g_signal_connect_data ((info->proxy), ("notify::visible"),
(((GCallback) (update_smart_separators))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
2664 G_CALLBACK (update_smart_separators), NULL)g_signal_connect_data ((info->proxy), ("notify::visible"),
(((GCallback) (update_smart_separators))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
;
2665 ctk_widget_set_name (info->proxy, info->name);
2666
2667 ctk_menu_item_set_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
, menu);
2668 ctk_menu_shell_insert (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
, info->proxy, pos);
2669 }
2670 }
2671 }
2672 else
2673 ctk_activatable_set_related_action (CTK_ACTIVATABLE (info->proxy)((((CtkActivatable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_activatable_get_type ()))))))
, action);
2674
2675 if (prev_submenu)
2676 {
2677 ctk_menu_item_set_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
,
2678 prev_submenu);
2679 g_object_unref (prev_submenu);
2680 }
2681
2682 if (CTK_IS_MENU (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_menu_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; }))))
)
2683 menu = info->proxy;
2684 else
2685 menu = ctk_menu_item_get_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
);
2686
2687 siblings = ctk_container_get_children (CTK_CONTAINER (menu)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_container_get_type ()))))))
);
2688
2689 if (siblings != NULL((void*)0) && CTK_IS_TEAROFF_MENU_ITEM (siblings->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(siblings->data)); GType __t = ((ctk_tearoff_menu_item_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; }))))
)
2690 {
2691 if (manager->private_data->add_tearoffs && !in_popup)
2692 ctk_widget_show (CTK_WIDGET (siblings->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((siblings->data)), ((ctk_widget_get_type ()))))))
);
2693 else
2694 ctk_widget_hide (CTK_WIDGET (siblings->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((siblings->data)), ((ctk_widget_get_type ()))))))
);
2695 }
2696
2697 g_list_free (siblings);
2698 }
2699 break;
2700 case NODE_TYPE_UNDECIDED:
2701 g_warning ("found undecided node!");
2702 break;
2703 case NODE_TYPE_ROOT:
2704 break;
2705 case NODE_TYPE_TOOLBAR:
2706 if (info->proxy == NULL((void*)0))
2707 {
2708 info->proxy = ctk_toolbar_new ();
2709 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2710 ctk_widget_set_name (info->proxy, info->name);
2711 ctk_widget_show (info->proxy);
2712 g_signal_emit (manager, ui_manager_signals[ADD_WIDGET], 0, info->proxy);
2713 }
2714 break;
2715 case NODE_TYPE_MENU_PLACEHOLDER:
2716 /* create menu items for placeholders if necessary ... */
2717 if (!CTK_IS_SEPARATOR_MENU_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_separator_menu_item_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; }))))
||
2718 !CTK_IS_SEPARATOR_MENU_ITEM (info->extra)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->extra)); GType __t = ((ctk_separator_menu_item_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; }))))
)
2719 {
2720 if (info->proxy)
2721 {
2722 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2723 info->proxy);
2724 g_object_unref (info->proxy);
2725 info->proxy = NULL((void*)0);
2726 }
2727 if (info->extra)
2728 {
2729 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->extra))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->extra))), ((ctk_container_get_type
()))))))
,
2730 info->extra);
2731 g_object_unref (info->extra);
2732 info->extra = NULL((void*)0);
2733 }
2734 }
2735 if (info->proxy == NULL((void*)0))
2736 {
2737 CtkWidget *menushell;
2738 gint pos;
2739
2740 if (find_menu_position (node, &menushell, &pos))
2741 {
2742 info->proxy = ctk_separator_menu_item_new ();
2743 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2744 g_object_set_data (G_OBJECT (info->proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), (((GType) ((20) << (2))))))))
,
2745 I_("ctk-separator-mode")g_intern_static_string ("ctk-separator-mode"),
2746 GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)((gpointer) (glong) (SEPARATOR_MODE_HIDDEN)));
2747 ctk_widget_set_no_show_all (info->proxy, TRUE(!(0)));
2748 ctk_menu_shell_insert (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
,
2749 NODE_INFO (node)((Node *)node->data)->proxy, pos);
2750
2751 info->extra = ctk_separator_menu_item_new ();
2752 g_object_ref_sink (info->extra)((__typeof__ (info->extra)) (g_object_ref_sink) (info->
extra))
;
2753 g_object_set_data (G_OBJECT (info->extra)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->extra)), (((GType) ((20) << (2))))))))
,
2754 I_("ctk-separator-mode")g_intern_static_string ("ctk-separator-mode"),
2755 GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)((gpointer) (glong) (SEPARATOR_MODE_HIDDEN)));
2756 ctk_widget_set_no_show_all (info->extra, TRUE(!(0)));
2757 ctk_menu_shell_insert (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
,
2758 NODE_INFO (node)((Node *)node->data)->extra, pos + 1);
2759 }
2760 }
2761 break;
2762 case NODE_TYPE_TOOLBAR_PLACEHOLDER:
2763 /* create toolbar items for placeholders if necessary ... */
2764 if (!CTK_IS_SEPARATOR_TOOL_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_separator_tool_item_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; }))))
||
2765 !CTK_IS_SEPARATOR_TOOL_ITEM (info->extra)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->extra)); GType __t = ((ctk_separator_tool_item_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; }))))
)
2766 {
2767 if (info->proxy)
2768 {
2769 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2770 info->proxy);
2771 g_object_unref (info->proxy);
2772 info->proxy = NULL((void*)0);
2773 }
2774 if (info->extra)
2775 {
2776 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->extra))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->extra))), ((ctk_container_get_type
()))))))
,
2777 info->extra);
2778 g_object_unref (info->extra);
2779 info->extra = NULL((void*)0);
2780 }
2781 }
2782 if (info->proxy == NULL((void*)0))
2783 {
2784 CtkWidget *toolbar;
2785 gint pos;
2786 CtkToolItem *item;
2787
2788 if (find_toolbar_position (node, &toolbar, &pos))
2789 {
2790 item = ctk_separator_tool_item_new ();
2791 ctk_toolbar_insert (CTK_TOOLBAR (toolbar)((((CtkToolbar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_toolbar_get_type ()))))))
, item, pos);
2792 info->proxy = CTK_WIDGET (item)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_widget_get_type ()))))))
;
2793 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2794 g_object_set_data (G_OBJECT (info->proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), (((GType) ((20) << (2))))))))
,
2795 I_("ctk-separator-mode")g_intern_static_string ("ctk-separator-mode"),
2796 GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)((gpointer) (glong) (SEPARATOR_MODE_HIDDEN)));
2797 ctk_widget_set_no_show_all (info->proxy, TRUE(!(0)));
2798
2799 item = ctk_separator_tool_item_new ();
2800 ctk_toolbar_insert (CTK_TOOLBAR (toolbar)((((CtkToolbar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_toolbar_get_type ()))))))
, item, pos+1);
2801 info->extra = CTK_WIDGET (item)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_widget_get_type ()))))))
;
2802 g_object_ref_sink (info->extra)((__typeof__ (info->extra)) (g_object_ref_sink) (info->
extra))
;
2803 g_object_set_data (G_OBJECT (info->extra)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->extra)), (((GType) ((20) << (2))))))))
,
2804 I_("ctk-separator-mode")g_intern_static_string ("ctk-separator-mode"),
2805 GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN)((gpointer) (glong) (SEPARATOR_MODE_HIDDEN)));
2806 ctk_widget_set_no_show_all (info->extra, TRUE(!(0)));
2807 }
2808 }
2809 break;
2810 case NODE_TYPE_MENUITEM:
2811 /* remove the proxy if it is of the wrong type ... */
2812 if (info->proxy &&
2813 G_OBJECT_TYPE (info->proxy)(((((GTypeClass*) (((GTypeInstance*) (info->proxy))->g_class
))->g_type)))
!= CTK_ACTION_GET_CLASS (action)((((CtkActionClass*) (((GTypeInstance*) ((action)))->g_class
))))
->menu_item_type)
2814 {
2815 g_signal_handlers_disconnect_by_func (info->proxy,g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2816 G_CALLBACK (update_smart_separators),g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2817 NULL)g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
;
2818 ctk_activatable_set_related_action (CTK_ACTIVATABLE (info->proxy)((((CtkActivatable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_activatable_get_type ()))))))
, NULL((void*)0));
2819 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2820 info->proxy);
2821 g_object_unref (info->proxy);
2822 info->proxy = NULL((void*)0);
2823 }
2824 /* create proxy if needed ... */
2825 if (info->proxy == NULL((void*)0))
2826 {
2827 CtkWidget *menushell;
2828 gint pos;
2829
2830 if (find_menu_position (node, &menushell, &pos))
2831 {
2832 info->proxy = ctk_action_create_menu_item (action);
2833 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2834 ctk_widget_set_name (info->proxy, info->name);
2835
2836 if (info->always_show_image_set &&
2837 CTK_IS_IMAGE_MENU_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_image_menu_item_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; }))))
)
2838 ctk_image_menu_item_set_always_show_image (CTK_IMAGE_MENU_ITEM (info->proxy)((((CtkImageMenuItem*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((info->proxy)), ((ctk_image_menu_item_get_type
()))))))
,
2839 info->always_show_image);
2840
2841 ctk_menu_shell_insert (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
,
2842 info->proxy, pos);
2843 }
2844 }
2845 else
2846 {
2847 g_signal_handlers_disconnect_by_func (info->proxy,g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2848 G_CALLBACK (update_smart_separators),g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2849 NULL)g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
;
2850 ctk_menu_item_set_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
, NULL((void*)0));
2851 ctk_activatable_set_related_action (CTK_ACTIVATABLE (info->proxy)((((CtkActivatable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_activatable_get_type ()))))))
, action);
2852 }
2853
2854 if (info->proxy)
2855 {
2856 g_signal_connect (info->proxy, "notify::visible",g_signal_connect_data ((info->proxy), ("notify::visible"),
(((GCallback) (update_smart_separators))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
2857 G_CALLBACK (update_smart_separators), NULL)g_signal_connect_data ((info->proxy), ("notify::visible"),
(((GCallback) (update_smart_separators))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
;
2858 if (in_popup && !popup_accels)
2859 {
2860 /* don't show accels in popups */
2861 CtkWidget *c = ctk_bin_get_child (CTK_BIN (info->proxy)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_bin_get_type ()))))))
);
2862 if (CTK_IS_ACCEL_LABEL (c)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(c)); GType __t = ((ctk_accel_label_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; }))))
)
2863 g_object_set (c, "accel-closure", NULL((void*)0), NULL((void*)0));
2864 }
2865 }
2866
2867 break;
2868 case NODE_TYPE_TOOLITEM:
2869 /* remove the proxy if it is of the wrong type ... */
2870 if (info->proxy &&
2871 G_OBJECT_TYPE (info->proxy)(((((GTypeClass*) (((GTypeInstance*) (info->proxy))->g_class
))->g_type)))
!= CTK_ACTION_GET_CLASS (action)((((CtkActionClass*) (((GTypeInstance*) ((action)))->g_class
))))
->toolbar_item_type)
2872 {
2873 g_signal_handlers_disconnect_by_func (info->proxy,g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2874 G_CALLBACK (update_smart_separators),g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2875 NULL)g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
;
2876 ctk_activatable_set_related_action (CTK_ACTIVATABLE (info->proxy)((((CtkActivatable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_activatable_get_type ()))))))
, NULL((void*)0));
2877 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2878 info->proxy);
2879 g_object_unref (info->proxy);
2880 info->proxy = NULL((void*)0);
2881 }
2882 /* create proxy if needed ... */
2883 if (info->proxy == NULL((void*)0))
2884 {
2885 CtkWidget *toolbar;
2886 gint pos;
2887
2888 if (find_toolbar_position (node, &toolbar, &pos))
2889 {
2890 info->proxy = ctk_action_create_tool_item (action);
2891 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2892 ctk_widget_set_name (info->proxy, info->name);
2893
2894 ctk_toolbar_insert (CTK_TOOLBAR (toolbar)((((CtkToolbar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_toolbar_get_type ()))))))
,
2895 CTK_TOOL_ITEM (info->proxy)((((CtkToolItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_tool_item_get_type ()))))))
, pos);
2896 }
2897 }
2898 else
2899 {
2900 g_signal_handlers_disconnect_by_func (info->proxy,g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2901 G_CALLBACK (update_smart_separators),g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
2902 NULL)g_signal_handlers_disconnect_matched ((info->proxy), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (update_smart_separators))), (((void*)0)))
;
2903 ctk_activatable_set_related_action (CTK_ACTIVATABLE (info->proxy)((((CtkActivatable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_activatable_get_type ()))))))
, action);
2904 }
2905
2906 if (info->proxy)
2907 {
2908 g_signal_connect (info->proxy, "notify::visible",g_signal_connect_data ((info->proxy), ("notify::visible"),
(((GCallback) (update_smart_separators))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
2909 G_CALLBACK (update_smart_separators), NULL)g_signal_connect_data ((info->proxy), ("notify::visible"),
(((GCallback) (update_smart_separators))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
;
2910 }
2911 break;
2912 case NODE_TYPE_SEPARATOR:
2913 if (NODE_INFO (node->parent)((Node *)node->parent->data)->type == NODE_TYPE_TOOLBAR ||
2914 NODE_INFO (node->parent)((Node *)node->parent->data)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER)
2915 {
2916 CtkWidget *toolbar;
2917 gint pos;
2918 gint separator_mode;
2919 CtkToolItem *item;
2920
2921 if (CTK_IS_SEPARATOR_TOOL_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_separator_tool_item_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; }))))
)
2922 {
2923 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2924 info->proxy);
2925 g_object_unref (info->proxy);
2926 info->proxy = NULL((void*)0);
2927 }
2928
2929 if (find_toolbar_position (node, &toolbar, &pos))
2930 {
2931 item = ctk_separator_tool_item_new ();
2932 ctk_toolbar_insert (CTK_TOOLBAR (toolbar)((((CtkToolbar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toolbar)), ((ctk_toolbar_get_type ()))))))
, item, pos);
2933 info->proxy = CTK_WIDGET (item)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_widget_get_type ()))))))
;
2934 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2935 ctk_widget_set_no_show_all (info->proxy, TRUE(!(0)));
2936 if (info->expand)
2937 {
2938 ctk_tool_item_set_expand (CTK_TOOL_ITEM (item)((((CtkToolItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((item)), ((ctk_tool_item_get_type ()))))))
, TRUE(!(0)));
2939 ctk_separator_tool_item_set_draw (CTK_SEPARATOR_TOOL_ITEM (item)((((CtkSeparatorToolItem*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((item)), ((ctk_separator_tool_item_get_type
()))))))
, FALSE(0));
2940 separator_mode = SEPARATOR_MODE_VISIBLE;
2941 }
2942 else
2943 separator_mode = SEPARATOR_MODE_SMART;
2944
2945 g_object_set_data (G_OBJECT (info->proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), (((GType) ((20) << (2))))))))
,
2946 I_("ctk-separator-mode")g_intern_static_string ("ctk-separator-mode"),
2947 GINT_TO_POINTER (separator_mode)((gpointer) (glong) (separator_mode)));
2948 ctk_widget_show (info->proxy);
2949 }
2950 }
2951 else
2952 {
2953 CtkWidget *menushell;
2954 gint pos;
2955
2956 if (CTK_IS_SEPARATOR_MENU_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_separator_menu_item_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; }))))
)
2957 {
2958 ctk_container_remove (CTK_CONTAINER (ctk_widget_get_parent (info->proxy))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (info->proxy))), ((ctk_container_get_type
()))))))
,
2959 info->proxy);
2960 g_object_unref (info->proxy);
2961 info->proxy = NULL((void*)0);
2962 }
2963
2964 if (find_menu_position (node, &menushell, &pos))
2965 {
2966 info->proxy = ctk_separator_menu_item_new ();
2967 g_object_ref_sink (info->proxy)((__typeof__ (info->proxy)) (g_object_ref_sink) (info->
proxy))
;
2968 ctk_widget_set_no_show_all (info->proxy, TRUE(!(0)));
2969 g_object_set_data (G_OBJECT (info->proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), (((GType) ((20) << (2))))))))
,
2970 I_("ctk-separator-mode")g_intern_static_string ("ctk-separator-mode"),
2971 GINT_TO_POINTER (SEPARATOR_MODE_SMART)((gpointer) (glong) (SEPARATOR_MODE_SMART)));
2972 ctk_menu_shell_insert (CTK_MENU_SHELL (menushell)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menushell)), ((ctk_menu_shell_get_type ()))))))
,
2973 info->proxy, pos);
2974 ctk_widget_show (info->proxy);
2975 }
2976 }
2977 break;
2978 case NODE_TYPE_ACCELERATOR:
2979 ctk_action_connect_accelerator (action);
2980 break;
2981 }
2982
2983 if (action)
2984 g_object_ref (action)((__typeof__ (action)) (g_object_ref) (action));
2985 if (info->action)
2986 g_object_unref (info->action);
2987 info->action = action;
2988
2989 recurse_children:
2990 /* process children */
2991 child = node->children;
2992 while (child)
2993 {
2994 GNode *current;
2995
2996 current = child;
2997 child = current->next;
2998 update_node (manager, current, in_popup, popup_accels);
2999 }
3000
3001 if (info->proxy)
3002 {
3003 if (info->type == NODE_TYPE_MENU && CTK_IS_MENU_ITEM (info->proxy)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(info->proxy)); GType __t = ((ctk_menu_item_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; }
))))
)
3004 update_smart_separators (ctk_menu_item_get_submenu (CTK_MENU_ITEM (info->proxy)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->proxy)), ((ctk_menu_item_get_type ()))))))
));
3005 else if (info->type == NODE_TYPE_MENU ||
3006 info->type == NODE_TYPE_TOOLBAR ||
3007 info->type == NODE_TYPE_POPUP)
3008 update_smart_separators (info->proxy);
3009 }
3010
3011 /* handle cleanup of dead nodes */
3012 if (node->children == NULL((void*)0) && info->uifiles == NULL((void*)0))
3013 {
3014 if (info->proxy)
3015 ctk_widget_destroy (info->proxy);
3016 if (info->extra)
3017 ctk_widget_destroy (info->extra);
3018 if (info->type == NODE_TYPE_ACCELERATOR && info->action != NULL((void*)0))
3019 ctk_action_disconnect_accelerator (info->action);
3020 free_node (node);
3021 g_node_destroy (node);
3022 }
3023}
3024
3025static gboolean
3026do_updates (CtkUIManager *manager)
3027{
3028 /* this function needs to check through the tree for dirty nodes.
3029 * For such nodes, it needs to do the following:
3030 *
3031 * 1) check if they are referenced by any loaded UI files anymore.
3032 * In which case, the proxy widget should be destroyed, unless
3033 * there are any subnodes.
3034 *
3035 * 2) lookup the action for this node again. If it is different to
3036 * the current one (or if no previous action has been looked up),
3037 * the proxy is reconnected to the new action (or a new proxy widget
3038 * is created and added to the parent container).
3039 */
3040 update_node (manager, manager->private_data->root_node, FALSE(0), FALSE(0));
3041
3042 manager->private_data->update_tag = 0;
3043
3044 return FALSE(0);
3045}
3046
3047static gboolean
3048do_updates_idle (CtkUIManager *manager)
3049{
3050 do_updates (manager);
3051
3052 return FALSE(0);
3053}
3054
3055static void
3056queue_update (CtkUIManager *manager)
3057{
3058 if (manager->private_data->update_tag != 0)
3059 return;
3060
3061 manager->private_data->update_tag = cdk_threads_add_idle (
3062 (GSourceFunc)do_updates_idle,
3063 manager);
3064 g_source_set_name_by_id (manager->private_data->update_tag, "[ctk+] do_updates_idle");
3065}
3066
3067
3068/**
3069 * ctk_ui_manager_ensure_update:
3070 * @manager: a #CtkUIManager
3071 *
3072 * Makes sure that all pending updates to the UI have been completed.
3073 *
3074 * This may occasionally be necessary, since #CtkUIManager updates the
3075 * UI in an idle function. A typical example where this function is
3076 * useful is to enforce that the menubar and toolbar have been added to
3077 * the main window before showing it:
3078 * |[<!-- language="C" -->
3079 * ctk_container_add (CTK_CONTAINER (window), vbox);
3080 * g_signal_connect (merge, "add-widget",
3081 * G_CALLBACK (add_widget), vbox);
3082 * ctk_ui_manager_add_ui_from_file (merge, "my-menus");
3083 * ctk_ui_manager_add_ui_from_file (merge, "my-toolbars");
3084 * ctk_ui_manager_ensure_update (merge);
3085 * ctk_widget_show (window);
3086 * ]|
3087 *
3088 * Since: 2.4
3089 **/
3090void
3091ctk_ui_manager_ensure_update (CtkUIManager *manager)
3092{
3093 if (manager->private_data->update_tag != 0)
3094 {
3095 g_source_remove (manager->private_data->update_tag);
3096 do_updates (manager);
3097 }
3098}
3099
3100static gboolean
3101dirty_traverse_func (GNode *node,
3102 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
3103{
3104 NODE_INFO (node)((Node *)node->data)->dirty = TRUE(!(0));
3105 return FALSE(0);
3106}
3107
3108static void
3109dirty_all_nodes (CtkUIManager *manager)
3110{
3111 g_node_traverse (manager->private_data->root_node,
3112 G_PRE_ORDER, G_TRAVERSE_ALL, -1,
3113 dirty_traverse_func, NULL((void*)0));
3114 queue_update (manager);
3115}
3116
3117static void
3118mark_node_dirty (GNode *node)
3119{
3120 GNode *p;
3121
3122 /* FIXME could optimize this */
3123 for (p = node; p; p = p->parent)
3124 NODE_INFO (p)((Node *)p->data)->dirty = TRUE(!(0));
3125}
3126
3127static void
3128print_node (CtkUIManager *manager,
3129 GNode *node,
3130 gint indent_level,
3131 GString *buffer)
3132{
3133 Node *mnode;
3134 GNode *child;
3135
3136 mnode = node->data;
3137
3138 switch (mnode->type)
3139 {
3140 case NODE_TYPE_UNDECIDED:
3141 g_string_append_printf (buffer, "%*s<UNDECIDED", indent_level, "");
3142 break;
3143 case NODE_TYPE_ROOT:
3144 g_string_append_printf (buffer, "%*s<ui", indent_level, "");
3145 break;
3146 case NODE_TYPE_MENUBAR:
3147 g_string_append_printf (buffer, "%*s<menubar", indent_level, "");
3148 break;
3149 case NODE_TYPE_MENU:
3150 g_string_append_printf (buffer, "%*s<menu", indent_level, "");
3151 break;
3152 case NODE_TYPE_TOOLBAR:
3153 g_string_append_printf (buffer, "%*s<toolbar", indent_level, "");
3154 break;
3155 case NODE_TYPE_MENU_PLACEHOLDER:
3156 case NODE_TYPE_TOOLBAR_PLACEHOLDER:
3157 g_string_append_printf (buffer, "%*s<placeholder", indent_level, "");
3158 break;
3159 case NODE_TYPE_POPUP:
3160 g_string_append_printf (buffer, "%*s<popup", indent_level, "");
3161 break;
3162 case NODE_TYPE_MENUITEM:
3163 g_string_append_printf (buffer, "%*s<menuitem", indent_level, "");
3164 break;
3165 case NODE_TYPE_TOOLITEM:
3166 g_string_append_printf (buffer, "%*s<toolitem", indent_level, "");
3167 break;
3168 case NODE_TYPE_SEPARATOR:
3169 g_string_append_printf (buffer, "%*s<separator", indent_level, "");
3170 break;
3171 case NODE_TYPE_ACCELERATOR:
3172 g_string_append_printf (buffer, "%*s<accelerator", indent_level, "");
3173 break;
3174 default:
3175 ;; /* Nothing */
3176 }
3177
3178 if (mnode->type != NODE_TYPE_ROOT)
3179 {
3180 if (mnode->name)
3181 g_string_append_printf (buffer, " name=\"%s\"", mnode->name);
3182
3183 if (mnode->action_name)
3184 g_string_append_printf (buffer, " action=\"%s\"",
3185 g_quark_to_string (mnode->action_name));
3186 }
3187
3188 switch (mnode->type)
3189 {
3190 case NODE_TYPE_UNDECIDED:
3191 case NODE_TYPE_ROOT:
3192 case NODE_TYPE_MENUBAR:
3193 case NODE_TYPE_MENU:
3194 case NODE_TYPE_TOOLBAR:
3195 case NODE_TYPE_MENU_PLACEHOLDER:
3196 case NODE_TYPE_TOOLBAR_PLACEHOLDER:
3197 case NODE_TYPE_POPUP:
3198 g_string_append (buffer, ">\n")(__builtin_constant_p (">\n") ? __extension__ ({ const char
* const __val = (">\n"); g_string_append_len_inline (buffer
, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !
(__val))) : (gssize) -1); }) : g_string_append_len_inline (buffer
, ">\n", (gssize) -1))
;
3199 break;
3200 default:
3201 g_string_append (buffer, "/>\n")(__builtin_constant_p ("/>\n") ? __extension__ ({ const char
* const __val = ("/>\n"); g_string_append_len_inline (buffer
, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !
(__val))) : (gssize) -1); }) : g_string_append_len_inline (buffer
, "/>\n", (gssize) -1))
;
3202 break;
3203 }
3204
3205 for (child = node->children; child != NULL((void*)0); child = child->next)
3206 print_node (manager, child, indent_level + 2, buffer);
3207
3208 switch (mnode->type)
3209 {
3210 case NODE_TYPE_UNDECIDED:
3211 g_string_append_printf (buffer, "%*s</UNDECIDED>\n", indent_level, "");
3212 break;
3213 case NODE_TYPE_ROOT:
3214 g_string_append_printf (buffer, "%*s</ui>\n", indent_level, "");
3215 break;
3216 case NODE_TYPE_MENUBAR:
3217 g_string_append_printf (buffer, "%*s</menubar>\n", indent_level, "");
3218 break;
3219 case NODE_TYPE_MENU:
3220 g_string_append_printf (buffer, "%*s</menu>\n", indent_level, "");
3221 break;
3222 case NODE_TYPE_TOOLBAR:
3223 g_string_append_printf (buffer, "%*s</toolbar>\n", indent_level, "");
3224 break;
3225 case NODE_TYPE_MENU_PLACEHOLDER:
3226 case NODE_TYPE_TOOLBAR_PLACEHOLDER:
3227 g_string_append_printf (buffer, "%*s</placeholder>\n", indent_level, "");
3228 break;
3229 case NODE_TYPE_POPUP:
3230 g_string_append_printf (buffer, "%*s</popup>\n", indent_level, "");
3231 break;
3232 default:
3233 ;; /* Nothing */
3234 }
3235}
3236
3237static gboolean
3238ctk_ui_manager_buildable_custom_tag_start (CtkBuildable *buildable,
3239 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
3240 GObject *child,
3241 const gchar *tagname,
3242 GMarkupParser *parser,
3243 gpointer *data)
3244{
3245 if (child)
3246 return FALSE(0);
3247
3248 if (strcmp (tagname, "ui") == 0)
3249 {
3250 ParseContext *ctx;
3251
3252 ctx = g_new0 (ParseContext, 1)((ParseContext *) g_malloc0_n ((1), sizeof (ParseContext)));
3253 ctx->state = STATE_START;
3254 ctx->manager = CTK_UI_MANAGER (buildable)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_ui_manager_get_type ()))))))
;
3255 ctx->current = NULL((void*)0);
3256 ctx->merge_id = ctk_ui_manager_new_merge_id (CTK_UI_MANAGER (buildable)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_ui_manager_get_type ()))))))
);
3257
3258 *data = ctx;
3259 *parser = ui_parser;
3260
3261 return TRUE(!(0));
3262 }
3263
3264 return FALSE(0);
3265
3266}
3267
3268static void
3269ctk_ui_manager_buildable_custom_tag_end (CtkBuildable *buildable,
3270 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
3271 GObject *child G_GNUC_UNUSED__attribute__ ((__unused__)),
3272 const gchar *tagname G_GNUC_UNUSED__attribute__ ((__unused__)),
3273 gpointer *data)
3274{
3275 queue_update (CTK_UI_MANAGER (buildable)((((CtkUIManager*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_ui_manager_get_type ()))))))
);
3276 g_object_notify (G_OBJECT (buildable)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), (((GType) ((20) << (2))))))))
, "ui");
3277 g_free (data);
3278}
3279
3280/**
3281 * ctk_ui_manager_get_ui:
3282 * @manager: a #CtkUIManager
3283 *
3284 * Creates a [UI definition][XML-UI] of the merged UI.
3285 *
3286 * Returns: A newly allocated string containing an XML representation of
3287 * the merged UI.
3288 *
3289 * Since: 2.4
3290 **/
3291gchar *
3292ctk_ui_manager_get_ui (CtkUIManager *manager)
3293{
3294 GString *buffer;
3295
3296 buffer = g_string_new (NULL((void*)0));
3297
3298 ctk_ui_manager_ensure_update (manager);
3299
3300 print_node (manager, manager->private_data->root_node, 0, buffer);
3301
3302 return g_string_free (buffer, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((buffer
), ((0))) : g_string_free_and_steal (buffer)) : (g_string_free
) ((buffer), ((0))))
;
3303}