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.TreeSelection; 26 27 private import glib.ListG; 28 private import gobject.ObjectG; 29 private import gobject.Signals; 30 private import gtk.TreeIter; 31 private import gtk.TreeModelIF; 32 private import gtk.TreePath; 33 private import gtk.TreeView; 34 private import gtk.c.functions; 35 public import gtk.c.types; 36 public import gtkc.gtktypes; 37 private import std.algorithm; 38 39 40 /** 41 * The #GtkTreeSelection object is a helper object to manage the selection 42 * for a #GtkTreeView widget. The #GtkTreeSelection object is 43 * automatically created when a new #GtkTreeView widget is created, and 44 * cannot exist independently of this widget. The primary reason the 45 * #GtkTreeSelection objects exists is for cleanliness of code and API. 46 * That is, there is no conceptual reason all these functions could not be 47 * methods on the #GtkTreeView widget instead of a separate function. 48 * 49 * The #GtkTreeSelection object is gotten from a #GtkTreeView by calling 50 * gtk_tree_view_get_selection(). It can be manipulated to check the 51 * selection status of the tree, as well as select and deselect individual 52 * rows. Selection is done completely view side. As a result, multiple 53 * views of the same model can have completely different selections. 54 * Additionally, you cannot change the selection of a row on the model that 55 * is not currently displayed by the view without expanding its parents 56 * first. 57 * 58 * One of the important things to remember when monitoring the selection of 59 * a view is that the #GtkTreeSelection::changed signal is mostly a hint. 60 * That is, it may only emit one signal when a range of rows is selected. 61 * Additionally, it may on occasion emit a #GtkTreeSelection::changed signal 62 * when nothing has happened (mostly as a result of programmers calling 63 * select_row on an already selected row). 64 */ 65 public class TreeSelection : ObjectG 66 { 67 /** the main Gtk struct */ 68 protected GtkTreeSelection* gtkTreeSelection; 69 70 /** Get the main Gtk struct */ 71 public GtkTreeSelection* getTreeSelectionStruct(bool transferOwnership = false) 72 { 73 if (transferOwnership) 74 ownedRef = false; 75 return gtkTreeSelection; 76 } 77 78 /** the main Gtk struct as a void* */ 79 protected override void* getStruct() 80 { 81 return cast(void*)gtkTreeSelection; 82 } 83 84 /** 85 * Sets our main struct and passes it to the parent class. 86 */ 87 public this (GtkTreeSelection* gtkTreeSelection, bool ownedRef = false) 88 { 89 this.gtkTreeSelection = gtkTreeSelection; 90 super(cast(GObject*)gtkTreeSelection, ownedRef); 91 } 92 93 /** 94 * Returns an TreeIter set to the currently selected node if selection 95 * is set to Selection.SINGLE or Selection.BROWSE. 96 * This function will not work if you use selection is Selection.MULTIPLE. 97 * Returns: A TreeIter for the selected node. 98 */ 99 public TreeIter getSelected() 100 { 101 TreeModelIF model; 102 TreeIter iter = new TreeIter(); 103 104 if ( getSelected(model, iter) ) 105 { 106 iter.setModel(model); 107 return iter; 108 } 109 else 110 { 111 return null; 112 } 113 } 114 115 /** 116 * Creates a list of path of all selected rows. Additionally, if you are 117 * planning on modifying the model after calling this function, you may 118 * want to convert the returned list into a list of TreeRowReferences. 119 * Since: 2.2 120 * Params: 121 * model = A pointer to set to the GtkTreeModel, or NULL. 122 * Returns: 123 * A GList containing a GtkTreePath for each selected row. 124 */ 125 TreePath[] getSelectedRows(out TreeModelIF model) 126 { 127 TreePath[] paths; 128 GtkTreeModel* outmodel = null; 129 GList* gList = gtk_tree_selection_get_selected_rows(gtkTreeSelection, &outmodel); 130 if ( gList !is null ) 131 { 132 ListG list = new ListG(gList); 133 for ( int i=0 ; i<list.length() ; i++ ) 134 { 135 paths ~= new TreePath(cast(GtkTreePath*)list.nthData(i)); 136 } 137 } 138 model = ObjectG.getDObject!(TreeModelIF)(outmodel); 139 140 return paths; 141 } 142 143 /** 144 */ 145 146 /** */ 147 public static GType getType() 148 { 149 return gtk_tree_selection_get_type(); 150 } 151 152 /** 153 * Returns the number of rows that have been selected in @tree. 154 * 155 * Returns: The number of rows selected. 156 * 157 * Since: 2.2 158 */ 159 public int countSelectedRows() 160 { 161 return gtk_tree_selection_count_selected_rows(gtkTreeSelection); 162 } 163 164 /** 165 * Gets the selection mode for @selection. See 166 * gtk_tree_selection_set_mode(). 167 * 168 * Returns: the current selection mode 169 */ 170 public GtkSelectionMode getMode() 171 { 172 return gtk_tree_selection_get_mode(gtkTreeSelection); 173 } 174 175 /** 176 * Returns the current selection function. 177 * 178 * Returns: The function. 179 * 180 * Since: 2.14 181 */ 182 public GtkTreeSelectionFunc getSelectFunction() 183 { 184 return gtk_tree_selection_get_select_function(gtkTreeSelection); 185 } 186 187 /** 188 * Sets @iter to the currently selected node if @selection is set to 189 * #GTK_SELECTION_SINGLE or #GTK_SELECTION_BROWSE. @iter may be NULL if you 190 * just want to test if @selection has any selected nodes. @model is filled 191 * with the current model as a convenience. This function will not work if you 192 * use @selection is #GTK_SELECTION_MULTIPLE. 193 * 194 * Params: 195 * model = A pointer to set to the #GtkTreeModel, or NULL. 196 * iter = The #GtkTreeIter, or NULL. 197 * 198 * Returns: TRUE, if there is a selected node. 199 */ 200 public bool getSelected(out TreeModelIF model, out TreeIter iter) 201 { 202 GtkTreeModel* outmodel = null; 203 GtkTreeIter* outiter = gMalloc!GtkTreeIter(); 204 205 auto p = gtk_tree_selection_get_selected(gtkTreeSelection, &outmodel, outiter) != 0; 206 207 model = ObjectG.getDObject!(TreeModelIF)(outmodel); 208 iter = ObjectG.getDObject!(TreeIter)(outiter, true); 209 210 return p; 211 } 212 213 /** 214 * Returns the tree view associated with @selection. 215 * 216 * Returns: A #GtkTreeView 217 */ 218 public TreeView getTreeView() 219 { 220 auto p = gtk_tree_selection_get_tree_view(gtkTreeSelection); 221 222 if(p is null) 223 { 224 return null; 225 } 226 227 return ObjectG.getDObject!(TreeView)(cast(GtkTreeView*) p); 228 } 229 230 /** 231 * Returns the user data for the selection function. 232 * 233 * Returns: The user data. 234 */ 235 public void* getUserData() 236 { 237 return gtk_tree_selection_get_user_data(gtkTreeSelection); 238 } 239 240 /** 241 * Returns %TRUE if the row at @iter is currently selected. 242 * 243 * Params: 244 * iter = A valid #GtkTreeIter 245 * 246 * Returns: %TRUE, if @iter is selected 247 */ 248 public bool iterIsSelected(TreeIter iter) 249 { 250 return gtk_tree_selection_iter_is_selected(gtkTreeSelection, (iter is null) ? null : iter.getTreeIterStruct()) != 0; 251 } 252 253 /** 254 * Returns %TRUE if the row pointed to by @path is currently selected. If @path 255 * does not point to a valid location, %FALSE is returned 256 * 257 * Params: 258 * path = A #GtkTreePath to check selection on. 259 * 260 * Returns: %TRUE if @path is selected. 261 */ 262 public bool pathIsSelected(TreePath path) 263 { 264 return gtk_tree_selection_path_is_selected(gtkTreeSelection, (path is null) ? null : path.getTreePathStruct()) != 0; 265 } 266 267 /** 268 * Selects all the nodes. @selection must be set to #GTK_SELECTION_MULTIPLE 269 * mode. 270 */ 271 public void selectAll() 272 { 273 gtk_tree_selection_select_all(gtkTreeSelection); 274 } 275 276 /** 277 * Selects the specified iterator. 278 * 279 * Params: 280 * iter = The #GtkTreeIter to be selected. 281 */ 282 public void selectIter(TreeIter iter) 283 { 284 gtk_tree_selection_select_iter(gtkTreeSelection, (iter is null) ? null : iter.getTreeIterStruct()); 285 } 286 287 /** 288 * Select the row at @path. 289 * 290 * Params: 291 * path = The #GtkTreePath to be selected. 292 */ 293 public void selectPath(TreePath path) 294 { 295 gtk_tree_selection_select_path(gtkTreeSelection, (path is null) ? null : path.getTreePathStruct()); 296 } 297 298 /** 299 * Selects a range of nodes, determined by @start_path and @end_path inclusive. 300 * @selection must be set to #GTK_SELECTION_MULTIPLE mode. 301 * 302 * Params: 303 * startPath = The initial node of the range. 304 * endPath = The final node of the range. 305 */ 306 public void selectRange(TreePath startPath, TreePath endPath) 307 { 308 gtk_tree_selection_select_range(gtkTreeSelection, (startPath is null) ? null : startPath.getTreePathStruct(), (endPath is null) ? null : endPath.getTreePathStruct()); 309 } 310 311 /** 312 * Calls a function for each selected node. Note that you cannot modify 313 * the tree or selection from within this function. As a result, 314 * gtk_tree_selection_get_selected_rows() might be more useful. 315 * 316 * Params: 317 * func = The function to call for each selected node. 318 * data = user data to pass to the function. 319 */ 320 public void selectedForeach(GtkTreeSelectionForeachFunc func, void* data) 321 { 322 gtk_tree_selection_selected_foreach(gtkTreeSelection, func, data); 323 } 324 325 /** 326 * Sets the selection mode of the @selection. If the previous type was 327 * #GTK_SELECTION_MULTIPLE, then the anchor is kept selected, if it was 328 * previously selected. 329 * 330 * Params: 331 * type = The selection mode 332 */ 333 public void setMode(GtkSelectionMode type) 334 { 335 gtk_tree_selection_set_mode(gtkTreeSelection, type); 336 } 337 338 /** 339 * Sets the selection function. 340 * 341 * If set, this function is called before any node is selected or unselected, 342 * giving some control over which nodes are selected. The select function 343 * should return %TRUE if the state of the node may be toggled, and %FALSE 344 * if the state of the node should be left unchanged. 345 * 346 * Params: 347 * func = The selection function. May be %NULL 348 * data = The selection function’s data. May be %NULL 349 * destroy = The destroy function for user data. May be %NULL 350 */ 351 public void setSelectFunction(GtkTreeSelectionFunc func, void* data, GDestroyNotify destroy) 352 { 353 gtk_tree_selection_set_select_function(gtkTreeSelection, func, data, destroy); 354 } 355 356 /** 357 * Unselects all the nodes. 358 */ 359 public void unselectAll() 360 { 361 gtk_tree_selection_unselect_all(gtkTreeSelection); 362 } 363 364 /** 365 * Unselects the specified iterator. 366 * 367 * Params: 368 * iter = The #GtkTreeIter to be unselected. 369 */ 370 public void unselectIter(TreeIter iter) 371 { 372 gtk_tree_selection_unselect_iter(gtkTreeSelection, (iter is null) ? null : iter.getTreeIterStruct()); 373 } 374 375 /** 376 * Unselects the row at @path. 377 * 378 * Params: 379 * path = The #GtkTreePath to be unselected. 380 */ 381 public void unselectPath(TreePath path) 382 { 383 gtk_tree_selection_unselect_path(gtkTreeSelection, (path is null) ? null : path.getTreePathStruct()); 384 } 385 386 /** 387 * Unselects a range of nodes, determined by @start_path and @end_path 388 * inclusive. 389 * 390 * Params: 391 * startPath = The initial node of the range. 392 * endPath = The initial node of the range. 393 * 394 * Since: 2.2 395 */ 396 public void unselectRange(TreePath startPath, TreePath endPath) 397 { 398 gtk_tree_selection_unselect_range(gtkTreeSelection, (startPath is null) ? null : startPath.getTreePathStruct(), (endPath is null) ? null : endPath.getTreePathStruct()); 399 } 400 401 protected class OnChangedDelegateWrapper 402 { 403 void delegate(TreeSelection) dlg; 404 gulong handlerId; 405 406 this(void delegate(TreeSelection) dlg) 407 { 408 this.dlg = dlg; 409 onChangedListeners ~= this; 410 } 411 412 void remove(OnChangedDelegateWrapper source) 413 { 414 foreach(index, wrapper; onChangedListeners) 415 { 416 if (wrapper.handlerId == source.handlerId) 417 { 418 onChangedListeners[index] = null; 419 onChangedListeners = std.algorithm.remove(onChangedListeners, index); 420 break; 421 } 422 } 423 } 424 } 425 OnChangedDelegateWrapper[] onChangedListeners; 426 427 /** 428 * Emitted whenever the selection has (possibly) changed. Please note that 429 * this signal is mostly a hint. It may only be emitted once when a range 430 * of rows are selected, and it may occasionally be emitted when nothing 431 * has happened. 432 */ 433 gulong addOnChanged(void delegate(TreeSelection) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 434 { 435 auto wrapper = new OnChangedDelegateWrapper(dlg); 436 wrapper.handlerId = Signals.connectData( 437 this, 438 "changed", 439 cast(GCallback)&callBackChanged, 440 cast(void*)wrapper, 441 cast(GClosureNotify)&callBackChangedDestroy, 442 connectFlags); 443 return wrapper.handlerId; 444 } 445 446 extern(C) static void callBackChanged(GtkTreeSelection* treeselectionStruct, OnChangedDelegateWrapper wrapper) 447 { 448 wrapper.dlg(wrapper.outer); 449 } 450 451 extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure) 452 { 453 wrapper.remove(wrapper); 454 } 455 }