Mercurial > projects > dwt2
comparison org.eclipse.jface/src/org/eclipse/jface/viewers/DialogCellEditor.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, 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.viewers.DialogCellEditor; | |
14 | |
15 import org.eclipse.jface.viewers.CellEditor; | |
16 | |
17 import org.eclipse.swt.SWT; | |
18 import org.eclipse.swt.events.FocusEvent; | |
19 import org.eclipse.swt.events.FocusListener; | |
20 import org.eclipse.swt.events.KeyAdapter; | |
21 import org.eclipse.swt.events.KeyEvent; | |
22 import org.eclipse.swt.events.SelectionAdapter; | |
23 import org.eclipse.swt.events.SelectionEvent; | |
24 import org.eclipse.swt.graphics.Color; | |
25 import org.eclipse.swt.graphics.Font; | |
26 import org.eclipse.swt.graphics.Point; | |
27 import org.eclipse.swt.graphics.Rectangle; | |
28 import org.eclipse.swt.widgets.Button; | |
29 import org.eclipse.swt.widgets.Composite; | |
30 import org.eclipse.swt.widgets.Control; | |
31 import org.eclipse.swt.widgets.Label; | |
32 import org.eclipse.swt.widgets.Layout; | |
33 import org.eclipse.jface.resource.ImageDescriptor; | |
34 import org.eclipse.jface.resource.ImageRegistry; | |
35 import org.eclipse.jface.resource.JFaceResources; | |
36 | |
37 import java.lang.all; | |
38 import java.util.Set; | |
39 import tango.text.convert.Format; | |
40 | |
41 /** | |
42 * An abstract cell editor that uses a dialog. | |
43 * Dialog cell editors usually have a label control on the left and a button on | |
44 * the right. Pressing the button opens a dialog window (for example, a color dialog | |
45 * or a file dialog) to change the cell editor's value. | |
46 * The cell editor's value is the value of the dialog. | |
47 * <p> | |
48 * Subclasses may override the following methods: | |
49 * <ul> | |
50 * <li><code>createButton</code>: creates the cell editor's button control</li> | |
51 * <li><code>createContents</code>: creates the cell editor's 'display value' control</li> | |
52 * <li><code>updateContents</code>: updates the cell editor's 'display value' control | |
53 * after its value has changed</li> | |
54 * <li><code>openDialogBox</code>: opens the dialog box when the end user presses | |
55 * the button</li> | |
56 * </ul> | |
57 * </p> | |
58 */ | |
59 public abstract class DialogCellEditor : CellEditor { | |
60 | |
61 /** | |
62 * Image registry key for three dot image (value <code>"cell_editor_dots_button_image"</code>). | |
63 */ | |
64 public static const String CELL_EDITOR_IMG_DOTS_BUTTON = "cell_editor_dots_button_image";//$NON-NLS-1$ | |
65 | |
66 /** | |
67 * The editor control. | |
68 */ | |
69 private Composite editor; | |
70 | |
71 /** | |
72 * The current contents. | |
73 */ | |
74 private Control contents; | |
75 | |
76 /** | |
77 * The label that gets reused by <code>updateLabel</code>. | |
78 */ | |
79 private Label defaultLabel; | |
80 | |
81 /** | |
82 * The button. | |
83 */ | |
84 private Button button; | |
85 | |
86 /** | |
87 * Listens for 'focusLost' events and fires the 'apply' event as long | |
88 * as the focus wasn't lost because the dialog was opened. | |
89 */ | |
90 private FocusListener buttonFocusListener; | |
91 | |
92 /** | |
93 * The value of this cell editor; initially <code>null</code>. | |
94 */ | |
95 private Object value = null; | |
96 | |
97 static this() { | |
98 ImageRegistry reg = JFaceResources.getImageRegistry(); | |
99 reg.put(CELL_EDITOR_IMG_DOTS_BUTTON, ImageDescriptor.createFromFile( | |
100 getImportData!("org.eclipse.jface.images.dots_button.gif")));//$NON-NLS-1$ | |
101 } | |
102 | |
103 /** | |
104 * Internal class for laying out the dialog. | |
105 */ | |
106 private class DialogCellLayout : Layout { | |
107 public override void layout(Composite editor, bool force) { | |
108 Rectangle bounds = editor.getClientArea(); | |
109 Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, force); | |
110 if (contents !is null) { | |
111 contents.setBounds(0, 0, bounds.width - size.x, bounds.height); | |
112 } | |
113 button.setBounds(bounds.width - size.x, 0, size.x, bounds.height); | |
114 } | |
115 | |
116 public override Point computeSize(Composite editor, int wHint, int hHint, | |
117 bool force) { | |
118 if (wHint !is SWT.DEFAULT && hHint !is SWT.DEFAULT) { | |
119 return new Point(wHint, hHint); | |
120 } | |
121 Point contentsSize = contents.computeSize(SWT.DEFAULT, SWT.DEFAULT, | |
122 force); | |
123 Point buttonSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, | |
124 force); | |
125 // Just return the button width to ensure the button is not clipped | |
126 // if the label is long. | |
127 // The label will just use whatever extra width there is | |
128 Point result = new Point(buttonSize.x, Math.max(contentsSize.y, | |
129 buttonSize.y)); | |
130 return result; | |
131 } | |
132 } | |
133 | |
134 /** | |
135 * Default DialogCellEditor style | |
136 */ | |
137 private static const int defaultStyle = SWT.NONE; | |
138 | |
139 /** | |
140 * Creates a new dialog cell editor with no control | |
141 * @since 2.1 | |
142 */ | |
143 public this() { | |
144 setStyle(defaultStyle); | |
145 } | |
146 | |
147 /** | |
148 * Creates a new dialog cell editor parented under the given control. | |
149 * The cell editor value is <code>null</code> initially, and has no | |
150 * validator. | |
151 * | |
152 * @param parent the parent control | |
153 */ | |
154 protected this(Composite parent) { | |
155 this(parent, defaultStyle); | |
156 } | |
157 | |
158 /** | |
159 * Creates a new dialog cell editor parented under the given control. | |
160 * The cell editor value is <code>null</code> initially, and has no | |
161 * validator. | |
162 * | |
163 * @param parent the parent control | |
164 * @param style the style bits | |
165 * @since 2.1 | |
166 */ | |
167 protected this(Composite parent, int style) { | |
168 super(parent, style); | |
169 } | |
170 | |
171 /** | |
172 * Creates the button for this cell editor under the given parent control. | |
173 * <p> | |
174 * The default implementation of this framework method creates the button | |
175 * display on the right hand side of the dialog cell editor. Subclasses | |
176 * may extend or reimplement. | |
177 * </p> | |
178 * | |
179 * @param parent the parent control | |
180 * @return the new button control | |
181 */ | |
182 protected Button createButton(Composite parent) { | |
183 Button result = new Button(parent, SWT.DOWN); | |
184 result.setText("..."); //$NON-NLS-1$ | |
185 return result; | |
186 } | |
187 | |
188 /** | |
189 * Creates the controls used to show the value of this cell editor. | |
190 * <p> | |
191 * The default implementation of this framework method creates | |
192 * a label widget, using the same font and background color as the parent control. | |
193 * </p> | |
194 * <p> | |
195 * Subclasses may reimplement. If you reimplement this method, you | |
196 * should also reimplement <code>updateContents</code>. | |
197 * </p> | |
198 * | |
199 * @param cell the control for this cell editor | |
200 * @return the underlying control | |
201 */ | |
202 protected Control createContents(Composite cell) { | |
203 defaultLabel = new Label(cell, SWT.LEFT); | |
204 defaultLabel.setFont(cell.getFont()); | |
205 defaultLabel.setBackground(cell.getBackground()); | |
206 return defaultLabel; | |
207 } | |
208 | |
209 /* (non-Javadoc) | |
210 * Method declared on CellEditor. | |
211 */ | |
212 protected override Control createControl(Composite parent) { | |
213 | |
214 Font font = parent.getFont(); | |
215 Color bg = parent.getBackground(); | |
216 | |
217 editor = new Composite(parent, getStyle()); | |
218 editor.setFont(font); | |
219 editor.setBackground(bg); | |
220 editor.setLayout(new DialogCellLayout()); | |
221 | |
222 contents = createContents(editor); | |
223 updateContents(value); | |
224 | |
225 button = createButton(editor); | |
226 button.setFont(font); | |
227 | |
228 button.addKeyListener(new class KeyAdapter { | |
229 /* (non-Javadoc) | |
230 * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) | |
231 */ | |
232 public void keyReleased(KeyEvent e) { | |
233 if (e.character is '\u001b') { // Escape | |
234 fireCancelEditor(); | |
235 } | |
236 } | |
237 }); | |
238 | |
239 button.addFocusListener(getButtonFocusListener()); | |
240 | |
241 button.addSelectionListener(new class SelectionAdapter { | |
242 /* (non-Javadoc) | |
243 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) | |
244 */ | |
245 public void widgetSelected(SelectionEvent event) { | |
246 // Remove the button's focus listener since it's guaranteed | |
247 // to lose focus when the dialog opens | |
248 button.removeFocusListener(getButtonFocusListener()); | |
249 | |
250 Object newValue = openDialogBox(editor); | |
251 | |
252 // Re-add the listener once the dialog closes | |
253 button.addFocusListener(getButtonFocusListener()); | |
254 | |
255 if (newValue !is null) { | |
256 bool newValidState = isCorrect(newValue); | |
257 if (newValidState) { | |
258 markDirty(); | |
259 doSetValue(newValue); | |
260 } else { | |
261 // try to insert the current value into the error message. | |
262 setErrorMessage(Format(getErrorMessage(), | |
263 newValue.toString() )); | |
264 } | |
265 fireApplyEditorValue(); | |
266 } | |
267 } | |
268 }); | |
269 | |
270 setValueValid(true); | |
271 | |
272 return editor; | |
273 } | |
274 | |
275 /* (non-Javadoc) | |
276 * | |
277 * Override in order to remove the button's focus listener if the celleditor | |
278 * is deactivating. | |
279 * | |
280 * @see org.eclipse.jface.viewers.CellEditor#deactivate() | |
281 */ | |
282 public override void deactivate() { | |
283 if (button !is null && !button.isDisposed()) { | |
284 button.removeFocusListener(getButtonFocusListener()); | |
285 } | |
286 | |
287 super.deactivate(); | |
288 } | |
289 | |
290 /* (non-Javadoc) | |
291 * Method declared on CellEditor. | |
292 */ | |
293 protected override Object doGetValue() { | |
294 return value; | |
295 } | |
296 | |
297 /* (non-Javadoc) | |
298 * Method declared on CellEditor. | |
299 * The focus is set to the cell editor's button. | |
300 */ | |
301 protected override void doSetFocus() { | |
302 button.setFocus(); | |
303 | |
304 // add a FocusListener to the button | |
305 button.addFocusListener(getButtonFocusListener()); | |
306 } | |
307 | |
308 /** | |
309 * Return a listener for button focus. | |
310 * @return FocusListener | |
311 */ | |
312 private FocusListener getButtonFocusListener() { | |
313 if (buttonFocusListener is null) { | |
314 buttonFocusListener = new class FocusListener { | |
315 | |
316 /* (non-Javadoc) | |
317 * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) | |
318 */ | |
319 public void focusGained(FocusEvent e) { | |
320 // Do nothing | |
321 } | |
322 | |
323 /* (non-Javadoc) | |
324 * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) | |
325 */ | |
326 public void focusLost(FocusEvent e) { | |
327 this.outer.focusLost(); | |
328 } | |
329 }; | |
330 } | |
331 | |
332 return buttonFocusListener; | |
333 } | |
334 | |
335 /* (non-Javadoc) | |
336 * Method declared on CellEditor. | |
337 */ | |
338 protected override void doSetValue(Object value) { | |
339 this.value = value; | |
340 updateContents(value); | |
341 } | |
342 | |
343 /** | |
344 * Returns the default label widget created by <code>createContents</code>. | |
345 * | |
346 * @return the default label widget | |
347 */ | |
348 protected Label getDefaultLabel() { | |
349 return defaultLabel; | |
350 } | |
351 | |
352 /** | |
353 * Opens a dialog box under the given parent control and returns the | |
354 * dialog's value when it closes, or <code>null</code> if the dialog | |
355 * was canceled or no selection was made in the dialog. | |
356 * <p> | |
357 * This framework method must be implemented by concrete subclasses. | |
358 * It is called when the user has pressed the button and the dialog | |
359 * box must pop up. | |
360 * </p> | |
361 * | |
362 * @param cellEditorWindow the parent control cell editor's window | |
363 * so that a subclass can adjust the dialog box accordingly | |
364 * @return the selected value, or <code>null</code> if the dialog was | |
365 * canceled or no selection was made in the dialog | |
366 */ | |
367 protected abstract Object openDialogBox(Control cellEditorWindow); | |
368 | |
369 /** | |
370 * Updates the controls showing the value of this cell editor. | |
371 * <p> | |
372 * The default implementation of this framework method just converts | |
373 * the passed object to a string using <code>toString</code> and | |
374 * sets this as the text of the label widget. | |
375 * </p> | |
376 * <p> | |
377 * Subclasses may reimplement. If you reimplement this method, you | |
378 * should also reimplement <code>createContents</code>. | |
379 * </p> | |
380 * | |
381 * @param value the new value of this cell editor | |
382 */ | |
383 protected void updateContents(Object value) { | |
384 if (defaultLabel is null) { | |
385 return; | |
386 } | |
387 | |
388 String text = "";//$NON-NLS-1$ | |
389 if (value !is null) { | |
390 text = value.toString(); | |
391 } | |
392 defaultLabel.setText(text); | |
393 } | |
394 } |