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