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 gtk.EntryCompletion; 26 27 private import glib.ConstructionException; 28 private import glib.Str; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 private import gtk.BuildableIF; 32 private import gtk.BuildableT; 33 private import gtk.CellArea; 34 private import gtk.CellLayoutIF; 35 private import gtk.CellLayoutT; 36 private import gtk.TreeIter; 37 private import gtk.TreeModel; 38 private import gtk.TreeModelIF; 39 private import gtk.Widget; 40 private import gtkc.gtk; 41 public import gtkc.gtktypes; 42 private import std.algorithm; 43 44 45 /** 46 * #GtkEntryCompletion is an auxiliary object to be used in conjunction with 47 * #GtkEntry to provide the completion functionality. It implements the 48 * #GtkCellLayout interface, to allow the user to add extra cells to the 49 * #GtkTreeView with completion matches. 50 * 51 * “Completion functionality” means that when the user modifies the text 52 * in the entry, #GtkEntryCompletion checks which rows in the model match 53 * the current content of the entry, and displays a list of matches. 54 * By default, the matching is done by comparing the entry text 55 * case-insensitively against the text column of the model (see 56 * gtk_entry_completion_set_text_column()), but this can be overridden 57 * with a custom match function (see gtk_entry_completion_set_match_func()). 58 * 59 * When the user selects a completion, the content of the entry is 60 * updated. By default, the content of the entry is replaced by the 61 * text column of the model, but this can be overridden by connecting 62 * to the #GtkEntryCompletion::match-selected signal and updating the 63 * entry in the signal handler. Note that you should return %TRUE from 64 * the signal handler to suppress the default behaviour. 65 * 66 * To add completion functionality to an entry, use gtk_entry_set_completion(). 67 * 68 * In addition to regular completion matches, which will be inserted into the 69 * entry when they are selected, #GtkEntryCompletion also allows to display 70 * “actions” in the popup window. Their appearance is similar to menuitems, 71 * to differentiate them clearly from completion strings. When an action is 72 * selected, the #GtkEntryCompletion::action-activated signal is emitted. 73 * 74 * GtkEntryCompletion uses a #GtkTreeModelFilter model to represent the 75 * subset of the entire model that is currently matching. While the 76 * GtkEntryCompletion signals #GtkEntryCompletion::match-selected and 77 * #GtkEntryCompletion::cursor-on-match take the original model and an 78 * iter pointing to that model as arguments, other callbacks and signals 79 * (such as #GtkCellLayoutDataFuncs or #GtkCellArea::apply-attributes) 80 * will generally take the filter model as argument. As long as you are 81 * only calling gtk_tree_model_get(), this will make no difference to 82 * you. If for some reason, you need the original model, use 83 * gtk_tree_model_filter_get_model(). Don’t forget to use 84 * gtk_tree_model_filter_convert_iter_to_child_iter() to obtain a 85 * matching iter. 86 */ 87 public class EntryCompletion : ObjectG, BuildableIF, CellLayoutIF 88 { 89 /** the main Gtk struct */ 90 protected GtkEntryCompletion* gtkEntryCompletion; 91 92 /** Get the main Gtk struct */ 93 public GtkEntryCompletion* getEntryCompletionStruct() 94 { 95 return gtkEntryCompletion; 96 } 97 98 /** the main Gtk struct as a void* */ 99 protected override void* getStruct() 100 { 101 return cast(void*)gtkEntryCompletion; 102 } 103 104 protected override void setStruct(GObject* obj) 105 { 106 gtkEntryCompletion = cast(GtkEntryCompletion*)obj; 107 super.setStruct(obj); 108 } 109 110 /** 111 * Sets our main struct and passes it to the parent class. 112 */ 113 public this (GtkEntryCompletion* gtkEntryCompletion, bool ownedRef = false) 114 { 115 this.gtkEntryCompletion = gtkEntryCompletion; 116 super(cast(GObject*)gtkEntryCompletion, ownedRef); 117 } 118 119 // add the Buildable capabilities 120 mixin BuildableT!(GtkEntryCompletion); 121 122 // add the CellLayout capabilities 123 mixin CellLayoutT!(GtkEntryCompletion); 124 125 126 /** */ 127 public static GType getType() 128 { 129 return gtk_entry_completion_get_type(); 130 } 131 132 /** 133 * Creates a new #GtkEntryCompletion object. 134 * 135 * Returns: A newly created #GtkEntryCompletion object 136 * 137 * Since: 2.4 138 * 139 * Throws: ConstructionException GTK+ fails to create the object. 140 */ 141 public this() 142 { 143 auto p = gtk_entry_completion_new(); 144 145 if(p is null) 146 { 147 throw new ConstructionException("null returned by new"); 148 } 149 150 this(cast(GtkEntryCompletion*) p, true); 151 } 152 153 /** 154 * Creates a new #GtkEntryCompletion object using the 155 * specified @area to layout cells in the underlying 156 * #GtkTreeViewColumn for the drop-down menu. 157 * 158 * Params: 159 * area = the #GtkCellArea used to layout cells 160 * 161 * Returns: A newly created #GtkEntryCompletion object 162 * 163 * Since: 3.0 164 * 165 * Throws: ConstructionException GTK+ fails to create the object. 166 */ 167 public this(CellArea area) 168 { 169 auto p = gtk_entry_completion_new_with_area((area is null) ? null : area.getCellAreaStruct()); 170 171 if(p is null) 172 { 173 throw new ConstructionException("null returned by new_with_area"); 174 } 175 176 this(cast(GtkEntryCompletion*) p, true); 177 } 178 179 /** 180 * Requests a completion operation, or in other words a refiltering of the 181 * current list with completions, using the current key. The completion list 182 * view will be updated accordingly. 183 * 184 * Since: 2.4 185 */ 186 public void complete() 187 { 188 gtk_entry_completion_complete(gtkEntryCompletion); 189 } 190 191 /** 192 * Computes the common prefix that is shared by all rows in @completion 193 * that start with @key. If no row matches @key, %NULL will be returned. 194 * Note that a text column must have been set for this function to work, 195 * see gtk_entry_completion_set_text_column() for details. 196 * 197 * Params: 198 * key = The text to complete for 199 * 200 * Returns: The common prefix all rows starting with 201 * @key or %NULL if no row matches @key. 202 * 203 * Since: 3.4 204 */ 205 public string computePrefix(string key) 206 { 207 auto retStr = gtk_entry_completion_compute_prefix(gtkEntryCompletion, Str.toStringz(key)); 208 209 scope(exit) Str.freeString(retStr); 210 return Str.toString(retStr); 211 } 212 213 /** 214 * Deletes the action at @index_ from @completion’s action list. 215 * 216 * Note that @index_ is a relative position and the position of an 217 * action may have changed since it was inserted. 218 * 219 * Params: 220 * index = the index of the item to delete 221 * 222 * Since: 2.4 223 */ 224 public void deleteAction(int index) 225 { 226 gtk_entry_completion_delete_action(gtkEntryCompletion, index); 227 } 228 229 /** 230 * Get the original text entered by the user that triggered 231 * the completion or %NULL if there’s no completion ongoing. 232 * 233 * Returns: the prefix for the current completion 234 * 235 * Since: 2.12 236 */ 237 public string getCompletionPrefix() 238 { 239 return Str.toString(gtk_entry_completion_get_completion_prefix(gtkEntryCompletion)); 240 } 241 242 /** 243 * Gets the entry @completion has been attached to. 244 * 245 * Returns: The entry @completion has been attached to 246 * 247 * Since: 2.4 248 */ 249 public Widget getEntry() 250 { 251 auto p = gtk_entry_completion_get_entry(gtkEntryCompletion); 252 253 if(p is null) 254 { 255 return null; 256 } 257 258 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 259 } 260 261 /** 262 * Returns whether the common prefix of the possible completions should 263 * be automatically inserted in the entry. 264 * 265 * Returns: %TRUE if inline completion is turned on 266 * 267 * Since: 2.6 268 */ 269 public bool getInlineCompletion() 270 { 271 return gtk_entry_completion_get_inline_completion(gtkEntryCompletion) != 0; 272 } 273 274 /** 275 * Returns %TRUE if inline-selection mode is turned on. 276 * 277 * Returns: %TRUE if inline-selection mode is on 278 * 279 * Since: 2.12 280 */ 281 public bool getInlineSelection() 282 { 283 return gtk_entry_completion_get_inline_selection(gtkEntryCompletion) != 0; 284 } 285 286 /** 287 * Returns the minimum key length as set for @completion. 288 * 289 * Returns: The currently used minimum key length 290 * 291 * Since: 2.4 292 */ 293 public int getMinimumKeyLength() 294 { 295 return gtk_entry_completion_get_minimum_key_length(gtkEntryCompletion); 296 } 297 298 /** 299 * Returns the model the #GtkEntryCompletion is using as data source. 300 * Returns %NULL if the model is unset. 301 * 302 * Returns: A #GtkTreeModel, or %NULL if none 303 * is currently being used 304 * 305 * Since: 2.4 306 */ 307 public TreeModelIF getModel() 308 { 309 auto p = gtk_entry_completion_get_model(gtkEntryCompletion); 310 311 if(p is null) 312 { 313 return null; 314 } 315 316 return ObjectG.getDObject!(TreeModel, TreeModelIF)(cast(GtkTreeModel*) p); 317 } 318 319 /** 320 * Returns whether the completions should be presented in a popup window. 321 * 322 * Returns: %TRUE if popup completion is turned on 323 * 324 * Since: 2.6 325 */ 326 public bool getPopupCompletion() 327 { 328 return gtk_entry_completion_get_popup_completion(gtkEntryCompletion) != 0; 329 } 330 331 /** 332 * Returns whether the completion popup window will be resized to the 333 * width of the entry. 334 * 335 * Returns: %TRUE if the popup window will be resized to the width of 336 * the entry 337 * 338 * Since: 2.8 339 */ 340 public bool getPopupSetWidth() 341 { 342 return gtk_entry_completion_get_popup_set_width(gtkEntryCompletion) != 0; 343 } 344 345 /** 346 * Returns whether the completion popup window will appear even if there is 347 * only a single match. 348 * 349 * Returns: %TRUE if the popup window will appear regardless of the 350 * number of matches 351 * 352 * Since: 2.8 353 */ 354 public bool getPopupSingleMatch() 355 { 356 return gtk_entry_completion_get_popup_single_match(gtkEntryCompletion) != 0; 357 } 358 359 /** 360 * Returns the column in the model of @completion to get strings from. 361 * 362 * Returns: the column containing the strings 363 * 364 * Since: 2.6 365 */ 366 public int getTextColumn() 367 { 368 return gtk_entry_completion_get_text_column(gtkEntryCompletion); 369 } 370 371 /** 372 * Inserts an action in @completion’s action item list at position @index_ 373 * with markup @markup. 374 * 375 * Params: 376 * index = the index of the item to insert 377 * markup = markup of the item to insert 378 * 379 * Since: 2.4 380 */ 381 public void insertActionMarkup(int index, string markup) 382 { 383 gtk_entry_completion_insert_action_markup(gtkEntryCompletion, index, Str.toStringz(markup)); 384 } 385 386 /** 387 * Inserts an action in @completion’s action item list at position @index_ 388 * with text @text. If you want the action item to have markup, use 389 * gtk_entry_completion_insert_action_markup(). 390 * 391 * Note that @index_ is a relative position in the list of actions and 392 * the position of an action can change when deleting a different action. 393 * 394 * Params: 395 * index = the index of the item to insert 396 * text = text of the item to insert 397 * 398 * Since: 2.4 399 */ 400 public void insertActionText(int index, string text) 401 { 402 gtk_entry_completion_insert_action_text(gtkEntryCompletion, index, Str.toStringz(text)); 403 } 404 405 /** 406 * Requests a prefix insertion. 407 * 408 * Since: 2.6 409 */ 410 public void insertPrefix() 411 { 412 gtk_entry_completion_insert_prefix(gtkEntryCompletion); 413 } 414 415 /** 416 * Sets whether the common prefix of the possible completions should 417 * be automatically inserted in the entry. 418 * 419 * Params: 420 * inlineCompletion = %TRUE to do inline completion 421 * 422 * Since: 2.6 423 */ 424 public void setInlineCompletion(bool inlineCompletion) 425 { 426 gtk_entry_completion_set_inline_completion(gtkEntryCompletion, inlineCompletion); 427 } 428 429 /** 430 * Sets whether it is possible to cycle through the possible completions 431 * inside the entry. 432 * 433 * Params: 434 * inlineSelection = %TRUE to do inline selection 435 * 436 * Since: 2.12 437 */ 438 public void setInlineSelection(bool inlineSelection) 439 { 440 gtk_entry_completion_set_inline_selection(gtkEntryCompletion, inlineSelection); 441 } 442 443 /** 444 * Sets the match function for @completion to be @func. The match function 445 * is used to determine if a row should or should not be in the completion 446 * list. 447 * 448 * Params: 449 * func = the #GtkEntryCompletionMatchFunc to use 450 * funcData = user data for @func 451 * funcNotify = destroy notify for @func_data. 452 * 453 * Since: 2.4 454 */ 455 public void setMatchFunc(GtkEntryCompletionMatchFunc func, void* funcData, GDestroyNotify funcNotify) 456 { 457 gtk_entry_completion_set_match_func(gtkEntryCompletion, func, funcData, funcNotify); 458 } 459 460 /** 461 * Requires the length of the search key for @completion to be at least 462 * @length. This is useful for long lists, where completing using a small 463 * key takes a lot of time and will come up with meaningless results anyway 464 * (ie, a too large dataset). 465 * 466 * Params: 467 * length = the minimum length of the key in order to start completing 468 * 469 * Since: 2.4 470 */ 471 public void setMinimumKeyLength(int length) 472 { 473 gtk_entry_completion_set_minimum_key_length(gtkEntryCompletion, length); 474 } 475 476 /** 477 * Sets the model for a #GtkEntryCompletion. If @completion already has 478 * a model set, it will remove it before setting the new model. 479 * If model is %NULL, then it will unset the model. 480 * 481 * Params: 482 * model = the #GtkTreeModel 483 * 484 * Since: 2.4 485 */ 486 public void setModel(TreeModelIF model) 487 { 488 gtk_entry_completion_set_model(gtkEntryCompletion, (model is null) ? null : model.getTreeModelStruct()); 489 } 490 491 /** 492 * Sets whether the completions should be presented in a popup window. 493 * 494 * Params: 495 * popupCompletion = %TRUE to do popup completion 496 * 497 * Since: 2.6 498 */ 499 public void setPopupCompletion(bool popupCompletion) 500 { 501 gtk_entry_completion_set_popup_completion(gtkEntryCompletion, popupCompletion); 502 } 503 504 /** 505 * Sets whether the completion popup window will be resized to be the same 506 * width as the entry. 507 * 508 * Params: 509 * popupSetWidth = %TRUE to make the width of the popup the same as the entry 510 * 511 * Since: 2.8 512 */ 513 public void setPopupSetWidth(bool popupSetWidth) 514 { 515 gtk_entry_completion_set_popup_set_width(gtkEntryCompletion, popupSetWidth); 516 } 517 518 /** 519 * Sets whether the completion popup window will appear even if there is 520 * only a single match. You may want to set this to %FALSE if you 521 * are using [inline completion][GtkEntryCompletion--inline-completion]. 522 * 523 * Params: 524 * popupSingleMatch = %TRUE if the popup should appear even for a single 525 * match 526 * 527 * Since: 2.8 528 */ 529 public void setPopupSingleMatch(bool popupSingleMatch) 530 { 531 gtk_entry_completion_set_popup_single_match(gtkEntryCompletion, popupSingleMatch); 532 } 533 534 /** 535 * Convenience function for setting up the most used case of this code: a 536 * completion list with just strings. This function will set up @completion 537 * to have a list displaying all (and just) strings in the completion list, 538 * and to get those strings from @column in the model of @completion. 539 * 540 * This functions creates and adds a #GtkCellRendererText for the selected 541 * column. If you need to set the text column, but don't want the cell 542 * renderer, use g_object_set() to set the #GtkEntryCompletion:text-column 543 * property directly. 544 * 545 * Params: 546 * column = the column in the model of @completion to get strings from 547 * 548 * Since: 2.4 549 */ 550 public void setTextColumn(int column) 551 { 552 gtk_entry_completion_set_text_column(gtkEntryCompletion, column); 553 } 554 555 protected class OnActionActivatedDelegateWrapper 556 { 557 static OnActionActivatedDelegateWrapper[] listeners; 558 void delegate(int, EntryCompletion) dlg; 559 gulong handlerId; 560 561 this(void delegate(int, EntryCompletion) dlg) 562 { 563 this.dlg = dlg; 564 this.listeners ~= this; 565 } 566 567 void remove(OnActionActivatedDelegateWrapper source) 568 { 569 foreach(index, wrapper; listeners) 570 { 571 if (wrapper.handlerId == source.handlerId) 572 { 573 listeners[index] = null; 574 listeners = std.algorithm.remove(listeners, index); 575 break; 576 } 577 } 578 } 579 } 580 581 /** 582 * Gets emitted when an action is activated. 583 * 584 * Params: 585 * index = the index of the activated action 586 * 587 * Since: 2.4 588 */ 589 gulong addOnActionActivated(void delegate(int, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 590 { 591 auto wrapper = new OnActionActivatedDelegateWrapper(dlg); 592 wrapper.handlerId = Signals.connectData( 593 this, 594 "action-activated", 595 cast(GCallback)&callBackActionActivated, 596 cast(void*)wrapper, 597 cast(GClosureNotify)&callBackActionActivatedDestroy, 598 connectFlags); 599 return wrapper.handlerId; 600 } 601 602 extern(C) static void callBackActionActivated(GtkEntryCompletion* entrycompletionStruct, int index, OnActionActivatedDelegateWrapper wrapper) 603 { 604 wrapper.dlg(index, wrapper.outer); 605 } 606 607 extern(C) static void callBackActionActivatedDestroy(OnActionActivatedDelegateWrapper wrapper, GClosure* closure) 608 { 609 wrapper.remove(wrapper); 610 } 611 612 protected class OnCursorOnMatchDelegateWrapper 613 { 614 static OnCursorOnMatchDelegateWrapper[] listeners; 615 bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg; 616 gulong handlerId; 617 618 this(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg) 619 { 620 this.dlg = dlg; 621 this.listeners ~= this; 622 } 623 624 void remove(OnCursorOnMatchDelegateWrapper source) 625 { 626 foreach(index, wrapper; listeners) 627 { 628 if (wrapper.handlerId == source.handlerId) 629 { 630 listeners[index] = null; 631 listeners = std.algorithm.remove(listeners, index); 632 break; 633 } 634 } 635 } 636 } 637 638 /** 639 * Gets emitted when a match from the cursor is on a match 640 * of the list. The default behaviour is to replace the contents 641 * of the entry with the contents of the text column in the row 642 * pointed to by @iter. 643 * 644 * Note that @model is the model that was passed to 645 * gtk_entry_completion_set_model(). 646 * 647 * Params: 648 * model = the #GtkTreeModel containing the matches 649 * iter = a #GtkTreeIter positioned at the selected match 650 * 651 * Returns: %TRUE if the signal has been handled 652 * 653 * Since: 2.12 654 */ 655 gulong addOnCursorOnMatch(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 656 { 657 auto wrapper = new OnCursorOnMatchDelegateWrapper(dlg); 658 wrapper.handlerId = Signals.connectData( 659 this, 660 "cursor-on-match", 661 cast(GCallback)&callBackCursorOnMatch, 662 cast(void*)wrapper, 663 cast(GClosureNotify)&callBackCursorOnMatchDestroy, 664 connectFlags); 665 return wrapper.handlerId; 666 } 667 668 extern(C) static int callBackCursorOnMatch(GtkEntryCompletion* entrycompletionStruct, GtkTreeModel* model, GtkTreeIter* iter, OnCursorOnMatchDelegateWrapper wrapper) 669 { 670 return wrapper.dlg(ObjectG.getDObject!(TreeModel, TreeModelIF)(model), ObjectG.getDObject!(TreeIter)(iter), wrapper.outer); 671 } 672 673 extern(C) static void callBackCursorOnMatchDestroy(OnCursorOnMatchDelegateWrapper wrapper, GClosure* closure) 674 { 675 wrapper.remove(wrapper); 676 } 677 678 protected class OnInsertPrefixDelegateWrapper 679 { 680 static OnInsertPrefixDelegateWrapper[] listeners; 681 bool delegate(string, EntryCompletion) dlg; 682 gulong handlerId; 683 684 this(bool delegate(string, EntryCompletion) dlg) 685 { 686 this.dlg = dlg; 687 this.listeners ~= this; 688 } 689 690 void remove(OnInsertPrefixDelegateWrapper source) 691 { 692 foreach(index, wrapper; listeners) 693 { 694 if (wrapper.handlerId == source.handlerId) 695 { 696 listeners[index] = null; 697 listeners = std.algorithm.remove(listeners, index); 698 break; 699 } 700 } 701 } 702 } 703 704 /** 705 * Gets emitted when the inline autocompletion is triggered. 706 * The default behaviour is to make the entry display the 707 * whole prefix and select the newly inserted part. 708 * 709 * Applications may connect to this signal in order to insert only a 710 * smaller part of the @prefix into the entry - e.g. the entry used in 711 * the #GtkFileChooser inserts only the part of the prefix up to the 712 * next '/'. 713 * 714 * Params: 715 * prefix = the common prefix of all possible completions 716 * 717 * Returns: %TRUE if the signal has been handled 718 * 719 * Since: 2.6 720 */ 721 gulong addOnInsertPrefix(bool delegate(string, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 722 { 723 auto wrapper = new OnInsertPrefixDelegateWrapper(dlg); 724 wrapper.handlerId = Signals.connectData( 725 this, 726 "insert-prefix", 727 cast(GCallback)&callBackInsertPrefix, 728 cast(void*)wrapper, 729 cast(GClosureNotify)&callBackInsertPrefixDestroy, 730 connectFlags); 731 return wrapper.handlerId; 732 } 733 734 extern(C) static int callBackInsertPrefix(GtkEntryCompletion* entrycompletionStruct, char* prefix, OnInsertPrefixDelegateWrapper wrapper) 735 { 736 return wrapper.dlg(Str.toString(prefix), wrapper.outer); 737 } 738 739 extern(C) static void callBackInsertPrefixDestroy(OnInsertPrefixDelegateWrapper wrapper, GClosure* closure) 740 { 741 wrapper.remove(wrapper); 742 } 743 744 protected class OnMatchSelectedDelegateWrapper 745 { 746 static OnMatchSelectedDelegateWrapper[] listeners; 747 bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg; 748 gulong handlerId; 749 750 this(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg) 751 { 752 this.dlg = dlg; 753 this.listeners ~= this; 754 } 755 756 void remove(OnMatchSelectedDelegateWrapper source) 757 { 758 foreach(index, wrapper; listeners) 759 { 760 if (wrapper.handlerId == source.handlerId) 761 { 762 listeners[index] = null; 763 listeners = std.algorithm.remove(listeners, index); 764 break; 765 } 766 } 767 } 768 } 769 770 /** 771 * Gets emitted when a match from the list is selected. 772 * The default behaviour is to replace the contents of the 773 * entry with the contents of the text column in the row 774 * pointed to by @iter. 775 * 776 * Note that @model is the model that was passed to 777 * gtk_entry_completion_set_model(). 778 * 779 * Params: 780 * model = the #GtkTreeModel containing the matches 781 * iter = a #GtkTreeIter positioned at the selected match 782 * 783 * Returns: %TRUE if the signal has been handled 784 * 785 * Since: 2.4 786 */ 787 gulong addOnMatchSelected(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 788 { 789 auto wrapper = new OnMatchSelectedDelegateWrapper(dlg); 790 wrapper.handlerId = Signals.connectData( 791 this, 792 "match-selected", 793 cast(GCallback)&callBackMatchSelected, 794 cast(void*)wrapper, 795 cast(GClosureNotify)&callBackMatchSelectedDestroy, 796 connectFlags); 797 return wrapper.handlerId; 798 } 799 800 extern(C) static int callBackMatchSelected(GtkEntryCompletion* entrycompletionStruct, GtkTreeModel* model, GtkTreeIter* iter, OnMatchSelectedDelegateWrapper wrapper) 801 { 802 return wrapper.dlg(ObjectG.getDObject!(TreeModel, TreeModelIF)(model), ObjectG.getDObject!(TreeIter)(iter), wrapper.outer); 803 } 804 805 extern(C) static void callBackMatchSelectedDestroy(OnMatchSelectedDelegateWrapper wrapper, GClosure* closure) 806 { 807 wrapper.remove(wrapper); 808 } 809 810 protected class OnNoMatchesDelegateWrapper 811 { 812 static OnNoMatchesDelegateWrapper[] listeners; 813 void delegate(EntryCompletion) dlg; 814 gulong handlerId; 815 816 this(void delegate(EntryCompletion) dlg) 817 { 818 this.dlg = dlg; 819 this.listeners ~= this; 820 } 821 822 void remove(OnNoMatchesDelegateWrapper source) 823 { 824 foreach(index, wrapper; listeners) 825 { 826 if (wrapper.handlerId == source.handlerId) 827 { 828 listeners[index] = null; 829 listeners = std.algorithm.remove(listeners, index); 830 break; 831 } 832 } 833 } 834 } 835 836 /** 837 * Gets emitted when the filter model has zero 838 * number of rows in completion_complete method. 839 * (In other words when GtkEntryCompletion is out of 840 * suggestions) 841 * 842 * Since: 3.14 843 */ 844 gulong addOnNoMatches(void delegate(EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 845 { 846 auto wrapper = new OnNoMatchesDelegateWrapper(dlg); 847 wrapper.handlerId = Signals.connectData( 848 this, 849 "no-matches", 850 cast(GCallback)&callBackNoMatches, 851 cast(void*)wrapper, 852 cast(GClosureNotify)&callBackNoMatchesDestroy, 853 connectFlags); 854 return wrapper.handlerId; 855 } 856 857 extern(C) static void callBackNoMatches(GtkEntryCompletion* entrycompletionStruct, OnNoMatchesDelegateWrapper wrapper) 858 { 859 wrapper.dlg(wrapper.outer); 860 } 861 862 extern(C) static void callBackNoMatchesDestroy(OnNoMatchesDelegateWrapper wrapper, GClosure* closure) 863 { 864 wrapper.remove(wrapper); 865 } 866 }