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 gsv.SourceCompletion;
26 
27 private import glib.ErrorG;
28 private import glib.GException;
29 private import glib.ListG;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gsv.SourceCompletionContext;
33 private import gsv.SourceCompletionInfo;
34 private import gsv.SourceCompletionProviderIF;
35 private import gsv.SourceView;
36 private import gsvc.gsv;
37 public  import gsvc.gsvtypes;
38 private import gtk.BuildableIF;
39 private import gtk.BuildableT;
40 private import gtk.TextIter;
41 public  import gtkc.gdktypes;
42 private import std.algorithm;
43 
44 
45 /** */
46 public class SourceCompletion : ObjectG, BuildableIF
47 {
48 	/** the main Gtk struct */
49 	protected GtkSourceCompletion* gtkSourceCompletion;
50 
51 	/** Get the main Gtk struct */
52 	public GtkSourceCompletion* getSourceCompletionStruct()
53 	{
54 		return gtkSourceCompletion;
55 	}
56 
57 	/** the main Gtk struct as a void* */
58 	protected override void* getStruct()
59 	{
60 		return cast(void*)gtkSourceCompletion;
61 	}
62 
63 	protected override void setStruct(GObject* obj)
64 	{
65 		gtkSourceCompletion = cast(GtkSourceCompletion*)obj;
66 		super.setStruct(obj);
67 	}
68 
69 	/**
70 	 * Sets our main struct and passes it to the parent class.
71 	 */
72 	public this (GtkSourceCompletion* gtkSourceCompletion, bool ownedRef = false)
73 	{
74 		this.gtkSourceCompletion = gtkSourceCompletion;
75 		super(cast(GObject*)gtkSourceCompletion, ownedRef);
76 	}
77 
78 	// add the Buildable capabilities
79 	mixin BuildableT!(GtkSourceCompletion);
80 
81 
82 	/** */
83 	public static GType getType()
84 	{
85 		return gtk_source_completion_get_type();
86 	}
87 
88 	/**
89 	 * Add a new #GtkSourceCompletionProvider to the completion object. This will
90 	 * add a reference @provider, so make sure to unref your own copy when you
91 	 * no longer need it.
92 	 *
93 	 * Params:
94 	 *     provider = a #GtkSourceCompletionProvider.
95 	 *
96 	 * Return: %TRUE if @provider was successfully added, otherwise if @error
97 	 *     is provided, it will be set with the error and %FALSE is returned.
98 	 *
99 	 * Throws: GException on failure.
100 	 */
101 	public bool addProvider(SourceCompletionProviderIF provider)
102 	{
103 		GError* err = null;
104 		
105 		auto p = gtk_source_completion_add_provider(gtkSourceCompletion, (provider is null) ? null : provider.getSourceCompletionProviderStruct(), &err) != 0;
106 		
107 		if (err !is null)
108 		{
109 			throw new GException( new ErrorG(err) );
110 		}
111 		
112 		return p;
113 	}
114 
115 	/**
116 	 * Block interactive completion. This can be used to disable interactive
117 	 * completion when inserting or deleting text from the buffer associated with
118 	 * the completion. Use gtk_source_completion_unblock_interactive() to enable
119 	 * interactive completion again.
120 	 *
121 	 * This function may be called multiple times. It will continue to block
122 	 * interactive completion until gtk_source_completion_unblock_interactive()
123 	 * has been called the same number of times.
124 	 */
125 	public void blockInteractive()
126 	{
127 		gtk_source_completion_block_interactive(gtkSourceCompletion);
128 	}
129 
130 	/**
131 	 * Create a new #GtkSourceCompletionContext for @completion. The position where
132 	 * the completion occurs can be specified by @position. If @position is %NULL,
133 	 * the current cursor position will be used.
134 	 *
135 	 * Params:
136 	 *     position = a #GtkTextIter, or %NULL.
137 	 *
138 	 * Return: a new #GtkSourceCompletionContext.
139 	 *     The reference being returned is a 'floating' reference,
140 	 *     so if you invoke gtk_source_completion_show() with this context
141 	 *     you don't need to unref it.
142 	 */
143 	public SourceCompletionContext createContext(TextIter position)
144 	{
145 		auto p = gtk_source_completion_create_context(gtkSourceCompletion, (position is null) ? null : position.getTextIterStruct());
146 		
147 		if(p is null)
148 		{
149 			return null;
150 		}
151 		
152 		return ObjectG.getDObject!(SourceCompletionContext)(cast(GtkSourceCompletionContext*) p);
153 	}
154 
155 	/**
156 	 * The info widget is the window where the completion displays optional extra
157 	 * information of the proposal.
158 	 *
159 	 * Return: The #GtkSourceCompletionInfo window
160 	 *     associated with @completion.
161 	 */
162 	public SourceCompletionInfo getInfoWindow()
163 	{
164 		auto p = gtk_source_completion_get_info_window(gtkSourceCompletion);
165 		
166 		if(p is null)
167 		{
168 			return null;
169 		}
170 		
171 		return ObjectG.getDObject!(SourceCompletionInfo)(cast(GtkSourceCompletionInfo*) p);
172 	}
173 
174 	/**
175 	 * Get list of providers registered on @completion. The returned list is owned
176 	 * by the completion and should not be freed.
177 	 *
178 	 * Return: list of #GtkSourceCompletionProvider.
179 	 */
180 	public ListG getProviders()
181 	{
182 		auto p = gtk_source_completion_get_providers(gtkSourceCompletion);
183 		
184 		if(p is null)
185 		{
186 			return null;
187 		}
188 		
189 		return new ListG(cast(GList*) p);
190 	}
191 
192 	/**
193 	 * The #GtkSourceView associated with @completion, or %NULL if the view has been
194 	 * destroyed.
195 	 *
196 	 * Return: The #GtkSourceView associated with @completion, or %NULL.
197 	 */
198 	public SourceView getView()
199 	{
200 		auto p = gtk_source_completion_get_view(gtkSourceCompletion);
201 		
202 		if(p is null)
203 		{
204 			return null;
205 		}
206 		
207 		return ObjectG.getDObject!(SourceView)(cast(GtkSourceView*) p);
208 	}
209 
210 	/**
211 	 * Hides the completion if it is active (visible).
212 	 */
213 	public void hide()
214 	{
215 		gtk_source_completion_hide(gtkSourceCompletion);
216 	}
217 
218 	/**
219 	 * Move the completion window to a specific iter.
220 	 *
221 	 * Deprecated: Use gtk_source_completion_provider_get_start_iter() instead.
222 	 *
223 	 * Params:
224 	 *     iter = a #GtkTextIter.
225 	 */
226 	public void moveWindow(TextIter iter)
227 	{
228 		gtk_source_completion_move_window(gtkSourceCompletion, (iter is null) ? null : iter.getTextIterStruct());
229 	}
230 
231 	/**
232 	 * Remove @provider from the completion.
233 	 *
234 	 * Params:
235 	 *     provider = a #GtkSourceCompletionProvider.
236 	 *
237 	 * Return: %TRUE if @provider was successfully removed, otherwise if @error
238 	 *     is provided, it will be set with the error and %FALSE is returned.
239 	 *
240 	 * Throws: GException on failure.
241 	 */
242 	public bool removeProvider(SourceCompletionProviderIF provider)
243 	{
244 		GError* err = null;
245 		
246 		auto p = gtk_source_completion_remove_provider(gtkSourceCompletion, (provider is null) ? null : provider.getSourceCompletionProviderStruct(), &err) != 0;
247 		
248 		if (err !is null)
249 		{
250 			throw new GException( new ErrorG(err) );
251 		}
252 		
253 		return p;
254 	}
255 
256 	/**
257 	 * Starts a new completion with the specified #GtkSourceCompletionContext and
258 	 * a list of potential candidate providers for completion.
259 	 *
260 	 * It can be convenient for showing a completion on-the-fly, without the need to
261 	 * add or remove providers to the #GtkSourceCompletion.
262 	 *
263 	 * Another solution is to add providers with
264 	 * gtk_source_completion_add_provider(), and implement
265 	 * gtk_source_completion_provider_match() for each provider.
266 	 *
267 	 * Params:
268 	 *     providers = a list of #GtkSourceCompletionProvider, or %NULL.
269 	 *     context = The #GtkSourceCompletionContext
270 	 *         with which to start the completion.
271 	 *
272 	 * Return: %TRUE if it was possible to the show completion window.
273 	 */
274 	public bool show(ListG providers, SourceCompletionContext context)
275 	{
276 		return gtk_source_completion_show(gtkSourceCompletion, (providers is null) ? null : providers.getListGStruct(), (context is null) ? null : context.getSourceCompletionContextStruct()) != 0;
277 	}
278 
279 	/**
280 	 * Unblock interactive completion. This can be used after using
281 	 * gtk_source_completion_block_interactive() to enable interactive completion
282 	 * again.
283 	 */
284 	public void unblockInteractive()
285 	{
286 		gtk_source_completion_unblock_interactive(gtkSourceCompletion);
287 	}
288 
289 	protected class OnActivateProposalDelegateWrapper
290 	{
291 		void delegate(SourceCompletion) dlg;
292 		gulong handlerId;
293 		ConnectFlags flags;
294 		this(void delegate(SourceCompletion) dlg, gulong handlerId, ConnectFlags flags)
295 		{
296 			this.dlg = dlg;
297 			this.handlerId = handlerId;
298 			this.flags = flags;
299 		}
300 	}
301 	protected OnActivateProposalDelegateWrapper[] onActivateProposalListeners;
302 
303 	/**
304 	 * The #GtkSourceCompletion::activate-proposal signal is a
305 	 * keybinding signal which gets emitted when the user initiates
306 	 * a proposal activation.
307 	 *
308 	 * Applications should not connect to it, but may emit it with
309 	 * g_signal_emit_by_name() if they need to control the proposal
310 	 * activation programmatically.
311 	 */
312 	gulong addOnActivateProposal(void delegate(SourceCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
313 	{
314 		onActivateProposalListeners ~= new OnActivateProposalDelegateWrapper(dlg, 0, connectFlags);
315 		onActivateProposalListeners[onActivateProposalListeners.length - 1].handlerId = Signals.connectData(
316 			this,
317 			"activate-proposal",
318 			cast(GCallback)&callBackActivateProposal,
319 			cast(void*)onActivateProposalListeners[onActivateProposalListeners.length - 1],
320 			cast(GClosureNotify)&callBackActivateProposalDestroy,
321 			connectFlags);
322 		return onActivateProposalListeners[onActivateProposalListeners.length - 1].handlerId;
323 	}
324 	
325 	extern(C) static void callBackActivateProposal(GtkSourceCompletion* sourcecompletionStruct,OnActivateProposalDelegateWrapper wrapper)
326 	{
327 		wrapper.dlg(wrapper.outer);
328 	}
329 	
330 	extern(C) static void callBackActivateProposalDestroy(OnActivateProposalDelegateWrapper wrapper, GClosure* closure)
331 	{
332 		wrapper.outer.internalRemoveOnActivateProposal(wrapper);
333 	}
334 
335 	protected void internalRemoveOnActivateProposal(OnActivateProposalDelegateWrapper source)
336 	{
337 		foreach(index, wrapper; onActivateProposalListeners)
338 		{
339 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
340 			{
341 				onActivateProposalListeners[index] = null;
342 				onActivateProposalListeners = std.algorithm.remove(onActivateProposalListeners, index);
343 				break;
344 			}
345 		}
346 	}
347 	
348 
349 	protected class OnHideDelegateWrapper
350 	{
351 		void delegate(SourceCompletion) dlg;
352 		gulong handlerId;
353 		ConnectFlags flags;
354 		this(void delegate(SourceCompletion) dlg, gulong handlerId, ConnectFlags flags)
355 		{
356 			this.dlg = dlg;
357 			this.handlerId = handlerId;
358 			this.flags = flags;
359 		}
360 	}
361 	protected OnHideDelegateWrapper[] onHideListeners;
362 
363 	/**
364 	 * Emitted when the completion window is hidden. The default handler
365 	 * will actually hide the window.
366 	 */
367 	gulong addOnHide(void delegate(SourceCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
368 	{
369 		onHideListeners ~= new OnHideDelegateWrapper(dlg, 0, connectFlags);
370 		onHideListeners[onHideListeners.length - 1].handlerId = Signals.connectData(
371 			this,
372 			"hide",
373 			cast(GCallback)&callBackHide,
374 			cast(void*)onHideListeners[onHideListeners.length - 1],
375 			cast(GClosureNotify)&callBackHideDestroy,
376 			connectFlags);
377 		return onHideListeners[onHideListeners.length - 1].handlerId;
378 	}
379 	
380 	extern(C) static void callBackHide(GtkSourceCompletion* sourcecompletionStruct,OnHideDelegateWrapper wrapper)
381 	{
382 		wrapper.dlg(wrapper.outer);
383 	}
384 	
385 	extern(C) static void callBackHideDestroy(OnHideDelegateWrapper wrapper, GClosure* closure)
386 	{
387 		wrapper.outer.internalRemoveOnHide(wrapper);
388 	}
389 
390 	protected void internalRemoveOnHide(OnHideDelegateWrapper source)
391 	{
392 		foreach(index, wrapper; onHideListeners)
393 		{
394 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
395 			{
396 				onHideListeners[index] = null;
397 				onHideListeners = std.algorithm.remove(onHideListeners, index);
398 				break;
399 			}
400 		}
401 	}
402 	
403 
404 	protected class OnMoveCursorDelegateWrapper
405 	{
406 		void delegate(GtkScrollStep, int, SourceCompletion) dlg;
407 		gulong handlerId;
408 		ConnectFlags flags;
409 		this(void delegate(GtkScrollStep, int, SourceCompletion) dlg, gulong handlerId, ConnectFlags flags)
410 		{
411 			this.dlg = dlg;
412 			this.handlerId = handlerId;
413 			this.flags = flags;
414 		}
415 	}
416 	protected OnMoveCursorDelegateWrapper[] onMoveCursorListeners;
417 
418 	/**
419 	 * The #GtkSourceCompletion::move-cursor signal is a keybinding
420 	 * signal which gets emitted when the user initiates a cursor
421 	 * movement.
422 	 *
423 	 * The <keycap>Up</keycap>, <keycap>Down</keycap>,
424 	 * <keycap>PageUp</keycap>, <keycap>PageDown</keycap>,
425 	 * <keycap>Home</keycap> and <keycap>End</keycap> keys are bound to the
426 	 * normal behavior expected by those keys.
427 	 *
428 	 * When @step is equal to %GTK_SCROLL_PAGES, the page size is defined by
429 	 * the #GtkSourceCompletion:proposal-page-size property. It is used for
430 	 * the <keycap>PageDown</keycap> and <keycap>PageUp</keycap> keys.
431 	 *
432 	 * Applications should not connect to it, but may emit it with
433 	 * g_signal_emit_by_name() if they need to control the cursor
434 	 * programmatically.
435 	 *
436 	 * Params:
437 	 *     step = The #GtkScrollStep by which to move the cursor
438 	 *     num = The amount of steps to move the cursor
439 	 */
440 	gulong addOnMoveCursor(void delegate(GtkScrollStep, int, SourceCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
441 	{
442 		onMoveCursorListeners ~= new OnMoveCursorDelegateWrapper(dlg, 0, connectFlags);
443 		onMoveCursorListeners[onMoveCursorListeners.length - 1].handlerId = Signals.connectData(
444 			this,
445 			"move-cursor",
446 			cast(GCallback)&callBackMoveCursor,
447 			cast(void*)onMoveCursorListeners[onMoveCursorListeners.length - 1],
448 			cast(GClosureNotify)&callBackMoveCursorDestroy,
449 			connectFlags);
450 		return onMoveCursorListeners[onMoveCursorListeners.length - 1].handlerId;
451 	}
452 	
453 	extern(C) static void callBackMoveCursor(GtkSourceCompletion* sourcecompletionStruct, GtkScrollStep step, int num,OnMoveCursorDelegateWrapper wrapper)
454 	{
455 		wrapper.dlg(step, num, wrapper.outer);
456 	}
457 	
458 	extern(C) static void callBackMoveCursorDestroy(OnMoveCursorDelegateWrapper wrapper, GClosure* closure)
459 	{
460 		wrapper.outer.internalRemoveOnMoveCursor(wrapper);
461 	}
462 
463 	protected void internalRemoveOnMoveCursor(OnMoveCursorDelegateWrapper source)
464 	{
465 		foreach(index, wrapper; onMoveCursorListeners)
466 		{
467 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
468 			{
469 				onMoveCursorListeners[index] = null;
470 				onMoveCursorListeners = std.algorithm.remove(onMoveCursorListeners, index);
471 				break;
472 			}
473 		}
474 	}
475 	
476 
477 	protected class OnMovePageDelegateWrapper
478 	{
479 		void delegate(GtkScrollStep, int, SourceCompletion) dlg;
480 		gulong handlerId;
481 		ConnectFlags flags;
482 		this(void delegate(GtkScrollStep, int, SourceCompletion) dlg, gulong handlerId, ConnectFlags flags)
483 		{
484 			this.dlg = dlg;
485 			this.handlerId = handlerId;
486 			this.flags = flags;
487 		}
488 	}
489 	protected OnMovePageDelegateWrapper[] onMovePageListeners;
490 
491 	/**
492 	 * The #GtkSourceCompletion::move-page signal is a keybinding
493 	 * signal which gets emitted when the user initiates a page
494 	 * movement (i.e. switches between provider pages).
495 	 *
496 	 * <keycombo><keycap>Control</keycap><keycap>Left</keycap></keycombo>
497 	 * is for going to the previous provider.
498 	 * <keycombo><keycap>Control</keycap><keycap>Right</keycap></keycombo>
499 	 * is for going to the next provider.
500 	 * <keycombo><keycap>Control</keycap><keycap>Home</keycap></keycombo>
501 	 * is for displaying all the providers.
502 	 * <keycombo><keycap>Control</keycap><keycap>End</keycap></keycombo>
503 	 * is for going to the last provider.
504 	 *
505 	 * When @step is equal to #GTK_SCROLL_PAGES, the page size is defined by
506 	 * the #GtkSourceCompletion:provider-page-size property.
507 	 *
508 	 * Applications should not connect to it, but may emit it with
509 	 * g_signal_emit_by_name() if they need to control the page selection
510 	 * programmatically.
511 	 *
512 	 * Params:
513 	 *     step = The #GtkScrollStep by which to move the page
514 	 *     num = The amount of steps to move the page
515 	 */
516 	gulong addOnMovePage(void delegate(GtkScrollStep, int, SourceCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
517 	{
518 		onMovePageListeners ~= new OnMovePageDelegateWrapper(dlg, 0, connectFlags);
519 		onMovePageListeners[onMovePageListeners.length - 1].handlerId = Signals.connectData(
520 			this,
521 			"move-page",
522 			cast(GCallback)&callBackMovePage,
523 			cast(void*)onMovePageListeners[onMovePageListeners.length - 1],
524 			cast(GClosureNotify)&callBackMovePageDestroy,
525 			connectFlags);
526 		return onMovePageListeners[onMovePageListeners.length - 1].handlerId;
527 	}
528 	
529 	extern(C) static void callBackMovePage(GtkSourceCompletion* sourcecompletionStruct, GtkScrollStep step, int num,OnMovePageDelegateWrapper wrapper)
530 	{
531 		wrapper.dlg(step, num, wrapper.outer);
532 	}
533 	
534 	extern(C) static void callBackMovePageDestroy(OnMovePageDelegateWrapper wrapper, GClosure* closure)
535 	{
536 		wrapper.outer.internalRemoveOnMovePage(wrapper);
537 	}
538 
539 	protected void internalRemoveOnMovePage(OnMovePageDelegateWrapper source)
540 	{
541 		foreach(index, wrapper; onMovePageListeners)
542 		{
543 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
544 			{
545 				onMovePageListeners[index] = null;
546 				onMovePageListeners = std.algorithm.remove(onMovePageListeners, index);
547 				break;
548 			}
549 		}
550 	}
551 	
552 
553 	protected class OnPopulateContextDelegateWrapper
554 	{
555 		void delegate(SourceCompletionContext, SourceCompletion) dlg;
556 		gulong handlerId;
557 		ConnectFlags flags;
558 		this(void delegate(SourceCompletionContext, SourceCompletion) dlg, gulong handlerId, ConnectFlags flags)
559 		{
560 			this.dlg = dlg;
561 			this.handlerId = handlerId;
562 			this.flags = flags;
563 		}
564 	}
565 	protected OnPopulateContextDelegateWrapper[] onPopulateContextListeners;
566 
567 	/**
568 	 * Emitted just before starting to populate the completion with providers.
569 	 * You can use this signal to add additional attributes in the context.
570 	 *
571 	 * Params:
572 	 *     context = The #GtkSourceCompletionContext for the current completion
573 	 */
574 	gulong addOnPopulateContext(void delegate(SourceCompletionContext, SourceCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
575 	{
576 		onPopulateContextListeners ~= new OnPopulateContextDelegateWrapper(dlg, 0, connectFlags);
577 		onPopulateContextListeners[onPopulateContextListeners.length - 1].handlerId = Signals.connectData(
578 			this,
579 			"populate-context",
580 			cast(GCallback)&callBackPopulateContext,
581 			cast(void*)onPopulateContextListeners[onPopulateContextListeners.length - 1],
582 			cast(GClosureNotify)&callBackPopulateContextDestroy,
583 			connectFlags);
584 		return onPopulateContextListeners[onPopulateContextListeners.length - 1].handlerId;
585 	}
586 	
587 	extern(C) static void callBackPopulateContext(GtkSourceCompletion* sourcecompletionStruct, GtkSourceCompletionContext* context,OnPopulateContextDelegateWrapper wrapper)
588 	{
589 		wrapper.dlg(ObjectG.getDObject!(SourceCompletionContext)(context), wrapper.outer);
590 	}
591 	
592 	extern(C) static void callBackPopulateContextDestroy(OnPopulateContextDelegateWrapper wrapper, GClosure* closure)
593 	{
594 		wrapper.outer.internalRemoveOnPopulateContext(wrapper);
595 	}
596 
597 	protected void internalRemoveOnPopulateContext(OnPopulateContextDelegateWrapper source)
598 	{
599 		foreach(index, wrapper; onPopulateContextListeners)
600 		{
601 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
602 			{
603 				onPopulateContextListeners[index] = null;
604 				onPopulateContextListeners = std.algorithm.remove(onPopulateContextListeners, index);
605 				break;
606 			}
607 		}
608 	}
609 	
610 
611 	protected class OnShowDelegateWrapper
612 	{
613 		void delegate(SourceCompletion) dlg;
614 		gulong handlerId;
615 		ConnectFlags flags;
616 		this(void delegate(SourceCompletion) dlg, gulong handlerId, ConnectFlags flags)
617 		{
618 			this.dlg = dlg;
619 			this.handlerId = handlerId;
620 			this.flags = flags;
621 		}
622 	}
623 	protected OnShowDelegateWrapper[] onShowListeners;
624 
625 	/**
626 	 * Emitted when the completion window is shown. The default handler
627 	 * will actually show the window.
628 	 */
629 	gulong addOnShow(void delegate(SourceCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
630 	{
631 		onShowListeners ~= new OnShowDelegateWrapper(dlg, 0, connectFlags);
632 		onShowListeners[onShowListeners.length - 1].handlerId = Signals.connectData(
633 			this,
634 			"show",
635 			cast(GCallback)&callBackShow,
636 			cast(void*)onShowListeners[onShowListeners.length - 1],
637 			cast(GClosureNotify)&callBackShowDestroy,
638 			connectFlags);
639 		return onShowListeners[onShowListeners.length - 1].handlerId;
640 	}
641 	
642 	extern(C) static void callBackShow(GtkSourceCompletion* sourcecompletionStruct,OnShowDelegateWrapper wrapper)
643 	{
644 		wrapper.dlg(wrapper.outer);
645 	}
646 	
647 	extern(C) static void callBackShowDestroy(OnShowDelegateWrapper wrapper, GClosure* closure)
648 	{
649 		wrapper.outer.internalRemoveOnShow(wrapper);
650 	}
651 
652 	protected void internalRemoveOnShow(OnShowDelegateWrapper source)
653 	{
654 		foreach(index, wrapper; onShowListeners)
655 		{
656 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
657 			{
658 				onShowListeners[index] = null;
659 				onShowListeners = std.algorithm.remove(onShowListeners, index);
660 				break;
661 			}
662 		}
663 	}
664 	
665 }