001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: */
013: package org.pentaho.designstudio.controls;
014:
015: import java.text.MessageFormat;
016:
017: import org.eclipse.jface.util.Assert;
018: import org.eclipse.jface.viewers.CellEditor;
019: import org.eclipse.swt.SWT;
020: import org.eclipse.swt.custom.CCombo;
021: import org.eclipse.swt.events.FocusAdapter;
022: import org.eclipse.swt.events.FocusEvent;
023: import org.eclipse.swt.events.KeyAdapter;
024: import org.eclipse.swt.events.KeyEvent;
025: import org.eclipse.swt.events.SelectionAdapter;
026: import org.eclipse.swt.events.SelectionEvent;
027: import org.eclipse.swt.events.TraverseEvent;
028: import org.eclipse.swt.events.TraverseListener;
029: import org.eclipse.swt.graphics.GC;
030: import org.eclipse.swt.widgets.Composite;
031: import org.eclipse.swt.widgets.Control;
032:
033: public class CustomComboBoxCellEditor extends CellEditor {
034:
035: /**
036: * The list of items to present in the combo box.
037: */
038: private String[] items;
039:
040: /**
041: * The zero-based index of the selected item.
042: */
043: int selection;
044:
045: /**
046: * The custom combo box control.
047: */
048: protected CCombo comboBox;
049:
050: /**
051: * Default ComboBoxCellEditor style
052: */
053: private static final int defaultStyle = SWT.NONE;
054:
055: /**
056: * Creates a new cell editor with no control and no st of choices. Initially,
057: * the cell editor has no cell validator.
058: *
059: * @since 2.1
060: * @see #setStyle
061: * @see #create
062: * @see #setItems
063: * @see #dispose
064: */
065: public CustomComboBoxCellEditor() {
066: setStyle(defaultStyle);
067: }
068:
069: /**
070: * Creates a new cell editor with a combo containing the given
071: * list of choices and parented under the given control. The cell
072: * editor value is the zero-based index of the selected item.
073: * Initially, the cell editor has no cell validator and
074: * the first item in the list is selected.
075: *
076: * @param parent the parent control
077: * @param items the list of strings for the combo box
078: */
079: public CustomComboBoxCellEditor(Composite parent, String[] items) {
080: this (parent, items, defaultStyle);
081: }
082:
083: /**
084: * Creates a new cell editor with a combo containing the given
085: * list of choices and parented under the given control. The cell
086: * editor value is the zero-based index of the selected item.
087: * Initially, the cell editor has no cell validator and
088: * the first item in the list is selected.
089: *
090: * @param parent the parent control
091: * @param items the list of strings for the combo box
092: * @param style the style bits
093: * @since 2.1
094: */
095: public CustomComboBoxCellEditor(Composite parent, String[] items,
096: int style) {
097: super (parent, style);
098: setItems(items);
099: }
100:
101: /**
102: * Returns the list of choices for the combo box
103: *
104: * @return the list of choices for the combo box
105: */
106: public String[] getItems() {
107: return this .items;
108: }
109:
110: /**
111: * Sets the list of choices for the combo box
112: *
113: * @param items the list of choices for the combo box
114: */
115: public void setItems(String[] items) {
116: Assert.isNotNull(items);
117: this .items = items;
118: populateComboBoxItems();
119: }
120:
121: /* (non-Javadoc)
122: * Method declared on CellEditor.
123: */
124: protected Control createControl(Composite parent) {
125:
126: comboBox = new CCombo(parent, getStyle());
127: comboBox.setFont(parent.getFont());
128:
129: comboBox.addKeyListener(new KeyAdapter() {
130: // hook key pressed - see PR 14201
131: public void keyPressed(KeyEvent e) {
132: keyReleaseOccured(e);
133: }
134: });
135:
136: comboBox.addSelectionListener(new SelectionAdapter() {
137: public void widgetDefaultSelected(SelectionEvent event) {
138: applyEditorValueAndDeactivate();
139: }
140:
141: public void widgetSelected(SelectionEvent event) {
142: selection = comboBox.getSelectionIndex();
143: applyEditorValueAndDeactivate();
144: }
145: });
146:
147: comboBox.addTraverseListener(new TraverseListener() {
148: public void keyTraversed(TraverseEvent e) {
149: if (e.detail == SWT.TRAVERSE_ESCAPE
150: || e.detail == SWT.TRAVERSE_RETURN) {
151: e.doit = false;
152: }
153: }
154: });
155:
156: comboBox.addFocusListener(new FocusAdapter() {
157: public void focusLost(FocusEvent e) {
158: CustomComboBoxCellEditor.this .focusLost();
159: }
160: });
161: return comboBox;
162: }
163:
164: /**
165: * The <code>ComboBoxCellEditor</code> implementation of
166: * this <code>CellEditor</code> framework method returns
167: * the zero-based index of the current selection.
168: *
169: * @return the zero-based index of the current selection wrapped
170: * as an <code>Integer</code>
171: */
172: protected Object doGetValue() {
173: return new Integer(selection);
174: }
175:
176: /* (non-Javadoc)
177: * Method declared on CellEditor.
178: */
179: protected void doSetFocus() {
180: comboBox.setFocus();
181: }
182:
183: /**
184: * The <code>ComboBoxCellEditor</code> implementation of
185: * this <code>CellEditor</code> framework method sets the
186: * minimum width of the cell. The minimum width is 10 characters
187: * if <code>comboBox</code> is not <code>null</code> or <code>disposed</code>
188: * eles it is 60 pixels to make sure the arrow button and some text is visible.
189: * The list of CCombo will be wide enough to show its longest item.
190: */
191: public LayoutData getLayoutData() {
192: LayoutData layoutData = super .getLayoutData();
193: if ((comboBox == null) || comboBox.isDisposed())
194: layoutData.minimumWidth = 60;
195: else {
196: // make the comboBox 10 characters wide
197: GC gc = new GC(comboBox);
198: layoutData.minimumWidth = (gc.getFontMetrics()
199: .getAverageCharWidth() * 10) + 10;
200: gc.dispose();
201: }
202: return layoutData;
203: }
204:
205: /**
206: * The <code>ComboBoxCellEditor</code> implementation of
207: * this <code>CellEditor</code> framework method
208: * accepts a zero-based index of a selection.
209: *
210: * @param value the zero-based index of the selection wrapped
211: * as an <code>Integer</code>
212: */
213: protected void doSetValue(Object value) {
214: Assert.isTrue(comboBox != null && (value instanceof Integer));
215: selection = ((Integer) value).intValue();
216: comboBox.select(selection);
217: }
218:
219: /**
220: * Updates the list of choices for the combo box for the current control.
221: */
222: private void populateComboBoxItems() {
223: if (comboBox != null && items != null) {
224: comboBox.removeAll();
225: for (int i = 0; i < items.length; i++)
226: comboBox.add(items[i], i);
227:
228: setValueValid(true);
229: selection = 0;
230: }
231: }
232:
233: /**
234: * Applies the currently selected value and deactiavates the cell editor
235: */
236: void applyEditorValueAndDeactivate() {
237: // must set the selection before getting value
238: selection = comboBox.getSelectionIndex();
239: Object newValue = doGetValue();
240: markDirty();
241: boolean isValid = isCorrect(newValue);
242: setValueValid(isValid);
243: if (!isValid) {
244: // try to insert the current value into the error message.
245: setErrorMessage(MessageFormat.format(getErrorMessage(),
246: new Object[] { items[selection] }));
247: }
248: fireApplyEditorValue();
249: deactivate();
250: }
251:
252: /*
253: * (non-Javadoc)
254: * @see org.eclipse.jface.viewers.CellEditor#focusLost()
255: */
256: protected void focusLost() {
257: if (isActivated()) {
258: applyEditorValueAndDeactivate();
259: }
260: }
261:
262: /*
263: * (non-Javadoc)
264: * @see org.eclipse.jface.viewers.CellEditor#keyReleaseOccured(org.eclipse.swt.events.KeyEvent)
265: */
266: protected void keyReleaseOccured(KeyEvent keyEvent) {
267: if (keyEvent.character == '\u001b') { // Escape character
268: fireCancelEditor();
269: } else if (keyEvent.character == '\t') { // tab key
270: applyEditorValueAndDeactivate();
271: }
272: }
273: }
|