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 gio.MountOperation;
26 
27 private import glib.ArrayG;
28 private import glib.ConstructionException;
29 private import glib.Str;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 public  import gtkc.gdktypes;
33 private import gtkc.gio;
34 public  import gtkc.giotypes;
35 private import std.algorithm;
36 
37 
38 /**
39  * #GMountOperation provides a mechanism for interacting with the user.
40  * It can be used for authenticating mountable operations, such as loop
41  * mounting files, hard drive partitions or server locations. It can
42  * also be used to ask the user questions or show a list of applications
43  * preventing unmount or eject operations from completing.
44  * 
45  * Note that #GMountOperation is used for more than just #GMount
46  * objects – for example it is also used in g_drive_start() and
47  * g_drive_stop().
48  * 
49  * Users should instantiate a subclass of this that implements all the
50  * various callbacks to show the required dialogs, such as
51  * #GtkMountOperation. If no user interaction is desired (for example
52  * when automounting filesystems at login time), usually %NULL can be
53  * passed, see each method taking a #GMountOperation for details.
54  */
55 public class MountOperation : ObjectG
56 {
57 	/** the main Gtk struct */
58 	protected GMountOperation* gMountOperation;
59 
60 	/** Get the main Gtk struct */
61 	public GMountOperation* getMountOperationStruct()
62 	{
63 		return gMountOperation;
64 	}
65 
66 	/** the main Gtk struct as a void* */
67 	protected override void* getStruct()
68 	{
69 		return cast(void*)gMountOperation;
70 	}
71 
72 	protected override void setStruct(GObject* obj)
73 	{
74 		gMountOperation = cast(GMountOperation*)obj;
75 		super.setStruct(obj);
76 	}
77 
78 	/**
79 	 * Sets our main struct and passes it to the parent class.
80 	 */
81 	public this (GMountOperation* gMountOperation, bool ownedRef = false)
82 	{
83 		this.gMountOperation = gMountOperation;
84 		super(cast(GObject*)gMountOperation, ownedRef);
85 	}
86 
87 
88 	/** */
89 	public static GType getType()
90 	{
91 		return g_mount_operation_get_type();
92 	}
93 
94 	/**
95 	 * Creates a new mount operation.
96 	 *
97 	 * Return: a #GMountOperation.
98 	 *
99 	 * Throws: ConstructionException GTK+ fails to create the object.
100 	 */
101 	public this()
102 	{
103 		auto p = g_mount_operation_new();
104 		
105 		if(p is null)
106 		{
107 			throw new ConstructionException("null returned by new");
108 		}
109 		
110 		this(cast(GMountOperation*) p, true);
111 	}
112 
113 	/**
114 	 * Check to see whether the mount operation is being used
115 	 * for an anonymous user.
116 	 *
117 	 * Return: %TRUE if mount operation is anonymous.
118 	 */
119 	public bool getAnonymous()
120 	{
121 		return g_mount_operation_get_anonymous(gMountOperation) != 0;
122 	}
123 
124 	/**
125 	 * Gets a choice from the mount operation.
126 	 *
127 	 * Return: an integer containing an index of the user's choice from
128 	 *     the choice's list, or %0.
129 	 */
130 	public int getChoice()
131 	{
132 		return g_mount_operation_get_choice(gMountOperation);
133 	}
134 
135 	/**
136 	 * Gets the domain of the mount operation.
137 	 *
138 	 * Return: a string set to the domain.
139 	 */
140 	public string getDomain()
141 	{
142 		return Str.toString(g_mount_operation_get_domain(gMountOperation));
143 	}
144 
145 	/**
146 	 * Gets a password from the mount operation.
147 	 *
148 	 * Return: a string containing the password within @op.
149 	 */
150 	public string getPassword()
151 	{
152 		return Str.toString(g_mount_operation_get_password(gMountOperation));
153 	}
154 
155 	/**
156 	 * Gets the state of saving passwords for the mount operation.
157 	 *
158 	 * Return: a #GPasswordSave flag.
159 	 */
160 	public GPasswordSave getPasswordSave()
161 	{
162 		return g_mount_operation_get_password_save(gMountOperation);
163 	}
164 
165 	/**
166 	 * Get the user name from the mount operation.
167 	 *
168 	 * Return: a string containing the user name.
169 	 */
170 	public string getUsername()
171 	{
172 		return Str.toString(g_mount_operation_get_username(gMountOperation));
173 	}
174 
175 	/**
176 	 * Emits the #GMountOperation::reply signal.
177 	 *
178 	 * Params:
179 	 *     result = a #GMountOperationResult
180 	 */
181 	public void reply(GMountOperationResult result)
182 	{
183 		g_mount_operation_reply(gMountOperation, result);
184 	}
185 
186 	/**
187 	 * Sets the mount operation to use an anonymous user if @anonymous is %TRUE.
188 	 *
189 	 * Params:
190 	 *     anonymous = boolean value.
191 	 */
192 	public void setAnonymous(bool anonymous)
193 	{
194 		g_mount_operation_set_anonymous(gMountOperation, anonymous);
195 	}
196 
197 	/**
198 	 * Sets a default choice for the mount operation.
199 	 *
200 	 * Params:
201 	 *     choice = an integer.
202 	 */
203 	public void setChoice(int choice)
204 	{
205 		g_mount_operation_set_choice(gMountOperation, choice);
206 	}
207 
208 	/**
209 	 * Sets the mount operation's domain.
210 	 *
211 	 * Params:
212 	 *     domain = the domain to set.
213 	 */
214 	public void setDomain(string domain)
215 	{
216 		g_mount_operation_set_domain(gMountOperation, Str.toStringz(domain));
217 	}
218 
219 	/**
220 	 * Sets the mount operation's password to @password.
221 	 *
222 	 * Params:
223 	 *     password = password to set.
224 	 */
225 	public void setPassword(string password)
226 	{
227 		g_mount_operation_set_password(gMountOperation, Str.toStringz(password));
228 	}
229 
230 	/**
231 	 * Sets the state of saving passwords for the mount operation.
232 	 *
233 	 * Params:
234 	 *     save = a set of #GPasswordSave flags.
235 	 */
236 	public void setPasswordSave(GPasswordSave save)
237 	{
238 		g_mount_operation_set_password_save(gMountOperation, save);
239 	}
240 
241 	/**
242 	 * Sets the user name within @op to @username.
243 	 *
244 	 * Params:
245 	 *     username = input username.
246 	 */
247 	public void setUsername(string username)
248 	{
249 		g_mount_operation_set_username(gMountOperation, Str.toStringz(username));
250 	}
251 
252 	protected class OnAbortedDelegateWrapper
253 	{
254 		void delegate(MountOperation) dlg;
255 		gulong handlerId;
256 		ConnectFlags flags;
257 		this(void delegate(MountOperation) dlg, gulong handlerId, ConnectFlags flags)
258 		{
259 			this.dlg = dlg;
260 			this.handlerId = handlerId;
261 			this.flags = flags;
262 		}
263 	}
264 	protected OnAbortedDelegateWrapper[] onAbortedListeners;
265 
266 	/**
267 	 * Emitted by the backend when e.g. a device becomes unavailable
268 	 * while a mount operation is in progress.
269 	 *
270 	 * Implementations of GMountOperation should handle this signal
271 	 * by dismissing open password dialogs.
272 	 *
273 	 * Since: 2.20
274 	 */
275 	gulong addOnAborted(void delegate(MountOperation) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
276 	{
277 		onAbortedListeners ~= new OnAbortedDelegateWrapper(dlg, 0, connectFlags);
278 		onAbortedListeners[onAbortedListeners.length - 1].handlerId = Signals.connectData(
279 			this,
280 			"aborted",
281 			cast(GCallback)&callBackAborted,
282 			cast(void*)onAbortedListeners[onAbortedListeners.length - 1],
283 			cast(GClosureNotify)&callBackAbortedDestroy,
284 			connectFlags);
285 		return onAbortedListeners[onAbortedListeners.length - 1].handlerId;
286 	}
287 	
288 	extern(C) static void callBackAborted(GMountOperation* mountoperationStruct,OnAbortedDelegateWrapper wrapper)
289 	{
290 		wrapper.dlg(wrapper.outer);
291 	}
292 	
293 	extern(C) static void callBackAbortedDestroy(OnAbortedDelegateWrapper wrapper, GClosure* closure)
294 	{
295 		wrapper.outer.internalRemoveOnAborted(wrapper);
296 	}
297 
298 	protected void internalRemoveOnAborted(OnAbortedDelegateWrapper source)
299 	{
300 		foreach(index, wrapper; onAbortedListeners)
301 		{
302 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
303 			{
304 				onAbortedListeners[index] = null;
305 				onAbortedListeners = std.algorithm.remove(onAbortedListeners, index);
306 				break;
307 			}
308 		}
309 	}
310 	
311 
312 	protected class OnAskPasswordDelegateWrapper
313 	{
314 		void delegate(string, string, string, GAskPasswordFlags, MountOperation) dlg;
315 		gulong handlerId;
316 		ConnectFlags flags;
317 		this(void delegate(string, string, string, GAskPasswordFlags, MountOperation) dlg, gulong handlerId, ConnectFlags flags)
318 		{
319 			this.dlg = dlg;
320 			this.handlerId = handlerId;
321 			this.flags = flags;
322 		}
323 	}
324 	protected OnAskPasswordDelegateWrapper[] onAskPasswordListeners;
325 
326 	/**
327 	 * Emitted when a mount operation asks the user for a password.
328 	 *
329 	 * If the message contains a line break, the first line should be
330 	 * presented as a heading. For example, it may be used as the
331 	 * primary text in a #GtkMessageDialog.
332 	 *
333 	 * Params:
334 	 *     message = string containing a message to display to the user.
335 	 *     defaultUser = string containing the default user name.
336 	 *     defaultDomain = string containing the default domain.
337 	 *     flags = a set of #GAskPasswordFlags.
338 	 */
339 	gulong addOnAskPassword(void delegate(string, string, string, GAskPasswordFlags, MountOperation) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
340 	{
341 		onAskPasswordListeners ~= new OnAskPasswordDelegateWrapper(dlg, 0, connectFlags);
342 		onAskPasswordListeners[onAskPasswordListeners.length - 1].handlerId = Signals.connectData(
343 			this,
344 			"ask-password",
345 			cast(GCallback)&callBackAskPassword,
346 			cast(void*)onAskPasswordListeners[onAskPasswordListeners.length - 1],
347 			cast(GClosureNotify)&callBackAskPasswordDestroy,
348 			connectFlags);
349 		return onAskPasswordListeners[onAskPasswordListeners.length - 1].handlerId;
350 	}
351 	
352 	extern(C) static void callBackAskPassword(GMountOperation* mountoperationStruct, char* message, char* defaultUser, char* defaultDomain, GAskPasswordFlags flags,OnAskPasswordDelegateWrapper wrapper)
353 	{
354 		wrapper.dlg(Str.toString(message), Str.toString(defaultUser), Str.toString(defaultDomain), flags, wrapper.outer);
355 	}
356 	
357 	extern(C) static void callBackAskPasswordDestroy(OnAskPasswordDelegateWrapper wrapper, GClosure* closure)
358 	{
359 		wrapper.outer.internalRemoveOnAskPassword(wrapper);
360 	}
361 
362 	protected void internalRemoveOnAskPassword(OnAskPasswordDelegateWrapper source)
363 	{
364 		foreach(index, wrapper; onAskPasswordListeners)
365 		{
366 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
367 			{
368 				onAskPasswordListeners[index] = null;
369 				onAskPasswordListeners = std.algorithm.remove(onAskPasswordListeners, index);
370 				break;
371 			}
372 		}
373 	}
374 	
375 
376 	protected class OnAskQuestionDelegateWrapper
377 	{
378 		void delegate(string, string[], MountOperation) dlg;
379 		gulong handlerId;
380 		ConnectFlags flags;
381 		this(void delegate(string, string[], MountOperation) dlg, gulong handlerId, ConnectFlags flags)
382 		{
383 			this.dlg = dlg;
384 			this.handlerId = handlerId;
385 			this.flags = flags;
386 		}
387 	}
388 	protected OnAskQuestionDelegateWrapper[] onAskQuestionListeners;
389 
390 	/**
391 	 * Emitted when asking the user a question and gives a list of
392 	 * choices for the user to choose from.
393 	 *
394 	 * If the message contains a line break, the first line should be
395 	 * presented as a heading. For example, it may be used as the
396 	 * primary text in a #GtkMessageDialog.
397 	 *
398 	 * Params:
399 	 *     message = string containing a message to display to the user.
400 	 *     choices = an array of strings for each possible choice.
401 	 */
402 	gulong addOnAskQuestion(void delegate(string, string[], MountOperation) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
403 	{
404 		onAskQuestionListeners ~= new OnAskQuestionDelegateWrapper(dlg, 0, connectFlags);
405 		onAskQuestionListeners[onAskQuestionListeners.length - 1].handlerId = Signals.connectData(
406 			this,
407 			"ask-question",
408 			cast(GCallback)&callBackAskQuestion,
409 			cast(void*)onAskQuestionListeners[onAskQuestionListeners.length - 1],
410 			cast(GClosureNotify)&callBackAskQuestionDestroy,
411 			connectFlags);
412 		return onAskQuestionListeners[onAskQuestionListeners.length - 1].handlerId;
413 	}
414 	
415 	extern(C) static void callBackAskQuestion(GMountOperation* mountoperationStruct, char* message, char** choices,OnAskQuestionDelegateWrapper wrapper)
416 	{
417 		wrapper.dlg(Str.toString(message), Str.toStringArray(choices), wrapper.outer);
418 	}
419 	
420 	extern(C) static void callBackAskQuestionDestroy(OnAskQuestionDelegateWrapper wrapper, GClosure* closure)
421 	{
422 		wrapper.outer.internalRemoveOnAskQuestion(wrapper);
423 	}
424 
425 	protected void internalRemoveOnAskQuestion(OnAskQuestionDelegateWrapper source)
426 	{
427 		foreach(index, wrapper; onAskQuestionListeners)
428 		{
429 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
430 			{
431 				onAskQuestionListeners[index] = null;
432 				onAskQuestionListeners = std.algorithm.remove(onAskQuestionListeners, index);
433 				break;
434 			}
435 		}
436 	}
437 	
438 
439 	protected class OnReplyDelegateWrapper
440 	{
441 		void delegate(GMountOperationResult, MountOperation) dlg;
442 		gulong handlerId;
443 		ConnectFlags flags;
444 		this(void delegate(GMountOperationResult, MountOperation) dlg, gulong handlerId, ConnectFlags flags)
445 		{
446 			this.dlg = dlg;
447 			this.handlerId = handlerId;
448 			this.flags = flags;
449 		}
450 	}
451 	protected OnReplyDelegateWrapper[] onReplyListeners;
452 
453 	/**
454 	 * Emitted when the user has replied to the mount operation.
455 	 *
456 	 * Params:
457 	 *     result = a #GMountOperationResult indicating how the request was handled
458 	 */
459 	gulong addOnReply(void delegate(GMountOperationResult, MountOperation) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
460 	{
461 		onReplyListeners ~= new OnReplyDelegateWrapper(dlg, 0, connectFlags);
462 		onReplyListeners[onReplyListeners.length - 1].handlerId = Signals.connectData(
463 			this,
464 			"reply",
465 			cast(GCallback)&callBackReply,
466 			cast(void*)onReplyListeners[onReplyListeners.length - 1],
467 			cast(GClosureNotify)&callBackReplyDestroy,
468 			connectFlags);
469 		return onReplyListeners[onReplyListeners.length - 1].handlerId;
470 	}
471 	
472 	extern(C) static void callBackReply(GMountOperation* mountoperationStruct, GMountOperationResult result,OnReplyDelegateWrapper wrapper)
473 	{
474 		wrapper.dlg(result, wrapper.outer);
475 	}
476 	
477 	extern(C) static void callBackReplyDestroy(OnReplyDelegateWrapper wrapper, GClosure* closure)
478 	{
479 		wrapper.outer.internalRemoveOnReply(wrapper);
480 	}
481 
482 	protected void internalRemoveOnReply(OnReplyDelegateWrapper source)
483 	{
484 		foreach(index, wrapper; onReplyListeners)
485 		{
486 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
487 			{
488 				onReplyListeners[index] = null;
489 				onReplyListeners = std.algorithm.remove(onReplyListeners, index);
490 				break;
491 			}
492 		}
493 	}
494 	
495 
496 	protected class OnShowProcessesDelegateWrapper
497 	{
498 		void delegate(string, ArrayG, string[], MountOperation) dlg;
499 		gulong handlerId;
500 		ConnectFlags flags;
501 		this(void delegate(string, ArrayG, string[], MountOperation) dlg, gulong handlerId, ConnectFlags flags)
502 		{
503 			this.dlg = dlg;
504 			this.handlerId = handlerId;
505 			this.flags = flags;
506 		}
507 	}
508 	protected OnShowProcessesDelegateWrapper[] onShowProcessesListeners;
509 
510 	/**
511 	 * Emitted when one or more processes are blocking an operation
512 	 * e.g. unmounting/ejecting a #GMount or stopping a #GDrive.
513 	 *
514 	 * Note that this signal may be emitted several times to update the
515 	 * list of blocking processes as processes close files. The
516 	 * application should only respond with g_mount_operation_reply() to
517 	 * the latest signal (setting #GMountOperation:choice to the choice
518 	 * the user made).
519 	 *
520 	 * If the message contains a line break, the first line should be
521 	 * presented as a heading. For example, it may be used as the
522 	 * primary text in a #GtkMessageDialog.
523 	 *
524 	 * Params:
525 	 *     message = string containing a message to display to the user.
526 	 *     processes = an array of #GPid for processes
527 	 *         blocking the operation.
528 	 *     choices = an array of strings for each possible choice.
529 	 *
530 	 * Since: 2.22
531 	 */
532 	gulong addOnShowProcesses(void delegate(string, ArrayG, string[], MountOperation) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
533 	{
534 		onShowProcessesListeners ~= new OnShowProcessesDelegateWrapper(dlg, 0, connectFlags);
535 		onShowProcessesListeners[onShowProcessesListeners.length - 1].handlerId = Signals.connectData(
536 			this,
537 			"show-processes",
538 			cast(GCallback)&callBackShowProcesses,
539 			cast(void*)onShowProcessesListeners[onShowProcessesListeners.length - 1],
540 			cast(GClosureNotify)&callBackShowProcessesDestroy,
541 			connectFlags);
542 		return onShowProcessesListeners[onShowProcessesListeners.length - 1].handlerId;
543 	}
544 	
545 	extern(C) static void callBackShowProcesses(GMountOperation* mountoperationStruct, char* message, GArray* processes, char** choices,OnShowProcessesDelegateWrapper wrapper)
546 	{
547 		wrapper.dlg(Str.toString(message), new ArrayG(processes), Str.toStringArray(choices), wrapper.outer);
548 	}
549 	
550 	extern(C) static void callBackShowProcessesDestroy(OnShowProcessesDelegateWrapper wrapper, GClosure* closure)
551 	{
552 		wrapper.outer.internalRemoveOnShowProcesses(wrapper);
553 	}
554 
555 	protected void internalRemoveOnShowProcesses(OnShowProcessesDelegateWrapper source)
556 	{
557 		foreach(index, wrapper; onShowProcessesListeners)
558 		{
559 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
560 			{
561 				onShowProcessesListeners[index] = null;
562 				onShowProcessesListeners = std.algorithm.remove(onShowProcessesListeners, index);
563 				break;
564 			}
565 		}
566 	}
567 	
568 
569 	protected class OnShowUnmountProgressDelegateWrapper
570 	{
571 		void delegate(string, long, long, MountOperation) dlg;
572 		gulong handlerId;
573 		ConnectFlags flags;
574 		this(void delegate(string, long, long, MountOperation) dlg, gulong handlerId, ConnectFlags flags)
575 		{
576 			this.dlg = dlg;
577 			this.handlerId = handlerId;
578 			this.flags = flags;
579 		}
580 	}
581 	protected OnShowUnmountProgressDelegateWrapper[] onShowUnmountProgressListeners;
582 
583 	/**
584 	 * Emitted when an unmount operation has been busy for more than some time
585 	 * (typically 1.5 seconds).
586 	 *
587 	 * When unmounting or ejecting a volume, the kernel might need to flush
588 	 * pending data in its buffers to the volume stable storage, and this operation
589 	 * can take a considerable amount of time. This signal may be emitted several
590 	 * times as long as the unmount operation is outstanding, and then one
591 	 * last time when the operation is completed, with @bytes_left set to zero.
592 	 *
593 	 * Implementations of GMountOperation should handle this signal by
594 	 * showing an UI notification, and then dismiss it, or show another notification
595 	 * of completion, when @bytes_left reaches zero.
596 	 *
597 	 * If the message contains a line break, the first line should be
598 	 * presented as a heading. For example, it may be used as the
599 	 * primary text in a #GtkMessageDialog.
600 	 *
601 	 * Params:
602 	 *     message = string containing a mesage to display to the user
603 	 *     timeLeft = the estimated time left before the operation completes,
604 	 *         in microseconds, or -1
605 	 *     bytesLeft = the amount of bytes to be written before the operation
606 	 *         completes (or -1 if such amount is not known), or zero if the operation
607 	 *         is completed
608 	 *
609 	 * Since: 2.34
610 	 */
611 	gulong addOnShowUnmountProgress(void delegate(string, long, long, MountOperation) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
612 	{
613 		onShowUnmountProgressListeners ~= new OnShowUnmountProgressDelegateWrapper(dlg, 0, connectFlags);
614 		onShowUnmountProgressListeners[onShowUnmountProgressListeners.length - 1].handlerId = Signals.connectData(
615 			this,
616 			"show-unmount-progress",
617 			cast(GCallback)&callBackShowUnmountProgress,
618 			cast(void*)onShowUnmountProgressListeners[onShowUnmountProgressListeners.length - 1],
619 			cast(GClosureNotify)&callBackShowUnmountProgressDestroy,
620 			connectFlags);
621 		return onShowUnmountProgressListeners[onShowUnmountProgressListeners.length - 1].handlerId;
622 	}
623 	
624 	extern(C) static void callBackShowUnmountProgress(GMountOperation* mountoperationStruct, char* message, long timeLeft, long bytesLeft,OnShowUnmountProgressDelegateWrapper wrapper)
625 	{
626 		wrapper.dlg(Str.toString(message), timeLeft, bytesLeft, wrapper.outer);
627 	}
628 	
629 	extern(C) static void callBackShowUnmountProgressDestroy(OnShowUnmountProgressDelegateWrapper wrapper, GClosure* closure)
630 	{
631 		wrapper.outer.internalRemoveOnShowUnmountProgress(wrapper);
632 	}
633 
634 	protected void internalRemoveOnShowUnmountProgress(OnShowUnmountProgressDelegateWrapper source)
635 	{
636 		foreach(index, wrapper; onShowUnmountProgressListeners)
637 		{
638 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
639 			{
640 				onShowUnmountProgressListeners[index] = null;
641 				onShowUnmountProgressListeners = std.algorithm.remove(onShowUnmountProgressListeners, index);
642 				break;
643 			}
644 		}
645 	}
646 	
647 }