1 /******************************************************************************* 2 * Copyright (c) 2000, 2008 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Port to the D programming language: 11 * Frank Benoit <benoit@tionex.de> 12 *******************************************************************************/ 13 module org.eclipse.swt.widgets.TreeItem; 14 15 import java.lang.all; 16 17 18 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.SWTException; 21 import org.eclipse.swt.graphics.Color; 22 import org.eclipse.swt.graphics.Font; 23 import org.eclipse.swt.graphics.Image; 24 import org.eclipse.swt.graphics.Rectangle; 25 import org.eclipse.swt.internal.gtk.OS; 26 import org.eclipse.swt.widgets.Item; 27 import org.eclipse.swt.widgets.Tree; 28 import org.eclipse.swt.widgets.ImageList; 29 30 31 /** 32 * Instances of this class represent a selectable user interface object 33 * that represents a hierarchy of tree items in a tree widget. 34 * 35 * <dl> 36 * <dt><b>Styles:</b></dt> 37 * <dd>(none)</dd> 38 * <dt><b>Events:</b></dt> 39 * <dd>(none)</dd> 40 * </dl> 41 * <p> 42 * IMPORTANT: This class is <em>not</em> intended to be subclassed. 43 * </p> 44 * 45 * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a> 46 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 47 */ 48 public class TreeItem : Item { 49 Tree parent; 50 Font font; 51 Font[] cellFont; 52 bool cached, grayed; 53 static const int EXPANDER_EXTRA_PADDING = 4; 54 55 /** 56 * Constructs a new instance of this class given its parent 57 * (which must be a <code>Tree</code> or a <code>TreeItem</code>) 58 * and a style value describing its behavior and appearance. 59 * The item is added to the end of the items maintained by its parent. 60 * <p> 61 * The style value is either one of the style constants defined in 62 * class <code>SWT</code> which is applicable to instances of this 63 * class, or must be built by <em>bitwise OR</em>'ing together 64 * (that is, using the <code>int</code> "|" operator) two or more 65 * of those <code>SWT</code> style constants. The class description 66 * lists the style constants that are applicable to the class. 67 * Style bits are also inherited from superclasses. 68 * </p> 69 * 70 * @param parent a tree control which will be the parent of the new instance (cannot be null) 71 * @param style the style of control to construct 72 * 73 * @exception IllegalArgumentException <ul> 74 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 75 * </ul> 76 * @exception SWTException <ul> 77 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 78 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 79 * </ul> 80 * 81 * @see SWT 82 * @see Widget#checkSubclass 83 * @see Widget#getStyle 84 */ 85 public this (Tree parent, int style) { 86 this (checkNull (parent), null, style, -1, true); 87 } 88 89 /** 90 * Constructs a new instance of this class given its parent 91 * (which must be a <code>Tree</code> or a <code>TreeItem</code>), 92 * a style value describing its behavior and appearance, and the index 93 * at which to place it in the items maintained by its parent. 94 * <p> 95 * The style value is either one of the style constants defined in 96 * class <code>SWT</code> which is applicable to instances of this 97 * class, or must be built by <em>bitwise OR</em>'ing together 98 * (that is, using the <code>int</code> "|" operator) two or more 99 * of those <code>SWT</code> style constants. The class description 100 * lists the style constants that are applicable to the class. 101 * Style bits are also inherited from superclasses. 102 * </p> 103 * 104 * @param parent a tree control which will be the parent of the new instance (cannot be null) 105 * @param style the style of control to construct 106 * @param index the zero-relative index to store the receiver in its parent 107 * 108 * @exception IllegalArgumentException <ul> 109 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 110 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> 111 * </ul> 112 * @exception SWTException <ul> 113 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 114 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 115 * </ul> 116 * 117 * @see SWT 118 * @see Widget#checkSubclass 119 * @see Widget#getStyle 120 */ 121 public this (Tree parent, int style, int index) { 122 this (checkNull (parent), null, style, checkIndex (index), true); 123 } 124 125 /** 126 * Constructs a new instance of this class given its parent 127 * (which must be a <code>Tree</code> or a <code>TreeItem</code>) 128 * and a style value describing its behavior and appearance. 129 * The item is added to the end of the items maintained by its parent. 130 * <p> 131 * The style value is either one of the style constants defined in 132 * class <code>SWT</code> which is applicable to instances of this 133 * class, or must be built by <em>bitwise OR</em>'ing together 134 * (that is, using the <code>int</code> "|" operator) two or more 135 * of those <code>SWT</code> style constants. The class description 136 * lists the style constants that are applicable to the class. 137 * Style bits are also inherited from superclasses. 138 * </p> 139 * 140 * @param parentItem a tree control which will be the parent of the new instance (cannot be null) 141 * @param style the style of control to construct 142 * 143 * @exception IllegalArgumentException <ul> 144 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 145 * </ul> 146 * @exception SWTException <ul> 147 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 148 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 149 * </ul> 150 * 151 * @see SWT 152 * @see Widget#checkSubclass 153 * @see Widget#getStyle 154 */ 155 public this (TreeItem parentItem, int style) { 156 this (checkNull (parentItem).parent, cast(GtkTreeIter*)parentItem.handle, style, -1, true); 157 } 158 159 /** 160 * Constructs a new instance of this class given its parent 161 * (which must be a <code>Tree</code> or a <code>TreeItem</code>), 162 * a style value describing its behavior and appearance, and the index 163 * at which to place it in the items maintained by its parent. 164 * <p> 165 * The style value is either one of the style constants defined in 166 * class <code>SWT</code> which is applicable to instances of this 167 * class, or must be built by <em>bitwise OR</em>'ing together 168 * (that is, using the <code>int</code> "|" operator) two or more 169 * of those <code>SWT</code> style constants. The class description 170 * lists the style constants that are applicable to the class. 171 * Style bits are also inherited from superclasses. 172 * </p> 173 * 174 * @param parentItem a tree control which will be the parent of the new instance (cannot be null) 175 * @param style the style of control to construct 176 * @param index the zero-relative index to store the receiver in its parent 177 * 178 * @exception IllegalArgumentException <ul> 179 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 180 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> 181 * </ul> 182 * @exception SWTException <ul> 183 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 184 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 185 * </ul> 186 * 187 * @see SWT 188 * @see Widget#checkSubclass 189 * @see Widget#getStyle 190 */ 191 public this (TreeItem parentItem, int style, int index) { 192 this (checkNull (parentItem).parent, cast(GtkTreeIter*)parentItem.handle, style, checkIndex (index), true); 193 } 194 195 this (Tree parent, GtkTreeIter* parentIter, int style, int index, bool create) { 196 super (parent, style); 197 this.parent = parent; 198 if (create) { 199 parent.createItem (this, parentIter, index); 200 } else { 201 handle = cast(GtkWidget*)OS.g_malloc (GtkTreeIter.sizeof); 202 OS.gtk_tree_model_iter_nth_child (parent.modelHandle, handle, parentIter, index); 203 } 204 } 205 206 static int checkIndex (int index) { 207 if (index < 0) SWT.error (SWT.ERROR_INVALID_RANGE); 208 return index; 209 } 210 211 static TreeItem checkNull (TreeItem item) { 212 if (item is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 213 return item; 214 } 215 216 static Tree checkNull (Tree control) { 217 if (control is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 218 return control; 219 } 220 221 protected override void checkSubclass () { 222 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); 223 } 224 225 Color _getBackground () { 226 void* ptr; 227 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.BACKGROUND_COLUMN, &ptr); 228 if (ptr is null) return parent.getBackground (); 229 GdkColor* gdkColor = new GdkColor (); 230 *gdkColor = *cast(GdkColor*) ptr; 231 return Color.gtk_new (display, gdkColor); 232 } 233 234 Color _getBackground (int index) { 235 int count = Math.max (1, parent.columnCount); 236 if (0 > index || index > count - 1) return _getBackground (); 237 void* ptr; 238 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 239 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_BACKGROUND, &ptr); 240 if (ptr is null) return _getBackground (); 241 GdkColor* gdkColor = new GdkColor (); 242 *gdkColor = *cast(GdkColor*) ptr; 243 return Color.gtk_new (display, gdkColor); 244 } 245 246 bool _getChecked () { 247 void* ptr; 248 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.CHECKED_COLUMN, &ptr); 249 return ptr !is null; 250 } 251 252 Color _getForeground () { 253 void* ptr; 254 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.FOREGROUND_COLUMN, &ptr); 255 if (ptr is null) return parent.getForeground (); 256 GdkColor* gdkColor = new GdkColor (); 257 *gdkColor = *cast(GdkColor*) ptr; 258 return Color.gtk_new (display, gdkColor); 259 } 260 261 Color _getForeground (int index) { 262 int count = Math.max (1, parent.columnCount); 263 if (0 > index || index > count - 1) return _getForeground (); 264 void* ptr; 265 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 266 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_FOREGROUND, &ptr); 267 if (ptr is null) return _getForeground (); 268 GdkColor* gdkColor = new GdkColor (); 269 *gdkColor = *cast(GdkColor*) ptr; 270 return Color.gtk_new (display, gdkColor); 271 } 272 273 Image _getImage (int index) { 274 int count = Math.max (1, parent.getColumnCount ()); 275 if (0 > index || index > count - 1) return null; 276 void* ptr; 277 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 278 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_PIXBUF, &ptr); 279 if (ptr is null) return null; 280 ImageList imageList = parent.imageList; 281 int imageIndex = imageList.indexOf (ptr); 282 if (imageIndex is -1) return null; 283 return imageList.get (imageIndex); 284 } 285 286 String _getText (int index) { 287 int count = Math.max (1, parent.getColumnCount ()); 288 if (0 > index || index > count - 1) return ""; 289 void* ptr; 290 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 291 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Tree.CELL_TEXT, &ptr); 292 if (ptr is null) return ""; //$NON-NLS-1$ 293 String buffer = fromStringz( cast(char*)ptr)._idup(); 294 OS.g_free (ptr); 295 return buffer; 296 } 297 298 void clear () { 299 if (parent.currentItem is this) return; 300 if (cached || (parent.style & SWT.VIRTUAL) is 0) { 301 int columnCount = OS.gtk_tree_model_get_n_columns (parent.modelHandle); 302 for (int i=Tree.CHECKED_COLUMN; i<columnCount; i++) { 303 OS.gtk_tree_store_set1(parent.modelHandle, cast(GtkTreeIter*)handle, i, null); 304 } 305 /* 306 * Bug in GTK. When using fixed-height-mode, 307 * row changes do not cause the row to be repainted. The fix is to 308 * invalidate the row when it is cleared. 309 */ 310 if ((parent.style & SWT.VIRTUAL) !is 0) { 311 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 312 redraw (); 313 } 314 } 315 } 316 cached = false; 317 font = null; 318 cellFont = null; 319 } 320 321 /** 322 * Clears the item at the given zero-relative index in the receiver. 323 * The text, icon and other attributes of the item are set to the default 324 * value. If the tree was created with the <code>SWT.VIRTUAL</code> style, 325 * these attributes are requested again as needed. 326 * 327 * @param index the index of the item to clear 328 * @param all <code>true</code> if all child items of the indexed item should be 329 * cleared recursively, and <code>false</code> otherwise 330 * 331 * @exception IllegalArgumentException <ul> 332 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> 333 * </ul> 334 * @exception SWTException <ul> 335 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 336 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 337 * </ul> 338 * 339 * @see SWT#VIRTUAL 340 * @see SWT#SetData 341 * 342 * @since 3.2 343 */ 344 public void clear (int index, bool all) { 345 checkWidget (); 346 parent.clear (cast(GtkTreeIter*)handle, index, all); 347 } 348 349 /** 350 * Clears all the items in the receiver. The text, icon and other 351 * attributes of the items are set to their default values. If the 352 * tree was created with the <code>SWT.VIRTUAL</code> style, these 353 * attributes are requested again as needed. 354 * 355 * @param all <code>true</code> if all child items should be cleared 356 * recursively, and <code>false</code> otherwise 357 * 358 * @exception SWTException <ul> 359 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 360 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 361 * </ul> 362 * 363 * @see SWT#VIRTUAL 364 * @see SWT#SetData 365 * 366 * @since 3.2 367 */ 368 public void clearAll (bool all) { 369 checkWidget (); 370 parent.clearAll (all, cast(GtkTreeIter*)handle); 371 } 372 373 override void destroyWidget () { 374 parent.releaseItem (this, false); 375 parent.destroyItem (this); 376 releaseHandle (); 377 } 378 379 /** 380 * Returns the receiver's background color. 381 * 382 * @return the background color 383 * 384 * @exception SWTException <ul> 385 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 386 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 387 * </ul> 388 * 389 * @since 2.0 390 * 391 */ 392 public Color getBackground () { 393 checkWidget (); 394 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 395 return _getBackground (); 396 } 397 398 /** 399 * Returns the background color at the given column index in the receiver. 400 * 401 * @param index the column index 402 * @return the background color 403 * 404 * @exception SWTException <ul> 405 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 406 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 407 * </ul> 408 * 409 * @since 3.1 410 */ 411 public Color getBackground (int index) { 412 checkWidget (); 413 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 414 return _getBackground (index); 415 } 416 417 /** 418 * Returns a rectangle describing the receiver's size and location 419 * relative to its parent at a column in the tree. 420 * 421 * @param index the index that specifies the column 422 * @return the receiver's bounding column rectangle 423 * 424 * @exception SWTException <ul> 425 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 426 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 427 * </ul> 428 * 429 * @since 3.1 430 */ 431 public Rectangle getBounds (int index) { 432 // TODO fully test on early and later versions of GTK 433 checkWidget(); 434 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 435 auto parentHandle = parent.handle; 436 GtkTreeViewColumn* column; 437 if (index >= 0 && index < parent.columnCount) { 438 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 439 } else { 440 column = OS.gtk_tree_view_get_column (parentHandle, index); 441 } 442 if (column is null) return new Rectangle (0, 0, 0, 0); 443 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 444 OS.gtk_widget_realize (parentHandle); 445 GdkRectangle rect; 446 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 447 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 448 449 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { 450 int buffer; 451 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); 452 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; 453 rect.width -= buffer + TreeItem.EXPANDER_EXTRA_PADDING; 454 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 455 rect.x += buffer; 456 //rect.width -= buffer [0]; // TODO Is this required for some versions? 457 } 458 /* 459 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even 460 * when the widget is mirrored. The fix is to sum up the indentation 461 * of the expanders. 462 */ 463 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { 464 int depth = OS.gtk_tree_path_get_depth (path); 465 int expanderSize; 466 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); 467 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); 468 } 469 OS.gtk_tree_path_free (path); 470 471 if (index is 0 && (parent.style & SWT.CHECK) !is 0) { 472 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 473 int x, w; 474 OS.gtk_tree_view_column_cell_get_position (column, parent.checkRenderer, &x, &w); 475 rect.x += x + w; 476 rect.width -= x + w; 477 } else { 478 int w; 479 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); 480 int buffer; 481 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 482 rect.x += w + buffer; 483 rect.width -= w + buffer; 484 } 485 } 486 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; 487 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 488 } 489 490 /** 491 * Returns a rectangle describing the receiver's size and location 492 * relative to its parent. 493 * 494 * @return the receiver's bounding rectangle 495 * 496 * @exception SWTException <ul> 497 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 498 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 499 * </ul> 500 */ 501 public Rectangle getBounds () { 502 // TODO fully test on early and later versions of GTK 503 // shifted a bit too far right on later versions of GTK - however, old Tree also had this problem 504 checkWidget (); 505 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 506 auto parentHandle = parent.handle; 507 auto column = OS.gtk_tree_view_get_column (parentHandle, 0); 508 if (column is null) return new Rectangle (0, 0, 0, 0); 509 auto textRenderer = parent.getTextRenderer (column); 510 auto pixbufRenderer = parent.getPixbufRenderer (column); 511 if (textRenderer is null || pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); 512 513 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 514 OS.gtk_widget_realize (parentHandle); 515 516 bool isExpander = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle) > 0; 517 bool isExpanded = cast(bool)OS.gtk_tree_view_row_expanded (parentHandle, path); 518 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, isExpander, isExpanded); 519 520 GdkRectangle rect; 521 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 522 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 523 int right = rect.x + rect.width; 524 525 int x, w; 526 parent.ignoreSize = true; 527 OS.gtk_cell_renderer_get_size (textRenderer, parentHandle, null, null, null, &w, null); 528 parent.ignoreSize = false; 529 rect.width = w; 530 int buffer; 531 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { 532 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); 533 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; 534 } 535 /* 536 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even 537 * when the widget is mirrored. The fix is to sum up the indentation 538 * of the expanders. 539 */ 540 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { 541 int depth = OS.gtk_tree_path_get_depth (path); 542 int expanderSize; 543 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); 544 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); 545 } 546 OS.gtk_tree_path_free (path); 547 548 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 549 int horizontalSeparator = buffer; 550 rect.x += horizontalSeparator; 551 552 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 553 OS.gtk_tree_view_column_cell_get_position (column, textRenderer, &x, null); 554 rect.x += x; 555 } else { 556 if ((parent.style & SWT.CHECK) !is 0) { 557 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); 558 rect.x += w + horizontalSeparator; 559 } 560 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); 561 rect.x += w + horizontalSeparator; 562 } 563 if (parent.columnCount > 0) { 564 if (rect.x + rect.width > right) { 565 rect.width = Math.max (0, right - rect.x); 566 } 567 } 568 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; 569 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 570 } 571 572 /** 573 * Returns <code>true</code> if the receiver is checked, 574 * and false otherwise. When the parent does not have 575 * the <code>CHECK style, return false. 576 * <p> 577 * 578 * @return the checked state 579 * 580 * @exception SWTException <ul> 581 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 582 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 583 * </ul> 584 */ 585 public bool getChecked () { 586 checkWidget(); 587 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 588 if ((parent.style & SWT.CHECK) is 0) return false; 589 return _getChecked (); 590 } 591 592 /** 593 * Returns <code>true</code> if the receiver is expanded, 594 * and false otherwise. 595 * <p> 596 * 597 * @return the expanded state 598 * 599 * @exception SWTException <ul> 600 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 601 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 602 * </ul> 603 */ 604 public bool getExpanded () { 605 checkWidget(); 606 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 607 bool answer = cast(bool)OS.gtk_tree_view_row_expanded (parent.handle, path); 608 OS.gtk_tree_path_free (path); 609 return answer; 610 } 611 612 /** 613 * Returns the font that the receiver will use to paint textual information for this item. 614 * 615 * @return the receiver's font 616 * 617 * @exception SWTException <ul> 618 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 619 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 620 * </ul> 621 * 622 * @since 3.0 623 */ 624 public Font getFont () { 625 checkWidget (); 626 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 627 return font !is null ? font : parent.getFont (); 628 } 629 630 /** 631 * Returns the font that the receiver will use to paint textual information 632 * for the specified cell in this item. 633 * 634 * @param index the column index 635 * @return the receiver's font 636 * 637 * @exception SWTException <ul> 638 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 639 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 640 * </ul> 641 * 642 * @since 3.1 643 */ 644 public Font getFont (int index) { 645 checkWidget (); 646 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 647 int count = Math.max (1, parent.columnCount); 648 if (0 > index || index > count - 1) return getFont (); 649 if (cellFont is null || cellFont [index] is null) return getFont (); 650 return cellFont [index]; 651 } 652 653 654 /** 655 * Returns the foreground color that the receiver will use to draw. 656 * 657 * @return the receiver's foreground color 658 * 659 * @exception SWTException <ul> 660 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 661 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 662 * </ul> 663 * 664 * @since 2.0 665 * 666 */ 667 public Color getForeground () { 668 checkWidget (); 669 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 670 return _getForeground (); 671 } 672 673 /** 674 * 675 * Returns the foreground color at the given column index in the receiver. 676 * 677 * @param index the column index 678 * @return the foreground color 679 * 680 * @exception SWTException <ul> 681 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 682 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 683 * </ul> 684 * 685 * @since 3.1 686 */ 687 public Color getForeground (int index) { 688 checkWidget (); 689 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 690 return _getForeground (index); 691 } 692 693 /** 694 * Returns <code>true</code> if the receiver is grayed, 695 * and false otherwise. When the parent does not have 696 * the <code>CHECK style, return false. 697 * <p> 698 * 699 * @return the grayed state of the checkbox 700 * 701 * @exception SWTException <ul> 702 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 703 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 704 * </ul> 705 */ 706 public bool getGrayed () { 707 checkWidget (); 708 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 709 if ((parent.style & SWT.CHECK) is 0) return false; 710 return grayed; 711 } 712 713 public override Image getImage () { 714 checkWidget (); 715 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 716 return getImage (0); 717 } 718 719 /** 720 * Returns the image stored at the given column index in the receiver, 721 * or null if the image has not been set or if the column does not exist. 722 * 723 * @param index the column index 724 * @return the image stored at the given column index in the receiver 725 * 726 * @exception SWTException <ul> 727 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 728 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 729 * </ul> 730 * 731 * @since 3.1 732 */ 733 public Image getImage (int index) { 734 checkWidget (); 735 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 736 return _getImage (index); 737 } 738 739 /** 740 * Returns a rectangle describing the size and location 741 * relative to its parent of an image at a column in the 742 * tree. 743 * 744 * @param index the index that specifies the column 745 * @return the receiver's bounding image rectangle 746 * 747 * @exception SWTException <ul> 748 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 749 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 750 * </ul> 751 * 752 * @since 3.1 753 */ 754 public Rectangle getImageBounds (int index) { 755 // TODO fully test on early and later versions of GTK 756 checkWidget (); 757 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 758 auto parentHandle = parent.handle; 759 GtkTreeViewColumn* column; 760 if (index >= 0 && index < parent.getColumnCount ()) { 761 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 762 } else { 763 column = OS.gtk_tree_view_get_column (parentHandle, index); 764 } 765 if (column is null) return new Rectangle (0, 0, 0, 0); 766 auto pixbufRenderer = parent.getPixbufRenderer (column); 767 if (pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); 768 GdkRectangle rect; 769 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 770 OS.gtk_widget_realize (parentHandle); 771 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 772 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 773 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { 774 int buffer; 775 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); 776 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; 777 rect.width -= buffer + TreeItem.EXPANDER_EXTRA_PADDING; 778 //OS.gtk_widget_style_get (parentHandle, OS.horizontal_separator, buffer, 0); 779 //int horizontalSeparator = buffer[0]; 780 //rect.x += horizontalSeparator; 781 } 782 /* 783 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even 784 * when the widget is mirrored. The fix is to sum up the indentation 785 * of the expanders. 786 */ 787 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { 788 int depth = OS.gtk_tree_path_get_depth (path); 789 int expanderSize; 790 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); 791 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); 792 } 793 OS.gtk_tree_path_free (path); 794 795 /* 796 * The OS call gtk_cell_renderer_get_size() provides the width of image to be drawn 797 * by the cell renderer. If there is no image in the cell, the width is zero. If the table contains 798 * images of varying widths, gtk_cell_renderer_get_size() will return the width of the image, 799 * not the width of the area in which the image is drawn. 800 * New API was added in GTK 2.1.3 for determining the full width of the renderer area. 801 * For earlier versions of GTK, the result is only correct if all rows have images of the same 802 * width. 803 */ 804 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 805 int x, w; 806 OS.gtk_tree_view_column_cell_get_position (column, pixbufRenderer, &x, &w); 807 rect.x += x; 808 rect.width = w; 809 } else { 810 int w; 811 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, false, false); 812 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); 813 rect.width = w; 814 } 815 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width : 0; 816 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 817 } 818 819 /** 820 * Returns the number of items contained in the receiver 821 * that are direct item children of the receiver. 822 * 823 * @return the number of items 824 * 825 * @exception SWTException <ul> 826 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 827 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 828 * </ul> 829 */ 830 public int getItemCount () { 831 checkWidget(); 832 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 833 return OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle); 834 } 835 836 /** 837 * Returns the item at the given, zero-relative index in the 838 * receiver. Throws an exception if the index is out of range. 839 * 840 * @param index the index of the item to return 841 * @return the item at the given index 842 * 843 * @exception IllegalArgumentException <ul> 844 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> 845 * </ul> 846 * @exception SWTException <ul> 847 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 848 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 849 * </ul> 850 * 851 * @since 3.1 852 */ 853 public TreeItem getItem (int index) { 854 checkWidget(); 855 if (index < 0) error (SWT.ERROR_INVALID_RANGE); 856 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 857 int itemCount = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle); 858 if (index >= itemCount) error (SWT.ERROR_INVALID_RANGE); 859 return parent._getItem (cast(GtkTreeIter*)handle, index); 860 } 861 862 /** 863 * Returns a (possibly empty) array of <code>TreeItem</code>s which 864 * are the direct item children of the receiver. 865 * <p> 866 * Note: This is not the actual structure used by the receiver 867 * to maintain its list of items, so modifying the array will 868 * not affect the receiver. 869 * </p> 870 * 871 * @return the receiver's items 872 * 873 * @exception SWTException <ul> 874 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 875 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 876 * </ul> 877 */ 878 public TreeItem [] getItems () { 879 checkWidget(); 880 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 881 return parent.getItems (cast(GtkTreeIter*)handle); 882 } 883 884 override String getNameText () { 885 if ((parent.style & SWT.VIRTUAL) !is 0) { 886 if (!cached) return "*virtual*"; //$NON-NLS-1$ 887 } 888 return super.getNameText (); 889 } 890 891 /** 892 * Returns the receiver's parent, which must be a <code>Tree</code>. 893 * 894 * @return the receiver's parent 895 * 896 * @exception SWTException <ul> 897 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 898 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 899 * </ul> 900 */ 901 public Tree getParent () { 902 checkWidget (); 903 return parent; 904 } 905 906 /** 907 * Returns the receiver's parent item, which must be a 908 * <code>TreeItem</code> or null when the receiver is a 909 * root. 910 * 911 * @return the receiver's parent item 912 * 913 * @exception SWTException <ul> 914 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 915 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 916 * </ul> 917 */ 918 public TreeItem getParentItem () { 919 checkWidget(); 920 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 921 TreeItem item = null; 922 int depth = OS.gtk_tree_path_get_depth (path); 923 if (depth > 1) { 924 OS.gtk_tree_path_up (path); 925 GtkTreeIter iter; 926 if (OS.gtk_tree_model_get_iter (parent.modelHandle, &iter, path)) { 927 item = parent._getItem (&iter); 928 } 929 } 930 OS.gtk_tree_path_free (path); 931 return item; 932 } 933 934 public override String getText () { 935 checkWidget (); 936 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 937 return getText (0); 938 } 939 940 /** 941 * Returns the text stored at the given column index in the receiver, 942 * or empty string if the text has not been set. 943 * 944 * @param index the column index 945 * @return the text stored at the given column index in the receiver 946 * 947 * @exception SWTException <ul> 948 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 949 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 950 * </ul> 951 * 952 * @since 3.1 953 */ 954 public String getText (int index) { 955 checkWidget (); 956 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 957 return _getText (index); 958 } 959 960 /** 961 * Returns a rectangle describing the size and location 962 * relative to its parent of the text at a column in the 963 * tree. 964 * 965 * @param index the index that specifies the column 966 * @return the receiver's bounding text rectangle 967 * 968 * @exception SWTException <ul> 969 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 970 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 971 * </ul> 972 * 973 * @since 3.3 974 */ 975 public Rectangle getTextBounds (int index) { 976 checkWidget (); 977 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 978 int count = Math.max (1, parent.getColumnCount ()); 979 if (0 > index || index > count - 1) return new Rectangle (0, 0, 0, 0); 980 // TODO fully test on early and later versions of GTK 981 // shifted a bit too far right on later versions of GTK - however, old Tree also had this problem 982 auto parentHandle = parent.handle; 983 GtkTreeViewColumn* column; 984 if (index >= 0 && index < parent.columnCount) { 985 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 986 } else { 987 column = OS.gtk_tree_view_get_column (parentHandle, index); 988 } 989 if (column is null) return new Rectangle (0, 0, 0, 0); 990 auto textRenderer = parent.getTextRenderer (column); 991 auto pixbufRenderer = parent.getPixbufRenderer (column); 992 if (textRenderer is null || pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); 993 994 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 995 OS.gtk_widget_realize (parentHandle); 996 997 bool isExpander = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle) > 0; 998 bool isExpanded = cast(bool)OS.gtk_tree_view_row_expanded (parentHandle, path); 999 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, isExpander, isExpanded); 1000 1001 GdkRectangle rect; 1002 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 1003 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 1004 int right = rect.x + rect.width; 1005 1006 int x, w; 1007 parent.ignoreSize = true; 1008 OS.gtk_cell_renderer_get_size (textRenderer, parentHandle, null, null, null, &w, null); 1009 parent.ignoreSize = false; 1010 int buffer; 1011 if (OS.GTK_VERSION < OS.buildVERSION (2, 8, 18) && OS.gtk_tree_view_get_expander_column (parentHandle) is column) { 1012 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); 1013 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; 1014 } 1015 /* 1016 * Bug in GTK. In GTK 2.8.x, the cell area is left aligned even 1017 * when the widget is mirrored. The fix is to sum up the indentation 1018 * of the expanders. 1019 */ 1020 if ((parent.getStyle () & SWT.MIRRORED) !is 0 && (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0))) { 1021 int depth = OS.gtk_tree_path_get_depth (path); 1022 int expanderSize; 1023 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &expanderSize); 1024 rect.x += depth * (expanderSize + TreeItem.EXPANDER_EXTRA_PADDING); 1025 } 1026 OS.gtk_tree_path_free (path); 1027 1028 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 1029 int horizontalSeparator = buffer; 1030 rect.x += horizontalSeparator; 1031 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 1032 OS.gtk_tree_view_column_cell_get_position (column, textRenderer, &x, null); 1033 rect.x += x; 1034 } else { 1035 if ((parent.style & SWT.CHECK) !is 0) { 1036 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); 1037 rect.x += w + horizontalSeparator; 1038 } 1039 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); 1040 rect.x += w + horizontalSeparator; 1041 } 1042 if (parent.columnCount > 0) { 1043 if (rect.x + rect.width > right) { 1044 rect.width = Math.max (0, right - rect.x); 1045 } 1046 } 1047 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; 1048 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 1049 } 1050 1051 /** 1052 * Searches the receiver's list starting at the first item 1053 * (index 0) until an item is found that is equal to the 1054 * argument, and returns the index of that item. If no item 1055 * is found, returns -1. 1056 * 1057 * @param item the search item 1058 * @return the index of the item 1059 * 1060 * @exception IllegalArgumentException <ul> 1061 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> 1062 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> 1063 * </ul> 1064 * @exception SWTException <ul> 1065 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1066 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1067 * </ul> 1068 * 1069 * @since 3.1 1070 */ 1071 public int indexOf (TreeItem item) { 1072 checkWidget(); 1073 if (item is null) error (SWT.ERROR_NULL_ARGUMENT); 1074 if (item.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); 1075 int index = -1; 1076 bool isParent = false; 1077 auto currentPath = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 1078 auto parentPath = OS.gtk_tree_model_get_path (parent.modelHandle, item.handle); 1079 int depth = OS.gtk_tree_path_get_depth (parentPath); 1080 if (depth > 1 && OS.gtk_tree_path_up(parentPath)) { 1081 if (OS.gtk_tree_path_compare(currentPath, parentPath) is 0) isParent = true; 1082 } 1083 OS.gtk_tree_path_free (currentPath); 1084 OS.gtk_tree_path_free (parentPath); 1085 if (!isParent) return index; 1086 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, item.handle); 1087 if (depth > 1) { 1088 auto indices = OS.gtk_tree_path_get_indices (path); 1089 if (indices !is null) { 1090 int[] temp = indices[ 0 .. depth]; 1091 index = temp[temp.length - 1]; 1092 } 1093 } 1094 OS.gtk_tree_path_free (path); 1095 return index; 1096 } 1097 1098 void redraw () { 1099 auto parentHandle = parent.handle; 1100 if ((OS.GTK_WIDGET_FLAGS (parentHandle) & OS.GTK_REALIZED) !is 0) { 1101 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 1102 GdkRectangle rect; 1103 OS.gtk_tree_view_get_cell_area (parentHandle, path, null, &rect); 1104 OS.gtk_tree_path_free (path); 1105 auto window = OS.gtk_tree_view_get_bin_window (parentHandle); 1106 rect.x = 0; 1107 int w, h; 1108 OS.gdk_drawable_get_size (window, &w, &h); 1109 rect.width = w; 1110 OS.gdk_window_invalidate_rect (window, &rect, false); 1111 } 1112 } 1113 1114 override void releaseChildren (bool destroy) { 1115 if (destroy) { 1116 parent.releaseItems (cast(GtkTreeIter*)handle); 1117 } 1118 super.releaseChildren (destroy); 1119 } 1120 1121 override void releaseHandle () { 1122 if (handle !is null) OS.g_free (handle); 1123 handle = null; 1124 super.releaseHandle (); 1125 parent = null; 1126 } 1127 1128 override void releaseWidget () { 1129 super.releaseWidget (); 1130 font = null; 1131 cellFont = null; 1132 } 1133 1134 /** 1135 * Removes all of the items from the receiver. 1136 * <p> 1137 * @exception SWTException <ul> 1138 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1139 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1140 * </ul> 1141 * 1142 * @since 3.1 1143 */ 1144 public void removeAll () { 1145 checkWidget (); 1146 int length = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle); 1147 if (length is 0) return; 1148 GtkTreeIter iter; 1149 int index; 1150 while (OS.gtk_tree_model_iter_children (parent.modelHandle, &iter, handle)) { 1151 OS.gtk_tree_model_get1 (parent.modelHandle, &iter, Tree.ID_COLUMN, cast(void**)&index); 1152 if (index !is -1) { 1153 TreeItem item = parent.items [index]; 1154 if (item !is null && !item.isDisposed ()) { 1155 item.dispose (); 1156 } 1157 } 1158 } 1159 } 1160 1161 /** 1162 * Sets the receiver's background color to the color specified 1163 * by the argument, or to the default system color for the item 1164 * if the argument is null. 1165 * 1166 * @param color the new color (or null) 1167 * 1168 * @exception IllegalArgumentException <ul> 1169 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1170 * </ul> 1171 * @exception SWTException <ul> 1172 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1173 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1174 * </ul> 1175 * 1176 * @since 2.0 1177 * 1178 */ 1179 public void setBackground (Color color) { 1180 checkWidget (); 1181 if (color !is null && color.isDisposed ()) { 1182 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1183 } 1184 if (_getBackground ().opEquals (color)) return; 1185 GdkColor* gdkColor = color !is null ? color.handle : null; 1186 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.BACKGROUND_COLUMN, gdkColor); 1187 /* 1188 * Bug in GTK. When using fixed-height-mode, 1189 * row changes do not cause the row to be repainted. The fix is to 1190 * invalidate the row when it is cleared. 1191 */ 1192 if ((parent.style & SWT.VIRTUAL) !is 0) { 1193 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1194 redraw (); 1195 } 1196 } 1197 cached = true; 1198 } 1199 1200 /** 1201 * Sets the background color at the given column index in the receiver 1202 * to the color specified by the argument, or to the default system color for the item 1203 * if the argument is null. 1204 * 1205 * @param index the column index 1206 * @param color the new color (or null) 1207 * 1208 * @exception IllegalArgumentException <ul> 1209 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1210 * </ul> 1211 * @exception SWTException <ul> 1212 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1213 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1214 * </ul> 1215 * 1216 * @since 3.1 1217 * 1218 */ 1219 public void setBackground (int index, Color color) { 1220 checkWidget (); 1221 if (color !is null && color.isDisposed ()) { 1222 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1223 } 1224 if (_getBackground (index).opEquals (color)) return; 1225 int count = Math.max (1, parent.getColumnCount ()); 1226 if (0 > index || index > count - 1) return; 1227 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 1228 GdkColor* gdkColor = color !is null ? color.handle : null; 1229 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_BACKGROUND, gdkColor); 1230 /* 1231 * Bug in GTK. When using fixed-height-mode, 1232 * row changes do not cause the row to be repainted. The fix is to 1233 * invalidate the row when it is cleared. 1234 */ 1235 if ((parent.style & SWT.VIRTUAL) !is 0) { 1236 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1237 redraw (); 1238 } 1239 } 1240 cached = true; 1241 1242 if (color !is null) { 1243 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; 1244 if (!customDraw) { 1245 if ((parent.style & SWT.VIRTUAL) is 0) { 1246 auto parentHandle = parent.handle; 1247 GtkTreeViewColumn* column; 1248 if (parent.columnCount > 0) { 1249 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 1250 } else { 1251 column = OS.gtk_tree_view_get_column (parentHandle, index); 1252 } 1253 if (column is null) return; 1254 auto textRenderer = parent.getTextRenderer (column); 1255 auto imageRenderer = parent.getPixbufRenderer (column); 1256 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)textRenderer ); 1257 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)imageRenderer ); 1258 } 1259 if (parent.columnCount is 0) { 1260 parent.firstCustomDraw = true; 1261 } else { 1262 parent.columns [index].customDraw = true; 1263 } 1264 } 1265 } 1266 } 1267 1268 /** 1269 * Sets the checked state of the receiver. 1270 * <p> 1271 * 1272 * @param checked the new checked state 1273 * 1274 * @exception SWTException <ul> 1275 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1276 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1277 * </ul> 1278 */ 1279 public void setChecked (bool checked) { 1280 checkWidget(); 1281 if ((parent.style & SWT.CHECK) is 0) return; 1282 if (_getChecked () is checked) return; 1283 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.CHECKED_COLUMN, cast(void*)cast(int)checked); 1284 /* 1285 * GTK+'s "inconsistent" state does not match SWT's concept of grayed. To 1286 * show checked+grayed differently from unchecked+grayed, we must toggle the 1287 * grayed state on check and uncheck. 1288 */ 1289 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.GRAYED_COLUMN, cast(void*)cast(int)( !checked ? false : grayed)); 1290 cached = true; 1291 } 1292 1293 /** 1294 * Sets the expanded state of the receiver. 1295 * <p> 1296 * 1297 * @param expanded the new expanded state 1298 * 1299 * @exception SWTException <ul> 1300 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1301 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1302 * </ul> 1303 */ 1304 public void setExpanded (bool expanded) { 1305 checkWidget(); 1306 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 1307 if (expanded) { 1308 OS.g_signal_handlers_block_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_EXPAND_ROW); 1309 OS.gtk_tree_view_expand_row (parent.handle, path, false); 1310 OS.g_signal_handlers_unblock_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_EXPAND_ROW); 1311 } else { 1312 OS.g_signal_handlers_block_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_COLLAPSE_ROW); 1313 OS.gtk_widget_realize (parent.handle); 1314 OS.gtk_tree_view_collapse_row (parent.handle, path); 1315 OS.g_signal_handlers_unblock_matched (parent.handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEST_COLLAPSE_ROW); 1316 } 1317 OS.gtk_tree_path_free (path); 1318 cached = true; 1319 } 1320 1321 1322 /** 1323 * Sets the font that the receiver will use to paint textual information 1324 * for this item to the font specified by the argument, or to the default font 1325 * for that kind of control if the argument is null. 1326 * 1327 * @param font the new font (or null) 1328 * 1329 * @exception IllegalArgumentException <ul> 1330 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1331 * </ul> 1332 * @exception SWTException <ul> 1333 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1334 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1335 * </ul> 1336 * 1337 * @since 3.0 1338 */ 1339 public void setFont (Font font){ 1340 checkWidget (); 1341 if (font !is null && font.isDisposed ()) { 1342 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1343 } 1344 Font oldFont = this.font; 1345 if (oldFont is font) return; 1346 this.font = font; 1347 if (oldFont !is null && oldFont.opEquals (font)) return; 1348 void* fontHandle = font !is null ? font.handle : null; 1349 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.FONT_COLUMN, fontHandle); 1350 /* 1351 * Bug in GTK. When using fixed-height-mode, 1352 * row changes do not cause the row to be repainted. The fix is to 1353 * invalidate the row when it is cleared. 1354 */ 1355 if ((parent.style & SWT.VIRTUAL) !is 0) { 1356 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1357 redraw (); 1358 } 1359 } 1360 cached = true; 1361 } 1362 1363 /** 1364 * Sets the font that the receiver will use to paint textual information 1365 * for the specified cell in this item to the font specified by the 1366 * argument, or to the default font for that kind of control if the 1367 * argument is null. 1368 * 1369 * @param index the column index 1370 * @param font the new font (or null) 1371 * 1372 * @exception IllegalArgumentException <ul> 1373 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1374 * </ul> 1375 * @exception SWTException <ul> 1376 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1377 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1378 * </ul> 1379 * 1380 * @since 3.1 1381 */ 1382 public void setFont (int index, Font font) { 1383 checkWidget (); 1384 if (font !is null && font.isDisposed ()) { 1385 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1386 } 1387 int count = Math.max (1, parent.getColumnCount ()); 1388 if (0 > index || index > count - 1) return; 1389 if (cellFont is null) { 1390 if (font is null) return; 1391 cellFont = new Font [count]; 1392 } 1393 Font oldFont = cellFont [index]; 1394 if (oldFont is font) return; 1395 cellFont [index] = font; 1396 if (oldFont !is null && oldFont.opEquals (font)) return; 1397 1398 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 1399 auto fontHandle = font !is null ? font.handle : null; 1400 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_FONT, fontHandle); 1401 /* 1402 * Bug in GTK. When using fixed-height-mode, 1403 * row changes do not cause the row to be repainted. The fix is to 1404 * invalidate the row when it is cleared. 1405 */ 1406 if ((parent.style & SWT.VIRTUAL) !is 0) { 1407 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1408 redraw (); 1409 } 1410 } 1411 cached = true; 1412 1413 if (font !is null) { 1414 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; 1415 if (!customDraw) { 1416 if ((parent.style & SWT.VIRTUAL) is 0) { 1417 auto parentHandle = parent.handle; 1418 GtkTreeViewColumn* column; 1419 if (parent.columnCount > 0) { 1420 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 1421 } else { 1422 column = OS.gtk_tree_view_get_column (parentHandle, index); 1423 } 1424 if (column is null) return; 1425 auto textRenderer = parent.getTextRenderer (column); 1426 auto imageRenderer = parent.getPixbufRenderer (column); 1427 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)textRenderer ); 1428 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)imageRenderer ); 1429 } 1430 if (parent.columnCount is 0) { 1431 parent.firstCustomDraw = true; 1432 } else { 1433 parent.columns [index].customDraw = true; 1434 } 1435 } 1436 } 1437 } 1438 1439 /** 1440 * Sets the receiver's foreground color to the color specified 1441 * by the argument, or to the default system color for the item 1442 * if the argument is null. 1443 * 1444 * @param color the new color (or null) 1445 * 1446 * @since 2.0 1447 * 1448 * @exception IllegalArgumentException <ul> 1449 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1450 * </ul> 1451 * @exception SWTException <ul> 1452 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1453 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1454 * </ul> 1455 * 1456 * @since 2.0 1457 * 1458 */ 1459 public void setForeground (Color color){ 1460 checkWidget (); 1461 if (color !is null && color.isDisposed ()) { 1462 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1463 } 1464 if (_getForeground ().opEquals (color)) return; 1465 GdkColor *gdkColor = color !is null ? color.handle : null; 1466 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.FOREGROUND_COLUMN, gdkColor); 1467 /* 1468 * Bug in GTK. When using fixed-height-mode, 1469 * row changes do not cause the row to be repainted. The fix is to 1470 * invalidate the row when it is cleared. 1471 */ 1472 if ((parent.style & SWT.VIRTUAL) !is 0) { 1473 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1474 redraw (); 1475 } 1476 } 1477 cached = true; 1478 } 1479 1480 /** 1481 * Sets the foreground color at the given column index in the receiver 1482 * to the color specified by the argument, or to the default system color for the item 1483 * if the argument is null. 1484 * 1485 * @param index the column index 1486 * @param color the new color (or null) 1487 * 1488 * @exception IllegalArgumentException <ul> 1489 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1490 * </ul> 1491 * @exception SWTException <ul> 1492 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1493 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1494 * </ul> 1495 * 1496 * @since 3.1 1497 * 1498 */ 1499 public void setForeground (int index, Color color){ 1500 checkWidget (); 1501 if (color !is null && color.isDisposed ()) { 1502 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1503 } 1504 if (_getForeground (index).opEquals (color)) return; 1505 int count = Math.max (1, parent.getColumnCount ()); 1506 if (0 > index || index > count - 1) return; 1507 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 1508 GdkColor *gdkColor = color !is null ? color.handle : null; 1509 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_FOREGROUND, gdkColor); 1510 /* 1511 * Bug in GTK. When using fixed-height-mode, 1512 * row changes do not cause the row to be repainted. The fix is to 1513 * invalidate the row when it is cleared. 1514 */ 1515 if ((parent.style & SWT.VIRTUAL) !is 0) { 1516 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1517 redraw (); 1518 } 1519 } 1520 cached = true; 1521 1522 if (color !is null) { 1523 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; 1524 if (!customDraw) { 1525 if ((parent.style & SWT.VIRTUAL) is 0) { 1526 auto parentHandle = parent.handle; 1527 GtkTreeViewColumn* column; 1528 if (parent.columnCount > 0) { 1529 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 1530 } else { 1531 column = OS.gtk_tree_view_get_column (parentHandle, index); 1532 } 1533 if (column is null) return; 1534 auto textRenderer = parent.getTextRenderer (column); 1535 auto imageRenderer = parent.getPixbufRenderer (column); 1536 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)textRenderer ); 1537 display.doCellDataProc( parentHandle, cast(GtkTreeViewColumn*)column, cast(GtkCellRenderer*)imageRenderer ); 1538 } 1539 if (parent.columnCount is 0) { 1540 parent.firstCustomDraw = true; 1541 } else { 1542 parent.columns [index].customDraw = true; 1543 } 1544 } 1545 } 1546 } 1547 1548 /** 1549 * Sets the grayed state of the checkbox for this item. This state change 1550 * only applies if the Tree was created with the SWT.CHECK style. 1551 * 1552 * @param grayed the new grayed state of the checkbox 1553 * 1554 * @exception SWTException <ul> 1555 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1556 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1557 * </ul> 1558 */ 1559 public void setGrayed (bool grayed) { 1560 checkWidget(); 1561 if ((parent.style & SWT.CHECK) is 0) return; 1562 if (this.grayed is grayed) return; 1563 this.grayed = grayed; 1564 /* 1565 * GTK+'s "inconsistent" state does not match SWT's concept of grayed. 1566 * Render checked+grayed as "inconsistent", unchecked+grayed as blank. 1567 */ 1568 void* ptr; 1569 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Tree.CHECKED_COLUMN, &ptr); 1570 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, Tree.GRAYED_COLUMN, cast(void*)cast(int)( ptr is null ? false : grayed)); 1571 cached = true; 1572 } 1573 1574 /** 1575 * Sets the receiver's image at a column. 1576 * 1577 * @param index the column index 1578 * @param image the new image 1579 * 1580 * @exception IllegalArgumentException <ul> 1581 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> 1582 * </ul> 1583 * @exception SWTException <ul> 1584 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1585 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1586 * </ul> 1587 * 1588 * @since 3.1 1589 */ 1590 public void setImage (int index, Image image) { 1591 checkWidget (); 1592 if (image !is null && image.isDisposed()) { 1593 error(SWT.ERROR_INVALID_ARGUMENT); 1594 } 1595 if (image !is null && image.type is SWT.ICON) { 1596 if (image.opEquals (_getImage (index))) return; 1597 } 1598 int count = Math.max (1, parent.getColumnCount ()); 1599 if (0 > index || index > count - 1) return; 1600 GdkPixbuf* pixbuf; 1601 if (image !is null) { 1602 ImageList imageList = parent.imageList; 1603 if (imageList is null) imageList = parent.imageList = new ImageList (); 1604 int imageIndex = imageList.indexOf (image); 1605 if (imageIndex is -1) imageIndex = imageList.add (image); 1606 pixbuf = imageList.getPixbuf (imageIndex); 1607 } 1608 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 1609 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_PIXBUF, pixbuf); 1610 /* 1611 * Bug in GTK. When using fixed-height-mode, 1612 * row changes do not cause the row to be repainted. The fix is to 1613 * invalidate the row when the image changes. 1614 */ 1615 if ((parent.style & SWT.VIRTUAL) !is 0) { 1616 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1617 if (parent.columnCount is 0) { 1618 redraw (); 1619 } 1620 } 1621 } 1622 /* 1623 * Bug in GTK. When using fixed-height-mode, GTK does not recalculate the cell renderer width 1624 * when the image is changed in the model. The fix is to force it to recalculate the width if 1625 * more space is required. 1626 */ 1627 if ((parent.style & SWT.VIRTUAL) !is 0 && parent.currentItem is null) { 1628 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2)) { 1629 if (image !is null) { 1630 auto parentHandle = parent.handle; 1631 auto column = OS.gtk_tree_view_get_column (parentHandle, index); 1632 int w; 1633 auto pixbufRenderer = parent.getPixbufRenderer(column); 1634 OS.gtk_tree_view_column_cell_get_position (column, pixbufRenderer, null, &w); 1635 if (w < image.getBounds().width) { 1636 /* 1637 * There is no direct way to clear the cell renderer width so we 1638 * are relying on the fact that it is done as part of modifying 1639 * the style. 1640 */ 1641 auto style = OS.gtk_widget_get_modifier_style (parentHandle); 1642 parent.modifyStyle (parentHandle, style); 1643 } 1644 } 1645 } 1646 } 1647 cached = true; 1648 } 1649 1650 public override void setImage (Image image) { 1651 checkWidget (); 1652 setImage (0, image); 1653 } 1654 1655 /** 1656 * Sets the image for multiple columns in the tree. 1657 * 1658 * @param images the array of new images 1659 * 1660 * @exception IllegalArgumentException <ul> 1661 * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li> 1662 * </ul> 1663 * @exception SWTException <ul> 1664 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1665 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1666 * </ul> 1667 * 1668 * @since 3.1 1669 */ 1670 public void setImage (Image [] images) { 1671 checkWidget (); 1672 // SWT extension: allow null for zero length string 1673 //if (images is null) error (SWT.ERROR_NULL_ARGUMENT); 1674 for (int i=0; i<images.length; i++) { 1675 setImage (i, images [i]); 1676 } 1677 } 1678 1679 /** 1680 * Sets the number of child items contained in the receiver. 1681 * 1682 * @param count the number of items 1683 * 1684 * @exception SWTException <ul> 1685 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1686 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1687 * </ul> 1688 * 1689 * @since 3.2 1690 */ 1691 public void setItemCount (int count) { 1692 checkWidget (); 1693 count = Math.max (0, count); 1694 parent.setItemCount (cast(GtkTreeIter*)handle, count); 1695 } 1696 1697 /** 1698 * Sets the receiver's text at a column 1699 * 1700 * @param index the column index 1701 * @param string the new text 1702 * 1703 * @exception SWTException <ul> 1704 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1705 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1706 * </ul> 1707 * 1708 * @since 3.1 1709 */ 1710 public void setText (int index, String string) { 1711 checkWidget (); 1712 // SWT extension: allow null for zero length string 1713 //if (string is null) error (SWT.ERROR_NULL_ARGUMENT); 1714 if (_getText (index).equals (string)) return; 1715 int count = Math.max (1, parent.getColumnCount ()); 1716 if (0 > index || index > count - 1) return; 1717 char* buffer = toStringz(string); 1718 int modelIndex = parent.columnCount is 0 ? Tree.FIRST_COLUMN : parent.columns [index].modelIndex; 1719 OS.gtk_tree_store_set1 (parent.modelHandle, cast(GtkTreeIter*)handle, modelIndex + Tree.CELL_TEXT, buffer); 1720 /* 1721 * Bug in GTK. When using fixed-height-mode, 1722 * row changes do not cause the row to be repainted. The fix is to 1723 * invalidate the row when the text changes. 1724 */ 1725 if ((parent.style & SWT.VIRTUAL) !is 0) { 1726 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1727 redraw (); 1728 } 1729 } 1730 cached = true; 1731 } 1732 1733 public override void setText (String string) { 1734 checkWidget (); 1735 setText (0, string); 1736 } 1737 1738 /** 1739 * Sets the text for multiple columns in the tree. 1740 * 1741 * @param strings the array of new strings 1742 * 1743 * @exception SWTException <ul> 1744 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1745 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1746 * </ul> 1747 * 1748 * @since 3.1 1749 */ 1750 public void setText (String [] strings) { 1751 checkWidget (); 1752 // SWT extension: allow null for zero length string 1753 //if (strings is null) error (SWT.ERROR_NULL_ARGUMENT); 1754 for (int i=0; i<strings.length; i++) { 1755 String string = strings [i]; 1756 if (string !is null) setText (i, string); 1757 } 1758 } 1759 }