ac.soton.eventb.roseEditor.propertySections.abstracts.AbstractTablePropertySection.java Source code

Java tutorial

Introduction

Here is the source code for ac.soton.eventb.roseEditor.propertySections.abstracts.AbstractTablePropertySection.java

Source

/*******************************************************************************
 * Copyright (c) 2006,2007,2008 University of Southampton 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
 *******************************************************************************/

package ac.soton.eventb.roseEditor.propertySections.abstracts;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.ChangeCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eventb.emf.core.CoreFactory;
import org.eventb.emf.core.CorePackage;
import org.eventb.emf.core.EventBCommented;
import org.eventb.emf.core.EventBElement;
import org.eventb.emf.core.EventBNamed;
import org.eventb.emf.core.Project;
import org.eventb.emf.core.util.NameUtils;
import org.rodinp.keyboard.ui.RodinKeyboardUIPlugin;
import org.rodinp.keyboard.ui.preferences.PreferenceConstants;

import ac.soton.eventb.roseEditor.properties.TextChangeHelper;

/**
 * Abstract property section displaying items as a table
 *
 * @author  cfs
 *
 */

public abstract class AbstractTablePropertySection extends AbstractEventBPropertySection {

    protected boolean singular;
    protected boolean createControlsCompleted;

    protected abstract EStructuralFeature getFeature();

    protected abstract Object getFeatureForCol(int col);

    protected String getTableLabel() {
        return null;
    }

    protected String getNewChildrenDialogTitle() {
        String elementKind = getFeature().getEType().getName();
        String featureName = getFeature().getName();
        return "Select new " + elementKind + "s to be added to " + featureName;
    }

    protected String getButtonLabelText() {
        String label = "<unknown element>";
        label = getFeature().getName();
        if (label.endsWith("s"))
            label = label.substring(0, label.length() - 1);
        label = label.substring(0, 1).toUpperCase() + label.substring(1);
        return label;
    }

    protected List<String> getValuesForRow(final Object object) {
        ArrayList<String> ret = new ArrayList<String>();
        int col = 0;
        Object feature = null;
        if (object instanceof EventBElement) {
            while ((feature = getFeatureForCol(col++)) != null) {
                String value = "<unknown feature>";
                if (feature instanceof EStructuralFeature) {
                    Object featureValue = ((EventBElement) object).eGet((EStructuralFeature) feature);
                    if (featureValue instanceof String) {
                        value = (String) featureValue;
                    } else if (featureValue instanceof List) {
                        value = "";
                        for (Object element : (List<?>) featureValue) {
                            if (element instanceof EventBNamed) {
                                if (value != "")
                                    value = value + ",";
                                value = value + ((EventBNamed) element).getName();
                            }
                        }
                    } else if (featureValue instanceof EventBNamed) {
                        value = ((EventBNamed) featureValue).getName();
                    } else if (featureValue instanceof Boolean) {
                        value = ((Boolean) featureValue).toString();
                    } else if (featureValue instanceof Enumerator) {
                        value = ((Enumerator) featureValue).getLiteral();
                    } else if (featureValue == null) {
                        value = "<null>";
                    }

                }
                ret.add(value);
            }
        } else if (object instanceof String) {
            ret.add((String) object);
        } else if (object instanceof Boolean) {
            //         EDataType eDataType = null; //((EDataType) object).eClass();
            //         String instanceValue = EcoreFactory.eINSTANCE.convertToString(eDataType, object);
            //         ret.add(instanceValue);
        }
        return ret;
    }

    protected List<String> getColumnLabelText() {
        ArrayList<String> ret = new ArrayList<String>();
        int col = 0;
        Object feature;
        while ((feature = getFeatureForCol(col++)) != null) {
            String label = "<unknown feature>";
            if (feature instanceof EStructuralFeature) {
                label = ((EStructuralFeature) feature).getName();
                label = label.substring(0, 1).toUpperCase() + label.substring(1);
            }
            ret.add(label);
        }
        return ret;
    }

    protected Object getNewValue() {
        if (getFeature() instanceof EReference) {
            if (((EReference) getFeature()).isContainment()) {
                EClass eClass = ((EReference) getFeature()).getEReferenceType();
                return eClass.getEPackage().getEFactoryInstance().create(eClass);
            } else {
                return getNewReferences();
            }
        } else if (getFeature() instanceof EAttribute) {
            EDataType eDataType = ((EAttribute) getFeature()).getEAttributeType();
            String literalValue = getNewDataValue();
            return EcoreFactory.eINSTANCE.createFromString(eDataType, literalValue);
        } else
            return null;
    }

