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 }