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