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 }