blob: bc34f6e0739cf52d289629e44e33d128b25c91d6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2013 EclipseSource Muenchen GmbH 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:
* Eugen Neufeld - initial API and implementation
*
*******************************************************************************/
package org.eclipse.emf.ecp.edit.internal.swt.controls;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.EObjectObservableMap;
import org.eclipse.emf.databinding.edit.EMFEditObservables;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecp.edit.ECPControlContext;
import org.eclipse.emf.ecp.edit.internal.swt.Activator;
import org.eclipse.emf.ecp.edit.internal.swt.table.TableColumnConfiguration;
import org.eclipse.emf.ecp.edit.internal.swt.table.TableControlConfiguration;
import org.eclipse.emf.ecp.edit.internal.swt.util.CellEditorFactory;
import org.eclipse.emf.ecp.edit.internal.swt.util.ECPCellEditor;
import org.eclipse.emf.ecp.edit.internal.swt.util.ECPDialogExecutor;
import org.eclipse.emf.ecp.edit.internal.swt.util.SWTControl;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapCellLabelProvider;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogLabelKeys;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.IStructuredSelection;
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.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableColumn;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* The class describing a table control.
*
* @author Eugen Neufeld
*
*/
public class TableControl extends SWTControl {
private TableViewer tableViewer;
private ComposedAdapterFactory composedAdapterFactory;
private AdapterFactoryItemDelegator adapterFactoryItemDelegator;
private Button unsetButton;
private EClass clazz;
private TableControlConfiguration tableControlConfiguration;
private Map<EObject, Map<EStructuralFeature, Diagnostic>> featureErrorMap = new HashMap<EObject, Map<EStructuralFeature, Diagnostic>>();
/**
* Constructor for a String control.
*
* @param showLabel whether to show a label
* @param itemPropertyDescriptor the {@link IItemPropertyDescriptor} to use
* @param feature the {@link EStructuralFeature} to use
* @param modelElementContext the {@link ECPControlContext} to use
* @param embedded whether this control is embedded in another control
*/
public TableControl(boolean showLabel, IItemPropertyDescriptor itemPropertyDescriptor, EStructuralFeature feature,
ECPControlContext modelElementContext, boolean embedded) {
super(showLabel, itemPropertyDescriptor, feature, modelElementContext, embedded);
}
/**
* Constructor for a String control.
*
* @param showLabel whether to show a label
* @param itemPropertyDescriptor the {@link IItemPropertyDescriptor} to use
* @param feature the {@link EStructuralFeature} to use
* @param modelElementContext the {@link ECPControlContext} to use
* @param embedded whether this control is embedded in another control
*/
public TableControl(boolean showLabel, IItemPropertyDescriptor itemPropertyDescriptor, EStructuralFeature feature,
ECPControlContext modelElementContext, boolean embedded, TableControlConfiguration tableControlConfiguration) {
super(showLabel, itemPropertyDescriptor, feature, modelElementContext, embedded);
this.tableControlConfiguration = tableControlConfiguration;
}
@Override
protected Binding bindValue() {
return null;
}
@Override
public Composite createControl(final Composite parent) {
composedAdapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
new ReflectiveItemProviderAdapterFactory(),
new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });
adapterFactoryItemDelegator = new AdapterFactoryItemDelegator(composedAdapterFactory);
clazz = ((EReference) getStructuralFeature()).getEReferenceType();
Composite titleComposite = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, false).span(2, 1).align(SWT.FILL, SWT.BEGINNING)
.applyTo(titleComposite);
GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(titleComposite);
Label label = new Label(titleComposite, SWT.NONE);
label.setText(getItemPropertyDescriptor().getDisplayName(null));
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).grab(true, false).applyTo(label);
// VALIDATION
validationLabel = new Label(titleComposite, SWT.NONE);
// set the size of the label to the size of the image
GridDataFactory.fillDefaults().hint(16, 17).applyTo(validationLabel);
boolean createButtons = true;
if (tableControlConfiguration != null) {
createButtons = !tableControlConfiguration.isAddRemoveDisabled();
}
if (createButtons) {
// addButtons
Composite buttonComposite = new Composite(titleComposite, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.END, SWT.BEGINNING).grab(true, false).applyTo(buttonComposite);
int numButtons = 2;
createAddRowButton(clazz, buttonComposite);
createRemoveRowButton(clazz, buttonComposite);
if (!isEmbedded() && getStructuralFeature().isUnsettable()) {
unsetButton = new Button(buttonComposite, SWT.PUSH);
unsetButton.setToolTipText(getUnsetButtonTooltip());
unsetButton.setImage(Activator.getImage("icons/delete.png")); //$NON-NLS-1$
numButtons++;
}
GridLayoutFactory.fillDefaults().numColumns(numButtons).equalWidth(true).applyTo(buttonComposite);
}
Composite controlComposite = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).span(2, 1).align(SWT.FILL, SWT.FILL).applyTo(controlComposite);
GridLayoutFactory.fillDefaults().numColumns(1).applyTo(controlComposite);
// delegate to super class
createContentControl(controlComposite);
return parent;
}
/*
* (non-Javadoc)
* @see
* org.eclipse.emf.ecp.edit.internal.swt.util.SWTControl#fillControlComposite(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void fillControlComposite(Composite parent) {
final Composite composite = new Composite(parent, SWT.NONE);
// composite.setLayout(new FillLayout());
GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).hint(1, 200).applyTo(composite);
tableViewer = new TableViewer(composite, SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
// GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, SWT.DEFAULT)
// .applyTo(tableViewer.getTable());
tableViewer.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_table");
tableViewer.getTable().setHeaderVisible(true);
tableViewer.getTable().setLinesVisible(true);
TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer,
new FocusCellOwnerDrawHighlighter(tableViewer));
ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(tableViewer) {
@Override
protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION
|| event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR
|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
}
};
TableViewerEditor.create(tableViewer, focusCellManager, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL
| ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL
| ColumnViewerEditor.KEYBOARD_ACTIVATION);
// create a content provider
ObservableListContentProvider cp = new ObservableListContentProvider();
EObject tempInstance = clazz.getEPackage().getEFactoryInstance().create(clazz);
ECPTableViewerComparator comparator = new ECPTableViewerComparator();
tableViewer.setComparator(comparator);
int columnNumber = 0;
List<EStructuralFeature> structuralFeatures = clazz.getEAllStructuralFeatures();
Map<EStructuralFeature, Boolean> readOnlyColumn = null;
if (tableControlConfiguration != null) {
structuralFeatures = new ArrayList<EStructuralFeature>();
readOnlyColumn = new HashMap<EStructuralFeature, Boolean>();
for (TableColumnConfiguration tcc : tableControlConfiguration.getColumns()) {
structuralFeatures.add(tcc.getColumnAttribute());
readOnlyColumn.put(tcc.getColumnAttribute(), tcc.isReadOnly());
}
}
for (final EStructuralFeature feature : structuralFeatures) {
IItemPropertyDescriptor itemPropertyDescriptor = adapterFactoryItemDelegator.getPropertyDescriptor(
tempInstance, feature);
if (itemPropertyDescriptor == null) {
// if we can't render because no edit information is available, do nothing
continue;
}
final CellEditor cellEditor = CellEditorFactory.INSTANCE.getCellEditor(itemPropertyDescriptor,
tempInstance, tableViewer.getTable());
// create a new column
final TableViewerColumn column = new TableViewerColumn(tableViewer, cellEditor.getStyle());
if (ECPCellEditor.class.isInstance(cellEditor)) {
column.getColumn().setData("width", ((ECPCellEditor) cellEditor).getColumnWidthWeight());
} else {
column.getColumn().setData("width", 100);
}
// determine the attribute that should be observed
IObservableMap map = null;
if (feature.isMany()) {
map = new EObjectObservableMap(cp.getKnownElements(), feature);
} else {
map = EMFProperties.value(feature).observeDetail(cp.getKnownElements());
}
column.setLabelProvider(new ObservableMapCellLabelProvider(map) {
@Override
public void update(ViewerCell cell) {
EObject element = (EObject) cell.getElement();
Object value = attributeMaps[0].get(element);
if (ECPCellEditor.class.isInstance(cellEditor)) {
ECPCellEditor ecpCellEditor = (ECPCellEditor) cellEditor;
String text = ecpCellEditor.getFormatedString(value);
cell.setText(text == null ? "" : text);
} else {
cell.setText(value == null ? "" : value.toString()); //$NON-NLS-1$
cell.getControl().setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_edit_cellEditor_string");
}
if (featureErrorMap.containsKey(element)
&& featureErrorMap.get(element).containsKey(attributeMaps[0].getValueType())) {
cell.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
} else {
cell.setBackground(null);
}
}
});
column.getColumn().addSelectionListener(getSelectionAdapter(comparator, column.getColumn(), columnNumber));
// set the column title & set the size
column.getColumn().setText(itemPropertyDescriptor.getDisplayName(null));
column.getColumn().setToolTipText(itemPropertyDescriptor.getDescription(null));
column.getColumn().setResizable(true);
column.getColumn().setMoveable(false);
boolean addEditingSupport = true;
if (readOnlyColumn != null) {
addEditingSupport = !readOnlyColumn.get(feature);
}
if (addEditingSupport) {
// remove if no editing needed
EditingSupport observableSupport = new EditingSupport(tableViewer) {
private EditingState editingState;
private final ColumnViewerEditorActivationListenerHelper activationListener = new ColumnViewerEditorActivationListenerHelper();
/**
* Default implementation always returns <code>true</code>.
*
* @see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
*/
@Override
protected boolean canEdit(Object element) {
// return false here otherwise
return true;
}
/**
* Default implementation always returns <code>null</code> as this will be
* handled by the Binding.
*
* @see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
*/
@Override
protected Object getValue(Object element) {
// no op
return null;
}
/**
* Default implementation does nothing as this will be handled by the
* Binding.
*
* @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object, java.lang.Object)
*/
@Override
protected void setValue(Object element, Object value) {
// no op
}
/**
* Creates a {@link Binding} between the editor and the element to be
* edited. Invokes {@link #doCreateCellEditorObservable(CellEditor)},
* {@link #doCreateElementObservable(Object, ViewerCell)}, and then
* {@link #createBinding(IObservableValue, IObservableValue)}.
*/
@Override
protected void initializeCellEditorValue(CellEditor cellEditor, ViewerCell cell) {
IObservableValue target = doCreateCellEditorObservable(cellEditor);
Assert.isNotNull(target, "doCreateCellEditorObservable(...) did not return an observable"); //$NON-NLS-1$
IObservableValue model = doCreateElementObservable(cell.getElement(), cell);
Assert.isNotNull(model, "doCreateElementObservable(...) did not return an observable"); //$NON-NLS-1$
Binding binding = createBinding(target, model);
Assert.isNotNull(binding, "createBinding(...) did not return a binding"); //$NON-NLS-1$
editingState = new EditingState(binding, target, model);
getViewer().getColumnViewerEditor().addEditorActivationListener(activationListener);
}
@Override
protected CellEditor getCellEditor(Object element) {
return cellEditor;
}
protected Binding createBinding(IObservableValue target, IObservableValue model) {
return getDataBindingContext().bindValue(target, model);
}
protected IObservableValue doCreateElementObservable(Object element, ViewerCell cell) {
return EMFEditObservables.observeValue(getModelElementContext().getEditingDomain(),
(EObject) element, feature);
}
protected IObservableValue doCreateCellEditorObservable(CellEditor cellEditor) {
if (ECPCellEditor.class.isInstance(cellEditor)) {
return ((ECPCellEditor) cellEditor).getValueProperty().observe(cellEditor);
}
return SWTObservables.observeText(cellEditor.getControl(), SWT.FocusOut);
}
@Override
final protected void saveCellEditorValue(CellEditor cellEditor, ViewerCell cell) {
editingState.binding.updateTargetToModel();
}
class ColumnViewerEditorActivationListenerHelper extends ColumnViewerEditorActivationListener {
@Override
public void afterEditorActivated(ColumnViewerEditorActivationEvent event) {
// do nothing
}
@Override
public void afterEditorDeactivated(ColumnViewerEditorDeactivationEvent event) {
editingState.dispose();
editingState = null;
getViewer().getColumnViewerEditor().removeEditorActivationListener(this);
}
@Override
public void beforeEditorActivated(ColumnViewerEditorActivationEvent event) {
// do nothing
}
@Override
public void beforeEditorDeactivated(ColumnViewerEditorDeactivationEvent event) {
// do nothing
}
}
/**
* Maintains references to objects that only live for the length of the edit
* cycle.
*/
class EditingState {
IObservableValue target;
IObservableValue model;
Binding binding;
EditingState(Binding binding, IObservableValue target, IObservableValue model) {
this.binding = binding;
this.target = target;
this.model = model;
}
void dispose() {
binding.dispose();
target.dispose();
model.dispose();
}
}
};
column.setEditingSupport(observableSupport);
}
columnNumber++;
}
tableViewer.setContentProvider(cp);
IObservableList list = EMFEditObservables.observeList(getModelElementContext().getEditingDomain(),
getModelElementContext().getModelElement(), getStructuralFeature());
tableViewer.setInput(list);
// IMPORTANT:
// - the minimumWidth and (non)resizable settings of the ColumnWeightData are not supported properly
// - the layout stops resizing columns that have been resized manually by the user (this could be considered a
// feature though)
TableColumnLayout layout = new TableColumnLayout();
composite.setLayout(layout);
for (int i = 0; i < tableViewer.getTable().getColumns().length; i++) {
Integer storedValue = (Integer) tableViewer.getTable().getColumns()[i].getData("width");
layout.setColumnData(tableViewer.getTable().getColumns()[i], new ColumnWeightData(storedValue == null ? 50
: storedValue));
}
}
@Override
protected Button getCustomUnsetButton() {
return unsetButton;
}
private SelectionAdapter getSelectionAdapter(final ECPTableViewerComparator comparator, final TableColumn column,
final int index) {
SelectionAdapter selectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
comparator.setColumn(index);
int dir = comparator.getDirection();
tableViewer.getTable().setSortDirection(dir);
tableViewer.getTable().setSortColumn(column);
tableViewer.refresh();
}
};
return selectionAdapter;
}
private Button removeButton;
private void createRemoveRowButton(EClass clazz, final Composite buttonComposite) {
removeButton = new Button(buttonComposite, SWT.None);
Image image = Activator.getImage("icons/delete.png"); //$NON-NLS-1$
removeButton.setImage(image);
removeButton.setToolTipText("Remove the selected " + clazz.getInstanceClass().getSimpleName());
removeButton.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
if (selection == null || selection.getFirstElement() == null) {
return;
}
final List<EObject> deletionList = new ArrayList<EObject>();
Iterator<?> iterator = selection.iterator();
while (iterator.hasNext()) {
deletionList.add((EObject) iterator.next());
}
MessageDialog dialog = new MessageDialog(tableViewer.getTable().getShell(), "Delete?", null,
"Are you sure you want to delete the selected Elements?", MessageDialog.CONFIRM, new String[] {
JFaceResources.getString(IDialogLabelKeys.YES_LABEL_KEY),
JFaceResources.getString(IDialogLabelKeys.NO_LABEL_KEY) }, 0);
final EObject modelElement = getModelElementContext().getModelElement();
new ECPDialogExecutor(dialog) {
@Override
public void handleResult(int codeResult) {
if (codeResult == IDialogConstants.CANCEL_ID) {
return;
}
EditingDomain editingDomain = getModelElementContext().getEditingDomain();
editingDomain.getCommandStack().execute(
RemoveCommand.create(editingDomain, modelElement, getStructuralFeature(), deletionList));
}
}.execute();
List<?> containments = (List<?>) modelElement.eGet(getStructuralFeature());
if (containments.size() < getStructuralFeature().getUpperBound()) {
addButton.setEnabled(true);
}
if (containments.size() <= getStructuralFeature().getLowerBound()) {
removeButton.setEnabled(false);
}
}
});
EObject modelElement = getModelElementContext().getModelElement();
List<?> containments = (List<?>) modelElement.eGet(getStructuralFeature());
if (containments.size() <= getStructuralFeature().getLowerBound()) {
removeButton.setEnabled(false);
}
}
private Button addButton;
private void createAddRowButton(final EClass clazz, final Composite buttonComposite) {
addButton = new Button(buttonComposite, SWT.None);
Image image = Activator.getImage("icons/add.png"); //$NON-NLS-1$
addButton.setImage(image);
addButton.setToolTipText("Add an instance of " + clazz.getInstanceClass().getSimpleName());
addButton.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
addRow(clazz);
EObject modelElement = getModelElementContext().getModelElement();
List<?> containments = (List<?>) modelElement.eGet(getStructuralFeature());
if (getStructuralFeature().getUpperBound() != -1
&& containments.size() == getStructuralFeature().getUpperBound()) {
addButton.setEnabled(false);
}
if (containments.size() > getStructuralFeature().getLowerBound()) {
removeButton.setEnabled(true);
}
}
});
EObject modelElement = getModelElementContext().getModelElement();
List<?> containments = (List<?>) modelElement.eGet(getStructuralFeature());
if (getStructuralFeature().getUpperBound() != -1
&& containments.size() >= getStructuralFeature().getUpperBound()) {
addButton.setEnabled(false);
}
}
/**
* {@inheritDoc}
*/
public void dispose() {
composedAdapterFactory.dispose();
}
/**
* {@inheritDoc}
*/
public void handleValidation(Diagnostic diagnostic) {
if (diagnostic.getSeverity() == Diagnostic.ERROR || diagnostic.getSeverity() == Diagnostic.WARNING) {
Image image = Activator.getImage(VALIDATION_ERROR_ICON);
validationLabel.setImage(image);
validationLabel.setToolTipText(diagnostic.getMessage());
EObject object = (EObject) diagnostic.getData().get(0);
if (!featureErrorMap.containsKey(object)) {
featureErrorMap.put(object, new HashMap<EStructuralFeature, Diagnostic>());
}
featureErrorMap.get(object).put((EStructuralFeature) diagnostic.getData().get(1), diagnostic);
tableViewer.update(object, null);
// tableViewer.refresh();
}
}
/**
* {@inheritDoc}
*/
public void resetValidation() {
featureErrorMap.clear();
tableViewer.refresh();
if (validationLabel == null || validationLabel.isDisposed()) {
return;
}
validationLabel.setImage(null);
}
/**
* {@inheritDoc}
*/
public void setEditable(boolean isEditable) {
tableViewer.getTable().setEnabled(false);
}
private void addRow(EClass clazz) {
EObject modelElement = getModelElementContext().getModelElement();
EObject instance = clazz.getEPackage().getEFactoryInstance().create(clazz);
EditingDomain editingDomain = getModelElementContext().getEditingDomain();
editingDomain.getCommandStack().execute(
AddCommand.create(editingDomain, modelElement, getStructuralFeature(), instance));
}
private class ECPTableViewerComparator extends ViewerComparator {
private int propertyIndex;
private static final int NONE = 0;
private int direction = NONE;
public ECPTableViewerComparator() {
propertyIndex = 0;
direction = NONE;
}
public int getDirection() {
switch (direction) {
case 0:
return SWT.NONE;
case 1:
return SWT.UP;
case 2:
return SWT.DOWN;
default:
return SWT.NONE;
}
}
public void setColumn(int column) {
if (column == propertyIndex) {
// Same column as last sort; toggle the direction
direction = (direction + 1) % 3;
} else {
// New column; do an ascending sort
propertyIndex = column;
direction = 1;
}
}
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
if (direction == 0) {
return 0;
}
int rc = 0;
EObject object1 = (EObject) e1;
EObject object2 = (EObject) e2;
EStructuralFeature feat1 = object1.eClass().getEAllStructuralFeatures().get(propertyIndex);
EStructuralFeature feat2 = object2.eClass().getEAllStructuralFeatures().get(propertyIndex);
Object value1 = object1.eGet(feat1);
Object value2 = object2.eGet(feat2);
if (value1 == null) {
rc = 1;
} else if (value2 == null) {
rc = -1;
} else {
rc = value1.toString().compareTo(value2.toString());
}
// If descending order, flip the direction
if (direction == 2) {
rc = -rc;
}
return rc;
}
}
/*
* (non-Javadoc)
* @see org.eclipse.emf.ecp.edit.internal.swt.util.SWTControl#getUnsetLabelText()
*/
@Override
protected String getUnsetLabelText() {
return "Not set. Click to set!";
}
/*
* (non-Javadoc)
* @see org.eclipse.emf.ecp.edit.internal.swt.util.SWTControl#getUnsetButtonTooltip()
*/
@Override
protected String getUnsetButtonTooltip() {
return "Unset";
}
/*
* (non-Javadoc)
* @see org.eclipse.emf.ecp.edit.internal.swt.util.SWTControl#getControlForTooltip()
*/
@Override
protected Control[] getControlsForTooltip() {
return new Control[] { tableViewer.getControl() };
}
}