/*******************************************************************************
* Copyright (c) 2011 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
******************************************************************************/
package org.eclipse.bpmn2.modeler.ui.property;
import java.util.ArrayList;
import org.eclipse.bpmn2.di.provider.BpmnDiItemProviderAdapterFactory;
import org.eclipse.bpmn2.modeler.ui.Activator;
import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor;
import org.eclipse.bpmn2.provider.Bpmn2ItemProviderAdapterFactory;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.dd.dc.provider.DcItemProviderAdapterFactory;
import org.eclipse.dd.di.provider.DiItemProviderAdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.widgets.FormToolkit;
public abstract class AbstractBpmn2PropertiesComposite extends Composite {
public final static ComposedAdapterFactory ADAPTER_FACTORY;
protected EObject be;
protected BPMN2Editor bpmn2Editor;
protected final DataBindingContext bindingContext;
protected final ArrayList<Widget> widgets = new ArrayList<Widget>();
protected final ArrayList<Binding> bindings = new ArrayList<Binding>();
protected final Composite parent;
protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
protected IProject project;
private Text text_1;
static {
ADAPTER_FACTORY = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
ADAPTER_FACTORY.addAdapterFactory(new ResourceItemProviderAdapterFactory());
ADAPTER_FACTORY.addAdapterFactory(new Bpmn2ItemProviderAdapterFactory());
ADAPTER_FACTORY.addAdapterFactory(new BpmnDiItemProviderAdapterFactory());
ADAPTER_FACTORY.addAdapterFactory(new DiItemProviderAdapterFactory());
ADAPTER_FACTORY.addAdapterFactory(new DcItemProviderAdapterFactory());
ADAPTER_FACTORY.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
}
/**
* NB! Must call setEObject for updating contents and rebuild the UI.
*
* @param parent
* @param style
*/
public AbstractBpmn2PropertiesComposite(Composite parent, int style) {
super(parent, style);
this.parent = parent;
bindingContext = new DataBindingContext();
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
toolkit.dispose();
}
});
toolkit.adapt(this);
toolkit.paintBordersFor(this);
setLayout(new GridLayout(3, false));
}
public final void setEObject(BPMN2Editor bpmn2Editor, final EObject be) {
String projectName = bpmn2Editor.getDiagramTypeProvider().getDiagram().eResource().getURI().segment(1);
project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
setDiagramEditor(bpmn2Editor);
setEObject(be);
}
private final void setDiagramEditor(BPMN2Editor bpmn2Editor) {
this.bpmn2Editor = bpmn2Editor;
}
private final void setEObject(final EObject be) {
this.be = be;
cleanBindings();
if (be != null) {
createBindings();
}
layout(true, true);
}
/**
* This method is called when setEObject is called and this should recreate all bindings and widgets for the
* component.
*/
public abstract void createBindings();
protected Text createTextInput(String name, boolean multiLine) {
createLabel(name);
int flag = SWT.BORDER;
if (multiLine) {
flag |= SWT.BORDER | SWT.WRAP | SWT.MULTI;
}
Text text = new Text(this, flag);
GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
if (multiLine) {
data.heightHint = 50;
}
text.setLayoutData(data);
toolkit.adapt(text, true, true);
widgets.add(text);
return text;
}
protected Text createIntInput(String name) {
createLabel(name);
Text text = new Text(this, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
toolkit.adapt(text, true, true);
widgets.add(text);
return text;
}
protected Button createBooleanInput(String name) {
createLabel(name);
Button button = new Button(this, SWT.CHECK);
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
toolkit.adapt(button, true, true);
widgets.add(button);
return button;
}
protected void createLabel(String name) {
Label label = new Label(this, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
toolkit.adapt(label, true, true);
label.setText(name);
widgets.add(label);
}
protected void bind(final EStructuralFeature a, final Text text) {
Object eGet = be.eGet(a);
if (eGet != null) {
text.setText(eGet.toString());
}
IObservableValue textObserver = SWTObservables.observeText(text, SWT.Modify);
textObserver.addValueChangeListener(new IValueChangeListener() {
@SuppressWarnings("restriction")
@Override
public void handleValueChange(final ValueChangeEvent e) {
if (!text.getText().equals(be.eGet(a))) {
TransactionalEditingDomain editingDomain = bpmn2Editor.getEditingDomain();
editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain) {
@Override
protected void doExecute() {
be.eSet(a, e.diff.getNewValue());
}
});
if (bpmn2Editor.getDiagnostics()!=null) {
// revert the change and display error status message.
text.setText((String) be.eGet(a));
bpmn2Editor.showErrorMessage(bpmn2Editor.getDiagnostics().getMessage());
}
else
bpmn2Editor.showErrorMessage(null);
}
}
});
text.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
bpmn2Editor.showErrorMessage(null);
}
});
}
protected void bindBoolean(final EStructuralFeature a, final Button button) {
bindBoolean(a, button, be);
}
protected void bindBoolean(final EStructuralFeature a, final Button button, final EObject object) {
button.setSelection((Boolean) object.eGet(a));
IObservableValue buttonObserver = SWTObservables.observeSelection(button);
buttonObserver.addValueChangeListener(new IValueChangeListener() {
@SuppressWarnings("restriction")
@Override
public void handleValueChange(ValueChangeEvent event) {
if (!object.eGet(a).equals(button.getSelection())) {
TransactionalEditingDomain editingDomain = bpmn2Editor.getEditingDomain();
editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain) {
@Override
protected void doExecute() {
object.eSet(a, button.getSelection());
}
});
if (bpmn2Editor.getDiagnostics()!=null) {
// revert the change and display error status message.
button.setSelection((Boolean) be.eGet(a));
bpmn2Editor.showErrorMessage(bpmn2Editor.getDiagnostics().getMessage());
}
else
bpmn2Editor.showErrorMessage(null);
}
}
});
button.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
bpmn2Editor.showErrorMessage(null);
}
});
}
protected void bindInt(final EStructuralFeature a, final Text text) {
text.addVerifyListener(new VerifyListener() {
/**
* taken from
* http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets
* /Snippet19.java?view=co
*/
@Override
public void verifyText(VerifyEvent e) {
String string = e.text;
char[] chars = new char[string.length()];
string.getChars(0, chars.length, chars, 0);
for (int i = 0; i < chars.length; i++) {
if (!('0' <= chars[i] && chars[i] <= '9')) {
e.doit = false;
return;
}
}
}
});
Object eGet = be.eGet(a);
if (eGet != null) {
text.setText(eGet.toString());
}
IObservableValue textObserveTextObserveWidget = SWTObservables.observeText(text, SWT.Modify);
textObserveTextObserveWidget.addValueChangeListener(new IValueChangeListener() {
@Override
public void handleValueChange(ValueChangeEvent event) {
try {
final int i = Integer.parseInt(text.getText());
if (!be.eGet(a).equals(i)) {
setFeatureValue(i);
}
} catch (NumberFormatException e) {
text.setText((String) be.eGet(a));
Activator.logError(e);
}
}
@SuppressWarnings("restriction")
private void setFeatureValue(final int i) {
RecordingCommand command = new RecordingCommand(bpmn2Editor.getEditingDomain()) {
@Override
protected void doExecute() {
be.eSet(a, i);
}
};
bpmn2Editor.getEditingDomain().getCommandStack().execute(command);
if (bpmn2Editor.getDiagnostics()!=null) {
// revert the change and display error status message.
text.setText((String) be.eGet(a));
bpmn2Editor.showErrorMessage(bpmn2Editor.getDiagnostics().getMessage());
}
else
bpmn2Editor.showErrorMessage(null);
}
});
text.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
bpmn2Editor.showErrorMessage(null);
}
});
}
protected void cleanBindings() {
for (Binding b : bindings) {
b.dispose();
}
bindings.clear();
for (Widget w : widgets) {
w.dispose();
}
widgets.clear();
}
}