diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt')
6 files changed, 0 insertions, 14952 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/Table.java deleted file mode 100644 index af445fdd61..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/Table.java +++ /dev/null @@ -1,4166 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.widgets; - -import org.eclipse.swt.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; -import org.eclipse.swt.internal.*; - -/** - * Instances of this class implement a selectable user interface - * object that displays a list of images and strings and issues - * notification when selected. - * <p> - * The item children that may be added to instances of this class - * must be of type <code>TableItem</code>. - * </p><p> - * Style <code>VIRTUAL</code> is used to create a <code>Table</code> whose - * <code>TableItem</code>s are to be populated by the client on an on-demand basis - * instead of up-front. This can provide significant performance improvements for - * tables that are very large or for which <code>TableItem</code> population is - * expensive (for example, retrieving values from an external source). - * </p><p> - * Here is an example of using a <code>Table</code> with style <code>VIRTUAL</code>: - * <code><pre> - * final Table table = new Table (parent, SWT.VIRTUAL | SWT.BORDER); - * table.setItemCount (1000000); - * table.addListener (SWT.SetData, new Listener () { - * public void handleEvent (Event event) { - * TableItem item = (TableItem) event.item; - * int index = table.indexOf (item); - * item.setText ("Item " + index); - * System.out.println (item.getText ()); - * } - * }); - * </pre></code> - * </p><p> - * Note that although this class is a subclass of <code>Composite</code>, - * it does not normally make sense to add <code>Control</code> children to - * it, or set a layout on it, unless implementing something like a cell - * editor. - * </p><p> - * <dl> - * <dt><b>Styles:</b></dt> - * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, VIRTUAL, NO_SCROLL</dd> - * <dt><b>Events:</b></dt> - * <dd>Selection, DefaultSelection, SetData, MeasureItem, EraseItem, PaintItem</dd> - * </dl> - * </p><p> - * Note: Only one of the styles SINGLE, and MULTI may be specified. - * </p><p> - * IMPORTANT: This class is <em>not</em> intended to be subclassed. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem, TableColumn snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @noextend This class is not intended to be subclassed by clients. - */ -public class Table extends Composite { - Canvas header; - TableColumn[] columns = new TableColumn [0]; - TableColumn[] orderedColumns; - TableItem[] items = new TableItem [0]; - TableItem[] selectedItems = new TableItem [0]; - TableItem focusItem, anchorItem, lastClickedItem; - Event lastSelectionEvent; - boolean linesVisible, ignoreKey, ignoreDispose, customHeightSet; - int itemsCount = 0; - int topIndex = 0, horizontalOffset = 0; - int fontHeight = 0, imageHeight = 0, itemHeight = 0; - int col0ImageWidth = 0; - int headerImageHeight = 0; - TableColumn resizeColumn; - int resizeColumnX = -1; - int drawCount = 0; - TableColumn sortColumn; - int sortDirection = SWT.NONE; - - /* column header tooltip */ - Listener toolTipListener; - Shell toolTipShell; - Label toolTipLabel; - - Rectangle arrowBounds, checkboxBounds, clientArea; - - static final int MARGIN_IMAGE = 3; - static final int MARGIN_CELL = 1; - static final int SIZE_HORIZONTALSCROLL = 5; - static final int TOLLERANCE_COLUMNRESIZE = 2; - static final int WIDTH_HEADER_SHADOW = 2; - static final int WIDTH_CELL_HIGHLIGHT = 1; - static final int [] toolTipEvents = new int[] {SWT.MouseExit, SWT.MouseHover, SWT.MouseMove, SWT.MouseDown}; - static final String ELLIPSIS = "..."; //$NON-NLS-1$ - static final String ID_UNCHECKED = "UNCHECKED"; //$NON-NLS-1$ - static final String ID_GRAYUNCHECKED = "GRAYUNCHECKED"; //$NON-NLS-1$ - static final String ID_CHECKMARK = "CHECKMARK"; //$NON-NLS-1$ - static final String ID_ARROWUP = "ARROWUP"; //$NON-NLS-1$ - static final String ID_ARROWDOWN = "ARROWDOWN"; //$NON-NLS-1$ - -//TEMPORARY CODE -boolean hasFocus; -public boolean isFocusControl() { - return hasFocus; -} - -/** - * 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 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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT#SINGLE - * @see SWT#MULTI - * @see SWT#CHECK - * @see SWT#FULL_SELECTION - * @see SWT#HIDE_SELECTION - * @see SWT#VIRTUAL - * @see SWT#NO_SCROLL - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public Table (Composite parent, int style) { - super (parent, checkStyle (style)); - setForeground (null); /* set foreground and background to chosen default colors */ - setBackground (null); - GC gc = new GC (this); - fontHeight = gc.getFontMetrics ().getHeight (); - gc.dispose (); - itemHeight = fontHeight + (2 * getCellPadding ()); - initImages (display); - checkboxBounds = getUncheckedImage ().getBounds (); - arrowBounds = getArrowDownImage ().getBounds (); - clientArea = getClientArea (); - - Listener listener = new Listener () { - public void handleEvent (Event event) { - handleEvents (event); - } - }; - addListener (SWT.Paint, listener); - addListener (SWT.MouseDown, listener); - addListener (SWT.MouseUp, listener); - addListener (SWT.MouseDoubleClick, listener); - addListener (SWT.Dispose, listener); - addListener (SWT.Resize, listener); - addListener (SWT.KeyDown, listener); - addListener (SWT.FocusOut, listener); - addListener (SWT.FocusIn, listener); - addListener (SWT.Traverse, listener); - - header = new Canvas (this, SWT.NO_REDRAW_RESIZE | SWT.NO_FOCUS); - header.setVisible (false); - header.setBounds (0, 0, 0, fontHeight + 2 * getHeaderPadding ()); - header.addListener (SWT.Paint, listener); - header.addListener (SWT.MouseDown, listener); - header.addListener (SWT.MouseUp, listener); - header.addListener (SWT.MouseHover, listener); - header.addListener (SWT.MouseDoubleClick, listener); - header.addListener (SWT.MouseMove, listener); - header.addListener (SWT.MouseExit, listener); - header.addListener (SWT.MenuDetect, listener); - - toolTipListener = new Listener () { - public void handleEvent (Event event) { - switch (event.type) { - case SWT.MouseHover: - case SWT.MouseMove: - if (headerUpdateToolTip (event.x)) break; - // FALL THROUGH - case SWT.MouseExit: - case SWT.MouseDown: - headerHideToolTip (); - break; - } - } - }; - - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setValues (0, 0, 1, 1, 1, 1); - hBar.setVisible (false); - hBar.addListener (SWT.Selection, listener); - } - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - vBar.setValues (0, 0, 1, 1, 1, 1); - vBar.setVisible (false); - vBar.addListener (SWT.Selection, listener); - } -} -/** - * 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 the <code>SWT.CHECK</code> style 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) error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Selection, typedListener); - addListener (SWT.DefaultSelection, typedListener); -} -boolean checkData (TableItem item, boolean redraw) { - if (item.cached) return true; - if ((style & SWT.VIRTUAL) != 0) { - item.cached = true; - Event event = new Event (); - event.item = item; - event.index = indexOf (item); - sendEvent (SWT.SetData, event); - if (isDisposed () || item.isDisposed ()) return false; - if (redraw) redrawItem (item.index, false); - } - return true; -} -static int checkStyle (int style) { - /* - * Feature in Windows. Even when WS_HSCROLL or - * WS_VSCROLL is not specified, Windows creates - * trees and tables with scroll bars. The fix - * is to set H_SCROLL and V_SCROLL. - * - * NOTE: This code appears on all platforms so that - * applications have consistent scroll bar behavior. - */ - if ((style & SWT.NO_SCROLL) == 0) { - style |= SWT.H_SCROLL | SWT.V_SCROLL; - } - style |= SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED; - //TEMPORARY CODE - style |= SWT.FULL_SELECTION; - return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0); -} -protected void checkSubclass () { - if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); -} -/** - * Clears the item at the given zero-relative index in the receiver. - * The text, icon and other attributes of the item are set to the default - * value. If the table was created with the <code>SWT.VIRTUAL</code> style, - * these attributes are requested again as needed. - * - * @param index the index of the item to clear - * - * @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> - * - * @see SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.0 - */ -public void clear (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) error (SWT.ERROR_INVALID_RANGE); - Rectangle bounds = items [index].getBounds (false); - int oldRightX = bounds.x + bounds.width; - items [index].clear (); - if (columns.length == 0) updateHorizontalBar (0, -oldRightX); - redrawItem (index, false); -} -/** - * Removes the items from the receiver which are between the given - * zero-relative start and end indices (inclusive). The text, icon - * and other attributes of the items are set to their default values. - * If the table was created with the <code>SWT.VIRTUAL</code> style, - * these attributes are requested again as needed. - * - * @param start the start index of the item to clear - * @param end the end index of the item to clear - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_RANGE - if either the start or end are 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> - * - * @see SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.0 - */ -public void clear (int start, int end) { - checkWidget (); - if (start > end) return; - if (!(0 <= start && start <= end && end < itemsCount)) { - error (SWT.ERROR_INVALID_RANGE); - } - for (int i = start; i <= end; i++) { - items [i].clear (); - } - updateHorizontalBar (); - redrawItems (start, end, false); -} -/** - * Clears the items at the given zero-relative indices in the receiver. - * The text, icon and other attributes of the items are set to their default - * values. If the table was created with the <code>SWT.VIRTUAL</code> style, - * these attributes are requested again as needed. - * - * @param indices the array of indices of the items - * - * @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> - * <li>ERROR_NULL_ARGUMENT - if the indices array 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 SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.0 - */ -public void clear (int [] indices) { - checkWidget (); - if (indices == null) error (SWT.ERROR_NULL_ARGUMENT); - if (indices.length == 0) return; - for (int i = 0; i < indices.length; i++) { - if (!(0 <= indices [i] && indices [i] < itemsCount)) { - error (SWT.ERROR_INVALID_RANGE); - } - } - - for (int i = 0; i < indices.length; i++) { - items [indices [i]].clear (); - } - updateHorizontalBar (); - for (int i = 0; i < indices.length; i++) { - redrawItem (indices [i], false); - } -} -/** - * Clears all the items in the receiver. The text, icon and other - * attributes of the items are set to their default values. If the - * table was created with the <code>SWT.VIRTUAL</code> style, these - * attributes are requested again as needed. - * - * @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 SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.0 - */ -public void clearAll () { - checkWidget (); - clear (0, itemsCount - 1); -} -/* - * Returns the ORDERED index of the column that the specified x falls within, - * or -1 if the x lies to the right of the last column. - */ -int computeColumnIntersect (int x, int startColumn) { - TableColumn[] orderedColumns = getOrderedColumns (); - if (orderedColumns.length - 1 < startColumn) return -1; - int rightX = orderedColumns [startColumn].getX (); - for (int i = startColumn; i < orderedColumns.length; i++) { - rightX += orderedColumns [i].width; - if (x < rightX) return i; - } - return -1; -} -public Point computeSize (int wHint, int hHint, boolean changed) { - checkWidget (); - int width = 0, height = 0; - if (wHint != SWT.DEFAULT) { - width = wHint; - } else { - if (columns.length == 0) { - for (int i = 0; i < itemsCount; i++) { - Rectangle itemBounds = items [i].getBounds (false); - width = Math.max (width, itemBounds.x + itemBounds.width); - } - } else { - TableColumn[] orderedColumns = getOrderedColumns (); - TableColumn lastColumn = orderedColumns [orderedColumns.length - 1]; - width = lastColumn.getX () + lastColumn.width; - } - } - if (hHint != SWT.DEFAULT) { - height = hHint; - } else { - height = getHeaderHeight () + itemsCount * itemHeight; - } - Rectangle result = computeTrim (0, 0, width, height); - return new Point (result.width, result.height); -} -void createItem (TableColumn column, int index) { - TableColumn[] newColumns = new TableColumn [columns.length + 1]; - System.arraycopy (columns, 0, newColumns, 0, index); - newColumns [index] = column; - System.arraycopy (columns, index, newColumns, index + 1, columns.length - index); - columns = newColumns; - - if (orderedColumns != null) { - int insertIndex = 0; - if (index > 0) { - insertIndex = columns [index - 1].getOrderIndex () + 1; - } - TableColumn[] newOrderedColumns = new TableColumn [orderedColumns.length + 1]; - System.arraycopy (orderedColumns, 0, newOrderedColumns, 0, insertIndex); - newOrderedColumns [insertIndex] = column; - System.arraycopy ( - orderedColumns, - insertIndex, - newOrderedColumns, - insertIndex + 1, - orderedColumns.length - insertIndex); - orderedColumns = newOrderedColumns; - } - - /* allow all items to update their internal structures accordingly */ - for (int i = 0; i < itemsCount; i++) { - items [i].addColumn (column); - } - - /* existing items become hidden when going from 0 to 1 column (0 width) */ - if (columns.length == 1 && itemsCount > 0) { - redrawFromItemDownwards (topIndex); - } else { - /* checkboxes become hidden when creating a column with index == orderedIndex == 0 (0 width) */ - if (itemsCount > 0 && (style & SWT.CHECK) != 0 && index == 0 && column.getOrderIndex () == 0) { - redrawFromItemDownwards (topIndex); - } - } -} -void createItem (TableItem item) { - int index = item.index; - if (itemsCount == items.length) { - int grow = drawCount <= 0 ? 4 : Math.max (4, items.length * 3 / 2); - TableItem[] newItems = new TableItem [items.length + grow]; - System.arraycopy (items, 0, newItems, 0, items.length); - items = newItems; - } - if (index != itemsCount) { - /* new item is not at end of list, so shift other items right to create space for it */ - System.arraycopy (items, index, items, index + 1, itemsCount - index); - } - items [index] = item; - itemsCount++; - - /* update the index for items bumped down by this new item */ - for (int i = index + 1; i < itemsCount; i++) { - items [i].index = i; - } - - /* update scrollbars */ - updateVerticalBar (); - Rectangle bounds = item.getBounds (false); - int rightX = bounds.x + bounds.width; - updateHorizontalBar (rightX, rightX); - /* - * If new item is above viewport then adjust topIndex and the vertical - * scrollbar so that the current viewport items will not change. - */ - if (item.index < topIndex) { - topIndex++; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - return; - } - /* - * If this is the first item and the receiver has focus then its boundary - * focus ring must be removed. - */ - if (itemsCount == 1 && isFocusControl ()) { - focusItem = item; - redraw (); - return; - } - if (item.isInViewport ()) { - redrawFromItemDownwards (index); - } -} -/** - * Deselects the item at the given zero-relative index in the receiver. - * If the item at the index was already deselected, it remains - * deselected. Indices that are out of range are ignored. - * - * @param index the index of the item to deselect - * - * @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 deselect (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) return; - TableItem item = items [index]; - int selectIndex = getSelectionIndex (item); - if (selectIndex == -1) return; - - TableItem[] newSelectedItems = new TableItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, selectIndex); - System.arraycopy (selectedItems, selectIndex + 1, newSelectedItems, selectIndex, newSelectedItems.length - selectIndex); - selectedItems = newSelectedItems; - - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - redrawItem (item.index, false); - } -} -/** - * Deselects the items at the given zero-relative indices in the receiver. - * If the item at the given zero-relative index in the receiver - * is selected, it is deselected. If the item at the index - * was not selected, it remains deselected. The range of the - * indices is inclusive. Indices that are out of range are ignored. - * - * @param start the start index of the items to deselect - * @param end the end index of the items to deselect - * - * @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 deselect (int start, int end) { - checkWidget (); - if (start == 0 && end == itemsCount - 1) { - deselectAll (); - } else { - start = Math.max (start, 0); - end = Math.min (end, itemsCount - 1); - for (int i = start; i <= end; i++) { - deselect (i); - } - } -} -/** - * Deselects the items at the given zero-relative indices in the receiver. - * If the item at the given zero-relative index in the receiver - * is selected, it is deselected. If the item at the index - * was not selected, it remains deselected. Indices that are out - * of range and duplicate indices are ignored. - * - * @param indices the array of indices for the items to deselect - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the set of indices 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 void deselect (int [] indices) { - checkWidget (); - if (indices == null) error (SWT.ERROR_NULL_ARGUMENT); - if (indices.length == 0) return; - for (int i = 0; i < indices.length; i++) { - deselect (indices [i]); - } -} -/** - * Deselects all selected items in the receiver. - * - * @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 deselectAll () { - checkWidget (); - TableItem[] oldSelection = selectedItems; - selectedItems = new TableItem [0]; - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - for (int i = 0; i < oldSelection.length; i++) { - redrawItem (oldSelection [i].index, true); - } - } -} -void deselectItem (TableItem item) { - int index = getSelectionIndex (item); - if (index == -1) return; - TableItem[] newSelectedItems = new TableItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, index); - System.arraycopy ( - selectedItems, - index + 1, - newSelectedItems, - index, - newSelectedItems.length - index); - selectedItems = newSelectedItems; -} -void destroyItem (TableColumn column) { - headerHideToolTip (); - int index = column.getIndex (); - int orderedIndex = column.getOrderIndex (); - - TableColumn[] newColumns = new TableColumn [columns.length - 1]; - System.arraycopy (columns, 0, newColumns, 0, index); - System.arraycopy (columns, index + 1, newColumns, index, newColumns.length - index); - columns = newColumns; - - if (orderedColumns != null) { - if (columns.length < 2) { - orderedColumns = null; - } else { - int removeIndex = column.getOrderIndex (); - TableColumn[] newOrderedColumns = new TableColumn [orderedColumns.length - 1]; - System.arraycopy (orderedColumns, 0, newOrderedColumns, 0, removeIndex); - System.arraycopy ( - orderedColumns, - removeIndex + 1, - newOrderedColumns, - removeIndex, - newOrderedColumns.length - removeIndex); - orderedColumns = newOrderedColumns; - } - } - - /* ensure that column 0 always has left-alignment */ - if (index == 0 && columns.length > 0) { - columns [0].style |= SWT.LEFT; - columns [0].style &= ~(SWT.CENTER | SWT.RIGHT); - } - - /* allow all items to update their internal structures accordingly */ - for (int i = 0; i < itemsCount; i++) { - items [i].removeColumn (column, index); - } - - /* update horizontal scrollbar */ - int lastColumnIndex = columns.length - 1; - if (lastColumnIndex < 0) { /* no more columns */ - updateHorizontalBar (); - } else { - int newWidth = 0; - for (int i = 0; i < columns.length; i++) { - newWidth += columns [i].width; - } - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setMaximum (newWidth); - hBar.setVisible (clientArea.width < newWidth); - } - int selection = hBar.getSelection (); - if (selection != horizontalOffset) { - horizontalOffset = selection; - redraw (); - if (header.isVisible () && drawCount <= 0) header.redraw (); - } - } - TableColumn[] orderedColumns = getOrderedColumns (); - for (int i = orderedIndex; i < orderedColumns.length; i++) { - if (!orderedColumns [i].isDisposed ()) { - orderedColumns [i].sendEvent (SWT.Move); - } - } - - if (sortColumn == column) { - sortColumn = null; - } -} -/* - * Allows the Table to update internal structures it has that may contain the - * item being destroyed. - */ -void destroyItem (TableItem item) { - if (item == focusItem) reassignFocus (); - - int index = item.index; - Rectangle bounds = item.getBounds (false); - int rightX = bounds.x + bounds.width; - - if (index != itemsCount - 1) { - /* item is not at end of items list, so must shift items left to reclaim its slot */ - System.arraycopy (items, index + 1, items, index, itemsCount - index - 1); - items [itemsCount - 1] = null; - } else { - items [index] = null; /* last item, so no array copy needed */ - } - itemsCount--; - - if (drawCount <= 0 && items.length - itemsCount == 4) { - /* shrink the items array */ - TableItem[] newItems = new TableItem [itemsCount]; - System.arraycopy (items, 0, newItems, 0, newItems.length); - items = newItems; - } - - /* update the index on affected items */ - for (int i = index; i < itemsCount; i++) { - items [i].index = i; - } - item.index = -1; - - int oldTopIndex = topIndex; - updateVerticalBar (); - updateHorizontalBar (0, -rightX); - /* - * If destroyed item is above viewport then adjust topIndex and the vertical - * scrollbar so that the current viewport items will not change. - */ - if (index < topIndex) { - topIndex = oldTopIndex - 1; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - } - - /* selectedItems array */ - if (item.isSelected ()) { - int selectionIndex = getSelectionIndex (item); - TableItem[] newSelectedItems = new TableItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, selectionIndex); - System.arraycopy ( - selectedItems, - selectionIndex + 1, - newSelectedItems, - selectionIndex, - newSelectedItems.length - selectionIndex); - selectedItems = newSelectedItems; - } - if (item == anchorItem) anchorItem = null; - if (item == lastClickedItem) lastClickedItem = null; - /* - * If this was the last item and the receiver has focus then its boundary - * focus ring must be redrawn. - */ - if (itemsCount == 0 && isFocusControl ()) { - redraw (); - return; - } -} -Image getArrowDownImage () { - return (Image) display.getData (ID_ARROWDOWN); -} -Image getArrowUpImage () { - return (Image) display.getData (ID_ARROWUP); -} -int getCellPadding () { - return MARGIN_CELL + WIDTH_CELL_HIGHLIGHT; -} -Image getCheckmarkImage () { - return (Image) display.getData (ID_CHECKMARK); -} -public Control[] getChildren () { - checkWidget (); - Control[] controls = _getChildren (); - if (header == null) return controls; - Control[] result = new Control [controls.length - 1]; - /* remove the Header from the returned set of children */ - int index = 0; - for (int i = 0; i < controls.length; i++) { - if (controls [i] != header) { - result [index++] = controls [i]; - } - } - return result; -} -/** - * Returns the column at the given, zero-relative index in the - * receiver. Throws an exception if the index is out of range. - * Columns are returned in the order that they were created. - * If no <code>TableColumn</code>s were created by the programmer, - * this method will throw <code>ERROR_INVALID_RANGE</code> despite - * the fact that a single column of data may be visible in the table. - * This occurs when the programmer uses the table like a list, adding - * items but never creating a column. - * - * @param index the index of the column to return - * @return the column 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> - * - * @see Table#getColumnOrder() - * @see Table#setColumnOrder(int[]) - * @see TableColumn#getMoveable() - * @see TableColumn#setMoveable(boolean) - * @see SWT#Move - */ -public TableColumn getColumn (int index) { - checkWidget (); - if (!(0 <= index && index < columns.length)) error (SWT.ERROR_INVALID_RANGE); - return columns [index]; -} -/** - * Returns the number of columns contained in the receiver. - * If no <code>TableColumn</code>s were created by the programmer, - * this value is zero, despite the fact that visually, one column - * of items may be visible. This occurs when the programmer uses - * the table like a list, adding items but never creating a column. - * - * @return the number of columns - * - * @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 int getColumnCount () { - checkWidget (); - return columns.length; -} -/** - * Returns an array of zero-relative integers that map - * the creation order of the receiver's items to the - * order in which they are currently being displayed. - * <p> - * Specifically, the indices of the returned array represent - * the current visual order of the items, and the contents - * of the array represent the creation order of the items. - * </p><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 current visual order of the receiver's items - * - * @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 Table#setColumnOrder(int[]) - * @see TableColumn#getMoveable() - * @see TableColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.1 - */ -public int[] getColumnOrder () { - checkWidget (); - int[] result = new int [columns.length]; - if (orderedColumns != null) { - for (int i = 0; i < result.length; i++) { - result [i] = orderedColumns [i].getIndex (); - } - } else { - for (int i = 0; i < columns.length; i++) { - result [i] = i; - } - } - return result; -} -/** - * Returns an array of <code>TableColumn</code>s which are the - * columns in the receiver. Columns are returned in the order - * that they were created. If no <code>TableColumn</code>s were - * created by the programmer, the array is empty, despite the fact - * that visually, one column of items may be visible. This occurs - * when the programmer uses the table like a list, adding items but - * never creating a column. - * <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 items in the receiver - * - * @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 Table#getColumnOrder() - * @see Table#setColumnOrder(int[]) - * @see TableColumn#getMoveable() - * @see TableColumn#setMoveable(boolean) - * @see SWT#Move - */ -public TableColumn[] getColumns () { - checkWidget (); - TableColumn[] result = new TableColumn [columns.length]; - System.arraycopy (columns, 0, result, 0, columns.length); - return result; -} -Image getGrayUncheckedImage () { - return (Image) display.getData (ID_GRAYUNCHECKED); -} -/** - * Returns the width in pixels of a grid line. - * - * @return the width of a grid line in pixels - * - * @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 int getGridLineWidth () { - checkWidget (); - return 1; -} -/** - * Returns the height of the receiver's header - * - * @return the height of the header or zero if the header is not visible - * - * @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 int getHeaderHeight () { - checkWidget (); - if (!header.getVisible ()) return 0; - return header.getSize ().y; -} -int getHeaderPadding () { - return MARGIN_CELL + WIDTH_HEADER_SHADOW; -} -/** - * Returns <code>true</code> if the receiver's header is visible, - * and <code>false</code> otherwise. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, this method - * may still indicate that it is considered visible even though - * it may not actually be showing. - * </p> - * - * @return the receiver's header's visibility state - * - * @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 getHeaderVisible () { - checkWidget (); - return header.getVisible (); -} -/** - * 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> - */ -public TableItem getItem (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) 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. - * <p> - * The item that is returned represents an item that could be selected by the user. - * For example, if selection only occurs in items in the first column, then null is - * returned if the point is outside of the item. - * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy, - * determines the extent of the selection. - * </p> - * - * @param point the point used to locate the item - * @return the item at the given point, or null if the point is not in a selectable item - * - * @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 TableItem getItem (Point point) { - checkWidget (); - if (point == null) error (SWT.ERROR_NULL_ARGUMENT); - int index = (point.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < itemsCount)) return null; /* below the last item */ - TableItem result = items [index]; - if (!result.getHitBounds ().contains (point)) return null; /* considers the x value */ - return result; -} -/** - * Returns the number of items contained in the receiver. - * - * @return the number of items - * - * @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 int getItemCount () { - checkWidget (); - return itemsCount; -} -/** - * Returns the height of the area which would be used to - * display <em>one</em> of the items in the receiver. - * - * @return the height of one item - * - * @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 int getItemHeight () { - checkWidget (); - return itemHeight; -} -/** - * Returns a (possibly empty) array of <code>TableItem</code>s which - * are the items in 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 items in the receiver - * - * @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 TableItem[] getItems () { - checkWidget (); - TableItem[] result = new TableItem [itemsCount]; - System.arraycopy (items, 0, result, 0, itemsCount); - return result; -} -/* - * Returns the current y-coordinate that the specified item should have. - */ -int getItemY (TableItem item) { - return (item.index - topIndex) * itemHeight + getHeaderHeight (); -} -/** - * Returns <code>true</code> if the receiver's lines are visible, - * and <code>false</code> otherwise. Note that some platforms draw - * grid lines while others may draw alternating row colors. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, this method - * may still indicate that it is considered visible even though - * it may not actually be showing. - * </p> - * - * @return the visibility state of the lines - * - * @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 getLinesVisible () { - checkWidget (); - return linesVisible; -} -TableColumn[] getOrderedColumns () { - if (orderedColumns != null) return orderedColumns; - return columns; -} -/** - * Returns an array of <code>TableItem</code>s that are currently - * selected in the receiver. The order of the items is unspecified. - * An empty array indicates that no items are selected. - * <p> - * Note: This is not the actual structure used by the receiver - * to maintain its selection, so modifying the array will - * not affect the receiver. - * </p> - * @return an array representing the selection - * - * @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 TableItem[] getSelection () { - checkWidget (); - TableItem[] result = new TableItem [selectedItems.length]; - System.arraycopy (selectedItems, 0, result, 0, selectedItems.length); - sortAscent (result); - return result; -} -/** - * Returns the number of selected items contained in the receiver. - * - * @return the number of selected items - * - * @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 int getSelectionCount () { - checkWidget (); - return selectedItems.length; -} -/** - * Returns the zero-relative index of the item which is currently - * selected in the receiver, or -1 if no item is selected. - * - * @return the index of the selected item - * - * @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 int getSelectionIndex () { - checkWidget (); - if (selectedItems.length == 0) return -1; - return selectedItems [0].index; -} -/* - * Returns the index of the argument in the receiver's array of currently- - * selected items, or -1 if the item is not currently selected. - */ -int getSelectionIndex (TableItem item) { - for (int i = 0; i < selectedItems.length; i++) { - if (selectedItems [i] == item) return i; - } - return -1; -} -/** - * Returns the zero-relative indices of the items which are currently - * selected in the receiver. The order of the indices is unspecified. - * The array is empty if no items are selected. - * <p> - * Note: This is not the actual structure used by the receiver - * to maintain its selection, so modifying the array will - * not affect the receiver. - * </p> - * @return the array of indices of the selected items - * - * @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 int [] getSelectionIndices () { - checkWidget (); - int[] result = new int [selectedItems.length]; - for (int i = 0; i < selectedItems.length; i++) { - result [i] = selectedItems [i].index; - } - sortAscent (result); - return result; -} -/** - * Returns the column which shows the sort indicator for - * the receiver. The value may be null if no column shows - * the sort indicator. - * - * @return the sort indicator - * - * @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 #setSortColumn(TableColumn) - * - * @since 3.2 - */ -public TableColumn getSortColumn () { - checkWidget (); - return sortColumn; -} -/** - * Returns the direction of the sort indicator for the receiver. - * The value will be one of <code>UP</code>, <code>DOWN</code> - * or <code>NONE</code>. - * - * @return the sort direction - * - * @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 #setSortDirection(int) - * - * @since 3.2 - */ -public int getSortDirection () { - checkWidget (); - return sortDirection; -} -/** - * Returns the zero-relative index of the item which is currently - * at the top of the receiver. This index can change when items are - * scrolled or new items are added or removed. - * - * @return the index of the top item - * - * @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 int getTopIndex () { - checkWidget (); - return topIndex; -} -Image getUncheckedImage () { - return (Image) display.getData (ID_UNCHECKED); -} -void handleEvents (Event event) { - switch (event.type) { - case SWT.Paint: - if (event.widget == header) { - headerOnPaint (event); - } else { - onPaint (event); - } - break; - case SWT.MenuDetect: { - notifyListeners (SWT.MenuDetect, event); - break; - } - case SWT.MouseDown: - if (event.widget == header) { - headerOnMouseDown (event); - } else { - onMouseDown (event); - } - break; - case SWT.MouseUp: - if (event.widget == header) { - headerOnMouseUp (event); - } else { - onMouseUp (event); - } - break; - case SWT.MouseHover: - headerOnMouseHover (event); break; - case SWT.MouseMove: - headerOnMouseMove (event); break; - case SWT.MouseDoubleClick: - if (event.widget == header) { - headerOnMouseDoubleClick (event); - } else { - onMouseDoubleClick (event); - } - break; - case SWT.MouseExit: - headerOnMouseExit (); break; - case SWT.Dispose: - onDispose (event); break; - case SWT.KeyDown: - onKeyDown (event); break; - case SWT.Resize: - onResize (event); break; - case SWT.Selection: - if (event.widget == getHorizontalBar ()) { - onScrollHorizontal (event); - } - if (event.widget == getVerticalBar ()) { - onScrollVertical (event); - } - break; - case SWT.FocusOut: - onFocusOut (); break; - case SWT.FocusIn: - onFocusIn (); break; - case SWT.Traverse: - switch (event.detail) { - case SWT.TRAVERSE_ESCAPE: - case SWT.TRAVERSE_RETURN: - case SWT.TRAVERSE_TAB_NEXT: - case SWT.TRAVERSE_TAB_PREVIOUS: - case SWT.TRAVERSE_PAGE_NEXT: - case SWT.TRAVERSE_PAGE_PREVIOUS: - event.doit = true; - break; - } - break; - } -} -String headerGetToolTip (int x) { - if (resizeColumn != null) return null; - int orderedIndex = computeColumnIntersect (x, 0); - if (orderedIndex == -1) return null; - TableColumn[] orderedColumns = getOrderedColumns (); - TableColumn column = orderedColumns [orderedIndex]; - if (column.toolTipText == null) return null; - - /* no tooltip should appear if the hover is at a column resize opportunity */ - int columnX = column.getX (); - if (orderedIndex > 0 && orderedColumns [orderedIndex - 1].resizable) { - /* left column bound is resizable */ - if (x - columnX <= TOLLERANCE_COLUMNRESIZE) return null; - } - if (column.resizable) { - /* right column bound is resizable */ - int columnRightX = columnX + column.width; - if (columnRightX - x <= TOLLERANCE_COLUMNRESIZE) return null; - } - return removeMnemonics (column.toolTipText); -} -void headerHideToolTip() { - if (toolTipShell == null) return; - for (int i = 0; i < toolTipEvents.length; i++) { - header.removeListener (toolTipEvents [i], toolTipListener); - } - toolTipShell.dispose (); - toolTipShell = null; - toolTipLabel = null; -} -void headerOnMouseDoubleClick (Event event) { - if (!isFocusControl ()) setFocus (); - if (columns.length == 0) return; - TableColumn[] orderedColumns = getOrderedColumns (); - int x = -horizontalOffset; - for (int i = 0; i < orderedColumns.length; i++) { - TableColumn column = orderedColumns [i]; - x += column.width; - if (event.x < x) { - /* found the clicked column */ - TableColumn packColumn = null; - if (x - event.x <= TOLLERANCE_COLUMNRESIZE) { - /* clicked on column bound for this column */ - packColumn = column; - } else { - if (i > 0 && event.x - column.getX () <= TOLLERANCE_COLUMNRESIZE) { - /* clicked on column bound that applies to previous column */ - packColumn = orderedColumns [i - 1]; - } - } - if (packColumn != null) { - packColumn.pack (); - resizeColumn = null; - if (Math.abs (packColumn.getX () + packColumn.width - event.x) > TOLLERANCE_COLUMNRESIZE) { - /* column separator has relocated away from pointer location */ - setCursor (null); - } - return; - } - /* did not click on column separator, so just fire column event */ - Event newEvent = new Event (); - newEvent.widget = column; - column.postEvent (SWT.DefaultSelection, newEvent); - return; - } - } -} -void headerOnMouseDown (Event event) { - if (event.button != 1) return; - TableColumn[] orderedColumns = getOrderedColumns (); - int x = -horizontalOffset; - for (int i = 0; i < orderedColumns.length; i++) { - TableColumn column = orderedColumns [i]; - x += column.width; - /* if close to a resizable column separator line then begin column resize */ - if (column.resizable && Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) { - resizeColumn = column; - resizeColumnX = x; - return; - } - /* - * If within column but not near separator line then start column drag - * if column is moveable, or just fire column Selection otherwise. - */ - if (event.x < x) { - if (column.moveable) { - /* open tracker on the dragged column's header cell */ - int columnX = column.getX (); - int pointerOffset = event.x - columnX; - headerHideToolTip (); - Tracker tracker = new Tracker (this, SWT.NONE); - tracker.setRectangles (new Rectangle[] { - new Rectangle (columnX, 0, column.width, getHeaderHeight ()) - }); - if (!tracker.open ()) return; /* cancelled */ - /* determine which column was dragged onto */ - Rectangle result = tracker.getRectangles () [0]; - int pointerX = result.x + pointerOffset; - if (pointerX < 0) return; /* dragged too far left */ - x = -horizontalOffset; - for (int destIndex = 0; destIndex < orderedColumns.length; destIndex++) { - TableColumn destColumn = orderedColumns [destIndex]; - x += destColumn.width; - if (pointerX < x) { - int oldIndex = column.getOrderIndex (); - if (destIndex == oldIndex) { /* dragged onto self */ - Event newEvent = new Event (); - newEvent.widget = column; - column.postEvent (SWT.Selection, newEvent); - return; - } - int leftmostIndex = Math.min (destIndex, oldIndex); - int[] oldOrder = getColumnOrder (); - int[] newOrder = new int [oldOrder.length]; - System.arraycopy (oldOrder, 0, newOrder, 0, leftmostIndex); - if (leftmostIndex == oldIndex) { - /* column moving to the right */ - System.arraycopy (oldOrder, oldIndex + 1, newOrder, oldIndex, destIndex - oldIndex); - } else { - /* column moving to the left */ - System.arraycopy (oldOrder, destIndex, newOrder, destIndex + 1, oldIndex - destIndex); - } - newOrder [destIndex] = oldOrder [oldIndex]; - int rightmostIndex = Math.max (destIndex, oldIndex); - System.arraycopy ( - oldOrder, - rightmostIndex + 1, - newOrder, - rightmostIndex + 1, - newOrder.length - rightmostIndex - 1); - setColumnOrder (newOrder); - return; - } - } - return; /* dragged too far right */ - } - /* column is not moveable */ - Event newEvent = new Event (); - newEvent.widget = column; - column.postEvent (SWT.Selection, newEvent); - return; - } - } -} -void headerOnMouseExit () { - if (resizeColumn != null) return; - setCursor (null); /* ensure that a column resize cursor does not escape */ -} -void headerOnMouseHover (Event event) { - headerShowToolTip (event.x); -} -void headerOnMouseMove (Event event) { - if (resizeColumn == null) { - /* not currently resizing a column */ - for (int i = 0; i < columns.length; i++) { - TableColumn column = columns [i]; - int x = column.getX () + column.width; - if (Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) { - if (column.resizable) { - setCursor (display.getSystemCursor (SWT.CURSOR_SIZEWE)); - } else { - setCursor (null); - } - return; - } - } - setCursor (null); - return; - } - - /* currently resizing a column */ - - /* don't allow the resize x to move left of the column's x position */ - if (event.x <= resizeColumn.getX ()) return; - - /* redraw the resizing line at its new location */ - GC gc = new GC (this); - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - int lineHeight = clientArea.height; - redraw (resizeColumnX - 1, 0, 1, lineHeight, false); - resizeColumnX = event.x; - gc.drawLine (resizeColumnX - 1, 0, resizeColumnX - 1, lineHeight); - gc.dispose (); -} -void headerOnMouseUp (Event event) { - if (resizeColumn == null) return; /* not resizing a column */ - - /* remove the resize line */ - GC gc = new GC (this); - redraw (resizeColumnX - 1, 0, 1, clientArea.height, false); - gc.dispose (); - - int newWidth = resizeColumnX - resizeColumn.getX (); - if (newWidth != resizeColumn.width) { - setCursor (null); - updateColumnWidth (resizeColumn, newWidth); - } - resizeColumnX = -1; - resizeColumn = null; -} -void headerOnPaint (Event event) { - TableColumn[] orderedColumns = getOrderedColumns (); - int numColumns = orderedColumns.length; - GC gc = event.gc; - Rectangle clipping = gc.getClipping (); - int startColumn = -1, endColumn = -1; - if (numColumns > 0) { - startColumn = computeColumnIntersect (clipping.x, 0); - if (startColumn != -1) { /* the clip x is within a column's bounds */ - endColumn = computeColumnIntersect (clipping.x + clipping.width, startColumn); - if (endColumn == -1) endColumn = numColumns - 1; - } - } else { - startColumn = endColumn = 0; - } - - /* paint the column header shadow that spans the full header width */ - Point headerSize = header.getSize (); - headerPaintHShadows (gc, 0, 0, headerSize.x, headerSize.y); - - /* if all damage is to the right of the last column then finished */ - if (startColumn == -1) return; - - /* paint each of the column headers */ - if (numColumns == 0) return; /* no headers to paint */ - for (int i = startColumn; i <= endColumn; i++) { - headerPaintVShadows (gc, orderedColumns [i].getX (), 0, orderedColumns [i].width, headerSize.y); - orderedColumns [i].paint (gc); - } -} -void headerPaintHShadows (GC gc, int x, int y, int width, int height) { - gc.setClipping (x, y, width, height); - int endX = x + width; - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); - gc.drawLine (x, y, endX, y); /* highlight shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawLine (x, height - 2, endX, height - 2); /* lowlight shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_DARK_SHADOW)); - gc.drawLine (x, height - 1, endX, height - 1); /* outer shadow */ -} -void headerPaintVShadows (GC gc, int x, int y, int width, int height) { - gc.setClipping (x, y, width, height); - int endX = x + width; - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); - gc.drawLine (x, y, x, y + height - 1); /* highlight shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawLine (endX - 2, y + 1, endX - 2, height - 2); /* light inner shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_DARK_SHADOW)); - gc.drawLine (endX - 1, y, endX - 1, height - 1); /* dark outer shadow */ -} -void headerShowToolTip (int x) { - String tooltip = headerGetToolTip (x); - if (tooltip == null || tooltip.length () == 0) return; - - if (toolTipShell == null) { - toolTipShell = new Shell (getShell (), SWT.ON_TOP | SWT.TOOL); - toolTipLabel = new Label (toolTipShell, SWT.CENTER); - Display display = toolTipShell.getDisplay (); - toolTipLabel.setForeground (display.getSystemColor (SWT.COLOR_INFO_FOREGROUND)); - toolTipLabel.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND)); - for (int i = 0; i < toolTipEvents.length; i++) { - header.addListener (toolTipEvents [i], toolTipListener); - } - } - if (headerUpdateToolTip (x)) { - toolTipShell.setVisible (true); - } else { - headerHideToolTip (); - } -} -boolean headerUpdateToolTip (int x) { - String tooltip = headerGetToolTip (x); - if (tooltip == null || tooltip.length () == 0) return false; - if (tooltip.equals (toolTipLabel.getText ())) return true; - - toolTipLabel.setText (tooltip); - TableColumn column = getOrderedColumns () [computeColumnIntersect (x, 0)]; - toolTipShell.setData (new Integer (column.getIndex ())); - Point labelSize = toolTipLabel.computeSize (SWT.DEFAULT, SWT.DEFAULT, true); - labelSize.x += 2; labelSize.y += 2; - toolTipLabel.setSize (labelSize); - toolTipShell.pack (); - /* - * On some platforms, there is a minimum size for a shell - * which may be greater than the label size. - * To avoid having the background of the tip shell showing - * around the label, force the label to fill the entire client area. - */ - Rectangle area = toolTipShell.getClientArea (); - toolTipLabel.setSize (area.width, area.height); - - /* Position the tooltip and ensure it's not located off the screen */ - Point cursorLocation = getDisplay ().getCursorLocation (); - int cursorHeight = 21; /* assuming cursor is 21x21 */ - Point size = toolTipShell.getSize (); - Rectangle rect = getMonitor ().getBounds (); - Point pt = new Point (cursorLocation.x, cursorLocation.y + cursorHeight + 2); - pt.x = Math.max (pt.x, rect.x); - if (pt.x + size.x > rect.x + rect.width) pt.x = rect.x + rect.width - size.x; - if (pt.y + size.y > rect.y + rect.height) pt.y = cursorLocation.y - 2 - size.y; - toolTipShell.setLocation (pt); - return true; -} -/** - * Searches the receiver's list starting at the first column - * (index 0) until a column is found that is equal to the - * argument, and returns the index of that column. If no column - * is found, returns -1. - * - * @param column the search column - * @return the index of the column - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the column 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 int indexOf (TableColumn column) { - checkWidget (); - if (column == null) error (SWT.ERROR_NULL_ARGUMENT); - if (column.parent != this) return -1; - return column.getIndex (); -} -/** - * Searches the receiver's list starting at the first item - * (index 0) until an item is found that is equal to the - * argument, and returns the index of that item. If no item - * is found, returns -1. - * - * @param item the search item - * @return the index of the item - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the item 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 int indexOf (TableItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.parent != this) return -1; - return item.index; -} -static void initImages (final Display display) { - PaletteData arrowPalette = new PaletteData (new RGB[] { - new RGB (0, 0, 0), new RGB (255, 255, 255)}); - if (display.getData (ID_ARROWDOWN) == null) { - ImageData arrowDown = new ImageData ( - 7, 4, 1, - arrowPalette, 1, - new byte[] {0x00, (byte)0x83, (byte)0xC7, (byte)0xEF}); - arrowDown.transparentPixel = 0x1; /* use white for transparency */ - display.setData (ID_ARROWDOWN, new Image (display, arrowDown)); - } - if (display.getData (ID_ARROWUP) == null) { - ImageData arrowUp = new ImageData ( - 7, 4, 1, - arrowPalette, 1, - new byte[] {(byte)0xEF, (byte)0xC7, (byte)0x83, 0x00}); - arrowUp.transparentPixel = 0x1; /* use white for transparency */ - display.setData (ID_ARROWUP, new Image (display, arrowUp)); - } - - PaletteData checkMarkPalette = new PaletteData ( - new RGB[] {new RGB (0, 0, 0), new RGB (252, 3, 251)}); - byte[] checkbox = new byte[] {0, 0, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 0, 0}; - ImageData checkmark = new ImageData (7, 7, 1, checkMarkPalette, 1, new byte[] {-4, -8, 112, 34, 6, -114, -34}); - checkmark.transparentPixel = 1; - if (display.getData (ID_CHECKMARK) == null) { - display.setData (ID_CHECKMARK, new Image (display, checkmark)); - } - - if (display.getData (ID_UNCHECKED) == null) { - PaletteData uncheckedPalette = new PaletteData ( - new RGB[] {new RGB (128, 128, 128), new RGB (255, 255, 255)}); - ImageData unchecked = new ImageData (11, 11, 1, uncheckedPalette, 2, checkbox); - display.setData (ID_UNCHECKED, new Image (display, unchecked)); - } - - if (display.getData (ID_GRAYUNCHECKED) == null) { - PaletteData grayUncheckedPalette = new PaletteData ( - new RGB[] {new RGB (128, 128, 128), new RGB (192, 192, 192)}); - ImageData grayUnchecked = new ImageData (11, 11, 1, grayUncheckedPalette, 2, checkbox); - display.setData (ID_GRAYUNCHECKED, new Image (display, grayUnchecked)); - } - - display.disposeExec (new Runnable () { - public void run() { - Image unchecked = (Image) display.getData (ID_UNCHECKED); - if (unchecked != null) unchecked.dispose (); - Image grayUnchecked = (Image) display.getData (ID_GRAYUNCHECKED); - if (grayUnchecked != null) grayUnchecked.dispose (); - Image checkmark = (Image) display.getData (ID_CHECKMARK); - if (checkmark != null) checkmark.dispose (); - Image arrowDown = (Image) display.getData (ID_ARROWDOWN); - if (arrowDown != null) arrowDown.dispose (); - Image arrowUp = (Image) display.getData (ID_ARROWUP); - if (arrowUp != null) arrowUp.dispose (); - - display.setData (ID_UNCHECKED, null); - display.setData (ID_GRAYUNCHECKED, null); - display.setData (ID_CHECKMARK, null); - display.setData (ID_ARROWDOWN, null); - display.setData (ID_ARROWUP, null); - } - }); -} -/** - * Returns <code>true</code> if the item is selected, - * and <code>false</code> otherwise. Indices out of - * range are ignored. - * - * @param index the index of the item - * @return the selection state of the item at the index - * - * @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 isSelected (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) return false; - return items [index].isSelected (); -} -void onArrowDown (int stateMask) { - if ((stateMask & (SWT.SHIFT | SWT.CTRL)) == 0) { - /* Down Arrow with no modifiers */ - int newFocusIndex = focusItem.index + 1; - if (newFocusIndex == itemsCount) return; /* at bottom */ - selectItem (items [newFocusIndex], false); - setFocusItem (items [newFocusIndex], true); - redrawItem (newFocusIndex, true); - showItem (items [newFocusIndex]); - Event newEvent = new Event (); - newEvent.item = items [newFocusIndex]; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Down Arrow, CTRL+Shift+Down Arrow */ - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (itemsCount <= topIndex + visibleItemCount) return; /* at bottom */ - update (); - topIndex++; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, -itemHeight); - gc.dispose (); - return; - } - /* Shift+Down Arrow */ - int newFocusIndex = focusItem.index + 1; - if (newFocusIndex == itemsCount) return; /* at bottom */ - selectItem (items [newFocusIndex], false); - setFocusItem (items [newFocusIndex], true); - redrawItem (newFocusIndex, true); - showItem (items [newFocusIndex]); - Event newEvent = new Event (); - newEvent.item = items [newFocusIndex]; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+Down Arrow */ - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (itemsCount <= topIndex + visibleItemCount) return; /* at bottom */ - update (); - topIndex++; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, -itemHeight); - gc.dispose (); - return; - } - /* CTRL+Down Arrow */ - int focusIndex = focusItem.index; - if (focusIndex == itemsCount - 1) return; /* at bottom */ - TableItem newFocusItem = items [focusIndex + 1]; - setFocusItem (newFocusItem, true); - redrawItem (newFocusItem.index, true); - showItem (newFocusItem); - return; - } - /* Shift+Down Arrow */ - int newFocusIndex = focusItem.index + 1; - if (newFocusIndex == itemsCount) return; /* at bottom */ - if (anchorItem == null) anchorItem = focusItem; - if (focusItem.index < anchorItem.index) { - deselectItem (focusItem); - redrawItem (focusItem.index, true); - } - selectItem (items [newFocusIndex], true); - setFocusItem (items [newFocusIndex], true); - redrawItem (newFocusIndex, true); - showItem (items [newFocusIndex]); - Event newEvent = new Event (); - newEvent.item = items [newFocusIndex]; - postEvent (SWT.Selection, newEvent); -} -void onArrowLeft (int stateMask) { - if (horizontalOffset == 0) return; - int newSelection = Math.max (0, horizontalOffset - SIZE_HORIZONTALSCROLL); - update (); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - if (header.getVisible ()) { - header.update (); - Rectangle headerClientArea = header.getClientArea (); - gc = new GC (header); - gc.copyArea ( - 0, 0, - headerClientArea.width, headerClientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose(); - } - horizontalOffset = newSelection; - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) hBar.setSelection (horizontalOffset); -} -void onArrowRight (int stateMask) { - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - int maximum = hBar.getMaximum (); - int clientWidth = clientArea.width; - if ((horizontalOffset + clientArea.width) == maximum) return; - if (maximum <= clientWidth) return; - int newSelection = Math.min (horizontalOffset + SIZE_HORIZONTALSCROLL, maximum - clientWidth); - update (); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - if (header.getVisible ()) { - Rectangle headerClientArea = header.getClientArea (); - header.update (); - gc = new GC (header); - gc.copyArea ( - 0, 0, - headerClientArea.width, headerClientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose(); - } - horizontalOffset = newSelection; - hBar.setSelection (horizontalOffset); -} -void onArrowUp (int stateMask) { - if ((stateMask & (SWT.SHIFT | SWT.CTRL)) == 0) { - /* Up Arrow with no modifiers */ - int newFocusIndex = focusItem.index - 1; - if (newFocusIndex < 0) return; /* at top */ - TableItem item = items [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (newFocusIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Up Arrow, CTRL+Shift+Up Arrow */ - if (topIndex == 0) return; /* at top */ - update (); - topIndex--; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, itemHeight); - gc.dispose (); - return; - } - /* Shift+Up Arrow */ - int newFocusIndex = focusItem.index - 1; - if (newFocusIndex < 0) return; /* at top */ - TableItem item = items [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (newFocusIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+Up Arrow */ - if (topIndex == 0) return; /* at top */ - update (); - topIndex--; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, itemHeight); - gc.dispose (); - return; - } - /* CTRL+Up Arrow */ - int focusIndex = focusItem.index; - if (focusIndex == 0) return; /* at top */ - TableItem newFocusItem = items [focusIndex - 1]; - setFocusItem (newFocusItem, true); - showItem (newFocusItem); - redrawItem (newFocusItem.index, true); - return; - } - /* Shift+Up Arrow */ - int newFocusIndex = focusItem.index - 1; - if (newFocusIndex < 0) return; /* at top */ - if (anchorItem == null) anchorItem = focusItem; - if (anchorItem.index < focusItem.index) { - deselectItem (focusItem); - redrawItem (focusItem.index, true); - } - TableItem item = items [newFocusIndex]; - selectItem (item, true); - setFocusItem (item, true); - redrawItem (newFocusIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); -} -void onCR () { - if (focusItem == null) return; - Event event = new Event (); - event.item = focusItem; - postEvent (SWT.DefaultSelection, event); -} -void onDispose (Event event) { - if (isDisposed ()) return; - if (ignoreDispose) return; - ignoreDispose = true; - notifyListeners(SWT.Dispose, event); - event.type = SWT.None; - for (int i = 0; i < itemsCount; i++) { - items [i].dispose (false); - } - for (int i = 0; i < columns.length; i++) { - columns [i].dispose (false); - } - if (toolTipShell != null) { - toolTipShell.dispose (); - toolTipShell = null; - toolTipLabel = null; - } - toolTipListener = null; - itemsCount = topIndex = horizontalOffset = 0; - items = selectedItems = null; - columns = orderedColumns = null; - focusItem = anchorItem = lastClickedItem = null; - lastSelectionEvent = null; - header = null; - resizeColumn = sortColumn = null; -} -void onEnd (int stateMask) { - int lastAvailableIndex = itemsCount - 1; - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* End with no modifiers */ - if (focusItem.index == lastAvailableIndex) return; /* at bottom */ - TableItem item = items [lastAvailableIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (lastAvailableIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+End, CTRL+Shift+End */ - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - setTopIndex (itemsCount - visibleItemCount); - return; - } - /* Shift+End */ - if (focusItem.index == lastAvailableIndex) return; /* at bottom */ - TableItem item = items [lastAvailableIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (lastAvailableIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+End */ - showItem (items [lastAvailableIndex]); - return; - } - /* CTRL+End */ - if (focusItem.index == lastAvailableIndex) return; /* at bottom */ - TableItem item = items [lastAvailableIndex]; - setFocusItem (item, true); - showItem (item); - redrawItem (item.index, true); - return; - } - /* Shift+End */ - if (anchorItem == null) anchorItem = focusItem; - TableItem selectedItem = items [lastAvailableIndex]; - if (selectedItem == focusItem && selectedItem.isSelected ()) return; - int anchorIndex = anchorItem.index; - int selectIndex = selectedItem.index; - TableItem[] newSelection = new TableItem [selectIndex - anchorIndex + 1]; - int writeIndex = 0; - for (int i = anchorIndex; i <= selectIndex; i++) { - newSelection [writeIndex++] = items [i]; - } - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems (anchorIndex, selectIndex, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onFocusIn () { - hasFocus = true; - if (itemsCount == 0) { - redraw (); - return; - } - if ((style & (SWT.HIDE_SELECTION | SWT.MULTI)) == (SWT.HIDE_SELECTION | SWT.MULTI)) { - for (int i = 0; i < selectedItems.length; i++) { - redrawItem (selectedItems [i].index, true); - } - } - if (focusItem != null) { - redrawItem (focusItem.index, true); - return; - } - /* an initial focus item must be selected */ - TableItem initialFocus; - if (selectedItems.length > 0) { - initialFocus = selectedItems [0]; - } else { - initialFocus = items [topIndex]; - } - setFocusItem (initialFocus, false); - redrawItem (initialFocus.index, true); - return; -} -void onFocusOut () { - hasFocus = false; - if (itemsCount == 0) { - redraw (); - return; - } - if (focusItem != null) { - redrawItem (focusItem.index, true); - } - if ((style & (SWT.HIDE_SELECTION | SWT.MULTI)) == (SWT.HIDE_SELECTION | SWT.MULTI)) { - for (int i = 0; i < selectedItems.length; i++) { - redrawItem (selectedItems [i].index, true); - } - } -} -void onHome (int stateMask) { - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* Home with no modifiers */ - if (focusItem.index == 0) return; /* at top */ - TableItem item = items [0]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (0, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Home, CTRL+Shift+Home */ - setTopIndex (0); - return; - } - /* Shift+Home */ - if (focusItem.index == 0) return; /* at top */ - TableItem item = items [0]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (0, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+Home */ - setTopIndex (0); - return; - } - /* CTRL+Home */ - if (focusItem.index == 0) return; /* at top */ - TableItem item = items [0]; - setFocusItem (item, true); - showItem (item); - redrawItem (item.index, true); - return; - } - /* Shift+Home */ - if (anchorItem == null) anchorItem = focusItem; - TableItem selectedItem = items [0]; - if (selectedItem == focusItem && selectedItem.isSelected ()) return; - int anchorIndex = anchorItem.index; - int selectIndex = selectedItem.index; - TableItem[] newSelection = new TableItem [anchorIndex + 1]; - int writeIndex = 0; - for (int i = anchorIndex; i >= 0; i--) { - newSelection [writeIndex++] = items [i]; - } - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems (anchorIndex, selectIndex, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onKeyDown (Event event) { - if (ignoreKey) { - ignoreKey = false; - return; - } - ignoreKey = true; - notifyListeners (event.type, event); - event.type = SWT.None; - if (!event.doit) return; - if (focusItem == null) return; - if ((event.stateMask & SWT.SHIFT) == 0 && event.keyCode != SWT.SHIFT) { - anchorItem = null; - } - switch (event.keyCode) { - case SWT.ARROW_UP: - onArrowUp (event.stateMask); - return; - case SWT.ARROW_DOWN: - onArrowDown (event.stateMask); - return; - case SWT.ARROW_LEFT: - onArrowLeft (event.stateMask); - return; - case SWT.ARROW_RIGHT: - onArrowRight (event.stateMask); - return; - case SWT.PAGE_UP: - onPageUp (event.stateMask); - return; - case SWT.PAGE_DOWN: - onPageDown (event.stateMask); - return; - case SWT.HOME: - onHome (event.stateMask); - return; - case SWT.END: - onEnd (event.stateMask); - return; - } - if (event.character == ' ') { - onSpace (); - return; - } - if (event.character == SWT.CR) { - onCR (); - return; - } - if ((event.stateMask & SWT.CTRL) != 0) return; - - int initialIndex = focusItem.index; - char character = Character.toLowerCase (event.character); - /* check available items from current focus item to bottom */ - for (int i = initialIndex + 1; i < itemsCount; i++) { - TableItem item = items [i]; - String text = item.getText (0, false); - if (text.length () > 0) { - if (Character.toLowerCase (text.charAt (0)) == character) { - selectItem (item, false); - setFocusItem (item, true); - redrawItem (i, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - } - } - /* check available items from top to current focus item */ - for (int i = 0; i < initialIndex; i++) { - TableItem item = items [i]; - String text = item.getText (0, false); - if (text.length () > 0) { - if (Character.toLowerCase (text.charAt (0)) == character) { - selectItem (item, false); - setFocusItem (item, true); - redrawItem (i, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - } - } -} -void onMouseDoubleClick (Event event) { - if (!isFocusControl ()) setFocus (); - int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < itemsCount)) return; /* not on an available item */ - TableItem selectedItem = items [index]; - - /* - * If the two clicks of the double click did not occur over the same item then do not - * consider this to be a default selection. - */ - if (selectedItem != lastClickedItem) return; - - if (!selectedItem.getHitBounds ().contains (event.x, event.y)) return; /* considers x */ - - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.DefaultSelection, newEvent); -} -void onMouseDown (Event event) { - if (!isFocusControl ()) forceFocus (); - int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < itemsCount)) return; /* not on an available item */ - TableItem selectedItem = items [index]; - - /* if click was in checkbox */ - if ((style & SWT.CHECK) != 0 && selectedItem.getCheckboxBounds ().contains (event.x, event.y)) { - if (event.button != 1) return; - selectedItem.setChecked (!selectedItem.checked); - Event newEvent = new Event (); - newEvent.item = selectedItem; - newEvent.detail = SWT.CHECK; - postEvent (SWT.Selection, newEvent); - return; - } - - if (!selectedItem.getHitBounds ().contains (event.x, event.y)) return; - - if ((event.stateMask & SWT.SHIFT) == 0 && event.keyCode != SWT.SHIFT) anchorItem = null; - - boolean sendSelection = true; - /* Detect when this is the second click of a DefaultSelection and don't fire Selection */ - if (lastSelectionEvent != null && lastSelectionEvent.item == selectedItem) { - if (event.time - lastSelectionEvent.time <= display.getDoubleClickTime ()) { - sendSelection = false; - } else { - lastSelectionEvent = event; - event.item = selectedItem; - } - } else { - lastSelectionEvent = event; - event.item = selectedItem; - } - - if ((style & SWT.SINGLE) != 0) { - if (!selectedItem.isSelected ()) { - if (event.button == 1) { - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.index, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.index, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - } - /* item is selected */ - if (event.button == 1) { - /* fire a selection event, though the selection did not change */ - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - } - /* SWT.MULTI */ - if (!selectedItem.isSelected ()) { - if (event.button == 1) { - if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == SWT.SHIFT) { - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.index; - int selectIndex = selectedItem.index; - TableItem[] newSelection = new TableItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = items [i]; - } - newSelection [writeIndex] = items [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems ( - Math.min (anchorIndex, selectIndex), - Math.max (anchorIndex, selectIndex), - true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - selectItem (selectedItem, (event.stateMask & SWT.CTRL) != 0); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.index, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - /* button 3 */ - if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.index, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - } - /* item is selected */ - if (event.button != 1) return; - if ((event.stateMask & SWT.CTRL) != 0) { - removeSelectedItem (getSelectionIndex (selectedItem)); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.index, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - if ((event.stateMask & SWT.SHIFT) != 0) { - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.index; - int selectIndex = selectedItem.index; - TableItem[] newSelection = new TableItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = items [i]; - } - newSelection [writeIndex] = items [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems ( - Math.min (anchorIndex, selectIndex), - Math.max (anchorIndex, selectIndex), - true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.index, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } -} -void onMouseUp (Event event) { - int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < itemsCount)) return; /* not on an available item */ - lastClickedItem = items [index]; -} -void onPageDown (int stateMask) { - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* PageDown with no modifiers */ - int newFocusIndex = focusItem.index + visibleItemCount - 1; - newFocusIndex = Math.min (newFocusIndex, itemsCount - 1); - if (newFocusIndex == focusItem.index) return; - TableItem item = items [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.index, true); - return; - } - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == (SWT.CTRL | SWT.SHIFT)) { - /* CTRL+Shift+PageDown */ - int newTopIndex = topIndex + visibleItemCount; - newTopIndex = Math.min (newTopIndex, itemsCount - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopIndex (newTopIndex); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* Shift+PageDown */ - int newFocusIndex = focusItem.index + visibleItemCount - 1; - newFocusIndex = Math.min (newFocusIndex, itemsCount - 1); - if (newFocusIndex == focusItem.index) return; - TableItem item = items [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.index, true); - return; - } - /* CTRL+PageDown */ - int newTopIndex = topIndex + visibleItemCount; - newTopIndex = Math.min (newTopIndex, itemsCount - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopIndex (newTopIndex); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+PageDown */ - int bottomIndex = Math.min (topIndex + visibleItemCount - 1, itemsCount - 1); - if (focusItem.index != bottomIndex) { - /* move focus to bottom item in viewport */ - setFocusItem (items [bottomIndex], true); - redrawItem (bottomIndex, true); - } else { - /* at bottom of viewport, so set focus to bottom item one page down */ - int newFocusIndex = Math.min (itemsCount - 1, bottomIndex + visibleItemCount); - if (newFocusIndex == focusItem.index) return; - setFocusItem (items [newFocusIndex], true); - showItem (items [newFocusIndex]); - redrawItem (newFocusIndex, true); - } - return; - } - /* Shift+PageDown */ - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.index; - int bottomIndex = Math.min (topIndex + visibleItemCount - 1, itemsCount - 1); - int selectIndex; - if (focusItem.index != bottomIndex) { - /* select from focus to bottom item in viewport */ - selectIndex = bottomIndex; - } else { - /* already at bottom of viewport, so select to bottom of one page down */ - selectIndex = Math.min (itemsCount - 1, bottomIndex + visibleItemCount); - if (selectIndex == focusItem.index && focusItem.isSelected ()) return; - } - TableItem selectedItem = items [selectIndex]; - TableItem[] newSelection = new TableItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = items [i]; - } - newSelection [writeIndex] = items [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onPageUp (int stateMask) { - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* PageUp with no modifiers */ - int newFocusIndex = Math.max (0, focusItem.index - visibleItemCount + 1); - if (newFocusIndex == focusItem.index) return; - TableItem item = items [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.index, true); - return; - } - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == (SWT.CTRL | SWT.SHIFT)) { - /* CTRL+Shift+PageUp */ - int newTopIndex = Math.max (0, topIndex - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopIndex (newTopIndex); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* Shift+PageUp */ - int newFocusIndex = Math.max (0, focusItem.index - visibleItemCount + 1); - if (newFocusIndex == focusItem.index) return; - TableItem item = items [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.index, true); - return; - } - /* CTRL+PageUp */ - int newTopIndex = Math.max (0, topIndex - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopIndex (newTopIndex); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+PageUp */ - if (focusItem.index != topIndex) { - /* move focus to top item in viewport */ - setFocusItem (items [topIndex], true); - redrawItem (topIndex, true); - } else { - /* at top of viewport, so set focus to top item one page up */ - int newFocusIndex = Math.max (0, focusItem.index - visibleItemCount); - if (newFocusIndex == focusItem.index) return; - setFocusItem (items [newFocusIndex], true); - showItem (items [newFocusIndex]); - redrawItem (newFocusIndex, true); - } - return; - } - /* Shift+PageUp */ - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.index; - int selectIndex; - if (focusItem.index != topIndex) { - /* select from focus to top item in viewport */ - selectIndex = topIndex; - } else { - /* already at top of viewport, so select to top of one page up */ - selectIndex = Math.max (0, topIndex - visibleItemCount); - if (selectIndex == focusItem.index && focusItem.isSelected ()) return; - } - TableItem selectedItem = items [selectIndex]; - TableItem[] newSelection = new TableItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = items [i]; - } - newSelection [writeIndex] = items [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onPaint (Event event) { - TableColumn[] orderedColumns = getOrderedColumns (); - GC gc = event.gc; - Rectangle clipping = gc.getClipping (); - int headerHeight = getHeaderHeight (); - int numColumns = orderedColumns.length; - int startColumn = -1, endColumn = -1; - if (numColumns > 0) { - startColumn = computeColumnIntersect (clipping.x, 0); - if (startColumn != -1) { /* the clip x is within a column's bounds */ - endColumn = computeColumnIntersect (clipping.x + clipping.width, startColumn); - if (endColumn == -1) endColumn = numColumns - 1; - } - } else { - startColumn = endColumn = 0; - } - - /* Determine the items to be painted */ - int startIndex = (clipping.y - headerHeight) / itemHeight + topIndex; - int endIndex = -1; - if (startIndex < itemsCount) { - endIndex = startIndex + Compatibility.ceil (clipping.height, itemHeight); - } - startIndex = Math.max (0, startIndex); - endIndex = Math.min (endIndex, itemsCount - 1); - - /* fill background not handled by items */ - gc.setBackground (getBackground ()); - gc.setClipping (clipping); - int bottomY = endIndex >= 0 ? getItemY (items [endIndex]) + itemHeight : 0; - int fillHeight = Math.max (0, clientArea.height - bottomY); - if (fillHeight > 0) { /* space below bottom item */ - drawBackground (gc, 0, bottomY, clientArea.width, fillHeight); - } - if (columns.length > 0) { - TableColumn column = orderedColumns [orderedColumns.length - 1]; /* last column */ - int rightX = column.getX () + column.width; - if (rightX < clientArea.width) { - drawBackground (gc, rightX, 0, clientArea.width - rightX, clientArea.height - fillHeight); - } - } - - /* paint the items */ - boolean noFocusDraw = false; - int[] lineDash = gc.getLineDash (); - int lineWidth = gc.getLineWidth (); - for (int i = startIndex; i <= Math.min (endIndex, itemsCount - 1); i++) { - TableItem item = items [i]; - if (!item.isDisposed ()) { /* ensure that item was not disposed in a callback */ - if (startColumn == -1) { - /* indicates that region to paint is to the right of the last column */ - noFocusDraw = item.paint (gc, null, true) || noFocusDraw; - } else { - if (numColumns == 0) { - noFocusDraw = item.paint (gc, null, false) || noFocusDraw; - } else { - for (int j = startColumn; j <= Math.min (endColumn, columns.length - 1); j++) { - if (!item.isDisposed ()) { /* ensure that item was not disposed in a callback */ - noFocusDraw = item.paint (gc, orderedColumns [j], false) || noFocusDraw; - } - if (isDisposed () || gc.isDisposed ()) return; /* ensure that receiver was not disposed in a callback */ - } - } - } - } - if (isDisposed () || gc.isDisposed ()) return; /* ensure that receiver was not disposed in a callback */ - } - - /* repaint grid lines */ - gc.setClipping(clipping); - gc.setLineWidth (lineWidth); - if (linesVisible) { - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_LIGHT_SHADOW)); - gc.setLineDash (lineDash); - if (numColumns > 0 && startColumn != -1) { - /* vertical column lines */ - for (int i = startColumn; i <= endColumn; i++) { - int x = orderedColumns [i].getX () + orderedColumns [i].width - 1; - gc.drawLine (x, clipping.y, x, clipping.y + clipping.height); - } - } - /* horizontal item lines */ - bottomY = clipping.y + clipping.height; - int rightX = clipping.x + clipping.width; - int y = (clipping.y - headerHeight) / itemHeight * itemHeight + headerHeight; - while (y <= bottomY) { - gc.drawLine (clipping.x, y, rightX, y); - y += itemHeight; - } - } - - /* paint focus rectangle */ - if (!noFocusDraw && isFocusControl ()) { - if (focusItem != null) { - Rectangle focusBounds = focusItem.getFocusBounds (); - if (focusBounds.width > 0) { - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - gc.setClipping (focusBounds); - if (focusItem.isSelected ()) { - gc.setLineDash (new int[] {2, 2}); - } else { - gc.setLineDash (new int[] {1, 1}); - } - gc.drawFocus (focusBounds.x, focusBounds.y, focusBounds.width, focusBounds.height); - } - } else { - /* no items, so draw focus border around Table */ - int y = headerHeight + 1; - int width = Math.max (0, clientArea.width - 2); - int height = Math.max (0, clientArea.height - headerHeight - 2); - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - gc.setClipping (1, y, width, height); - gc.setLineDash (new int[] {1, 1}); - gc.drawFocus (1, y, width, height); - } - } -} -void onResize (Event event) { - clientArea = getClientArea (); - /* vertical scrollbar */ - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - int clientHeight = (clientArea.height - getHeaderHeight ()) / itemHeight; - int thumb = Math.min (clientHeight, itemsCount); - vBar.setThumb (thumb); - vBar.setPageIncrement (thumb); - int index = vBar.getSelection (); - if (index != topIndex) { - topIndex = index; - redraw (); - } - boolean visible = clientHeight < itemsCount; - if (visible != vBar.getVisible ()) { - vBar.setVisible (visible); - clientArea = getClientArea (); - } - } - - /* horizontal scrollbar */ - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - int hBarMaximum = hBar.getMaximum (); - int thumb = Math.min (clientArea.width, hBarMaximum); - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - horizontalOffset = hBar.getSelection (); - boolean visible = clientArea.width < hBarMaximum; - if (visible != hBar.getVisible ()) { - hBar.setVisible (visible); - clientArea = getClientArea (); - } - } - - /* header */ - int headerHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding (); - header.setSize (clientArea.width, headerHeight); - - /* if this is the focus control but there are no items then the boundary focus ring must be repainted */ - if (itemsCount == 0 && isFocusControl ()) redraw (); -} -void onScrollHorizontal (Event event) { - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - int newSelection = hBar.getSelection (); - update (); - if (itemsCount > 0) { - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - } else { - redraw (); /* ensure that static focus rectangle updates properly */ - } - - if (drawCount <= 0 && header.isVisible ()) { - header.update (); - Rectangle headerClientArea = header.getClientArea (); - GC gc = new GC (header); - gc.copyArea ( - 0, 0, - headerClientArea.width, headerClientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - } - horizontalOffset = newSelection; -} -void onScrollVertical (Event event) { - ScrollBar vBar = getVerticalBar (); - if (vBar == null) return; - int newSelection = vBar.getSelection (); - update (); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, (topIndex - newSelection) * itemHeight); - gc.dispose (); - topIndex = newSelection; -} -void onSpace () { - if (focusItem == null) return; - if (!focusItem.isSelected ()) { - selectItem (focusItem, (style & SWT.MULTI) != 0); - redrawItem (focusItem.index, true); - } - if ((style & SWT.CHECK) != 0) { - focusItem.setChecked (!focusItem.checked); - } - showItem (focusItem); - Event event = new Event (); - event.item = focusItem; - postEvent (SWT.Selection, event); - if ((style & SWT.CHECK) == 0) return; - - /* SWT.CHECK */ - event = new Event (); - event.item = focusItem; - event.detail = SWT.CHECK; - postEvent (SWT.Selection, event); -} -/* - * The current focus item is about to become unavailable, so reassign focus. - */ -void reassignFocus () { - if (focusItem == null) return; - - /* - * reassign to the previous root-level item if there is one, or the next - * root-level item otherwise - */ - int index = focusItem.index; - if (index != 0) { - index--; - } else { - index++; - } - if (index < itemsCount) { - TableItem item = items [index]; - setFocusItem (item, false); - showItem (item); - } else { - setFocusItem (null, false); /* no items left */ - } -} -public void redraw () { - checkWidget (); - if (drawCount <= 0) super.redraw (); -} -public void redraw (int x, int y, int width, int height, boolean all) { - checkWidget (); - if (drawCount <= 0) super.redraw (x, y, width, height, all); -} -/* - * Redraws from the specified index down to the last available item inclusive. Note - * that the redraw bounds do not extend beyond the current last item, so clients - * that reduce the number of available items should use #redrawItems(int,int) instead - * to ensure that redrawing extends down to the previous bottom item boundary. - */ -void redrawFromItemDownwards (int index) { - redrawItems (index, itemsCount - 1, false); -} -/* - * Redraws the table item at the specified index. It is valid for this index to reside - * beyond the last available item. - */ -void redrawItem (int itemIndex, boolean focusBoundsOnly) { - if (itemIndex < itemsCount && !items [itemIndex].isInViewport ()) return; - redrawItems (itemIndex, itemIndex, focusBoundsOnly); -} -/* - * Redraws the table between the start and end item indices inclusive. It is valid - * for the end index value to extend beyond the last available item. - */ -void redrawItems (int startIndex, int endIndex, boolean focusBoundsOnly) { - if (drawCount > 0) return; - - int startY = (startIndex - topIndex) * itemHeight + getHeaderHeight (); - int height = (endIndex - startIndex + 1) * itemHeight; - if (focusBoundsOnly) { - boolean custom = hooks (SWT.EraseItem) || hooks (SWT.PaintItem); - if (!custom && columns.length > 0) { - TableColumn lastColumn; - if ((style & SWT.FULL_SELECTION) != 0) { - TableColumn[] orderedColumns = getOrderedColumns (); - lastColumn = orderedColumns [orderedColumns.length - 1]; - } else { - lastColumn = columns [0]; - } - int rightX = lastColumn.getX () + lastColumn.getWidth (); - if (rightX <= 0) return; /* focus column(s) not visible */ - } - endIndex = Math.min (endIndex, itemsCount - 1); - for (int i = startIndex; i <= endIndex; i++) { - TableItem item = items [i]; - if (item.isInViewport ()) { - /* if custom painting is being done then repaint the full item */ - if (custom) { - redraw (0, getItemY (item), clientArea.width, itemHeight, false); - } else { - /* repaint the item's focus bounds */ - Rectangle bounds = item.getFocusBounds (); - redraw (bounds.x, startY, bounds.width, height, false); - } - } - } - } else { - redraw (0, startY, clientArea.width, height, false); - } -} -/** - * Removes the item from the receiver at the given - * zero-relative index. - * - * @param index the index for the item - * - * @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> - */ -public void remove (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) error (SWT.ERROR_INVALID_RANGE); - items [index].dispose (); -} -/** - * Removes the items from the receiver which are - * between the given zero-relative start and end - * indices (inclusive). - * - * @param start the start of the range - * @param end the end of the range - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_RANGE - if either the start or end are 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> - */ -public void remove (int start, int end) { - checkWidget (); - if (start > end) return; - if (!(0 <= start && start <= end && end < itemsCount)) { - error (SWT.ERROR_INVALID_RANGE); - } - if (start == 0 && end == itemsCount - 1) { - removeAll (); - } else { - for (int i = end; i >= start; i--) { - items [i].dispose (); - } - } -} -/** - * Removes the items from the receiver's list at the given - * zero-relative indices. - * - * @param indices the array of indices of the items - * - * @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> - * <li>ERROR_NULL_ARGUMENT - if the indices array 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 void remove (int [] indices) { - checkWidget (); - if (indices == null) error (SWT.ERROR_NULL_ARGUMENT); - if (indices.length == 0) return; - int [] newIndices = new int [indices.length]; - System.arraycopy (indices, 0, newIndices, 0, indices.length); - sortDescent (newIndices); - int start = newIndices [newIndices.length - 1], end = newIndices [0]; - if (!(0 <= start && start <= end && end < itemsCount)) { - error (SWT.ERROR_INVALID_RANGE); - } - int lastRemovedIndex = -1; - for (int i = 0; i < newIndices.length; i++) { - if (newIndices [i] != lastRemovedIndex) { - items [newIndices [i]].dispose (); - lastRemovedIndex = newIndices [i]; - } - } -} -/** - * Removes all of the items from the receiver. - * - * @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 removeAll () { - checkWidget (); - if (itemsCount == 0) return; - setRedraw (false); - - setFocusItem (null, false); - for (int i = 0; i < itemsCount; i++) { - items [i].dispose (false); - } - items = new TableItem [0]; - selectedItems = new TableItem [0]; - itemsCount = topIndex = 0; - anchorItem = lastClickedItem = null; - lastSelectionEvent = null; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - vBar.setMaximum (1); - vBar.setVisible (false); - } - if (columns.length == 0) { - horizontalOffset = 0; - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setMaximum (1); - hBar.setVisible (false); - } - } - - setRedraw (true); -} -String removeMnemonics (String string) { - /* removes single ampersands and preserves double-ampersands */ - char [] chars = new char [string.length ()]; - string.getChars (0, chars.length, chars, 0); - int i = 0, j = 0; - for ( ; i < chars.length; i++, j++) { - if (chars[i] == '&') { - if (++i == chars.length) break; - if (chars[i] == '&') { - chars[j++] = chars[i - 1]; - } - } - chars[j] = chars[i]; - } - if (i == j) return string; - return new String (chars, 0, j); -} -void removeSelectedItem (int index) { - TableItem[] newSelectedItems = new TableItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, index); - System.arraycopy (selectedItems, index + 1, newSelectedItems, index, newSelectedItems.length - index); - selectedItems = newSelectedItems; -} -/** - * 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(SelectionListener) - */ -public void removeSelectionListener (SelectionListener listener) { - checkWidget (); - if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); - removeListener (SWT.Selection, listener); - removeListener (SWT.DefaultSelection, listener); -} -/** - * Selects the item at the given zero-relative index in the receiver. - * If the item at the index was already selected, it remains - * selected. Indices that are out of range are ignored. - * - * @param index the index of the item to select - * - * @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 select (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) return; - selectItem (items [index], (style & SWT.MULTI) != 0); - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - redrawItem (index, false); - } -} -/** - * Selects the items in the range specified by the given zero-relative - * indices in the receiver. The range of indices is inclusive. - * The current selection is not cleared before the new items are selected. - * <p> - * If an item in the given range is not selected, it is selected. - * If an item in the given range was already selected, it remains selected. - * Indices that are out of range are ignored and no items will be selected - * if start is greater than end. - * If the receiver is single-select and there is more than one item in the - * given range, then all indices are ignored. - * </p> - * - * @param start the start of the range - * @param end the end of the range - * - * @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 Table#setSelection(int,int) - */ -public void select (int start, int end) { - checkWidget (); - if (end < 0 || start > end || ((style & SWT.SINGLE) != 0 && start != end)) return; - if (itemsCount == 0 || start >= itemsCount) return; - start = Math.max (start, 0); - end = Math.min (end, itemsCount - 1); - for (int i = start; i <= end; i++) { - selectItem (items [i], (style & SWT.MULTI) != 0); - } - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - redrawItems (start, end, false); - } -} -/** - * Selects the items at the given zero-relative indices in the receiver. - * The current selection is not cleared before the new items are selected. - * <p> - * If the item at a given index is not selected, it is selected. - * If the item at a given index was already selected, it remains selected. - * Indices that are out of range and duplicate indices are ignored. - * If the receiver is single-select and multiple indices are specified, - * then all indices are ignored. - * </p> - * - * @param indices the array of indices for the items to select - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the array of indices 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 Table#setSelection(int[]) - */ -public void select (int [] indices) { - checkWidget (); - if (indices == null) error (SWT.ERROR_NULL_ARGUMENT); - if (indices.length == 0 || ((style & SWT.SINGLE) != 0 && indices.length > 1)) return; - - for (int i = 0; i < indices.length; i++) { - if (0 <= indices [i] && indices [i] < itemsCount) { - selectItem (items [indices [i]], (style & SWT.MULTI) != 0); - } - } - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - for (int i = 0; i < indices.length; i++) { - if (0 <= indices [i] && indices [i] < itemsCount) { - redrawItem (indices [i], false); - } - } - } -} -/** - * Selects all of the items in the receiver. - * <p> - * If the receiver is single-select, do nothing. - * </p> - * - * @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 selectAll () { - checkWidget (); - if ((style & SWT.SINGLE) != 0) return; - selectedItems = new TableItem [itemsCount]; - System.arraycopy (items, 0, selectedItems, 0, itemsCount); - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - redraw (); - } -} -void selectItem (TableItem item, boolean addToSelection) { - TableItem[] oldSelectedItems = selectedItems; - if (!addToSelection || (style & SWT.SINGLE) != 0) { - selectedItems = new TableItem[] {item}; - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - for (int i = 0; i < oldSelectedItems.length; i++) { - if (oldSelectedItems [i] != item) { - redrawItem (oldSelectedItems [i].index, true); - } - } - } - } else { - if (item.isSelected ()) return; - selectedItems = new TableItem [selectedItems.length + 1]; - System.arraycopy (oldSelectedItems, 0, selectedItems, 0, oldSelectedItems.length); - selectedItems [selectedItems.length - 1] = item; - } -} -public void setBackground (Color color) { - checkWidget (); - if (color == null) color = display.getSystemColor (SWT.COLOR_LIST_BACKGROUND); - super.setBackground (color); -} -public void setForeground (Color color) { - checkWidget (); - if (color == null) color = display.getSystemColor (SWT.COLOR_LIST_FOREGROUND); - super.setForeground (color); -} -/** - * Sets the order that the items in the receiver should - * be displayed in to the given argument which is described - * in terms of the zero-relative ordering of when the items - * were added. - * - * @param order the new order to display the items - * - * @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> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the item order is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li> - * </ul> - * - * @see Table#getColumnOrder() - * @see TableColumn#getMoveable() - * @see TableColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.1 - */ -public void setColumnOrder (int [] order) { - checkWidget (); - if (order == null) error (SWT.ERROR_NULL_ARGUMENT); - if (columns.length == 0) { - if (order.length != 0) error (SWT.ERROR_INVALID_ARGUMENT); - return; - } - if (order.length != columns.length) error (SWT.ERROR_INVALID_ARGUMENT); - boolean reorder = false; - boolean [] seen = new boolean [columns.length]; - int[] oldOrder = getColumnOrder (); - for (int i = 0; i < order.length; i++) { - int index = order [i]; - if (index < 0 || index >= columns.length) error (SWT.ERROR_INVALID_RANGE); - if (seen [index]) error (SWT.ERROR_INVALID_ARGUMENT); - seen [index] = true; - if (index != oldOrder [i]) reorder = true; - } - if (!reorder) return; - - headerHideToolTip (); - int[] oldX = new int [columns.length]; - for (int i = 0; i < columns.length; i++) { - oldX [i] = columns [i].getX (); - } - orderedColumns = new TableColumn [order.length]; - for (int i = 0; i < order.length; i++) { - orderedColumns [i] = columns [order [i]]; - } - for (int i = 0; i < orderedColumns.length; i++) { - TableColumn column = orderedColumns [i]; - if (!column.isDisposed () && column.getX () != oldX [column.getIndex ()]) { - column.sendEvent (SWT.Move); - } - } - - redraw (); - if (drawCount <= 0 && header.isVisible ()) header.redraw (); -} -void setFocusItem (TableItem item, boolean redrawOldFocus) { - if (item == focusItem) return; - TableItem oldFocusItem = focusItem; - focusItem = item; - if (redrawOldFocus && oldFocusItem != null) { - redrawItem (oldFocusItem.index, true); - } -} -public void setFont (Font value) { - checkWidget (); - Font oldFont = getFont (); - super.setFont (value); - Font font = getFont (); - if (font.equals (oldFont)) return; - - GC gc = new GC (this); - - /* recompute the receiver's cached font height and item height values */ - fontHeight = gc.getFontMetrics ().getHeight (); - setItemHeight (Math.max (fontHeight, imageHeight) + 2 * getCellPadding ()); - Point headerSize = header.getSize (); - int newHeaderHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding (); - if (headerSize.y != newHeaderHeight) { - header.setSize (headerSize.x, newHeaderHeight); - } - header.setFont (font); - - /* - * Notify all columns and items of the font change so that elements that - * use the receiver's font can recompute their cached string widths. - */ - for (int i = 0; i < columns.length; i++) { - columns [i].updateFont (gc); - } - for (int i = 0; i < itemsCount; i++) { - items [i].updateFont (gc); - } - - gc.dispose (); - - if (drawCount <= 0 && header.isVisible ()) header.redraw (); - - /* update scrollbars */ - if (columns.length == 0) updateHorizontalBar (); - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - int thumb = (clientArea.height - getHeaderHeight ()) / itemHeight; - vBar.setThumb (thumb); - vBar.setPageIncrement (thumb); - topIndex = vBar.getSelection (); - vBar.setVisible (thumb < vBar.getMaximum ()); - } - redraw (); -} -void setHeaderImageHeight (int value) { - headerImageHeight = value; - Point headerSize = header.getSize (); - int newHeaderHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding (); - if (headerSize.y != newHeaderHeight) { - header.setSize (headerSize.x, newHeaderHeight); - } -} -/** - * Marks the receiver's header as visible if the argument is <code>true</code>, - * and marks it invisible otherwise. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, marking - * it visible may not actually cause it to be displayed. - * </p> - * - * @param show the new visibility state - * - * @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 setHeaderVisible (boolean value) { - checkWidget (); - if (header.getVisible () == value) return; /* no change */ - headerHideToolTip (); - header.setVisible (value); - updateVerticalBar (); - redraw (); -} -void setImageHeight (int value) { - imageHeight = value; - setItemHeight (Math.max (fontHeight, imageHeight) + 2 * getCellPadding ()); -} -/** - * Sets the number of items contained in the receiver. - * - * @param count the number of items - * - * @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 setItemCount (int count) { - checkWidget (); - count = Math.max (0, count); - if (count == itemsCount) return; - int oldCount = itemsCount; - int redrawStart, redrawEnd; - - /* if the new item count is less than the current count then remove all excess items from the end */ - if (count < itemsCount) { - redrawStart = count; - redrawEnd = itemsCount - 1; - for (int i = count; i < itemsCount; i++) { - items [i].dispose (false); - } - - int newSelectedCount = 0; - for (int i = 0; i < selectedItems.length; i++) { - if (!selectedItems [i].isDisposed ()) newSelectedCount++; - } - if (newSelectedCount != selectedItems.length) { - /* one or more selected items have been disposed */ - TableItem[] newSelectedItems = new TableItem [newSelectedCount]; - int pos = 0; - for (int i = 0; i < selectedItems.length; i++) { - TableItem item = selectedItems [i]; - if (!item.isDisposed ()) { - newSelectedItems [pos++] = item; - } - } - selectedItems = newSelectedItems; - } - - if (anchorItem != null && anchorItem.isDisposed ()) anchorItem = null; - if (lastClickedItem != null && lastClickedItem.isDisposed ()) lastClickedItem = null; - if (focusItem != null && focusItem.isDisposed ()) { - TableItem newFocusItem = count > 0 ? items [count - 1] : null; - setFocusItem (newFocusItem, false); - } - itemsCount = count; - if (columns.length == 0) updateHorizontalBar (); - } else { - redrawStart = itemsCount; - redrawEnd = count - 1; - TableItem[] newItems = new TableItem [count]; - System.arraycopy (items, 0, newItems, 0, itemsCount); - items = newItems; - for (int i = itemsCount; i < count; i++) { - items [i] = new TableItem (this, SWT.NONE, i, false); - itemsCount++; - } - if (oldCount == 0) focusItem = items [0]; - } - - updateVerticalBar (); - /* - * If this is the focus control and the item count is going from 0->!0 or !0->0 then the - * receiver must be redrawn to ensure that its boundary focus ring is updated. - */ - if ((oldCount == 0 || itemsCount == 0) && isFocusControl ()) { - redraw (); - return; - } - redrawItems (redrawStart, redrawEnd, false); -} -boolean setItemHeight (int value) { - boolean update = !customHeightSet || itemHeight < value; - if (update) itemHeight = value; - return update; -} -/** - * Marks the receiver's lines as visible if the argument is <code>true</code>, - * and marks it invisible otherwise. Note that some platforms draw grid lines - * while others may draw alternating row colors. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, marking - * it visible may not actually cause it to be displayed. - * </p> - * - * @param show the new visibility state - * - * @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 setLinesVisible (boolean value) { - checkWidget (); - if (linesVisible == value) return; /* no change */ - linesVisible = value; - redraw (); -} -public void setMenu (Menu menu) { - super.setMenu (menu); - header.setMenu (menu); -} -public void setRedraw (boolean value) { - checkWidget(); - if (value) { - if (--drawCount == 0) { - if (items.length - itemsCount > 3) { - TableItem[] newItems = new TableItem [itemsCount]; - System.arraycopy (items, 0, newItems, 0, itemsCount); - items = newItems; - } - updateVerticalBar (); - updateHorizontalBar (); - } - } else { - drawCount++; - } - super.setRedraw (value); - header.setRedraw (value); -} -/** - * Sets the receiver's selection to the given item. - * The current selection is cleared before the new item is selected. - * <p> - * If the item is not in the receiver, then it is ignored. - * </p> - * - * @param item the item to select - * - * @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> - * - * @since 3.2 - */ -public void setSelection (TableItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - setSelection (new TableItem[] {item}, true); -} -/** - * 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. - * </p> - * - * @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 items 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 Table#deselectAll() - * @see Table#select(int[]) - * @see Table#setSelection(int[]) - */ -public void setSelection (TableItem[] items) { - checkWidget (); - if (items == null) error (SWT.ERROR_NULL_ARGUMENT); - setSelection (items, true); -} -void setSelection (TableItem[] items, boolean updateViewport) { - if (items.length == 0 || ((style & SWT.SINGLE) != 0 && items.length > 1)) { - deselectAll (); - return; - } - TableItem[] oldSelection = selectedItems; - - /* remove null and duplicate items */ - int index = 0; - selectedItems = new TableItem [items.length]; /* assume all valid items */ - for (int i = 0; i < items.length; i++) { - TableItem item = items [i]; - if (item != null && item.parent == this && !item.isSelected ()) { - selectedItems [index++] = item; - } - } - if (index != items.length) { - /* an invalid item was provided so resize the array accordingly */ - TableItem[] temp = new TableItem [index]; - System.arraycopy (selectedItems, 0, temp, 0, index); - selectedItems = temp; - } - if (selectedItems.length == 0) { /* no valid items */ - deselectAll (); - return; - } - - if (hasFocus () || (style & SWT.HIDE_SELECTION) == 0) { - for (int i = 0; i < oldSelection.length; i++) { - if (!oldSelection [i].isSelected ()) { - redrawItem (oldSelection [i].index, true); - } - } - for (int i = 0; i < selectedItems.length; i++) { - redrawItem (selectedItems [i].index, true); - } - } - if (updateViewport) { - showItem (selectedItems [0]); - setFocusItem (selectedItems [0], true); - } -} -/** - * Sets the column used by the sort indicator for the receiver. A null - * value will clear the sort indicator. The current sort column is cleared - * before the new column is set. - * - * @param column the column used by the sort indicator or <code>null</code> - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the column is 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.2 - */ -public void setSortColumn (TableColumn column) { - checkWidget (); - if (column != null && column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (column == sortColumn) return; - if (sortColumn != null && !sortColumn.isDisposed ()) { - sortColumn.setSortDirection (SWT.NONE); - } - sortColumn = column; - if (sortColumn != null) { - sortColumn.setSortDirection (sortDirection); - } -} -/** - * Sets the direction of the sort indicator for the receiver. The value - * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>. - * - * @param direction the direction of the sort indicator - * - * @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.2 - */ -public void setSortDirection (int direction) { - checkWidget (); - if (direction != SWT.UP && direction != SWT.DOWN && direction != SWT.NONE) return; - sortDirection = direction; - if (sortColumn == null || sortColumn.isDisposed ()) return; - sortColumn.setSortDirection (sortDirection); -} -/** - * Selects the item at the given zero-relative index in the receiver. - * The current selection is first cleared, then the new item is selected. - * - * @param index the index of the item to select - * - * @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 Table#deselectAll() - * @see Table#select(int) - */ -public void setSelection (int index) { - checkWidget (); - deselectAll (); - if (!(0 <= index && index < itemsCount)) return; - selectItem (items [index], false); - setFocusItem (items [index], true); - redrawItem (index, true); - showSelection (); -} -/** - * Selects the items in the range specified by the given zero-relative - * indices in the receiver. The range of indices is inclusive. - * The current selection is cleared before the new items are selected. - * <p> - * Indices that are out of range are ignored and no items will be selected - * if start is greater than end. - * If the receiver is single-select and there is more than one item in the - * given range, then all indices are ignored. - * </p> - * - * @param start the start index of the items to select - * @param end the end index of the items to select - * - * @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 Table#deselectAll() - * @see Table#select(int,int) - */ -public void setSelection (int start, int end) { - checkWidget (); - deselectAll (); - if (end < 0 || start > end || ((style & SWT.SINGLE) != 0 && start != end)) return; - if (itemsCount == 0 || start >= itemsCount) return; - start = Math.max (0, start); - end = Math.min (end, itemsCount - 1); - select (start, end); - setFocusItem (items [start], true); - showSelection (); -} -/** - * Selects the items at the given zero-relative indices in the receiver. - * The current selection is cleared before the new items are selected. - * <p> - * Indices that are out of range and duplicate indices are ignored. - * If the receiver is single-select and multiple indices are specified, - * then all indices are ignored. - * </p> - * - * @param indices the indices of the items to select - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the array of indices 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 Table#deselectAll() - * @see Table#select(int[]) - */ -public void setSelection (int [] indices) { - checkWidget (); - if (indices == null) error (SWT.ERROR_NULL_ARGUMENT); - deselectAll (); - int length = indices.length; - if (length == 0 || ((style & SWT.SINGLE) != 0 && length > 1)) return; - select (indices); - int focusIndex = -1; - for (int i = 0; i < indices.length && focusIndex == -1; i++) { - if (0 <= indices [i] && indices [i] < itemsCount) { - focusIndex = indices [i]; - } - } - if (focusIndex != -1) setFocusItem (items [focusIndex], true); - showSelection (); -} -/** - * Sets the zero-relative index of the item which is currently - * at the top of the receiver. This index can change when items - * are scrolled or new items are added and removed. - * - * @param index the index of the top item - * - * @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 setTopIndex (int index) { - checkWidget (); - if (!(0 <= index && index < itemsCount)) return; - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (itemsCount <= visibleItemCount) return; - index = Math.min (index, itemsCount - visibleItemCount); - if (index == topIndex) return; - - update (); - int change = topIndex - index; - topIndex = index; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - if (drawCount <= 0) { - GC gc = new GC (this); - gc.copyArea (0, 0, clientArea.width, clientArea.height, 0, change * itemHeight); - gc.dispose (); - } -} -/** - * Shows the column. If the column is already showing in the receiver, - * this method simply returns. Otherwise, the columns are scrolled until - * the column is visible. - * - * @param column the column to be shown - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the column is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the column 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 showColumn (TableColumn column) { - checkWidget (); - if (column == null) error (SWT.ERROR_NULL_ARGUMENT); - if (column.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT); - if (column.parent != this) return; - - int x = column.getX (); - int rightX = x + column.width; - if (0 <= x && rightX <= clientArea.width) return; /* column is fully visible */ - - headerHideToolTip (); - int absX = 0; /* the X of the column irrespective of the horizontal scroll */ - TableColumn[] orderedColumns = getOrderedColumns (); - for (int i = 0; i < column.getOrderIndex (); i++) { - absX += orderedColumns [i].width; - } - if (x < clientArea.x) { /* column is to left of viewport */ - horizontalOffset = absX; - } else { - horizontalOffset = absX + column.width - clientArea.width; - } - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) hBar.setSelection (horizontalOffset); - redraw (); - if (drawCount <= 0 && header.isVisible ()) header.redraw (); -} -/** - * Shows the item. If the item is already showing in the receiver, - * this method simply returns. Otherwise, the items are scrolled 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 Table#showSelection() - */ -public void showItem (TableItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (item.parent != this) return; - - int index = item.index; - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - /* nothing to do if item is already in viewport */ - if (topIndex <= index && index < topIndex + visibleItemCount) return; - - if (index <= topIndex) { - /* item is above current viewport, so show on top */ - setTopIndex (item.index); - } else { - /* item is below current viewport, so show on bottom */ - visibleItemCount = Math.max (visibleItemCount, 1); /* item to show should be top item */ - setTopIndex (Math.min (index - visibleItemCount + 1, itemsCount - 1)); - } -} -/** - * Shows the selection. If the selection is already showing in the receiver, - * this method simply returns. Otherwise, the items are scrolled until - * the selection is visible. - * - * @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 Table#showItem(TableItem) - */ -public void showSelection () { - checkWidget (); - if (selectedItems.length == 0) return; - showItem (selectedItems [0]); -} -void sortDescent (int [] items) { - /* Shell Sort from K&R, pg 108 */ - int length = items.length; - for (int gap = length / 2; gap > 0; gap /= 2) { - for (int i = gap; i < length; i++) { - for (int j = i - gap; j >= 0; j -= gap) { - if (items [j] <= items [j + gap]) { - int swap = items [j]; - items [j] = items [j + gap]; - items [j + gap] = swap; - } - } - } - } -} -void sortAscent (int [] items) { - /* Shell Sort from K&R, pg 108 */ - int length = items.length; - for (int gap = length / 2; gap > 0; gap /= 2) { - for (int i = gap; i < length; i++) { - for (int j = i - gap; j >= 0; j -= gap) { - if (items [j] >= items [j + gap]) { - int swap = items [j]; - items [j] = items [j + gap]; - items [j + gap] = swap; - } - } - } - } -} -void sortAscent (TableItem [] items) { - /* Shell Sort from K&R, pg 108 */ - int length = items.length; - for (int gap = length / 2; gap > 0; gap /= 2) { - for (int i = gap; i < length; i++) { - for (int j = i - gap; j >= 0; j -= gap) { - if (items [j].index >= items [j + gap].index) { - TableItem swap = items [j]; - items [j] = items [j + gap]; - items [j + gap] = swap; - } - } - } - } -} -void updateColumnWidth (TableColumn column, int width) { - headerHideToolTip (); - int oldWidth = column.width; - int columnX = column.getX (); - int x = columnX + oldWidth - 1; /* -1 ensures that grid line is included */ - - update (); - GC gc = new GC (this); - gc.copyArea (x, 0, clientArea.width - x, clientArea.height, columnX + width - 1, 0); /* dest x -1 offsets x's -1 above */ - if (width > oldWidth) { - /* column width grew */ - int change = width - oldWidth + 1; /* +1 offsets x's -1 above */ - /* -1/+1 below ensure that right bound of selection redraws correctly in column */ - redraw (x - 1, 0, change + 1, clientArea.height, false); - } else { - int change = oldWidth - width + 1; /* +1 offsets x's -1 above */ - redraw (clientArea.width - change, 0, change, clientArea.height, false); - } - /* the focus box must be repainted because its stipple may become shifted as a result of its new width */ - if (focusItem != null) redrawItem (focusItem.index, true); - - GC headerGC = new GC (header); - if (drawCount <= 0 && header.getVisible ()) { - Rectangle headerBounds = header.getClientArea (); - header.update (); - x -= 1; /* -1 ensures that full header column separator is included */ - headerGC.copyArea (x, 0, headerBounds.width - x, headerBounds.height, columnX + width - 2, 0); /* dest x -2 offsets x's -1s above */ - if (width > oldWidth) { - /* column width grew */ - int change = width - oldWidth + 2; /* +2 offsets x's -1s above */ - header.redraw (x, 0, change, headerBounds.height, false); - } else { - int change = oldWidth - width + 2; /* +2 offsets x's -1s above */ - header.redraw (headerBounds.width - change, 0, change, headerBounds.height, false); - } - } - - column.width = width; - - /* - * Notify column and all items of column width change so that display labels - * can be recomputed if needed. - */ - column.updateWidth (headerGC); - headerGC.dispose (); - for (int i = 0; i < itemsCount; i++) { - items [i].updateColumnWidth (column, gc); - } - gc.dispose (); - - int maximum = 0; - for (int i = 0; i < columns.length; i++) { - maximum += columns [i].width; - } - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setMaximum (Math.max (1, maximum)); /* setting a value of 0 here is ignored */ - if (hBar.getThumb () != clientArea.width) { - hBar.setThumb (clientArea.width); - hBar.setPageIncrement (clientArea.width); - } - int oldHorizontalOffset = horizontalOffset; /* hBar.setVisible() can modify horizontalOffset */ - hBar.setVisible (clientArea.width < maximum); - int selection = hBar.getSelection (); - if (selection != oldHorizontalOffset) { - horizontalOffset = selection; - redraw (); - if (drawCount <= 0 && header.getVisible ()) header.redraw (); - } - } - - column.sendEvent (SWT.Resize); - TableColumn[] orderedColumns = getOrderedColumns (); - for (int i = column.getOrderIndex () + 1; i < orderedColumns.length; i++) { - if (!orderedColumns [i].isDisposed ()) { - orderedColumns [i].sendEvent (SWT.Move); - } - } - - if (itemsCount == 0) redraw (); /* ensure that static focus rectangle updates properly */ -} -/* - * This is a naive implementation that computes the value from scratch. - */ -void updateHorizontalBar () { - if (drawCount > 0) return; - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - - int maxX = 0; - if (columns.length > 0) { - for (int i = 0; i < columns.length; i++) { - maxX += columns [i].width; - } - } else { - for (int i = 0; i < itemsCount; i++) { - Rectangle itemBounds = items [i].getCellBounds (0); - maxX = Math.max (maxX, itemBounds.x + itemBounds.width + horizontalOffset); - } - } - - int clientWidth = clientArea.width; - if (maxX != hBar.getMaximum ()) { - hBar.setMaximum (Math.max (1, maxX)); /* setting a value of 0 here is ignored */ - } - int thumb = Math.min (clientWidth, maxX); - if (thumb != hBar.getThumb ()) { - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - } - hBar.setVisible (clientWidth < maxX); - - /* reclaim any space now left on the right */ - if (maxX < horizontalOffset + thumb) { - horizontalOffset = maxX - thumb; - hBar.setSelection (horizontalOffset); - redraw (); - } else { - int selection = hBar.getSelection (); - if (selection != horizontalOffset) { - horizontalOffset = selection; - redraw (); - } - } -} -/* - * Update the horizontal bar, if needed, in response to an item change (eg.- created, - * disposed, expanded, etc.). newRightX is the new rightmost X value of the item, - * and rightXchange is the change that led to the item's rightmost X value becoming - * newRightX (so oldRightX + rightXchange = newRightX) - */ -void updateHorizontalBar (int newRightX, int rightXchange) { - if (drawCount > 0) return; - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - - newRightX += horizontalOffset; - int barMaximum = hBar.getMaximum (); - if (newRightX > barMaximum) { /* item has extended beyond previous maximum */ - hBar.setMaximum (newRightX); - int clientAreaWidth = clientArea.width; - int thumb = Math.min (newRightX, clientAreaWidth); - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - hBar.setVisible (clientAreaWidth <= newRightX); - return; - } - - int previousRightX = newRightX - rightXchange; - if (previousRightX != barMaximum) { - /* this was not the rightmost item, so just check for client width change */ - int clientAreaWidth = clientArea.width; - int thumb = Math.min (barMaximum, clientAreaWidth); - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - hBar.setVisible (clientAreaWidth <= barMaximum); - return; - } - updateHorizontalBar (); /* must search for the new rightmost item */ -} -void updateVerticalBar () { - if (drawCount > 0) return; - ScrollBar vBar = getVerticalBar (); - if (vBar == null) return; - - int pageSize = (clientArea.height - getHeaderHeight ()) / itemHeight; - int maximum = Math.max (1, itemsCount); /* setting a value of 0 here is ignored */ - if (maximum != vBar.getMaximum ()) { - vBar.setMaximum (maximum); - } - int thumb = Math.min (pageSize, maximum); - if (thumb != vBar.getThumb ()) { - vBar.setThumb (thumb); - vBar.setPageIncrement (thumb); - } - vBar.setVisible (pageSize < maximum); - - /* reclaim any space now left on the bottom */ - if (maximum < topIndex + thumb) { - topIndex = maximum - thumb; - vBar.setSelection (topIndex); - redraw (); - } else { - int selection = vBar.getSelection (); - if (selection != topIndex) { - topIndex = selection; - redraw (); - } - } -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TableColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TableColumn.java deleted file mode 100644 index 7ef48a0fdd..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TableColumn.java +++ /dev/null @@ -1,762 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.widgets; - -import org.eclipse.swt.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; - -/** - * Instances of this class represent a column in a table widget. - * <p><dl> - * <dt><b>Styles:</b></dt> - * <dd>LEFT, RIGHT, CENTER</dd> - * <dt><b>Events:</b></dt> - * <dd> Move, Resize, Selection</dd> - * </dl> - * </p><p> - * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified. - * </p><p> - * IMPORTANT: This class is <em>not</em> intended to be subclassed. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem, TableColumn snippets</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @noextend This class is not intended to be subclassed by clients. - */ -public class TableColumn extends Item { - Table parent; - String displayText = ""; - int width; - boolean moveable, resizable = true; - int sort = SWT.NONE; - String toolTipText; - -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Table</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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TableColumn (Table parent, int style) { - this (parent, style, checkNull (parent).columns.length); -} -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Table</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> - * <p> - * Note that due to a restriction on some platforms, the first column - * is always left aligned. - * </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 zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> - * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TableColumn (Table parent, int style, int index) { - super (parent, checkStyle (style), index); - if (!(0 <= index && index <= parent.columns.length)) error (SWT.ERROR_INVALID_RANGE); - this.parent = parent; - parent.createItem (this, index); -} -/** - * Adds the listener to the collection of listeners who will - * be notified when the control is moved or resized, by sending - * it one of the messages defined in the <code>ControlListener</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 ControlListener - * @see #removeControlListener - */ -public void addControlListener (ControlListener listener) { - checkWidget (); - if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Resize, typedListener); - addListener (SWT.Move, typedListener); -} -/** - * Adds the listener to the collection of listeners who will - * be notified when the control is selected by the user, by sending - * it one of the messages defined in the <code>SelectionListener</code> - * interface. - * <p> - * <code>widgetSelected</code> is called when the column header is selected. - * <code>widgetDefaultSelected</code> is not called. - * </p> - * - * @param listener the listener which should be notified when the control is selected by the user - * - * @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) error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Selection, typedListener); - addListener (SWT.DefaultSelection, typedListener); -} -static Table checkNull (Table table) { - if (table == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - return table; -} -static int checkStyle (int style) { - return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0); -} -protected void checkSubclass () { - if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); -} -void computeDisplayText (GC gc) { - int availableWidth = width - 2 * parent.getHeaderPadding (); - if (image != null) { - availableWidth -= image.getBounds ().width; - availableWidth -= Table.MARGIN_IMAGE; - } - if (sort != SWT.NONE) { - availableWidth -= parent.arrowBounds.width; - availableWidth -= Table.MARGIN_IMAGE; - } - String text = this.text; - int textWidth = gc.textExtent (text, SWT.DRAW_MNEMONIC).x; - if (textWidth <= availableWidth) { - displayText = text; - return; - } - - /* Ellipsis will be needed, so subtract their width from the available text width */ - int ellipsisWidth = gc.stringExtent (Table.ELLIPSIS).x; - availableWidth -= ellipsisWidth; - if (availableWidth <= 0) { - displayText = Table.ELLIPSIS; - return; - } - - /* Make initial guess. */ - int index = Math.min (availableWidth / gc.getFontMetrics ().getAverageCharWidth (), text.length ()); - textWidth = gc.textExtent (text.substring (0, index), SWT.DRAW_MNEMONIC).x; - - /* Initial guess is correct. */ - if (availableWidth == textWidth) { - displayText = text.substring (0, index) + Table.ELLIPSIS; - return; - } - - /* Initial guess is too high, so reduce until fit is found. */ - if (availableWidth < textWidth) { - do { - index--; - if (index < 0) { - displayText = Table.ELLIPSIS; - return; - } - text = text.substring (0, index); - textWidth = gc.textExtent (text, SWT.DRAW_MNEMONIC).x; - } while (availableWidth < textWidth); - displayText = text + Table.ELLIPSIS; - return; - } - - /* Initial guess is too low, so increase until overrun is found. */ - while (textWidth < availableWidth) { - index++; - textWidth = gc.textExtent (text.substring (0, index), SWT.DRAW_MNEMONIC).x; - } - displayText = text.substring (0, index - 1) + Table.ELLIPSIS; -} -public void dispose () { - if (isDisposed ()) return; - Rectangle parentBounds = parent.clientArea; - int x = getX (); - int index = getIndex (); - int orderIndex = getOrderIndex (); - int nextColumnAlignment = parent.columns.length > 1 ? parent.columns [1].getAlignment () : SWT.LEFT; - Table parent = this.parent; - dispose (true); - - int width = parentBounds.width - x; - parent.redraw (x, 0, width, parentBounds.height, false); - /* - * If column 0 was disposed then the new column 0 must be redrawn if it appears to the - * left of the disposed column in the column order AND one the following are true: - * - the parent has style CHECK, since these will now appear in the new column 0 - * - the new column 0 had non-left alignment before the dispose, since the parent will have - * changed this to LEFT in the call to dispose(true) - */ - if (index == 0 && ((parent.style & SWT.CHECK) != 0 || nextColumnAlignment != SWT.LEFT)) { - if (parent.columns.length > 0) { - TableColumn newColumn0 = parent.columns [0]; - if (newColumn0.getOrderIndex () < orderIndex) { - int newColumn0x = newColumn0.getX (); - parent.redraw (newColumn0x, 0, newColumn0.width, parentBounds.height, false); - /* if the alignment changed then the header text must be repainted with its new alignment */ - if (nextColumnAlignment != SWT.LEFT && parent.getHeaderVisible () && parent.drawCount <= 0) { - parent.header.redraw (newColumn0x, 0, newColumn0.width, parent.header.getClientArea ().height, false); - } - } - } - } - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - parent.header.redraw (x, 0, width, parent.getHeaderHeight (), false); - } -} -void dispose (boolean notifyParent) { - super.dispose (); /* super is intentional here */ - if (notifyParent) parent.destroyItem (this); - parent = null; -} -/** - * Returns a value which describes the position of the - * text or image in the receiver. The value will be one of - * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>. - * - * @return the alignment - * - * @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 int getAlignment () { - checkWidget (); - if ((style & SWT.CENTER) != 0) return SWT.CENTER; - if ((style & SWT.RIGHT) != 0) return SWT.RIGHT; - return SWT.LEFT; -} -/* - * Returns the width of the header's content - * (image + text + sort arrow + internal margins) - */ -int getContentWidth (GC gc, boolean useDisplayText) { - int contentWidth = 0; - String text = useDisplayText ? displayText : this.text; - if (text.length () > 0) { - contentWidth += gc.textExtent (text, SWT.DRAW_MNEMONIC).x; - } - if (image != null) { - contentWidth += image.getBounds ().width; - if (text.length () > 0) contentWidth += Table.MARGIN_IMAGE; - } - if (sort != SWT.NONE) { - contentWidth += parent.arrowBounds.width; - if (text.length () > 0 || image != null) { - contentWidth += Table.MARGIN_IMAGE; - } - } - return contentWidth; -} -int getIndex () { - TableColumn[] columns = parent.columns; - for (int i = 0; i < columns.length; i++) { - if (columns [i] == this) return i; - } - return -1; -} -/** - * Gets the moveable attribute. A column that is - * not moveable cannot be reordered by the user - * by dragging the header but may be reordered - * by the programmer. - * - * @return the moveable attribute - * - * @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 Table#getColumnOrder() - * @see Table#setColumnOrder(int[]) - * @see TableColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.1 - */ -public boolean getMoveable () { - checkWidget (); - return moveable; -} -int getOrderIndex () { - TableColumn[] orderedColumns = parent.orderedColumns; - if (orderedColumns == null) return getIndex (); - for (int i = 0; i < orderedColumns.length; i++) { - if (orderedColumns [i] == this) return i; - } - return -1; -} -/** - * Returns the receiver's parent, which must be a <code>Table</code>. - * - * @return the receiver's parent - * - * @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 Table getParent () { - checkWidget (); - return parent; -} -int getPreferredWidth () { - if (!parent.getHeaderVisible ()) return 0; - GC gc = new GC (parent); - int result = getContentWidth (gc, false); - gc.dispose (); - return result + 2 * parent.getHeaderPadding (); -} -/** - * Gets the resizable attribute. A column that is - * not resizable cannot be dragged by the user but - * may be resized by the programmer. - * - * @return the resizable attribute - * - * @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 getResizable () { - checkWidget (); - return resizable; -} -/** - * Returns the receiver's tool tip text, or null if it has - * not been set. - * - * @return the receiver's tool tip text - * - * @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.2 - */ -public String getToolTipText () { - checkWidget (); - return toolTipText; -} -/** - * Gets the width of the receiver. - * - * @return the width - * - * @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 int getWidth () { - checkWidget (); - return width; -} -int getX () { - TableColumn[] orderedColumns = parent.getOrderedColumns (); - int index = getOrderIndex (); - int result = -parent.horizontalOffset; - for (int i = 0; i < index; i++) { - result += orderedColumns [i].width; - } - return result; -} -/** - * Causes the receiver to be resized to its preferred size. - * For a composite, this involves computing the preferred size - * from its layout, if there is one. - * - * @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 pack () { - checkWidget (); - TableItem[] items = parent.items; - int index = getIndex (); - int newWidth = getPreferredWidth (); - for (int i = 0; i < parent.itemsCount; i++) { - int width = items [i].getPreferredWidth (index); - /* ensure that receiver and parent were not disposed in a callback */ - if (parent.isDisposed () || isDisposed ()) return; - if (!items [i].isDisposed ()) { - newWidth = Math.max (newWidth, width); - } - } - if (newWidth != width) parent.updateColumnWidth (this, newWidth); -} -void paint (GC gc) { - int padding = parent.getHeaderPadding (); - - int x = getX (); - int startX = x + padding; - if ((style & SWT.LEFT) == 0) { - int contentWidth = getContentWidth (gc, true); - if ((style & SWT.RIGHT) != 0) { - startX = Math.max (startX, x + width - padding - contentWidth); - } else { /* SWT.CENTER */ - startX = Math.max (startX, x + (width - contentWidth) / 2); - } - } - int headerHeight = parent.getHeaderHeight (); - - /* restrict the clipping region to the header cell */ - gc.setClipping ( - x + padding, - padding, - width - 2 * padding, - headerHeight - 2 * padding); - - if (image != null) { - Rectangle imageBounds = image.getBounds (); - int drawHeight = Math.min (imageBounds.height, headerHeight - 2 * padding); - gc.drawImage ( - image, - 0, 0, - imageBounds.width, imageBounds.height, - startX, (headerHeight - drawHeight) / 2, - imageBounds.width, drawHeight); - startX += imageBounds.width + Table.MARGIN_IMAGE; - } - if (displayText.length () > 0) { - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - int fontHeight = parent.fontHeight; - gc.drawText (displayText, startX, (headerHeight - fontHeight) / 2, SWT.DRAW_MNEMONIC); - startX += gc.textExtent (displayText, SWT.DRAW_MNEMONIC).x + Table.MARGIN_IMAGE; - } - if (sort != SWT.NONE) { - Image image = sort == SWT.DOWN ? parent.getArrowDownImage () : parent.getArrowUpImage (); - int y = (headerHeight - parent.arrowBounds.height) / 2; - gc.drawImage (image, startX, y); - } -} -/** - * Removes the listener from the collection of listeners who will - * be notified when the control is moved or resized. - * - * @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 ControlListener - * @see #addControlListener - */ -public void removeControlListener (ControlListener listener) { - checkWidget (); - if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); - if (eventTable == null) return; - eventTable.unhook (SWT.Move, listener); - eventTable.unhook (SWT.Resize, listener); -} -/** - * Removes the listener from the collection of listeners who will - * be notified when the control is selected by the user. - * - * @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) error (SWT.ERROR_NULL_ARGUMENT); - removeListener (SWT.Selection, listener); - removeListener (SWT.DefaultSelection, listener); -} -/** - * Controls how text and images will be displayed in the receiver. - * The argument should be one of <code>LEFT</code>, <code>RIGHT</code> - * or <code>CENTER</code>. - * <p> - * Note that due to a restriction on some platforms, the first column - * is always left aligned. - * </p> - * @param alignment the new alignment - * - * @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 setAlignment (int alignment) { - checkWidget (); - if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return; - int index = getIndex (); - if (index == -1 || index == 0) return; /* column 0 can only have left-alignment */ - alignment = checkBits (alignment, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0); - if ((style & alignment) != 0) return; /* same value */ - style &= ~(SWT.LEFT | SWT.CENTER | SWT.RIGHT); - style |= alignment; - int x = getX (); - parent.redraw (x, 0, width, parent.clientArea.height, false); - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (x, 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -public void setImage (Image value) { - checkWidget (); - if (value == image) return; - if (value != null && value.equals (image)) return; /* same value */ - super.setImage (value); - - /* An image width change may affect the space available for the column's displayText. */ - GC gc = new GC (parent); - computeDisplayText (gc); - gc.dispose (); - - /* - * If this is the first image being put into the header then the header - * height may be adjusted, in which case a full redraw is needed. - */ - if (parent.headerImageHeight == 0) { - int oldHeaderHeight = parent.getHeaderHeight (); - parent.setHeaderImageHeight (value.getBounds ().height); - if (oldHeaderHeight != parent.getHeaderHeight ()) { - /* parent header height changed */ - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - parent.header.redraw (); - } - parent.redraw (); - return; - } - } - - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (getX (), 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -/** - * Sets the moveable attribute. A column that is - * moveable can be reordered by the user by dragging - * the header. A column that is not moveable cannot be - * dragged by the user but may be reordered - * by the programmer. - * - * @param moveable the moveable attribute - * - * @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 Table#setColumnOrder(int[]) - * @see Table#getColumnOrder() - * @see TableColumn#getMoveable() - * @see SWT#Move - * - * @since 3.1 - */ -public void setMoveable (boolean moveable) { - checkWidget (); - this.moveable = moveable; -} -/** - * Sets the resizable attribute. A column that is - * resizable can be resized by the user dragging the - * edge of the header. A column that is not resizable - * cannot be dragged by the user but may be resized - * by the programmer. - * - * @param resizable the resize attribute - * - * @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 setResizable (boolean value) { - checkWidget (); - resizable = value; -} -void setSortDirection (int value) { - if (value == sort) return; - boolean widthChange = value == SWT.NONE || sort == SWT.NONE; - sort = value; - if (widthChange) { - /* - * adding/removing the sort arrow decreases/increases the width that is - * available for the column's header text, so recompute the display text - */ - GC gc = new GC (parent); - computeDisplayText (gc); - gc.dispose (); - } - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (getX (), 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -public void setText (String value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - if (value.equals (text)) return; /* same value */ - super.setText (value); - GC gc = new GC (parent); - computeDisplayText (gc); - gc.dispose (); - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (getX (), 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -/** - * Sets the receiver's tool tip text to the argument, which - * may be null indicating that the default tool tip for the - * control will be shown. For a control that has a default - * tool tip, such as the Tree control on Windows, setting - * the tool tip text to an empty string replaces the default, - * causing no tool tip text to be shown. - * <p> - * The mnemonic indicator (character '&') is not displayed in a tool tip. - * To display a single '&' in the tool tip, the character '&' can be - * escaped by doubling it in the string. - * </p> - * - * @param string the new tool tip text (or null) - * - * @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.2 - */ -public void setToolTipText (String string) { - checkWidget (); - if (toolTipText == string) return; - if (toolTipText != null && toolTipText.equals (string)) return; - toolTipText = string; - if (parent.toolTipShell == null) return; /* tooltip not currently showing */ - if (((Integer) parent.toolTipShell.getData ()).intValue () != getIndex ()) return; /* tooltip showing for different column */ - parent.headerUpdateToolTip (getX () + (width / 2)); /* update the tooltip text */ -} -/** - * Sets the width of the receiver. - * - * @param width the new width - * - * @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 setWidth (int value) { - checkWidget (); - if (value < 0) return; - if (width == value) return; /* same value */ - parent.updateColumnWidth (this, value); -} -void updateFont (GC gc) { - computeDisplayText (gc); -} -/* - * Perform any internal changes necessary to reflect a changed width. - */ -void updateWidth (GC gc) { - String oldDisplayText = displayText; - computeDisplayText (gc); - /* the header must be damaged if the display text has changed or if the alignment is not LEFT */ - if (parent.getHeaderVisible ()) { - if ((style & SWT.LEFT) == 0 || !oldDisplayText.equals (displayText)) { - int padding = parent.getHeaderPadding (); - parent.header.redraw (getX () + padding, 0, width - padding, parent.getHeaderHeight (), false); - } - } -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TableItem.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TableItem.java deleted file mode 100644 index e4c3476995..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TableItem.java +++ /dev/null @@ -1,2032 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.widgets; - -import org.eclipse.swt.*; -import org.eclipse.swt.graphics.*; - -/** - * Instances of this class represent a selectable user interface object - * that represents an item in a table. - * <dl> - * <dt><b>Styles:</b></dt> - * <dd>(none)</dd> - * <dt><b>Events:</b></dt> - * <dd>(none)</dd> - * </dl> - * <p> - * IMPORTANT: This class is <em>not</em> intended to be subclassed. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem, TableColumn snippets</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @noextend This class is not intended to be subclassed by clients. - */ -public class TableItem extends Item { - Table parent; - int index = -1; - boolean checked, grayed, cached; - - String[] texts; - int[] textWidths = new int [1]; /* cached string measurements */ - int customWidth = -1; /* width specified by Measure callback */ - int fontHeight; /* cached item font height */ - int[] fontHeights; - int imageIndent; - Image[] images; - Color foreground, background; - String[] displayTexts; - Color[] cellForegrounds, cellBackgrounds; - Font font; - Font[] cellFonts; - - static final int MARGIN_TEXT = 3; /* the left and right margins within the text's space */ - -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Table</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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TableItem (Table parent, int style) { - this (parent, style, checkNull (parent).itemsCount); -} -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Table</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 zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> - * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TableItem (Table parent, int style, int index) { - this (parent, style, index, true); -} -TableItem (Table parent, int style, int index, boolean notifyParent) { - super (parent, style); - int validItemIndex = parent.itemsCount; - if (!(0 <= index && index <= validItemIndex)) error (SWT.ERROR_INVALID_RANGE); - this.parent = parent; - this.index = index; - int columnCount = parent.columns.length; - if (columnCount > 0) { - displayTexts = new String [columnCount]; - if (columnCount > 1) { - texts = new String [columnCount]; - textWidths = new int [columnCount]; - images = new Image [columnCount]; - } - } - if (notifyParent) parent.createItem (this); -} -/* - * Updates internal structures in the receiver and its child items to handle the creation of a new column. - */ -void addColumn (TableColumn column) { - int index = column.getIndex (); - int columnCount = parent.columns.length; - - if (columnCount > 1) { - if (columnCount == 2) { - texts = new String [2]; - } else { - String[] newTexts = new String [columnCount]; - System.arraycopy (texts, 0, newTexts, 0, index); - System.arraycopy (texts, index, newTexts, index + 1, columnCount - index - 1); - texts = newTexts; - } - if (index == 0) { - texts [1] = text; - text = ""; //$NON-NLS-1$ - } - - if (columnCount == 2) { - images = new Image [2]; - } else { - Image[] newImages = new Image [columnCount]; - System.arraycopy (images, 0, newImages, 0, index); - System.arraycopy (images, index, newImages, index + 1, columnCount - index - 1); - images = newImages; - } - if (index == 0) { - images [1] = image; - image = null; - } - - int[] newTextWidths = new int [columnCount]; - System.arraycopy (textWidths, 0, newTextWidths, 0, index); - System.arraycopy (textWidths, index, newTextWidths, index + 1, columnCount - index - 1); - textWidths = newTextWidths; - } else { - customWidth = -1; /* columnCount == 1 */ - } - - /* - * The length of displayTexts always matches the parent's column count, unless this - * count is zero, in which case displayTexts is null. - */ - String[] newDisplayTexts = new String [columnCount]; - if (columnCount > 1) { - System.arraycopy (displayTexts, 0, newDisplayTexts, 0, index); - System.arraycopy (displayTexts, index, newDisplayTexts, index + 1, columnCount - index - 1); - } - displayTexts = newDisplayTexts; - - if (cellBackgrounds != null) { - Color[] newCellBackgrounds = new Color [columnCount]; - System.arraycopy (cellBackgrounds, 0, newCellBackgrounds, 0, index); - System.arraycopy (cellBackgrounds, index, newCellBackgrounds, index + 1, columnCount - index - 1); - cellBackgrounds = newCellBackgrounds; - } - if (cellForegrounds != null) { - Color[] newCellForegrounds = new Color [columnCount]; - System.arraycopy (cellForegrounds, 0, newCellForegrounds, 0, index); - System.arraycopy (cellForegrounds, index, newCellForegrounds, index + 1, columnCount - index - 1); - cellForegrounds = newCellForegrounds; - } - if (cellFonts != null) { - Font[] newCellFonts = new Font [columnCount]; - System.arraycopy (cellFonts, 0, newCellFonts, 0, index); - System.arraycopy (cellFonts, index, newCellFonts, index + 1, columnCount - index - 1); - cellFonts = newCellFonts; - - int[] newFontHeights = new int [columnCount]; - System.arraycopy (fontHeights, 0, newFontHeights, 0, index); - System.arraycopy (fontHeights, index, newFontHeights, index + 1, columnCount - index - 1); - fontHeights = newFontHeights; - } - - if (index == 0 && columnCount > 1) { - /* - * The new second column may have more width available to it than it did when it was - * the first column if checkboxes are being shown, so recompute its displayText if needed. - */ - if ((parent.style & SWT.CHECK) != 0) { - GC gc = new GC (parent); - gc.setFont (getFont (1, false)); - computeDisplayText (1, gc); - gc.dispose (); - } - } -} -static Table checkNull (Table table) { - if (table == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - return table; -} -protected void checkSubclass () { - if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); -} -void clear () { - checked = grayed = false; - texts = null; - textWidths = new int [1]; - fontHeight = 0; - fontHeights = null; - images = null; - foreground = background = null; - displayTexts = null; - cellForegrounds = cellBackgrounds = null; - font = null; - cellFonts = null; - cached = false; - text = ""; - image = null; - - int columnCount = parent.columns.length; - if (columnCount > 0) { - displayTexts = new String [columnCount]; - if (columnCount > 1) { - texts = new String [columnCount]; - textWidths = new int [columnCount]; - images = new Image [columnCount]; - } - } -} -void computeDisplayText (int columnIndex, GC gc) { - if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return; /* nothing to do */ - - int columnCount = parent.columns.length; - if (columnCount == 0) { - String text = getText (0, false); - textWidths [columnIndex] = gc.stringExtent (text).x; - return; - } - - TableColumn column = parent.columns [columnIndex]; - int availableWidth = column.width - 2 * parent.getCellPadding () - 2 * MARGIN_TEXT; - if (columnIndex == 0) { - availableWidth -= parent.col0ImageWidth; - if (parent.col0ImageWidth > 0) availableWidth -= Table.MARGIN_IMAGE; - if ((parent.style & SWT.CHECK) != 0) { - availableWidth -= parent.checkboxBounds.width; - availableWidth -= Table.MARGIN_IMAGE; - } - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - availableWidth -= image.getBounds ().width; - availableWidth -= Table.MARGIN_IMAGE; - } - } - - String text = getText (columnIndex, false); - int textWidth = gc.stringExtent (text).x; - if (textWidth <= availableWidth) { - displayTexts [columnIndex] = text; - textWidths [columnIndex] = textWidth; - return; - } - - /* Ellipsis will be needed, so subtract their width from the available text width */ - int ellipsisWidth = gc.stringExtent (Table.ELLIPSIS).x; - availableWidth -= ellipsisWidth; - if (availableWidth <= 0) { - displayTexts [columnIndex] = Table.ELLIPSIS; - textWidths [columnIndex] = ellipsisWidth; - return; - } - - /* Make initial guess. */ - int index = Math.min (availableWidth / gc.getFontMetrics ().getAverageCharWidth (), text.length ()); - textWidth = gc.stringExtent (text.substring (0, index)).x; - - /* Initial guess is correct. */ - if (availableWidth == textWidth) { - displayTexts [columnIndex] = text.substring (0, index) + Table.ELLIPSIS; - textWidths [columnIndex] = textWidth + ellipsisWidth; - return; - } - - /* Initial guess is too high, so reduce until fit is found. */ - if (availableWidth < textWidth) { - do { - index--; - if (index < 0) { - displayTexts [columnIndex] = Table.ELLIPSIS; - textWidths [columnIndex] = ellipsisWidth; - return; - } - text = text.substring (0, index); - textWidth = gc.stringExtent (text).x; - } while (availableWidth < textWidth); - displayTexts [columnIndex] = text + Table.ELLIPSIS; - textWidths [columnIndex] = textWidth + ellipsisWidth; - return; - } - - /* Initial guess is too low, so increase until overrun is found. */ - int previousWidth = 0; - while (textWidth < availableWidth) { - index++; - previousWidth = textWidth; - textWidth = gc.stringExtent (text.substring (0, index)).x; - } - displayTexts [columnIndex] = text.substring (0, index - 1) + Table.ELLIPSIS; - textWidths [columnIndex] = previousWidth + ellipsisWidth; -} -void computeDisplayTexts (GC gc) { - if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return; /* nothing to do */ - - int columnCount = parent.columns.length; - if (columnCount == 0) return; - - for (int i = 0; i < columnCount; i++) { - gc.setFont (getFont (i, false)); - computeDisplayText (i, gc); - } -} -/* - * Computes the cached text widths. - */ -void computeTextWidths (GC gc) { - if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return; /* nothing to do */ - - int validColumnCount = Math.max (1, parent.columns.length); - textWidths = new int [validColumnCount]; - for (int i = 0; i < textWidths.length; i++) { - String value = getDisplayText (i); - if (value != null) { - gc.setFont (getFont (i, false)); - textWidths [i] = gc.stringExtent (value).x; - } - } -} -public void dispose () { - if (isDisposed ()) return; - Table parent = this.parent; - int startIndex = index; - int endIndex = parent.itemsCount - 1; - dispose (true); - parent.redrawItems (startIndex, endIndex, false); -} -void dispose (boolean notifyParent) { - if (isDisposed ()) return; - if (notifyParent) parent.destroyItem (this); - super.dispose (); /* super is intentional here */ - background = foreground = null; - cellBackgrounds = cellForegrounds = null; - font = null; - cellFonts = null; - images = null; - texts = displayTexts = null; - textWidths = fontHeights = null; - parent = null; -} -/** - * 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 (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (background != null) return background; - return parent.getBackground (); -} -/** - * Returns the background color at the given column index in the receiver. - * - * @param index the column index - * @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 3.0 - */ -public Color getBackground (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getBackground (); - if (cellBackgrounds == null || cellBackgrounds [columnIndex] == null) return getBackground (); - return cellBackgrounds [columnIndex]; -} -/** - * 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> - * - * @since 3.2 - */ -public Rectangle getBounds () { - checkWidget (); - return getBounds (true); -} -Rectangle getBounds (boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int x = getTextX (0); - int width = textWidths [0] + 2 * MARGIN_TEXT; - if (parent.columns.length > 0) { - TableColumn column = parent.columns [0]; - int right = column.getX () + column.width; - if (x + width > right) { - width = Math.max (0, right - x); - } - } - return new Rectangle (x, parent.getItemY (this), width, parent.itemHeight); -} -/** - * Returns a rectangle describing the receiver's size and location - * relative to its parent at a column in the table. - * - * @param index the index that specifies the column - * @return the receiver's bounding column 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 columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - TableColumn[] columns = parent.columns; - int columnCount = columns.length; - int validColumnCount = Math.max (1, columnCount); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) { - return new Rectangle (0, 0, 0, 0); - } - /* - * If there are no columns then this is the bounds of the receiver's content. - */ - if (columnCount == 0) { - int width = getContentWidth (0); - return new Rectangle ( - getContentX (0), - parent.getItemY (this), - width, - parent.itemHeight - 1); - } - - TableColumn column = columns [columnIndex]; - if (columnIndex == 0) { - /* - * For column 0 this is bounds from the beginning of the content to the - * end of the column. - */ - int x = getContentX (0); - int offset = x - column.getX (); - int width = Math.max (0, column.width - offset - 1); /* max is for columns with small widths */ - return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1); - } - /* - * For columns > 0 this is the bounds of the table cell. - */ - return new Rectangle (column.getX (), parent.getItemY (this) + 1, column.width, parent.itemHeight - 1); -} -/* - * Returns the full bounds of a cell in a table, regardless of its content. - */ -Rectangle getCellBounds (int columnIndex) { - int y = parent.getItemY (this); - if (parent.columns.length == 0) { - int width; - if (customWidth != -1) { - width = getContentX (0) + customWidth + parent.horizontalOffset; - } else { - int textPaintWidth = textWidths [0] + 2 * MARGIN_TEXT; - width = getTextX (0) + textPaintWidth + parent.horizontalOffset; - } - return new Rectangle (-parent.horizontalOffset, y, width, parent.itemHeight); - } - TableColumn column = parent.columns [columnIndex]; - return new Rectangle (column.getX (), y, column.width, parent.itemHeight); -} -/* - * Returns the bounds of the receiver's checkbox, or null if the parent's style does not - * include SWT.CHECK. - */ -Rectangle getCheckboxBounds () { - if ((parent.getStyle () & SWT.CHECK) == 0) return null; - Rectangle result = parent.checkboxBounds; - if (parent.columns.length == 0) { - result.x = parent.getCellPadding () - parent.horizontalOffset; - } else { - result.x = parent.columns [0].getX () + parent.getCellPadding (); - } - result.y = parent.getItemY (this) + (parent.itemHeight - result.height) / 2; - return result; -} -/** - * Returns <code>true</code> if the receiver is checked, - * and false otherwise. When the parent does not have - * the <code>CHECK</code> 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 (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return checked; -} -int getContentWidth (int columnIndex) { - int width = textWidths [columnIndex] + 2 * MARGIN_TEXT; - if (columnIndex == 0) { - width += parent.col0ImageWidth; - if (parent.col0ImageWidth > 0) width += Table.MARGIN_IMAGE; - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - width += image.getBounds ().width + Table.MARGIN_IMAGE; - } - } - return width; -} -/* - * Returns the x value where the receiver's content (ie.- its image or text) begins - * for the specified column. - */ -int getContentX (int columnIndex) { - int minX = parent.getCellPadding (); - if (columnIndex == 0) { - Rectangle checkboxBounds = getCheckboxBounds (); - if (checkboxBounds != null) { - minX += checkboxBounds.width + Table.MARGIN_IMAGE; - } - } - - if (parent.columns.length == 0) return minX - parent.horizontalOffset; /* free first column */ - - TableColumn column = parent.columns [columnIndex]; - int columnX = column.getX (); - if ((column.style & SWT.LEFT) != 0) return columnX + minX; - - /* column is not left-aligned */ - int contentWidth = getContentWidth (columnIndex); - int contentX = 0; - if ((column.style & SWT.RIGHT) != 0) { - contentX = column.width - parent.getCellPadding () - contentWidth; - } else { /* SWT.CENTER */ - contentX = (column.width - contentWidth) / 2; - } - return Math.max (columnX + minX, columnX + contentX); -} -String getDisplayText (int columnIndex) { - if (parent.columns.length == 0) return getText (0, false); - String result = displayTexts [columnIndex]; - return result != null ? result : ""; //$NON-NLS-1$ -} -/* - * Returns the bounds that should be used for drawing a focus rectangle on the receiver - */ -Rectangle getFocusBounds () { - int x = 0; - TableColumn[] columns = parent.columns; - int[] columnOrder = parent.getColumnOrder (); - if ((parent.style & SWT.FULL_SELECTION) != 0) { - int col0index = columnOrder.length == 0 ? 0 : columnOrder [0]; - if (col0index == 0) { - x = getTextX (0); - } else { - x = -parent.horizontalOffset; - } - } else { - x = getTextX (0); - } - - if (columns.length > 0) { - /* ensure that the focus x does not start beyond the right bound of column 0 */ - int rightX = columns [0].getX () + columns [0].width; - x = Math.min (x, rightX - 1); - } - - int width; - if (columns.length == 0) { - if (customWidth != -1) { - width = customWidth; - } else { - width = textWidths [0] + 2 * MARGIN_TEXT; - } - } else { - TableColumn column; - if ((parent.style & SWT.FULL_SELECTION) != 0) { - column = columns [columnOrder [columnOrder.length - 1]]; - } else { - column = columns [0]; - } - width = column.getX () + column.width - x - 1; - } - return new Rectangle ( - x, - parent.getItemY (this) + (parent.linesVisible ? 1 : 0), - width, - parent.itemHeight - (parent.linesVisible ? 1 : 0)); -} -/** - * 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 getFont (true); -} -Font getFont (boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (font != null) return font; - return parent.getFont (); -} -/** - * Returns the font that the receiver will use to paint textual information - * for the specified cell in this item. - * - * @param index the column index - * @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 (int columnIndex) { - checkWidget (); - return getFont (columnIndex, true); -} -Font getFont (int columnIndex, boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getFont (checkData); - if (cellFonts == null || cellFonts [columnIndex] == null) return getFont (checkData); - return cellFonts [columnIndex]; -} -int getFontHeight () { - if (fontHeight != 0) return fontHeight; - return parent.fontHeight; -} -int getFontHeight (int columnIndex) { - if (fontHeights == null || fontHeights [columnIndex] == 0) return getFontHeight (); - return fontHeights [columnIndex]; -} -/** - * 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 (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (foreground != null) return foreground; - return parent.getForeground (); -} -/** - * - * Returns the foreground color at the given column index in the receiver. - * - * @param index the column index - * @return the 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 3.0 - */ -public Color getForeground (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getForeground (); - if (cellForegrounds == null || cellForegrounds [columnIndex] == null) return getForeground (); - return cellForegrounds [columnIndex]; -} -/** - * 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> - */ -public boolean getGrayed () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return grayed; -} -/* - * Returns the bounds representing the clickable region that should select the receiver. - */ -Rectangle getHitBounds () { - int[] columnOrder = parent.getColumnOrder (); - int contentX = 0; - if ((parent.style & SWT.FULL_SELECTION) != 0) { - int col0index = columnOrder.length == 0 ? 0 : columnOrder [0]; - if (col0index == 0) { - contentX = getContentX (0); - } else { - contentX = 0; - } - } else { - contentX = getContentX (0); - } - - int width = 0; - TableColumn[] columns = parent.columns; - if (columns.length == 0) { - width = getContentWidth (0); - } else { - /* - * If there are columns then this spans from the beginning of the receiver's column 0 - * image or text to the end of either column 0 or the last column (FULL_SELECTION). - */ - TableColumn column; - if ((parent.style & SWT.FULL_SELECTION) != 0) { - column = columns [columnOrder [columnOrder.length - 1]]; - } else { - column = columns [0]; - } - width = column.getX () + column.width - contentX; - } - return new Rectangle (contentX, parent.getItemY (this), width, parent.itemHeight); -} -public Image getImage () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return super.getImage (); -} -/** - * Returns the image stored at the given column index in the receiver, - * or null if the image has not been set or if the column does not exist. - * - * @param index the column index - * @return the image stored at the given column index in the receiver - * - * @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 Image getImage (int columnIndex) { - checkWidget (); - return getImage (columnIndex, true); -} -Image getImage (int columnIndex, boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return null; - if (columnIndex == 0) return super.getImage (); /* super is intentional here */ - return images [columnIndex]; -} -/** - * Returns a rectangle describing the size and location - * relative to its parent of an image at a column in the - * table. An empty rectangle is returned if index exceeds - * the index of the table's last column. - * - * @param index the index that specifies the column - * @return the receiver's bounding image 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 getImageBounds (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return new Rectangle (0,0,0,0); - - int padding = parent.getCellPadding (); - int startX = getContentX (columnIndex); - int itemHeight = parent.itemHeight; - int imageSpaceY = itemHeight - 2 * padding; - int y = parent.getItemY (this); - Image image = getImage (columnIndex, false); - int drawWidth = 0; - if (columnIndex == 0) { - /* for column 0 all images have the same width */ - drawWidth = parent.col0ImageWidth; - } else { - if (image != null) drawWidth = image.getBounds ().width; - } - return new Rectangle (startX, y + padding, drawWidth, imageSpaceY); -} -/** - * Gets the image indent. - * - * @return the indent - * - * @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 int getImageIndent () { - checkWidget(); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return imageIndent; // TODO -} -String getNameText () { - if ((parent.style & SWT.VIRTUAL) != 0) { - if (!cached) return "*virtual*"; //$NON-NLS-1$ - } - return super.getNameText (); -} -/** - * Returns the receiver's parent, which must be a <code>Table</code>. - * - * @return the receiver's parent - * - * @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 Table getParent () { - checkWidget (); - return parent; -} -/* - * Returns the receiver's ideal width for the specified columnIndex. - */ -int getPreferredWidth (int columnIndex) { - int width = 0; - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - width += gc.stringExtent (getText (columnIndex, false)).x + 2 * MARGIN_TEXT; - if (columnIndex == 0) { - if (parent.col0ImageWidth > 0) { - width += parent.col0ImageWidth; - width += Table.MARGIN_IMAGE; - } - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - width += image.getBounds ().width; - width += Table.MARGIN_IMAGE; - } - } - - if (parent.hooks (SWT.MeasureItem)) { - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - event.x = getContentX (columnIndex); - event.y = parent.getItemY (this); - event.width = width; - event.height = parent.itemHeight; - parent.sendEvent (SWT.MeasureItem, event); - if (parent.itemHeight != event.height) { - parent.customHeightSet = true; - boolean update = parent.setItemHeight (event.height + 2 * parent.getCellPadding ()); - if (update) parent.redraw (); - } - width = event.width; - } - - gc.dispose (); - if (columnIndex == 0 && (parent.style & SWT.CHECK) != 0) { - width += parent.checkboxBounds.width; - width += Table.MARGIN_IMAGE; - } - return width + 2 * parent.getCellPadding (); -} -public String getText () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return super.getText (); -} -/** - * Returns the text stored at the given column index in the receiver, - * or empty string if the text has not been set. - * - * @param index the column index - * @return the text stored at the given column index in the receiver - * - * @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 String getText (int columnIndex) { - checkWidget (); - return getText (columnIndex, true); -} -String getText (int columnIndex, boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return ""; //$NON-NLS-1$ - if (columnIndex == 0) return super.getText (); /* super is intentional here */ - if (texts [columnIndex] == null) return ""; //$NON-NLS-1$ - return texts [columnIndex]; -} -/** - * Returns a rectangle describing the size and location - * relative to its parent of the text at a column in the - * table. An empty rectangle is returned if index exceeds - * the index of the table's last column. - * - * @param index the index that specifies the column - * @return the receiver's bounding text 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> - * - * @since 3.3 - */ -public Rectangle getTextBounds (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - TableColumn[] columns = parent.columns; - int columnCount = columns.length; - int validColumnCount = Math.max (1, columnCount); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) { - return new Rectangle (0, 0, 0, 0); - } - /* - * If there are no columns then this is the bounds of the receiver's content, - * starting from the text. - */ - if (columnCount == 0) { - int x = getTextX (0) + MARGIN_TEXT; - int width = Math.max (0, getContentX(0) + getContentWidth (0) - x); - return new Rectangle ( - x, - parent.getItemY (this), - width, - parent.itemHeight - 1); - } - - TableColumn column = columns [columnIndex]; - if (columnIndex == 0) { - /* - * For column 0 this is bounds from the beginning of the content to the - * end of the column, starting from the text. - */ - int x = getTextX (0) + MARGIN_TEXT; - int offset = x - column.getX (); - int width = Math.max (0, column.width - offset - 1); /* max is for columns with small widths */ - return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1); - } - /* - * For columns > 0 this is the bounds of the table cell, starting from the text. - */ - int x = getTextX (columnIndex) + MARGIN_TEXT; - int offset = x - column.getX (); - int width = Math.max (0, column.width - offset - MARGIN_TEXT); - return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1); -} -/* - * Returns the x value where the receiver's text begins. - */ -int getTextX (int columnIndex) { - int textX = getContentX (columnIndex); - if (columnIndex == 0) { - textX += parent.col0ImageWidth; - if (parent.col0ImageWidth > 0) textX += Table.MARGIN_IMAGE; - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - textX += image.getBounds ().width + Table.MARGIN_IMAGE; - } - } - return textX; -} -/* - * Answers a boolean indicating whether the receiver's y is within the current - * viewport of the parent. - */ -boolean isInViewport () { - int topIndex = parent.topIndex; - if (index < topIndex) return false; - int visibleCount = parent.clientArea.height / parent.itemHeight; - return index <= topIndex + visibleCount; -} -boolean isSelected () { - return parent.getSelectionIndex (this) != -1; -} -/* - * The backgroundOnly argument indicates whether the item should only - * worry about painting its background color and selection. - * - * Returns a boolean indicating whether to abort drawing focus on the item. - * If the receiver is not the current focus item then this value is irrelevant. - */ -boolean paint (GC gc, TableColumn column, boolean backgroundOnly) { - if (!parent.checkData (this, true)) return false; - int columnIndex = 0, x = 0; - if (column != null) { - columnIndex = column.getIndex (); - x = column.getX (); - } - - /* - * Capture GC attributes that will need to be restored later in the paint - * process to ensure that the item paints as intended without being affected - * by GC changes made in MeasureItem/EraseItem/PaintItem callbacks. - */ - int oldAlpha = gc.getAlpha (); - boolean oldAdvanced = gc.getAdvanced (); - int oldAntialias = gc.getAntialias (); - Pattern oldBackgroundPattern = gc.getBackgroundPattern (); - Pattern oldForegroundPattern = gc.getForegroundPattern (); - int oldInterpolation = gc.getInterpolation (); - int oldTextAntialias = gc.getTextAntialias (); - - if (parent.hooks (SWT.MeasureItem)) { - int contentWidth = getContentWidth (columnIndex); - int contentX = getContentX (columnIndex); - gc.setFont (getFont (columnIndex, false)); - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - event.x = contentX; - event.y = parent.getItemY (this); - event.width = contentWidth; - event.height = parent.itemHeight; - parent.sendEvent (SWT.MeasureItem, event); - event.gc = null; - if (gc.isDisposed ()) return false; - gc.setAlpha (oldAlpha); - gc.setAntialias (oldAntialias); - gc.setBackgroundPattern (oldBackgroundPattern); - gc.setForegroundPattern (oldForegroundPattern); - gc.setInterpolation (oldInterpolation); - gc.setTextAntialias (oldTextAntialias); - gc.setAdvanced (oldAdvanced); - if (isDisposed ()) return false; - if (parent.itemHeight != event.height) { - parent.customHeightSet = true; - boolean update = parent.setItemHeight (event.height + 2 * parent.getCellPadding ()); - if (update) parent.redraw (); - } - if (parent.columns.length == 0) { - int change = event.width - (customWidth != -1 ? customWidth : contentWidth); - if (event.width != contentWidth || customWidth != -1) customWidth = event.width; - if (change != 0) { /* scrollbar may be affected since no columns */ - parent.updateHorizontalBar (contentX + event.width, change); - // TODO what if clip is too small now? - } - } - } - - /* if this cell is completely to the right of the client area then there's no need to paint it */ - Rectangle clientArea = parent.clientArea; - if (clientArea.x + clientArea.width < x) return false; - - Rectangle cellBounds = getCellBounds (columnIndex); - if (parent.linesVisible) { - cellBounds.y++; - cellBounds.height--; - } - int cellRightX = 0; - if (column != null) { - cellRightX = column.getX () + column.width; - } else { - cellRightX = cellBounds.x + cellBounds.width; - } - - /* restrict the clipping region to the cell */ - gc.setClipping (x, cellBounds.y, clientArea.width - x, cellBounds.height); - - int y = parent.getItemY (this); - int itemHeight = parent.itemHeight; - - /* draw the parent background color/image of this cell */ - if (column == null) { - parent.drawBackground (gc, 0, y, clientArea.width, itemHeight); - } else { - int fillWidth = cellBounds.width; - if (parent.linesVisible) fillWidth--; - parent.drawBackground (gc, cellBounds.x, cellBounds.y, fillWidth, cellBounds.height); - } - - boolean isSelected = isSelected (); - boolean isFocusItem = parent.focusItem == this && parent.isFocusControl (); - boolean drawBackground = true; - boolean drawForeground = true; - boolean drawSelection = isSelected; - boolean drawFocus = isFocusItem; - if (parent.hooks (SWT.EraseItem)) { - drawBackground = background != null || (cellBackgrounds != null && cellBackgrounds [columnIndex] != null); - gc.setFont (getFont (columnIndex, false)); - if (isSelected && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT)); - gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION)); - } else { - gc.setForeground (getForeground (columnIndex)); - gc.setBackground (getBackground (columnIndex)); - } - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - event.doit = true; - event.detail = SWT.FOREGROUND; - if (drawBackground) event.detail |= SWT.BACKGROUND; - if (isSelected) event.detail |= SWT.SELECTED; - if (isFocusItem) event.detail |= SWT.FOCUSED; - event.x = cellBounds.x; - event.y = cellBounds.y; - event.width = cellBounds.width; - event.height = cellBounds.height; - gc.setClipping (cellBounds); - parent.sendEvent (SWT.EraseItem, event); - event.gc = null; - if (gc.isDisposed ()) return false; - gc.setAlpha (oldAlpha); - gc.setAntialias (oldAntialias); - gc.setBackgroundPattern (oldBackgroundPattern); - gc.setClipping (cellBounds); - gc.setForegroundPattern (oldForegroundPattern); - gc.setInterpolation (oldInterpolation); - gc.setTextAntialias (oldTextAntialias); - gc.setAdvanced (oldAdvanced); - if (isDisposed ()) return false; - if (!event.doit) { - drawBackground = drawForeground = drawSelection = drawFocus = false; - } else { - drawBackground = drawBackground && (event.detail & SWT.BACKGROUND) != 0; - drawForeground = (event.detail & SWT.FOREGROUND) != 0; - drawSelection = isSelected && (event.detail & SWT.SELECTED) != 0; - drawFocus = isFocusItem && (event.detail & SWT.FOCUSED) != 0; - } - } - - /* draw the cell's set background if appropriate */ - if (drawBackground) { - gc.setBackground (getBackground (columnIndex)); - if (columnIndex == 0 && (column == null || column.getOrderIndex () == 0)) { - Rectangle focusBounds = getFocusBounds (); - int fillWidth = 0; - if (column == null) { - fillWidth = focusBounds.width; - } else { - fillWidth = column.width - focusBounds.x; - if (parent.linesVisible) fillWidth--; - } - gc.fillRectangle (focusBounds.x, focusBounds.y, fillWidth, focusBounds.height); - } else { - int fillWidth = cellBounds.width; - gc.fillRectangle (cellBounds.x, cellBounds.y, fillWidth, cellBounds.height); - } - } - - /* draw the selection bar if the receiver is selected */ - if (drawSelection && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - if (parent.hasFocus () || (parent.style & SWT.HIDE_SELECTION) == 0) { - gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION)); - if (columnIndex == 0) { - Rectangle focusBounds = getFocusBounds (); - int startX, fillWidth; - if (column == null || column.getOrderIndex () == 0 || (parent.style & SWT.FULL_SELECTION) == 0) { - startX = focusBounds.x + 1; /* space for left bound of focus rect */ - } else { - startX = column.getX (); - } - if (column == null) { - fillWidth = focusBounds.width - 2; - } else { - fillWidth = column.getX () + column.width - startX; - if (column.getOrderIndex () == parent.columns.length - 1 || (parent.style & SWT.FULL_SELECTION) == 0) { - fillWidth -= 2; /* space for right bound of focus rect */ - } - } - if (fillWidth > 0) { - gc.fillRectangle (startX, focusBounds.y + 1, fillWidth, focusBounds.height - 2); - } - } else { - int startX = column.getX (); - int fillWidth = column.width; - if (column.getOrderIndex () == 0) { - startX += 1; /* space for left bound of focus rect */ - fillWidth -= 1; - } - if (column.getOrderIndex () == parent.columns.length - 1) { - fillWidth -= 2; /* space for right bound of focus rect */ - } - if (fillWidth > 0) { - gc.fillRectangle ( - column.getX (), - cellBounds.y + 1, - fillWidth, - cellBounds.height - 2); - } - } - } - } - - if (backgroundOnly) return false; - - /* Draw checkbox if drawing column 0 and parent has style SWT.CHECK */ - if (columnIndex == 0 && (parent.style & SWT.CHECK) != 0) { - Image baseImage = grayed ? parent.getGrayUncheckedImage () : parent.getUncheckedImage (); - Rectangle checkboxBounds = getCheckboxBounds (); - gc.drawImage (baseImage, checkboxBounds.x, checkboxBounds.y); - /* Draw checkmark if item is checked */ - if (checked) { - Image checkmarkImage = parent.getCheckmarkImage (); - Rectangle checkmarkBounds = checkmarkImage.getBounds (); - int xInset = (checkboxBounds.width - checkmarkBounds.width) / 2; - int yInset = (checkboxBounds.height - checkmarkBounds.height) / 2; - gc.drawImage (checkmarkImage, checkboxBounds.x + xInset, checkboxBounds.y + yInset); - } - } - - if (drawForeground) { - Image image = getImage (columnIndex, false); - String text = getDisplayText (columnIndex); - Rectangle imageArea = getImageBounds (columnIndex); - int startX = imageArea.x; - - /* while painting the cell's content restrict the clipping region */ - int padding = parent.getCellPadding (); - gc.setClipping ( - startX, - cellBounds.y + padding - (parent.linesVisible ? 1 : 0), - cellRightX - startX - padding, - cellBounds.height - 2 * (padding - (parent.linesVisible ? 1 : 0))); - - /* draw the image */ - if (image != null) { - Rectangle imageBounds = image.getBounds (); - gc.drawImage ( - image, - 0, 0, /* source x, y */ - imageBounds.width, imageBounds.height, /* source width, height */ - imageArea.x, imageArea.y, /* dest x, y */ - imageArea.width, imageArea.height); /* dest width, height */ - } - - /* draw the text */ - if (text.length () > 0) { - gc.setFont (getFont (columnIndex, false)); - int fontHeight = getFontHeight (columnIndex); - if (drawSelection && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - if (parent.hasFocus () || (parent.style & SWT.HIDE_SELECTION) == 0) { - gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT)); - } - } else { - if (!isSelected || drawSelection) { - gc.setForeground (getForeground (columnIndex)); - } - } - x = getTextX (columnIndex) + MARGIN_TEXT; - gc.drawString (text, x, y + (itemHeight - fontHeight) / 2, true); - } - } - - if (parent.hooks (SWT.PaintItem)) { - int contentWidth = getContentWidth (columnIndex); - int contentX = getContentX (columnIndex); - gc.setFont (getFont (columnIndex, false)); - if (isSelected && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT)); - gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION)); - } else { - gc.setForeground (getForeground (columnIndex)); - gc.setBackground (getBackground (columnIndex)); - } - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - if (isSelected) event.detail |= SWT.SELECTED; - if (drawFocus) event.detail |= SWT.FOCUSED; - event.x = contentX; - event.y = cellBounds.y; - event.width = contentWidth; - event.height = cellBounds.height; - gc.setClipping (cellBounds); - parent.sendEvent (SWT.PaintItem, event); - event.gc = null; - if (gc.isDisposed ()) return false; - gc.setAlpha (oldAlpha); - gc.setAntialias (oldAntialias); - gc.setBackgroundPattern (oldBackgroundPattern); - gc.setClipping (cellBounds); - gc.setForegroundPattern (oldForegroundPattern); - gc.setInterpolation (oldInterpolation); - gc.setTextAntialias (oldTextAntialias); - gc.setAdvanced (oldAdvanced); - drawFocus = isFocusItem && (event.detail & SWT.FOCUSED) != 0; - } - - return isFocusItem && !drawFocus; -} -/* - * Redraw part of the receiver. If either EraseItem or PaintItem is hooked then - * only full cells should be damaged, so adjust accordingly. If neither of these - * events are hooked then the exact bounds given for damaging can be used. - */ -void redraw (int x, int y, int width, int height, int columnIndex) { - if (!parent.hooks (SWT.EraseItem) && !parent.hooks (SWT.PaintItem)) { - parent.redraw (x, y, width, height, false); - return; - } - Rectangle cellBounds = getCellBounds (columnIndex); - parent.redraw (cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, false); -} -void redrawItem () { - parent.redraw (0, parent.getItemY (this), parent.clientArea.width, parent.itemHeight, false); -} -/* - * Updates internal structures in the receiver and its child items to handle the removal of a column. - */ -void removeColumn (TableColumn column, int index) { - int columnCount = parent.columns.length; - - if (columnCount == 0) { - /* reverts to normal table when last column disposed */ - cellBackgrounds = cellForegrounds = null; - displayTexts = null; - cellFonts = null; - fontHeights = null; - GC gc = new GC (parent); - computeTextWidths (gc); - gc.dispose (); - return; - } - - String[] newTexts = new String [columnCount]; - System.arraycopy (texts, 0, newTexts, 0, index); - System.arraycopy (texts, index + 1, newTexts, index, columnCount - index); - texts = newTexts; - - Image[] newImages = new Image [columnCount]; - System.arraycopy (images, 0, newImages, 0, index); - System.arraycopy (images, index + 1, newImages, index, columnCount - index); - images = newImages; - - int[] newTextWidths = new int [columnCount]; - System.arraycopy (textWidths, 0, newTextWidths, 0, index); - System.arraycopy (textWidths, index + 1, newTextWidths, index, columnCount - index); - textWidths = newTextWidths; - - String[] newDisplayTexts = new String [columnCount]; - System.arraycopy (displayTexts, 0, newDisplayTexts, 0, index); - System.arraycopy (displayTexts, index + 1, newDisplayTexts, index, columnCount - index); - displayTexts = newDisplayTexts; - - if (cellBackgrounds != null) { - Color[] newCellBackgrounds = new Color [columnCount]; - System.arraycopy (cellBackgrounds, 0, newCellBackgrounds, 0, index); - System.arraycopy (cellBackgrounds, index + 1, newCellBackgrounds, index, columnCount - index); - cellBackgrounds = newCellBackgrounds; - } - if (cellForegrounds != null) { - Color[] newCellForegrounds = new Color [columnCount]; - System.arraycopy (cellForegrounds, 0, newCellForegrounds, 0, index); - System.arraycopy (cellForegrounds, index + 1, newCellForegrounds, index, columnCount - index); - cellForegrounds = newCellForegrounds; - } - if (cellFonts != null) { - Font[] newCellFonts = new Font [columnCount]; - System.arraycopy (cellFonts, 0, newCellFonts, 0, index); - System.arraycopy (cellFonts, index + 1, newCellFonts, index, columnCount - index); - cellFonts = newCellFonts; - - int[] newFontHeights = new int [columnCount]; - System.arraycopy (fontHeights, 0, newFontHeights, 0, index); - System.arraycopy (fontHeights, index + 1, newFontHeights, index, columnCount - index); - fontHeights = newFontHeights; - } - - if (index == 0) { - text = texts [0] != null ? texts [0] : ""; //$NON-NLS-1$ - texts [0] = null; - image = images [0]; - images [0] = null; - /* - * The new first column may not have as much width available to it as it did when it was - * the second column if checkboxes are being shown, so recompute its displayText if needed. - */ - if ((parent.style & SWT.CHECK) != 0) { - GC gc = new GC (parent); - gc.setFont (getFont (0, false)); - computeDisplayText (0, gc); - gc.dispose (); - } - } - if (columnCount < 2) { - texts = null; - images = 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); - } - Color oldColor = background; - if (oldColor == color) return; - background = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - redrawItem (); -} -/** - * Sets the background color at the given column index in the receiver - * to the color specified by the argument, or to the default system color for the item - * if the argument is null. - * - * @param index the column index - * @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 3.0 - */ -public void setBackground (int columnIndex, Color color) { - checkWidget (); - if (color != null && color.isDisposed ()) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (cellBackgrounds == null) { - if (color == null) return; - cellBackgrounds = new Color [validColumnCount]; - } - Color oldColor = cellBackgrounds [columnIndex]; - if (oldColor == color) return; - cellBackgrounds [columnIndex] = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - if (isInViewport ()) { - Rectangle bounds = getCellBounds (columnIndex); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -/** - * 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 value) { - checkWidget (); - if ((parent.getStyle () & SWT.CHECK) == 0) return; - if (checked == value) return; - checked = value; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - if (isInViewport ()) { - if (parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) { - redrawItem (); - } else { - Rectangle bounds = getCheckboxBounds (); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } - } -} -/** - * 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); - } - Font oldFont = this.font; - if (oldFont == font) return; - this.font = font; - if (oldFont != null && oldFont.equals (font)) return; - - Rectangle bounds = getBounds (false); - int oldRightX = bounds.x + bounds.width; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - /* recompute cached values for string measurements */ - GC gc = new GC (parent); - gc.setFont (getFont (false)); - fontHeight = gc.getFontMetrics ().getHeight (); - computeDisplayTexts (gc); - computeTextWidths (gc); - gc.dispose (); - - /* horizontal bar could be affected if table has no columns */ - if (parent.columns.length == 0) { - bounds = getBounds (false); - int newRightX = bounds.x + bounds.width; - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } - redrawItem (); -} -/** - * Sets the font that the receiver will use to paint textual information - * for the specified cell in 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 index the column index - * @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 (int columnIndex, Font font) { - checkWidget (); - if (font != null && font.isDisposed ()) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (cellFonts == null) { - if (font == null) return; - cellFonts = new Font [validColumnCount]; - } - Font oldFont = cellFonts [columnIndex]; - if (oldFont == font) return; - cellFonts [columnIndex] = font; - if (oldFont != null && oldFont.equals (font)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - /* recompute cached values for string measurements */ - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - if (fontHeights == null) fontHeights = new int [validColumnCount]; - fontHeights [columnIndex] = gc.getFontMetrics ().getHeight (); - computeDisplayText (columnIndex, gc); - gc.dispose (); - - if (isInViewport ()) { - Rectangle bounds = getCellBounds (columnIndex); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -/** - * 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) - * - * @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); - } - Color oldColor = foreground; - if (oldColor == color) return; - foreground = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - redrawItem (); -} -/** - * Sets the foreground color at the given column index in the receiver - * to the color specified by the argument, or to the default system color for the item - * if the argument is null. - * - * @param index the column index - * @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 3.0 - */ -public void setForeground (int columnIndex, Color color) { - checkWidget (); - if (color != null && color.isDisposed ()) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (cellForegrounds == null) { - if (color == null) return; - cellForegrounds = new Color [validColumnCount]; - } - Color oldColor = cellForegrounds [columnIndex]; - if (oldColor == color) return; - cellForegrounds [columnIndex] = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - if (isInViewport ()) { - redraw ( - getTextX (columnIndex), - parent.getItemY (this), - textWidths [columnIndex] + 2 * MARGIN_TEXT, - parent.itemHeight, - columnIndex); - } -} -/** - * 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> - */ -public void setGrayed (boolean value) { - checkWidget (); - if ((parent.getStyle () & SWT.CHECK) == 0) return; - if (grayed == value) return; - grayed = value; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - if (isInViewport ()) { - Rectangle bounds = getCheckboxBounds (); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -public void setImage (Image value) { - checkWidget (); - setImage (0, value); -} -/** - * Sets the image for multiple columns in the table. - * - * @param images the array of new images - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li> - * <li>ERROR_INVALID_ARGUMENT - if one of the images 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> - */ -public void setImage (Image[] value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - - // TODO make a smarter implementation of this - for (int i = 0; i < value.length; i++) { - if (value [i] != null) setImage (i, value [i]); - } -} -/** - * Sets the receiver's image at a column. - * - * @param index the column index - * @param image the new image - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the image 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> - */ -public void setImage (int columnIndex, Image value) { - checkWidget (); - if (value != null && value.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - - TableColumn[] columns = parent.columns; - int validColumnCount = Math.max (1, columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - Image image = getImage (columnIndex, false); - if (value == image) return; - if (value != null && value.equals (image)) return; - if (columnIndex == 0) { - super.setImage (value); - } else { - images [columnIndex] = value; - } - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - /* - * An image width change may affect the space available for the item text, so - * recompute the displayText if there are columns. - */ - if (columns.length > 0) { - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - computeDisplayText (columnIndex, gc); - gc.dispose (); - } - - if (value == null) { - redrawItem (); // TODO why the whole item? - return; - } - - /* - * If this is the first image being put into the table then its item height - * may be adjusted, in which case a full redraw is needed. - */ - if (parent.imageHeight == 0) { - int oldItemHeight = parent.itemHeight; - parent.setImageHeight (value.getBounds ().height); - if (oldItemHeight != parent.itemHeight) { - if (columnIndex == 0) { - parent.col0ImageWidth = value.getBounds ().width; - if (columns.length > 0) { - /* - * All column 0 cells will now have less room available for their texts, - * so all items must now recompute their column 0 displayTexts. - */ - GC gc = new GC (parent); - TableItem[] rootItems = parent.items; - for (int i = 0; i < parent.itemsCount; i++) { - rootItems [i].updateColumnWidth (columns [0], gc); - } - gc.dispose (); - } - } - parent.redraw (); - return; - } - } - - /* - * If this is the first image being put into column 0 then all cells - * in the column should also indent accordingly. - */ - if (columnIndex == 0 && parent.col0ImageWidth == 0) { - parent.col0ImageWidth = value.getBounds ().width; - /* redraw the column */ - if (columns.length == 0) { - parent.redraw (); - } else { - /* - * All column 0 cells will now have less room available for their texts, - * so all items must now recompute their column 0 displayTexts. - */ - GC gc = new GC (parent); - TableItem[] rootItems = parent.items; - for (int i = 0; i < parent.itemsCount; i++) { - rootItems [i].updateColumnWidth (columns [0], gc); - } - gc.dispose (); - parent.redraw ( - columns [0].getX (), 0, - columns [0].width, - parent.clientArea.height, - false); - } - return; - } - redrawItem (); // TODO why the whole item? -} -/** - * Sets the indent of the first column's image, expressed in terms of the image's width. - * - * @param indent the new indent - * - * </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> - * - * @deprecated this functionality is not supported on most platforms - */ -public void setImageIndent (int indent) { - checkWidget(); - if (indent < 0) return; - if (imageIndent == indent) return; - imageIndent = indent; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; -} -/** - * Sets the receiver's text at a column - * - * @param index the column index - * @param string the new text - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the text 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 void setText (int columnIndex, String value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (value.equals (getText (columnIndex, false))) return; - if (columnIndex == 0) { - super.setText (value); - } else { - texts [columnIndex] = value; - } - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - int oldWidth = textWidths [columnIndex]; - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - computeDisplayText (columnIndex, gc); - gc.dispose (); - - if (parent.columns.length == 0) { - Rectangle bounds = getBounds (false); - int rightX = bounds.x + bounds.width; - parent.updateHorizontalBar (rightX, textWidths [columnIndex] - oldWidth); - } - if (isInViewport ()) { - redraw ( - getTextX (columnIndex), - parent.getItemY (this), - Math.max (oldWidth, textWidths [columnIndex]) + 2 * MARGIN_TEXT, - parent.itemHeight, - columnIndex); - } -} -public void setText (String value) { - checkWidget (); - Rectangle bounds = getBounds (false); - int oldRightX = bounds.x + bounds.width; - setText (0, value); - /* horizontal bar could be affected if table has no columns */ - if (parent.columns.length == 0) { - bounds = getBounds (false); - int newRightX = bounds.x + bounds.width; - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } -} -/** - * Sets the text for multiple columns in the table. - * - * @param strings the array of new strings - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the text 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 void setText (String[] value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - Rectangle bounds = getBounds (false); - int oldRightX = bounds.x + bounds.width; - // TODO make a smarter implementation of this - for (int i = 0; i < value.length; i++) { - if (value [i] != null) setText (i, value [i]); - } - /* horizontal bar could be affected if table has no columns */ - if (parent.columns.length == 0) { - bounds = getBounds (false); - int newRightX = bounds.x + bounds.width; - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } -} -/* - * Perform any internal changes necessary to reflect a changed column width. - */ -void updateColumnWidth (TableColumn column, GC gc) { - int columnIndex = column.getIndex (); - gc.setFont (getFont (columnIndex, false)); - String oldDisplayText = displayTexts [columnIndex]; - computeDisplayText (columnIndex, gc); - - /* the cell must be damaged if there is custom drawing being done or if the alignment is not LEFT */ - if (isInViewport ()) { - boolean columnIsLeft = (column.style & SWT.LEFT) != 0; - if (!columnIsLeft || parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) { - Rectangle cellBounds = getCellBounds (columnIndex); - parent.redraw (cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, false); - return; - } - /* if the display text has changed then the cell text must be damaged in order to repaint */ - if (oldDisplayText == null || !oldDisplayText.equals (displayTexts [columnIndex])) { - Rectangle cellBounds = getCellBounds (columnIndex); - int textX = getTextX (columnIndex); - parent.redraw (textX, cellBounds.y, cellBounds.x + cellBounds.width - textX, cellBounds.height, false); - } - } -} -/* - * The parent's font has changed, so if this font was being used by the receiver then - * recompute its cached text sizes using the gc argument. - */ -void updateFont (GC gc) { - if (font == null) { /* receiver is using the Table's font */ - computeDisplayTexts (gc); - computeTextWidths (gc); - } -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/Tree.java deleted file mode 100644 index 1e65f8c530..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/Tree.java +++ /dev/null @@ -1,4295 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.widgets; - -import org.eclipse.swt.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; -import org.eclipse.swt.internal.*; - -/** - * Instances of this class provide a selectable user interface object - * that displays a hierarchy of items and issues notification when an - * item in the hierarchy is selected. - * <p> - * The item children that may be added to instances of this class - * must be of type <code>TreeItem</code>. - * </p><p> - * Style <code>VIRTUAL</code> is used to create a <code>Tree</code> whose - * <code>TreeItem</code>s are to be populated by the client on an on-demand basis - * instead of up-front. This can provide significant performance improvements for - * trees that are very large or for which <code>TreeItem</code> population is - * expensive (for example, retrieving values from an external source). - * </p><p> - * Here is an example of using a <code>Tree</code> with style <code>VIRTUAL</code>: - * <code><pre> - * final Tree tree = new Tree(parent, SWT.VIRTUAL | SWT.BORDER); - * tree.setItemCount(20); - * tree.addListener(SWT.SetData, new Listener() { - * public void handleEvent(Event event) { - * TreeItem item = (TreeItem)event.item; - * TreeItem parentItem = item.getParentItem(); - * String text = null; - * if (parentItem == null) { - * text = "node " + tree.indexOf(item); - * } else { - * text = parentItem.getText() + " - " + parentItem.indexOf(item); - * } - * item.setText(text); - * System.out.println(text); - * item.setItemCount(10); - * } - * }); - * </pre></code> - * </p><p> - * Note that although this class is a subclass of <code>Composite</code>, - * it does not normally make sense to add <code>Control</code> children to - * it, or set a layout on it, unless implementing something like a cell - * editor. - * </p><p> - * <dl> - * <dt><b>Styles:</b></dt> - * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL, NO_SCROLL</dd> - * <dt><b>Events:</b></dt> - * <dd>Selection, DefaultSelection, Collapse, Expand, SetData, MeasureItem, EraseItem, PaintItem</dd> - * </dl> - * </p><p> - * Note: Only one of the styles SINGLE and MULTI may be specified. - * </p><p> - * IMPORTANT: This class is <em>not</em> intended to be subclassed. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @noextend This class is not intended to be subclassed by clients. - */ -public class Tree extends Composite { - Canvas header; - TreeColumn[] columns = new TreeColumn [0]; - TreeColumn[] orderedColumns; - TreeItem[] items = NO_ITEMS; - TreeItem[] availableItems = NO_ITEMS; - TreeItem[] selectedItems = NO_ITEMS; - TreeItem focusItem, anchorItem, insertMarkItem; - TreeItem lastClickedItem; - Event lastSelectionEvent; - int availableItemsCount = 0; - boolean insertMarkPrecedes = false; - boolean linesVisible, ignoreKey, ignoreDispose, customHeightSet; - int topIndex = 0, horizontalOffset = 0; - int fontHeight = 0, imageHeight = 0, itemHeight = 0; - int headerImageHeight = 0, orderedCol0imageWidth = 0; - TreeColumn resizeColumn; - int resizeColumnX = -1; - int drawCount = 0; - boolean inExpand = false; /* for item creation within Expand callback */ - TreeColumn sortColumn; - int sortDirection = SWT.NONE; - - /* column header tooltip */ - Listener toolTipListener; - Shell toolTipShell; - Label toolTipLabel; - - Rectangle arrowBounds, expanderBounds, checkboxBounds, clientArea; - - static final TreeItem[] NO_ITEMS = new TreeItem [0]; - - static final int MARGIN_IMAGE = 3; - static final int MARGIN_CELL = 1; - static final int SIZE_HORIZONTALSCROLL = 5; - static final int TOLLERANCE_COLUMNRESIZE = 2; - static final int WIDTH_HEADER_SHADOW = 2; - static final int WIDTH_CELL_HIGHLIGHT = 1; - static final int [] toolTipEvents = new int[] {SWT.MouseExit, SWT.MouseHover, SWT.MouseMove, SWT.MouseDown}; - static final String ELLIPSIS = "..."; //$NON-NLS-1$ - static final String ID_EXPANDED = "EXPANDED"; //$NON-NLS-1$ - static final String ID_COLLAPSED = "COLLAPSED"; //$NON-NLS-1$ - static final String ID_UNCHECKED = "UNCHECKED"; //$NON-NLS-1$ - static final String ID_GRAYUNCHECKED = "GRAYUNCHECKED"; //$NON-NLS-1$ - static final String ID_CHECKMARK = "CHECKMARK"; //$NON-NLS-1$ - static final String ID_CONNECTOR_COLOR = "CONNECTOR_COLOR"; //$NON-NLS-1$ - static final String ID_ARROWUP = "ARROWUP"; //$NON-NLS-1$ - static final String ID_ARROWDOWN = "ARROWDOWN"; //$NON-NLS-1$ - -// TEMPORARY CODE -boolean hasFocus; - -public boolean isFocusControl() { - return hasFocus; -} - -/** - * 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 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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT#SINGLE - * @see SWT#MULTI - * @see SWT#CHECK - * @see SWT#FULL_SELECTION - * @see SWT#VIRTUAL - * @see SWT#NO_SCROLL - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public Tree (Composite parent, int style) { - super (parent, checkStyle (style)); - setForeground (null); /* set foreground and background to chosen default colors */ - setBackground (null); - GC gc = new GC (this); - fontHeight = gc.getFontMetrics ().getHeight (); - gc.dispose (); - itemHeight = fontHeight + (2 * getCellPadding ()); - initImages (display); - expanderBounds = getExpandedImage ().getBounds (); - checkboxBounds = getUncheckedImage ().getBounds (); - arrowBounds = getArrowDownImage ().getBounds (); - clientArea = getClientArea (); - - Listener listener = new Listener () { - public void handleEvent (Event event) { - handleEvents (event); - } - }; - addListener (SWT.Paint, listener); - addListener (SWT.MouseDown, listener); - addListener (SWT.MouseUp, listener); - addListener (SWT.MouseDoubleClick, listener); - addListener (SWT.Dispose, listener); - addListener (SWT.Resize, listener); - addListener (SWT.KeyDown, listener); - addListener (SWT.FocusOut, listener); - addListener (SWT.FocusIn, listener); - addListener (SWT.Traverse, listener); - - header = new Canvas (this, SWT.NO_REDRAW_RESIZE | SWT.NO_FOCUS); - header.setVisible (false); - header.setBounds (0, 0, 0, fontHeight + 2 * getHeaderPadding ()); - header.addListener (SWT.Paint, listener); - header.addListener (SWT.MouseDown, listener); - header.addListener (SWT.MouseUp, listener); - header.addListener (SWT.MouseHover, listener); - header.addListener (SWT.MouseDoubleClick, listener); - header.addListener (SWT.MouseMove, listener); - header.addListener (SWT.MouseExit, listener); - header.addListener (SWT.MenuDetect, listener); - - toolTipListener = new Listener () { - public void handleEvent (Event event) { - switch (event.type) { - case SWT.MouseHover: - case SWT.MouseMove: - if (headerUpdateToolTip (event.x)) break; - // FALL THROUGH - case SWT.MouseExit: - case SWT.MouseDown: - headerHideToolTip (); - break; - } - } - }; - - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setValues (0, 0, 1, 1, 1, 1); - hBar.setVisible (false); - hBar.addListener (SWT.Selection, listener); - } - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - vBar.setValues (0, 0, 1, 1, 1, 1); - vBar.setVisible (false); - vBar.addListener (SWT.Selection, listener); - } -} -/** - * 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 the <code>SWT.CHECK</code> style 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) 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) error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Expand, typedListener); - addListener (SWT.Collapse, typedListener); -} -boolean checkData (TreeItem item, boolean redraw) { - if (item.cached) return true; - if ((style & SWT.VIRTUAL) != 0) { - item.cached = true; - Event event = new Event (); - TreeItem parentItem = item.getParentItem (); - event.item = item; - event.index = parentItem == null ? indexOf (item) : parentItem.indexOf (item); - sendEvent (SWT.SetData, event); - if (isDisposed () || item.isDisposed ()) return false; - if (redraw) redrawItem (item.availableIndex, false); - } - return true; -} -static int checkStyle (int style) { - /* - * Feature in Windows. Even when WS_HSCROLL or - * WS_VSCROLL is not specified, Windows creates - * trees and tables with scroll bars. The fix - * is to set H_SCROLL and V_SCROLL. - * - * NOTE: This code appears on all platforms so that - * applications have consistent scroll bar behavior. - */ - if ((style & SWT.NO_SCROLL) == 0) { - style |= SWT.H_SCROLL | SWT.V_SCROLL; - } - style |= SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED; - //TEMPORARY CODE - style |= SWT.FULL_SELECTION; - return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0); -} -protected void checkSubclass () { - if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); -} -/** - * Clears the item at the given zero-relative index in the receiver. - * The text, icon and other attributes of the item are set to the default - * value. If the tree was created with the <code>SWT.VIRTUAL</code> style, - * these attributes are requested again as needed. - * - * @param index the index of the item to clear - * @param all <code>true</code> if all child items of the indexed item should be - * cleared recursively, and <code>false</code> otherwise - * - * @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> - * - * @see SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.2 - */ -public void clear (int index, boolean recursive) { - checkWidget (); - if (!(0 <= index && index < items.length)) error (SWT.ERROR_INVALID_RANGE); - TreeItem item = items [index]; - - /* if there are no columns then the horizontal scrollbar may need adjusting */ - TreeItem[] availableDescendents = null; - int oldRightX = 0; - if (columns.length == 0) { - if (recursive) { - availableDescendents = item.computeAvailableDescendents (); - for (int i = 0; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - oldRightX = Math.max (oldRightX, bounds.x + bounds.width); - } - } else { - Rectangle bounds = item.getBounds (false); - oldRightX = bounds.x + bounds.width; - } - } - - /* clear the item(s) */ - item.clear (); - if (recursive) { - item.clearAll (true, false); - } - - /* adjust the horizontal scrollbar if needed */ - if (columns.length == 0) { - int newRightX = 0; - if (recursive) { - for (int i = 0; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - newRightX = Math.max (newRightX, bounds.x + bounds.width); - } - } else { - Rectangle bounds = item.getBounds (false); - newRightX = bounds.x + bounds.width; - } - updateHorizontalBar (newRightX, newRightX - oldRightX); - } - - /* redraw the item(s) */ - if (recursive && item.expanded) { - int descendentCount = availableDescendents == null ? - item.computeAvailableDescendentCount () : - availableDescendents.length; - redrawItems (item.availableIndex, item.availableIndex + descendentCount - 1, false); - } else { - redrawItem (item.availableIndex, false); - } -} -/** - * Clears all the items in the receiver. The text, icon and other - * attributes of the items are set to their default values. If the - * tree was created with the <code>SWT.VIRTUAL</code> style, these - * attributes are requested again as needed. - * - * @param all <code>true</code> if all child items should be cleared - * recursively, and <code>false</code> otherwise - * - * @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 SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.2 - */ -public void clearAll (boolean recursive) { - checkWidget (); - if (items.length == 0) return; - - /* if there are no columns then the horizontal scrollbar may need adjusting */ - int oldRightX = 0; - if (columns.length == 0 && !recursive) { - for (int i = 0; i < items.length; i++) { - Rectangle bounds = items [i].getBounds (false); - oldRightX = Math.max (oldRightX, bounds.x + bounds.width); - } - } - - /* clear the item(s) */ - for (int i = 0; i < items.length; i++) { - items [i].clear (); - if (recursive) items [i].clearAll (true, false); - } - - /* adjust the horizontal scrollbar if needed */ - if (columns.length == 0) { - if (recursive) { - updateHorizontalBar (); /* recompute from scratch */ - } else { - /* - * All cleared root items will have the same x and width values now, - * so just measure the first one as a sample. - */ - Rectangle bounds = items [0].getBounds (false); - int newRightX = bounds.x + bounds.width; - updateHorizontalBar (newRightX, newRightX - oldRightX); - } - } - - /* redraw the item(s) */ - if (recursive) { - redrawItems (0, availableItemsCount - 1, false); - } else { - for (int i = 0; i < items.length; i++) { - redrawItem (items [i].availableIndex, false); - } - } -} -/* - * Returns the ORDERED index of the column that the specified x falls within, - * or -1 if the x lies to the right of the last column. - */ -int computeColumnIntersect (int x, int startColumn) { - TreeColumn[] orderedColumns = getOrderedColumns (); - if (orderedColumns.length - 1 < startColumn) return -1; - int rightX = orderedColumns [startColumn].getX (); - for (int i = startColumn; i < orderedColumns.length; i++) { - rightX += orderedColumns [i].width; - if (x < rightX) return i; - } - return -1; -} -public Point computeSize (int wHint, int hHint, boolean changed) { - checkWidget (); - int width = 0, height = 0; - if (wHint != SWT.DEFAULT) { - width = wHint; - } else { - if (columns.length == 0) { - for (int i = 0; i < availableItemsCount; i++) { - Rectangle itemBounds = availableItems [i].getBounds (false); - width = Math.max (width, itemBounds.x + itemBounds.width); - } - } else { - TreeColumn[] orderedColumns = getOrderedColumns (); - TreeColumn lastColumn = orderedColumns [orderedColumns.length - 1]; - width = lastColumn.getX () + lastColumn.width; - } - } - if (hHint != SWT.DEFAULT) { - height = hHint; - } else { - height = getHeaderHeight () + availableItemsCount * itemHeight; - } - Rectangle result = computeTrim (0, 0, width, height); - return new Point (result.width, result.height); -} -void createItem (TreeColumn column, int index) { - TreeColumn[] newColumns = new TreeColumn [columns.length + 1]; - System.arraycopy (columns, 0, newColumns, 0, index); - newColumns [index] = column; - System.arraycopy (columns, index, newColumns, index + 1, columns.length - index); - columns = newColumns; - - if (orderedColumns != null) { - int insertIndex = 0; - if (index > 0) { - insertIndex = columns [index - 1].getOrderIndex () + 1; - } - TreeColumn[] newOrderedColumns = new TreeColumn [orderedColumns.length + 1]; - System.arraycopy (orderedColumns, 0, newOrderedColumns, 0, insertIndex); - newOrderedColumns [insertIndex] = column; - System.arraycopy ( - orderedColumns, - insertIndex, - newOrderedColumns, - insertIndex + 1, - orderedColumns.length - insertIndex); - orderedColumns = newOrderedColumns; - } - - if (columns.length == 1) { - column.itemImageWidth = orderedCol0imageWidth; - } else { - if (column.getOrderIndex () == 0) orderedCol0imageWidth = 0; - } - - /* allow all items to update their internal structures accordingly */ - for (int i = 0; i < items.length; i++) { - items [i].addColumn (column); - } - - /* existing items become hidden when going from 0 to 1 column (0 width) */ - if (columns.length == 1 && availableItemsCount > 0) { - redrawFromItemDownwards (topIndex); - } else { - /* checkboxes become hidden when creating a column with index == ordered index == 0 (0 width) */ - if (availableItemsCount > 0 && (style & SWT.CHECK) != 0 && index == 0 && column.getOrderIndex () == 0) { - redrawFromItemDownwards (topIndex); - } - } -} -void createItem (TreeItem item, int index) { - TreeItem[] newItems = new TreeItem [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; - - /* determine the item's availability index */ - int startIndex; - if (index == items.length - 1) { - startIndex = availableItemsCount; /* last item */ - } else { - startIndex = items [index + 1].availableIndex; - } - - if (availableItemsCount == availableItems.length) { - int grow = drawCount <= 0 ? 4 : Math.max (4, availableItems.length * 3 / 2); - TreeItem[] newAvailableItems = new TreeItem [availableItems.length + grow]; - System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItems.length); - availableItems = newAvailableItems; - } - if (startIndex != availableItemsCount) { - /* new item is not at end of list, so shift other items right to create space for it */ - System.arraycopy ( - availableItems, - startIndex, - availableItems, - startIndex + 1, - availableItemsCount - startIndex); - } - availableItems [startIndex] = item; - availableItemsCount++; - - /* update the availableIndex for items bumped down by this new item */ - for (int i = startIndex; i < availableItemsCount; i++) { - availableItems [i].availableIndex = i; - } - - /* update scrollbars */ - updateVerticalBar (); - Rectangle bounds = item.getBounds (false); - int rightX = bounds.x + bounds.width; - updateHorizontalBar (rightX, rightX); - /* - * If new item is above viewport then adjust topIndex and the vertical - * scrollbar so that the current viewport items will not change. - */ - if (item.availableIndex < topIndex) { - topIndex++; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - return; - } - /* - * If this is the first item and the receiver has focus then its boundary - * focus ring must be removed. - */ - if (availableItemsCount == 1 && isFocusControl ()) { - focusItem = item; - redraw (); - return; - } - int redrawIndex = index; - if (redrawIndex > 0 && item.isLastChild ()) redrawIndex--; - redrawFromItemDownwards (items [redrawIndex].availableIndex); -} -/** - * Deselects an item in the receiver. If the item was already - * deselected, it remains deselected. - * - * @param item the item to be deselected - * - * @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> - * - * @since 3.4 - */ -public void deselect (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - deselectItem (item); - redrawItem (item.availableIndex, true); -} -/** - * Deselects all selected items in the receiver. - * - * @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 deselectAll () { - checkWidget (); - TreeItem[] oldSelection = selectedItems; - selectedItems = NO_ITEMS; - for (int i = 0; i < oldSelection.length; i++) { - redrawItem (oldSelection [i].availableIndex, true); - } -} -void deselectItem (TreeItem item) { - int index = getSelectionIndex (item); - if (index == -1) return; - TreeItem[] newSelectedItems = new TreeItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, index); - System.arraycopy ( - selectedItems, - index + 1, - newSelectedItems, - index, - newSelectedItems.length - index); - selectedItems = newSelectedItems; -} -void destroyItem (TreeColumn column) { - headerHideToolTip (); - int index = column.getIndex (); - int orderedIndex = column.getOrderIndex (); - - TreeColumn[] newColumns = new TreeColumn [columns.length - 1]; - System.arraycopy (columns, 0, newColumns, 0, index); - System.arraycopy (columns, index + 1, newColumns, index, newColumns.length - index); - columns = newColumns; - - if (orderedColumns != null) { - if (columns.length < 2) { - orderedColumns = null; - } else { - int removeIndex = column.getOrderIndex (); - TreeColumn[] newOrderedColumns = new TreeColumn [orderedColumns.length - 1]; - System.arraycopy (orderedColumns, 0, newOrderedColumns, 0, removeIndex); - System.arraycopy ( - orderedColumns, - removeIndex + 1, - newOrderedColumns, - removeIndex, - newOrderedColumns.length - removeIndex); - orderedColumns = newOrderedColumns; - } - } - - if (orderedIndex == 0 && columns.length > 0) { - orderedCol0imageWidth = columns [getColumnOrder ()[0]].itemImageWidth; - } - - /* allow all items to update their internal structures accordingly */ - for (int i = 0; i < items.length; i++) { - items [i].removeColumn (column, index, orderedIndex); - } - - /* update horizontal scrollbar */ - int lastColumnIndex = columns.length - 1; - if (lastColumnIndex < 0) { /* no more columns */ - updateHorizontalBar (); - } else { - int newWidth = 0; - for (int i = 0; i < columns.length; i++) { - newWidth += columns [i].width; - } - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setMaximum (newWidth); - hBar.setVisible (clientArea.width < newWidth); - int selection = hBar.getSelection (); - if (selection != horizontalOffset) { - horizontalOffset = selection; - redraw (); - if (header.isVisible () && drawCount <= 0) header.redraw (); - } - } - } - TreeColumn[] orderedColumns = getOrderedColumns (); - for (int i = orderedIndex; i < orderedColumns.length; i++) { - if (!orderedColumns [i].isDisposed ()) { - orderedColumns [i].sendEvent (SWT.Move); - } - } - - if (sortColumn == column) { - sortColumn = null; - } -} -/* - * Allows the Tree to update internal structures it has that may contain the - * item being destroyed. The argument is not necessarily a root-level item. - */ -void destroyItem (TreeItem item) { - if (item == focusItem) reassignFocus (); - - /* availableItems array */ - int availableIndex = item.availableIndex; - if (availableIndex != -1) { - Rectangle bounds = item.getBounds (false); - int rightX = bounds.x + bounds.width; - - if (availableIndex != availableItemsCount - 1) { - /* item is not at end of available items list, so must shift items left to reclaim its slot */ - System.arraycopy ( - availableItems, - availableIndex + 1, - availableItems, - availableIndex, - availableItemsCount - availableIndex - 1); - availableItems [availableItemsCount - 1] = null; - } else { - availableItems [availableIndex] = null; /* last item, so no array copy needed */ - } - availableItemsCount--; - - if (drawCount <= 0 && availableItems.length - availableItemsCount == 4) { - /* shrink the available items array */ - TreeItem[] newAvailableItems = new TreeItem [availableItemsCount]; - System.arraycopy (availableItems, 0, newAvailableItems, 0, newAvailableItems.length); - availableItems = newAvailableItems; - } - - /* update the availableIndex on affected items */ - for (int i = availableIndex; i < availableItemsCount; i++) { - availableItems [i].availableIndex = i; - } - item.availableIndex = -1; - int oldTopIndex = topIndex; - updateVerticalBar (); - updateHorizontalBar (0, -rightX); - /* - * If destroyed item is above viewport then adjust topIndex and the vertical - * scrollbar so that the current viewport items will not change. - */ - if (availableIndex < topIndex) { - topIndex = oldTopIndex - 1; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - } - } - /* selectedItems array */ - if (item.isSelected ()) { - int selectionIndex = getSelectionIndex (item); - TreeItem[] newSelectedItems = new TreeItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, selectionIndex); - System.arraycopy ( - selectedItems, - selectionIndex + 1, - newSelectedItems, - selectionIndex, - newSelectedItems.length - selectionIndex); - selectedItems = newSelectedItems; - } - /* root-level items array */ - if (item.depth == 0) { - int index = item.getIndex (); - TreeItem[] newItems = new TreeItem [items.length - 1]; - System.arraycopy (items, 0, newItems, 0, index); - System.arraycopy (items, index + 1, newItems, index, newItems.length - index); - items = newItems; - } - if (item == anchorItem) anchorItem = null; - if (item == insertMarkItem) insertMarkItem = null; - if (item == lastClickedItem) lastClickedItem = null; - /* - * If this was the last item and the receiver has focus then its boundary - * focus ring must be redrawn. - */ - if (availableItemsCount == 0 && isFocusControl ()) { - redraw (); - return; - } -} -Image getArrowDownImage () { - return (Image) display.getData (ID_ARROWDOWN); -} -Image getArrowUpImage () { - return (Image) display.getData (ID_ARROWUP); -} -int getCellPadding () { - return MARGIN_CELL + WIDTH_CELL_HIGHLIGHT; -} -Image getCheckmarkImage () { - return (Image) display.getData (ID_CHECKMARK); -} -public Control[] getChildren () { - checkWidget (); - Control[] controls = _getChildren (); - if (header == null) return controls; - Control[] result = new Control [controls.length - 1]; - /* remove the Header from the returned set of children */ - int index = 0; - for (int i = 0; i < controls.length; i++) { - if (controls [i] != header) { - result [index++] = controls [i]; - } - } - return result; -} -Image getCollapsedImage () { - return (Image) display.getData (ID_COLLAPSED); -} -/** - * Returns the column at the given, zero-relative index in the - * receiver. Throws an exception if the index is out of range. - * Columns are returned in the order that they were created. - * If no <code>TreeColumn</code>s were created by the programmer, - * this method will throw <code>ERROR_INVALID_RANGE</code> despite - * the fact that a single column of data may be visible in the tree. - * This occurs when the programmer uses the tree like a list, adding - * items but never creating a column. - * - * @param index the index of the column to return - * @return the column 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> - * - * @see Tree#getColumnOrder() - * @see Tree#setColumnOrder(int[]) - * @see TreeColumn#getMoveable() - * @see TreeColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.1 - */ -public TreeColumn getColumn (int index) { - checkWidget (); - if (!(0 <= index && index < columns.length)) error (SWT.ERROR_INVALID_RANGE); - return columns [index]; -} -/** - * Returns the number of columns contained in the receiver. - * If no <code>TreeColumn</code>s were created by the programmer, - * this value is zero, despite the fact that visually, one column - * of items may be visible. This occurs when the programmer uses - * the tree like a list, adding items but never creating a column. - * - * @return the number of columns - * - * @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 int getColumnCount () { - checkWidget (); - return columns.length; -} -/** - * Returns an array of zero-relative integers that map - * the creation order of the receiver's items to the - * order in which they are currently being displayed. - * <p> - * Specifically, the indices of the returned array represent - * the current visual order of the items, and the contents - * of the array represent the creation order of the items. - * </p><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 current visual order of the receiver's items - * - * @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 Tree#setColumnOrder(int[]) - * @see TreeColumn#getMoveable() - * @see TreeColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.2 - */ -public int[] getColumnOrder () { - checkWidget (); - int[] result = new int [columns.length]; - if (orderedColumns != null) { - for (int i = 0; i < result.length; i++) { - result [i] = orderedColumns [i].getIndex (); - } - } else { - for (int i = 0; i < columns.length; i++) { - result [i] = i; - } - } - return result; -} -/** - * Returns an array of <code>TreeColumn</code>s which are the - * columns in the receiver. Columns are returned in the order - * that they were created. If no <code>TreeColumn</code>s were - * created by the programmer, the array is empty, despite the fact - * that visually, one column of items may be visible. This occurs - * when the programmer uses the tree like a list, adding items but - * never creating a column. - * <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 items in the receiver - * - * @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 Tree#getColumnOrder() - * @see Tree#setColumnOrder(int[]) - * @see TreeColumn#getMoveable() - * @see TreeColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.1 - */ -public TreeColumn[] getColumns () { - checkWidget (); - TreeColumn[] result = new TreeColumn [columns.length]; - System.arraycopy (columns, 0, result, 0, columns.length); - return result; -} -Color getConnectorColor () { - return (Color) display.getData (ID_CONNECTOR_COLOR); -} -Image getExpandedImage () { - return (Image) display.getData (ID_EXPANDED); -} -Image getGrayUncheckedImage () { - return (Image) display.getData (ID_GRAYUNCHECKED); -} -/** - * Returns the width in pixels of a grid line. - * - * @return the width of a grid line in pixels - * - * @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 int getGridLineWidth () { - checkWidget (); - return 1; -} -/** - * Returns the height of the receiver's header - * - * @return the height of the header or zero if the header is not visible - * - * @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 int getHeaderHeight () { - checkWidget (); - if (!header.getVisible ()) return 0; - return header.getSize ().y; -} -int getHeaderPadding () { - return MARGIN_CELL + WIDTH_HEADER_SHADOW; -} -/** - * Returns <code>true</code> if the receiver's header is visible, - * and <code>false</code> otherwise. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, this method - * may still indicate that it is considered visible even though - * it may not actually be showing. - * </p> - * - * @return the receiver's header's visibility state - * - * @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 boolean getHeaderVisible () { - checkWidget (); - return header.getVisible (); -} -/** - * 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. - * <p> - * The item that is returned represents an item that could be selected by the user. - * For example, if selection only occurs in items in the first column, then null is - * returned if the point is outside of the item. - * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy, - * determines the extent of the selection. - * </p> - * - * @param point the point used to locate the item - * @return the item at the given point, or null if the point is not in a selectable item - * - * @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 TreeItem getItem (Point point) { - checkWidget (); - if (point == null) error (SWT.ERROR_NULL_ARGUMENT); - int index = (point.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < availableItemsCount)) return null; /* below the last item */ - TreeItem result = availableItems [index]; - if (!result.getHitBounds ().contains (point)) return null; /* considers the x value */ - return result; -} -/** - * 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 TreeItem getItem (int index) { - checkWidget (); - if (!(0 <= index && index < items.length)) 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. The - * number that is returned is the number of roots in the - * tree. - * - * @return the number of items - * - * @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 int getItemCount () { - checkWidget (); - return items.length; -} -/** - * Returns the height of the area which would be used to - * display <em>one</em> of the items in the tree. - * - * @return the height of one item - * - * @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 int getItemHeight () { - checkWidget (); - return itemHeight; -} -/** - * Returns a (possibly empty) array of items contained in the - * receiver that are direct item children of the receiver. These - * are the roots of the tree. - * <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 items - * - * @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 TreeItem[] getItems () { - checkWidget (); - TreeItem[] result = new TreeItem [items.length]; - System.arraycopy (items, 0, result, 0, items.length); - return result; -} -/* - * Returns the current y-coordinate that the specified item should have. - */ -int getItemY (TreeItem item) { - int index = item.availableIndex; - if (index == -1) return -1; - return (index - topIndex) * itemHeight + getHeaderHeight (); -} -/** - * Returns <code>true</code> if the receiver's lines are visible, - * and <code>false</code> otherwise. Note that some platforms draw - * grid lines while others may draw alternating row colors. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, this method - * may still indicate that it is considered visible even though - * it may not actually be showing. - * </p> - * - * @return the visibility state of the lines - * - * @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 boolean getLinesVisible () { - checkWidget (); - return linesVisible; -} -TreeColumn[] getOrderedColumns () { - if (orderedColumns != null) return orderedColumns; - return columns; -} -/** - * Returns the receiver's parent item, which must be a - * <code>TreeItem</code> or null when the receiver is a - * root. - * - * @return the receiver's parent item - * - * @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 TreeItem getParentItem () { - checkWidget (); - return null; -} -/** - * Returns an array of <code>TreeItem</code>s that are currently - * selected in the receiver. The order of the items is unspecified. - * An empty array indicates that no items are selected. - * <p> - * Note: This is not the actual structure used by the receiver - * to maintain its selection, so modifying the array will - * not affect the receiver. - * </p> - * @return an array representing the selection - * - * @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 TreeItem[] getSelection () { - checkWidget (); - int count = selectedItems.length; - TreeItem[] result = new TreeItem [count]; - if (count > 0) { - if (count == 1) { - System.arraycopy (selectedItems, 0, result, 0, count); - } else { - getSelection (result, items, 0); - } - } - return result; -} -int getSelection (TreeItem[] result, TreeItem[] items, int index) { - for (int i = 0; i < items.length; i++) { - TreeItem item = items [i]; - if (item.isSelected ()) result [index++] = item; - if (index == result.length) break; - index = getSelection (result, items [i].items, index); - if (index == result.length) break; - } - return index; -} -/** - * Returns the number of selected items contained in the receiver. - * - * @return the number of selected items - * - * @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 int getSelectionCount () { - checkWidget (); - return selectedItems.length; -} -/* - * Returns the index of the argument in the receiver's array of currently- - * selected items, or -1 if the item is not currently selected. - */ -int getSelectionIndex (TreeItem item) { - for (int i = 0; i < selectedItems.length; i++) { - if (selectedItems [i] == item) return i; - } - return -1; -} -/** - * Returns the column which shows the sort indicator for - * the receiver. The value may be null if no column shows - * the sort indicator. - * - * @return the sort indicator - * - * @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 #setSortColumn(TreeColumn) - * - * @since 3.2 - */ -public TreeColumn getSortColumn () { - checkWidget (); - return sortColumn; -} -/** - * Returns the direction of the sort indicator for the receiver. - * The value will be one of <code>UP</code>, <code>DOWN</code> - * or <code>NONE</code>. - * - * @return the sort direction - * - * @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 #setSortDirection(int) - * - * @since 3.2 - */ -public int getSortDirection () { - checkWidget (); - return sortDirection; -} -/** - * Returns the item which is currently at the top of the receiver. - * This item can change when items are expanded, collapsed, scrolled - * or new items are added or removed. - * - * @return the item at the top of the receiver - * - * @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 TreeItem getTopItem () { - checkWidget (); - if (availableItemsCount == 0) return null; - return availableItems [topIndex]; -} -Image getUncheckedImage () { - return (Image) display.getData (ID_UNCHECKED); -} -void handleEvents (Event event) { - switch (event.type) { - case SWT.Paint: - if (event.widget == header) { - headerOnPaint (event); - } else { - onPaint (event); - } - break; - case SWT.MenuDetect: { - notifyListeners (SWT.MenuDetect, event); - break; - } - case SWT.MouseDown: - if (event.widget == header) { - headerOnMouseDown (event); - } else { - onMouseDown (event); - } - break; - case SWT.MouseUp: - if (event.widget == header) { - headerOnMouseUp (event); - } else { - onMouseUp (event); - } - break; - case SWT.MouseHover: - headerOnMouseHover (event); break; - case SWT.MouseMove: - headerOnMouseMove (event); break; - case SWT.MouseDoubleClick: - if (event.widget == header) { - headerOnMouseDoubleClick (event); - } else { - onMouseDoubleClick (event); - } - break; - case SWT.MouseExit: - headerOnMouseExit (); break; - case SWT.Dispose: - onDispose (event); break; - case SWT.KeyDown: - onKeyDown (event); break; - case SWT.Resize: - onResize (event); break; - case SWT.Selection: - if (event.widget == getHorizontalBar ()) { - onScrollHorizontal (event); - } - if (event.widget == getVerticalBar ()) { - onScrollVertical (event); - } - break; - case SWT.FocusOut: - onFocusOut (); break; - case SWT.FocusIn: - onFocusIn (); break; - case SWT.Traverse: - switch (event.detail) { - case SWT.TRAVERSE_ESCAPE: - case SWT.TRAVERSE_RETURN: - case SWT.TRAVERSE_TAB_NEXT: - case SWT.TRAVERSE_TAB_PREVIOUS: - case SWT.TRAVERSE_PAGE_NEXT: - case SWT.TRAVERSE_PAGE_PREVIOUS: - event.doit = true; - break; - } - break; - } -} -String headerGetToolTip (int x) { - if (resizeColumn != null) return null; - int orderedIndex = computeColumnIntersect (x, 0); - if (orderedIndex == -1) return null; - TreeColumn[] orderedColumns = getOrderedColumns (); - TreeColumn column = orderedColumns [orderedIndex]; - if (column.toolTipText == null) return null; - - /* no tooltip should appear if the hover is at a column resize opportunity */ - int columnX = column.getX (); - if (orderedIndex > 0 && orderedColumns [orderedIndex - 1].resizable) { - /* left column bound is resizable */ - if (x - columnX <= TOLLERANCE_COLUMNRESIZE) return null; - } - if (column.resizable) { - /* right column bound is resizable */ - int columnRightX = columnX + column.width; - if (columnRightX - x <= TOLLERANCE_COLUMNRESIZE) return null; - } - return removeMnemonics (column.toolTipText); -} -void headerHideToolTip() { - if (toolTipShell == null) return; - for (int i = 0; i < toolTipEvents.length; i++) { - header.removeListener (toolTipEvents [i], toolTipListener); - } - toolTipShell.dispose (); - toolTipShell = null; - toolTipLabel = null; -} -void headerOnMouseDoubleClick (Event event) { - if (!isFocusControl ()) setFocus (); - if (columns.length == 0) return; - TreeColumn[] orderedColumns = getOrderedColumns (); - int x = -horizontalOffset; - for (int i = 0; i < orderedColumns.length; i++) { - TreeColumn column = orderedColumns [i]; - x += column.width; - if (event.x < x) { - /* found the clicked column */ - TreeColumn packColumn = null; - if (x - event.x <= TOLLERANCE_COLUMNRESIZE) { - /* clicked on column bound for this column */ - packColumn = column; - } else { - if (i > 0 && event.x - column.getX () <= TOLLERANCE_COLUMNRESIZE) { - /* clicked on column bound that applies to previous column */ - packColumn = orderedColumns [i - 1]; - } - } - if (packColumn != null) { - packColumn.pack (); - resizeColumn = null; - if (Math.abs (packColumn.getX () + packColumn.width - event.x) > TOLLERANCE_COLUMNRESIZE) { - /* column separator has relocated away from pointer location */ - setCursor (null); - } - return; - } - /* did not click on column separator, so just fire column event */ - Event newEvent = new Event (); - newEvent.widget = column; - column.postEvent (SWT.DefaultSelection, newEvent); - return; - } - } -} -void headerOnMouseDown (Event event) { - if (event.button != 1) return; - TreeColumn[] orderedColumns = getOrderedColumns (); - int x = -horizontalOffset; - for (int i = 0; i < orderedColumns.length; i++) { - TreeColumn column = orderedColumns [i]; - x += column.width; - /* if close to a resizable column separator line then begin column resize */ - if (column.resizable && Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) { - resizeColumn = column; - resizeColumnX = x; - return; - } - /* - * If within column but not near separator line then start column drag - * if column is moveable, or just fire column Selection otherwise. - */ - if (event.x < x) { - if (column.moveable) { - /* open tracker on the dragged column's header cell */ - int columnX = column.getX (); - int pointerOffset = event.x - columnX; - headerHideToolTip (); - Tracker tracker = new Tracker (this, SWT.NONE); - tracker.setRectangles (new Rectangle[] { - new Rectangle (columnX, 0, column.width, getHeaderHeight ()) - }); - if (!tracker.open ()) return; /* cancelled */ - /* determine which column was dragged onto */ - Rectangle result = tracker.getRectangles () [0]; - int pointerX = result.x + pointerOffset; - if (pointerX < 0) return; /* dragged too far left */ - x = -horizontalOffset; - for (int destIndex = 0; destIndex < orderedColumns.length; destIndex++) { - TreeColumn destColumn = orderedColumns [destIndex]; - x += destColumn.width; - if (pointerX < x) { - int oldIndex = column.getOrderIndex (); - if (destIndex == oldIndex) { /* dragged onto self */ - Event newEvent = new Event (); - newEvent.widget = column; - column.postEvent (SWT.Selection, newEvent); - return; - } - int leftmostIndex = Math.min (destIndex, oldIndex); - int[] oldOrder = getColumnOrder (); - int[] newOrder = new int [oldOrder.length]; - System.arraycopy (oldOrder, 0, newOrder, 0, leftmostIndex); - if (leftmostIndex == oldIndex) { - /* column moving to the right */ - System.arraycopy (oldOrder, oldIndex + 1, newOrder, oldIndex, destIndex - oldIndex); - } else { - /* column moving to the left */ - System.arraycopy (oldOrder, destIndex, newOrder, destIndex + 1, oldIndex - destIndex); - } - newOrder [destIndex] = oldOrder [oldIndex]; - int rightmostIndex = Math.max (destIndex, oldIndex); - System.arraycopy ( - oldOrder, - rightmostIndex + 1, - newOrder, - rightmostIndex + 1, - newOrder.length - rightmostIndex - 1); - setColumnOrder (newOrder); - return; - } - } - return; /* dragged too far right */ - } - /* column is not moveable */ - Event newEvent = new Event (); - newEvent.widget = column; - column.postEvent (SWT.Selection, newEvent); - return; - } - } -} -void headerOnMouseExit () { - if (resizeColumn != null) return; - setCursor (null); /* ensure that a column resize cursor does not escape */ -} -void headerOnMouseHover (Event event) { - headerShowToolTip (event.x); -} -void headerOnMouseMove (Event event) { - if (resizeColumn == null) { - /* not currently resizing a column */ - for (int i = 0; i < columns.length; i++) { - TreeColumn column = columns [i]; - int x = column.getX () + column.width; - if (Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) { - if (column.resizable) { - setCursor (display.getSystemCursor (SWT.CURSOR_SIZEWE)); - } else { - setCursor (null); - } - return; - } - } - setCursor (null); - return; - } - - /* currently resizing a column */ - - /* don't allow the resize x to move left of the column's x position */ - if (event.x <= resizeColumn.getX ()) return; - - /* redraw the resizing line at its new location */ - GC gc = new GC (this); - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - int lineHeight = clientArea.height; - redraw (resizeColumnX - 1, 0, 1, lineHeight, false); - resizeColumnX = event.x; - gc.drawLine (resizeColumnX - 1, 0, resizeColumnX - 1, lineHeight); - gc.dispose (); -} -void headerOnMouseUp (Event event) { - if (resizeColumn == null) return; /* not resizing a column */ - - /* remove the resize line */ - GC gc = new GC (this); - redraw (resizeColumnX - 1, 0, 1, clientArea.height, false); - gc.dispose (); - - int newWidth = resizeColumnX - resizeColumn.getX (); - if (newWidth != resizeColumn.width) { - setCursor (null); - updateColumnWidth (resizeColumn, newWidth); - } - resizeColumnX = -1; - resizeColumn = null; -} -void headerOnPaint (Event event) { - TreeColumn[] orderedColumns = getOrderedColumns (); - int numColumns = orderedColumns.length; - GC gc = event.gc; - Rectangle clipping = gc.getClipping (); - int startColumn = -1, endColumn = -1; - if (numColumns > 0) { - startColumn = computeColumnIntersect (clipping.x, 0); - if (startColumn != -1) { /* the clip x is within a column's bounds */ - endColumn = computeColumnIntersect (clipping.x + clipping.width, startColumn); - if (endColumn == -1) endColumn = numColumns - 1; - } - } else { - startColumn = endColumn = 0; - } - - /* paint the column header shadow that spans the full header width */ - Point headerSize = header.getSize (); - headerPaintHShadows (gc, 0, 0, headerSize.x, headerSize.y); - - /* if all damage is to the right of the last column then finished */ - if (startColumn == -1) return; - - /* paint each of the column headers */ - if (numColumns == 0) return; /* no headers to paint */ - for (int i = startColumn; i <= endColumn; i++) { - headerPaintVShadows (gc, orderedColumns [i].getX (), 0, orderedColumns [i].width, headerSize.y); - orderedColumns [i].paint (gc); - } -} -void headerPaintHShadows (GC gc, int x, int y, int width, int height) { - gc.setClipping (x, y, width, height); - int endX = x + width; - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); - gc.drawLine (x, y, endX, y); /* highlight shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawLine (x, height - 2, endX, height - 2); /* lowlight shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_DARK_SHADOW)); - gc.drawLine (x, height - 1, endX, height - 1); /* outer shadow */ -} -void headerPaintVShadows (GC gc, int x, int y, int width, int height) { - gc.setClipping (x, y, width, height); - int endX = x + width; - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); - gc.drawLine (x, y, x, y + height - 1); /* highlight shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawLine (endX - 2, y + 1, endX - 2, height - 2); /* light inner shadow */ - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_DARK_SHADOW)); - gc.drawLine (endX - 1, y, endX - 1, height - 1); /* dark outer shadow */ -} -void headerShowToolTip (int x) { - String tooltip = headerGetToolTip (x); - if (tooltip == null || tooltip.length () == 0) return; - - if (toolTipShell == null) { - toolTipShell = new Shell (getShell (), SWT.ON_TOP | SWT.TOOL); - toolTipLabel = new Label (toolTipShell, SWT.CENTER); - Display display = toolTipShell.getDisplay (); - toolTipLabel.setForeground (display.getSystemColor (SWT.COLOR_INFO_FOREGROUND)); - toolTipLabel.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND)); - for (int i = 0; i < toolTipEvents.length; i++) { - header.addListener (toolTipEvents [i], toolTipListener); - } - } - if (headerUpdateToolTip (x)) { - toolTipShell.setVisible (true); - } else { - headerHideToolTip (); - } -} -boolean headerUpdateToolTip (int x) { - String tooltip = headerGetToolTip (x); - if (tooltip == null || tooltip.length () == 0) return false; - if (tooltip.equals (toolTipLabel.getText ())) return true; - - toolTipLabel.setText (tooltip); - TreeColumn column = getOrderedColumns () [computeColumnIntersect (x, 0)]; - toolTipShell.setData (new Integer (column.getIndex ())); - Point labelSize = toolTipLabel.computeSize (SWT.DEFAULT, SWT.DEFAULT, true); - labelSize.x += 2; labelSize.y += 2; - toolTipLabel.setSize (labelSize); - toolTipShell.pack (); - /* - * On some platforms, there is a minimum size for a shell - * which may be greater than the label size. - * To avoid having the background of the tip shell showing - * around the label, force the label to fill the entire client area. - */ - Rectangle area = toolTipShell.getClientArea (); - toolTipLabel.setSize (area.width, area.height); - - /* Position the tooltip and ensure it's not located off the screen */ - Point cursorLocation = getDisplay ().getCursorLocation (); - int cursorHeight = 21; /* assuming cursor is 21x21 */ - Point size = toolTipShell.getSize (); - Rectangle rect = getMonitor ().getBounds (); - Point pt = new Point (cursorLocation.x, cursorLocation.y + cursorHeight + 2); - pt.x = Math.max (pt.x, rect.x); - if (pt.x + size.x > rect.x + rect.width) pt.x = rect.x + rect.width - size.x; - if (pt.y + size.y > rect.y + rect.height) pt.y = cursorLocation.y - 2 - size.y; - toolTipShell.setLocation (pt); - return true; -} -/** - * Searches the receiver's list starting at the first column - * (index 0) until a column is found that is equal to the - * argument, and returns the index of that column. If no column - * is found, returns -1. - * - * @param column the search column - * @return the index of the column - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the column 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> - * - * @since 3.1 - */ -public int indexOf (TreeColumn column) { - checkWidget (); - if (column == null) error (SWT.ERROR_NULL_ARGUMENT); - if (column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - return column.getIndex (); -} -/** - * Searches the receiver's list starting at the first item - * (index 0) until an item is found that is equal to the - * argument, and returns the index of that item. If no item - * is found, returns -1. - * - * @param item the search item - * @return the index of the item - * - * @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> - * - * @since 3.1 - */ -public int indexOf (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (item.parentItem != null || item.parent != this) return -1; - return item.getIndex (); -} -static void initImages (final Display display) { - PaletteData fourBit = new PaletteData (new RGB[] { - new RGB (0, 0, 0), new RGB (128, 0, 0), new RGB (0, 128, 0), new RGB (128, 128, 0), - new RGB (0, 0, 128), new RGB (128, 0, 128), new RGB (0, 128, 128), new RGB (128, 128, 128), - new RGB (192, 192, 192), new RGB (255, 0, 0), new RGB (0, 255, 0), new RGB (255, 255, 0), - new RGB (0, 0, 255), new RGB (255, 0, 255), new RGB (0, 255, 255), new RGB (255, 255, 255)}); - - if (display.getData (ID_EXPANDED) == null) { - ImageData expanded = new ImageData ( - 9, 9, 4, /* width, height, depth */ - fourBit, 4, - new byte[] { - 119, 119, 119, 119, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 127, 0, 0, 15, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 119, 119, 119, 119, 112, 0, 0, 0}); - expanded.transparentPixel = 15; /* use white for transparency */ - display.setData (ID_EXPANDED, new Image (display, expanded)); - } - - if (display.getData (ID_COLLAPSED) == null) { - ImageData collapsed = new ImageData ( - 9, 9, 4, /* width, height, depth */ - fourBit, 4, - new byte[] { - 119, 119, 119, 119, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 127, -1, 15, -1, 112, 0, 0, 0, - 127, -1, 15, -1, 112, 0, 0, 0, - 127, 0, 0, 15, 112, 0, 0, 0, - 127, -1, 15, -1, 112, 0, 0, 0, - 127, -1, 15, -1, 112, 0, 0, 0, - 127, -1, -1, -1, 112, 0, 0, 0, - 119, 119, 119, 119, 112, 0, 0, 0}); - collapsed.transparentPixel = 15; /* use white for transparency */ - display.setData (ID_COLLAPSED, new Image (display, collapsed)); - } - - PaletteData arrowPalette = new PaletteData (new RGB[] { - new RGB (0, 0, 0), new RGB (255, 255, 255)}); - if (display.getData (ID_ARROWDOWN) == null) { - ImageData arrowDown = new ImageData ( - 7, 4, 1, - arrowPalette, 1, - new byte[] {0x00, (byte)0x83, (byte)0xC7, (byte)0xEF}); - arrowDown.transparentPixel = 0x1; /* use white for transparency */ - display.setData (ID_ARROWDOWN, new Image (display, arrowDown)); - } - if (display.getData (ID_ARROWUP) == null) { - ImageData arrowUp = new ImageData ( - 7, 4, 1, - arrowPalette, 1, - new byte[] {(byte)0xEF, (byte)0xC7, (byte)0x83, 0x00}); - arrowUp.transparentPixel = 0x1; /* use white for transparency */ - display.setData (ID_ARROWUP, new Image (display, arrowUp)); - } - - PaletteData checkMarkPalette = new PaletteData ( - new RGB[] {new RGB (0, 0, 0), new RGB (252, 3, 251)}); - byte[] checkbox = new byte[] {0, 0, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 127, -64, 0, 0}; - ImageData checkmark = new ImageData (7, 7, 1, checkMarkPalette, 1, new byte[] {-4, -8, 112, 34, 6, -114, -34}); - checkmark.transparentPixel = 1; - if (display.getData (ID_CHECKMARK) == null) { - display.setData (ID_CHECKMARK, new Image (display, checkmark)); - } - - if (display.getData (ID_UNCHECKED) == null) { - PaletteData uncheckedPalette = new PaletteData ( - new RGB[] {new RGB (128, 128, 128), new RGB (255, 255, 255)}); - ImageData unchecked = new ImageData (11, 11, 1, uncheckedPalette, 2, checkbox); - display.setData (ID_UNCHECKED, new Image (display, unchecked)); - } - - if (display.getData (ID_GRAYUNCHECKED) == null) { - PaletteData grayUncheckedPalette = new PaletteData ( - new RGB[] {new RGB (128, 128, 128), new RGB (192, 192, 192)}); - ImageData grayUnchecked = new ImageData (11, 11, 1, grayUncheckedPalette, 2, checkbox); - display.setData (ID_GRAYUNCHECKED, new Image (display, grayUnchecked)); - } - - if (display.getData (ID_CONNECTOR_COLOR) == null) { - display.setData (ID_CONNECTOR_COLOR, new Color (display, 170, 170, 170)); - } - - display.disposeExec (new Runnable () { - public void run() { - Image expanded = (Image) display.getData (ID_EXPANDED); - if (expanded != null) expanded.dispose (); - Image collapsed = (Image) display.getData (ID_COLLAPSED); - if (collapsed != null) collapsed.dispose (); - Color connectorColor = (Color) display.getData (ID_CONNECTOR_COLOR); - if (connectorColor != null) connectorColor.dispose (); - Image unchecked = (Image) display.getData (ID_UNCHECKED); - if (unchecked != null) unchecked.dispose (); - Image grayUnchecked = (Image) display.getData (ID_GRAYUNCHECKED); - if (grayUnchecked != null) grayUnchecked.dispose (); - Image checkmark = (Image) display.getData (ID_CHECKMARK); - if (checkmark != null) checkmark.dispose (); - Image arrowDown = (Image) display.getData (ID_ARROWDOWN); - if (arrowDown != null) arrowDown.dispose (); - Image arrowUp = (Image) display.getData (ID_ARROWUP); - if (arrowUp != null) arrowUp.dispose (); - - display.setData (ID_EXPANDED, null); - display.setData (ID_COLLAPSED, null); - display.setData (ID_CONNECTOR_COLOR, null); - display.setData (ID_UNCHECKED, null); - display.setData (ID_GRAYUNCHECKED, null); - display.setData (ID_CHECKMARK, null); - display.setData (ID_ARROWDOWN, null); - display.setData (ID_ARROWUP, null); - } - }); -} -/* - * Important: Assumes that item just became available (ie.- was either created - * or the parent item was expanded) and the parent is available. - */ -void makeAvailable (TreeItem item) { - int parentItemCount = item.parentItem.items.length; - int index = 0; - if (parentItemCount == 1) { /* this is the only child of parentItem */ - index = item.parentItem.availableIndex + 1; - } else { - /* determine this item's index in its parent */ - int itemIndex = 0; - TreeItem[] items = item.parentItem.items; - for (int i = 0; i < items.length; i++) { - if (items [i] == item) { - itemIndex = i; - break; - } - } - if (itemIndex != parentItemCount - 1) { /* this is not the last child */ - index = items [itemIndex + 1].availableIndex; - } else { /* this is the last child */ - TreeItem previousItem = items [itemIndex - 1]; - index = previousItem.availableIndex + previousItem.computeAvailableDescendentCount (); - } - } - - if (availableItemsCount == availableItems.length) { - int grow = drawCount <= 0 ? 4 : Math.max (4, availableItems.length * 3 / 2); - TreeItem[] newAvailableItems = new TreeItem [availableItems.length + grow]; - System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItems.length); - availableItems = newAvailableItems; - } - if (index != availableItemsCount) { - /* new item is not at end of list, so shift other items right to create space for it */ - System.arraycopy (availableItems, index, availableItems, index + 1, availableItemsCount - index); - } - availableItems [index] = item; - availableItemsCount++; - - /* update availableIndex as needed */ - for (int i = index; i < availableItemsCount; i++) { - availableItems [i].availableIndex = i; - } -} - -/* - * Important: Assumes that item is available and its descendents have just become - * available (ie.- they were either created or the item was expanded). - */ -void makeDescendentsAvailable (TreeItem item, TreeItem[] descendents) { - int itemAvailableIndex = item.availableIndex; - TreeItem[] newAvailableItems = new TreeItem [availableItemsCount + descendents.length - 1]; - - System.arraycopy (availableItems, 0, newAvailableItems, 0, itemAvailableIndex); - System.arraycopy (descendents, 0, newAvailableItems, itemAvailableIndex, descendents.length); - int startIndex = itemAvailableIndex + 1; - System.arraycopy ( - availableItems, - startIndex, - newAvailableItems, - itemAvailableIndex + descendents.length, - availableItemsCount - startIndex); - availableItems = newAvailableItems; - availableItemsCount = availableItems.length; - - /* update availableIndex as needed */ - for (int i = itemAvailableIndex; i < availableItemsCount; i++) { - availableItems [i].availableIndex = i; - } -} - -/* - * Important: Assumes that item is available and its descendents have just become - * unavailable (ie.- they were either disposed or the item was collapsed). - */ -void makeDescendentsUnavailable (TreeItem item, TreeItem[] descendents) { - int descendentsLength = descendents.length; - TreeItem[] newAvailableItems = new TreeItem [availableItemsCount - descendentsLength + 1]; - - System.arraycopy (availableItems, 0, newAvailableItems, 0, item.availableIndex + 1); - int startIndex = item.availableIndex + descendentsLength; - System.arraycopy ( - availableItems, - startIndex, - newAvailableItems, - item.availableIndex + 1, - availableItemsCount - startIndex); - availableItems = newAvailableItems; - availableItemsCount = availableItems.length; - - /* update availableIndexes */ - for (int i = 1; i < descendents.length; i++) { - /* skip the first descendent since this is the item being collapsed */ - descendents [i].availableIndex = -1; - } - for (int i = item.availableIndex; i < availableItemsCount; i++) { - availableItems [i].availableIndex = i; - } - - /* remove the selection from all descendents */ - for (int i = selectedItems.length - 1; i >= 0; i--) { - if (selectedItems [i] != item && selectedItems [i].hasAncestor (item)) { - removeSelectedItem (i); - } - } - - /* if the anchorItem is being hidden then clear it */ - if (anchorItem != null && anchorItem != item && anchorItem.hasAncestor (item)) { - anchorItem = null; - } -} -void onArrowDown (int stateMask) { - if ((stateMask & (SWT.SHIFT | SWT.CTRL)) == 0) { - /* Down Arrow with no modifiers */ - int newFocusIndex = focusItem.availableIndex + 1; - if (newFocusIndex == availableItemsCount) return; /* at bottom */ - selectItem (availableItems [newFocusIndex], false); - setFocusItem (availableItems [newFocusIndex], true); - redrawItem (newFocusIndex, true); - showItem (availableItems [newFocusIndex]); - Event newEvent = new Event (); - newEvent.item = availableItems [newFocusIndex]; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Down Arrow, CTRL+Shift+Down Arrow */ - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (availableItemsCount <= topIndex + visibleItemCount) return; /* at bottom */ - update (); - topIndex++; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, -itemHeight); - gc.dispose (); - return; - } - /* Shift+Down Arrow */ - int newFocusIndex = focusItem.availableIndex + 1; - if (newFocusIndex == availableItemsCount) return; /* at bottom */ - selectItem (availableItems [newFocusIndex], false); - setFocusItem (availableItems [newFocusIndex], true); - redrawItem (newFocusIndex, true); - showItem (availableItems [newFocusIndex]); - Event newEvent = new Event (); - newEvent.item = availableItems [newFocusIndex]; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+Down Arrow */ - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (availableItemsCount <= topIndex + visibleItemCount) return; /* at bottom */ - update (); - topIndex++; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, -itemHeight); - gc.dispose (); - return; - } - /* CTRL+Down Arrow */ - int focusIndex = focusItem.availableIndex; - if (focusIndex == availableItemsCount - 1) return; /* at bottom */ - TreeItem newFocusItem = availableItems [focusIndex + 1]; - setFocusItem (newFocusItem, true); - redrawItem (newFocusItem.availableIndex, true); - showItem (newFocusItem); - return; - } - /* Shift+Down Arrow */ - int newFocusIndex = focusItem.availableIndex + 1; - if (newFocusIndex == availableItemsCount) return; /* at bottom */ - if (anchorItem == null) anchorItem = focusItem; - if (focusItem.availableIndex < anchorItem.availableIndex) { - deselectItem (focusItem); - redrawItem (focusItem.availableIndex, true); - } - selectItem (availableItems [newFocusIndex], true); - setFocusItem (availableItems [newFocusIndex], true); - redrawItem (newFocusIndex, true); - showItem (availableItems [newFocusIndex]); - Event newEvent = new Event (); - newEvent.item = availableItems [newFocusIndex]; - postEvent (SWT.Selection, newEvent); -} -void onArrowLeft (int stateMask) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Left Arrow, CTRL+Shift+Left Arrow */ - if (horizontalOffset == 0) return; - int newSelection = Math.max (0, horizontalOffset - SIZE_HORIZONTALSCROLL); - update (); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - if (header.getVisible ()) { - header.update (); - Rectangle headerClientArea = header.getClientArea (); - gc = new GC (header); - gc.copyArea ( - 0, 0, - headerClientArea.width, headerClientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose(); - } - horizontalOffset = newSelection; - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) hBar.setSelection (horizontalOffset); - return; - } - /* Left Arrow with no modifiers, Shift+Left Arrow */ - if (focusItem.expanded) { - focusItem.setExpanded (false); - Event newEvent = new Event (); - newEvent.item = focusItem; - sendEvent (SWT.Collapse, newEvent); - return; - } - TreeItem parentItem = focusItem.parentItem; - if (parentItem == null) return; - - selectItem (parentItem, false); - setFocusItem (parentItem, true); - redrawItem (parentItem.availableIndex, true); - showItem (parentItem); - Event newEvent = new Event (); - newEvent.item = parentItem; - postEvent (SWT.Selection, newEvent); -} -void onArrowRight (int stateMask) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Right Arrow, CTRL+Shift+Right Arrow */ - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - int maximum = hBar.getMaximum (); - int clientWidth = clientArea.width; - if ((horizontalOffset + clientWidth) == maximum) return; - if (maximum <= clientWidth) return; - int newSelection = Math.min (horizontalOffset + SIZE_HORIZONTALSCROLL, maximum - clientWidth); - update (); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - if (header.getVisible ()) { - Rectangle headerClientArea = header.getClientArea (); - header.update (); - gc = new GC (header); - gc.copyArea ( - 0, 0, - headerClientArea.width, headerClientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose(); - } - horizontalOffset = newSelection; - hBar.setSelection (horizontalOffset); - } - return; - } - /* Right Arrow with no modifiers, Shift+Right Arrow */ - TreeItem[] children = focusItem.items; - if (children.length == 0) return; - if (!focusItem.expanded) { - focusItem.setExpanded (true); - Event newEvent = new Event (); - newEvent.item = focusItem; - inExpand = true; - sendEvent (SWT.Expand, newEvent); - inExpand = false; - if (isDisposed ()) return; - if (focusItem.items.length == 0) { - focusItem.expanded = false; - } - return; - } - selectItem (children [0], false); - setFocusItem (children [0], true); - redrawItem (children [0].availableIndex, true); - showItem (children [0]); - Event newEvent = new Event (); - newEvent.item = children [0]; - postEvent (SWT.Selection, newEvent); -} -void onArrowUp (int stateMask) { - if ((stateMask & (SWT.SHIFT | SWT.CTRL)) == 0) { - /* Up Arrow with no modifiers */ - int newFocusIndex = focusItem.availableIndex - 1; - if (newFocusIndex < 0) return; /* at top */ - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (newFocusIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Up Arrow, CTRL+Shift+Up Arrow */ - if (topIndex == 0) return; /* at top */ - update (); - topIndex--; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, itemHeight); - gc.dispose (); - return; - } - /* Shift+Up Arrow */ - int newFocusIndex = focusItem.availableIndex - 1; - if (newFocusIndex < 0) return; /* at top */ - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (newFocusIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+Up Arrow */ - if (topIndex == 0) return; /* at top */ - update (); - topIndex--; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, itemHeight); - gc.dispose (); - return; - } - /* CTRL+Up Arrow */ - int focusIndex = focusItem.availableIndex; - if (focusIndex == 0) return; /* at top */ - TreeItem newFocusItem = availableItems [focusIndex - 1]; - setFocusItem (newFocusItem, true); - showItem (newFocusItem); - redrawItem (newFocusItem.availableIndex, true); - return; - } - /* Shift+Up Arrow */ - int newFocusIndex = focusItem.availableIndex - 1; - if (newFocusIndex < 0) return; /* at top */ - if (anchorItem == null) anchorItem = focusItem; - if (anchorItem.availableIndex < focusItem.availableIndex) { - deselectItem (focusItem); - redrawItem (focusItem.availableIndex, true); - } - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, true); - setFocusItem (item, true); - redrawItem (newFocusIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); -} -void onCR () { - if (focusItem == null) return; - Event event = new Event (); - event.item = focusItem; - postEvent (SWT.DefaultSelection, event); -} -void onDispose (Event event) { - if (isDisposed ()) return; - if (ignoreDispose) return; - ignoreDispose = true; - notifyListeners(SWT.Dispose, event); - event.type = SWT.None; - for (int i = 0; i < items.length; i++) { - items [i].dispose (false); - } - for (int i = 0; i < columns.length; i++) { - columns [i].dispose (false); - } - if (toolTipShell != null) { - toolTipShell.dispose (); - toolTipShell = null; - toolTipLabel = null; - } - toolTipListener = null; - topIndex = availableItemsCount = horizontalOffset = 0; - availableItems = items = selectedItems = null; - columns = orderedColumns = null; - focusItem = anchorItem = insertMarkItem = lastClickedItem = null; - lastSelectionEvent = null; - header = null; - resizeColumn = sortColumn = null; - expanderBounds = null; -} -void onEnd (int stateMask) { - int lastAvailableIndex = availableItemsCount - 1; - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* End with no modifiers */ - if (focusItem.availableIndex == lastAvailableIndex) return; /* at bottom */ - TreeItem item = availableItems [lastAvailableIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (lastAvailableIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+End, CTRL+Shift+End */ - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - setTopItem (availableItems [availableItemsCount - visibleItemCount]); - return; - } - /* Shift+End */ - if (focusItem.availableIndex == lastAvailableIndex) return; /* at bottom */ - TreeItem item = availableItems [lastAvailableIndex]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (lastAvailableIndex, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+End */ - showItem (availableItems [lastAvailableIndex]); - return; - } - /* CTRL+End */ - if (focusItem.availableIndex == lastAvailableIndex) return; /* at bottom */ - TreeItem item = availableItems [lastAvailableIndex]; - setFocusItem (item, true); - showItem (item); - redrawItem (item.availableIndex, true); - return; - } - /* Shift+End */ - if (anchorItem == null) anchorItem = focusItem; - TreeItem selectedItem = availableItems [lastAvailableIndex]; - if (selectedItem == focusItem && selectedItem.isSelected ()) return; - int anchorIndex = anchorItem.availableIndex; - int selectIndex = selectedItem.availableIndex; - TreeItem[] newSelection = new TreeItem [selectIndex - anchorIndex + 1]; - int writeIndex = 0; - for (int i = anchorIndex; i <= selectIndex; i++) { - newSelection [writeIndex++] = availableItems [i]; - } - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems (anchorIndex, selectIndex, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onFocusIn () { - hasFocus = true; - - if (items.length == 0) { - redraw (); - return; - } - if (focusItem != null) { - redrawItem (focusItem.availableIndex, true); - return; - } - /* an initial focus item must be selected */ - TreeItem initialFocus = null; - if (selectedItems.length > 0) { - for (int i = 0; i < selectedItems.length && initialFocus == null; i++) { - if (selectedItems [i].isAvailable ()) { - initialFocus = selectedItems [i]; - } - } - if (initialFocus == null) { - /* none of the selected items are available */ - initialFocus = availableItems [topIndex]; - } - } else { - initialFocus = availableItems [topIndex]; - } - setFocusItem (initialFocus, false); - redrawItem (initialFocus.availableIndex, true); - return; -} -void onFocusOut () { - hasFocus = false; - - if (items.length == 0) { - redraw (); - return; - } - - if (focusItem != null) { - redrawItem (focusItem.availableIndex, true); - } -} -void onHome (int stateMask) { - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* Home with no modifiers */ - if (focusItem.availableIndex == 0) return; /* at top */ - TreeItem item = availableItems [0]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (0, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+Home, CTRL+Shift+Home */ - setTopItem (availableItems [0]); - return; - } - /* Shift+Home */ - if (focusItem.availableIndex == 0) return; /* at top */ - TreeItem item = availableItems [0]; - selectItem (item, false); - setFocusItem (item, true); - redrawItem (0, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* CTRL+Shift+Home */ - setTopItem (availableItems [0]); - return; - } - /* CTRL+Home */ - if (focusItem.availableIndex == 0) return; /* at top */ - TreeItem item = availableItems [0]; - setFocusItem (item, true); - showItem (item); - redrawItem (item.availableIndex, true); - return; - } - /* Shift+Home */ - if (anchorItem == null) anchorItem = focusItem; - TreeItem selectedItem = availableItems [0]; - if (selectedItem == focusItem && selectedItem.isSelected ()) return; - int anchorIndex = anchorItem.availableIndex; - int selectIndex = selectedItem.availableIndex; - TreeItem[] newSelection = new TreeItem [anchorIndex + 1]; - int writeIndex = 0; - for (int i = anchorIndex; i >= 0; i--) { - newSelection [writeIndex++] = availableItems [i]; - } - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems (anchorIndex, selectIndex, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onKeyDown (Event event) { - if (ignoreKey) { - ignoreKey = false; - return; - } - ignoreKey = true; - notifyListeners (event.type, event); - event.type = SWT.None; - if (!event.doit) return; - if (focusItem == null) return; - if ((event.stateMask & SWT.SHIFT) == 0 && event.keyCode != SWT.SHIFT) { - anchorItem = null; - } - switch (event.keyCode) { - case SWT.ARROW_UP: - onArrowUp (event.stateMask); - return; - case SWT.ARROW_DOWN: - onArrowDown (event.stateMask); - return; - case SWT.ARROW_LEFT: - onArrowLeft (event.stateMask); - return; - case SWT.ARROW_RIGHT: - onArrowRight (event.stateMask); - return; - case SWT.PAGE_UP: - onPageUp (event.stateMask); - return; - case SWT.PAGE_DOWN: - onPageDown (event.stateMask); - return; - case SWT.HOME: - onHome (event.stateMask); - return; - case SWT.END: - onEnd (event.stateMask); - return; - } - if (event.character == ' ') { - onSpace (); - return; - } - if (event.character == SWT.CR) { - onCR (); - return; - } - if ((event.stateMask & SWT.CTRL) != 0) return; - - int initialIndex = focusItem.availableIndex; - char character = Character.toLowerCase (event.character); - /* check available items from current focus item to bottom */ - for (int i = initialIndex + 1; i < availableItemsCount; i++) { - TreeItem item = availableItems [i]; - String text = item.getText (0, false); - if (text.length() > 0) { - if (Character.toLowerCase (text.charAt (0)) == character) { - selectItem (item, false); - setFocusItem (item, true); - redrawItem (i, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - } - } - /* check available items from top to current focus item */ - for (int i = 0; i < initialIndex; i++) { - TreeItem item = availableItems [i]; - String text = item.getText (0, false); - if (text.length() > 0) { - if (Character.toLowerCase (text.charAt (0)) == character) { - selectItem (item, false); - setFocusItem (item, true); - redrawItem (i, true); - showItem (item); - Event newEvent = new Event (); - newEvent.item = item; - postEvent (SWT.Selection, newEvent); - return; - } - } - } -} -void onMouseDoubleClick (Event event) { - if (!isFocusControl ()) setFocus (); - int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < availableItemsCount)) return; /* not on an available item */ - TreeItem selectedItem = availableItems [index]; - - /* - * If the two clicks of the double click did not occur over the same item then do not - * consider this to be a default selection. - */ - if (selectedItem != lastClickedItem) return; - - /* if click was in expander box then don't fire event */ - if (selectedItem.items.length > 0 && selectedItem.getExpanderBounds ().contains (event.x, event.y)) { - return; - } - - if (!selectedItem.getHitBounds ().contains (event.x, event.y)) return; /* considers x */ - - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.DefaultSelection, newEvent); -} -void onMouseDown (Event event) { - if (!isFocusControl ()) forceFocus (); - int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < availableItemsCount)) return; /* not on an available item */ - TreeItem selectedItem = availableItems [index]; - - /* if click was in expander box */ - if (selectedItem.items.length > 0 && selectedItem.getExpanderBounds ().contains (event.x, event.y)) { - if (event.button != 1) return; - boolean expand = !selectedItem.expanded; - selectedItem.setExpanded (expand); - Event newEvent = new Event (); - newEvent.item = selectedItem; - if (expand) { - inExpand = true; - sendEvent (SWT.Expand, newEvent); - inExpand = false; - if (isDisposed ()) return; - if (selectedItem.items.length == 0) { - selectedItem.expanded = false; - } - } else { - sendEvent (SWT.Collapse, newEvent); - } - return; - } - /* if click was in checkbox */ - if ((style & SWT.CHECK) != 0 && selectedItem.getCheckboxBounds ().contains (event.x, event.y)) { - if (event.button != 1) return; - selectedItem.setChecked (!selectedItem.checked); - Event newEvent = new Event (); - newEvent.item = selectedItem; - newEvent.detail = SWT.CHECK; - postEvent (SWT.Selection, newEvent); - return; - } - - if (!selectedItem.getHitBounds ().contains (event.x, event.y)) return; - - if ((event.stateMask & SWT.SHIFT) == 0 && event.keyCode != SWT.SHIFT) anchorItem = null; - - boolean sendSelection = true; - /* Detect when this is the second click of a DefaultSelection and don't fire Selection */ - if (lastSelectionEvent != null && lastSelectionEvent.item == selectedItem) { - if (event.time - lastSelectionEvent.time <= display.getDoubleClickTime ()) { - sendSelection = false; - } else { - lastSelectionEvent = event; - event.item = selectedItem; - } - } else { - lastSelectionEvent = event; - event.item = selectedItem; - } - - if ((style & SWT.SINGLE) != 0) { - if (!selectedItem.isSelected ()) { - if (event.button == 1) { - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.availableIndex, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.availableIndex, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - } - /* item is selected */ - if (event.button == 1) { - /* fire a selection event, though the selection did not change */ - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - } - /* SWT.MULTI */ - if (!selectedItem.isSelected ()) { - if (event.button == 1) { - if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == SWT.SHIFT) { - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.availableIndex; - int selectIndex = selectedItem.availableIndex; - TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = availableItems [i]; - } - newSelection [writeIndex] = availableItems [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems ( - Math.min (anchorIndex, selectIndex), - Math.max (anchorIndex, selectIndex), - true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - selectItem (selectedItem, (event.stateMask & SWT.CTRL) != 0); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.availableIndex, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - /* button 3 */ - if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.availableIndex, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - } - /* item is selected */ - if (event.button != 1) return; - if ((event.stateMask & SWT.CTRL) != 0) { - removeSelectedItem (getSelectionIndex (selectedItem)); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.availableIndex, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - if ((event.stateMask & SWT.SHIFT) != 0) { - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.availableIndex; - int selectIndex = selectedItem.availableIndex; - TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = availableItems [i]; - } - newSelection [writeIndex] = availableItems [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - redrawItems ( - Math.min (anchorIndex, selectIndex), - Math.max (anchorIndex, selectIndex), - true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } - return; - } - selectItem (selectedItem, false); - setFocusItem (selectedItem, true); - redrawItem (selectedItem.availableIndex, true); - if (sendSelection) { - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); - } -} -void onMouseUp (Event event) { - int index = (event.y - getHeaderHeight ()) / itemHeight + topIndex; - if (!(0 <= index && index < availableItemsCount)) return; /* not on an available item */ - lastClickedItem = availableItems [index]; -} -void onPageDown (int stateMask) { - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* PageDown with no modifiers */ - int newFocusIndex = focusItem.availableIndex + visibleItemCount - 1; - newFocusIndex = Math.min (newFocusIndex, availableItemsCount - 1); - if (newFocusIndex == focusItem.availableIndex) return; - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.availableIndex, true); - return; - } - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == (SWT.CTRL | SWT.SHIFT)) { - /* CTRL+Shift+PageDown */ - int newTopIndex = topIndex + visibleItemCount; - newTopIndex = Math.min (newTopIndex, availableItemsCount - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopItem (availableItems [newTopIndex]); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* Shift+PageDown */ - int newFocusIndex = focusItem.availableIndex + visibleItemCount - 1; - newFocusIndex = Math.min (newFocusIndex, availableItemsCount - 1); - if (newFocusIndex == focusItem.availableIndex) return; - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.availableIndex, true); - return; - } - /* CTRL+PageDown */ - int newTopIndex = topIndex + visibleItemCount; - newTopIndex = Math.min (newTopIndex, availableItemsCount - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopItem (availableItems [newTopIndex]); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+PageDown */ - int bottomIndex = Math.min (topIndex + visibleItemCount - 1, availableItemsCount - 1); - if (focusItem.availableIndex != bottomIndex) { - /* move focus to bottom item in viewport */ - setFocusItem (availableItems [bottomIndex], true); - redrawItem (bottomIndex, true); - } else { - /* at bottom of viewport, so set focus to bottom item one page down */ - int newFocusIndex = Math.min (availableItemsCount - 1, bottomIndex + visibleItemCount); - if (newFocusIndex == focusItem.availableIndex) return; - setFocusItem (availableItems [newFocusIndex], true); - showItem (availableItems [newFocusIndex]); - redrawItem (newFocusIndex, true); - } - return; - } - /* Shift+PageDown */ - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.availableIndex; - int bottomIndex = Math.min (topIndex + visibleItemCount - 1, availableItemsCount - 1); - int selectIndex; - if (focusItem.availableIndex != bottomIndex) { - /* select from focus to bottom item in viewport */ - selectIndex = bottomIndex; - } else { - /* already at bottom of viewport, so select to bottom of one page down */ - selectIndex = Math.min (availableItemsCount - 1, bottomIndex + visibleItemCount); - if (selectIndex == focusItem.availableIndex && focusItem.isSelected ()) return; - } - TreeItem selectedItem = availableItems [selectIndex]; - TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = availableItems [i]; - } - newSelection [writeIndex] = availableItems [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onPageUp (int stateMask) { - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { - /* PageUp with no modifiers */ - int newFocusIndex = Math.max (0, focusItem.availableIndex - visibleItemCount + 1); - if (newFocusIndex == focusItem.availableIndex) return; - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.availableIndex, true); - return; - } - if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == (SWT.CTRL | SWT.SHIFT)) { - /* CTRL+Shift+PageUp */ - int newTopIndex = Math.max (0, topIndex - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopItem (availableItems [newTopIndex]); - return; - } - if ((style & SWT.SINGLE) != 0) { - if ((stateMask & SWT.SHIFT) != 0) { - /* Shift+PageUp */ - int newFocusIndex = Math.max (0, focusItem.availableIndex - visibleItemCount + 1); - if (newFocusIndex == focusItem.availableIndex) return; - TreeItem item = availableItems [newFocusIndex]; - selectItem (item, false); - setFocusItem (item, true); - showItem (item); - redrawItem (item.availableIndex, true); - return; - } - /* CTRL+PageUp */ - int newTopIndex = Math.max (0, topIndex - visibleItemCount); - if (newTopIndex == topIndex) return; - setTopItem (availableItems [newTopIndex]); - return; - } - /* SWT.MULTI */ - if ((stateMask & SWT.CTRL) != 0) { - /* CTRL+PageUp */ - if (focusItem.availableIndex != topIndex) { - /* move focus to top item in viewport */ - setFocusItem (availableItems [topIndex], true); - redrawItem (topIndex, true); - } else { - /* at top of viewport, so set focus to top item one page up */ - int newFocusIndex = Math.max (0, focusItem.availableIndex - visibleItemCount); - if (newFocusIndex == focusItem.availableIndex) return; - setFocusItem (availableItems [newFocusIndex], true); - showItem (availableItems [newFocusIndex]); - redrawItem (newFocusIndex, true); - } - return; - } - /* Shift+PageUp */ - if (anchorItem == null) anchorItem = focusItem; - int anchorIndex = anchorItem.availableIndex; - int selectIndex; - if (focusItem.availableIndex != topIndex) { - /* select from focus to top item in viewport */ - selectIndex = topIndex; - } else { - /* already at top of viewport, so select to top of one page up */ - selectIndex = Math.max (0, topIndex - visibleItemCount); - if (selectIndex == focusItem.availableIndex && focusItem.isSelected ()) return; - } - TreeItem selectedItem = availableItems [selectIndex]; - TreeItem[] newSelection = new TreeItem [Math.abs (anchorIndex - selectIndex) + 1]; - int step = anchorIndex < selectIndex ? 1 : -1; - int writeIndex = 0; - for (int i = anchorIndex; i != selectIndex; i += step) { - newSelection [writeIndex++] = availableItems [i]; - } - newSelection [writeIndex] = availableItems [selectIndex]; - setSelection (newSelection, false); - setFocusItem (selectedItem, true); - showItem (selectedItem); - Event newEvent = new Event (); - newEvent.item = selectedItem; - postEvent (SWT.Selection, newEvent); -} -void onPaint (Event event) { - TreeColumn[] orderedColumns = getOrderedColumns (); - GC gc = event.gc; - Rectangle clipping = gc.getClipping (); - int headerHeight = getHeaderHeight (); - int numColumns = orderedColumns.length; - int startColumn = -1, endColumn = -1; - if (numColumns > 0) { - startColumn = computeColumnIntersect (clipping.x, 0); - if (startColumn != -1) { /* the clip x is within a column's bounds */ - endColumn = computeColumnIntersect (clipping.x + clipping.width, startColumn); - if (endColumn == -1) endColumn = numColumns - 1; - } - } else { - startColumn = endColumn = 0; - } - - /* Determine the items to be painted */ - int startIndex = (clipping.y - headerHeight) / itemHeight + topIndex; - int endIndex = -1; - if (startIndex < availableItemsCount) { - endIndex = startIndex + Compatibility.ceil (clipping.height, itemHeight); - } - startIndex = Math.max (0, startIndex); - endIndex = Math.min (endIndex, availableItemsCount - 1); - - /* fill background not handled by items */ - gc.setBackground (getBackground ()); - gc.setClipping (clipping); - int bottomY = endIndex >= 0 ? getItemY (availableItems [endIndex]) + itemHeight : 0; - int fillHeight = Math.max (0, clientArea.height - bottomY); - if (fillHeight > 0) { /* space below bottom item */ - drawBackground (gc, 0, bottomY, clientArea.width, fillHeight); - } - if (columns.length > 0) { - TreeColumn column = orderedColumns [orderedColumns.length - 1]; /* last column */ - int rightX = column.getX () + column.width; - if (rightX < clientArea.width) { - drawBackground (gc, rightX, 0, clientArea.width - rightX, clientArea.height - fillHeight); - } - } - - /* paint the items */ - boolean noFocusDraw = false; - int[] lineDash = gc.getLineDash (); - int lineWidth = gc.getLineWidth (); - for (int i = startIndex; i <= Math.min (endIndex, availableItemsCount - 1); i++) { - TreeItem item = availableItems [i]; - if (!item.isDisposed ()) { /* ensure that item was not disposed in a callback */ - if (startColumn == -1) { - /* indicates that region to paint is to the right of the last column */ - noFocusDraw = item.paint (gc, null, true) || noFocusDraw; - } else { - if (numColumns == 0) { - noFocusDraw = item.paint (gc, null, false) || noFocusDraw; - } else { - for (int j = startColumn; j <= Math.min (endColumn, columns.length - 1); j++) { - if (!item.isDisposed ()) { /* ensure that item was not disposed in a callback */ - noFocusDraw = item.paint (gc, orderedColumns [j], false) || noFocusDraw; - } - if (isDisposed () || gc.isDisposed ()) return; /* ensure that receiver was not disposed in a callback */ - } - } - } - } - if (isDisposed () || gc.isDisposed ()) return; /* ensure that receiver was not disposed in a callback */ - } - - /* repaint grid lines */ - gc.setClipping(clipping); - gc.setLineWidth (lineWidth); - if (linesVisible) { - gc.setForeground (display.getSystemColor (SWT.COLOR_WIDGET_LIGHT_SHADOW)); - gc.setLineDash (lineDash); - if (numColumns > 0 && startColumn != -1) { - /* vertical column lines */ - for (int i = startColumn; i <= endColumn; i++) { - int x = orderedColumns [i].getX () + orderedColumns [i].width - 1; - gc.drawLine (x, clipping.y, x, clipping.y + clipping.height); - } - } - /* horizontal item lines */ - bottomY = clipping.y + clipping.height; - int rightX = clipping.x + clipping.width; - int y = (clipping.y - headerHeight) / itemHeight * itemHeight + headerHeight; - while (y <= bottomY) { - gc.drawLine (clipping.x, y, rightX, y); - y += itemHeight; - } - } - - /* draw focus rectangle */ - if (!noFocusDraw && isFocusControl ()) { - if (focusItem != null) { - Rectangle focusBounds = focusItem.getFocusBounds (); - if (focusBounds.width > 0) { - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - gc.setClipping (focusBounds); - if (focusItem.isSelected ()) { - gc.setLineDash (new int[] {2, 2}); - } else { - gc.setLineDash (new int[] {1, 1}); - } - gc.drawFocus (focusBounds.x, focusBounds.y, focusBounds.width, focusBounds.height); - } - } else { - /* no items, so draw focus border around Tree */ - int y = headerHeight + 1; - int width = Math.max (0, clientArea.width - 2); - int height = Math.max (0, clientArea.height - headerHeight - 2); - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - gc.setClipping (1, y, width, height); - gc.setLineDash (new int[] {1, 1}); - gc.drawFocus (1, y, width, height); - } - } - - /* draw insert mark */ - if (insertMarkItem != null) { - Rectangle focusBounds = insertMarkItem.getFocusBounds (); - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - gc.setClipping (focusBounds); - gc.setLineDash (lineDash); - if (insertMarkPrecedes) { - gc.drawLine (focusBounds.x, focusBounds.y, focusBounds.x + focusBounds.width, focusBounds.y); - } else { - int y = focusBounds.y + focusBounds.height - 1; - gc.drawLine (focusBounds.x, y, focusBounds.x + focusBounds.width, y); - } - } -} -void onResize (Event event) { - clientArea = getClientArea (); - /* vertical scrollbar */ - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - int clientHeight = (clientArea.height - getHeaderHeight ()) / itemHeight; - int thumb = Math.min (clientHeight, availableItemsCount); - vBar.setThumb (thumb); - vBar.setPageIncrement (thumb); - int index = vBar.getSelection (); - if (index != topIndex) { - topIndex = index; - redraw (); - } - boolean visible = clientHeight < availableItemsCount; - if (visible != vBar.getVisible ()) { - vBar.setVisible (visible); - clientArea = getClientArea (); - } - } - - /* horizontal scrollbar */ - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - int hBarMaximum = hBar.getMaximum (); - int thumb = Math.min (clientArea.width, hBarMaximum); - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - horizontalOffset = hBar.getSelection (); - boolean visible = clientArea.width < hBarMaximum; - if (visible != hBar.getVisible ()) { - hBar.setVisible (visible); - clientArea = getClientArea (); - } - } - - /* header */ - int headerHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding (); - header.setSize (clientArea.width, headerHeight); - - /* if this is the focus control but there are no items then the boundary focus ring must be repainted */ - if (availableItemsCount == 0 && isFocusControl ()) redraw (); -} -void onScrollHorizontal (Event event) { - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - int newSelection = hBar.getSelection (); - update (); - if (availableItemsCount > 0) { - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - } else { - redraw (); /* ensure that static focus rectangle updates properly */ - } - if (drawCount <= 0 && header.isVisible ()) { - header.update (); - Rectangle headerClientArea = header.getClientArea (); - GC gc = new GC (header); - gc.copyArea ( - 0, 0, - headerClientArea.width, headerClientArea.height, - horizontalOffset - newSelection, 0); - gc.dispose (); - } - horizontalOffset = newSelection; -} -void onScrollVertical (Event event) { - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - int newSelection = vBar.getSelection (); - update (); - GC gc = new GC (this); - gc.copyArea ( - 0, 0, - clientArea.width, clientArea.height, - 0, (topIndex - newSelection) * itemHeight); - gc.dispose (); - topIndex = newSelection; - } -} -void onSpace () { - if (focusItem == null) return; - if (!focusItem.isSelected ()) { - selectItem (focusItem, (style & SWT.MULTI) != 0); - redrawItem (focusItem.availableIndex, true); - } - if ((style & SWT.CHECK) != 0) { - focusItem.setChecked (!focusItem.checked); - } - showItem (focusItem); - Event event = new Event (); - event.item = focusItem; - postEvent (SWT.Selection, event); - if ((style & SWT.CHECK) == 0) return; - - /* SWT.CHECK */ - event = new Event (); - event.item = focusItem; - event.detail = SWT.CHECK; - postEvent (SWT.Selection, event); -} -/* - * The current focus item is about to become unavailable, so reassign focus. - */ -void reassignFocus () { - if (focusItem == null) return; - - /* reassign to current focus' parent item if it has one */ - if (focusItem.parentItem != null) { - TreeItem item = focusItem.parentItem; - setFocusItem (item, false); - showItem (item); - return; - } - - /* - * reassign to the previous root-level item if there is one, or the next - * root-level item otherwise - */ - int index = focusItem.getIndex (); - if (index != 0) { - index--; - } else { - index++; - } - if (index < items.length) { - TreeItem item = items [index]; - setFocusItem (item, false); - showItem (item); - } else { - setFocusItem (null, false); /* no items left */ - } -} -public void redraw () { - checkWidget (); - if (drawCount <= 0) super.redraw (); -} -public void redraw (int x, int y, int width, int height, boolean all) { - checkWidget (); - if (drawCount <= 0) super.redraw (x, y, width, height, all); -} -/* - * Redraws from the specified index down to the last available item inclusive. Note - * that the redraw bounds do not extend beyond the current last item, so clients - * that reduce the number of available items should use #redrawItems(int,int) instead - * to ensure that redrawing extends down to the previous bottom item boundary. - */ -void redrawFromItemDownwards (int index) { - redrawItems (index, availableItemsCount - 1, false); -} -/* - * Redraws the tree item at the specified index. It is valid for this index to reside - * beyond the last available item. - */ -void redrawItem (int itemIndex, boolean focusBoundsOnly) { - if (itemIndex == -1) return; - if (itemIndex < availableItemsCount && !availableItems [itemIndex].isInViewport ()) return; - redrawItems (itemIndex, itemIndex, focusBoundsOnly); -} -/* - * Redraws the tree between the start and end item indices inclusive. It is valid - * for the end index value to extend beyond the last available item. - */ -void redrawItems (int startIndex, int endIndex, boolean focusBoundsOnly) { - if (drawCount > 0) return; - - int startY = (startIndex - topIndex) * itemHeight + getHeaderHeight (); - int height = (endIndex - startIndex + 1) * itemHeight; - if (focusBoundsOnly) { - boolean custom = hooks (SWT.EraseItem) || hooks (SWT.PaintItem); - if (!custom && columns.length > 0) { - TreeColumn lastColumn; - if ((style & SWT.FULL_SELECTION) != 0) { - TreeColumn[] orderedColumns = getOrderedColumns (); - lastColumn = orderedColumns [orderedColumns.length - 1]; - } else { - lastColumn = columns [0]; - } - int rightX = lastColumn.getX () + lastColumn.getWidth (); - if (rightX <= 0) return; /* focus column(s) not visible */ - } - endIndex = Math.min (endIndex, availableItemsCount - 1); - for (int i = startIndex; i <= endIndex; i++) { - TreeItem item = availableItems [i]; - if (item.isInViewport ()) { - /* if custom painting is being done then repaint the full item */ - if (custom) { - redraw (0, getItemY (item), clientArea.width, itemHeight, false); - } else { - /* repaint the item's focus bounds */ - Rectangle bounds = item.getFocusBounds (); - redraw (bounds.x, startY, bounds.width, height, false); - } - } - } - } else { - redraw (0, startY, clientArea.width, height, false); - } -} -/** - * Removes all of the items from the receiver. - * - * @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 removeAll () { - checkWidget (); - if (items.length == 0) return; - setRedraw (false); - - setFocusItem (null, false); - for (int i = 0; i < items.length; i++) { - items [i].dispose (false); - } - items = availableItems = selectedItems = NO_ITEMS; - availableItemsCount = topIndex = 0; - anchorItem = lastClickedItem = insertMarkItem = null; - lastSelectionEvent = null; - inExpand = false; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - vBar.setMaximum (1); - vBar.setVisible (false); - } - if (columns.length == 0) { - horizontalOffset = 0; - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setMaximum (1); - hBar.setVisible (false); - } - } - - setRedraw (true); -} -String removeMnemonics (String string) { - /* removes single ampersands and preserves double-ampersands */ - char [] chars = new char [string.length ()]; - string.getChars (0, chars.length, chars, 0); - int i = 0, j = 0; - for ( ; i < chars.length; i++, j++) { - if (chars[i] == '&') { - if (++i == chars.length) break; - if (chars[i] == '&') { - chars[j++] = chars[i - 1]; - } - } - chars[j] = chars[i]; - } - if (i == j) return string; - return new String (chars, 0, j); -} -void removeSelectedItem (int index) { - TreeItem[] newSelectedItems = new TreeItem [selectedItems.length - 1]; - System.arraycopy (selectedItems, 0, newSelectedItems, 0, index); - System.arraycopy (selectedItems, index + 1, newSelectedItems, index, newSelectedItems.length - index); - selectedItems = newSelectedItems; -} -/** - * 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) 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) error (SWT.ERROR_NULL_ARGUMENT); - removeListener (SWT.Expand, listener); - removeListener (SWT.Collapse, listener); -} -/** - * Selects an item in the receiver. If the item was already - * selected, it remains selected. - * - * @param item the item to be selected - * - * @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> - * - * @since 3.4 - */ -public void select (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - selectItem (item, (style & SWT.MULTI) != 0); - redrawItem (item.availableIndex, true); -} -/** - * Selects all of the items in the receiver. - * <p> - * If the receiver is single-select, do nothing. - * </p> - * - * @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 selectAll () { - checkWidget (); - if ((style & SWT.SINGLE) != 0) return; - selectedItems = new TreeItem [availableItemsCount]; - System.arraycopy (availableItems, 0, selectedItems, 0, availableItemsCount); - redraw (); -} -void selectItem (TreeItem item, boolean addToSelection) { - TreeItem[] oldSelectedItems = selectedItems; - if (!addToSelection || (style & SWT.SINGLE) != 0) { - selectedItems = new TreeItem[] {item}; - for (int i = 0; i < oldSelectedItems.length; i++) { - if (oldSelectedItems [i] != item) { - redrawItem (oldSelectedItems [i].availableIndex, true); - } - } - } else { - if (item.isSelected ()) return; - selectedItems = new TreeItem [selectedItems.length + 1]; - System.arraycopy (oldSelectedItems, 0, selectedItems, 0, oldSelectedItems.length); - selectedItems [selectedItems.length - 1] = item; - } -} -public void setBackground (Color color) { - checkWidget (); - if (color == null) color = display.getSystemColor (SWT.COLOR_LIST_BACKGROUND); - super.setBackground (color); -} -/** - * Sets the order that the items in the receiver should - * be displayed in to the given argument which is described - * in terms of the zero-relative ordering of when the items - * were added. - * - * @param order the new order to display the items - * - * @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> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the item order is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li> - * </ul> - * - * @see Tree#getColumnOrder() - * @see TreeColumn#getMoveable() - * @see TreeColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.2 - */ -public void setColumnOrder (int [] order) { - checkWidget (); - if (order == null) error (SWT.ERROR_NULL_ARGUMENT); - if (columns.length == 0) { - if (order.length != 0) error (SWT.ERROR_INVALID_ARGUMENT); - return; - } - if (order.length != columns.length) error (SWT.ERROR_INVALID_ARGUMENT); - boolean reorder = false; - boolean [] seen = new boolean [columns.length]; - int[] oldOrder = getColumnOrder (); - for (int i = 0; i < order.length; i++) { - int index = order [i]; - if (index < 0 || index >= columns.length) error (SWT.ERROR_INVALID_RANGE); - if (seen [index]) error (SWT.ERROR_INVALID_ARGUMENT); - seen [index] = true; - if (index != oldOrder [i]) reorder = true; - } - if (!reorder) return; - - headerHideToolTip (); - int[] oldX = new int [columns.length]; - for (int i = 0; i < columns.length; i++) { - oldX [i] = columns [i].getX (); - } - orderedColumns = new TreeColumn [order.length]; - for (int i = 0; i < order.length; i++) { - orderedColumns [i] = columns [order [i]]; - } - /* - * If the first ordered column has changed then the old and new ordered column 0's - * have to recompute their display texts since they will now have just gained/lost - * space as a result of the hierarchy decorations that appear in ordered column 0. - */ - if (oldOrder [0] != order [0]) { - orderedCol0imageWidth = columns [order [0]].itemImageWidth; - GC gc = new GC (this); - for (int i = 0; i < items.length; i++) { - items [i].updateColumnWidth (columns [oldOrder [0]], gc); - items [i].updateColumnWidth (columns [order [0]], gc); - } - gc.dispose(); - } - for (int i = 0; i < orderedColumns.length; i++) { - TreeColumn column = orderedColumns [i]; - if (!column.isDisposed () && column.getX () != oldX [column.getIndex ()]) { - column.sendEvent (SWT.Move); - } - } - - redraw (); - if (drawCount <= 0 && header.isVisible ()) header.redraw (); -} -void setFocusItem (TreeItem item, boolean redrawOldFocus) { - if (item == focusItem) return; - TreeItem oldFocusItem = focusItem; - focusItem = item; - if (redrawOldFocus && oldFocusItem != null) { - redrawItem (oldFocusItem.availableIndex, true); - } -} -public void setFont (Font value) { - checkWidget (); - Font oldFont = getFont (); - super.setFont (value); - Font font = getFont (); - if (font.equals (oldFont)) return; - - GC gc = new GC (this); - - /* recompute the receiver's cached font height and item height values */ - fontHeight = gc.getFontMetrics ().getHeight (); - setItemHeight (Math.max (fontHeight, imageHeight) + 2 * getCellPadding ()); - Point headerSize = header.getSize (); - int newHeaderHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding (); - if (headerSize.y != newHeaderHeight) { - header.setSize (headerSize.x, newHeaderHeight); - } - header.setFont (font); - - /* - * Notify all columns and items of the font change so that elements that - * use the receiver's font can recompute their cached string widths. - */ - for (int i = 0; i < columns.length; i++) { - columns [i].updateFont (gc); - } - for (int i = 0; i < items.length; i++) { - items [i].updateFont (gc); - } - - gc.dispose (); - - if (drawCount <= 0 && header.isVisible ()) header.redraw (); - - /* update scrollbars */ - if (columns.length == 0) updateHorizontalBar (); - ScrollBar vBar = getVerticalBar (); - if (vBar != null) { - int thumb = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (vBar.getThumb () != thumb) { - vBar.setThumb (thumb); - vBar.setPageIncrement (thumb); - } - topIndex = vBar.getSelection (); - vBar.setVisible (thumb < vBar.getMaximum ()); - } - redraw (); -} -public void setForeground (Color color) { - checkWidget (); - if (color == null) color = display.getSystemColor (SWT.COLOR_LIST_FOREGROUND); - super.setForeground (color); -} -void setHeaderImageHeight (int value) { - headerImageHeight = value; - Point headerSize = header.getSize (); - int newHeaderHeight = Math.max (fontHeight, headerImageHeight) + 2 * getHeaderPadding (); - if (headerSize.y != newHeaderHeight) { - header.setSize (headerSize.x, newHeaderHeight); - } -} -/** - * Marks the receiver's header as visible if the argument is <code>true</code>, - * and marks it invisible otherwise. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, marking - * it visible may not actually cause it to be displayed. - * </p> - * - * @param show the new visibility state - * - * @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 void setHeaderVisible (boolean value) { - checkWidget (); - if (header.getVisible () == value) return; /* no change */ - headerHideToolTip (); - header.setVisible (value); - updateVerticalBar (); - redraw (); -} -void setImageHeight (int value) { - imageHeight = value; - setItemHeight (Math.max (fontHeight, imageHeight) + 2 * getCellPadding ()); -} -/** - * Display a mark indicating the point at which an item will be inserted. - * The drop insert item has a visual hint to show where a dragged item - * will be inserted when dropped on the tree. - * - * @param item the insert item. Null will clear the insertion mark. - * @param before true places the insert mark above 'item'. false places - * the insert mark below 'item'. - * - * @exception IllegalArgumentException <ul> - * <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> - */ -public void setInsertMark (TreeItem item, boolean before) { - checkWidget (); - if (item != null && item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (item != null && item.parent != this) return; - if (item == insertMarkItem && before == insertMarkPrecedes) return; /* no change */ - - TreeItem oldInsertItem = insertMarkItem; - insertMarkItem = item; - insertMarkPrecedes = before; - if (oldInsertItem != null && oldInsertItem.availableIndex != -1) { - redrawItem (oldInsertItem.availableIndex, true); - } - if (item != null && item != oldInsertItem && item.availableIndex != -1) { - redrawItem (item.availableIndex, true); - } -} -/** - * Sets the number of root-level items contained in the receiver. - * - * @param count the number of items - * - * @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.2 - */ -public void setItemCount (int count) { - checkWidget (); - count = Math.max (0, count); - if (count == items.length) return; - int oldCount = availableItemsCount; - int redrawStart, redrawEnd; - - /* if the new item count is less than the current count then remove all excess items from the end */ - if (count < items.length) { - redrawStart = count > 0 ? items [count - 1].availableIndex : 0; - redrawEnd = availableItemsCount - 1; - availableItemsCount = items [count].availableIndex; - for (int i = count; i < items.length; i++) { - items [i].dispose (false); - } - if (count == 0) { - items = Tree.NO_ITEMS; - } else { - TreeItem[] newItems = new TreeItem [count]; - System.arraycopy (items, 0, newItems, 0, count); - items = newItems; - } - - int newSelectedCount = 0; - for (int i = 0; i < selectedItems.length; i++) { - if (!selectedItems [i].isDisposed ()) newSelectedCount++; - } - if (newSelectedCount != selectedItems.length) { - /* one or more selected items have been disposed */ - TreeItem[] newSelectedItems = new TreeItem [newSelectedCount]; - int pos = 0; - for (int i = 0; i < selectedItems.length; i++) { - TreeItem item = selectedItems [i]; - if (!item.isDisposed ()) { - newSelectedItems [pos++] = item; - } - } - selectedItems = newSelectedItems; - } - - if (insertMarkItem != null && insertMarkItem.isDisposed ()) insertMarkItem = null; - if (lastClickedItem != null && lastClickedItem.isDisposed ()) lastClickedItem = null; - if (anchorItem != null && anchorItem.isDisposed ()) anchorItem = null; - if (focusItem != null && focusItem.isDisposed ()) { - TreeItem newFocusItem = count > 0 ? items [count - 1] : null; - setFocusItem (newFocusItem, false); - } - if (columns.length == 0) updateHorizontalBar (); - } else { - int grow = count - items.length; - redrawStart = items.length == 0 ? 0 : items [items.length - 1].availableIndex; - redrawEnd = availableItemsCount + grow - 1; - TreeItem[] newItems = new TreeItem [count]; - System.arraycopy (items, 0, newItems, 0, items.length); - items = newItems; - if (availableItems.length < availableItemsCount + grow) { - TreeItem[] newAvailableItems = new TreeItem [availableItemsCount + grow]; - System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItemsCount); - availableItems = newAvailableItems; - } - for (int i = items.length - grow; i < count; i++) { - TreeItem newItem = new TreeItem (this, SWT.NONE, i, false); - items [i] = newItem; - items [i].availableIndex = availableItemsCount; - availableItems [availableItemsCount++] = newItem; - } - if (oldCount == 0) focusItem = availableItems [0]; - } - - updateVerticalBar (); - /* - * If this is the focus control and the available item count is going from 0->!0 or !0->0 - * then the receiver must be redrawn to ensure that its boundary focus ring is updated. - */ - if ((oldCount == 0 || availableItemsCount == 0) && isFocusControl ()) { - redraw (); - return; - } - redrawItems (redrawStart, redrawEnd, false); -} -boolean setItemHeight (int value) { - boolean update = !customHeightSet || itemHeight < value; - if (update) itemHeight = value; - return update; -} -/** - * Marks the receiver's lines as visible if the argument is <code>true</code>, - * and marks it invisible otherwise. Note that some platforms draw - * grid lines while others may draw alternating row colors. - * <p> - * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, marking - * it visible may not actually cause it to be displayed. - * </p> - * - * @param show the new visibility state - * - * @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 void setLinesVisible (boolean value) { - checkWidget (); - if (linesVisible == value) return; /* no change */ - linesVisible = value; - redraw (); -} -public void setMenu (Menu menu) { - super.setMenu (menu); - header.setMenu (menu); -} -public void setRedraw (boolean value) { - checkWidget(); - if (value) { - if (--drawCount == 0) { - if (availableItems.length - availableItemsCount > 3) { - TreeItem[] newAvailableItems = new TreeItem [availableItemsCount]; - System.arraycopy (availableItems, 0, newAvailableItems, 0, availableItemsCount); - availableItems = newAvailableItems; - } - updateVerticalBar (); - updateHorizontalBar (); - } - } else { - drawCount++; - } - super.setRedraw (value); - header.setRedraw (value); -} -/** - * Sets the receiver's selection to the given item. - * The current selection is cleared before the new item is selected. - * <p> - * If the item is not in the receiver, then it is ignored. - * </p> - * - * @param item the item to select - * - * @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> - * - * @since 3.2 - */ -public void setSelection (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - setSelection (new TreeItem [] {item}, true); -} -/** - * 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. - * </p> - * - * @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 items 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 Tree#deselectAll() - */ -public void setSelection (TreeItem[] items) { - checkWidget (); - if (items == null) error (SWT.ERROR_NULL_ARGUMENT); - setSelection (items, true); -} - -void setSelection (TreeItem[] items, boolean updateViewport) { - if (items.length == 0 || ((style & SWT.SINGLE) != 0 && items.length > 1)) { - deselectAll (); - return; - } - TreeItem[] oldSelection = selectedItems; - - /* remove null and duplicate items */ - int index = 0; - selectedItems = new TreeItem [items.length]; /* initially assume all valid items */ - for (int i = 0; i < items.length; i++) { - TreeItem item = items [i]; - if (item != null && item.parent == this && !item.isSelected ()) { - selectedItems [index++] = item; - } - } - if (index != items.length) { - /* an invalid item was provided so resize the array accordingly */ - TreeItem[] temp = new TreeItem [index]; - System.arraycopy (selectedItems, 0, temp, 0, index); - selectedItems = temp; - } - if (selectedItems.length == 0) { /* no valid items */ - deselectAll (); - return; - } - - for (int i = 0; i < oldSelection.length; i++) { - if (!oldSelection [i].isSelected ()) { - int availableIndex = oldSelection [i].availableIndex; - if (availableIndex != -1) { - redrawItem (availableIndex, true); - } - } - } - if (updateViewport) { - showItem (selectedItems [0]); - setFocusItem (selectedItems [0], true); - } - for (int i = 0; i < selectedItems.length; i++) { - int availableIndex = selectedItems [i].availableIndex; - if (availableIndex != -1) { - redrawItem (availableIndex, true); - } - } -} -/** - * Sets the column used by the sort indicator for the receiver. A null - * value will clear the sort indicator. The current sort column is cleared - * before the new column is set. - * - * @param column the column used by the sort indicator or <code>null</code> - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the column is 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.2 - */ -public void setSortColumn (TreeColumn column) { - checkWidget (); - if (column != null && column.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (column == sortColumn) return; - if (sortColumn != null && !sortColumn.isDisposed ()) { - sortColumn.setSortDirection (SWT.NONE); - } - sortColumn = column; - if (sortColumn != null) { - sortColumn.setSortDirection (sortDirection); - } -} -/** - * Sets the direction of the sort indicator for the receiver. The value - * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>. - * - * @param direction the direction of the sort indicator - * - * @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.2 - */ -public void setSortDirection (int direction) { - checkWidget (); - if (direction != SWT.UP && direction != SWT.DOWN && direction != SWT.NONE) return; - sortDirection = direction; - if (sortColumn == null || sortColumn.isDisposed ()) return; - sortColumn.setSortDirection (sortDirection); -} -/** - * Sets the item which is currently at the top of the receiver. - * This item can change when items are expanded, collapsed, scrolled - * or new items are added or removed. - * - * @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 Tree#getTopItem() - * - * @since 2.1 - */ -public void setTopItem (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (item.parent != this) return; - - /* item must be available */ - if (!item.isAvailable ()) item.parentItem.expandAncestors (); - - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - if (availableItemsCount < visibleItemCount) return; - int index = Math.min (item.availableIndex, availableItemsCount - visibleItemCount); - if (topIndex == index) return; - - update (); - int change = topIndex - index; - topIndex = index; - ScrollBar vBar = getVerticalBar (); - if (vBar != null) vBar.setSelection (topIndex); - if (drawCount <= 0) { - GC gc = new GC (this); - gc.copyArea (0, 0, clientArea.width, clientArea.height, 0, change * itemHeight); - gc.dispose (); - } -} -/** - * Shows the column. If the column is already showing in the receiver, - * this method simply returns. Otherwise, the columns are scrolled until - * the column is visible. - * - * @param column the column 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> - * - * @since 3.1 - */ -public void showColumn (TreeColumn column) { - checkWidget (); - if (column == null) error (SWT.ERROR_NULL_ARGUMENT); - if (column.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT); - if (column.parent != this) return; - - int x = column.getX (); - int rightX = x + column.width; - if (0 <= x && rightX <= clientArea.width) return; /* column is fully visible */ - - headerHideToolTip (); - int absX = 0; /* the X of the column irrespective of the horizontal scroll */ - TreeColumn[] orderedColumns = getOrderedColumns (); - for (int i = 0; i < column.getOrderIndex (); i++) { - absX += orderedColumns [i].width; - } - if (x < clientArea.x) { /* column is to left of viewport */ - horizontalOffset = absX; - } else { - horizontalOffset = absX + column.width - clientArea.width; - } - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) hBar.setSelection (horizontalOffset); - redraw (); - if (drawCount <= 0 && header.isVisible ()) header.redraw (); -} -/** - * 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 Tree#showSelection() - */ -public void showItem (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (item.parent != this) return; - - /* item must be available */ - if (!item.isAvailable ()) item.parentItem.expandAncestors (); - - int index = item.availableIndex; - int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight; - /* nothing to do if item is already in viewport */ - if (topIndex <= index && index < topIndex + visibleItemCount) return; - - if (index <= topIndex) { - /* item is above current viewport, so show on top */ - setTopItem (item); - } else { - /* item is below current viewport, so show on bottom */ - visibleItemCount = Math.max (visibleItemCount, 1); /* item to show should be top item */ - setTopItem (availableItems [Math.min (index - visibleItemCount + 1, availableItemsCount - 1)]); - } -} -/** - * Shows the selection. If the selection is already showing in the receiver, - * this method simply returns. Otherwise, the items are scrolled until - * the selection is visible. - * - * @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 Tree#showItem(TreeItem) - */ -public void showSelection () { - checkWidget (); - if (selectedItems.length == 0) return; - showItem (selectedItems [0]); -} -void updateColumnWidth (TreeColumn column, int width) { - headerHideToolTip (); - int oldWidth = column.width; - int columnX = column.getX (); - int x = columnX + oldWidth - 1; /* -1 ensures that grid line is included */ - - update (); - GC gc = new GC (this); - gc.copyArea (x, 0, clientArea.width - x, clientArea.height, columnX + width - 1, 0); /* dest x -1 offsets x's -1 above */ - if (width > oldWidth) { - /* column width grew */ - int change = width - oldWidth + 1; /* +1 offsets x's -1 above */ - /* -1/+1 below ensure that right bound of selection redraws correctly in column */ - redraw (x - 1, 0, change + 1, clientArea.height, false); - } else { - int change = oldWidth - width + 1; /* +1 offsets x's -1 above */ - redraw (clientArea.width - change, 0, change, clientArea.height, false); - } - /* the focus box must be repainted because its stipple may become shifted as a result of its new width */ - if (focusItem != null) redrawItem (focusItem.availableIndex, true); - - GC headerGC = new GC (header); - if (drawCount <= 0 && header.getVisible ()) { - Rectangle headerBounds = header.getClientArea (); - header.update (); - x -= 1; /* -1 ensures that full header column separator is included */ - headerGC.copyArea (x, 0, headerBounds.width - x, headerBounds.height, columnX + width - 2, 0); /* dest x -2 offsets x's -1s above */ - if (width > oldWidth) { - /* column width grew */ - int change = width - oldWidth + 2; /* +2 offsets x's -1s above */ - header.redraw (x, 0, change, headerBounds.height, false); - } else { - int change = oldWidth - width + 2; /* +2 offsets x's -1s above */ - header.redraw (headerBounds.width - change, 0, change, headerBounds.height, false); - } - } - - column.width = width; - - /* - * Notify column and all items of column width change so that display labels - * can be recomputed if needed. - */ - column.updateWidth (headerGC); - headerGC.dispose (); - for (int i = 0; i < items.length; i++) { - items [i].updateColumnWidth (column, gc); - } - gc.dispose (); - - int maximum = 0; - for (int i = 0; i < columns.length; i++) { - maximum += columns [i].width; - } - ScrollBar hBar = getHorizontalBar (); - if (hBar != null) { - hBar.setMaximum (Math.max (1, maximum)); /* setting a value of 0 here is ignored */ - if (hBar.getThumb () != clientArea.width) { - hBar.setThumb (clientArea.width); - hBar.setPageIncrement (clientArea.width); - } - int oldHorizontalOffset = horizontalOffset; /* hBar.setVisible() can modify horizontalOffset */ - hBar.setVisible (clientArea.width < maximum); - int selection = hBar.getSelection (); - if (selection != oldHorizontalOffset) { - horizontalOffset = selection; - redraw (); - if (drawCount <= 0 && header.getVisible ()) header.redraw (); - } - } - - column.sendEvent (SWT.Resize); - TreeColumn[] orderedColumns = getOrderedColumns (); - for (int i = column.getOrderIndex () + 1; i < orderedColumns.length; i++) { - if (!orderedColumns [i].isDisposed ()) { - orderedColumns [i].sendEvent (SWT.Move); - } - } - - if (availableItemsCount == 0) redraw (); /* ensure that static focus rectangle updates properly */ -} -/* - * This is a naive implementation that computes the value from scratch. - */ -void updateHorizontalBar () { - if (drawCount > 0) return; - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - - int maxX = 0; - if (columns.length > 0) { - for (int i = 0; i < columns.length; i++) { - maxX += columns [i].width; - } - } else { - for (int i = 0; i < availableItemsCount; i++) { - Rectangle itemBounds = availableItems [i].getCellBounds (0); - maxX = Math.max (maxX, itemBounds.x + itemBounds.width + horizontalOffset); - } - } - - int clientWidth = clientArea.width; - if (maxX != hBar.getMaximum ()) { - hBar.setMaximum (Math.max (1, maxX)); /* setting a value of 0 here is ignored */ - } - int thumb = Math.min (clientWidth, maxX); - if (thumb != hBar.getThumb ()) { - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - } - hBar.setVisible (clientWidth < maxX); - - /* reclaim any space now left on the right */ - if (maxX < horizontalOffset + thumb) { - horizontalOffset = maxX - thumb; - hBar.setSelection (horizontalOffset); - redraw (); - } else { - int selection = hBar.getSelection (); - if (selection != horizontalOffset) { - horizontalOffset = selection; - redraw (); - } - } -} -/* - * Update the horizontal bar, if needed, in response to an item change (eg.- created, - * disposed, expanded, etc.). newRightX is the new rightmost X value of the item, - * and rightXchange is the change that led to the item's rightmost X value becoming - * newRightX (so oldRightX + rightXchange = newRightX) - */ -void updateHorizontalBar (int newRightX, int rightXchange) { - if (drawCount > 0) return; - ScrollBar hBar = getHorizontalBar (); - if (hBar == null) return; - - newRightX += horizontalOffset; - int barMaximum = hBar.getMaximum (); - if (newRightX > barMaximum) { /* item has extended beyond previous maximum */ - hBar.setMaximum (newRightX); - int clientAreaWidth = clientArea.width; - int thumb = Math.min (newRightX, clientAreaWidth); - if (hBar.getThumb () != thumb) { - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - } - hBar.setVisible (clientAreaWidth <= newRightX); - return; - } - - int previousRightX = newRightX - rightXchange; - if (previousRightX != barMaximum) { - /* this was not the rightmost item, so just check for client width change */ - int clientAreaWidth = clientArea.width; - int thumb = Math.min (barMaximum, clientAreaWidth); - if (hBar.getThumb () != thumb) { - hBar.setThumb (thumb); - hBar.setPageIncrement (thumb); - } - hBar.setVisible (clientAreaWidth <= barMaximum); - return; - } - updateHorizontalBar (); /* must search for the new rightmost item */ -} -void updateVerticalBar () { - if (drawCount > 0) return; - ScrollBar vBar = getVerticalBar (); - if (vBar == null) return; - - int pageSize = (clientArea.height - getHeaderHeight ()) / itemHeight; - int maximum = Math.max (1, availableItemsCount); - if (maximum != vBar.getMaximum ()) { - vBar.setMaximum (maximum); - } - int thumb = Math.min (pageSize, maximum); - if (thumb != vBar.getThumb ()) { - vBar.setThumb (thumb); - vBar.setPageIncrement (thumb); - } - vBar.setVisible (pageSize < maximum); - - /* reclaim any space now left on the bottom */ - if (maximum < topIndex + thumb) { - topIndex = maximum - thumb; - vBar.setSelection (topIndex); - redraw (); - } else { - int selection = vBar.getSelection (); - if (selection != topIndex) { - topIndex = selection; - redraw (); - } - } -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TreeColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TreeColumn.java deleted file mode 100644 index 41d1715a87..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TreeColumn.java +++ /dev/null @@ -1,738 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.widgets; - -import org.eclipse.swt.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; - -/** - * Instances of this class represent a column in a tree widget. - * <p><dl> - * <dt><b>Styles:</b></dt> - * <dd>LEFT, RIGHT, CENTER</dd> - * <dt><b>Events:</b></dt> - * <dd> Move, Resize, Selection</dd> - * </dl> - * </p><p> - * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified. - * </p><p> - * IMPORTANT: This class is <em>not</em> intended to be subclassed. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * - * @since 3.1 - * @noextend This class is not intended to be subclassed by clients. - */ -public class TreeColumn extends Item { - Tree parent; - String displayText = ""; - int width, itemImageWidth; - boolean moveable, resizable = true; - int sort = SWT.NONE; - String toolTipText; - -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Tree</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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TreeColumn (Tree parent, int style) { - this (parent, style, checkNull (parent).columns.length); -} -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Tree</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> - * <p> - * Note that due to a restriction on some platforms, the first column - * is always left aligned. - * </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 zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> - * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TreeColumn (Tree parent, int style, int index) { - super (parent, checkStyle (style), index); - if (!(0 <= index && index <= parent.columns.length)) error (SWT.ERROR_INVALID_RANGE); - this.parent = parent; - parent.createItem (this, index); -} -/** - * Adds the listener to the collection of listeners who will - * be notified when the control is moved or resized, by sending - * it one of the messages defined in the <code>ControlListener</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 ControlListener - * @see #removeControlListener - */ -public void addControlListener (ControlListener listener) { - checkWidget (); - if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Resize, typedListener); - addListener (SWT.Move, typedListener); -} -/** - * Adds the listener to the collection of listeners who will - * be notified when the control is selected by the user, by sending - * it one of the messages defined in the <code>SelectionListener</code> - * interface. - * <p> - * <code>widgetSelected</code> is called when the column header is selected. - * <code>widgetDefaultSelected</code> is not called. - * </p> - * - * @param listener the listener which should be notified when the control is selected by the user - * - * @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) error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Selection, typedListener); - addListener (SWT.DefaultSelection, typedListener); -} -static Tree checkNull (Tree tree) { - if (tree == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - return tree; -} -static int checkStyle (int style) { - return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0); -} -protected void checkSubclass () { - if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); -} -void computeDisplayText (GC gc) { - int availableWidth = width - 2 * parent.getHeaderPadding (); - if (image != null) { - availableWidth -= image.getBounds ().width; - availableWidth -= Tree.MARGIN_IMAGE; - } - if (sort != SWT.NONE) { - availableWidth -= parent.arrowBounds.width; - availableWidth -= Tree.MARGIN_IMAGE; - } - String text = this.text; - int textWidth = gc.textExtent (text, SWT.DRAW_MNEMONIC).x; - if (textWidth <= availableWidth) { - displayText = text; - return; - } - - /* Ellipsis will be needed, so subtract their width from the available text width */ - int ellipsisWidth = gc.stringExtent (Tree.ELLIPSIS).x; - availableWidth -= ellipsisWidth; - if (availableWidth <= 0) { - displayText = Tree.ELLIPSIS; - return; - } - - /* Make initial guess. */ - int index = Math.min (availableWidth / gc.getFontMetrics ().getAverageCharWidth (), text.length ()); - textWidth = gc.textExtent (text.substring (0, index), SWT.DRAW_MNEMONIC).x; - - /* Initial guess is correct. */ - if (availableWidth == textWidth) { - displayText = text.substring (0, index) + Tree.ELLIPSIS; - return; - } - - /* Initial guess is too high, so reduce until fit is found. */ - if (availableWidth < textWidth) { - do { - index--; - if (index < 0) { - displayText = Tree.ELLIPSIS; - return; - } - text = text.substring (0, index); - textWidth = gc.textExtent (text, SWT.DRAW_MNEMONIC).x; - } while (availableWidth < textWidth); - displayText = text + Tree.ELLIPSIS; - return; - } - - /* Initial guess is too low, so increase until overrun is found. */ - while (textWidth < availableWidth) { - index++; - textWidth = gc.textExtent (text.substring (0, index), SWT.DRAW_MNEMONIC).x; - } - displayText = text.substring (0, index - 1) + Tree.ELLIPSIS; -} -public void dispose () { - if (isDisposed ()) return; - Rectangle parentBounds = parent.clientArea; - int x = getX (); - Tree parent = this.parent; - dispose (true); - int width = parentBounds.width - x; - parent.redraw (x, 0, width, parentBounds.height, false); - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - parent.header.redraw (x, 0, width, parent.getHeaderHeight (), false); - } -} -void dispose (boolean notifyParent) { - super.dispose (); /* super is intentional here */ - if (notifyParent) parent.destroyItem (this); - parent = null; -} -/** - * Returns a value which describes the position of the - * text or image in the receiver. The value will be one of - * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>. - * - * @return the alignment - * - * @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 int getAlignment () { - checkWidget (); - if ((style & SWT.CENTER) != 0) return SWT.CENTER; - if ((style & SWT.RIGHT) != 0) return SWT.RIGHT; - return SWT.LEFT; -} -/* - * Returns the width of the header's content - * (image + text + sort arrow + internal margins) - */ -int getContentWidth (GC gc, boolean useDisplayText) { - int contentWidth = 0; - String text = useDisplayText ? displayText : this.text; - if (text.length () > 0) { - contentWidth += gc.textExtent (text, SWT.DRAW_MNEMONIC).x; - } - if (image != null) { - contentWidth += image.getBounds ().width; - if (text.length () > 0) contentWidth += Tree.MARGIN_IMAGE; - } - if (sort != SWT.NONE) { - contentWidth += parent.arrowBounds.width; - if (text.length () > 0 || image != null) { - contentWidth += Tree.MARGIN_IMAGE; - } - } - return contentWidth; -} -int getIndex () { - TreeColumn[] columns = parent.columns; - for (int i = 0; i < columns.length; i++) { - if (columns [i] == this) return i; - } - return -1; -} -/** - * Gets the moveable attribute. A column that is - * not moveable cannot be reordered by the user - * by dragging the header but may be reordered - * by the programmer. - * - * @return the moveable attribute - * - * @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 Tree#getColumnOrder() - * @see Tree#setColumnOrder(int[]) - * @see TreeColumn#setMoveable(boolean) - * @see SWT#Move - * - * @since 3.2 - */ -public boolean getMoveable () { - checkWidget (); - return moveable; -} -int getOrderIndex () { - TreeColumn[] orderedColumns = parent.orderedColumns; - if (orderedColumns == null) return getIndex (); - for (int i = 0; i < orderedColumns.length; i++) { - if (orderedColumns [i] == this) return i; - } - return -1; -} -/** - * Returns the receiver's parent, which must be a <code>Tree</code>. - * - * @return the receiver's parent - * - * @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 Tree getParent () { - checkWidget (); - return parent; -} -int getPreferredWidth () { - if (!parent.getHeaderVisible ()) return 0; - GC gc = new GC (parent); - int result = getContentWidth (gc, false); - gc.dispose (); - return result + 2 * parent.getHeaderPadding (); -} -/** - * Gets the resizable attribute. A column that is - * not resizable cannot be dragged by the user but - * may be resized by the programmer. - * - * @return the resizable attribute - * - * @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 getResizable () { - checkWidget (); - return resizable; -} -/** - * Returns the receiver's tool tip text, or null if it has - * not been set. - * - * @return the receiver's tool tip text - * - * @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.2 - */ -public String getToolTipText () { - checkWidget (); - return toolTipText; -} -/** - * Gets the width of the receiver. - * - * @return the width - * - * @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 int getWidth () { - checkWidget (); - return width; -} -int getX () { - TreeColumn[] orderedColumns = parent.getOrderedColumns (); - int index = getOrderIndex (); - int result = -parent.horizontalOffset; - for (int i = 0; i < index; i++) { - result += orderedColumns [i].width; - } - return result; -} -void paint (GC gc) { - int padding = parent.getHeaderPadding (); - - int x = getX (); - int startX = x + padding; - if (getOrderIndex () != 0 && (style & SWT.LEFT) == 0) { - int contentWidth = getContentWidth (gc, true); - if ((style & SWT.RIGHT) != 0) { - startX = Math.max (startX, x + width - padding - contentWidth); - } else { /* SWT.CENTER */ - startX = Math.max (startX, x + (width - contentWidth) / 2); - } - } - int headerHeight = parent.getHeaderHeight (); - - /* restrict the clipping region to the header cell */ - gc.setClipping ( - x + padding, - padding, - width - 2 * padding, - headerHeight - 2 * padding); - - if (image != null) { - Rectangle imageBounds = image.getBounds (); - int drawHeight = Math.min (imageBounds.height, headerHeight - 2 * padding); - gc.drawImage ( - image, - 0, 0, - imageBounds.width, imageBounds.height, - startX, (headerHeight - drawHeight) / 2, - imageBounds.width, drawHeight); - startX += imageBounds.width; - startX += Tree.MARGIN_IMAGE; - } - if (displayText.length () > 0) { - gc.setForeground (display.getSystemColor (SWT.COLOR_BLACK)); - int fontHeight = parent.fontHeight; - gc.drawText (displayText, startX, (headerHeight - fontHeight) / 2, SWT.DRAW_MNEMONIC); - startX += gc.textExtent (displayText, SWT.DRAW_MNEMONIC).x + Tree.MARGIN_IMAGE; - } - if (sort != SWT.NONE) { - Image image = sort == SWT.DOWN ? parent.getArrowDownImage () : parent.getArrowUpImage (); - int y = (headerHeight - parent.arrowBounds.height) / 2; - gc.drawImage (image, startX, y); - } -} -/** - * Causes the receiver to be resized to its preferred size. - * For a composite, this involves computing the preferred size - * from its layout, if there is one. - * - * @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 pack () { - checkWidget (); - TreeItem[] availableItems = parent.availableItems; - int index = getIndex (); - int newWidth = getPreferredWidth (); - for (int i = 0; i < parent.availableItemsCount; i++) { - int width = availableItems [i].getPreferredWidth (index); - /* ensure that receiver and parent were not disposed in a callback */ - if (parent.isDisposed () || isDisposed ()) return; - if (!availableItems [i].isDisposed ()) { - newWidth = Math.max (newWidth, width); - } - } - if (newWidth != width) parent.updateColumnWidth (this, newWidth); -} -/** - * Removes the listener from the collection of listeners who will - * be notified when the control is moved or resized. - * - * @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 ControlListener - * @see #addControlListener - */ -public void removeControlListener (ControlListener listener) { - checkWidget (); - if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); - if (eventTable == null) return; - eventTable.unhook (SWT.Move, listener); - eventTable.unhook (SWT.Resize, listener); -} -/** - * Removes the listener from the collection of listeners who will - * be notified when the control is selected by the user. - * - * @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) error (SWT.ERROR_NULL_ARGUMENT); - removeListener (SWT.Selection, listener); - removeListener (SWT.DefaultSelection, listener); -} -/** - * Controls how text and images will be displayed in the receiver. - * The argument should be one of <code>LEFT</code>, <code>RIGHT</code> - * or <code>CENTER</code>. - * <p> - * Note that due to a restriction on some platforms, the first column - * is always left aligned. - * </p> - * @param alignment the new alignment - * - * @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 setAlignment (int alignment) { - checkWidget (); - if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return; - alignment = checkBits (alignment, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0); - if ((style & alignment) != 0) return; /* same value */ - style &= ~(SWT.LEFT | SWT.CENTER | SWT.RIGHT); - style |= alignment; - if (getOrderIndex () == 0) return; /* no update needed since first ordered column appears left-aligned */ - int x = getX (); - parent.redraw (x, 0, width, parent.clientArea.height, false); - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (x, 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -public void setImage (Image value) { - checkWidget (); - if (value == image) return; - if (value != null && value.equals (image)) return; /* same value */ - super.setImage (value); - - /* An image width change may affect the space available for the column's displayText. */ - GC gc = new GC (parent); - computeDisplayText (gc); - gc.dispose (); - - /* - * If this is the first image being put into the header then the header - * height may be adjusted, in which case a full redraw is needed. - */ - if (parent.headerImageHeight == 0) { - int oldHeaderHeight = parent.getHeaderHeight (); - parent.setHeaderImageHeight (value.getBounds ().height); - if (oldHeaderHeight != parent.getHeaderHeight ()) { - /* parent header height changed */ - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - parent.header.redraw (); - } - parent.redraw (); - return; - } - } - - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (getX (), 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -/** - * Sets the moveable attribute. A column that is - * moveable can be reordered by the user by dragging - * the header. A column that is not moveable cannot be - * dragged by the user but may be reordered - * by the programmer. - * - * @param moveable the moveable attribute - * - * @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 Tree#setColumnOrder(int[]) - * @see Tree#getColumnOrder() - * @see TreeColumn#getMoveable() - * @see SWT#Move - * - * @since 3.2 - */ -public void setMoveable (boolean moveable) { - checkWidget (); - this.moveable = moveable; -} -/** - * Sets the resizable attribute. A column that is - * not resizable cannot be dragged by the user but - * may be resized by the programmer. - * - * @param resizable the resize attribute - * - * @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 setResizable (boolean value) { - checkWidget (); - resizable = value; -} -void setSortDirection (int value) { - if (value == sort) return; - boolean widthChange = value == SWT.NONE || sort == SWT.NONE; - sort = value; - if (widthChange) { - /* - * adding/removing the sort arrow decreases/increases the width that is - * available for the column's header text, so recompute the display text - */ - GC gc = new GC (parent); - computeDisplayText (gc); - gc.dispose (); - } - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (getX (), 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -public void setText (String value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - if (value.equals (text)) return; /* same value */ - super.setText (value); - GC gc = new GC (parent); - computeDisplayText (gc); - gc.dispose (); - if (parent.drawCount <= 0 && parent.getHeaderVisible ()) { - /* don't damage the header's drawn borders */ - parent.header.redraw (getX (), 1, width - 2, parent.getHeaderHeight () - 3, false); - } -} -/** - * Sets the receiver's tool tip text to the argument, which - * may be null indicating that the default tool tip for the - * control will be shown. For a control that has a default - * tool tip, such as the Tree control on Windows, setting - * the tool tip text to an empty string replaces the default, - * causing no tool tip text to be shown. - * <p> - * The mnemonic indicator (character '&') is not displayed in a tool tip. - * To display a single '&' in the tool tip, the character '&' can be - * escaped by doubling it in the string. - * </p> - * - * @param string the new tool tip text (or null) - * - * @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.2 - */ -public void setToolTipText (String string) { - checkWidget (); - if (toolTipText == string) return; - if (toolTipText != null && toolTipText.equals (string)) return; - toolTipText = string; - if (parent.toolTipShell == null) return; /* tooltip not currently showing */ - if (((Integer) parent.toolTipShell.getData ()).intValue () != getIndex ()) return; /* tooltip showing for different column */ - parent.headerUpdateToolTip (getX () + (width / 2)); /* update the tooltip text */ -} -/** - * Sets the width of the receiver. - * - * @param width the new width - * - * @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 setWidth (int value) { - checkWidget (); - if (value < 0) return; - if (width == value) return; /* same value */ - parent.updateColumnWidth (this, value); -} -/* - * Perform any internal changes necessary to reflect a changed width. - */ -void updateWidth (GC gc) { - String oldDisplayText = displayText; - computeDisplayText (gc); - /* the header must be damaged if the display text has changed or if the alignment is not LEFT */ - if (parent.getHeaderVisible ()) { - if ((style & SWT.LEFT) == 0 || !oldDisplayText.equals (displayText)) { - int padding = parent.getHeaderPadding (); - parent.header.redraw (getX () + padding, 0, width - padding, parent.getHeaderHeight (), false); - } - } -} -void updateFont (GC gc) { - computeDisplayText (gc); -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TreeItem.java deleted file mode 100644 index f762439f45..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/treetable/org/eclipse/swt/widgets/TreeItem.java +++ /dev/null @@ -1,2959 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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.widgets; - -import org.eclipse.swt.*; -import org.eclipse.swt.graphics.*; -import org.eclipse.swt.internal.Compatibility; - -/** - * Instances of this class represent a selectable user interface object - * that represents a hierarchy of tree items in a tree widget. - * - * <dl> - * <dt><b>Styles:</b></dt> - * <dd>(none)</dd> - * <dt><b>Events:</b></dt> - * <dd>(none)</dd> - * </dl> - * <p> - * IMPORTANT: This class is <em>not</em> intended to be subclassed. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @noextend This class is not intended to be subclassed by clients. - */ -public class TreeItem extends Item { - Tree parent; - TreeItem parentItem; - TreeItem[] items = Tree.NO_ITEMS; - int availableIndex = -1; /* index in parent's flat list of available (though not necessarily within viewport) items */ - int depth = 0; /* cached for performance, does not change after instantiation */ - boolean checked, grayed, expanded, cached; - - String[] texts; - int[] textWidths = new int [1]; /* cached string measurements */ - int customWidth = -1; /* width specified by Measure callback */ - int fontHeight; /* cached item font height */ - int[] fontHeights; - Image[] images; - Color foreground, background; - String[] displayTexts; - Color[] cellForegrounds, cellBackgrounds; - Font font; - Font[] cellFonts; - - static final int INDENT_HIERARCHY = 6; /* the margin between an item's expander and its checkbox or content */ - static final int MARGIN_TEXT = 3; /* the left and right margins within the text's space */ - -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Tree</code> or a <code>TreeItem</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 tree 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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TreeItem (Tree parent, int style) { - this (parent, style, checkNull (parent).items.length); -} -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Tree</code> or a <code>TreeItem</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 tree control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * @param index the zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> - * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TreeItem (Tree parent, int style, int index) { - this (parent, style, index, true); -} -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Tree</code> or a <code>TreeItem</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 parentItem a tree 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> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TreeItem (TreeItem parentItem, int style) { - this (parentItem, style, checkNull (parentItem).items.length); -} -/** - * Constructs a new instance of this class given its parent - * (which must be a <code>Tree</code> or a <code>TreeItem</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 parentItem a tree control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * @param index the zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> - * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> - * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> - * </ul> - * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ -public TreeItem (TreeItem parentItem, int style, int index) { - this (parentItem, style, index, true); -} -TreeItem (TreeItem parentItem, int style, int index, boolean notifyParent) { - super (parentItem, style); - this.parentItem = parentItem; - parent = parentItem.parent; - depth = parentItem.depth + 1; - int validItemIndex = parentItem.items.length; - if (!(0 <= index && index <= validItemIndex)) error (SWT.ERROR_INVALID_RANGE); - int columnCount = parent.columns.length; - if (columnCount > 0) { - displayTexts = new String [columnCount]; - if (columnCount > 1) { - texts = new String [columnCount]; - textWidths = new int [columnCount]; - images = new Image [columnCount]; - } - } - if (notifyParent) parentItem.addItem (this, index); -} -TreeItem (Tree parent, int style, int index, boolean notifyParent) { - super (parent, style); - int validItemIndex = parent.items.length; - if (!(0 <= index && index <= validItemIndex)) error (SWT.ERROR_INVALID_RANGE); - this.parent = parent; - int columnCount = parent.columns.length; - if (columnCount > 0) { - displayTexts = new String [columnCount]; - if (columnCount > 1) { - texts = new String [columnCount]; - textWidths = new int [columnCount]; - images = new Image [columnCount]; - } - } - if (notifyParent) parent.createItem (this, index); -} -/* - * Updates internal structures in the receiver and its child items to handle the creation of a new column. - */ -void addColumn (TreeColumn column) { - int index = column.getIndex (); - int columnCount = parent.columns.length; - - if (columnCount > 1) { - if (columnCount == 2) { - texts = new String [2]; - } else { - String[] newTexts = new String [columnCount]; - System.arraycopy (texts, 0, newTexts, 0, index); - System.arraycopy (texts, index, newTexts, index + 1, columnCount - index - 1); - texts = newTexts; - } - if (index == 0) { - texts [1] = text; - text = ""; //$NON-NLS-1$ - } - - if (columnCount == 2) { - images = new Image [2]; - } else { - Image[] newImages = new Image [columnCount]; - System.arraycopy (images, 0, newImages, 0, index); - System.arraycopy (images, index, newImages, index + 1, columnCount - index - 1); - images = newImages; - } - if (index == 0) { - images [1] = image; - image = null; - } - - int[] newTextWidths = new int [columnCount]; - System.arraycopy (textWidths, 0, newTextWidths, 0, index); - System.arraycopy (textWidths, index, newTextWidths, index + 1, columnCount - index - 1); - textWidths = newTextWidths; - } else { - customWidth = -1; /* columnCount == 1 */ - } - - /* - * The length of displayTexts always matches the parent's column count, unless this - * count is zero, in which case displayTexts is null. - */ - String[] newDisplayTexts = new String [columnCount]; - if (columnCount > 1) { - System.arraycopy (displayTexts, 0, newDisplayTexts, 0, index); - System.arraycopy (displayTexts, index, newDisplayTexts, index + 1, columnCount - index - 1); - } - displayTexts = newDisplayTexts; - - if (cellBackgrounds != null) { - Color[] newCellBackgrounds = new Color [columnCount]; - System.arraycopy (cellBackgrounds, 0, newCellBackgrounds, 0, index); - System.arraycopy (cellBackgrounds, index, newCellBackgrounds, index + 1, columnCount - index - 1); - cellBackgrounds = newCellBackgrounds; - } - if (cellForegrounds != null) { - Color[] newCellForegrounds = new Color [columnCount]; - System.arraycopy (cellForegrounds, 0, newCellForegrounds, 0, index); - System.arraycopy (cellForegrounds, index, newCellForegrounds, index + 1, columnCount - index - 1); - cellForegrounds = newCellForegrounds; - } - if (cellFonts != null) { - Font[] newCellFonts = new Font [columnCount]; - System.arraycopy (cellFonts, 0, newCellFonts, 0, index); - System.arraycopy (cellFonts, index, newCellFonts, index + 1, columnCount - index - 1); - cellFonts = newCellFonts; - - int[] newFontHeights = new int [columnCount]; - System.arraycopy (fontHeights, 0, newFontHeights, 0, index); - System.arraycopy (fontHeights, index, newFontHeights, index + 1, columnCount - index - 1); - fontHeights = newFontHeights; - } - - int orderedIndex = column.getOrderIndex (); - if (orderedIndex == 0 && columnCount > 1) { - /* - * The new second ordered column now has more space available to it than it did while - * it was the first ordered column since it no longer has to show hierarchy decorations, - * so recompute its displayText. - */ - TreeColumn[] orderedColumns = parent.getOrderedColumns (); - int secondColumnIndex = orderedColumns [1].getIndex (); - GC gc = new GC (parent); - gc.setFont (getFont (secondColumnIndex, false)); - computeDisplayText (secondColumnIndex, gc); - gc.dispose (); - } - - /* notify all child items as well */ - for (int i = 0; i < items.length; i++) { - items[i].addColumn (column); - } -} -/* - * Adds a child item to the receiver. - */ -void addItem (TreeItem item, int index) { - TreeItem[] newChildren = new TreeItem [items.length + 1]; - System.arraycopy (items, 0, newChildren, 0, index); - newChildren [index] = item; - System.arraycopy (items, index, newChildren, index + 1, items.length - index); - items = newChildren; - - if (!item.isAvailable ()) { - /* receiver will now need an expander box if this is its first child */ - if (isInViewport () && items.length == 1) { - Rectangle bounds = getExpanderBounds (); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } - return; - } - - /* item should be available immediately so update parent */ - parent.makeAvailable (item); - - /* update scrollbars */ - Rectangle bounds = item.getBounds (false); - int rightX = bounds.x + bounds.width; - parent.updateHorizontalBar (rightX, rightX); - parent.updateVerticalBar (); - /* - * If new item is above viewport then adjust topIndex and the vertical scrollbar - * so that the current viewport items will not change. - */ - if (item.availableIndex < parent.topIndex) { - parent.topIndex++; - ScrollBar vBar = parent.getVerticalBar (); - if (vBar != null) vBar.setSelection (parent.topIndex); - return; - } - - parent.redrawFromItemDownwards (availableIndex); -} -static Tree checkNull (Tree tree) { - if (tree == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - return tree; -} -static TreeItem checkNull (TreeItem item) { - if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - return item; -} -protected void checkSubclass () { - if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); -} -void clear () { - checked = grayed = false; - texts = null; - textWidths = new int [1]; - fontHeight = 0; - fontHeights = null; - images = null; - foreground = background = null; - displayTexts = null; - cellForegrounds = cellBackgrounds = null; - font = null; - cellFonts = null; - cached = false; - text = ""; - image = null; - - int columnCount = parent.columns.length; - if (columnCount > 0) { - displayTexts = new String [columnCount]; - if (columnCount > 1) { - texts = new String [columnCount]; - textWidths = new int [columnCount]; - images = new Image [columnCount]; - } - } -} -/** - * Clears the item at the given zero-relative index in the receiver. - * The text, icon and other attributes of the item are set to the default - * value. If the tree was created with the <code>SWT.VIRTUAL</code> style, - * these attributes are requested again as needed. - * - * @param index the index of the item to clear - * @param all <code>true</code> if all child items of the indexed item should be - * cleared recursively, and <code>false</code> otherwise - * - * @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> - * - * @see SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.2 - */ -public void clear (int index, boolean recursive) { - checkWidget (); - if (!(0 <= index && index < items.length)) error (SWT.ERROR_INVALID_RANGE); - TreeItem item = items [index]; - - /* if there are no columns then the horizontal scrollbar may need adjusting */ - TreeItem[] availableDescendents = null; - int oldRightX = 0; - if (item.availableIndex != -1 && parent.columns.length == 0) { - if (recursive) { - availableDescendents = item.computeAvailableDescendents (); - for (int i = 0; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - oldRightX = Math.max (oldRightX, bounds.x + bounds.width); - } - } else { - Rectangle bounds = item.getBounds (false); - oldRightX = bounds.x + bounds.width; - } - } - - /* clear the item(s) */ - item.clear (); - if (recursive) { - item.clearAll (true, false); - } - if (item.availableIndex == -1) return; /* no visual update needed */ - - /* adjust the horizontal scrollbar if needed */ - if (parent.columns.length == 0) { - int newRightX = 0; - if (recursive) { - for (int i = 0; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - newRightX = Math.max (newRightX, bounds.x + bounds.width); - } - } else { - Rectangle bounds = item.getBounds (false); - newRightX = bounds.x + bounds.width; - } - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } - - /* redraw the item(s) */ - if (recursive) { - int descendentCount = availableDescendents == null ? - item.computeAvailableDescendentCount () : - availableDescendents.length; - parent.redrawItems (item.availableIndex, item.availableIndex + descendentCount - 1, false); - } else { - parent.redrawItem (item.availableIndex, false); - } -} -/** - * Clears all the items in the receiver. The text, icon and other - * attributes of the items are set to their default values. If the - * tree was created with the <code>SWT.VIRTUAL</code> style, these - * attributes are requested again as needed. - * - * @param all <code>true</code> if all child items should be cleared - * recursively, and <code>false</code> otherwise - * - * @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 SWT#VIRTUAL - * @see SWT#SetData - * - * @since 3.2 - */ -public void clearAll (boolean recursive) { - clearAll (recursive, true); -} -void clearAll (boolean recursive, boolean doVisualUpdate) { - checkWidget (); - if (items.length == 0) return; - - /* if there are no columns then the horizontal scrollbar may need adjusting */ - TreeItem[] availableDescendents = null; - int oldRightX = 0; - if (doVisualUpdate && availableIndex != -1 && expanded && parent.columns.length == 0) { - if (recursive) { - availableDescendents = computeAvailableDescendents (); - /* - * i starts at 1 here because item 0 in availableDescendents - * will be the receiver, but this item is not being cleared. - */ - for (int i = 1; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - oldRightX = Math.max (oldRightX, bounds.x + bounds.width); - } - } else { - for (int i = 0; i < items.length; i++) { - Rectangle bounds = items [i].getBounds (false); - oldRightX = Math.max (oldRightX, bounds.x + bounds.width); - } - } - } - - /* clear the item(s) */ - for (int i = 0; i < items.length; i++) { - items [i].clear (); - if (recursive) items [i].clearAll (true, false); - } - - if (!doVisualUpdate || availableIndex == -1 || !expanded) return; /* no visual update needed */ - - /* adjust the horizontal scrollbar if needed */ - if (parent.columns.length == 0) { - int newRightX = 0; - if (recursive) { - /* - * i starts at 1 here because item 0 in availableDescendents - * is the receiver, but this item was not cleared. - */ - for (int i = 1; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - newRightX = Math.max (newRightX, bounds.x + bounds.width); - } - } else { - /* - * All cleared direct child items will have the same x and width - * values now, so just measure the first one as a sample. - */ - Rectangle bounds = items [0].getBounds (false); - newRightX = bounds.x + bounds.width; - } - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } - - /* redraw the item(s) */ - if (recursive) { - int startIndex = items [0].availableIndex; - TreeItem lastChild = items [items.length - 1]; - int endIndex = lastChild.availableIndex + lastChild.computeAvailableDescendentCount () - 1; - parent.redrawItems (startIndex, endIndex, false); - } else { - for (int i = 0; i < items.length; i++) { - parent.redrawItem (items [i].availableIndex, false); - } - } -} -/* - * Returns a collection of all tree items descending from the receiver, including - * the receiver. The order of the items in this collection are receiver, child0tree, - * child1tree, ..., childNtree. - */ -TreeItem[] computeAllDescendents () { - int childCount = items.length; - TreeItem[][] childResults = new TreeItem [childCount][]; - int count = 1; /* receiver */ - for (int i = 0; i < childCount; i++) { - childResults [i] = items [i].computeAllDescendents (); - count += childResults [i].length; - } - TreeItem[] result = new TreeItem [count]; - int index = 0; - result [index++] = this; - for (int i = 0; i < childCount; i++) { - System.arraycopy (childResults [i], 0, result, index, childResults [i].length); - index += childResults [i].length; - } - return result; -} -/* - * Returns the number of tree items descending from the receiver, including the - * receiver, that are currently available. It is assumed that the receiver is - * currently available. - */ -int computeAvailableDescendentCount () { - int result = 1; /* receiver */ - if (!expanded) return result; - for (int i = 0; i < items.length; i++) { - result += items [i].computeAvailableDescendentCount (); - } - return result; -} -/* - * Returns a collection of the tree items descending from the receiver, including - * the receiver, that are currently available. It is assumed that the receiver is - * currently available. The order of the items in this collection are receiver, - * child0tree, child1tree, ..., childNtree. - */ -TreeItem[] computeAvailableDescendents () { - if (!expanded) return new TreeItem[] {this}; - int childCount = items.length; - TreeItem[][] childResults = new TreeItem [childCount][]; - int count = 1; /* receiver */ - for (int i = 0; i < childCount; i++) { - childResults [i] = items [i].computeAvailableDescendents (); - count += childResults [i].length; - } - TreeItem[] result = new TreeItem [count]; - int index = 0; - result [index++] = this; - for (int i = 0; i < childCount; i++) { - System.arraycopy (childResults [i], 0, result, index, childResults [i].length); - index += childResults [i].length; - } - return result; -} -void computeDisplayText (int columnIndex, GC gc) { - if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return; /* nothing to do */ - - int columnCount = parent.columns.length; - if (columnCount == 0) { - String text = getText (0, false); - textWidths [columnIndex] = gc.stringExtent (text).x; - return; - } - - int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex (); - TreeColumn column = parent.columns [columnIndex]; - int availableWidth; - if (orderedIndex == 0) { - /* ordered column 0 is always LEFT and must consider hierarchy decorations */ - availableWidth = column.getX () + column.width - getTextX (columnIndex) - 2 * MARGIN_TEXT; - } else { - /* ordered columns > 0 may not be LEFT so cannot use getTextX (int) */ - availableWidth = column.width - 2 * parent.getCellPadding () - 2 * MARGIN_TEXT; - if (images [columnIndex] != null) { - availableWidth -= images [columnIndex].getBounds ().width; - availableWidth -= Tree.MARGIN_IMAGE; - } - } - String text = getText (columnIndex, false); - int textWidth = gc.stringExtent (text).x; - if (textWidth <= availableWidth) { - displayTexts [columnIndex] = text; - textWidths [columnIndex] = textWidth; - return; - } - - /* Ellipsis will be needed, so subtract their width from the available text width */ - int ellipsisWidth = gc.stringExtent (Tree.ELLIPSIS).x; - availableWidth -= ellipsisWidth; - if (availableWidth <= 0) { - displayTexts [columnIndex] = Tree.ELLIPSIS; - textWidths [columnIndex] = ellipsisWidth; - return; - } - - /* Make initial guess. */ - int index = Math.min (availableWidth / gc.getFontMetrics ().getAverageCharWidth (), text.length ()); - textWidth = gc.stringExtent (text.substring (0, index)).x; - - /* Initial guess is correct. */ - if (availableWidth == textWidth) { - displayTexts [columnIndex] = text.substring (0, index) + Tree.ELLIPSIS; - textWidths [columnIndex] = textWidth + ellipsisWidth; - return; - } - - /* Initial guess is too high, so reduce until fit is found. */ - if (availableWidth < textWidth) { - do { - index--; - if (index < 0) { - displayTexts [columnIndex] = Tree.ELLIPSIS; - textWidths [columnIndex] = ellipsisWidth; - return; - } - text = text.substring (0, index); - textWidth = gc.stringExtent (text).x; - } while (availableWidth < textWidth); - displayTexts [columnIndex] = text + Tree.ELLIPSIS; - textWidths [columnIndex] = textWidth + ellipsisWidth; - return; - } - - /* Initial guess is too low, so increase until overrun is found. */ - int previousWidth = 0; - while (textWidth < availableWidth) { - index++; - previousWidth = textWidth; - textWidth = gc.stringExtent (text.substring (0, index)).x; - } - displayTexts [columnIndex] = text.substring (0, index - 1) + Tree.ELLIPSIS; - textWidths [columnIndex] = previousWidth + ellipsisWidth; -} -void computeDisplayTexts (GC gc) { - if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return; /* nothing to do */ - - int columnCount = parent.columns.length; - if (columnCount == 0) return; - - for (int i = 0; i < columnCount; i++) { - gc.setFont (getFont (i, false)); - computeDisplayText (i, gc); - } -} -/* - * Computes the cached text widths. - */ -void computeTextWidths (GC gc) { - if ((parent.style & SWT.VIRTUAL) != 0 && !cached) return; /* nothing to do */ - - int validColumnCount = Math.max (1, parent.columns.length); - textWidths = new int [validColumnCount]; - for (int i = 0; i < textWidths.length; i++) { - String value = getDisplayText (i); - if (value != null) { - gc.setFont (getFont (i, false)); - textWidths [i] = gc.stringExtent (value).x; - } - } -} -public void dispose () { - if (isDisposed ()) return; - int startIndex = -1, endIndex = -1; - Tree parent = this.parent; - int index = getIndex (); - - /* determine the indices, if any, that will need to be visually updated */ - if (isAvailable ()) { - if (isLastChild () && index > 0) { - /* vertical connector lines no longer needed for this item */ - if (parentItem != null) { - startIndex = parentItem.items [index - 1].availableIndex; - } else { - startIndex = parent.items [index - 1].availableIndex; - } - } else { - startIndex = availableIndex; - } - endIndex = parent.availableItemsCount - 1; - } - - /* for performance do this upfront for whole descendent chain */ - TreeItem focusItem = parent.focusItem; - if (focusItem != null && focusItem.hasAncestor (this)) { - parent.setFocusItem (this, false); - parent.reassignFocus (); - focusItem = parent.focusItem; - if (focusItem != null) { - parent.redrawItem (focusItem.availableIndex, true); - } - } - if (parentItem != null) parentItem.removeItem (this, index); - dispose (true); - if (startIndex != -1) { - parent.redrawItems (startIndex, endIndex, false); - } -} -void dispose (boolean notifyParent) { - if (isDisposed ()) return; - for (int i = 0; i < items.length; i++) { - items [i].dispose (notifyParent); - } - if (notifyParent) parent.destroyItem (this); - super.dispose (); /* super is intentional here */ - background = foreground = null; - cellBackgrounds = cellForegrounds = null; - font = null; - cellFonts = null; - images = null; - texts = displayTexts = null; - textWidths = fontHeights = null; - parent = null; - parentItem = null; - items = null; -} -/* - * Ensure that all ancestors of the receiver are expanded - */ -void expandAncestors () { - if (parentItem != null) parentItem.expandAncestors (); - setExpanded (true); - Event newEvent = new Event (); - newEvent.item = this; - parent.inExpand = true; - parent.sendEvent (SWT.Expand, newEvent); - parent.inExpand = false; - if (isDisposed ()) return; - if (items.length == 0) { - expanded = false; - } -} -/** - * 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 (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (background != null) return background; - return parent.getBackground (); -} -/** - * Returns the background color at the given column index in the receiver. - * - * @param index the column index - * @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 3.1 - */ -public Color getBackground (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getBackground (); - if (cellBackgrounds == null || cellBackgrounds [columnIndex] == null) return getBackground (); - return cellBackgrounds [columnIndex]; -} -/** - * 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 () { - checkWidget (); - return getBounds (true); -} -Rectangle getBounds (boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (!isAvailable ()) return new Rectangle (0, 0, 0, 0); - TreeColumn[] orderedColumns = parent.getOrderedColumns (); - int orderedCol0Index = orderedColumns.length == 0 ? 0 : orderedColumns [0].getIndex (); - int x = getTextX (orderedCol0Index); - int width = textWidths [orderedCol0Index] + 2 * MARGIN_TEXT; - if (orderedColumns.length > 0) { - TreeColumn column = orderedColumns [0]; - int right = column.getX () + column.width; - if (x + width > right) { - width = Math.max (0, right - x); - } - } - return new Rectangle (x, parent.getItemY (this), width, parent.itemHeight); -} -/** - * Returns a rectangle describing the receiver's size and location - * relative to its parent at a column in the tree. - * - * @param index the index that specifies the column - * @return the receiver's bounding column 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> - * - * @since 3.1 - */ -public Rectangle getBounds (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (!isAvailable ()) return new Rectangle (0, 0, 0, 0); - TreeColumn[] columns = parent.columns; - int columnCount = columns.length; - int validColumnCount = Math.max (1, columnCount); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) { - return new Rectangle (0, 0, 0, 0); - } - /* - * If there are no columns then this is the bounds of the receiver's content. - */ - if (columnCount == 0) { - return new Rectangle ( - getContentX (0), - parent.getItemY (this), - getContentWidth (0), - parent.itemHeight - 1); - } - - TreeColumn column = columns [columnIndex]; - if (column.getOrderIndex () == 0) { - /* - * For ordered column 0 this is bounds from the beginning of the content to the - * end of the column. - */ - int x = getContentX (columnIndex); - int offset = x - column.getX (); - int width = Math.max (0, column.width - offset - 1); /* max is for columns with small widths */ - return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1); - } - /* - * For ordered columns > 0 this is the bounds of the tree cell. - */ - return new Rectangle (column.getX (), parent.getItemY (this) + 1, column.width, parent.itemHeight - 1); -} -/* - * Returns the full bounds of a cell in a tree, regardless of its content. - */ -Rectangle getCellBounds (int columnIndex) { - int y = parent.getItemY (this); - if (parent.columns.length == 0) { - int width; - if (customWidth != -1) { - width = getContentX (0) + customWidth + parent.horizontalOffset; - } else { - int textPaintWidth = textWidths [0] + 2 * MARGIN_TEXT; - width = getTextX (0) + textPaintWidth + parent.horizontalOffset; - } - return new Rectangle (-parent.horizontalOffset, y, width, parent.itemHeight); - } - TreeColumn column = parent.columns [columnIndex]; - return new Rectangle (column.getX (), y, column.width, parent.itemHeight); -} -/* - * Returns the bounds of the receiver's checkbox, or null if the parent's style does not - * include SWT.CHECK. - */ -Rectangle getCheckboxBounds () { - if ((parent.getStyle () & SWT.CHECK) == 0) return null; - int itemHeight = parent.itemHeight; - Rectangle result = parent.checkboxBounds; - Point[] hLinePoints = getHconnectorEndpoints (); - result.x = hLinePoints [1].x; - result.y = parent.getItemY (this) + (itemHeight - result.height) / 2; - return result; -} -/** - * Returns <code>true</code> if the receiver is checked, - * and false otherwise. When the parent does not have - * the <code>CHECK style, return false. - * <p> - * - * @return the checked state - * - * @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 (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return checked; -} -int getContentWidth (int columnIndex) { - int width = textWidths [columnIndex] + 2 * MARGIN_TEXT; - int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex (); - if (orderedIndex == 0) { - width += parent.orderedCol0imageWidth; - if (parent.orderedCol0imageWidth > 0) width += Tree.MARGIN_IMAGE; - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - width += image.getBounds ().width + Tree.MARGIN_IMAGE; - } - } - return width; -} -/* - * Returns the x value where the receiver's content (ie.- its image or text) begins - * for the specified column. For ordered columns > 0 this is dependent upon column - * alignment, and for ordered column 0 this is dependent upon the receiver's depth in - * the tree item hierarchy and the presence/absence of a checkbox. - */ -int getContentX (int columnIndex) { - int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex (); - if (orderedIndex > 0) { - TreeColumn column = parent.columns [columnIndex]; - int contentX = column.getX () + parent.getCellPadding (); - if ((column.style & SWT.LEFT) != 0) return contentX; - - /* column is not left-aligned */ - int contentWidth = getContentWidth (columnIndex); - if ((column.style & SWT.RIGHT) != 0) { - int padding = parent.getCellPadding (); - contentX = Math.max (contentX, column.getX () + column.width - padding - contentWidth); - } else { /* SWT.CENTER */ - contentX = Math.max (contentX, column.getX () + (column.width - contentWidth) / 2); - } - return contentX; - } - - /* ordered column 0 (always left-aligned) */ - if ((parent.style & SWT.CHECK) != 0) { - Rectangle checkBounds = getCheckboxBounds (); - return checkBounds.x + checkBounds.width + Tree.MARGIN_IMAGE; - } - - int contentX = parent.getCellPadding () - parent.horizontalOffset; - if (parentItem != null) { - int expanderWidth = parent.expanderBounds.width + INDENT_HIERARCHY; - contentX += expanderWidth * depth; - } - contentX += parent.expanderBounds.width; - return contentX + Tree.MARGIN_IMAGE + INDENT_HIERARCHY; -} -String getDisplayText (int columnIndex) { - if (parent.columns.length == 0) return getText (0, false); - String result = displayTexts [columnIndex]; - return result != null ? result : ""; //$NON-NLS-1$ -} -/** - * Returns <code>true</code> if the receiver is expanded, - * and false otherwise. - * <p> - * - * @return the expanded state - * - * @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 getExpanded () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return expanded; -} -/* - * Returns the bounds of the receiver's expander box, regardless of whether the - * receiver currently has children or not. - */ -Rectangle getExpanderBounds () { - int itemHeight = parent.itemHeight; - int x = parent.getCellPadding () - parent.horizontalOffset; - int y = parent.getItemY (this); - if (parentItem != null) { - int expanderWidth = parent.expanderBounds.width + INDENT_HIERARCHY; - x += expanderWidth * depth; - } - return new Rectangle ( - x, y + (itemHeight - parent.expanderBounds.height) / 2, - parent.expanderBounds.width, parent.expanderBounds.height); -} -/* - * Returns the bounds that should be used for drawing a focus rectangle on the receiver - */ -Rectangle getFocusBounds () { - TreeColumn[] columns = parent.columns; - int orderedCol0index = columns.length == 0 ? 0 : parent.getOrderedColumns ()[0].getIndex (); - int x = getTextX (orderedCol0index); - - int width; - if (columns.length > 0) { - /* ensure that the focus x does not start beyond the right bound of ordered column 0 */ - int rightX = columns [orderedCol0index].getX () + columns [orderedCol0index].width; - x = Math.min (x, rightX - 1); - - TreeColumn column; - if ((parent.style & SWT.FULL_SELECTION) != 0) { - int[] columnOrder = parent.getColumnOrder (); - column = columns [columnOrder [columnOrder.length - 1]]; /* last ordered column */ - } else { - column = columns [orderedCol0index]; - } - width = column.getX () + column.width - x - 1; - } else { /* no columns */ - if (customWidth != -1) { - width = customWidth; - } else { - width = textWidths [0] + 2 * MARGIN_TEXT; - } - } - - return new Rectangle ( - x, - parent.getItemY (this) + (parent.linesVisible ? 1 : 0), - width, - parent.itemHeight - (parent.linesVisible ? 1 : 0)); -} -/** - * 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 getFont (true); -} -Font getFont (boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (font != null) return font; - return parent.getFont (); -} -/** - * Returns the font that the receiver will use to paint textual information - * for the specified cell in this item. - * - * @param index the column index - * @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.1 - */ -public Font getFont (int columnIndex) { - checkWidget (); - return getFont (columnIndex, true); -} -Font getFont (int columnIndex, boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getFont (checkData); - if (cellFonts == null || cellFonts [columnIndex] == null) return getFont (checkData); - return cellFonts [columnIndex]; -} -int getFontHeight () { - if (fontHeight != 0) return fontHeight; - return parent.fontHeight; -} -int getFontHeight (int columnIndex) { - if (fontHeights == null || fontHeights [columnIndex] == 0) return getFontHeight (); - return fontHeights [columnIndex]; -} -/** - * 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 (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (foreground != null) return foreground; - return parent.getForeground (); -} -/** - * - * Returns the foreground color at the given column index in the receiver. - * - * @param index the column index - * @return the 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 3.1 - */ -public Color getForeground (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return getForeground (); - if (cellForegrounds == null || cellForegrounds [columnIndex] == null) return getForeground (); - return cellForegrounds [columnIndex]; -} -/** - * Returns <code>true</code> if the receiver is grayed, - * and false otherwise. When the parent does not have - * the <code>CHECK style, return false. - * <p> - * - * @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> - */ -public boolean getGrayed () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return grayed; -} -/* - * Answers the start and end points of the horizontal connector line that is - * drawn between an item's expander box and its checkbox or content. - */ -Point[] getHconnectorEndpoints () { - Rectangle expanderBounds = getExpanderBounds (); - int x, width; - if (items.length == 0) { /* no child items, so no expander box */ - x = expanderBounds.x + Compatibility.ceil (expanderBounds.width, 2); - width = Compatibility.floor (expanderBounds.width, 2) + INDENT_HIERARCHY; - } else { /* has child items */ - x = expanderBounds.x + expanderBounds.width; - width = INDENT_HIERARCHY; - } - int y = expanderBounds.y + expanderBounds.height / 2; - return new Point[] { - new Point (x, y), - new Point (x + width, y) - }; -} -/* - * Returns the bounds representing the clickable region that should select the receiver. - */ -Rectangle getHitBounds () { - int[] columnOrder = parent.getColumnOrder (); - int orderedCol0index = columnOrder.length == 0 ? 0 : parent.columns [columnOrder [0]].getIndex (); - int contentX = getContentX (orderedCol0index); - int width = 0; - TreeColumn[] columns = parent.columns; - if (columns.length == 0) { - width = getContentWidth (0); - } else { - /* - * If there are columns then this spans from the beginning of the receiver's column 0 - * image or text to the end of either column 0 or the last column (FULL_SELECTION). - */ - TreeColumn column; - if ((parent.style & SWT.FULL_SELECTION) != 0) { - column = columns [columnOrder [columnOrder.length - 1]]; /* last column */ - } else { - column = columns [orderedCol0index]; - } - width = column.getX () + column.width - contentX; - } - return new Rectangle (contentX, parent.getItemY (this), width, parent.itemHeight); -} -public Image getImage () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return super.getImage (); -} -/** - * Returns the image stored at the given column index in the receiver, - * or null if the image has not been set or if the column does not exist. - * - * @param index the column index - * @return the image stored at the given column index in the receiver - * - * @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 Image getImage (int columnIndex) { - checkWidget (); - return getImage (columnIndex, true); -} -Image getImage (int columnIndex, boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return null; - if (columnIndex == 0) return super.getImage (); /* super is intentional here */ - return images [columnIndex]; -} -/** - * Returns a rectangle describing the size and location - * relative to its parent of an image at a column in the - * tree. - * - * @param index the index that specifies the column - * @return the receiver's bounding image 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> - * - * @since 3.1 - */ -public Rectangle getImageBounds (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return new Rectangle (0,0,0,0); - - int padding = parent.getCellPadding (); - int startX = getContentX (columnIndex); - int itemHeight = parent.itemHeight; - int imageSpaceY = itemHeight - 2 * padding; - int y = parent.getItemY (this); - int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex (); - Image image = getImage (columnIndex, false); - int drawWidth = 0; - if (orderedIndex == 0) { - /* for ordered column 0 all images have the same width */ - drawWidth = parent.orderedCol0imageWidth; - } else { - if (image != null) drawWidth = image.getBounds ().width; - } - return new Rectangle (startX, y + padding, drawWidth, imageSpaceY); -} -int getIndex () { - TreeItem[] items; - if (parentItem != null) { - items = parentItem.items; - } else { - items = parent.items; - } - for (int i = 0; i < items.length; i++) { - if (items [i] == this) return i; - } - return -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 TreeItem getItem (int index) { - checkWidget (); - if (index < 0) error (SWT.ERROR_INVALID_RANGE); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (index >= items.length) 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 - * - * @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 int getItemCount () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return items.length; -} -String getNameText () { - if ((parent.style & SWT.VIRTUAL) != 0) { - if (!cached) return "*virtual*"; //$NON-NLS-1$ - } - return super.getNameText (); -} -/** - * Returns a (possibly empty) array of <code>TreeItem</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 - * - * @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 TreeItem [] getItems () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - TreeItem[] result = new TreeItem [items.length]; - System.arraycopy (items, 0, result, 0, items.length); - return result; -} -/** - * Returns the receiver's parent, which must be a <code>Tree</code>. - * - * @return the receiver's parent - * - * @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 Tree getParent () { - checkWidget (); - return parent; -} -/** - * Returns the receiver's parent item, which must be a - * <code>TreeItem</code> or null when the receiver is a - * root. - * - * @return the receiver's parent item - * - * @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 TreeItem getParentItem () { - checkWidget (); - return parentItem; -} -/* - * Returns the receiver's ideal width for the specified columnIndex. - */ -int getPreferredWidth (int columnIndex) { - int width = 0; - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - width += gc.stringExtent (getText (columnIndex, false)).x + 2 * MARGIN_TEXT; - int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex (); - if (orderedIndex == 0) { - if (parent.orderedCol0imageWidth > 0) { - width += parent.orderedCol0imageWidth; - width += Tree.MARGIN_IMAGE; - } - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - width += image.getBounds ().width; - width += Tree.MARGIN_IMAGE; - } - } - - if (parent.hooks (SWT.MeasureItem)) { - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - event.x = getContentX (columnIndex); - event.y = parent.getItemY (this); - event.width = width; - event.height = parent.itemHeight; - parent.sendEvent (SWT.MeasureItem, event); - if (parent.itemHeight != event.height) { - parent.customHeightSet = true; - boolean update = parent.setItemHeight (event.height + 2 * parent.getCellPadding ()); - if (update) parent.redraw (); - } - width = event.width; - } - gc.dispose (); - - if (orderedIndex == 0) { - return getContentX (columnIndex) + parent.horizontalOffset + width + parent.getCellPadding (); /* right side cell pad */ - } - - return width + 2 * parent.getCellPadding (); -} -public String getText () { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - return super.getText (); -} -/** - * Returns the text stored at the given column index in the receiver, - * or empty string if the text has not been set. - * - * @param index the column index - * @return the text stored at the given column index in the receiver - * - * @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 String getText (int columnIndex) { - checkWidget (); - return getText (columnIndex, true); -} -String getText (int columnIndex, boolean checkData) { - if (checkData && !parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return ""; //$NON-NLS-1$ - if (columnIndex == 0) return super.getText (); /* super is intentional here */ - if (texts [columnIndex] == null) return ""; //$NON-NLS-1$ - return texts [columnIndex]; -} -/** - * Returns a rectangle describing the size and location - * relative to its parent of the text at a column in the - * tree. - * - * @param index the index that specifies the column - * @return the receiver's bounding text 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> - * - * @since 3.3 - */ -public Rectangle getTextBounds (int columnIndex) { - checkWidget (); - if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); - if (!isAvailable ()) return new Rectangle (0, 0, 0, 0); - TreeColumn[] columns = parent.columns; - int columnCount = columns.length; - int validColumnCount = Math.max (1, columnCount); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) { - return new Rectangle (0, 0, 0, 0); - } - /* - * If there are no columns then this is the bounds of the receiver's content. - */ - if (columnCount == 0) { - int x = getTextX (0) + MARGIN_TEXT; - int width = Math.max (0, getContentX(0) + getContentWidth (0) - x); - return new Rectangle ( - x, - parent.getItemY (this), - width, - parent.itemHeight - 1); - } - - TreeColumn column = columns [columnIndex]; - if (column.getOrderIndex () == 0) { - /* - * For ordered column 0 this is bounds from the beginning of the content to the - * end of the column. - */ - int x = getTextX (columnIndex) + MARGIN_TEXT; - int offset = x - column.getX (); - int width = Math.max (0, column.width - offset - 1); /* max is for columns with small widths */ - return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1); - } - /* - * For ordered columns > 0 this is the bounds of the tree cell. - */ - int x = getTextX (columnIndex) + MARGIN_TEXT; - int offset = x - column.getX (); - int width = Math.max (0, column.width - offset - MARGIN_TEXT); - return new Rectangle (x, parent.getItemY (this) + 1, width, parent.itemHeight - 1); -} -/* - * Returns the x value where the receiver's text begins. - */ -int getTextX (int columnIndex) { - int orderedIndex = parent.columns.length == 0 ? 0 : parent.columns [columnIndex].getOrderIndex (); - int textX = getContentX (columnIndex); - if (orderedIndex == 0) { - textX += parent.orderedCol0imageWidth; - if (parent.orderedCol0imageWidth > 0) textX += Tree.MARGIN_IMAGE; - } else { - Image image = getImage (columnIndex, false); - if (image != null) { - textX += image.getBounds ().width + Tree.MARGIN_IMAGE; - } - } - return textX; -} -/* - * Returns true if the receiver descends from (or is identical to) the item. - */ -boolean hasAncestor (TreeItem item) { - if (this == item) return true; - if (parentItem == null) return false; - return parentItem.hasAncestor (item); -} -/** - * Searches the receiver's list starting at the first item - * (index 0) until an item is found that is equal to the - * argument, and returns the index of that item. If no item - * is found, returns -1. - * - * @param item the search item - * @return the index of the item - * - * @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> - * - * @since 3.1 - */ -public int indexOf (TreeItem item) { - checkWidget (); - if (item == null) error (SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - if (item.parentItem != this) return -1; - return item.getIndex (); -} -/* - * Returns true if the receiver is currently available (though not necessary in the viewport). - */ -boolean isAvailable () { - if (parentItem == null) return true; /* root items are always available */ - if (!parentItem.expanded) return false; - return parentItem.isAvailable (); -} -/* - * Answers a boolean indicating whether the receiver's y is within the current - * viewport of the parent. - */ -boolean isInViewport () { - if (availableIndex == -1) return false; - int topIndex = parent.topIndex; - if (availableIndex < topIndex) return false; - int visibleCount = parent.clientArea.height / parent.itemHeight; - return availableIndex <= topIndex + visibleCount; -} -/* - * Returns true if the receiver is the last child of its parent item, or of its parent - * if the receiver is a root item, and false otherwise. - */ -boolean isLastChild () { - if (parentItem != null) { - return getIndex () == parentItem.items.length - 1; - } - return getIndex () == parent.items.length - 1; -} -boolean isSelected () { - return parent.getSelectionIndex (this) != -1; -} -/* - * The backgroundOnly argument indicates whether the item should only - * worry about painting its background color and selection. - * - * Returns a boolean indicating whether to abort drawing focus on the item. - * If the receiver is not the current focus item then this value is irrelevant. - */ -boolean paint (GC gc, TreeColumn column, boolean backgroundOnly) { - if (!parent.checkData (this, true)) return false; - int columnIndex = 0, orderedIndex = 0, x = 0; - if (column != null) { - columnIndex = column.getIndex (); - orderedIndex = column.getOrderIndex (); - x = column.getX (); - } - - /* - * Capture GC attributes that will need to be restored later in the paint - * process to ensure that the item paints as intended without being affected - * by GC changes made in MeasureItem/EraseItem/PaintItem callbacks. - */ - int oldAlpha = gc.getAlpha (); - boolean oldAdvanced = gc.getAdvanced (); - int oldAntialias = gc.getAntialias (); - Pattern oldBackgroundPattern = gc.getBackgroundPattern (); - Pattern oldForegroundPattern = gc.getForegroundPattern (); - int oldInterpolation = gc.getInterpolation (); - int[] oldLineDash = gc.getLineDash (); - int oldLineWidth = gc.getLineWidth (); - int oldTextAntialias = gc.getTextAntialias (); - - if (parent.hooks (SWT.MeasureItem)) { - int contentWidth = getContentWidth (columnIndex); - int contentX = getContentX (columnIndex); - gc.setFont (getFont (columnIndex, false)); - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - event.x = contentX; - event.y = parent.getItemY (this); - event.width = contentWidth; - event.height = parent.itemHeight; - parent.sendEvent (SWT.MeasureItem, event); - event.gc = null; - if (gc.isDisposed ()) return false; - gc.setAlpha (oldAlpha); - gc.setAntialias (oldAntialias); - gc.setBackgroundPattern (oldBackgroundPattern); - gc.setForegroundPattern (oldForegroundPattern); - gc.setInterpolation (oldInterpolation); - gc.setLineDash (oldLineDash); - gc.setLineWidth (oldLineWidth); - gc.setTextAntialias (oldTextAntialias); - gc.setAdvanced (oldAdvanced); - if (isDisposed ()) return false; - if (parent.itemHeight != event.height) { - parent.customHeightSet = true; - boolean update = parent.setItemHeight (event.height + 2 * parent.getCellPadding ()); - if (update) parent.redraw (); - } - if (parent.columns.length == 0) { - int change = event.width - (customWidth != -1 ? customWidth : contentWidth); - if (event.width != contentWidth || customWidth != -1) customWidth = event.width; - if (change != 0) { /* scrollbar may be affected since no columns */ - parent.updateHorizontalBar (contentX + event.width, change); - // TODO what if clip is too small now? - } - } - } - - /* if this cell is completely to the right of the client area then there's no need to paint it */ - Rectangle clientArea = parent.clientArea; - if (clientArea.x + clientArea.width < x) return false; - - Rectangle cellBounds = getCellBounds (columnIndex); - if (parent.linesVisible) { - cellBounds.y++; - cellBounds.height--; - } - int cellRightX = 0; - if (column != null) { - cellRightX = column.getX () + column.width; - } else { - cellRightX = cellBounds.x + cellBounds.width; - } - - /* restrict the clipping region to the cell */ - gc.setClipping (x, cellBounds.y, clientArea.width - x, cellBounds.height); - - int y = parent.getItemY (this); - int itemHeight = parent.itemHeight; - - /* draw the parent background color/image of this cell */ - if (column == null) { - parent.drawBackground (gc, 0, y, clientArea.width, itemHeight); - } else { - int fillWidth = cellBounds.width; - if (parent.linesVisible) fillWidth--; - parent.drawBackground (gc, cellBounds.x, cellBounds.y, fillWidth, cellBounds.height); - } - - boolean isSelected = isSelected (); - boolean isFocusItem = parent.focusItem == this && parent.isFocusControl (); - boolean drawBackground = true; - boolean drawForeground = true; - boolean drawSelection = isSelected; - boolean drawFocus = isFocusItem; - if (parent.hooks (SWT.EraseItem)) { - drawBackground = background != null || (cellBackgrounds != null && cellBackgrounds [columnIndex] != null); - gc.setFont (getFont (columnIndex, false)); - if (isSelected && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT)); - gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION)); - } else { - gc.setForeground (getForeground (columnIndex)); - gc.setBackground (getBackground (columnIndex)); - } - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - event.doit = true; - event.detail = SWT.FOREGROUND; - if (drawBackground) event.detail |= SWT.BACKGROUND; - if (isSelected) event.detail |= SWT.SELECTED; - if (isFocusItem) event.detail |= SWT.FOCUSED; - event.x = cellBounds.x; - event.y = cellBounds.y; - event.width = cellBounds.width; - event.height = cellBounds.height; - gc.setClipping (cellBounds); - parent.sendEvent (SWT.EraseItem, event); - event.gc = null; - if (gc.isDisposed ()) return false; - gc.setAlpha (oldAlpha); - gc.setAntialias (oldAntialias); - gc.setBackgroundPattern (oldBackgroundPattern); - gc.setClipping (cellBounds); - gc.setForegroundPattern (oldForegroundPattern); - gc.setInterpolation (oldInterpolation); - gc.setLineDash (oldLineDash); - gc.setLineWidth (oldLineWidth); - gc.setTextAntialias (oldTextAntialias); - gc.setAdvanced (oldAdvanced); - if (isDisposed ()) return false; - if (!event.doit) { - drawBackground = drawForeground = drawSelection = drawFocus = false; - } else { - drawBackground = drawBackground && (event.detail & SWT.BACKGROUND) != 0; - drawForeground = (event.detail & SWT.FOREGROUND) != 0; - drawSelection = isSelected && (event.detail & SWT.SELECTED) != 0; - drawFocus = isFocusItem && (event.detail & SWT.FOCUSED) != 0; - } - } - - /* draw the cell's set background if appropriate */ - if (drawBackground) { - gc.setBackground (getBackground (columnIndex)); - if (columnIndex == 0 && (column == null || column.getOrderIndex () == 0)) { - Rectangle focusBounds = getFocusBounds (); - int fillWidth = 0; - if (column == null) { - fillWidth = focusBounds.width; - } else { - fillWidth = column.width - focusBounds.x; - if (parent.linesVisible) fillWidth--; - } - gc.fillRectangle (focusBounds.x, focusBounds.y, fillWidth, focusBounds.height); - } else { - int fillWidth = cellBounds.width; - gc.fillRectangle (cellBounds.x, cellBounds.y, fillWidth, cellBounds.height); - } - } - - /* draw the selection bar if the receiver is selected */ - if (drawSelection && isSelected && (orderedIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION)); - if (orderedIndex == 0) { - Rectangle focusBounds = getFocusBounds (); - int fillWidth = focusBounds.width; - if (parent.columns.length < 2 || (parent.style & SWT.FULL_SELECTION) == 0) { - fillWidth -= 2; /* space for right bound of focus rect */ - } - if (fillWidth > 0) { - gc.fillRectangle (focusBounds.x + 1, focusBounds.y + 1, fillWidth, focusBounds.height - 2); - } - } else { - int fillWidth = column.width; - int[] columnOrder = parent.getColumnOrder (); - if (columnIndex == columnOrder [columnOrder.length - 1]) { - fillWidth -= 2; /* space for right bound of focus rect */ - } - if (fillWidth > 0) { - gc.fillRectangle ( - column.getX (), - cellBounds.y + 1, - fillWidth, - cellBounds.height - 2); - } - } - } - - if (backgroundOnly) return false; - - /* Draw column 0 decorations */ - if (orderedIndex == 0) { - gc.setClipping (cellBounds); - - /* Draw hierarchy connector lines */ - Rectangle expanderBounds = getExpanderBounds (); - Color oldForeground = gc.getForeground (); - gc.setForeground (parent.getConnectorColor ()); - - /* Draw vertical line above expander */ - int lineX = expanderBounds.x + expanderBounds.width / 2; - int y2 = expanderBounds.y; - if (items.length == 0) { - y2 += expanderBounds.height / 2; - } - /* Do not draw this line iff this is the very first item in the tree */ - if (parentItem != null || getIndex () != 0) { - gc.drawLine (lineX, y, lineX, y2); - } - - /* Draw vertical line below expander if the receiver has lower siblings */ - if (!isLastChild ()) { - if (items.length != 0) y2 += expanderBounds.height; - gc.drawLine (lineX, y2, lineX, y + itemHeight); - } - - /* Draw horizontal line to right of expander */ - Point[] endpoints = getHconnectorEndpoints (); - gc.drawLine (endpoints [0].x, endpoints [0].y, endpoints [1].x - Tree.MARGIN_IMAGE, endpoints [1].y); - - /* - * Draw hierarchy lines that are needed by other items that are shown below - * this item but whose parents are shown above (ie.- lines to the left of - * this item's connector line). - */ - TreeItem item = parentItem; - while (item != null) { - if (!item.isLastChild ()) { - Rectangle itemExpanderBounds = item.getExpanderBounds (); - lineX = itemExpanderBounds.x + itemExpanderBounds.width / 2; - gc.drawLine (lineX, y, lineX, y + itemHeight); - } - item = item.parentItem; - } - - gc.setForeground (oldForeground); - - /* Draw expand/collapse image if receiver has children */ - if (items.length > 0) { - Image image = expanded ? parent.getExpandedImage () : parent.getCollapsedImage (); - gc.drawImage (image, expanderBounds.x, expanderBounds.y); - } - - /* Draw checkbox if parent Tree has style SWT.CHECK */ - if ((parent.style & SWT.CHECK) != 0) { - Image baseImage = grayed ? parent.getGrayUncheckedImage () : parent.getUncheckedImage (); - Rectangle checkboxBounds = getCheckboxBounds (); - gc.drawImage (baseImage, checkboxBounds.x, checkboxBounds.y); - /* Draw checkmark if item is checked */ - if (checked) { - Image checkmarkImage = parent.getCheckmarkImage (); - Rectangle checkmarkBounds = checkmarkImage.getBounds (); - int xInset = (checkboxBounds.width - checkmarkBounds.width) / 2; - int yInset = (checkboxBounds.height - checkmarkBounds.height) / 2; - gc.drawImage (checkmarkImage, checkboxBounds.x + xInset, checkboxBounds.y + yInset); - } - } - } - - if (drawForeground) { - Image image = getImage (columnIndex, false); - String text = getDisplayText (columnIndex); - Rectangle imageArea = getImageBounds (columnIndex); - int startX = imageArea.x; - - /* while painting the cell's content restrict the clipping region */ - int padding = parent.getCellPadding (); - gc.setClipping ( - startX, - cellBounds.y + padding - (parent.linesVisible ? 1 : 0), - cellRightX - startX - padding, - cellBounds.height - 2 * (padding - (parent.linesVisible ? 1 : 0))); - - /* draw the image */ - if (image != null) { - Rectangle imageBounds = image.getBounds (); - gc.drawImage ( - image, - 0, 0, /* source x, y */ - imageBounds.width, imageBounds.height, /* source width, height */ - imageArea.x, imageArea.y, /* dest x, y */ - imageArea.width, imageArea.height); /* dest width, height */ - } - - /* draw the text */ - if (text.length () > 0) { - gc.setFont (getFont (columnIndex, false)); - int fontHeight = getFontHeight (columnIndex); - if (drawSelection && (orderedIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT)); - } else { - if (!isSelected || drawSelection) { - gc.setForeground (getForeground (columnIndex)); - } - } - x = getTextX (columnIndex) + MARGIN_TEXT; - gc.drawString (text, x, y + (itemHeight - fontHeight) / 2, true); - } - } - - if (parent.hooks (SWT.PaintItem)) { - int contentWidth = getContentWidth (columnIndex); - int contentX = getContentX (columnIndex); - gc.setFont (getFont (columnIndex, false)); - if (isSelected && (columnIndex == 0 || (parent.style & SWT.FULL_SELECTION) != 0)) { - gc.setForeground (display.getSystemColor (SWT.COLOR_LIST_SELECTION_TEXT)); - gc.setBackground (display.getSystemColor (SWT.COLOR_LIST_SELECTION)); - } else { - gc.setForeground (getForeground (columnIndex)); - gc.setBackground (getBackground (columnIndex)); - } - Event event = new Event (); - event.item = this; - event.gc = gc; - event.index = columnIndex; - if (isSelected) event.detail |= SWT.SELECTED; - if (drawFocus) event.detail |= SWT.FOCUSED; - event.x = contentX; - event.y = cellBounds.y; - event.width = contentWidth; - event.height = cellBounds.height; - gc.setClipping (cellBounds); - parent.sendEvent (SWT.PaintItem, event); - event.gc = null; - if (gc.isDisposed ()) return false; - gc.setAlpha (oldAlpha); - gc.setAntialias (oldAntialias); - gc.setBackgroundPattern (oldBackgroundPattern); - gc.setClipping (cellBounds); - gc.setForegroundPattern (oldForegroundPattern); - gc.setInterpolation (oldInterpolation); - gc.setLineDash (oldLineDash); - gc.setLineWidth (oldLineWidth); - gc.setTextAntialias (oldTextAntialias); - gc.setAdvanced (oldAdvanced); - drawFocus = isFocusItem && (event.detail & SWT.FOCUSED) != 0; - } - - return isFocusItem && !drawFocus; -} -/* - * Redraw part of the receiver. If either EraseItem or PaintItem is hooked then - * only full cells should be damaged, so adjust accordingly. If neither of these - * events are hooked then the exact bounds given for damaging can be used. - */ -void redraw (int x, int y, int width, int height, int columnIndex) { - if (!parent.hooks (SWT.EraseItem) && !parent.hooks (SWT.PaintItem)) { - parent.redraw (x, y, width, height, false); - return; - } - Rectangle cellBounds = getCellBounds (columnIndex); - parent.redraw (cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, false); -} -void redrawItem () { - if (!isAvailable ()) return; - parent.redraw (0, parent.getItemY (this), parent.clientArea.width, parent.itemHeight, false); -} -/* - * Updates internal structures in the receiver and its child items to handle the removal of a column. - */ -void removeColumn (TreeColumn column, int index, int orderedIndex) { - int columnCount = parent.columns.length; - - if (columnCount == 0) { - /* reverts to normal tree when last column disposed */ - cellBackgrounds = cellForegrounds = null; - displayTexts = null; - cellFonts = null; - fontHeights = null; - GC gc = new GC (parent); - computeTextWidths (gc); - gc.dispose (); - /* notify all child items as well */ - for (int i = 0; i < items.length; i++) { - items [i].removeColumn (column, index, orderedIndex); - } - return; - } - - String[] newTexts = new String [columnCount]; - System.arraycopy (texts, 0, newTexts, 0, index); - System.arraycopy (texts, index + 1, newTexts, index, columnCount - index); - texts = newTexts; - - Image[] newImages = new Image [columnCount]; - System.arraycopy (images, 0, newImages, 0, index); - System.arraycopy (images, index + 1, newImages, index, columnCount - index); - images = newImages; - - int[] newTextWidths = new int [columnCount]; - System.arraycopy (textWidths, 0, newTextWidths, 0, index); - System.arraycopy (textWidths, index + 1, newTextWidths, index, columnCount - index); - textWidths = newTextWidths; - - String[] newDisplayTexts = new String [columnCount]; - System.arraycopy (displayTexts, 0, newDisplayTexts, 0, index); - System.arraycopy (displayTexts, index + 1, newDisplayTexts, index, columnCount - index); - displayTexts = newDisplayTexts; - - if (cellBackgrounds != null) { - Color[] newCellBackgrounds = new Color [columnCount]; - System.arraycopy (cellBackgrounds, 0, newCellBackgrounds, 0, index); - System.arraycopy (cellBackgrounds, index + 1, newCellBackgrounds, index, columnCount - index); - cellBackgrounds = newCellBackgrounds; - } - if (cellForegrounds != null) { - Color[] newCellForegrounds = new Color [columnCount]; - System.arraycopy (cellForegrounds, 0, newCellForegrounds, 0, index); - System.arraycopy (cellForegrounds, index + 1, newCellForegrounds, index, columnCount - index); - cellForegrounds = newCellForegrounds; - } - if (cellFonts != null) { - Font[] newCellFonts = new Font [columnCount]; - System.arraycopy (cellFonts, 0, newCellFonts, 0, index); - System.arraycopy (cellFonts, index + 1, newCellFonts, index, columnCount - index); - cellFonts = newCellFonts; - - int[] newFontHeights = new int [columnCount]; - System.arraycopy (fontHeights, 0, newFontHeights, 0, index); - System.arraycopy (fontHeights, index + 1, newFontHeights, index, columnCount - index); - fontHeights = newFontHeights; - } - - if (index == 0) { - text = texts [0] != null ? texts [0] : ""; //$NON-NLS-1$ - texts [0] = null; - image = images [0]; - images [0] = null; - } - - if (orderedIndex == 0) { - /* - * The new first ordered column will not have as much width available to it as it did when - * it was the second ordered column since it now has to show hierarchy decorations as well, - * so recompute its displayText. - */ - int firstColumnIndex = parent.getOrderedColumns () [0].getIndex (); - GC gc = new GC (parent); - gc.setFont (getFont (firstColumnIndex, false)); - computeDisplayText (firstColumnIndex, gc); - gc.dispose (); - } - if (columnCount < 2) { - texts = null; - images = null; - } - - /* notify all child items as well */ - for (int i = 0; i < items.length; i++) { - items [i].removeColumn (column, index, orderedIndex); - } -} -/** - * Removes all of the items from the receiver. - * <p> - * @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 void removeAll () { - checkWidget (); - if (items.length == 0) return; - - int lastAvailableIndex = parent.availableItemsCount - 1; - /* for performance do this upfront for whole descendent chain */ - TreeItem focusItem = parent.focusItem; - if (focusItem != null && focusItem.hasAncestor (this)) { - parent.setFocusItem (this, false); - } - while (items.length > 0) { - items [0].dispose (true); - removeItem (items [0], 0); - } - items = Tree.NO_ITEMS; - expanded = false; - if (isAvailable ()) { - parent.redrawItems (availableIndex, lastAvailableIndex, false); - } -} -/* - * Removes a child item from the receiver. - */ -void removeItem (TreeItem item, int index) { - if (isDisposed ()) return; - TreeItem[] newItems = new TreeItem [items.length - 1]; - System.arraycopy (items, 0, newItems, 0, index); - System.arraycopy (items, index + 1, newItems, index, newItems.length - index); - items = newItems; - if (items.length == 0) { - items = Tree.NO_ITEMS; - /* condition below handles creation of item within Expand callback */ - if (!parent.inExpand) { - expanded = false; - if (isInViewport ()) { - Rectangle bounds = getExpanderBounds (); /* expander box no longer needed */ - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } - } - return; - } -} -/** - * 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); - } - Color oldColor = background; - if (oldColor == color) return; - background = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - redrawItem (); -} -/** - * Sets the background color at the given column index in the receiver - * to the color specified by the argument, or to the default system color for the item - * if the argument is null. - * - * @param index the column index - * @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 3.1 - * - */ -public void setBackground (int columnIndex, Color color) { - checkWidget (); - if (color != null && color.isDisposed ()) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (cellBackgrounds == null) { - if (color == null) return; - cellBackgrounds = new Color [validColumnCount]; - } - Color oldColor = cellBackgrounds [columnIndex]; - if (oldColor == color) return; - cellBackgrounds [columnIndex] = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - if (isInViewport ()) { - Rectangle bounds = getCellBounds (columnIndex); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -/** - * Sets the checked state of the receiver. - * <p> - * - * @param checked the new checked state - * - * @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 value) { - checkWidget (); - if ((parent.getStyle () & SWT.CHECK) == 0) return; - if (checked == value) return; - checked = value; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - if (isInViewport ()) { - if (parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) { - redrawItem (); - } else { - Rectangle bounds = getCheckboxBounds (); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } - } -} -/** - * Sets the expanded state of the receiver. - * <p> - * - * @param expanded the new expanded state - * - * @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 setExpanded (boolean value) { - checkWidget (); - if (expanded == value) return; - if (items.length == 0) return; - if (parent.inExpand) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - if (value) { - expanded = value; - if (availableIndex == -1) return; - - TreeItem[] availableDescendents = computeAvailableDescendents (); - int descendentsCount = availableDescendents.length; - if (availableIndex != parent.availableItemsCount - 1) { - /* the receiver is not the last available item */ - Rectangle clientArea = parent.clientArea; - int y = parent.getItemY (this) + parent.itemHeight; - if (0 < y && y < clientArea.height) { - if (parent.drawCount <= 0) { - parent.update (); - GC gc = new GC (parent); - gc.copyArea ( - 0, y, - clientArea.width, clientArea.height - y, - 0, y + ((descendentsCount - 1) * parent.itemHeight)); - gc.dispose (); - } - } - } - - parent.makeDescendentsAvailable (this, availableDescendents); - - /* update scrollbars */ - int rightX = 0; - for (int i = 1; i < availableDescendents.length; i++) { - Rectangle bounds = availableDescendents [i].getBounds (false); - rightX = Math.max (rightX, bounds.x + bounds.width); - } - parent.updateHorizontalBar (rightX, rightX); - parent.updateVerticalBar (); - /* - * If new item is above viewport then adjust topIndex and the vertical scrollbar - * so that the current viewport items will not change. - */ - if (availableIndex < parent.topIndex) { - parent.topIndex += descendentsCount - 1; - ScrollBar vBar = parent.getVerticalBar (); - if (vBar != null) vBar.setSelection (parent.topIndex); - return; - } - - int redrawStart = availableIndex + 1; - int redrawEnd = redrawStart + descendentsCount - 2; - parent.redrawItems (redrawStart, redrawEnd, false); - } else { - TreeItem[] descendents = computeAvailableDescendents (); - expanded = value; - if (availableIndex == -1) return; - Rectangle clientArea = parent.clientArea; - - int y = parent.getItemY (this) + parent.itemHeight; - int startY = y + (descendents.length - 1) * parent.itemHeight; - if (y < clientArea.height && 0 < startY) { /* determine whether any visual update is actually needed */ - if (parent.drawCount <= 0) { - parent.update (); - GC gc = new GC (parent); - gc.copyArea (0, startY, clientArea.width, clientArea.height - startY, 0, y); - gc.dispose (); - int redrawY = y + Math.max (0, clientArea.height - startY); - parent.redraw (0, redrawY, clientArea.width, clientArea.height - redrawY, false); - } - } - - parent.makeDescendentsUnavailable (this, descendents); - - /* - * If all collapsed items are above the viewport then adjust topIndex and - * the vertical scrollbar so that the current viewport items will not change. - */ - int bottomIndex = availableIndex + descendents.length - 1; - if (bottomIndex < parent.topIndex) { - parent.topIndex = parent.topIndex - descendents.length + 1; - ScrollBar vBar = parent.getVerticalBar (); - if (vBar != null) vBar.setSelection (parent.topIndex); - } - - parent.updateHorizontalBar (); - parent.updateVerticalBar (); - - /* move focus (and selection if SWT.SINGLE) to item if a descendent had focus */ - TreeItem focusItem = parent.focusItem; - if (focusItem != null && focusItem != this && focusItem.hasAncestor (this)) { - parent.setFocusItem (this, false); - if ((parent.style & SWT.SINGLE) != 0) { - parent.selectItem (this, false); - } - /* Fire an event since the selection is being changed automatically */ - Event newEvent = new Event (); - newEvent.item = this; - parent.sendEvent (SWT.Selection, newEvent); - if (isDisposed ()) return; - parent.showItem (this); - parent.redrawItem (availableIndex, true); - } - } - /* redraw the receiver's expander box */ - if (isInViewport ()) { - Rectangle bounds = getExpanderBounds (); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -/** - * 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); - } - Font oldFont = this.font; - if (oldFont == font) return; - this.font = font; - if (oldFont != null && oldFont.equals (font)) return; - - Rectangle bounds = getBounds (false); - int oldRightX = bounds.x + bounds.width; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - /* recompute cached values for string measurements */ - GC gc = new GC (parent); - gc.setFont (getFont (false)); - fontHeight = gc.getFontMetrics ().getHeight (); - computeDisplayTexts (gc); - computeTextWidths (gc); - gc.dispose (); - - /* horizontal bar could be affected if tree has no columns */ - if (parent.columns.length == 0) { - bounds = getBounds (false); - int newRightX = bounds.x + bounds.width; - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } - redrawItem (); -} -/** - * Sets the font that the receiver will use to paint textual information - * for the specified cell in 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 index the column index - * @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.1 - */ -public void setFont (int columnIndex, Font font) { - checkWidget (); - if (font != null && font.isDisposed ()) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (cellFonts == null) { - if (font == null) return; - cellFonts = new Font [validColumnCount]; - } - Font oldFont = cellFonts [columnIndex]; - if (oldFont == font) return; - cellFonts [columnIndex] = font; - if (oldFont != null && oldFont.equals (font)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - /* recompute cached values for string measurements */ - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - if (fontHeights == null) fontHeights = new int [validColumnCount]; - fontHeights [columnIndex] = gc.getFontMetrics ().getHeight (); - computeDisplayText (columnIndex, gc); - gc.dispose (); - - if (isInViewport ()) { - Rectangle bounds = getCellBounds (columnIndex); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -/** - * 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); - } - Color oldColor = foreground; - if (oldColor == color) return; - foreground = color; - if (oldColor != null && oldColor.equals (color)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - redrawItem (); -} -/** - * Sets the foreground color at the given column index in the receiver - * to the color specified by the argument, or to the default system color for the item - * if the argument is null. - * - * @param index the column index - * @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 3.1 - * - */ -public void setForeground (int columnIndex, Color value) { - checkWidget (); - if (value != null && value.isDisposed ()) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (cellForegrounds == null) { - if (value == null) return; - cellForegrounds = new Color [validColumnCount]; - } - Color oldColor = cellForegrounds [columnIndex]; - if (oldColor == value) return; - cellForegrounds [columnIndex] = value; - if (oldColor != null && oldColor.equals (value)) return; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - if (isInViewport ()) { - redraw ( - getTextX (columnIndex), - parent.getItemY (this), - textWidths [columnIndex] + 2 * MARGIN_TEXT, - parent.itemHeight, - columnIndex); - } -} -/** - * Sets the grayed state of the checkbox for this item. This state change - * only applies if the Tree 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> - */ -public void setGrayed (boolean value) { - checkWidget (); - if ((parent.getStyle () & SWT.CHECK) == 0) return; - if (grayed == value) return; - grayed = value; - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - if (isInViewport ()) { - Rectangle bounds = getCheckboxBounds (); - parent.redraw (bounds.x, bounds.y, bounds.width, bounds.height, false); - } -} -public void setImage (Image value) { - checkWidget (); - setImage (0, value); -} -/** - * Sets the image for multiple columns in the tree. - * - * @param images the array of new images - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li> - * <li>ERROR_INVALID_ARGUMENT - if one of the images 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.1 - */ -public void setImage (Image[] value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - - // TODO make a smarter implementation of this - for (int i = 0; i < value.length; i++) { - if (value [i] != null) setImage (i, value [i]); - } -} -/** - * Sets the receiver's image at a column. - * - * @param index the column index - * @param image the new image - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the image 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.1 - */ -public void setImage (int columnIndex, Image value) { - checkWidget (); - if (value != null && value.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); - - TreeColumn[] columns = parent.columns; - int validColumnCount = Math.max (1, columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - Image image = getImage (columnIndex, false); - if (value == image) return; - if (value != null && value.equals (image)) return; - if (columnIndex == 0) { - super.setImage (value); - } else { - images [columnIndex] = value; - } - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - /* - * An image width change may affect the space available for the item text, so - * recompute the displayText if there are columns. - */ - if (columns.length > 0) { - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - computeDisplayText (columnIndex, gc); - gc.dispose (); - } - - if (value == null) { - redrawItem (); // TODO why the whole item? - return; - } - - if (columns.length == 0) { - if (parent.imageHeight == 0) { - /* this is the first image being put into the parent Tree */ - Rectangle bounds = value.getBounds (); - parent.orderedCol0imageWidth = bounds.width; - parent.setImageHeight (bounds.height); - parent.redrawItems (0, parent.availableItemsCount - 1, false); - } else { - redrawItem (); - } - return; - } - - /* there are 1+ columns */ - TreeColumn column = columns [columnIndex]; - int orderedIndex = column.getOrderIndex (); - Rectangle bounds = value.getBounds (); - if (column.itemImageWidth == 0) column.itemImageWidth = bounds.width; - - if (parent.imageHeight == 0) { - /* this is the first image being put into the parent Tree */ - int oldItemHeight = parent.itemHeight; - parent.setImageHeight (bounds.height); - - if (orderedIndex == 0) { /* the first ordered column */ - parent.orderedCol0imageWidth = bounds.width; - /* - * All column 0 cells will now have less room available for their texts, - * so all items must now recompute their column 0 displayTexts. - */ - TreeItem[] rootItems = parent.items; - GC gc = new GC (parent); - for (int i = 0; i < rootItems.length; i++) { - rootItems [i].updateColumnWidth (column, gc); - } - gc.dispose (); - if (oldItemHeight != parent.itemHeight) { - /* the item height grew as a result of the new image height, so redraw everything */ - parent.redraw (); - } else { - /* redraw the column since all items should now have image space */ - parent.redraw (column.getX (), 0, column.width, parent.clientArea.height, false); - } - } else { /* not the first ordered column */ - if (oldItemHeight != parent.itemHeight) { - /* the item height grew as a result of the new image height, so redraw everything */ - parent.redraw (); - } else { - redrawItem (); - } - } - return; - } - - if (orderedIndex == 0 && parent.orderedCol0imageWidth == 0) { - /* this is the first image being put into the current ordered column 0 */ - parent.orderedCol0imageWidth = bounds.width; - /* - * All column 0 cells will now have less room available for their texts, - * so all items must now recompute their column 0 displayTexts. - */ - TreeItem[] rootItems = parent.items; - GC gc = new GC (parent); - for (int i = 0; i < rootItems.length; i++) { - rootItems [i].updateColumnWidth (column, gc); - } - gc.dispose (); - parent.redraw (column.getX (), 0, column.width, parent.clientArea.height, false); - return; - } - - redrawItem (); // TODO why the whole item? -} -/** - * Sets the number of child items contained in the receiver. - * - * @param count the number of items - * - * @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.2 - */ -public void setItemCount (int count) { - checkWidget (); - count = Math.max (0, count); - if (count == items.length) return; - int redrawStart, redrawEnd; - - /* if the new item count is less than the current count then remove all excess items from the end */ - if (count < items.length) { - redrawStart = count > 0 ? items [count - 1].availableIndex : availableIndex; - redrawEnd = parent.availableItemsCount - 1; - for (int i = count; i < items.length; i++) { - items [i].dispose (true); - } - if (count == 0) { - items = Tree.NO_ITEMS; - } else { - TreeItem[] newItems = new TreeItem [count]; - System.arraycopy (items, 0, newItems, 0, count); - items = newItems; - } - if (count == 0) expanded = false; - } else { - int oldAvailableDescendentCount = computeAvailableDescendentCount (); - int grow = count - items.length; - redrawStart = items.length == 0 ? availableIndex : items [items.length - 1].availableIndex; - redrawEnd = expanded && isAvailable () ? parent.availableItemsCount + grow - 1: redrawStart; - TreeItem[] newItems = new TreeItem [count]; - System.arraycopy (items, 0, newItems, 0, items.length); - items = newItems; - for (int i = items.length - grow; i < count; i++) { - items [i] = new TreeItem (this, SWT.NONE, i, false); - } - - if (expanded && availableIndex != -1) { - /* expand the availableItems array if necessary */ - if (parent.availableItems.length < parent.availableItemsCount + grow) { - TreeItem[] newAvailableItems = new TreeItem [parent.availableItemsCount + grow]; - System.arraycopy (parent.availableItems, 0, newAvailableItems, 0, parent.availableItemsCount); - parent.availableItems = newAvailableItems; - } - TreeItem[] availableItems = parent.availableItems; - /* shift items right to create space for the new available items */ - int dest = availableIndex + oldAvailableDescendentCount + grow; - System.arraycopy ( - availableItems, - availableIndex + oldAvailableDescendentCount, - availableItems, - dest, - availableItems.length - dest); - parent.availableItemsCount += grow; - /* copy new items in */ - System.arraycopy ( - items, - items.length - grow, - availableItems, - availableIndex + oldAvailableDescendentCount, - grow); - /* update availableIndex for all affected items */ - for (int i = availableIndex + oldAvailableDescendentCount; i < parent.availableItemsCount; i++) { - availableItems [i].availableIndex = i; - } - } - } - - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - if (availableIndex != -1) { - if (expanded) parent.updateVerticalBar (); - parent.redrawItems (redrawStart, redrawEnd, false); - } -} -public void setText (String value) { - checkWidget (); - Rectangle bounds = getBounds (false); - int oldRightX = bounds.x + bounds.width; - setText (0, value); - /* horizontal bar could be affected if tree has no columns */ - if (parent.columns.length == 0) { - bounds = getBounds (false); - int newRightX = bounds.x + bounds.width; - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } -} -/** - * Sets the text for multiple columns in the tree. - * - * @param strings the array of new strings - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the text 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> - * - * @since 3.1 - */ -public void setText (String[] value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - Rectangle bounds = getBounds (false); - int oldRightX = bounds.x + bounds.width; - // TODO make a smarter implementation of this - for (int i = 0; i < value.length; i++) { - if (value [i] != null) setText (i, value [i]); - } - /* horizontal bar could be affected if tree has no columns */ - if (parent.columns.length == 0) { - bounds = getBounds (false); - int newRightX = bounds.x + bounds.width; - parent.updateHorizontalBar (newRightX, newRightX - oldRightX); - } -} -/** - * Sets the receiver's text at a column - * - * @param index the column index - * @param string the new text - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the text 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> - * - * @since 3.1 - */ -public void setText (int columnIndex, String value) { - checkWidget (); - if (value == null) error (SWT.ERROR_NULL_ARGUMENT); - int validColumnCount = Math.max (1, parent.columns.length); - if (!(0 <= columnIndex && columnIndex < validColumnCount)) return; - if (value.equals (getText (columnIndex, false))) return; - if (columnIndex == 0) { - super.setText (value); - } else { - texts [columnIndex] = value; - } - if ((parent.style & SWT.VIRTUAL) != 0) cached = true; - - int oldWidth = textWidths [columnIndex]; - GC gc = new GC (parent); - gc.setFont (getFont (columnIndex, false)); - computeDisplayText (columnIndex, gc); - gc.dispose (); - if (availableIndex == -1) return; - if (parent.columns.length == 0) { - Rectangle bounds = getBounds (false); - int rightX = bounds.x + bounds.width; - parent.updateHorizontalBar (rightX, textWidths [columnIndex] - oldWidth); - } - if (isInViewport ()) { - redraw ( - getTextX (columnIndex), - parent.getItemY (this), - Math.max (oldWidth, textWidths [columnIndex]) + 2 * MARGIN_TEXT, - parent.itemHeight, - columnIndex); - } -} -/* - * Perform any internal changes necessary to reflect a changed column width. - */ -void updateColumnWidth (TreeColumn column, GC gc) { - int columnIndex = column.getIndex (); - gc.setFont (getFont (columnIndex, false)); - String oldDisplayText = displayTexts [columnIndex]; - computeDisplayText (columnIndex, gc); - - /* the cell must be damaged if there is custom drawing being done or if the alignment is not LEFT */ - if (isInViewport ()) { - boolean columnIsLeft = (column.style & SWT.LEFT) != 0; - if (!columnIsLeft || parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) { - Rectangle cellBounds = getCellBounds (columnIndex); - parent.redraw (cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, false); - } else { - /* if the display text has changed then the cell text must be damaged in order to repaint */ - if (oldDisplayText == null || !oldDisplayText.equals (displayTexts [columnIndex])) { - Rectangle cellBounds = getCellBounds (columnIndex); - int textX = getTextX (columnIndex); - parent.redraw (textX, cellBounds.y, cellBounds.x + cellBounds.width - textX, cellBounds.height, false); - } - } - } - - for (int i = 0; i < items.length; i++) { - items [i].updateColumnWidth (column, gc); - } -} - -/* - * The parent's font has changed, so if this font was being used by the receiver then - * recompute its cached text sizes using the gc argument. Pass this notification on to - * all child items as well. - */ -void updateFont (GC gc) { - if (font == null) { /* receiver is using the Tree's font */ - computeDisplayTexts (gc); - computeTextWidths (gc); - } - /* pass notification on to all children */ - for (int i = 0; i < items.length; i++) { - items [i].updateFont (gc); - } -} -} |