blob: cca4cd3e27bec4bd4f2ab11c4073eac8a1054988 [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.internal;
import java.util.Locale;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableValueEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YValueBindable;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatatype;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDecimalDatatype;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YDecimalField;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IDecimalFieldEditpart;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IBindingManager;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import org.eclipse.osbp.runtime.web.vaadin.components.converter.DecimalConverter;
import org.eclipse.osbp.runtime.web.vaadin.components.fields.DecimalField;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.server.ErrorMessage;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;
// TODO: Auto-generated Javadoc
/**
* This presenter is responsible to render a text area on the given layout.
*/
public class DecimalFieldPresentation extends AbstractFieldWidgetPresenter<Component> {
/** The model access. */
private final ModelAccess modelAccess;
/** The decimal field. */
private CustomField decimalField;
/** The binding_value to ui. */
private Binding binding_valueToUI;
/** The property. */
private ObjectProperty<Double> property;
/**
* Constructor.
*
* @param editpart
* The editpart of that presenter
*/
public DecimalFieldPresentation(IElementEditpart editpart) {
super((IDecimalFieldEditpart) editpart);
this.modelAccess = new ModelAccess((YDecimalField) editpart.getModel());
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "serial" })
@Override
public Component doCreateWidget(Object parent) {
if (decimalField == null) {
decimalField = new CustomField((DecimalConverter) getConverter());
decimalField.addStyleName(CSS_CLASS_CONTROL);
decimalField.setImmediate(true);
setupComponent(decimalField, getCastedModel());
associateWidget(decimalField, modelAccess.yField);
if (modelAccess.isCssIdValid()) {
decimalField.setId(modelAccess.getCssID());
} else {
decimalField.setId(getEditpart().getId());
}
property = new ObjectProperty<Double>(0d, Double.class);
decimalField.setPropertyDataSource(property);
if (modelAccess.isCssClassValid()) {
decimalField.addStyleName(modelAccess.getCssClass());
}
applyCaptions();
doApplyDatatype(modelAccess.yField.getDatatype());
initializeField(decimalField);
// creates the binding for the field
createBindings(modelAccess.yField, decimalField);
// send an event, that the content was rendered again
sendRenderedLifecycleEvent();
}
return decimalField;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractFieldWidgetPresenter#getDefaultConverter()
*/
@Override
protected Converter<?, ?> getDefaultConverter() {
return new DecimalConverter();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractFieldWidgetPresenter#doUpdateConverter(com.vaadin.data.util.
* converter.Converter)
*/
@SuppressWarnings("rawtypes")
protected void doUpdateConverter(Converter converter) {
super.doUpdateConverter(converter);
// if converter changes, then apply the settings from datatype to it
doApplyDatatype(modelAccess.yField.getDatatype());
}
/**
* Applies the datatype options to the field.
*
* @param yDt
* the y dt
*/
protected void doApplyDatatype(YDatatype yDt) {
if (decimalField == null) {
return;
}
int oldPrecision = decimalField.getPrecision();
if (yDt == null) {
decimalField.setPrecision(2);
decimalField.setUseGrouping(true);
decimalField.setMarkNegative(true);
} else {
YDecimalDatatype yCasted = (YDecimalDatatype) yDt;
decimalField.setPrecision(yCasted.getPrecision());
decimalField.setUseGrouping(yCasted.isGrouping());
decimalField.setMarkNegative(yCasted.isMarkNegative());
}
if (isRendered()) {
// if the precision changed, then update the value from the ui field
// to the ECViewModel
if (oldPrecision != decimalField.getPrecision()) {
updateUiToECViewModel();
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
*/
@Override
protected void doUpdateLocale(Locale locale) {
// update the captions
applyCaptions();
// tell the number field about the locale change
if (decimalField != null) {
decimalField.setLocale(locale);
}
}
/**
* Applies the labels to the widgets.
*/
protected void applyCaptions() {
Util.applyCaptions(getI18nService(), modelAccess.getLabel(), modelAccess.getLabelI18nKey(), getLocale(),
decimalField);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractFieldWidgetPresenter#doGetField()
*/
@Override
protected Field<?> doGetField() {
return decimalField;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractVaadinWidgetPresenter#internalGetObservableEndpoint(org.eclipse.
* osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint)
*/
@Override
protected IObservable internalGetObservableEndpoint(YEmbeddableBindingEndpoint bindableValue) {
if (bindableValue == null) {
throw new IllegalArgumentException("BindableValue must not be null!");
}
if (bindableValue instanceof YEmbeddableValueEndpoint) {
return internalGetValueEndpoint();
}
throw new IllegalArgumentException("Not a valid input: " + bindableValue);
}
/**
* Returns the observable to observe value.
*
* @return the i observable value
*/
protected IObservableValue internalGetValueEndpoint() {
// return the observable value for text
return EMFObservables.observeValue(castEObject(getModel()),
ExtensionModelPackage.Literals.YDECIMAL_FIELD__VALUE);
}
/**
* Creates the bindings for the given values.
*
* @param yField
* the y field
* @param field
* the field
*/
protected void createBindings(YDecimalField yField, DecimalField field) {
// create the value binding from widget to ECView-model
binding_valueToUI = createBindings_Value(castEObject(getModel()),
ExtensionModelPackage.Literals.YDECIMAL_FIELD__VALUE, field);
registerBinding(binding_valueToUI);
super.createBindings(yField, field, null);
}
/**
* Creates the model binding.
*
* @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 the binding
*/
protected Binding createModelBinding(EObject model, EStructuralFeature modelFeature, AbstractField<?> 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.observeConvertedValue(field);
return bindingManager.bindValue(uiObservable, modelObservable, targetToModel, modelToTarget);
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* getWidget()
*/
@Override
public Component getWidget() {
return decimalField;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* isRendered()
*/
@Override
public boolean isRendered() {
return decimalField != null;
}
/**
* {@inheritDoc}
*/
@Override
public void doUnrender() {
if (decimalField != null) {
// unbind all active bindings
unbind();
Component parent = ((Component) decimalField.getParent());
if (parent != null && parent instanceof ComponentContainer) {
((ComponentContainer) parent).removeComponent(decimalField);
}
// remove assocations
unassociateWidget(decimalField);
decimalField = null;
sendUnrenderedLifecycleEvent();
}
}
/**
* {@inheritDoc}
*/
@Override
protected void internalDispose() {
try {
unrender();
binding_valueToUI = null;
} finally {
super.internalDispose();
}
}
/**
* Update ui to ec view model.
*/
protected void updateUiToECViewModel() {
if (binding_valueToUI != null) {
binding_valueToUI.updateTargetToModel();
}
Binding domainToEObjectBinding = ModelUtil.getValueBinding((YValueBindable) getModel());
if (domainToEObjectBinding != null) {
domainToEObjectBinding.updateTargetToModel();
}
}
/**
* A helper class.
*/
private static class ModelAccess {
/** The y field. */
private final YDecimalField yField;
/**
* Instantiates a new model access.
*
* @param yField
* the y field
*/
public ModelAccess(YDecimalField yField) {
super();
this.yField = yField;
}
/**
* Gets the css class.
*
* @return the css class
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
*/
public String getCssClass() {
return yField.getCssClass();
}
/**
* Returns true, if the css class is not null and not empty.
*
* @return true, if is css class valid
*/
public boolean isCssClassValid() {
return getCssClass() != null && !getCssClass().equals("");
}
/**
* Gets the css id.
*
* @return the css id
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
*/
public String getCssID() {
return yField.getCssID();
}
/**
* Returns true, if the css id is not null and not empty.
*
* @return true, if is css id valid
*/
public boolean isCssIdValid() {
return getCssID() != null && !getCssID().equals("");
}
/**
* Returns the label.
*
* @return the label
*/
public String getLabel() {
return yField.getDatadescription() != null ? yField.getDatadescription().getLabel() : null;
}
/**
* Returns the label.
*
* @return the label i18n key
*/
public String getLabelI18nKey() {
return yField.getDatadescription() != null ? yField.getDatadescription().getLabelI18nKey() : null;
}
}
/**
* The Class CustomField.
*/
@SuppressWarnings("serial")
private class CustomField extends DecimalField {
/**
* Instantiates a new custom field.
*
* @param converter
* the converter
*/
public CustomField(DecimalConverter converter) {
super("", converter);
}
/*
* (non-Javadoc)
*
* @see com.vaadin.ui.AbstractField#getErrorMessage()
*/
@Override
public ErrorMessage getErrorMessage() {
if (isDisposed()) {
// after disposal, Vaadin will call this method once.
return null;
}
ErrorMessage message = super.getErrorMessage();
reportValidationError(message);
return message;
}
public void clear() {
setValue("0.0");
}
}
}