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.ActionGroup;
26 
27 private import glib.ConstructionException;
28 private import glib.ListG;
29 private import glib.Str;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtk.AccelGroup;
33 private import gtk.Action;
34 private import gtk.BuildableIF;
35 private import gtk.BuildableT;
36 private import gtk.Widget;
37 public  import gtkc.gdktypes;
38 private import gtkc.gtk;
39 public  import gtkc.gtktypes;
40 private import std.algorithm;
41 
42 
43 /**
44  * Actions are organised into groups. An action group is essentially a
45  * map from names to #GtkAction objects.
46  * 
47  * All actions that would make sense to use in a particular context
48  * should be in a single group. Multiple action groups may be used for a
49  * particular user interface. In fact, it is expected that most nontrivial
50  * applications will make use of multiple groups. For example, in an
51  * application that can edit multiple documents, one group holding global
52  * actions (e.g. quit, about, new), and one group per document holding
53  * actions that act on that document (eg. save, cut/copy/paste, etc). Each
54  * window’s menus would be constructed from a combination of two action
55  * groups.
56  * 
57  * ## Accelerators ## {#Action-Accel}
58  * 
59  * Accelerators are handled by the GTK+ accelerator map. All actions are
60  * assigned an accelerator path (which normally has the form
61  * `<Actions>/group-name/action-name`) and a shortcut is associated with
62  * this accelerator path. All menuitems and toolitems take on this accelerator
63  * path. The GTK+ accelerator map code makes sure that the correct shortcut
64  * is displayed next to the menu item.
65  * 
66  * # GtkActionGroup as GtkBuildable # {#GtkActionGroup-BUILDER-UI}
67  * 
68  * The #GtkActionGroup implementation of the #GtkBuildable interface accepts
69  * #GtkAction objects as <child> elements in UI definitions.
70  * 
71  * Note that it is probably more common to define actions and action groups
72  * in the code, since they are directly related to what the code can do.
73  * 
74  * The GtkActionGroup implementation of the GtkBuildable interface supports
75  * a custom <accelerator> element, which has attributes named “key“ and
76  * “modifiers“ and allows to specify accelerators. This is similar to the
77  * <accelerator> element of #GtkWidget, the main difference is that
78  * it doesn’t allow you to specify a signal.
79  * 
80  * ## A #GtkDialog UI definition fragment. ##
81  * |[
82  * <object class="GtkActionGroup" id="actiongroup">
83  * <child>
84  * <object class="GtkAction" id="About">
85  * <property name="name">About</property>
86  * <property name="stock_id">gtk-about</property>
87  * <signal handler="about_activate" name="activate"/>
88  * </object>
89  * <accelerator key="F1" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>
90  * </child>
91  * </object>
92  * ]|
93  */
94 public class ActionGroup : ObjectG, BuildableIF
95 {
96 	/** the main Gtk struct */
97 	protected GtkActionGroup* gtkActionGroup;
98 
99 	/** Get the main Gtk struct */
100 	public GtkActionGroup* getActionGroupStruct()
101 	{
102 		return gtkActionGroup;
103 	}
104 
105 	/** the main Gtk struct as a void* */
106 	protected override void* getStruct()
107 	{
108 		return cast(void*)gtkActionGroup;
109 	}
110 
111 	protected override void setStruct(GObject* obj)
112 	{
113 		gtkActionGroup = cast(GtkActionGroup*)obj;
114 		super.setStruct(obj);
115 	}
116 
117 	/**
118 	 * Sets our main struct and passes it to the parent class.
119 	 */
120 	public this (GtkActionGroup* gtkActionGroup, bool ownedRef = false)
121 	{
122 		this.gtkActionGroup = gtkActionGroup;
123 		super(cast(GObject*)gtkActionGroup, ownedRef);
124 	}
125 
126 	// add the Buildable capabilities
127 	mixin BuildableT!(GtkActionGroup);
128 
129 
130 	/** */
131 	public static GType getType()
132 	{
133 		return gtk_action_group_get_type();
134 	}
135 
136 	/**
137 	 * Creates a new #GtkActionGroup object. The name of the action group
138 	 * is used when associating [keybindings][Action-Accel]
139 	 * with the actions.
140 	 *
141 	 * Params:
142 	 *     name = the name of the action group.
143 	 *
144 	 * Return: the new #GtkActionGroup
145 	 *
146 	 * Since: 2.4
147 	 *
148 	 * Throws: ConstructionException GTK+ fails to create the object.
149 	 */
150 	public this(string name)
151 	{
152 		auto p = gtk_action_group_new(Str.toStringz(name));
153 		
154 		if(p is null)
155 		{
156 			throw new ConstructionException("null returned by new");
157 		}
158 		
159 		this(cast(GtkActionGroup*) p, true);
160 	}
161 
162 	/**
163 	 * Adds an action object to the action group. Note that this function
164 	 * does not set up the accel path of the action, which can lead to problems
165 	 * if a user tries to modify the accelerator of a menuitem associated with
166 	 * the action. Therefore you must either set the accel path yourself with
167 	 * gtk_action_set_accel_path(), or use
168 	 * `gtk_action_group_add_action_with_accel (..., NULL)`.
169 	 *
170 	 * Params:
171 	 *     action = an action
172 	 *
173 	 * Since: 2.4
174 	 */
175 	public void addAction(Action action)
176 	{
177 		gtk_action_group_add_action(gtkActionGroup, (action is null) ? null : action.getActionStruct());
178 	}
179 
180 	/**
181 	 * Adds an action object to the action group and sets up the accelerator.
182 	 *
183 	 * If @accelerator is %NULL, attempts to use the accelerator associated
184 	 * with the stock_id of the action.
185 	 *
186 	 * Accel paths are set to `<Actions>/group-name/action-name`.
187 	 *
188 	 * Params:
189 	 *     action = the action to add
190 	 *     accelerator = the accelerator for the action, in
191 	 *         the format understood by gtk_accelerator_parse(), or "" for no accelerator, or
192 	 *         %NULL to use the stock accelerator
193 	 *
194 	 * Since: 2.4
195 	 */
196 	public void addActionWithAccel(Action action, string accelerator)
197 	{
198 		gtk_action_group_add_action_with_accel(gtkActionGroup, (action is null) ? null : action.getActionStruct(), Str.toStringz(accelerator));
199 	}
200 
201 	/**
202 	 * This is a convenience function to create a number of actions and add them
203 	 * to the action group.
204 	 *
205 	 * The “activate” signals of the actions are connected to the callbacks
206 	 * and their accel paths are set to `<Actions>/group-name/action-name`.
207 	 *
208 	 * Params:
209 	 *     entries = an array of action descriptions
210 	 *     nEntries = the number of entries
211 	 *     userData = data to pass to the action callbacks
212 	 *
213 	 * Since: 2.4
214 	 */
215 	public void addActions(GtkActionEntry[] entries, void* userData)
216 	{
217 		gtk_action_group_add_actions(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData);
218 	}
219 
220 	/**
221 	 * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
222 	 * callback for @user_data.
223 	 *
224 	 * Params:
225 	 *     entries = an array of action descriptions
226 	 *     nEntries = the number of entries
227 	 *     userData = data to pass to the action callbacks
228 	 *     destroy = destroy notification callback for @user_data
229 	 *
230 	 * Since: 2.4
231 	 */
232 	public void addActionsFull(GtkActionEntry[] entries, void* userData, GDestroyNotify destroy)
233 	{
234 		gtk_action_group_add_actions_full(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData, destroy);
235 	}
236 
237 	/**
238 	 * This is a convenience routine to create a group of radio actions and
239 	 * add them to the action group.
240 	 *
241 	 * The “changed” signal of the first radio action is connected to the
242 	 * @on_change callback and the accel paths of the actions are set to
243 	 * `<Actions>/group-name/action-name`.
244 	 *
245 	 * Params:
246 	 *     entries = an array of radio action descriptions
247 	 *     nEntries = the number of entries
248 	 *     value = the value of the action to activate initially, or -1 if
249 	 *         no action should be activated
250 	 *     onChange = the callback to connect to the changed signal
251 	 *     userData = data to pass to the action callbacks
252 	 *
253 	 * Since: 2.4
254 	 */
255 	public void addRadioActions(GtkRadioActionEntry[] entries, int value, GCallback onChange, void* userData)
256 	{
257 		gtk_action_group_add_radio_actions(gtkActionGroup, entries.ptr, cast(uint)entries.length, value, onChange, userData);
258 	}
259 
260 	/**
261 	 * This variant of gtk_action_group_add_radio_actions() adds a
262 	 * #GDestroyNotify callback for @user_data.
263 	 *
264 	 * Params:
265 	 *     entries = an array of radio action descriptions
266 	 *     nEntries = the number of entries
267 	 *     value = the value of the action to activate initially, or -1 if
268 	 *         no action should be activated
269 	 *     onChange = the callback to connect to the changed signal
270 	 *     userData = data to pass to the action callbacks
271 	 *     destroy = destroy notification callback for @user_data
272 	 *
273 	 * Since: 2.4
274 	 */
275 	public void addRadioActionsFull(GtkRadioActionEntry[] entries, int value, GCallback onChange, void* userData, GDestroyNotify destroy)
276 	{
277 		gtk_action_group_add_radio_actions_full(gtkActionGroup, entries.ptr, cast(uint)entries.length, value, onChange, userData, destroy);
278 	}
279 
280 	/**
281 	 * This is a convenience function to create a number of toggle actions and add them
282 	 * to the action group.
283 	 *
284 	 * The “activate” signals of the actions are connected to the callbacks
285 	 * and their accel paths are set to `<Actions>/group-name/action-name`.
286 	 *
287 	 * Params:
288 	 *     entries = an array of toggle action descriptions
289 	 *     nEntries = the number of entries
290 	 *     userData = data to pass to the action callbacks
291 	 *
292 	 * Since: 2.4
293 	 */
294 	public void addToggleActions(GtkToggleActionEntry[] entries, void* userData)
295 	{
296 		gtk_action_group_add_toggle_actions(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData);
297 	}
298 
299 	/**
300 	 * This variant of gtk_action_group_add_toggle_actions() adds a
301 	 * #GDestroyNotify callback for @user_data.
302 	 *
303 	 * Params:
304 	 *     entries = an array of toggle action descriptions
305 	 *     nEntries = the number of entries
306 	 *     userData = data to pass to the action callbacks
307 	 *     destroy = destroy notification callback for @user_data
308 	 *
309 	 * Since: 2.4
310 	 */
311 	public void addToggleActionsFull(GtkToggleActionEntry[] entries, void* userData, GDestroyNotify destroy)
312 	{
313 		gtk_action_group_add_toggle_actions_full(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData, destroy);
314 	}
315 
316 	/**
317 	 * Gets the accelerator group.
318 	 *
319 	 * Return: the accelerator group associated with this action
320 	 *     group or %NULL if there is none.
321 	 *
322 	 * Since: 3.6
323 	 */
324 	public AccelGroup getAccelGroup()
325 	{
326 		auto p = gtk_action_group_get_accel_group(gtkActionGroup);
327 		
328 		if(p is null)
329 		{
330 			return null;
331 		}
332 		
333 		return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p);
334 	}
335 
336 	/**
337 	 * Looks up an action in the action group by name.
338 	 *
339 	 * Params:
340 	 *     actionName = the name of the action
341 	 *
342 	 * Return: the action, or %NULL if no action by that name exists
343 	 *
344 	 * Since: 2.4
345 	 */
346 	public Action getAction(string actionName)
347 	{
348 		auto p = gtk_action_group_get_action(gtkActionGroup, Str.toStringz(actionName));
349 		
350 		if(p is null)
351 		{
352 			return null;
353 		}
354 		
355 		return ObjectG.getDObject!(Action)(cast(GtkAction*) p);
356 	}
357 
358 	/**
359 	 * Gets the name of the action group.
360 	 *
361 	 * Return: the name of the action group.
362 	 *
363 	 * Since: 2.4
364 	 */
365 	public string getName()
366 	{
367 		return Str.toString(gtk_action_group_get_name(gtkActionGroup));
368 	}
369 
370 	/**
371 	 * Returns %TRUE if the group is sensitive.  The constituent actions
372 	 * can only be logically sensitive (see gtk_action_is_sensitive()) if
373 	 * they are sensitive (see gtk_action_get_sensitive()) and their group
374 	 * is sensitive.
375 	 *
376 	 * Return: %TRUE if the group is sensitive.
377 	 *
378 	 * Since: 2.4
379 	 */
380 	public bool getSensitive()
381 	{
382 		return gtk_action_group_get_sensitive(gtkActionGroup) != 0;
383 	}
384 
385 	/**
386 	 * Returns %TRUE if the group is visible.  The constituent actions
387 	 * can only be logically visible (see gtk_action_is_visible()) if
388 	 * they are visible (see gtk_action_get_visible()) and their group
389 	 * is visible.
390 	 *
391 	 * Return: %TRUE if the group is visible.
392 	 *
393 	 * Since: 2.4
394 	 */
395 	public bool getVisible()
396 	{
397 		return gtk_action_group_get_visible(gtkActionGroup) != 0;
398 	}
399 
400 	/**
401 	 * Lists the actions in the action group.
402 	 *
403 	 * Return: an allocated list of the action objects in the action group
404 	 *
405 	 * Since: 2.4
406 	 */
407 	public ListG listActions()
408 	{
409 		auto p = gtk_action_group_list_actions(gtkActionGroup);
410 		
411 		if(p is null)
412 		{
413 			return null;
414 		}
415 		
416 		return new ListG(cast(GList*) p);
417 	}
418 
419 	/**
420 	 * Removes an action object from the action group.
421 	 *
422 	 * Params:
423 	 *     action = an action
424 	 *
425 	 * Since: 2.4
426 	 */
427 	public void removeAction(Action action)
428 	{
429 		gtk_action_group_remove_action(gtkActionGroup, (action is null) ? null : action.getActionStruct());
430 	}
431 
432 	/**
433 	 * Sets the accelerator group to be used by every action in this group.
434 	 *
435 	 * Params:
436 	 *     accelGroup = a #GtkAccelGroup to set or %NULL
437 	 *
438 	 * Since: 3.6
439 	 */
440 	public void setAccelGroup(AccelGroup accelGroup)
441 	{
442 		gtk_action_group_set_accel_group(gtkActionGroup, (accelGroup is null) ? null : accelGroup.getAccelGroupStruct());
443 	}
444 
445 	/**
446 	 * Changes the sensitivity of @action_group
447 	 *
448 	 * Params:
449 	 *     sensitive = new sensitivity
450 	 *
451 	 * Since: 2.4
452 	 */
453 	public void setSensitive(bool sensitive)
454 	{
455 		gtk_action_group_set_sensitive(gtkActionGroup, sensitive);
456 	}
457 
458 	/**
459 	 * Sets a function to be used for translating the @label and @tooltip of
460 	 * #GtkActionEntrys added by gtk_action_group_add_actions().
461 	 *
462 	 * If you’re using gettext(), it is enough to set the translation domain
463 	 * with gtk_action_group_set_translation_domain().
464 	 *
465 	 * Params:
466 	 *     func = a #GtkTranslateFunc
467 	 *     data = data to be passed to @func and @notify
468 	 *     notify = a #GDestroyNotify function to be called when @action_group is
469 	 *         destroyed and when the translation function is changed again
470 	 *
471 	 * Since: 2.4
472 	 */
473 	public void setTranslateFunc(GtkTranslateFunc func, void* data, GDestroyNotify notify)
474 	{
475 		gtk_action_group_set_translate_func(gtkActionGroup, func, data, notify);
476 	}
477 
478 	/**
479 	 * Sets the translation domain and uses g_dgettext() for translating the
480 	 * @label and @tooltip of #GtkActionEntrys added by
481 	 * gtk_action_group_add_actions().
482 	 *
483 	 * If you’re not using gettext() for localization, see
484 	 * gtk_action_group_set_translate_func().
485 	 *
486 	 * Params:
487 	 *     domain = the translation domain to use for g_dgettext()
488 	 *         calls, or %NULL to use the domain set with textdomain()
489 	 *
490 	 * Since: 2.4
491 	 */
492 	public void setTranslationDomain(string domain)
493 	{
494 		gtk_action_group_set_translation_domain(gtkActionGroup, Str.toStringz(domain));
495 	}
496 
497 	/**
498 	 * Changes the visible of @action_group.
499 	 *
500 	 * Params:
501 	 *     visible = new visiblity
502 	 *
503 	 * Since: 2.4
504 	 */
505 	public void setVisible(bool visible)
506 	{
507 		gtk_action_group_set_visible(gtkActionGroup, visible);
508 	}
509 
510 	/**
511 	 * Translates a string using the function set with
512 	 * gtk_action_group_set_translate_func(). This
513 	 * is mainly intended for language bindings.
514 	 *
515 	 * Params:
516 	 *     str = a string
517 	 *
518 	 * Return: the translation of @string
519 	 *
520 	 * Since: 2.6
521 	 */
522 	public string translateString(string str)
523 	{
524 		return Str.toString(gtk_action_group_translate_string(gtkActionGroup, Str.toStringz(str)));
525 	}
526 
527 	protected class OnConnectProxyDelegateWrapper
528 	{
529 		void delegate(Action, Widget, ActionGroup) dlg;
530 		gulong handlerId;
531 		ConnectFlags flags;
532 		this(void delegate(Action, Widget, ActionGroup) dlg, gulong handlerId, ConnectFlags flags)
533 		{
534 			this.dlg = dlg;
535 			this.handlerId = handlerId;
536 			this.flags = flags;
537 		}
538 	}
539 	protected OnConnectProxyDelegateWrapper[] onConnectProxyListeners;
540 
541 	/**
542 	 * The ::connect-proxy signal is emitted after connecting a proxy to
543 	 * an action in the group. Note that the proxy may have been connected
544 	 * to a different action before.
545 	 *
546 	 * This is intended for simple customizations for which a custom action
547 	 * class would be too clumsy, e.g. showing tooltips for menuitems in the
548 	 * statusbar.
549 	 *
550 	 * #GtkUIManager proxies the signal and provides global notification
551 	 * just before any action is connected to a proxy, which is probably more
552 	 * convenient to use.
553 	 *
554 	 * Params:
555 	 *     action = the action
556 	 *     proxy = the proxy
557 	 *
558 	 * Since: 2.4
559 	 */
560 	gulong addOnConnectProxy(void delegate(Action, Widget, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
561 	{
562 		onConnectProxyListeners ~= new OnConnectProxyDelegateWrapper(dlg, 0, connectFlags);
563 		onConnectProxyListeners[onConnectProxyListeners.length - 1].handlerId = Signals.connectData(
564 			this,
565 			"connect-proxy",
566 			cast(GCallback)&callBackConnectProxy,
567 			cast(void*)onConnectProxyListeners[onConnectProxyListeners.length - 1],
568 			cast(GClosureNotify)&callBackConnectProxyDestroy,
569 			connectFlags);
570 		return onConnectProxyListeners[onConnectProxyListeners.length - 1].handlerId;
571 	}
572 	
573 	extern(C) static void callBackConnectProxy(GtkActionGroup* actiongroupStruct, GtkAction* action, GtkWidget* proxy,OnConnectProxyDelegateWrapper wrapper)
574 	{
575 		wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer);
576 	}
577 	
578 	extern(C) static void callBackConnectProxyDestroy(OnConnectProxyDelegateWrapper wrapper, GClosure* closure)
579 	{
580 		wrapper.outer.internalRemoveOnConnectProxy(wrapper);
581 	}
582 
583 	protected void internalRemoveOnConnectProxy(OnConnectProxyDelegateWrapper source)
584 	{
585 		foreach(index, wrapper; onConnectProxyListeners)
586 		{
587 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
588 			{
589 				onConnectProxyListeners[index] = null;
590 				onConnectProxyListeners = std.algorithm.remove(onConnectProxyListeners, index);
591 				break;
592 			}
593 		}
594 	}
595 	
596 
597 	protected class OnDisconnectProxyDelegateWrapper
598 	{
599 		void delegate(Action, Widget, ActionGroup) dlg;
600 		gulong handlerId;
601 		ConnectFlags flags;
602 		this(void delegate(Action, Widget, ActionGroup) dlg, gulong handlerId, ConnectFlags flags)
603 		{
604 			this.dlg = dlg;
605 			this.handlerId = handlerId;
606 			this.flags = flags;
607 		}
608 	}
609 	protected OnDisconnectProxyDelegateWrapper[] onDisconnectProxyListeners;
610 
611 	/**
612 	 * The ::disconnect-proxy signal is emitted after disconnecting a proxy
613 	 * from an action in the group.
614 	 *
615 	 * #GtkUIManager proxies the signal and provides global notification
616 	 * just before any action is connected to a proxy, which is probably more
617 	 * convenient to use.
618 	 *
619 	 * Params:
620 	 *     action = the action
621 	 *     proxy = the proxy
622 	 *
623 	 * Since: 2.4
624 	 */
625 	gulong addOnDisconnectProxy(void delegate(Action, Widget, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
626 	{
627 		onDisconnectProxyListeners ~= new OnDisconnectProxyDelegateWrapper(dlg, 0, connectFlags);
628 		onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1].handlerId = Signals.connectData(
629 			this,
630 			"disconnect-proxy",
631 			cast(GCallback)&callBackDisconnectProxy,
632 			cast(void*)onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1],
633 			cast(GClosureNotify)&callBackDisconnectProxyDestroy,
634 			connectFlags);
635 		return onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1].handlerId;
636 	}
637 	
638 	extern(C) static void callBackDisconnectProxy(GtkActionGroup* actiongroupStruct, GtkAction* action, GtkWidget* proxy,OnDisconnectProxyDelegateWrapper wrapper)
639 	{
640 		wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer);
641 	}
642 	
643 	extern(C) static void callBackDisconnectProxyDestroy(OnDisconnectProxyDelegateWrapper wrapper, GClosure* closure)
644 	{
645 		wrapper.outer.internalRemoveOnDisconnectProxy(wrapper);
646 	}
647 
648 	protected void internalRemoveOnDisconnectProxy(OnDisconnectProxyDelegateWrapper source)
649 	{
650 		foreach(index, wrapper; onDisconnectProxyListeners)
651 		{
652 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
653 			{
654 				onDisconnectProxyListeners[index] = null;
655 				onDisconnectProxyListeners = std.algorithm.remove(onDisconnectProxyListeners, index);
656 				break;
657 			}
658 		}
659 	}
660 	
661 
662 	protected class OnPostActivateDelegateWrapper
663 	{
664 		void delegate(Action, ActionGroup) dlg;
665 		gulong handlerId;
666 		ConnectFlags flags;
667 		this(void delegate(Action, ActionGroup) dlg, gulong handlerId, ConnectFlags flags)
668 		{
669 			this.dlg = dlg;
670 			this.handlerId = handlerId;
671 			this.flags = flags;
672 		}
673 	}
674 	protected OnPostActivateDelegateWrapper[] onPostActivateListeners;
675 
676 	/**
677 	 * The ::post-activate signal is emitted just after the @action in the
678 	 * @action_group is activated
679 	 *
680 	 * This is intended for #GtkUIManager to proxy the signal and provide global
681 	 * notification just after any action is activated.
682 	 *
683 	 * Params:
684 	 *     action = the action
685 	 *
686 	 * Since: 2.4
687 	 */
688 	gulong addOnPostActivate(void delegate(Action, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
689 	{
690 		onPostActivateListeners ~= new OnPostActivateDelegateWrapper(dlg, 0, connectFlags);
691 		onPostActivateListeners[onPostActivateListeners.length - 1].handlerId = Signals.connectData(
692 			this,
693 			"post-activate",
694 			cast(GCallback)&callBackPostActivate,
695 			cast(void*)onPostActivateListeners[onPostActivateListeners.length - 1],
696 			cast(GClosureNotify)&callBackPostActivateDestroy,
697 			connectFlags);
698 		return onPostActivateListeners[onPostActivateListeners.length - 1].handlerId;
699 	}
700 	
701 	extern(C) static void callBackPostActivate(GtkActionGroup* actiongroupStruct, GtkAction* action,OnPostActivateDelegateWrapper wrapper)
702 	{
703 		wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer);
704 	}
705 	
706 	extern(C) static void callBackPostActivateDestroy(OnPostActivateDelegateWrapper wrapper, GClosure* closure)
707 	{
708 		wrapper.outer.internalRemoveOnPostActivate(wrapper);
709 	}
710 
711 	protected void internalRemoveOnPostActivate(OnPostActivateDelegateWrapper source)
712 	{
713 		foreach(index, wrapper; onPostActivateListeners)
714 		{
715 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
716 			{
717 				onPostActivateListeners[index] = null;
718 				onPostActivateListeners = std.algorithm.remove(onPostActivateListeners, index);
719 				break;
720 			}
721 		}
722 	}
723 	
724 
725 	protected class OnPreActivateDelegateWrapper
726 	{
727 		void delegate(Action, ActionGroup) dlg;
728 		gulong handlerId;
729 		ConnectFlags flags;
730 		this(void delegate(Action, ActionGroup) dlg, gulong handlerId, ConnectFlags flags)
731 		{
732 			this.dlg = dlg;
733 			this.handlerId = handlerId;
734 			this.flags = flags;
735 		}
736 	}
737 	protected OnPreActivateDelegateWrapper[] onPreActivateListeners;
738 
739 	/**
740 	 * The ::pre-activate signal is emitted just before the @action in the
741 	 * @action_group is activated
742 	 *
743 	 * This is intended for #GtkUIManager to proxy the signal and provide global
744 	 * notification just before any action is activated.
745 	 *
746 	 * Params:
747 	 *     action = the action
748 	 *
749 	 * Since: 2.4
750 	 */
751 	gulong addOnPreActivate(void delegate(Action, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
752 	{
753 		onPreActivateListeners ~= new OnPreActivateDelegateWrapper(dlg, 0, connectFlags);
754 		onPreActivateListeners[onPreActivateListeners.length - 1].handlerId = Signals.connectData(
755 			this,
756 			"pre-activate",
757 			cast(GCallback)&callBackPreActivate,
758 			cast(void*)onPreActivateListeners[onPreActivateListeners.length - 1],
759 			cast(GClosureNotify)&callBackPreActivateDestroy,
760 			connectFlags);
761 		return onPreActivateListeners[onPreActivateListeners.length - 1].handlerId;
762 	}
763 	
764 	extern(C) static void callBackPreActivate(GtkActionGroup* actiongroupStruct, GtkAction* action,OnPreActivateDelegateWrapper wrapper)
765 	{
766 		wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer);
767 	}
768 	
769 	extern(C) static void callBackPreActivateDestroy(OnPreActivateDelegateWrapper wrapper, GClosure* closure)
770 	{
771 		wrapper.outer.internalRemoveOnPreActivate(wrapper);
772 	}
773 
774 	protected void internalRemoveOnPreActivate(OnPreActivateDelegateWrapper source)
775 	{
776 		foreach(index, wrapper; onPreActivateListeners)
777 		{
778 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
779 			{
780 				onPreActivateListeners[index] = null;
781 				onPreActivateListeners = std.algorithm.remove(onPreActivateListeners, index);
782 				break;
783 			}
784 		}
785 	}
786 	
787 }