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