changeset 22:7e823642932b

MessageDialogWithToggle
author Frank Benoit <benoit@tionex.de>
date Thu, 03 Apr 2008 00:40:15 +0200
parents cb935a3f6e90
children 1451821c3e00
files dwtx/jface/dialogs/MessageDialogWithToggle.d
diffstat 1 files changed, 713 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/dialogs/MessageDialogWithToggle.d	Thu Apr 03 00:40:15 2008 +0200
@@ -0,0 +1,713 @@
+/*******************************************************************************
+ * 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.dialogs.MessageDialogWithToggle;
+
+import dwtx.jface.dialogs.MessageDialog;
+import dwtx.jface.dialogs.IDialogConstants;
+
+import dwt.DWT;
+import dwt.events.SelectionAdapter;
+import dwt.events.SelectionEvent;
+import dwt.graphics.Image;
+import dwt.layout.GridData;
+import dwt.widgets.Button;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Shell;
+import dwtx.jface.preference.IPreferenceStore;
+import dwtx.jface.resource.JFaceResources;
+
+import dwt.dwthelper.utils;
+
+/**
+ * <p>
+ * A message dialog which also allows the user to adjust a toggle setting. If a
+ * preference store is provided and the user selects the toggle, then the user's
+ * answer (yes/ok or no) will be persisted in the store. If no store is
+ * provided, then this information can be queried after the dialog closes.
+ * </p>
+ * <p>
+ * This type of dialog should be used whenever you want to user to be able to
+ * avoid being prompted in the future. It is <strong>strongly </strong>
+ * recommended that a cancel option be provided, so that the user has the option
+ * of making the decision at a later point in time. The semantic for a cancel
+ * button should be to cancel the operation (if it has not yet started), or stop
+ * the operation (if it has already started).
+ * </p>
+ * <p>
+ * It is the responsibility of the developer to provide a mechanism for the user
+ * to change this preference at some later point in time (e.g., through a
+ * preference page).
+ * </p>
+ *
+ * @since 3.0
+ */
+public class MessageDialogWithToggle : MessageDialog {
+
+    /**
+     * The value of the preference when the user has asked that the answer to
+     * the question always be "okay" or "yes".
+     */
+    public static const String ALWAYS = "always"; //$NON-NLS-1$
+
+    /**
+     * The value of the preference when the user has asked that the answer to
+     * the question always be "no".
+     */
+    public static const String NEVER = "never"; //$NON-NLS-1$
+
+    /**
+     * The value of the preference when the user wishes to prompted for an
+     * answer every time the question is to be asked.
+     */
+    public static const String PROMPT = "prompt"; //$NON-NLS-1$
+
+    /**
+     * Convenience method to open a standard error dialog.
+     *
+     * @param parent
+     *            the parent shell of the dialog, or <code>null</code> if none
+     * @param title
+     *            the dialog's title, or <code>null</code> if none
+     * @param message
+     *            the message
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     * @param store
+     *            the IPreference store in which the user's preference should be
+     *            persisted; <code>null</code> if you don't want it persisted
+     *            automatically.
+     * @param key
+     *            the key to use when persisting the user's preference;
+     *            <code>null</code> if you don't want it persisted.
+     * @return the dialog, after being closed by the user, which the client can
+     *         only call <code>getReturnCode()</code> or
+     *         <code>getToggleState()</code>
+     */
+    public static MessageDialogWithToggle openError(Shell parent, String title,
+            String message, String toggleMessage, bool toggleState,
+            IPreferenceStore store, String key) {
+        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
+                title, null, // accept the default window icon
+                message, ERROR, [ IDialogConstants.OK_LABEL ], 0, // ok
+                // is
+                // the
+                // default
+                toggleMessage, toggleState);
+        dialog.prefStore = store;
+        dialog.prefKey = key;
+        dialog.open();
+        return dialog;
+    }
+
+    /**
+     * Convenience method to open a standard information dialog.
+     *
+     * @param parent
+     *            the parent shell of the dialog, or <code>null</code> if none
+     * @param title
+     *            the dialog's title, or <code>null</code> if none
+     * @param message
+     *            the message
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     * @param store
+     *            the IPreference store in which the user's preference should be
+     *            persisted; <code>null</code> if you don't want it persisted
+     *            automatically.
+     * @param key
+     *            the key to use when persisting the user's preference;
+     *            <code>null</code> if you don't want it persisted.
+     *
+     * @return the dialog, after being closed by the user, which the client can
+     *         only call <code>getReturnCode()</code> or
+     *         <code>getToggleState()</code>
+     */
+    public static MessageDialogWithToggle openInformation(Shell parent,
+            String title, String message, String toggleMessage,
+            bool toggleState, IPreferenceStore store, String key) {
+        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
+                title, null, // accept the default window icon
+                message, INFORMATION,
+                [ IDialogConstants.OK_LABEL ], 0, // ok is the
+                // default
+                toggleMessage, toggleState);
+        dialog.prefStore = store;
+        dialog.prefKey = key;
+        dialog.open();
+        return dialog;
+    }
+
+    /**
+     * Convenience method to open a simple confirm (OK/Cancel) dialog.
+     *
+     * @param parent
+     *            the parent shell of the dialog, or <code>null</code> if none
+     * @param title
+     *            the dialog's title, or <code>null</code> if none
+     * @param message
+     *            the message
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     * @param store
+     *            the IPreference store in which the user's preference should be
+     *            persisted; <code>null</code> if you don't want it persisted
+     *            automatically.
+     * @param key
+     *            the key to use when persisting the user's preference;
+     *            <code>null</code> if you don't want it persisted.
+     * @return the dialog, after being closed by the user, which the client can
+     *         only call <code>getReturnCode()</code> or
+     *         <code>getToggleState()</code>
+     */
+    public static MessageDialogWithToggle openOkCancelConfirm(Shell parent,
+            String title, String message, String toggleMessage,
+            bool toggleState, IPreferenceStore store, String key) {
+        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
+                title, null, // accept the default window icon
+                message, QUESTION, [ IDialogConstants.OK_LABEL,
+                        IDialogConstants.CANCEL_LABEL ], 0, // OK is the default
+                toggleMessage, toggleState);
+        dialog.prefStore = store;
+        dialog.prefKey = key;
+        dialog.open();
+        return dialog;
+    }
+
+    /**
+     * Convenience method to open a standard warning dialog.
+     *
+     * @param parent
+     *            the parent shell of the dialog, or <code>null</code> if none
+     * @param title
+     *            the dialog's title, or <code>null</code> if none
+     * @param message
+     *            the message
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     * @param store
+     *            the IPreference store in which the user's preference should be
+     *            persisted; <code>null</code> if you don't want it persisted
+     *            automatically.
+     * @param key
+     *            the key to use when persisting the user's preference;
+     *            <code>null</code> if you don't want it persisted.
+     * @return the dialog, after being closed by the user, which the client can
+     *         only call <code>getReturnCode()</code> or
+     *         <code>getToggleState()</code>
+     */
+    public static MessageDialogWithToggle openWarning(Shell parent,
+            String title, String message, String toggleMessage,
+            bool toggleState, IPreferenceStore store, String key) {
+        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
+                title, null, // accept the default window icon
+                message, WARNING, [ IDialogConstants.OK_LABEL ],
+                0, // ok is the default
+                toggleMessage, toggleState);
+        dialog.prefStore = store;
+        dialog.prefKey = key;
+        dialog.open();
+        return dialog;
+    }
+
+    /**
+     * Convenience method to open a simple question Yes/No/Cancel dialog.
+     *
+     * @param parent
+     *            the parent shell of the dialog, or <code>null</code> if none
+     * @param title
+     *            the dialog's title, or <code>null</code> if none
+     * @param message
+     *            the message
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     * @param store
+     *            the IPreference store in which the user's preference should be
+     *            persisted; <code>null</code> if you don't want it persisted
+     *            automatically.
+     * @param key
+     *            the key to use when persisting the user's preference;
+     *            <code>null</code> if you don't want it persisted.
+     * @return the dialog, after being closed by the user, which the client can
+     *         only call <code>getReturnCode()</code> or
+     *         <code>getToggleState()</code>
+     */
+    public static MessageDialogWithToggle openYesNoCancelQuestion(Shell parent,
+            String title, String message, String toggleMessage,
+            bool toggleState, IPreferenceStore store, String key) {
+        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
+                title, null, // accept the default window icon
+                message, QUESTION, [ IDialogConstants.YES_LABEL,
+                        IDialogConstants.NO_LABEL,
+                        IDialogConstants.CANCEL_LABEL ], 0, // YES is the
+                // default
+                toggleMessage, toggleState);
+        dialog.prefStore = store;
+        dialog.prefKey = key;
+        dialog.open();
+        return dialog;
+    }
+
+    /**
+     * Convenience method to open a simple Yes/No question dialog.
+     *
+     * @param parent
+     *            the parent shell of the dialog, or <code>null</code> if none
+     * @param title
+     *            the dialog's title, or <code>null</code> if none
+     * @param message
+     *            the message
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     * @param store
+     *            the IPreference store in which the user's preference should be
+     *            persisted; <code>null</code> if you don't want it persisted
+     *            automatically.
+     * @param key
+     *            the key to use when persisting the user's preference;
+     *            <code>null</code> if you don't want it persisted.
+     *
+     * @return the dialog, after being closed by the user, which the client can
+     *         only call <code>getReturnCode()</code> or
+     *         <code>getToggleState()</code>
+     */
+    public static MessageDialogWithToggle openYesNoQuestion(Shell parent,
+            String title, String message, String toggleMessage,
+            bool toggleState, IPreferenceStore store, String key) {
+        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
+                title, null, // accept the default window icon
+                message, QUESTION, [ IDialogConstants.YES_LABEL,
+                        IDialogConstants.NO_LABEL ], 0, // yes is the default
+                toggleMessage, toggleState);
+        dialog.prefStore = store;
+        dialog.prefKey = key;
+        dialog.open();
+        return dialog;
+    }
+
+    /**
+     * The key at which the toggle state should be stored within the
+     * preferences. This value may be <code>null</code>, which indicates that
+     * no preference should be updated automatically. It is then the
+     * responsibility of the user of this API to use the information from the
+     * toggle. Note: a <code>prefStore</code> is also needed.
+     */
+    private String prefKey = null;
+
+    /**
+     * The preference store which will be affected by the toggle button. This
+     * value may be <code>null</code>, which indicates that no preference
+     * should be updated automatically. It is then the responsibility of the
+     * user of this API to use the information from the toggle. Note: a
+     * <code>prefKey</code> is also needed.
+     */
+    private IPreferenceStore prefStore = null;
+
+    /**
+     * The toggle button (widget). This value is <code>null</code> until the
+     * dialog is created.
+     */
+    private Button toggleButton = null;
+
+    /**
+     * The message displayed to the user, with the toggle button. This is the
+     * text besides the toggle. If it is <code>null</code>, this means that
+     * the default text for the toggle should be used.
+     */
+    private String toggleMessage;
+
+    /**
+     * The initial selected state of the toggle.
+     */
+    private bool toggleState;
+
+    /**
+     * Creates a message dialog with a toggle. See the superclass constructor
+     * for info on the other parameters.
+     *
+     * @param parentShell
+     *            the parent shell
+     * @param dialogTitle
+     *            the dialog title, or <code>null</code> if none
+     * @param image
+     *            the dialog title image, or <code>null</code> if none
+     * @param message
+     *            the dialog message
+     * @param dialogImageType
+     *            one of the following values:
+     *            <ul>
+     *            <li><code>MessageDialog.NONE</code> for a dialog with no
+     *            image</li>
+     *            <li><code>MessageDialog.ERROR</code> for a dialog with an
+     *            error image</li>
+     *            <li><code>MessageDialog.INFORMATION</code> for a dialog
+     *            with an information image</li>
+     *            <li><code>MessageDialog.QUESTION </code> for a dialog with a
+     *            question image</li>
+     *            <li><code>MessageDialog.WARNING</code> for a dialog with a
+     *            warning image</li>
+     *            </ul>
+     * @param dialogButtonLabels
+     *            an array of labels for the buttons in the button bar
+     * @param defaultIndex
+     *            the index in the button label array of the default button
+     * @param toggleMessage
+     *            the message for the toggle control, or <code>null</code> for
+     *            the default message
+     * @param toggleState
+     *            the initial state for the toggle
+     *
+     */
+    public this(Shell parentShell, String dialogTitle,
+            Image image, String message, int dialogImageType,
+            String[] dialogButtonLabels, int defaultIndex,
+            String toggleMessage, bool toggleState) {
+        super(parentShell, dialogTitle, image, message, dialogImageType,
+                dialogButtonLabels, defaultIndex);
+        this.toggleMessage = toggleMessage;
+        this.toggleState = toggleState;
+        setButtonLabels(dialogButtonLabels);
+    }
+
+    /**
+     * @see dwtx.jface.dialogs.Dialog#buttonPressed(int)
+     */
+    protected void buttonPressed(int buttonId) {
+        super.buttonPressed(buttonId);
+
+        if (buttonId !is IDialogConstants.CANCEL_ID && toggleState
+                && prefStore !is null && prefKey !is null) {
+            switch (buttonId) {
+            case IDialogConstants.YES_ID:
+            case IDialogConstants.YES_TO_ALL_ID:
+            case IDialogConstants.PROCEED_ID:
+            case IDialogConstants.OK_ID:
+                prefStore.setValue(prefKey, ALWAYS);
+                break;
+            case IDialogConstants.NO_ID:
+            case IDialogConstants.NO_TO_ALL_ID:
+                prefStore.setValue(prefKey, NEVER);
+                break;
+            }
+        }
+    }
+
+    /**
+     * @see Dialog#createButtonBar(Composite)
+     */
+    protected void createButtonsForButtonBar(Composite parent) {
+        String[] buttonLabels = getButtonLabels();
+        Button[] buttons = new Button[buttonLabels.length];
+        int defaultButtonIndex = getDefaultButtonIndex();
+
+        int suggestedId = IDialogConstants.INTERNAL_ID;
+        for (int i = 0; i < buttonLabels.length; i++) {
+            String label = buttonLabels[i];
+            // get the JFace button ID that matches the label, or use the specified
+            // id if there is no match.
+            int id = mapButtonLabelToButtonID(label, suggestedId);
+
+            // if the suggested id was used, increment the default for next use
+            if (id is suggestedId) {
+                suggestedId++;
+            }
+
+            Button button = createButton(parent, id, label,
+                    defaultButtonIndex is i);
+            buttons[i] = button;
+
+        }
+        setButtons(buttons);
+    }
+
+    /**
+     * @see Dialog#createDialogArea(Composite)
+     */
+    protected Control createDialogArea(Composite parent) {
+        Composite dialogAreaComposite = cast(Composite) super
+                .createDialogArea(parent);
+        setToggleButton(createToggleButton(dialogAreaComposite));
+        return dialogAreaComposite;
+    }
+
+    /**
+     * Creates a toggle button without any text or state.  The text and state
+     * will be created by <code>createDialogArea</code>.
+     *
+     * @param parent
+     *            The composite in which the toggle button should be placed;
+     *            must not be <code>null</code>.
+     * @return The added toggle button; never <code>null</code>.
+     */
+    protected Button createToggleButton(Composite parent) {
+        Button button = new Button(parent, DWT.CHECK | DWT.LEFT);
+
+        GridData data = new GridData(DWT.NONE);
+        data.horizontalSpan = 2;
+        button.setLayoutData(data);
+        button.setFont(parent.getFont());
+
+        button.addSelectionListener(new class SelectionAdapter {
+            Button button_;
+            this(){ button_=button; }
+            public void widgetSelected(SelectionEvent e) {
+                toggleState = button_.getSelection();
+            }
+
+        });
+
+        return button;
+    }
+
+    /**
+     * Returns the toggle button.
+     *
+     * @return the toggle button
+     */
+    protected Button getToggleButton() {
+        return toggleButton;
+    }
+
+    /**
+     * An accessor for the current preference store for this dialog.
+     *
+     * @return The preference store; this value may be <code>null</code> if no
+     *         preference is being used.
+     */
+    public IPreferenceStore getPrefStore() {
+        return prefStore;
+    }
+
+    /**
+     * An accessor for the current key of the toggle preference.
+     *
+     * @return The preference key; this value may be <code>null</code> if no
+     *         preference is being used.
+     */
+    public String getPrefKey() {
+        return prefKey;
+    }
+
+    /**
+     * Returns the toggle state. This can be called even after the dialog is
+     * closed.
+     *
+     * @return <code>true</code> if the toggle button is checked,
+     *         <code>false</code> if not
+     */
+    public bool getToggleState() {
+        return toggleState;
+    }
+
+    /**
+     * A mutator for the key of the preference to be modified by the toggle
+     * button.
+     *
+     * @param prefKey
+     *            The prefKey to set. If this value is <code>null</code>,
+     *            then no preference will be modified.
+     */
+    public void setPrefKey(String prefKey) {
+        this.prefKey = prefKey;
+    }
+
+    /**
+     * A mutator for the preference store to be modified by the toggle button.
+     *
+     * @param prefStore
+     *            The prefStore to set. If this value is <code>null</code>,
+     *            then no preference will be modified.
+     */
+    public void setPrefStore(IPreferenceStore prefStore) {
+        this.prefStore = prefStore;
+    }
+
+    /**
+     * A mutator for the button providing the toggle option. If the button
+     * exists, then it will automatically get the text set to the current toggle
+     * message, and its selection state set to the current selection state.
+     *
+     * @param button
+     *            The button to use; must not be <code>null</code>.
+     */
+    protected void setToggleButton(Button button) {
+        if (button is null) {
+            throw new NullPointerException(
+                    "A message dialog with toggle may not have a null toggle button.");} //$NON-NLS-1$
+
+        if (!button.isDisposed()) {
+            String text;
+            if (toggleMessage is null) {
+                text = JFaceResources
+                        .getString("MessageDialogWithToggle.defaultToggleMessage"); //$NON-NLS-1$
+            } else {
+                text = toggleMessage;
+            }
+            button.setText(text);
+            button.setSelection(toggleState);
+        }
+
+        this.toggleButton = button;
+    }
+
+    /**
+     * A mutator for the text on the toggle button. The button will
+     * automatically get updated with the new text, if it exists.
+     *
+     * @param message
+     *            The new text of the toggle button; if it is <code>null</code>,
+     *            then used the default toggle message.
+     */
+    protected void setToggleMessage(String message) {
+        this.toggleMessage = message;
+
+        if ((toggleButton !is null) && (!toggleButton.isDisposed())) {
+            String text;
+            if (toggleMessage is null) {
+                text = JFaceResources
+                        .getString("MessageDialogWithToggle.defaultToggleMessage"); //$NON-NLS-1$
+            } else {
+                text = toggleMessage;
+            }
+            toggleButton.setText(text);
+        }
+    }
+
+    /**
+     * A mutator for the state of the toggle button. This method will update the
+     * button, if it exists.
+     *
+     * @param toggleState
+     *            The desired state of the toggle button (<code>true</code>
+     *            means the toggle should be selected).
+     */
+    public void setToggleState(bool toggleState) {
+        this.toggleState = toggleState;
+
+        // Update the button, if it exists.
+        if ((toggleButton !is null) && (!toggleButton.isDisposed())) {
+            toggleButton.setSelection(toggleState);
+        }
+    }
+
+    /**
+     * Attempt to find a standard JFace button id that matches the specified button
+     * label.  If no match can be found, use the default id provided.
+     *
+     * @param buttonLabel the button label whose id is sought
+     * @param defaultId the id to use for the button if there is no standard id
+     * @return the id for the specified button label
+     */
+    private int mapButtonLabelToButtonID(String buttonLabel, int defaultId) {
+        // Not pretty but does the job...
+        if (IDialogConstants.OK_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.OK_ID;
+        }
+
+        if (IDialogConstants.YES_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.YES_ID;
+        }
+
+        if (IDialogConstants.NO_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.NO_ID;
+        }
+
+        if (IDialogConstants.CANCEL_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.CANCEL_ID;
+        }
+
+        if (IDialogConstants.YES_TO_ALL_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.YES_TO_ALL_ID;
+        }
+
+        if (IDialogConstants.SKIP_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.SKIP_ID;
+        }
+
+        if (IDialogConstants.STOP_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.STOP_ID;
+        }
+
+        if (IDialogConstants.ABORT_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.ABORT_ID;
+        }
+
+        if (IDialogConstants.RETRY_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.RETRY_ID;
+        }
+
+        if (IDialogConstants.IGNORE_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.IGNORE_ID;
+        }
+
+        if (IDialogConstants.PROCEED_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.PROCEED_ID;
+        }
+
+        if (IDialogConstants.OPEN_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.OPEN_ID;
+        }
+
+        if (IDialogConstants.CLOSE_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.CLOSE_ID;
+        }
+
+        if (IDialogConstants.BACK_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.BACK_ID;
+        }
+
+        if (IDialogConstants.NEXT_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.NEXT_ID;
+        }
+
+        if (IDialogConstants.FINISH_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.FINISH_ID;
+        }
+
+        if (IDialogConstants.HELP_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.HELP_ID;
+        }
+
+        if (IDialogConstants.NO_TO_ALL_LABEL.equals(buttonLabel)) {
+            return IDialogConstants.NO_TO_ALL_ID;
+        }
+
+        //          No XXX_LABEL in IDialogConstants for these. Unlikely
+        //            they would be used in a message dialog though.
+        //          public int DETAILS_ID = 13;
+        //          public int SELECT_ALL_ID = 18;
+        //          public int DESELECT_ALL_ID = 19;
+        //          public int SELECT_TYPES_ID = 20;
+
+        return defaultId;
+    }
+}