/*******************************************************************************
* Copyright (c) 2008, 2011 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.emf.eef.runtime.ui.widgets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
import org.eclipse.emf.common.ui.celleditor.ExtendedComboBoxCellEditor;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ItemProvider;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.eef.runtime.impl.filters.business.BusinessViewerFilter;
import org.eclipse.emf.eef.runtime.ui.utils.EEFRuntimeUIMessages;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
/**
* @author <a href="mailto:goulwen.lefur@obeo.fr">Goulwen Le Fur</a>
*/
public class EEFFeatureEditorDialog extends Dialog {
protected ILabelProvider labelProvider;
protected IContentProvider contentProvider;
protected Object object;
protected EClassifier eClassifier;
protected String displayName;
protected ItemProvider values;
protected List<?> choiceOfValues;
protected EList<?> result;
protected boolean multiLine;
/**
* List of static filters
*/
private List<ViewerFilter> filters;
/**
* List of business filters
*/
private List<ViewerFilter> brFilters;
public EEFFeatureEditorDialog(Shell parent, String displayName, ILabelProvider labelProvider,
List<?> currentValues, List<?> choiceOfValues, boolean multiLine, boolean sortChoices,
List<ViewerFilter> filters, List<ViewerFilter> brFilters) {
super(parent);
setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
this.labelProvider = labelProvider;
this.displayName = displayName;
this.choiceOfValues = choiceOfValues;
this.multiLine = multiLine;
this.filters = filters;
this.brFilters = brFilters;
AdapterFactory adapterFactory = new ComposedAdapterFactory(Collections.<AdapterFactory> emptyList());
values = new ItemProvider(adapterFactory, currentValues);
contentProvider = new AdapterFactoryContentProvider(adapterFactory);
if (sortChoices && choiceOfValues != null) {
this.choiceOfValues = new ArrayList<Object>(choiceOfValues);
ExtendedComboBoxCellEditor.createItems(this.choiceOfValues, labelProvider, true);
}
}
public EEFFeatureEditorDialog(Shell parent, String displayName, ILabelProvider labelProvider,
List<?> currentValues, EClassifier eClassifier, List<?> choiceOfValues, boolean multiLine,
boolean sortChoices, List<ViewerFilter> filters, List<ViewerFilter> brFilters) {
this(parent, displayName, labelProvider, currentValues, choiceOfValues, multiLine, sortChoices,
filters, brFilters);
this.eClassifier = eClassifier;
}
@Override
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText(EMFEditUIPlugin.INSTANCE.getString(
"_UI_FeatureEditorDialog_title", new Object[] {displayName, //$NON-NLS-1$
labelProvider.getText(object)}));
shell.setImage(labelProvider.getImage(object));
}
@Override
protected Control createDialogArea(Composite parent) {
Composite contents = (Composite)super.createDialogArea(parent);
GridLayout contentsGridLayout = (GridLayout)contents.getLayout();
contentsGridLayout.numColumns = 3;
GridData contentsGridData = (GridData)contents.getLayoutData();
contentsGridData.horizontalAlignment = SWT.FILL;
contentsGridData.verticalAlignment = SWT.FILL;
Composite choiceComposite = new Composite(contents, SWT.NONE);
{
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.horizontalAlignment = SWT.END;
choiceComposite.setLayoutData(data);
GridLayout layout = new GridLayout();
data.horizontalAlignment = SWT.FILL;
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 1;
choiceComposite.setLayout(layout);
}
Label choiceLabel = new Label(choiceComposite, SWT.NONE);
choiceLabel
.setText(choiceOfValues == null ? EMFEditUIPlugin.INSTANCE.getString("_UI_Value_label") : EMFEditUIPlugin.INSTANCE //$NON-NLS-1$
.getString("_UI_Choices_label")); //$NON-NLS-1$
GridData choiceLabelGridData = new GridData();
choiceLabelGridData.verticalAlignment = SWT.FILL;
choiceLabelGridData.horizontalAlignment = SWT.FILL;
choiceLabel.setLayoutData(choiceLabelGridData);
final Table choiceTable = choiceOfValues == null ? null : new Table(choiceComposite, SWT.MULTI
| SWT.BORDER);
if (choiceTable != null) {
GridData choiceTableGridData = new GridData();
choiceTableGridData.widthHint = Display.getCurrent().getBounds().width / 5;
choiceTableGridData.heightHint = Display.getCurrent().getBounds().height / 3;
choiceTableGridData.verticalAlignment = SWT.FILL;
choiceTableGridData.horizontalAlignment = SWT.FILL;
choiceTableGridData.grabExcessHorizontalSpace = true;
choiceTableGridData.grabExcessVerticalSpace = true;
choiceTable.setLayoutData(choiceTableGridData);
}
final TableViewer choiceTableViewer = choiceOfValues == null ? null : new TableViewer(choiceTable);
if (choiceTableViewer != null) {
choiceTableViewer.setContentProvider(new AdapterFactoryContentProvider(new AdapterFactoryImpl()));
choiceTableViewer.setLabelProvider(labelProvider);
choiceTableViewer.setInput(new ItemProvider(choiceOfValues));
if (filters != null) {
for (ViewerFilter filter : filters) {
choiceTableViewer.addFilter(filter);
}
}
// business rules
List<Button> checkButtons = new ArrayList<Button>();
if (brFilters != null && !brFilters.isEmpty()) {
String currentModel = EEFRuntimeUIMessages.EEFFeatureEditorDialog_current_model_filter_title;
String referencedModels = EEFRuntimeUIMessages.EEFFeatureEditorDialog_referenced_models_filter_title;
String differentContainer = EEFRuntimeUIMessages.EEFFeatureEditorDialog_different_container_filter_title;
for (int i = 0; i < brFilters.size(); i++) {
String filterName = null;
if (brFilters.get(i) instanceof BusinessViewerFilter) {
final BusinessViewerFilter viewerFilter = (BusinessViewerFilter)brFilters.get(i);
Button filteredContent = new Button(choiceComposite, SWT.CHECK);
filterName = viewerFilter.getName();
if (filterName != null) {
filteredContent.setText(filterName);
} else {
filteredContent.setText(EEFRuntimeUIMessages.EEFFeatureEditorDialog_filter_name);
}
filteredContent.setData(viewerFilter);
checkButtons.add(filteredContent);
}
// selection "contenu filtre"
if (filterName != null && !filterName.equals(currentModel)
&& !filterName.equals(referencedModels) && !filterName.equals(differentContainer)) {
checkButtons.get(i).setSelection(true);
choiceTableViewer.addFilter((ViewerFilter)checkButtons.get(i).getData());
for (int j = 0; j < choiceTable.getColumns().length; j++) {
choiceTable.getColumn(j).pack();
}
}
}
// selection listener for business rules
for (final Button b : checkButtons) {
b.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (b.getSelection() == false) {
choiceTableViewer.removeFilter((ViewerFilter)b.getData());
} else {
choiceTableViewer.addFilter((ViewerFilter)b.getData());
}
for (int i = 0; i < choiceTable.getColumns().length; i++) {
choiceTable.getColumn(i).pack();
}
}
});
}
}
}
// We use multi even for a single line because we want to respond to the
// enter key.
//
int style = multiLine ? SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER : SWT.MULTI | SWT.BORDER;
final Text choiceText = choiceOfValues == null ? new Text(choiceComposite, style) : null;
if (choiceText != null) {
GridData choiceTextGridData = new GridData();
choiceTextGridData.widthHint = Display.getCurrent().getBounds().width / 5;
choiceTextGridData.verticalAlignment = SWT.BEGINNING;
choiceTextGridData.horizontalAlignment = SWT.FILL;
choiceTextGridData.grabExcessHorizontalSpace = true;
if (multiLine) {
choiceTextGridData.verticalAlignment = SWT.FILL;
choiceTextGridData.grabExcessVerticalSpace = true;
}
choiceText.setLayoutData(choiceTextGridData);
}
Composite controlButtons = new Composite(contents, SWT.NONE);
GridData controlButtonsGridData = new GridData();
controlButtonsGridData.verticalAlignment = SWT.FILL;
controlButtonsGridData.horizontalAlignment = SWT.FILL;
controlButtons.setLayoutData(controlButtonsGridData);
GridLayout controlsButtonGridLayout = new GridLayout();
controlButtons.setLayout(controlsButtonGridLayout);
new Label(controlButtons, SWT.NONE);
final Button addButton = new Button(controlButtons, SWT.PUSH);
addButton.setText(EMFEditUIPlugin.INSTANCE.getString("_UI_Add_label")); //$NON-NLS-1$
GridData addButtonGridData = new GridData();
addButtonGridData.verticalAlignment = SWT.FILL;
addButtonGridData.horizontalAlignment = SWT.FILL;
addButton.setLayoutData(addButtonGridData);
final Button removeButton = new Button(controlButtons, SWT.PUSH);
removeButton.setText(EMFEditUIPlugin.INSTANCE.getString("_UI_Remove_label")); //$NON-NLS-1$
GridData removeButtonGridData = new GridData();
removeButtonGridData.verticalAlignment = SWT.FILL;
removeButtonGridData.horizontalAlignment = SWT.FILL;
removeButton.setLayoutData(removeButtonGridData);
Label spaceLabel = new Label(controlButtons, SWT.NONE);
GridData spaceLabelGridData = new GridData();
spaceLabelGridData.verticalSpan = 2;
spaceLabel.setLayoutData(spaceLabelGridData);
final Button upButton = new Button(controlButtons, SWT.PUSH);
upButton.setText(EMFEditUIPlugin.INSTANCE.getString("_UI_Up_label")); //$NON-NLS-1$
GridData upButtonGridData = new GridData();
upButtonGridData.verticalAlignment = SWT.FILL;
upButtonGridData.horizontalAlignment = SWT.FILL;
upButton.setLayoutData(upButtonGridData);
final Button downButton = new Button(controlButtons, SWT.PUSH);
downButton.setText(EMFEditUIPlugin.INSTANCE.getString("_UI_Down_label")); //$NON-NLS-1$
GridData downButtonGridData = new GridData();
downButtonGridData.verticalAlignment = SWT.FILL;
downButtonGridData.horizontalAlignment = SWT.FILL;
downButton.setLayoutData(downButtonGridData);
Composite featureComposite = new Composite(contents, SWT.NONE);
{
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.horizontalAlignment = SWT.END;
featureComposite.setLayoutData(data);
GridLayout layout = new GridLayout();
data.horizontalAlignment = SWT.FILL;
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 1;
featureComposite.setLayout(layout);
}
Label featureLabel = new Label(featureComposite, SWT.NONE);
featureLabel.setText(EMFEditUIPlugin.INSTANCE.getString("_UI_Feature_label")); //$NON-NLS-1$
GridData featureLabelGridData = new GridData();
featureLabelGridData.horizontalSpan = 2;
featureLabelGridData.horizontalAlignment = SWT.FILL;
featureLabelGridData.verticalAlignment = SWT.FILL;
featureLabel.setLayoutData(featureLabelGridData);
final Table featureTable = new Table(featureComposite, SWT.MULTI | SWT.BORDER);
GridData featureTableGridData = new GridData();
featureTableGridData.widthHint = Display.getCurrent().getBounds().width / 5;
featureTableGridData.heightHint = Display.getCurrent().getBounds().height / 3;
featureTableGridData.verticalAlignment = SWT.FILL;
featureTableGridData.horizontalAlignment = SWT.FILL;
featureTableGridData.grabExcessHorizontalSpace = true;
featureTableGridData.grabExcessVerticalSpace = true;
featureTable.setLayoutData(featureTableGridData);
final TableViewer featureTableViewer = new TableViewer(featureTable);
featureTableViewer.setContentProvider(contentProvider);
featureTableViewer.setLabelProvider(labelProvider);
featureTableViewer.setInput(values);
if (!values.getChildren().isEmpty()) {
featureTableViewer.setSelection(new StructuredSelection(values.getChildren().get(0)));
}
if (choiceTableViewer != null) {
choiceTableViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
if (addButton.isEnabled()) {
addButton.notifyListeners(SWT.Selection, null);
}
}
});
featureTableViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
if (removeButton.isEnabled()) {
removeButton.notifyListeners(SWT.Selection, null);
}
}
});
}
if (choiceText != null) {
choiceText.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent event) {
if (!multiLine && (event.character == '\r' || event.character == '\n')) {
try {
Object value = EcoreUtil.createFromString((EDataType)eClassifier,
choiceText.getText());
values.getChildren().add(value);
choiceText.setText(""); //$NON-NLS-1$
featureTableViewer.setSelection(new StructuredSelection(value));
event.doit = false;
} catch (RuntimeException exception) {
// Ignore
}
} else if (event.character == '\33') {
choiceText.setText(""); //$NON-NLS-1$
event.doit = false;
}
}
});
}
upButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
IStructuredSelection selection = (IStructuredSelection)featureTableViewer.getSelection();
int minIndex = 0;
for (Iterator<?> i = selection.iterator(); i.hasNext();) {
Object value = i.next();
int index = values.getChildren().indexOf(value);
values.getChildren().move(Math.max(index - 1, minIndex++), value);
}
}
});
downButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
IStructuredSelection selection = (IStructuredSelection)featureTableViewer.getSelection();
int maxIndex = values.getChildren().size() - selection.size();
for (Iterator<?> i = selection.iterator(); i.hasNext();) {
Object value = i.next();
int index = values.getChildren().indexOf(value);
values.getChildren().move(Math.min(index + 1, maxIndex++), value);
}
}
});
addButton.addSelectionListener(new SelectionAdapter() {
// event is null when choiceTableViewer is double clicked
@Override
public void widgetSelected(SelectionEvent event) {
if (choiceTableViewer != null) {
IStructuredSelection selection = (IStructuredSelection)choiceTableViewer.getSelection();
for (Iterator<?> i = selection.iterator(); i.hasNext();) {
Object value = i.next();
if (!values.getChildren().contains(value)) {
values.getChildren().add(value);
}
}
featureTableViewer.setSelection(selection);
} else if (choiceText != null) {
try {
Object value = EcoreUtil.createFromString((EDataType)eClassifier,
choiceText.getText());
values.getChildren().add(value);
choiceText.setText(""); //$NON-NLS-1$
featureTableViewer.setSelection(new StructuredSelection(value));
} catch (RuntimeException exception) {
// Ignore
}
}
}
});
removeButton.addSelectionListener(new SelectionAdapter() {
// event is null when featureTableViewer is double clicked
@Override
public void widgetSelected(SelectionEvent event) {
IStructuredSelection selection = (IStructuredSelection)featureTableViewer.getSelection();
Object firstValue = null;
for (Iterator<?> i = selection.iterator(); i.hasNext();) {
Object value = i.next();
if (firstValue == null) {
firstValue = value;
}
values.getChildren().remove(value);
}
if (!values.getChildren().isEmpty()) {
featureTableViewer.setSelection(new StructuredSelection(values.getChildren().get(0)));
}
if (choiceTableViewer != null) {
choiceTableViewer.setSelection(selection);
} else if (choiceText != null) {
if (firstValue != null) {
String value = EcoreUtil.convertToString((EDataType)eClassifier, firstValue);
choiceText.setText(value);
}
}
}
});
return contents;
}
@Override
protected void okPressed() {
result = new BasicEList<Object>(values.getChildren());
super.okPressed();
}
@Override
public boolean close() {
contentProvider.dispose();
return super.close();
}
public EList<?> getResult() {
return result;
}
}