1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.UIManager;
26 
27 private import glib.ConstructionException;
28 private import glib.ErrorG;
29 private import glib.GException;
30 private import glib.ListG;
31 private import glib.ListSG;
32 private import glib.Str;
33 private import gobject.ObjectG;
34 private import gobject.Signals;
35 private import gobject.Type;
36 private import gtk.AccelGroup;
37 private import gtk.Action;
38 private import gtk.ActionGroup;
39 private import gtk.BuildableIF;
40 private import gtk.BuildableT;
41 private import gtk.CheckMenuItem;
42 private import gtk.ImageMenuItem;
43 private import gtk.Menu;
44 private import gtk.MenuBar;
45 private import gtk.MenuItem;
46 private import gtk.MenuToolButton;
47 private import gtk.RadioMenuItem;
48 private import gtk.RadioToolButton;
49 private import gtk.SeparatorMenuItem;
50 private import gtk.SeparatorToolItem;
51 private import gtk.TearoffMenuItem;
52 private import gtk.ToggleToolButton;
53 private import gtk.ToolButton;
54 private import gtk.ToolItem;
55 private import gtk.Toolbar;
56 private import gtk.Widget;
57 public  import gtkc.gdktypes;
58 private import gtkc.gtk;
59 public  import gtkc.gtktypes;
60 private import std.algorithm;
61 
62 
63 /**
64  * A #GtkUIManager constructs a user interface (menus and toolbars) from
65  * one or more UI definitions, which reference actions from one or more
66  * action groups.
67  * 
68  * # UI Definitions # {#XML-UI}
69  * 
70  * The UI definitions are specified in an XML format which can be
71  * roughly described by the following DTD.
72  * 
73  * > Do not confuse the GtkUIManager UI Definitions described here with
74  * > the similarly named [GtkBuilder UI Definitions][BUILDER-UI].
75  * 
76  * |[
77  * <!ELEMENT ui          (menubar|toolbar|popup|accelerator)* >
78  * <!ELEMENT menubar     (menuitem|separator|placeholder|menu)* >
79  * <!ELEMENT menu        (menuitem|separator|placeholder|menu)* >
80  * <!ELEMENT popup       (menuitem|separator|placeholder|menu)* >
81  * <!ELEMENT toolbar     (toolitem|separator|placeholder)* >
82  * <!ELEMENT placeholder (menuitem|toolitem|separator|placeholder|menu)* >
83  * <!ELEMENT menuitem     EMPTY >
84  * <!ELEMENT toolitem     (menu?) >
85  * <!ELEMENT separator    EMPTY >
86  * <!ELEMENT accelerator  EMPTY >
87  * <!ATTLIST menubar      name                      #IMPLIED
88  * action                    #IMPLIED >
89  * <!ATTLIST toolbar      name                      #IMPLIED
90  * action                    #IMPLIED >
91  * <!ATTLIST popup        name                      #IMPLIED
92  * action                    #IMPLIED
93  * accelerators (true|false) #IMPLIED >
94  * <!ATTLIST placeholder  name                      #IMPLIED
95  * action                    #IMPLIED >
96  * <!ATTLIST separator    name                      #IMPLIED
97  * action                    #IMPLIED
98  * expand       (true|false) #IMPLIED >
99  * <!ATTLIST menu         name                      #IMPLIED
100  * action                    #REQUIRED
101  * position     (top|bot)    #IMPLIED >
102  * <!ATTLIST menuitem     name                      #IMPLIED
103  * action                    #REQUIRED
104  * position     (top|bot)    #IMPLIED
105  * always-show-image (true|false) #IMPLIED >
106  * <!ATTLIST toolitem     name                      #IMPLIED
107  * action                    #REQUIRED
108  * position     (top|bot)    #IMPLIED >
109  * <!ATTLIST accelerator  name                      #IMPLIED
110  * action                    #REQUIRED >
111  * ]|
112  * 
113  * There are some additional restrictions beyond those specified in the
114  * DTD, e.g. every toolitem must have a toolbar in its anchestry and
115  * every menuitem must have a menubar or popup in its anchestry. Since
116  * a #GMarkupParser is used to parse the UI description, it must not only
117  * be valid XML, but valid markup.
118  * 
119  * If a name is not specified, it defaults to the action. If an action is
120  * not specified either, the element name is used. The name and action
121  * attributes must not contain “/” characters after parsing (since that
122  * would mess up path lookup) and must be usable as XML attributes when
123  * enclosed in doublequotes, thus they must not “"” characters or references
124  * to the &quot; entity.
125  * 
126  * # A UI definition #
127  * 
128  * |[
129  * <ui>
130  * <menubar>
131  * <menu name="FileMenu" action="FileMenuAction">
132  * <menuitem name="New" action="New2Action" />
133  * <placeholder name="FileMenuAdditions" />
134  * </menu>
135  * <menu name="JustifyMenu" action="JustifyMenuAction">
136  * <menuitem name="Left" action="justify-left"/>
137  * <menuitem name="Centre" action="justify-center"/>
138  * <menuitem name="Right" action="justify-right"/>
139  * <menuitem name="Fill" action="justify-fill"/>
140  * </menu>
141  * </menubar>
142  * <toolbar action="toolbar1">
143  * <placeholder name="JustifyToolItems">
144  * <separator/>
145  * <toolitem name="Left" action="justify-left"/>
146  * <toolitem name="Centre" action="justify-center"/>
147  * <toolitem name="Right" action="justify-right"/>
148  * <toolitem name="Fill" action="justify-fill"/>
149  * <separator/>
150  * </placeholder>
151  * </toolbar>
152  * </ui>
153  * ]|
154  * 
155  * The constructed widget hierarchy is very similar to the element tree
156  * of the XML, with the exception that placeholders are merged into their
157  * parents. The correspondence of XML elements to widgets should be
158  * almost obvious:
159  * 
160  * - menubar
161  * 
162  * a #GtkMenuBar
163  * 
164  * - toolbar
165  * 
166  * a #GtkToolbar
167  * 
168  * - popup
169  * 
170  * a toplevel #GtkMenu
171  * 
172  * - menu
173  * 
174  * a #GtkMenu attached to a menuitem
175  * 
176  * - menuitem
177  * 
178  * a #GtkMenuItem subclass, the exact type depends on the action
179  * 
180  * - toolitem
181  * 
182  * a #GtkToolItem subclass, the exact type depends on the
183  * action. Note that toolitem elements may contain a menu element,
184  * but only if their associated action specifies a
185  * #GtkMenuToolButton as proxy.
186  * 
187  * - separator
188  * 
189  * a #GtkSeparatorMenuItem or #GtkSeparatorToolItem
190  * 
191  * - accelerator
192  * 
193  * a keyboard accelerator
194  * 
195  * The “position” attribute determines where a constructed widget is positioned
196  * wrt. to its siblings in the partially constructed tree. If it is
197  * “top”, the widget is prepended, otherwise it is appended.
198  * 
199  * # UI Merging # {#UI-Merging}
200  * 
201  * The most remarkable feature of #GtkUIManager is that it can overlay a set
202  * of menuitems and toolitems over another one, and demerge them later.
203  * 
204  * Merging is done based on the names of the XML elements. Each element is
205  * identified by a path which consists of the names of its anchestors, separated
206  * by slashes. For example, the menuitem named “Left” in the example above
207  * has the path `/ui/menubar/JustifyMenu/Left` and the
208  * toolitem with the same name has path
209  * `/ui/toolbar1/JustifyToolItems/Left`.
210  * 
211  * # Accelerators #
212  * 
213  * Every action has an accelerator path. Accelerators are installed together
214  * with menuitem proxies, but they can also be explicitly added with
215  * <accelerator> elements in the UI definition. This makes it possible to
216  * have accelerators for actions even if they have no visible proxies.
217  * 
218  * # Smart Separators # {#Smart-Separators}
219  * 
220  * The separators created by #GtkUIManager are “smart”, i.e. they do not show up
221  * in the UI unless they end up between two visible menu or tool items. Separators
222  * which are located at the very beginning or end of the menu or toolbar
223  * containing them, or multiple separators next to each other, are hidden. This
224  * is a useful feature, since the merging of UI elements from multiple sources
225  * can make it hard or impossible to determine in advance whether a separator
226  * will end up in such an unfortunate position.
227  * 
228  * For separators in toolbars, you can set `expand="true"` to
229  * turn them from a small, visible separator to an expanding, invisible one.
230  * Toolitems following an expanding separator are effectively right-aligned.
231  * 
232  * # Empty Menus
233  * 
234  * Submenus pose similar problems to separators inconnection with merging. It is
235  * impossible to know in advance whether they will end up empty after merging.
236  * #GtkUIManager offers two ways to treat empty submenus:
237  * 
238  * - make them disappear by hiding the menu item they’re attached to
239  * 
240  * - add an insensitive “Empty” item
241  * 
242  * The behaviour is chosen based on the “hide_if_empty” property of the action
243  * to which the submenu is associated.
244  * 
245  * # GtkUIManager as GtkBuildable # {#GtkUIManager-BUILDER-UI}
246  * 
247  * The GtkUIManager implementation of the GtkBuildable interface accepts
248  * GtkActionGroup objects as <child> elements in UI definitions.
249  * 
250  * A GtkUIManager UI definition as described above can be embedded in
251  * an GtkUIManager <object> element in a GtkBuilder UI definition.
252  * 
253  * The widgets that are constructed by a GtkUIManager can be embedded in
254  * other parts of the constructed user interface with the help of the
255  * “constructor” attribute. See the example below.
256  * 
257  * ## An embedded GtkUIManager UI definition
258  * 
259  * |[
260  * <object class="GtkUIManager" id="uiman">
261  * <child>
262  * <object class="GtkActionGroup" id="actiongroup">
263  * <child>
264  * <object class="GtkAction" id="file">
265  * <property name="label">_File</property>
266  * </object>
267  * </child>
268  * </object>
269  * </child>
270  * <ui>
271  * <menubar name="menubar1">
272  * <menu action="file">
273  * </menu>
274  * </menubar>
275  * </ui>
276  * </object>
277  * <object class="GtkWindow" id="main-window">
278  * <child>
279  * <object class="GtkMenuBar" id="menubar1" constructor="uiman"/>
280  * </child>
281  * </object>
282  * ]|
283  */
284 public class UIManager : ObjectG, BuildableIF
285 {
286 	/** the main Gtk struct */
287 	protected GtkUIManager* gtkUIManager;
288 
289 	/** Get the main Gtk struct */
290 	public GtkUIManager* getUIManagerStruct()
291 	{
292 		return gtkUIManager;
293 	}
294 
295 	/** the main Gtk struct as a void* */
296 	protected override void* getStruct()
297 	{
298 		return cast(void*)gtkUIManager;
299 	}
300 
301 	protected override void setStruct(GObject* obj)
302 	{
303 		gtkUIManager = cast(GtkUIManager*)obj;
304 		super.setStruct(obj);
305 	}
306 
307 	/**
308 	 * Sets our main struct and passes it to the parent class.
309 	 */
310 	public this (GtkUIManager* gtkUIManager, bool ownedRef = false)
311 	{
312 		this.gtkUIManager = gtkUIManager;
313 		super(cast(GObject*)gtkUIManager, ownedRef);
314 	}
315 
316 	// add the Buildable capabilities
317 	mixin BuildableT!(GtkUIManager);
318 
319 	/**
320 	 * Warning: getWidget is deprecated and should not be used in newly-written code. 3.10
321 	 *
322 	 * Looks up a widget by following a path.
323 	 * The path consists of the names specified in the XML description of the UI.
324 	 * separated by '/'. Elements which don't have a name or action attribute in
325 	 * the XML (e.g. &lt;popup&gt;) can be addressed by their XML element name
326 	 * (e.g. "popup"). The root element ("/ui") can be omitted in the path.
327 	 *
328 	 * Note that the widget found by following a path that ends in a &lt;menu&gt;
329 	 * element is the menuitem to which the menu is attached, not the menu itself.
330 	 *
331 	 * Also note that the widgets constructed by a ui manager are not tied to
332 	 * the lifecycle of the ui manager. If you add the widgets returned by this
333 	 * function to some container or explicitly ref them, they will survive the
334 	 * destruction of the ui manager.
335 	 *
336 	 * Since 2.4
337 	 *
338 	 * Params:
339 	 *    path = a path
340 	 *
341 	 * Returns: the widget found by following the path, or null if no widget was found.
342 	 */
343 	public Widget getWidget(string path)
344 	{
345 		// GtkWidget * gtk_ui_manager_get_widget (GtkUIManager *manager,  const gchar *path);
346 		auto p = gtk_ui_manager_get_widget(gtkUIManager, Str.toStringz(path));
347 		
348 		if(p is null)
349 		{
350 			return null;
351 		}
352 		
353 		string typeName = Type.name((cast(GTypeInstance*)p).gClass.gType);
354 		
355 		switch(typeName)
356 		{
357 			case "GtkCheckMenuItem":
358 			return ObjectG.getDObject!(CheckMenuItem)(cast(GtkCheckMenuItem*) p);
359 			case "GtkImageMenuItem":
360 			return ObjectG.getDObject!(ImageMenuItem)(cast(GtkImageMenuItem*) p);
361 			case "GtkMenu":
362 			return ObjectG.getDObject!(Menu)(cast(GtkMenu*) p);
363 			case "GtkMenuBar":
364 			return ObjectG.getDObject!(MenuBar)(cast(GtkMenuBar*) p);
365 			case "GtkMenuItem":
366 			return ObjectG.getDObject!(MenuItem)(cast(GtkMenuItem*) p);
367 			case "GtkMenuToolButton":
368 			return ObjectG.getDObject!(MenuToolButton)(cast(GtkMenuToolButton*) p);
369 			case "GtkRadioMenuItem":
370 			return ObjectG.getDObject!(RadioMenuItem)(cast(GtkRadioMenuItem*) p);
371 			case "GtkRadioToolButton":
372 			return ObjectG.getDObject!(RadioToolButton)(cast(GtkRadioToolButton*) p);
373 			case "GtkSeparatorMenuItem":
374 			return ObjectG.getDObject!(SeparatorMenuItem)(cast(GtkSeparatorMenuItem*) p);
375 			case "GtkSeparatorToolItem":
376 			return ObjectG.getDObject!(SeparatorToolItem)(cast(GtkSeparatorToolItem*) p);
377 			case "GtkTearoffMenuItem":
378 			return ObjectG.getDObject!(TearoffMenuItem)(cast(GtkTearoffMenuItem*) p);
379 			case "GtkToggleToolButton":
380 			return ObjectG.getDObject!(ToggleToolButton)(cast(GtkToggleToolButton*) p);
381 			case "GtkToolbar":
382 			return ObjectG.getDObject!(Toolbar)(cast(GtkToolbar*) p);
383 			case "GtkToolButton":
384 			return ObjectG.getDObject!(ToolButton)(cast(GtkToolButton*) p);
385 			case "GtkToolItem":
386 			return ObjectG.getDObject!(ToolItem)(cast(GtkToolItem*) p);
387 			default:
388 			return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
389 		}
390 	}
391 
392 	/**
393 	 */
394 
395 	/** */
396 	public static GType getType()
397 	{
398 		return gtk_ui_manager_get_type();
399 	}
400 
401 	/**
402 	 * Creates a new ui manager object.
403 	 *
404 	 * Return: a new ui manager object.
405 	 *
406 	 * Since: 2.4
407 	 *
408 	 * Throws: ConstructionException GTK+ fails to create the object.
409 	 */
410 	public this()
411 	{
412 		auto p = gtk_ui_manager_new();
413 		
414 		if(p is null)
415 		{
416 			throw new ConstructionException("null returned by new");
417 		}
418 		
419 		this(cast(GtkUIManager*) p, true);
420 	}
421 
422 	/**
423 	 * Adds a UI element to the current contents of @manager.
424 	 *
425 	 * If @type is %GTK_UI_MANAGER_AUTO, GTK+ inserts a menuitem, toolitem or
426 	 * separator if such an element can be inserted at the place determined by
427 	 * @path. Otherwise @type must indicate an element that can be inserted at
428 	 * the place determined by @path.
429 	 *
430 	 * If @path points to a menuitem or toolitem, the new element will be inserted
431 	 * before or after this item, depending on @top.
432 	 *
433 	 * Params:
434 	 *     mergeId = the merge id for the merged UI, see gtk_ui_manager_new_merge_id()
435 	 *     path = a path
436 	 *     name = the name for the added UI element
437 	 *     action = the name of the action to be proxied, or %NULL to add a separator
438 	 *     type = the type of UI element to add.
439 	 *     top = if %TRUE, the UI element is added before its siblings, otherwise it
440 	 *         is added after its siblings.
441 	 *
442 	 * Since: 2.4
443 	 */
444 	public void addUi(uint mergeId, string path, string name, string action, GtkUIManagerItemType type, bool top)
445 	{
446 		gtk_ui_manager_add_ui(gtkUIManager, mergeId, Str.toStringz(path), Str.toStringz(name), Str.toStringz(action), type, top);
447 	}
448 
449 	/**
450 	 * Parses a file containing a [UI definition][XML-UI] and
451 	 * merges it with the current contents of @manager.
452 	 *
453 	 * Params:
454 	 *     filename = the name of the file to parse
455 	 *
456 	 * Return: The merge id for the merged UI. The merge id can be used
457 	 *     to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred,
458 	 *     the return value is 0.
459 	 *
460 	 * Since: 2.4
461 	 *
462 	 * Throws: GException on failure.
463 	 */
464 	public uint addUiFromFile(string filename)
465 	{
466 		GError* err = null;
467 		
468 		auto p = gtk_ui_manager_add_ui_from_file(gtkUIManager, Str.toStringz(filename), &err);
469 		
470 		if (err !is null)
471 		{
472 			throw new GException( new ErrorG(err) );
473 		}
474 		
475 		return p;
476 	}
477 
478 	/**
479 	 * Parses a resource file containing a [UI definition][XML-UI] and
480 	 * merges it with the current contents of @manager.
481 	 *
482 	 * Params:
483 	 *     resourcePath = the resource path of the file to parse
484 	 *
485 	 * Return: The merge id for the merged UI. The merge id can be used
486 	 *     to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred,
487 	 *     the return value is 0.
488 	 *
489 	 * Since: 3.4
490 	 *
491 	 * Throws: GException on failure.
492 	 */
493 	public uint addUiFromResource(string resourcePath)
494 	{
495 		GError* err = null;
496 		
497 		auto p = gtk_ui_manager_add_ui_from_resource(gtkUIManager, Str.toStringz(resourcePath), &err);
498 		
499 		if (err !is null)
500 		{
501 			throw new GException( new ErrorG(err) );
502 		}
503 		
504 		return p;
505 	}
506 
507 	/**
508 	 * Parses a string containing a [UI definition][XML-UI] and merges it with
509 	 * the current contents of @manager. An enclosing <ui> element is added if
510 	 * it is missing.
511 	 *
512 	 * Params:
513 	 *     buffer = the string to parse
514 	 *     length = the length of @buffer (may be -1 if @buffer is nul-terminated)
515 	 *
516 	 * Return: The merge id for the merged UI. The merge id can be used
517 	 *     to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred,
518 	 *     the return value is 0.
519 	 *
520 	 * Since: 2.4
521 	 *
522 	 * Throws: GException on failure.
523 	 */
524 	public uint addUiFromString(string buffer, ptrdiff_t length)
525 	{
526 		GError* err = null;
527 		
528 		auto p = gtk_ui_manager_add_ui_from_string(gtkUIManager, Str.toStringz(buffer), length, &err);
529 		
530 		if (err !is null)
531 		{
532 			throw new GException( new ErrorG(err) );
533 		}
534 		
535 		return p;
536 	}
537 
538 	/**
539 	 * Makes sure that all pending updates to the UI have been completed.
540 	 *
541 	 * This may occasionally be necessary, since #GtkUIManager updates the
542 	 * UI in an idle function. A typical example where this function is
543 	 * useful is to enforce that the menubar and toolbar have been added to
544 	 * the main window before showing it:
545 	 * |[<!-- language="C" -->
546 	 * gtk_container_add (GTK_CONTAINER (window), vbox);
547 	 * g_signal_connect (merge, "add-widget",
548 	 * G_CALLBACK (add_widget), vbox);
549 	 * gtk_ui_manager_add_ui_from_file (merge, "my-menus");
550 	 * gtk_ui_manager_add_ui_from_file (merge, "my-toolbars");
551 	 * gtk_ui_manager_ensure_update (merge);
552 	 * gtk_widget_show (window);
553 	 * ]|
554 	 *
555 	 * Since: 2.4
556 	 */
557 	public void ensureUpdate()
558 	{
559 		gtk_ui_manager_ensure_update(gtkUIManager);
560 	}
561 
562 	/**
563 	 * Returns the #GtkAccelGroup associated with @manager.
564 	 *
565 	 * Return: the #GtkAccelGroup.
566 	 *
567 	 * Since: 2.4
568 	 */
569 	public AccelGroup getAccelGroup()
570 	{
571 		auto p = gtk_ui_manager_get_accel_group(gtkUIManager);
572 		
573 		if(p is null)
574 		{
575 			return null;
576 		}
577 		
578 		return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p);
579 	}
580 
581 	/**
582 	 * Looks up an action by following a path. See gtk_ui_manager_get_widget()
583 	 * for more information about paths.
584 	 *
585 	 * Params:
586 	 *     path = a path
587 	 *
588 	 * Return: the action whose proxy widget is found by following the path,
589 	 *     or %NULL if no widget was found.
590 	 *
591 	 * Since: 2.4
592 	 */
593 	public Action getAction(string path)
594 	{
595 		auto p = gtk_ui_manager_get_action(gtkUIManager, Str.toStringz(path));
596 		
597 		if(p is null)
598 		{
599 			return null;
600 		}
601 		
602 		return ObjectG.getDObject!(Action)(cast(GtkAction*) p);
603 	}
604 
605 	/**
606 	 * Returns the list of action groups associated with @manager.
607 	 *
608 	 * Return: a #GList of
609 	 *     action groups. The list is owned by GTK+
610 	 *     and should not be modified.
611 	 *
612 	 * Since: 2.4
613 	 */
614 	public ListG getActionGroups()
615 	{
616 		auto p = gtk_ui_manager_get_action_groups(gtkUIManager);
617 		
618 		if(p is null)
619 		{
620 			return null;
621 		}
622 		
623 		return new ListG(cast(GList*) p);
624 	}
625 
626 	/**
627 	 * Returns whether menus generated by this #GtkUIManager
628 	 * will have tearoff menu items.
629 	 *
630 	 * Deprecated: Tearoff menus are deprecated and should not
631 	 * be used in newly written code.
632 	 *
633 	 * Return: whether tearoff menu items are added
634 	 *
635 	 * Since: 2.4
636 	 */
637 	public bool getAddTearoffs()
638 	{
639 		return gtk_ui_manager_get_add_tearoffs(gtkUIManager) != 0;
640 	}
641 
642 	/**
643 	 * Obtains a list of all toplevel widgets of the requested types.
644 	 *
645 	 * Params:
646 	 *     types = specifies the types of toplevel widgets to include. Allowed
647 	 *         types are #GTK_UI_MANAGER_MENUBAR, #GTK_UI_MANAGER_TOOLBAR and
648 	 *         #GTK_UI_MANAGER_POPUP.
649 	 *
650 	 * Return: a newly-allocated #GSList of
651 	 *     all toplevel widgets of the requested types.  Free the returned list with g_slist_free().
652 	 *
653 	 * Since: 2.4
654 	 */
655 	public ListSG getToplevels(GtkUIManagerItemType types)
656 	{
657 		auto p = gtk_ui_manager_get_toplevels(gtkUIManager, types);
658 		
659 		if(p is null)
660 		{
661 			return null;
662 		}
663 		
664 		return new ListSG(cast(GSList*) p);
665 	}
666 
667 	/**
668 	 * Creates a [UI definition][XML-UI] of the merged UI.
669 	 *
670 	 * Return: A newly allocated string containing an XML representation of
671 	 *     the merged UI.
672 	 *
673 	 * Since: 2.4
674 	 */
675 	public string getUi()
676 	{
677 		auto retStr = gtk_ui_manager_get_ui(gtkUIManager);
678 		
679 		scope(exit) Str.freeString(retStr);
680 		return Str.toString(retStr);
681 	}
682 
683 	/**
684 	 * Inserts an action group into the list of action groups associated
685 	 * with @manager. Actions in earlier groups hide actions with the same
686 	 * name in later groups.
687 	 *
688 	 * If @pos is larger than the number of action groups in @manager, or
689 	 * negative, @action_group will be inserted at the end of the internal
690 	 * list.
691 	 *
692 	 * Params:
693 	 *     actionGroup = the action group to be inserted
694 	 *     pos = the position at which the group will be inserted.
695 	 *
696 	 * Since: 2.4
697 	 */
698 	public void insertActionGroup(ActionGroup actionGroup, int pos)
699 	{
700 		gtk_ui_manager_insert_action_group(gtkUIManager, (actionGroup is null) ? null : actionGroup.getActionGroupStruct(), pos);
701 	}
702 
703 	/**
704 	 * Returns an unused merge id, suitable for use with
705 	 * gtk_ui_manager_add_ui().
706 	 *
707 	 * Return: an unused merge id.
708 	 *
709 	 * Since: 2.4
710 	 */
711 	public uint newMergeId()
712 	{
713 		return gtk_ui_manager_new_merge_id(gtkUIManager);
714 	}
715 
716 	/**
717 	 * Removes an action group from the list of action groups associated
718 	 * with @manager.
719 	 *
720 	 * Params:
721 	 *     actionGroup = the action group to be removed
722 	 *
723 	 * Since: 2.4
724 	 */
725 	public void removeActionGroup(ActionGroup actionGroup)
726 	{
727 		gtk_ui_manager_remove_action_group(gtkUIManager, (actionGroup is null) ? null : actionGroup.getActionGroupStruct());
728 	}
729 
730 	/**
731 	 * Unmerges the part of @manager's content identified by @merge_id.
732 	 *
733 	 * Params:
734 	 *     mergeId = a merge id as returned by gtk_ui_manager_add_ui_from_string()
735 	 *
736 	 * Since: 2.4
737 	 */
738 	public void removeUi(uint mergeId)
739 	{
740 		gtk_ui_manager_remove_ui(gtkUIManager, mergeId);
741 	}
742 
743 	/**
744 	 * Sets the “add_tearoffs” property, which controls whether menus
745 	 * generated by this #GtkUIManager will have tearoff menu items.
746 	 *
747 	 * Note that this only affects regular menus. Generated popup
748 	 * menus never have tearoff menu items.
749 	 *
750 	 * Deprecated: Tearoff menus are deprecated and should not
751 	 * be used in newly written code.
752 	 *
753 	 * Params:
754 	 *     addTearoffs = whether tearoff menu items are added
755 	 *
756 	 * Since: 2.4
757 	 */
758 	public void setAddTearoffs(bool addTearoffs)
759 	{
760 		gtk_ui_manager_set_add_tearoffs(gtkUIManager, addTearoffs);
761 	}
762 
763 	protected class OnActionsChangedDelegateWrapper
764 	{
765 		void delegate(UIManager) dlg;
766 		gulong handlerId;
767 		ConnectFlags flags;
768 		this(void delegate(UIManager) dlg, gulong handlerId, ConnectFlags flags)
769 		{
770 			this.dlg = dlg;
771 			this.handlerId = handlerId;
772 			this.flags = flags;
773 		}
774 	}
775 	protected OnActionsChangedDelegateWrapper[] onActionsChangedListeners;
776 
777 	/**
778 	 * The ::actions-changed signal is emitted whenever the set of actions
779 	 * changes.
780 	 *
781 	 * Since: 2.4
782 	 */
783 	gulong addOnActionsChanged(void delegate(UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
784 	{
785 		onActionsChangedListeners ~= new OnActionsChangedDelegateWrapper(dlg, 0, connectFlags);
786 		onActionsChangedListeners[onActionsChangedListeners.length - 1].handlerId = Signals.connectData(
787 			this,
788 			"actions-changed",
789 			cast(GCallback)&callBackActionsChanged,
790 			cast(void*)onActionsChangedListeners[onActionsChangedListeners.length - 1],
791 			cast(GClosureNotify)&callBackActionsChangedDestroy,
792 			connectFlags);
793 		return onActionsChangedListeners[onActionsChangedListeners.length - 1].handlerId;
794 	}
795 	
796 	extern(C) static void callBackActionsChanged(GtkUIManager* uimanagerStruct,OnActionsChangedDelegateWrapper wrapper)
797 	{
798 		wrapper.dlg(wrapper.outer);
799 	}
800 	
801 	extern(C) static void callBackActionsChangedDestroy(OnActionsChangedDelegateWrapper wrapper, GClosure* closure)
802 	{
803 		wrapper.outer.internalRemoveOnActionsChanged(wrapper);
804 	}
805 
806 	protected void internalRemoveOnActionsChanged(OnActionsChangedDelegateWrapper source)
807 	{
808 		foreach(index, wrapper; onActionsChangedListeners)
809 		{
810 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
811 			{
812 				onActionsChangedListeners[index] = null;
813 				onActionsChangedListeners = std.algorithm.remove(onActionsChangedListeners, index);
814 				break;
815 			}
816 		}
817 	}
818 	
819 
820 	protected class OnAddWidgetDelegateWrapper
821 	{
822 		void delegate(Widget, UIManager) dlg;
823 		gulong handlerId;
824 		ConnectFlags flags;
825 		this(void delegate(Widget, UIManager) dlg, gulong handlerId, ConnectFlags flags)
826 		{
827 			this.dlg = dlg;
828 			this.handlerId = handlerId;
829 			this.flags = flags;
830 		}
831 	}
832 	protected OnAddWidgetDelegateWrapper[] onAddWidgetListeners;
833 
834 	/**
835 	 * The ::add-widget signal is emitted for each generated menubar and toolbar.
836 	 * It is not emitted for generated popup menus, which can be obtained by
837 	 * gtk_ui_manager_get_widget().
838 	 *
839 	 * Params:
840 	 *     widget = the added widget
841 	 *
842 	 * Since: 2.4
843 	 */
844 	gulong addOnAddWidget(void delegate(Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
845 	{
846 		onAddWidgetListeners ~= new OnAddWidgetDelegateWrapper(dlg, 0, connectFlags);
847 		onAddWidgetListeners[onAddWidgetListeners.length - 1].handlerId = Signals.connectData(
848 			this,
849 			"add-widget",
850 			cast(GCallback)&callBackAddWidget,
851 			cast(void*)onAddWidgetListeners[onAddWidgetListeners.length - 1],
852 			cast(GClosureNotify)&callBackAddWidgetDestroy,
853 			connectFlags);
854 		return onAddWidgetListeners[onAddWidgetListeners.length - 1].handlerId;
855 	}
856 	
857 	extern(C) static void callBackAddWidget(GtkUIManager* uimanagerStruct, GtkWidget* widget,OnAddWidgetDelegateWrapper wrapper)
858 	{
859 		wrapper.dlg(ObjectG.getDObject!(Widget)(widget), wrapper.outer);
860 	}
861 	
862 	extern(C) static void callBackAddWidgetDestroy(OnAddWidgetDelegateWrapper wrapper, GClosure* closure)
863 	{
864 		wrapper.outer.internalRemoveOnAddWidget(wrapper);
865 	}
866 
867 	protected void internalRemoveOnAddWidget(OnAddWidgetDelegateWrapper source)
868 	{
869 		foreach(index, wrapper; onAddWidgetListeners)
870 		{
871 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
872 			{
873 				onAddWidgetListeners[index] = null;
874 				onAddWidgetListeners = std.algorithm.remove(onAddWidgetListeners, index);
875 				break;
876 			}
877 		}
878 	}
879 	
880 
881 	protected class OnConnectProxyDelegateWrapper
882 	{
883 		void delegate(Action, Widget, UIManager) dlg;
884 		gulong handlerId;
885 		ConnectFlags flags;
886 		this(void delegate(Action, Widget, UIManager) dlg, gulong handlerId, ConnectFlags flags)
887 		{
888 			this.dlg = dlg;
889 			this.handlerId = handlerId;
890 			this.flags = flags;
891 		}
892 	}
893 	protected OnConnectProxyDelegateWrapper[] onConnectProxyListeners;
894 
895 	/**
896 	 * The ::connect-proxy signal is emitted after connecting a proxy to
897 	 * an action in the group.
898 	 *
899 	 * This is intended for simple customizations for which a custom action
900 	 * class would be too clumsy, e.g. showing tooltips for menuitems in the
901 	 * statusbar.
902 	 *
903 	 * Params:
904 	 *     action = the action
905 	 *     proxy = the proxy
906 	 *
907 	 * Since: 2.4
908 	 */
909 	gulong addOnConnectProxy(void delegate(Action, Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
910 	{
911 		onConnectProxyListeners ~= new OnConnectProxyDelegateWrapper(dlg, 0, connectFlags);
912 		onConnectProxyListeners[onConnectProxyListeners.length - 1].handlerId = Signals.connectData(
913 			this,
914 			"connect-proxy",
915 			cast(GCallback)&callBackConnectProxy,
916 			cast(void*)onConnectProxyListeners[onConnectProxyListeners.length - 1],
917 			cast(GClosureNotify)&callBackConnectProxyDestroy,
918 			connectFlags);
919 		return onConnectProxyListeners[onConnectProxyListeners.length - 1].handlerId;
920 	}
921 	
922 	extern(C) static void callBackConnectProxy(GtkUIManager* uimanagerStruct, GtkAction* action, GtkWidget* proxy,OnConnectProxyDelegateWrapper wrapper)
923 	{
924 		wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer);
925 	}
926 	
927 	extern(C) static void callBackConnectProxyDestroy(OnConnectProxyDelegateWrapper wrapper, GClosure* closure)
928 	{
929 		wrapper.outer.internalRemoveOnConnectProxy(wrapper);
930 	}
931 
932 	protected void internalRemoveOnConnectProxy(OnConnectProxyDelegateWrapper source)
933 	{
934 		foreach(index, wrapper; onConnectProxyListeners)
935 		{
936 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
937 			{
938 				onConnectProxyListeners[index] = null;
939 				onConnectProxyListeners = std.algorithm.remove(onConnectProxyListeners, index);
940 				break;
941 			}
942 		}
943 	}
944 	
945 
946 	protected class OnDisconnectProxyDelegateWrapper
947 	{
948 		void delegate(Action, Widget, UIManager) dlg;
949 		gulong handlerId;
950 		ConnectFlags flags;
951 		this(void delegate(Action, Widget, UIManager) dlg, gulong handlerId, ConnectFlags flags)
952 		{
953 			this.dlg = dlg;
954 			this.handlerId = handlerId;
955 			this.flags = flags;
956 		}
957 	}
958 	protected OnDisconnectProxyDelegateWrapper[] onDisconnectProxyListeners;
959 
960 	/**
961 	 * The ::disconnect-proxy signal is emitted after disconnecting a proxy
962 	 * from an action in the group.
963 	 *
964 	 * Params:
965 	 *     action = the action
966 	 *     proxy = the proxy
967 	 *
968 	 * Since: 2.4
969 	 */
970 	gulong addOnDisconnectProxy(void delegate(Action, Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
971 	{
972 		onDisconnectProxyListeners ~= new OnDisconnectProxyDelegateWrapper(dlg, 0, connectFlags);
973 		onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1].handlerId = Signals.connectData(
974 			this,
975 			"disconnect-proxy",
976 			cast(GCallback)&callBackDisconnectProxy,
977 			cast(void*)onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1],
978 			cast(GClosureNotify)&callBackDisconnectProxyDestroy,
979 			connectFlags);
980 		return onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1].handlerId;
981 	}
982 	
983 	extern(C) static void callBackDisconnectProxy(GtkUIManager* uimanagerStruct, GtkAction* action, GtkWidget* proxy,OnDisconnectProxyDelegateWrapper wrapper)
984 	{
985 		wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer);
986 	}
987 	
988 	extern(C) static void callBackDisconnectProxyDestroy(OnDisconnectProxyDelegateWrapper wrapper, GClosure* closure)
989 	{
990 		wrapper.outer.internalRemoveOnDisconnectProxy(wrapper);
991 	}
992 
993 	protected void internalRemoveOnDisconnectProxy(OnDisconnectProxyDelegateWrapper source)
994 	{
995 		foreach(index, wrapper; onDisconnectProxyListeners)
996 		{
997 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
998 			{
999 				onDisconnectProxyListeners[index] = null;
1000 				onDisconnectProxyListeners = std.algorithm.remove(onDisconnectProxyListeners, index);
1001 				break;
1002 			}
1003 		}
1004 	}
1005 	
1006 
1007 	protected class OnPostActivateDelegateWrapper
1008 	{
1009 		void delegate(Action, UIManager) dlg;
1010 		gulong handlerId;
1011 		ConnectFlags flags;
1012 		this(void delegate(Action, UIManager) dlg, gulong handlerId, ConnectFlags flags)
1013 		{
1014 			this.dlg = dlg;
1015 			this.handlerId = handlerId;
1016 			this.flags = flags;
1017 		}
1018 	}
1019 	protected OnPostActivateDelegateWrapper[] onPostActivateListeners;
1020 
1021 	/**
1022 	 * The ::post-activate signal is emitted just after the @action
1023 	 * is activated.
1024 	 *
1025 	 * This is intended for applications to get notification
1026 	 * just after any action is activated.
1027 	 *
1028 	 * Params:
1029 	 *     action = the action
1030 	 *
1031 	 * Since: 2.4
1032 	 */
1033 	gulong addOnPostActivate(void delegate(Action, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1034 	{
1035 		onPostActivateListeners ~= new OnPostActivateDelegateWrapper(dlg, 0, connectFlags);
1036 		onPostActivateListeners[onPostActivateListeners.length - 1].handlerId = Signals.connectData(
1037 			this,
1038 			"post-activate",
1039 			cast(GCallback)&callBackPostActivate,
1040 			cast(void*)onPostActivateListeners[onPostActivateListeners.length - 1],
1041 			cast(GClosureNotify)&callBackPostActivateDestroy,
1042 			connectFlags);
1043 		return onPostActivateListeners[onPostActivateListeners.length - 1].handlerId;
1044 	}
1045 	
1046 	extern(C) static void callBackPostActivate(GtkUIManager* uimanagerStruct, GtkAction* action,OnPostActivateDelegateWrapper wrapper)
1047 	{
1048 		wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer);
1049 	}
1050 	
1051 	extern(C) static void callBackPostActivateDestroy(OnPostActivateDelegateWrapper wrapper, GClosure* closure)
1052 	{
1053 		wrapper.outer.internalRemoveOnPostActivate(wrapper);
1054 	}
1055 
1056 	protected void internalRemoveOnPostActivate(OnPostActivateDelegateWrapper source)
1057 	{
1058 		foreach(index, wrapper; onPostActivateListeners)
1059 		{
1060 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
1061 			{
1062 				onPostActivateListeners[index] = null;
1063 				onPostActivateListeners = std.algorithm.remove(onPostActivateListeners, index);
1064 				break;
1065 			}
1066 		}
1067 	}
1068 	
1069 
1070 	protected class OnPreActivateDelegateWrapper
1071 	{
1072 		void delegate(Action, UIManager) dlg;
1073 		gulong handlerId;
1074 		ConnectFlags flags;
1075 		this(void delegate(Action, UIManager) dlg, gulong handlerId, ConnectFlags flags)
1076 		{
1077 			this.dlg = dlg;
1078 			this.handlerId = handlerId;
1079 			this.flags = flags;
1080 		}
1081 	}
1082 	protected OnPreActivateDelegateWrapper[] onPreActivateListeners;
1083 
1084 	/**
1085 	 * The ::pre-activate signal is emitted just before the @action
1086 	 * is activated.
1087 	 *
1088 	 * This is intended for applications to get notification
1089 	 * just before any action is activated.
1090 	 *
1091 	 * Params:
1092 	 *     action = the action
1093 	 *
1094 	 * Since: 2.4
1095 	 */
1096 	gulong addOnPreActivate(void delegate(Action, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1097 	{
1098 		onPreActivateListeners ~= new OnPreActivateDelegateWrapper(dlg, 0, connectFlags);
1099 		onPreActivateListeners[onPreActivateListeners.length - 1].handlerId = Signals.connectData(
1100 			this,
1101 			"pre-activate",
1102 			cast(GCallback)&callBackPreActivate,
1103 			cast(void*)onPreActivateListeners[onPreActivateListeners.length - 1],
1104 			cast(GClosureNotify)&callBackPreActivateDestroy,
1105 			connectFlags);
1106 		return onPreActivateListeners[onPreActivateListeners.length - 1].handlerId;
1107 	}
1108 	
1109 	extern(C) static void callBackPreActivate(GtkUIManager* uimanagerStruct, GtkAction* action,OnPreActivateDelegateWrapper wrapper)
1110 	{
1111 		wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer);
1112 	}
1113 	
1114 	extern(C) static void callBackPreActivateDestroy(OnPreActivateDelegateWrapper wrapper, GClosure* closure)
1115 	{
1116 		wrapper.outer.internalRemoveOnPreActivate(wrapper);
1117 	}
1118 
1119 	protected void internalRemoveOnPreActivate(OnPreActivateDelegateWrapper source)
1120 	{
1121 		foreach(index, wrapper; onPreActivateListeners)
1122 		{
1123 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
1124 			{
1125 				onPreActivateListeners[index] = null;
1126 				onPreActivateListeners = std.algorithm.remove(onPreActivateListeners, index);
1127 				break;
1128 			}
1129 		}
1130 	}
1131 	
1132 }