package org.csstudio.sds.ui.internal.editor.newproperties;
import java.util.ArrayList;
import java.util.List;
import org.csstudio.sds.internal.model.PointlistProperty;
import org.csstudio.sds.ui.SdsUiPlugin;
import org.csstudio.sds.ui.internal.editor.newproperties.table.ColumnConfig;
import org.csstudio.sds.ui.internal.editor.newproperties.table.ConvenienceTableWrapper;
import org.csstudio.sds.ui.internal.editor.newproperties.table.ITableRow;
import org.csstudio.sds.ui.internal.properties.IntegerCellEditor;
import org.csstudio.ui.util.CustomMediaFactory;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
public class PointListSection extends AbstractBaseSection<PointlistProperty> {
private TableViewer tableViewer;
private List<TableEditor> tableEditors = new ArrayList<TableEditor>();
public PointListSection(String propertyId) {
super(propertyId);
}
@Override
protected void doCreateControls(Composite parent,
TabbedPropertySheetPage aTabbedPropertySheetPage) {
GridLayoutFactory.swtDefaults().numColumns(5).applyTo(parent);
// .. table for viewing and editing the entries
Composite tableComposite = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().hint(STANDARD_WIDGET_WIDTH, 100)
.span(5, 1).applyTo(tableComposite);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
tableComposite.setLayout(tableColumnLayout);
Table table = getWidgetFactory().createTable(tableComposite,
SWT.FULL_SELECTION | SWT.DOUBLE_BUFFERED | SWT.SCROLL_PAGE | SWT.V_SCROLL);
table.setLinesVisible(true);
table.setHeaderVisible(false);
tableViewer = ConvenienceTableWrapper.equip(table,
new ColumnConfig("x", "x", 30, 10, false),
new ColumnConfig("y", "y", 30, 10, false),
new ColumnConfig("remove", "Remove", 30, -1, true),
new ColumnConfig("up", "Up", 30, -1, true));
// .. button to add new entries to the table
final Hyperlink addHyperLink = getWidgetFactory().createHyperlink(parent, "Add Point...", SWT.NONE);
addHyperLink.setUnderlined(false);
addHyperLink.addHyperlinkListener(new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
PointlistProperty property = getMainWidgetProperty();
if (property != null) {
PointDialog dialog = new PointDialog(addHyperLink.getShell());
if (Window.OK == dialog.open()) {
Point point = dialog.getPoint();
PointList original = property.getPropertyValue();
PointList list = original.getCopy();
list.addPoint(point);
applyPropertyChange(list);
}
}
}
});
}
@Override
protected void doRefreshControls(PointlistProperty widgetProperty) {
// .. (re)create the table editors used for removing single lines of the
// table
if (tableEditors != null) {
// .. dispose existing editors
for (TableEditor editor : tableEditors) {
if (editor.getEditor() != null) {
editor.getEditor().dispose();
}
editor.dispose();
}
tableEditors.clear();
}
// .. create new editors
if (widgetProperty != null && tableViewer.getContentProvider() != null) {
PointList original = widgetProperty.getPropertyValue();
PointList list = original.getCopy();
List<ITableRow> rows = new ArrayList<ITableRow>();
for (int i = 0; i < list.size(); i++) {
rows.add(new PointRowAdapter(list, list.getPoint(i), i));
}
tableViewer.setInput(rows);
TableItem[] items = tableViewer.getTable().getItems();
for (int i = 0; i < items.length; i++) {
final TableItem item = items[i];
TableEditor deleteTableEditor = new TableEditor(tableViewer
.getTable());
Button deleteButton = new Button(tableViewer.getTable(),
SWT.FLAT);
deleteButton.setImage(CustomMediaFactory.getInstance()
.getImageFromPlugin(SdsUiPlugin.PLUGIN_ID,
"icons/delete.gif"));
deleteButton.pack();
deleteTableEditor.minimumWidth = deleteButton.getSize().x;
deleteTableEditor.horizontalAlignment = SWT.LEFT;
deleteTableEditor.setEditor(deleteButton, item, 2);
deleteButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
PointRowAdapter data = (PointRowAdapter)item.getData();
data.setValue(2, "true");
}
});
tableEditors.add(deleteTableEditor);
TableEditor upTableEditor = new TableEditor(tableViewer
.getTable());
final Button upButton = new Button(tableViewer.getTable(),
SWT.FLAT);
upButton.setImage(CustomMediaFactory.getInstance()
.getImageFromPlugin(SdsUiPlugin.PLUGIN_ID,
"icons/search_prev.gif"));
upButton.pack();
upTableEditor.minimumWidth = upButton.getSize().x;
upTableEditor.horizontalAlignment = SWT.LEFT;
upTableEditor.setEditor(upButton, item, 3);
upButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
PointRowAdapter data = (PointRowAdapter)item.getData();
data.setValue(3, "true");
}
});
tableEditors.add(upTableEditor);
}
}
}
private class PointRowAdapter implements ITableRow {
private final PointList _list;
private final Point _point;
private final int _index;
public PointRowAdapter(PointList list, Point point, int index) {
_list = list;
_point = point;
_index = index;
}
@Override
public boolean canModify(int column) {
return true;
}
@Override
public RGB getBackgroundColor(int column) {
return null;
}
@Override
public CellEditor getCellEditor(int column, Composite parent) {
switch (column) {
case 0:
return new IntegerCellEditor(parent);
case 1:
return new IntegerCellEditor(parent);
default:
return null;
}
}
@Override
public String getDisplayValue(int column) {
switch (column) {
case 0:
return String.valueOf(_point.x);
case 1:
return String.valueOf(_point.y);
default:
return null;
}
}
@Override
public String getEditingValue(int column) {
switch (column) {
case 0:
return String.valueOf(_point.x);
case 1:
return String.valueOf(_point.y);
default:
return null;
}
}
@Override
public Font getFont(int column) {
return null;
}
@Override
public RGB getForegroundColor(int column) {
return null;
}
@Override
public Image getImage(int column) {
return null;
}
@Override
public String getTooltip() {
return null;
}
@Override
public void setValue(int column, Object value) {
switch (column) {
case 0:
_point.x = (Integer)value;
_list.setPoint(_point, _index);
applyPropertyChange(_list);
break;
case 1:
_point.y = (Integer)value;
_list.setPoint(_point, _index);
applyPropertyChange(_list);
break;
case 2:
_list.removePoint(_index);
applyPropertyChange(_list);
break;
case 3:
movePoint(_list, _index);
applyPropertyChange(_list);
break;
default:
break;
}
}
/**
* Moves the current selected Point one step up or down, depending on
* the given boolean.
*
* @param up
* True, if the Point should be moved up, false otherwise
*/
private void movePoint(PointList list, int index) {
if (index > 0) {
Point point1 = list.getPoint(index);
Point point2 = list.getPoint(index-1);
list.setPoint(point1, index-1);
list.setPoint(point2, index);
}
}
@Override
public int compareTo(ITableRow o) {
return 0;
}
}
/**
* This class represents a Dialog for editing a Point.
*
* @author Kai Meyer
*/
private final class PointDialog extends Dialog {
/**
* The Spinner for the x-value of the Point.
*/
private Spinner _xSpinner;
/**
* The Spinner for the y-value of the Point.
*/
private Spinner _ySpinner;
/**
* A boolean, which indicates if the Point is new.
*/
private Point _result;
/**
* Creates an input dialog with OK and Cancel buttons. Note that the
* dialog will have no visual representation (no widgets) until it is
* told to open.
* <p>
* Note that the <code>open</code> method blocks for input dialogs.
* </p>
*
* @param parentShell
* the parent shell, or <code>null</code> to create a
* top-level shell
* @param dialogTitle
* the dialog title, or <code>null</code> if none
* @param dialogMessage
* the dialog message, or <code>null</code> if none
* @param initialValue
* the initial input value, or <code>null</code> if none
* @param isNew
* true id the Point is new, false otherwise
*/
public PointDialog(final Shell parentShell) {
super(parentShell);
}
/**
* {@inheritDoc}
*/
@Override
protected void configureShell(final Shell shell) {
super.configureShell(shell);
shell.setText("New Point");
}
/**
* {@inheritDoc}
*/
@Override
protected Control createDialogArea(final Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayout(new GridLayout(2, false));
Label label = new Label(composite, SWT.NONE);
label.setText("x:");
_xSpinner = new Spinner(composite, SWT.BORDER);
_xSpinner.setMaximum(10000);
_xSpinner.setMinimum(-10000);
_xSpinner.setSelection(100);
label = new Label(composite, SWT.NONE);
label.setText("y:");
_ySpinner = new Spinner(composite, SWT.BORDER);
_ySpinner.setMaximum(10000);
_ySpinner.setMinimum(-10000);
_ySpinner.setSelection(100);
return composite;
}
public Point getPoint() {
return _result;
}
/**
* {@inheritDoc}
*/
@Override
protected void okPressed() {
this.getButton(IDialogConstants.OK_ID).setFocus();
_result = new Point(_xSpinner.getSelection(), _ySpinner
.getSelection());
super.okPressed();
}
}
}