diff dwtx/jface/viewers/TableTreeViewer.d @ 10:b6c35faf97c8

Viewers
author Frank Benoit <benoit@tionex.de>
date Mon, 31 Mar 2008 00:47:19 +0200
parents
children 644f1334b451
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/viewers/TableTreeViewer.d	Mon Mar 31 00:47:19 2008 +0200
@@ -0,0 +1,882 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *     Tom Schindl <tom.schindl@bestsolution.at> - bug 153993
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+module dwtx.jface.viewers.TableTreeViewer;
+
+import dwtx.jface.viewers.AbstractTreeViewer;
+import dwtx.jface.viewers.CellEditor;
+import dwtx.jface.viewers.ICellEditorListener;
+import dwtx.jface.viewers.ICellModifier;
+import dwtx.jface.viewers.ColumnViewer;
+import dwtx.jface.viewers.IBaseLabelProvider;
+import dwtx.jface.viewers.StructuredSelection;
+import dwtx.jface.viewers.Viewer;
+import dwtx.jface.viewers.DoubleClickEvent;
+import dwtx.jface.viewers.OpenEvent;
+import dwtx.jface.viewers.ITableLabelProvider;
+import dwtx.jface.viewers.ViewerLabel;
+
+import tango.util.collection.model.SeqView;
+
+import dwt.DWT;
+import dwt.custom.TableTree;
+import dwt.custom.TableTreeEditor;
+import dwt.custom.TableTreeItem;
+import dwt.events.FocusAdapter;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.MouseAdapter;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.TreeListener;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Item;
+import dwt.widgets.Widget;
+
+import dwt.dwthelper.utils;
+
+/**
+ * A concrete viewer based on a DWT <code>TableTree</code> control.
+ * <p>
+ * This class is not intended to be subclassed outside the viewer framework. It
+ * is designed to be instantiated with a pre-existing DWT table tree control and
+ * configured with a domain-specific content provider, label provider, element
+ * filter (optional), and element sorter (optional).
+ * </p>
+ * <p>
+ * Content providers for table tree viewers must implement the
+ * <code>ITreeContentProvider</code> interface.
+ * </p>
+ * <p>
+ * Label providers for table tree viewers must implement either the
+ * <code>ITableLabelProvider</code> or the <code>ILabelProvider</code>
+ * interface (see <code>TableTreeViewer.setLabelProvider</code> for more
+ * details).
+ * </p>
+ *
+ * @deprecated As of 3.1 use {@link TreeViewer} instead
+ */
+public class TableTreeViewer : AbstractTreeViewer {
+    alias AbstractTreeViewer.setSelection setSelection;
+    /**
+     * Internal table viewer implementation.
+     */
+    private TableTreeEditorImpl tableEditorImpl;
+
+    /**
+     * This viewer's table tree control.
+     */
+    private TableTree tableTree;
+
+    /**
+     * This viewer's table tree editor.
+     */
+    private TableTreeEditor tableTreeEditor;
+
+    /**
+     * Copied from original TableEditorImpl and moved here since refactoring
+     * completely wiped out the original implementation in 3.3
+     *
+     * @since 3.1
+     */
+    class TableTreeEditorImpl {
+
+        private CellEditor cellEditor;
+
+        private CellEditor[] cellEditors;
+
+        private ICellModifier cellModifier;
+
+        private String[] columnProperties;
+
+        private Item tableItem;
+
+        private int columnNumber;
+
+        private ICellEditorListener cellEditorListener;
+
+        private FocusListener focusListener;
+
+        private MouseListener mouseListener;
+
+        private int doubleClickExpirationTime;
+
+        private ColumnViewer viewer;
+
+        private this(ColumnViewer viewer) {
+            this.viewer = viewer;
+            initCellEditorListener();
+        }
+
+        /**
+         * Returns this <code>TableViewerImpl</code> viewer
+         *
+         * @return the viewer
+         */
+        public ColumnViewer getViewer() {
+            return viewer;
+        }
+
+        private void activateCellEditor() {
+            if( cellEditors !is null ) {
+                if( cellEditors[columnNumber] !is null && cellModifier !is null ) {
+                    Object element = tableItem.getData();
+                    String property = columnProperties[columnNumber];
+
+                    if( cellModifier.canModify(element, property) ) {
+                        cellEditor = cellEditors[columnNumber];
+
+                        cellEditor.addListener(cellEditorListener);
+
+                        Object value = cellModifier.getValue(element, property);
+                        cellEditor.setValue(value);
+                        // Tricky flow of control here:
+                        // activate() can trigger callback to cellEditorListener
+                        // which will clear cellEditor
+                        // so must get control first, but must still call activate()
+                        // even if there is no control.
+                        final Control control = cellEditor.getControl();
+                        cellEditor.activate();
+                        if (control is null) {
+                            return;
+                        }
+                        setLayoutData(cellEditor.getLayoutData());
+                        setEditor(control, tableItem, columnNumber);
+                        cellEditor.setFocus();
+                        if (focusListener is null) {
+                            focusListener = new class FocusAdapter {
+                                public void focusLost(FocusEvent e) {
+                                    applyEditorValue();
+                                }
+                            };
+                        }
+                        control.addFocusListener(focusListener);
+                        mouseListener = new class MouseAdapter {
+                            Control control_;
+                            this(){
+                                control_=control;
+                            }
+                            public void mouseDown(MouseEvent e) {
+                                // time wrap?
+                                // check for expiration of doubleClickTime
+                                if (e.time <= doubleClickExpirationTime) {
+                                    control_.removeMouseListener(mouseListener);
+                                    cancelEditing();
+                                    handleDoubleClickEvent();
+                                } else if (mouseListener !is null) {
+                                    control_.removeMouseListener(mouseListener);
+                                }
+                            }
+                        };
+                        control.addMouseListener(mouseListener);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Activate a cell editor for the given mouse position.
+         */
+        private void activateCellEditor(MouseEvent event) {
+            if (tableItem is null || tableItem.isDisposed()) {
+                // item no longer exists
+                return;
+            }
+            int columnToEdit;
+            int columns = getColumnCount();
+            if (columns is 0) {
+                // If no TableColumn, Table acts as if it has a single column
+                // which takes the whole width.
+                columnToEdit = 0;
+            } else {
+                columnToEdit = -1;
+                for (int i = 0; i < columns; i++) {
+                    Rectangle bounds = getBounds(tableItem, i);
+                    if (bounds.contains(event.x, event.y)) {
+                        columnToEdit = i;
+                        break;
+                    }
+                }
+                if (columnToEdit is -1) {
+                    return;
+                }
+            }
+
+            columnNumber = columnToEdit;
+            activateCellEditor();
+        }
+
+        /**
+         * Deactivates the currently active cell editor.
+         */
+        public void applyEditorValue() {
+            CellEditor c = this.cellEditor;
+            if (c !is null) {
+                // null out cell editor before calling save
+                // in case save results in applyEditorValue being re-entered
+                // see 1GAHI8Z: ITPUI:ALL - How to code event notification when
+                // using cell editor ?
+                this.cellEditor = null;
+                Item t = this.tableItem;
+                // don't null out table item -- same item is still selected
+                if (t !is null && !t.isDisposed()) {
+                    saveEditorValue(c, t);
+                }
+                setEditor(null, null, 0);
+                c.removeListener(cellEditorListener);
+                Control control = c.getControl();
+                if (control !is null) {
+                    if (mouseListener !is null) {
+                        control.removeMouseListener(mouseListener);
+                    }
+                    if (focusListener !is null) {
+                        control.removeFocusListener(focusListener);
+                    }
+                }
+                c.deactivate();
+            }
+        }
+
+        /**
+         * Cancels the active cell editor, without saving the value back to the
+         * domain model.
+         */
+        public void cancelEditing() {
+            if (cellEditor !is null) {
+                setEditor(null, null, 0);
+                cellEditor.removeListener(cellEditorListener);
+                CellEditor oldEditor = cellEditor;
+                cellEditor = null;
+                oldEditor.deactivate();
+            }
+        }
+
+        /**
+         * Start editing the given element.
+         *
+         * @param element
+         * @param column
+         */
+        public void editElement(Object element, int column) {
+            if (cellEditor !is null) {
+                applyEditorValue();
+            }
+
+            setSelection(new StructuredSelection(element), true);
+            Item[] selection = getSelection();
+            if (selection.length !is 1) {
+                return;
+            }
+
+            tableItem = selection[0];
+
+            // Make sure selection is visible
+            showSelection();
+            columnNumber = column;
+            activateCellEditor();
+
+        }
+
+        /**
+         * Return the array of CellEditors used in the viewer
+         *
+         * @return the cell editors
+         */
+        public CellEditor[] getCellEditors() {
+            return cellEditors;
+        }
+
+        /**
+         * Get the cell modifier
+         *
+         * @return the cell modifier
+         */
+        public ICellModifier getCellModifier() {
+            return cellModifier;
+        }
+
+        /**
+         * Return the properties for the column
+         *
+         * @return the array of column properties
+         */
+        public Object[] getColumnProperties() {
+            Object[] res;
+            foreach( str; columnProperties ){
+                res ~= new ArrayWrapperString( str );
+            }
+            return res;
+        }
+
+        /**
+         * Handles the mouse down event; activates the cell editor.
+         *
+         * @param event
+         *            the mouse event that should be handled
+         */
+        public void handleMouseDown(MouseEvent event) {
+            if (event.button !is 1) {
+                return;
+            }
+
+            if (cellEditor !is null) {
+                applyEditorValue();
+            }
+
+            // activate the cell editor immediately. If a second mouseDown
+            // is received prior to the expiration of the doubleClick time then
+            // the cell editor will be deactivated and a doubleClick event will
+            // be processed.
+            //
+            doubleClickExpirationTime = event.time
+                    + Display.getCurrent().getDoubleClickTime();
+
+            Item[] items = getSelection();
+            // Do not edit if more than one row is selected.
+            if (items.length !is 1) {
+                tableItem = null;
+                return;
+            }
+            tableItem = items[0];
+
+            activateCellEditor(event);
+        }
+
+        private void initCellEditorListener() {
+            cellEditorListener = new class ICellEditorListener {
+                public void editorValueChanged(bool oldValidState,
+                        bool newValidState) {
+                    // Ignore.
+                }
+
+                public void cancelEditor() {
+                    this.outer.cancelEditing();
+                }
+
+                public void applyEditorValue() {
+                    this.outer.applyEditorValue();
+                }
+            };
+        }
+
+        /**
+         * Return whether there is an active cell editor.
+         *
+         * @return <code>true</code> if there is an active cell editor;
+         *         otherwise <code>false</code> is returned.
+         */
+        public bool isCellEditorActive() {
+            return cellEditor !is null;
+        }
+
+        /**
+         * Saves the value of the currently active cell editor, by delegating to
+         * the cell modifier.
+         */
+        private void saveEditorValue(CellEditor cellEditor, Item tableItem) {
+            if( cellModifier !is null ) {
+                if( ! cellEditor.isValueValid() ) {
+                    // Do what????
+                }
+            }
+            String property = null;
+
+            if( columnProperties !is null && columnNumber < columnProperties.length ) {
+                property = columnProperties[columnNumber];
+            }
+            cellModifier.modify(tableItem, property, cellEditor.getValue());
+        }
+
+        /**
+         * Set the cell editors
+         *
+         * @param editors
+         */
+        public void setCellEditors(CellEditor[] editors) {
+            this.cellEditors = editors;
+        }
+
+        /**
+         * Set the cell modifier
+         *
+         * @param modifier
+         */
+        public void setCellModifier(ICellModifier modifier) {
+            this.cellModifier = modifier;
+        }
+
+        /**
+         * Set the column properties
+         *
+         * @param columnProperties
+         */
+        public void setColumnProperties(String[] columnProperties) {
+            this.columnProperties = columnProperties;
+        }
+
+        Rectangle getBounds(Item item, int columnNumber) {
+            return (cast(TableTreeItem) item).getBounds(columnNumber);
+        }
+
+        int getColumnCount() {
+            // getColumnCount() should be a API in TableTree.
+            return getTableTree().getTable().getColumnCount();
+        }
+
+        Item[] getSelection() {
+            return getTableTree().getSelection();
+        }
+
+        void setEditor(Control w, Item item, int columnNumber) {
+            tableTreeEditor.setEditor(w, cast(TableTreeItem) item, columnNumber);
+        }
+
+        void setSelection(StructuredSelection selection, bool b) {
+            this.outer.setSelection(selection, b);
+        }
+
+        void showSelection() {
+            getTableTree().showSelection();
+        }
+
+        void setLayoutData(CellEditor.LayoutData layoutData) {
+            tableTreeEditor.horizontalAlignment = layoutData.horizontalAlignment;
+            tableTreeEditor.grabHorizontal = layoutData.grabHorizontal;
+            tableTreeEditor.minimumWidth = layoutData.minimumWidth;
+        }
+
+        void handleDoubleClickEvent() {
+            Viewer viewer = getViewer();
+            fireDoubleClick(new DoubleClickEvent(viewer, viewer.getSelection()));
+            fireOpen(new OpenEvent(viewer, viewer.getSelection()));
+        }
+    }
+
+    /**
+     * Creates a table tree viewer on the given table tree control. The viewer
+     * has no input, no content provider, a default label provider, no sorter,
+     * and no filters.
+     *
+     * @param tree
+     *            the table tree control
+     */
+    public this(TableTree tree) {
+        super();
+        tableTree = tree;
+        hookControl(tree);
+        tableTreeEditor = new TableTreeEditor(tableTree);
+        tableEditorImpl = new TableTreeEditorImpl(this);
+    }
+
+    /**
+     * Creates a table tree viewer on a newly-created table tree control under
+     * the given parent. The table tree control is created using the DWT style
+     * bits <code>MULTI, H_SCROLL, V_SCROLL, and BORDER</code>. The viewer
+     * has no input, no content provider, a default label provider, no sorter,
+     * and no filters.
+     *
+     * @param parent
+     *            the parent control
+     */
+    public this(Composite parent) {
+        this(parent, DWT.MULTI | DWT.H_SCROLL | DWT.V_SCROLL | DWT.BORDER);
+    }
+
+    /**
+     * Creates a table tree viewer on a newly-created table tree control under
+     * the given parent. The table tree control is created using the given DWT
+     * style bits. The viewer has no input, no content provider, a default label
+     * provider, no sorter, and no filters.
+     *
+     * @param parent
+     *            the parent control
+     * @param style
+     *            the DWT style bits
+     */
+    public this(Composite parent, int style) {
+        this(new TableTree(parent, style));
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected void addTreeListener(Control c, TreeListener listener) {
+        (cast(TableTree) c).addTreeListener(listener);
+    }
+
+    /**
+     * Cancels a currently active cell editor. All changes already done in the
+     * cell editor are lost.
+     */
+    public void cancelEditing() {
+        tableEditorImpl.cancelEditing();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected void doUpdateItem(Item item, Object element) {
+        // update icon and label
+        // Similar code in TableTreeViewer.doUpdateItem()
+        IBaseLabelProvider prov = getLabelProvider();
+        ITableLabelProvider tprov = null;
+
+        if ( auto t = cast(ITableLabelProvider) prov ) {
+            tprov = t;
+        }
+
+        int columnCount = tableTree.getTable().getColumnCount();
+        TableTreeItem ti = cast(TableTreeItem) item;
+        // Also enter loop if no columns added. See 1G9WWGZ: JFUIF:WINNT -
+        // TableViewer with 0 columns does not work
+        for (int column = 0; column < columnCount || column is 0; column++) {
+            String text = "";//$NON-NLS-1$
+            Image image = null;
+            if (tprov !is null) {
+                text = tprov.getColumnText(element, column);
+                image = tprov.getColumnImage(element, column);
+            } else {
+                if (column is 0) {
+                    ViewerLabel updateLabel = new ViewerLabel(item.getText(),
+                            item.getImage());
+                    buildLabel(updateLabel, element);
+
+                    // As it is possible for user code to run the event
+                    // loop check here.
+                    if (item.isDisposed()) {
+                        unmapElement(element, item);
+                        return;
+                    }
+
+                    text = updateLabel.getText();
+                    image = updateLabel.getImage();
+                }
+            }
+
+            // Avoid setting text to null
+            if (text is null) {
+                text = ""; //$NON-NLS-1$
+            }
+
+            ti.setText(column, text);
+            // Apparently a problem to setImage to null if already null
+            if (ti.getImage(column) !is image) {
+                ti.setImage(column, image);
+            }
+
+            getColorAndFontCollector().setFontsAndColors(element);
+            getColorAndFontCollector().applyFontsAndColors(ti);
+        }
+
+    }
+
+    /**
+     * Starts editing the given element.
+     *
+     * @param element
+     *            the element
+     * @param column
+     *            the column number
+     */
+    public void editElement(Object element, int column) {
+        tableEditorImpl.editElement(element, column);
+    }
+
+    /**
+     * Returns the cell editors of this viewer.
+     *
+     * @return the list of cell editors
+     */
+    public CellEditor[] getCellEditors() {
+        return tableEditorImpl.getCellEditors();
+    }
+
+    /**
+     * Returns the cell modifier of this viewer.
+     *
+     * @return the cell modifier
+     */
+    public ICellModifier getCellModifier() {
+        return tableEditorImpl.getCellModifier();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected Item[] getChildren(Widget o) {
+        if (auto i = cast(TableTreeItem) o ) {
+            return i.getItems();
+        }
+        if (auto i = cast(TableTree) o ) {
+            return i.getItems();
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see dwtx.jface.viewers.AbstractTreeViewer#getChild(dwt.widgets.Widget,
+     *      int)
+     */
+    protected Item getChild(Widget widget, int index) {
+        if (auto w = cast(TableTreeItem) widget ) {
+            return w.getItem(index);
+        }
+        if (auto w = cast(TableTree) widget ) {
+            return w.getItem(index);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the column properties of this viewer. The properties must
+     * correspond with the columns of the table control. They are used to
+     * identify the column in a cell modifier.
+     *
+     * @return the list of column properties
+     */
+    public Object[] getColumnProperties() {
+        return tableEditorImpl.getColumnProperties();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on Viewer.
+     */
+    public Control getControl() {
+        return tableTree;
+    }
+
+    /**
+     * Returns the element with the given index from this viewer. Returns
+     * <code>null</code> if the index is out of range.
+     * <p>
+     * This method is internal to the framework.
+     * </p>
+     *
+     * @param index
+     *            the zero-based index
+     * @return the element at the given index, or <code>null</code> if the
+     *         index is out of range
+     */
+    public Object getElementAt(int index) {
+        // XXX: Workaround for 1GBCSB1: DWT:WIN2000 - TableTree should have
+        // getItem(int index)
+        TableTreeItem i = tableTree.getItems()[index];
+        if (i !is null) {
+            return i.getData();
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected bool getExpanded(Item item) {
+        return (cast(TableTreeItem) item).getExpanded();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see dwtx.jface.viewers.ColumnViewer#getItemAt(dwt.graphics.Point)
+     */
+    protected Item getItemAt(Point p) {
+        return getTableTree().getTable().getItem(p);
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected int getItemCount(Control widget) {
+        return (cast(TableTree) widget).getItemCount();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected int getItemCount(Item item) {
+        return (cast(TableTreeItem) item).getItemCount();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected dwt.widgets.Item.Item[] getItems(
+            dwt.widgets.Item.Item item) {
+        return (cast(TableTreeItem) item).getItems();
+    }
+
+    /**
+     * The table tree viewer implementation of this <code>Viewer</code>
+     * framework method returns the label provider, which in the case of table
+     * tree viewers will be an instance of either
+     * <code>ITableLabelProvider</code> or <code>ILabelProvider</code>. If
+     * it is an <code>ITableLabelProvider</code>, then it provides a separate
+     * label text and image for each column. If it is an
+     * <code>ILabelProvider</code>, then it provides only the label text and
+     * image for the first column, and any remaining columns are blank.
+     */
+    public IBaseLabelProvider getLabelProvider() {
+        return super.getLabelProvider();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected Item getParentItem(Item item) {
+        return (cast(TableTreeItem) item).getParentItem();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected Item[] getSelection(Control widget) {
+        return (cast(TableTree) widget).getSelection();
+    }
+
+    /**
+     * Returns this table tree viewer's table tree control.
+     *
+     * @return the table tree control
+     */
+    public TableTree getTableTree() {
+        return tableTree;
+    }
+
+    /*
+     * (non-Javadoc) Method declared on AbstractTreeViewer.
+     */
+    protected void hookControl(Control control) {
+        super.hookControl(control);
+        tableTree.getTable().addMouseListener(new class MouseAdapter {
+            public void mouseDown(MouseEvent e) {
+                /*
+                 * If user clicked on the [+] or [-], do not activate
+                 * CellEditor.
+                 */
+                // XXX: This code should not be here. DWT should either have
+                // support to see
+                // if the user clicked on the [+]/[-] or manage the table editor
+                // activation
+                dwt.widgets.TableItem.TableItem[] items = tableTree
+                        .getTable().getItems();
+                for (int i = 0; i < items.length; i++) {
+                    Rectangle rect = items[i].getImageBounds(0);
+                    if (rect.contains(e.x, e.y)) {
+                        return;
+                    }
+                }
+
+                tableEditorImpl.handleMouseDown(e);
+            }
+        });
+    }
+
+    /**
+     * Returns whether there is an active cell editor.
+     *
+     * @return <code>true</code> if there is an active cell editor, and
+     *         <code>false</code> otherwise
+     */
+    public bool isCellEditorActive() {
+        return tableEditorImpl.isCellEditorActive();
+    }
+
+    /*
+     * (non-Javadoc) Method declared in AbstractTreeViewer.
+     */
+    protected Item newItem(Widget parent, int flags, int ix) {
+        TableTreeItem item;
+        if (ix >= 0) {
+            if (cast(TableTreeItem) parent ) {
+                item = new TableTreeItem(cast(TableTreeItem) parent, flags, ix);
+            } else {
+                item = new TableTreeItem(cast(TableTree) parent, flags, ix);
+            }
+        } else {
+            if (cast(TableTreeItem)parent ) {
+                item = new TableTreeItem(cast(TableTreeItem) parent, flags);
+            } else {
+                item = new TableTreeItem(cast(TableTree) parent, flags);
+            }
+        }
+        return item;
+    }
+
+    /*
+     * (non-Javadoc) Method declared in AbstractTreeViewer.
+     */
+    protected void removeAll(Control widget) {
+        (cast(TableTree) widget).removeAll();
+    }
+
+    /**
+     * Sets the cell editors of this table viewer.
+     *
+     * @param editors
+     *            the list of cell editors
+     */
+    public void setCellEditors(CellEditor[] editors) {
+        tableEditorImpl.setCellEditors(editors);
+    }
+
+    /**
+     * Sets the cell modifier of this table viewer.
+     *
+     * @param modifier
+     *            the cell modifier
+     */
+    public void setCellModifier(ICellModifier modifier) {
+        tableEditorImpl.setCellModifier(modifier);
+    }
+
+    /**
+     * Sets the column properties of this table viewer. The properties must
+     * correspond with the columns of the table control. They are used to
+     * identify the column in a cell modifier.
+     *
+     * @param columnProperties
+     *            the list of column properties
+     */
+    public void setColumnProperties(String[] columnProperties) {
+        tableEditorImpl.setColumnProperties(columnProperties);
+    }
+
+    /*
+     * (non-Javadoc) Method declared in AbstractTreeViewer.
+     */
+    protected void setExpanded(Item node, bool expand) {
+        (cast(TableTreeItem) node).setExpanded(expand);
+    }
+
+    /*
+     * (non-Javadoc) Method declared in AbstractTreeViewer.
+     */
+    protected void setSelection(SeqView!(Item) items) {
+        getTableTree().setSelection(cast(TableTreeItem[]) items.toArray);
+    }
+
+    /*
+     * (non-Javadoc) Method declared in AbstractTreeViewer.
+     */
+    protected void showItem(Item item) {
+        getTableTree().showItem(cast(TableTreeItem) item);
+    }
+}