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