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() 189 { 190 return gtkListStore; 191 } 192 193 /** the main Gtk struct as a void* */ 194 protected override void* getStruct() 195 { 196 return cast(void*)gtkListStore; 197 } 198 199 protected override void setStruct(GObject* obj) 200 { 201 gtkListStore = cast(GtkListStore*)obj; 202 super.setStruct(obj); 203 } 204 205 /** 206 * Sets our main struct and passes it to the parent class. 207 */ 208 public this (GtkListStore* gtkListStore, bool ownedRef = false) 209 { 210 this.gtkListStore = gtkListStore; 211 super(cast(GObject*)gtkListStore, ownedRef); 212 } 213 214 // add the Buildable capabilities 215 mixin BuildableT!(GtkListStore); 216 217 // add the TreeDragDest capabilities 218 mixin TreeDragDestT!(GtkListStore); 219 220 // add the TreeDragSource capabilities 221 mixin TreeDragSourceT!(GtkListStore); 222 223 // add the TreeModel capabilities 224 mixin TreeModelT!(GtkListStore); 225 226 // add the TreeSortable capabilities 227 mixin TreeSortableT!(GtkListStore); 228 229 /** 230 * Creates a top level iteractor. 231 * I don't think lists have but the top level iteractor 232 */ 233 TreeIter createIter() 234 { 235 GtkTreeIter* iter = new GtkTreeIter; 236 gtk_list_store_append(getListStoreStruct(), iter); 237 return new TreeIter(iter); 238 } 239 240 /** 241 * sets the values for one row 242 * Params: 243 * iter = the row iteractor 244 * columns = an arrays with the columns to set 245 * values = an arrays with the values 246 */ 247 void set(TreeIter iter, int[] columns, char*[] values) 248 { 249 for ( int i=0 ; i<columns.length && i<values.length; i++ ) 250 { 251 gtk_list_store_set( 252 gtkListStore, 253 iter.getTreeIterStruct(), 254 columns[i], 255 values[i],-1); 256 } 257 } 258 259 /** ditto */ 260 void set(TreeIter iter, int[] columns, string[] values) 261 { 262 for ( int i=0 ; i<columns.length && i<values.length; i++ ) 263 { 264 gtk_list_store_set( 265 gtkListStore, 266 iter.getTreeIterStruct(), 267 columns[i], 268 Str.toStringz(values[i]),-1); 269 } 270 } 271 272 /** */ 273 void setValue(TreeIter iter, int column, string value) 274 { 275 Value v = new Value(value); 276 gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct()); 277 //gtk_list_store_set_value(obj(), iter.getIter(), column, (GValue*)cChar(value)); 278 } 279 280 /** */ 281 void setValue(TreeIter iter, int column, int value) 282 { 283 Value v = new Value(value); 284 gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct()); 285 } 286 287 /** 288 */ 289 290 /** */ 291 public static GType getType() 292 { 293 return gtk_list_store_get_type(); 294 } 295 296 /** 297 * Non-vararg creation function. Used primarily by language bindings. 298 * 299 * Params: 300 * nColumns = number of columns in the list store 301 * types = an array of #GType types for the columns, from first to last 302 * 303 * Return: a new #GtkListStore 304 * 305 * Throws: ConstructionException GTK+ fails to create the object. 306 */ 307 public this(GType[] types) 308 { 309 auto p = gtk_list_store_newv(cast(int)types.length, types.ptr); 310 311 if(p is null) 312 { 313 throw new ConstructionException("null returned by newv"); 314 } 315 316 this(cast(GtkListStore*) p, true); 317 } 318 319 /** 320 * Appends a new row to @list_store. @iter will be changed to point to this new 321 * row. The row will be empty after this function is called. To fill in 322 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 323 * 324 * Params: 325 * iter = An unset #GtkTreeIter to set to the appended row 326 */ 327 public void append(out TreeIter iter) 328 { 329 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 330 331 gtk_list_store_append(gtkListStore, outiter); 332 333 iter = ObjectG.getDObject!(TreeIter)(outiter); 334 } 335 336 /** 337 * Removes all rows from the list store. 338 */ 339 public void clear() 340 { 341 gtk_list_store_clear(gtkListStore); 342 } 343 344 /** 345 * Creates a new row at @position. @iter will be changed to point to this new 346 * row. If @position is -1 or is larger than the number of rows on the list, 347 * then the new row will be appended to the list. The row will be empty after 348 * this function is called. To fill in values, you need to call 349 * gtk_list_store_set() or gtk_list_store_set_value(). 350 * 351 * Params: 352 * iter = An unset #GtkTreeIter to set to the new row 353 * position = position to insert the new row, or -1 for last 354 */ 355 public void insert(out TreeIter iter, int position) 356 { 357 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 358 359 gtk_list_store_insert(gtkListStore, outiter, position); 360 361 iter = ObjectG.getDObject!(TreeIter)(outiter); 362 } 363 364 /** 365 * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be 366 * prepended to the beginning of the list. @iter will be changed to point to 367 * this new row. The row will be empty after this function is called. To fill 368 * in values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 369 * 370 * Params: 371 * iter = An unset #GtkTreeIter to set to the new row 372 * sibling = A valid #GtkTreeIter, or %NULL 373 */ 374 public void insertAfter(out TreeIter iter, TreeIter sibling) 375 { 376 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 377 378 gtk_list_store_insert_after(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct()); 379 380 iter = ObjectG.getDObject!(TreeIter)(outiter); 381 } 382 383 /** 384 * Inserts a new row before @sibling. If @sibling is %NULL, then the row will 385 * be appended to the end of the list. @iter will be changed to point to this 386 * new row. The row will be empty after this function is called. To fill in 387 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 388 * 389 * Params: 390 * iter = An unset #GtkTreeIter to set to the new row 391 * sibling = A valid #GtkTreeIter, or %NULL 392 */ 393 public void insertBefore(out TreeIter iter, TreeIter sibling) 394 { 395 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 396 397 gtk_list_store_insert_before(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct()); 398 399 iter = ObjectG.getDObject!(TreeIter)(outiter); 400 } 401 402 /** 403 * A variant of gtk_list_store_insert_with_values() which 404 * takes the columns and values as two arrays, instead of 405 * varargs. This function is mainly intended for 406 * language-bindings. 407 * 408 * Params: 409 * iter = An unset #GtkTreeIter to set to the new row, or %NULL. 410 * position = position to insert the new row, or -1 for last 411 * columns = an array of column numbers 412 * values = an array of GValues 413 * nValues = the length of the @columns and @values arrays 414 * 415 * Since: 2.6 416 */ 417 public void insertWithValuesv(out TreeIter iter, int position, int[] columns, Value[] values) 418 { 419 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 420 421 GValue[] valuesArray = new GValue[values.length]; 422 for ( int i = 0; i < values.length; i++ ) 423 { 424 valuesArray[i] = *(values[i].getValueStruct()); 425 } 426 427 gtk_list_store_insert_with_valuesv(gtkListStore, outiter, position, columns.ptr, valuesArray.ptr, cast(int)values.length); 428 429 iter = ObjectG.getDObject!(TreeIter)(outiter); 430 } 431 432 /** 433 * > This function is slow. Only use it for debugging and/or testing 434 * > purposes. 435 * 436 * Checks if the given iter is a valid iter for this #GtkListStore. 437 * 438 * Params: 439 * iter = A #GtkTreeIter. 440 * 441 * Return: %TRUE if the iter is valid, %FALSE if the iter is invalid. 442 * 443 * Since: 2.2 444 */ 445 public bool iterIsValid(TreeIter iter) 446 { 447 return gtk_list_store_iter_is_valid(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 448 } 449 450 /** 451 * Moves @iter in @store to the position after @position. Note that this 452 * function only works with unsorted stores. If @position is %NULL, @iter 453 * will be moved to the start of the list. 454 * 455 * Params: 456 * iter = A #GtkTreeIter. 457 * position = A #GtkTreeIter or %NULL. 458 * 459 * Since: 2.2 460 */ 461 public void moveAfter(TreeIter iter, TreeIter position) 462 { 463 gtk_list_store_move_after(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct()); 464 } 465 466 /** 467 * Moves @iter in @store to the position before @position. Note that this 468 * function only works with unsorted stores. If @position is %NULL, @iter 469 * will be moved to the end of the list. 470 * 471 * Params: 472 * iter = A #GtkTreeIter. 473 * position = A #GtkTreeIter, or %NULL. 474 * 475 * Since: 2.2 476 */ 477 public void moveBefore(TreeIter iter, TreeIter position) 478 { 479 gtk_list_store_move_before(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct()); 480 } 481 482 /** 483 * Prepends a new row to @list_store. @iter will be changed to point to this new 484 * row. The row will be empty after this function is called. To fill in 485 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value(). 486 * 487 * Params: 488 * iter = An unset #GtkTreeIter to set to the prepend row 489 */ 490 public void prepend(out TreeIter iter) 491 { 492 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 493 494 gtk_list_store_prepend(gtkListStore, outiter); 495 496 iter = ObjectG.getDObject!(TreeIter)(outiter); 497 } 498 499 /** 500 * Removes the given row from the list store. After being removed, 501 * @iter is set to be the next valid row, or invalidated if it pointed 502 * to the last row in @list_store. 503 * 504 * Params: 505 * iter = A valid #GtkTreeIter 506 * 507 * Return: %TRUE if @iter is valid, %FALSE if not. 508 */ 509 public bool remove(TreeIter iter) 510 { 511 return gtk_list_store_remove(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 512 } 513 514 /** 515 * Reorders @store to follow the order indicated by @new_order. Note that 516 * this function only works with unsorted stores. 517 * 518 * Params: 519 * newOrder = an array of integers mapping the new 520 * position of each child to its old position before the re-ordering, 521 * i.e. @new_order`[newpos] = oldpos`. It must have 522 * exactly as many items as the list store’s length. 523 * 524 * Since: 2.2 525 */ 526 public void reorder(int[] newOrder) 527 { 528 gtk_list_store_reorder(gtkListStore, newOrder.ptr); 529 } 530 531 /** 532 * This function is meant primarily for #GObjects that inherit from #GtkListStore, 533 * and should only be used when constructing a new #GtkListStore. It will not 534 * function after a row has been added, or a method on the #GtkTreeModel 535 * interface is called. 536 * 537 * Params: 538 * nColumns = Number of columns for the list store 539 * types = An array length n of #GTypes 540 */ 541 public void setColumnTypes(GType[] types) 542 { 543 gtk_list_store_set_column_types(gtkListStore, cast(int)types.length, types.ptr); 544 } 545 546 /** 547 * See gtk_list_store_set(); this version takes a va_list for use by language 548 * bindings. 549 * 550 * Params: 551 * iter = A valid #GtkTreeIter for the row being modified 552 * varArgs = va_list of column/value pairs 553 */ 554 public void setValist(TreeIter iter, void* varArgs) 555 { 556 gtk_list_store_set_valist(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), varArgs); 557 } 558 559 /** 560 * Sets the data in the cell specified by @iter and @column. 561 * The type of @value must be convertible to the type of the 562 * column. 563 * 564 * Params: 565 * iter = A valid #GtkTreeIter for the row being modified 566 * column = column number to modify 567 * value = new value for the cell 568 */ 569 public void setValue(TreeIter iter, int column, Value value) 570 { 571 gtk_list_store_set_value(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), column, (value is null) ? null : value.getValueStruct()); 572 } 573 574 /** 575 * A variant of gtk_list_store_set_valist() which 576 * takes the columns and values as two arrays, instead of 577 * varargs. This function is mainly intended for 578 * language-bindings and in case the number of columns to 579 * change is not known until run-time. 580 * 581 * Params: 582 * iter = A valid #GtkTreeIter for the row being modified 583 * columns = an array of column numbers 584 * values = an array of GValues 585 * nValues = the length of the @columns and @values arrays 586 * 587 * Since: 2.12 588 */ 589 public void setValuesv(TreeIter iter, int[] columns, Value[] values) 590 { 591 GValue[] valuesArray = new GValue[values.length]; 592 for ( int i = 0; i < values.length; i++ ) 593 { 594 valuesArray[i] = *(values[i].getValueStruct()); 595 } 596 597 gtk_list_store_set_valuesv(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), columns.ptr, valuesArray.ptr, cast(int)values.length); 598 } 599 600 /** 601 * Swaps @a and @b in @store. Note that this function only works with 602 * unsorted stores. 603 * 604 * Params: 605 * a = A #GtkTreeIter. 606 * b = Another #GtkTreeIter. 607 * 608 * Since: 2.2 609 */ 610 public void swap(TreeIter a, TreeIter b) 611 { 612 gtk_list_store_swap(gtkListStore, (a is null) ? null : a.getTreeIterStruct(), (b is null) ? null : b.getTreeIterStruct()); 613 } 614 }