org.switchyard.tools.ui.editor.diagram.shared.AbstractSwitchyardComposite.java Source code

Java tutorial

Introduction

Here is the source code for org.switchyard.tools.ui.editor.diagram.shared.AbstractSwitchyardComposite.java

Source

/******************************************************************************* 
 * Copyright (c) 2012 Red Hat, Inc. 
 *  All rights reserved. 
 * This program is 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: 
 * Red Hat, Inc. - initial API and implementation 
 *
 * @author bfitzpat
 ******************************************************************************/
package org.switchyard.tools.ui.editor.diagram.shared;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.internal.databinding.swt.SWTObservableValueDecorator;
import org.eclipse.jface.internal.databinding.swt.SWTVetoableValueDecorator;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
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.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.layout.GridData;
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.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.internal.dialogs.PropertyDialog;
import org.switchyard.tools.ui.editor.Activator;
import org.switchyard.tools.ui.editor.impl.SwitchyardSCAEditor;
import org.switchyard.tools.ui.editor.util.ErrorUtils;

/**
 * @author bfitzpat
 * 
 */
@SuppressWarnings("restriction")
public abstract class AbstractSwitchyardComposite
        implements FocusListener, KeyListener, ModifyListener, SelectionListener {

    private boolean _canEdit = true;
    private String _errorMessage = null;
    private GridData _rootGridData = null;
    private boolean _openOnCreate = false;
    private boolean _hasChanged = false;
    private boolean _inUpdate = false;
    private ArrayList<Control> _observableControls = new ArrayList<Control>();
    private Control _comboTextChanged = null;
    private TextValueChangeListener _textValueChangeListener = null;
    private ComboValueChangeListener _comboValueChangeListener = null;
    private ButtonValueChangeListener _buttonValueChangeListener = null;
    private ArrayList<IObservable> _observables = null;
    private boolean _observersAdded = false;
    private final FormToolkit _toolkit;

    // change listeners
    private ListenerList _changeListeners;

    /**
     * Empty constructor.
     * 
     * @param toolkit the toolkit for creating controls
     */
    public AbstractSwitchyardComposite(FormToolkit toolkit) {
        _toolkit = toolkit;
    }

    /**
     * @return the toolkit associated with this composite
     */
    public FormToolkit getToolkit() {
        return _toolkit;
    }

    abstract protected boolean validate();

    protected boolean hasChanged() {
        return _hasChanged;
    }

    protected void setHasChanged(boolean flag) {
        this._hasChanged = flag;
    }

    /**
     * @param parent Composite parent
     * @param style any style bits
     * @param dataBindingContext the context to be used for binding controls
     */
    abstract public void createContents(Composite parent, int style, DataBindingContext dataBindingContext);

    abstract protected void handleModify(final Control control);

    /**
     * @return panel
     */
    abstract public Composite getPanel();

    /**
     * @return string error message
     */
    public String getErrorMessage() {
        return this._errorMessage;
    }

    /**
     * @param msg string to set
     */
    public void setErrorMessage(String msg) {
        this._errorMessage = msg;
    }

    /**
     * If we changed, fire a changed event.
     * 
     * @param source
     */
    protected void fireChangedEvent(Object source) {
        ChangeEvent e = new ChangeEvent(source);
        // inform any listeners of the change event
        if (this._changeListeners != null && !this._changeListeners.isEmpty()) {
            Object[] listeners = this._changeListeners.getListeners();
            for (int i = 0; i < listeners.length; ++i) {
                ((ChangeListener) listeners[i]).stateChanged(e);
            }
        }
    }

    /**
     * Add a change listener.
     * 
     * @param listener new listener
     */
    public void addChangeListener(ChangeListener listener) {
        if (this._changeListeners == null) {
            this._changeListeners = new ListenerList();
        }
        this._changeListeners.add(listener);
    }

    /**
     * Remove a change listener.
     * 
     * @param listener to remove
     */
    public void removeChangeListener(ChangeListener listener) {
        if (this._changeListeners != null && !this._changeListeners.isEmpty()) {
            this._changeListeners.remove(listener);
        }
    }

    /**
     * @return flag
     */
    public boolean canEdit() {
        return this._canEdit;
    }

    /**
     * @param canEdit flag
     */
    public void setCanEdit(boolean canEdit) {
        this._canEdit = canEdit;
    }

    /**
     * @param rootGridData the _rootGridData to set
     */
    public void setRootGridData(GridData rootGridData) {
        this._rootGridData = rootGridData;
    }

    /**
     * @return GridData or null
     */
    public GridData getRootGridData() {
        return this._rootGridData;
    }

    /**
     * @param flag open on create? true/false
     */
    public void setOpenOnCreate(boolean flag) {
        this._openOnCreate = flag;
    }

    /**
     * @return true/false
     */
    public boolean openOnCreate() {
        return this._openOnCreate;
    }

    /**
     * Dispose of the composite widgets.
     */
    public void dispose() {
        if (getPanel() != null) {
            disposeChildWidgets(getPanel());
        }
    }

    /**
     * @param parent Parent composite
     */
    public static void disposeChildWidgets(Composite parent) {
        if (parent.isDisposed()) {
            return;
        }
        Control[] kids = parent.getChildren();
        for (Control k : kids) {
            if (k instanceof Composite) {
                disposeChildWidgets((Composite) k);
            }
            k.dispose();
        }
    }

    /**
     * @param parent parent composite
     * @param label string for label
     * @return reference to created Button
     */
    protected Button createCheckbox(Composite parent, String label) {
        return createCheckbox(parent, label, 1);
    }

    /**
     * @param parent parent composite
     * @param label string for label
     * @return reference to created Button
     */
    protected Button createCheckbox(Composite parent, String label, int horizSpan) {
        Button newButton = getToolkit().createButton(parent, label, SWT.CHECK | SWT.LEFT);
        GridData gd = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
        if (horizSpan > 1) {
            gd.horizontalSpan = horizSpan;
        }
        newButton.setLayoutData(gd);
        _observableControls.add(newButton);

        return newButton;
    }

    private void addEnterNextListener(final Control control) {
        control.addTraverseListener(new TraverseListener() {

            @Override
            public void keyTraversed(TraverseEvent e) {
                if (e.character == SWT.CR) {
                    control.traverse(SWT.TRAVERSE_TAB_NEXT);
                }
            }
        });
    }

    /**
     * @param parent parent composite
     * @param label string to put in label
     * @return reference to created Text control
     */
    protected Text createLabelAndText(Composite parent, String label) {
        return createLabelAndText(parent, label, 1);
    }

    /**
     * @param parent parent composite
     * @param label string to put in label
     * @param horizSpan number of GridData columns to span vertically
     * @return reference to created Text control
     */
    protected Text createLabelAndText(Composite parent, String label, int horizSpan) {
        if (label != null && !label.trim().isEmpty()) {
            getToolkit().createLabel(parent, label, SWT.NONE);
        }
        Text newText = getToolkit().createText(parent, "", SWT.BORDER);
        GridData gd = new GridData(SWT.FILL, SWT.NONE, true, false);
        if (horizSpan > 1) {
            gd.horizontalSpan = horizSpan;
        }
        newText.setLayoutData(gd);
        newText.addKeyListener(this);
        addEnterNextListener(newText);

        _observableControls.add(newText);

        return newText;
    }

    protected void handleChange(Control control) {
        setHasChanged(true);
        validate();
        handleModify(control);
        fireChangedEvent(this);
    }

    class TextValueChangeListener implements IValueChangeListener {
        @Override
        public void handleValueChange(final ValueChangeEvent e) {
            if (!inUpdate() && e.diff != null && !e.diff.getOldValue().equals(e.diff.getNewValue())) {
                System.out.println("AbstractSwitchyardComposite:TextValueChanged: " + e.diff); //$NON-NLS-1$
                SWTVetoableValueDecorator decorator = (SWTVetoableValueDecorator) e.getSource();
                Control ctrl = (Control) decorator.getWidget();
                if (!ctrl.isDisposed()) {
                    handleChange((Control) decorator.getWidget());
                    ErrorUtils.showErrorMessage(null);
                }
            }
        }
    }

    class ComboValueChangeListener implements IValueChangeListener {
        @Override
        public void handleValueChange(final ValueChangeEvent e) {
            if (!inUpdate() && e.diff != null) {
                System.out.println("AbstractSwitchyardComposite:ComboValueChanged: " + e.diff); //$NON-NLS-1$
                SWTObservableValueDecorator decorator = (SWTObservableValueDecorator) e.getSource();
                handleChange((Control) decorator.getWidget());
                ErrorUtils.showErrorMessage(null);
            }
        }
    }

    class ButtonValueChangeListener implements IValueChangeListener {
        @Override
        public void handleValueChange(final ValueChangeEvent e) {
            if (!inUpdate() && e.diff != null) {
                if (!inUpdate() && e.diff != null) {
                    System.out.println("AbstractSwitchyardComposite:ButtonValueChanged: " + e.diff); //$NON-NLS-1$
                    SWTObservableValueDecorator decorator = (SWTObservableValueDecorator) e.getSource();
                    handleChange((Control) decorator.getWidget());
                }
            }
        }
    }

    protected void addObservableListeners() {
        addObservableListeners(false);
    }

    protected void addObservableListeners(boolean reset) {
        if (_observersAdded && !reset) {
            return;
        }

        if (reset && _observables != null && _observables.size() > 0) {
            for (int i = 0; i < _observables.size(); i++) {
                _observables.get(i).dispose();
            }
            _observables.clear();
        }
        _observables = new ArrayList<IObservable>();

        if (_textValueChangeListener == null) {
            _textValueChangeListener = new TextValueChangeListener();
        }
        if (_comboValueChangeListener == null) {
            _comboValueChangeListener = new ComboValueChangeListener();
        }
        if (_buttonValueChangeListener == null) {
            _buttonValueChangeListener = new ButtonValueChangeListener();
        }

        int styleBit = 0;
        Composite parent = this.getPanel().getParent();
        System.out.println(parent);
        while (parent != null && !(parent instanceof Shell)) {
            parent = parent.getParent();
        }
        if (parent != null && parent instanceof Shell) {
            Shell shell = (Shell) parent;
            if (shell.getData() instanceof WizardDialog || shell.getData() instanceof PropertyDialog) {
                styleBit = SWT.Modify;
            }
        }

        Iterator<Control> iter = _observableControls.iterator();
        while (iter.hasNext()) {
            Control ctrl = iter.next();
            if (ctrl.isDisposed()) {
                continue;
            }
            if (ctrl instanceof Text) {
                Text newText = (Text) ctrl;
                ISWTObservableValue focusObserver = SWTObservables.observeText(newText, SWT.FocusOut | styleBit);
                _observables.add(focusObserver);
                // focusObserver.removeValueChangeListener(_textValueChangeListener);
                focusObserver.addValueChangeListener(_textValueChangeListener);
            } else if (ctrl instanceof Combo) {
                final Combo newCombo = (Combo) ctrl;
                if ((newCombo.getStyle() & SWT.READ_ONLY) == 0) {
                    newCombo.addKeyListener(new KeyListener() {
                        @Override
                        public void keyPressed(KeyEvent e) {
                        }

                        @Override
                        public void keyReleased(KeyEvent e) {
                            if ((e.keyCode >= 97 && e.keyCode <= 122) || // characters
                            (e.keyCode >= 48 && e.keyCode <= 57) || // digits
                            (e.keyCode == 32) || // spacebar
                            (e.keyCode == SWT.BS) || // backspace
                            (e.keyCode == SWT.ARROW_UP) || // up arrow
                            (e.keyCode == SWT.ARROW_DOWN)) {
                                AbstractSwitchyardComposite.this._comboTextChanged = (Control) e.widget;
                            }
                        }
                    });
                    newCombo.addModifyListener(new ModifyListener() {
                        @Override
                        public void modifyText(ModifyEvent arg0) {
                            AbstractSwitchyardComposite.this._comboTextChanged = (Control) arg0.widget;
                        }
                    });
                    if (styleBit != 0) {
                        newCombo.addSelectionListener(new SelectionAdapter() {
                            @Override
                            public void widgetSelected(SelectionEvent e) {
                                if (AbstractSwitchyardComposite.this._comboTextChanged == (Control) e.getSource()) {
                                    System.out.println(
                                            "AbstractSwitchyardComposite:New Combo Selection (text entry): " //$NON-NLS-1$
                                                    + ((Combo) e.getSource()).getText());
                                    handleChange((Control) e.getSource());
                                    AbstractSwitchyardComposite.this._comboTextChanged = null;
                                }
                            }
                        });
                    }
                    newCombo.addFocusListener(new FocusListener() {
                        @Override
                        public void focusGained(FocusEvent e) {
                        }

                        @Override
                        public void focusLost(FocusEvent e) {
                            if (AbstractSwitchyardComposite.this._comboTextChanged == (Control) e.getSource()) {
                                System.out.println("AbstractSwitchyardComposite:New Combo Value (text entry): " //$NON-NLS-1$
                                        + ((Combo) e.getSource()).getText());
                                handleChange((Control) e.getSource());
                                AbstractSwitchyardComposite.this._comboTextChanged = null;
                            }
                        }
                    });
                }

                ISWTObservableValue selectionObserver = SWTObservables.observeSelection(newCombo);
                _observables.add(selectionObserver);
                // selectionObserver.removeValueChangeListener(_comboValueChangeListener);
                selectionObserver.addValueChangeListener(_comboValueChangeListener);

            } else if (ctrl instanceof Button) {
                Button newButton = (Button) ctrl;
                ISWTObservableValue buttonObserver = SWTObservables.observeSelection(newButton);
                _observables.add(buttonObserver);
                // buttonObserver.removeValueChangeListener(_buttonValueChangeListener);
                buttonObserver.addValueChangeListener(_buttonValueChangeListener);
            }
        }
        _observersAdded = true;
    }

    /**
     * @param parent parent composite
     * @param label string to put in label
     * @return reference to created Text control
     */
    protected Combo createLabelAndCombo(Composite parent, String label) {
        return createLabelAndCombo(parent, label, false);
    }

    /**
     * @param parent parent composite
     * @param label string to put in label
     * @param readOnly should combo text be editable
     * @return reference to created Text control
     */
    protected Combo createLabelAndCombo(Composite parent, String label, boolean readOnly) {
        return createLabelAndCombo(parent, label, readOnly, 1);
    }

    /**
     * @param parent parent composite
     * @param label string to put in label
     * @param readOnly should combo text be editable
     * @param horizSpan how many GridData cols should it span?
     * @return reference to created Text control
     */
    protected Combo createLabelAndCombo(Composite parent, String label, boolean readOnly, int horizSpan) {
        if (label != null && !label.trim().isEmpty()) {
            getToolkit().createLabel(parent, label, SWT.NONE);
        }
        int styles = SWT.BORDER | SWT.DROP_DOWN;
        if (readOnly) {
            styles = SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY;
        }
        Combo combo = new Combo(parent, styles);
        GridData gd = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
        if (horizSpan > 1) {
            gd.horizontalSpan = horizSpan;
        }
        combo.setLayoutData(gd);
        if (!readOnly) {
            addEnterNextListener(combo);
        }
        _observableControls.add(combo);
        getToolkit().adapt(combo, true, true);

        return combo;
    }

    protected ComboViewer createLabelAndComboViewer(Composite parent, String label, boolean readOnly) {
        return createLabelAndComboViewer(parent, label, readOnly, 1);
    }

    protected ComboViewer createLabelAndComboViewer(Composite parent, String label, boolean readOnly,
            int horizSpan) {
        if (label != null && !label.trim().isEmpty()) {
            getToolkit().createLabel(parent, label, SWT.NONE);
        }
        int styles = SWT.BORDER | SWT.DROP_DOWN;
        if (readOnly) {
            styles = SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY;
        }
        ComboViewer combo = new ComboViewer(parent, styles);
        GridData gd = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
        if (horizSpan > 1) {
            gd.horizontalSpan = horizSpan;
        }
        combo.getCombo().setLayoutData(gd);
        if (!readOnly) {
            addEnterNextListener(combo.getCombo());
        }
        _observableControls.add(combo.getCombo());
        getToolkit().adapt(combo.getCombo(), true, true);

        return combo;
    }

    @Override
    public void focusGained(FocusEvent e) {
        // ignore
    }

    @Override
    public void focusLost(FocusEvent e) {
        // ignore
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.keyCode != SWT.CR && e.keyCode != SWT.TAB) {
            setHasChanged(true);
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.keyCode == SWT.ESC) {
            Control control = (Control) e.getSource();
            setInUpdate(true);
            handleUndo(control);
            setInUpdate(false);
        }
    }

    protected boolean inUpdate() {
        return _inUpdate;
    }

    protected void setInUpdate(boolean inUpdate) {
        this._inUpdate = inUpdate;
    }

    @Override
    public void modifyText(ModifyEvent e) {
        if (!inUpdate()) {
            _hasChanged = true;
        }
    }

    @Override
    public void widgetSelected(SelectionEvent e) {
        if (!inUpdate()) {
            _hasChanged = true;
        }
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
        widgetSelected(e);
    }

    /**
     * @param text Text field
     * @param value value to set
     */
    public void setTextValue(Text text, String value) {
        if (value == null) {
            value = ""; //$NON-NLS-1$
        }
        if (text != null && !text.isDisposed()) {
            text.setText(value);
        }
    }

    /**
     * @param combo Combo field
     * @param value value to set
     */
    public void setTextValue(Combo combo, String value) {
        if (value == null) {
            value = ""; //$NON-NLS-1$
        }
        if (combo != null && !combo.isDisposed()) {
            combo.setText(value);
        }
    }

    /**
     * @param eObject incoming object to update
     * @param featureId feature to update
     * @param value value for feature
     * @throws Exception in case something can't be found
     */
    public void setFeatureValue(EObject eObject, String featureId, Object value) throws Exception {
        EClass eClass = eObject.eClass();
        for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i) {
            EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);
            if (eStructuralFeature.isChangeable()) {
                if (eStructuralFeature.getName().equalsIgnoreCase(featureId)) {
                    if (value != null) {
                        eObject.eSet(eStructuralFeature, value);
                    } else {
                        eObject.eUnset(eStructuralFeature);
                    }
                    return;
                }
            }
        }
        System.out.println("AbstractSwitchyardComposite: Didn't find feature: " + featureId); //$NON-NLS-1$
        showFeatures(eObject);
        throw new Exception("AbstractSwitchyardComposite:Feature ID (" + featureId + ") not found."); //$NON-NLS-1$ //$NON-NLS-2$
    }

    private void showFeatures(EObject eObject) {
        EClass eClass = eObject.eClass();
        for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i) {
            EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);
            if (eStructuralFeature.isChangeable()) {
                System.out.println("AbstractSwitchyardComposite:Feature: " + eStructuralFeature.getName()); //$NON-NLS-1$
            }
        }
    }

    /**
     * @param eObject incoming object to retrieve
     * @param featureId feature to retrieve
     * @return object value
     */
    public Object getFeatureValue(EObject eObject, String featureId) {
        EClass eClass = eObject.eClass();
        for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i) {
            EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);
            if (eStructuralFeature.isChangeable()) {
                if (eStructuralFeature.getName().equalsIgnoreCase(featureId)) {
                    return eObject.eGet(eStructuralFeature);
                }
            }
        }
        System.out.println("AbstractSwitchyardComposite: Didn't find feature: " + featureId); //$NON-NLS-1$
        showFeatures(eObject);
        return null;
    }

    /**
     * Parse the list.
     * 
     * @param str_list string to parse
     * @param token token string
     * @return parsed string array
     */
    public String[] parseString(String str_list, String token) {
        StringTokenizer tk = new StringTokenizer(str_list, token);
        String[] pieces = new String[tk.countTokens()];
        int index = 0;
        while (tk.hasMoreTokens()) {
            pieces[index++] = tk.nextToken();
        }
        return pieces;
    }

    protected void handleUndo(Control control) {
    }

    protected TransactionalEditingDomain getDomain(EObject object) {
        if (object != null) {
            SwitchyardSCAEditor editor = SwitchyardSCAEditor.getEditor(object);
            return editor == null ? null : editor.getEditingDomain();
        }
        return null;
    }

    /**
     * @author bfitzpat
     */
    public class BasicEObjectOperation extends ModelOperation {

        private EObject _localObject;
        private String _localFeature;
        private Object _localValue;

        /**
         * @param object incoming object
         * @param featureId feature id
         * @param value incoming value
         */
        public BasicEObjectOperation(EObject object, String featureId, Object value) {
            _localObject = object;
            _localFeature = featureId;
            _localValue = value;
        }

        @Override
        public void run() throws Exception {
            try {
                if (_localValue instanceof String && ((String) _localValue).length() == 0) {
                    setFeatureValue(_localObject, _localFeature, null);
                } else {
                    setFeatureValue(_localObject, _localFeature, _localValue);
                }
            } catch (Exception e) {
                throw e;
            }
        }
    }

    protected void wrapOperation(final EObject eobject, final List<ModelOperation> ops) {
        TransactionalEditingDomain domain = getDomain(eobject);
        if (domain != null) {
            domain.getCommandStack().execute(new RecordingCommand(domain) {
                @Override
                protected void doExecute() {
                    Iterator<ModelOperation> execOps = ops.iterator();
                    while (execOps.hasNext()) {
                        try {
                            execOps.next().run();
                        } catch (Exception e) {
                            Activator.logError(e);
                            break;
                        }
                    }
                }
            });
        } else {
            Iterator<ModelOperation> execOps = ops.iterator();
            while (execOps.hasNext()) {
                try {
                    execOps.next().run();
                } catch (Exception e) {
                    Activator.logError(e);
                    break;
                }
            }
        }
    }

    protected void updateFeature(EObject eObject, String featureId, Object value) {
        ArrayList<ModelOperation> ops = new ArrayList<ModelOperation>();
        ops.add(new BasicEObjectOperation(eObject, featureId, value));
        wrapOperation(eObject, ops);
    }

    protected void addGridData(Control control, int columns, int style) {
        GridData controlGD = new GridData(style);
        controlGD.horizontalSpan = columns;
        control.setLayoutData(controlGD);
    }
}