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