comparison org.eclipse.jface/src/org/eclipse/jface/viewers/TextCellEditor.d @ 12:bc29606a740c

Added dwt-addons in original directory structure of eclipse.org
author Frank Benoit <benoit@tionex.de>
date Sat, 14 Mar 2009 18:23:29 +0100
parents
children 6f068362a363
comparison
equal deleted inserted replaced
11:43904fec5dca 12:bc29606a740c
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13
14 module org.eclipse.jface.viewers.TextCellEditor;
15
16 import org.eclipse.jface.viewers.CellEditor;
17
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.FocusAdapter;
20 import org.eclipse.swt.events.FocusEvent;
21 import org.eclipse.swt.events.KeyAdapter;
22 import org.eclipse.swt.events.KeyEvent;
23 import org.eclipse.swt.events.ModifyEvent;
24 import org.eclipse.swt.events.ModifyListener;
25 import org.eclipse.swt.events.MouseAdapter;
26 import org.eclipse.swt.events.MouseEvent;
27 import org.eclipse.swt.events.SelectionAdapter;
28 import org.eclipse.swt.events.SelectionEvent;
29 import org.eclipse.swt.events.TraverseEvent;
30 import org.eclipse.swt.events.TraverseListener;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Text;
34 import org.eclipse.core.runtime.Assert;
35
36 import java.lang.all;
37 import java.util.Set;
38 import tango.text.convert.Format;
39
40 /**
41 * A cell editor that manages a text entry field.
42 * The cell editor's value is the text string itself.
43 * <p>
44 * This class may be instantiated; it is not intended to be subclassed.
45 * </p>
46 * @noextend This class is not intended to be subclassed by clients.
47 */
48 public class TextCellEditor : CellEditor {
49
50 /**
51 * The text control; initially <code>null</code>.
52 */
53 protected Text text;
54
55 private ModifyListener modifyListener;
56
57 /**
58 * State information for updating action enablement
59 */
60 private bool isSelection = false;
61
62 private bool isDeleteable = false;
63
64 private bool isSelectable = false;
65
66 /**
67 * Default TextCellEditor style
68 * specify no borders on text widget as cell outline in table already
69 * provides the look of a border.
70 */
71 private static const int defaultStyle = SWT.SINGLE;
72
73 /**
74 * Creates a new text string cell editor with no control
75 * The cell editor value is the string itself, which is initially the empty
76 * string. Initially, the cell editor has no cell validator.
77 *
78 * @since 2.1
79 */
80 public this() {
81 setStyle(defaultStyle);
82 }
83
84 /**
85 * Creates a new text string cell editor parented under the given control.
86 * The cell editor value is the string itself, which is initially the empty string.
87 * Initially, the cell editor has no cell validator.
88 *
89 * @param parent the parent control
90 */
91 public this(Composite parent) {
92 this(parent, defaultStyle);
93 }
94
95 /**
96 * Creates a new text string cell editor parented under the given control.
97 * The cell editor value is the string itself, which is initially the empty string.
98 * Initially, the cell editor has no cell validator.
99 *
100 * @param parent the parent control
101 * @param style the style bits
102 * @since 2.1
103 */
104 public this(Composite parent, int style) {
105 super(parent, style);
106 }
107
108 /**
109 * Checks to see if the "deletable" state (can delete/
110 * nothing to delete) has changed and if so fire an
111 * enablement changed notification.
112 */
113 private void checkDeleteable() {
114 bool oldIsDeleteable = isDeleteable;
115 isDeleteable = isDeleteEnabled();
116 if (oldIsDeleteable !is isDeleteable) {
117 fireEnablementChanged(DELETE);
118 }
119 }
120
121 /**
122 * Checks to see if the "selectable" state (can select)
123 * has changed and if so fire an enablement changed notification.
124 */
125 private void checkSelectable() {
126 bool oldIsSelectable = isSelectable;
127 isSelectable = isSelectAllEnabled();
128 if (oldIsSelectable !is isSelectable) {
129 fireEnablementChanged(SELECT_ALL);
130 }
131 }
132
133 /**
134 * Checks to see if the selection state (selection /
135 * no selection) has changed and if so fire an
136 * enablement changed notification.
137 */
138 private void checkSelection() {
139 bool oldIsSelection = isSelection;
140 isSelection = text.getSelectionCount() > 0;
141 if (oldIsSelection !is isSelection) {
142 fireEnablementChanged(COPY);
143 fireEnablementChanged(CUT);
144 }
145 }
146
147 /* (non-Javadoc)
148 * Method declared on CellEditor.
149 */
150 protected override Control createControl(Composite parent) {
151 text = new Text(parent, getStyle());
152 text.addSelectionListener(new class SelectionAdapter {
153 public void widgetDefaultSelected(SelectionEvent e) {
154 handleDefaultSelection(e);
155 }
156 });
157 text.addKeyListener(new class KeyAdapter {
158 // hook key pressed - see PR 14201
159 public void keyPressed(KeyEvent e) {
160 keyReleaseOccured(e);
161
162 // as a result of processing the above call, clients may have
163 // disposed this cell editor
164 if ((getControl() is null) || getControl().isDisposed()) {
165 return;
166 }
167 checkSelection(); // see explanation below
168 checkDeleteable();
169 checkSelectable();
170 }
171 });
172 text.addTraverseListener(new class TraverseListener {
173 public void keyTraversed(TraverseEvent e) {
174 if (e.detail is SWT.TRAVERSE_ESCAPE
175 || e.detail is SWT.TRAVERSE_RETURN) {
176 e.doit = false;
177 }
178 }
179 });
180 // We really want a selection listener but it is not supported so we
181 // use a key listener and a mouse listener to know when selection changes
182 // may have occurred
183 text.addMouseListener(new class MouseAdapter {
184 public void mouseUp(MouseEvent e) {
185 checkSelection();
186 checkDeleteable();
187 checkSelectable();
188 }
189 });
190 text.addFocusListener(new class FocusAdapter {
191 public void focusLost(FocusEvent e) {
192 this.outer.focusLost();
193 }
194 });
195 text.setFont(parent.getFont());
196 text.setBackground(parent.getBackground());
197 text.setText("");//$NON-NLS-1$
198 text.addModifyListener(getModifyListener());
199 return text;
200 }
201
202 /**
203 * The <code>TextCellEditor</code> implementation of
204 * this <code>CellEditor</code> framework method returns
205 * the text string.
206 *
207 * @return the text string
208 */
209 protected override Object doGetValue() {
210 return new ArrayWrapperString(text.getText());
211 }
212
213 /* (non-Javadoc)
214 * Method declared on CellEditor.
215 */
216 protected override void doSetFocus() {
217 if (text !is null) {
218 text.selectAll();
219 text.setFocus();
220 checkSelection();
221 checkDeleteable();
222 checkSelectable();
223 }
224 }
225
226 /**
227 * The <code>TextCellEditor</code> implementation of
228 * this <code>CellEditor</code> framework method accepts
229 * a text string (type <code>String</code>).
230 *
231 * @param value a text string (type <code>String</code>)
232 */
233 protected override void doSetValue(Object value) {
234 Assert.isTrue(text !is null && ( cast(ArrayWrapperString)value ));
235 text.removeModifyListener(getModifyListener());
236 text.setText((cast(ArrayWrapperString)value).array);
237 text.addModifyListener(getModifyListener());
238 }
239
240 /**
241 * Processes a modify event that occurred in this text cell editor.
242 * This framework method performs validation and sets the error message
243 * accordingly, and then reports a change via <code>fireEditorValueChanged</code>.
244 * Subclasses should call this method at appropriate times. Subclasses
245 * may extend or reimplement.
246 *
247 * @param e the SWT modify event
248 */
249 protected void editOccured(ModifyEvent e) {
250 String value = text.getText();
251 if (value is null) {
252 value = "";//$NON-NLS-1$
253 }
254 Object typedValue = new ArrayWrapperString(value);
255 bool oldValidState = isValueValid();
256 bool newValidState = isCorrect(typedValue);
257 if (typedValue is null && newValidState) {
258 Assert.isTrue(false,
259 "Validator isn't limiting the cell editor's type range");//$NON-NLS-1$
260 }
261 if (!newValidState) {
262 // try to insert the current value into the error message.
263 setErrorMessage(Format(getErrorMessage(), value ));
264 }
265 valueChanged(oldValidState, newValidState);
266 }
267
268 /**
269 * Since a text editor field is scrollable we don't
270 * set a minimumSize.
271 */
272 public override LayoutData getLayoutData() {
273 return new LayoutData();
274 }
275
276 /**
277 * Return the modify listener.
278 */
279 private ModifyListener getModifyListener() {
280 if (modifyListener is null) {
281 modifyListener = new class ModifyListener {
282 public void modifyText(ModifyEvent e) {
283 editOccured(e);
284 }
285 };
286 }
287 return modifyListener;
288 }
289
290 /**
291 * Handles a default selection event from the text control by applying the editor
292 * value and deactivating this cell editor.
293 *
294 * @param event the selection event
295 *
296 * @since 3.0
297 */
298 protected void handleDefaultSelection(SelectionEvent event) {
299 // same with enter-key handling code in keyReleaseOccured(e);
300 fireApplyEditorValue();
301 deactivate();
302 }
303
304 /**
305 * The <code>TextCellEditor</code> implementation of this
306 * <code>CellEditor</code> method returns <code>true</code> if
307 * the current selection is not empty.
308 */
309 public override bool isCopyEnabled() {
310 if (text is null || text.isDisposed()) {
311 return false;
312 }
313 return text.getSelectionCount() > 0;
314 }
315
316 /**
317 * The <code>TextCellEditor</code> implementation of this
318 * <code>CellEditor</code> method returns <code>true</code> if
319 * the current selection is not empty.
320 */
321 public override bool isCutEnabled() {
322 if (text is null || text.isDisposed()) {
323 return false;
324 }
325 return text.getSelectionCount() > 0;
326 }
327
328 /**
329 * The <code>TextCellEditor</code> implementation of this
330 * <code>CellEditor</code> method returns <code>true</code>
331 * if there is a selection or if the caret is not positioned
332 * at the end of the text.
333 */
334 public override bool isDeleteEnabled() {
335 if (text is null || text.isDisposed()) {
336 return false;
337 }
338 return text.getSelectionCount() > 0
339 || text.getCaretPosition() < text.getCharCount();
340 }
341
342 /**
343 * The <code>TextCellEditor</code> implementation of this
344 * <code>CellEditor</code> method always returns <code>true</code>.
345 */
346 public override bool isPasteEnabled() {
347 if (text is null || text.isDisposed()) {
348 return false;
349 }
350 return true;
351 }
352
353 /**
354 * Check if save all is enabled
355 * @return true if it is
356 */
357 public bool isSaveAllEnabled() {
358 if (text is null || text.isDisposed()) {
359 return false;
360 }
361 return true;
362 }
363
364 /**
365 * Returns <code>true</code> if this cell editor is
366 * able to perform the select all action.
367 * <p>
368 * This default implementation always returns
369 * <code>false</code>.
370 * </p>
371 * <p>
372 * Subclasses may override
373 * </p>
374 * @return <code>true</code> if select all is possible,
375 * <code>false</code> otherwise
376 */
377 public override bool isSelectAllEnabled() {
378 if (text is null || text.isDisposed()) {
379 return false;
380 }
381 return text.getCharCount() > 0;
382 }
383
384 /**
385 * Processes a key release event that occurred in this cell editor.
386 * <p>
387 * The <code>TextCellEditor</code> implementation of this framework method
388 * ignores when the RETURN key is pressed since this is handled in
389 * <code>handleDefaultSelection</code>.
390 * An exception is made for Ctrl+Enter for multi-line texts, since
391 * a default selection event is not sent in this case.
392 * </p>
393 *
394 * @param keyEvent the key event
395 */
396 protected override void keyReleaseOccured(KeyEvent keyEvent) {
397 if (keyEvent.character is '\r') { // Return key
398 // Enter is handled in handleDefaultSelection.
399 // Do not apply the editor value in response to an Enter key event
400 // since this can be received from the IME when the intent is -not-
401 // to apply the value.
402 // See bug 39074 [CellEditors] [DBCS] canna input mode fires bogus event from Text Control
403 //
404 // An exception is made for Ctrl+Enter for multi-line texts, since
405 // a default selection event is not sent in this case.
406 if (text !is null && !text.isDisposed()
407 && (text.getStyle() & SWT.MULTI) !is 0) {
408 if ((keyEvent.stateMask & SWT.CTRL) !is 0) {
409 super.keyReleaseOccured(keyEvent);
410 }
411 }
412 return;
413 }
414 super.keyReleaseOccured(keyEvent);
415 }
416
417 /**
418 * The <code>TextCellEditor</code> implementation of this
419 * <code>CellEditor</code> method copies the
420 * current selection to the clipboard.
421 */
422 public override void performCopy() {
423 text.copy();
424 }
425
426 /**
427 * The <code>TextCellEditor</code> implementation of this
428 * <code>CellEditor</code> method cuts the
429 * current selection to the clipboard.
430 */
431 public override void performCut() {
432 text.cut();
433 checkSelection();
434 checkDeleteable();
435 checkSelectable();
436 }
437
438 /**
439 * The <code>TextCellEditor</code> implementation of this
440 * <code>CellEditor</code> method deletes the
441 * current selection or, if there is no selection,
442 * the character next character from the current position.
443 */
444 public override void performDelete() {
445 if (text.getSelectionCount() > 0) {
446 // remove the contents of the current selection
447 text.insert(""); //$NON-NLS-1$
448 } else {
449 // remove the next character
450 int pos = text.getCaretPosition();
451 if (pos < text.getCharCount()) {
452 text.setSelection(pos, pos + 1);
453 text.insert(""); //$NON-NLS-1$
454 }
455 }
456 checkSelection();
457 checkDeleteable();
458 checkSelectable();
459 }
460
461 /**
462 * The <code>TextCellEditor</code> implementation of this
463 * <code>CellEditor</code> method pastes the
464 * the clipboard contents over the current selection.
465 */
466 public override void performPaste() {
467 text.paste();
468 checkSelection();
469 checkDeleteable();
470 checkSelectable();
471 }
472
473 /**
474 * The <code>TextCellEditor</code> implementation of this
475 * <code>CellEditor</code> method selects all of the
476 * current text.
477 */
478 public override void performSelectAll() {
479 text.selectAll();
480 checkSelection();
481 checkDeleteable();
482 }
483
484 /**
485 * This implementation of
486 * {@link CellEditor#dependsOnExternalFocusListener()} returns false if the
487 * current instance's class is TextCellEditor, and true otherwise.
488 * Subclasses that hook their own focus listener should override this method
489 * and return false. See also bug 58777.
490 *
491 * @since 3.4
492 */
493 protected override bool dependsOnExternalFocusListener() {
494 return this.classinfo !is TextCellEditor.classinfo;
495 }
496 }