/******************************************************************************* * Copyright (c) 2010 protos software gmbh (http://www.protos.de). * 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: * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution) * *******************************************************************************/ package org.eclipse.etrice.ui.common.dialogs; import java.util.HashMap; import java.util.List; import org.eclipse.core.databinding.AggregateValidationStatus; import org.eclipse.core.databinding.Binding; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.beans.PojoObservables; import org.eclipse.core.databinding.conversion.Converter; import org.eclipse.core.databinding.conversion.IConverter; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.validation.IValidator; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.jface.databinding.swt.ISWTObservable; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.FormDialog; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; public abstract class AbstractPropertyDialog extends FormDialog { static class Reference2StringConverter extends Converter { private EAttribute nameAttr; Reference2StringConverter(Object type, EAttribute nameAttr) { super(type, String.class); this.nameAttr = nameAttr; } @Override public Object convert(Object fromObject) { return ((EObject)fromObject).eGet(nameAttr); } } static class String2ReferenceConverter extends Converter { private List<? extends EObject> candidates; private EAttribute nameAttr; String2ReferenceConverter(Object type, List<? extends EObject> candidates, EAttribute nameAttr) { super(String.class, type); this.candidates = candidates; this.nameAttr = nameAttr; } @Override public Object convert(Object fromObject) { for (EObject obj : candidates) { if (obj.eGet(nameAttr).equals(fromObject)) return obj; } return null; } } private String title; private FormToolkit toolkit; private DataBindingContext bindingContext; private HashMap<Control, ControlDecoration> decoratorMap = new HashMap<Control, ControlDecoration>(); public AbstractPropertyDialog(Shell shell, String title) { super(shell); this.title = title; } abstract protected Image getImage(); @Override protected void createFormContent(IManagedForm mform) { toolkit = mform.getToolkit(); bindingContext = new DataBindingContext(); Form form = mform.getForm().getForm(); form.setText(title); form.setImage(getImage()); mform.getToolkit().decorateFormHeading(form); Composite body = form.getBody(); body.setLayout(new GridLayout(2, false)); body.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); toolkit.createLabel(body, "", SWT.NONE) .setText("Validation Status:"); Label validationErrorLabel = toolkit.createLabel( body, "", SWT.NONE); validationErrorLabel .setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); createContent(mform, body, bindingContext); AggregateValidationStatus aggregateValidationStatus = new AggregateValidationStatus( bindingContext.getBindings(), AggregateValidationStatus.MAX_SEVERITY); aggregateValidationStatus.addChangeListener(new IChangeListener() { public void handleChange(ChangeEvent event) { boolean ok = true; for (Object o : bindingContext.getBindings()) { Binding binding = (Binding) o; IStatus status = (IStatus) binding.getValidationStatus() .getValue(); Control control = null; if (binding.getTarget() instanceof ISWTObservable) { ISWTObservable swtObservable = (ISWTObservable) binding .getTarget(); control = (Control) swtObservable.getWidget(); } ControlDecoration decoration = decoratorMap.get(control); if (decoration != null) { if (status.isOK()) { decoration.hide(); } else { ok = false; decoration.setDescriptionText(status.getMessage()); decoration.show(); } } } Button okButton = getButton(IDialogConstants.OK_ID); if (okButton!=null) okButton.setEnabled(ok); } }); bindingContext.bindValue(SWTObservables .observeText(validationErrorLabel), aggregateValidationStatus, null, null); } protected abstract void createContent(IManagedForm mform, Composite body, DataBindingContext bindingContext); protected Text createText(Composite parent, String label, EObject obj, EAttribute att) { return createText(parent, label, obj, att, null); } protected Text createText(Composite parent, String label, EObject obj, EAttribute att, IValidator validator) { return createText(parent, label, obj, att, validator, false); } protected Text createText(Composite parent, String label, EObject obj, EAttribute att, IValidator validator, boolean multiline) { return createText(parent, label, obj, att, validator, null, null, multiline); } protected Text createText(Composite parent, String label, EObject obj, EStructuralFeature feat, IValidator validator, IConverter s2m, IConverter m2s, boolean multiline) { Label l = toolkit.createLabel(parent, label, SWT.NONE); l.setLayoutData(new GridData(SWT.NONE)); int style = SWT.BORDER; if (multiline) style |= SWT.MULTI; Text text = toolkit.createText(parent, "", style); text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); UpdateValueStrategy t2m = null; UpdateValueStrategy m2t = null; if (validator!=null || s2m!=null || m2s!=null) { t2m = new UpdateValueStrategy(); if (s2m!=null) t2m.setConverter(s2m); if (validator!=null) { t2m.setAfterConvertValidator(validator); t2m.setBeforeSetValidator(validator); } m2t = new UpdateValueStrategy(); if (m2s!=null) m2t.setConverter(m2s); if (validator!=null) { m2t.setAfterConvertValidator(validator); m2t.setBeforeSetValidator(validator); } } bindingContext.bindValue(SWTObservables.observeText(text, SWT.Modify), PojoObservables.observeValue( obj, feat.getName()), t2m, m2t); return text; } protected Button createCheck(Composite parent, String label, EObject obj, EAttribute att) { return createCheck(parent, label, obj, att, null); } protected Button createCheck(Composite parent, String label, EObject obj, EAttribute att, IValidator validator) { Label l = toolkit.createLabel(parent, label, SWT.NONE); l.setLayoutData(new GridData(SWT.NONE)); Button check = toolkit.createButton(parent, "", SWT.CHECK); check.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); UpdateValueStrategy t2m = null; UpdateValueStrategy m2t = null; if (validator!=null) { t2m = new UpdateValueStrategy(); t2m.setAfterConvertValidator(validator); t2m.setBeforeSetValidator(validator); m2t = new UpdateValueStrategy(); m2t.setAfterConvertValidator(validator); m2t.setBeforeSetValidator(validator); } bindingContext.bindValue(SWTObservables.observeSelection(check), PojoObservables.observeValue( obj, att.getName()), t2m, m2t); return check; } protected Combo createCombo(Composite parent, String label, EObject obj, Object type, EReference ref, List<? extends EObject> candidates, EAttribute nameAttr) { return createCombo(parent, label, obj, type, ref, candidates, nameAttr, null); } protected Combo createCombo(Composite parent, String label, EObject obj, Object type, EReference ref, List<? extends EObject> candidates, EAttribute nameAttr, IValidator validator) { Label l = toolkit.createLabel(parent, label, SWT.NONE); l.setLayoutData(new GridData(SWT.NONE)); Combo combo = new Combo(parent, SWT.READ_ONLY); combo.setLayoutData(new GridData(SWT.HORIZONTAL)); combo.setVisibleItemCount(10); toolkit.adapt(combo, true, true); Reference2StringConverter r2s = new Reference2StringConverter(type, nameAttr); for (EObject o : candidates) { combo.add((String) r2s.convert(o)); } String2ReferenceConverter s2r = new String2ReferenceConverter(type, candidates, nameAttr); UpdateValueStrategy t2m = new UpdateValueStrategy().setConverter(s2r); UpdateValueStrategy m2t = new UpdateValueStrategy().setConverter(r2s); if (validator!=null) { t2m.setAfterConvertValidator(validator); t2m.setBeforeSetValidator(validator); m2t.setAfterConvertValidator(validator); m2t.setBeforeSetValidator(validator); } bindingContext.bindValue(SWTObservables.observeText(combo), PojoObservables.observeValue(obj, ref.getName()), t2m, m2t); return combo; } protected ControlDecoration createDecorator(Control ctrl, String message) { ControlDecoration controlDecoration = new ControlDecoration(ctrl, SWT.LEFT | SWT.TOP); controlDecoration.setDescriptionText(message); FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration( FieldDecorationRegistry.DEC_ERROR); controlDecoration.setImage(fieldDecoration.getImage()); controlDecoration.hide(); decoratorMap.put(ctrl, controlDecoration); return controlDecoration; } protected DataBindingContext getBindingContext() { return bindingContext; } }