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