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);
+    }
+}