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 " 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. <popup>) 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 <menu> 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 }