/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 * @noreference This API will be deleted in a future release. See bug 475833 for details.
 * @noextend This API will be deleted in a future release. See bug 475833 for details.
 */
@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 = 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 = 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();
}
}
