blob: 8a5f4262d725938771b0a7285acc30976406e1c1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.javabean.metadata.properties;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.xwt.XWTMaps;
import org.eclipse.xwt.metadata.ILoadingType;
/**
*
* @author yyang (yves.yang@soyatec.com)
*/
public class TableEditorDynamicProperty extends AbstractProperty {
public TableEditorDynamicProperty() {
super(PropertiesConstants.PROPERTY_DYNAMIC, Boolean.class);
}
public TableEditorDynamicProperty(ILoadingType loadingType) {
super(PropertiesConstants.PROPERTY_DYNAMIC, Boolean.class, loadingType);
}
/**
* @see org.eclipse.xwt.metadata.IProperty#getValue(java.lang.Object)
*/
public Object getValue(Object target) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchFieldException {
return null;
}
/**
* @see org.eclipse.xwt.metadata.IProperty#setValue(java.lang.Object, java.lang.Object)
*/
public void setValue(Object target, Object value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchFieldException {
Boolean isDynamic = (Boolean) value;
TableEditor tableEditor = (TableEditor) target;
final Control control = tableEditor.getEditor();
Table tableParent = null;
Composite parent = control.getParent();
if (parent instanceof Table) {
tableParent = (Table) parent;
} else if (tableEditor.getItem() != null) {
tableParent = tableEditor.getItem().getParent();
}
if (tableParent == null) {
return;
}
final Table table = tableParent;
if (isDynamic) {
control.setVisible(false);
control.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
control.setVisible(false);
}
});
control.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.character == SWT.CR && control.isFocusControl()) {
table.notifyListeners(SWT.DefaultSelection, new Event());
}
}
});
Object mouseHander = table.getData(PropertiesConstants.DATA_TABLE_UTIL);
if (mouseHander == null) {
TableUtil tableUtil = new TableUtil(table);
table.setData(PropertiesConstants.DATA_TABLE_UTIL, tableUtil);
}
table.addSelectionListener(new TableSelectionHandler(table, tableEditor));
}
}
static private class TableSelectionHandler implements SelectionListener {
private Table table;
private TableEditor tableEditor;
public TableSelectionHandler(Table table, TableEditor tableEditor) {
this.table = table;
this.tableEditor = tableEditor;
}
public void widgetDefaultSelected(SelectionEvent e) {
Control editor = tableEditor.getEditor();
if (editor.isDisposed()) {
return;
}
if (editor.isFocusControl()) {
editor.setVisible(false);
} else {
editor.setFocus();
}
}
public void widgetSelected(SelectionEvent e) {
Control editor = tableEditor.getEditor();
if (editor.isDisposed()) {
return;
}
TableUtil tableUtil = (TableUtil) table.getData(PropertiesConstants.DATA_TABLE_UTIL);
TableItem item = tableUtil.getItem();
int column = tableUtil.getColumn();
if (item == tableEditor.getItem() && column == tableEditor.getColumn()) {
editor.setVisible(true);
} else {
editor.setVisible(false);
}
}
}
private static class TableUtil extends MouseAdapter implements KeyListener {
private Table table;
private TableItem item;
private TableColumn column;
public TableUtil(Table table) {
this.table = table;
table.addMouseListener(this);
table.addKeyListener(this);
}
@Override
public void mouseDown(MouseEvent e) {
if (table.isDisposed() || !table.isVisible())
return;
Point pt = new Point(e.x, e.y);
int lineWidth = table.getLinesVisible() ? table.getGridLineWidth() : 0;
TableItem item = table.getItem(pt);
int start = item != null ? table.indexOf(item) : table.getTopIndex();
int end = table.getItemCount();
Rectangle clientRect = table.getClientArea();
for (int i = start; i < end; i++) {
TableItem nextItem = table.getItem(i);
Rectangle rect = nextItem.getBounds(0);
if (pt.y >= rect.y && pt.y < rect.y + rect.height + lineWidth) {
item = nextItem;
break;
}
if (rect.y > clientRect.y + clientRect.height)
return;
}
if (item == null)
return;
this.item = item;
TableColumn newColumn = null;
int columnCount = table.getColumnCount();
if (columnCount == 0) {
if ((table.getStyle() & SWT.FULL_SELECTION) == 0) {
Rectangle rect = item.getBounds(0);
rect.width += lineWidth;
rect.height += lineWidth;
if (!rect.contains(pt))
return;
}
} else {
for (int i = 0; i < columnCount; i++) {
Rectangle rect = item.getBounds(i);
rect.width += lineWidth;
rect.height += lineWidth;
if (rect.contains(pt)) {
newColumn = table.getColumn(i);
break;
}
}
if (newColumn == null) {
if ((table.getStyle() & SWT.FULL_SELECTION) == 0)
return;
newColumn = table.getColumn(0);
}
}
column = newColumn;
table.notifyListeners(SWT.DefaultSelection, new Event());
}
public TableItem getItem() {
return item;
}
public int getRow() {
return item == null ? (table.getItemCount() > 0 ? 0 : -1) : table.indexOf(item);
}
public void setRow(int rowIndex) {
if (rowIndex >= 0 && rowIndex < table.getItemCount()) {
item = table.getItem(rowIndex);
} else {
item = null;
}
}
public int getColumn() {
return column == null ? (table.getColumnCount() > 0 ? 0 : -1) : table.indexOf(column);
}
public void setColumn(int columnIndex) {
if (columnIndex >= 0 && columnIndex < table.getColumnCount()) {
column = table.getColumn(columnIndex);
} else {
column = null;
}
}
public void keyPressed(KeyEvent event) {
int rowIndex = getRow();
int columnIndex = column == null ? 0 : table.indexOf(column);
switch (event.keyCode) {
case SWT.ARROW_UP:
setRow(Math.max(0, rowIndex - 1));
break;
case SWT.ARROW_DOWN:
setRow(Math.min(rowIndex + 1, table.getItemCount() - 1));
break;
case SWT.ARROW_LEFT:
case SWT.ARROW_RIGHT:
int columnCount = table.getColumnCount();
if (columnCount == 0)
break;
int[] order = table.getColumnOrder();
int index = 0;
while (index < order.length) {
if (order[index] == columnIndex)
break;
index++;
}
if (index == order.length)
index = 0;
int leadKey = (XWTMaps.getStyle("SWT.RIGHT_TO_LEFT") != SWT.NONE)
? ((table.getStyle() & XWTMaps.getStyle("SWT.RIGHT_TO_LEFT")) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT)
: SWT.ARROW_LEFT;
if (event.keyCode == leadKey) {
setColumn(order[Math.max(0, index - 1)]);
} else {
setColumn(order[Math.min(columnCount - 1, index + 1)]);
}
table.notifyListeners(SWT.Selection, new Event());
break;
case SWT.HOME:
setRow(0);
setColumn(columnIndex);
break;
case SWT.END:
setRow(table.getItemCount() - 1);
setColumn(columnIndex);
break;
case SWT.PAGE_UP:
int topIndex = table.getTopIndex();
if (topIndex == rowIndex) {
Rectangle rect = table.getClientArea();
TableItem item = table.getItem(topIndex);
Rectangle itemRect = item.getBounds(0);
rect.height -= itemRect.y;
int height = table.getItemHeight();
int page = Math.max(1, rect.height / height);
topIndex = Math.max(0, topIndex - page + 1);
}
setRow(topIndex);
break;
case SWT.PAGE_DOWN:
int downIndex = table.getTopIndex();
Rectangle rect = table.getClientArea();
TableItem item = table.getItem(downIndex);
Rectangle itemRect = item.getBounds(0);
rect.height -= itemRect.y;
int height = table.getItemHeight();
int page = Math.max(1, rect.height / height);
int end = table.getItemCount() - 1;
downIndex = Math.min(end, downIndex + page - 1);
if (downIndex == rowIndex) {
downIndex = Math.min(end, downIndex + page - 1);
}
setRow(downIndex);
break;
}
}
public void keyReleased(KeyEvent e) {
// Ignore
}
}
}