/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG 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: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.ui.ridgets.swt.optional; import java.util.Comparator; import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.viewers.AbstractTableViewer; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ViewerColumn; import org.eclipse.nebula.jface.gridviewer.GridTableViewer; import org.eclipse.nebula.jface.gridviewer.GridViewerColumn; import org.eclipse.nebula.widgets.grid.Grid; import org.eclipse.nebula.widgets.grid.GridCellRenderer; import org.eclipse.nebula.widgets.grid.GridColumn; import org.eclipse.nebula.widgets.grid.GridItem; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Widget; import org.eclipse.riena.internal.ui.ridgets.swt.AbstractTableRidget; import org.eclipse.riena.internal.ui.ridgets.swt.ITableTreeWrapper; import org.eclipse.riena.internal.ui.ridgets.swt.TableComparator; import org.eclipse.riena.internal.ui.ridgets.swt.TableRidgetLabelProvider; import org.eclipse.riena.ui.ridgets.IColumnFormatter; import org.eclipse.riena.ui.ridgets.listener.ClickEvent; import org.eclipse.riena.ui.ridgets.swt.SortableComparator; import org.eclipse.riena.ui.ridgets.swt.optional.IGridRidget; /** * Ridget for SWT/Nebula {@link Grid} widgets. */ public class GridRidget extends AbstractTableRidget implements IGridRidget { private final GridCellRenderer cellRenderer; private final GridCellRenderer emptyCellRenderer; public GridRidget() { super(); sortListener = new ColumnSortListener(); cellRenderer = new GridRidgetCellRenderer(this); emptyCellRenderer = new GridRidgetEmptyCellRenderer(); } @Override public Grid getUIControl() { return (Grid) super.getUIControl(); } @Override protected final int getUiSelectionCount() { final Grid control = getUIControl(); return control == null ? -1 : control.getSelectionCount(); } @Override public boolean isErrorMarked(final Widget item) { return super.isErrorMarked(item); } // // @Override // protected final int getUiSelectionIndex() { // final Grid control = getUIControl(); // return control == null ? -1 : control.getSelectionIndex(); // } // // @Override // protected final void setUiSelection(final int index) { // final Grid control = getUIControl(); // if (control == null) { // return; // } // control.setSelection(index); // } @Override protected final void setUiSelection(final Widget item) { Assert.isTrue(item instanceof GridItem); final Grid control = getUIControl(); if (control != null) { final int index = control.getIndexOfItem((GridItem) item); control.setSelection(index); } } @Override public int getSelectionIndex() { final Grid control = getUIControl(); return control == null ? -1 : control.getSelectionIndex(); } @Override public int[] getSelectionIndices() { final Grid control = getUIControl(); return control == null ? new int[0] : control.getSelectionIndices(); } @Override public void setNativeToolTip(final boolean nativeToolTip) { if (!nativeToolTip) { throw new IllegalArgumentException("Grid only supports 'natvie' tool tips!"); //$NON-NLS-1$ } } /** * {@inheritDoc} * <p> * The UI control must be a {@link Grid}. */ @Override protected final void checkUIControl(final Object uiControl) { checkType(uiControl, Grid.class); } @Override protected GridTableViewer getTableViewer() { return (GridTableViewer) super.getTableViewer(); } @Override protected final void bindUIControl() { super.bindUIControl(); final Grid control = getUIControl(); if (control != null) { for (final GridColumn column : control.getColumns()) { column.addSelectionListener(sortListener); column.setCellRenderer(cellRenderer); } control.addSelectionListener(selectionTypeEnforcer); control.setEmptyCellRenderer(emptyCellRenderer); } } @Override protected final void unbindUIControl() { super.unbindUIControl(); final Grid control = getUIControl(); if (control != null) { for (final GridColumn column : control.getColumns()) { column.removeSelectionListener(sortListener); } control.removeSelectionListener(selectionTypeEnforcer); } } @Override protected final void applyColumns() { final Grid control = getUIControl(); if (control == null) { return; } final int expectedCols = getExpectedColumnCount(); if (getColumnCount() != expectedCols) { for (final GridColumn column : control.getColumns()) { column.dispose(); } for (int i = 0; i < expectedCols; i++) { new GridColumn(control, SWT.NONE); } applyColumnWidths(); } final GridColumn[] columns = control.getColumns(); for (int columnIndex = 0; columnIndex < columns.length; columnIndex++) { final ViewerColumn viewerColumn = new GridViewerColumn(getTableViewer(), columns[columnIndex]); applyEditingSupport(viewerColumn, columnIndex); } } @Override protected final void applyColumnsMovable() { final Grid control = getUIControl(); if (control == null) { return; } for (final GridColumn column : control.getColumns()) { column.setMoveable(hasMoveableColumns()); } } @Override protected final void applyTableColumnHeaders() { final Grid control = getUIControl(); final boolean headersVisible = columnHeaders != null; control.setHeaderVisible(headersVisible); if (headersVisible) { final GridColumn[] columns = control.getColumns(); for (int i = 0; i < columns.length; i++) { String columnHeader = ""; //$NON-NLS-1$ if (i < columnHeaders.length && columnHeaders[i] != null) { columnHeader = columnHeaders[i]; } columns[i].setText(columnHeader); // not necessary for GridColumns because they implement this function already! // final String tooltip = isShowColumnTooltip(columns[i], columnHeader) ? columnHeader : ""; //$NON-NLS-1$ // columns[i].setHeaderTooltip(tooltip); } } } @Override protected final void applyComparator(final Map<Integer, Comparator<?>> comparatorMap) { if (getTableViewer() != null) { Comparator<?> compi = null; if (getSortedColumn() != -1) { final Integer key = Integer.valueOf(getSortedColumn()); compi = comparatorMap.get(key); } final Grid control = getUIControl(); clearSortIndicator(); if (compi != null) { final GridColumn column = control.getColumn(getSortedColumn()); final int direction = getSortDirection(); column.setSort(direction); final SortableComparator sortableComparator = new SortableComparator(this, compi); getTableViewer().setComparator(new TableComparator(sortableComparator)); } else { getTableViewer().setComparator(null); } } } @Override protected int getColumnStyle(final int columnIndex) { checkColumnRange(columnIndex); final Grid control = getUIControl(); if (control == null) { return SWT.DEFAULT; } final GridColumn[] columns = control.getColumns(); return columns[columnIndex].getStyle(); } private void clearSortIndicator() { final Grid control = getUIControl(); if (control == null) { return; } final GridColumn[] columns = control.getColumns(); for (final GridColumn column : columns) { column.setSort(SWT.NONE); } } /** * {@inheritDoc} * <p> * Sets for every item the tool tip text. The text can be configured with the {@link IColumnFormatter}. * <p> * <i>note: The tool tip of a grid is only shown, if in a cell not the complete text can be displayed.</i> */ @Override protected final void updateToolTipSupport() { final Grid control = getUIControl(); if (control == null) { return; } int colCount = getColumnCount(); final GridItem[] items = control.getItems(); for (final GridItem item : items) { for (final int colIndex = 0; colCount < colCount; colCount++) { String toolTip = null; if (toolTip == null) { toolTip = getToolTipText(item, colIndex); } item.setToolTipText(colIndex, toolTip); } } } private String getToolTipText(final GridItem item, final int column) { String result = null; final IBaseLabelProvider labelProvider = getTableViewer().getLabelProvider(); if (labelProvider != null) { final Object element = item.getData(); result = ((TableRidgetLabelProvider) labelProvider).getToolTipText(element, column); } if (result == null) { result = item.getText(column); } return result; } @Override protected AbstractTableViewer createTableViewer() { return new GridRidgetGridTableViewer(this); } @Override protected ITableTreeWrapper createTableWrapper() { Assert.isNotNull(getUIControl()); return new GridWrapper(getUIControl()); } @Override protected ClickEvent createClickEvent(final MouseEvent e) { final Grid grid = (Grid) e.widget; final int colIndex = findColumn(grid, new Point(e.x, e.y)); // x = 0 gets us an item even not using SWT.FULL_SELECTION final Item item = getItem(new Point(0, e.y)); final Object rowData = item != null ? item.getData() : null; final ClickEvent event = new ClickEvent(this, e.button, colIndex, rowData); return event; } /** * Returns the 0 based index of the column at {@code pt}. The code can handle re-ordered columns. The index refers to the original ordering (as used by SWT * API). * <p> * Will return -1 if no column could be computed -- this is the case when all columns are resized to have width 0. */ private int findColumn(final Grid grid, final Point pt) { int width = 0; final int[] colOrder = grid.getColumnOrder(); // compute the current column ordering final GridColumn[] columns = new GridColumn[colOrder.length]; for (int i = 0; i < colOrder.length; i++) { final int idx = colOrder[i]; columns[i] = grid.getColumn(idx); } // find the column under Point pt\ for (final GridColumn col : columns) { final int colWidth = col.getWidth(); if (width < pt.x && pt.x < width + colWidth) { return grid.indexOf(col); } width += colWidth; } return -1; } /** * Selection listener for table headers that changes the sort order of a column according to the information stored in the ridget. */ private final class ColumnSortListener extends SelectionAdapter { @Override public void widgetSelected(final SelectionEvent e) { final GridColumn column = (GridColumn) e.widget; final int columnIndex = column.getParent().indexOf(column); final int direction = column.getSort(); if (columnIndex == getSortedColumn()) { if (direction == SWT.UP) { setSortedAscending(false); } else if (direction == SWT.DOWN) { setSortedColumn(-1); } } else if (isColumnSortable(columnIndex)) { setSortedColumn(columnIndex); if (direction == SWT.NONE) { setSortedAscending(true); } } column.getParent().showSelection(); } } }