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.TableItem; 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.Table; 28 import org.eclipse.swt.widgets.ImageList; 29 import org.eclipse.swt.widgets.TreeItem; 30 31 32 /** 33 * Instances of this class represent a selectable user interface object 34 * that represents an item in a table. 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/#table">Table, TableItem, TableColumn snippets</a> 46 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 47 */ 48 public class TableItem : Item { 49 Table parent; 50 Font font; 51 Font[] cellFont; 52 bool cached, grayed; 53 54 /** 55 * Constructs a new instance of this class given its parent 56 * (which must be a <code>Table</code>), a style value 57 * describing its behavior and appearance, and the index 58 * at which to place it in the items maintained by its parent. 59 * <p> 60 * The style value is either one of the style constants defined in 61 * class <code>SWT</code> which is applicable to instances of this 62 * class, or must be built by <em>bitwise OR</em>'ing together 63 * (that is, using the <code>int</code> "|" operator) two or more 64 * of those <code>SWT</code> style constants. The class description 65 * lists the style constants that are applicable to the class. 66 * Style bits are also inherited from superclasses. 67 * </p> 68 * 69 * @param parent a composite control which will be the parent of the new instance (cannot be null) 70 * @param style the style of control to construct 71 * @param index the zero-relative index to store the receiver in its parent 72 * 73 * @exception IllegalArgumentException <ul> 74 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 75 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> 76 * </ul> 77 * @exception SWTException <ul> 78 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 79 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 80 * </ul> 81 * 82 * @see SWT 83 * @see Widget#checkSubclass 84 * @see Widget#getStyle 85 */ 86 public this (Table parent, int style, int index) { 87 this (parent, style, index, true); 88 } 89 90 /** 91 * Constructs a new instance of this class given its parent 92 * (which must be a <code>Table</code>) and a style value 93 * describing its behavior and appearance. The item is added 94 * to the end of the items maintained by its parent. 95 * <p> 96 * The style value is either one of the style constants defined in 97 * class <code>SWT</code> which is applicable to instances of this 98 * class, or must be built by <em>bitwise OR</em>'ing together 99 * (that is, using the <code>int</code> "|" operator) two or more 100 * of those <code>SWT</code> style constants. The class description 101 * lists the style constants that are applicable to the class. 102 * Style bits are also inherited from superclasses. 103 * </p> 104 * 105 * @param parent a composite control which will be the parent of the new instance (cannot be null) 106 * @param style the style of control to construct 107 * 108 * @exception IllegalArgumentException <ul> 109 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 110 * </ul> 111 * @exception SWTException <ul> 112 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 113 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 114 * </ul> 115 * 116 * @see SWT 117 * @see Widget#checkSubclass 118 * @see Widget#getStyle 119 */ 120 public this (Table parent, int style) { 121 this (parent, style, checkNull (parent).getItemCount (), true); 122 } 123 124 125 this (Table parent, int style, int index, bool create) { 126 super (parent, style); 127 this.parent = parent; 128 if (create) { 129 parent.createItem (this, index); 130 } else { 131 handle = cast(GtkWidget*)OS.g_malloc (GtkTreeIter.sizeof); 132 OS.gtk_tree_model_iter_nth_child (parent.modelHandle, handle, null, index); 133 } 134 } 135 136 static Table checkNull (Table control) { 137 if (control is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 138 return control; 139 } 140 141 Color _getBackground () { 142 void* ptr; 143 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Table.BACKGROUND_COLUMN, &ptr); 144 if (ptr is null) return parent.getBackground (); 145 GdkColor* gdkColor = new GdkColor (); 146 *gdkColor = *cast(GdkColor*) ptr; 147 return Color.gtk_new (display, gdkColor); 148 } 149 150 Color _getBackground (int index) { 151 int count = Math.max (1, parent.columnCount); 152 if (0 > index || index > count - 1) return _getBackground (); 153 void* ptr; 154 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 155 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Table.CELL_BACKGROUND, &ptr); 156 if (ptr is null) return _getBackground (); 157 GdkColor* gdkColor = new GdkColor (); 158 *gdkColor = *cast(GdkColor*) ptr; 159 return Color.gtk_new (display, gdkColor); 160 } 161 162 bool _getChecked () { 163 void* ptr; 164 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Table.CHECKED_COLUMN, &ptr); 165 return ptr !is null; 166 } 167 168 Color _getForeground () { 169 void* ptr; 170 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Table.FOREGROUND_COLUMN, &ptr); 171 if (ptr is null) return parent.getForeground (); 172 GdkColor* gdkColor = new GdkColor (); 173 *gdkColor = *cast(GdkColor*) ptr; 174 return Color.gtk_new (display, gdkColor); 175 } 176 177 Color _getForeground (int index) { 178 int count = Math.max (1, parent.columnCount); 179 if (0 > index || index > count - 1) return _getForeground (); 180 void* ptr; 181 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 182 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Table.CELL_FOREGROUND, &ptr); 183 if (ptr is null) return _getForeground (); 184 GdkColor* gdkColor = new GdkColor (); 185 *gdkColor = *cast(GdkColor*) ptr; 186 return Color.gtk_new (display, gdkColor); 187 } 188 189 Image _getImage (int index) { 190 int count = Math.max (1, parent.getColumnCount ()); 191 if (0 > index || index > count - 1) return null; 192 void* ptr; 193 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 194 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Table.CELL_PIXBUF, &ptr); 195 if (ptr is null) return null; 196 ImageList imageList = parent.imageList; 197 int imageIndex = imageList.indexOf (ptr); 198 if (imageIndex is -1) return null; 199 return imageList.get (imageIndex); 200 } 201 202 String _getText (int index) { 203 int count = Math.max (1, parent.getColumnCount ()); 204 if (0 > index || index > count - 1) return ""; 205 void* ptr; 206 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 207 OS.gtk_tree_model_get1 (parent.modelHandle, handle, modelIndex + Table.CELL_TEXT, &ptr); 208 if (ptr is null) return ""; 209 String buffer = fromStringz( cast(char*)ptr)._idup(); 210 OS.g_free (ptr); 211 return buffer; 212 } 213 214 protected override void checkSubclass () { 215 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); 216 } 217 218 void clear () { 219 if (parent.currentItem is this) return; 220 if (cached || (parent.style & SWT.VIRTUAL) is 0) { 221 int columnCount = OS.gtk_tree_model_get_n_columns (parent.modelHandle); 222 for (int i=0; i<columnCount; i++) { 223 OS.gtk_list_store_set1 (parent.modelHandle, handle, i, null); 224 } 225 /* 226 * Bug in GTK. When using fixed-height-mode, 227 * row changes do not cause the row to be repainted. The fix is to 228 * invalidate the row when it is cleared. 229 */ 230 if ((parent.style & SWT.VIRTUAL) !is 0) { 231 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 232 redraw (); 233 } 234 } 235 } 236 cached = false; 237 font = null; 238 cellFont = null; 239 } 240 241 override void destroyWidget () { 242 parent.destroyItem (this); 243 releaseHandle (); 244 } 245 246 /** 247 * Returns the receiver's background color. 248 * 249 * @return the background color 250 * 251 * @exception SWTException <ul> 252 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 253 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 254 * </ul> 255 * 256 * @since 2.0 257 */ 258 public Color getBackground () { 259 checkWidget (); 260 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 261 return _getBackground (); 262 } 263 264 /** 265 * Returns a rectangle describing the receiver's size and location 266 * relative to its parent. 267 * 268 * @return the receiver's bounding rectangle 269 * 270 * @exception SWTException <ul> 271 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 272 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 273 * </ul> 274 * 275 * @since 3.2 276 */ 277 public Rectangle getBounds () { 278 // TODO fully test on early and later versions of GTK 279 // shifted a bit too far right on later versions of GTK - however, old Tree also had this problem 280 checkWidget (); 281 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 282 auto parentHandle = parent.handle; 283 auto column = OS.gtk_tree_view_get_column (parentHandle, 0); 284 if (column is null) return new Rectangle (0, 0, 0, 0); 285 auto textRenderer = parent.getTextRenderer (column); 286 auto pixbufRenderer = parent.getPixbufRenderer (column); 287 if (textRenderer is null || pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); 288 289 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 290 OS.gtk_widget_realize (parentHandle); 291 292 bool isExpander = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle) > 0; 293 bool isExpanded = cast(bool)OS.gtk_tree_view_row_expanded (parentHandle, path); 294 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, isExpander, isExpanded); 295 296 GdkRectangle rect; 297 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 298 OS.gtk_tree_path_free (path); 299 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 300 int right = rect.x + rect.width; 301 302 int x, w; 303 parent.ignoreSize = true; 304 OS.gtk_cell_renderer_get_size (textRenderer, parentHandle, null, null, null, &w, null); 305 parent.ignoreSize = false; 306 rect.width = w; 307 int buffer; 308 if (OS.gtk_tree_view_get_expander_column (parentHandle) is column) { 309 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); 310 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; 311 } 312 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 313 int horizontalSeparator = buffer; 314 rect.x += horizontalSeparator; 315 316 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 317 OS.gtk_tree_view_column_cell_get_position (column, textRenderer, &x, null); 318 rect.x += x; 319 } else { 320 if ((parent.style & SWT.CHECK) !is 0) { 321 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); 322 rect.x += w + horizontalSeparator; 323 } 324 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); 325 rect.x += w + horizontalSeparator; 326 } 327 if (parent.columnCount > 0) { 328 if (rect.x + rect.width > right) { 329 rect.width = Math.max (0, right - rect.x); 330 } 331 } 332 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; 333 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 334 } 335 336 /** 337 * Returns the background color at the given column index in the receiver. 338 * 339 * @param index the column index 340 * @return the background color 341 * 342 * @exception SWTException <ul> 343 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 344 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 345 * </ul> 346 * 347 * @since 3.0 348 */ 349 public Color getBackground (int index) { 350 checkWidget (); 351 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 352 return _getBackground (index); 353 } 354 355 /** 356 * Returns a rectangle describing the receiver's size and location 357 * relative to its parent at a column in the table. 358 * 359 * @param index the index that specifies the column 360 * @return the receiver's bounding column rectangle 361 * 362 * @exception SWTException <ul> 363 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 364 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 365 * </ul> 366 */ 367 public Rectangle getBounds (int index) { 368 checkWidget(); 369 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 370 auto parentHandle = parent.handle; 371 GtkTreeViewColumn* column; 372 if (index >= 0 && index < parent.columnCount) { 373 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 374 } else { 375 column = OS.gtk_tree_view_get_column (parentHandle, index); 376 } 377 if (column is null) return new Rectangle (0, 0, 0, 0); 378 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 379 OS.gtk_widget_realize (parentHandle); 380 GdkRectangle rect; 381 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 382 OS.gtk_tree_path_free (path); 383 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 384 385 if (index is 0 && (parent.style & SWT.CHECK) !is 0) { 386 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 387 int x, w; 388 OS.gtk_tree_view_column_cell_get_position (column, parent.checkRenderer, &x, &w); 389 rect.x += x + w; 390 rect.width -= x + w; 391 } else { 392 int w; 393 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); 394 int buffer; 395 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 396 rect.x += w + buffer; 397 rect.width -= w + buffer; 398 } 399 } 400 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; 401 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 402 } 403 404 /** 405 * Returns <code>true</code> if the receiver is checked, 406 * and false otherwise. When the parent does not have 407 * the <code>CHECK</code> style, return false. 408 * 409 * @return the checked state of the checkbox 410 * 411 * @exception SWTException <ul> 412 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 413 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 414 * </ul> 415 */ 416 public bool getChecked () { 417 checkWidget(); 418 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 419 if ((parent.style & SWT.CHECK) is 0) return false; 420 return _getChecked (); 421 } 422 423 /** 424 * Returns the font that the receiver will use to paint textual information for this item. 425 * 426 * @return the receiver's font 427 * 428 * @exception SWTException <ul> 429 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 430 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 431 * </ul> 432 * 433 * @since 3.0 434 */ 435 public Font getFont () { 436 checkWidget (); 437 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 438 return font !is null ? font : parent.getFont (); 439 } 440 441 /** 442 * Returns the font that the receiver will use to paint textual information 443 * for the specified cell in this item. 444 * 445 * @param index the column index 446 * @return the receiver's font 447 * 448 * @exception SWTException <ul> 449 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 450 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 451 * </ul> 452 * 453 * @since 3.0 454 */ 455 public Font getFont (int index) { 456 checkWidget (); 457 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 458 int count = Math.max (1, parent.columnCount); 459 if (0 > index || index > count - 1) return getFont (); 460 if (cellFont is null || cellFont [index] is null) return getFont (); 461 return cellFont [index]; 462 } 463 464 /** 465 * Returns the foreground color that the receiver will use to draw. 466 * 467 * @return the receiver's foreground color 468 * 469 * @exception SWTException <ul> 470 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 471 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 472 * </ul> 473 * 474 * @since 2.0 475 */ 476 public Color getForeground () { 477 checkWidget (); 478 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 479 return _getForeground (); 480 } 481 482 /** 483 * 484 * Returns the foreground color at the given column index in the receiver. 485 * 486 * @param index the column index 487 * @return the foreground color 488 * 489 * @exception SWTException <ul> 490 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 491 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 492 * </ul> 493 * 494 * @since 3.0 495 */ 496 public Color getForeground (int index) { 497 checkWidget (); 498 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 499 return _getForeground (index); 500 } 501 502 /** 503 * Returns <code>true</code> if the receiver is grayed, 504 * and false otherwise. When the parent does not have 505 * the <code>CHECK</code> style, return false. 506 * 507 * @return the grayed state of the checkbox 508 * 509 * @exception SWTException <ul> 510 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 511 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 512 * </ul> 513 */ 514 public bool getGrayed () { 515 checkWidget (); 516 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 517 if ((parent.style & SWT.CHECK) is 0) return false; 518 return grayed; 519 } 520 521 public override Image getImage () { 522 checkWidget (); 523 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 524 return getImage (0); 525 } 526 527 /** 528 * Returns the image stored at the given column index in the receiver, 529 * or null if the image has not been set or if the column does not exist. 530 * 531 * @param index the column index 532 * @return the image stored at the given column index in the receiver 533 * 534 * @exception SWTException <ul> 535 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 536 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 537 * </ul> 538 */ 539 public Image getImage (int index) { 540 checkWidget (); 541 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 542 return _getImage (index); 543 } 544 545 /** 546 * Returns a rectangle describing the size and location 547 * relative to its parent of an image at a column in the 548 * table. An empty rectangle is returned if index exceeds 549 * the index of the table's last column. 550 * 551 * @param index the index that specifies the column 552 * @return the receiver's bounding image rectangle 553 * 554 * @exception SWTException <ul> 555 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 556 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 557 * </ul> 558 */ 559 public Rectangle getImageBounds (int index) { 560 checkWidget (); 561 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 562 auto parentHandle = parent.handle; 563 GtkTreeViewColumn* column; 564 if (index >= 0 && index < parent.columnCount) { 565 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 566 } else { 567 column = OS.gtk_tree_view_get_column (parentHandle, index); 568 } 569 if (column is null) return new Rectangle (0, 0, 0, 0); 570 auto pixbufRenderer = parent.getPixbufRenderer (column); 571 if (pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); 572 GdkRectangle rect; 573 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 574 OS.gtk_widget_realize (parentHandle); 575 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 576 OS.gtk_tree_path_free (path); 577 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 578 /* 579 * The OS call gtk_cell_renderer_get_size() provides the width of image to be drawn 580 * by the cell renderer. If there is no image in the cell, the width is zero. If the table contains 581 * images of varying widths, gtk_cell_renderer_get_size() will return the width of the image, 582 * not the width of the area in which the image is drawn. 583 * New API was added in GTK 2.1.3 for determining the full width of the renderer area. 584 * For earlier versions of GTK, the result is only correct if all rows have images of the same 585 * width. 586 */ 587 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 588 int x, w; 589 OS.gtk_tree_view_column_cell_get_position (column, pixbufRenderer, &x, &w); 590 rect.x += x; 591 rect.width = w; 592 } else { 593 int w; 594 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, false, false); 595 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); 596 rect.width = w; 597 } 598 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width : 0; 599 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 600 } 601 602 /** 603 * Gets the image indent. 604 * 605 * @return the indent 606 * 607 * @exception SWTException <ul> 608 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 609 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 610 * </ul> 611 */ 612 public int getImageIndent () { 613 checkWidget (); 614 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 615 /* Image indent is not supported on GTK */ 616 return 0; 617 } 618 619 override String getNameText () { 620 if ((parent.style & SWT.VIRTUAL) !is 0) { 621 if (!cached) return "*virtual*"; //$NON-NLS-1$ 622 } 623 return super.getNameText (); 624 } 625 626 /** 627 * Returns the receiver's parent, which must be a <code>Table</code>. 628 * 629 * @return the receiver's parent 630 * 631 * @exception SWTException <ul> 632 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 633 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 634 * </ul> 635 */ 636 public Table getParent () { 637 checkWidget (); 638 return parent; 639 } 640 641 public override String getText () { 642 checkWidget (); 643 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 644 return getText (0); 645 } 646 647 /** 648 * Returns the text stored at the given column index in the receiver, 649 * or empty string if the text has not been set. 650 * 651 * @param index the column index 652 * @return the text stored at the given column index in the receiver 653 * 654 * @exception SWTException <ul> 655 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 656 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 657 * </ul> 658 */ 659 public String getText (int index) { 660 checkWidget (); 661 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 662 return _getText (index); 663 } 664 665 /** 666 * Returns a rectangle describing the size and location 667 * relative to its parent of the text at a column in the 668 * table. An empty rectangle is returned if index exceeds 669 * the index of the table's last column. 670 * 671 * @param index the index that specifies the column 672 * @return the receiver's bounding text rectangle 673 * 674 * @exception SWTException <ul> 675 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 676 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 677 * </ul> 678 * 679 * @since 3.3 680 */ 681 public Rectangle getTextBounds (int index) { 682 checkWidget (); 683 if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); 684 int count = Math.max (1, parent.getColumnCount ()); 685 if (0 > index || index > count - 1) return new Rectangle (0, 0, 0, 0); 686 // TODO fully test on early and later versions of GTK 687 // shifted a bit too far right on later versions of GTK - however, old Tree also had this problem 688 auto parentHandle = parent.handle; 689 GtkTreeViewColumn* column; 690 if (index >= 0 && index < parent.columnCount) { 691 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 692 } else { 693 column = OS.gtk_tree_view_get_column (parentHandle, index); 694 } 695 if (column is null) return new Rectangle (0, 0, 0, 0); 696 auto textRenderer = parent.getTextRenderer (column); 697 auto pixbufRenderer = parent.getPixbufRenderer (column); 698 if (textRenderer is null || pixbufRenderer is null) return new Rectangle (0, 0, 0, 0); 699 700 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 701 OS.gtk_widget_realize (parentHandle); 702 703 bool isExpander = OS.gtk_tree_model_iter_n_children (parent.modelHandle, handle) > 0; 704 bool isExpanded = cast(bool)OS.gtk_tree_view_row_expanded (parentHandle, path); 705 OS.gtk_tree_view_column_cell_set_cell_data (column, parent.modelHandle, handle, isExpander, isExpanded); 706 707 GdkRectangle rect; 708 OS.gtk_tree_view_get_cell_area (parentHandle, path, column, &rect); 709 OS.gtk_tree_path_free (path); 710 if ((parent.getStyle () & SWT.MIRRORED) !is 0) rect.x = parent.getClientWidth () - rect.width - rect.x; 711 int right = rect.x + rect.width; 712 713 int x, w; 714 parent.ignoreSize = true; 715 OS.gtk_cell_renderer_get_size (textRenderer, parentHandle, null, null, null, &w, null); 716 parent.ignoreSize = false; 717 int buffer; 718 if (OS.gtk_tree_view_get_expander_column (parentHandle) is column) { 719 OS.gtk_widget_style_get1 (parentHandle, OS.expander_size.ptr, &buffer); 720 rect.x += buffer + TreeItem.EXPANDER_EXTRA_PADDING; 721 } 722 OS.gtk_widget_style_get1 (parentHandle, OS.horizontal_separator.ptr, &buffer); 723 int horizontalSeparator = buffer; 724 rect.x += horizontalSeparator; 725 726 if (OS.GTK_VERSION >= OS.buildVERSION (2, 1, 3)) { 727 OS.gtk_tree_view_column_cell_get_position (column, textRenderer, &x, null); 728 rect.x += x; 729 } else { 730 if ((parent.style & SWT.CHECK) !is 0) { 731 OS.gtk_cell_renderer_get_size (parent.checkRenderer, parentHandle, null, null, null, &w, null); 732 rect.x += w + horizontalSeparator; 733 } 734 OS.gtk_cell_renderer_get_size (pixbufRenderer, parentHandle, null, null, null, &w, null); 735 rect.x += w + horizontalSeparator; 736 } 737 if (parent.columnCount > 0) { 738 if (rect.x + rect.width > right) { 739 rect.width = Math.max (0, right - rect.x); 740 } 741 } 742 int width = OS.gtk_tree_view_column_get_visible (column) ? rect.width + 1 : 0; 743 return new Rectangle (rect.x, rect.y, width, rect.height + 1); 744 } 745 746 void redraw () { 747 if ((OS.GTK_WIDGET_FLAGS (parent.handle) & OS.GTK_REALIZED) !is 0) { 748 auto parentHandle = parent.handle; 749 auto path = OS.gtk_tree_model_get_path (parent.modelHandle, handle); 750 GdkRectangle rect; 751 OS.gtk_tree_view_get_cell_area (parentHandle, path, null, &rect); 752 OS.gtk_tree_path_free (path); 753 auto window = OS.gtk_tree_view_get_bin_window (parentHandle); 754 rect.x = 0; 755 int w, h; 756 OS.gdk_drawable_get_size (window, &w, &h); 757 rect.width = w; 758 OS.gdk_window_invalidate_rect (window, &rect, false); 759 } 760 } 761 762 override void releaseHandle () { 763 if (handle !is null) OS.g_free (handle); 764 handle = null; 765 super.releaseHandle (); 766 parent = null; 767 } 768 769 override void releaseWidget () { 770 super.releaseWidget (); 771 font = null; 772 cellFont = null; 773 } 774 775 /** 776 * Sets the receiver's background color to the color specified 777 * by the argument, or to the default system color for the item 778 * if the argument is null. 779 * 780 * @param color the new color (or null) 781 * 782 * @exception IllegalArgumentException <ul> 783 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 784 * </ul> 785 * @exception SWTException <ul> 786 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 787 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 788 * </ul> 789 * 790 * @since 2.0 791 */ 792 public void setBackground (Color color) { 793 checkWidget (); 794 if (color !is null && color.isDisposed ()) { 795 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 796 } 797 if (_getBackground ().opEquals (color)) return; 798 GdkColor* gdkColor = color !is null ? color.handle : null; 799 OS.gtk_list_store_set1 (parent.modelHandle, handle, Table.BACKGROUND_COLUMN, gdkColor); 800 /* 801 * Bug in GTK. When using fixed-height-mode, 802 * row changes do not cause the row to be repainted. The fix is to 803 * invalidate the row when it is cleared. 804 */ 805 if ((parent.style & SWT.VIRTUAL) !is 0) { 806 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 807 redraw (); 808 } 809 } 810 cached = true; 811 } 812 813 /** 814 * Sets the background color at the given column index in the receiver 815 * to the color specified by the argument, or to the default system color for the item 816 * if the argument is null. 817 * 818 * @param index the column index 819 * @param color the new color (or null) 820 * 821 * @exception IllegalArgumentException <ul> 822 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 823 * </ul> 824 * @exception SWTException <ul> 825 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 826 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 827 * </ul> 828 * 829 * @since 3.0 830 */ 831 public void setBackground (int index, Color color) { 832 checkWidget (); 833 if (color !is null && color.isDisposed ()) { 834 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 835 } 836 if (_getBackground (index).opEquals (color)) return; 837 int count = Math.max (1, parent.getColumnCount ()); 838 if (0 > index || index > count - 1) return; 839 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 840 GdkColor* gdkColor = color !is null ? color.handle : null; 841 OS.gtk_list_store_set1 (parent.modelHandle, handle, modelIndex + Table.CELL_BACKGROUND, gdkColor); 842 /* 843 * Bug in GTK. When using fixed-height-mode, 844 * row changes do not cause the row to be repainted. The fix is to 845 * invalidate the row when it is cleared. 846 */ 847 if ((parent.style & SWT.VIRTUAL) !is 0) { 848 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 849 redraw (); 850 } 851 } 852 cached = true; 853 854 if (color !is null) { 855 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; 856 if (!customDraw) { 857 if ((parent.style & SWT.VIRTUAL) is 0) { 858 auto parentHandle = parent.handle; 859 GtkTreeViewColumn* column; 860 if (parent.columnCount > 0) { 861 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 862 } else { 863 column = OS.gtk_tree_view_get_column (parentHandle, index); 864 } 865 if (column is null) return; 866 auto textRenderer = parent.getTextRenderer (column); 867 auto imageRenderer = parent.getPixbufRenderer (column); 868 display.doCellDataProc( parentHandle, column, cast(GtkCellRenderer*)textRenderer ); 869 display.doCellDataProc( parentHandle, column, cast(GtkCellRenderer*)imageRenderer ); 870 } 871 if (parent.columnCount is 0) { 872 parent.firstCustomDraw = true; 873 } else { 874 parent.columns [index].customDraw = true; 875 } 876 } 877 } 878 } 879 880 /** 881 * Sets the checked state of the checkbox for this item. This state change 882 * only applies if the Table was created with the SWT.CHECK style. 883 * 884 * @param checked the new checked state of the checkbox 885 * 886 * @exception SWTException <ul> 887 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 888 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 889 * </ul> 890 */ 891 public void setChecked (bool checked) { 892 checkWidget(); 893 if ((parent.style & SWT.CHECK) is 0) return; 894 if (_getChecked () is checked) return; 895 OS.gtk_list_store_set1 (parent.modelHandle, handle, Table.CHECKED_COLUMN, cast(void*)cast(int)checked); 896 /* 897 * GTK+'s "inconsistent" state does not match SWT's concept of grayed. To 898 * show checked+grayed differently from unchecked+grayed, we must toggle the 899 * grayed state on check and uncheck. 900 */ 901 OS.gtk_list_store_set1 (parent.modelHandle, handle, Table.GRAYED_COLUMN, cast(void*)cast(int)( !checked ? false : grayed)); 902 cached = true; 903 } 904 905 /** 906 * Sets the font that the receiver will use to paint textual information 907 * for this item to the font specified by the argument, or to the default font 908 * for that kind of control if the argument is null. 909 * 910 * @param font the new font (or null) 911 * 912 * @exception IllegalArgumentException <ul> 913 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 914 * </ul> 915 * @exception SWTException <ul> 916 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 917 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 918 * </ul> 919 * 920 * @since 3.0 921 */ 922 public void setFont (Font font){ 923 checkWidget (); 924 if (font !is null && font.isDisposed ()) { 925 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 926 } 927 Font oldFont = this.font; 928 if (oldFont is font) return; 929 this.font = font; 930 if (oldFont !is null && oldFont.opEquals (font)) return; 931 auto fontHandle = font !is null ? font.handle : null; 932 OS.gtk_list_store_set1 (parent.modelHandle, handle, Table.FONT_COLUMN, fontHandle); 933 /* 934 * Bug in GTK. When using fixed-height-mode, 935 * row changes do not cause the row to be repainted. The fix is to 936 * invalidate the row when it is cleared. 937 */ 938 if ((parent.style & SWT.VIRTUAL) !is 0) { 939 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 940 redraw (); 941 } 942 } 943 cached = true; 944 } 945 946 /** 947 * Sets the font that the receiver will use to paint textual information 948 * for the specified cell in this item to the font specified by the 949 * argument, or to the default font for that kind of control if the 950 * argument is null. 951 * 952 * @param index the column index 953 * @param font the new font (or null) 954 * 955 * @exception IllegalArgumentException <ul> 956 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 957 * </ul> 958 * @exception SWTException <ul> 959 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 960 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 961 * </ul> 962 * 963 * @since 3.0 964 */ 965 public void setFont (int index, Font font) { 966 checkWidget (); 967 if (font !is null && font.isDisposed ()) { 968 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 969 } 970 int count = Math.max (1, parent.getColumnCount ()); 971 if (0 > index || index > count - 1) return; 972 if (cellFont is null) { 973 if (font is null) return; 974 cellFont = new Font [count]; 975 } 976 Font oldFont = cellFont [index]; 977 if (oldFont is font) return; 978 cellFont [index] = font; 979 if (oldFont !is null && oldFont.opEquals (font)) return; 980 981 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 982 auto fontHandle = font !is null ? font.handle : null; 983 OS.gtk_list_store_set1 (parent.modelHandle, handle, modelIndex + Table.CELL_FONT, fontHandle); 984 /* 985 * Bug in GTK. When using fixed-height-mode, 986 * row changes do not cause the row to be repainted. The fix is to 987 * invalidate the row when it is cleared. 988 */ 989 if ((parent.style & SWT.VIRTUAL) !is 0) { 990 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 991 redraw (); 992 } 993 } 994 cached = true; 995 996 if (font !is null) { 997 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; 998 if (!customDraw) { 999 if ((parent.style & SWT.VIRTUAL) is 0) { 1000 auto parentHandle = parent.handle; 1001 GtkTreeViewColumn* column; 1002 if (parent.columnCount > 0) { 1003 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 1004 } else { 1005 column = OS.gtk_tree_view_get_column (parentHandle, index); 1006 } 1007 if (column is null) return; 1008 auto textRenderer = parent.getTextRenderer (column); 1009 auto imageRenderer = parent.getPixbufRenderer (column); 1010 display.doCellDataProc( parentHandle, column, cast(GtkCellRenderer*)textRenderer ); 1011 display.doCellDataProc( parentHandle, column, cast(GtkCellRenderer*)imageRenderer ); 1012 } 1013 if (parent.columnCount is 0) { 1014 parent.firstCustomDraw = true; 1015 } else { 1016 parent.columns [index].customDraw = true; 1017 } 1018 } 1019 } 1020 } 1021 1022 /** 1023 * Sets the receiver's foreground color to the color specified 1024 * by the argument, or to the default system color for the item 1025 * if the argument is null. 1026 * 1027 * @param color the new color (or null) 1028 * 1029 * @exception IllegalArgumentException <ul> 1030 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1031 * </ul> 1032 * @exception SWTException <ul> 1033 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1034 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1035 * </ul> 1036 * 1037 * @since 2.0 1038 */ 1039 public void setForeground (Color color){ 1040 checkWidget (); 1041 if (color !is null && color.isDisposed ()) { 1042 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1043 } 1044 if (_getForeground ().opEquals (color)) return; 1045 GdkColor* gdkColor = color !is null ? color.handle : null; 1046 OS.gtk_list_store_set1 (parent.modelHandle, handle, Table.FOREGROUND_COLUMN, gdkColor); 1047 /* 1048 * Bug in GTK. When using fixed-height-mode, 1049 * row changes do not cause the row to be repainted. The fix is to 1050 * invalidate the row when it is cleared. 1051 */ 1052 if ((parent.style & SWT.VIRTUAL) !is 0) { 1053 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1054 redraw (); 1055 } 1056 } 1057 cached = true; 1058 } 1059 1060 /** 1061 * Sets the foreground color at the given column index in the receiver 1062 * to the color specified by the argument, or to the default system color for the item 1063 * if the argument is null. 1064 * 1065 * @param index the column index 1066 * @param color the new color (or null) 1067 * 1068 * @exception IllegalArgumentException <ul> 1069 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 1070 * </ul> 1071 * @exception SWTException <ul> 1072 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1073 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1074 * </ul> 1075 * 1076 * @since 3.0 1077 */ 1078 public void setForeground (int index, Color color){ 1079 checkWidget (); 1080 if (color !is null && color.isDisposed ()) { 1081 SWT.error (SWT.ERROR_INVALID_ARGUMENT); 1082 } 1083 if (_getForeground (index).opEquals (color)) return; 1084 int count = Math.max (1, parent.getColumnCount ()); 1085 if (0 > index || index > count - 1) return; 1086 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 1087 GdkColor* gdkColor = color !is null ? color.handle : null; 1088 OS.gtk_list_store_set1 (parent.modelHandle, handle, modelIndex + Table.CELL_FOREGROUND, gdkColor); 1089 /* 1090 * Bug in GTK. When using fixed-height-mode, 1091 * row changes do not cause the row to be repainted. The fix is to 1092 * invalidate the row when it is cleared. 1093 */ 1094 if ((parent.style & SWT.VIRTUAL) !is 0) { 1095 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1096 redraw (); 1097 } 1098 } 1099 cached = true; 1100 1101 if (color !is null) { 1102 bool customDraw = (parent.columnCount is 0) ? parent.firstCustomDraw : parent.columns [index].customDraw; 1103 if (!customDraw) { 1104 if ((parent.style & SWT.VIRTUAL) is 0) { 1105 auto parentHandle = parent.handle; 1106 GtkTreeViewColumn* column; 1107 if (parent.columnCount > 0) { 1108 column = cast(GtkTreeViewColumn*)parent.columns [index].handle; 1109 } else { 1110 column = OS.gtk_tree_view_get_column (parentHandle, index); 1111 } 1112 if (column is null) return; 1113 auto textRenderer = parent.getTextRenderer (column); 1114 auto imageRenderer = parent.getPixbufRenderer (column); 1115 display.doCellDataProc( parentHandle, column, cast(GtkCellRenderer*)textRenderer ); 1116 display.doCellDataProc( parentHandle, column, cast(GtkCellRenderer*)imageRenderer ); 1117 } 1118 if (parent.columnCount is 0) { 1119 parent.firstCustomDraw = true; 1120 } else { 1121 parent.columns [index].customDraw = true; 1122 } 1123 } 1124 } 1125 } 1126 1127 /** 1128 * Sets the grayed state of the checkbox for this item. This state change 1129 * only applies if the Table was created with the SWT.CHECK style. 1130 * 1131 * @param grayed the new grayed state of the checkbox; 1132 * 1133 * @exception SWTException <ul> 1134 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1135 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1136 * </ul> 1137 */ 1138 public void setGrayed (bool grayed) { 1139 checkWidget(); 1140 if ((parent.style & SWT.CHECK) is 0) return; 1141 if (this.grayed is grayed) return; 1142 this.grayed = grayed; 1143 /* 1144 * GTK+'s "inconsistent" state does not match SWT's concept of grayed. 1145 * Render checked+grayed as "inconsistent", unchecked+grayed as blank. 1146 */ 1147 void* ptr; 1148 OS.gtk_tree_model_get1 (parent.modelHandle, handle, Table.CHECKED_COLUMN, &ptr); 1149 OS.gtk_list_store_set1 (parent.modelHandle, handle, Table.GRAYED_COLUMN, cast(void*)cast(int)( ptr is null ? false : grayed)); 1150 cached = true; 1151 } 1152 1153 /** 1154 * Sets the receiver's image at a column. 1155 * 1156 * @param index the column index 1157 * @param image the new image 1158 * 1159 * @exception IllegalArgumentException <ul> 1160 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> 1161 * </ul> 1162 * @exception SWTException <ul> 1163 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1164 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1165 * </ul> 1166 */ 1167 public void setImage (int index, Image image) { 1168 checkWidget (); 1169 if (image !is null && image.isDisposed ()) { 1170 error(SWT.ERROR_INVALID_ARGUMENT); 1171 } 1172 if (image !is null && image.type is SWT.ICON) { 1173 if (image.opEquals (_getImage (index))) return; 1174 } 1175 int count = Math.max (1, parent.getColumnCount ()); 1176 if (0 > index || index > count - 1) return; 1177 void* pixbuf; 1178 if (image !is null) { 1179 ImageList imageList = parent.imageList; 1180 if (imageList is null) imageList = parent.imageList = new ImageList (); 1181 int imageIndex = imageList.indexOf (image); 1182 if (imageIndex is -1) imageIndex = imageList.add (image); 1183 pixbuf = imageList.getPixbuf (imageIndex); 1184 } 1185 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 1186 OS.gtk_list_store_set1 (parent.modelHandle, handle, modelIndex + Table.CELL_PIXBUF, pixbuf); 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 /* 1198 * Bug in GTK. When in fixed height mode, GTK does not recalculate the cell renderer width 1199 * when the image is changed in the model. The fix is to force it to recalculate the width if 1200 * more space is required. 1201 */ 1202 if ((parent.style & SWT.VIRTUAL) !is 0 && parent.currentItem is null) { 1203 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2)) { 1204 if (image !is null) { 1205 auto parentHandle = parent.handle; 1206 auto column = OS.gtk_tree_view_get_column (parentHandle, index); 1207 int w; 1208 auto pixbufRenderer = parent.getPixbufRenderer(column); 1209 OS.gtk_tree_view_column_cell_get_position (column, pixbufRenderer, null, &w); 1210 if (w < image.getBounds().width) { 1211 /* 1212 * There is no direct way to clear the cell renderer width so we 1213 * are relying on the fact that it is done as part of modifying 1214 * the style. 1215 */ 1216 auto style = OS.gtk_widget_get_modifier_style (parentHandle); 1217 parent.modifyStyle (parentHandle, style); 1218 } 1219 } 1220 } 1221 } 1222 cached = true; 1223 } 1224 1225 public override void setImage (Image image) { 1226 checkWidget (); 1227 setImage (0, image); 1228 } 1229 1230 /** 1231 * Sets the image for multiple columns in the table. 1232 * 1233 * @param images the array of new images 1234 * 1235 * @exception IllegalArgumentException <ul> 1236 * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li> 1237 * </ul> 1238 * @exception SWTException <ul> 1239 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1240 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1241 * </ul> 1242 */ 1243 public void setImage (Image [] images) { 1244 checkWidget (); 1245 for (int i=0; i<images.length; i++) { 1246 setImage (i, images [i]); 1247 } 1248 } 1249 1250 /** 1251 * Sets the indent of the first column's image, expressed in terms of the image's width. 1252 * 1253 * @param indent the new indent 1254 * 1255 * </ul> 1256 * @exception SWTException <ul> 1257 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1258 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1259 * </ul> 1260 * 1261 * @deprecated this functionality is not supported on most platforms 1262 */ 1263 public void setImageIndent (int indent) { 1264 checkWidget (); 1265 if (indent < 0) return; 1266 /* Image indent is not supported on GTK */ 1267 cached = true; 1268 } 1269 1270 /** 1271 * Sets the receiver's text at a column 1272 * 1273 * @param index the column index 1274 * @param string the new text 1275 * 1276 * @exception SWTException <ul> 1277 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1278 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1279 * </ul> 1280 */ 1281 public void setText (int index, String string) { 1282 checkWidget (); 1283 if (_getText (index).equals (string)) return; 1284 int count = Math.max (1, parent.getColumnCount ()); 1285 if (0 > index || index > count - 1) return; 1286 char* buffer = toStringz( string ); 1287 int modelIndex = parent.columnCount is 0 ? Table.FIRST_COLUMN : parent.columns [index].modelIndex; 1288 OS.gtk_list_store_set1 (parent.modelHandle, handle, modelIndex + Table.CELL_TEXT, buffer); 1289 /* 1290 * Bug in GTK. When using fixed-height-mode, 1291 * row changes do not cause the row to be repainted. The fix is to 1292 * invalidate the row when it is cleared. 1293 */ 1294 if ((parent.style & SWT.VIRTUAL) !is 0) { 1295 if (OS.GTK_VERSION >= OS.buildVERSION (2, 3, 2) && OS.GTK_VERSION < OS.buildVERSION (2, 6, 3)) { 1296 redraw (); 1297 } 1298 } 1299 cached = true; 1300 } 1301 1302 public override void setText (String string) { 1303 checkWidget (); 1304 setText (0, string); 1305 } 1306 1307 /** 1308 * Sets the text for multiple columns in the table. 1309 * 1310 * @param strings the array of new strings 1311 * 1312 * @exception SWTException <ul> 1313 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1314 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1315 * </ul> 1316 */ 1317 public void setText (String [] strings) { 1318 checkWidget (); 1319 for (int i=0; i<strings.length; i++) { 1320 String string = strings [i]; 1321 if (string !is null) setText (i, string); 1322 } 1323 } 1324 }