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  * Conversion parameters:
26  * inFile  = 
27  * outPack = gtk
28  * outFile = TreeIter
29  * strct   = GtkTreeIter
30  * realStrct=
31  * ctorStrct=
32  * clss    = TreeIter
33  * interf  = 
34  * class Code: Yes
35  * interface Code: No
36  * template for:
37  * extend  = 
38  * implements:
39  * prefixes:
40  * 	- gtk_tree_iter_
41  * omit structs:
42  * omit prefixes:
43  * omit code:
44  * omit signals:
45  * 	- row-changed
46  * 	- row-deleted
47  * 	- row-has-child-toggled
48  * 	- row-inserted
49  * 	- rows-reordered
50  * imports:
51  * 	- glib.Str
52  * 	- gtk.TreeModelIF
53  * 	- gtk.TreePath
54  * 	- gtk.TreeIterError
55  * 	- gobject.Value
56  * structWrap:
57  * 	- GtkTreeIter* -> TreeIter
58  * module aliases:
59  * local aliases:
60  * overrides:
61  */
62 
63 module gtk.TreeIter;
64 
65 public  import gtkc.gtktypes;
66 
67 private import gtkc.gtk;
68 private import glib.ConstructionException;
69 private import gobject.ObjectG;
70 
71 private import gobject.Signals;
72 public  import gtkc.gdktypes;
73 
74 private import glib.Str;
75 private import gtk.TreeModelIF;
76 private import gtk.TreePath;
77 private import gtk.TreeIterError;
78 private import gobject.Value;
79 
80 
81 
82 
83 /**
84  * Description
85  * The GtkTreeModel interface defines a generic tree interface for use by
86  * the GtkTreeView widget. It is an abstract interface, and is designed
87  * to be usable with any appropriate data structure. The programmer just
88  * has to implement this interface on their own data type for it to be
89  * viewable by a GtkTreeView widget.
90  * The model is represented as a hierarchical tree of strongly-typed,
91  * columned data. In other words, the model can be seen as a tree where
92  * every node has different values depending on which column is being
93  * queried. The type of data found in a column is determined by using the
94  * GType system (ie. G_TYPE_INT, GTK_TYPE_BUTTON, G_TYPE_POINTER, etc.).
95  * The types are homogeneous per column across all nodes. It is important
96  * to note that this interface only provides a way of examining a model and
97  * observing changes. The implementation of each individual model decides
98  * how and if changes are made.
99  * In order to make life simpler for programmers who do not need to write
100  * their own specialized model, two generic models are provided — the
101  * GtkTreeStore and the GtkListStore. To use these, the developer simply
102  * pushes data into these models as necessary. These models provide the
103  * data structure as well as all appropriate tree interfaces. As a result,
104  * implementing drag and drop, sorting, and storing data is trivial. For
105  * the vast majority of trees and lists, these two models are sufficient.
106  * Models are accessed on a node/column level of granularity. One can
107  * query for the value of a model at a certain node and a certain column
108  * on that node. There are two structures used to reference a particular
109  * node in a model. They are the GtkTreePath and the GtkTreeIter
110  * [4]
111  * Most of the interface consists of operations on a GtkTreeIter.
112  * A path is essentially a potential node. It is a location on a model
113  * that may or may not actually correspond to a node on a specific model.
114  * The GtkTreePath struct can be converted into either an array of
115  * unsigned integers or a string. The string form is a list of numbers
116  * separated by a colon. Each number refers to the offset at that level.
117  * Thus, the path “0” refers to the root node and the path
118  * “2:4” refers to the fifth child of the third node.
119  * By contrast, a GtkTreeIter is a reference to a specific node on a
120  * specific model. It is a generic struct with an integer and three
121  * generic pointers. These are filled in by the model in a model-specific
122  * way. One can convert a path to an iterator by calling
123  * gtk_tree_model_get_iter(). These iterators are the primary way of
124  * accessing a model and are similar to the iterators used by
125  * GtkTextBuffer. They are generally statically allocated on the stack and
126  * only used for a short time. The model interface defines a set of
127  * operations using them for navigating the model.
128  * It is expected that models fill in the iterator with private data. For
129  * example, the GtkListStore model, which is internally a simple linked
130  * list, stores a list node in one of the pointers. The GtkTreeModelSort
131  * stores an array and an offset in two of the pointers. Additionally,
132  * there is an integer field. This field is generally filled with a unique
133  * stamp per model. This stamp is for catching errors resulting from using
134  * invalid iterators with a model.
135  * The lifecycle of an iterator can be a little confusing at first.
136  * Iterators are expected to always be valid for as long as the model is
137  * unchanged (and doesn't emit a signal). The model is considered to own
138  * all outstanding iterators and nothing needs to be done to free them from
139  * the user's point of view. Additionally, some models guarantee that an
140  * iterator is valid for as long as the node it refers to is valid (most
141  * notably the GtkTreeStore and GtkListStore). Although generally
142  * uninteresting, as one always has to allow for the case where iterators
143  * do not persist beyond a signal, some very important performance
144  * enhancements were made in the sort model. As a result, the
145  * GTK_TREE_MODEL_ITERS_PERSIST flag was added to indicate this behavior.
146  * To help show some common operation of a model, some examples are
147  * provided. The first example shows three ways of getting the iter at the
148  * location “3:2:5”. While the first method shown is easier,
149  * the second is much more common, as you often get paths from callbacks.
150  * $(DDOC_COMMENT example)
151  * This second example shows a quick way of iterating through a list and
152  * getting a string and an integer from each row. The
153  * populate_model function used below is not shown, as
154  * it is specific to the GtkListStore. For information on how to write
155  * such a function, see the GtkListStore documentation.
156  * $(DDOC_COMMENT example)
157  */
158 public class TreeIter
159 {
160 	
161 	/** the main Gtk struct */
162 	protected GtkTreeIter* gtkTreeIter;
163 	
164 	
165 	public GtkTreeIter* getTreeIterStruct()
166 	{
167 		return gtkTreeIter;
168 	}
169 	
170 	
171 	/** the main Gtk struct as a void* */
172 	protected void* getStruct()
173 	{
174 		return cast(void*)gtkTreeIter;
175 	}
176 	
177 	/**
178 	 * Sets our main struct and passes it to the parent class
179 	 */
180 	public this (GtkTreeIter* gtkTreeIter)
181 	{
182 		this.gtkTreeIter = gtkTreeIter;
183 	}
184 	
185 	/**
186 	 * this will be set only when the iter
187 	 * is created from the model.
188 	 */
189 	GtkTreeModel* gtkTreeModel;
190 	
191 	/** */
192 	public void setModel(GtkTreeModel* gtkTreeModel)
193 	{
194 		this.gtkTreeModel = gtkTreeModel;
195 	}
196 	
197 	/** */
198 	public void setModel(TreeModelIF treeModel)
199 	{
200 		this.gtkTreeModel = treeModel.getTreeModelTStruct();
201 	}
202 	
203 	/**
204 	 * Throws: ConstructionException GTK+ fails to create the object.
205 	 */
206 	public this(TreeModelIF treeModel, string treePath)
207 	{
208 		this(treeModel, new TreePath(treePath));
209 	}
210 	
211 	/**
212 	 * Throws: ConstructionException GTK+ fails to create the object.
213 	 */
214 	public this(TreeModelIF treeModel, TreePath treePath)
215 	{
216 		this();
217 		setModel(treeModel);
218 		if ( !gtk_tree_model_get_iter_from_string(
219 		treeModel.getTreeModelTStruct(),
220 		getTreeIterStruct(), Str.toStringz(treePath.toString())) )
221 		{
222 			throw new ConstructionException("null returned by gtk_tree_model_get_iter_from_string");
223 		}
224 	}
225 	
226 	/**
227 	 * creates a new tree iteractor.
228 	 * used TreeView.createIter and TreeView.append() to create iteractor for a tree or list
229 	 */
230 	this()
231 	{
232 		this(new GtkTreeIter);
233 	}
234 	
235 	/**
236 	 * Get Value
237 	 * Params:
238 	 *  column =
239 	 *  value =
240 	 */
241 	void getValue(int column, Value value)
242 	{
243 		if ( gtkTreeModel  is  null )
244 		{
245 			throw new TreeIterError("getValue","Tree model not set");
246 		}
247 		gtk_tree_model_get_value(gtkTreeModel, gtkTreeIter, column, value.getValueStruct());
248 	}
249 	
250 	/**
251 	 * Get the value of a column as a string
252 	 * Params:
253 	 *  column = the column number
254 	 * Returns: a string representing the value of the column
255 	 */
256 	string getValueString(int column)
257 	{
258 		if ( gtkTreeModel  is  null )
259 		{
260 			throw new TreeIterError("getValueString","Tree model not set");
261 		}
262 		Value value = new Value();
263 		gtk_tree_model_get_value(gtkTreeModel, gtkTreeIter, column, value.getValueStruct());
264 		//printf("TreeIter.getValuaString = %.*s\n", value.getString().toString());
265 		return value.getString();
266 	}
267 	
268 	/**
269 	 * Get the value of a column as an int
270 	 * Params:
271 	 *  column = the column number
272 	 * Returns: a string representing the value of the column
273 	 */
274 	int getValueInt(int column)
275 	{
276 		if ( gtkTreeModel  is  null )
277 		{
278 			throw new TreeIterError("getValueInt", "Tree model not set");
279 		}
280 		Value value = new Value();
281 		gtk_tree_model_get_value(gtkTreeModel, gtkTreeIter, column, value.getValueStruct());
282 		return value.getInt();
283 	}
284 	
285 	/** */
286 	TreePath getTreePath()
287 	{
288 		if ( gtkTreeModel  is  null )
289 		{
290 			throw new TreeIterError("getTreePath","Tree model not set");
291 		}
292 		return new TreePath(gtk_tree_model_get_path(gtkTreeModel, gtkTreeIter));
293 	}
294 	
295 	/**
296 	 * This return the path visible to the user.
297 	 */
298 	string getVisiblePath(string separator)
299 	{
300 		string vPath;
301 		if ( gtkTreeModel  is  null )
302 		{
303 			throw new TreeIterError("getVisiblePath", "Tree model not set");
304 		}
305 		
306 		vPath = getValueString(0);
307 		TreeIter parent = getParent();
308 		while ( parent !is  null )
309 		{
310 			//printf("TreeIter.getVisiblePath parent = %.*s\n",parent.getValueString(0).toString());
311 			vPath = parent.getValueString(0) ~ separator ~ vPath;
312 			parent = parent.getParent();
313 		}
314 		
315 		//printf("TreeIter.getVisiblePath = %.*s\n", vPath.toString());
316 		
317 		return vPath;
318 	}
319 	
320 	/**
321 	 * Gets the parent of this iter
322 	 * Returns: the parent iter or null if can't get parent or an error occured
323 	 */
324 	TreeIter getParent()
325 	{
326 		if ( gtkTreeModel  is  null )
327 		{
328 			throw new TreeIterError("getParent", "Tree model not set");
329 		}
330 		TreeIter parent = new TreeIter();
331 		bool gotParent = gtk_tree_model_iter_parent(gtkTreeModel, parent.getTreeIterStruct(), gtkTreeIter) == 0 ? false : true;
332 		if ( !gotParent )
333 		{
334 			return null;
335 		}
336 		parent.setModel(gtkTreeModel);
337 		return parent;
338 	}
339 	
340 	/** */
341 	TreeIter getGrandParent()
342 	{
343 		if ( gtkTreeModel  is  null )
344 		{
345 			throw new TreeIterError("getGrandParent", "Tree model not set");
346 		}
347 		TreeIter grandParent = this;
348 		TreeIter parent = grandParent.getParent();
349 		while ( parent !is null )
350 		{
351 			grandParent = parent;
352 			parent = grandParent.getParent();
353 		}
354 		
355 		return grandParent;
356 	}
357 	
358 	/** A unique stamp to catch invalid iterators */
359 	public int stamp()
360 	{
361 		return gtkTreeIter.stamp;
362 	}
363 	
364 	/** Ditto */
365 	public void stamp(int stamp)
366 	{
367 		gtkTreeIter.stamp = stamp;
368 	}
369 	
370 	/** Model specific data */
371 	public void* userData()
372 	{
373 		return gtkTreeIter.userData;
374 	}
375 	
376 	/** Ditto */
377 	public void userData(void* data)
378 	{
379 		gtkTreeIter.userData = data;
380 	}
381 	
382 	public struct IterData
383 	{
384 		/// Data fields.
385 		union
386 		{
387 			int     dataInt;
388 			long    dataLong;
389 			double  dataFloat;
390 			double  dataDouble;
391 			string  dataString;
392 			
393 			void*   dataUser;
394 		}
395 		
396 		TypeInfo type = typeid(void);
397 	}
398 	
399 	/**
400 	 * setUserData and getUserData provide simple boxing
401 	 * around the userData field in the TreeIter struct.
402 	 * Throws: TreeIterError for unsuported types or a type mismatch.
403 	 * Example:
404 	 * ---
405 	 * Treeiter iter = new TreeIter();
406 	 *
407 	 * iter.setUserData(20);
408 	 * int i = iter.getUserData!(int)();
409 	 * ---
410 	 */
411 	public void setUserData(T)(T data)
412 	{
413 		IterData* itData = new IterData;
414 		itData.type = typeid(T);
415 		
416 		static if(is(T == int))
417 		{
418 			itData.dataInt = data;
419 		}
420 		else static if(is(T == long))
421 		{
422 			itData.dataLong = data;
423 		}
424 		else static if(is(T == float))
425 		{
426 			itData.dataFloat = data;
427 		}
428 		else static if(is(T == double))
429 		{
430 			itData.dataDouble = data;
431 		}
432 		else static if(is(T == string))
433 		{
434 			itData.dataString = data;
435 		}
436 		else static if(is(T == void*))
437 		{
438 			itData.dataUser = data;
439 		}
440 		else
441 		{
442 			pragma(msg, "IterData Type not Suported");
443 			
444 			throw new TreeIterError("getUserData", "IterData Type not Suported");
445 		}
446 		
447 		gtkTreeIter.userData = itData;
448 	}
449 	
450 	/** Ditto */
451 	public T getUserData(T)()
452 	{
453 		IterData* itData = cast(IterData*)gtkTreeIter.userData;
454 		
455 		static if(is(T == int))
456 		{
457 			if(itData.type is typeid(T))
458 			{
459 				return itData.dataInt;
460 			}
461 			else
462 			{
463 				throw new TreeIterError("getUserData", "IterData is not: int");
464 			}
465 		}
466 		else static if(is(T == long))
467 		{
468 			if(itData.type is typeid(T))
469 			{
470 				return itData.dataLong;
471 			}
472 			else
473 			{
474 				throw new TreeIterError("getUserData", "IterData is not: long");
475 			}
476 		}
477 		else static if(is(T == float))
478 		{
479 			if(itData.type is typeid(T))
480 			{
481 				return itData.dataFloat;
482 			}
483 			else
484 			{
485 				throw new TreeIterError("getUserData", "IterData is not: float");
486 			}
487 		}
488 		else static if(is(T == double))
489 		{
490 			if(itData.type is typeid(T))
491 			{
492 				return itData.dataDouble;
493 			}
494 			else
495 			{
496 				throw new TreeIterError("getUserData", "IterData is not: double");
497 			}
498 		}
499 		else static if(is(T == string))
500 		{
501 			if(itData.type is typeid(T))
502 			{
503 				return itData.dataString;
504 			}
505 			else
506 			{
507 				throw new TreeIterError("getUserData", "IterData is not: string");
508 			}
509 		}
510 		else static if(is(T == void*))
511 		{
512 			if(itData.type is typeid(T))
513 			{
514 				return itData.dataUser;
515 			}
516 			else
517 			{
518 				throw new TreeIterError("getUserData", "IterData is not: void*");
519 			}
520 		}
521 		else
522 		{
523 			pragma(msg, "IterData Type not Suported");
524 			
525 			throw new TreeIterError("getUserData", "IterData Type not Suported");
526 		}
527 	}
528 	
529 	/**
530 	 */
531 	
532 	/**
533 	 * Creates a dynamically allocated tree iterator as a copy of iter.
534 	 * This function is not intended for use in applications, because you
535 	 * can just copy the structs by value
536 	 * (GtkTreeIter new_iter = iter;).
537 	 * You must free this iter with gtk_tree_iter_free().
538 	 * Returns: a newly-allocated copy of iter.
539 	 */
540 	public TreeIter copy()
541 	{
542 		// GtkTreeIter * gtk_tree_iter_copy (GtkTreeIter *iter);
543 		auto p = gtk_tree_iter_copy(gtkTreeIter);
544 		
545 		if(p is null)
546 		{
547 			return null;
548 		}
549 		
550 		return ObjectG.getDObject!(TreeIter)(cast(GtkTreeIter*) p);
551 	}
552 	
553 	/**
554 	 * Frees an iterator that has been allocated by gtk_tree_iter_copy().
555 	 * This function is mainly used for language bindings.
556 	 */
557 	public void free()
558 	{
559 		// void gtk_tree_iter_free (GtkTreeIter *iter);
560 		gtk_tree_iter_free(gtkTreeIter);
561 	}
562 }