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