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 public import gtkc.gdktypes; 41 private import gtkc.gtk; 42 public import gtkc.gtktypes; 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 * Return: 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 * Return: 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 * Return: 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 * Return: 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 * Return: 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 * Return: %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 * Return: %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 * Return: 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 * Return: 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 * Return: %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 * Return: %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 * Return: %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 * Return: 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 int[string] connectedSignals; 556 557 void delegate(int, EntryCompletion)[] onActionActivatedListeners; 558 /** 559 * Gets emitted when an action is activated. 560 * 561 * Params: 562 * index = the index of the activated action 563 * 564 * Since: 2.4 565 */ 566 void addOnActionActivated(void delegate(int, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 567 { 568 if ( "action-activated" !in connectedSignals ) 569 { 570 Signals.connectData( 571 this, 572 "action-activated", 573 cast(GCallback)&callBackActionActivated, 574 cast(void*)this, 575 null, 576 connectFlags); 577 connectedSignals["action-activated"] = 1; 578 } 579 onActionActivatedListeners ~= dlg; 580 } 581 extern(C) static void callBackActionActivated(GtkEntryCompletion* entrycompletionStruct, int index, EntryCompletion _entrycompletion) 582 { 583 foreach ( void delegate(int, EntryCompletion) dlg; _entrycompletion.onActionActivatedListeners ) 584 { 585 dlg(index, _entrycompletion); 586 } 587 } 588 589 bool delegate(TreeModelIF, TreeIter, EntryCompletion)[] onCursorOnMatchListeners; 590 /** 591 * Gets emitted when a match from the cursor is on a match 592 * of the list. The default behaviour is to replace the contents 593 * of the entry with the contents of the text column in the row 594 * pointed to by @iter. 595 * 596 * Note that @model is the model that was passed to 597 * gtk_entry_completion_set_model(). 598 * 599 * Params: 600 * model = the #GtkTreeModel containing the matches 601 * iter = a #GtkTreeIter positioned at the selected match 602 * 603 * Return: %TRUE if the signal has been handled 604 * 605 * Since: 2.12 606 */ 607 void addOnCursorOnMatch(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 608 { 609 if ( "cursor-on-match" !in connectedSignals ) 610 { 611 Signals.connectData( 612 this, 613 "cursor-on-match", 614 cast(GCallback)&callBackCursorOnMatch, 615 cast(void*)this, 616 null, 617 connectFlags); 618 connectedSignals["cursor-on-match"] = 1; 619 } 620 onCursorOnMatchListeners ~= dlg; 621 } 622 extern(C) static int callBackCursorOnMatch(GtkEntryCompletion* entrycompletionStruct, GtkTreeModel* model, GtkTreeIter* iter, EntryCompletion _entrycompletion) 623 { 624 foreach ( bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg; _entrycompletion.onCursorOnMatchListeners ) 625 { 626 if ( dlg(ObjectG.getDObject!(TreeModel, TreeModelIF)(model), ObjectG.getDObject!(TreeIter)(iter), _entrycompletion) ) 627 { 628 return 1; 629 } 630 } 631 632 return 0; 633 } 634 635 bool delegate(string, EntryCompletion)[] onInsertPrefixListeners; 636 /** 637 * Gets emitted when the inline autocompletion is triggered. 638 * The default behaviour is to make the entry display the 639 * whole prefix and select the newly inserted part. 640 * 641 * Applications may connect to this signal in order to insert only a 642 * smaller part of the @prefix into the entry - e.g. the entry used in 643 * the #GtkFileChooser inserts only the part of the prefix up to the 644 * next '/'. 645 * 646 * Params: 647 * prefix = the common prefix of all possible completions 648 * 649 * Return: %TRUE if the signal has been handled 650 * 651 * Since: 2.6 652 */ 653 void addOnInsertPrefix(bool delegate(string, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 654 { 655 if ( "insert-prefix" !in connectedSignals ) 656 { 657 Signals.connectData( 658 this, 659 "insert-prefix", 660 cast(GCallback)&callBackInsertPrefix, 661 cast(void*)this, 662 null, 663 connectFlags); 664 connectedSignals["insert-prefix"] = 1; 665 } 666 onInsertPrefixListeners ~= dlg; 667 } 668 extern(C) static int callBackInsertPrefix(GtkEntryCompletion* entrycompletionStruct, char* prefix, EntryCompletion _entrycompletion) 669 { 670 foreach ( bool delegate(string, EntryCompletion) dlg; _entrycompletion.onInsertPrefixListeners ) 671 { 672 if ( dlg(Str.toString(prefix), _entrycompletion) ) 673 { 674 return 1; 675 } 676 } 677 678 return 0; 679 } 680 681 bool delegate(TreeModelIF, TreeIter, EntryCompletion)[] onMatchSelectedListeners; 682 /** 683 * Gets emitted when a match from the list is selected. 684 * The default behaviour is to replace the contents of the 685 * entry with the contents of the text column in the row 686 * pointed to by @iter. 687 * 688 * Note that @model is the model that was passed to 689 * gtk_entry_completion_set_model(). 690 * 691 * Params: 692 * model = the #GtkTreeModel containing the matches 693 * iter = a #GtkTreeIter positioned at the selected match 694 * 695 * Return: %TRUE if the signal has been handled 696 * 697 * Since: 2.4 698 */ 699 void addOnMatchSelected(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 700 { 701 if ( "match-selected" !in connectedSignals ) 702 { 703 Signals.connectData( 704 this, 705 "match-selected", 706 cast(GCallback)&callBackMatchSelected, 707 cast(void*)this, 708 null, 709 connectFlags); 710 connectedSignals["match-selected"] = 1; 711 } 712 onMatchSelectedListeners ~= dlg; 713 } 714 extern(C) static int callBackMatchSelected(GtkEntryCompletion* entrycompletionStruct, GtkTreeModel* model, GtkTreeIter* iter, EntryCompletion _entrycompletion) 715 { 716 foreach ( bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg; _entrycompletion.onMatchSelectedListeners ) 717 { 718 if ( dlg(ObjectG.getDObject!(TreeModel, TreeModelIF)(model), ObjectG.getDObject!(TreeIter)(iter), _entrycompletion) ) 719 { 720 return 1; 721 } 722 } 723 724 return 0; 725 } 726 727 void delegate(EntryCompletion)[] onNoMatchesListeners; 728 /** 729 * Gets emitted when the filter model has zero 730 * number of rows in completion_complete method. 731 * (In other words when GtkEntryCompletion is out of 732 * suggestions) 733 * 734 * Since: 3.14 735 */ 736 void addOnNoMatches(void delegate(EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 737 { 738 if ( "no-matches" !in connectedSignals ) 739 { 740 Signals.connectData( 741 this, 742 "no-matches", 743 cast(GCallback)&callBackNoMatches, 744 cast(void*)this, 745 null, 746 connectFlags); 747 connectedSignals["no-matches"] = 1; 748 } 749 onNoMatchesListeners ~= dlg; 750 } 751 extern(C) static void callBackNoMatches(GtkEntryCompletion* entrycompletionStruct, EntryCompletion _entrycompletion) 752 { 753 foreach ( void delegate(EntryCompletion) dlg; _entrycompletion.onNoMatchesListeners ) 754 { 755 dlg(_entrycompletion); 756 } 757 } 758 }