Mercurial > projects > dwt-addons
diff dwtx/jface/viewers/TableViewer.d @ 10:b6c35faf97c8
Viewers
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 31 Mar 2008 00:47:19 +0200 |
parents | |
children | cf7413989c65 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/viewers/TableViewer.d Mon Mar 31 00:47:19 2008 +0200 @@ -0,0 +1,390 @@ +/******************************************************************************* + * 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> - concept of ViewerRow, + * fix for 159597, refactoring (bug 153993), + * widget-independency (bug 154329), fix for 187826, 191468 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ + +module dwtx.jface.viewers.TableViewer; + +import dwtx.jface.viewers.AbstractTableViewer; +import dwtx.jface.viewers.TableViewerRow; +import dwtx.jface.viewers.ColumnViewerEditor; +import dwtx.jface.viewers.ISelection; +import dwtx.jface.viewers.ViewerRow; +import dwtx.jface.viewers.TableViewerEditor; +import dwtx.jface.viewers.ColumnViewerEditorActivationStrategy; + +import dwt.DWT; +import dwt.graphics.Point; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Item; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwt.widgets.Widget; +import dwtx.core.runtime.Assert; + +import dwt.dwthelper.utils; +import dwt.dwthelper.Runnable; + +/** + * A concrete viewer based on a DWT <code>Table</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 control and + * configured with a domain-specific content provider, table label provider, + * element filter (optional), and element sorter (optional). + * </p> + * <p> + * Label providers for table viewers must implement either the + * <code>ITableLabelProvider</code> or the <code>ILabelProvider</code> + * interface (see <code>TableViewer.setLabelProvider</code> for more details). + * </p> + * <p> + * As of 3.1 the TableViewer now supports the DWT.VIRTUAL flag. If the + * underlying table is DWT.VIRTUAL, the content provider may implement + * {@link ILazyContentProvider} instead of {@link IStructuredContentProvider}. + * Note that in this case, the viewer does not support sorting or filtering. + * Also note that in this case, the Widget based APIs may return null if the + * element is not specified or not created yet. + * </p> + * <p> + * Users of DWT.VIRTUAL should also avoid using getItems() from the Table within + * the TreeViewer as this does not necessarily generate a callback for the + * TreeViewer to populate the items. It also has the side effect of creating all + * of the items thereby eliminating the performance improvements of DWT.VIRTUAL. + * </p> + * + * @see DWT#VIRTUAL + * @see #doFindItem(Object) + * @see #internalRefresh(Object, bool) + */ +public class TableViewer : AbstractTableViewer { + + public alias AbstractTableViewer.preservingSelection preservingSelection; + + /** + * This viewer's table control. + */ + private Table table; + + /** + * The cached row which is reused all over + */ + private TableViewerRow cachedRow; + + /** + * Creates a table viewer on a newly-created table control under the given + * parent. The table control is created using the DWT style bits + * <code>MULTI, H_SCROLL, V_SCROLL,</code> and <code>BORDER</code>. The + * viewer has no input, no content provider, a default label provider, no + * sorter, and no filters. The table has no columns. + * + * @param parent + * the parent control + */ + public this(Composite parent) { + this(parent, DWT.MULTI | DWT.H_SCROLL | DWT.V_SCROLL | DWT.BORDER); + } + + /** + * Creates a table viewer on a newly-created table control under the given + * parent. The table control is created using the given style bits. The + * viewer has no input, no content provider, a default label provider, no + * sorter, and no filters. The table has no columns. + * + * @param parent + * the parent control + * @param style + * DWT style bits + */ + public this(Composite parent, int style) { + this(new Table(parent, style)); + } + + /** + * Creates a table viewer on the given table control. The viewer has no + * input, no content provider, a default label provider, no sorter, and no + * filters. + * + * @param table + * the table control + */ + public this(Table table) { + this.table = table; + hookControl(table); + } + + public Control getControl() { + return table; + } + + /** + * Returns this table viewer's table control. + * + * @return the table control + */ + public Table getTable() { + return table; + } + + protected ColumnViewerEditor createViewerEditor() { + return new TableViewerEditor(this,null,new ColumnViewerEditorActivationStrategy(this),ColumnViewerEditor.DEFAULT); + } + + /** + * <p> + * Sets a new selection for this viewer and optionally makes it visible. The + * TableViewer implementation of this method is inefficient for the + * ILazyContentProvider as lookup is done by indices rather than elements + * and may require population of the entire table in worse case. + * </p> + * <p> + * Use Table#setSelection(int[] indices) and Table#showSelection() if you + * wish to set selection more efficiently when using a ILazyContentProvider. + * </p> + * + * @param selection + * the new selection + * @param reveal + * <code>true</code> if the selection is to be made visible, + * and <code>false</code> otherwise + * @see Table#setSelection(int[]) + * @see Table#showSelection() + */ + public void setSelection(ISelection selection, bool reveal) { + super.setSelection(selection, reveal); + } + + protected ViewerRow getViewerRowFromItem(Widget item) { + if( cachedRow is null ) { + cachedRow = new TableViewerRow(cast(TableItem) item); + } else { + cachedRow.setItem(cast(TableItem) item); + } + + return cachedRow; + } + + /** + * Create a new row with style at index + * + * @param style + * @param rowIndex + * @return ViewerRow + * @since 3.3 + */ + protected ViewerRow internalCreateNewRowPart(int style, int rowIndex) { + TableItem item; + + if (rowIndex >= 0) { + item = new TableItem(table, style, rowIndex); + } else { + item = new TableItem(table, style); + } + + return getViewerRowFromItem(item); + } + + protected Item getItemAt(Point p) { + TableItem[] selection = table.getSelection(); + + if( selection.length is 1 ) { + int columnCount = table.getColumnCount(); + + for( int i = 0; i < columnCount; i++ ) { + if( selection[0].getBounds(i).contains(p) ) { + return selection[0]; + } + } + } + + return table.getItem(p); + } + + // Methods to provide widget independency + + protected int doGetItemCount() { + return table.getItemCount(); + } + + protected int doIndexOf(Item item) { + return table.indexOf(cast(TableItem)item); + } + + protected void doSetItemCount(int count) { + table.setItemCount(count); + } + + protected Item[] doGetItems() { + return table.getItems(); + } + + protected int doGetColumnCount() { + return table.getColumnCount(); + } + + protected Widget doGetColumn(int index) { + return table.getColumn(index); + } + + protected Item doGetItem(int index) { + return table.getItem(index); + } + + protected Item[] doGetSelection() { + return table.getSelection(); + } + + protected int[] doGetSelectionIndices() { + return table.getSelectionIndices(); + } + + protected void doClearAll() { + table.clearAll(); + } + + protected void doResetItem(Item item) { + TableItem tableItem = cast(TableItem) item; + int columnCount = Math.max(1, table.getColumnCount()); + for (int i = 0; i < columnCount; i++) { + tableItem.setText(i, ""); //$NON-NLS-1$ + if (tableItem.getImage(i) !is null) { + tableItem.setImage(i, null); + } + } + } + + protected void doRemove(int start, int end) { + table.remove(start, end); + } + + protected void doRemoveAll() { + table.removeAll(); + } + + protected void doRemove(int[] indices) { + table.remove(indices); + } + + protected void doShowItem(Item item) { + table.showItem(cast(TableItem)item); + } + + protected void doDeselectAll() { + table.deselectAll(); + } + + protected void doSetSelection(Item[] items) { +// Assert.isNotNull(items, "Items-Array can not be null"); //$NON-NLS-1$ + + TableItem[] t = new TableItem[items.length]; + System.arraycopy(items, 0, t, 0, t.length); + + table.setSelection(t); + } + + protected void doShowSelection() { + table.showSelection(); + } + + protected void doSetSelection(int[] indices) { + table.setSelection(indices); + } + + protected void doClear(int index) { + table.clear(index); + } + + protected void doSelect(int[] indices) { + table.select(indices); + } + + /** + * Refreshes this viewer starting with the given element. Labels are updated + * as described in <code>refresh(bool updateLabels)</code>. The + * methods attempts to preserve the selection. + * <p> + * Unlike the <code>update</code> methods, this handles structural changes + * to the given element (e.g. addition or removal of children). If only the + * given element needs updating, it is more efficient to use the + * <code>update</code> methods. + * </p> + * + * <p> + * Subclasses who can provide this feature can open this method for the + * public + * </p> + * + * @param element + * the element + * @param updateLabels + * <code>true</code> to update labels for existing elements, + * <code>false</code> to only update labels as needed, assuming + * that labels for existing elements are unchanged. + * @param reveal + * <code>true</code> to make the preserved selection visible + * afterwards + * + * @since 3.3 + */ + public void refresh(Object element, bool updateLabels, + bool reveal) { + if (isBusy()) + return; + + if( isCellEditorActive() ) { + cancelEditing(); + } + + preservingSelection(new class Runnable { + Object element_; + bool updateLabels_; + this(){ + element_ = element; + updateLabels_ = updateLabels; + } + public void run() { + internalRefresh(element_, updateLabels_); + } + }, reveal); + } + + /** + * Refreshes this viewer with information freshly obtained from this + * viewer's model. If <code>updateLabels</code> is <code>true</code> + * then labels for otherwise unaffected elements are updated as well. + * Otherwise, it assumes labels for existing elements are unchanged, and + * labels are only obtained as needed (for example, for new elements). + * <p> + * Calling <code>refresh(true)</code> has the same effect as + * <code>refresh()</code>. + * <p> + * Note that the implementation may still obtain labels for existing + * elements even if <code>updateLabels</code> is false. The intent is + * simply to allow optimization where possible. + * + * @param updateLabels + * <code>true</code> to update labels for existing elements, + * <code>false</code> to only update labels as needed, assuming + * that labels for existing elements are unchanged. + * @param reveal + * <code>true</code> to make the preserved selection visible + * afterwards + * + * @since 3.3 + */ + public void refresh(bool updateLabels, bool reveal) { + refresh(getRoot(), updateLabels, reveal); + } +}