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.TreeModelT; 26 27 public import glib.Str; 28 public import gobject.ObjectG; 29 public import gobject.Signals; 30 public import gobject.Value; 31 public import gtk.TreeIter; 32 public import gtk.TreePath; 33 public import gtk.c.functions; 34 public import gtk.c.types; 35 public import gtkc.gtktypes; 36 public import std.algorithm; 37 38 39 /** 40 * The #GtkTreeModel interface defines a generic tree interface for 41 * use by the #GtkTreeView widget. It is an abstract interface, and 42 * is designed to be usable with any appropriate data structure. The 43 * programmer just has to implement this interface on their own data 44 * type for it to be viewable by a #GtkTreeView widget. 45 * 46 * The model is represented as a hierarchical tree of strongly-typed, 47 * columned data. In other words, the model can be seen as a tree where 48 * every node has different values depending on which column is being 49 * queried. The type of data found in a column is determined by using 50 * the GType system (ie. #G_TYPE_INT, #GTK_TYPE_BUTTON, #G_TYPE_POINTER, 51 * etc). The types are homogeneous per column across all nodes. It is 52 * important to note that this interface only provides a way of examining 53 * a model and observing changes. The implementation of each individual 54 * model decides how and if changes are made. 55 * 56 * In order to make life simpler for programmers who do not need to 57 * write their own specialized model, two generic models are provided 58 * — the #GtkTreeStore and the #GtkListStore. To use these, the 59 * developer simply pushes data into these models as necessary. These 60 * models provide the data structure as well as all appropriate tree 61 * interfaces. As a result, implementing drag and drop, sorting, and 62 * storing data is trivial. For the vast majority of trees and lists, 63 * these two models are sufficient. 64 * 65 * Models are accessed on a node/column level of granularity. One can 66 * query for the value of a model at a certain node and a certain 67 * column on that node. There are two structures used to reference a 68 * particular node in a model. They are the #GtkTreePath-struct and 69 * the #GtkTreeIter-struct (“iter” is short for iterator). Most of the 70 * interface consists of operations on a #GtkTreeIter-struct. 71 * 72 * A path is essentially a potential node. It is a location on a model 73 * that may or may not actually correspond to a node on a specific 74 * model. The #GtkTreePath-struct can be converted into either an 75 * array of unsigned integers or a string. The string form is a list 76 * of numbers separated by a colon. Each number refers to the offset 77 * at that level. Thus, the path `0` refers to the root 78 * node and the path `2:4` refers to the fifth child of 79 * the third node. 80 * 81 * By contrast, a #GtkTreeIter-struct is a reference to a specific node on 82 * a specific model. It is a generic struct with an integer and three 83 * generic pointers. These are filled in by the model in a model-specific 84 * way. One can convert a path to an iterator by calling 85 * gtk_tree_model_get_iter(). These iterators are the primary way 86 * of accessing a model and are similar to the iterators used by 87 * #GtkTextBuffer. They are generally statically allocated on the 88 * stack and only used for a short time. The model interface defines 89 * a set of operations using them for navigating the model. 90 * 91 * It is expected that models fill in the iterator with private data. 92 * For example, the #GtkListStore model, which is internally a simple 93 * linked list, stores a list node in one of the pointers. The 94 * #GtkTreeModelSort stores an array and an offset in two of the 95 * pointers. Additionally, there is an integer field. This field is 96 * generally filled with a unique stamp per model. This stamp is for 97 * catching errors resulting from using invalid iterators with a model. 98 * 99 * The lifecycle of an iterator can be a little confusing at first. 100 * Iterators are expected to always be valid for as long as the model 101 * is unchanged (and doesn’t emit a signal). The model is considered 102 * to own all outstanding iterators and nothing needs to be done to 103 * free them from the user’s point of view. Additionally, some models 104 * guarantee that an iterator is valid for as long as the node it refers 105 * to is valid (most notably the #GtkTreeStore and #GtkListStore). 106 * Although generally uninteresting, as one always has to allow for 107 * the case where iterators do not persist beyond a signal, some very 108 * important performance enhancements were made in the sort model. 109 * As a result, the #GTK_TREE_MODEL_ITERS_PERSIST flag was added to 110 * indicate this behavior. 111 * 112 * To help show some common operation of a model, some examples are 113 * provided. The first example shows three ways of getting the iter at 114 * the location `3:2:5`. While the first method shown is 115 * easier, the second is much more common, as you often get paths from 116 * callbacks. 117 * 118 * ## Acquiring a #GtkTreeIter-struct 119 * 120 * |[<!-- language="C" --> 121 * // Three ways of getting the iter pointing to the location 122 * GtkTreePath *path; 123 * GtkTreeIter iter; 124 * GtkTreeIter parent_iter; 125 * 126 * // get the iterator from a string 127 * gtk_tree_model_get_iter_from_string (model, 128 * &iter, 129 * "3:2:5"); 130 * 131 * // get the iterator from a path 132 * path = gtk_tree_path_new_from_string ("3:2:5"); 133 * gtk_tree_model_get_iter (model, &iter, path); 134 * gtk_tree_path_free (path); 135 * 136 * // walk the tree to find the iterator 137 * gtk_tree_model_iter_nth_child (model, &iter, 138 * NULL, 3); 139 * parent_iter = iter; 140 * gtk_tree_model_iter_nth_child (model, &iter, 141 * &parent_iter, 2); 142 * parent_iter = iter; 143 * gtk_tree_model_iter_nth_child (model, &iter, 144 * &parent_iter, 5); 145 * ]| 146 * 147 * This second example shows a quick way of iterating through a list 148 * and getting a string and an integer from each row. The 149 * populate_model() function used below is not 150 * shown, as it is specific to the #GtkListStore. For information on 151 * how to write such a function, see the #GtkListStore documentation. 152 * 153 * ## Reading data from a #GtkTreeModel 154 * 155 * |[<!-- language="C" --> 156 * enum 157 * { 158 * STRING_COLUMN, 159 * INT_COLUMN, 160 * N_COLUMNS 161 * }; 162 * 163 * ... 164 * 165 * GtkTreeModel *list_store; 166 * GtkTreeIter iter; 167 * gboolean valid; 168 * gint row_count = 0; 169 * 170 * // make a new list_store 171 * list_store = gtk_list_store_new (N_COLUMNS, 172 * G_TYPE_STRING, 173 * G_TYPE_INT); 174 * 175 * // Fill the list store with data 176 * populate_model (list_store); 177 * 178 * // Get the first iter in the list, check it is valid and walk 179 * // through the list, reading each row. 180 * 181 * valid = gtk_tree_model_get_iter_first (list_store, 182 * &iter); 183 * while (valid) 184 * { 185 * gchar *str_data; 186 * gint int_data; 187 * 188 * // Make sure you terminate calls to gtk_tree_model_get() with a “-1” value 189 * gtk_tree_model_get (list_store, &iter, 190 * STRING_COLUMN, &str_data, 191 * INT_COLUMN, &int_data, 192 * -1); 193 * 194 * // Do something with the data 195 * g_print ("Row %d: (%s,%d)\n", 196 * row_count, str_data, int_data); 197 * g_free (str_data); 198 * 199 * valid = gtk_tree_model_iter_next (list_store, 200 * &iter); 201 * row_count++; 202 * } 203 * ]| 204 * 205 * The #GtkTreeModel interface contains two methods for reference 206 * counting: gtk_tree_model_ref_node() and gtk_tree_model_unref_node(). 207 * These two methods are optional to implement. The reference counting 208 * is meant as a way for views to let models know when nodes are being 209 * displayed. #GtkTreeView will take a reference on a node when it is 210 * visible, which means the node is either in the toplevel or expanded. 211 * Being displayed does not mean that the node is currently directly 212 * visible to the user in the viewport. Based on this reference counting 213 * scheme a caching model, for example, can decide whether or not to cache 214 * a node based on the reference count. A file-system based model would 215 * not want to keep the entire file hierarchy in memory, but just the 216 * folders that are currently expanded in every current view. 217 * 218 * When working with reference counting, the following rules must be taken 219 * into account: 220 * 221 * - Never take a reference on a node without owning a reference on its parent. 222 * This means that all parent nodes of a referenced node must be referenced 223 * as well. 224 * 225 * - Outstanding references on a deleted node are not released. This is not 226 * possible because the node has already been deleted by the time the 227 * row-deleted signal is received. 228 * 229 * - Models are not obligated to emit a signal on rows of which none of its 230 * siblings are referenced. To phrase this differently, signals are only 231 * required for levels in which nodes are referenced. For the root level 232 * however, signals must be emitted at all times (however the root level 233 * is always referenced when any view is attached). 234 */ 235 public template TreeModelT(TStruct) 236 { 237 /** Get the main Gtk struct */ 238 public GtkTreeModel* getTreeModelStruct(bool transferOwnership = false) 239 { 240 if (transferOwnership) 241 ownedRef = false; 242 return cast(GtkTreeModel*)getStruct(); 243 } 244 245 /** 246 * Get the value of a column as a char array. 247 * this is the same calling getValue and get the string from the value object 248 */ 249 string getValueString(TreeIter iter, int column) 250 { 251 Value value = getValue(iter, column); 252 return value.getString(); 253 } 254 255 /** 256 * Get the value of a column as a char array. 257 * this is the same calling getValue and get the int from the value object 258 */ 259 int getValueInt(TreeIter iter, int column) 260 { 261 Value value = getValue(iter, column); 262 return value.getInt(); 263 } 264 265 /** 266 * Sets iter to a valid iterator pointing to path. 267 * Params: 268 * iter = The uninitialized GtkTreeIter. 269 * path = The GtkTreePath. 270 * Returns: 271 * TRUE, if iter was set. 272 */ 273 public int getIter(TreeIter iter, TreePath path) 274 { 275 iter.setModel(this); 276 return gtk_tree_model_get_iter( 277 getTreeModelStruct(), 278 (iter is null) ? null : iter.getTreeIterStruct(), 279 (path is null) ? null : path.getTreePathStruct()); 280 } 281 282 /** 283 * Initializes and sets value to that at column. 284 * When done with value, g_value_unset() needs to be called 285 * to free any allocated memory. 286 * Params: 287 * iter = The GtkTreeIter. 288 * column = The column to lookup the value at. 289 * value = (inout) (transfer none) An empty GValue to set. 290 */ 291 public Value getValue(TreeIter iter, int column, Value value = null) 292 { 293 if ( value is null ) 294 value = new Value(); 295 296 gtk_tree_model_get_value(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct(), column, (value is null) ? null : value.getValueStruct()); 297 298 return value; 299 } 300 301 /** 302 */ 303 304 /** 305 * Calls func on each node in model in a depth-first fashion. 306 * 307 * If @func returns %TRUE, then the tree ceases to be walked, 308 * and gtk_tree_model_foreach() returns. 309 * 310 * Params: 311 * func = a function to be called on each row 312 * userData = user data to passed to @func 313 */ 314 public void foreac(GtkTreeModelForeachFunc func, void* userData) 315 { 316 gtk_tree_model_foreach(getTreeModelStruct(), func, userData); 317 } 318 319 /** 320 * Returns the type of the column. 321 * 322 * Params: 323 * index = the column index 324 * 325 * Returns: the type of the column 326 */ 327 public GType getColumnType(int index) 328 { 329 return gtk_tree_model_get_column_type(getTreeModelStruct(), index); 330 } 331 332 /** 333 * Returns a set of flags supported by this interface. 334 * 335 * The flags are a bitwise combination of #GtkTreeModelFlags. 336 * The flags supported should not change during the lifetime 337 * of the @tree_model. 338 * 339 * Returns: the flags supported by this interface 340 */ 341 public GtkTreeModelFlags getFlags() 342 { 343 return gtk_tree_model_get_flags(getTreeModelStruct()); 344 } 345 346 /** 347 * Initializes @iter with the first iterator in the tree 348 * (the one at the path "0") and returns %TRUE. Returns 349 * %FALSE if the tree is empty. 350 * 351 * Params: 352 * iter = the uninitialized #GtkTreeIter-struct 353 * 354 * Returns: %TRUE, if @iter was set 355 */ 356 public bool getIterFirst(out TreeIter iter) 357 { 358 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 359 360 auto p = gtk_tree_model_get_iter_first(getTreeModelStruct(), outiter) != 0; 361 362 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 363 364 return p; 365 } 366 367 /** 368 * Sets @iter to a valid iterator pointing to @path_string, if it 369 * exists. Otherwise, @iter is left invalid and %FALSE is returned. 370 * 371 * Params: 372 * iter = an uninitialized #GtkTreeIter-struct 373 * pathString = a string representation of a #GtkTreePath-struct 374 * 375 * Returns: %TRUE, if @iter was set 376 */ 377 public bool getIterFromString(out TreeIter iter, string pathString) 378 { 379 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 380 381 auto p = gtk_tree_model_get_iter_from_string(getTreeModelStruct(), outiter, Str.toStringz(pathString)) != 0; 382 383 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 384 385 return p; 386 } 387 388 /** 389 * Returns the number of columns supported by @tree_model. 390 * 391 * Returns: the number of columns 392 */ 393 public int getNColumns() 394 { 395 return gtk_tree_model_get_n_columns(getTreeModelStruct()); 396 } 397 398 /** 399 * Returns a newly-created #GtkTreePath-struct referenced by @iter. 400 * 401 * This path should be freed with gtk_tree_path_free(). 402 * 403 * Params: 404 * iter = the #GtkTreeIter-struct 405 * 406 * Returns: a newly-created #GtkTreePath-struct 407 */ 408 public TreePath getPath(TreeIter iter) 409 { 410 auto p = gtk_tree_model_get_path(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 411 412 if(p is null) 413 { 414 return null; 415 } 416 417 return ObjectG.getDObject!(TreePath)(cast(GtkTreePath*) p, true); 418 } 419 420 /** 421 * Generates a string representation of the iter. 422 * 423 * This string is a “:” separated list of numbers. 424 * For example, “4:10:0:3” would be an acceptable 425 * return value for this string. 426 * 427 * Params: 428 * iter = a #GtkTreeIter-struct 429 * 430 * Returns: a newly-allocated string. 431 * Must be freed with g_free(). 432 * 433 * Since: 2.2 434 */ 435 public string getStringFromIter(TreeIter iter) 436 { 437 auto retStr = gtk_tree_model_get_string_from_iter(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 438 439 scope(exit) Str.freeString(retStr); 440 return Str.toString(retStr); 441 } 442 443 /** 444 * See gtk_tree_model_get(), this version takes a va_list 445 * for language bindings to use. 446 * 447 * Params: 448 * iter = a row in @tree_model 449 * varArgs = va_list of column/return location pairs 450 */ 451 public void getValist(TreeIter iter, void* varArgs) 452 { 453 gtk_tree_model_get_valist(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct(), varArgs); 454 } 455 456 /** 457 * Sets @iter to point to the first child of @parent. 458 * 459 * If @parent has no children, %FALSE is returned and @iter is 460 * set to be invalid. @parent will remain a valid node after this 461 * function has been called. 462 * 463 * If @parent is %NULL returns the first node, equivalent to 464 * `gtk_tree_model_get_iter_first (tree_model, iter);` 465 * 466 * Params: 467 * iter = the new #GtkTreeIter-struct to be set to the child 468 * parent = the #GtkTreeIter-struct, or %NULL 469 * 470 * Returns: %TRUE, if @iter has been set to the first child 471 */ 472 public bool iterChildren(out TreeIter iter, TreeIter parent) 473 { 474 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 475 476 auto p = gtk_tree_model_iter_children(getTreeModelStruct(), outiter, (parent is null) ? null : parent.getTreeIterStruct()) != 0; 477 478 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 479 480 return p; 481 } 482 483 /** 484 * Returns %TRUE if @iter has children, %FALSE otherwise. 485 * 486 * Params: 487 * iter = the #GtkTreeIter-struct to test for children 488 * 489 * Returns: %TRUE if @iter has children 490 */ 491 public bool iterHasChild(TreeIter iter) 492 { 493 return gtk_tree_model_iter_has_child(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()) != 0; 494 } 495 496 /** 497 * Returns the number of children that @iter has. 498 * 499 * As a special case, if @iter is %NULL, then the number 500 * of toplevel nodes is returned. 501 * 502 * Params: 503 * iter = the #GtkTreeIter-struct, or %NULL 504 * 505 * Returns: the number of children of @iter 506 */ 507 public int iterNChildren(TreeIter iter) 508 { 509 return gtk_tree_model_iter_n_children(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 510 } 511 512 /** 513 * Sets @iter to point to the node following it at the current level. 514 * 515 * If there is no next @iter, %FALSE is returned and @iter is set 516 * to be invalid. 517 * 518 * Params: 519 * iter = the #GtkTreeIter-struct 520 * 521 * Returns: %TRUE if @iter has been changed to the next node 522 */ 523 public bool iterNext(TreeIter iter) 524 { 525 return gtk_tree_model_iter_next(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()) != 0; 526 } 527 528 /** 529 * Sets @iter to be the child of @parent, using the given index. 530 * 531 * The first index is 0. If @n is too big, or @parent has no children, 532 * @iter is set to an invalid iterator and %FALSE is returned. @parent 533 * will remain a valid node after this function has been called. As a 534 * special case, if @parent is %NULL, then the @n-th root node 535 * is set. 536 * 537 * Params: 538 * iter = the #GtkTreeIter-struct to set to the nth child 539 * parent = the #GtkTreeIter-struct to get the child from, or %NULL. 540 * n = the index of the desired child 541 * 542 * Returns: %TRUE, if @parent has an @n-th child 543 */ 544 public bool iterNthChild(out TreeIter iter, TreeIter parent, int n) 545 { 546 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 547 548 auto p = gtk_tree_model_iter_nth_child(getTreeModelStruct(), outiter, (parent is null) ? null : parent.getTreeIterStruct(), n) != 0; 549 550 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 551 552 return p; 553 } 554 555 /** 556 * Sets @iter to be the parent of @child. 557 * 558 * If @child is at the toplevel, and doesn’t have a parent, then 559 * @iter is set to an invalid iterator and %FALSE is returned. 560 * @child will remain a valid node after this function has been 561 * called. 562 * 563 * @iter will be initialized before the lookup is performed, so @child 564 * and @iter cannot point to the same memory location. 565 * 566 * Params: 567 * iter = the new #GtkTreeIter-struct to set to the parent 568 * child = the #GtkTreeIter-struct 569 * 570 * Returns: %TRUE, if @iter is set to the parent of @child 571 */ 572 public bool iterParent(out TreeIter iter, TreeIter child) 573 { 574 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 575 576 auto p = gtk_tree_model_iter_parent(getTreeModelStruct(), outiter, (child is null) ? null : child.getTreeIterStruct()) != 0; 577 578 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 579 580 return p; 581 } 582 583 /** 584 * Sets @iter to point to the previous node at the current level. 585 * 586 * If there is no previous @iter, %FALSE is returned and @iter is 587 * set to be invalid. 588 * 589 * Params: 590 * iter = the #GtkTreeIter-struct 591 * 592 * Returns: %TRUE if @iter has been changed to the previous node 593 * 594 * Since: 3.0 595 */ 596 public bool iterPrevious(TreeIter iter) 597 { 598 return gtk_tree_model_iter_previous(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()) != 0; 599 } 600 601 /** 602 * Lets the tree ref the node. 603 * 604 * This is an optional method for models to implement. 605 * To be more specific, models may ignore this call as it exists 606 * primarily for performance reasons. 607 * 608 * This function is primarily meant as a way for views to let 609 * caching models know when nodes are being displayed (and hence, 610 * whether or not to cache that node). Being displayed means a node 611 * is in an expanded branch, regardless of whether the node is currently 612 * visible in the viewport. For example, a file-system based model 613 * would not want to keep the entire file-hierarchy in memory, 614 * just the sections that are currently being displayed by 615 * every current view. 616 * 617 * A model should be expected to be able to get an iter independent 618 * of its reffed state. 619 * 620 * Params: 621 * iter = the #GtkTreeIter-struct 622 */ 623 public void refNode(TreeIter iter) 624 { 625 gtk_tree_model_ref_node(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 626 } 627 628 /** 629 * Emits the #GtkTreeModel::row-changed signal on @tree_model. 630 * 631 * Params: 632 * path = a #GtkTreePath-struct pointing to the changed row 633 * iter = a valid #GtkTreeIter-struct pointing to the changed row 634 */ 635 public void rowChanged(TreePath path, TreeIter iter) 636 { 637 gtk_tree_model_row_changed(getTreeModelStruct(), (path is null) ? null : path.getTreePathStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 638 } 639 640 /** 641 * Emits the #GtkTreeModel::row-deleted signal on @tree_model. 642 * 643 * This should be called by models after a row has been removed. 644 * The location pointed to by @path should be the location that 645 * the row previously was at. It may not be a valid location anymore. 646 * 647 * Nodes that are deleted are not unreffed, this means that any 648 * outstanding references on the deleted node should not be released. 649 * 650 * Params: 651 * path = a #GtkTreePath-struct pointing to the previous location of 652 * the deleted row 653 */ 654 public void rowDeleted(TreePath path) 655 { 656 gtk_tree_model_row_deleted(getTreeModelStruct(), (path is null) ? null : path.getTreePathStruct()); 657 } 658 659 /** 660 * Emits the #GtkTreeModel::row-has-child-toggled signal on 661 * @tree_model. This should be called by models after the child 662 * state of a node changes. 663 * 664 * Params: 665 * path = a #GtkTreePath-struct pointing to the changed row 666 * iter = a valid #GtkTreeIter-struct pointing to the changed row 667 */ 668 public void rowHasChildToggled(TreePath path, TreeIter iter) 669 { 670 gtk_tree_model_row_has_child_toggled(getTreeModelStruct(), (path is null) ? null : path.getTreePathStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 671 } 672 673 /** 674 * Emits the #GtkTreeModel::row-inserted signal on @tree_model. 675 * 676 * Params: 677 * path = a #GtkTreePath-struct pointing to the inserted row 678 * iter = a valid #GtkTreeIter-struct pointing to the inserted row 679 */ 680 public void rowInserted(TreePath path, TreeIter iter) 681 { 682 gtk_tree_model_row_inserted(getTreeModelStruct(), (path is null) ? null : path.getTreePathStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 683 } 684 685 /** 686 * Emits the #GtkTreeModel::rows-reordered signal on @tree_model. 687 * 688 * This should be called by models when their rows have been 689 * reordered. 690 * 691 * Params: 692 * path = a #GtkTreePath-struct pointing to the tree node whose children 693 * have been reordered 694 * iter = a valid #GtkTreeIter-struct pointing to the node whose children 695 * have been reordered, or %NULL if the depth of @path is 0 696 * newOrder = an array of integers mapping the current position of 697 * each child to its old position before the re-ordering, 698 * i.e. @new_order`[newpos] = oldpos` 699 */ 700 public void rowsReordered(TreePath path, TreeIter iter, int* newOrder) 701 { 702 gtk_tree_model_rows_reordered(getTreeModelStruct(), (path is null) ? null : path.getTreePathStruct(), (iter is null) ? null : iter.getTreeIterStruct(), newOrder); 703 } 704 705 /** 706 * Emits the #GtkTreeModel::rows-reordered signal on @tree_model. 707 * 708 * This should be called by models when their rows have been 709 * reordered. 710 * 711 * Params: 712 * path = a #GtkTreePath-struct pointing to the tree node whose children 713 * have been reordered 714 * iter = a valid #GtkTreeIter-struct pointing to the node 715 * whose children have been reordered, or %NULL if the depth 716 * of @path is 0 717 * newOrder = an array of integers 718 * mapping the current position of each child to its old 719 * position before the re-ordering, 720 * i.e. @new_order`[newpos] = oldpos` 721 * 722 * Since: 3.10 723 */ 724 public void rowsReorderedWithLength(TreePath path, TreeIter iter, int[] newOrder) 725 { 726 gtk_tree_model_rows_reordered_with_length(getTreeModelStruct(), (path is null) ? null : path.getTreePathStruct(), (iter is null) ? null : iter.getTreeIterStruct(), newOrder.ptr, cast(int)newOrder.length); 727 } 728 729 /** 730 * Lets the tree unref the node. 731 * 732 * This is an optional method for models to implement. 733 * To be more specific, models may ignore this call as it exists 734 * primarily for performance reasons. For more information on what 735 * this means, see gtk_tree_model_ref_node(). 736 * 737 * Please note that nodes that are deleted are not unreffed. 738 * 739 * Params: 740 * iter = the #GtkTreeIter-struct 741 */ 742 public void unrefNode(TreeIter iter) 743 { 744 gtk_tree_model_unref_node(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct()); 745 } 746 747 protected class OnRowChangedDelegateWrapper 748 { 749 void delegate(TreePath, TreeIter, TreeModelIF) dlg; 750 gulong handlerId; 751 752 this(void delegate(TreePath, TreeIter, TreeModelIF) dlg) 753 { 754 this.dlg = dlg; 755 onRowChangedListeners ~= this; 756 } 757 758 void remove(OnRowChangedDelegateWrapper source) 759 { 760 foreach(index, wrapper; onRowChangedListeners) 761 { 762 if (wrapper.handlerId == source.handlerId) 763 { 764 onRowChangedListeners[index] = null; 765 onRowChangedListeners = std.algorithm.remove(onRowChangedListeners, index); 766 break; 767 } 768 } 769 } 770 } 771 OnRowChangedDelegateWrapper[] onRowChangedListeners; 772 773 /** 774 * This signal is emitted when a row in the model has changed. 775 * 776 * Params: 777 * path = a #GtkTreePath-struct identifying the changed row 778 * iter = a valid #GtkTreeIter-struct pointing to the changed row 779 */ 780 gulong addOnRowChanged(void delegate(TreePath, TreeIter, TreeModelIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 781 { 782 auto wrapper = new OnRowChangedDelegateWrapper(dlg); 783 wrapper.handlerId = Signals.connectData( 784 this, 785 "row-changed", 786 cast(GCallback)&callBackRowChanged, 787 cast(void*)wrapper, 788 cast(GClosureNotify)&callBackRowChangedDestroy, 789 connectFlags); 790 return wrapper.handlerId; 791 } 792 793 extern(C) static void callBackRowChanged(GtkTreeModel* treemodelStruct, GtkTreePath* path, GtkTreeIter* iter, OnRowChangedDelegateWrapper wrapper) 794 { 795 wrapper.dlg(ObjectG.getDObject!(TreePath)(path), ObjectG.getDObject!(TreeIter)(iter), wrapper.outer); 796 } 797 798 extern(C) static void callBackRowChangedDestroy(OnRowChangedDelegateWrapper wrapper, GClosure* closure) 799 { 800 wrapper.remove(wrapper); 801 } 802 803 protected class OnRowDeletedDelegateWrapper 804 { 805 void delegate(TreePath, TreeModelIF) dlg; 806 gulong handlerId; 807 808 this(void delegate(TreePath, TreeModelIF) dlg) 809 { 810 this.dlg = dlg; 811 onRowDeletedListeners ~= this; 812 } 813 814 void remove(OnRowDeletedDelegateWrapper source) 815 { 816 foreach(index, wrapper; onRowDeletedListeners) 817 { 818 if (wrapper.handlerId == source.handlerId) 819 { 820 onRowDeletedListeners[index] = null; 821 onRowDeletedListeners = std.algorithm.remove(onRowDeletedListeners, index); 822 break; 823 } 824 } 825 } 826 } 827 OnRowDeletedDelegateWrapper[] onRowDeletedListeners; 828 829 /** 830 * This signal is emitted when a row has been deleted. 831 * 832 * Note that no iterator is passed to the signal handler, 833 * since the row is already deleted. 834 * 835 * This should be called by models after a row has been removed. 836 * The location pointed to by @path should be the location that 837 * the row previously was at. It may not be a valid location anymore. 838 * 839 * Params: 840 * path = a #GtkTreePath-struct identifying the row 841 */ 842 gulong addOnRowDeleted(void delegate(TreePath, TreeModelIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 843 { 844 auto wrapper = new OnRowDeletedDelegateWrapper(dlg); 845 wrapper.handlerId = Signals.connectData( 846 this, 847 "row-deleted", 848 cast(GCallback)&callBackRowDeleted, 849 cast(void*)wrapper, 850 cast(GClosureNotify)&callBackRowDeletedDestroy, 851 connectFlags); 852 return wrapper.handlerId; 853 } 854 855 extern(C) static void callBackRowDeleted(GtkTreeModel* treemodelStruct, GtkTreePath* path, OnRowDeletedDelegateWrapper wrapper) 856 { 857 wrapper.dlg(ObjectG.getDObject!(TreePath)(path), wrapper.outer); 858 } 859 860 extern(C) static void callBackRowDeletedDestroy(OnRowDeletedDelegateWrapper wrapper, GClosure* closure) 861 { 862 wrapper.remove(wrapper); 863 } 864 865 protected class OnRowHasChildToggledDelegateWrapper 866 { 867 void delegate(TreePath, TreeIter, TreeModelIF) dlg; 868 gulong handlerId; 869 870 this(void delegate(TreePath, TreeIter, TreeModelIF) dlg) 871 { 872 this.dlg = dlg; 873 onRowHasChildToggledListeners ~= this; 874 } 875 876 void remove(OnRowHasChildToggledDelegateWrapper source) 877 { 878 foreach(index, wrapper; onRowHasChildToggledListeners) 879 { 880 if (wrapper.handlerId == source.handlerId) 881 { 882 onRowHasChildToggledListeners[index] = null; 883 onRowHasChildToggledListeners = std.algorithm.remove(onRowHasChildToggledListeners, index); 884 break; 885 } 886 } 887 } 888 } 889 OnRowHasChildToggledDelegateWrapper[] onRowHasChildToggledListeners; 890 891 /** 892 * This signal is emitted when a row has gotten the first child 893 * row or lost its last child row. 894 * 895 * Params: 896 * path = a #GtkTreePath-struct identifying the row 897 * iter = a valid #GtkTreeIter-struct pointing to the row 898 */ 899 gulong addOnRowHasChildToggled(void delegate(TreePath, TreeIter, TreeModelIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 900 { 901 auto wrapper = new OnRowHasChildToggledDelegateWrapper(dlg); 902 wrapper.handlerId = Signals.connectData( 903 this, 904 "row-has-child-toggled", 905 cast(GCallback)&callBackRowHasChildToggled, 906 cast(void*)wrapper, 907 cast(GClosureNotify)&callBackRowHasChildToggledDestroy, 908 connectFlags); 909 return wrapper.handlerId; 910 } 911 912 extern(C) static void callBackRowHasChildToggled(GtkTreeModel* treemodelStruct, GtkTreePath* path, GtkTreeIter* iter, OnRowHasChildToggledDelegateWrapper wrapper) 913 { 914 wrapper.dlg(ObjectG.getDObject!(TreePath)(path), ObjectG.getDObject!(TreeIter)(iter), wrapper.outer); 915 } 916 917 extern(C) static void callBackRowHasChildToggledDestroy(OnRowHasChildToggledDelegateWrapper wrapper, GClosure* closure) 918 { 919 wrapper.remove(wrapper); 920 } 921 922 protected class OnRowInsertedDelegateWrapper 923 { 924 void delegate(TreePath, TreeIter, TreeModelIF) dlg; 925 gulong handlerId; 926 927 this(void delegate(TreePath, TreeIter, TreeModelIF) dlg) 928 { 929 this.dlg = dlg; 930 onRowInsertedListeners ~= this; 931 } 932 933 void remove(OnRowInsertedDelegateWrapper source) 934 { 935 foreach(index, wrapper; onRowInsertedListeners) 936 { 937 if (wrapper.handlerId == source.handlerId) 938 { 939 onRowInsertedListeners[index] = null; 940 onRowInsertedListeners = std.algorithm.remove(onRowInsertedListeners, index); 941 break; 942 } 943 } 944 } 945 } 946 OnRowInsertedDelegateWrapper[] onRowInsertedListeners; 947 948 /** 949 * This signal is emitted when a new row has been inserted in 950 * the model. 951 * 952 * Note that the row may still be empty at this point, since 953 * it is a common pattern to first insert an empty row, and 954 * then fill it with the desired values. 955 * 956 * Params: 957 * path = a #GtkTreePath-struct identifying the new row 958 * iter = a valid #GtkTreeIter-struct pointing to the new row 959 */ 960 gulong addOnRowInserted(void delegate(TreePath, TreeIter, TreeModelIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 961 { 962 auto wrapper = new OnRowInsertedDelegateWrapper(dlg); 963 wrapper.handlerId = Signals.connectData( 964 this, 965 "row-inserted", 966 cast(GCallback)&callBackRowInserted, 967 cast(void*)wrapper, 968 cast(GClosureNotify)&callBackRowInsertedDestroy, 969 connectFlags); 970 return wrapper.handlerId; 971 } 972 973 extern(C) static void callBackRowInserted(GtkTreeModel* treemodelStruct, GtkTreePath* path, GtkTreeIter* iter, OnRowInsertedDelegateWrapper wrapper) 974 { 975 wrapper.dlg(ObjectG.getDObject!(TreePath)(path), ObjectG.getDObject!(TreeIter)(iter), wrapper.outer); 976 } 977 978 extern(C) static void callBackRowInsertedDestroy(OnRowInsertedDelegateWrapper wrapper, GClosure* closure) 979 { 980 wrapper.remove(wrapper); 981 } 982 983 protected class OnRowsReorderedDelegateWrapper 984 { 985 void delegate(TreePath, TreeIter, void*, TreeModelIF) dlg; 986 gulong handlerId; 987 988 this(void delegate(TreePath, TreeIter, void*, TreeModelIF) dlg) 989 { 990 this.dlg = dlg; 991 onRowsReorderedListeners ~= this; 992 } 993 994 void remove(OnRowsReorderedDelegateWrapper source) 995 { 996 foreach(index, wrapper; onRowsReorderedListeners) 997 { 998 if (wrapper.handlerId == source.handlerId) 999 { 1000 onRowsReorderedListeners[index] = null; 1001 onRowsReorderedListeners = std.algorithm.remove(onRowsReorderedListeners, index); 1002 break; 1003 } 1004 } 1005 } 1006 } 1007 OnRowsReorderedDelegateWrapper[] onRowsReorderedListeners; 1008 1009 /** 1010 * This signal is emitted when the children of a node in the 1011 * #GtkTreeModel have been reordered. 1012 * 1013 * Note that this signal is not emitted 1014 * when rows are reordered by DND, since this is implemented 1015 * by removing and then reinserting the row. 1016 * 1017 * Params: 1018 * path = a #GtkTreePath-struct identifying the tree node whose children 1019 * have been reordered 1020 * iter = a valid #GtkTreeIter-struct pointing to the node whose children 1021 * have been reordered, or %NULL if the depth of @path is 0 1022 * newOrder = an array of integers mapping the current position 1023 * of each child to its old position before the re-ordering, 1024 * i.e. @new_order`[newpos] = oldpos` 1025 */ 1026 gulong addOnRowsReordered(void delegate(TreePath, TreeIter, void*, TreeModelIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1027 { 1028 auto wrapper = new OnRowsReorderedDelegateWrapper(dlg); 1029 wrapper.handlerId = Signals.connectData( 1030 this, 1031 "rows-reordered", 1032 cast(GCallback)&callBackRowsReordered, 1033 cast(void*)wrapper, 1034 cast(GClosureNotify)&callBackRowsReorderedDestroy, 1035 connectFlags); 1036 return wrapper.handlerId; 1037 } 1038 1039 extern(C) static void callBackRowsReordered(GtkTreeModel* treemodelStruct, GtkTreePath* path, GtkTreeIter* iter, void* newOrder, OnRowsReorderedDelegateWrapper wrapper) 1040 { 1041 wrapper.dlg(ObjectG.getDObject!(TreePath)(path), ObjectG.getDObject!(TreeIter)(iter), newOrder, wrapper.outer); 1042 } 1043 1044 extern(C) static void callBackRowsReorderedDestroy(OnRowsReorderedDelegateWrapper wrapper, GClosure* closure) 1045 { 1046 wrapper.remove(wrapper); 1047 } 1048 }