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 " 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() 290 { 291 return gtkUIManager; 292 } 293 294 /** the main Gtk struct as a void* */ 295 protected override void* getStruct() 296 { 297 return cast(void*)gtkUIManager; 298 } 299 300 protected override void setStruct(GObject* obj) 301 { 302 gtkUIManager = cast(GtkUIManager*)obj; 303 super.setStruct(obj); 304 } 305 306 /** 307 * Sets our main struct and passes it to the parent class. 308 */ 309 public this (GtkUIManager* gtkUIManager, bool ownedRef = false) 310 { 311 this.gtkUIManager = gtkUIManager; 312 super(cast(GObject*)gtkUIManager, ownedRef); 313 } 314 315 // add the Buildable capabilities 316 mixin BuildableT!(GtkUIManager); 317 318 /** 319 * Warning: getWidget is deprecated and should not be used in newly-written code. 3.10 320 * 321 * Looks up a widget by following a path. 322 * The path consists of the names specified in the XML description of the UI. 323 * separated by '/'. Elements which don't have a name or action attribute in 324 * the XML (e.g. <popup>) can be addressed by their XML element name 325 * (e.g. "popup"). The root element ("/ui") can be omitted in the path. 326 * 327 * Note that the widget found by following a path that ends in a <menu> 328 * element is the menuitem to which the menu is attached, not the menu itself. 329 * 330 * Also note that the widgets constructed by a ui manager are not tied to 331 * the lifecycle of the ui manager. If you add the widgets returned by this 332 * function to some container or explicitly ref them, they will survive the 333 * destruction of the ui manager. 334 * 335 * Since 2.4 336 * 337 * Params: 338 * path = a path 339 * 340 * Returns: the widget found by following the path, or null if no widget was found. 341 */ 342 public Widget getWidget(string path) 343 { 344 // GtkWidget * gtk_ui_manager_get_widget (GtkUIManager *manager, const gchar *path); 345 auto p = gtk_ui_manager_get_widget(gtkUIManager, Str.toStringz(path)); 346 347 if(p is null) 348 { 349 return null; 350 } 351 352 string typeName = Type.name((cast(GTypeInstance*)p).gClass.gType); 353 354 switch(typeName) 355 { 356 case "GtkCheckMenuItem": 357 return ObjectG.getDObject!(CheckMenuItem)(cast(GtkCheckMenuItem*) p); 358 case "GtkImageMenuItem": 359 return ObjectG.getDObject!(ImageMenuItem)(cast(GtkImageMenuItem*) p); 360 case "GtkMenu": 361 return ObjectG.getDObject!(Menu)(cast(GtkMenu*) p); 362 case "GtkMenuBar": 363 return ObjectG.getDObject!(MenuBar)(cast(GtkMenuBar*) p); 364 case "GtkMenuItem": 365 return ObjectG.getDObject!(MenuItem)(cast(GtkMenuItem*) p); 366 case "GtkMenuToolButton": 367 return ObjectG.getDObject!(MenuToolButton)(cast(GtkMenuToolButton*) p); 368 case "GtkRadioMenuItem": 369 return ObjectG.getDObject!(RadioMenuItem)(cast(GtkRadioMenuItem*) p); 370 case "GtkRadioToolButton": 371 return ObjectG.getDObject!(RadioToolButton)(cast(GtkRadioToolButton*) p); 372 case "GtkSeparatorMenuItem": 373 return ObjectG.getDObject!(SeparatorMenuItem)(cast(GtkSeparatorMenuItem*) p); 374 case "GtkSeparatorToolItem": 375 return ObjectG.getDObject!(SeparatorToolItem)(cast(GtkSeparatorToolItem*) p); 376 case "GtkTearoffMenuItem": 377 return ObjectG.getDObject!(TearoffMenuItem)(cast(GtkTearoffMenuItem*) p); 378 case "GtkToggleToolButton": 379 return ObjectG.getDObject!(ToggleToolButton)(cast(GtkToggleToolButton*) p); 380 case "GtkToolbar": 381 return ObjectG.getDObject!(Toolbar)(cast(GtkToolbar*) p); 382 case "GtkToolButton": 383 return ObjectG.getDObject!(ToolButton)(cast(GtkToolButton*) p); 384 case "GtkToolItem": 385 return ObjectG.getDObject!(ToolItem)(cast(GtkToolItem*) p); 386 default: 387 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 388 } 389 } 390 391 /** 392 */ 393 394 /** */ 395 public static GType getType() 396 { 397 return gtk_ui_manager_get_type(); 398 } 399 400 /** 401 * Creates a new ui manager object. 402 * 403 * Returns: a new ui manager object. 404 * 405 * Since: 2.4 406 * 407 * Throws: ConstructionException GTK+ fails to create the object. 408 */ 409 public this() 410 { 411 auto p = gtk_ui_manager_new(); 412 413 if(p is null) 414 { 415 throw new ConstructionException("null returned by new"); 416 } 417 418 this(cast(GtkUIManager*) p, true); 419 } 420 421 /** 422 * Adds a UI element to the current contents of @manager. 423 * 424 * If @type is %GTK_UI_MANAGER_AUTO, GTK+ inserts a menuitem, toolitem or 425 * separator if such an element can be inserted at the place determined by 426 * @path. Otherwise @type must indicate an element that can be inserted at 427 * the place determined by @path. 428 * 429 * If @path points to a menuitem or toolitem, the new element will be inserted 430 * before or after this item, depending on @top. 431 * 432 * Params: 433 * mergeId = the merge id for the merged UI, see gtk_ui_manager_new_merge_id() 434 * path = a path 435 * name = the name for the added UI element 436 * action = the name of the action to be proxied, or %NULL to add a separator 437 * type = the type of UI element to add. 438 * top = if %TRUE, the UI element is added before its siblings, otherwise it 439 * is added after its siblings. 440 * 441 * Since: 2.4 442 */ 443 public void addUi(uint mergeId, string path, string name, string action, GtkUIManagerItemType type, bool top) 444 { 445 gtk_ui_manager_add_ui(gtkUIManager, mergeId, Str.toStringz(path), Str.toStringz(name), Str.toStringz(action), type, top); 446 } 447 448 /** 449 * Parses a file containing a [UI definition][XML-UI] and 450 * merges it with the current contents of @manager. 451 * 452 * Params: 453 * filename = the name of the file to parse 454 * 455 * Returns: The merge id for the merged UI. The merge id can be used 456 * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, 457 * the return value is 0. 458 * 459 * Since: 2.4 460 * 461 * Throws: GException on failure. 462 */ 463 public uint addUiFromFile(string filename) 464 { 465 GError* err = null; 466 467 auto p = gtk_ui_manager_add_ui_from_file(gtkUIManager, Str.toStringz(filename), &err); 468 469 if (err !is null) 470 { 471 throw new GException( new ErrorG(err) ); 472 } 473 474 return p; 475 } 476 477 /** 478 * Parses a resource file containing a [UI definition][XML-UI] and 479 * merges it with the current contents of @manager. 480 * 481 * Params: 482 * resourcePath = the resource path of the file to parse 483 * 484 * Returns: The merge id for the merged UI. The merge id can be used 485 * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, 486 * the return value is 0. 487 * 488 * Since: 3.4 489 * 490 * Throws: GException on failure. 491 */ 492 public uint addUiFromResource(string resourcePath) 493 { 494 GError* err = null; 495 496 auto p = gtk_ui_manager_add_ui_from_resource(gtkUIManager, Str.toStringz(resourcePath), &err); 497 498 if (err !is null) 499 { 500 throw new GException( new ErrorG(err) ); 501 } 502 503 return p; 504 } 505 506 /** 507 * Parses a string containing a [UI definition][XML-UI] and merges it with 508 * the current contents of @manager. An enclosing <ui> element is added if 509 * it is missing. 510 * 511 * Params: 512 * buffer = the string to parse 513 * length = the length of @buffer (may be -1 if @buffer is nul-terminated) 514 * 515 * Returns: The merge id for the merged UI. The merge id can be used 516 * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, 517 * the return value is 0. 518 * 519 * Since: 2.4 520 * 521 * Throws: GException on failure. 522 */ 523 public uint addUiFromString(string buffer, ptrdiff_t length) 524 { 525 GError* err = null; 526 527 auto p = gtk_ui_manager_add_ui_from_string(gtkUIManager, Str.toStringz(buffer), length, &err); 528 529 if (err !is null) 530 { 531 throw new GException( new ErrorG(err) ); 532 } 533 534 return p; 535 } 536 537 /** 538 * Makes sure that all pending updates to the UI have been completed. 539 * 540 * This may occasionally be necessary, since #GtkUIManager updates the 541 * UI in an idle function. A typical example where this function is 542 * useful is to enforce that the menubar and toolbar have been added to 543 * the main window before showing it: 544 * |[<!-- language="C" --> 545 * gtk_container_add (GTK_CONTAINER (window), vbox); 546 * g_signal_connect (merge, "add-widget", 547 * G_CALLBACK (add_widget), vbox); 548 * gtk_ui_manager_add_ui_from_file (merge, "my-menus"); 549 * gtk_ui_manager_add_ui_from_file (merge, "my-toolbars"); 550 * gtk_ui_manager_ensure_update (merge); 551 * gtk_widget_show (window); 552 * ]| 553 * 554 * Since: 2.4 555 */ 556 public void ensureUpdate() 557 { 558 gtk_ui_manager_ensure_update(gtkUIManager); 559 } 560 561 /** 562 * Returns the #GtkAccelGroup associated with @manager. 563 * 564 * Returns: the #GtkAccelGroup. 565 * 566 * Since: 2.4 567 */ 568 public AccelGroup getAccelGroup() 569 { 570 auto p = gtk_ui_manager_get_accel_group(gtkUIManager); 571 572 if(p is null) 573 { 574 return null; 575 } 576 577 return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p); 578 } 579 580 /** 581 * Looks up an action by following a path. See gtk_ui_manager_get_widget() 582 * for more information about paths. 583 * 584 * Params: 585 * path = a path 586 * 587 * Returns: the action whose proxy widget is found by following the path, 588 * or %NULL if no widget was found. 589 * 590 * Since: 2.4 591 */ 592 public Action getAction(string path) 593 { 594 auto p = gtk_ui_manager_get_action(gtkUIManager, Str.toStringz(path)); 595 596 if(p is null) 597 { 598 return null; 599 } 600 601 return ObjectG.getDObject!(Action)(cast(GtkAction*) p); 602 } 603 604 /** 605 * Returns the list of action groups associated with @manager. 606 * 607 * Returns: a #GList of 608 * action groups. The list is owned by GTK+ 609 * and should not be modified. 610 * 611 * Since: 2.4 612 */ 613 public ListG getActionGroups() 614 { 615 auto p = gtk_ui_manager_get_action_groups(gtkUIManager); 616 617 if(p is null) 618 { 619 return null; 620 } 621 622 return new ListG(cast(GList*) p); 623 } 624 625 /** 626 * Returns whether menus generated by this #GtkUIManager 627 * will have tearoff menu items. 628 * 629 * Deprecated: Tearoff menus are deprecated and should not 630 * be used in newly written code. 631 * 632 * Returns: whether tearoff menu items are added 633 * 634 * Since: 2.4 635 */ 636 public bool getAddTearoffs() 637 { 638 return gtk_ui_manager_get_add_tearoffs(gtkUIManager) != 0; 639 } 640 641 /** 642 * Obtains a list of all toplevel widgets of the requested types. 643 * 644 * Params: 645 * types = specifies the types of toplevel widgets to include. Allowed 646 * types are #GTK_UI_MANAGER_MENUBAR, #GTK_UI_MANAGER_TOOLBAR and 647 * #GTK_UI_MANAGER_POPUP. 648 * 649 * Returns: a newly-allocated #GSList of 650 * all toplevel widgets of the requested types. Free the returned list with g_slist_free(). 651 * 652 * Since: 2.4 653 */ 654 public ListSG getToplevels(GtkUIManagerItemType types) 655 { 656 auto p = gtk_ui_manager_get_toplevels(gtkUIManager, types); 657 658 if(p is null) 659 { 660 return null; 661 } 662 663 return new ListSG(cast(GSList*) p); 664 } 665 666 /** 667 * Creates a [UI definition][XML-UI] of the merged UI. 668 * 669 * Returns: A newly allocated string containing an XML representation of 670 * the merged UI. 671 * 672 * Since: 2.4 673 */ 674 public string getUi() 675 { 676 auto retStr = gtk_ui_manager_get_ui(gtkUIManager); 677 678 scope(exit) Str.freeString(retStr); 679 return Str.toString(retStr); 680 } 681 682 /** 683 * Inserts an action group into the list of action groups associated 684 * with @manager. Actions in earlier groups hide actions with the same 685 * name in later groups. 686 * 687 * If @pos is larger than the number of action groups in @manager, or 688 * negative, @action_group will be inserted at the end of the internal 689 * list. 690 * 691 * Params: 692 * actionGroup = the action group to be inserted 693 * pos = the position at which the group will be inserted. 694 * 695 * Since: 2.4 696 */ 697 public void insertActionGroup(ActionGroup actionGroup, int pos) 698 { 699 gtk_ui_manager_insert_action_group(gtkUIManager, (actionGroup is null) ? null : actionGroup.getActionGroupStruct(), pos); 700 } 701 702 /** 703 * Returns an unused merge id, suitable for use with 704 * gtk_ui_manager_add_ui(). 705 * 706 * Returns: an unused merge id. 707 * 708 * Since: 2.4 709 */ 710 public uint newMergeId() 711 { 712 return gtk_ui_manager_new_merge_id(gtkUIManager); 713 } 714 715 /** 716 * Removes an action group from the list of action groups associated 717 * with @manager. 718 * 719 * Params: 720 * actionGroup = the action group to be removed 721 * 722 * Since: 2.4 723 */ 724 public void removeActionGroup(ActionGroup actionGroup) 725 { 726 gtk_ui_manager_remove_action_group(gtkUIManager, (actionGroup is null) ? null : actionGroup.getActionGroupStruct()); 727 } 728 729 /** 730 * Unmerges the part of @manager's content identified by @merge_id. 731 * 732 * Params: 733 * mergeId = a merge id as returned by gtk_ui_manager_add_ui_from_string() 734 * 735 * Since: 2.4 736 */ 737 public void removeUi(uint mergeId) 738 { 739 gtk_ui_manager_remove_ui(gtkUIManager, mergeId); 740 } 741 742 /** 743 * Sets the “add_tearoffs” property, which controls whether menus 744 * generated by this #GtkUIManager will have tearoff menu items. 745 * 746 * Note that this only affects regular menus. Generated popup 747 * menus never have tearoff menu items. 748 * 749 * Deprecated: Tearoff menus are deprecated and should not 750 * be used in newly written code. 751 * 752 * Params: 753 * addTearoffs = whether tearoff menu items are added 754 * 755 * Since: 2.4 756 */ 757 public void setAddTearoffs(bool addTearoffs) 758 { 759 gtk_ui_manager_set_add_tearoffs(gtkUIManager, addTearoffs); 760 } 761 762 protected class OnActionsChangedDelegateWrapper 763 { 764 static OnActionsChangedDelegateWrapper[] listeners; 765 void delegate(UIManager) dlg; 766 gulong handlerId; 767 768 this(void delegate(UIManager) dlg) 769 { 770 this.dlg = dlg; 771 this.listeners ~= this; 772 } 773 774 void remove(OnActionsChangedDelegateWrapper source) 775 { 776 foreach(index, wrapper; listeners) 777 { 778 if (wrapper.handlerId == source.handlerId) 779 { 780 listeners[index] = null; 781 listeners = std.algorithm.remove(listeners, index); 782 break; 783 } 784 } 785 } 786 } 787 788 /** 789 * The ::actions-changed signal is emitted whenever the set of actions 790 * changes. 791 * 792 * Since: 2.4 793 */ 794 gulong addOnActionsChanged(void delegate(UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 795 { 796 auto wrapper = new OnActionsChangedDelegateWrapper(dlg); 797 wrapper.handlerId = Signals.connectData( 798 this, 799 "actions-changed", 800 cast(GCallback)&callBackActionsChanged, 801 cast(void*)wrapper, 802 cast(GClosureNotify)&callBackActionsChangedDestroy, 803 connectFlags); 804 return wrapper.handlerId; 805 } 806 807 extern(C) static void callBackActionsChanged(GtkUIManager* uimanagerStruct, OnActionsChangedDelegateWrapper wrapper) 808 { 809 wrapper.dlg(wrapper.outer); 810 } 811 812 extern(C) static void callBackActionsChangedDestroy(OnActionsChangedDelegateWrapper wrapper, GClosure* closure) 813 { 814 wrapper.remove(wrapper); 815 } 816 817 protected class OnAddWidgetDelegateWrapper 818 { 819 static OnAddWidgetDelegateWrapper[] listeners; 820 void delegate(Widget, UIManager) dlg; 821 gulong handlerId; 822 823 this(void delegate(Widget, UIManager) dlg) 824 { 825 this.dlg = dlg; 826 this.listeners ~= this; 827 } 828 829 void remove(OnAddWidgetDelegateWrapper source) 830 { 831 foreach(index, wrapper; listeners) 832 { 833 if (wrapper.handlerId == source.handlerId) 834 { 835 listeners[index] = null; 836 listeners = std.algorithm.remove(listeners, index); 837 break; 838 } 839 } 840 } 841 } 842 843 /** 844 * The ::add-widget signal is emitted for each generated menubar and toolbar. 845 * It is not emitted for generated popup menus, which can be obtained by 846 * gtk_ui_manager_get_widget(). 847 * 848 * Params: 849 * widget = the added widget 850 * 851 * Since: 2.4 852 */ 853 gulong addOnAddWidget(void delegate(Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 854 { 855 auto wrapper = new OnAddWidgetDelegateWrapper(dlg); 856 wrapper.handlerId = Signals.connectData( 857 this, 858 "add-widget", 859 cast(GCallback)&callBackAddWidget, 860 cast(void*)wrapper, 861 cast(GClosureNotify)&callBackAddWidgetDestroy, 862 connectFlags); 863 return wrapper.handlerId; 864 } 865 866 extern(C) static void callBackAddWidget(GtkUIManager* uimanagerStruct, GtkWidget* widget, OnAddWidgetDelegateWrapper wrapper) 867 { 868 wrapper.dlg(ObjectG.getDObject!(Widget)(widget), wrapper.outer); 869 } 870 871 extern(C) static void callBackAddWidgetDestroy(OnAddWidgetDelegateWrapper wrapper, GClosure* closure) 872 { 873 wrapper.remove(wrapper); 874 } 875 876 protected class OnConnectProxyDelegateWrapper 877 { 878 static OnConnectProxyDelegateWrapper[] listeners; 879 void delegate(Action, Widget, UIManager) dlg; 880 gulong handlerId; 881 882 this(void delegate(Action, Widget, UIManager) dlg) 883 { 884 this.dlg = dlg; 885 this.listeners ~= this; 886 } 887 888 void remove(OnConnectProxyDelegateWrapper source) 889 { 890 foreach(index, wrapper; listeners) 891 { 892 if (wrapper.handlerId == source.handlerId) 893 { 894 listeners[index] = null; 895 listeners = std.algorithm.remove(listeners, index); 896 break; 897 } 898 } 899 } 900 } 901 902 /** 903 * The ::connect-proxy signal is emitted after connecting a proxy to 904 * an action in the group. 905 * 906 * This is intended for simple customizations for which a custom action 907 * class would be too clumsy, e.g. showing tooltips for menuitems in the 908 * statusbar. 909 * 910 * Params: 911 * action = the action 912 * proxy = the proxy 913 * 914 * Since: 2.4 915 */ 916 gulong addOnConnectProxy(void delegate(Action, Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 917 { 918 auto wrapper = new OnConnectProxyDelegateWrapper(dlg); 919 wrapper.handlerId = Signals.connectData( 920 this, 921 "connect-proxy", 922 cast(GCallback)&callBackConnectProxy, 923 cast(void*)wrapper, 924 cast(GClosureNotify)&callBackConnectProxyDestroy, 925 connectFlags); 926 return wrapper.handlerId; 927 } 928 929 extern(C) static void callBackConnectProxy(GtkUIManager* uimanagerStruct, GtkAction* action, GtkWidget* proxy, OnConnectProxyDelegateWrapper wrapper) 930 { 931 wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer); 932 } 933 934 extern(C) static void callBackConnectProxyDestroy(OnConnectProxyDelegateWrapper wrapper, GClosure* closure) 935 { 936 wrapper.remove(wrapper); 937 } 938 939 protected class OnDisconnectProxyDelegateWrapper 940 { 941 static OnDisconnectProxyDelegateWrapper[] listeners; 942 void delegate(Action, Widget, UIManager) dlg; 943 gulong handlerId; 944 945 this(void delegate(Action, Widget, UIManager) dlg) 946 { 947 this.dlg = dlg; 948 this.listeners ~= this; 949 } 950 951 void remove(OnDisconnectProxyDelegateWrapper source) 952 { 953 foreach(index, wrapper; listeners) 954 { 955 if (wrapper.handlerId == source.handlerId) 956 { 957 listeners[index] = null; 958 listeners = std.algorithm.remove(listeners, index); 959 break; 960 } 961 } 962 } 963 } 964 965 /** 966 * The ::disconnect-proxy signal is emitted after disconnecting a proxy 967 * from an action in the group. 968 * 969 * Params: 970 * action = the action 971 * proxy = the proxy 972 * 973 * Since: 2.4 974 */ 975 gulong addOnDisconnectProxy(void delegate(Action, Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 976 { 977 auto wrapper = new OnDisconnectProxyDelegateWrapper(dlg); 978 wrapper.handlerId = Signals.connectData( 979 this, 980 "disconnect-proxy", 981 cast(GCallback)&callBackDisconnectProxy, 982 cast(void*)wrapper, 983 cast(GClosureNotify)&callBackDisconnectProxyDestroy, 984 connectFlags); 985 return wrapper.handlerId; 986 } 987 988 extern(C) static void callBackDisconnectProxy(GtkUIManager* uimanagerStruct, GtkAction* action, GtkWidget* proxy, OnDisconnectProxyDelegateWrapper wrapper) 989 { 990 wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer); 991 } 992 993 extern(C) static void callBackDisconnectProxyDestroy(OnDisconnectProxyDelegateWrapper wrapper, GClosure* closure) 994 { 995 wrapper.remove(wrapper); 996 } 997 998 protected class OnPostActivateDelegateWrapper 999 { 1000 static OnPostActivateDelegateWrapper[] listeners; 1001 void delegate(Action, UIManager) dlg; 1002 gulong handlerId; 1003 1004 this(void delegate(Action, UIManager) dlg) 1005 { 1006 this.dlg = dlg; 1007 this.listeners ~= this; 1008 } 1009 1010 void remove(OnPostActivateDelegateWrapper source) 1011 { 1012 foreach(index, wrapper; listeners) 1013 { 1014 if (wrapper.handlerId == source.handlerId) 1015 { 1016 listeners[index] = null; 1017 listeners = std.algorithm.remove(listeners, index); 1018 break; 1019 } 1020 } 1021 } 1022 } 1023 1024 /** 1025 * The ::post-activate signal is emitted just after the @action 1026 * is activated. 1027 * 1028 * This is intended for applications to get notification 1029 * just after any action is activated. 1030 * 1031 * Params: 1032 * action = the action 1033 * 1034 * Since: 2.4 1035 */ 1036 gulong addOnPostActivate(void delegate(Action, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1037 { 1038 auto wrapper = new OnPostActivateDelegateWrapper(dlg); 1039 wrapper.handlerId = Signals.connectData( 1040 this, 1041 "post-activate", 1042 cast(GCallback)&callBackPostActivate, 1043 cast(void*)wrapper, 1044 cast(GClosureNotify)&callBackPostActivateDestroy, 1045 connectFlags); 1046 return wrapper.handlerId; 1047 } 1048 1049 extern(C) static void callBackPostActivate(GtkUIManager* uimanagerStruct, GtkAction* action, OnPostActivateDelegateWrapper wrapper) 1050 { 1051 wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer); 1052 } 1053 1054 extern(C) static void callBackPostActivateDestroy(OnPostActivateDelegateWrapper wrapper, GClosure* closure) 1055 { 1056 wrapper.remove(wrapper); 1057 } 1058 1059 protected class OnPreActivateDelegateWrapper 1060 { 1061 static OnPreActivateDelegateWrapper[] listeners; 1062 void delegate(Action, UIManager) dlg; 1063 gulong handlerId; 1064 1065 this(void delegate(Action, UIManager) dlg) 1066 { 1067 this.dlg = dlg; 1068 this.listeners ~= this; 1069 } 1070 1071 void remove(OnPreActivateDelegateWrapper source) 1072 { 1073 foreach(index, wrapper; listeners) 1074 { 1075 if (wrapper.handlerId == source.handlerId) 1076 { 1077 listeners[index] = null; 1078 listeners = std.algorithm.remove(listeners, index); 1079 break; 1080 } 1081 } 1082 } 1083 } 1084 1085 /** 1086 * The ::pre-activate signal is emitted just before the @action 1087 * is activated. 1088 * 1089 * This is intended for applications to get notification 1090 * just before any action is activated. 1091 * 1092 * Params: 1093 * action = the action 1094 * 1095 * Since: 2.4 1096 */ 1097 gulong addOnPreActivate(void delegate(Action, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1098 { 1099 auto wrapper = new OnPreActivateDelegateWrapper(dlg); 1100 wrapper.handlerId = Signals.connectData( 1101 this, 1102 "pre-activate", 1103 cast(GCallback)&callBackPreActivate, 1104 cast(void*)wrapper, 1105 cast(GClosureNotify)&callBackPreActivateDestroy, 1106 connectFlags); 1107 return wrapper.handlerId; 1108 } 1109 1110 extern(C) static void callBackPreActivate(GtkUIManager* uimanagerStruct, GtkAction* action, OnPreActivateDelegateWrapper wrapper) 1111 { 1112 wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer); 1113 } 1114 1115 extern(C) static void callBackPreActivateDestroy(OnPreActivateDelegateWrapper wrapper, GClosure* closure) 1116 { 1117 wrapper.remove(wrapper); 1118 } 1119 }