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