comparison dwtx/jface/preference/ListEditor.d @ 34:b3c8e32d406f

preference
author Frank Benoit <benoit@tionex.de>
date Sat, 05 Apr 2008 01:45:47 +0200
parents
children ea8ff534f622
comparison
equal deleted inserted replaced
33:f25582573129 34:b3c8e32d406f
1 /*******************************************************************************
2 * Copyright (c) 2000, 2006 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 dwtx.jface.preference.ListEditor;
14
15 import dwtx.jface.preference.FieldEditor;
16
17 import dwt.DWT;
18 import dwt.events.DisposeEvent;
19 import dwt.events.DisposeListener;
20 import dwt.events.SelectionAdapter;
21 import dwt.events.SelectionEvent;
22 import dwt.events.SelectionListener;
23 import dwt.layout.GridData;
24 import dwt.layout.GridLayout;
25 import dwt.widgets.Button;
26 import dwt.widgets.Composite;
27 import dwt.widgets.Control;
28 import dwt.widgets.List;
29 import dwt.widgets.Shell;
30 import dwt.widgets.Widget;
31 import dwtx.core.runtime.Assert;
32 import dwtx.jface.dialogs.IDialogConstants;
33 import dwtx.jface.resource.JFaceResources;
34
35 import dwt.dwthelper.utils;
36
37 /**
38 * An abstract field editor that manages a list of input values.
39 * The editor displays a list containing the values, buttons for
40 * adding and removing values, and Up and Down buttons to adjust
41 * the order of elements in the list.
42 * <p>
43 * Subclasses must implement the <code>parseString</code>,
44 * <code>createList</code>, and <code>getNewInputObject</code>
45 * framework methods.
46 * </p>
47 */
48 public abstract class ListEditor : FieldEditor {
49
50 /**
51 * The list widget; <code>null</code> if none
52 * (before creation or after disposal).
53 */
54 private List list;
55
56 /**
57 * The button box containing the Add, Remove, Up, and Down buttons;
58 * <code>null</code> if none (before creation or after disposal).
59 */
60 private Composite buttonBox;
61
62 /**
63 * The Add button.
64 */
65 private Button addButton;
66
67 /**
68 * The Remove button.
69 */
70 private Button removeButton;
71
72 /**
73 * The Up button.
74 */
75 private Button upButton;
76
77 /**
78 * The Down button.
79 */
80 private Button downButton;
81
82 /**
83 * The selection listener.
84 */
85 private SelectionListener selectionListener;
86
87 /**
88 * Creates a new list field editor
89 */
90 protected this() {
91 }
92
93 /**
94 * Creates a list field editor.
95 *
96 * @param name the name of the preference this field editor works on
97 * @param labelText the label text of the field editor
98 * @param parent the parent of the field editor's control
99 */
100 protected this(String name, String labelText, Composite parent) {
101 init(name, labelText);
102 createControl(parent);
103 }
104
105 /**
106 * Notifies that the Add button has been pressed.
107 */
108 private void addPressed() {
109 setPresentsDefaultValue(false);
110 String input = getNewInputObject();
111
112 if (input !is null) {
113 int index = list.getSelectionIndex();
114 if (index >= 0) {
115 list.add(input, index + 1);
116 } else {
117 list.add(input, 0);
118 }
119 selectionChanged();
120 }
121 }
122
123 /* (non-Javadoc)
124 * Method declared on FieldEditor.
125 */
126 protected void adjustForNumColumns(int numColumns) {
127 Control control = getLabelControl();
128 (cast(GridData) control.getLayoutData()).horizontalSpan = numColumns;
129 (cast(GridData) list.getLayoutData()).horizontalSpan = numColumns - 1;
130 }
131
132 /**
133 * Creates the Add, Remove, Up, and Down button in the given button box.
134 *
135 * @param box the box for the buttons
136 */
137 private void createButtons(Composite box) {
138 addButton = createPushButton(box, "ListEditor.add");//$NON-NLS-1$
139 removeButton = createPushButton(box, "ListEditor.remove");//$NON-NLS-1$
140 upButton = createPushButton(box, "ListEditor.up");//$NON-NLS-1$
141 downButton = createPushButton(box, "ListEditor.down");//$NON-NLS-1$
142 }
143
144 /**
145 * Combines the given list of items into a single string.
146 * This method is the converse of <code>parseString</code>.
147 * <p>
148 * Subclasses must implement this method.
149 * </p>
150 *
151 * @param items the list of items
152 * @return the combined string
153 * @see #parseString
154 */
155 protected abstract String createList(String[] items);
156
157 /**
158 * Helper method to create a push button.
159 *
160 * @param parent the parent control
161 * @param key the resource name used to supply the button's label text
162 * @return Button
163 */
164 private Button createPushButton(Composite parent, String key) {
165 Button button = new Button(parent, DWT.PUSH);
166 button.setText(JFaceResources.getString(key));
167 button.setFont(parent.getFont());
168 GridData data = new GridData(GridData.FILL_HORIZONTAL);
169 int widthHint = convertHorizontalDLUsToPixels(button,
170 IDialogConstants.BUTTON_WIDTH);
171 data.widthHint = Math.max(widthHint, button.computeSize(DWT.DEFAULT,
172 DWT.DEFAULT, true).x);
173 button.setLayoutData(data);
174 button.addSelectionListener(getSelectionListener());
175 return button;
176 }
177
178 /**
179 * Creates a selection listener.
180 */
181 public void createSelectionListener() {
182 selectionListener = new class SelectionAdapter {
183 public void widgetSelected(SelectionEvent event) {
184 Widget widget = event.widget;
185 if (widget is addButton) {
186 addPressed();
187 } else if (widget is removeButton) {
188 removePressed();
189 } else if (widget is upButton) {
190 upPressed();
191 } else if (widget is downButton) {
192 downPressed();
193 } else if (widget is list) {
194 selectionChanged();
195 }
196 }
197 };
198 }
199
200 /* (non-Javadoc)
201 * Method declared on FieldEditor.
202 */
203 protected void doFillIntoGrid(Composite parent, int numColumns) {
204 Control control = getLabelControl(parent);
205 GridData gd = new GridData();
206 gd.horizontalSpan = numColumns;
207 control.setLayoutData(gd);
208
209 list = getListControl(parent);
210 gd = new GridData(GridData.FILL_HORIZONTAL);
211 gd.verticalAlignment = GridData.FILL;
212 gd.horizontalSpan = numColumns - 1;
213 gd.grabExcessHorizontalSpace = true;
214 list.setLayoutData(gd);
215
216 buttonBox = getButtonBoxControl(parent);
217 gd = new GridData();
218 gd.verticalAlignment = GridData.BEGINNING;
219 buttonBox.setLayoutData(gd);
220 }
221
222 /* (non-Javadoc)
223 * Method declared on FieldEditor.
224 */
225 protected void doLoad() {
226 if (list !is null) {
227 String s = getPreferenceStore().getString(getPreferenceName());
228 String[] array = parseString(s);
229 for (int i = 0; i < array.length; i++) {
230 list.add(array[i]);
231 }
232 }
233 }
234
235 /* (non-Javadoc)
236 * Method declared on FieldEditor.
237 */
238 protected void doLoadDefault() {
239 if (list !is null) {
240 list.removeAll();
241 String s = getPreferenceStore().getDefaultString(
242 getPreferenceName());
243 String[] array = parseString(s);
244 for (int i = 0; i < array.length; i++) {
245 list.add(array[i]);
246 }
247 }
248 }
249
250 /* (non-Javadoc)
251 * Method declared on FieldEditor.
252 */
253 protected void doStore() {
254 String s = createList(list.getItems());
255 if (s !is null) {
256 getPreferenceStore().setValue(getPreferenceName(), s);
257 }
258 }
259
260 /**
261 * Notifies that the Down button has been pressed.
262 */
263 private void downPressed() {
264 swap(false);
265 }
266
267 /**
268 * Returns this field editor's button box containing the Add, Remove,
269 * Up, and Down button.
270 *
271 * @param parent the parent control
272 * @return the button box
273 */
274 public Composite getButtonBoxControl(Composite parent) {
275 if (buttonBox is null) {
276 buttonBox = new Composite(parent, DWT.NULL);
277 GridLayout layout = new GridLayout();
278 layout.marginWidth = 0;
279 buttonBox.setLayout(layout);
280 createButtons(buttonBox);
281 buttonBox.addDisposeListener(new class DisposeListener {
282 public void widgetDisposed(DisposeEvent event) {
283 addButton = null;
284 removeButton = null;
285 upButton = null;
286 downButton = null;
287 buttonBox = null;
288 }
289 });
290
291 } else {
292 checkParent(buttonBox, parent);
293 }
294
295 selectionChanged();
296 return buttonBox;
297 }
298
299 /**
300 * Returns this field editor's list control.
301 *
302 * @param parent the parent control
303 * @return the list control
304 */
305 public List getListControl(Composite parent) {
306 if (list is null) {
307 list = new List(parent, DWT.BORDER | DWT.SINGLE | DWT.V_SCROLL
308 | DWT.H_SCROLL);
309 list.setFont(parent.getFont());
310 list.addSelectionListener(getSelectionListener());
311 list.addDisposeListener(new class DisposeListener {
312 public void widgetDisposed(DisposeEvent event) {
313 list = null;
314 }
315 });
316 } else {
317 checkParent(list, parent);
318 }
319 return list;
320 }
321
322 /**
323 * Creates and returns a new item for the list.
324 * <p>
325 * Subclasses must implement this method.
326 * </p>
327 *
328 * @return a new item
329 */
330 protected abstract String getNewInputObject();
331
332 /* (non-Javadoc)
333 * Method declared on FieldEditor.
334 */
335 public int getNumberOfControls() {
336 return 2;
337 }
338
339 /**
340 * Returns this field editor's selection listener.
341 * The listener is created if nessessary.
342 *
343 * @return the selection listener
344 */
345 private SelectionListener getSelectionListener() {
346 if (selectionListener is null) {
347 createSelectionListener();
348 }
349 return selectionListener;
350 }
351
352 /**
353 * Returns this field editor's shell.
354 * <p>
355 * This method is internal to the framework; subclassers should not call
356 * this method.
357 * </p>
358 *
359 * @return the shell
360 */
361 protected Shell getShell() {
362 if (addButton is null) {
363 return null;
364 }
365 return addButton.getShell();
366 }
367
368 /**
369 * Splits the given string into a list of strings.
370 * This method is the converse of <code>createList</code>.
371 * <p>
372 * Subclasses must implement this method.
373 * </p>
374 *
375 * @param stringList the string
376 * @return an array of <code>String</code>
377 * @see #createList
378 */
379 protected abstract String[] parseString(String stringList);
380
381 /**
382 * Notifies that the Remove button has been pressed.
383 */
384 private void removePressed() {
385 setPresentsDefaultValue(false);
386 int index = list.getSelectionIndex();
387 if (index >= 0) {
388 list.remove(index);
389 selectionChanged();
390 }
391 }
392
393 /**
394 * Notifies that the list selection has changed.
395 */
396 private void selectionChanged() {
397
398 int index = list.getSelectionIndex();
399 int size = list.getItemCount();
400
401 removeButton.setEnabled(index >= 0);
402 upButton.setEnabled(size > 1 && index > 0);
403 downButton.setEnabled(size > 1 && index >= 0 && index < size - 1);
404 }
405
406 /* (non-Javadoc)
407 * Method declared on FieldEditor.
408 */
409 public void setFocus() {
410 if (list !is null) {
411 list.setFocus();
412 }
413 }
414
415 /**
416 * Moves the currently selected item up or down.
417 *
418 * @param up <code>true</code> if the item should move up,
419 * and <code>false</code> if it should move down
420 */
421 private void swap(bool up) {
422 setPresentsDefaultValue(false);
423 int index = list.getSelectionIndex();
424 int target = up ? index - 1 : index + 1;
425
426 if (index >= 0) {
427 String[] selection = list.getSelection();
428 Assert.isTrue(selection.length is 1);
429 list.remove(index);
430 list.add(selection[0], target);
431 list.setSelection(target);
432 }
433 selectionChanged();
434 }
435
436 /**
437 * Notifies that the Up button has been pressed.
438 */
439 private void upPressed() {
440 swap(true);
441 }
442
443 /*
444 * @see FieldEditor.setEnabled(bool,Composite).
445 */
446 public void setEnabled(bool enabled, Composite parent) {
447 super.setEnabled(enabled, parent);
448 getListControl(parent).setEnabled(enabled);
449 addButton.setEnabled(enabled);
450 removeButton.setEnabled(enabled);
451 upButton.setEnabled(enabled);
452 downButton.setEnabled(enabled);
453 }
454 }