package org.csstudio.sds.ui.internal.editor.newproperties.table;
import java.util.List;
import org.csstudio.ui.util.CustomMediaFactory;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
/**
* Convenience wrapper for a SWT table viewer that allows for easy and fine
* grained customization of all aspects of a table, like
*
* <ul>
* <li>number of columns</li>
* <li>fore and background color of used in cells</li>
* <li>font used in cells</li>
* <li>cell editors</li>
* <li>cell content</li>
* </ul>
*
* The model for the table is a list of {@link ITableRow}s. Each
* {@link ITableRow} represents an adapter for an arbitrary object.
*
* To use this table just prepare {@link ITableRow} adapters for your model
* objects.
*
* @author Sven Wende
*
*/
public final class ConvenienceTableWrapper {
public static final TableViewer equip(Table table,
ColumnConfig... columnConfigurations) {
return equip(table.getParent(), table, columnConfigurations);
}
public static final TableViewer equip(Composite parent,
ColumnConfig[] columnConfigurations) {
// .. create a composite arround the table that allows for weighted
// column width of the table
Composite tableComposite = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, false).hint(0, 100).applyTo(
tableComposite);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
tableComposite.setLayout(tableColumnLayout);
// create table
Table table = new Table(tableComposite, SWT.FULL_SELECTION
| SWT.HIDE_SELECTION | SWT.DOUBLE_BUFFERED | SWT.SCROLL_PAGE);
table.setLinesVisible(true);
table.setHeaderVisible(false);
return equip(tableComposite, table, columnConfigurations);
}
private static final TableViewer equip(Composite parent, Table table,
ColumnConfig[] columnConfigurations) {
TableColumnLayout tableColumnLayout = (TableColumnLayout) parent
.getLayout();
// create the table viewer
TableViewer viewer = new TableViewer(table);
// .. create table columns
String[] columnNames = new String[columnConfigurations.length];
for (int i = 0; i < columnConfigurations.length; i++) {
ColumnConfig config = columnConfigurations[i];
columnNames[i] = config.getId();
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText(config.getTitle());
column.getColumn().setAlignment(SWT.LEFT);
tableColumnLayout.setColumnData(column.getColumn(), config
.getWeight() > 0 ? new ColumnWeightData(config.getWeight(),
config.getMinimumWidth(), config.isResizable())
: new ColumnPixelData(config.getMinimumWidth(), config
.isResizable()));
column.setEditingSupport(new DelegatingColumnEditingSupport(viewer,
i));
}
viewer.setColumnProperties(columnNames);
ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE);
// configure keyboard support
TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(
viewer, new FocusCellOwnerDrawHighlighter(viewer));
ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(
viewer) {
@Override
protected boolean isEditorActivationEvent(
final ColumnViewerEditorActivationEvent event) {
return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION
|| (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.F2)
|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
}
};
TableViewerEditor.create(viewer, focusCellManager, actSupport,
ColumnViewerEditor.TABBING_HORIZONTAL
| ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
| ColumnViewerEditor.TABBING_VERTICAL
| ColumnViewerEditor.KEYBOARD_ACTIVATION);
// .. sorter
viewer.setSorter(new ViewerSorter() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
ITableRow r1 = (ITableRow) e1;
ITableRow r2 = (ITableRow) e2;
return r1.compareTo(r2);
}
});
viewer.setContentProvider(new ContentProvider());
viewer.setLabelProvider(new LabelProvider());
return viewer;
}
/**
* Editing support implementation.
*
* @author Sven Wende
*/
static final class DelegatingColumnEditingSupport extends EditingSupport {
private int columnIndex;
public DelegatingColumnEditingSupport(ColumnViewer viewer,
int columnIndex) {
super(viewer);
assert columnIndex >= 0 : "columnIndex>=0";
this.columnIndex = columnIndex;
}
/**
* {@inheritDoc}
*/
@Override
protected boolean canEdit(Object element) {
ITableRow row = (ITableRow) element;
return row.canModify(columnIndex);
}
/**
* {@inheritDoc}
*/
@Override
protected CellEditor getCellEditor(Object element) {
ITableRow row = (ITableRow) element;
return row.getCellEditor(columnIndex, ((TableViewer) getViewer())
.getTable());
}
/**
* {@inheritDoc}
*/
@Override
protected Object getValue(Object element) {
ITableRow row = (ITableRow) element;
return row.getEditingValue(columnIndex);
}
/**
* {@inheritDoc}
*/
@Override
protected void setValue(Object element, Object value) {
ITableRow row = (ITableRow) element;
row.setValue(columnIndex, value);
getViewer().refresh();
}
/**
* {@inheritDoc}
*/
@Override
public ColumnViewer getViewer() {
return super.getViewer();
}
}
/**
* Content provider implementation.
*
* @author Sven Wende
*/
static final class ContentProvider implements IStructuredContentProvider {
/**
* {@inheritDoc}
*/
@Override
public void inputChanged(final Viewer viewer, final Object oldInput,
final Object newInput) {
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public Object[] getElements(final Object parent) {
return ((List<ITableRow>) parent).toArray();
}
/**
* {@inheritDoc}
*/
@Override
public void dispose() {
}
}
/**
* Label provider implementation.
*
* @author Sven Wende
*/
static final class LabelProvider extends ColumnLabelProvider {
/**
* {@inheritDoc}
*/
@Override
public void update(final ViewerCell cell) {
ITableRow row = (ITableRow) cell.getElement();
int index = cell.getColumnIndex();
// set the text
cell.setText(getText(row, index));
// image
Image img = row.getImage(index);
if (img != null) {
cell.setImage(img);
}
// background color
RGB bgColor = row.getBackgroundColor(index);
if (bgColor != null) {
cell.setBackground(CustomMediaFactory.getInstance().getColor(
bgColor));
}
// foreground color
RGB fgColor = row.getForegroundColor(index);
if (fgColor != null) {
cell.setForeground(CustomMediaFactory.getInstance().getColor(
fgColor));
}
// font
Font font = row.getFont(index);
if (font != null) {
cell.setFont(font);
}
}
/**
* Returns the text to display.
*
* @param element
* the current element
* @param column
* the current column index
* @return The text to display in the viewer
*/
private String getText(final Object element, final int column) {
ITableRow row = (ITableRow) element;
String result = row.getDisplayValue(column);
return result;
}
/**
* {@inheritDoc}
*/
@Override
public String getToolTipText(final Object element) {
ITableRow row = (ITableRow) element;
return row.getTooltip();
}
/**
* {@inheritDoc}
*/
@Override
public Point getToolTipShift(final Object object) {
return new Point(5, 5);
}
/**
* {@inheritDoc}
*/
@Override
public int getToolTipDisplayDelayTime(final Object object) {
return 100;
}
/**
* {@inheritDoc}
*/
@Override
public int getToolTipTimeDisplayed(final Object object) {
return 10000;
}
}
}