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 }