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