Mercurial > projects > dwt2
comparison org.eclipse.jface/src/org/eclipse/jface/preference/StringFieldEditor.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 |
comparison
equal
deleted
inserted
replaced
11:43904fec5dca | 12:bc29606a740c |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 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 module org.eclipse.jface.preference.StringFieldEditor; | |
14 | |
15 import org.eclipse.jface.preference.FieldEditor; | |
16 | |
17 import org.eclipse.swt.SWT; | |
18 import org.eclipse.swt.events.DisposeEvent; | |
19 import org.eclipse.swt.events.DisposeListener; | |
20 import org.eclipse.swt.events.FocusAdapter; | |
21 import org.eclipse.swt.events.FocusEvent; | |
22 import org.eclipse.swt.events.KeyAdapter; | |
23 import org.eclipse.swt.events.KeyEvent; | |
24 import org.eclipse.swt.graphics.GC; | |
25 import org.eclipse.swt.graphics.Point; | |
26 import org.eclipse.swt.layout.GridData; | |
27 import org.eclipse.swt.widgets.Composite; | |
28 import org.eclipse.swt.widgets.Text; | |
29 import org.eclipse.core.runtime.Assert; | |
30 import org.eclipse.jface.resource.JFaceResources; | |
31 | |
32 import java.lang.all; | |
33 import java.util.Set; | |
34 | |
35 /** | |
36 * A field editor for a string type preference. | |
37 * <p> | |
38 * This class may be used as is, or subclassed as required. | |
39 * </p> | |
40 */ | |
41 public class StringFieldEditor : FieldEditor { | |
42 | |
43 alias FieldEditor.showErrorMessage showErrorMessage; | |
44 /** | |
45 * Validation strategy constant (value <code>0</code>) indicating that | |
46 * the editor should perform validation after every key stroke. | |
47 * | |
48 * @see #setValidateStrategy | |
49 */ | |
50 public static const int VALIDATE_ON_KEY_STROKE = 0; | |
51 | |
52 /** | |
53 * Validation strategy constant (value <code>1</code>) indicating that | |
54 * the editor should perform validation only when the text widget | |
55 * loses focus. | |
56 * | |
57 * @see #setValidateStrategy | |
58 */ | |
59 public static const int VALIDATE_ON_FOCUS_LOST = 1; | |
60 | |
61 /** | |
62 * Text limit constant (value <code>-1</code>) indicating unlimited | |
63 * text limit and width. | |
64 */ | |
65 public static int UNLIMITED = -1; | |
66 | |
67 /** | |
68 * Cached valid state. | |
69 */ | |
70 private bool isValid_; | |
71 | |
72 /** | |
73 * Old text value. | |
74 * @since 3.4 this field is protected. | |
75 */ | |
76 protected String oldValue; | |
77 | |
78 /** | |
79 * The text field, or <code>null</code> if none. | |
80 */ | |
81 Text textField; | |
82 | |
83 /** | |
84 * Width of text field in characters; initially unlimited. | |
85 */ | |
86 private int widthInChars; | |
87 | |
88 /** | |
89 * Text limit of text field in characters; initially unlimited. | |
90 */ | |
91 private int textLimit; | |
92 | |
93 /** | |
94 * The error message, or <code>null</code> if none. | |
95 */ | |
96 private String errorMessage; | |
97 | |
98 /** | |
99 * Indicates whether the empty string is legal; | |
100 * <code>true</code> by default. | |
101 */ | |
102 private bool emptyStringAllowed = true; | |
103 | |
104 /** | |
105 * The validation strategy; | |
106 * <code>VALIDATE_ON_KEY_STROKE</code> by default. | |
107 */ | |
108 private int validateStrategy; | |
109 | |
110 /** | |
111 * Creates a new string field editor | |
112 */ | |
113 protected this() { | |
114 widthInChars = UNLIMITED; | |
115 textLimit = UNLIMITED; | |
116 validateStrategy = VALIDATE_ON_KEY_STROKE; | |
117 } | |
118 | |
119 /** | |
120 * Creates a string field editor. | |
121 * Use the method <code>setTextLimit</code> to limit the text. | |
122 * | |
123 * @param name the name of the preference this field editor works on | |
124 * @param labelText the label text of the field editor | |
125 * @param width the width of the text input field in characters, | |
126 * or <code>UNLIMITED</code> for no limit | |
127 * @param strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform | |
128 * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to | |
129 * perform validation only after the text has been typed in | |
130 * @param parent the parent of the field editor's control | |
131 * @since 2.0 | |
132 */ | |
133 public this(String name, String labelText, int width, | |
134 int strategy, Composite parent) { | |
135 this(); | |
136 init(name, labelText); | |
137 widthInChars = width; | |
138 setValidateStrategy(strategy); | |
139 isValid_ = false; | |
140 errorMessage = JFaceResources | |
141 .getString("StringFieldEditor.errorMessage");//$NON-NLS-1$ | |
142 createControl(parent); | |
143 } | |
144 | |
145 /** | |
146 * Creates a string field editor. | |
147 * Use the method <code>setTextLimit</code> to limit the text. | |
148 * | |
149 * @param name the name of the preference this field editor works on | |
150 * @param labelText the label text of the field editor | |
151 * @param width the width of the text input field in characters, | |
152 * or <code>UNLIMITED</code> for no limit | |
153 * @param parent the parent of the field editor's control | |
154 */ | |
155 public this(String name, String labelText, int width, | |
156 Composite parent) { | |
157 this(name, labelText, width, VALIDATE_ON_KEY_STROKE, parent); | |
158 } | |
159 | |
160 /** | |
161 * Creates a string field editor of unlimited width. | |
162 * Use the method <code>setTextLimit</code> to limit the text. | |
163 * | |
164 * @param name the name of the preference this field editor works on | |
165 * @param labelText the label text of the field editor | |
166 * @param parent the parent of the field editor's control | |
167 */ | |
168 public this(String name, String labelText, Composite parent) { | |
169 this(name, labelText, UNLIMITED, parent); | |
170 } | |
171 | |
172 /* (non-Javadoc) | |
173 * Method declared on FieldEditor. | |
174 */ | |
175 protected override void adjustForNumColumns(int numColumns) { | |
176 GridData gd = cast(GridData) textField.getLayoutData(); | |
177 gd.horizontalSpan = numColumns - 1; | |
178 // We only grab excess space if we have to | |
179 // If another field editor has more columns then | |
180 // we assume it is setting the width. | |
181 gd.grabExcessHorizontalSpace = gd.horizontalSpan is 1; | |
182 } | |
183 | |
184 /** | |
185 * Checks whether the text input field contains a valid value or not. | |
186 * | |
187 * @return <code>true</code> if the field value is valid, | |
188 * and <code>false</code> if invalid | |
189 */ | |
190 protected bool checkState() { | |
191 bool result = false; | |
192 if (emptyStringAllowed) { | |
193 result = true; | |
194 } | |
195 | |
196 if (textField is null) { | |
197 result = false; | |
198 } | |
199 | |
200 String txt = textField.getText(); | |
201 | |
202 result = (txt.trim().length > 0) || emptyStringAllowed; | |
203 | |
204 // call hook for subclasses | |
205 result = result && doCheckState(); | |
206 | |
207 if (result) { | |
208 clearErrorMessage(); | |
209 } else { | |
210 showErrorMessage(errorMessage); | |
211 } | |
212 | |
213 return result; | |
214 } | |
215 | |
216 /** | |
217 * Hook for subclasses to do specific state checks. | |
218 * <p> | |
219 * The default implementation of this framework method does | |
220 * nothing and returns <code>true</code>. Subclasses should | |
221 * override this method to specific state checks. | |
222 * </p> | |
223 * | |
224 * @return <code>true</code> if the field value is valid, | |
225 * and <code>false</code> if invalid | |
226 */ | |
227 protected bool doCheckState() { | |
228 return true; | |
229 } | |
230 | |
231 /** | |
232 * Fills this field editor's basic controls into the given parent. | |
233 * <p> | |
234 * The string field implementation of this <code>FieldEditor</code> | |
235 * framework method contributes the text field. Subclasses may override | |
236 * but must call <code>super.doFillIntoGrid</code>. | |
237 * </p> | |
238 */ | |
239 protected override void doFillIntoGrid(Composite parent, int numColumns) { | |
240 getLabelControl(parent); | |
241 | |
242 textField = getTextControl(parent); | |
243 GridData gd = new GridData(); | |
244 gd.horizontalSpan = numColumns - 1; | |
245 if (widthInChars !is UNLIMITED) { | |
246 GC gc = new GC(textField); | |
247 try { | |
248 Point extent = gc.textExtent("X");//$NON-NLS-1$ | |
249 gd.widthHint = widthInChars * extent.x; | |
250 } finally { | |
251 gc.dispose(); | |
252 } | |
253 } else { | |
254 gd.horizontalAlignment = GridData.FILL; | |
255 gd.grabExcessHorizontalSpace = true; | |
256 } | |
257 textField.setLayoutData(gd); | |
258 } | |
259 | |
260 /* (non-Javadoc) | |
261 * Method declared on FieldEditor. | |
262 */ | |
263 protected override void doLoad() { | |
264 if (textField !is null) { | |
265 String value = getPreferenceStore().getString(getPreferenceName()); | |
266 textField.setText(value); | |
267 oldValue = value; | |
268 } | |
269 } | |
270 | |
271 /* (non-Javadoc) | |
272 * Method declared on FieldEditor. | |
273 */ | |
274 protected override void doLoadDefault() { | |
275 if (textField !is null) { | |
276 String value = getPreferenceStore().getDefaultString( | |
277 getPreferenceName()); | |
278 textField.setText(value); | |
279 } | |
280 valueChanged(); | |
281 } | |
282 | |
283 /* (non-Javadoc) | |
284 * Method declared on FieldEditor. | |
285 */ | |
286 protected override void doStore() { | |
287 getPreferenceStore().setValue(getPreferenceName(), textField.getText()); | |
288 } | |
289 | |
290 /** | |
291 * Returns the error message that will be displayed when and if | |
292 * an error occurs. | |
293 * | |
294 * @return the error message, or <code>null</code> if none | |
295 */ | |
296 public String getErrorMessage() { | |
297 return errorMessage; | |
298 } | |
299 | |
300 /* (non-Javadoc) | |
301 * Method declared on FieldEditor. | |
302 */ | |
303 public override int getNumberOfControls() { | |
304 return 2; | |
305 } | |
306 | |
307 /** | |
308 * Returns the field editor's value. | |
309 * | |
310 * @return the current value | |
311 */ | |
312 public String getStringValue() { | |
313 if (textField !is null) { | |
314 return textField.getText(); | |
315 } | |
316 | |
317 return getPreferenceStore().getString(getPreferenceName()); | |
318 } | |
319 | |
320 /** | |
321 * Returns this field editor's text control. | |
322 * | |
323 * @return the text control, or <code>null</code> if no | |
324 * text field is created yet | |
325 */ | |
326 protected Text getTextControl() { | |
327 return textField; | |
328 } | |
329 | |
330 /** | |
331 * Returns this field editor's text control. | |
332 * <p> | |
333 * The control is created if it does not yet exist | |
334 * </p> | |
335 * | |
336 * @param parent the parent | |
337 * @return the text control | |
338 */ | |
339 public Text getTextControl(Composite parent) { | |
340 if (textField is null) { | |
341 textField = new Text(parent, SWT.SINGLE | SWT.BORDER); | |
342 textField.setFont(parent.getFont()); | |
343 switch (validateStrategy) { | |
344 case VALIDATE_ON_KEY_STROKE: | |
345 textField.addKeyListener(new class KeyAdapter { | |
346 | |
347 /* (non-Javadoc) | |
348 * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) | |
349 */ | |
350 public void keyReleased(KeyEvent e) { | |
351 valueChanged(); | |
352 } | |
353 }); | |
354 | |
355 break; | |
356 case VALIDATE_ON_FOCUS_LOST: | |
357 textField.addKeyListener(new class KeyAdapter { | |
358 public void keyPressed(KeyEvent e) { | |
359 clearErrorMessage(); | |
360 } | |
361 }); | |
362 textField.addFocusListener(new class FocusAdapter { | |
363 public void focusGained(FocusEvent e) { | |
364 refreshValidState(); | |
365 } | |
366 | |
367 public void focusLost(FocusEvent e) { | |
368 valueChanged(); | |
369 clearErrorMessage(); | |
370 } | |
371 }); | |
372 break; | |
373 default: | |
374 Assert.isTrue(false, "Unknown validate strategy");//$NON-NLS-1$ | |
375 } | |
376 textField.addDisposeListener(new class DisposeListener { | |
377 public void widgetDisposed(DisposeEvent event) { | |
378 textField = null; | |
379 } | |
380 }); | |
381 if (textLimit > 0) {//Only set limits above 0 - see SWT spec | |
382 textField.setTextLimit(textLimit); | |
383 } | |
384 } else { | |
385 checkParent(textField, parent); | |
386 } | |
387 return textField; | |
388 } | |
389 | |
390 /** | |
391 * Returns whether an empty string is a valid value. | |
392 * | |
393 * @return <code>true</code> if an empty string is a valid value, and | |
394 * <code>false</code> if an empty string is invalid | |
395 * @see #setEmptyStringAllowed | |
396 */ | |
397 public bool isEmptyStringAllowed() { | |
398 return emptyStringAllowed; | |
399 } | |
400 | |
401 /* (non-Javadoc) | |
402 * Method declared on FieldEditor. | |
403 */ | |
404 public override bool isValid() { | |
405 return isValid_; | |
406 } | |
407 | |
408 /* (non-Javadoc) | |
409 * Method declared on FieldEditor. | |
410 */ | |
411 protected override void refreshValidState() { | |
412 isValid_ = checkState(); | |
413 } | |
414 | |
415 /** | |
416 * Sets whether the empty string is a valid value or not. | |
417 * | |
418 * @param b <code>true</code> if the empty string is allowed, | |
419 * and <code>false</code> if it is considered invalid | |
420 */ | |
421 public void setEmptyStringAllowed(bool b) { | |
422 emptyStringAllowed = b; | |
423 } | |
424 | |
425 /** | |
426 * Sets the error message that will be displayed when and if | |
427 * an error occurs. | |
428 * | |
429 * @param message the error message | |
430 */ | |
431 public void setErrorMessage(String message) { | |
432 errorMessage = message; | |
433 } | |
434 | |
435 /* (non-Javadoc) | |
436 * Method declared on FieldEditor. | |
437 */ | |
438 public override void setFocus() { | |
439 if (textField !is null) { | |
440 textField.setFocus(); | |
441 } | |
442 } | |
443 | |
444 /** | |
445 * Sets this field editor's value. | |
446 * | |
447 * @param value the new value, or <code>null</code> meaning the empty string | |
448 */ | |
449 public void setStringValue(String value) { | |
450 if (textField !is null) { | |
451 if (value is null) { | |
452 value = "";//$NON-NLS-1$ | |
453 } | |
454 oldValue = textField.getText(); | |
455 if (!oldValue.equals(value)) { | |
456 textField.setText(value); | |
457 valueChanged(); | |
458 } | |
459 } | |
460 } | |
461 | |
462 /** | |
463 * Sets this text field's text limit. | |
464 * | |
465 * @param limit the limit on the number of character in the text | |
466 * input field, or <code>UNLIMITED</code> for no limit | |
467 | |
468 */ | |
469 public void setTextLimit(int limit) { | |
470 textLimit = limit; | |
471 if (textField !is null) { | |
472 textField.setTextLimit(limit); | |
473 } | |
474 } | |
475 | |
476 /** | |
477 * Sets the strategy for validating the text. | |
478 * <p> | |
479 * Calling this method has no effect after <code>createPartControl</code> | |
480 * is called. Thus this method is really only useful for subclasses to call | |
481 * in their constructor. However, it has public visibility for backward | |
482 * compatibility. | |
483 * </p> | |
484 * | |
485 * @param value either <code>VALIDATE_ON_KEY_STROKE</code> to perform | |
486 * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to | |
487 * perform validation only after the text has been typed in | |
488 */ | |
489 public void setValidateStrategy(int value) { | |
490 Assert.isTrue(value is VALIDATE_ON_FOCUS_LOST | |
491 || value is VALIDATE_ON_KEY_STROKE); | |
492 validateStrategy = value; | |
493 } | |
494 | |
495 /** | |
496 * Shows the error message set via <code>setErrorMessage</code>. | |
497 */ | |
498 public void showErrorMessage() { | |
499 showErrorMessage(errorMessage); | |
500 } | |
501 | |
502 /** | |
503 * Informs this field editor's listener, if it has one, about a change | |
504 * to the value (<code>VALUE</code> property) provided that the old and | |
505 * new values are different. | |
506 * <p> | |
507 * This hook is <em>not</em> called when the text is initialized | |
508 * (or reset to the default value) from the preference store. | |
509 * </p> | |
510 */ | |
511 protected void valueChanged() { | |
512 setPresentsDefaultValue(false); | |
513 bool oldState = isValid_; | |
514 refreshValidState(); | |
515 | |
516 if (isValid_ !is oldState) { | |
517 fireStateChanged(IS_VALID, oldState, isValid_); | |
518 } | |
519 | |
520 String newValue = textField.getText(); | |
521 if (!newValue.equals(oldValue)) { | |
522 fireValueChanged(VALUE, stringcast(oldValue), stringcast(newValue)); | |
523 oldValue = newValue; | |
524 } | |
525 } | |
526 | |
527 /* | |
528 * @see FieldEditor.setEnabled(bool,Composite). | |
529 */ | |
530 public override void setEnabled(bool enabled, Composite parent) { | |
531 super.setEnabled(enabled, parent); | |
532 getTextControl(parent).setEnabled(enabled); | |
533 } | |
534 } |