/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.infra.widgets.editors; import org.eclipse.core.databinding.observable.value.AbstractObservableValue; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.ValueDiff; import org.eclipse.papyrus.infra.tools.databinding.AggregatedObservable; import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider; import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider; import org.eclipse.papyrus.infra.widgets.providers.UnchangedObject; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; /** * A Widget for editing a String with an editable combo. * The combo proposes a set of default values. * * @author Camille Letavernier */ public class StringCombo extends ReferenceCombo { public StringCombo(Composite parent, int style) { super(parent, style); combo.setEditable(true); } public StringCombo(Composite parent, int style, String label) { super(parent, style, label); } @Override public Object getEditableType() { return String.class; } /** * Sets the content provider for this combo. The Content provider should * specify the objects that can be referred by this property * * @param provider */ @Override public void setContentProvider(IStaticContentProvider provider) { if(provider != null) { contentProvider = new EncapsulatedContentProvider(provider); viewer.setContentProvider(contentProvider); viewer.setInput(""); //$NON-NLS-1$ } } @Override protected IObservableValue getObservableValue() { return new CComboObservableValue(); } @Override public String getValue() { //See Bug 359835 : The ComboViewer doesn't support custom values //We can't rely on the ComboViewer#getSelection() method return combo.getText(); } @Override public void setValue(Object value) { //See Bug 359835 : The ComboViewer doesn't support custom values //We can't rely on the ComboViewer#setSelection() method if(value instanceof String) { combo.setText((String)value); } else { combo.setText(""); } } /** * Updates the controls display */ @Override protected void updateControls() { //See Bug 359835 : The ComboViewer doesn't support custom values String value = getValue(); super.updateControls(); setValue(value); } class CComboObservableValue extends AbstractObservableValue implements SelectionListener, KeyListener, FocusListener { private String previousValue; public CComboObservableValue() { previousValue = combo.getText(); combo.addSelectionListener(this); //Selection change combo.addKeyListener(this); //Enter pressed combo.addFocusListener(this); //Focus lost } public Object getValueType() { return String.class; } @Override protected String doGetValue() { return combo.getText(); } @Override protected void doSetValue(Object value) { if(modelProperty instanceof AggregatedObservable && ((AggregatedObservable)modelProperty).hasDifferentValues()) { combo.setText(UnchangedObject.instance.toString()); } else if(value instanceof String) { previousValue = combo.getText(); combo.setText((String)value); } } //Enter pressed public void keyReleased(KeyEvent e) { if((e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) && e.stateMask == SWT.NONE) { doFireChange(); e.doit = false; //Stops the propagation of the event } } //Selection change public void widgetSelected(SelectionEvent e) { doFireChange(); } //Focus lost public void focusLost(FocusEvent e) { doFireChange(); } private void doFireChange() { final String oldValue = previousValue; final String currentValue = previousValue = doGetValue(); fireValueChange(new ValueDiff() { @Override public Object getOldValue() { return oldValue; } @Override public Object getNewValue() { return currentValue; } }); } public void widgetDefaultSelected(SelectionEvent e) { //Nothing } public void focusGained(FocusEvent e) { //Nothing } public void keyPressed(KeyEvent e) { //Nothing } } }