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.SourceView;
26 
27 private import gdk.Event;
28 private import glib.ConstructionException;
29 private import glib.Str;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gsv.SourceBuffer;
33 private import gsv.SourceCompletion;
34 private import gsv.SourceGutter;
35 private import gsv.SourceMarkAttributes;
36 private import gsv.SpaceDrawer;
37 private import gsv.c.functions;
38 public  import gsv.c.types;
39 public  import gsvc.gsvtypes;
40 private import gtk.BuildableIF;
41 private import gtk.BuildableT;
42 private import gtk.ScrollableIF;
43 private import gtk.ScrollableT;
44 private import gtk.TextIter;
45 private import gtk.TextView;
46 private import gtk.Widget;
47 private import std.algorithm;
48 
49 
50 /** */
51 public class SourceView : TextView
52 {
53 	/** the main Gtk struct */
54 	protected GtkSourceView* gtkSourceView;
55 
56 	/** Get the main Gtk struct */
57 	public GtkSourceView* getSourceViewStruct(bool transferOwnership = false)
58 	{
59 		if (transferOwnership)
60 			ownedRef = false;
61 		return gtkSourceView;
62 	}
63 
64 	/** the main Gtk struct as a void* */
65 	protected override void* getStruct()
66 	{
67 		return cast(void*)gtkSourceView;
68 	}
69 
70 	protected override void setStruct(GObject* obj)
71 	{
72 		gtkSourceView = cast(GtkSourceView*)obj;
73 		super.setStruct(obj);
74 	}
75 
76 	/**
77 	 * Sets our main struct and passes it to the parent class.
78 	 */
79 	public this (GtkSourceView* gtkSourceView, bool ownedRef = false)
80 	{
81 		this.gtkSourceView = gtkSourceView;
82 		super(cast(GtkTextView*)gtkSourceView, ownedRef);
83 	}
84 
85 	/**
86 	 * Returns the GtkSourceBuffer being displayed by this source view.
87 	 * The reference count on the buffer is not incremented; the caller
88 	 * of this function won't own a new reference.
89 	 *
90 	 * Returns:
91 	 *  a GtkSourceBuffer
92 	 */
93 	public override SourceBuffer getBuffer()
94 	{
95 		auto p = gtk_text_view_get_buffer(cast(GtkTextView*)gtkSourceView);
96 
97 		return ObjectG.getDObject!(SourceBuffer)(cast(GtkSourceBuffer*) p);
98 	}
99 
100 	/**
101 	 */
102 
103 	/** */
104 	public static GType getType()
105 	{
106 		return gtk_source_view_get_type();
107 	}
108 
109 	/**
110 	 * Creates a new #GtkSourceView.
111 	 *
112 	 * By default, an empty #GtkSourceBuffer will be lazily created and can be
113 	 * retrieved with gtk_text_view_get_buffer().
114 	 *
115 	 * If you want to specify your own buffer, either override the
116 	 * #GtkTextViewClass create_buffer factory method, or use
117 	 * gtk_source_view_new_with_buffer().
118 	 *
119 	 * Returns: a new #GtkSourceView.
120 	 *
121 	 * Throws: ConstructionException GTK+ fails to create the object.
122 	 */
123 	public this()
124 	{
125 		auto p = gtk_source_view_new();
126 
127 		if(p is null)
128 		{
129 			throw new ConstructionException("null returned by new");
130 		}
131 
132 		this(cast(GtkSourceView*) p);
133 	}
134 
135 	/**
136 	 * Creates a new #GtkSourceView widget displaying the buffer
137 	 * @buffer. One buffer can be shared among many widgets.
138 	 *
139 	 * Params:
140 	 *     buffer = a #GtkSourceBuffer.
141 	 *
142 	 * Returns: a new #GtkSourceView.
143 	 *
144 	 * Throws: ConstructionException GTK+ fails to create the object.
145 	 */
146 	public this(SourceBuffer buffer)
147 	{
148 		auto p = gtk_source_view_new_with_buffer((buffer is null) ? null : buffer.getSourceBufferStruct());
149 
150 		if(p is null)
151 		{
152 			throw new ConstructionException("null returned by new_with_buffer");
153 		}
154 
155 		this(cast(GtkSourceView*) p);
156 	}
157 
158 	/**
159 	 * Returns whether auto-indentation of text is enabled.
160 	 *
161 	 * Returns: %TRUE if auto indentation is enabled.
162 	 */
163 	public bool getAutoIndent()
164 	{
165 		return gtk_source_view_get_auto_indent(gtkSourceView) != 0;
166 	}
167 
168 	/**
169 	 * Returns the #GtkSourceBackgroundPatternType specifying if and how
170 	 * the background pattern should be displayed for this @view.
171 	 *
172 	 * Returns: the #GtkSourceBackgroundPatternType.
173 	 *
174 	 * Since: 3.16
175 	 */
176 	public GtkSourceBackgroundPatternType getBackgroundPattern()
177 	{
178 		return gtk_source_view_get_background_pattern(gtkSourceView);
179 	}
180 
181 	/**
182 	 * Gets the #GtkSourceCompletion associated with @view. The returned object is
183 	 * guaranteed to be the same for the lifetime of @view. Each #GtkSourceView
184 	 * object has a different #GtkSourceCompletion.
185 	 *
186 	 * Returns: the #GtkSourceCompletion associated with @view.
187 	 */
188 	public SourceCompletion getCompletion()
189 	{
190 		auto p = gtk_source_view_get_completion(gtkSourceView);
191 
192 		if(p is null)
193 		{
194 			return null;
195 		}
196 
197 		return ObjectG.getDObject!(SourceCompletion)(cast(GtkSourceCompletion*) p);
198 	}
199 
200 	/**
201 	 * Returns the #GtkSourceDrawSpacesFlags specifying if and how spaces
202 	 * should be displayed for this @view.
203 	 *
204 	 * Deprecated: Use gtk_source_space_drawer_get_types_for_locations()
205 	 * instead.
206 	 *
207 	 * Returns: the #GtkSourceDrawSpacesFlags, 0 if no spaces should be drawn.
208 	 */
209 	public GtkSourceDrawSpacesFlags getDrawSpaces()
210 	{
211 		return gtk_source_view_get_draw_spaces(gtkSourceView);
212 	}
213 
214 	/**
215 	 * Returns the #GtkSourceGutter object associated with @window_type for @view.
216 	 * Only GTK_TEXT_WINDOW_LEFT and GTK_TEXT_WINDOW_RIGHT are supported,
217 	 * respectively corresponding to the left and right gutter. The line numbers
218 	 * and mark category icons are rendered in the left gutter.
219 	 *
220 	 * Params:
221 	 *     windowType = the gutter window type.
222 	 *
223 	 * Returns: the #GtkSourceGutter.
224 	 *
225 	 * Since: 2.8
226 	 */
227 	public SourceGutter getGutter(GtkTextWindowType windowType)
228 	{
229 		auto p = gtk_source_view_get_gutter(gtkSourceView, windowType);
230 
231 		if(p is null)
232 		{
233 			return null;
234 		}
235 
236 		return ObjectG.getDObject!(SourceGutter)(cast(GtkSourceGutter*) p);
237 	}
238 
239 	/**
240 	 * Returns whether the current line is highlighted.
241 	 *
242 	 * Returns: %TRUE if the current line is highlighted.
243 	 */
244 	public bool getHighlightCurrentLine()
245 	{
246 		return gtk_source_view_get_highlight_current_line(gtkSourceView) != 0;
247 	}
248 
249 	/**
250 	 * Returns whether when the tab key is pressed the current selection
251 	 * should get indented instead of replaced with the \t character.
252 	 *
253 	 * Returns: %TRUE if the selection is indented when tab is pressed.
254 	 */
255 	public bool getIndentOnTab()
256 	{
257 		return gtk_source_view_get_indent_on_tab(gtkSourceView) != 0;
258 	}
259 
260 	/**
261 	 * Returns the number of spaces to use for each step of indent.
262 	 * See gtk_source_view_set_indent_width() for details.
263 	 *
264 	 * Returns: indent width.
265 	 */
266 	public int getIndentWidth()
267 	{
268 		return gtk_source_view_get_indent_width(gtkSourceView);
269 	}
270 
271 	/**
272 	 * Returns whether when inserting a tabulator character it should
273 	 * be replaced by a group of space characters.
274 	 *
275 	 * Returns: %TRUE if spaces are inserted instead of tabs.
276 	 */
277 	public bool getInsertSpacesInsteadOfTabs()
278 	{
279 		return gtk_source_view_get_insert_spaces_instead_of_tabs(gtkSourceView) != 0;
280 	}
281 
282 	/**
283 	 * Gets attributes and priority for the @category.
284 	 *
285 	 * Params:
286 	 *     category = the category.
287 	 *     priority = place where priority of the category will be stored.
288 	 *
289 	 * Returns: #GtkSourceMarkAttributes for the @category.
290 	 *     The object belongs to @view, so it must not be unreffed.
291 	 */
292 	public SourceMarkAttributes getMarkAttributes(string category, int* priority)
293 	{
294 		auto p = gtk_source_view_get_mark_attributes(gtkSourceView, Str.toStringz(category), priority);
295 
296 		if(p is null)
297 		{
298 			return null;
299 		}
300 
301 		return ObjectG.getDObject!(SourceMarkAttributes)(cast(GtkSourceMarkAttributes*) p);
302 	}
303 
304 	/**
305 	 * Gets the position of the right margin in the given @view.
306 	 *
307 	 * Returns: the position of the right margin.
308 	 */
309 	public uint getRightMarginPosition()
310 	{
311 		return gtk_source_view_get_right_margin_position(gtkSourceView);
312 	}
313 
314 	/**
315 	 * Returns whether line marks are displayed beside the text.
316 	 *
317 	 * Returns: %TRUE if the line marks are displayed.
318 	 *
319 	 * Since: 2.2
320 	 */
321 	public bool getShowLineMarks()
322 	{
323 		return gtk_source_view_get_show_line_marks(gtkSourceView) != 0;
324 	}
325 
326 	/**
327 	 * Returns whether line numbers are displayed beside the text.
328 	 *
329 	 * Returns: %TRUE if the line numbers are displayed.
330 	 */
331 	public bool getShowLineNumbers()
332 	{
333 		return gtk_source_view_get_show_line_numbers(gtkSourceView) != 0;
334 	}
335 
336 	/**
337 	 * Returns whether a right margin is displayed.
338 	 *
339 	 * Returns: %TRUE if the right margin is shown.
340 	 */
341 	public bool getShowRightMargin()
342 	{
343 		return gtk_source_view_get_show_right_margin(gtkSourceView) != 0;
344 	}
345 
346 	/**
347 	 * Returns %TRUE if pressing the Backspace key will try to delete spaces
348 	 * up to the previous tab stop.
349 	 *
350 	 * Returns: %TRUE if smart Backspace handling is enabled.
351 	 *
352 	 * Since: 3.18
353 	 */
354 	public bool getSmartBackspace()
355 	{
356 		return gtk_source_view_get_smart_backspace(gtkSourceView) != 0;
357 	}
358 
359 	/**
360 	 * Returns a #GtkSourceSmartHomeEndType end value specifying
361 	 * how the cursor will move when HOME and END keys are pressed.
362 	 *
363 	 * Returns: a #GtkSourceSmartHomeEndType value.
364 	 */
365 	public GtkSourceSmartHomeEndType getSmartHomeEnd()
366 	{
367 		return gtk_source_view_get_smart_home_end(gtkSourceView);
368 	}
369 
370 	/**
371 	 * Gets the #GtkSourceSpaceDrawer associated with @view. The returned object is
372 	 * guaranteed to be the same for the lifetime of @view. Each #GtkSourceView
373 	 * object has a different #GtkSourceSpaceDrawer.
374 	 *
375 	 * Returns: the #GtkSourceSpaceDrawer associated with @view.
376 	 *
377 	 * Since: 3.24
378 	 */
379 	public SpaceDrawer getSpaceDrawer()
380 	{
381 		auto p = gtk_source_view_get_space_drawer(gtkSourceView);
382 
383 		if(p is null)
384 		{
385 			return null;
386 		}
387 
388 		return ObjectG.getDObject!(SpaceDrawer)(cast(GtkSourceSpaceDrawer*) p);
389 	}
390 
391 	/**
392 	 * Returns the width of tabulation in characters.
393 	 *
394 	 * Returns: width of tab.
395 	 */
396 	public uint getTabWidth()
397 	{
398 		return gtk_source_view_get_tab_width(gtkSourceView);
399 	}
400 
401 	/**
402 	 * Determines the visual column at @iter taking into consideration the
403 	 * #GtkSourceView:tab-width of @view.
404 	 *
405 	 * Params:
406 	 *     iter = a position in @view.
407 	 *
408 	 * Returns: the visual column at @iter.
409 	 */
410 	public uint getVisualColumn(TextIter iter)
411 	{
412 		return gtk_source_view_get_visual_column(gtkSourceView, (iter is null) ? null : iter.getTextIterStruct());
413 	}
414 
415 	/**
416 	 * Inserts one indentation level at the beginning of the specified lines. The
417 	 * empty lines are not indented.
418 	 *
419 	 * Params:
420 	 *     start = #GtkTextIter of the first line to indent
421 	 *     end = #GtkTextIter of the last line to indent
422 	 *
423 	 * Since: 3.16
424 	 */
425 	public void indentLines(TextIter start, TextIter end)
426 	{
427 		gtk_source_view_indent_lines(gtkSourceView, (start is null) ? null : start.getTextIterStruct(), (end is null) ? null : end.getTextIterStruct());
428 	}
429 
430 	/**
431 	 * If %TRUE auto-indentation of text is enabled.
432 	 *
433 	 * When Enter is pressed to create a new line, the auto-indentation inserts the
434 	 * same indentation as the previous line. This is <emphasis>not</emphasis> a
435 	 * "smart indentation" where an indentation level is added or removed depending
436 	 * on the context.
437 	 *
438 	 * Params:
439 	 *     enable = whether to enable auto indentation.
440 	 */
441 	public void setAutoIndent(bool enable)
442 	{
443 		gtk_source_view_set_auto_indent(gtkSourceView, enable);
444 	}
445 
446 	/**
447 	 * Set if and how the background pattern should be displayed.
448 	 *
449 	 * Params:
450 	 *     backgroundPattern = the #GtkSourceBackgroundPatternType.
451 	 *
452 	 * Since: 3.16
453 	 */
454 	public void setBackgroundPattern(GtkSourceBackgroundPatternType backgroundPattern)
455 	{
456 		gtk_source_view_set_background_pattern(gtkSourceView, backgroundPattern);
457 	}
458 
459 	/**
460 	 * Set if and how the spaces should be visualized. Specifying @flags as 0 will
461 	 * disable display of spaces.
462 	 *
463 	 * For a finer-grained method, there is also the GtkSourceTag's
464 	 * #GtkSourceTag:draw-spaces property.
465 	 *
466 	 * Deprecated: Use gtk_source_space_drawer_set_types_for_locations()
467 	 * instead.
468 	 *
469 	 * Params:
470 	 *     flags = #GtkSourceDrawSpacesFlags specifing how white spaces should
471 	 *         be displayed
472 	 */
473 	public void setDrawSpaces(GtkSourceDrawSpacesFlags flags)
474 	{
475 		gtk_source_view_set_draw_spaces(gtkSourceView, flags);
476 	}
477 
478 	/**
479 	 * If @highlight is %TRUE the current line will be highlighted.
480 	 *
481 	 * Params:
482 	 *     highlight = whether to highlight the current line.
483 	 */
484 	public void setHighlightCurrentLine(bool highlight)
485 	{
486 		gtk_source_view_set_highlight_current_line(gtkSourceView, highlight);
487 	}
488 
489 	/**
490 	 * If %TRUE, when the tab key is pressed when several lines are selected, the
491 	 * selected lines are indented of one level instead of being replaced with a \t
492 	 * character. Shift+Tab unindents the selection.
493 	 *
494 	 * If the first or last line is not selected completely, it is also indented or
495 	 * unindented.
496 	 *
497 	 * When the selection doesn't span several lines, the tab key always replaces
498 	 * the selection with a normal \t character.
499 	 *
500 	 * Params:
501 	 *     enable = whether to indent a block when tab is pressed.
502 	 */
503 	public void setIndentOnTab(bool enable)
504 	{
505 		gtk_source_view_set_indent_on_tab(gtkSourceView, enable);
506 	}
507 
508 	/**
509 	 * Sets the number of spaces to use for each step of indent when the tab key is
510 	 * pressed. If @width is -1, the value of the #GtkSourceView:tab-width property
511 	 * will be used.
512 	 *
513 	 * The #GtkSourceView:indent-width interacts with the
514 	 * #GtkSourceView:insert-spaces-instead-of-tabs property and
515 	 * #GtkSourceView:tab-width. An example will be clearer: if the
516 	 * #GtkSourceView:indent-width is 4 and
517 	 * #GtkSourceView:tab-width is 8 and
518 	 * #GtkSourceView:insert-spaces-instead-of-tabs is %FALSE, then pressing the tab
519 	 * key at the beginning of a line will insert 4 spaces. So far so good. Pressing
520 	 * the tab key a second time will remove the 4 spaces and insert a \t character
521 	 * instead (since #GtkSourceView:tab-width is 8). On the other hand, if
522 	 * #GtkSourceView:insert-spaces-instead-of-tabs is %TRUE, the second tab key
523 	 * pressed will insert 4 more spaces for a total of 8 spaces in the
524 	 * #GtkTextBuffer.
525 	 *
526 	 * The test-widget program (available in the GtkSourceView repository) may be
527 	 * useful to better understand the indentation settings (enable the space
528 	 * drawing!).
529 	 *
530 	 * Params:
531 	 *     width = indent width in characters.
532 	 */
533 	public void setIndentWidth(int width)
534 	{
535 		gtk_source_view_set_indent_width(gtkSourceView, width);
536 	}
537 
538 	/**
539 	 * If %TRUE a tab key pressed is replaced by a group of space characters. Of
540 	 * course it is still possible to insert a real \t programmatically with the
541 	 * #GtkTextBuffer API.
542 	 *
543 	 * Params:
544 	 *     enable = whether to insert spaces instead of tabs.
545 	 */
546 	public void setInsertSpacesInsteadOfTabs(bool enable)
547 	{
548 		gtk_source_view_set_insert_spaces_instead_of_tabs(gtkSourceView, enable);
549 	}
550 
551 	/**
552 	 * Sets attributes and priority for the @category.
553 	 *
554 	 * Params:
555 	 *     category = the category.
556 	 *     attributes = mark attributes.
557 	 *     priority = priority of the category.
558 	 */
559 	public void setMarkAttributes(string category, SourceMarkAttributes attributes, int priority)
560 	{
561 		gtk_source_view_set_mark_attributes(gtkSourceView, Str.toStringz(category), (attributes is null) ? null : attributes.getSourceMarkAttributesStruct(), priority);
562 	}
563 
564 	/**
565 	 * Sets the position of the right margin in the given @view.
566 	 *
567 	 * Params:
568 	 *     pos = the width in characters where to position the right margin.
569 	 */
570 	public void setRightMarginPosition(uint pos)
571 	{
572 		gtk_source_view_set_right_margin_position(gtkSourceView, pos);
573 	}
574 
575 	/**
576 	 * If %TRUE line marks will be displayed beside the text.
577 	 *
578 	 * Params:
579 	 *     show = whether line marks should be displayed.
580 	 *
581 	 * Since: 2.2
582 	 */
583 	public void setShowLineMarks(bool show)
584 	{
585 		gtk_source_view_set_show_line_marks(gtkSourceView, show);
586 	}
587 
588 	/**
589 	 * If %TRUE line numbers will be displayed beside the text.
590 	 *
591 	 * Params:
592 	 *     show = whether line numbers should be displayed.
593 	 */
594 	public void setShowLineNumbers(bool show)
595 	{
596 		gtk_source_view_set_show_line_numbers(gtkSourceView, show);
597 	}
598 
599 	/**
600 	 * If %TRUE a right margin is displayed.
601 	 *
602 	 * Params:
603 	 *     show = whether to show a right margin.
604 	 */
605 	public void setShowRightMargin(bool show)
606 	{
607 		gtk_source_view_set_show_right_margin(gtkSourceView, show);
608 	}
609 
610 	/**
611 	 * When set to %TRUE, pressing the Backspace key will try to delete spaces
612 	 * up to the previous tab stop.
613 	 *
614 	 * Params:
615 	 *     smartBackspace = whether to enable smart Backspace handling.
616 	 *
617 	 * Since: 3.18
618 	 */
619 	public void setSmartBackspace(bool smartBackspace)
620 	{
621 		gtk_source_view_set_smart_backspace(gtkSourceView, smartBackspace);
622 	}
623 
624 	/**
625 	 * Set the desired movement of the cursor when HOME and END keys
626 	 * are pressed.
627 	 *
628 	 * Params:
629 	 *     smartHomeEnd = the desired behavior among #GtkSourceSmartHomeEndType.
630 	 */
631 	public void setSmartHomeEnd(GtkSourceSmartHomeEndType smartHomeEnd)
632 	{
633 		gtk_source_view_set_smart_home_end(gtkSourceView, smartHomeEnd);
634 	}
635 
636 	/**
637 	 * Sets the width of tabulation in characters. The #GtkTextBuffer still contains
638 	 * \t characters, but they can take a different visual width in a #GtkSourceView
639 	 * widget.
640 	 *
641 	 * Params:
642 	 *     width = width of tab in characters.
643 	 */
644 	public void setTabWidth(uint width)
645 	{
646 		gtk_source_view_set_tab_width(gtkSourceView, width);
647 	}
648 
649 	/**
650 	 * Removes one indentation level at the beginning of the
651 	 * specified lines.
652 	 *
653 	 * Params:
654 	 *     start = #GtkTextIter of the first line to indent
655 	 *     end = #GtkTextIter of the last line to indent
656 	 *
657 	 * Since: 3.16
658 	 */
659 	public void unindentLines(TextIter start, TextIter end)
660 	{
661 		gtk_source_view_unindent_lines(gtkSourceView, (start is null) ? null : start.getTextIterStruct(), (end is null) ? null : end.getTextIterStruct());
662 	}
663 
664 	protected class OnChangeCaseDelegateWrapper
665 	{
666 		void delegate(GtkSourceChangeCaseType, SourceView) dlg;
667 		gulong handlerId;
668 
669 		this(void delegate(GtkSourceChangeCaseType, SourceView) dlg)
670 		{
671 			this.dlg = dlg;
672 			onChangeCaseListeners ~= this;
673 		}
674 
675 		void remove(OnChangeCaseDelegateWrapper source)
676 		{
677 			foreach(index, wrapper; onChangeCaseListeners)
678 			{
679 				if (wrapper.handlerId == source.handlerId)
680 				{
681 					onChangeCaseListeners[index] = null;
682 					onChangeCaseListeners = std.algorithm.remove(onChangeCaseListeners, index);
683 					break;
684 				}
685 			}
686 		}
687 	}
688 	OnChangeCaseDelegateWrapper[] onChangeCaseListeners;
689 
690 	/**
691 	 * Keybinding signal to change case of the text at the current cursor position.
692 	 *
693 	 * Params:
694 	 *     caseType = the case to use
695 	 *
696 	 * Since: 3.16
697 	 */
698 	gulong addOnChangeCase(void delegate(GtkSourceChangeCaseType, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
699 	{
700 		auto wrapper = new OnChangeCaseDelegateWrapper(dlg);
701 		wrapper.handlerId = Signals.connectData(
702 			this,
703 			"change-case",
704 			cast(GCallback)&callBackChangeCase,
705 			cast(void*)wrapper,
706 			cast(GClosureNotify)&callBackChangeCaseDestroy,
707 			connectFlags);
708 		return wrapper.handlerId;
709 	}
710 
711 	extern(C) static void callBackChangeCase(GtkSourceView* sourceviewStruct, GtkSourceChangeCaseType caseType, OnChangeCaseDelegateWrapper wrapper)
712 	{
713 		wrapper.dlg(caseType, wrapper.outer);
714 	}
715 
716 	extern(C) static void callBackChangeCaseDestroy(OnChangeCaseDelegateWrapper wrapper, GClosure* closure)
717 	{
718 		wrapper.remove(wrapper);
719 	}
720 
721 	protected class OnChangeNumberDelegateWrapper
722 	{
723 		void delegate(int, SourceView) dlg;
724 		gulong handlerId;
725 
726 		this(void delegate(int, SourceView) dlg)
727 		{
728 			this.dlg = dlg;
729 			onChangeNumberListeners ~= this;
730 		}
731 
732 		void remove(OnChangeNumberDelegateWrapper source)
733 		{
734 			foreach(index, wrapper; onChangeNumberListeners)
735 			{
736 				if (wrapper.handlerId == source.handlerId)
737 				{
738 					onChangeNumberListeners[index] = null;
739 					onChangeNumberListeners = std.algorithm.remove(onChangeNumberListeners, index);
740 					break;
741 				}
742 			}
743 		}
744 	}
745 	OnChangeNumberDelegateWrapper[] onChangeNumberListeners;
746 
747 	/**
748 	 * Keybinding signal to edit a number at the current cursor position.
749 	 *
750 	 * Params:
751 	 *     count = the number to add to the number at the current position
752 	 *
753 	 * Since: 3.16
754 	 */
755 	gulong addOnChangeNumber(void delegate(int, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
756 	{
757 		auto wrapper = new OnChangeNumberDelegateWrapper(dlg);
758 		wrapper.handlerId = Signals.connectData(
759 			this,
760 			"change-number",
761 			cast(GCallback)&callBackChangeNumber,
762 			cast(void*)wrapper,
763 			cast(GClosureNotify)&callBackChangeNumberDestroy,
764 			connectFlags);
765 		return wrapper.handlerId;
766 	}
767 
768 	extern(C) static void callBackChangeNumber(GtkSourceView* sourceviewStruct, int count, OnChangeNumberDelegateWrapper wrapper)
769 	{
770 		wrapper.dlg(count, wrapper.outer);
771 	}
772 
773 	extern(C) static void callBackChangeNumberDestroy(OnChangeNumberDelegateWrapper wrapper, GClosure* closure)
774 	{
775 		wrapper.remove(wrapper);
776 	}
777 
778 	protected class OnJoinLinesDelegateWrapper
779 	{
780 		void delegate(SourceView) dlg;
781 		gulong handlerId;
782 
783 		this(void delegate(SourceView) dlg)
784 		{
785 			this.dlg = dlg;
786 			onJoinLinesListeners ~= this;
787 		}
788 
789 		void remove(OnJoinLinesDelegateWrapper source)
790 		{
791 			foreach(index, wrapper; onJoinLinesListeners)
792 			{
793 				if (wrapper.handlerId == source.handlerId)
794 				{
795 					onJoinLinesListeners[index] = null;
796 					onJoinLinesListeners = std.algorithm.remove(onJoinLinesListeners, index);
797 					break;
798 				}
799 			}
800 		}
801 	}
802 	OnJoinLinesDelegateWrapper[] onJoinLinesListeners;
803 
804 	/**
805 	 * Keybinding signal to join the lines currently selected.
806 	 *
807 	 * Since: 3.16
808 	 */
809 	gulong addOnJoinLines(void delegate(SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
810 	{
811 		auto wrapper = new OnJoinLinesDelegateWrapper(dlg);
812 		wrapper.handlerId = Signals.connectData(
813 			this,
814 			"join-lines",
815 			cast(GCallback)&callBackJoinLines,
816 			cast(void*)wrapper,
817 			cast(GClosureNotify)&callBackJoinLinesDestroy,
818 			connectFlags);
819 		return wrapper.handlerId;
820 	}
821 
822 	extern(C) static void callBackJoinLines(GtkSourceView* sourceviewStruct, OnJoinLinesDelegateWrapper wrapper)
823 	{
824 		wrapper.dlg(wrapper.outer);
825 	}
826 
827 	extern(C) static void callBackJoinLinesDestroy(OnJoinLinesDelegateWrapper wrapper, GClosure* closure)
828 	{
829 		wrapper.remove(wrapper);
830 	}
831 
832 	protected class OnLineMarkActivatedDelegateWrapper
833 	{
834 		void delegate(TextIter, Event, SourceView) dlg;
835 		gulong handlerId;
836 
837 		this(void delegate(TextIter, Event, SourceView) dlg)
838 		{
839 			this.dlg = dlg;
840 			onLineMarkActivatedListeners ~= this;
841 		}
842 
843 		void remove(OnLineMarkActivatedDelegateWrapper source)
844 		{
845 			foreach(index, wrapper; onLineMarkActivatedListeners)
846 			{
847 				if (wrapper.handlerId == source.handlerId)
848 				{
849 					onLineMarkActivatedListeners[index] = null;
850 					onLineMarkActivatedListeners = std.algorithm.remove(onLineMarkActivatedListeners, index);
851 					break;
852 				}
853 			}
854 		}
855 	}
856 	OnLineMarkActivatedDelegateWrapper[] onLineMarkActivatedListeners;
857 
858 	/**
859 	 * Emitted when a line mark has been activated (for instance when there
860 	 * was a button press in the line marks gutter). You can use @iter to
861 	 * determine on which line the activation took place.
862 	 *
863 	 * Params:
864 	 *     iter = a #GtkTextIter
865 	 *     event = the #GdkEvent that activated the event
866 	 */
867 	gulong addOnLineMarkActivated(void delegate(TextIter, Event, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
868 	{
869 		auto wrapper = new OnLineMarkActivatedDelegateWrapper(dlg);
870 		wrapper.handlerId = Signals.connectData(
871 			this,
872 			"line-mark-activated",
873 			cast(GCallback)&callBackLineMarkActivated,
874 			cast(void*)wrapper,
875 			cast(GClosureNotify)&callBackLineMarkActivatedDestroy,
876 			connectFlags);
877 		return wrapper.handlerId;
878 	}
879 
880 	extern(C) static void callBackLineMarkActivated(GtkSourceView* sourceviewStruct, GtkTextIter* iter, GdkEvent* event, OnLineMarkActivatedDelegateWrapper wrapper)
881 	{
882 		wrapper.dlg(ObjectG.getDObject!(TextIter)(iter), ObjectG.getDObject!(Event)(event), wrapper.outer);
883 	}
884 
885 	extern(C) static void callBackLineMarkActivatedDestroy(OnLineMarkActivatedDelegateWrapper wrapper, GClosure* closure)
886 	{
887 		wrapper.remove(wrapper);
888 	}
889 
890 	protected class OnMoveLinesDelegateWrapper
891 	{
892 		void delegate(bool, int, SourceView) dlg;
893 		gulong handlerId;
894 
895 		this(void delegate(bool, int, SourceView) dlg)
896 		{
897 			this.dlg = dlg;
898 			onMoveLinesListeners ~= this;
899 		}
900 
901 		void remove(OnMoveLinesDelegateWrapper source)
902 		{
903 			foreach(index, wrapper; onMoveLinesListeners)
904 			{
905 				if (wrapper.handlerId == source.handlerId)
906 				{
907 					onMoveLinesListeners[index] = null;
908 					onMoveLinesListeners = std.algorithm.remove(onMoveLinesListeners, index);
909 					break;
910 				}
911 			}
912 		}
913 	}
914 	OnMoveLinesDelegateWrapper[] onMoveLinesListeners;
915 
916 	/**
917 	 * The ::move-lines signal is a keybinding which gets emitted
918 	 * when the user initiates moving a line. The default binding key
919 	 * is Alt+Up/Down arrow. And moves the currently selected lines,
920 	 * or the current line by @count. For the moment, only
921 	 * @count of -1 or 1 is valid.
922 	 *
923 	 * The @copy parameter is deprecated, it has never been used by
924 	 * GtkSourceView (the value is always %FALSE) and was buggy.
925 	 *
926 	 * Params:
927 	 *     copy = %TRUE if the line should be copied, %FALSE if it should be
928 	 *         moved. This parameter is deprecated and will be removed in a later
929 	 *         version, it should be always %FALSE.
930 	 *     count = the number of lines to move over. Only 1 and -1 are
931 	 *         supported.
932 	 *
933 	 * Since: 2.10
934 	 */
935 	gulong addOnMoveLines(void delegate(bool, int, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
936 	{
937 		auto wrapper = new OnMoveLinesDelegateWrapper(dlg);
938 		wrapper.handlerId = Signals.connectData(
939 			this,
940 			"move-lines",
941 			cast(GCallback)&callBackMoveLines,
942 			cast(void*)wrapper,
943 			cast(GClosureNotify)&callBackMoveLinesDestroy,
944 			connectFlags);
945 		return wrapper.handlerId;
946 	}
947 
948 	extern(C) static void callBackMoveLines(GtkSourceView* sourceviewStruct, bool copy, int count, OnMoveLinesDelegateWrapper wrapper)
949 	{
950 		wrapper.dlg(copy, count, wrapper.outer);
951 	}
952 
953 	extern(C) static void callBackMoveLinesDestroy(OnMoveLinesDelegateWrapper wrapper, GClosure* closure)
954 	{
955 		wrapper.remove(wrapper);
956 	}
957 
958 	protected class OnMoveToMatchingBracketDelegateWrapper
959 	{
960 		void delegate(bool, SourceView) dlg;
961 		gulong handlerId;
962 
963 		this(void delegate(bool, SourceView) dlg)
964 		{
965 			this.dlg = dlg;
966 			onMoveToMatchingBracketListeners ~= this;
967 		}
968 
969 		void remove(OnMoveToMatchingBracketDelegateWrapper source)
970 		{
971 			foreach(index, wrapper; onMoveToMatchingBracketListeners)
972 			{
973 				if (wrapper.handlerId == source.handlerId)
974 				{
975 					onMoveToMatchingBracketListeners[index] = null;
976 					onMoveToMatchingBracketListeners = std.algorithm.remove(onMoveToMatchingBracketListeners, index);
977 					break;
978 				}
979 			}
980 		}
981 	}
982 	OnMoveToMatchingBracketDelegateWrapper[] onMoveToMatchingBracketListeners;
983 
984 	/**
985 	 * Keybinding signal to move the cursor to the matching bracket.
986 	 *
987 	 * Params:
988 	 *     extendSelection = %TRUE if the move should extend the selection
989 	 *
990 	 * Since: 3.16
991 	 */
992 	gulong addOnMoveToMatchingBracket(void delegate(bool, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
993 	{
994 		auto wrapper = new OnMoveToMatchingBracketDelegateWrapper(dlg);
995 		wrapper.handlerId = Signals.connectData(
996 			this,
997 			"move-to-matching-bracket",
998 			cast(GCallback)&callBackMoveToMatchingBracket,
999 			cast(void*)wrapper,
1000 			cast(GClosureNotify)&callBackMoveToMatchingBracketDestroy,
1001 			connectFlags);
1002 		return wrapper.handlerId;
1003 	}
1004 
1005 	extern(C) static void callBackMoveToMatchingBracket(GtkSourceView* sourceviewStruct, bool extendSelection, OnMoveToMatchingBracketDelegateWrapper wrapper)
1006 	{
1007 		wrapper.dlg(extendSelection, wrapper.outer);
1008 	}
1009 
1010 	extern(C) static void callBackMoveToMatchingBracketDestroy(OnMoveToMatchingBracketDelegateWrapper wrapper, GClosure* closure)
1011 	{
1012 		wrapper.remove(wrapper);
1013 	}
1014 
1015 	protected class OnMoveWordsDelegateWrapper
1016 	{
1017 		void delegate(int, SourceView) dlg;
1018 		gulong handlerId;
1019 
1020 		this(void delegate(int, SourceView) dlg)
1021 		{
1022 			this.dlg = dlg;
1023 			onMoveWordsListeners ~= this;
1024 		}
1025 
1026 		void remove(OnMoveWordsDelegateWrapper source)
1027 		{
1028 			foreach(index, wrapper; onMoveWordsListeners)
1029 			{
1030 				if (wrapper.handlerId == source.handlerId)
1031 				{
1032 					onMoveWordsListeners[index] = null;
1033 					onMoveWordsListeners = std.algorithm.remove(onMoveWordsListeners, index);
1034 					break;
1035 				}
1036 			}
1037 		}
1038 	}
1039 	OnMoveWordsDelegateWrapper[] onMoveWordsListeners;
1040 
1041 	/**
1042 	 * The ::move-words signal is a keybinding which gets emitted
1043 	 * when the user initiates moving a word. The default binding key
1044 	 * is Alt+Left/Right Arrow and moves the current selection, or the current
1045 	 * word by one word.
1046 	 *
1047 	 * Params:
1048 	 *     count = the number of words to move over
1049 	 *
1050 	 * Since: 3.0
1051 	 */
1052 	gulong addOnMoveWords(void delegate(int, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1053 	{
1054 		auto wrapper = new OnMoveWordsDelegateWrapper(dlg);
1055 		wrapper.handlerId = Signals.connectData(
1056 			this,
1057 			"move-words",
1058 			cast(GCallback)&callBackMoveWords,
1059 			cast(void*)wrapper,
1060 			cast(GClosureNotify)&callBackMoveWordsDestroy,
1061 			connectFlags);
1062 		return wrapper.handlerId;
1063 	}
1064 
1065 	extern(C) static void callBackMoveWords(GtkSourceView* sourceviewStruct, int count, OnMoveWordsDelegateWrapper wrapper)
1066 	{
1067 		wrapper.dlg(count, wrapper.outer);
1068 	}
1069 
1070 	extern(C) static void callBackMoveWordsDestroy(OnMoveWordsDelegateWrapper wrapper, GClosure* closure)
1071 	{
1072 		wrapper.remove(wrapper);
1073 	}
1074 
1075 	protected class OnRedoDelegateWrapper
1076 	{
1077 		void delegate(SourceView) dlg;
1078 		gulong handlerId;
1079 
1080 		this(void delegate(SourceView) dlg)
1081 		{
1082 			this.dlg = dlg;
1083 			onRedoListeners ~= this;
1084 		}
1085 
1086 		void remove(OnRedoDelegateWrapper source)
1087 		{
1088 			foreach(index, wrapper; onRedoListeners)
1089 			{
1090 				if (wrapper.handlerId == source.handlerId)
1091 				{
1092 					onRedoListeners[index] = null;
1093 					onRedoListeners = std.algorithm.remove(onRedoListeners, index);
1094 					break;
1095 				}
1096 			}
1097 		}
1098 	}
1099 	OnRedoDelegateWrapper[] onRedoListeners;
1100 
1101 	/** */
1102 	gulong addOnRedo(void delegate(SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1103 	{
1104 		auto wrapper = new OnRedoDelegateWrapper(dlg);
1105 		wrapper.handlerId = Signals.connectData(
1106 			this,
1107 			"redo",
1108 			cast(GCallback)&callBackRedo,
1109 			cast(void*)wrapper,
1110 			cast(GClosureNotify)&callBackRedoDestroy,
1111 			connectFlags);
1112 		return wrapper.handlerId;
1113 	}
1114 
1115 	extern(C) static void callBackRedo(GtkSourceView* sourceviewStruct, OnRedoDelegateWrapper wrapper)
1116 	{
1117 		wrapper.dlg(wrapper.outer);
1118 	}
1119 
1120 	extern(C) static void callBackRedoDestroy(OnRedoDelegateWrapper wrapper, GClosure* closure)
1121 	{
1122 		wrapper.remove(wrapper);
1123 	}
1124 
1125 	protected class OnShowCompletionDelegateWrapper
1126 	{
1127 		void delegate(SourceView) dlg;
1128 		gulong handlerId;
1129 
1130 		this(void delegate(SourceView) dlg)
1131 		{
1132 			this.dlg = dlg;
1133 			onShowCompletionListeners ~= this;
1134 		}
1135 
1136 		void remove(OnShowCompletionDelegateWrapper source)
1137 		{
1138 			foreach(index, wrapper; onShowCompletionListeners)
1139 			{
1140 				if (wrapper.handlerId == source.handlerId)
1141 				{
1142 					onShowCompletionListeners[index] = null;
1143 					onShowCompletionListeners = std.algorithm.remove(onShowCompletionListeners, index);
1144 					break;
1145 				}
1146 			}
1147 		}
1148 	}
1149 	OnShowCompletionDelegateWrapper[] onShowCompletionListeners;
1150 
1151 	/**
1152 	 * The ::show-completion signal is a key binding signal which gets
1153 	 * emitted when the user requests a completion, by pressing
1154 	 * <keycombo><keycap>Control</keycap><keycap>space</keycap></keycombo>.
1155 	 *
1156 	 * This will create a #GtkSourceCompletionContext with the activation
1157 	 * type as %GTK_SOURCE_COMPLETION_ACTIVATION_USER_REQUESTED.
1158 	 *
1159 	 * Applications should not connect to it, but may emit it with
1160 	 * g_signal_emit_by_name() if they need to activate the completion by
1161 	 * another means, for example with another key binding or a menu entry.
1162 	 */
1163 	gulong addOnShowCompletion(void delegate(SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1164 	{
1165 		auto wrapper = new OnShowCompletionDelegateWrapper(dlg);
1166 		wrapper.handlerId = Signals.connectData(
1167 			this,
1168 			"show-completion",
1169 			cast(GCallback)&callBackShowCompletion,
1170 			cast(void*)wrapper,
1171 			cast(GClosureNotify)&callBackShowCompletionDestroy,
1172 			connectFlags);
1173 		return wrapper.handlerId;
1174 	}
1175 
1176 	extern(C) static void callBackShowCompletion(GtkSourceView* sourceviewStruct, OnShowCompletionDelegateWrapper wrapper)
1177 	{
1178 		wrapper.dlg(wrapper.outer);
1179 	}
1180 
1181 	extern(C) static void callBackShowCompletionDestroy(OnShowCompletionDelegateWrapper wrapper, GClosure* closure)
1182 	{
1183 		wrapper.remove(wrapper);
1184 	}
1185 
1186 	protected class OnSmartHomeEndDelegateWrapper
1187 	{
1188 		void delegate(TextIter, int, SourceView) dlg;
1189 		gulong handlerId;
1190 
1191 		this(void delegate(TextIter, int, SourceView) dlg)
1192 		{
1193 			this.dlg = dlg;
1194 			onSmartHomeEndListeners ~= this;
1195 		}
1196 
1197 		void remove(OnSmartHomeEndDelegateWrapper source)
1198 		{
1199 			foreach(index, wrapper; onSmartHomeEndListeners)
1200 			{
1201 				if (wrapper.handlerId == source.handlerId)
1202 				{
1203 					onSmartHomeEndListeners[index] = null;
1204 					onSmartHomeEndListeners = std.algorithm.remove(onSmartHomeEndListeners, index);
1205 					break;
1206 				}
1207 			}
1208 		}
1209 	}
1210 	OnSmartHomeEndDelegateWrapper[] onSmartHomeEndListeners;
1211 
1212 	/**
1213 	 * Emitted when a the cursor was moved according to the smart home
1214 	 * end setting. The signal is emitted after the cursor is moved, but
1215 	 * during the GtkTextView::move-cursor action. This can be used to find
1216 	 * out whether the cursor was moved by a normal home/end or by a smart
1217 	 * home/end.
1218 	 *
1219 	 * Params:
1220 	 *     iter = a #GtkTextIter
1221 	 *     count = the count
1222 	 *
1223 	 * Since: 3.0
1224 	 */
1225 	gulong addOnSmartHomeEnd(void delegate(TextIter, int, SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1226 	{
1227 		auto wrapper = new OnSmartHomeEndDelegateWrapper(dlg);
1228 		wrapper.handlerId = Signals.connectData(
1229 			this,
1230 			"smart-home-end",
1231 			cast(GCallback)&callBackSmartHomeEnd,
1232 			cast(void*)wrapper,
1233 			cast(GClosureNotify)&callBackSmartHomeEndDestroy,
1234 			connectFlags);
1235 		return wrapper.handlerId;
1236 	}
1237 
1238 	extern(C) static void callBackSmartHomeEnd(GtkSourceView* sourceviewStruct, GtkTextIter* iter, int count, OnSmartHomeEndDelegateWrapper wrapper)
1239 	{
1240 		wrapper.dlg(ObjectG.getDObject!(TextIter)(iter), count, wrapper.outer);
1241 	}
1242 
1243 	extern(C) static void callBackSmartHomeEndDestroy(OnSmartHomeEndDelegateWrapper wrapper, GClosure* closure)
1244 	{
1245 		wrapper.remove(wrapper);
1246 	}
1247 
1248 	protected class OnUndoDelegateWrapper
1249 	{
1250 		void delegate(SourceView) dlg;
1251 		gulong handlerId;
1252 
1253 		this(void delegate(SourceView) dlg)
1254 		{
1255 			this.dlg = dlg;
1256 			onUndoListeners ~= this;
1257 		}
1258 
1259 		void remove(OnUndoDelegateWrapper source)
1260 		{
1261 			foreach(index, wrapper; onUndoListeners)
1262 			{
1263 				if (wrapper.handlerId == source.handlerId)
1264 				{
1265 					onUndoListeners[index] = null;
1266 					onUndoListeners = std.algorithm.remove(onUndoListeners, index);
1267 					break;
1268 				}
1269 			}
1270 		}
1271 	}
1272 	OnUndoDelegateWrapper[] onUndoListeners;
1273 
1274 	/** */
1275 	gulong addOnUndo(void delegate(SourceView) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1276 	{
1277 		auto wrapper = new OnUndoDelegateWrapper(dlg);
1278 		wrapper.handlerId = Signals.connectData(
1279 			this,
1280 			"undo",
1281 			cast(GCallback)&callBackUndo,
1282 			cast(void*)wrapper,
1283 			cast(GClosureNotify)&callBackUndoDestroy,
1284 			connectFlags);
1285 		return wrapper.handlerId;
1286 	}
1287 
1288 	extern(C) static void callBackUndo(GtkSourceView* sourceviewStruct, OnUndoDelegateWrapper wrapper)
1289 	{
1290 		wrapper.dlg(wrapper.outer);
1291 	}
1292 
1293 	extern(C) static void callBackUndoDestroy(OnUndoDelegateWrapper wrapper, GClosure* closure)
1294 	{
1295 		wrapper.remove(wrapper);
1296 	}
1297 }