diff org.eclipse.jface/src/org/eclipse/jface/dialogs/Dialog.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 12b890a6392a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.jface/src/org/eclipse/jface/dialogs/Dialog.d	Sat Mar 14 18:23:29 2009 +0100
@@ -0,0 +1,1340 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *     Remy Chi Jian Suen <remy.suen@gmail.com> - Bug 218553 [JFace] mis-spelling of their in applyDialogFont(...)
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module org.eclipse.jface.dialogs.Dialog;
+
+import org.eclipse.jface.dialogs.IDialogBlockedHandler;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.IDialogConstants;
+// import tango.util.Arrays;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.Policy;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.jface.window.SameShellProvider;
+import org.eclipse.jface.window.Window;
+
+import java.lang.all;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * A dialog is a specialized window used for narrow-focused communication with
+ * the user.
+ * <p>
+ * Dialogs are usually modal. Consequently, it is generally bad practice to open
+ * a dialog without a parent. A modal dialog without a parent is not prevented
+ * from disappearing behind the application's other windows, making it very
+ * confusing for the user.
+ * </p>
+ * <p>
+ * If there is more than one modal dialog is open the second one should be
+ * parented off of the shell of the first one otherwise it is possible that the
+ * OS will give focus to the first dialog potentially blocking the UI.
+ * </p>
+ */
+public abstract class Dialog : Window {
+    /**
+     * Image registry key for error image (value
+     * <code>"dialog_error_image"</code>).
+     *
+     * @deprecated use
+     *             org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_ERROR)
+     */
+    public static const String DLG_IMG_ERROR = "dialog_error_image"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for info image (value <code>"dialog_info_image"</code>).
+     *
+     * @deprecated use
+     *             org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_INFORMATION)
+     */
+    public static const String DLG_IMG_INFO = "dialog_info_imageg"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for question image (value
+     * <code>"dialog_question_image"</code>).
+     *
+     * @deprecated org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_QUESTION)
+     */
+    public static const String DLG_IMG_QUESTION = "dialog_question_image"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for warning image (value
+     * <code>"dialog_warning_image"</code>).
+     *
+     * @deprecated use
+     *             org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_WARNING)
+     */
+    public static const String DLG_IMG_WARNING = "dialog_warning_image"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for info message image (value
+     * <code>"dialog_messasge_info_image"</code>).
+     *
+     * @since 2.0
+     */
+    public static const String DLG_IMG_MESSAGE_INFO = "dialog_messasge_info_image"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for info message image (value
+     * <code>"dialog_messasge_warning_image"</code>).
+     *
+     * @since 2.0
+     */
+    public static const String DLG_IMG_MESSAGE_WARNING = "dialog_messasge_warning_image"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for info message image (value
+     * <code>"dialog_message_error_image"</code>).
+     *
+     * @since 2.0
+     */
+    public static const String DLG_IMG_MESSAGE_ERROR = "dialog_message_error_image"; //$NON-NLS-1$
+
+    /**
+     * Image registry key for help image (value
+     * <code>"dialog_help_image"</code>).
+     *
+     * @since 3.2
+     */
+    public static const String DLG_IMG_HELP = "dialog_help_image"; //$NON-NLS-1$
+
+    /**
+     * The ellipsis is the string that is used to represent shortened text.
+     *
+     * @since 3.0
+     */
+    public static const String ELLIPSIS = "..."; //$NON-NLS-1$
+
+    /**
+     * The dialog settings key name for stored dialog x location.
+     *
+     * @since 3.2
+     */
+    private static const String DIALOG_ORIGIN_X = "DIALOG_X_ORIGIN"; //$NON-NLS-1$
+
+    /**
+     * The dialog settings key name for stored dialog y location.
+     *
+     * @since 3.2
+     */
+    private static const String DIALOG_ORIGIN_Y = "DIALOG_Y_ORIGIN"; //$NON-NLS-1$
+
+    /**
+     * The dialog settings key name for stored dialog width.
+     *
+     * @since 3.2
+     */
+    private static const String DIALOG_WIDTH = "DIALOG_WIDTH"; //$NON-NLS-1$
+
+    /**
+     * The dialog settings key name for stored dialog height.
+     *
+     * @since 3.2
+     */
+    private static const String DIALOG_HEIGHT = "DIALOG_HEIGHT"; //$NON-NLS-1$
+
+    /**
+     * The dialog settings key name for the font used when the dialog
+     * height and width was stored.
+     *
+     *@since 3.2
+     */
+    private static const String DIALOG_FONT_DATA = "DIALOG_FONT_NAME"; //$NON-NLS-1$
+
+    /**
+     * A value that can be used for stored dialog width or height that
+     * indicates that the default bounds should be used.
+     *
+     * @since 3.2
+     */
+    public static const int DIALOG_DEFAULT_BOUNDS = -1;
+
+    /**
+     * Constants that can be used for specifying the strategy for persisting
+     * dialog bounds.  These constants represent bit masks that can be used
+     * together.
+     *
+     *@since 3.2
+     */
+
+    /**
+     * Persist the last location of the dialog.
+     * @since 3.2
+     */
+    public static const int DIALOG_PERSISTLOCATION = 0x0001;
+    /**
+     * Persist the last known size of the dialog.
+     * @since 3.2
+     */
+    public static const int DIALOG_PERSISTSIZE = 0x0002;
+
+    /**
+     * The dialog area; <code>null</code> until dialog is layed out.
+     */
+    protected Control dialogArea;
+
+    /**
+     * The button bar; <code>null</code> until dialog is layed out.
+     */
+    public Control buttonBar;
+
+    /**
+     * Collection of buttons created by the <code>createButton</code> method.
+     */
+    private Button[int] buttons;
+
+    /**
+     * Font metrics to use for determining pixel sizes.
+     */
+    private FontMetrics fontMetrics;
+
+    /**
+     * Number of horizontal dialog units per character, value <code>4</code>.
+     */
+    private static const int HORIZONTAL_DIALOG_UNIT_PER_CHAR = 4;
+
+    /**
+     * Number of vertical dialog units per character, value <code>8</code>.
+     */
+    private static const int VERTICAL_DIALOG_UNITS_PER_CHAR = 8;
+
+    /**
+     * Returns the number of pixels corresponding to the height of the given
+     * number of characters.
+     * <p>
+     * The required <code>FontMetrics</code> parameter may be created in the
+     * following way: <code>
+     *  GC gc = new GC(control);
+     *  gc.setFont(control.getFont());
+     *  fontMetrics = gc.getFontMetrics();
+     *  gc.dispose();
+     * </code>
+     * </p>
+     *
+     * @param fontMetrics
+     *            used in performing the conversion
+     * @param chars
+     *            the number of characters
+     * @return the number of pixels
+     * @since 2.0
+     */
+    public static int convertHeightInCharsToPixels(FontMetrics fontMetrics,
+            int chars) {
+        return fontMetrics.getHeight() * chars;
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the given number of
+     * horizontal dialog units.
+     * <p>
+     * The required <code>FontMetrics</code> parameter may be created in the
+     * following way: <code>
+     *  GC gc = new GC(control);
+     *  gc.setFont(control.getFont());
+     *  fontMetrics = gc.getFontMetrics();
+     *  gc.dispose();
+     * </code>
+     * </p>
+     *
+     * @param fontMetrics
+     *            used in performing the conversion
+     * @param dlus
+     *            the number of horizontal dialog units
+     * @return the number of pixels
+     * @since 2.0
+     */
+    public static int convertHorizontalDLUsToPixels(FontMetrics fontMetrics,
+            int dlus) {
+        // round to the nearest pixel
+        return (fontMetrics.getAverageCharWidth() * dlus + HORIZONTAL_DIALOG_UNIT_PER_CHAR / 2)
+                / HORIZONTAL_DIALOG_UNIT_PER_CHAR;
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the given number of
+     * vertical dialog units.
+     * <p>
+     * The required <code>FontMetrics</code> parameter may be created in the
+     * following way: <code>
+     *  GC gc = new GC(control);
+     *  gc.setFont(control.getFont());
+     *  fontMetrics = gc.getFontMetrics();
+     *  gc.dispose();
+     * </code>
+     * </p>
+     *
+     * @param fontMetrics
+     *            used in performing the conversion
+     * @param dlus
+     *            the number of vertical dialog units
+     * @return the number of pixels
+     * @since 2.0
+     */
+    public static int convertVerticalDLUsToPixels(FontMetrics fontMetrics,
+            int dlus) {
+        // round to the nearest pixel
+        return (fontMetrics.getHeight() * dlus + VERTICAL_DIALOG_UNITS_PER_CHAR / 2)
+                / VERTICAL_DIALOG_UNITS_PER_CHAR;
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the width of the given
+     * number of characters.
+     * <p>
+     * The required <code>FontMetrics</code> parameter may be created in the
+     * following way: <code>
+     *  GC gc = new GC(control);
+     *  gc.setFont(control.getFont());
+     *  fontMetrics = gc.getFontMetrics();
+     *  gc.dispose();
+     * </code>
+     * </p>
+     *
+     * @param fontMetrics
+     *            used in performing the conversion
+     * @param chars
+     *            the number of characters
+     * @return the number of pixels
+     * @since 2.0
+     */
+    public static int convertWidthInCharsToPixels(FontMetrics fontMetrics,
+            int chars) {
+        return fontMetrics.getAverageCharWidth() * chars;
+    }
+
+    /**
+     * Shortens the given text <code>textValue</code> so that its width in
+     * pixels does not exceed the width of the given control. Overrides
+     * characters in the center of the original string with an ellipsis ("...")
+     * if necessary. If a <code>null</code> value is given, <code>null</code>
+     * is returned.
+     *
+     * @param textValue
+     *            the original string or <code>null</code>
+     * @param control
+     *            the control the string will be displayed on
+     * @return the string to display, or <code>null</code> if null was passed
+     *         in
+     *
+     * @since 3.0
+     */
+    public static String shortenText(String textValue, Control control) {
+        if (textValue is null) {
+            return null;
+        }
+        GC gc = new GC(control);
+        int maxWidth = control.getBounds().width - 5;
+        int maxExtent = gc.textExtent(textValue).x;
+        if (maxExtent < maxWidth) {
+            gc.dispose();
+            return textValue;
+        }
+        int length = textValue.length;
+        int charsToClip = cast(int) Math.round(0.95f*length * (1 - (cast(float)maxWidth/maxExtent)));
+        int pivot = length / 2;
+        int start = pivot - (charsToClip/2);
+        int end = pivot + (charsToClip/2) + 1;
+        while (start >= 0 && end < length) {
+            String s1 = textValue.substring(0, start);
+            String s2 = textValue.substring(end, length);
+            String s = s1 ~ ELLIPSIS ~ s2;
+            int l = gc.textExtent(s).x;
+            if (l < maxWidth) {
+                gc.dispose();
+                return s;
+            }
+            start--;
+            end++;
+        }
+        gc.dispose();
+        return textValue;
+    }
+
+    /**
+     * Create a default instance of the blocked handler which does not do
+     * anything.
+     */
+    private static IDialogBlockedHandler blockedHandler_;
+    public static IDialogBlockedHandler blockedHandler(){
+        static_this_blockedhandler();
+        return blockedHandler_;
+    }
+    public static IDialogBlockedHandler blockedHandler( IDialogBlockedHandler b ){
+        static_this_blockedhandler();
+        return ( blockedHandler_ = b );
+    }
+    private static bool static_this_blockedhandler_completed = false;
+    private static void static_this_blockedhandler(){
+        if( static_this_blockedhandler_completed ){
+            return;
+        }
+        synchronized{
+            if( static_this_blockedhandler_completed ){
+                return;
+            }
+            blockedHandler_ = new class IDialogBlockedHandler {
+                /*
+                * (non-Javadoc)
+                *
+                * @see org.eclipse.jface.dialogs.IDialogBlockedHandler#clearBlocked()
+                */
+                public void clearBlocked() {
+                    // No default behaviour
+                }
+
+                /*
+                * (non-Javadoc)
+                *
+                * @see org.eclipse.jface.dialogs.IDialogBlockedHandler#showBlocked(org.eclipse.core.runtime.IProgressMonitor,
+                *      org.eclipse.core.runtime.IStatus, java.lang.String)
+                */
+                public void showBlocked(IProgressMonitor blocking,
+                        IStatus blockingStatus, String blockedName) {
+                    // No default behaviour
+                }
+
+                /*
+                * (non-Javadoc)
+                *
+                * @see org.eclipse.jface.dialogs.IDialogBlockedHandler#showBlocked(org.eclipse.swt.widgets.Shell,
+                *      org.eclipse.core.runtime.IProgressMonitor,
+                *      org.eclipse.core.runtime.IStatus, java.lang.String)
+                */
+                public void showBlocked(Shell parentShell, IProgressMonitor blocking,
+                        IStatus blockingStatus, String blockedName) {
+                    // No default behaviour
+                }
+            };
+            static_this_blockedhandler_completed = true;
+        }
+    }
+
+    /**
+     * Creates a dialog instance. Note that the window will have no visual
+     * representation (no widgets) until it is told to open. By default,
+     * <code>open</code> blocks for dialogs.
+     *
+     * @param parentShell
+     *            the parent shell, or <code>null</code> to create a top-level
+     *            shell
+     */
+    protected this(Shell parentShell) {
+        this(new SameShellProvider(parentShell));
+        if (parentShell is null && Policy.DEBUG_DIALOG_NO_PARENT) {
+            Policy.getLog().log(
+                    new Status(IStatus.INFO, Policy.JFACE, IStatus.INFO, this
+                            .classinfo.name
+                            ~ " created with no shell",//$NON-NLS-1$
+                            new Exception( null, null )));
+        }
+    }
+
+    /**
+     * Creates a dialog with the given parent.
+     *
+     * @param parentShell
+     *            object that returns the current parent shell
+     *
+     * @since 3.1
+     */
+    protected this(IShellProvider parentShell) {
+        super(parentShell);
+        if (isResizable()) {
+            setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.MAX | SWT.RESIZE
+                    | getDefaultOrientation());
+        } else {
+            setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL
+                    | getDefaultOrientation());
+        }
+        setBlockOnOpen(true);
+    }
+
+    /**
+     * Notifies that this dialog's button with the given id has been pressed.
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method calls
+     * <code>okPressed</code> if the ok button is the pressed, and
+     * <code>cancelPressed</code> if the cancel button is the pressed. All
+     * other button presses are ignored. Subclasses may override to handle other
+     * buttons, but should call <code>super.buttonPressed</code> if the
+     * default handling of the ok and cancel buttons is desired.
+     * </p>
+     *
+     * @param buttonId
+     *            the id of the button that was pressed (see
+     *            <code>IDialogConstants.*_ID</code> constants)
+     */
+    protected void buttonPressed(int buttonId) {
+        if (IDialogConstants.OK_ID is buttonId) {
+            okPressed();
+        } else if (IDialogConstants.CANCEL_ID is buttonId) {
+            cancelPressed();
+        }
+    }
+
+    /**
+     * Notifies that the cancel button of this dialog has been pressed.
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method sets
+     * this dialog's return code to <code>Window.CANCEL</code> and closes the
+     * dialog. Subclasses may override if desired.
+     * </p>
+     */
+    protected void cancelPressed() {
+        setReturnCode(CANCEL);
+        close();
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the height of the given
+     * number of characters.
+     * <p>
+     * This method may only be called after <code>initializeDialogUnits</code>
+     * has been called.
+     * </p>
+     * <p>
+     * Clients may call this framework method, but should not override it.
+     * </p>
+     *
+     * @param chars
+     *            the number of characters
+     * @return the number of pixels
+     */
+    protected int convertHeightInCharsToPixels(int chars) {
+        // test for failure to initialize for backward compatibility
+        if (fontMetrics is null) {
+            return 0;
+        }
+        return convertHeightInCharsToPixels(fontMetrics, chars);
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the given number of
+     * horizontal dialog units.
+     * <p>
+     * This method may only be called after <code>initializeDialogUnits</code>
+     * has been called.
+     * </p>
+     * <p>
+     * Clients may call this framework method, but should not override it.
+     * </p>
+     *
+     * @param dlus
+     *            the number of horizontal dialog units
+     * @return the number of pixels
+     */
+    protected int convertHorizontalDLUsToPixels(int dlus) {
+        // test for failure to initialize for backward compatibility
+        if (fontMetrics is null) {
+            return 0;
+        }
+        return convertHorizontalDLUsToPixels(fontMetrics, dlus);
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the given number of
+     * vertical dialog units.
+     * <p>
+     * This method may only be called after <code>initializeDialogUnits</code>
+     * has been called.
+     * </p>
+     * <p>
+     * Clients may call this framework method, but should not override it.
+     * </p>
+     *
+     * @param dlus
+     *            the number of vertical dialog units
+     * @return the number of pixels
+     */
+    protected int convertVerticalDLUsToPixels(int dlus) {
+        // test for failure to initialize for backward compatibility
+        if (fontMetrics is null) {
+            return 0;
+        }
+        return convertVerticalDLUsToPixels(fontMetrics, dlus);
+    }
+
+    /**
+     * Returns the number of pixels corresponding to the width of the given
+     * number of characters.
+     * <p>
+     * This method may only be called after <code>initializeDialogUnits</code>
+     * has been called.
+     * </p>
+     * <p>
+     * Clients may call this framework method, but should not override it.
+     * </p>
+     *
+     * @param chars
+     *            the number of characters
+     * @return the number of pixels
+     */
+    protected int convertWidthInCharsToPixels(int chars) {
+        // test for failure to initialize for backward compatibility
+        if (fontMetrics is null) {
+            return 0;
+        }
+        return convertWidthInCharsToPixels(fontMetrics, chars);
+    }
+
+    /**
+     * Creates a new button with the given id.
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method creates
+     * a standard push button, registers it for selection events including
+     * button presses, and registers default buttons with its shell. The button
+     * id is stored as the button's client data. If the button id is
+     * <code>IDialogConstants.CANCEL_ID</code>, the new button will be
+     * accessible from <code>getCancelButton()</code>. If the button id is
+     * <code>IDialogConstants.OK_ID</code>, the new button will be accesible
+     * from <code>getOKButton()</code>. Note that the parent's layout is
+     * assumed to be a <code>GridLayout</code> and the number of columns in
+     * this layout is incremented. Subclasses may override.
+     * </p>
+     *
+     * @param parent
+     *            the parent composite
+     * @param id
+     *            the id of the button (see <code>IDialogConstants.*_ID</code>
+     *            constants for standard dialog button ids)
+     * @param label
+     *            the label from the button
+     * @param defaultButton
+     *            <code>true</code> if the button is to be the default button,
+     *            and <code>false</code> otherwise
+     *
+     * @return the new button
+     *
+     * @see #getCancelButton
+     * @see #getOKButton()
+     */
+    protected Button createButton(Composite parent, int id, String label,
+            bool defaultButton) {
+        // increment the number of columns in the button bar
+        (cast(GridLayout) parent.getLayout()).numColumns++;
+        Button button = new Button(parent, SWT.PUSH);
+        button.setText(label);
+        button.setFont(JFaceResources.getDialogFont());
+        button.setData(new ValueWrapperInt(id));
+        button.addSelectionListener(new class SelectionAdapter {
+            public void widgetSelected(SelectionEvent event) {
+                buttonPressed((cast(ValueWrapperInt) event.widget.getData()).value);
+            }
+        });
+        if (defaultButton) {
+            Shell shell = parent.getShell();
+            if (shell !is null) {
+                shell.setDefaultButton(button);
+            }
+        }
+        buttons[id] = button;
+        setButtonLayoutData(button);
+        return button;
+    }
+
+    /**
+     * Creates and returns the contents of this dialog's button bar.
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method lays
+     * out a button bar and calls the <code>createButtonsForButtonBar</code>
+     * framework method to populate it. Subclasses may override.
+     * </p>
+     * <p>
+     * The returned control's layout data must be an instance of
+     * <code>GridData</code>.
+     * </p>
+     *
+     * @param parent
+     *            the parent composite to contain the button bar
+     * @return the button bar control
+     */
+    protected Control createButtonBar(Composite parent) {
+        Composite composite = new Composite(parent, SWT.NONE);
+        // create a layout with spacing and margins appropriate for the font
+        // size.
+        GridLayout layout = new GridLayout();
+        layout.numColumns = 0; // this is incremented by createButton
+        layout.makeColumnsEqualWidth = true;
+        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+        composite.setLayout(layout);
+        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
+                | GridData.VERTICAL_ALIGN_CENTER);
+        composite.setLayoutData(data);
+        composite.setFont(parent.getFont());
+
+        // Add the buttons to the button bar.
+        createButtonsForButtonBar(composite);
+        return composite;
+    }
+
+    /**
+     * Adds buttons to this dialog's button bar.
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method adds
+     * standard ok and cancel buttons using the <code>createButton</code>
+     * framework method. These standard buttons will be accessible from
+     * <code>getCancelButton</code>, and <code>getOKButton</code>.
+     * Subclasses may override.
+     * </p>
+     *
+     * @param parent
+     *            the button bar composite
+     */
+    protected void createButtonsForButtonBar(Composite parent) {
+        // create OK and Cancel buttons by default
+        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+                true);
+        createButton(parent, IDialogConstants.CANCEL_ID,
+                IDialogConstants.CANCEL_LABEL, false);
+    }
+
+    /*
+     * @see Window.initializeBounds()
+     */
+    protected override void initializeBounds() {
+        String platform = SWT.getPlatform();
+        if ("carbon".equals(platform)) { //$NON-NLS-1$
+            // On Mac OS X the default button must be the right-most button
+            Shell shell = getShell();
+            if (shell !is null) {
+                Button defaultButton = shell.getDefaultButton();
+                if (defaultButton !is null
+                        && isContained(buttonBar, defaultButton)) {
+                    defaultButton.moveBelow(null);
+                }
+            }
+        }
+
+        super.initializeBounds();
+    }
+
+    /**
+     * Returns true if the given Control is a direct or indirect child of
+     * container.
+     *
+     * @param container
+     *            the potential parent
+     * @param control
+     * @return bool <code>true</code> if control is a child of container
+     */
+    private bool isContained(Control container, Control control) {
+        Composite parent;
+        while ((parent = control.getParent()) !is null) {
+            if (parent is container) {
+                return true;
+            }
+            control = parent;
+        }
+        return false;
+    }
+
+    /**
+     * The <code>Dialog</code> implementation of this <code>Window</code>
+     * method creates and lays out the top level composite for the dialog, and
+     * determines the appropriate horizontal and vertical dialog units based on
+     * the font size. It then calls the <code>createDialogArea</code> and
+     * <code>createButtonBar</code> methods to create the dialog area and
+     * button bar, respectively. Overriding <code>createDialogArea</code> and
+     * <code>createButtonBar</code> are recommended rather than overriding
+     * this method.
+     */
+    protected override Control createContents(Composite parent) {
+        // create the top level composite for the dialog
+        Composite composite = new Composite(parent, 0);
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        layout.verticalSpacing = 0;
+        composite.setLayout(layout);
+        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        applyDialogFont(composite);
+        // initialize the dialog units
+        initializeDialogUnits(composite);
+        // create the dialog area and button bar
+        dialogArea = createDialogArea(composite);
+        buttonBar = createButtonBar(composite);
+
+        return composite;
+    }
+
+    /**
+     * Creates and returns the contents of the upper part of this dialog (above
+     * the button bar).
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method creates
+     * and returns a new <code>Composite</code> with standard margins and
+     * spacing.
+     * </p>
+     * <p>
+     * The returned control's layout data must be an instance of
+     * <code>GridData</code>. This method must not modify the parent's
+     * layout.
+     * </p>
+     * <p>
+     * Subclasses must override this method but may call <code>super</code> as
+     * in the following example:
+     * </p>
+     *
+     * <pre>
+     * Composite composite = (Composite) super.createDialogArea(parent);
+     * //add controls to composite as necessary
+     * return composite;
+     * </pre>
+     *
+     * @param parent
+     *            the parent composite to contain the dialog area
+     * @return the dialog area control
+     */
+    protected Control createDialogArea(Composite parent) {
+        // create a composite with standard margins and spacing
+        Composite composite = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+        composite.setLayout(layout);
+        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        applyDialogFont(composite);
+        return composite;
+    }
+
+    /**
+     * Returns the button created by the method <code>createButton</code> for
+     * the specified ID as defined on <code>IDialogConstants</code>. If
+     * <code>createButton</code> was never called with this ID, or if
+     * <code>createButton</code> is overridden, this method will return
+     * <code>null</code>.
+     *
+     * @param id
+     *            the id of the button to look for
+     *
+     * @return the button for the ID or <code>null</code>
+     *
+     * @see #createButton(Composite, int, String, bool)
+     * @since 2.0
+     */
+    protected Button getButton(int id) {
+        if( auto btn = id in buttons ){
+            return *btn;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the button bar control.
+     * <p>
+     * Clients may call this framework method, but should not override it.
+     * </p>
+     *
+     * @return the button bar, or <code>null</code> if the button bar has not
+     *         been created yet
+     */
+    protected Control getButtonBar() {
+        return buttonBar;
+    }
+
+    /**
+     * Returns the button created when <code>createButton</code> is called
+     * with an ID of <code>IDialogConstants.CANCEL_ID</code>. If
+     * <code>createButton</code> was never called with this parameter, or if
+     * <code>createButton</code> is overridden, <code>getCancelButton</code>
+     * will return <code>null</code>.
+     *
+     * @return the cancel button or <code>null</code>
+     *
+     * @see #createButton(Composite, int, String, bool)
+     * @since 2.0
+     * @deprecated Use <code>getButton(IDialogConstants.CANCEL_ID)</code>
+     *             instead. This method will be removed soon.
+     */
+    protected Button getCancelButton() {
+        return getButton(IDialogConstants.CANCEL_ID);
+    }
+
+    /**
+     * Returns the dialog area control.
+     * <p>
+     * Clients may call this framework method, but should not override it.
+     * </p>
+     *
+     * @return the dialog area, or <code>null</code> if the dialog area has
+     *         not been created yet
+     */
+    protected Control getDialogArea() {
+        return dialogArea;
+    }
+
+    /**
+     * Returns the standard dialog image with the given key. Note that these
+     * images are managed by the dialog framework, and must not be disposed by
+     * another party.
+     *
+     * @param key
+     *            one of the <code>Dialog.DLG_IMG_* </code> constants
+     * @return the standard dialog image
+     *
+     * NOTE: Dialog does not use the following images in the registry
+     * DLG_IMG_ERROR DLG_IMG_INFO DLG_IMG_QUESTION DLG_IMG_WARNING
+     *
+     * They are now coming directly from SWT, see ImageRegistry. For backwards
+     * compatibility they are still supported, however new code should use SWT
+     * for these.
+     *
+     * @see Display#getSystemImage(int)
+     */
+    public static Image getImage(String key) {
+        return JFaceResources.getImageRegistry().get(key);
+    }
+
+    /**
+     * Returns the button created when <code>createButton</code> is called
+     * with an ID of <code>IDialogConstants.OK_ID</code>. If
+     * <code>createButton</code> was never called with this parameter, or if
+     * <code>createButton</code> is overridden, <code>getOKButton</code>
+     * will return <code>null</code>.
+     *
+     * @return the OK button or <code>null</code>
+     *
+     * @see #createButton(Composite, int, String, bool)
+     * @since 2.0
+     * @deprecated Use <code>getButton(IDialogConstants.OK_ID)</code> instead.
+     *             This method will be removed soon.
+     */
+    protected Button getOKButton() {
+        return getButton(IDialogConstants.OK_ID);
+    }
+
+    /**
+     * Initializes the computation of horizontal and vertical dialog units based
+     * on the size of current font.
+     * <p>
+     * This method must be called before any of the dialog unit based conversion
+     * methods are called.
+     * </p>
+     *
+     * @param control
+     *            a control from which to obtain the current font
+     */
+    protected void initializeDialogUnits(Control control) {
+        // Compute and store a font metric
+        GC gc = new GC(control);
+        gc.setFont(JFaceResources.getDialogFont());
+        fontMetrics = gc.getFontMetrics();
+        gc.dispose();
+    }
+
+    /**
+     * Notifies that the ok button of this dialog has been pressed.
+     * <p>
+     * The <code>Dialog</code> implementation of this framework method sets
+     * this dialog's return code to <code>Window.OK</code> and closes the
+     * dialog. Subclasses may override.
+     * </p>
+     */
+    protected void okPressed() {
+        setReturnCode(OK);
+        close();
+    }
+
+    /**
+     * Set the layout data of the button to a GridData with appropriate heights
+     * and widths.
+     *
+     * @param button
+     */
+    protected void setButtonLayoutData(Button button) {
+        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+        int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+        Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+        data.widthHint = Math.max(widthHint, minSize.x);
+        button.setLayoutData(data);
+    }
+
+    /**
+     * Set the layout data of the button to a FormData with appropriate heights
+     * and widths.
+     *
+     * @param button
+     */
+    protected void setButtonLayoutFormData(Button button) {
+        FormData data = new FormData();
+        int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+        Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+        data.width = Math.max(widthHint, minSize.x);
+        button.setLayoutData(data);
+    }
+
+    /**
+     * @see org.eclipse.jface.window.Window#close()
+     */
+    public override bool close() {
+        if (getShell() !is null && !getShell().isDisposed()) {
+            saveDialogBounds(getShell());
+        }
+
+        bool returnValue = super.close();
+        if (returnValue) {
+            buttons = null;
+            buttonBar = null;
+            dialogArea = null;
+        }
+        return returnValue;
+    }
+
+    /**
+     * Applies the dialog font to all controls that currently have the default
+     * font.
+     *
+     * @param control
+     *            the control to apply the font to. Font will also be applied to
+     *            its children. If the control is <code>null</code> nothing
+     *            happens.
+     */
+    public static void applyDialogFont(Control control) {
+        if (control is null || dialogFontIsDefault()) {
+            return;
+        }
+        Font dialogFont = JFaceResources.getDialogFont();
+        applyDialogFont(control, dialogFont);
+    }
+
+    /**
+     * Sets the dialog font on the control and any of its children if their font
+     * is not otherwise set.
+     *
+     * @param control
+     *            the control to apply the font to. Font will also be applied to
+     *            its children.
+     * @param dialogFont
+     *            the dialog font to set
+     */
+    private static void applyDialogFont(Control control, Font dialogFont) {
+        if (hasDefaultFont(control)) {
+            control.setFont(dialogFont);
+        }
+        if ( auto comp = cast(Composite)control ) {
+            Control[] children = comp.getChildren();
+            for (int i = 0; i < children.length; i++) {
+                applyDialogFont(children[i], dialogFont);
+            }
+        }
+    }
+
+    /**
+     * Return whether or not this control has the same font as it's default.
+     *
+     * @param control
+     *            Control
+     * @return bool
+     */
+    private static bool hasDefaultFont(Control control) {
+        FontData[] controlFontData = control.getFont().getFontData();
+        FontData[] defaultFontData = getDefaultFont(control).getFontData();
+        if (controlFontData.length is defaultFontData.length) {
+            for (int i = 0; i < controlFontData.length; i++) {
+                if (controlFontData[i].opEquals(defaultFontData[i])) {
+                    continue;
+                }
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the default font for this type of control.
+     *
+     * @param control
+     * @return the default font
+     */
+    private static Font getDefaultFont(Control control) {
+        String fontName = "DEFAULT_FONT_" ~ control.classinfo.name; //$NON-NLS-1$
+        if (JFaceResources.getFontRegistry().hasValueFor(fontName)) {
+            return JFaceResources.getFontRegistry().get(fontName);
+        }
+        Font cached = control.getFont();
+        control.setFont(null);
+        Font defaultFont = control.getFont();
+        control.setFont(cached);
+        JFaceResources.getFontRegistry().put(fontName,
+                defaultFont.getFontData());
+        return defaultFont;
+    }
+
+    /**
+     * Return whether or not the dialog font is currently the same as the
+     * default font.
+     *
+     * @return bool if the two are the same
+     */
+    protected static bool dialogFontIsDefault() {
+        FontData[] dialogFontData = JFaceResources.getFontRegistry()
+                .getFontData(JFaceResources.DIALOG_FONT);
+        FontData[] defaultFontData = JFaceResources.getFontRegistry()
+                .getFontData(JFaceResources.DEFAULT_FONT);
+        return ArrayEquals(dialogFontData, defaultFontData);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.jface.window.Window#create()
+     */
+    public override void create() {
+        super.create();
+        applyDialogFont(buttonBar);
+    }
+
+    /**
+     * Get the IDialogBlockedHandler to be used by WizardDialogs and
+     * ModalContexts.
+     *
+     * @return Returns the blockedHandler.
+     */
+    public static IDialogBlockedHandler getBlockedHandler() {
+        return blockedHandler;
+    }
+
+    /**
+     * Set the IDialogBlockedHandler to be used by WizardDialogs and
+     * ModalContexts.
+     *
+     * @param blockedHandler
+     *            The blockedHandler for the dialogs.
+     */
+    public static void setBlockedHandler(IDialogBlockedHandler blockedHandler) {
+        Dialog.blockedHandler = blockedHandler;
+    }
+
+    /**
+     * Gets the dialog settings that should be used for remembering the bounds of
+     * of the dialog, according to the dialog bounds strategy.
+     *
+     * @return settings the dialog settings used to store the dialog's location
+     *         and/or size, or <code>null</code> if the dialog's bounds should
+     *         never be stored.
+     *
+     * @since 3.2
+     * @see Dialog#getDialogBoundsStrategy()
+     */
+    protected IDialogSettings getDialogBoundsSettings() {
+        return null;
+    }
+
+    /**
+     * Get the integer constant that describes the strategy for persisting the
+     * dialog bounds. This strategy is ignored if the implementer does not also
+     * specify the dialog settings for storing the bounds in
+     * Dialog.getDialogBoundsSettings().
+     *
+     * @return the constant describing the strategy for persisting the dialog
+     *         bounds.
+     *
+     * @since 3.2
+     * @see Dialog#DIALOG_PERSISTLOCATION
+     * @see Dialog#DIALOG_PERSISTSIZE
+     * @see Dialog#getDialogBoundsSettings()
+     */
+    protected int getDialogBoundsStrategy() {
+        return DIALOG_PERSISTLOCATION | DIALOG_PERSISTSIZE;
+    }
+
+    /**
+     * Saves the bounds of the shell in the appropriate dialog settings. The
+     * bounds are recorded relative to the parent shell, if there is one, or
+     * display coordinates if there is no parent shell.
+     *
+     * @param shell
+     *            The shell whose bounds are to be stored
+     *
+     * @since 3.2
+     */
+    private void saveDialogBounds(Shell shell) {
+        IDialogSettings settings = getDialogBoundsSettings();
+        if (settings !is null) {
+            Point shellLocation = shell.getLocation();
+            Point shellSize = shell.getSize();
+            Shell parent = getParentShell();
+            if (parent !is null) {
+                Point parentLocation = parent.getLocation();
+                shellLocation.x -= parentLocation.x;
+                shellLocation.y -= parentLocation.y;
+            }
+            int strategy = getDialogBoundsStrategy();
+            if ((strategy & DIALOG_PERSISTLOCATION) !is 0) {
+                settings.put(DIALOG_ORIGIN_X, shellLocation.x);
+                settings.put(DIALOG_ORIGIN_Y, shellLocation.y);
+            }
+            if ((strategy & DIALOG_PERSISTSIZE) !is 0) {
+                settings.put(DIALOG_WIDTH, shellSize.x);
+                settings.put(DIALOG_HEIGHT, shellSize.y);
+                FontData [] fontDatas = JFaceResources.getDialogFont().getFontData();
+                if (fontDatas.length > 0) {
+                    settings.put(DIALOG_FONT_DATA, fontDatas[0].toString());
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the initial size to use for the shell. Overridden
+     * to check whether a size has been stored in dialog settings.
+     * If a size has been stored, it is returned.
+     *
+     * @return the initial size of the shell
+     *
+     * @since 3.2
+     * @see #getDialogBoundsSettings()
+     * @see #getDialogBoundsStrategy()
+     */
+    protected override Point getInitialSize() {
+        Point result = super.getInitialSize();
+
+        // Check the dialog settings for a stored size.
+        if ((getDialogBoundsStrategy() & DIALOG_PERSISTSIZE)!is 0) {
+            IDialogSettings settings = getDialogBoundsSettings();
+            if (settings !is null) {
+                // Check that the dialog font matches the font used
+                // when the bounds was stored.  If the font has changed,
+                // we do not honor the stored settings.
+                // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=132821
+                bool useStoredBounds = true;
+                String previousDialogFontData = settings.get(DIALOG_FONT_DATA);
+                // There is a previously stored font, so we will check it.
+                // Note that if we haven't stored the font before, then we will
+                // use the stored bounds.  This allows restoring of dialog bounds
+                // that were stored before we started storing the fontdata.
+                if (previousDialogFontData !is null && previousDialogFontData.length > 0) {
+                    FontData [] fontDatas = JFaceResources.getDialogFont().getFontData();
+                    if (fontDatas.length > 0) {
+                        String currentDialogFontData = fontDatas[0].toString();
+                        useStoredBounds = currentDialogFontData.equalsIgnoreCase(previousDialogFontData);
+                    }
+                }
+                if (useStoredBounds) {
+                    try {
+                        // Get the stored width and height.
+                        int width = settings.getInt(DIALOG_WIDTH);
+                        if (width !is DIALOG_DEFAULT_BOUNDS) {
+                            result.x = width;
+                        }
+                        int height = settings.getInt(DIALOG_HEIGHT);
+                        if (height !is DIALOG_DEFAULT_BOUNDS) {
+                            result.y = height;
+                        }
+
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            }
+        }
+        // No attempt is made to constrain the bounds. The default
+        // constraining behavior in Window will be used.
+        return result;
+    }
+
+    /**
+     * Returns the initial location to use for the shell. Overridden
+     * to check whether the bounds of the dialog have been stored in
+     * dialog settings.  If a location has been stored, it is returned.
+     *
+     * @param initialSize
+     *            the initial size of the shell, as returned by
+     *            <code>getInitialSize</code>.
+     * @return the initial location of the shell
+     *
+     * @since 3.2
+     * @see #getDialogBoundsSettings()
+     * @see #getDialogBoundsStrategy()
+     */
+    protected override Point getInitialLocation(Point initialSize) {
+        Point result = super.getInitialLocation(initialSize);
+        if ((getDialogBoundsStrategy() & DIALOG_PERSISTLOCATION)!is 0) {
+            IDialogSettings settings = getDialogBoundsSettings();
+            if (settings !is null) {
+                try {
+                    int x = settings.getInt(DIALOG_ORIGIN_X);
+                    int y = settings.getInt(DIALOG_ORIGIN_Y);
+                    result = new Point(x, y);
+                    // The coordinates were stored relative to the parent shell.
+                    // Convert to display coordinates.
+                    Shell parent = getParentShell();
+                    if (parent !is null) {
+                        Point parentLocation = parent.getLocation();
+                        result.x += parentLocation.x;
+                        result.y += parentLocation.y;
+                    }
+                } catch (NumberFormatException e) {
+                }
+            }
+        }
+        // No attempt is made to constrain the bounds. The default
+        // constraining behavior in Window will be used.
+        return result;
+    }
+    
+    /**
+     * Returns a bool indicating whether the dialog should be
+     * considered resizable when the shell style is initially
+     * set.  
+     * 
+     * This method is used to ensure that all style 
+     * bits appropriate for resizable dialogs are added to the 
+     * shell style.  Individual dialogs may always set the shell 
+     * style to ensure that a dialog is resizable, but using this
+     * method ensures that resizable dialogs will be created with
+     * the same set of style bits.
+     * 
+     * Style bits will never be removed based on the return value 
+     * of this method.  For example, if a dialog returns 
+     * <code>false</code>, but also sets a style bit for a 
+     * SWT.RESIZE border, the style bit will be honored.
+     * 
+     * @return a bool indicating whether the dialog is 
+     * resizable and should have the default style bits for
+     * resizable dialogs
+     * 
+     * @since 3.4
+     */
+    protected bool isResizable() {
+        return false;
+    }
+}