    protected Object[] getNewReferences() {
        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
        ElementListSelectionDialog dialog = new ElementListSelectionDialog(shell, new BLabelProvider());
        dialog.setFilter(null);
        dialog.setElements(getPossibleChildren().toArray());
        dialog.setTitle(getNewChildrenDialogTitle());
        dialog.create();
        dialog.open();
        if (dialog.getReturnCode() == Window.CANCEL)
            return null;
        return dialog.getResult();
    }

    protected String getNewDataValue() {
        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
        InputDialog inputDialog = new InputDialog(shell, "Add new " + getFeature().getName(),
                "Input new value for " + getFeature().getName(), "", null);
        inputDialog.create();
        inputDialog.open();
        return inputDialog.getValue();
    }

    protected EList<EObject> getPossibleChildren() {
        if (!(getFeature() instanceof EReference))
            return null;
        EReference feature = (EReference) getFeature();
        EClass eClass = feature.getEReferenceType();
        Project project = (Project) owner.getContaining(CorePackage.eINSTANCE.getProject());
        EList<EObject> possibles = project.getAllContained(eClass, false);
        possibles.removeAll(this.getElements());
        return possibles;
    }

    protected List<?> getPossibleValues(final int col) {
        Object feature = getFeatureForCol(col);
        if (feature instanceof EReference) {
            EClass eClass = ((EReference) feature).getEReferenceType();
            Project project = CoreFactory.eINSTANCE.createProject();
            project = (Project) owner.getContaining(project.eClass());
            return project.getAllContained(eClass, true);
        } else if (feature instanceof EAttribute) {
            EDataType dataType = ((EAttribute) feature).getEAttributeType();
            if (dataType instanceof EEnum) {
                return ((EEnum) dataType).getELiterals();
            } else if (dataType.getName().equals("EBoolean")) {
                List<Object> l = new ArrayList<Object>();
                l.add(true);
                l.add(false);
                return l;
            } else
                return null;
        } else if (feature instanceof EDataType) {
            EDataType dataType = (EDataType) feature;
            if (dataType instanceof EEnum) {
                return ((EEnum) dataType).getELiterals();
            } else if (dataType.getName().equals("EBoolean")) {
                List<Object> l = new ArrayList<Object>();
                l.add(true);
                l.add(false);
                return l;
            } else
                return null;
        } else {
            return null;
        }
    }

    protected Object getNewValue(final int col, final int index) {
        Object newValue = null;
        List<?> possVals = getPossibleValues(col);
        if (possVals != null)
            newValue = possVals.get(index);
        if (newValue instanceof EEnumLiteral)
            newValue = ((EEnumLiteral) newValue).getInstance();
        return newValue;
    }

    protected List<? extends Object> getElements() {
        ArrayList<Object> ret = new ArrayList<Object>();
        Object featureValue = owner.eGet(getFeature());
        if (featureValue instanceof List)
            for (Object element : (List<?>) featureValue) {
                ret.add(element);
            }
        else if (featureValue instanceof Object) {
            ret.add(featureValue);
        }
        return ret;
    }

    //the default column widths may be overridden in extensions
    protected int columnWidth(final int col) {
        return 150;
    }

    //a column can be made read-only
    protected boolean isReadOnly(final int col) {
        return false;
    }

    //a row can be made read-only
    protected boolean isReadOnly(final Object object) {
        return false;
    }

    private class BLabelProvider extends LabelProvider {
        @Override
        public String getText(final Object element) {
            if (element == null)
                return "<null>";
            else if (element instanceof EventBNamed)
                return ((EventBNamed) element).getName();
            return "<unknown element>";
        }

        @Override
        public org.eclipse.swt.graphics.Image getImage(final Object element) {
            if (element == null)
                return null;
            else if (element instanceof EventBElement) {
                //List adapters = ((EventBElement)element).eAdapters();
                return null;
            } else
                return null;
        }
    }

    protected void addButtonAction() {
        Command command;
        Object newValue = getNewValue();
        if (newValue == null) {
            command = UnexecutableCommand.INSTANCE;
        } else {
            if (singular) {
                command = SetCommand.create(editingDomain, owner, getFeature(), newValue);
            } else {
                command = AddCommand.create(editingDomain, owner, getFeature(), newValue);
            }
            if (newValue instanceof EventBCommented) {
                ((EventBCommented) newValue).setComment("");
            }
        }
        editingDomain.getCommandStack().execute(command);
        refresh();
    }

