blob: 0e7a4492cc64b288cf0b9d28ffc326d9c75ab76a [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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.IObservable;
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.IDialogEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IViewEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.binding.IBindableEndpointEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeChangeEvent;
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation;
import org.eclipse.osbp.ecview.core.common.services.IUiKitBasedService;
import org.eclipse.osbp.ecview.core.common.services.IWidgetAssocationsService;
import org.eclipse.osbp.ecview.core.common.tooling.IWidgetMouseClickService;
import org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.runtime.common.dispose.AbstractDisposable;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
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.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.services.WidgetAssocationsService;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.services.WidgetMouseClickService;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.osbp.vaadin.addons.suggesttext.SuggestTextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.event.MouseEvents.ClickEvent;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.Component.Focusable;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;
// TODO: Auto-generated Javadoc
/**
* This presenter is responsible to render a text field on the given layout.
*/
public class ViewPresentation extends AbstractDisposable implements
IViewPresentation<Component>, ILocaleChangedService.LocaleListener,
IDesignListener {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(ViewPresentation.class);
/** The model access. */
private ModelAccess modelAccess;
/** The editpart. */
private final IViewEditpart editpart;
/** The component base. */
private CssLayout componentBase;
/** The component. */
private GridLayout component;
/** The content. */
private IEmbeddableEditpart content;
/** The content component. */
private Component contentComponent;
/**
* Constructor.
*
* @param editpart
* The editpart for that presentation.
*/
public ViewPresentation(IViewEditpart editpart) {
this.editpart = editpart;
this.modelAccess = new ModelAccess((YView) editpart.getModel());
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getModel()
*/
@Override
public Object getModel() {
return editpart.getModel();
}
/**
* Returns the editpart the presenter will render for.
*
* @return editpart
*/
public IViewEditpart getEditpart() {
checkDisposed();
return editpart;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#render(java.util.Map)
*/
@Override
public void render(Map<String, Object> options) {
checkDisposed();
this.content = editpart.getContent();
ComponentContainer parent = (ComponentContainer) editpart.getContext()
.getRootLayout();
createWidget(parent);
}
/**
* Is called to render the content.
*/
protected void renderContent() {
if (!isRendered()) {
return;
}
component.removeAllComponents();
if (content != null) {
contentComponent = (Component) content.render(component);
component.addComponent(contentComponent);
applyAlignment(contentComponent,
modelAccess.yView.getContentAlignment());
} else {
LOGGER.warn("Content is null");
}
componentBase.setSizeFull();
component.setSizeFull();
// if (!isFillVertical(modelAccess.yView.getContentAlignment())) {
// int packingHelperRowIndex = component.getRows();
// component.setRows(packingHelperRowIndex + 1);
// component.setRowExpandRatio(packingHelperRowIndex, 1.0f);
// } else {
// componentBase.setHeight("100%");
// component.setHeight("100%");
// }
//
// if (!isFillHorizontal(modelAccess.yView.getContentAlignment())) {
// int packingHelperColumnIndex = component.getColumns();
// component.setColumns(packingHelperColumnIndex + 1);
// component.setColumnExpandRatio(packingHelperColumnIndex, 1.0f);
// } else {
// componentBase.setWidth("100%");
// component.setWidth("100%");
// }
}
// private boolean isFillVertical(YAlignment alignment) {
// switch (alignment) {
// case FILL_CENTER:
// case FILL_FILL:
// case FILL_LEFT:
// case FILL_RIGHT:
// return true;
// default:
// return false;
// }
// }
//
// private boolean isFillHorizontal(YAlignment contentAlignment) {
// switch (contentAlignment) {
// case MIDDLE_FILL:
// case FILL_FILL:
// case BOTTOM_FILL:
// case TOP_FILL:
// return true;
// default:
// return false;
// }
// }
/**
* {@inheritDoc}
*/
@Override
public Component createWidget(Object parent) {
if (componentBase == null) {
// create component base with grid layout to enable margins
//
componentBase = new CssLayout();
componentBase.setSizeFull();
componentBase.addStyleName(IConstants.CSS_CLASS_CONTROL_BASE);
componentBase.addStyleName(IConstants.CSS_CLASS_YVIEW_PROVIDER);
// register shared state
ISharedStateContext sharedState = getViewContext().getService(
ISharedStateContext.class.getName());
if (sharedState != null) {
Map<Object, Object> viewData = new HashMap<Object, Object>();
viewData.put(ISharedStateContext.class, sharedState);
componentBase.setData(viewData);
}
ComponentContainer parentContainer = (ComponentContainer) parent;
parentContainer.addComponent(componentBase);
// create the component
component = new GridLayout(1, 1);
component.addStyleName(IConstants.CSS_CLASS_CONTROL);
componentBase.addComponent(component);
component.setSizeFull();
if (modelAccess.isCssIdValid()) {
component.setId(modelAccess.getCssID());
} else {
component.setId(editpart.getId());
}
if (modelAccess.isCssClassValid()) {
component.addStyleName(modelAccess.getCssClass());
}
if (modelAccess.isMargin()) {
component.addStyleName(IConstants.CSS_CLASS_MARGIN);
}
setupDesignListener();
// render the content
//
renderContent();
// register as an locale change listener
IViewContext context = ModelUtil.getViewContext(modelAccess.yView);
ILocaleChangedService service = context
.getService(ILocaleChangedService.ID);
if (service != null) {
service.addLocaleListener(this);
}
}
return componentBase;
}
/**
* Setup a listener to observe design events.
*/
protected void setupDesignListener() {
IDesignerService designService = getViewContext().getService(
IDesignerService.class.getName());
if (designService != null) {
designService.addListener((IDesignListener) this);
IWidgetDesignConfigurator cService = getViewContext().getService(
IWidgetDesignConfigurator.class.getName());
if (cService != null && getWidget() != null) {
cService.configure(getWidget(), (YView) getModel(),
designService.isDesignMode());
}
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getWidget()
*/
@Override
public Component getWidget() {
return componentBase;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#isRendered()
*/
@Override
public boolean isRendered() {
return componentBase != null;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getUIBindings()
*/
@Override
public Set<Binding> getUIBindings() {
return Collections.emptySet();
}
/**
* {@inheritDoc}
*/
@Override
public void unrender() {
if (componentBase != null) {
// unregister as an locale change listener
IViewContext context = ModelUtil.getViewContext(modelAccess.yView);
ILocaleChangedService service = context
.getService(ILocaleChangedService.ID);
if (service != null) {
service.removeLocaleListener(this);
}
// unregister the design listener
IDesignerService designService = context
.getService(IDesignerService.class.getName());
if (designService != null) {
designService.removeListener((IDesignListener) this);
IWidgetDesignConfigurator cService = context
.getService(IWidgetDesignConfigurator.class.getName());
if (cService != null && getWidget() != null) {
cService.configure(getWidget(), (YView) getModel(), false);
}
}
ComponentContainer parent = ((ComponentContainer) componentBase
.getParent());
if (parent != null) {
parent.removeComponent(componentBase);
}
componentBase = null;
}
}
/**
* {@inheritDoc}
*/
@Override
protected void internalDispose() {
if (componentBase != null) {
unrender();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#setContent(org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart)
*/
@Override
public void setContent(IEmbeddableEditpart editpart) {
this.content = editpart;
renderContent();
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#requestFocus(org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart)
*/
@Override
public void requestFocus(IElementEditpart toFocus) {
if (toFocus instanceof IEmbeddableEditpart) {
Component component = (Component) ((IEmbeddableEditpart) toFocus)
.getWidget();
if (component instanceof Focusable) {
((Focusable) component).focus();
if(component instanceof TextField){
((TextField) component).selectAll();
}else if(component instanceof SuggestTextField){
SuggestTextField field = (SuggestTextField) component;
field.getTextField().selectAll();
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#getContent()
*/
@Override
public IEmbeddableEditpart getContent() {
return content;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getViewContext()
*/
@Override
public IViewContext getViewContext() {
return getEditpart().getContext();
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getObservableValue(java.lang.Object)
*/
@Override
public IObservable getObservableValue(Object model) {
throw new UnsupportedOperationException("Must be overridden!");
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#exec(java.lang.Runnable)
*/
@Override
public void exec(Runnable runnable) {
UI ui = componentBase.getUI();
if (ui == null) {
ui = UI.getCurrent();
}
if (ui == null) {
throw new IllegalStateException(
"The view is not attached to the UI nor are we running in a proper vaadin session thread!");
}
VaadinObservables.activateRealm(ui);
ui.accessSynchronously(runnable);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#execAsync(java.lang.Runnable)
*/
@Override
public Future<?> execAsync(Runnable runnable) {
UI ui = componentBase.getUI();
if (ui == null) {
ui = UI.getCurrent();
}
if (ui == null) {
throw new IllegalStateException(
"The view is not attached to the UI nor are we running in a proper vaadin session thread!");
}
return ui.access(runnable);
}
/* (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) {
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#updateContentAlignment()
*/
public void updateContentAlignment() {
applyAlignment(contentComponent,
modelAccess.yView.getContentAlignment());
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#updateSpacings()
*/
@Override
public void updateSpacings() {
if (component != null) {
component.setMargin(modelAccess.yView.isMargin());
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.visibility.IVisibilityProcessable#resetVisibilityProperties()
*/
@Override
public void resetVisibilityProperties() {
}
/* (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) {
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.context.ILocaleChangedService.LocaleListener#localeChanged(java.util.Locale)
*/
@Override
public void localeChanged(Locale locale) {
// pass the locale to the root element
component.setLocale(locale);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#createService(java.lang.Class)
*/
@SuppressWarnings({ "unchecked" })
@Override
public <A extends IUiKitBasedService> A createService(Class<A> serviceClass) {
if (serviceClass == IWidgetMouseClickService.class) {
final WidgetMouseClickService service = new WidgetMouseClickService(
getViewContext());
service.activate();
return (A) service;
} else if (serviceClass == IWidgetAssocationsService.class) {
WidgetAssocationsService service = new WidgetAssocationsService();
return (A) service;
}
throw new IllegalArgumentException(String.format(
"%s is not a supported service.", serviceClass.getName()));
}
/**
* Click.
*
* @param event
* the event
*/
public void click(ClickEvent event) {
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#openDialog(org.eclipse.osbp.ecview.core.common.editpart.IDialogEditpart, org.eclipse.osbp.ecview.core.common.editpart.binding.IBindableEndpointEditpart)
*/
@Override
public void openDialog(IDialogEditpart dialogEditpart,
IBindableEndpointEditpart inputData) {
if (!isRendered()) {
return;
}
// VaadinObservables.activateRealm(navigationView.getUI());
// set the input data to the child nav page
dialogEditpart.setInputDataBindingEndpoint(inputData);
Window dialog = (Window) dialogEditpart.render(null);
componentBase.getUI().addWindow(dialog);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#closeDialog(org.eclipse.osbp.ecview.core.common.editpart.IDialogEditpart)
*/
@Override
public void closeDialog(IDialogEditpart dialogEditpart) {
if (!isRendered()) {
return;
}
Window dialog = (Window) dialogEditpart.getWidget();
if (dialog != null) {
componentBase.getUI().removeWindow(dialog);
dialogEditpart.unrender();
}
}
/**
* Sets the alignment to the component.
*
* @param child
* the child
* @param yAlignment
* the y alignment
*/
protected void applyAlignment(Component child, YAlignment yAlignment) {
if (child == null) {
return;
}
if (yAlignment != null) {
child.setSizeUndefined();
switch (yAlignment) {
case BOTTOM_CENTER:
component.setComponentAlignment(child, Alignment.BOTTOM_CENTER);
break;
case BOTTOM_FILL:
component.setComponentAlignment(child, Alignment.BOTTOM_LEFT);
child.setWidth("100%");
break;
case BOTTOM_LEFT:
component.setComponentAlignment(child, Alignment.BOTTOM_LEFT);
break;
case BOTTOM_RIGHT:
component.setComponentAlignment(child, Alignment.BOTTOM_RIGHT);
break;
case MIDDLE_CENTER:
component.setComponentAlignment(child, Alignment.MIDDLE_CENTER);
break;
case MIDDLE_FILL:
component.setComponentAlignment(child, Alignment.MIDDLE_LEFT);
child.setWidth("100%");
break;
case MIDDLE_LEFT:
component.setComponentAlignment(child, Alignment.MIDDLE_LEFT);
break;
case MIDDLE_RIGHT:
component.setComponentAlignment(child, Alignment.MIDDLE_RIGHT);
break;
case TOP_CENTER:
component.setComponentAlignment(child, Alignment.TOP_CENTER);
break;
case TOP_FILL:
component.setComponentAlignment(child, Alignment.TOP_LEFT);
child.setWidth("100%");
break;
case TOP_LEFT:
component.setComponentAlignment(child, Alignment.TOP_LEFT);
break;
case TOP_RIGHT:
component.setComponentAlignment(child, Alignment.TOP_RIGHT);
break;
case FILL_CENTER:
component.setComponentAlignment(child, Alignment.TOP_CENTER);
child.setHeight("100%");
break;
case FILL_FILL:
component.setComponentAlignment(child, Alignment.TOP_LEFT);
child.setSizeFull();
break;
case FILL_LEFT:
component.setComponentAlignment(child, Alignment.TOP_LEFT);
child.setHeight("100%");
break;
case FILL_RIGHT:
component.setComponentAlignment(child, Alignment.TOP_RIGHT);
child.setHeight("100%");
break;
default:
break;
}
} else {
component.setComponentAlignment(child, Alignment.TOP_LEFT);
child.setSizeFull();
}
}
/**
* Maps the vertical part of the alignment to FILL.
*
* @param yAlignment
* the alignment
* @return alignment the mapped alignment
*/
// BEGIN SUPRESS CATCH EXCEPTION
protected YAlignment mapToVerticalFill(YAlignment yAlignment) {
// END SUPRESS CATCH EXCEPTION
if (yAlignment != null) {
switch (yAlignment) {
case BOTTOM_CENTER:
case MIDDLE_CENTER:
case TOP_CENTER:
return YAlignment.FILL_CENTER;
case BOTTOM_FILL:
case MIDDLE_FILL:
case TOP_FILL:
return YAlignment.FILL_FILL;
case BOTTOM_LEFT:
case MIDDLE_LEFT:
case TOP_LEFT:
return YAlignment.FILL_LEFT;
case BOTTOM_RIGHT:
case MIDDLE_RIGHT:
case TOP_RIGHT:
return YAlignment.FILL_RIGHT;
case FILL_FILL:
case FILL_LEFT:
case FILL_RIGHT:
case FILL_CENTER:
return YAlignment.FILL_FILL;
default:
break;
}
}
return YAlignment.FILL_FILL;
}
/**
* Maps the horizontal part of the alignment to FILL.
*
* @param yAlignment
* the alignment
* @return alignment the mapped alignment
*/
// BEGIN SUPRESS CATCH EXCEPTION
protected YAlignment mapToHorizontalFill(YAlignment yAlignment) {
// END SUPRESS CATCH EXCEPTION
if (yAlignment != null) {
switch (yAlignment) {
case BOTTOM_CENTER:
case BOTTOM_FILL:
case BOTTOM_LEFT:
case BOTTOM_RIGHT:
return YAlignment.BOTTOM_FILL;
case MIDDLE_CENTER:
case MIDDLE_FILL:
case MIDDLE_LEFT:
case MIDDLE_RIGHT:
return YAlignment.MIDDLE_FILL;
case TOP_CENTER:
case TOP_FILL:
case TOP_LEFT:
case TOP_RIGHT:
return YAlignment.TOP_FILL;
case FILL_FILL:
case FILL_LEFT:
case FILL_RIGHT:
case FILL_CENTER:
return YAlignment.FILL_FILL;
default:
break;
}
}
return YAlignment.FILL_FILL;
}
/**
* 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(), (YView) getModel(),
event.getType() == EventType.ENABLED);
}
}
/**
* An internal helper class.
*/
private static class ModelAccess {
/** The y view. */
private final YView yView;
/**
* Instantiates a new model access.
*
* @param yView
* the y view
*/
public ModelAccess(YView yView) {
super();
this.yView = yView;
}
/**
* Gets the css class.
*
* @return the css class
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
*/
public String getCssClass() {
return yView.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 yView.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("");
}
/**
* Checks if is margin.
*
* @return true, if is margin
* @see org.eclipse.osbp.ecview.core.ui.core.model.extension.YGridLayout#isMargin()
*/
public boolean isMargin() {
return yView.isMargin();
}
}
}