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.ListStore; 26 27 private import glib.ConstructionException; 28 private import gobject.ObjectG; 29 private import gobject.Value; 30 private import gtk.BuildableIF; 31 private import gtk.BuildableT; 32 private import gtk.TreeDragDestIF; 33 private import gtk.TreeDragDestT; 34 private import gtk.TreeDragSourceIF; 35 private import gtk.TreeDragSourceT; 36 private import gtk.TreeIter; 37 private import gtk.TreeModelIF; 38 private import gtk.TreeModelT; 39 private import gtk.TreeSortableIF; 40 private import gtk.TreeSortableT; 41 private import gtkc.gtk; 42 public import gtkc.gtktypes; 43 44 45 /** 46 * The #GtkListStore object is a list model for use with a #GtkTreeView 47 * widget. It implements the #GtkTreeModel interface, and consequentialy, 48 * can use all of the methods available there. It also implements the 49 * #GtkTreeSortable interface so it can be sorted by the view. 50 * Finally, it also implements the tree 51 * [drag and drop][gtk3-GtkTreeView-drag-and-drop] 52 * interfaces. 53 * 54 * The #GtkListStore can accept most GObject types as a column type, though 55 * it can’t accept all custom types. Internally, it will keep a copy of 56 * data passed in (such as a string or a boxed pointer). Columns that 57 * accept #GObjects are handled a little differently. The 58 * #GtkListStore will keep a reference to the object instead of copying the 59 * value. As a result, if the object is modified, it is up to the 60 * application writer to call gtk_tree_model_row_changed() to emit the 61 * #GtkTreeModel::row_changed signal. This most commonly affects lists with 62 * #GdkPixbufs stored. 63 * 64 * An example for creating a simple list store: 65 * |[<!-- language="C" --> 66 * enum { 67 * COLUMN_STRING, 68 * COLUMN_INT, 69 * COLUMN_BOOLEAN, 70 * N_COLUMNS 71 * }; 72 * 73 * { 74 * GtkListStore *list_store; 75 * GtkTreePath *path; 76 * GtkTreeIter iter; 77 * gint i; 78 * 79 * list_store = gtk_list_store_new (N_COLUMNS, 80 * G_TYPE_STRING, 81 * G_TYPE_INT, 82 * G_TYPE_BOOLEAN); 83 * 84 * for (i = 0; i < 10; i++) 85 * { 86 * gchar *some_data; 87 * 88 * some_data = get_some_data (i); 89 * 90 * // Add a new row to the model 91 * gtk_list_store_append (list_store, &iter); 92 * gtk_list_store_set (list_store, &iter, 93 * COLUMN_STRING, some_data, 94 * COLUMN_INT, i, 95 * COLUMN_BOOLEAN, FALSE, 96 * -1); 97 * 98 * // As the store will keep a copy of the string internally, 99 * // we free some_data. 100 * g_free (some_data); 101 * } 102 * 103 * // Modify a particular row 104 * path = gtk_tree_path_new_from_string ("4"); 105 * gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), 106 * &iter, 107 * path); 108 * gtk_tree_path_free (path); 109 * gtk_list_store_set (list_store, &iter, 110 * COLUMN_BOOLEAN, TRUE, 111 * -1); 112 * } 113 * ]| 114 * 115 * # Performance Considerations 116 * 117 * Internally, the #GtkListStore was implemented with a linked list with 118 * a tail pointer prior to GTK+ 2.6. As a result, it was fast at data 119 * insertion and deletion, and not fast at random data access. The 120 * #GtkListStore sets the #GTK_TREE_MODEL_ITERS_PERSIST flag, which means 121 * that #GtkTreeIters can be cached while the row exists. Thus, if 122 * access to a particular row is needed often and your code is expected to 123 * run on older versions of GTK+, it is worth keeping the iter around. 124 * 125 * # Atomic Operations 126 * 127 * It is important to note that only the methods 128 * gtk_list_store_insert_with_values() and gtk_list_store_insert_with_valuesv() 129 * are atomic, in the sense that the row is being appended to the store and the 130 * values filled in in a single operation with regard to #GtkTreeModel signaling. 131 * In contrast, using e.g. gtk_list_store_append() and then gtk_list_store_set() 132 * will first create a row, which triggers the #GtkTreeModel::row-inserted signal 133 * on #GtkListStore. The row, however, is still empty, and any signal handler 134 * connecting to #GtkTreeModel::row-inserted on this particular store should be prepared 135 * for the situation that the row might be empty. This is especially important 136 * if you are wrapping the #GtkListStore inside a #GtkTreeModelFilter and are 137 * using a #GtkTreeModelFilterVisibleFunc. Using any of the non-atomic operations 138 * to append rows to the #GtkListStore will cause the 139 * #GtkTreeModelFilterVisibleFunc to be visited with an empty row first; the 140 * function must be prepared for that. 141 * 142 * # GtkListStore as GtkBuildable 143 * 144 * The GtkListStore implementation of the GtkBuildable interface allows 145 * to specify the model columns with a <columns> element that may contain 146 * multiple <column> elements, each specifying one model column. The “type” 147 * attribute specifies the data type for the column. 148 * 149 * Additionally, it is possible to specify content for the list store 150 * in the UI definition, with the <data> element. It can contain multiple 151 * <row> elements, each specifying to content for one row of the list model. 152 * Inside a <row>, the <col> elements specify the content for individual cells. 153 * 154 * Note that it is probably more common to define your models in the code, 155 * and one might consider it a layering violation to specify the content of 156 * a list store in a UI definition, data, not presentation, and common wisdom 157 * is to separate the two, as far as possible. 158 * 159 * An example of a UI Definition fragment for a list store: 160 * |[<!-- language="C" --> 161 * <object class="GtkListStore"> 162 * <columns> 163 * <column type="gchararray"/> 164 * <column type="gchararray"/> 165 * <column type="gint"/> 166 * </columns> 167 * <data> 168 * <row> 169 * <col id="0">John</col> 170 * <col id="1">Doe</col> 171 * <col id="2">25</col> 172 * </row> 173 * <row> 174 * <col id="0">Johan</col> 175 * <col id="1">Dahlin</col> 176 * <col id="2">50</col> 177 * </row> 178 * </data> 179 * </object> 180 * ]| 181 */ 182 public class ListStore : ObjectG, BuildableIF, TreeDragDestIF, TreeDragSourceIF, TreeModelIF, TreeSortableIF 183 { 184 /** the main Gtk struct */ 185 protected GtkListStore* gtkListStore; 186 187 /** Get the main Gtk struct */ 188 public GtkListStore* getListStoreStruct(bool transferOwnership = false) 189 { 190 if (transferOwnership) 191 ownedRef = false; 192 return gtkListStore; 193 } 194 195 /** the main Gtk struct as a void* */ 196 protected override void* getStruct() 197 { 198 return cast(void*)gtkListStore; 199 } 200 201 protected override void setStruct(GObject* obj) 202 { 203 gtkListStore = cast(GtkListStore*)obj; 204 super.setStruct(obj); 205 } 206 207 /** 208 * Sets our main struct and passes it to the parent class. 209 */ 210 public this (GtkListStore* gtkListStore, bool ownedRef = false) 211 { 212 this.gtkListStore = gtkListStore; 213 super(cast(GObject*)gtkListStore, ownedRef); 214 } 215 216 // add the Buildable capabilities 217 mixin BuildableT!(GtkListStore); 218 219 // add the TreeDragDest capabilities 220 mixin TreeDragDestT!(GtkListStore); 221 222 // add the TreeDragSource capabilities 223 mixin TreeDragSourceT!(GtkListStore); 224 225 // add the TreeModel capabilities 226 mixin TreeModelT!(GtkListStore); 227 228 // add the TreeSortable capabilities 229 mixin TreeSortableT!(GtkListStore); 230 231 /** 232 * Creates a top level iteractor. 233 * I don't think lists have but the top level iteractor 234 */ 235 TreeIter createIter() 236 { 237 GtkTreeIter* iter = new GtkTreeIter; 238 gtk_list_store_append(getListStoreStruct(), iter); 239 return new TreeIter(iter); 240 } 241 242 /** 243 * sets the values for one row 244 * Params: 245 * iter = the row iteractor 246 * columns = an arrays with the columns to set 247 * values = an arrays with the values 248 */ 249 void set(TreeIter iter, int[] columns, char*[] values) 250 { 251 for ( int i=0 ; i<columns.length && i<values.length; i++ ) 252 { 253 gtk_list_store_set( 254 gtkListStore, 255 iter.getTreeIterStruct(), 256 columns[i], 257 values[i],-1); 258 } 259 } 260 261 /** ditto */ 262 void set(TreeIter iter, int[] columns, string[] values) 263 { 264 for ( int i=0 ; i<columns.length && i<values.length; i++ ) 265 { 266 gtk_list_store_set( 267 gtkListStore, 268 iter.getTreeIterStruct(), 269 columns[i], 270 Str.toStringz(values[i]),-1); 271 } 272 } 273 274 /** */ 275 void setValue(TreeIter iter, int column, string value) 276 { 277 Value v = new Value(value); 278 gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct()); 279 //gtk_list_store_set_value(obj(), iter.getIter(), column, (GValue*)cChar(value)); 280 } 281 282 /** */ 283 void setValue(TreeIter iter, int column, int value) 284 { 285 Value v = new Value(value); 286 gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct()); 287 } 288 289 /** 290 */ 291 292 /** */ 293 public static GType getType() 294 { 295 return gtk_list_store_get_type(); 296 } 297 298 /** 299 * Non-vararg creation function. Used primarily by language bindings. 300 * 301 * Params: 302 * nColumns = number of columns in the list store 303 * types = an array of #GType types for the columns, from first to last 304 * 305 * Returns: a new #GtkListStore 306 * 307 * Throws: ConstructionException GTK+ fails to create the object. 308 */ 309 public this(GType[] types) 310 { 311 auto p = gtk_list_store_newv(cast(int)types.length, types.ptr); 312 313 if(p is null) 314 { 315 throw new ConstructionException("null returned by newv"); 316 } 317 318 this(cast(GtkListStore*) p, true); 319 } 320 321 /** 322 * Appends a new row to @list_store. @iter will be changed to point to this new 323 * row. The row will be empty after this function is called. To fill in 324 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 325 * 326 * Params: 327 * iter = An unset #GtkTreeIter to set to the appended row 328 */ 329 public void append(out TreeIter iter) 330 { 331 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 332 333 gtk_list_store_append(gtkListStore, outiter); 334 335 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 336 } 337 338 /** 339 * Removes all rows from the list store. 340 */ 341 public void clear() 342 { 343 gtk_list_store_clear(gtkListStore); 344 } 345 346 /** 347 * Creates a new row at @position. @iter will be changed to point to this new 348 * row. If @position is -1 or is larger than the number of rows on the list, 349 * then the new row will be appended to the list. The row will be empty after 350 * this function is called. To fill in values, you need to call 351 * gtk_list_store_set() or gtk_list_store_set_value(). 352 * 353 * Params: 354 * iter = An unset #GtkTreeIter to set to the new row 355 * position = position to insert the new row, or -1 for last 356 */ 357 public void insert(out TreeIter iter, int position) 358 { 359 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 360 361 gtk_list_store_insert(gtkListStore, outiter, position); 362 363 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 364 } 365 366 /** 367 * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be 368 * prepended to the beginning of the list. @iter will be changed to point to 369 * this new row. The row will be empty after this function is called. To fill 370 * in values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 371 * 372 * Params: 373 * iter = An unset #GtkTreeIter to set to the new row 374 * sibling = A valid #GtkTreeIter, or %NULL 375 */ 376 public void insertAfter(out TreeIter iter, TreeIter sibling) 377 { 378 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 379 380 gtk_list_store_insert_after(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct()); 381 382 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 383 } 384 385 /** 386 * Inserts a new row before @sibling. If @sibling is %NULL, then the row will 387 * be appended to the end of the list. @iter will be changed to point to this 388 * new row. The row will be empty after this function is called. To fill in 389 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 390 * 391 * Params: 392 * iter = An unset #GtkTreeIter to set to the new row 393 * sibling = A valid #GtkTreeIter, or %NULL 394 */ 395 public void insertBefore(out TreeIter iter, TreeIter sibling) 396 { 397 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 398 399 gtk_list_store_insert_before(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct()); 400 401 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 402 } 403 404 /** 405 * A variant of gtk_list_store_insert_with_values() which 406 * takes the columns and values as two arrays, instead of 407 * varargs. This function is mainly intended for 408 * language-bindings. 409 * 410 * Params: 411 * iter = An unset #GtkTreeIter to set to the new row, or %NULL. 412 * position = position to insert the new row, or -1 for last 413 * columns = an array of column numbers 414 * values = an array of GValues 415 * nValues = the length of the @columns and @values arrays 416 * 417 * Since: 2.6 418 */ 419 public void insertWithValuesv(out TreeIter iter, int position, int[] columns, Value[] values) 420 { 421 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 422 423 GValue[] valuesArray = new GValue[values.length]; 424 for ( int i = 0; i < values.length; i++ ) 425 { 426 valuesArray[i] = *(values[i].getValueStruct()); 427 } 428 429 gtk_list_store_insert_with_valuesv(gtkListStore, outiter, position, columns.ptr, valuesArray.ptr, cast(int)values.length); 430 431 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 432 } 433 434 /** 435 * > This function is slow. Only use it for debugging and/or testing 436 * > purposes. 437 * 438 * Checks if the given iter is a valid iter for this #GtkListStore. 439 * 440 * Params: 441 * iter = A #GtkTreeIter. 442 * 443 * Returns: %TRUE if the iter is valid, %FALSE if the iter is invalid. 444 * 445 * Since: 2.2 446 */ 447 public bool iterIsValid(TreeIter iter) 448 { 449 return gtk_list_store_iter_is_valid(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 450 } 451 452 /** 453 * Moves @iter in @store to the position after @position. Note that this 454 * function only works with unsorted stores. If @position is %NULL, @iter 455 * will be moved to the start of the list. 456 * 457 * Params: 458 * iter = A #GtkTreeIter. 459 * position = A #GtkTreeIter or %NULL. 460 * 461 * Since: 2.2 462 */ 463 public void moveAfter(TreeIter iter, TreeIter position) 464 { 465 gtk_list_store_move_after(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct()); 466 } 467 468 /** 469 * Moves @iter in @store to the position before @position. Note that this 470 * function only works with unsorted stores. If @position is %NULL, @iter 471 * will be moved to the end of the list. 472 * 473 * Params: 474 * iter = A #GtkTreeIter. 475 * position = A #GtkTreeIter, or %NULL. 476 * 477 * Since: 2.2 478 */ 479 public void moveBefore(TreeIter iter, TreeIter position) 480 { 481 gtk_list_store_move_before(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct()); 482 } 483 484 /** 485 * Prepends a new row to @list_store. @iter will be changed to point to this new 486 * row. The row will be empty after this function is called. To fill in 487 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 488 * 489 * Params: 490 * iter = An unset #GtkTreeIter to set to the prepend row 491 */ 492 public void prepend(out TreeIter iter) 493 { 494 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 495 496 gtk_list_store_prepend(gtkListStore, outiter); 497 498 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 499 } 500 501 /** 502 * Removes the given row from the list store. After being removed, 503 * @iter is set to be the next valid row, or invalidated if it pointed 504 * to the last row in @list_store. 505 * 506 * Params: 507 * iter = A valid #GtkTreeIter 508 * 509 * Returns: %TRUE if @iter is valid, %FALSE if not. 510 */ 511 public bool remove(TreeIter iter) 512 { 513 return gtk_list_store_remove(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 514 } 515 516 /** 517 * Reorders @store to follow the order indicated by @new_order. Note that 518 * this function only works with unsorted stores. 519 * 520 * Params: 521 * newOrder = an array of integers mapping the new 522 * position of each child to its old position before the re-ordering, 523 * i.e. @new_order`[newpos] = oldpos`. It must have 524 * exactly as many items as the list store’s length. 525 * 526 * Since: 2.2 527 */ 528 public void reorder(int[] newOrder) 529 { 530 gtk_list_store_reorder(gtkListStore, newOrder.ptr); 531 } 532 533 /** 534 * This function is meant primarily for #GObjects that inherit from #GtkListStore, 535 * and should only be used when constructing a new #GtkListStore. It will not 536 * function after a row has been added, or a method on the #GtkTreeModel 537 * interface is called. 538 * 539 * Params: 540 * nColumns = Number of columns for the list store 541 * types = An array length n of #GTypes 542 */ 543 public void setColumnTypes(GType[] types) 544 { 545 gtk_list_store_set_column_types(gtkListStore, cast(int)types.length, types.ptr); 546 } 547 548 /** 549 * See gtk_list_store_set(); this version takes a va_list for use by language 550 * bindings. 551 * 552 * Params: 553 * iter = A valid #GtkTreeIter for the row being modified 554 * varArgs = va_list of column/value pairs 555 */ 556 public void setValist(TreeIter iter, void* varArgs) 557 { 558 gtk_list_store_set_valist(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), varArgs); 559 } 560 561 /** 562 * Sets the data in the cell specified by @iter and @column. 563 * The type of @value must be convertible to the type of the 564 * column. 565 * 566 * Params: 567 * iter = A valid #GtkTreeIter for the row being modified 568 * column = column number to modify 569 * value = new value for the cell 570 */ 571 public void setValue(TreeIter iter, int column, Value value) 572 { 573 gtk_list_store_set_value(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), column, (value is null) ? null : value.getValueStruct()); 574 } 575 576 /** 577 * A variant of gtk_list_store_set_valist() which 578 * takes the columns and values as two arrays, instead of 579 * varargs. This function is mainly intended for 580 * language-bindings and in case the number of columns to 581 * change is not known until run-time. 582 * 583 * Params: 584 * iter = A valid #GtkTreeIter for the row being modified 585 * columns = an array of column numbers 586 * values = an array of GValues 587 * nValues = the length of the @columns and @values arrays 588 * 589 * Since: 2.12 590 */ 591 public void setValuesv(TreeIter iter, int[] columns, Value[] values) 592 { 593 GValue[] valuesArray = new GValue[values.length]; 594 for ( int i = 0; i < values.length; i++ ) 595 { 596 valuesArray[i] = *(values[i].getValueStruct()); 597 } 598 599 gtk_list_store_set_valuesv(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), columns.ptr, valuesArray.ptr, cast(int)values.length); 600 } 601 602 /** 603 * Swaps @a and @b in @store. Note that this function only works with 604 * unsorted stores. 605 * 606 * Params: 607 * a = A #GtkTreeIter. 608 * b = Another #GtkTreeIter. 609 * 610 * Since: 2.2 611 */ 612 public void swap(TreeIter a, TreeIter b) 613 { 614 gtk_list_store_swap(gtkListStore, (a is null) ? null : a.getTreeIterStruct(), (b is null) ? null : b.getTreeIterStruct()); 615 } 616 }