    protected void removeButtonAction() {
        Object object = table.getSelection()[0].getData();
        if (singular) {
            editingDomain.getCommandStack()
                    .execute(SetCommand.create(editingDomain, owner, getFeature(), SetCommand.UNSET_VALUE));
        } else {
            editingDomain.getCommandStack()
                    .execute(RemoveCommand.create(editingDomain, owner, getFeature(), object));
        }
        refresh();
    }

    protected void upButtonAction() {
        move(-1);
    }

    protected void downButtonAction() {
        move(1);
    }

    private void move(final int movement) {
        Object object = table.getSelection()[0].getData();
        Object featureValue = owner.eGet(getFeature());
        if (featureValue instanceof EList) {
            int pos = ((EList<?>) featureValue).indexOf(object) + movement;
            if (pos < 0 || pos > ((EList<?>) featureValue).size() - 1)
                return;
            editingDomain.getCommandStack()
                    .execute(MoveCommand.create(editingDomain, owner, getFeature(), object, pos));
            refresh(); //redraw the new table
            table.select(pos); //reselect the same object ready for another move
            rowSelectionAction(); //do the actions needed for a selection event
        }
    }

    protected Table table;
    protected List<TableColumn> columns;
    protected Button addButton;
    protected Button removeButton;
    protected Button upButton;
    protected Button downButton;
    protected Button seeErrorsButton;

    private Combo combo = null;
    private Text text = null;
    private final ModifyListener rodinKbdListener = RodinKeyboardUIPlugin.getDefault().createRodinModifyListener();
    private final Font font = JFaceResources.getFont(PreferenceConstants.RODIN_MATH_FONT);
    private TableEditor editor;

    private List<String> getValuesForRow(final int row) {
        return getValuesForRow(getElements().get(row));
    }

    @Override
    public void createControls(final Composite parent, final TabbedPropertySheetPage tabbedPropertySheetPage) {
        super.createControls(parent, tabbedPropertySheetPage);
        createControlsCompleted = false;
    }

    /**
     * Some tables need to know the owner when creating the table. Since the selection is not always set (in the supertype)
     * when createControls is called, the main creation of controls is delayed until refresh is invoked.
     *
     **/

