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.MenuItem;
26 
27 private import glib.ConstructionException;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.AccelGroup;
32 private import gtk.ActionableIF;
33 private import gtk.ActionableT;
34 private import gtk.ActivatableIF;
35 private import gtk.ActivatableT;
36 private import gtk.Bin;
37 private import gtk.Menu;
38 private import gtk.Widget;
39 public  import gtkc.gdktypes;
40 private import gtkc.gtk;
41 public  import gtkc.gtktypes;
42 private import std.algorithm;
43 
44 
45 /**
46  * The #GtkMenuItem widget and the derived widgets are the only valid
47  * children for menus. Their function is to correctly handle highlighting,
48  * alignment, events and submenus.
49  * 
50  * As a GtkMenuItem derives from #GtkBin it can hold any valid child widget,
51  * although only a few are really useful.
52  * 
53  * By default, a GtkMenuItem sets a #GtkAccelLabel as its child.
54  * GtkMenuItem has direct functions to set the label and its mnemonic.
55  * For more advanced label settings, you can fetch the child widget from the GtkBin.
56  * 
57  * An example for setting markup and accelerator on a MenuItem:
58  * |[<!-- language="C" -->
59  * GtkWidget *child = gtk_bin_get_child (GTK_BIN (menu_item));
60  * gtk_label_set_markup (GTK_LABEL (child), "<i>new label</i> with <b>markup</b>");
61  * gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), GDK_KEY_1, 0);
62  * ]|
63  * 
64  * # GtkMenuItem as GtkBuildable
65  * 
66  * The GtkMenuItem implementation of the #GtkBuildable interface supports
67  * adding a submenu by specifying “submenu” as the “type” attribute of
68  * a <child> element.
69  * 
70  * An example of UI definition fragment with submenus:
71  * |[
72  * <object class="GtkMenuItem">
73  * <child type="submenu">
74  * <object class="GtkMenu"/>
75  * </child>
76  * </object>
77  * ]|
78  * 
79  * # CSS nodes
80  * 
81  * |[<!-- language="plain" -->
82  * menuitem
83  * ├── <child>
84  * ╰── [arrow.right]
85  * ]|
86  * 
87  * GtkMenuItem has a single CSS node with name menuitem. If the menuitem
88  * has a submenu, it gets another CSS node with name arrow, which has
89  * the .left or .right style class.
90  */
91 public class MenuItem : Bin, ActionableIF, ActivatableIF
92 {
93 	/** the main Gtk struct */
94 	protected GtkMenuItem* gtkMenuItem;
95 
96 	/** Get the main Gtk struct */
97 	public GtkMenuItem* getMenuItemStruct()
98 	{
99 		return gtkMenuItem;
100 	}
101 
102 	/** the main Gtk struct as a void* */
103 	protected override void* getStruct()
104 	{
105 		return cast(void*)gtkMenuItem;
106 	}
107 
108 	protected override void setStruct(GObject* obj)
109 	{
110 		gtkMenuItem = cast(GtkMenuItem*)obj;
111 		super.setStruct(obj);
112 	}
113 
114 	/**
115 	 * Sets our main struct and passes it to the parent class.
116 	 */
117 	public this (GtkMenuItem* gtkMenuItem, bool ownedRef = false)
118 	{
119 		this.gtkMenuItem = gtkMenuItem;
120 		super(cast(GtkBin*)gtkMenuItem, ownedRef);
121 	}
122 
123 	// add the Actionable capabilities
124 	mixin ActionableT!(GtkMenuItem);
125 
126 	// add the Activatable capabilities
127 	mixin ActivatableT!(GtkMenuItem);
128 
129 	/** store the action code passed in by the applcation */
130 	private string actionLabel;
131 	
132 	/** Gets the application set action code */
133 	public string getActionName()
134 	{
135 		if ( actionLabel is null )
136 		{
137 			actionLabel = "";
138 		}
139 		return actionLabel;
140 	}
141 	
142 	/**
143 	 * Creates a new menu item with a label and a listener and a action.
144 	 * used for backward compatibily with DUI.
145 	 */
146 	this(string label, void delegate(MenuItem)dlg, string action)
147 	{
148 		this(label);
149 		this.actionLabel = action;
150 		addOnActivate(dlg);
151 	}
152 	
153 	/**
154 	 * Creates a new Item associated with a "activate" delegate and with a action code
155 	 * and optionally accelGroup
156 	 */
157 	public this(void delegate(MenuItem) dlg, string label, string action,
158 	bool mnemonic=true,
159 	AccelGroup accelGroup=null,
160 	char accelKey='\0',
161 	GdkModifierType modifierType=GdkModifierType.CONTROL_MASK,
162 	GtkAccelFlags accelFlags=GtkAccelFlags.VISIBLE
163 	)
164 	{
165 		this(label, mnemonic);
166 		this.actionLabel = action;
167 		addOnActivate(dlg);
168 		if ( accelGroup !is null && accelKey != '\0' )
169 		{
170 			addAccelerator("activate",accelGroup,accelKey,modifierType,accelFlags);
171 		}
172 	}
173 	
174 	/**
175 	 * Creates a new Item associated with a "activate" delegate
176 	 */
177 	public this(void delegate(MenuItem) dlg, string label, bool mnemonic=true)
178 	{
179 		this(label, mnemonic);
180 		addOnActivate(dlg);
181 	}
182 	
183 	/**
184 	 * Creates a new GtkMenuItem whose child is a GtkLabel.
185 	 * Params:
186 	 *  label = the text for the label
187 	 *  mnemonic = if true the label
188 	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
189 	 *  in label indicate the mnemonic for the menu item.
190 	 * Throws: ConstructionException GTK+ fails to create the object.
191 	 */
192 	public this (string label, bool mnemonic=true)
193 	{
194 		GtkMenuItem* p;
195 		
196 		if ( mnemonic )
197 		{
198 			// GtkWidget* gtk_menu_item_new_with_mnemonic (const gchar *label);
199 			p = cast(GtkMenuItem*)gtk_menu_item_new_with_mnemonic(Str.toStringz(label));
200 		}
201 		else
202 		{
203 			// GtkWidget* gtk_menu_item_new_with_label (const gchar *label);
204 			p = cast(GtkMenuItem*)gtk_menu_item_new_with_label(Str.toStringz(label));
205 		}
206 		
207 		if(p is null)
208 		{
209 			throw new ConstructionException("null returned by gtk_menu_item_new_with_");
210 		}
211 		
212 		this(p);
213 		
214 		setName(label);
215 	}
216 
217 	/**
218 	 */
219 
220 	/** */
221 	public static GType getType()
222 	{
223 		return gtk_menu_item_get_type();
224 	}
225 
226 	/**
227 	 * Creates a new #GtkMenuItem.
228 	 *
229 	 * Return: the newly created #GtkMenuItem
230 	 *
231 	 * Throws: ConstructionException GTK+ fails to create the object.
232 	 */
233 	public this()
234 	{
235 		auto p = gtk_menu_item_new();
236 		
237 		if(p is null)
238 		{
239 			throw new ConstructionException("null returned by new");
240 		}
241 		
242 		this(cast(GtkMenuItem*) p);
243 	}
244 
245 	/**
246 	 * Emits the #GtkMenuItem::activate signal on the given item
247 	 */
248 	public void itemActivate()
249 	{
250 		gtk_menu_item_activate(gtkMenuItem);
251 	}
252 
253 	/**
254 	 * Emits the #GtkMenuItem::deselect signal on the given item.
255 	 */
256 	public void deselect()
257 	{
258 		gtk_menu_item_deselect(gtkMenuItem);
259 	}
260 
261 	/**
262 	 * Retrieve the accelerator path that was previously set on @menu_item.
263 	 *
264 	 * See gtk_menu_item_set_accel_path() for details.
265 	 *
266 	 * Return: the accelerator path corresponding to
267 	 *     this menu item’s functionality, or %NULL if not set
268 	 *
269 	 * Since: 2.14
270 	 */
271 	public string getAccelPath()
272 	{
273 		return Str.toString(gtk_menu_item_get_accel_path(gtkMenuItem));
274 	}
275 
276 	/**
277 	 * Sets @text on the @menu_item label
278 	 *
279 	 * Return: The text in the @menu_item label. This is the internal
280 	 *     string used by the label, and must not be modified.
281 	 *
282 	 * Since: 2.16
283 	 */
284 	public string getLabel()
285 	{
286 		return Str.toString(gtk_menu_item_get_label(gtkMenuItem));
287 	}
288 
289 	/**
290 	 * Returns whether the @menu_item reserves space for
291 	 * the submenu indicator, regardless if it has a submenu
292 	 * or not.
293 	 *
294 	 * Return: %TRUE if @menu_item always reserves space for the
295 	 *     submenu indicator
296 	 *
297 	 * Since: 3.0
298 	 */
299 	public bool getReserveIndicator()
300 	{
301 		return gtk_menu_item_get_reserve_indicator(gtkMenuItem) != 0;
302 	}
303 
304 	/**
305 	 * Gets whether the menu item appears justified at the right
306 	 * side of the menu bar.
307 	 *
308 	 * Deprecated: See gtk_menu_item_set_right_justified()
309 	 *
310 	 * Return: %TRUE if the menu item will appear at the
311 	 *     far right if added to a menu bar.
312 	 */
313 	public bool getRightJustified()
314 	{
315 		return gtk_menu_item_get_right_justified(gtkMenuItem) != 0;
316 	}
317 
318 	/**
319 	 * Gets the submenu underneath this menu item, if any.
320 	 * See gtk_menu_item_set_submenu().
321 	 *
322 	 * Return: submenu for this menu item, or %NULL if none
323 	 */
324 	public Widget getSubmenu()
325 	{
326 		auto p = gtk_menu_item_get_submenu(gtkMenuItem);
327 		
328 		if(p is null)
329 		{
330 			return null;
331 		}
332 		
333 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
334 	}
335 
336 	/**
337 	 * Checks if an underline in the text indicates the next character
338 	 * should be used for the mnemonic accelerator key.
339 	 *
340 	 * Return: %TRUE if an embedded underline in the label
341 	 *     indicates the mnemonic accelerator key.
342 	 *
343 	 * Since: 2.16
344 	 */
345 	public bool getUseUnderline()
346 	{
347 		return gtk_menu_item_get_use_underline(gtkMenuItem) != 0;
348 	}
349 
350 	/**
351 	 * Emits the #GtkMenuItem::select signal on the given item.
352 	 */
353 	public void select()
354 	{
355 		gtk_menu_item_select(gtkMenuItem);
356 	}
357 
358 	/**
359 	 * Set the accelerator path on @menu_item, through which runtime
360 	 * changes of the menu item’s accelerator caused by the user can be
361 	 * identified and saved to persistent storage (see gtk_accel_map_save()
362 	 * on this). To set up a default accelerator for this menu item, call
363 	 * gtk_accel_map_add_entry() with the same @accel_path. See also
364 	 * gtk_accel_map_add_entry() on the specifics of accelerator paths,
365 	 * and gtk_menu_set_accel_path() for a more convenient variant of
366 	 * this function.
367 	 *
368 	 * This function is basically a convenience wrapper that handles
369 	 * calling gtk_widget_set_accel_path() with the appropriate accelerator
370 	 * group for the menu item.
371 	 *
372 	 * Note that you do need to set an accelerator on the parent menu with
373 	 * gtk_menu_set_accel_group() for this to work.
374 	 *
375 	 * Note that @accel_path string will be stored in a #GQuark.
376 	 * Therefore, if you pass a static string, you can save some memory
377 	 * by interning it first with g_intern_static_string().
378 	 *
379 	 * Params:
380 	 *     accelPath = accelerator path, corresponding to this menu
381 	 *         item’s functionality, or %NULL to unset the current path.
382 	 */
383 	public void setAccelPath(string accelPath)
384 	{
385 		gtk_menu_item_set_accel_path(gtkMenuItem, Str.toStringz(accelPath));
386 	}
387 
388 	/**
389 	 * Sets @text on the @menu_item label
390 	 *
391 	 * Params:
392 	 *     label = the text you want to set
393 	 *
394 	 * Since: 2.16
395 	 */
396 	public void setLabel(string label)
397 	{
398 		gtk_menu_item_set_label(gtkMenuItem, Str.toStringz(label));
399 	}
400 
401 	/**
402 	 * Sets whether the @menu_item should reserve space for
403 	 * the submenu indicator, regardless if it actually has
404 	 * a submenu or not.
405 	 *
406 	 * There should be little need for applications to call
407 	 * this functions.
408 	 *
409 	 * Params:
410 	 *     reserve = the new value
411 	 *
412 	 * Since: 3.0
413 	 */
414 	public void setReserveIndicator(bool reserve)
415 	{
416 		gtk_menu_item_set_reserve_indicator(gtkMenuItem, reserve);
417 	}
418 
419 	/**
420 	 * Sets whether the menu item appears justified at the right
421 	 * side of a menu bar. This was traditionally done for “Help”
422 	 * menu items, but is now considered a bad idea. (If the widget
423 	 * layout is reversed for a right-to-left language like Hebrew
424 	 * or Arabic, right-justified-menu-items appear at the left.)
425 	 *
426 	 * Deprecated: If you insist on using it, use
427 	 * gtk_widget_set_hexpand() and gtk_widget_set_halign().
428 	 *
429 	 * Params:
430 	 *     rightJustified = if %TRUE the menu item will appear at the
431 	 *         far right if added to a menu bar
432 	 */
433 	public void setRightJustified(bool rightJustified)
434 	{
435 		gtk_menu_item_set_right_justified(gtkMenuItem, rightJustified);
436 	}
437 
438 	/**
439 	 * Sets or replaces the menu item’s submenu, or removes it when a %NULL
440 	 * submenu is passed.
441 	 *
442 	 * Params:
443 	 *     submenu = the submenu, or %NULL
444 	 */
445 	public void setSubmenu(Menu submenu)
446 	{
447 		gtk_menu_item_set_submenu(gtkMenuItem, (submenu is null) ? null : cast(GtkWidget*)submenu.getMenuStruct());
448 	}
449 
450 	/**
451 	 * If true, an underline in the text indicates the next character
452 	 * should be used for the mnemonic accelerator key.
453 	 *
454 	 * Params:
455 	 *     setting = %TRUE if underlines in the text indicate mnemonics
456 	 *
457 	 * Since: 2.16
458 	 */
459 	public void setUseUnderline(bool setting)
460 	{
461 		gtk_menu_item_set_use_underline(gtkMenuItem, setting);
462 	}
463 
464 	/**
465 	 * Emits the #GtkMenuItem::toggle-size-allocate signal on the given item.
466 	 *
467 	 * Params:
468 	 *     allocation = the allocation to use as signal data.
469 	 */
470 	public void toggleSizeAllocate(int allocation)
471 	{
472 		gtk_menu_item_toggle_size_allocate(gtkMenuItem, allocation);
473 	}
474 
475 	/**
476 	 * Emits the #GtkMenuItem::toggle-size-request signal on the given item.
477 	 *
478 	 * Params:
479 	 *     requisition = the requisition to use as signal data.
480 	 */
481 	public void toggleSizeRequest(ref int requisition)
482 	{
483 		gtk_menu_item_toggle_size_request(gtkMenuItem, &requisition);
484 	}
485 
486 	protected class OnActivateDelegateWrapper
487 	{
488 		void delegate(MenuItem) dlg;
489 		gulong handlerId;
490 		ConnectFlags flags;
491 		this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags)
492 		{
493 			this.dlg = dlg;
494 			this.handlerId = handlerId;
495 			this.flags = flags;
496 		}
497 	}
498 	protected OnActivateDelegateWrapper[] onActivateListeners;
499 
500 	/**
501 	 * Emitted when the item is activated.
502 	 */
503 	gulong addOnActivate(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
504 	{
505 		onActivateListeners ~= new OnActivateDelegateWrapper(dlg, 0, connectFlags);
506 		onActivateListeners[onActivateListeners.length - 1].handlerId = Signals.connectData(
507 			this,
508 			"activate",
509 			cast(GCallback)&callBackActivate,
510 			cast(void*)onActivateListeners[onActivateListeners.length - 1],
511 			cast(GClosureNotify)&callBackActivateDestroy,
512 			connectFlags);
513 		return onActivateListeners[onActivateListeners.length - 1].handlerId;
514 	}
515 	
516 	extern(C) static void callBackActivate(GtkMenuItem* menuitemStruct,OnActivateDelegateWrapper wrapper)
517 	{
518 		wrapper.dlg(wrapper.outer);
519 	}
520 	
521 	extern(C) static void callBackActivateDestroy(OnActivateDelegateWrapper wrapper, GClosure* closure)
522 	{
523 		wrapper.outer.internalRemoveOnActivate(wrapper);
524 	}
525 
526 	protected void internalRemoveOnActivate(OnActivateDelegateWrapper source)
527 	{
528 		foreach(index, wrapper; onActivateListeners)
529 		{
530 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
531 			{
532 				onActivateListeners[index] = null;
533 				onActivateListeners = std.algorithm.remove(onActivateListeners, index);
534 				break;
535 			}
536 		}
537 	}
538 	
539 
540 	protected class OnActivateItemDelegateWrapper
541 	{
542 		void delegate(MenuItem) dlg;
543 		gulong handlerId;
544 		ConnectFlags flags;
545 		this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags)
546 		{
547 			this.dlg = dlg;
548 			this.handlerId = handlerId;
549 			this.flags = flags;
550 		}
551 	}
552 	protected OnActivateItemDelegateWrapper[] onActivateItemListeners;
553 
554 	/**
555 	 * Emitted when the item is activated, but also if the menu item has a
556 	 * submenu. For normal applications, the relevant signal is
557 	 * #GtkMenuItem::activate.
558 	 */
559 	gulong addOnActivateItem(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
560 	{
561 		onActivateItemListeners ~= new OnActivateItemDelegateWrapper(dlg, 0, connectFlags);
562 		onActivateItemListeners[onActivateItemListeners.length - 1].handlerId = Signals.connectData(
563 			this,
564 			"activate-item",
565 			cast(GCallback)&callBackActivateItem,
566 			cast(void*)onActivateItemListeners[onActivateItemListeners.length - 1],
567 			cast(GClosureNotify)&callBackActivateItemDestroy,
568 			connectFlags);
569 		return onActivateItemListeners[onActivateItemListeners.length - 1].handlerId;
570 	}
571 	
572 	extern(C) static void callBackActivateItem(GtkMenuItem* menuitemStruct,OnActivateItemDelegateWrapper wrapper)
573 	{
574 		wrapper.dlg(wrapper.outer);
575 	}
576 	
577 	extern(C) static void callBackActivateItemDestroy(OnActivateItemDelegateWrapper wrapper, GClosure* closure)
578 	{
579 		wrapper.outer.internalRemoveOnActivateItem(wrapper);
580 	}
581 
582 	protected void internalRemoveOnActivateItem(OnActivateItemDelegateWrapper source)
583 	{
584 		foreach(index, wrapper; onActivateItemListeners)
585 		{
586 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
587 			{
588 				onActivateItemListeners[index] = null;
589 				onActivateItemListeners = std.algorithm.remove(onActivateItemListeners, index);
590 				break;
591 			}
592 		}
593 	}
594 	
595 
596 	protected class OnDeselectDelegateWrapper
597 	{
598 		void delegate(MenuItem) dlg;
599 		gulong handlerId;
600 		ConnectFlags flags;
601 		this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags)
602 		{
603 			this.dlg = dlg;
604 			this.handlerId = handlerId;
605 			this.flags = flags;
606 		}
607 	}
608 	protected OnDeselectDelegateWrapper[] onDeselectListeners;
609 
610 	/** */
611 	gulong addOnDeselect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
612 	{
613 		onDeselectListeners ~= new OnDeselectDelegateWrapper(dlg, 0, connectFlags);
614 		onDeselectListeners[onDeselectListeners.length - 1].handlerId = Signals.connectData(
615 			this,
616 			"deselect",
617 			cast(GCallback)&callBackDeselect,
618 			cast(void*)onDeselectListeners[onDeselectListeners.length - 1],
619 			cast(GClosureNotify)&callBackDeselectDestroy,
620 			connectFlags);
621 		return onDeselectListeners[onDeselectListeners.length - 1].handlerId;
622 	}
623 	
624 	extern(C) static void callBackDeselect(GtkMenuItem* menuitemStruct,OnDeselectDelegateWrapper wrapper)
625 	{
626 		wrapper.dlg(wrapper.outer);
627 	}
628 	
629 	extern(C) static void callBackDeselectDestroy(OnDeselectDelegateWrapper wrapper, GClosure* closure)
630 	{
631 		wrapper.outer.internalRemoveOnDeselect(wrapper);
632 	}
633 
634 	protected void internalRemoveOnDeselect(OnDeselectDelegateWrapper source)
635 	{
636 		foreach(index, wrapper; onDeselectListeners)
637 		{
638 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
639 			{
640 				onDeselectListeners[index] = null;
641 				onDeselectListeners = std.algorithm.remove(onDeselectListeners, index);
642 				break;
643 			}
644 		}
645 	}
646 	
647 
648 	protected class OnSelectDelegateWrapper
649 	{
650 		void delegate(MenuItem) dlg;
651 		gulong handlerId;
652 		ConnectFlags flags;
653 		this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags)
654 		{
655 			this.dlg = dlg;
656 			this.handlerId = handlerId;
657 			this.flags = flags;
658 		}
659 	}
660 	protected OnSelectDelegateWrapper[] onSelectListeners;
661 
662 	/** */
663 	gulong addOnSelect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
664 	{
665 		onSelectListeners ~= new OnSelectDelegateWrapper(dlg, 0, connectFlags);
666 		onSelectListeners[onSelectListeners.length - 1].handlerId = Signals.connectData(
667 			this,
668 			"select",
669 			cast(GCallback)&callBackSelect,
670 			cast(void*)onSelectListeners[onSelectListeners.length - 1],
671 			cast(GClosureNotify)&callBackSelectDestroy,
672 			connectFlags);
673 		return onSelectListeners[onSelectListeners.length - 1].handlerId;
674 	}
675 	
676 	extern(C) static void callBackSelect(GtkMenuItem* menuitemStruct,OnSelectDelegateWrapper wrapper)
677 	{
678 		wrapper.dlg(wrapper.outer);
679 	}
680 	
681 	extern(C) static void callBackSelectDestroy(OnSelectDelegateWrapper wrapper, GClosure* closure)
682 	{
683 		wrapper.outer.internalRemoveOnSelect(wrapper);
684 	}
685 
686 	protected void internalRemoveOnSelect(OnSelectDelegateWrapper source)
687 	{
688 		foreach(index, wrapper; onSelectListeners)
689 		{
690 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
691 			{
692 				onSelectListeners[index] = null;
693 				onSelectListeners = std.algorithm.remove(onSelectListeners, index);
694 				break;
695 			}
696 		}
697 	}
698 	
699 
700 	protected class OnToggleSizeAllocateDelegateWrapper
701 	{
702 		void delegate(int, MenuItem) dlg;
703 		gulong handlerId;
704 		ConnectFlags flags;
705 		this(void delegate(int, MenuItem) dlg, gulong handlerId, ConnectFlags flags)
706 		{
707 			this.dlg = dlg;
708 			this.handlerId = handlerId;
709 			this.flags = flags;
710 		}
711 	}
712 	protected OnToggleSizeAllocateDelegateWrapper[] onToggleSizeAllocateListeners;
713 
714 	/** */
715 	gulong addOnToggleSizeAllocate(void delegate(int, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
716 	{
717 		onToggleSizeAllocateListeners ~= new OnToggleSizeAllocateDelegateWrapper(dlg, 0, connectFlags);
718 		onToggleSizeAllocateListeners[onToggleSizeAllocateListeners.length - 1].handlerId = Signals.connectData(
719 			this,
720 			"toggle-size-allocate",
721 			cast(GCallback)&callBackToggleSizeAllocate,
722 			cast(void*)onToggleSizeAllocateListeners[onToggleSizeAllocateListeners.length - 1],
723 			cast(GClosureNotify)&callBackToggleSizeAllocateDestroy,
724 			connectFlags);
725 		return onToggleSizeAllocateListeners[onToggleSizeAllocateListeners.length - 1].handlerId;
726 	}
727 	
728 	extern(C) static void callBackToggleSizeAllocate(GtkMenuItem* menuitemStruct, int object,OnToggleSizeAllocateDelegateWrapper wrapper)
729 	{
730 		wrapper.dlg(object, wrapper.outer);
731 	}
732 	
733 	extern(C) static void callBackToggleSizeAllocateDestroy(OnToggleSizeAllocateDelegateWrapper wrapper, GClosure* closure)
734 	{
735 		wrapper.outer.internalRemoveOnToggleSizeAllocate(wrapper);
736 	}
737 
738 	protected void internalRemoveOnToggleSizeAllocate(OnToggleSizeAllocateDelegateWrapper source)
739 	{
740 		foreach(index, wrapper; onToggleSizeAllocateListeners)
741 		{
742 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
743 			{
744 				onToggleSizeAllocateListeners[index] = null;
745 				onToggleSizeAllocateListeners = std.algorithm.remove(onToggleSizeAllocateListeners, index);
746 				break;
747 			}
748 		}
749 	}
750 	
751 
752 	protected class OnToggleSizeRequestDelegateWrapper
753 	{
754 		void delegate(void*, MenuItem) dlg;
755 		gulong handlerId;
756 		ConnectFlags flags;
757 		this(void delegate(void*, MenuItem) dlg, gulong handlerId, ConnectFlags flags)
758 		{
759 			this.dlg = dlg;
760 			this.handlerId = handlerId;
761 			this.flags = flags;
762 		}
763 	}
764 	protected OnToggleSizeRequestDelegateWrapper[] onToggleSizeRequestListeners;
765 
766 	/** */
767 	gulong addOnToggleSizeRequest(void delegate(void*, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
768 	{
769 		onToggleSizeRequestListeners ~= new OnToggleSizeRequestDelegateWrapper(dlg, 0, connectFlags);
770 		onToggleSizeRequestListeners[onToggleSizeRequestListeners.length - 1].handlerId = Signals.connectData(
771 			this,
772 			"toggle-size-request",
773 			cast(GCallback)&callBackToggleSizeRequest,
774 			cast(void*)onToggleSizeRequestListeners[onToggleSizeRequestListeners.length - 1],
775 			cast(GClosureNotify)&callBackToggleSizeRequestDestroy,
776 			connectFlags);
777 		return onToggleSizeRequestListeners[onToggleSizeRequestListeners.length - 1].handlerId;
778 	}
779 	
780 	extern(C) static void callBackToggleSizeRequest(GtkMenuItem* menuitemStruct, void* object,OnToggleSizeRequestDelegateWrapper wrapper)
781 	{
782 		wrapper.dlg(object, wrapper.outer);
783 	}
784 	
785 	extern(C) static void callBackToggleSizeRequestDestroy(OnToggleSizeRequestDelegateWrapper wrapper, GClosure* closure)
786 	{
787 		wrapper.outer.internalRemoveOnToggleSizeRequest(wrapper);
788 	}
789 
790 	protected void internalRemoveOnToggleSizeRequest(OnToggleSizeRequestDelegateWrapper source)
791 	{
792 		foreach(index, wrapper; onToggleSizeRequestListeners)
793 		{
794 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
795 			{
796 				onToggleSizeRequestListeners[index] = null;
797 				onToggleSizeRequestListeners = std.algorithm.remove(onToggleSizeRequestListeners, index);
798 				break;
799 			}
800 		}
801 	}
802 	
803 }