Skip to content

Content of file EnumCellEditor.java

/*******************************************************************************
 * Copyright (c) 2017 EclipseSource Muenchen GmbH and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * Edgar Mueller - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.ecp.view.spi.table.swt;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.INativePropertyListener;
import org.eclipse.core.databinding.property.ISimplePropertyListener;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.core.databinding.property.value.SimpleValueProperty;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPEnumCellEditor;
import org.eclipse.emf.ecp.view.internal.core.swt.ComboUtil;
import org.eclipse.emf.ecp.view.internal.core.swt.MatchItemComboViewer;
import org.eclipse.emf.ecp.view.internal.table.swt.FigureUtilities;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emfforms.common.Optional;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
 * Generic {@link org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor ECPCellEditor} which is
 * applicable for all {@link EAttribute EAttributes} with a Single {@link EEnum} data type.
 *
 * @since 1.13
 * @deprecated Use {@link ItemProviderEnumCellEditor} instead
 */
@Deprecated
public class EnumCellEditor extends ECPEnumCellEditor {

	private static final String EMPTY = ""; //$NON-NLS-1$
	private EEnum eEnum;
	private MatchItemComboViewer viewer;
	private int minWidth;
	private String text;
	private EnumCellEditorLabelProvider labelProvider;

	/**
	 * Default constructor.
	 *
	 * @param parent the parent
	 */
	public EnumCellEditor(Composite parent) {
		super(parent);
	}

