Skip to content

Content of file DataTypeControl.java

/*******************************************************************************
 * Copyright (c) 2011-2013 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:
 * Clemens Elflein - initial API and implementation
 ******************************************************************************/
package org.eclipse.emfforms.internal.editor.ecore.controls;

import java.util.List;

import javax.inject.Inject;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.conversion.Converter;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlJFaceViewerSWTRenderer;
import org.eclipse.emf.ecp.view.spi.model.VControl;
import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
import org.eclipse.emfforms.spi.editor.helpers.ResourceSetHelpers;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.fieldassist.AutoCompleteField; import org.eclipse.jface.fieldassist.ComboContentAdapter; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; /** * A control to select the DataType for ETypedElements. * * This control assists the user while selecting EDataTypes. * For example you can type "String" in order to select "EString" * */ public class DataTypeControl extends SimpleControlJFaceViewerSWTRenderer { /** * Default constructor. * * @param vElement the view model element to be rendered * @param viewContext the view context * @param reportService The {@link ReportService} * @param emfFormsDatabinding The {@link EMFFormsDatabinding} * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider} * @param vtViewTemplateProvider The {@link VTViewTemplateProvider} */ @Inject public DataTypeControl(VControl vElement, ViewModelContext viewContext, ReportService reportService, EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider, VTViewTemplateProvider vtViewTemplateProvider) { super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider); } @Override protected String getUnsetText() { return "No EDataType set!"; } @Override protected Viewer createJFaceViewer(Composite parent) { final ComboViewer combo = new ComboViewer(parent, SWT.DROP_DOWN); Class<?> type = EClassifier.class; boolean includeEcorePackage = false; if (getViewModelContext().getDomainModel() instanceof EAttribute) { type = EDataType.class; includeEcorePackage = true; } else if (getViewModelContext().getDomainModel() instanceof EReference) { type = EClass.class; includeEcorePackage = false; } else if (getViewModelContext().getDomainModel() instanceof EOperation) { includeEcorePackage = true; } else if (getViewModelContext().getDomainModel() instanceof EParameter) { includeEcorePackage = true; } final List<?> classifiers = ResourceSetHelpers.findAllOfTypeInResourceSet( getViewModelContext().getDomainModel(), type, includeEcorePackage); combo.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { if (element instanceof EClassifier) { return ((EClassifier) element).getName(); } return super.getText(element); } }); combo.setContentProvider(new ArrayContentProvider()); combo.setInput(classifiers.toArray()); new AutoCompleteField(combo.getCombo(), new ComboContentAdapter(), combo.getCombo().getItems()); return combo; } @Override protected Binding[] createBindings(final Viewer viewer) throws DatabindingFailedException { final Binding binding = getDataBindingContext().bindValue( WidgetProperties.text().observe( ((ComboViewer) viewer).getCombo()), getModelValue(), new EMFUpdateValueStrategy().setConverter(new Converter( String.class, EClassifier.class) { @Override public Object convert(Object fromObject) { // We want the result for such a request to be null, not a DataType with null name (can occur) if (fromObject == null) { return null; } final Object[] classifiers = (Object[]) ((ComboViewer) viewer).getInput(); for (int i = 0; i < classifiers.length; i++) { if (fromObject .equals(((EClassifier) classifiers[i]) .getName())) { return classifiers[i]; } } // If we haven't found the DataType yet, Try adding an E to the Input and search again. // So we find EString even if String was searched. final String fromStringWithE = "E" + fromObject.toString(); for (int i = 0; i < classifiers.length; i++) { if (fromStringWithE.equals(((EClassifier) classifiers[i]).getName())) { return classifiers[i]; } } return null; } }), new EMFUpdateValueStrategy().setConverter(new Converter(EClassifier.class, String.class) { @Override public Object convert(Object fromObject) { if (fromObject == null) { return ""; } return ((EClassifier) fromObject).getName(); } })); // TODO: this update creates a nasty usability bug! /* * ((ComboViewer)viewer).getCombo().addFocusListener(new FocusListener() { * @Override * public void focusLost(FocusEvent e) { * binding.updateModelToTarget(); * } * @Override * public void focusGained(FocusEvent e) { * } * }); */ return new Binding[] { binding }; } @Override protected boolean isUnsettable() { // We unset the property via databinding as soon as the input is invalid return false; } }