blob: bca933bbc852200f31de306268e600821bb0ecbc [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.ext.widgets.reference.internal;
import org.eclipse.eef.EEFWidgetDescription;
import org.eclipse.eef.common.api.utils.Util;
import org.eclipse.eef.common.ui.api.EEFWidgetFactory;
import org.eclipse.eef.core.api.EditingContextAdapter;
import org.eclipse.eef.core.api.controllers.IEEFWidgetController;
import org.eclipse.eef.core.ext.widgets.reference.internal.EEFExtReferenceController;
import org.eclipse.eef.ext.widgets.reference.eefextwidgetsreference.EEFExtReferenceDescription;
import org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager;
import org.eclipse.eef.ide.ui.api.widgets.EEFStyleHelper;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
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.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
/**
* Common superclass of both the single and multi-valued reference lifecycle managers.
*
* @author sbegaudeau
*/
public abstract class AbstractEEFExtReferenceLifecycleManager extends AbstractEEFWidgetLifecycleManager {
/**
* The minimum width of the button.
*/
private static final int MINIMUM_BUTTON_WIDTH = 80;
/**
* The description.
*/
protected EEFExtReferenceDescription description;
/**
* The target.
*/
protected EObject target;
/**
* The EReference.
*/
protected EReference eReference;
/**
* The controller.
*/
protected EEFExtReferenceController controller;
/**
* The composed adapter factory.
*/
protected ComposedAdapterFactory composedAdapterFactory;
/**
* The widget factory.
*/
protected EEFWidgetFactory widgetFactory;
/**
* The browse button.
*/
protected Button browseButton;
/**
* The listener for the browse button.
*/
protected ButtonSelectionListener browseButtonListener;
/**
* The add button.
*/
protected Button addButton;
/**
* The listener for the add button.
*/
protected ButtonSelectionListener addButtonListener;
/**
* The remove button.
*/
protected Button removeButton;
/**
* The listener for the remove button.
*/
protected ButtonSelectionListener removeButtonListener;
/**
* The constructor.
*
* @param description
* The description of the reference
* @param target
* The target
* @param eReference
* The EReference to display
* @param variableManager
* The variable manager
* @param interpreter
* The interpreter
* @param editingContextAdapter
* The context adapter
*/
public AbstractEEFExtReferenceLifecycleManager(EEFExtReferenceDescription description, EObject target, EReference eReference,
IVariableManager variableManager, IInterpreter interpreter, EditingContextAdapter editingContextAdapter) {
super(variableManager, interpreter, editingContextAdapter);
this.description = description;
this.target = target;
this.eReference = eReference;
}
/**
* {@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.api.widgets.AbstractEEFWidgetLifecycleManager#getWidgetDescription()
*/
@Override
protected EEFWidgetDescription getWidgetDescription() {
return this.description;
}
/**
* Creates a button used to edit the reference.
*
* @param parent
* The parent composite
* @param image
* The image of the button
* @return The button created
*/
protected Button createButton(Composite parent, Image image) {
Button button = this.widgetFactory.createButton(parent, "", SWT.NONE); //$NON-NLS-1$
button.setImage(image);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.grabExcessHorizontalSpace = true;
gridData.minimumWidth = MINIMUM_BUTTON_WIDTH;
button.setLayoutData(gridData);
return button;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#aboutToBeShown()
*/
@Override
public void aboutToBeShown() {
super.aboutToBeShown();
if (!this.eReference.isContainment()) {
this.initializeBrowseButton();
}
this.initializeAddButton();
this.initializeRemoveButton();
}
/**
* Initializes the browse button.
*/
private void initializeBrowseButton() {
this.browseButtonListener = new ButtonSelectionListener(this.editingContextAdapter, () -> this.browseButtonCallback());
this.browseButton.addSelectionListener(this.browseButtonListener);
this.browseButton.setToolTipText(Messages.ReferenceBrowseButton_tooltipText);
}
/**
* This method is called once the browse button is clicked to select an existing element from the resource set.
*/
protected abstract void browseButtonCallback();
/**
* Initializes the add button.
*/
private void initializeAddButton() {
this.addButtonListener = new ButtonSelectionListener(this.editingContextAdapter, () -> this.addButtonCallback());
this.addButton.addSelectionListener(this.addButtonListener);
this.addButton.setToolTipText(Messages.ReferenceAddButton_tooltipText);
}
/**
* This method is called once the add button is clicked in order to open the "add dialog".
*/
protected abstract void addButtonCallback();
/**
* Initializes the remove button.
*/
private void initializeRemoveButton() {
this.removeButtonListener = new ButtonSelectionListener(this.editingContextAdapter, () -> this.removeButtonCallback());
this.removeButton.addSelectionListener(this.removeButtonListener);
if (this.eReference.isContainment()) {
this.removeButton.setToolTipText(Messages.ReferenceRemoveButton_containmentTooltipText);
} else {
this.removeButton.setToolTipText(Messages.ReferenceRemoveButton_nonContainmentTooltipText);
}
}
/**
* This method is called once the remove button is clicked in order to remove the selected element.
*/
protected abstract void removeButtonCallback();
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFLifecycleManager#refresh()
*/
@Override
public void refresh() {
super.refresh();
if (Util.isBlank(this.description.getLabelExpression())) {
Adapter adapter = this.composedAdapterFactory.adapt(this.target, IItemPropertySource.class);
if (adapter instanceof IItemPropertySource) {
IItemPropertySource propertySource = (IItemPropertySource) adapter;
IItemPropertyDescriptor propertyDescriptor = propertySource.getPropertyDescriptor(this.target, this.eReference);
if (propertyDescriptor != null) {
String displayName = propertyDescriptor.getDisplayName(this.eReference);
this.label.setText(displayName);
} else {
this.label.setText(this.eReference.getName());
}
}
}
this.setLabelFontStyle();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#setEnabled(boolean)
*/
@Override
protected void setEnabled(boolean isEnabled) {
if (this.addButton != null && !this.addButton.isDisposed()) {
this.addButton.setEnabled(isEnabled);
}
if (this.removeButton != null && !this.removeButton.isDisposed()) {
this.removeButton.setEnabled(isEnabled);
}
if (this.browseButton != null && !this.browseButton.isDisposed()) {
this.browseButton.setEnabled(isEnabled);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#isEnabled()
*/
@Override
protected boolean isEnabled() {
return super.isEnabled() && this.eReference.isChangeable();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#aboutToBeHidden()
*/
@Override
public void aboutToBeHidden() {
super.aboutToBeHidden();
if (!this.eReference.isContainment()) {
this.removeListener(this.browseButton, this.browseButtonListener);
}
this.removeListener(this.addButton, this.addButtonListener);
this.removeListener(this.removeButton, this.removeButtonListener);
}
/**
* Removes the given listener from the given button.
*
* @param button
* The button
* @param listener
* The listener to remove
*/
protected void removeListener(Button button, ButtonSelectionListener listener) {
if (!button.isDisposed()) {
button.removeSelectionListener(listener);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#dispose()
*/
@Override
public void dispose() {
super.dispose();
this.composedAdapterFactory.dispose();
}
/**
* Utility class used to encapsulate the selection listener.
*
* @author sbegaudeau
*/
protected static class ButtonSelectionListener implements SelectionListener {
/**
* The context adapter.
*/
private EditingContextAdapter editingContextAdapter;
/**
* The behavior to execute when the button is clicked.
*/
private Runnable runnable;
/**
* The constructor.
*
* @param editingContextAdapter
* The {@link EditingContextAdapter}
* @param runnable
* The behavior to execute when the button is clicked
*/
public ButtonSelectionListener(EditingContextAdapter editingContextAdapter, Runnable runnable) {
this.editingContextAdapter = editingContextAdapter;
this.runnable = runnable;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent event) {
this.editingContextAdapter.performModelChange(this.runnable);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetDefaultSelected(SelectionEvent event) {
this.editingContextAdapter.performModelChange(this.runnable);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#getEEFStyleHelper()
*/
@Override
protected EEFStyleHelper getEEFStyleHelper() {
return new EEFExtStyleHelper(this.interpreter, this.variableManager);
}
}