blob: 5a67f8c06a1615072a97cfc805b76a18a3160851 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Obeo.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.eef.ide.ui.internal.widgets;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.eef.EEFHyperlinkDescription;
import org.eclipse.eef.EEFHyperlinkStyle;
import org.eclipse.eef.EEFWidgetAction;
import org.eclipse.eef.EEFWidgetDescription;
import org.eclipse.eef.EEFWidgetStyle;
import org.eclipse.eef.common.ui.api.EEFWidgetFactory;
import org.eclipse.eef.common.ui.api.IEEFFormContainer;
import org.eclipse.eef.core.api.EditingContextAdapter;
import org.eclipse.eef.core.api.controllers.EEFControllersFactory;
import org.eclipse.eef.core.api.controllers.IConsumer;
import org.eclipse.eef.core.api.controllers.IEEFHyperlinkController;
import org.eclipse.eef.core.api.controllers.IEEFWidgetController;
import org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager;
import org.eclipse.eef.ide.ui.api.widgets.EEFStyleHelper;
import org.eclipse.eef.ide.ui.api.widgets.EEFStyleHelper.IEEFTextStyleCallback;
import org.eclipse.eef.ide.ui.internal.EEFIdeUiPlugin;
import org.eclipse.sirius.common.interpreter.api.IInterpreter;
import org.eclipse.sirius.common.interpreter.api.IVariableManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
/**
* This class will be used in order to manager the lifecycle of an hyperlink.
*
* @author mbats
*/
public class EEFHyperlinkLifecycleManager extends AbstractEEFWidgetLifecycleManager {
/**
* The description.
*/
private EEFHyperlinkDescription description;
/**
* The hyperlink.
*/
private StyledText hyperlink;
/**
* The widget factory.
*/
private EEFWidgetFactory widgetFactory;
/**
* The action buttons.
*/
private List<ActionButton> actionButtons = new ArrayList<ActionButton>();
/**
* The controller.
*/
private IEEFHyperlinkController controller;
/**
* The listener on the hyperlink.
*/
private MouseListener hyperlinkListener;
/**
* The constructor.
*
* @param description
* The description
* @param variableManager
* The variable manager
* @param interpreter
* The interpreter
* @param contextAdapter
* The editing context adapter
*/
public EEFHyperlinkLifecycleManager(EEFHyperlinkDescription description, IVariableManager variableManager, IInterpreter interpreter,
EditingContextAdapter contextAdapter) {
super(variableManager, interpreter, contextAdapter);
this.description = description;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#createMainControl(org.eclipse.swt.widgets.Composite,
* org.eclipse.eef.common.ui.api.IEEFFormContainer)
*/
@Override
protected void createMainControl(Composite parent, IEEFFormContainer formContainer) {
this.widgetFactory = formContainer.getWidgetFactory();
// this is the parent composite
Composite hyperlinkComposite = this.widgetFactory.createFlatFormComposite(parent);
GridLayout layout = new GridLayout(2, false);
// Remove the 5px left margin only
layout.marginWidth = 0;
layout.marginRight = 5;
hyperlinkComposite.setLayout(layout);
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
hyperlinkComposite.setLayoutData(gridData);
this.createHyperlink(hyperlinkComposite);
this.createWidgetActionButtons(hyperlinkComposite);
this.controller = new EEFControllersFactory().createHyperlinkController(this.description, this.variableManager, this.interpreter,
this.contextAdapter);
}
/**
* Create the hyperlink widget.
*
* @param parent
* The parent composite
*/
private void createHyperlink(Composite parent) {
this.hyperlink = widgetFactory.createStyledText(parent, SWT.READ_ONLY);
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gridData.horizontalIndent = VALIDATION_MARKER_OFFSET;
this.hyperlink.setLayoutData(gridData);
this.hyperlink.setEditable(false);
}
/**
* Creates widget action buttons.
*
* @param parent
* The parent composite
*/
private void createWidgetActionButtons(Composite parent) {
Composite buttons = this.widgetFactory.createFlatFormComposite(parent);
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = false;
buttons.setLayoutData(gridData);
buttons.setLayout(new GridLayout(this.description.getActions().size(), true));
// Buttons are visible only if an action is defined
for (EEFWidgetAction action : this.description.getActions()) {
ActionButton actionButton = new ActionButton(action, buttons, this.widgetFactory, this.interpreter, this.variableManager);
actionButtons.add(actionButton);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#getLabelVerticalAlignment()
*/
@Override
protected int getLabelVerticalAlignment() {
return GridData.VERTICAL_ALIGN_CENTER;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#getController()
*/
@Override
protected IEEFWidgetController getController() {
return this.controller;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.internal.widgets.AbstractEEFWidgetLifecycleManager#getWidgetDescription()
*/
@Override
protected EEFWidgetDescription getWidgetDescription() {
return this.description;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#aboutToBeShown()
*/
@Override
public void aboutToBeShown() {
super.aboutToBeShown();
this.hyperlinkListener = new EEFHyperlinkListener(this, this.hyperlink, this.container, this.controller);
hyperlink.addMouseListener(hyperlinkListener);
this.controller.onNewValue(new IConsumer<Object>() {
@Override
public void apply(Object value) {
if (!hyperlink.isDisposed()) {
if (!(hyperlink.getText() != null && hyperlink.getText().equals(value))) {
String text = controller.computeDisplayValue(value);
hyperlink.setText(text);
hyperlink.setData(value);
}
EEFHyperlinkLifecycleManager.this.setStyle();
if (!hyperlink.isEnabled()) {
hyperlink.setEnabled(true);
}
}
}
});
for (final ActionButton actionButton : actionButtons) {
SelectionAdapter selectionListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (!EEFHyperlinkLifecycleManager.this.container.isRenderingInProgress()) {
IStatus result = controller.action(actionButton.getAction());
if (result != null && result.getSeverity() == IStatus.ERROR) {
EEFIdeUiPlugin.INSTANCE.log(result);
} else {
refresh();
}
}
}
};
actionButton.addSelectionListener(selectionListener);
}
}
/**
* Set the style.
*/
private void setStyle() {
EEFStyleHelper styleHelper = new EEFStyleHelper(this.interpreter, this.variableManager);
EEFWidgetStyle widgetStyle = styleHelper.getWidgetStyle(this.description);
if (widgetStyle instanceof EEFHyperlinkStyle) {
EEFHyperlinkStyle style = (EEFHyperlinkStyle) widgetStyle;
IEEFTextStyleCallback callback = new EEFStyledTextStyleCallback(this.hyperlink);
styleHelper.applyTextStyle(style.getFontNameExpression(), style.getFontSizeExpression(), style.getFontStyleExpression(),
this.hyperlink.getFont(), style.getBackgroundColorExpression(), null, callback);
}
// Sets the default hyperlink style properties
StyleRange[] styleRanges = hyperlink.getStyleRanges();
StyleRange styleRange;
if (styleRanges.length > 0) {
styleRange = styleRanges[0];
} else {
styleRange = new StyleRange();
}
if (styleRange != null) {
styleRange.start = 0;
styleRange.length = hyperlink.getText().length();
styleRange.underline = true;
styleRange.underlineStyle = SWT.UNDERLINE_LINK;
}
hyperlink.setStyleRange(styleRange);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#getValidationControl()
*/
@Override
protected Control getValidationControl() {
return this.hyperlink;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#aboutToBeHidden()
*/
@Override
public void aboutToBeHidden() {
super.aboutToBeHidden();
if (!hyperlink.isDisposed()) {
this.hyperlink.removeMouseListener(this.hyperlinkListener);
}
for (ActionButton actionButton : this.actionButtons) {
actionButton.removeSelectionListener();
}
this.controller.removeNewValueConsumer();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#refresh()
*/
@Override
public void refresh() {
super.refresh();
this.hyperlink.setEnabled(isEnabled());
for (ActionButton actionButton : this.actionButtons) {
actionButton.setEnabled(this.isEnabled());
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#dispose()
*/
@Override
public void dispose() {
super.dispose();
this.actionButtons.clear();
}
}