| /** |
| * 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.DecimalDoubleConverter; |
| import org.eclipse.osbp.runtime.web.vaadin.components.fields.DecimalField; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables; |
| |
| 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; |
| |
| /** |
| * 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} |
| */ |
| @Override |
| public Component doCreateWidget(Object parent) { |
| if (decimalField == null) { |
| |
| decimalField = new CustomField((DecimalDoubleConverter) 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 DecimalDoubleConverter(); |
| } |
| |
| /* |
| * (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(DecimalDoubleConverter 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"); |
| } |
| } |
| } |