/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.attribute.editor; import java.text.MessageFormat; import org.eclipse.jface.util.Assert; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; /** * @author aleksey * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class ComboBoxCellEditorEx extends CellEditor { private CCombo combo; private String[] items = new String[0]; private Object value = null; private int selection; private boolean skipDeactivate = Boolean.FALSE.booleanValue(); public ComboBoxCellEditorEx() { super(); } public ComboBoxCellEditorEx(Composite parent) { create(parent); } public ComboBoxCellEditorEx(Composite parent, int style) { this.setStyle(style); create(parent); } public ComboBoxCellEditorEx(Composite parent, String[] items, int style) { if (items!=null) this.items = items; this.setStyle(style); create(parent); } public void activate() { super.activate(); } public void create(Composite parent) { super.create(parent); } public void deactivate() { if (!this.skipDeactivate) super.deactivate(); } protected Control createControl(Composite parent) { combo = new CCombo(parent, getStyle()); combo.setItems(items); combo.setFont(parent.getFont()); combo.addKeyListener(new KeyAdapter() { // hook key pressed - see PR 14201 public void keyPressed(KeyEvent e) { keyReleaseOccured(e); } }); combo.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent event) { widgetSelected(event); } public void widgetSelected(SelectionEvent event) { if(!isActivated()) return; int i = combo.getSelectionIndex(); if(i >= 0) combo.setText(combo.getItem(i)); applyEditorValueAndDeactivate(); } }); combo.addTraverseListener(new TraverseListener() { public void keyTraversed(TraverseEvent e) { if (e.detail == SWT.TRAVERSE_ESCAPE || e.detail == SWT.TRAVERSE_RETURN) { e.doit = false; } } }); combo.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { ComboBoxCellEditorEx.this.focusLost(); } }); combo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { check(); } }); setValueValid(true); return combo; } protected boolean check() { String value = combo.getText(); if (value == null) { value = "";//$NON-NLS-1$ } Object typedValue = value; boolean oldValidState = isValueValid(); boolean newValidState = isCorrect(typedValue); if (typedValue == null && newValidState) { Assert.isTrue(false, "Validator isn't limiting the cell editor's type range");//$NON-NLS-1$ } if (!newValidState) { // try to insert the current value into the error message. setErrorMessage(MessageFormat.format(getErrorMessage(), new Object[] { value })); } valueChanged(oldValidState, newValidState); return newValidState; } protected Object doGetValue() { return this.value; } protected void doSetFocus() { if (combo!=null && !combo.isDisposed()) combo.setFocus(); } public void focusLost() { if(check()) { value = combo.getText(); } // valueChanged(true, true); this.fireApplyEditorValue(); super.focusLost(); } public Control getControl() { return super.getControl(); } ///fix bug 8473 ///private boolean forceFocus = Boolean.FALSE.booleanValue(); protected void fireApplyEditorValue() { super.fireApplyEditorValue(); ///if (forceFocus) return; ///forceFocus = Boolean.TRUE.booleanValue(); ///if(combo != null && !combo.isDisposed()) combo.forceFocus(); ///forceFocus = Boolean.FALSE.booleanValue(); } protected void fireCancelEditor() { skipDeactivate = Boolean.TRUE.booleanValue(); super.fireCancelEditor(); skipDeactivate = Boolean.FALSE.booleanValue(); deactivate(); } protected void doSetValue(Object value) { this.value = value; int selection; if (value instanceof Integer) { selection = ((Integer) value).intValue(); combo.select(selection); } if (value instanceof String) { selection = findIndex(value); if(selection < 0) combo.setText(value.toString()); else combo.select(selection); } doSetFocus(); } private int findIndex(Object value) { String[] items = getItems(); if(items == null) return 0; for (int i = 0;i < items.length; i++) { if(items[i].equals(value)) return i; } return -1; } public String[] getItems() { return this.items; } public void setItems(String[] items) { Assert.isNotNull(items); this.items = items; populateComboBoxItems(); } private void populateComboBoxItems() { if (combo != null && items != null) { combo.removeAll(); for (int i = 0; i < items.length; i++) combo.add(items[i], i); setValueValid(true); selection = 0; } } private void applyEditorValueAndDeactivate() { Object newValue = combo.getText(); markDirty(); boolean isValid = isCorrect(newValue); setValueValid(isValid); if (!isValid) { // try to insert the current value into the error message. setErrorMessage( MessageFormat.format(getErrorMessage(), new Object[] {items[selection]})); } else { this.value = newValue; } fireApplyEditorValue(); deactivate(); } }