blob: 7ff81f1f4c34cb1d33d5cdd44ad7be9d3da5ab91 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2017 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.EEFListDescription;
import org.eclipse.eef.EEFWidgetAction;
import org.eclipse.eef.EEFWidgetDescription;
import org.eclipse.eef.common.ui.api.EEFWidgetFactory;
import org.eclipse.eef.common.ui.api.IEEFFormContainer;
import org.eclipse.eef.common.ui.api.SWTUtils;
import org.eclipse.eef.core.api.EditingContextAdapter;
import org.eclipse.eef.core.api.controllers.EEFControllersFactory;
import org.eclipse.eef.core.api.controllers.IEEFListController;
import org.eclipse.eef.core.api.controllers.IEEFWidgetController;
import org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager;
import org.eclipse.eef.ide.ui.internal.EEFIdeUiPlugin;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
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.ScrolledComposite;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
/**
* This class will be used in order to manager the lifecycle of a list widget.
*
* @author sbegaudeau
*/
public class EEFListLifecycleManager extends AbstractEEFWidgetLifecycleManager {
/**
* Default height.
*/
private static final int DEFAULT_HEIGHT = 34;
/**
* Minimal height of the table widget.
*/
private static final int TABLE_MINIMAL_HEIGHT = 100;
/**
* The description.
*/
private EEFListDescription description;
/**
* The widget factory.
*/
private EEFWidgetFactory widgetFactory;
/**
* The action buttons.
*/
private List<ActionButton> actionButtons = new ArrayList<ActionButton>();
/**
* The default background color of the text field.
*/
private Color defaultBackgroundColor;
/**
* The controller.
*/
private IEEFListController controller;
/**
* The table viewer used to display the list.
*/
private TableViewer tableViewer;
/**
* The listener used to run the onClick expression when the user will click on the table.
*/
private SelectionListener tableSelectionListener;
/**
* The constructor.
*
* @param description
* The description
* @param variableManager
* The variable manager
* @param interpreter
* The interpreter
* @param editingContextAdapter
* The editing context adapter
*/
public EEFListLifecycleManager(EEFListDescription description, IVariableManager variableManager, IInterpreter interpreter,
EditingContextAdapter editingContextAdapter) {
super(variableManager, interpreter, editingContextAdapter);
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) {
widgetFactory = formContainer.getWidgetFactory();
defaultBackgroundColor = parent.getBackground();
// this is the parent composite
Composite list = widgetFactory.createFlatFormComposite(parent);
GridLayout layout = new GridLayout(2, false);
list.setLayout(layout);
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
list.setLayoutData(gridData);
this.createListWidget(list);
this.createWidgetActionButtons(list);
widgetFactory.paintBordersFor(parent);
this.controller = new EEFControllersFactory().createListController(this.description, this.variableManager, this.interpreter,
this.editingContextAdapter);
}
/**
* Create table widget.
*
* @param parent
* The parent composite
*/
private void createListWidget(Composite parent) {
ScrolledComposite scrolledComposite = widgetFactory.createScrolledComposite(parent, SWT.NONE);
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = SWT.FILL;
scrolledComposite.setLayoutData(gridData);
// CHECKSTYLE:OFF
int style = SWT.READ_ONLY | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI | SWT.VIRTUAL;
// CHECKSTYLE:ON
Table table = widgetFactory.createTable(scrolledComposite, style);
this.tableViewer = new TableViewer(table);
GridData tableGridData = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1);
tableGridData.horizontalIndent = VALIDATION_MARKER_OFFSET;
this.tableViewer.getTable().setLayoutData(tableGridData);
this.tableViewer.setContentProvider(ArrayContentProvider.getInstance());
this.tableViewer.setLabelProvider(new EEFListTableLabelProvider(this.description, this.interpreter, this.variableManager));
scrolledComposite.setContent(table);
int widgetHeight = DEFAULT_HEIGHT;
List<EEFWidgetAction> actions = description.getActions();
if (actions != null && actions.size() > 0) {
widgetHeight = widgetHeight * (actions.size() + 1);
}
final int clientWidth = scrolledComposite.getClientArea().width;
this.tableViewer.getTable().setSize(clientWidth, Math.max(TABLE_MINIMAL_HEIGHT, widgetHeight));
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setAlwaysShowScrollBars(true);
}
/**
* Create widget action buttons.
*
* @param parent
* The parent composite
*/
private void createWidgetActionButtons(Composite parent) {
Composite buttons = widgetFactory.createFlatFormComposite(parent);
GridData gridData = new GridData();
gridData.verticalAlignment = SWT.BEGINNING;
buttons.setLayoutData(gridData);
buttons.setLayout(new GridLayout(1, false));
// Buttons are visible only if an action is defined
for (EEFWidgetAction action : this.description.getActions()) {
ActionButton actionButton = new ActionButton(action, buttons, widgetFactory, this.interpreter, this.variableManager);
actionButtons.add(actionButton);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#aboutToBeShown()
*/
@Override
public void aboutToBeShown() {
super.aboutToBeShown();
this.tableSelectionListener = new EEFListSelectionListener(this.controller);
this.tableViewer.getTable().addSelectionListener(tableSelectionListener);
this.controller.onNewValue((value) -> {
if (value == null) {
return;
}
this.setListValue(value);
});
this.actionButtons.forEach(actionButton -> {
SelectionListener selectionListener = SWTUtils.widgetSelectedAdapter((event) -> {
if (!this.container.isRenderingInProgress()) {
List<Object> selections = new ArrayList<Object>();
IStructuredSelection structuredSelection = (IStructuredSelection) tableViewer.getSelection();
for (Object selection : structuredSelection.toList()) {
selections.add(selection);
}
IStatus result = controller.action(actionButton.getAction(), selections);
if (result != null && result.getSeverity() == IStatus.ERROR) {
EEFIdeUiPlugin.INSTANCE.log(result);
} else {
refresh();
}
}
});
actionButton.addSelectionListener(selectionListener);
});
}
/**
* Set the value of the list.
*
* @param value
* Value to select
*/
private void setListValue(Object value) {
if (!this.tableViewer.getTable().isDisposed()) {
final ISelection selection = new StructuredSelection(value);
tableViewer.setSelection(selection);
List<Object> values = new ArrayList<Object>();
if (value instanceof Iterable<?>) {
for (Object val : (Iterable<?>) value) {
values.add(val);
}
} else {
values.add(value);
}
tableViewer.setInput(values.toArray());
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#setEnabled(boolean)
*/
@Override
protected void setEnabled(boolean isEnabled) {
if (this.tableViewer != null && this.tableViewer.getTable() != null && !this.tableViewer.getTable().isDisposed()) {
this.tableViewer.getTable().setBackground(this.getBackgroundColor(isEnabled));
this.tableViewer.getTable().setEnabled(isEnabled);
}
this.actionButtons.stream().filter(actionButton -> !actionButton.getButton().isDisposed())
.forEach(actionButton -> actionButton.setEnabled(isEnabled));
}
/**
* Get the background color according to the current valid style.
*
* @param isEnabled
* <code>true</code> if the widget is enabled, <code>false</code> otherwise
*
* @return The background color to use in the text field.
*/
private Color getBackgroundColor(boolean isEnabled) {
Color color = defaultBackgroundColor;
if (!isEnabled) {
color = widgetFactory.getColors().getInactiveBackground();
}
return color;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#aboutToBeHidden()
*/
@Override
public void aboutToBeHidden() {
super.aboutToBeHidden();
this.actionButtons.forEach(ActionButton::removeSelectionListener);
if (this.tableViewer != null && this.tableViewer.getTable() != null && !this.tableViewer.getTable().isDisposed()) {
this.tableViewer.getTable().removeSelectionListener(this.tableSelectionListener);
}
this.controller.removeNewValueConsumer();
}
/**
* {@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;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFLifecycleManager#getValidationControl()
*/
@Override
protected Control getValidationControl() {
return this.tableViewer.getTable().getParent();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.eef.ide.ui.api.widgets.AbstractEEFWidgetLifecycleManager#dispose()
*/
@Override
public void dispose() {
super.dispose();
this.actionButtons.clear();
}
}