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