1 /******************************************************************************* 2 * Copyright (c) 2000, 2007 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.custom.TableTree; 14 15 16 17 import org.eclipse.swt.SWT; 18 import org.eclipse.swt.SWTException; 19 import org.eclipse.swt.events.SelectionEvent; 20 import org.eclipse.swt.events.SelectionListener; 21 import org.eclipse.swt.events.TreeListener; 22 import org.eclipse.swt.graphics.Color; 23 import org.eclipse.swt.graphics.Font; 24 import org.eclipse.swt.graphics.GC; 25 import org.eclipse.swt.graphics.Image; 26 import org.eclipse.swt.graphics.ImageData; 27 import org.eclipse.swt.graphics.PaletteData; 28 import org.eclipse.swt.graphics.Point; 29 import org.eclipse.swt.graphics.RGB; 30 import org.eclipse.swt.graphics.Rectangle; 31 import org.eclipse.swt.widgets.Composite; 32 import org.eclipse.swt.widgets.Event; 33 import org.eclipse.swt.widgets.Listener; 34 import org.eclipse.swt.widgets.Menu; 35 import org.eclipse.swt.widgets.Table; 36 import org.eclipse.swt.widgets.TableItem; 37 import org.eclipse.swt.widgets.TypedListener; 38 import org.eclipse.swt.custom.TableTreeItem; 39 import java.lang.all; 40 41 /** 42 * A TableTree is a selectable user interface object 43 * that displays a hierarchy of items, and issues 44 * notification when an item is selected. 45 * A TableTree may be single or multi select. 46 * <p> 47 * The item children that may be added to instances of this class 48 * must be of type <code>TableTreeItem</code>. 49 * </p><p> 50 * Note that although this class is a subclass of <code>Composite</code>, 51 * it does not make sense to add <code>Control</code> children to it, 52 * or set a layout on it. 53 * </p><p> 54 * <dl> 55 * <dt><b>Styles:</b> <dd> SINGLE, MULTI, CHECK, FULL_SELECTION 56 * <dt><b>Events:</b> <dd> Selection, DefaultSelection, Collapse, Expand 57 * </dl> 58 * <p> 59 * Note: Only one of the styles SINGLE, and MULTI may be specified. 60 * </p> 61 * 62 * @deprecated As of 3.1 use Tree, TreeItem and TreeColumn 63 */ 64 public class TableTree : Composite { 65 66 alias Composite.computeSize computeSize; 67 68 Table table; 69 TableTreeItem[] items; 70 Image plusImage, minusImage, sizeImage; 71 72 /* 73 * TableTreeItems are not treated as children but rather as items. 74 * When the TableTree is disposed, all children are disposed because 75 * TableTree inherits this behaviour from Composite. The items 76 * must be disposed separately. Because TableTree is not part of 77 * the org.eclipse.swt.widgets module, the method releaseWidget can 78 * not be overridden (this is how items are disposed of in Table and Tree). 79 * Instead, the items are disposed of in response to the dispose event on the 80 * TableTree. The "inDispose" flag is used to distinguish between disposing 81 * one TableTreeItem (e.g. when removing an entry from the TableTree) and 82 * disposing the entire TableTree. 83 */ 84 bool inDispose = false; 85 86 static /+const+/ TableTreeItem[] EMPTY_ITEMS; 87 static /+const+/ String[] EMPTY_TEXTS; 88 static /+const+/ Image[] EMPTY_IMAGES; 89 static /+const+/ String ITEMID = "TableTreeItemID"; //$NON-NLS-1$ 90 91 /** 92 * Constructs a new instance of this class given its parent 93 * and a style value describing its behavior and appearance. 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 widget which will be the parent of the new instance (cannot be null) 105 * @param style the style of widget to construct 106 * 107 * @exception IllegalArgumentException <ul> 108 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 109 * </ul> 110 * @exception SWTException <ul> 111 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 112 * </ul> 113 * 114 * @see SWT#SINGLE 115 * @see SWT#MULTI 116 * @see SWT#CHECK 117 * @see SWT#FULL_SELECTION 118 * @see #getStyle 119 */ 120 public this(Composite parent, int style) { 121 super(parent, checkStyle (style)); 122 items = EMPTY_ITEMS; 123 table = new Table(this, style); 124 Listener tableListener = new class() Listener { 125 public void handleEvent(Event e) { 126 switch (e.type) { 127 case SWT.MouseDown: onMouseDown(e); break; 128 case SWT.Selection: onSelection(e); break; 129 case SWT.DefaultSelection: onSelection(e); break; 130 case SWT.KeyDown: onKeyDown(e); break; 131 default: 132 } 133 } 134 }; 135 int[] tableEvents = [SWT.MouseDown, 136 SWT.Selection, 137 SWT.DefaultSelection, 138 SWT.KeyDown]; 139 for (int i = 0; i < tableEvents.length; i++) { 140 table.addListener(tableEvents[i], tableListener); 141 } 142 143 Listener listener = new class() Listener { 144 public void handleEvent(Event e) { 145 switch (e.type) { 146 case SWT.Dispose: onDispose(e); break; 147 case SWT.Resize: onResize(e); break; 148 case SWT.FocusIn: onFocusIn(e); break; 149 default: 150 } 151 } 152 }; 153 int[] events = [SWT.Dispose, 154 SWT.Resize, 155 SWT.FocusIn]; 156 for (int i = 0; i < events.length; i++) { 157 addListener(events[i], listener); 158 } 159 } 160 161 int addItem(TableTreeItem item, int index) { 162 if (index < 0 || index > items.length) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 163 TableTreeItem[] newItems = new TableTreeItem[items.length + 1]; 164 System.arraycopy(items, 0, newItems, 0, index); 165 newItems[index] = item; 166 System.arraycopy(items, index, newItems, index + 1, items.length - index); 167 items = newItems; 168 169 /* Return the index in the table where this table should be inserted */ 170 if (index is items.length - 1 ) 171 return table.getItemCount(); 172 else 173 return table.indexOf(items[index+1].tableItem); 174 } 175 176 /** 177 * Adds the listener to the collection of listeners who will 178 * be notified when the user changes the receiver's selection, by sending 179 * it one of the messages defined in the <code>SelectionListener</code> 180 * interface. 181 * <p> 182 * When <code>widgetSelected</code> is called, the item field of the event object is valid. 183 * If the receiver has <code>SWT.CHECK</code> style set and the check selection changes, 184 * the event object detail field contains the value <code>SWT.CHECK</code>. 185 * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked. 186 * The item field of the event object is valid for default selection, but the detail field is not used. 187 * </p> 188 * 189 * @param listener the listener which should be notified when the user changes the receiver's selection 190 * 191 * @exception IllegalArgumentException <ul> 192 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 193 * </ul> 194 * @exception SWTException <ul> 195 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 196 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 197 * </ul> 198 * 199 * @see SelectionListener 200 * @see #removeSelectionListener 201 * @see SelectionEvent 202 */ 203 public void addSelectionListener(SelectionListener listener) { 204 checkWidget(); 205 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 206 TypedListener typedListener = new TypedListener (listener); 207 addListener (SWT.Selection,typedListener); 208 addListener (SWT.DefaultSelection,typedListener); 209 } 210 211 /** 212 * Adds the listener to the collection of listeners who will 213 * be notified when an item in the receiver is expanded or collapsed 214 * by sending it one of the messages defined in the <code>TreeListener</code> 215 * interface. 216 * 217 * @param listener the listener which should be notified 218 * 219 * @exception IllegalArgumentException <ul> 220 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 221 * </ul> 222 * @exception SWTException <ul> 223 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 224 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 225 * </ul> 226 * 227 * @see TreeListener 228 * @see #removeTreeListener 229 */ 230 public void addTreeListener(TreeListener listener) { 231 checkWidget(); 232 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 233 TypedListener typedListener = new TypedListener (listener); 234 addListener (SWT.Expand, typedListener); 235 addListener (SWT.Collapse, typedListener); 236 } 237 private static int checkStyle (int style) { 238 int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; 239 style = style & mask; 240 return style; 241 } 242 public override Point computeSize (int wHint, int hHint, bool changed) { 243 checkWidget(); 244 return table.computeSize (wHint, hHint, changed); 245 } 246 public override Rectangle computeTrim (int x, int y, int width, int height) { 247 checkWidget(); 248 return table.computeTrim(x, y, width, height); 249 } 250 251 /** 252 * Deselects all items. 253 * <p> 254 * If an item is selected, it is deselected. 255 * If an item is not selected, it remains unselected. 256 * 257 * @exception SWTException <ul> 258 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread 259 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed 260 * </ul> 261 */ 262 public void deselectAll () { 263 checkWidget(); 264 table.deselectAll(); 265 } 266 267 /* Expand upward from the specified leaf item. */ 268 void expandItem (TableTreeItem item) { 269 if (item is null) return; 270 expandItem(item.parentItem); 271 if (!item.getVisible()) item.setVisible(true); 272 if ( !item.expanded && item.items.length > 0) { 273 item.setExpanded(true); 274 Event event = new Event(); 275 event.item = item; 276 notifyListeners(SWT.Expand, event); 277 } 278 } 279 public override Color getBackground () { 280 // This method must be overridden otherwise, in a TableTree in which the first 281 // item has no sub items, a grey (Widget background colour) square will appear in 282 // the first column of the first item. 283 // It is not possible in the constructor to set the background of the TableTree 284 // to be the same as the background of the Table because this interferes with 285 // the TableTree adapting to changes in the System color settings. 286 return table.getBackground(); 287 } 288 public override Rectangle getClientArea () { 289 return table.getClientArea(); 290 } 291 public override Color getForeground () { 292 return table.getForeground(); 293 } 294 public override Font getFont () { 295 return table.getFont(); 296 } 297 /** 298 * Gets the number of items. 299 * <p> 300 * @return the number of items in the widget 301 */ 302 public int getItemCount () { 303 //checkWidget(); 304 return cast(int)/*64bit*/items.length; 305 } 306 307 /** 308 * Gets the height of one item. 309 * <p> 310 * This operation will fail if the height of 311 * one item could not be queried from the OS. 312 * 313 * @return the height of one item in the widget 314 * 315 * @exception SWTException <ul> 316 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread 317 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed 318 * </ul> 319 */ 320 public int getItemHeight () { 321 checkWidget(); 322 return table.getItemHeight(); 323 } 324 325 /** 326 * Gets the items. 327 * <p> 328 * @return the items in the widget 329 */ 330 public TableTreeItem [] getItems () { 331 //checkWidget(); 332 TableTreeItem[] newItems = new TableTreeItem[items.length]; 333 System.arraycopy(items, 0, newItems, 0, items.length); 334 return newItems; 335 } 336 337 /** 338 * Gets the selected items. 339 * <p> 340 * This operation will fail if the selected 341 * items cannot be queried from the OS. 342 * 343 * @return the selected items in the widget 344 * 345 * @exception SWTException <ul> 346 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> 347 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> 348 * </ul> 349 */ 350 public TableTreeItem [] getSelection () { 351 checkWidget(); 352 TableItem[] selection = table.getSelection(); 353 TableTreeItem [] result = new TableTreeItem[selection.length]; 354 for (int i = 0; i < selection.length; i++){ 355 result[i] = cast(TableTreeItem) selection[i].getData(ITEMID); 356 } 357 return result; 358 } 359 360 /** 361 * Gets the number of selected items. 362 * <p> 363 * This operation will fail if the number of selected 364 * items cannot be queried from the OS. 365 * 366 * @return the number of selected items in the widget 367 * 368 * @exception SWTException <ul> 369 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> 370 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> 371 * </ul> 372 */ 373 public int getSelectionCount () { 374 checkWidget(); 375 return table.getSelectionCount(); 376 } 377 378 public override int getStyle () { 379 checkWidget(); 380 return table.getStyle(); 381 } 382 383 /** 384 * Returns the underlying Table control. 385 * 386 * @return the underlying Table control 387 */ 388 public Table getTable () { 389 //checkWidget(); 390 return table; 391 } 392 393 void createImages () { 394 395 int itemHeight = sizeImage.getBounds().height; 396 // Calculate border around image. 397 // At least 9 pixels are needed to draw the image 398 // Leave at least a 6 pixel border. 399 int indent = Math.min(6, (itemHeight - 9) / 2); 400 indent = Math.max(0, indent); 401 int size = Math.max (10, itemHeight - 2 * indent); 402 size = ((size + 1) / 2) * 2; // size must be an even number 403 int midpoint = indent + size / 2; 404 405 Color foreground = getForeground(); 406 Color plusMinus = getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); 407 Color background = getBackground(); 408 409 /* Plus image */ 410 PaletteData palette = new PaletteData( [ foreground.getRGB(), background.getRGB(), plusMinus.getRGB()]); 411 ImageData imageData = new ImageData(itemHeight, itemHeight, 4, palette); 412 imageData.transparentPixel = 1; 413 plusImage = new Image(getDisplay(), imageData); 414 GC gc = new GC(plusImage); 415 gc.setBackground(background); 416 gc.fillRectangle(0, 0, itemHeight, itemHeight); 417 gc.setForeground(plusMinus); 418 gc.drawRectangle(indent, indent, size, size); 419 gc.setForeground(foreground); 420 gc.drawLine(midpoint, indent + 2, midpoint, indent + size - 2); 421 gc.drawLine(indent + 2, midpoint, indent + size - 2, midpoint); 422 gc.dispose(); 423 424 /* Minus image */ 425 palette = new PaletteData([foreground.getRGB(), background.getRGB(), plusMinus.getRGB()]); 426 imageData = new ImageData(itemHeight, itemHeight, 4, palette); 427 imageData.transparentPixel = 1; 428 minusImage = new Image(getDisplay(), imageData); 429 gc = new GC(minusImage); 430 gc.setBackground(background); 431 gc.fillRectangle(0, 0, itemHeight, itemHeight); 432 gc.setForeground(plusMinus); 433 gc.drawRectangle(indent, indent, size, size); 434 gc.setForeground(foreground); 435 gc.drawLine(indent + 2, midpoint, indent + size - 2, midpoint); 436 gc.dispose(); 437 } 438 439 Image getPlusImage() { 440 if (plusImage is null) createImages(); 441 return plusImage; 442 } 443 444 Image getMinusImage() { 445 if (minusImage is null) createImages(); 446 return minusImage; 447 } 448 449 /** 450 * Gets the index of an item. 451 * 452 * <p>The widget is searched starting at 0 until an 453 * item is found that is equal to the search item. 454 * If no item is found, -1 is returned. Indexing 455 * is zero based. This index is relative to the parent only. 456 * 457 * @param item the search item 458 * @return the index of the item or -1 459 */ 460 public int indexOf (TableTreeItem item) { 461 //checkWidget(); 462 for (int i = 0; i < items.length; i++) { 463 if (item is items[i]) return i; 464 } 465 return -1; 466 } 467 468 void onDispose(Event e) { 469 /* 470 * Usually when an item is disposed, destroyItem will change the size of the items array 471 * and dispose of the underlying table items. 472 * Since the whole table tree is being disposed, this is not necessary. For speed 473 * the inDispose flag is used to skip over this part of the item dispose. 474 */ 475 inDispose = true; 476 for (int i = 0; i < items.length; i++) { 477 items[i].dispose(); 478 } 479 inDispose = false; 480 if (plusImage !is null) plusImage.dispose(); 481 if (minusImage !is null) minusImage.dispose(); 482 if (sizeImage !is null) sizeImage.dispose(); 483 plusImage = minusImage = sizeImage = null; 484 } 485 486 void onResize(Event e) { 487 Point size = getSize(); 488 table.setBounds(0, 0, size.x, size.y); 489 } 490 491 void onSelection(Event e) { 492 Event event = new Event(); 493 TableItem tableItem = cast(TableItem)e.item; 494 TableTreeItem item = getItem(tableItem); 495 event.item = item; 496 497 if (e.type is SWT.Selection && e.detail is SWT.CHECK && item !is null) { 498 event.detail = SWT.CHECK; 499 item.checked = tableItem.getChecked(); 500 } 501 notifyListeners(e.type, event); 502 } 503 /** 504 * Returns the item at the given, zero-relative index in the 505 * receiver. Throws an exception if the index is out of range. 506 * 507 * @param index the index of the item to return 508 * @return the item at the given index 509 * 510 * @exception IllegalArgumentException <ul> 511 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> 512 * </ul> 513 * @exception SWTException <ul> 514 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 515 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 516 * </ul> 517 * 518 * @since 3.1 519 */ 520 public TableTreeItem getItem (int index) { 521 checkWidget(); 522 int count = cast(int)/*64bit*/items.length; 523 if (!(0 <= index && index < count)) SWT.error (SWT.ERROR_INVALID_RANGE); 524 return items [index]; 525 } 526 527 /** 528 * Returns the item at the given point in the receiver 529 * or null if no such item exists. The point is in the 530 * coordinate system of the receiver. 531 * 532 * @param point the point used to locate the item 533 * @return the item at the given point 534 * 535 * @exception IllegalArgumentException <ul> 536 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> 537 * </ul> 538 * @exception SWTException <ul> 539 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 540 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 541 * </ul> 542 */ 543 public TableTreeItem getItem(Point point) { 544 checkWidget(); 545 TableItem item = table.getItem(point); 546 if (item is null) return null; 547 return getItem(item); 548 549 } 550 TableTreeItem getItem(TableItem tableItem) { 551 if (tableItem is null) return null; 552 for (int i = 0; i < items.length; i++) { 553 TableTreeItem item = items[i].getItem(tableItem); 554 if (item !is null) return item; 555 } 556 return null; 557 } 558 void onFocusIn (Event e) { 559 table.setFocus(); 560 } 561 562 void onKeyDown (Event e) { 563 TableTreeItem[] selection = getSelection(); 564 if (selection.length is 0) return; 565 TableTreeItem item = selection[0]; 566 int type = 0; 567 if (e.keyCode is SWT.ARROW_RIGHT || e.keyCode is SWT.ARROW_LEFT) { 568 int trailKey = (getStyle() & SWT.MIRRORED) !is 0 ? SWT.ARROW_LEFT : SWT.ARROW_RIGHT; 569 if (e.keyCode is trailKey) { 570 if (item.getItemCount() is 0) return; 571 if (item.getExpanded()) { 572 TableTreeItem newSelection = item.getItems()[0]; 573 table.setSelection([newSelection.tableItem]); 574 showItem(newSelection); 575 type = SWT.Selection; 576 } else { 577 item.setExpanded(true); 578 type = SWT.Expand; 579 } 580 } else { 581 if (item.getExpanded()) { 582 item.setExpanded(false); 583 type = SWT.Collapse; 584 } else { 585 TableTreeItem parent = item.getParentItem(); 586 if (parent !is null) { 587 int index = parent.indexOf(item); 588 if (index !is 0) return; 589 table.setSelection([parent.tableItem]); 590 type = SWT.Selection; 591 } 592 } 593 } 594 } 595 if (e.character is '*') { 596 item.expandAll(true); 597 } 598 if (e.character is '-') { 599 if (item.getExpanded()) { 600 item.setExpanded(false); 601 type = SWT.Collapse; 602 } 603 } 604 if (e.character is '+') { 605 if (item.getItemCount() > 0 && !item.getExpanded()) { 606 item.setExpanded(true); 607 type = SWT.Expand; 608 } 609 } 610 if (type is 0) return; 611 Event event = new Event(); 612 event.item = item; 613 notifyListeners(type, event); 614 } 615 void onMouseDown(Event event) { 616 /* If user clicked on the [+] or [-], expand or collapse the tree. */ 617 TableItem[] items = table.getItems(); 618 for (int i = 0; i < items.length; i++) { 619 Rectangle rect = items[i].getImageBounds(0); 620 if (rect.contains(event.x, event.y)) { 621 TableTreeItem item = cast(TableTreeItem) items[i].getData(ITEMID); 622 event = new Event(); 623 event.item = item; 624 item.setExpanded(!item.getExpanded()); 625 if (item.getExpanded()) { 626 notifyListeners(SWT.Expand, event); 627 } else { 628 notifyListeners(SWT.Collapse, event); 629 } 630 return; 631 } 632 } 633 } 634 635 /** 636 * Removes all items. 637 * <p> 638 * This operation will fail when an item 639 * could not be removed in the OS. 640 * 641 * @exception SWTException <ul> 642 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread 643 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed 644 * </ul> 645 */ 646 public void removeAll () { 647 checkWidget(); 648 setRedraw(false); 649 for (ptrdiff_t i = cast(ptrdiff_t) (items.length) - 1; i >= 0; i--) { 650 items[i].dispose(); 651 } 652 items = EMPTY_ITEMS; 653 setRedraw(true); 654 } 655 656 void removeItem(TableTreeItem item) { 657 int index = 0; 658 while (index < items.length && items[index] !is item) index++; 659 if (index is items.length) return; 660 TableTreeItem[] newItems = new TableTreeItem[items.length - 1]; 661 System.arraycopy(items, 0, newItems, 0, index); 662 System.arraycopy(items, index + 1, newItems, index, items.length - index - 1); 663 items = newItems; 664 } 665 666 /** 667 * Removes the listener from the collection of listeners who will 668 * be notified when the user changes the receiver's selection. 669 * 670 * @param listener the listener which should no longer be notified 671 * 672 * @exception IllegalArgumentException <ul> 673 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 674 * </ul> 675 * @exception SWTException <ul> 676 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 677 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 678 * </ul> 679 * 680 * @see SelectionListener 681 * @see #addSelectionListener 682 */ 683 public void removeSelectionListener (SelectionListener listener) { 684 checkWidget(); 685 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 686 removeListener(SWT.Selection, listener); 687 removeListener(SWT.DefaultSelection, listener); 688 } 689 690 /** 691 * Removes the listener from the collection of listeners who will 692 * be notified when items in the receiver are expanded or collapsed. 693 * 694 * @param listener the listener which should no longer be notified 695 * 696 * @exception IllegalArgumentException <ul> 697 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 698 * </ul> 699 * @exception SWTException <ul> 700 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 701 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 702 * </ul> 703 * 704 * @see TreeListener 705 * @see #addTreeListener 706 */ 707 public void removeTreeListener (TreeListener listener) { 708 checkWidget(); 709 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 710 removeListener(SWT.Expand, listener); 711 removeListener(SWT.Collapse, listener); 712 } 713 714 /** 715 * Selects all of the items in the receiver. 716 * <p> 717 * If the receiver is single-select, do nothing. 718 * 719 * @exception SWTException <ul> 720 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread 721 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed 722 * </ul> 723 */ 724 public void selectAll () { 725 checkWidget(); 726 table.selectAll(); 727 } 728 public override void setBackground (Color color) { 729 super.setBackground(color); 730 table.setBackground(color); 731 if (sizeImage !is null) { 732 GC gc = new GC (sizeImage); 733 gc.setBackground(getBackground()); 734 Rectangle size = sizeImage.getBounds(); 735 gc.fillRectangle(size); 736 gc.dispose(); 737 } 738 } 739 public override void setEnabled (bool enabled) { 740 super.setEnabled(enabled); 741 table.setEnabled(enabled); 742 } 743 public override void setFont (Font font) { 744 super.setFont(font); 745 table.setFont(font); 746 } 747 public override void setForeground (Color color) { 748 super.setForeground(color); 749 table.setForeground(color); 750 } 751 public override void setMenu (Menu menu) { 752 super.setMenu(menu); 753 table.setMenu(menu); 754 } 755 756 /** 757 * Sets the receiver's selection to be the given array of items. 758 * The current selection is cleared before the new items are selected. 759 * <p> 760 * Items that are not in the receiver are ignored. 761 * If the receiver is single-select and multiple items are specified, 762 * then all items are ignored. 763 * 764 * @param items the array of items 765 * 766 * @exception IllegalArgumentException <ul> 767 * <li>ERROR_INVALID_ARGUMENT - if one of the item has been disposed</li> 768 * </ul> 769 * @exception SWTException <ul> 770 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 771 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 772 * </ul> 773 * 774 * @see TableTree#deselectAll() 775 */ 776 public void setSelection (TableTreeItem[] items) { 777 checkWidget (); 778 // SWT extension: allow null for zero length string 779 //if (items is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 780 int length = cast(int)/*64bit*/items.length; 781 if (length is 0 || ((table.getStyle() & SWT.SINGLE) !is 0 && length > 1)) { 782 deselectAll(); 783 return; 784 } 785 TableItem[] tableItems = new TableItem[length]; 786 for (int i = 0; i < length; i++) { 787 if (items[i] is null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 788 if (!items[i].getVisible()) expandItem (items[i]); 789 tableItems[i] = items[i].tableItem; 790 } 791 table.setSelection(tableItems); 792 } 793 public override void setToolTipText (String string) { 794 super.setToolTipText(string); 795 table.setToolTipText(string); 796 } 797 798 /** 799 * Shows the item. If the item is already showing in the receiver, 800 * this method simply returns. Otherwise, the items are scrolled 801 * and expanded until the item is visible. 802 * 803 * @param item the item to be shown 804 * 805 * @exception IllegalArgumentException <ul> 806 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> 807 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> 808 * </ul> 809 * @exception SWTException <ul> 810 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 811 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 812 * </ul> 813 * 814 * @see TableTree#showSelection() 815 */ 816 public void showItem (TableTreeItem item) { 817 checkWidget(); 818 if (item is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 819 if (!item.getVisible()) expandItem (item); 820 TableItem tableItem = item.tableItem; 821 table.showItem(tableItem); 822 } 823 824 /** 825 * Shows the selection. 826 * <p> 827 * If there is no selection or the selection 828 * is already visible, this method does nothing. 829 * If the selection is scrolled out of view, 830 * the top index of the widget is changed such 831 * that selection becomes visible. 832 * 833 * @exception SWTException <ul> 834 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread 835 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed 836 * </ul> 837 */ 838 public void showSelection () { 839 checkWidget(); 840 table.showSelection(); 841 } 842 }