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.Assistant;
26 
27 private import gdkpixbuf.Pixbuf;
28 private import glib.ConstructionException;
29 private import glib.Str;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtk.Widget;
33 private import gtk.Window;
34 public  import gtkc.gdktypes;
35 private import gtkc.gtk;
36 public  import gtkc.gtktypes;
37 private import std.algorithm;
38 
39 
40 /**
41  * A #GtkAssistant is a widget used to represent a generally complex
42  * operation splitted in several steps, guiding the user through its
43  * pages and controlling the page flow to collect the necessary data.
44  * 
45  * The design of GtkAssistant is that it controls what buttons to show
46  * and to make sensitive, based on what it knows about the page sequence
47  * and the [type][GtkAssistantPageType] of each page,
48  * in addition to state information like the page
49  * [completion][gtk-assistant-set-page-complete]
50  * and [committed][gtk-assistant-commit] status.
51  * 
52  * If you have a case that doesn’t quite fit in #GtkAssistants way of
53  * handling buttons, you can use the #GTK_ASSISTANT_PAGE_CUSTOM page
54  * type and handle buttons yourself.
55  * 
56  * # GtkAssistant as GtkBuildable
57  * 
58  * The GtkAssistant implementation of the #GtkBuildable interface
59  * exposes the @action_area as internal children with the name
60  * “action_area”.
61  * 
62  * To add pages to an assistant in #GtkBuilder, simply add it as a
63  * child to the GtkAssistant object, and set its child properties
64  * as necessary.
65  * 
66  * # CSS nodes
67  * 
68  * GtkAssistant has a single CSS node with the name assistant.
69  */
70 public class Assistant : Window
71 {
72 	/** the main Gtk struct */
73 	protected GtkAssistant* gtkAssistant;
74 
75 	/** Get the main Gtk struct */
76 	public GtkAssistant* getAssistantStruct()
77 	{
78 		return gtkAssistant;
79 	}
80 
81 	/** the main Gtk struct as a void* */
82 	protected override void* getStruct()
83 	{
84 		return cast(void*)gtkAssistant;
85 	}
86 
87 	protected override void setStruct(GObject* obj)
88 	{
89 		gtkAssistant = cast(GtkAssistant*)obj;
90 		super.setStruct(obj);
91 	}
92 
93 	/**
94 	 * Sets our main struct and passes it to the parent class.
95 	 */
96 	public this (GtkAssistant* gtkAssistant, bool ownedRef = false)
97 	{
98 		this.gtkAssistant = gtkAssistant;
99 		super(cast(GtkWindow*)gtkAssistant, ownedRef);
100 	}
101 
102 
103 	/** */
104 	public static GType getType()
105 	{
106 		return gtk_assistant_get_type();
107 	}
108 
109 	/**
110 	 * Creates a new #GtkAssistant.
111 	 *
112 	 * Return: a newly created #GtkAssistant
113 	 *
114 	 * Since: 2.10
115 	 *
116 	 * Throws: ConstructionException GTK+ fails to create the object.
117 	 */
118 	public this()
119 	{
120 		auto p = gtk_assistant_new();
121 		
122 		if(p is null)
123 		{
124 			throw new ConstructionException("null returned by new");
125 		}
126 		
127 		this(cast(GtkAssistant*) p);
128 	}
129 
130 	/**
131 	 * Adds a widget to the action area of a #GtkAssistant.
132 	 *
133 	 * Params:
134 	 *     child = a #GtkWidget
135 	 *
136 	 * Since: 2.10
137 	 */
138 	public void addActionWidget(Widget child)
139 	{
140 		gtk_assistant_add_action_widget(gtkAssistant, (child is null) ? null : child.getWidgetStruct());
141 	}
142 
143 	/**
144 	 * Appends a page to the @assistant.
145 	 *
146 	 * Params:
147 	 *     page = a #GtkWidget
148 	 *
149 	 * Return: the index (starting at 0) of the inserted page
150 	 *
151 	 * Since: 2.10
152 	 */
153 	public int appendPage(Widget page)
154 	{
155 		return gtk_assistant_append_page(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
156 	}
157 
158 	/**
159 	 * Erases the visited page history so the back button is not
160 	 * shown on the current page, and removes the cancel button
161 	 * from subsequent pages.
162 	 *
163 	 * Use this when the information provided up to the current
164 	 * page is hereafter deemed permanent and cannot be modified
165 	 * or undone. For example, showing a progress page to track
166 	 * a long-running, unreversible operation after the user has
167 	 * clicked apply on a confirmation page.
168 	 *
169 	 * Since: 2.22
170 	 */
171 	public void commit()
172 	{
173 		gtk_assistant_commit(gtkAssistant);
174 	}
175 
176 	/**
177 	 * Returns the page number of the current page.
178 	 *
179 	 * Return: The index (starting from 0) of the current
180 	 *     page in the @assistant, or -1 if the @assistant has no pages,
181 	 *     or no current page.
182 	 *
183 	 * Since: 2.10
184 	 */
185 	public int getCurrentPage()
186 	{
187 		return gtk_assistant_get_current_page(gtkAssistant);
188 	}
189 
190 	/**
191 	 * Returns the number of pages in the @assistant
192 	 *
193 	 * Return: the number of pages in the @assistant
194 	 *
195 	 * Since: 2.10
196 	 */
197 	public int getNPages()
198 	{
199 		return gtk_assistant_get_n_pages(gtkAssistant);
200 	}
201 
202 	/**
203 	 * Returns the child widget contained in page number @page_num.
204 	 *
205 	 * Params:
206 	 *     pageNum = the index of a page in the @assistant,
207 	 *         or -1 to get the last page
208 	 *
209 	 * Return: the child widget, or %NULL
210 	 *     if @page_num is out of bounds
211 	 *
212 	 * Since: 2.10
213 	 */
214 	public Widget getNthPage(int pageNum)
215 	{
216 		auto p = gtk_assistant_get_nth_page(gtkAssistant, pageNum);
217 		
218 		if(p is null)
219 		{
220 			return null;
221 		}
222 		
223 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
224 	}
225 
226 	/**
227 	 * Gets whether @page is complete.
228 	 *
229 	 * Params:
230 	 *     page = a page of @assistant
231 	 *
232 	 * Return: %TRUE if @page is complete.
233 	 *
234 	 * Since: 2.10
235 	 */
236 	public bool getPageComplete(Widget page)
237 	{
238 		return gtk_assistant_get_page_complete(gtkAssistant, (page is null) ? null : page.getWidgetStruct()) != 0;
239 	}
240 
241 	/**
242 	 * Gets whether page has padding.
243 	 *
244 	 * Params:
245 	 *     page = a page of @assistant
246 	 *
247 	 * Return: %TRUE if @page has padding
248 	 *
249 	 * Since: 3.18
250 	 */
251 	public bool getPageHasPadding(Widget page)
252 	{
253 		return gtk_assistant_get_page_has_padding(gtkAssistant, (page is null) ? null : page.getWidgetStruct()) != 0;
254 	}
255 
256 	/**
257 	 * Gets the header image for @page.
258 	 *
259 	 * Deprecated: Since GTK+ 3.2, a header is no longer shown;
260 	 * add your header decoration to the page content instead.
261 	 *
262 	 * Params:
263 	 *     page = a page of @assistant
264 	 *
265 	 * Return: the header image for @page,
266 	 *     or %NULL if there’s no header image for the page
267 	 *
268 	 * Since: 2.10
269 	 */
270 	public Pixbuf getPageHeaderImage(Widget page)
271 	{
272 		auto p = gtk_assistant_get_page_header_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
273 		
274 		if(p is null)
275 		{
276 			return null;
277 		}
278 		
279 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) p);
280 	}
281 
282 	/**
283 	 * Gets the side image for @page.
284 	 *
285 	 * Deprecated: Since GTK+ 3.2, sidebar images are not
286 	 * shown anymore.
287 	 *
288 	 * Params:
289 	 *     page = a page of @assistant
290 	 *
291 	 * Return: the side image for @page,
292 	 *     or %NULL if there’s no side image for the page
293 	 *
294 	 * Since: 2.10
295 	 */
296 	public Pixbuf getPageSideImage(Widget page)
297 	{
298 		auto p = gtk_assistant_get_page_side_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
299 		
300 		if(p is null)
301 		{
302 			return null;
303 		}
304 		
305 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) p);
306 	}
307 
308 	/**
309 	 * Gets the title for @page.
310 	 *
311 	 * Params:
312 	 *     page = a page of @assistant
313 	 *
314 	 * Return: the title for @page
315 	 *
316 	 * Since: 2.10
317 	 */
318 	public string getPageTitle(Widget page)
319 	{
320 		return Str.toString(gtk_assistant_get_page_title(gtkAssistant, (page is null) ? null : page.getWidgetStruct()));
321 	}
322 
323 	/**
324 	 * Gets the page type of @page.
325 	 *
326 	 * Params:
327 	 *     page = a page of @assistant
328 	 *
329 	 * Return: the page type of @page
330 	 *
331 	 * Since: 2.10
332 	 */
333 	public GtkAssistantPageType getPageType(Widget page)
334 	{
335 		return gtk_assistant_get_page_type(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
336 	}
337 
338 	/**
339 	 * Inserts a page in the @assistant at a given position.
340 	 *
341 	 * Params:
342 	 *     page = a #GtkWidget
343 	 *     position = the index (starting at 0) at which to insert the page,
344 	 *         or -1 to append the page to the @assistant
345 	 *
346 	 * Return: the index (starting from 0) of the inserted page
347 	 *
348 	 * Since: 2.10
349 	 */
350 	public int insertPage(Widget page, int position)
351 	{
352 		return gtk_assistant_insert_page(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), position);
353 	}
354 
355 	/**
356 	 * Navigate to the next page.
357 	 *
358 	 * It is a programming error to call this function when
359 	 * there is no next page.
360 	 *
361 	 * This function is for use when creating pages of the
362 	 * #GTK_ASSISTANT_PAGE_CUSTOM type.
363 	 *
364 	 * Since: 3.0
365 	 */
366 	public void nextPage()
367 	{
368 		gtk_assistant_next_page(gtkAssistant);
369 	}
370 
371 	/**
372 	 * Prepends a page to the @assistant.
373 	 *
374 	 * Params:
375 	 *     page = a #GtkWidget
376 	 *
377 	 * Return: the index (starting at 0) of the inserted page
378 	 *
379 	 * Since: 2.10
380 	 */
381 	public int prependPage(Widget page)
382 	{
383 		return gtk_assistant_prepend_page(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
384 	}
385 
386 	/**
387 	 * Navigate to the previous visited page.
388 	 *
389 	 * It is a programming error to call this function when
390 	 * no previous page is available.
391 	 *
392 	 * This function is for use when creating pages of the
393 	 * #GTK_ASSISTANT_PAGE_CUSTOM type.
394 	 *
395 	 * Since: 3.0
396 	 */
397 	public void previousPage()
398 	{
399 		gtk_assistant_previous_page(gtkAssistant);
400 	}
401 
402 	/**
403 	 * Removes a widget from the action area of a #GtkAssistant.
404 	 *
405 	 * Params:
406 	 *     child = a #GtkWidget
407 	 *
408 	 * Since: 2.10
409 	 */
410 	public void removeActionWidget(Widget child)
411 	{
412 		gtk_assistant_remove_action_widget(gtkAssistant, (child is null) ? null : child.getWidgetStruct());
413 	}
414 
415 	/**
416 	 * Removes the @page_num’s page from @assistant.
417 	 *
418 	 * Params:
419 	 *     pageNum = the index of a page in the @assistant,
420 	 *         or -1 to remove the last page
421 	 *
422 	 * Since: 3.2
423 	 */
424 	public void removePage(int pageNum)
425 	{
426 		gtk_assistant_remove_page(gtkAssistant, pageNum);
427 	}
428 
429 	/**
430 	 * Switches the page to @page_num.
431 	 *
432 	 * Note that this will only be necessary in custom buttons,
433 	 * as the @assistant flow can be set with
434 	 * gtk_assistant_set_forward_page_func().
435 	 *
436 	 * Params:
437 	 *     pageNum = index of the page to switch to, starting from 0.
438 	 *         If negative, the last page will be used. If greater
439 	 *         than the number of pages in the @assistant, nothing
440 	 *         will be done.
441 	 *
442 	 * Since: 2.10
443 	 */
444 	public void setCurrentPage(int pageNum)
445 	{
446 		gtk_assistant_set_current_page(gtkAssistant, pageNum);
447 	}
448 
449 	/**
450 	 * Sets the page forwarding function to be @page_func.
451 	 *
452 	 * This function will be used to determine what will be
453 	 * the next page when the user presses the forward button.
454 	 * Setting @page_func to %NULL will make the assistant to
455 	 * use the default forward function, which just goes to the
456 	 * next visible page.
457 	 *
458 	 * Params:
459 	 *     pageFunc = the #GtkAssistantPageFunc, or %NULL
460 	 *         to use the default one
461 	 *     data = user data for @page_func
462 	 *     destroy = destroy notifier for @data
463 	 *
464 	 * Since: 2.10
465 	 */
466 	public void setForwardPageFunc(GtkAssistantPageFunc pageFunc, void* data, GDestroyNotify destroy)
467 	{
468 		gtk_assistant_set_forward_page_func(gtkAssistant, pageFunc, data, destroy);
469 	}
470 
471 	/**
472 	 * Sets whether @page contents are complete.
473 	 *
474 	 * This will make @assistant update the buttons state
475 	 * to be able to continue the task.
476 	 *
477 	 * Params:
478 	 *     page = a page of @assistant
479 	 *     complete = the completeness status of the page
480 	 *
481 	 * Since: 2.10
482 	 */
483 	public void setPageComplete(Widget page, bool complete)
484 	{
485 		gtk_assistant_set_page_complete(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), complete);
486 	}
487 
488 	/**
489 	 * Sets whether the assistant is adding padding around
490 	 * the page.
491 	 *
492 	 * Params:
493 	 *     page = a page of @assistant
494 	 *     hasPadding = whether this page has padding
495 	 *
496 	 * Since: 3.18
497 	 */
498 	public void setPageHasPadding(Widget page, bool hasPadding)
499 	{
500 		gtk_assistant_set_page_has_padding(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), hasPadding);
501 	}
502 
503 	/**
504 	 * Sets a header image for @page.
505 	 *
506 	 * Deprecated: Since GTK+ 3.2, a header is no longer shown;
507 	 * add your header decoration to the page content instead.
508 	 *
509 	 * Params:
510 	 *     page = a page of @assistant
511 	 *     pixbuf = the new header image @page
512 	 *
513 	 * Since: 2.10
514 	 */
515 	public void setPageHeaderImage(Widget page, Pixbuf pixbuf)
516 	{
517 		gtk_assistant_set_page_header_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), (pixbuf is null) ? null : pixbuf.getPixbufStruct());
518 	}
519 
520 	/**
521 	 * Sets a side image for @page.
522 	 *
523 	 * This image used to be displayed in the side area of the assistant
524 	 * when @page is the current page.
525 	 *
526 	 * Deprecated: Since GTK+ 3.2, sidebar images are not
527 	 * shown anymore.
528 	 *
529 	 * Params:
530 	 *     page = a page of @assistant
531 	 *     pixbuf = the new side image @page
532 	 *
533 	 * Since: 2.10
534 	 */
535 	public void setPageSideImage(Widget page, Pixbuf pixbuf)
536 	{
537 		gtk_assistant_set_page_side_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), (pixbuf is null) ? null : pixbuf.getPixbufStruct());
538 	}
539 
540 	/**
541 	 * Sets a title for @page.
542 	 *
543 	 * The title is displayed in the header area of the assistant
544 	 * when @page is the current page.
545 	 *
546 	 * Params:
547 	 *     page = a page of @assistant
548 	 *     title = the new title for @page
549 	 *
550 	 * Since: 2.10
551 	 */
552 	public void setPageTitle(Widget page, string title)
553 	{
554 		gtk_assistant_set_page_title(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), Str.toStringz(title));
555 	}
556 
557 	/**
558 	 * Sets the page type for @page.
559 	 *
560 	 * The page type determines the page behavior in the @assistant.
561 	 *
562 	 * Params:
563 	 *     page = a page of @assistant
564 	 *     type = the new type for @page
565 	 *
566 	 * Since: 2.10
567 	 */
568 	public void setPageType(Widget page, GtkAssistantPageType type)
569 	{
570 		gtk_assistant_set_page_type(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), type);
571 	}
572 
573 	/**
574 	 * Forces @assistant to recompute the buttons state.
575 	 *
576 	 * GTK+ automatically takes care of this in most situations,
577 	 * e.g. when the user goes to a different page, or when the
578 	 * visibility or completeness of a page changes.
579 	 *
580 	 * One situation where it can be necessary to call this
581 	 * function is when changing a value on the current page
582 	 * affects the future page flow of the assistant.
583 	 *
584 	 * Since: 2.10
585 	 */
586 	public void updateButtonsState()
587 	{
588 		gtk_assistant_update_buttons_state(gtkAssistant);
589 	}
590 
591 	protected class OnApplyDelegateWrapper
592 	{
593 		void delegate(Assistant) dlg;
594 		gulong handlerId;
595 		ConnectFlags flags;
596 		this(void delegate(Assistant) dlg, gulong handlerId, ConnectFlags flags)
597 		{
598 			this.dlg = dlg;
599 			this.handlerId = handlerId;
600 			this.flags = flags;
601 		}
602 	}
603 	protected OnApplyDelegateWrapper[] onApplyListeners;
604 
605 	/**
606 	 * The ::apply signal is emitted when the apply button is clicked.
607 	 *
608 	 * The default behavior of the #GtkAssistant is to switch to the page
609 	 * after the current page, unless the current page is the last one.
610 	 *
611 	 * A handler for the ::apply signal should carry out the actions for
612 	 * which the wizard has collected data. If the action takes a long time
613 	 * to complete, you might consider putting a page of type
614 	 * %GTK_ASSISTANT_PAGE_PROGRESS after the confirmation page and handle
615 	 * this operation within the #GtkAssistant::prepare signal of the progress
616 	 * page.
617 	 *
618 	 * Since: 2.10
619 	 */
620 	gulong addOnApply(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
621 	{
622 		onApplyListeners ~= new OnApplyDelegateWrapper(dlg, 0, connectFlags);
623 		onApplyListeners[onApplyListeners.length - 1].handlerId = Signals.connectData(
624 			this,
625 			"apply",
626 			cast(GCallback)&callBackApply,
627 			cast(void*)onApplyListeners[onApplyListeners.length - 1],
628 			cast(GClosureNotify)&callBackApplyDestroy,
629 			connectFlags);
630 		return onApplyListeners[onApplyListeners.length - 1].handlerId;
631 	}
632 	
633 	extern(C) static void callBackApply(GtkAssistant* assistantStruct,OnApplyDelegateWrapper wrapper)
634 	{
635 		wrapper.dlg(wrapper.outer);
636 	}
637 	
638 	extern(C) static void callBackApplyDestroy(OnApplyDelegateWrapper wrapper, GClosure* closure)
639 	{
640 		wrapper.outer.internalRemoveOnApply(wrapper);
641 	}
642 
643 	protected void internalRemoveOnApply(OnApplyDelegateWrapper source)
644 	{
645 		foreach(index, wrapper; onApplyListeners)
646 		{
647 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
648 			{
649 				onApplyListeners[index] = null;
650 				onApplyListeners = std.algorithm.remove(onApplyListeners, index);
651 				break;
652 			}
653 		}
654 	}
655 	
656 
657 	protected class OnCancelDelegateWrapper
658 	{
659 		void delegate(Assistant) dlg;
660 		gulong handlerId;
661 		ConnectFlags flags;
662 		this(void delegate(Assistant) dlg, gulong handlerId, ConnectFlags flags)
663 		{
664 			this.dlg = dlg;
665 			this.handlerId = handlerId;
666 			this.flags = flags;
667 		}
668 	}
669 	protected OnCancelDelegateWrapper[] onCancelListeners;
670 
671 	/**
672 	 * The ::cancel signal is emitted when then the cancel button is clicked.
673 	 *
674 	 * Since: 2.10
675 	 */
676 	gulong addOnCancel(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
677 	{
678 		onCancelListeners ~= new OnCancelDelegateWrapper(dlg, 0, connectFlags);
679 		onCancelListeners[onCancelListeners.length - 1].handlerId = Signals.connectData(
680 			this,
681 			"cancel",
682 			cast(GCallback)&callBackCancel,
683 			cast(void*)onCancelListeners[onCancelListeners.length - 1],
684 			cast(GClosureNotify)&callBackCancelDestroy,
685 			connectFlags);
686 		return onCancelListeners[onCancelListeners.length - 1].handlerId;
687 	}
688 	
689 	extern(C) static void callBackCancel(GtkAssistant* assistantStruct,OnCancelDelegateWrapper wrapper)
690 	{
691 		wrapper.dlg(wrapper.outer);
692 	}
693 	
694 	extern(C) static void callBackCancelDestroy(OnCancelDelegateWrapper wrapper, GClosure* closure)
695 	{
696 		wrapper.outer.internalRemoveOnCancel(wrapper);
697 	}
698 
699 	protected void internalRemoveOnCancel(OnCancelDelegateWrapper source)
700 	{
701 		foreach(index, wrapper; onCancelListeners)
702 		{
703 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
704 			{
705 				onCancelListeners[index] = null;
706 				onCancelListeners = std.algorithm.remove(onCancelListeners, index);
707 				break;
708 			}
709 		}
710 	}
711 	
712 
713 	protected class OnCloseDelegateWrapper
714 	{
715 		void delegate(Assistant) dlg;
716 		gulong handlerId;
717 		ConnectFlags flags;
718 		this(void delegate(Assistant) dlg, gulong handlerId, ConnectFlags flags)
719 		{
720 			this.dlg = dlg;
721 			this.handlerId = handlerId;
722 			this.flags = flags;
723 		}
724 	}
725 	protected OnCloseDelegateWrapper[] onCloseListeners;
726 
727 	/**
728 	 * The ::close signal is emitted either when the close button of
729 	 * a summary page is clicked, or when the apply button in the last
730 	 * page in the flow (of type %GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
731 	 *
732 	 * Since: 2.10
733 	 */
734 	gulong addOnClose(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
735 	{
736 		onCloseListeners ~= new OnCloseDelegateWrapper(dlg, 0, connectFlags);
737 		onCloseListeners[onCloseListeners.length - 1].handlerId = Signals.connectData(
738 			this,
739 			"close",
740 			cast(GCallback)&callBackClose,
741 			cast(void*)onCloseListeners[onCloseListeners.length - 1],
742 			cast(GClosureNotify)&callBackCloseDestroy,
743 			connectFlags);
744 		return onCloseListeners[onCloseListeners.length - 1].handlerId;
745 	}
746 	
747 	extern(C) static void callBackClose(GtkAssistant* assistantStruct,OnCloseDelegateWrapper wrapper)
748 	{
749 		wrapper.dlg(wrapper.outer);
750 	}
751 	
752 	extern(C) static void callBackCloseDestroy(OnCloseDelegateWrapper wrapper, GClosure* closure)
753 	{
754 		wrapper.outer.internalRemoveOnClose(wrapper);
755 	}
756 
757 	protected void internalRemoveOnClose(OnCloseDelegateWrapper source)
758 	{
759 		foreach(index, wrapper; onCloseListeners)
760 		{
761 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
762 			{
763 				onCloseListeners[index] = null;
764 				onCloseListeners = std.algorithm.remove(onCloseListeners, index);
765 				break;
766 			}
767 		}
768 	}
769 	
770 
771 	protected class OnEscapeDelegateWrapper
772 	{
773 		void delegate(Assistant) dlg;
774 		gulong handlerId;
775 		ConnectFlags flags;
776 		this(void delegate(Assistant) dlg, gulong handlerId, ConnectFlags flags)
777 		{
778 			this.dlg = dlg;
779 			this.handlerId = handlerId;
780 			this.flags = flags;
781 		}
782 	}
783 	protected OnEscapeDelegateWrapper[] onEscapeListeners;
784 
785 	/** */
786 	gulong addOnEscape(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
787 	{
788 		onEscapeListeners ~= new OnEscapeDelegateWrapper(dlg, 0, connectFlags);
789 		onEscapeListeners[onEscapeListeners.length - 1].handlerId = Signals.connectData(
790 			this,
791 			"escape",
792 			cast(GCallback)&callBackEscape,
793 			cast(void*)onEscapeListeners[onEscapeListeners.length - 1],
794 			cast(GClosureNotify)&callBackEscapeDestroy,
795 			connectFlags);
796 		return onEscapeListeners[onEscapeListeners.length - 1].handlerId;
797 	}
798 	
799 	extern(C) static void callBackEscape(GtkAssistant* assistantStruct,OnEscapeDelegateWrapper wrapper)
800 	{
801 		wrapper.dlg(wrapper.outer);
802 	}
803 	
804 	extern(C) static void callBackEscapeDestroy(OnEscapeDelegateWrapper wrapper, GClosure* closure)
805 	{
806 		wrapper.outer.internalRemoveOnEscape(wrapper);
807 	}
808 
809 	protected void internalRemoveOnEscape(OnEscapeDelegateWrapper source)
810 	{
811 		foreach(index, wrapper; onEscapeListeners)
812 		{
813 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
814 			{
815 				onEscapeListeners[index] = null;
816 				onEscapeListeners = std.algorithm.remove(onEscapeListeners, index);
817 				break;
818 			}
819 		}
820 	}
821 	
822 
823 	protected class OnPrepareDelegateWrapper
824 	{
825 		void delegate(Widget, Assistant) dlg;
826 		gulong handlerId;
827 		ConnectFlags flags;
828 		this(void delegate(Widget, Assistant) dlg, gulong handlerId, ConnectFlags flags)
829 		{
830 			this.dlg = dlg;
831 			this.handlerId = handlerId;
832 			this.flags = flags;
833 		}
834 	}
835 	protected OnPrepareDelegateWrapper[] onPrepareListeners;
836 
837 	/**
838 	 * The ::prepare signal is emitted when a new page is set as the
839 	 * assistant's current page, before making the new page visible.
840 	 *
841 	 * A handler for this signal can do any preparations which are
842 	 * necessary before showing @page.
843 	 *
844 	 * Params:
845 	 *     page = the current page
846 	 *
847 	 * Since: 2.10
848 	 */
849 	gulong addOnPrepare(void delegate(Widget, Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
850 	{
851 		onPrepareListeners ~= new OnPrepareDelegateWrapper(dlg, 0, connectFlags);
852 		onPrepareListeners[onPrepareListeners.length - 1].handlerId = Signals.connectData(
853 			this,
854 			"prepare",
855 			cast(GCallback)&callBackPrepare,
856 			cast(void*)onPrepareListeners[onPrepareListeners.length - 1],
857 			cast(GClosureNotify)&callBackPrepareDestroy,
858 			connectFlags);
859 		return onPrepareListeners[onPrepareListeners.length - 1].handlerId;
860 	}
861 	
862 	extern(C) static void callBackPrepare(GtkAssistant* assistantStruct, GtkWidget* page,OnPrepareDelegateWrapper wrapper)
863 	{
864 		wrapper.dlg(ObjectG.getDObject!(Widget)(page), wrapper.outer);
865 	}
866 	
867 	extern(C) static void callBackPrepareDestroy(OnPrepareDelegateWrapper wrapper, GClosure* closure)
868 	{
869 		wrapper.outer.internalRemoveOnPrepare(wrapper);
870 	}
871 
872 	protected void internalRemoveOnPrepare(OnPrepareDelegateWrapper source)
873 	{
874 		foreach(index, wrapper; onPrepareListeners)
875 		{
876 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
877 			{
878 				onPrepareListeners[index] = null;
879 				onPrepareListeners = std.algorithm.remove(onPrepareListeners, index);
880 				break;
881 			}
882 		}
883 	}
884 	
885 }