	/**
	 * Constructor allowing to specify a SWT style.
	 *
	 * @param parent the parent
	 * @param style the SWT style
	 */
	public EnumCellEditor(Composite parent, int style) {
		super(parent, style);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getValueProperty()
	 */
	@Override
	public IValueProperty getValueProperty() {
return new ComboValueProperty(); } /** * * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#instantiate(org.eclipse.emf.ecore.EStructuralFeature, * org.eclipse.emf.ecp.view.spi.context.ViewModelContext) */ @Override public void instantiate(EStructuralFeature feature, ViewModelContext viewModelContext) { final EAttribute attribute = EAttribute.class.cast(feature); eEnum = EEnum.class.cast(attribute.getEAttributeType()); final int literalsSize = getELiterals().size(); viewer.getCCombo().setVisibleItemCount(literalsSize <= 25 ? literalsSize : 25); final Point emptyViewerSize = viewer.getCCombo().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); minWidth = 50; for (final EEnumLiteral literal : getELiterals()) { final String string = literal.getInstance().getLiteral(); final int newWidth = FigureUtilities.getTextWidth(string, viewer.getCCombo().getFont()); if (newWidth > minWidth) { minWidth = newWidth; } } minWidth += emptyViewerSize.x; } /** * * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getFormatedString(java.lang.Object) */ @Override public String getFormatedString(Object value) { if (value != null) { final Enumerator enumerator = (Enumerator) value; return enumerator.getLiteral(); } return EMPTY; } /** * * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getColumnWidthWeight() */ @Override public int getColumnWidthWeight() { return 100; } /** * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getMinWidth() */ @Override public int getMinWidth() { return minWidth; } /** * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getImage(java.lang.Object) */ @Override public Image getImage(Object value) { return null; } /** * * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getTargetToModelStrategy(org.eclipse.core.databinding.DataBindingContext) */ @Override public UpdateValueStrategy getTargetToModelStrategy(DataBindingContext databindingContext) { return new TargetToModelStrategy(); } /** * * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#getModelToTargetStrategy(org.eclipse.core.databinding.DataBindingContext) */ @Override public UpdateValueStrategy getModelToTargetStrategy(DataBindingContext databindingContext) { return new ModelToTargetStrategy(); } /** * * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#getLayoutData() */ @Override public LayoutData getLayoutData() { final LayoutData data = new LayoutData(); data.minimumWidth = 0; return data; } /** * * {@inheritDoc} * * @see org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor#setEditable(boolean) */ @Override public void setEditable(boolean editable) { viewer.getCCombo().setEnabled(editable); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#createControl(org.eclipse.swt.widgets.Composite) */ @Override protected Control createControl(Composite parent) { viewer = new MatchItemComboViewer(new CCombo(parent, SWT.NONE)) { @Override public void onEnter() { final int selectedIndex = ComboUtil.getClosestMatchIndex(getCCombo().getItems(), getBuffer().asString()); if (!getBuffer().isEmpty() && selectedIndex > -1) { final String closestMatch = getCCombo().getItems()[selectedIndex]; final Optional<SelectedEnumeratorMapping> selectedMappping = SelectedEnumeratorMapping .findLiteral((SelectedEnumeratorMapping[]) getInput(), closestMatch); if (selectedMappping.isPresent()) { setSelection(new StructuredSelection(selectedMappping.get())); } } else { setClosestMatch(getCCombo().getText()); } focusLost(); } /** * {@inheritDoc} * * @see org.eclipse.emf.ecp.view.internal.core.swt.MatchItemComboViewer#onEscape() */ @Override protected void onEscape() { EnumCellEditor.this.fireCancelEditor(); } }; final CCombo combo = viewer.getCCombo(); GridDataFactory.fillDefaults().grab(true, false).applyTo(combo); labelProvider = new EnumCellEditorLabelProvider(); viewer.setContentProvider(ArrayContentProvider.getInstance()); viewer.setLabelProvider(labelProvider); return combo; } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#doGetValue() */ @Override protected Object doGetValue() { return viewer.getInput(); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#doSetFocus() */ @Override protected void doSetFocus() { final CCombo combo = viewer.getCCombo(); if (combo == null || combo.isDisposed()) { return; } combo.setFocus(); // Remove text selection and move the cursor to the end. final String text = combo.getText(); if (text != null) { combo.setSelection(new Point(text.length(), text.length())); } } /** * * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#activate(org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent) */ @Override public void activate(ColumnViewerEditorActivationEvent actEvent) { super.activate(actEvent); if (actEvent.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED) { final CCombo control = (CCombo) getControl(); if (control != null && Character.isLetterOrDigit(actEvent.character)) { viewer.getBuffer().reset(); // key pressed is not fired during activation viewer.getBuffer().addLast(actEvent.character); } } } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#deactivate() */ @Override public void deactivate() { final CCombo control = (CCombo) getControl(); if (control != null && !control.isDisposed()) { text = control.getText(); text = text == null ? EMPTY : text; } final SelectedEnumeratorMapping[] selectedMapping = (SelectedEnumeratorMapping[]) viewer.getInput(); if (selectedMapping != null) { final Optional<SelectedEnumeratorMapping> sel = SelectedEnumeratorMapping.findLiteral(selectedMapping, text); if (sel.isPresent()) { sel.get().setSelected(true); viewer.setSelection(new StructuredSelection(sel.get())); } } text = EMPTY; viewer.getBuffer().reset(); // As the same cell editor is used for all the rows. // We need to reset the value to avoid the values are cached. if (control != null && !control.isDisposed()) { control.setText(""); //$NON-NLS-1$ } super.deactivate(); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.CellEditor#doSetValue(java.lang.Object) */ @Override protected void doSetValue(Object value) { viewer.setInput(value); } private String getComboText(SelectedEnumeratorMapping[] input) { final Optional<Enumerator> selected = SelectedEnumeratorMapping.findSelected(input); if (selected.isPresent()) { return selected.get().getLiteral(); } return EMPTY; } /** * Returns the {@link EEnum} is cell editor responsible for. * * @return the enum */ @Override public EEnum getEEnum() { return eEnum; } /** * Label provider for the drop down. * * */ private class EnumCellEditorLabelProvider extends LabelProvider { /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { final SelectedEnumeratorMapping mapping = (SelectedEnumeratorMapping) element; return mapping.getEnumerator().getLiteral(); } } /** * Target to model update strategy. * * */ private class TargetToModelStrategy extends EMFUpdateValueStrategy { /* * (non-Javadoc) * @see org.eclipse.core.databinding.UpdateValueStrategy#convert(java.lang.Object) */ @Override public Object convert(Object value) { final SelectedEnumeratorMapping[] mapping = (SelectedEnumeratorMapping[]) value; final Optional<Enumerator> selected = SelectedEnumeratorMapping.findSelected(mapping); return selected.orNull(); } } /** * Model to target update strategy. * * */ private class ModelToTargetStrategy extends EMFUpdateValueStrategy { @Override public Object convert(Object value) { final Enumerator enumerator = (Enumerator) value; final SelectedEnumeratorMapping[] mapping = SelectedEnumeratorMapping.createFromList(getELiterals()); SelectedEnumeratorMapping.select(mapping, enumerator); return mapping; } } /** * Value property working on the combo. * */ private class ComboValueProperty extends SimpleValueProperty { @Override public Object getValueType() { return CCombo.class; } @Override protected Object doGetValue(Object source) { return EnumCellEditor.this.getValue(); } @Override protected void doSetValue(Object source, Object value) { EnumCellEditor.this.doSetValue(value); } @Override public IObservableValue observe(Object source) { return new ComboObservableValue(); } @Override public INativePropertyListener adaptListener(ISimplePropertyListener listener) { return null; } } /** * Observable value for the combo. * */ private class ComboObservableValue extends AbstractObservableValue { private final EnumSelectionAdapter selectionAdapter; /** * Default Constructor. */ ComboObservableValue() { selectionAdapter = new EnumSelectionAdapter(); viewer.addSelectionChangedListener(selectionAdapter); } /** * {@inheritDoc} * * @see org.eclipse.core.databinding.observable.value.IObservableValue#getValueType() */ @Override public Object getValueType() { return null; } /** * {@inheritDoc} * * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#doGetValue() */ @Override protected Object doGetValue() { return viewer.getInput(); } /** * {@inheritDoc} * * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#doSetValue(java.lang.Object) */ @Override protected void doSetValue(Object value) { viewer.setInput(value); viewer.getCCombo().setText(getComboText((SelectedEnumeratorMapping[]) value)); } /** * {@inheritDoc} * * @see org.eclipse.core.databinding.observable.AbstractObservable#dispose() */ @Override public synchronized void dispose() { viewer.removeSelectionChangedListener(selectionAdapter); super.dispose(); } /** * Selection adapter for the combo. * * */ private class EnumSelectionAdapter implements ISelectionChangedListener { @Override public void selectionChanged(SelectionChangedEvent event) { final SelectedEnumeratorMapping mapping = (SelectedEnumeratorMapping) ((IStructuredSelection) event .getSelection()) .getFirstElement(); if (mapping == null) { return; } final SelectedEnumeratorMapping[] allMapping = (SelectedEnumeratorMapping[]) viewer.getInput(); SelectedEnumeratorMapping.deselectAll(allMapping); mapping.setSelected(!mapping.isSelected()); viewer.getCCombo().setText(getComboText((SelectedEnumeratorMapping[]) viewer.getInput())); viewer.update(mapping, null); fireValueChange(Diffs.createValueDiff(!mapping.isSelected(), mapping.isSelected())); } } } }