    private void doCreateControls() {
        singular = getFeature().getUpperBound() == 1;
        Composite composite = getWidgetFactory().createFlatFormComposite(parent);
        FormData data;
        table = getWidgetFactory().createTable(composite, SWT.FILL | SWT.FULL_SELECTION);
        createTable();
        table.setFont(JFaceResources.getFont(PreferenceConstants.RODIN_MATH_FONT));
        editor = new TableEditor(table);
        editor.grabHorizontal = true;
        Shell shell = new Shell();
        GC gc = new GC(shell);
        gc.setFont(shell.getFont());
        Point point = gc.textExtent("");
        int buttonHeight = point.y + 11;
        gc.dispose();
        shell.dispose();

        FormAttachment leftData = null;

        //label
        if (getTableLabel() != null) {
            CLabel nameLabel = getWidgetFactory().createCLabel(composite, getTableLabel());
            data = new FormData();
            data.left = new FormAttachment(0, 0);
            data.right = new FormAttachment(table, -ITabbedPropertyConstants.HSPACE);
            data.top = new FormAttachment(table, 0, SWT.CENTER);
            nameLabel.setLayoutData(data);
            leftData = new FormAttachment(0, getStandardLabelWidth(composite, new String[] { getTableLabel() }));
        } else {
            leftData = new FormAttachment(0, 0);
        }

        FormAttachment buttonTopData = null;
        FormAttachment buttonBottomData = null;
        if (singular) {
            buttonTopData = new FormAttachment(table, 0);
            buttonBottomData = new FormAttachment(table, buttonHeight + 6, SWT.BOTTOM);
        } else {
            buttonTopData = new FormAttachment(100, -buttonHeight);
            buttonBottomData = new FormAttachment(100, 0);
        }

        //add button
        addButton = getWidgetFactory().createButton(composite,
                MessageFormat.format("Add {0}", new Object[] { getButtonLabelText() }), SWT.PUSH);
        data = new FormData();
        data.left = leftData;
        data.bottom = buttonBottomData;
        data.top = buttonTopData;
        addButton.setLayoutData(data);
        addButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent event) {
                addButtonAction();
            }
        });

        //delete button
        removeButton = getWidgetFactory().createButton(composite,
                MessageFormat.format("Delete {0}", new Object[] { getButtonLabelText() }), SWT.PUSH);
        data = new FormData();
        data.left = new FormAttachment(addButton, ITabbedPropertyConstants.VSPACE, SWT.BOTTOM);
        data.bottom = buttonBottomData;
        data.top = buttonTopData;
        removeButton.setLayoutData(data);
        removeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent event) {
                removeButtonAction();
            }
        });
        Button lastButton = removeButton;

        //move buttons
        if (!singular) {
            //up button
            upButton = getWidgetFactory().createButton(composite, MessageFormat.format("Move Up", new Object[] {}),
                    SWT.PUSH);
            data = new FormData();
            data.left = new FormAttachment(lastButton, ITabbedPropertyConstants.VSPACE, SWT.BOTTOM);
            data.bottom = buttonBottomData;
            data.top = buttonTopData;
            upButton.setLayoutData(data);
            upButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(final SelectionEvent event) {
                    upButtonAction();
                }
            });
            //down button
            downButton = getWidgetFactory().createButton(composite,
                    MessageFormat.format("Move Down", new Object[] {}), SWT.PUSH);
            data = new FormData();
            data.left = new FormAttachment(upButton, ITabbedPropertyConstants.VSPACE, SWT.BOTTOM);
            data.bottom = buttonBottomData;
            data.top = buttonTopData;
            downButton.setLayoutData(data);
            downButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(final SelectionEvent event) {
                    downButtonAction();
                }
            });
            lastButton = downButton;
        }

        //main table layout and row selection
        data = new FormData();
        data.left = leftData;
        data.right = new FormAttachment(100, 0);
        data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
        if (!singular) {
            data.bottom = new FormAttachment(addButton, -ITabbedPropertyConstants.VSPACE);
        }
        data.width = 400;
        table.setLayoutData(data);
        table.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent event) {
                rowSelectionAction();
            }
        });

    }

    private void rowSelectionAction() {
        removeButton.setEnabled(true);
        if (upButton != null)
            upButton.setEnabled(true);
        if (downButton != null)
            downButton.setEnabled(true);
    }

    @Override
    public boolean shouldUseExtraSpace() {
        return true;
    }

    private void createTable() {
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        createColumns();
        table.addListener(SWT.MouseUp, tableMouseListener);
        table.addDisposeListener(disposeListener);
    }

    private void createColumns() {
        List<String> labels = getColumnLabelText();
        columns = new ArrayList<TableColumn>();
        int col = 0;
        for (String label : labels) {
            TableColumn column = new TableColumn(table, SWT.NONE);
            column.setText(label);
            columns.add(column);
            column.setWidth(columnWidth(col));
            col++;
        }
    }

    @Override
    public void refresh() {
        if (createControlsCompleted == false)
            doCreateControls();
        createControlsCompleted = true;
        if (combo != null)
            combo.dispose();
        if (text != null)
            text.dispose();
        table.removeAll();
        table.redraw();
        if (getFeature().getUpperBound() < 0 || getElements().size() < getFeature().getUpperBound()) {
            addButton.setEnabled(true);
        } else {
            addButton.setEnabled(false);
        }
        removeButton.setEnabled(false);
        if (upButton != null)
            upButton.setEnabled(false);
        if (downButton != null)
            downButton.setEnabled(false);
        if (seeErrorsButton != null)
            seeErrorsButton.setEnabled(false);
        for (Object next : getElements()) {
            // create the table item
            TableItem item = new TableItem(table, SWT.NONE);
            String[] values = new String[columns.size()];
            List<String> valuesForRow = getValuesForRow(next);
            for (int j = 0; j < columns.size(); j++)
                if (j < valuesForRow.size())
                    values[j] = valuesForRow.get(j);
                else
                    values[j] = "";
            item.setText(values);
            item.setData(next);
            if (isReadOnly(next))
                item.setGrayed(true);
        }

        if (owner instanceof EventBElement && ((EventBElement) owner).isGenerated()) {
            table.setEnabled(false);
            addButton.setEnabled(false);
        } else {
            table.setEnabled(true);
            addButton.setEnabled(true);
        }

        table.redraw();
    }

    private final Listener tableMouseListener = new Listener() {
        TableItem tableItem = null;
        int row = 0;
        int column = 0;

        public void handleEvent(final Event event) {
            if (combo != null)
                combo.dispose();
            textChangeListener.stopListeningTo(text);
            if (text != null)
                text.dispose();
            text = null;
            row = table.getTopIndex();
            boolean found = false;
            while (row < table.getItemCount()) {
                tableItem = table.getItem(row);
                column = 0;
                found = false;
                while (column < table.getColumnCount()) {
                    Rectangle rect = tableItem.getBounds(column);
                    if (rect.contains(new Point(event.x, event.y))) {
                        if (isReadOnly(column) || isReadOnly(tableItem.getData())) {
                            found = false;
                            break;
                        } else {
                            found = true;
                            break;
                        }
                    } else if (!rect.intersects(table.getClientArea())) {
                        found = false;
                        break;
                    }
                    column++;
                }
                if (found == true)
                    break;
                else
                    row++;
            }
            if (found == false)
                return;

            tableItem.setFont(font);
            if (getPossibleValues(column) == null) { //if the list of names of possible values is null must be a text field
                text = new Text(table, SWT.NONE);
                //eventBListener
                text.addModifyListener(rodinKbdListener);
                text.setFont(font);
                textChangeListener.startListeningTo(text);
                textChangeListener.startListeningForEnter(text);
                editor.setEditor(text, tableItem, column);
                text.setText(tableItem.getText(column));
                text.selectAll();
                text.setFocus();
            } else {
                combo = new Combo(table, SWT.READ_ONLY);
                combo.setFont(font);
                combo.setItems(NameUtils.getNames(getPossibleValues(column)).toArray(new String[0]));
                combo.addSelectionListener(comboSelectionListener);
                editor.setEditor(combo, tableItem, column);
                combo.setText(tableItem.getText(column));
            }
        }

        private final TextChangeHelper textChangeListener = new TextChangeHelper() {
            @Override
            public void textChanged(final Control control) {
                if (text.isDisposed())
                    return;
                String newText = text.getText();
                String oldText = getValuesForRow(row).get(column);
                //         EventBElement EventBElement =getEventBElements().get(row);
                if (oldText == null || !oldText.equals(newText)) {
                    if (getFeatureForCol(column).equals(CorePackage.eINSTANCE.getEventBNamed_Name())) {
                        //                //when changing a name must check for naming collisions and rename files
                        //                if (DiagramUtilities.nameCollision(EventBElement, newText, EventBElement.eContainer(), getFeature())) {
                        //                   MessageDialog.openError(getPart().getSite().getShell(),"Warning", "The element cannot be renamed because another element already exists with that name");
                        //                   text.setFocus();
                        //                   text.setText(oldText);
                        //                   tableItem.setText(oldText);
                        //                   return;
                        //                }//else...
                        //                //rename any diagram files that are affected by this change
                        //                text.setFocus();
                        //                DiagramUtilities.renameFiles(EventBElement, oldText, newText);
                    }
                    tableItem.setText(column, newText);
                    handleTextChanged(column, row, newText);
                }
            }
        };

        SelectionListener comboSelectionListener = new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent arg0) {
                return;
            }

            public void widgetSelected(SelectionEvent e) {
                Object object = getElements().get(row);
                if (combo.getSelectionIndex() != -1) {
                    Object newValue = getNewValue(column, combo.getSelectionIndex());
                    //EditingDomain editingDomain = propertySheetPage.getEditor().getEditingDomain();
                    if (getFeatureForCol(column) != null)
                        editingDomain.getCommandStack().execute(
                                SetCommand.create(editingDomain, object, getFeatureForCol(column), newValue));
                    String setText = newValue instanceof String ? (String) newValue
                            : NameUtils.getNames(getPossibleValues(column)).get(combo.getSelectionIndex());
                    tableItem.setText(column, setText);
                }
                combo.dispose();
            }
        };

    };

    protected void handleTextChanged(int column, int row, String newText) {
        Object feature = getFeatureForCol(column);
        if (feature instanceof EStructuralFeature) {
            Object object = getElements().get(row);
            editingDomain.getCommandStack().execute(SetCommand.create(editingDomain, object, feature, newText));
        } else if (getFeature() instanceof EAttribute && feature instanceof EDataType) {
            if (((EDataType) feature).getName().equals("EString")) {
                editingDomain.getCommandStack()
                        .execute(new SetTextInListCommand(owner, getFeature(), column, newText));
            }
        }
    }

    protected class SetTextInListCommand extends ChangeCommand {
        final EventBElement owner;
        final EStructuralFeature feature;
        final String newText;
        final int index;

        SetTextInListCommand(EventBElement owner, EStructuralFeature feature, int index, String newText) {
            super(new ChangeRecorder(owner).endRecording());
            this.owner = owner;
            this.feature = feature;
            this.newText = newText;
            this.index = index;
        }

        @SuppressWarnings("unchecked")
        @Override
        public void doExecute() {
            ((EList<String>) owner.eGet(feature)).set(index, newText);
        }
    }

    private final DisposeListener disposeListener = new DisposeListener() {
        public void widgetDisposed(DisposeEvent e) {
            refresh();
        }
    };

}