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 128 public static GType getType() 129 { 130 return gtk_entry_completion_get_type(); 131 } 132 133 /** 134 * Creates a new #GtkEntryCompletion object. 135 * 136 * Return: A newly created #GtkEntryCompletion object 137 * 138 * Since: 2.4 139 * 140 * Throws: ConstructionException GTK+ fails to create the object. 141 */ 142 public this() 143 { 144 auto p = gtk_entry_completion_new(); 145 146 if(p is null) 147 { 148 throw new ConstructionException("null returned by new"); 149 } 150 151 this(cast(GtkEntryCompletion*) p, true); 152 } 153 154 /** 155 * Creates a new #GtkEntryCompletion object using the 156 * specified @area to layout cells in the underlying 157 * #GtkTreeViewColumn for the drop-down menu. 158 * 159 * Params: 160 * area = the #GtkCellArea used to layout cells 161 * 162 * Return: A newly created #GtkEntryCompletion object 163 * 164 * Since: 3.0 165 * 166 * Throws: ConstructionException GTK+ fails to create the object. 167 */ 168 public this(CellArea area) 169 { 170 auto p = gtk_entry_completion_new_with_area((area is null) ? null : area.getCellAreaStruct()); 171 172 if(p is null) 173 { 174 throw new ConstructionException("null returned by new_with_area"); 175 } 176 177 this(cast(GtkEntryCompletion*) p, true); 178 } 179 180 /** 181 * Requests a completion operation, or in other words a refiltering of the 182 * current list with completions, using the current key. The completion list 183 * view will be updated accordingly. 184 * 185 * Since: 2.4 186 */ 187 public void complete() 188 { 189 gtk_entry_completion_complete(gtkEntryCompletion); 190 } 191 192 /** 193 * Computes the common prefix that is shared by all rows in @completion 194 * that start with @key. If no row matches @key, %NULL will be returned. 195 * Note that a text column must have been set for this function to work, 196 * see gtk_entry_completion_set_text_column() for details. 197 * 198 * Params: 199 * key = The text to complete for 200 * 201 * Return: The common prefix all rows starting with @key 202 * or %NULL if no row matches @key. 203 * 204 * Since: 3.4 205 */ 206 public string computePrefix(string key) 207 { 208 return Str.toString(gtk_entry_completion_compute_prefix(gtkEntryCompletion, Str.toStringz(key))); 209 } 210 211 /** 212 * Deletes the action at @index_ from @completion’s action list. 213 * 214 * Note that @index_ is a relative position and the position of an 215 * action may have changed since it was inserted. 216 * 217 * Params: 218 * index = the index of the item to delete 219 * 220 * Since: 2.4 221 */ 222 public void deleteAction(int index) 223 { 224 gtk_entry_completion_delete_action(gtkEntryCompletion, index); 225 } 226 227 /** 228 * Get the original text entered by the user that triggered 229 * the completion or %NULL if there’s no completion ongoing. 230 * 231 * Return: the prefix for the current completion 232 * 233 * Since: 2.12 234 */ 235 public string getCompletionPrefix() 236 { 237 return Str.toString(gtk_entry_completion_get_completion_prefix(gtkEntryCompletion)); 238 } 239 240 /** 241 * Gets the entry @completion has been attached to. 242 * 243 * Return: The entry @completion has been attached to 244 * 245 * Since: 2.4 246 */ 247 public Widget getEntry() 248 { 249 auto p = gtk_entry_completion_get_entry(gtkEntryCompletion); 250 251 if(p is null) 252 { 253 return null; 254 } 255 256 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 257 } 258 259 /** 260 * Returns whether the common prefix of the possible completions should 261 * be automatically inserted in the entry. 262 * 263 * Return: %TRUE if inline completion is turned on 264 * 265 * Since: 2.6 266 */ 267 public bool getInlineCompletion() 268 { 269 return gtk_entry_completion_get_inline_completion(gtkEntryCompletion) != 0; 270 } 271 272 /** 273 * Returns %TRUE if inline-selection mode is turned on. 274 * 275 * Return: %TRUE if inline-selection mode is on 276 * 277 * Since: 2.12 278 */ 279 public bool getInlineSelection() 280 { 281 return gtk_entry_completion_get_inline_selection(gtkEntryCompletion) != 0; 282 } 283 284 /** 285 * Returns the minimum key length as set for @completion. 286 * 287 * Return: The currently used minimum key length 288 * 289 * Since: 2.4 290 */ 291 public int getMinimumKeyLength() 292 { 293 return gtk_entry_completion_get_minimum_key_length(gtkEntryCompletion); 294 } 295 296 /** 297 * Returns the model the #GtkEntryCompletion is using as data source. 298 * Returns %NULL if the model is unset. 299 * 300 * Return: A #GtkTreeModel, or %NULL if none 301 * is currently being used 302 * 303 * Since: 2.4 304 */ 305 public TreeModelIF getModel() 306 { 307 auto p = gtk_entry_completion_get_model(gtkEntryCompletion); 308 309 if(p is null) 310 { 311 return null; 312 } 313 314 return ObjectG.getDObject!(TreeModel, TreeModelIF)(cast(GtkTreeModel*) p); 315 } 316 317 /** 318 * Returns whether the completions should be presented in a popup window. 319 * 320 * Return: %TRUE if popup completion is turned on 321 * 322 * Since: 2.6 323 */ 324 public bool getPopupCompletion() 325 { 326 return gtk_entry_completion_get_popup_completion(gtkEntryCompletion) != 0; 327 } 328 329 /** 330 * Returns whether the completion popup window will be resized to the 331 * width of the entry. 332 * 333 * Return: %TRUE if the popup window will be resized to the width of 334 * the entry 335 * 336 * Since: 2.8 337 */ 338 public bool getPopupSetWidth() 339 { 340 return gtk_entry_completion_get_popup_set_width(gtkEntryCompletion) != 0; 341 } 342 343 /** 344 * Returns whether the completion popup window will appear even if there is 345 * only a single match. 346 * 347 * Return: %TRUE if the popup window will appear regardless of the 348 * number of matches 349 * 350 * Since: 2.8 351 */ 352 public bool getPopupSingleMatch() 353 { 354 return gtk_entry_completion_get_popup_single_match(gtkEntryCompletion) != 0; 355 } 356 357 /** 358 * Returns the column in the model of @completion to get strings from. 359 * 360 * Return: the column containing the strings 361 * 362 * Since: 2.6 363 */ 364 public int getTextColumn() 365 { 366 return gtk_entry_completion_get_text_column(gtkEntryCompletion); 367 } 368 369 /** 370 * Inserts an action in @completion’s action item list at position @index_ 371 * with markup @markup. 372 * 373 * Params: 374 * index = the index of the item to insert 375 * markup = markup of the item to insert 376 * 377 * Since: 2.4 378 */ 379 public void insertActionMarkup(int index, string markup) 380 { 381 gtk_entry_completion_insert_action_markup(gtkEntryCompletion, index, Str.toStringz(markup)); 382 } 383 384 /** 385 * Inserts an action in @completion’s action item list at position @index_ 386 * with text @text. If you want the action item to have markup, use 387 * gtk_entry_completion_insert_action_markup(). 388 * 389 * Note that @index_ is a relative position in the list of actions and 390 * the position of an action can change when deleting a different action. 391 * 392 * Params: 393 * index = the index of the item to insert 394 * text = text of the item to insert 395 * 396 * Since: 2.4 397 */ 398 public void insertActionText(int index, string text) 399 { 400 gtk_entry_completion_insert_action_text(gtkEntryCompletion, index, Str.toStringz(text)); 401 } 402 403 /** 404 * Requests a prefix insertion. 405 * 406 * Since: 2.6 407 */ 408 public void insertPrefix() 409 { 410 gtk_entry_completion_insert_prefix(gtkEntryCompletion); 411 } 412 413 /** 414 * Sets whether the common prefix of the possible completions should 415 * be automatically inserted in the entry. 416 * 417 * Params: 418 * inlineCompletion = %TRUE to do inline completion 419 * 420 * Since: 2.6 421 */ 422 public void setInlineCompletion(bool inlineCompletion) 423 { 424 gtk_entry_completion_set_inline_completion(gtkEntryCompletion, inlineCompletion); 425 } 426 427 /** 428 * Sets whether it is possible to cycle through the possible completions 429 * inside the entry. 430 * 431 * Params: 432 * inlineSelection = %TRUE to do inline selection 433 * 434 * Since: 2.12 435 */ 436 public void setInlineSelection(bool inlineSelection) 437 { 438 gtk_entry_completion_set_inline_selection(gtkEntryCompletion, inlineSelection); 439 } 440 441 /** 442 * Sets the match function for @completion to be @func. The match function 443 * is used to determine if a row should or should not be in the completion 444 * list. 445 * 446 * Params: 447 * func = the #GtkEntryCompletionMatchFunc to use 448 * funcData = user data for @func 449 * funcNotify = destroy notify for @func_data. 450 * 451 * Since: 2.4 452 */ 453 public void setMatchFunc(GtkEntryCompletionMatchFunc func, void* funcData, GDestroyNotify funcNotify) 454 { 455 gtk_entry_completion_set_match_func(gtkEntryCompletion, func, funcData, funcNotify); 456 } 457 458 /** 459 * Requires the length of the search key for @completion to be at least 460 * @length. This is useful for long lists, where completing using a small 461 * key takes a lot of time and will come up with meaningless results anyway 462 * (ie, a too large dataset). 463 * 464 * Params: 465 * length = the minimum length of the key in order to start completing 466 * 467 * Since: 2.4 468 */ 469 public void setMinimumKeyLength(int length) 470 { 471 gtk_entry_completion_set_minimum_key_length(gtkEntryCompletion, length); 472 } 473 474 /** 475 * Sets the model for a #GtkEntryCompletion. If @completion already has 476 * a model set, it will remove it before setting the new model. 477 * If model is %NULL, then it will unset the model. 478 * 479 * Params: 480 * model = the #GtkTreeModel 481 * 482 * Since: 2.4 483 */ 484 public void setModel(TreeModelIF model) 485 { 486 gtk_entry_completion_set_model(gtkEntryCompletion, (model is null) ? null : model.getTreeModelStruct()); 487 } 488 489 /** 490 * Sets whether the completions should be presented in a popup window. 491 * 492 * Params: 493 * popupCompletion = %TRUE to do popup completion 494 * 495 * Since: 2.6 496 */ 497 public void setPopupCompletion(bool popupCompletion) 498 { 499 gtk_entry_completion_set_popup_completion(gtkEntryCompletion, popupCompletion); 500 } 501 502 /** 503 * Sets whether the completion popup window will be resized to be the same 504 * width as the entry. 505 * 506 * Params: 507 * popupSetWidth = %TRUE to make the width of the popup the same as the entry 508 * 509 * Since: 2.8 510 */ 511 public void setPopupSetWidth(bool popupSetWidth) 512 { 513 gtk_entry_completion_set_popup_set_width(gtkEntryCompletion, popupSetWidth); 514 } 515 516 /** 517 * Sets whether the completion popup window will appear even if there is 518 * only a single match. You may want to set this to %FALSE if you 519 * are using [inline completion][GtkEntryCompletion--inline-completion]. 520 * 521 * Params: 522 * popupSingleMatch = %TRUE if the popup should appear even for a single 523 * match 524 * 525 * Since: 2.8 526 */ 527 public void setPopupSingleMatch(bool popupSingleMatch) 528 { 529 gtk_entry_completion_set_popup_single_match(gtkEntryCompletion, popupSingleMatch); 530 } 531 532 /** 533 * Convenience function for setting up the most used case of this code: a 534 * completion list with just strings. This function will set up @completion 535 * to have a list displaying all (and just) strings in the completion list, 536 * and to get those strings from @column in the model of @completion. 537 * 538 * This functions creates and adds a #GtkCellRendererText for the selected 539 * column. If you need to set the text column, but don't want the cell 540 * renderer, use g_object_set() to set the #GtkEntryCompletion:text-column 541 * property directly. 542 * 543 * Params: 544 * column = the column in the model of @completion to get strings from 545 * 546 * Since: 2.4 547 */ 548 public void setTextColumn(int column) 549 { 550 gtk_entry_completion_set_text_column(gtkEntryCompletion, column); 551 } 552 553 int[string] connectedSignals; 554 555 void delegate(int, EntryCompletion)[] onActionActivatedListeners; 556 /** 557 * Gets emitted when an action is activated. 558 * 559 * Params: 560 * index = the index of the activated action 561 * 562 * Since: 2.4 563 */ 564 void addOnActionActivated(void delegate(int, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 565 { 566 if ( "action-activated" !in connectedSignals ) 567 { 568 Signals.connectData( 569 this, 570 "action-activated", 571 cast(GCallback)&callBackActionActivated, 572 cast(void*)this, 573 null, 574 connectFlags); 575 connectedSignals["action-activated"] = 1; 576 } 577 onActionActivatedListeners ~= dlg; 578 } 579 extern(C) static void callBackActionActivated(GtkEntryCompletion* entrycompletionStruct, int index, EntryCompletion _entrycompletion) 580 { 581 foreach ( void delegate(int, EntryCompletion) dlg; _entrycompletion.onActionActivatedListeners ) 582 { 583 dlg(index, _entrycompletion); 584 } 585 } 586 587 bool delegate(TreeModelIF, TreeIter, EntryCompletion)[] onCursorOnMatchListeners; 588 /** 589 * Gets emitted when a match from the cursor is on a match 590 * of the list. The default behaviour is to replace the contents 591 * of the entry with the contents of the text column in the row 592 * pointed to by @iter. 593 * 594 * Note that @model is the model that was passed to 595 * gtk_entry_completion_set_model(). 596 * 597 * Params: 598 * model = the #GtkTreeModel containing the matches 599 * iter = a #GtkTreeIter positioned at the selected match 600 * 601 * Return: %TRUE if the signal has been handled 602 * 603 * Since: 2.12 604 */ 605 void addOnCursorOnMatch(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 606 { 607 if ( "cursor-on-match" !in connectedSignals ) 608 { 609 Signals.connectData( 610 this, 611 "cursor-on-match", 612 cast(GCallback)&callBackCursorOnMatch, 613 cast(void*)this, 614 null, 615 connectFlags); 616 connectedSignals["cursor-on-match"] = 1; 617 } 618 onCursorOnMatchListeners ~= dlg; 619 } 620 extern(C) static int callBackCursorOnMatch(GtkEntryCompletion* entrycompletionStruct, GtkTreeModel* model, GtkTreeIter* iter, EntryCompletion _entrycompletion) 621 { 622 foreach ( bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg; _entrycompletion.onCursorOnMatchListeners ) 623 { 624 if ( dlg(ObjectG.getDObject!(TreeModel, TreeModelIF)(model), ObjectG.getDObject!(TreeIter)(iter), _entrycompletion) ) 625 { 626 return 1; 627 } 628 } 629 630 return 0; 631 } 632 633 bool delegate(string, EntryCompletion)[] onInsertPrefixListeners; 634 /** 635 * Gets emitted when the inline autocompletion is triggered. 636 * The default behaviour is to make the entry display the 637 * whole prefix and select the newly inserted part. 638 * 639 * Applications may connect to this signal in order to insert only a 640 * smaller part of the @prefix into the entry - e.g. the entry used in 641 * the #GtkFileChooser inserts only the part of the prefix up to the 642 * next '/'. 643 * 644 * Params: 645 * prefix = the common prefix of all possible completions 646 * 647 * Return: %TRUE if the signal has been handled 648 * 649 * Since: 2.6 650 */ 651 void addOnInsertPrefix(bool delegate(string, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 652 { 653 if ( "insert-prefix" !in connectedSignals ) 654 { 655 Signals.connectData( 656 this, 657 "insert-prefix", 658 cast(GCallback)&callBackInsertPrefix, 659 cast(void*)this, 660 null, 661 connectFlags); 662 connectedSignals["insert-prefix"] = 1; 663 } 664 onInsertPrefixListeners ~= dlg; 665 } 666 extern(C) static int callBackInsertPrefix(GtkEntryCompletion* entrycompletionStruct, char* prefix, EntryCompletion _entrycompletion) 667 { 668 foreach ( bool delegate(string, EntryCompletion) dlg; _entrycompletion.onInsertPrefixListeners ) 669 { 670 if ( dlg(Str.toString(prefix), _entrycompletion) ) 671 { 672 return 1; 673 } 674 } 675 676 return 0; 677 } 678 679 bool delegate(TreeModelIF, TreeIter, EntryCompletion)[] onMatchSelectedListeners; 680 /** 681 * Gets emitted when a match from the list is selected. 682 * The default behaviour is to replace the contents of the 683 * entry with the contents of the text column in the row 684 * pointed to by @iter. 685 * 686 * Note that @model is the model that was passed to 687 * gtk_entry_completion_set_model(). 688 * 689 * Params: 690 * model = the #GtkTreeModel containing the matches 691 * iter = a #GtkTreeIter positioned at the selected match 692 * 693 * Return: %TRUE if the signal has been handled 694 * 695 * Since: 2.4 696 */ 697 void addOnMatchSelected(bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 698 { 699 if ( "match-selected" !in connectedSignals ) 700 { 701 Signals.connectData( 702 this, 703 "match-selected", 704 cast(GCallback)&callBackMatchSelected, 705 cast(void*)this, 706 null, 707 connectFlags); 708 connectedSignals["match-selected"] = 1; 709 } 710 onMatchSelectedListeners ~= dlg; 711 } 712 extern(C) static int callBackMatchSelected(GtkEntryCompletion* entrycompletionStruct, GtkTreeModel* model, GtkTreeIter* iter, EntryCompletion _entrycompletion) 713 { 714 foreach ( bool delegate(TreeModelIF, TreeIter, EntryCompletion) dlg; _entrycompletion.onMatchSelectedListeners ) 715 { 716 if ( dlg(ObjectG.getDObject!(TreeModel, TreeModelIF)(model), ObjectG.getDObject!(TreeIter)(iter), _entrycompletion) ) 717 { 718 return 1; 719 } 720 } 721 722 return 0; 723 } 724 725 void delegate(EntryCompletion)[] onNoMatchesListeners; 726 /** 727 * Gets emitted when the filter model has zero 728 * number of rows in completion_complete method. 729 * (In other words when GtkEntryCompletion is out of 730 * suggestions) 731 * 732 * Since: 3.14 733 */ 734 void addOnNoMatches(void delegate(EntryCompletion) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 735 { 736 if ( "no-matches" !in connectedSignals ) 737 { 738 Signals.connectData( 739 this, 740 "no-matches", 741 cast(GCallback)&callBackNoMatches, 742 cast(void*)this, 743 null, 744 connectFlags); 745 connectedSignals["no-matches"] = 1; 746 } 747 onNoMatchesListeners ~= dlg; 748 } 749 extern(C) static void callBackNoMatches(GtkEntryCompletion* entrycompletionStruct, EntryCompletion _entrycompletion) 750 { 751 foreach ( void delegate(EntryCompletion) dlg; _entrycompletion.onNoMatchesListeners ) 752 { 753 dlg(_entrycompletion); 754 } 755 } 756 }