1 /*
2  * This file is part of d-dazzle.
3  *
4  * d-dazzle 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  * d-dazzle 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 d-dazzle; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 module dazzle.Tree;
20 
21 private import dazzle.TreeBuilder;
22 private import dazzle.TreeNode;
23 private import dazzle.c.functions;
24 public  import dazzle.c.types;
25 private import gio.MenuModel;
26 private import glib.Str;
27 private import gobject.ObjectG;
28 private import gobject.Signals;
29 private import gtk.BuildableIF;
30 private import gtk.BuildableT;
31 private import gtk.ScrollableIF;
32 private import gtk.ScrollableT;
33 private import gtk.TreeView;
34 private import gtk.Widget;
35 private import std.algorithm;
36 
37 
38 /** */
39 public class Tree : TreeView
40 {
41 	/** the main Gtk struct */
42 	protected DzlTree* dzlTree;
43 
44 	/** Get the main Gtk struct */
45 	public DzlTree* getTreeStruct(bool transferOwnership = false)
46 	{
47 		if (transferOwnership)
48 			ownedRef = false;
49 		return dzlTree;
50 	}
51 
52 	/** the main Gtk struct as a void* */
53 	protected override void* getStruct()
54 	{
55 		return cast(void*)dzlTree;
56 	}
57 
58 	/**
59 	 * Sets our main struct and passes it to the parent class.
60 	 */
61 	public this (DzlTree* dzlTree, bool ownedRef = false)
62 	{
63 		this.dzlTree = dzlTree;
64 		super(cast(GtkTreeView*)dzlTree, ownedRef);
65 	}
66 
67 
68 	/** */
69 	public static GType getType()
70 	{
71 		return dzl_tree_get_type();
72 	}
73 
74 	/**
75 	 * Add a builder to the tree.
76 	 *
77 	 * Params:
78 	 *     builder = A #DzlTreeBuilder to add.
79 	 */
80 	public void addBuilder(TreeBuilder builder)
81 	{
82 		dzl_tree_add_builder(dzlTree, (builder is null) ? null : builder.getTreeBuilderStruct());
83 	}
84 
85 	/** */
86 	public void expandToNode(TreeNode node)
87 	{
88 		dzl_tree_expand_to_node(dzlTree, (node is null) ? null : node.getTreeNodeStruct());
89 	}
90 
91 	/**
92 	 * Searches through the direct children of @node for a matching child.
93 	 * @find_func should return %TRUE if the child matches, otherwise %FALSE.
94 	 *
95 	 * Params:
96 	 *     node = A #DzlTreeNode
97 	 *     findFunc = A callback to locate the child
98 	 *     userData = user data for @find_func
99 	 *
100 	 * Returns: A #DzlTreeNode or %NULL.
101 	 */
102 	public TreeNode findChildNode(TreeNode node, DzlTreeFindFunc findFunc, void* userData)
103 	{
104 		auto p = dzl_tree_find_child_node(dzlTree, (node is null) ? null : node.getTreeNodeStruct(), findFunc, userData);
105 
106 		if(p is null)
107 		{
108 			return null;
109 		}
110 
111 		return ObjectG.getDObject!(TreeNode)(cast(DzlTreeNode*) p);
112 	}
113 
114 	/**
115 	 * Walks the entire tree looking for the first item that matches given
116 	 * @equal_func and @key.
117 	 *
118 	 * The first parameter to @equal_func will always be @key.
119 	 * The second parameter will be the nodes #DzlTreeNode:item property.
120 	 *
121 	 * Params:
122 	 *     equalFunc = A #GEqualFunc
123 	 *     key = the key for @equal_func
124 	 *
125 	 * Returns: A #DzlTreeNode or %NULL.
126 	 */
127 	public TreeNode findCustom(GEqualFunc equalFunc, void* key)
128 	{
129 		auto p = dzl_tree_find_custom(dzlTree, equalFunc, key);
130 
131 		if(p is null)
132 		{
133 			return null;
134 		}
135 
136 		return ObjectG.getDObject!(TreeNode)(cast(DzlTreeNode*) p);
137 	}
138 
139 	/**
140 	 * Finds a #DzlTreeNode with an item property matching @item.
141 	 *
142 	 * Params:
143 	 *     item = A #GObject or %NULL.
144 	 *
145 	 * Returns: A #DzlTreeNode or %NULL.
146 	 */
147 	public TreeNode findItem(ObjectG item)
148 	{
149 		auto p = dzl_tree_find_item(dzlTree, (item is null) ? null : item.getObjectGStruct());
150 
151 		if(p is null)
152 		{
153 			return null;
154 		}
155 
156 		return ObjectG.getDObject!(TreeNode)(cast(DzlTreeNode*) p);
157 	}
158 
159 	/**
160 	 * Returns: A #GMenuModel or %NULL.
161 	 */
162 	public MenuModel getContextMenu()
163 	{
164 		auto p = dzl_tree_get_context_menu(dzlTree);
165 
166 		if(p is null)
167 		{
168 			return null;
169 		}
170 
171 		return ObjectG.getDObject!(MenuModel)(cast(GMenuModel*) p);
172 	}
173 
174 	/**
175 	 * Retrieves the root node of the tree. The root node is not a visible node
176 	 * in the self, but a placeholder for all other builders to build upon.
177 	 *
178 	 * Returns: A #DzlTreeNode or %NULL.
179 	 */
180 	public TreeNode getRoot()
181 	{
182 		auto p = dzl_tree_get_root(dzlTree);
183 
184 		if(p is null)
185 		{
186 			return null;
187 		}
188 
189 		return ObjectG.getDObject!(TreeNode)(cast(DzlTreeNode*) p);
190 	}
191 
192 	/**
193 	 * Gets the currently selected node in the tree.
194 	 *
195 	 * Returns: A #DzlTreeNode.
196 	 */
197 	public TreeNode getSelected()
198 	{
199 		auto p = dzl_tree_get_selected(dzlTree);
200 
201 		if(p is null)
202 		{
203 			return null;
204 		}
205 
206 		return ObjectG.getDObject!(TreeNode)(cast(DzlTreeNode*) p);
207 	}
208 
209 	/** */
210 	public bool getShowIcons()
211 	{
212 		return dzl_tree_get_show_icons(dzlTree) != 0;
213 	}
214 
215 	/** */
216 	public void rebuild()
217 	{
218 		dzl_tree_rebuild(dzlTree);
219 	}
220 
221 	/**
222 	 * Removes a builder from the tree.
223 	 *
224 	 * Params:
225 	 *     builder = A #DzlTreeBuilder to remove.
226 	 */
227 	public void removeBuilder(TreeBuilder builder)
228 	{
229 		dzl_tree_remove_builder(dzlTree, (builder is null) ? null : builder.getTreeBuilderStruct());
230 	}
231 
232 	/** */
233 	public void scrollToNode(TreeNode node)
234 	{
235 		dzl_tree_scroll_to_node(dzlTree, (node is null) ? null : node.getTreeNodeStruct());
236 	}
237 
238 	/** */
239 	public void setContextMenu(MenuModel contextMenu)
240 	{
241 		dzl_tree_set_context_menu(dzlTree, (contextMenu is null) ? null : contextMenu.getMenuModelStruct());
242 	}
243 
244 	/**
245 	 * Sets the filter function to be used to determine visability of a tree node.
246 	 *
247 	 * Params:
248 	 *     filterFunc = A callback to determien visibility.
249 	 *     filterData = User data for @filter_func.
250 	 *     filterDataDestroy = Destroy notify for @filter_data.
251 	 */
252 	public void setFilter(DzlTreeFilterFunc filterFunc, void* filterData, GDestroyNotify filterDataDestroy)
253 	{
254 		dzl_tree_set_filter(dzlTree, filterFunc, filterData, filterDataDestroy);
255 	}
256 
257 	/**
258 	 * Sets the root node of the #DzlTree widget. This is used to build
259 	 * the items within the treeview. The item itself will not be added
260 	 * to the self, but the direct children will be.
261 	 *
262 	 * Params:
263 	 *     node = A #DzlTreeNode.
264 	 */
265 	public void setRoot(TreeNode node)
266 	{
267 		dzl_tree_set_root(dzlTree, (node is null) ? null : node.getTreeNodeStruct());
268 	}
269 
270 	/** */
271 	public void setShowIcons(bool showIcons)
272 	{
273 		dzl_tree_set_show_icons(dzlTree, showIcons);
274 	}
275 
276 	/**
277 	 * Unselects the currently selected node in the tree.
278 	 */
279 	public void unselectAll()
280 	{
281 		dzl_tree_unselect_all(dzlTree);
282 	}
283 
284 	/** */
285 	gulong addOnAction(void delegate(string, string, string, Tree) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
286 	{
287 		return Signals.connect(this, "action", dlg, connectFlags ^ ConnectFlags.SWAPPED);
288 	}
289 
290 	/** */
291 	gulong addOnPopulatePopup(void delegate(Widget, Tree) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
292 	{
293 		return Signals.connect(this, "populate-popup", dlg, connectFlags ^ ConnectFlags.SWAPPED);
294 	}
295 }