blob: 89870dd593f80a7ab7b2731093bf3d3e6a51a6e6 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateListStrategy;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.internal.databinding.BindingStatus;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.osbp.ecview.core.common.context.ILocaleChangedService;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeChangeEvent;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelFactory;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YBlurNotifier;
import org.eclipse.osbp.ecview.core.common.model.core.YContextClickEvent;
import org.eclipse.osbp.ecview.core.common.model.core.YEditable;
import org.eclipse.osbp.ecview.core.common.model.core.YElement;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableEvent;
import org.eclipse.osbp.ecview.core.common.model.core.YEnable;
import org.eclipse.osbp.ecview.core.common.model.core.YFocusNotifier;
import org.eclipse.osbp.ecview.core.common.model.core.YFocusable;
import org.eclipse.osbp.ecview.core.common.model.core.YVisibleable;
import org.eclipse.osbp.ecview.core.common.model.core.util.CoreModelUtil;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatatype;
import org.eclipse.osbp.ecview.core.common.model.visibility.YColor;
import org.eclipse.osbp.ecview.core.common.model.visibility.YVisibilityProperties;
import org.eclipse.osbp.ecview.core.common.notification.ILifecycleEvent;
import org.eclipse.osbp.ecview.core.common.notification.ILifecycleService;
import org.eclipse.osbp.ecview.core.common.notification.LifecycleEvent;
import org.eclipse.osbp.ecview.core.common.presentation.IInitializerService;
import org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation;
import org.eclipse.osbp.ecview.core.common.services.IWidgetAssocationsService;
import org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler;
import org.eclipse.osbp.ecview.core.databinding.emf.common.ECViewUpdateValueStrategy;
import org.eclipse.osbp.runtime.common.dispose.AbstractDisposable;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
import org.eclipse.osbp.runtime.designer.api.IDesignerService;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.DesignEvent;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.EventType;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.IDesignListener;
import org.eclipse.osbp.runtime.designer.api.IWidgetDesignConfigurator;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IBindingManager;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinProperties;
import org.eclipse.osbp.runtime.web.vaadin.databinding.values.IVaadinObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.data.Container;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeNotifier;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.event.ContextClickEvent.ContextClickNotifier;
import com.vaadin.event.FieldEvents.BlurNotifier;
import com.vaadin.event.FieldEvents.FocusNotifier;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.AbstractSelect;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Component.Focusable;
import com.vaadin.ui.Field;
import com.vaadin.ui.Slider;
import fi.jasoft.dragdroplayouts.client.ui.LayoutDragMode;
// TODO: Auto-generated Javadoc
/**
* An abstract implementation of the {@link IWidgetPresentation}.
*
* @param <A>
* the generic type
*/
@SuppressWarnings({ "restriction", "rawtypes" })
public abstract class AbstractVaadinWidgetPresenter<A extends Component> extends AbstractDisposable
implements IWidgetPresentation<A>, ILocaleChangedService.LocaleListener {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractVaadinWidgetPresenter.class);
/**
* See {@link IConstants#CSS_CLASS_CONTROL_BASE}.
*/
public static final String CSS_CLASS_CONTROL_BASE = IConstants.CSS_CLASS_CONTROL_BASE;
/**
* See {@link IConstants#CSS_CLASS_CONTROL}.
*/
public static final String CSS_CLASS_CONTROL = IConstants.CSS_CLASS_CONTROL;
/**
* See {@link IConstants#CSS_CLASS_COMPRESSOR}.
*/
public static final String CSS_CLASS_COMPRESSOR = IConstants.CSS_CLASS_COMPRESSOR;
/** The view context. */
private IViewContext viewContext;
/** The editpart. */
private final IEmbeddableEditpart editpart;
/** The binding manger. */
private IBindingManager bindingManger;
/** The bindings. */
private Set<Binding> bindings = new HashSet<Binding>();
/** The visibility options applier. */
private VisibilityOptionsApplier visibilityOptionsApplier;
private ILocaleChangedService localeChangedService;
private AbstractVaadinWidgetPresenter<A>.LabelAdapter labelAdapter;
private Component component;
/**
* Instantiates a new abstract vaadin widget presenter.
*
* @param editpart
* the editpart
*/
public AbstractVaadinWidgetPresenter(IEmbeddableEditpart editpart) {
this.editpart = editpart;
viewContext = editpart.getView().getContext();
}
/**
* Returns the editpart the presenter will render for.
*
* @return the editpart
*/
protected IEmbeddableEditpart getEditpart() {
return editpart;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* getModel()
*/
@Override
public Object getModel() {
return getEditpart().getModel();
}
/**
* Gets the casted model.
*
* @return the casted model
*/
protected YElement getCastedModel() {
return (YElement) getModel();
}
/**
* Returns the view context.
*
* @return viewContext
*/
public IViewContext getViewContext() {
return viewContext;
}
/**
* Returns the active locale for the view.
*
* @return the locale
*/
protected Locale getLocale() {
return viewContext.getLocale();
}
/**
* Returns the i18n service or <code>null</code> if no service is available.
*
* @return the i18n service
*/
protected II18nService getI18nService() {
return viewContext.getService(II18nService.ID);
}
/**
* Returns the IResourceProvider or <code>null</code> if no service is
* available.
*
* @return the resource provider
*/
protected IResourceProvider getResourceProvider() {
return viewContext.getService(IResourceProvider.class.getName());
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.ecview.core.common.context.ILocaleChangedService.
* LocaleListener#localeChanged(java.util.Locale)
*/
@Override
public void localeChanged(Locale locale) {
doUpdateLocale(locale);
}
/**
* Needs to be overridden by subclasses to update the locale.
*
* @param locale
* the locale
*/
protected abstract void doUpdateLocale(Locale locale);
protected void doSetStyle(String style) {
if (component != null && style != null) {
component.addStyleName(style);
}
}
protected void doUnSetStyle(String style) {
if (component != null && style != null) {
component.removeStyleName(style);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.ecview.core.common.editpart.visibility.
* IVisibilityProcessable
* #apply(org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler)
*/
@Override
public void apply(IVisibilityHandler handler) {
if (visibilityOptionsApplier == null) {
visibilityOptionsApplier = createVisibilityOptionsApplier();
}
visibilityOptionsApplier.apply(Util.mapYProperties(handler));
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* notifyDatatypeChanged
* (org.eclipse.osbp.ecview.core.common.editpart.datatypes
* .IDatatypeEditpart.DatatypeChangeEvent)
*/
@Override
public void notifyDatatypeChanged(DatatypeChangeEvent event) {
if (event.isUnsetEvent()) {
doApplyDatatype(null);
} else {
doApplyDatatype((YDatatype) event.getEditpart().getModel());
}
}
/**
* Do apply datatype.
*
* @param yDt
* the y dt
*/
protected void doApplyDatatype(YDatatype yDt) {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.ecview.core.common.editpart.visibility.
* IVisibilityProcessable#resetVisibilityProperties()
*/
@Override
public void resetVisibilityProperties() {
visibilityOptionsApplier.apply(null);
}
/**
* Creates a new instance of the visibility options applier.
*
* @return the visibility options applier
*/
protected VisibilityOptionsApplier createVisibilityOptionsApplier() {
return new VisibilityOptionsApplier(getWidget());
}
/**
* Is called to initialize the newly created component.
*
* @param component
* the component
* @param model
* the model
*/
protected void setupComponent(Component component, YElement model) {
this.component = component;
IInitializerService service = getViewContext().getService(IInitializerService.class.getName());
if (service != null) {
service.initialize(component, model);
}
if (this instanceof IDesignListener) {
IDesignerService designService = getDesignService();
if (designService != null) {
designService.addListener((IDesignListener) this);
IWidgetDesignConfigurator cService = getViewContext()
.getService(IWidgetDesignConfigurator.class.getName());
if (cService != null && getWidget() != null) {
cService.configure(getWidget(), (YEmbeddable) getModel(), designService.isDesignMode());
}
}
}
labelAdapter = new LabelAdapter();
model.eAdapters().add(labelAdapter);
}
/**
* Must be called by subclasses.
*
* @param event
* the event
*/
public void notify(DesignEvent event) {
configureForDesignMode(event);
}
/**
* Configure / deconfigure the widget for the design mode.
*
* @param event
* the event
*/
protected void configureForDesignMode(DesignEvent event) {
IWidgetDesignConfigurator service = getViewContext().getService(IWidgetDesignConfigurator.class.getName());
if (service != null && getWidget() != null) {
service.configure(getWidget(), (YEmbeddable) getModel(), event.getType() == EventType.ENABLED);
}
}
/**
* Creates the bindings from the ECView EMF model to the given UI element.
*
* @param yEmbeddable
* the y embeddable
* @param widget
* the widget
* @param container
* the container
*/
protected void createBindings(YEmbeddable yEmbeddable, AbstractComponent widget, AbstractComponent container) {
ensureBindingManager();
applyDefaults(yEmbeddable);
if (container != null) {
registerBinding(createBindingsVisiblility(yEmbeddable, container));
} else {
registerBinding(createBindingsVisiblility(yEmbeddable, widget));
}
if (yEmbeddable instanceof YEnable) {
registerBinding(createBindingsEnabled((YEnable) yEmbeddable, widget));
}
if (yEmbeddable instanceof YEditable) {
registerBinding(createBindingsEditable((YEditable) yEmbeddable, widget));
}
// createBindingsCaption(yEmbeddable, widget);
}
/**
* Creates the binding.
*
* @param target
* the target
* @param model
* the model
* @return Binding - the created binding
*/
protected Binding createBindings(IObservableValue target, IObservableValue model) {
ensureBindingManager();
return bindingManger.bindValue(target, model);
}
/**
* Creates the binding.
*
* @param target
* the target
* @param model
* the model
* @param targetToModel
* the target to model
* @param modelToTarget
* the model to target
* @return Binding - the created binding
*/
protected Binding createBindings(IObservableValue target, IObservableValue model, UpdateValueStrategy targetToModel,
UpdateValueStrategy modelToTarget) {
ensureBindingManager();
return bindingManger.bindValue(target, model, targetToModel, modelToTarget);
}
/**
* Creates the binding.
*
* @param target
* the target
* @param model
* the model
* @return Binding - the created binding
*/
protected Binding createBindings(IObservableList target, IObservableList model) {
ensureBindingManager();
return bindingManger.bindList(target, model);
}
/**
* Ensure binding manager.
*/
protected void ensureBindingManager() {
if (bindingManger == null) {
bindingManger = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
}
}
/**
* Binds the editable flag from the ecview model to the ui element.
*
* @param yEditable
* the y editable
* @param abstractComponent
* the abstract component
* @return Binding - the created binding
*/
protected Binding createBindingsEditable(YEditable yEditable, AbstractComponent abstractComponent) {
ensureBindingManager();
if (abstractComponent instanceof Property.ReadOnlyStatusChangeNotifier) {
return bindingManger.bindReadonly(yEditable, (Property.ReadOnlyStatusChangeNotifier) abstractComponent);
} else {
return bindingManger.bindReadonlyOneway(yEditable, abstractComponent);
}
}
/**
* Applies the defaults to the ecview model. Transient values will be
* configured properly.
*
* @param yEmbeddable
* the y embeddable
*/
protected void applyDefaults(YEmbeddable yEmbeddable) {
// initialize the transient values
//
CoreModelUtil.initTransientValues(yEmbeddable);
}
/**
* Binds the visible flag from the ecview model to the ui element.
*
* @param yVisibleable
* the y visibleable
* @param abstractComponent
* the abstract component
* @return Binding - the created binding
*/
protected Binding createBindingsVisiblility(YVisibleable yVisibleable, AbstractComponent abstractComponent) {
ensureBindingManager();
return bindingManger.bindVisible(yVisibleable, abstractComponent);
}
/**
* Binds the enabled flag from the ecview model to the ui element.
*
* @param yEnable
* the y enable
* @param abstractComponent
* the abstract component
* @return Binding - the created binding
*/
protected Binding createBindingsEnabled(YEnable yEnable, AbstractComponent abstractComponent) {
IBindingManager bindingManger = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
// bind enabled
return bindingManger.bindEnabled(yEnable, abstractComponent);
}
/**
* Creates a binding for the value attribute from the ECView-UI-model to the
* UI element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @return Binding - the created binding
*/
protected Binding createBindings_Value(EObject model, EStructuralFeature modelFeature, Field<?> field) {
return createBindingsValue(model, modelFeature, field, null, null);
}
/**
* Binds the value attribute from the ecview model to the ui element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param targetToModel
* the target to model
* @param modelToTarget
* the model to target
* @return Binding - the created binding
*/
protected Binding createBindingsValue(EObject model, EStructuralFeature modelFeature, Field<?> field,
UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinObservables.observeValue(field);
return bindingManager.bindValue(uiObservable, modelObservable, targetToModel, modelToTarget);
}
return null;
}
/**
* Binds the image attribute from the ecview model to the ui element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param targetToModel
* the target to model
* @param modelToTarget
* the model to target
* @return Binding - the created binding
*/
protected Binding createBindingsButtonImage(EObject model, EStructuralFeature modelFeature, Button field) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinObservables.observeIcon(field);
return bindingManager.bindValue(uiObservable, modelObservable,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
}
return null;
}
/**
* Creates the bindings by accessor.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param property
* the property
* @return the binding
*/
protected Binding createBindingsByAccessor(EObject model, EStructuralFeature modelFeature, Field<?> field,
String property) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinProperties.accessor(Slider.class, property).observe(field);
return bindingManager.bindValue(uiObservable, modelObservable,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
}
return null;
}
protected Binding createBindingsByAccessor(EObject model, EStructuralFeature modelFeature, Object field,
String property, UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinProperties.accessor(field.getClass(), property).observe(field);
return bindingManager.bindValue(uiObservable, modelObservable, targetToModel, modelToTarget);
}
return null;
}
/**
* Creates a binding for the value attribute from the ECView-UI-model to the
* UI element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @return Binding - the created binding
*/
protected Binding createBindingsButtonClick(EObject model, EStructuralFeature modelFeature, Button field) {
return createBindingsButtonClick(model, modelFeature, field, null, null);
}
/**
* Binds the value attribute from the ecview model to the ui element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param targetToModel
* the target to model
* @param modelToTarget
* the model to target
* @return Binding - the created binding
*/
protected Binding createBindingsButtonClick(EObject model, EStructuralFeature modelFeature, Button field,
UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinObservables.observeButtonClick(field);
return bindingManager.bindValue(uiObservable, modelObservable, targetToModel, modelToTarget);
}
return null;
}
/**
* Creates a binding for the value attribute from the ECView-UI-model to the
* UI element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @return Binding - the created binding
*/
protected Binding createBindings_Value(EObject model, EStructuralFeature modelFeature, ValueChangeNotifier field) {
return createBindingsValue(model, modelFeature, field, null, null);
}
/**
* Binds the value attribute from the ecview model to the ui element.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param targetToModel
* the target to model
* @param modelToTarget
* the model to target
* @return Binding - the created binding
*/
protected Binding createBindingsValue(EObject model, EStructuralFeature modelFeature, ValueChangeNotifier field,
UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinObservables.observeValue(field);
return bindingManager.bindValue(uiObservable, modelObservable, targetToModel, modelToTarget);
}
return null;
}
/**
* Binds the selection of the selectable to the ECView model. It uses an
* validator to detect problems setting a not allowed selection. In that
* case, the current selection of the UI-model is passed to the ECView model
* again.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param type
* the type of selected object
* @return Binding - the created binding
*/
protected Binding createBindingsSelection(EObject model, EStructuralFeature modelFeature,
final AbstractSelect field, Class<?> type) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature);
IObservableValue uiObservable = VaadinObservables.observeSingleSelection(field, type);
// create a modelToTarget update strategy with a validator
//
ECViewUpdateValueStrategy modelToTarget = new ECViewUpdateValueStrategy(
ECViewUpdateValueStrategy.POLICY_UPDATE);
modelToTarget.setBeforeSetValidator(new IValidator() {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public IStatus validate(Object value) {
if (value == null) {
return Status.OK_STATUS;
}
Object convertedValue = value;
if (!("".equals(value))) {
Converter converter = field.getConverter();
if (converter != null) {
try {
convertedValue = converter.convertToPresentation(value, converter.getPresentationType(),
getLocale());
} catch (ConversionException e) {
LOGGER.error("{}", e);
}
}
}
if (!field.containsId(convertedValue)) {
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
});
final Binding binding = bindingManager.bindValue(uiObservable, modelObservable, null, modelToTarget);
registerBinding(binding);
// now bind the validation state to an observable value. If the
// doSetValue is called, we check whether the set operation was
// successfully. Otherwise we send the target value back to the
// model.
Binding validationBinding = bindingManager.bindValue(binding.getValidationStatus(),
new AbstractObservableValue() {
@Override
public Object getValueType() {
return null;
}
@Override
protected Object doGetValue() {
return null;
}
@Override
protected void doSetValue(Object value) {
BindingStatus status = (BindingStatus) value;
if (status.getSeverity() == BindingStatus.CANCEL) {
binding.updateTargetToModel();
}
}
});
registerBinding(validationBinding);
return binding;
}
return null;
}
/**
* Binds the multi selection of the selectable to the ECView model. It uses
* an validator to detect problems setting a not allowed selection. In that
* case, the current selection of the UI-model is passed to the ECView model
* again.
*
* @param model
* the model
* @param modelFeature
* the model feature
* @param field
* the field
* @param collectionType
* the type contained in the selection result
* @return Binding - the created binding
*/
protected Binding createBindingsMultiSelection(EObject model, EStructuralFeature modelFeature,
final AbstractSelect field, Class<?> collectionType) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableList modelObservable = EMFProperties.list(modelFeature).observe(getModel());
IVaadinObservableList uiObservable = VaadinObservables.observeMultiSelectionAsList(field, collectionType);
final Binding binding = bindingManager.bindList(uiObservable, modelObservable, null, null);
registerBinding(binding);
return binding;
}
return null;
}
/**
* Creates a binding for the contents of the vaadin container from the
* ECView-UI-model to the UI element.
*
* @param model
* the ECView model
* @param modelFeature
* the eFeature of the model
* @param field
* the ui field
* @param collectionType
* the type of the collection contents
* @return Binding - the created binding
*/
protected Binding createBindings_ContainerContents(EObject model, EStructuralFeature modelFeature,
Container.ItemSetChangeNotifier field, Class<?> collectionType) {
return createBindingsContainerContents(model, modelFeature, field, collectionType, null, null);
}
/**
* Creates a binding for the contents of the vaadin container from the
* ECView-UI-model to the UI element.
*
* @param model
* the ECView model
* @param modelFeature
* the eFeature of the model
* @param field
* the ui field
* @param collectionType
* the type of the collection contents
* @param targetToModel
* the update strategy
* @param modelToTarget
* the update strategy
* @return Binding - the created binding
*/
protected Binding createBindingsContainerContents(EObject model, EStructuralFeature modelFeature,
Container.ItemSetChangeNotifier field, Class<?> collectionType, UpdateListStrategy targetToModel,
UpdateListStrategy modelToTarget) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableList modelObservable = EMFProperties.list(modelFeature).observe(getModel());
IObservableList uiObservable = VaadinObservables.observeContainerItemSetContents(field, collectionType);
return bindingManager.bindList(uiObservable, modelObservable, targetToModel, modelToTarget);
}
return null;
}
protected Binding createBindingsContainerContents(EObject model, EStructuralFeature modelFeature,
Container.ItemSetChangeNotifier field, Class<?> collectionType, boolean containerReadonly) {
IBindingManager bindingManager = getViewContext()
.getService(org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName());
if (bindingManager != null) {
// bind the value of yText to textRidget
IObservableList modelObservable = EMFProperties.list(modelFeature).observe(getModel());
IObservableList uiObservable = VaadinObservables.observeContainerItemSetContents(field, collectionType);
if (containerReadonly) {
return bindingManager.bindList(uiObservable, modelObservable,
new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE),
new UpdateListStrategy(UpdateListStrategy.POLICY_NEVER));
} else {
return bindingManager.bindList(uiObservable, modelObservable,
new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE),
new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE));
}
}
return null;
}
// /**
// * Binds the caption attribute from the ecview model to the ui element.
// *
// * @param model
// * the model
// * @param comp
// * the component
// * @param targetToModel
// * the target to model
// * @param modelToTarget
// * the model to target
// * @return Binding - the created binding
// */
// protected Binding createBindingsCaption(EObject model, Component comp) {
// IBindingManager bindingManager = getViewContext()
// .getService(
// org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class
// .getName());
// if (bindingManager != null) {
// // bind the caption
// IObservableValue modelObservable = EMFObservables.observeValue(
// model, CoreModelPackage.Literals.YEMBEDDABLE__LABEL);
// IObservableValue uiObservable = VaadinObservables
// .observeCaption(comp);
// return bindingManager.bindValue(uiObservable, modelObservable);
// }
// return null;
// }
/**
* Registers the given binding to be managed by the presenter. If the widget
* becomes disposed or unrendered, all the bindings will become disposed.
*
* @param binding
* the binding
*/
protected void registerBinding(Binding binding) {
bindings.add(binding);
}
/**
* Disposes the given binding and removes it from the bindings collection.
*
* @param binding
* the binding
*/
protected void unregisterBinding(Binding binding) {
bindings.remove(binding);
if (!binding.isDisposed()) {
binding.dispose();
}
}
/**
* Unbinds all currently active bindings.
*/
protected void unbind() {
for (Binding binding : bindings) {
binding.dispose();
}
bindings.clear();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* getObservableValue(java.lang.Object)
*/
@Override
public IObservable getObservableValue(Object model) {
return internalGetObservableEndpoint((YEmbeddableBindingEndpoint) model);
}
/**
* Has to provide an instance of IObservable for the given bindableValue.
*
* @param bindableValue
* the bindable value
* @return the i observable
*/
protected IObservable internalGetObservableEndpoint(YEmbeddableBindingEndpoint bindableValue) {
throw new UnsupportedOperationException("Must be overridden!");
}
/**
* Cast e object.
*
* @param model
* the model
* @return the e object
*/
protected EObject castEObject(Object model) {
return (EObject) model;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.common.dispose.AbstractDisposable#
* internalDispose ()
*/
@Override
protected void internalDispose() {
unregisterFromLocaleChangedService();
component = null;
}
/**
* Does general initialization of the widget.
*
* @param component
* the component
* @param model
* the model
*/
protected void initialize(Component component, YElement model) {
// initialize the tab index
if (component instanceof Focusable && model instanceof YFocusable) {
YFocusable yFocusable = (YFocusable) model;
Focusable focusable = (Focusable) component;
if (yFocusable.getTabIndex() >= 0) {
focusable.setTabIndex(yFocusable.getTabIndex());
}
}
if (component instanceof FocusNotifier && model instanceof YFocusNotifier) {
((FocusNotifier) component).addFocusListener(e -> {
YEmbeddableEvent event = CoreModelFactory.eINSTANCE.createYEmbeddableEvent();
event.setTime(new Date());
event.setEmbeddable((YEmbeddable) getModel());
event.setRawEvent(e);
((YFocusNotifier) model).setLastFocusEvent(event);
});
}
if (component instanceof BlurNotifier && model instanceof YBlurNotifier) {
((BlurNotifier) component).addBlurListener(e -> {
YEmbeddableEvent event = CoreModelFactory.eINSTANCE.createYEmbeddableEvent();
event.setTime(new Date());
event.setEmbeddable((YEmbeddable) getModel());
event.setRawEvent(e);
((YBlurNotifier) model).setLastBlurEvent(event);
});
}
if (component instanceof ContextClickNotifier && model instanceof YEmbeddable) {
((ContextClickNotifier) component).addContextClickListener(e -> {
YContextClickEvent event = CoreModelFactory.eINSTANCE.createYContextClickEvent();
event.setTime(new Date());
event.setEmbeddable((YEmbeddable) getModel());
event.setRawEvent(e);
((YEmbeddable) model).setLastContextClick(event);
});
}
}
/**
* Uses the {@link IWidgetAssocationsService} to register the widget.
*
* @param component
* the component
* @param yElement
* the y element
*/
protected void associateWidget(Component component, EObject yElement) {
IWidgetAssocationsService<Component, EObject> service = getViewContext()
.getService(IWidgetAssocationsService.ID);
service.associate(component, yElement);
}
/**
* Uses the {@link IWidgetAssocationsService} to unregister the widget.
*
* @param component
* the component
*/
protected void unassociateWidget(Component component) {
IWidgetAssocationsService<Component, EObject> service = getViewContext()
.getService(IWidgetAssocationsService.ID);
service.remove(component);
}
/**
* Locale change events are catched by that class.
*/
protected void registerAtLocaleChangedService() {
localeChangedService = getViewContext().getService(ILocaleChangedService.ID);
localeChangedService.addLocaleListener(this);
}
/**
* Locale change events are not catched by that class.
*/
protected void unregisterFromLocaleChangedService() {
if (localeChangedService != null) {
localeChangedService.removeLocaleListener(this);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.common.dispose.AbstractDisposable#
* notifyDisposeListeners()
*/
@Override
protected void notifyDisposeListeners() {
super.notifyDisposeListeners();
sendDisposedLifecycleEvent();
}
/**
* Send a dispose lifecycle event to all registered listeners.
*/
protected void sendDisposedLifecycleEvent() {
ILifecycleService service = getViewContext().getService(ILifecycleService.class.getName());
if (service != null) {
service.notifyLifecycle(new LifecycleEvent(getEditpart(), ILifecycleEvent.TYPE_DISPOSED));
}
}
/**
* Send a rendered lifecycle event to all registered listeners.
*/
protected void sendRenderedLifecycleEvent() {
ILifecycleService service = getViewContext().getService(ILifecycleService.class.getName());
if (service != null) {
service.notifyLifecycle(new LifecycleEvent(getEditpart(), ILifecycleEvent.TYPE_RENDERED));
}
}
/**
* Send a rendered lifecycle event to all registered listeners.
*/
protected void sendUnrenderedLifecycleEvent() {
ILifecycleService service = getViewContext().getService(ILifecycleService.class.getName());
if (service != null) {
service.notifyLifecycle(new LifecycleEvent(getEditpart(), ILifecycleEvent.TYPE_UNRENDERED));
}
}
// /**
// * Reports the validation error to the IFieldValidationManager.
// *
// * @param message
// */
// protected void reportValidationError(ErrorMessage message) {
// IFieldValidationManager service = getViewContext().getService(
// IFieldValidationManager.class.getName());
// if (service != null) {
// service.registerResult(getModel(),
// Util.createStatus((YEmbeddable) getModel(), message));
// }
// }
/**
* For testing purposes.
*
* @return the UI bindings
*/
@Override
public Set<Binding> getUIBindings() {
return bindings;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* createWidget(java.lang.Object)
*/
@Override
public A createWidget(Object parent) {
A result = doCreateWidget(parent);
registerAtLocaleChangedService();
return result;
}
/**
* Returns the design service or <code>null</code> if no design service is
* available.
*
* @return the design service
*/
protected IDesignerService getDesignService() {
return viewContext.getService(IDesignerService.class.getName());
}
/**
* Returns the design service or <code>null</code> if no design service is
* available.
*
* @return the drag mode
*/
protected LayoutDragMode getDragMode() {
IDesignerService service = getDesignService();
if (service == null) {
return LayoutDragMode.NONE;
}
return service.isDesignMode() ? LayoutDragMode.CLONE : LayoutDragMode.NONE;
}
/**
* Needs to be implemented by subclasses to render the widget.
*
* @param parent
* - The parent ui component
* @return the a
*/
protected abstract A doCreateWidget(Object parent);
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* unrender()
*/
@Override
public void unrender() {
unregisterFromLocaleChangedService();
if (this instanceof IDesignListener) {
IDesignerService designService = getDesignService();
if (designService != null) {
designService.removeListener((IDesignListener) this);
}
IWidgetDesignConfigurator service = getViewContext().getService(IWidgetDesignConfigurator.class.getName());
if (service != null && getWidget() != null) {
service.configure(getWidget(), (YEmbeddable) getModel(), false);
}
}
if (labelAdapter != null) {
getCastedModel().eAdapters().remove(labelAdapter);
labelAdapter = null;
}
doUnrender();
}
/**
* Needs to be implemented by subclasses to unrender the widget.
*/
protected abstract void doUnrender();
/**
* Applies the visibility options to the component.
*/
protected class VisibilityOptionsApplier {
/** The component. */
protected final Component component;
/**
* Instantiates a new visibility options applier.
*
* @param component
* the component
*/
public VisibilityOptionsApplier(Component component) {
this.component = component;
}
/**
* Reset stylenames.
*/
public void resetStylenames() {
component.removeStyleName("l-strikethrough");
component.removeStyleName("l-border");
component.removeStyleName("l-bold");
component.removeStyleName("l-italic");
component.removeStyleName("l-underline");
component.removeStyleName("l-foreground-red");
component.removeStyleName("l-foreground-white");
component.removeStyleName("l-foreground-blue");
component.removeStyleName("l-foreground-green");
component.removeStyleName("l-foreground-black");
component.removeStyleName("l-foreground-yellow");
component.removeStyleName("l-foreground-gray");
component.removeStyleName("l-foreground-light-gray");
component.removeStyleName("l-foreground-dark-gray");
component.removeStyleName("l-background-red");
component.removeStyleName("l-background-white");
component.removeStyleName("l-background-blue");
component.removeStyleName("l-background-green");
component.removeStyleName("l-background-black");
component.removeStyleName("l-background-yellow");
component.removeStyleName("l-background-gray");
component.removeStyleName("l-background-light-gray");
component.removeStyleName("l-background-dark-gray");
}
/**
* Applies the visibility options to the component. Passing
* <code>null</code> as argument means a reset to default values.
*
* @param yProps
* the y props
*/
public void apply(YVisibilityProperties yProps) {
resetStylenames();
applyVisible(yProps);
applyEnabled(yProps);
applyReadOnly(yProps);
applyStrikeThrough(yProps);
applyBorder(yProps);
applyItalic(yProps);
applyUnderline(yProps);
applyForegroundColor(yProps);
applyBackgroundColor(yProps);
}
/**
* Apply css class.
*
* @param yProps
* the y props
*/
public void applyCssClass(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
String yCssClass = yProps.getCssClass();
if (yCssClass != null) {
component.addStyleName(yCssClass);
}
}
/**
* Apply css id.
*
* @param yProps
* the y props
*/
public void applyCssId(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
String yCssId = yProps.getCssId();
if (yCssId != null) {
component.setId(yCssId);
}
}
/**
* Apply underline.
*
* @param yProps
* the y props
*/
public void applyUnderline(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
if (yProps.isUnderline()) {
component.addStyleName("l-underline");
}
}
/**
* Apply italic.
*
* @param yProps
* the y props
*/
public void applyItalic(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
if (yProps.isItalic()) {
component.addStyleName("l-italic");
}
}
/**
* Apply border.
*
* @param yProps
* the y props
*/
public void applyBorder(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
if (yProps.isBorder()) {
component.addStyleName("l-border");
}
}
/**
* Apply strike through.
*
* @param yProps
* the y props
*/
public void applyStrikeThrough(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
if (yProps.isStrikethrough()) {
component.addStyleName("l-strikethrough");
}
}
/**
* Apply read only.
*
* @param yProps
* the y props
*/
public void applyReadOnly(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
YElement model = getCastedModel();
if (model instanceof YEditable) {
YEditable yEditable = (YEditable) model;
yEditable.setEditable(yProps.isEditable());
}
}
/**
* Apply enabled.
*
* @param yProps
* the y props
*/
public void applyEnabled(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
YElement model = getCastedModel();
if (model instanceof YEnable) {
YEnable yEnable = (YEnable) model;
yEnable.setEnabled(yProps.isEnabled());
}
}
/**
* Apply visible.
*
* @param yProps
* the y props
*/
public void applyVisible(YVisibilityProperties yProps) {
if (yProps == null) {
return;
}
YElement model = getCastedModel();
if (model instanceof YVisibleable) {
YVisibleable yVisibleable = (YVisibleable) model;
yVisibleable.setVisible(yProps.isVisible());
}
}
/**
* Apply foreground color.
*
* @param yProps
* the y props
*/
public void applyForegroundColor(YVisibilityProperties yProps) {
YColor yColor = yProps.getForegroundColor();
if (yColor != null) {
component.addStyleName("l-foreground-" + yColor.getName().toLowerCase());
}
}
/**
* Apply background color.
*
* @param yProps
* the y props
*/
public void applyBackgroundColor(YVisibilityProperties yProps) {
YColor yColor = yProps.getBackgroundColor();
if (yColor != null) {
component.addStyleName("l-background-" + yColor.getName().toLowerCase());
}
}
}
private class LabelAdapter extends AdapterImpl {
@Override
public void notifyChanged(Notification msg) {
if (msg.getFeature() == CoreModelPackage.Literals.YEMBEDDABLE__LABEL_I1_8N_KEY
|| msg.getFeature() == CoreModelPackage.Literals.YEMBEDDABLE__LABEL) {
doUpdateLocale(getLocale());
} else if (msg.getFeature() == CoreModelPackage.Literals.YCSS_ABLE__CSS_CLASS) {
if (msg.getEventType() == Notification.SET) {
doUnSetStyle(msg.getOldStringValue());
doSetStyle(msg.getNewStringValue());
} else {
doUnSetStyle(msg.getOldStringValue());
}
}
}
}
}