diff options
9 files changed, 2352 insertions, 30 deletions
diff --git a/bundles/org.eclipse.swt/.settings/.api_filters b/bundles/org.eclipse.swt/.settings/.api_filters index 6600b29f76..48a1a2b9a6 100644 --- a/bundles/org.eclipse.swt/.settings/.api_filters +++ b/bundles/org.eclipse.swt/.settings/.api_filters @@ -1404,28 +1404,4 @@ </message_arguments> </filter> </resource> - <resource path="META-INF/MANIFEST.MF" type="org.eclipse.swt.custom.TableTree"> - <filter comment="Bug 475833: Delete TableTree and related items" id="305324134"> - <message_arguments> - <message_argument value="org.eclipse.swt.custom.TableTree"/> - <message_argument value="org.eclipse.swt_3.104.0"/> - </message_arguments> - </filter> - </resource> - <resource path="META-INF/MANIFEST.MF" type="org.eclipse.swt.custom.TableTreeEditor"> - <filter comment="Bug 475833: Delete TableTree and related items" id="305324134"> - <message_arguments> - <message_argument value="org.eclipse.swt.custom.TableTreeEditor"/> - <message_argument value="org.eclipse.swt_3.104.0"/> - </message_arguments> - </filter> - </resource> - <resource path="META-INF/MANIFEST.MF" type="org.eclipse.swt.custom.TableTreeItem"> - <filter comment="Bug 475833: Delete TableTree and related items" id="305324134"> - <message_arguments> - <message_argument value="org.eclipse.swt.custom.TableTreeItem"/> - <message_argument value="org.eclipse.swt_3.104.0"/> - </message_arguments> - </filter> - </resource> </component> diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java new file mode 100644 index 0000000000..f5ac1e3578 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTree.java @@ -0,0 +1,832 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.custom; + + +import org.eclipse.swt.*; +import org.eclipse.swt.events.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; + +/** + * A TableTree is a selectable user interface object + * that displays a hierarchy of items, and issues + * notification when an item is selected. + * A TableTree may be single or multi select. + * <p> + * The item children that may be added to instances of this class + * must be of type <code>TableTreeItem</code>. + * </p><p> + * Note that although this class is a subclass of <code>Composite</code>, + * it does not make sense to add <code>Control</code> children to it, + * or set a layout on it. + * </p><p> + * <dl> + * <dt><b>Styles:</b> <dd> SINGLE, MULTI, CHECK, FULL_SELECTION + * <dt><b>Events:</b> <dd> Selection, DefaultSelection, Collapse, Expand + * </dl> + * <p> + * Note: Only one of the styles SINGLE, and MULTI may be specified. + * </p> + * + * @deprecated As of 3.1 use Tree, TreeItem and TreeColumn + */ +@Deprecated +public class TableTree extends Composite { + Table table; + TableTreeItem[] items = EMPTY_ITEMS; + Image plusImage, minusImage, sizeImage; + Listener listener; + + /* + * TableTreeItems are not treated as children but rather as items. + * When the TableTree is disposed, all children are disposed because + * TableTree inherits this behaviour from Composite. The items + * must be disposed separately. Because TableTree is not part of + * the org.eclipse.swt.widgets package, the method releaseWidget can + * not be overridden (this is how items are disposed of in Table and Tree). + * Instead, the items are disposed of in response to the dispose event on the + * TableTree. The "inDispose" flag is used to distinguish between disposing + * one TableTreeItem (e.g. when removing an entry from the TableTree) and + * disposing the entire TableTree. + */ + boolean inDispose = false; + + static final TableTreeItem[] EMPTY_ITEMS = new TableTreeItem [0]; + static final String[] EMPTY_TEXTS = new String [0]; + static final Image[] EMPTY_IMAGES = new Image [0]; + static final String ITEMID = "TableTreeItemID"; //$NON-NLS-1$ + +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a widget which will be the parent of the new instance (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT#SINGLE + * @see SWT#MULTI + * @see SWT#CHECK + * @see SWT#FULL_SELECTION + * @see #getStyle + */ +public TableTree(Composite parent, int style) { + super(parent, checkStyle (style)); + table = new Table(this, style); + Listener tableListener = new Listener() { + public void handleEvent(Event e) { + switch (e.type) { + case SWT.MouseDown: onMouseDown(e); break; + case SWT.Selection: onSelection(e); break; + case SWT.DefaultSelection: onSelection(e); break; + case SWT.KeyDown: onKeyDown(e); break; + } + } + }; + int[] tableEvents = new int[]{SWT.MouseDown, + SWT.Selection, + SWT.DefaultSelection, + SWT.KeyDown}; + for (int i = 0; i < tableEvents.length; i++) { + table.addListener(tableEvents[i], tableListener); + } + + listener = new Listener() { + public void handleEvent(Event e) { + switch (e.type) { + case SWT.Dispose: onDispose(e); break; + case SWT.Resize: onResize(e); break; + case SWT.FocusIn: onFocusIn(e); break; + } + } + }; + int[] events = new int[]{SWT.Dispose, + SWT.Resize, + SWT.FocusIn}; + for (int i = 0; i < events.length; i++) { + addListener(events[i], listener); + } +} + +int addItem(TableTreeItem item, int index) { + if (index < 0 || index > items.length) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + TableTreeItem[] newItems = new TableTreeItem[items.length + 1]; + System.arraycopy(items, 0, newItems, 0, index); + newItems[index] = item; + System.arraycopy(items, index, newItems, index + 1, items.length - index); + items = newItems; + + /* Return the index in the table where this table should be inserted */ + if (index == items.length - 1 ) + return table.getItemCount(); + else + return table.indexOf(items[index+1].tableItem); +} + +/** + * Adds the listener to the collection of listeners who will + * be notified when the user changes the receiver's selection, by sending + * it one of the messages defined in the <code>SelectionListener</code> + * interface. + * <p> + * When <code>widgetSelected</code> is called, the item field of the event object is valid. + * If the receiver has <code>SWT.CHECK</code> style set and the check selection changes, + * the event object detail field contains the value <code>SWT.CHECK</code>. + * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked. + * The item field of the event object is valid for default selection, but the detail field is not used. + * </p> + * + * @param listener the listener which should be notified when the user changes the receiver's selection + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ +public void addSelectionListener(SelectionListener listener) { + checkWidget(); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener (listener); + addListener (SWT.Selection,typedListener); + addListener (SWT.DefaultSelection,typedListener); +} + +/** + * Adds the listener to the collection of listeners who will + * be notified when an item in the receiver is expanded or collapsed + * by sending it one of the messages defined in the <code>TreeListener</code> + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see TreeListener + * @see #removeTreeListener + */ +public void addTreeListener(TreeListener listener) { + checkWidget(); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener (listener); + addListener (SWT.Expand, typedListener); + addListener (SWT.Collapse, typedListener); +} +private static int checkStyle (int style) { + int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; + style = style & mask; + return style; +} +@Override +public Point computeSize (int wHint, int hHint, boolean changed) { + checkWidget(); + return table.computeSize (wHint, hHint, changed); +} +@Override +public Rectangle computeTrim (int x, int y, int width, int height) { + checkWidget(); + return table.computeTrim(x, y, width, height); +} + +/** + * Deselects all items. + * <p> + * If an item is selected, it is deselected. + * If an item is not selected, it remains unselected. + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed + * </ul> + */ +public void deselectAll () { + checkWidget(); + table.deselectAll(); +} + +/* Expand upward from the specified leaf item. */ +void expandItem (TableTreeItem item) { + if (item == null) return; + expandItem(item.parentItem); + if (!item.getVisible()) item.setVisible(true); + if ( !item.expanded && item.items.length > 0) { + item.setExpanded(true); + Event event = new Event(); + event.item = item; + notifyListeners(SWT.Expand, event); + } +} +@Override +public Color getBackground () { + // This method must be overridden otherwise, in a TableTree in which the first + // item has no sub items, a grey (Widget background colour) square will appear in + // the first column of the first item. + // It is not possible in the constructor to set the background of the TableTree + // to be the same as the background of the Table because this interferes with + // the TableTree adapting to changes in the System color settings. + return table.getBackground(); +} +@Override +public Rectangle getClientArea () { + return table.getClientArea(); +} +@Override +public Color getForeground () { + return table.getForeground(); +} +@Override +public Font getFont () { + return table.getFont(); +} +/** + * Gets the number of items. + * <p> + * @return the number of items in the widget + */ +public int getItemCount () { + //checkWidget(); + return items.length; +} + +/** + * Gets the height of one item. + * <p> + * This operation will fail if the height of + * one item could not be queried from the OS. + * + * @return the height of one item in the widget + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed + * </ul> + */ +public int getItemHeight () { + checkWidget(); + return table.getItemHeight(); +} + +/** + * Gets the items. + * <p> + * @return the items in the widget + */ +public TableTreeItem [] getItems () { + //checkWidget(); + TableTreeItem[] newItems = new TableTreeItem[items.length]; + System.arraycopy(items, 0, newItems, 0, items.length); + return newItems; +} + +/** + * Gets the selected items. + * <p> + * This operation will fail if the selected + * items cannot be queried from the OS. + * + * @return the selected items in the widget + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> + * </ul> + */ +public TableTreeItem [] getSelection () { + checkWidget(); + TableItem[] selection = table.getSelection(); + TableTreeItem [] result = new TableTreeItem[selection.length]; + for (int i = 0; i < selection.length; i++){ + result[i] = (TableTreeItem) selection[i].getData(ITEMID); + } + return result; +} + +/** + * Gets the number of selected items. + * <p> + * This operation will fail if the number of selected + * items cannot be queried from the OS. + * + * @return the number of selected items in the widget + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> + * </ul> + */ +public int getSelectionCount () { + checkWidget(); + return table.getSelectionCount(); +} + +@Override +public int getStyle () { + checkWidget(); + return table.getStyle(); +} + +/** + * Returns the underlying Table control. + * + * @return the underlying Table control + */ +public Table getTable () { + //checkWidget(); + return table; +} + +void createImages () { + + int itemHeight = sizeImage.getBounds().height; + // Calculate border around image. + // At least 9 pixels are needed to draw the image + // Leave at least a 6 pixel border. + int indent = Math.min(6, (itemHeight - 9) / 2); + indent = Math.max(0, indent); + int size = Math.max (10, itemHeight - 2 * indent); + size = ((size + 1) / 2) * 2; // size must be an even number + int midpoint = indent + size / 2; + + Color foreground = getForeground(); + Color plusMinus = getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + Color background = getBackground(); + + /* Plus image */ + PaletteData palette = new PaletteData(new RGB[]{foreground.getRGB(), background.getRGB(), plusMinus.getRGB()}); + ImageData imageData = new ImageData(itemHeight, itemHeight, 4, palette); + imageData.transparentPixel = 1; + plusImage = new Image(getDisplay(), imageData); + GC gc = new GC(plusImage); + gc.setBackground(background); + gc.fillRectangle(0, 0, itemHeight, itemHeight); + gc.setForeground(plusMinus); + gc.drawRectangle(indent, indent, size, size); + gc.setForeground(foreground); + gc.drawLine(midpoint, indent + 2, midpoint, indent + size - 2); + gc.drawLine(indent + 2, midpoint, indent + size - 2, midpoint); + gc.dispose(); + + /* Minus image */ + palette = new PaletteData(new RGB[]{foreground.getRGB(), background.getRGB(), plusMinus.getRGB()}); + imageData = new ImageData(itemHeight, itemHeight, 4, palette); + imageData.transparentPixel = 1; + minusImage = new Image(getDisplay(), imageData); + gc = new GC(minusImage); + gc.setBackground(background); + gc.fillRectangle(0, 0, itemHeight, itemHeight); + gc.setForeground(plusMinus); + gc.drawRectangle(indent, indent, size, size); + gc.setForeground(foreground); + gc.drawLine(indent + 2, midpoint, indent + size - 2, midpoint); + gc.dispose(); +} + +Image getPlusImage() { + if (plusImage == null) createImages(); + return plusImage; +} + +Image getMinusImage() { + if (minusImage == null) createImages(); + return minusImage; +} + +/** + * Gets the index of an item. + * + * <p>The widget is searched starting at 0 until an + * item is found that is equal to the search item. + * If no item is found, -1 is returned. Indexing + * is zero based. This index is relative to the parent only. + * + * @param item the search item + * @return the index of the item or -1 + */ +public int indexOf (TableTreeItem item) { + //checkWidget(); + for (int i = 0; i < items.length; i++) { + if (item == items[i]) return i; + } + return -1; +} + +void onDispose(Event e) { + removeListener(SWT.Dispose, listener); + notifyListeners(SWT.Dispose, e); + e.type = SWT.None; + /* + * Usually when an item is disposed, destroyItem will change the size of the items array + * and dispose of the underlying table items. + * Since the whole table tree is being disposed, this is not necessary. For speed + * the inDispose flag is used to skip over this part of the item dispose. + */ + inDispose = true; + for (int i = 0; i < items.length; i++) { + items[i].dispose(); + } + inDispose = false; + if (plusImage != null) plusImage.dispose(); + if (minusImage != null) minusImage.dispose(); + if (sizeImage != null) sizeImage.dispose(); + plusImage = minusImage = sizeImage = null; +} + +void onResize(Event e) { + Point size = getSize(); + table.setBounds(0, 0, size.x, size.y); +} + +void onSelection(Event e) { + Event event = new Event(); + TableItem tableItem = (TableItem)e.item; + TableTreeItem item = getItem(tableItem); + event.item = item; + + if (e.type == SWT.Selection && e.detail == SWT.CHECK && item != null) { + event.detail = SWT.CHECK; + item.checked = tableItem.getChecked(); + } + notifyListeners(e.type, event); +} +/** + * Returns the item at the given, zero-relative index in the + * receiver. Throws an exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.1 + */ +public TableTreeItem getItem (int index) { + checkWidget(); + int count = items.length; + if (!(0 <= index && index < count)) SWT.error (SWT.ERROR_INVALID_RANGE); + return items [index]; +} + +/** + * Returns the item at the given point in the receiver + * or null if no such item exists. The point is in the + * coordinate system of the receiver. + * + * @param point the point used to locate the item + * @return the item at the given point + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the point is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public TableTreeItem getItem(Point point) { + checkWidget(); + TableItem item = table.getItem(point); + if (item == null) return null; + return getItem(item); + +} +TableTreeItem getItem(TableItem tableItem) { + if (tableItem == null) return null; + for (int i = 0; i < items.length; i++) { + TableTreeItem item = items[i].getItem(tableItem); + if (item != null) return item; + } + return null; +} +void onFocusIn (Event e) { + table.setFocus(); +} + +void onKeyDown (Event e) { + TableTreeItem[] selection = getSelection(); + if (selection.length == 0) return; + TableTreeItem item = selection[0]; + int type = 0; + if (e.keyCode == SWT.ARROW_RIGHT || e.keyCode == SWT.ARROW_LEFT) { + int trailKey = (getStyle() & SWT.MIRRORED) != 0 ? SWT.ARROW_LEFT : SWT.ARROW_RIGHT; + if (e.keyCode == trailKey) { + if (item.getItemCount() == 0) return; + if (item.getExpanded()) { + TableTreeItem newSelection = item.getItems()[0]; + table.setSelection(new TableItem[]{newSelection.tableItem}); + showItem(newSelection); + type = SWT.Selection; + } else { + item.setExpanded(true); + type = SWT.Expand; + } + } else { + if (item.getExpanded()) { + item.setExpanded(false); + type = SWT.Collapse; + } else { + TableTreeItem parent = item.getParentItem(); + if (parent != null) { + int index = parent.indexOf(item); + if (index != 0) return; + table.setSelection(new TableItem[]{parent.tableItem}); + type = SWT.Selection; + } + } + } + } + if (e.character == '*') { + item.expandAll(true); + } + if (e.character == '-') { + if (item.getExpanded()) { + item.setExpanded(false); + type = SWT.Collapse; + } + } + if (e.character == '+') { + if (item.getItemCount() > 0 && !item.getExpanded()) { + item.setExpanded(true); + type = SWT.Expand; + } + } + if (type == 0) return; + Event event = new Event(); + event.item = item; + notifyListeners(type, event); +} +void onMouseDown(Event event) { + /* If user clicked on the [+] or [-], expand or collapse the tree. */ + TableItem[] items = table.getItems(); + for (int i = 0; i < items.length; i++) { + Rectangle rect = items[i].getImageBounds(0); + if (rect.contains(event.x, event.y)) { + TableTreeItem item = (TableTreeItem) items[i].getData(ITEMID); + event = new Event(); + event.item = item; + item.setExpanded(!item.getExpanded()); + if (item.getExpanded()) { + notifyListeners(SWT.Expand, event); + } else { + notifyListeners(SWT.Collapse, event); + } + return; + } + } +} + +/** + * Removes all items. + * <p> + * This operation will fail when an item + * could not be removed in the OS. + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed + * </ul> + */ +public void removeAll () { + checkWidget(); + setRedraw(false); + for (int i = items.length - 1; i >= 0; i--) { + items[i].dispose(); + } + items = EMPTY_ITEMS; + setRedraw(true); +} + +void removeItem(TableTreeItem item) { + int index = 0; + while (index < items.length && items[index] != item) index++; + if (index == items.length) return; + TableTreeItem[] newItems = new TableTreeItem[items.length - 1]; + System.arraycopy(items, 0, newItems, 0, index); + System.arraycopy(items, index + 1, newItems, index, items.length - index - 1); + items = newItems; +} + +/** + * Removes the listener from the collection of listeners who will + * be notified when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see SelectionListener + * @see #addSelectionListener + */ +public void removeSelectionListener (SelectionListener listener) { + checkWidget(); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + removeListener(SWT.Selection, listener); + removeListener(SWT.DefaultSelection, listener); +} + +/** + * Removes the listener from the collection of listeners who will + * be notified when items in the receiver are expanded or collapsed. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see TreeListener + * @see #addTreeListener + */ +public void removeTreeListener (TreeListener listener) { + checkWidget(); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + removeListener(SWT.Expand, listener); + removeListener(SWT.Collapse, listener); +} + +/** + * Selects all of the items in the receiver. + * <p> + * If the receiver is single-select, do nothing. + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed + * </ul> + */ +public void selectAll () { + checkWidget(); + table.selectAll(); +} +@Override +public void setBackground (Color color) { + super.setBackground(color); + table.setBackground(color); + if (sizeImage != null) { + GC gc = new GC (sizeImage); + gc.setBackground(getBackground()); + Rectangle size = sizeImage.getBounds(); + gc.fillRectangle(size); + gc.dispose(); + } +} +@Override +public void setEnabled (boolean enabled) { + super.setEnabled(enabled); + table.setEnabled(enabled); +} +@Override +public void setFont (Font font) { + super.setFont(font); + table.setFont(font); +} +@Override +public void setForeground (Color color) { + super.setForeground(color); + table.setForeground(color); +} +@Override +public void setMenu (Menu menu) { + super.setMenu(menu); + table.setMenu(menu); +} + +/** + * Sets the receiver's selection to be the given array of items. + * The current selection is cleared before the new items are selected. + * <p> + * Items that are not in the receiver are ignored. + * If the receiver is single-select and multiple items are specified, + * then all items are ignored. + * + * @param items the array of items + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li> + * <li>ERROR_INVALID_ARGUMENT - if one of the item has been disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see TableTree#deselectAll() + */ +public void setSelection (TableTreeItem[] items) { + checkWidget (); + if (items == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + int length = items.length; + if (length == 0 || ((table.getStyle() & SWT.SINGLE) != 0 && length > 1)) { + deselectAll(); + return; + } + TableItem[] tableItems = new TableItem[length]; + for (int i = 0; i < length; i++) { + if (items[i] == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (!items[i].getVisible()) expandItem (items[i]); + tableItems[i] = items[i].tableItem; + } + table.setSelection(tableItems); +} +@Override +public void setToolTipText (String string) { + super.setToolTipText(string); + table.setToolTipText(string); +} + +/** + * Shows the item. If the item is already showing in the receiver, + * this method simply returns. Otherwise, the items are scrolled + * and expanded until the item is visible. + * + * @param item the item to be shown + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the item is null</li> + * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see TableTree#showSelection() + */ +public void showItem (TableTreeItem item) { + checkWidget(); + if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + if (!item.getVisible()) expandItem (item); + TableItem tableItem = item.tableItem; + table.showItem(tableItem); +} + +/** + * Shows the selection. + * <p> + * If there is no selection or the selection + * is already visible, this method does nothing. + * If the selection is scrolled out of view, + * the top index of the widget is changed such + * that selection becomes visible. + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed + * </ul> + */ +public void showSelection () { + checkWidget(); + table.showSelection(); +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTreeEditor.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTreeEditor.java new file mode 100644 index 0000000000..29379e0e97 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTreeEditor.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.custom; + + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; +import org.eclipse.swt.events.*; +/** +* +* A TableTreeEditor is a manager for a Control that appears above a cell in a TableTree +* and tracks with the moving and resizing of that cell. It can be used to display a +* text widget above a cell in a TableTree so that the user can edit the contents of +* that cell. It can also be used to display a button that can launch a dialog for +* modifying the contents of the associated cell. +* +* <p> Here is an example of using a TableTreeEditor: +* <code><pre> +* final TableTree tableTree = new TableTree(shell, SWT.FULL_SELECTION | SWT.HIDE_SELECTION); +* final Table table = tableTree.getTable(); +* TableColumn column1 = new TableColumn(table, SWT.NONE); +* TableColumn column2 = new TableColumn(table, SWT.NONE); +* for (int i = 0; i < 10; i++) { +* TableTreeItem item = new TableTreeItem(tableTree, SWT.NONE); +* item.setText(0, "item " + i); +* item.setText(1, "edit this value"); +* for (int j = 0; j < 3; j++) { +* TableTreeItem subitem = new TableTreeItem(item, SWT.NONE); +* subitem.setText(0, "subitem " + i + " " + j); +* subitem.setText(1, "edit this value"); +* } +* } +* column1.setWidth(100); +* column2.pack(); +* +* final TableTreeEditor editor = new TableTreeEditor(tableTree); +* //The editor must have the same size as the cell and must +* //not be any smaller than 50 pixels. +* editor.horizontalAlignment = SWT.LEFT; +* editor.grabHorizontal = true; +* editor.minimumWidth = 50; +* // editing the second column +* final int EDITABLECOLUMN = 1; +* +* tableTree.addSelectionListener(new SelectionAdapter() { +* public void widgetSelected(SelectionEvent e) { +* // Clean up any previous editor control +* Control oldEditor = editor.getEditor(); +* if (oldEditor != null) oldEditor.dispose(); +* +* // Identify the selected row +* TableTreeItem item = (TableTreeItem)e.item; +* if (item == null) return; +* +* // The control that will be the editor must be a child of the Table +* Text newEditor = new Text(table, SWT.NONE); +* newEditor.setText(item.getText(EDITABLECOLUMN)); +* newEditor.addModifyListener(new ModifyListener() { +* public void modifyText(ModifyEvent e) { +* Text text = (Text)editor.getEditor(); +* editor.getItem().setText(EDITABLECOLUMN, text.getText()); +* } +* }); +* newEditor.selectAll(); +* newEditor.setFocus(); +* editor.setEditor(newEditor, item, EDITABLECOLUMN); +* } +* }); +* </pre></code> +* +* @deprecated As of 3.1 use TreeEditor with Tree, TreeItem and TreeColumn +*/ +@Deprecated +public class TableTreeEditor extends ControlEditor { + + TableTree tableTree; + TableTreeItem item; + int column = -1; + ControlListener columnListener; + TreeListener treeListener; +/** +* Creates a TableTreeEditor for the specified TableTree. +* +* @param tableTree the TableTree Control above which this editor will be displayed +* +*/ +public TableTreeEditor (TableTree tableTree) { + super(tableTree.getTable()); + this.tableTree = tableTree; + + treeListener = new TreeListener () { + final Runnable runnable = new Runnable() { + public void run() { + if (editor == null || editor.isDisposed()) return; + if (TableTreeEditor.this.tableTree.isDisposed()) return; + layout(); + editor.setVisible(true); + } + }; + public void treeCollapsed(TreeEvent e) { + if (editor == null || editor.isDisposed ()) return; + editor.setVisible(false); + e.display.asyncExec(runnable); + } + public void treeExpanded(TreeEvent e) { + if (editor == null || editor.isDisposed ()) return; + editor.setVisible(false); + e.display.asyncExec(runnable); + } + }; + tableTree.addTreeListener(treeListener); + + columnListener = new ControlListener() { + public void controlMoved(ControlEvent e){ + layout (); + } + public void controlResized(ControlEvent e){ + layout (); + } + }; + + // To be consistent with older versions of SWT, grabVertical defaults to true + grabVertical = true; +} +@Override +Rectangle computeBounds () { + if (item == null || column == -1 || item.isDisposed() || item.tableItem == null) return new Rectangle(0, 0, 0, 0); + Rectangle cell = item.getBounds(column); + Rectangle area = tableTree.getClientArea(); + if (cell.x < area.x + area.width) { + if (cell.x + cell.width > area.x + area.width) { + cell.width = area.x + area.width - cell.x; + } + } + Rectangle editorRect = new Rectangle(cell.x, cell.y, minimumWidth, minimumHeight); + + if (grabHorizontal) { + editorRect.width = Math.max(cell.width, minimumWidth); + } + + if (grabVertical) { + editorRect.height = Math.max(cell.height, minimumHeight); + } + + if (horizontalAlignment == SWT.RIGHT) { + editorRect.x += cell.width - editorRect.width; + } else if (horizontalAlignment == SWT.LEFT) { + // do nothing - cell.x is the right answer + } else { // default is CENTER + editorRect.x += (cell.width - editorRect.width)/2; + } + + if (verticalAlignment == SWT.BOTTOM) { + editorRect.y += cell.height - editorRect.height; + } else if (verticalAlignment == SWT.TOP) { + // do nothing - cell.y is the right answer + } else { // default is CENTER + editorRect.y += (cell.height - editorRect.height)/2; + } + return editorRect; +} +/** + * Removes all associations between the TableTreeEditor and the cell in the table tree. The + * TableTree and the editor Control are <b>not</b> disposed. + */ +@Override +public void dispose () { + if (tableTree != null && !tableTree.isDisposed()) { + Table table = tableTree.getTable(); + if (table != null && !table.isDisposed()) { + if (this.column > -1 && this.column < table.getColumnCount()){ + TableColumn tableColumn = table.getColumn(this.column); + tableColumn.removeControlListener(columnListener); + } + } + if (treeListener != null) tableTree.removeTreeListener(treeListener); + } + treeListener = null; + columnListener = null; + tableTree = null; + item = null; + column = -1; + super.dispose(); +} +/** +* Returns the zero based index of the column of the cell being tracked by this editor. +* +* @return the zero based index of the column of the cell being tracked by this editor +*/ +public int getColumn () { + return column; +} +/** +* Returns the TableTreeItem for the row of the cell being tracked by this editor. +* +* @return the TableTreeItem for the row of the cell being tracked by this editor +*/ +public TableTreeItem getItem () { + return item; +} +public void setColumn(int column) { + Table table = tableTree.getTable(); + int columnCount = table.getColumnCount(); + // Separately handle the case where the table has no TableColumns. + // In this situation, there is a single default column. + if (columnCount == 0) { + this.column = (column == 0) ? 0 : -1; + layout(); + return; + } + if (this.column > -1 && this.column < columnCount){ + TableColumn tableColumn = table.getColumn(this.column); + tableColumn.removeControlListener(columnListener); + this.column = -1; + } + + if (column < 0 || column >= table.getColumnCount()) return; + + this.column = column; + TableColumn tableColumn = table.getColumn(this.column); + tableColumn.addControlListener(columnListener); + layout(); +} +public void setItem (TableTreeItem item) { + this.item = item; + layout(); +} + +/** +* Specify the Control that is to be displayed and the cell in the table that it is to be positioned above. +* +* <p>Note: The Control provided as the editor <b>must</b> be created with its parent being the Table control +* specified in the TableEditor constructor. +* +* @param editor the Control that is displayed above the cell being edited +* @param item the TableItem for the row of the cell being tracked by this editor +* @param column the zero based index of the column of the cell being tracked by this editor +*/ +public void setEditor (Control editor, TableTreeItem item, int column) { + setItem(item); + setColumn(column); + setEditor(editor); +} +@Override +public void layout () { + if (tableTree == null || tableTree.isDisposed()) return; + if (item == null || item.isDisposed()) return; + Table table = tableTree.getTable(); + int columnCount = table.getColumnCount(); + if (columnCount == 0 && column != 0) return; + if (columnCount > 0 && (column < 0 || column >= columnCount)) return; + super.layout(); +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTreeItem.java new file mode 100644 index 0000000000..10d145febd --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/TableTreeItem.java @@ -0,0 +1,882 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.custom; + + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; + +/** + * A TableTreeItem is a selectable user interface object + * that represents an item in a hierarchy of items in a + * TableTree. + * + * @deprecated As of 3.1 use Tree, TreeItem and TreeColumn + */ +@Deprecated +public class TableTreeItem extends Item { + TableItem tableItem; + TableTree parent; + TableTreeItem parentItem; + TableTreeItem [] items = TableTree.EMPTY_ITEMS; + String[] texts = TableTree.EMPTY_TEXTS; + Image[] images = TableTree.EMPTY_IMAGES; + Color background; + Color foreground; + Font font; + boolean expanded; + boolean checked; + boolean grayed; + +/** + * Constructs a new instance of this class given its parent + * (which must be a <code>TableTree</code>) + * and a style value describing its behavior and appearance. + * The item is added to the end of the items maintained by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT + * @see Widget#getStyle() + */ +public TableTreeItem(TableTree parent, int style) { + this (parent, style, parent.getItemCount()); +} + +/** + * Constructs a new instance of this class given its parent + * (which must be a <code>TableTree</code>, + * a style value describing its behavior and appearance, and the index + * at which to place it in the items maintained by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * @param index the index to store the receiver in its parent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT + * @see Widget#getStyle() + */ +public TableTreeItem(TableTree parent, int style, int index) { + this (parent, null, style, index); +} + +/** + * Constructs a new instance of this class given its parent + * (which must be a <code>TableTreeItem</code>) + * and a style value describing its behavior and appearance. + * The item is added to the end of the items maintained by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT + * @see Widget#getStyle() + */ +public TableTreeItem(TableTreeItem parent, int style) { + this (parent, style, parent.getItemCount()); +} + +/** + * Constructs a new instance of this class given its parent + * (which must be a <code>TableTreeItem</code>), + * a style value describing its behavior and appearance, and the index + * at which to place it in the items maintained by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * @param index the index to store the receiver in its parent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT + * @see Widget#getStyle() + */ +public TableTreeItem(TableTreeItem parent, int style, int index) { + this (parent.getParent(), parent, style, index); +} + +TableTreeItem(TableTree parent, TableTreeItem parentItem, int style, int index) { + super(parent, style); + this.parent = parent; + this.parentItem = parentItem; + if (parentItem == null) { + + /* Root items are visible immediately */ + int tableIndex = parent.addItem(this, index); + tableItem = new TableItem(parent.getTable(), style, tableIndex); + tableItem.setData(TableTree.ITEMID, this); + addCheck(); + /* + * Feature in the Table. The table uses the first image that + * is inserted into the table to size the table rows. If the + * user is allowed to insert the first image, this will cause + * the +/- images to be scaled. The fix is to insert a dummy + * image to force the size. + */ + if (parent.sizeImage == null) { + int itemHeight = parent.getItemHeight(); + parent.sizeImage = new Image(parent.getDisplay(), itemHeight, itemHeight); + GC gc = new GC (parent.sizeImage); + gc.setBackground(parent.getBackground()); + gc.fillRectangle(0, 0, itemHeight, itemHeight); + gc.dispose(); + tableItem.setImage(0, parent.sizeImage); + } + } else { + parentItem.addItem(this, index); + } +} +void addCheck() { + Table table = parent.getTable(); + if ((table.getStyle() & SWT.CHECK) == 0) return; + tableItem.setChecked(checked); + tableItem.setGrayed(grayed); +} +void addItem(TableTreeItem item, int index) { + if (item == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (index < 0 || index > items.length) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + + /* Now that item has a sub-node it must indicate that it can be expanded */ + if (items.length == 0 && index == 0) { + if (tableItem != null) { + Image image = expanded ? parent.getMinusImage() : parent.getPlusImage(); + tableItem.setImage(0, image); + } + } + + /* Put the item in the items list */ + TableTreeItem[] newItems = new TableTreeItem[items.length + 1]; + System.arraycopy(items, 0, newItems, 0, index); + newItems[index] = item; + System.arraycopy(items, index, newItems, index + 1, items.length - index); + items = newItems; + if (expanded) item.setVisible(true); +} + +/** + * Returns the receiver's background color. + * + * @return the background color + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 2.0 + * + */ +public Color getBackground () { + checkWidget (); + return (background == null) ? parent.getBackground() : background; +} + +/** + * Returns a rectangle describing the receiver's size and location + * relative to its parent. + * + * @return the receiver's bounding rectangle + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public Rectangle getBounds (int index) { + checkWidget(); + if (tableItem != null) { + return tableItem.getBounds(index); + } else { + return new Rectangle(0, 0, 0, 0); + } +} +/** + * Returns <code>true</code> if the receiver is checked, + * and false otherwise. When the parent does not have + * the <code>CHECK style, return false. + * + * @return the checked state of the checkbox + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public boolean getChecked () { + checkWidget(); + if (tableItem == null) return checked; + return tableItem.getChecked(); +} + +/** + * Returns <code>true</code> if the receiver is grayed, + * and false otherwise. When the parent does not have + * the <code>CHECK</code> style, return false. + * + * @return the grayed state of the checkbox + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 2.1 + */ +public boolean getGrayed () { + checkWidget(); + if (tableItem == null) return grayed; + return tableItem.getGrayed(); +} + +/** + * Returns <code>true</code> if the receiver is expanded, + * and false otherwise. + * <p> + * + * @return the expanded state + */ +public boolean getExpanded () { + //checkWidget(); + return expanded; +} + +/** + * Returns the font that the receiver will use to paint textual information for this item. + * + * @return the receiver's font + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.0 + */ +public Font getFont () { + checkWidget (); + return (font == null) ? parent.getFont() : font; +} +/** + * Returns the foreground color that the receiver will use to draw. + * + * @return the receiver's foreground color + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 2.0 + * + */ +public Color getForeground () { + checkWidget (); + return (foreground == null) ? parent.getForeground() : foreground; +} +/** + * Gets the first image. + * <p> + * The image in column 0 is reserved for the [+] and [-] + * images of the tree, therefore getImage(0) will return null. + * + * @return the image at index 0 + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +@Override +public Image getImage () { + checkWidget(); + return getImage(0); +} + +/** + * Gets the image at the specified index. + * <p> + * Indexing is zero based. The image can be null. + * The image in column 0 is reserved for the [+] and [-] + * images of the tree, therefore getImage(0) will return null. + * Return null if the index is out of range. + * + * @param index the index of the image + * @return the image at the specified index or null + */ +public Image getImage (int index) { + //checkWidget(); + if (0 < index && index < images.length) return images[index]; + return null; +} + +int getIndent() { + if (parentItem == null) return 0; + return parentItem.getIndent() + 1; +} + +/** + * Returns the item at the given, zero-relative index in the + * receiver. Throws an exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.1 + */ +public TableTreeItem getItem (int index) { + checkWidget(); + int count = items.length; + if (!(0 <= index && index < count)) SWT.error (SWT.ERROR_INVALID_RANGE); + return items [index]; +} + +/** + * Returns the number of items contained in the receiver + * that are direct item children of the receiver. + * + * @return the number of items + */ +public int getItemCount () { + //checkWidget(); + return items.length; +} + +/** + * Returns an array of <code>TableTreeItem</code>s which are the + * direct item children of the receiver. + * <p> + * Note: This is not the actual structure used by the receiver + * to maintain its list of items, so modifying the array will + * not affect the receiver. + * </p> + * + * @return the receiver's items + */ +public TableTreeItem[] getItems () { + //checkWidget(); + TableTreeItem[] newItems = new TableTreeItem[items.length]; + System.arraycopy(items, 0, newItems, 0, items.length); + return newItems; +} + +TableTreeItem getItem(TableItem tableItem) { + if (tableItem == null) return null; + if (this.tableItem == tableItem) return this; + for (int i = 0; i < items.length; i++) { + TableTreeItem item = items[i].getItem(tableItem); + if (item != null) return item; + } + return null; +} + +/** + * Returns the receiver's parent, which must be a <code>TableTree</code>. + * + * @return the receiver's parent + */ +public TableTree getParent () { + //checkWidget(); + return parent; +} + +/** + * Returns the receiver's parent item, which must be a + * <code>TableTreeItem</code> or null when the receiver is a + * root. + * + * @return the receiver's parent item + */ +public TableTreeItem getParentItem () { + //checkWidget(); + return parentItem; +} +@Override +public String getText () { + checkWidget(); + return getText(0); +} + +/** + * Gets the item text at the specified index. + * <p> + * Indexing is zero based. + * + * This operation will fail when the index is out + * of range or an item could not be queried from + * the OS. + * + * @param index the index of the item + * @return the item text at the specified index, which can be null + */ +public String getText(int index) { + //checkWidget(); + if (0 <= index && index < texts.length) return texts[index]; + return null; +} + +boolean getVisible () { + return tableItem != null; +} + +/** + * Gets the index of the specified item. + * + * <p>The widget is searched starting at 0 until an + * item is found that is equal to the search item. + * If no item is found, -1 is returned. Indexing + * is zero based. This index is relative to the parent only. + * + * @param item the search item + * @return the index of the item or -1 if the item is not found + * + */ +public int indexOf (TableTreeItem item) { + //checkWidget(); + for (int i = 0; i < items.length; i++) { + if (items[i] == item) return i; + } + return -1; +} + +void expandAll(boolean notify) { + if (items.length == 0) return; + if (!expanded) { + setExpanded(true); + if (notify) { + Event event = new Event(); + event.item = this; + parent.notifyListeners(SWT.Expand, event); + } + } + for (int i = 0; i < items.length; i++) { + items[i].expandAll(notify); + } +} +int expandedIndexOf (TableTreeItem item) { + int index = 0; + for (int i = 0; i < items.length; i++) { + if (items[i] == item) return index; + if (items[i].expanded) index += items[i].visibleChildrenCount (); + index++; + } + return -1; +} + +int visibleChildrenCount () { + int count = 0; + for (int i = 0; i < items.length; i++) { + if (items[i].getVisible ()) { + count += 1 + items[i].visibleChildrenCount (); + } + } + return count; +} + +@Override +public void dispose () { + if (isDisposed()) return; + for (int i = items.length - 1; i >= 0; i--) { + items[i].dispose(); + } + super.dispose(); + if (!parent.inDispose) { + if (parentItem != null) { + parentItem.removeItem(this); + } else { + parent.removeItem(this); + } + if (tableItem != null) tableItem.dispose(); + } + items = null; + parentItem = null; + parent = null; + images = null; + texts = null; + tableItem = null; + foreground = null; + background = null; + font = null; +} + +void removeItem(TableTreeItem item) { + int index = 0; + while (index < items.length && items[index] != item) index++; + if (index == items.length) return; + TableTreeItem[] newItems = new TableTreeItem[items.length - 1]; + System.arraycopy(items, 0, newItems, 0, index); + System.arraycopy(items, index + 1, newItems, index, items.length - index - 1); + items = newItems; + if (items.length == 0) { + if (tableItem != null) tableItem.setImage(0, null); + } +} + +/** + * Sets the receiver's background color to the color specified + * by the argument, or to the default system color for the item + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 2.0 + * + */ +public void setBackground (Color color) { + checkWidget (); + if (color != null && color.isDisposed ()) { + SWT.error (SWT.ERROR_INVALID_ARGUMENT); + } + if (tableItem != null) { + tableItem.setBackground(color); + } + background = color; +} + +/** + * Sets the checked state of the checkbox for this item. This state change + * only applies if the Table was created with the SWT.CHECK style. + * + * @param checked the new checked state of the checkbox + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public void setChecked (boolean checked) { + checkWidget(); + Table table = parent.getTable(); + if ((table.getStyle() & SWT.CHECK) == 0) return; + if (tableItem != null) { + tableItem.setChecked(checked); + } + this.checked = checked; +} + +/** + * Sets the grayed state of the checkbox for this item. This state change + * only applies if the Table was created with the SWT.CHECK style. + * + * @param grayed the new grayed state of the checkbox; + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 2.1 + */ +public void setGrayed (boolean grayed) { + checkWidget(); + Table table = parent.getTable(); + if ((table.getStyle() & SWT.CHECK) == 0) return; + if (tableItem != null) { + tableItem.setGrayed(grayed); + } + this.grayed = grayed; +} + +/** + * Sets the expanded state. + * <p> + * @param expanded the new expanded state. + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> + * </ul> + */ +public void setExpanded (boolean expanded) { + checkWidget(); + if (items.length == 0) return; + if (this.expanded == expanded) return; + this.expanded = expanded; + if (tableItem == null) return; + parent.setRedraw(false); + for (int i = 0; i < items.length; i++) { + items[i].setVisible(expanded); + } + Image image = expanded ? parent.getMinusImage() : parent.getPlusImage(); + tableItem.setImage(0, image); + parent.setRedraw(true); +} + +/** + * Sets the font that the receiver will use to paint textual information + * for this item to the font specified by the argument, or to the default font + * for that kind of control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 3.0 + */ +public void setFont (Font font){ + checkWidget (); + if (font != null && font.isDisposed ()) { + SWT.error (SWT.ERROR_INVALID_ARGUMENT); + } + if (tableItem != null) { + tableItem.setFont(font); + } + this.font = font; +} +/** + * Sets the receiver's foreground color to the color specified + * by the argument, or to the default system color for the item + * if the argument is null. + * + * @param color the new color (or null) + * + * @since 2.0 + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @since 2.0 + * + */ +public void setForeground (Color color) { + checkWidget (); + if (color != null && color.isDisposed ()) { + SWT.error (SWT.ERROR_INVALID_ARGUMENT); + } + if (tableItem != null) { + tableItem.setForeground(color); + } + foreground = color; +} + +/** + * Sets the image at an index. + * <p> + * The image can be null. + * The image in column 0 is reserved for the [+] and [-] + * images of the tree, therefore do nothing if index is 0. + * + * @param image the new image or null + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> + * </ul> + */ +public void setImage (int index, Image image) { + checkWidget(); + int columnCount = Math.max(parent.getTable().getColumnCount(), 1); + if (index <= 0 || index >= columnCount) return; + if (images.length < columnCount) { + Image[] newImages = new Image[columnCount]; + System.arraycopy(images, 0, newImages, 0, images.length); + images = newImages; + } + images[index] = image; + if (tableItem != null) tableItem.setImage(index, image); +} + +/** + * Sets the first image. + * <p> + * The image can be null. + * The image in column 0 is reserved for the [+] and [-] + * images of the tree, therefore do nothing. + * + * @param image the new image or null + * + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> + * </ul> + */ +@Override +public void setImage (Image image) { + setImage(0, image); +} + +/** + * Sets the widget text. + * <p> + * + * The widget text for an item is the label of the + * item or the label of the text specified by a column + * number. + * + * @param index the column number + * @param text the new text + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the text is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> + * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> + * </ul> + */ +public void setText(int index, String text) { + checkWidget(); + if (text == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + int columnCount = Math.max(parent.getTable().getColumnCount(), 1); + if (index < 0 || index >= columnCount) return; + if (texts.length < columnCount) { + String[] newTexts = new String[columnCount]; + System.arraycopy(texts, 0, newTexts, 0, texts.length); + texts = newTexts; + } + texts[index] = text; + if (tableItem != null) tableItem.setText(index, text); +} +@Override +public void setText (String string) { + setText(0, string); +} + +void setVisible (boolean show) { + if (parentItem == null) return; // this is a root and can not be toggled between visible and hidden + if (getVisible() == show) return; + + if (show) { + if (!parentItem.getVisible()) return; // parentItem must already be visible + // create underlying table item and set data in table item to stored data + Table table = parent.getTable(); + int parentIndex = table.indexOf(parentItem.tableItem); + int index = parentItem.expandedIndexOf(this) + parentIndex + 1; + if (index < 0) return; + tableItem = new TableItem(table, getStyle(), index); + tableItem.setData(TableTree.ITEMID, this); + tableItem.setImageIndent(getIndent()); + if (background != null) tableItem.setBackground(background); + if (foreground != null) tableItem.setForeground(foreground); + if (font != null) tableItem.setFont(font); + addCheck(); + + // restore fields to item + // ignore any images in the first column + int columnCount = Math.max(table.getColumnCount(), 1); + for (int i = 0; i < columnCount; i++) { + if (i < texts.length && texts[i] != null) setText(i, texts[i]); + if (i < images.length && images[i] != null) setImage(i, images[i]); + } + + // display the children and the appropriate [+]/[-] symbol as required + if (items.length != 0) { + if (expanded) { + tableItem.setImage(0, parent.getMinusImage()); + for (int i = 0, length = items.length; i < length; i++) { + items[i].setVisible(true); + } + } else { + tableItem.setImage(0, parent.getPlusImage()); + } + } + + } else { + + for (int i = 0, length = items.length; i < length; i++) { + items[i].setVisible(false); + } + // remove row from table + tableItem.dispose(); + tableItem = null; + } +} +} diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/AllWidgetTests.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/AllWidgetTests.java index a510bad3b4..f1228499c8 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/AllWidgetTests.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/AllWidgetTests.java @@ -37,8 +37,9 @@ import org.junit.runners.Suite; Test_org_eclipse_swt_widgets_DateTime.class, Test_org_eclipse_swt_widgets_ColorDialog.class, Test_org_eclipse_swt_widgets_FileDialog.class, Test_org_eclipse_swt_widgets_DirectoryDialog.class, Test_org_eclipse_swt_widgets_FontDialog.class, Test_org_eclipse_swt_widgets_MessageBox.class, - Test_org_eclipse_swt_widgets_Monitor.class, Test_org_eclipse_swt_custom_StyleRange.class, - Test_org_eclipse_swt_custom_CCombo.class, Test_org_eclipse_swt_custom_CLabel.class, + Test_org_eclipse_swt_widgets_Monitor.class, Test_org_eclipse_swt_custom_TableTree.class, + Test_org_eclipse_swt_custom_StyleRange.class, Test_org_eclipse_swt_custom_CCombo.class, + Test_org_eclipse_swt_custom_TableTreeItem.class, Test_org_eclipse_swt_custom_CLabel.class, Test_org_eclipse_swt_custom_CTabItem.class, Test_org_eclipse_swt_custom_StyledText.class, Test_org_eclipse_swt_custom_CTabFolder.class }) public class AllWidgetTests { diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ConsistencyUtility.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ConsistencyUtility.java index f7c4306738..125c232931 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ConsistencyUtility.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/ConsistencyUtility.java @@ -40,6 +40,7 @@ public class ConsistencyUtility { eventOrdering.put("TableMouseSelection", new String[] {"MouseDown", "Selection:", "MouseUp" }); eventOrdering.put("ToolBarMouseSelection", new String[] {"MouseDown", "MouseUp", "Selection:"}); eventOrdering.put("TreeMouseSelection", new String[] {"MouseDown", "Selection:", "MouseUp" }); + eventOrdering.put("TableTreeMouseSelection",new String[] {"MouseDown", "Selection:", "MouseUp" }); eventOrdering.put("CTabFolderMouseSelection",new String[] {"Selection:", "MouseDown", "MouseUp" }); eventOrdering.put("ListDoubleClick", new String[] {"MouseDown", "MouseUp", "Selection:", "MouseDown", "MouseDoubleClick", "DefaultSelection", "MouseUp"}); @@ -48,13 +49,16 @@ public class ConsistencyUtility { eventOrdering.put("CComboEnterSelection", new String[] {"Traverse:Return", "DefaultSelection", "KeyDown", "KeyUp"}); eventOrdering.put("ToolBarEnterSelection", new String[] {"Traverse:Return", "Selection:", "KeyDown", "KeyUp"}); eventOrdering.put("TreeDragDetect", new String[] {"MouseDown", "Selection:", "DragDetect", "MouseUp"}); + eventOrdering.put("TableTreeDragDetect", new String[] {"MouseDown", "Selection:", "DragDetect", "MouseUp"}); eventOrdering.put("TableMenuDetect", new String[] {"MenuDetect", "MouseDown", "Selection:", "MouseUp"}); + eventOrdering.put("TableTreeMenuDetect", new String[] {"MenuDetect", "MouseDown", "Selection:", "MouseUp"}); eventOrdering.put("ButtonSpaceSelection", new String[] {"Traverse:Mnemonic", "KeyDown", "KeyUp", "Selection:"}); eventOrdering.put("ExpandBarSpaceSelection",new String[] {"MouseDown", "MouseUp", "Selection:", "Traverse:Mnemonic", "KeyDown", "KeyUp"}); eventOrdering.put("ListSpaceSelection", new String[] {"Selection:", "KeyDown", "KeyUp"}); eventOrdering.put("ToolBarSpaceSelection", new String[] {"MouseDown", "MouseUp", "Selection:", "Traverse:Mnemonic", "KeyDown", "KeyUp"}); eventOrdering.put("TreeSpaceSelection", new String[] {"Selection:", "KeyDown", "KeyUp"}); + eventOrdering.put("TableTreeSpaceSelection",new String[] {"KeyDown", "KeyUp"}); eventOrdering.put("ComboKeySelection", new String[] {"KeyDown", "Verify", "Modify", "Selection:", "KeyUp"}); eventOrdering.put("CComboKeySelection", new String[] {"Traverse:Arrow Next", "Modify", "Selection:", "KeyDown", "KeyUp"}); @@ -87,6 +91,10 @@ public class ConsistencyUtility { eventOrdering.put("TreeKeyExpand", new String[] {"Traverse:Arrow Next", "KeyDown", "Expand", "KeyUp"}); eventOrdering.put("TreeMouseExpand", new String[] {"Expand", "MouseDown", "MouseUp"}); + eventOrdering.put("TableTreeKeyExpand", new String[] {"Traverse:Arrow Next", "Expand", "KeyDown", "KeyUp"}); + eventOrdering.put("TableTreeMouseExpand", new String[] {"Expand", "MouseDown", "Selection:", "MouseUp"}); + + eventOrdering.put("TableTreeTable", new String[] {"MouseDown", "MouseUp", "MouseDoubleClick", "KeyDown", "KeyUp", "MenuDetect", "DragDetect", "Traverse"}); eventTypes.put("None", new Integer(SWT.None)); eventTypes.put("KeyDown", new Integer(SWT.KeyDown)); diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_TableTree.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_TableTree.java new file mode 100644 index 0000000000..69397506cb --- /dev/null +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_TableTree.java @@ -0,0 +1,314 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.junit; + + +import static org.junit.Assert.assertArrayEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TableTree; +import org.eclipse.swt.custom.TableTreeItem; +import org.eclipse.swt.widgets.TableColumn; + +/** + * Automated Test Suite for class org.eclipse.swt.custom.TableTree + * + * @see org.eclipse.swt.custom.TableTree + */ +@SuppressWarnings("deprecation") +public class Test_org_eclipse_swt_custom_TableTree extends Test_org_eclipse_swt_widgets_Composite { + +public Test_org_eclipse_swt_custom_TableTree(String name) { + super(name); +} + +@Override +protected void setUp() { + super.setUp(); + tableTree = new TableTree(shell, style = SWT.MULTI); + setWidget(tableTree); +} + +@Override +public void test_ConstructorLorg_eclipse_swt_widgets_CompositeI() { +} + +public void test_getSelection() { + int number = 8; + TableTreeItem[] items = new TableTreeItem[number]; + for (int i = 0; i < number; i++) { + items[i] = new TableTreeItem(tableTree, SWT.NONE); + } + assertArrayEquals("MULTI: After adding items, but before selecting any", new TableTreeItem[] {}, tableTree.getSelection()); + + // getSelection() is further tested in test_selectAll and test_setSelection$Lorg_eclipse_swt_custom_TableTreeItem +} + +public void test_getSelectionCount() { + int number = 8; + TableTreeItem[] items = new TableTreeItem[number]; + for (int i = 0; i < number; i++) { + items[i] = new TableTreeItem(tableTree, SWT.NONE); + } + assertEquals("MULTI: After adding items, but before selecting any", 0, tableTree.getSelectionCount()); + + // getSelectionCount() is further tested in test_selectAll and test_setSelection$Lorg_eclipse_swt_custom_TableTreeItem +} + +@Override +public void test_getChildren() { + /* Overriding test_getChildren from Test_org_eclipse_swt_widgets_Composite + * to do nothing, because the child of a TableTree is always a Table. + */ +} + +public void test_selectAll() { + /* FUTURE: Should also add sub-nodes, and test both single and multi with those. + * i.e. subitems[i] = new TableTreeItem(items[i], SWT.NONE); */ + + selectAll_helper("Empty table tree", new TableTreeItem[] {}); + + int number = 8; + TableTreeItem[] items = new TableTreeItem[number]; + for (int i = 0; i < number; i++) { + items[i] = new TableTreeItem(tableTree, SWT.NONE); + } + selectAll_helper("selectAll()", items); + + + /* Now run the same tests on a single-select TableTree. */ + singleSelect(); + selectAll_helper("Empty table tree", new TableTreeItem[] {}); + + items = new TableTreeItem[number]; + for (int i = 0; i < number; i++) { + items[i] = new TableTreeItem(tableTree, SWT.NONE); + } + selectAll_helper("selectAll()", new TableTreeItem[] {}); +} + +public void test_setSelection$Lorg_eclipse_swt_custom_TableTreeItem() { + /* FUTURE: Should also add sub-nodes, and test both single and multi with those. + * i.e. subitems[i] = new TableTreeItem(items[i], SWT.NONE); */ + + setSelection_helper("Select no items in empty table tree", new TableTreeItem[] {}, new TableTreeItem[] {}); + try { + tableTree.setSelection((TableTreeItem[]) null); + fail("MULTI: No exception thrown for selecting null in empty table tree"); + } + catch (IllegalArgumentException e) { + } + + int number = 8; + TableTreeItem[] items = new TableTreeItem[number]; + for (int i = 0; i < number; i++) { + items[i] = new TableTreeItem(tableTree, 0); + } + + setSelection_helper("Select no items in table tree with items", new TableTreeItem[] {}, new TableTreeItem[] {}); + try { + tableTree.setSelection((TableTreeItem[]) null); + fail("MULTI: No exception thrown for selecting null in table tree with items"); + } + catch (IllegalArgumentException e) { + } + + for (int i = 0; i < number; i++) { + setSelection_helper("Select item " + i, new TableTreeItem[] {items[i]}, new TableTreeItem[] {items[i]}); + } + setSelection_helper("Select items", items, items); + setSelection_helper("Select tableTree.getItems()", tableTree.getItems(), tableTree.getItems()); + setSelection_helper("Select 2 contiguous items", new TableTreeItem[] {items[0], items[1]}, new TableTreeItem[] {items[0], items[1]}); + setSelection_helper("Select 2 non-contiguous items", new TableTreeItem[] {items[3], items[6]}, new TableTreeItem[] {items[3], items[6]}); + setSelection_helper("Select 3 contiguous items", new TableTreeItem[] {items[2], items[3], items[4]}, new TableTreeItem[] {items[2], items[3], items[4]}); + setSelection_helper("Select 3 non-contiguous items", new TableTreeItem[] {items[2], items[5], items[7]}, new TableTreeItem[] {items[2], items[5], items[7]}); + setSelection_helper("Select 3 unordered contiguous items", new TableTreeItem[] {items[4], items[2], items[3]}, new TableTreeItem[] {items[2], items[3], items[4]}); + setSelection_helper("Select 3 unordered non-contiguous items", new TableTreeItem[] {items[5], items[2], items[7]}, new TableTreeItem[] {items[2], items[5], items[7]}); + setSelection_helper("Select 3 reverse-order contiguous items", new TableTreeItem[] {items[4], items[3], items[2]}, new TableTreeItem[] {items[2], items[3], items[4]}); + setSelection_helper("Select 3 reverse-order non-contiguous items", new TableTreeItem[] {items[7], items[5], items[2]}, new TableTreeItem[] {items[2], items[5], items[7]}); + setSelection_helper("Select same item twice", new TableTreeItem[] {items[0], items[4], items[0]}, new TableTreeItem[] {items[0], items[4]}); + setSelection_helper("Select same item multiple times", new TableTreeItem[] {items[4], items[4], items[4], items[4], items[4], items[4]}, new TableTreeItem[] {items[4]}); + setSelection_helper("Select multiple items multiple times", new TableTreeItem[] {items[4], items[0], items[2], items[4], items[4], items[0], items[4], items[2]}, new TableTreeItem[] {items[0], items[2], items[4]}); + + + /* Now run the same tests on a single-select TableTree. */ + singleSelect(); + + setSelection_helper("Select no items in empty table tree", new TableTreeItem[] {}, new TableTreeItem[] {}); + try { + tableTree.setSelection((TableTreeItem[]) null); + fail("SINGLE: No exception thrown for selecting null in empty table tree"); + } + catch (IllegalArgumentException e) { + } + + items = new TableTreeItem[number]; + for (int i = 0; i < number; i++) { + items[i] = new TableTreeItem(tableTree, 0); + } + + setSelection_helper("Select no items in table tree with items", new TableTreeItem[] {}, new TableTreeItem[] {}); + try { + tableTree.setSelection((TableTreeItem[]) null); + fail("SINGLE: No exception thrown for selecting null in table tree with items"); + } + catch (IllegalArgumentException e) { + } + + for (int i = 0; i < number; i++) { + setSelection_helper("Select item " + i, new TableTreeItem[] {items[i]}, new TableTreeItem[] {items[i]}); + } + setSelection_helper("Select items", items, new TableTreeItem[] {}); + setSelection_helper("Select tableTree.getItems()", tableTree.getItems(), new TableTreeItem[] {}); + setSelection_helper("Select 2 contiguous items", new TableTreeItem[] {items[0], items[1]}, new TableTreeItem[] {}); + setSelection_helper("Select 2 non-contiguous items", new TableTreeItem[] {items[3], items[6]}, new TableTreeItem[] {}); + setSelection_helper("Select 3 contiguous items", new TableTreeItem[] {items[2], items[3], items[4]}, new TableTreeItem[] {}); + setSelection_helper("Select 3 non-contiguous items", new TableTreeItem[] {items[2], items[5], items[7]}, new TableTreeItem[] {}); + setSelection_helper("Select 3 unordered contiguous items", new TableTreeItem[] {items[4], items[2], items[3]}, new TableTreeItem[] {}); + setSelection_helper("Select 3 unordered non-contiguous items", new TableTreeItem[] {items[5], items[2], items[7]}, new TableTreeItem[] {}); + setSelection_helper("Select 3 reverse-order contiguous items", new TableTreeItem[] {items[4], items[3], items[2]}, new TableTreeItem[] {}); + setSelection_helper("Select 3 reverse-order non-contiguous items", new TableTreeItem[] {items[7], items[5], items[2]}, new TableTreeItem[] {}); + setSelection_helper("Select same item twice", new TableTreeItem[] {items[0], items[4], items[0]}, new TableTreeItem[] {}); + setSelection_helper("Select same item multiple times", new TableTreeItem[] {items[4], items[4], items[4], items[4], items[4], items[4]}, new TableTreeItem[] {}); + setSelection_helper("Select multiple items multiple times", new TableTreeItem[] {items[4], items[0], items[2], items[4], items[4], items[0], items[4], items[2]}, new TableTreeItem[] {}); +} + +/* custom */ +private TableTree tableTree; +private int style; + +/* + * Sets a single-select TableTree as the test widget. + * Note: This method must be private or protected so that the auto-gen tool keeps it. + */ +private void singleSelect() { + tableTree.dispose(); + tableTree = new TableTree(shell, style = SWT.SINGLE); + setWidget(tableTree); +} + +/* + * Used in test_selectAll. + * Note: This method must be private or protected so that the auto-gen tool keeps it. + */ +private void selectAll_helper(String message, TableTreeItem[] expectedSelection) { + tableTree.selectAll(); + message = (style == SWT.MULTI ? "MULTI" : "SINGLE") + ": " + message; + assertEquals(message, expectedSelection.length, tableTree.getSelectionCount()); + assertArrayEquals(message, expectedSelection, tableTree.getSelection()); +} + +/* + * Used in test_setSelection$Lorg_eclipse_swt_custom_TableTreeItem. + * Note: This method must be private or protected so that the auto-gen tool keeps it. + */ +private void setSelection_helper(String message, TableTreeItem[] itemsToSelect, TableTreeItem[] expectedSelection) { + tableTree.setSelection(itemsToSelect); + message = (style == SWT.MULTI ? "MULTI" : "SINGLE") + ": " + message; + assertEquals(message, expectedSelection.length, tableTree.getSelectionCount()); + assertArrayEquals(message, expectedSelection, tableTree.getSelection()); +} + +private void createTableTree(List<String> events, boolean traverse) { + String test = getTestName(); + tableTree = new TableTree(shell, SWT.BORDER | SWT.SINGLE); + for (int col = 0; col < 3; col++) { + TableColumn column = new TableColumn(tableTree.getTable(), SWT.NONE); + column.setText("Col " + col); + column.setWidth(70); + hookExpectedEvents(column, test, events); + } + for (int node = 0; node < 4; node++) { + TableTreeItem item = new TableTreeItem(tableTree, SWT.NONE); + for (int col = 0; col < 3; col++) { + item.setText(col, "TTItem" + node + col); + } + hookExpectedEvents(item, test, events); + TableTreeItem subitem = new TableTreeItem(item, SWT.NONE); + for (int col = 0; col < 3; col++) { + subitem.setText(col, "TTSub" + node + col); + } + hookExpectedEvents(subitem, test, events); + } + String[] types = ConsistencyUtility.eventOrdering.get("TableTreeTable"); + if(!traverse) { + String[] temp = new String[types.length -1]; + System.arraycopy(types, 0, temp, 0, types.length-1); + types = temp; + } + hookExpectedEvents(tableTree.getTable(), types, events); + setWidget(tableTree); +} + +public void test_consistency_KeySelection() { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyEvent(0, SWT.ARROW_DOWN, 0, 0, ConsistencyUtility.KEY_PRESS, events); +} + +public void test_consistency_MouseSelection() { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyEvent(30, 30, 1, 0, ConsistencyUtility.MOUSE_CLICK, events); +} + +public void test_consistency_MouseExpand() { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyEvent(11, 10, 1, 0, ConsistencyUtility.MOUSE_CLICK, events); +} + +public void test_consistency_KeyExpand() { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + tableTree.setSelection(new TableTreeItem[] { tableTree.getItems()[0]}); + int code=SWT.ARROW_RIGHT; + if(SwtTestUtil.isGTK) + code = SWT.KEYPAD_ADD; + consistencyEvent(0, code, 0, 0, ConsistencyUtility.KEY_PRESS, events); +} + +public void test_consistency_DoubleClick () { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyPrePackShell(); + consistencyEvent(20, tableTree.getItemHeight()*2, 1, 0, + ConsistencyUtility.MOUSE_DOUBLECLICK, events); +} + +public void test_consistency_EnterSelection () { + List<String> events = new ArrayList<String>(); + createTableTree(events, false); + consistencyEvent(13, 10, 0, 0, ConsistencyUtility.KEY_PRESS, events); +} + +public void test_consistency_SpaceSelection () { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyEvent(' ', 32, 0, 0, ConsistencyUtility.KEY_PRESS, events); +} + +public void test_consistency_MenuDetect () { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyEvent(50, 25, 3, 0, ConsistencyUtility.MOUSE_CLICK, events); +} + +public void test_consistency_DragDetect () { + List<String> events = new ArrayList<String>(); + createTableTree(events, true); + consistencyEvent(30, 20, 50, 30, ConsistencyUtility.MOUSE_DRAG, events); +} + +} diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_TableTreeItem.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_TableTreeItem.java new file mode 100644 index 0000000000..b85aeaa19c --- /dev/null +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_TableTreeItem.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.junit; + +import org.eclipse.swt.custom.TableTree; +import org.eclipse.swt.custom.TableTreeItem; + +/** + * Automated Test Suite for class org.eclipse.swt.custom.TableTreeItem + * + * @see org.eclipse.swt.custom.TableTreeItem + */ +@SuppressWarnings("deprecation") +public class Test_org_eclipse_swt_custom_TableTreeItem extends Test_org_eclipse_swt_widgets_Item { + + TableTree tableTree; + TableTreeItem tableTreeItem; + +public Test_org_eclipse_swt_custom_TableTreeItem(String name) { + super(name); +} + +@Override +protected void setUp() { + super.setUp(); + tableTree = new TableTree(shell, 0); + tableTreeItem = new TableTreeItem(tableTree, 0); + setWidget(tableTreeItem); +} + +@Override +public void test_setImageLorg_eclipse_swt_graphics_Image() { +} + +@Override +public void test_setTextLjava_lang_String() { +} +} diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java index 292bec10a6..762eedd4a6 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Widget.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.swt.tests.junit; +import junit.framework.TestCase; + import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; @@ -21,8 +23,6 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; import org.junit.Test; -import junit.framework.TestCase; - /** * Automated Test Suite for class org.eclipse.swt.widgets.Widget * @@ -190,8 +190,8 @@ protected String getTestName() { if(index != -1) test = test.substring(index+1, test.length()); String clss = getClassName(); - if((!test.equals("MenuDetect") || clss.equals("Table") || test.startsWith("Chevron")) && - (!test.equals("DragDetect") || clss.equals("Tree") || test.startsWith("Chevron")) && + if((!test.equals("MenuDetect") || clss.equals("Table") || clss.equals("TableTree") || test.startsWith("Chevron")) && + (!test.equals("DragDetect") || clss.equals("Tree") || clss.equals("TableTree") || test.startsWith("Chevron")) && (!test.equals("DoubleClick") || clss.equals("List")) && (!test.equals("KeySelection") || clss.equals("Slider") || clss.equals("Combo") || clss.equals("CCombo") || clss.equals("CTabFolder")) && (!test.equals("EnterSelection") || clss.equals("Button") || clss.equals("ToolBar") || clss.equals("CCombo") || clss.equals("ExpandBar"))) |