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