Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/custom/TableTree.d @ 49:7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 27 Mar 2009 12:59:54 +0100 |
parents | f713da8bc051 |
children | c01d033c633a |
rev | line source |
---|---|
25 | 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 | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
86 static const TableTreeItem[] EMPTY_ITEMS; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
87 static const String[] EMPTY_TEXTS; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
88 static const Image[] EMPTY_IMAGES; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
89 static const String ITEMID = "TableTreeItemID"; //$NON-NLS-1$ |
25 | 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 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 = 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 (int i = 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 = 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 } |