Mercurial > projects > dwt-addons
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/preference/ListEditor.d Sat Apr 05 01:45:47 2008 +0200 @@ -0,0 +1,454 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.preference.ListEditor; + +import dwtx.jface.preference.FieldEditor; + +import dwt.DWT; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.SelectionAdapter; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Button; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.List; +import dwt.widgets.Shell; +import dwt.widgets.Widget; +import dwtx.core.runtime.Assert; +import dwtx.jface.dialogs.IDialogConstants; +import dwtx.jface.resource.JFaceResources; + +import dwt.dwthelper.utils; + +/** + * An abstract field editor that manages a list of input values. + * The editor displays a list containing the values, buttons for + * adding and removing values, and Up and Down buttons to adjust + * the order of elements in the list. + * <p> + * Subclasses must implement the <code>parseString</code>, + * <code>createList</code>, and <code>getNewInputObject</code> + * framework methods. + * </p> + */ +public abstract class ListEditor : FieldEditor { + + /** + * The list widget; <code>null</code> if none + * (before creation or after disposal). + */ + private List list; + + /** + * The button box containing the Add, Remove, Up, and Down buttons; + * <code>null</code> if none (before creation or after disposal). + */ + private Composite buttonBox; + + /** + * The Add button. + */ + private Button addButton; + + /** + * The Remove button. + */ + private Button removeButton; + + /** + * The Up button. + */ + private Button upButton; + + /** + * The Down button. + */ + private Button downButton; + + /** + * The selection listener. + */ + private SelectionListener selectionListener; + + /** + * Creates a new list field editor + */ + protected this() { + } + + /** + * Creates a list field editor. + * + * @param name the name of the preference this field editor works on + * @param labelText the label text of the field editor + * @param parent the parent of the field editor's control + */ + protected this(String name, String labelText, Composite parent) { + init(name, labelText); + createControl(parent); + } + + /** + * Notifies that the Add button has been pressed. + */ + private void addPressed() { + setPresentsDefaultValue(false); + String input = getNewInputObject(); + + if (input !is null) { + int index = list.getSelectionIndex(); + if (index >= 0) { + list.add(input, index + 1); + } else { + list.add(input, 0); + } + selectionChanged(); + } + } + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void adjustForNumColumns(int numColumns) { + Control control = getLabelControl(); + (cast(GridData) control.getLayoutData()).horizontalSpan = numColumns; + (cast(GridData) list.getLayoutData()).horizontalSpan = numColumns - 1; + } + + /** + * Creates the Add, Remove, Up, and Down button in the given button box. + * + * @param box the box for the buttons + */ + private void createButtons(Composite box) { + addButton = createPushButton(box, "ListEditor.add");//$NON-NLS-1$ + removeButton = createPushButton(box, "ListEditor.remove");//$NON-NLS-1$ + upButton = createPushButton(box, "ListEditor.up");//$NON-NLS-1$ + downButton = createPushButton(box, "ListEditor.down");//$NON-NLS-1$ + } + + /** + * Combines the given list of items into a single string. + * This method is the converse of <code>parseString</code>. + * <p> + * Subclasses must implement this method. + * </p> + * + * @param items the list of items + * @return the combined string + * @see #parseString + */ + protected abstract String createList(String[] items); + + /** + * Helper method to create a push button. + * + * @param parent the parent control + * @param key the resource name used to supply the button's label text + * @return Button + */ + private Button createPushButton(Composite parent, String key) { + Button button = new Button(parent, DWT.PUSH); + button.setText(JFaceResources.getString(key)); + button.setFont(parent.getFont()); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + int widthHint = convertHorizontalDLUsToPixels(button, + IDialogConstants.BUTTON_WIDTH); + data.widthHint = Math.max(widthHint, button.computeSize(DWT.DEFAULT, + DWT.DEFAULT, true).x); + button.setLayoutData(data); + button.addSelectionListener(getSelectionListener()); + return button; + } + + /** + * Creates a selection listener. + */ + public void createSelectionListener() { + selectionListener = new class SelectionAdapter { + public void widgetSelected(SelectionEvent event) { + Widget widget = event.widget; + if (widget is addButton) { + addPressed(); + } else if (widget is removeButton) { + removePressed(); + } else if (widget is upButton) { + upPressed(); + } else if (widget is downButton) { + downPressed(); + } else if (widget is list) { + selectionChanged(); + } + } + }; + } + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doFillIntoGrid(Composite parent, int numColumns) { + Control control = getLabelControl(parent); + GridData gd = new GridData(); + gd.horizontalSpan = numColumns; + control.setLayoutData(gd); + + list = getListControl(parent); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.verticalAlignment = GridData.FILL; + gd.horizontalSpan = numColumns - 1; + gd.grabExcessHorizontalSpace = true; + list.setLayoutData(gd); + + buttonBox = getButtonBoxControl(parent); + gd = new GridData(); + gd.verticalAlignment = GridData.BEGINNING; + buttonBox.setLayoutData(gd); + } + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doLoad() { + if (list !is null) { + String s = getPreferenceStore().getString(getPreferenceName()); + String[] array = parseString(s); + for (int i = 0; i < array.length; i++) { + list.add(array[i]); + } + } + } + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doLoadDefault() { + if (list !is null) { + list.removeAll(); + String s = getPreferenceStore().getDefaultString( + getPreferenceName()); + String[] array = parseString(s); + for (int i = 0; i < array.length; i++) { + list.add(array[i]); + } + } + } + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doStore() { + String s = createList(list.getItems()); + if (s !is null) { + getPreferenceStore().setValue(getPreferenceName(), s); + } + } + + /** + * Notifies that the Down button has been pressed. + */ + private void downPressed() { + swap(false); + } + + /** + * Returns this field editor's button box containing the Add, Remove, + * Up, and Down button. + * + * @param parent the parent control + * @return the button box + */ + public Composite getButtonBoxControl(Composite parent) { + if (buttonBox is null) { + buttonBox = new Composite(parent, DWT.NULL); + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + buttonBox.setLayout(layout); + createButtons(buttonBox); + buttonBox.addDisposeListener(new class DisposeListener { + public void widgetDisposed(DisposeEvent event) { + addButton = null; + removeButton = null; + upButton = null; + downButton = null; + buttonBox = null; + } + }); + + } else { + checkParent(buttonBox, parent); + } + + selectionChanged(); + return buttonBox; + } + + /** + * Returns this field editor's list control. + * + * @param parent the parent control + * @return the list control + */ + public List getListControl(Composite parent) { + if (list is null) { + list = new List(parent, DWT.BORDER | DWT.SINGLE | DWT.V_SCROLL + | DWT.H_SCROLL); + list.setFont(parent.getFont()); + list.addSelectionListener(getSelectionListener()); + list.addDisposeListener(new class DisposeListener { + public void widgetDisposed(DisposeEvent event) { + list = null; + } + }); + } else { + checkParent(list, parent); + } + return list; + } + + /** + * Creates and returns a new item for the list. + * <p> + * Subclasses must implement this method. + * </p> + * + * @return a new item + */ + protected abstract String getNewInputObject(); + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + public int getNumberOfControls() { + return 2; + } + + /** + * Returns this field editor's selection listener. + * The listener is created if nessessary. + * + * @return the selection listener + */ + private SelectionListener getSelectionListener() { + if (selectionListener is null) { + createSelectionListener(); + } + return selectionListener; + } + + /** + * Returns this field editor's shell. + * <p> + * This method is internal to the framework; subclassers should not call + * this method. + * </p> + * + * @return the shell + */ + protected Shell getShell() { + if (addButton is null) { + return null; + } + return addButton.getShell(); + } + + /** + * Splits the given string into a list of strings. + * This method is the converse of <code>createList</code>. + * <p> + * Subclasses must implement this method. + * </p> + * + * @param stringList the string + * @return an array of <code>String</code> + * @see #createList + */ + protected abstract String[] parseString(String stringList); + + /** + * Notifies that the Remove button has been pressed. + */ + private void removePressed() { + setPresentsDefaultValue(false); + int index = list.getSelectionIndex(); + if (index >= 0) { + list.remove(index); + selectionChanged(); + } + } + + /** + * Notifies that the list selection has changed. + */ + private void selectionChanged() { + + int index = list.getSelectionIndex(); + int size = list.getItemCount(); + + removeButton.setEnabled(index >= 0); + upButton.setEnabled(size > 1 && index > 0); + downButton.setEnabled(size > 1 && index >= 0 && index < size - 1); + } + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + public void setFocus() { + if (list !is null) { + list.setFocus(); + } + } + + /** + * Moves the currently selected item up or down. + * + * @param up <code>true</code> if the item should move up, + * and <code>false</code> if it should move down + */ + private void swap(bool up) { + setPresentsDefaultValue(false); + int index = list.getSelectionIndex(); + int target = up ? index - 1 : index + 1; + + if (index >= 0) { + String[] selection = list.getSelection(); + Assert.isTrue(selection.length is 1); + list.remove(index); + list.add(selection[0], target); + list.setSelection(target); + } + selectionChanged(); + } + + /** + * Notifies that the Up button has been pressed. + */ + private void upPressed() { + swap(true); + } + + /* + * @see FieldEditor.setEnabled(bool,Composite). + */ + public void setEnabled(bool enabled, Composite parent) { + super.setEnabled(enabled, parent); + getListControl(parent).setEnabled(enabled); + addButton.setEnabled(enabled); + removeButton.setEnabled(enabled); + upButton.setEnabled(enabled); + downButton.setEnabled(enabled); + } +}