All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jface.dialogs.Dialog Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Remy Chi Jian Suen  - Bug 218553 [JFace] mis-spelling of their in applyDialogFont(...)
 *******************************************************************************/
package org.eclipse.jface.dialogs;

import java.util.Arrays;
import java.util.HashMap;

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.widgets.WidgetFactory;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
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;

/**
 * A dialog is a specialized window used for narrow-focused communication with
 * the user.
 * 

* 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. *

*

* If 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. *

*

* This class also moves the default button to the right if required, see * {@link #initializeBounds()}. *

*/ public abstract class Dialog extends Window { /** * Image registry key for error image (value * "dialog_error_image"). * * @deprecated use * org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_ERROR) */ @Deprecated(forRemoval = true, since = "2023-12") public static final String DLG_IMG_ERROR = "dialog_error_image"; //$NON-NLS-1$ /** * Image registry key for info image (value "dialog_info_image"). * * @deprecated use * org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_INFORMATION) */ @Deprecated(forRemoval = true, since = "2023-12") public static final String DLG_IMG_INFO = "dialog_info_imageg"; //$NON-NLS-1$ /** * Image registry key for question image (value * "dialog_question_image"). * * @deprecated org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_QUESTION) */ @Deprecated(forRemoval = true, since = "2023-12") public static final String DLG_IMG_QUESTION = "dialog_question_image"; //$NON-NLS-1$ /** * Image registry key for warning image (value * "dialog_warning_image"). * * @deprecated use * org.eclipse.swt.widgets.Display.getSystemImage(SWT.ICON_WARNING) */ @Deprecated public static final String DLG_IMG_WARNING = "dialog_warning_image"; //$NON-NLS-1$ /** * Image registry key for info message image (value * "dialog_messasge_info_image"). * * @since 2.0 */ public static final String DLG_IMG_MESSAGE_INFO = "dialog_messasge_info_image"; //$NON-NLS-1$ /** * Image registry key for info message image (value * "dialog_messasge_warning_image"). * * @since 2.0 */ public static final String DLG_IMG_MESSAGE_WARNING = "dialog_messasge_warning_image"; //$NON-NLS-1$ /** * Image registry key for info message image (value * "dialog_message_error_image"). * * @since 2.0 */ public static final String DLG_IMG_MESSAGE_ERROR = "dialog_message_error_image"; //$NON-NLS-1$ /** * Image registry key for help image (value * "dialog_help_image"). * * @since 3.2 */ public static final 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 final String ELLIPSIS = "..."; //$NON-NLS-1$ /** * The dialog settings key name for stored dialog x location. * * @since 3.2 */ private static final 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 final String DIALOG_ORIGIN_Y = "DIALOG_Y_ORIGIN"; //$NON-NLS-1$ /** * The dialog settings key name for stored dialog width. * * @since 3.2 */ private static final String DIALOG_WIDTH = "DIALOG_WIDTH"; //$NON-NLS-1$ /** * The dialog settings key name for stored dialog height. * * @since 3.2 */ private static final 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 final 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 final 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 final int DIALOG_PERSISTLOCATION = 0x0001; /** * Persist the last known size of the dialog. * @since 3.2 */ public static final int DIALOG_PERSISTSIZE = 0x0002; /** * The dialog area; null until dialog is layed out. */ protected Control dialogArea; /** * The button bar; null until dialog is layed out. */ public Control buttonBar; /** * Collection of buttons created by the createButton method. */ private HashMap buttons = new HashMap<>(); /** * Font metrics to use for determining pixel sizes. */ private FontMetrics fontMetrics; /** * Number of horizontal dialog units per character, value 4. */ private static final int HORIZONTAL_DIALOG_UNIT_PER_CHAR = 4; /** * Number of vertical dialog units per character, value 8. */ private static final int VERTICAL_DIALOG_UNITS_PER_CHAR = 8; /** * Returns the number of pixels corresponding to the height of the given number * of characters. *

* The required FontMetrics parameter may be created in the * following way: *

* *
	 * GC gc = new GC(control);
	 * gc.setFont(control.getFont());
	 * fontMetrics = gc.getFontMetrics();
	 * gc.dispose();
	 * 
* * @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. *

* The required FontMetrics parameter may be created in the * following way: *

* *
	 * GC gc = new GC(control);
	 * gc.setFont(control.getFont());
	 * fontMetrics = gc.getFontMetrics();
	 * gc.dispose();
	 * 
* * @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 (int) ((fontMetrics.getAverageCharacterWidth() * 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. *

* The required FontMetrics parameter may be created in the * following way: *

* *
	 * GC gc = new GC(control);
	 * gc.setFont(control.getFont());
	 * fontMetrics = gc.getFontMetrics();
	 * gc.dispose();
	 * 
* * @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. *

* The required FontMetrics parameter may be created in the * following way: *

* *
	 * GC gc = new GC(control);
	 * gc.setFont(control.getFont());
	 * fontMetrics = gc.getFontMetrics();
	 * gc.dispose();
	 * 
* * @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 (int) (fontMetrics.getAverageCharacterWidth() * chars); } /** * Try to shorten the given text textValue 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 null value is given, null is returned. *

* Note: if the text cannot be shortened because the width of control is * too low the full original string is returned. *

* * @param textValue the original string or null * @param control the control the string will be displayed on * @return the string to display, or null if null was passed in * * @since 3.0 */ public static String shortenText(String textValue, Control control) { if (textValue == 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 = Math.round(0.95f*length * (1 - ((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. */ public static IDialogBlockedHandler blockedHandler = new IDialogBlockedHandler() { @Override public void clearBlocked() { // No default behavior } @Override public void showBlocked(IProgressMonitor blocking, IStatus blockingStatus, String blockedName) { // No default behavior } @Override public void showBlocked(Shell parentShell, IProgressMonitor blocking, IStatus blockingStatus, String blockedName) { // No default behavior } }; /** * Creates a dialog instance. Note that the window will have no visual * representation (no widgets) until it is told to open. By default, * open blocks for dialogs. * * @param parentShell * the parent shell, or null to create a top-level * shell */ protected Dialog(Shell parentShell) { this(new SameShellProvider(parentShell)); if (parentShell == null && Policy.DEBUG_DIALOG_NO_PARENT) { Policy.getLog().log( new Status(IStatus.INFO, Policy.JFACE, IStatus.INFO, this .getClass() + " created with no shell",//$NON-NLS-1$ new Exception())); } } /** * Creates a dialog with the given parent. * * @param parentShell * object that returns the current parent shell * * @since 3.1 */ protected Dialog(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. *

* The Dialog implementation of this framework method calls * okPressed if the ok button is the pressed, and * cancelPressed if the cancel button is the pressed. All * other button presses are ignored. Subclasses may override to handle other * buttons, but should call super.buttonPressed if the * default handling of the ok and cancel buttons is desired. *

* * @param buttonId * the id of the button that was pressed (see * IDialogConstants.*_ID constants) */ protected void buttonPressed(int buttonId) { if (IDialogConstants.OK_ID == buttonId) { okPressed(); } else if (IDialogConstants.CANCEL_ID == buttonId) { cancelPressed(); } } /** * Notifies that the cancel button of this dialog has been pressed. *

* The Dialog implementation of this framework method sets * this dialog's return code to Window.CANCEL and closes the * dialog. Subclasses may override if desired. *

*/ protected void cancelPressed() { setReturnCode(CANCEL); close(); } /** * Returns the number of pixels corresponding to the height of the given * number of characters. *

* This method may only be called after initializeDialogUnits * has been called. *

*

* Clients may call this framework method, but should not override it. *

* * @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 == null) { return 0; } return convertHeightInCharsToPixels(fontMetrics, chars); } /** * Returns the number of pixels corresponding to the given number of * horizontal dialog units. *

* This method may only be called after initializeDialogUnits * has been called. *

*

* Clients may call this framework method, but should not override it. *

* * @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 == null) { return 0; } return convertHorizontalDLUsToPixels(fontMetrics, dlus); } /** * Returns the number of pixels corresponding to the given number of * vertical dialog units. *

* This method may only be called after initializeDialogUnits * has been called. *

*

* Clients may call this framework method, but should not override it. *

* * @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 == null) { return 0; } return convertVerticalDLUsToPixels(fontMetrics, dlus); } /** * Returns the number of pixels corresponding to the width of the given * number of characters. *

* This method may only be called after initializeDialogUnits * has been called. *

*

* Clients may call this framework method, but should not override it. *

* * @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 == null) { return 0; } return convertWidthInCharsToPixels(fontMetrics, chars); } /** * Creates a new button with the given id. *

* The Dialog 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 * IDialogConstants.CANCEL_ID, the new button will be * accessible from getCancelButton(). If the button id is * IDialogConstants.OK_ID, the new button will be accesible * from getOKButton(). Note that the parent's layout is * assumed to be a GridLayout and the number of columns in * this layout is incremented. Subclasses may override. *

*

* Note: The common button order is: {other buttons}, OK, Cancel. * On some platforms, {@link #initializeBounds()} will move the default button to the right. *

* * @param parent * the parent composite * @param id * the id of the button (see IDialogConstants.*_ID * constants for standard dialog button ids) * @param label * the label from the button * @param defaultButton * true if the button is to be the default button, * and false otherwise * * @return the new button * * @see #getCancelButton * @see #getOKButton() */ protected Button createButton(Composite parent, int id, String label, boolean defaultButton) { // increment the number of columns in the button bar ((GridLayout) parent.getLayout()).numColumns++; Button button = WidgetFactory.button(SWT.PUSH).text(label).font(JFaceResources.getDialogFont()) .data(Integer.valueOf(id)) .onSelect(event -> buttonPressed(((Integer) event.widget.getData()).intValue())). create(parent); if (defaultButton) { Shell shell = parent.getShell(); if (shell != null) { shell.setDefaultButton(button); } } buttons.put(Integer.valueOf(id), button); setButtonLayoutData(button); return button; } /** * Creates and returns the contents of this dialog's button bar. *

* The Dialog implementation of this framework method lays * out a button bar and calls the createButtonsForButtonBar * framework method to populate it. Subclasses may override. *

*

* The returned control's layout data must be an instance of * GridData. *

* * @param parent * the parent composite to contain the button bar * @return the button bar control */ protected Control createButtonBar(Composite parent) { // 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); GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); Composite composite = WidgetFactory.composite(SWT.NONE).layout(layout).layoutData(data).font(parent.getFont()) .create(parent); // Add the buttons to the button bar. createButtonsForButtonBar(composite); return composite; } /** * Adds buttons to this dialog's button bar. *

* The Dialog implementation of this framework method adds * standard ok and cancel buttons using the createButton * framework method. These standard buttons will be accessible from * getCancelButton, and getOKButton. * Subclasses may override. *

*

* Note: The common button order is: {other buttons}, OK, Cancel. * On some platforms, {@link #initializeBounds()} will move the default button to the right. *

* * @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); } /** * {@inheritDoc} *

* The implementation in {@link #Dialog} also moves the * {@link Shell#getDefaultButton() default button} in the * {@link #createButtonBar(Composite) button bar} to the right * if that's required by the * {@link Display#getDismissalAlignment() platform convention}. *

*/ @Override protected void initializeBounds() { // UI guidelines: // https://developer.gnome.org/hig/stable/dialogs.html.en#primary-buttons // https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/WindowDialogs.html#//apple_ref/doc/uid/20000957-CH43-SW5 // https://msdn.microsoft.com/en-us/library/windows/desktop/dn742499(v=vs.85).aspx#win_dialog_box_image25 Shell shell = getShell(); if (shell != null) { if (shell.getDisplay().getDismissalAlignment() == SWT.RIGHT) { // make the default button the right-most button Button defaultButton = shell.getDefaultButton(); if (defaultButton != null && isContained(buttonBar, defaultButton)) { defaultButton.moveBelow(null); defaultButton.getParent().layout(); } } } super.initializeBounds(); } /** * Returns true if the given Control is a direct or indirect child of * container. * * @param container * the potential parent * @return boolean true if control is a child of container */ private boolean isContained(Control container, Control control) { Composite parent; while ((parent = control.getParent()) != null) { if (parent == container) { return true; } control = parent; } return false; } /** * The Dialog implementation of this Window * 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 createDialogArea and * createButtonBar methods to create the dialog area and * button bar, respectively. Overriding createDialogArea and * createButtonBar are recommended rather than overriding * this method. */ @Override protected Control createContents(Composite parent) { // create the top level composite for the dialog GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; layout.verticalSpacing = 0; Composite composite = WidgetFactory.composite(0).layout(layout).layoutData(new GridData(GridData.FILL_BOTH)) .create(parent); 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). *

* The Dialog implementation of this framework method creates * and returns a new Composite with standard margins and * spacing. *

*

* The returned control's layout data must be an instance of * GridData. This method must not modify the parent's * layout. *

*

* Subclasses must override this method but may call super as * in the following example: *

* *
	 * Composite composite = (Composite) super.createDialogArea(parent);
	 * //add controls to composite as necessary
	 * return composite;
	 * 
* * @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 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 composite = WidgetFactory.composite(SWT.NONE).layout(layout) .layoutData(new GridData(GridData.FILL_BOTH)).create(parent); applyDialogFont(composite); return composite; } /** * Returns the button created by the method createButton for * the specified ID as defined on IDialogConstants. If * createButton was never called with this ID, or if * createButton is overridden, this method will return * null. * * @param id * the id of the button to look for * * @return the button for the ID or null * * @see #createButton(Composite, int, String, boolean) * @since 2.0 */ protected Button getButton(int id) { return buttons.get(Integer.valueOf(id)); } /** * Returns the button bar control. *

* Clients may call this framework method, but should not override it. *

* * @return the button bar, or null if the button bar has not * been created yet */ protected Control getButtonBar() { return buttonBar; } /** * Returns the button created when createButton is called * with an ID of IDialogConstants.CANCEL_ID. If * createButton was never called with this parameter, or if * createButton is overridden, getCancelButton * will return null. * * @return the cancel button or null * * @see #createButton(Composite, int, String, boolean) * @since 2.0 * @deprecated Use getButton(IDialogConstants.CANCEL_ID) * instead. This method will be removed soon. */ @Deprecated protected Button getCancelButton() { return getButton(IDialogConstants.CANCEL_ID); } /** * Returns the dialog area control. *

* Clients may call this framework method, but should not override it. *

* * @return the dialog area, or null 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 Dialog.DLG_IMG_* 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 createButton is called * with an ID of IDialogConstants.OK_ID. If * createButton was never called with this parameter, or if * createButton is overridden, getOKButton * will return null. * * @return the OK button or null * * @see #createButton(Composite, int, String, boolean) * @since 2.0 * @deprecated Use getButton(IDialogConstants.OK_ID) instead. * This method will be removed soon. */ @Deprecated protected Button getOKButton() { return getButton(IDialogConstants.OK_ID); } /** * Initializes the computation of horizontal and vertical dialog units based * on the size of current font. *

* This method must be called before any of the dialog unit based conversion * methods are called. *

* * @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. *

* The Dialog implementation of this framework method sets * this dialog's return code to Window.OK and closes the * dialog. Subclasses may override. *

*/ protected void okPressed() { setReturnCode(OK); close(); } /** * Set the layout data of the button to a GridData with appropriate heights and * widths. * * @param button The button which layout data is to be set. */ 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 The button which layout data is to be set. */ 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() */ @Override public boolean close() { if (getShell() != null && !getShell().isDisposed()) { saveDialogBounds(getShell()); } boolean returnValue = super.close(); if (returnValue) { buttons = new HashMap<>(); 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 null nothing * happens. */ public static void applyDialogFont(Control control) { if (control == 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 (control instanceof Composite) { Control[] children = ((Composite) control).getChildren(); for (Control element : children) { applyDialogFont(element, dialogFont); } } } /** * Return whether or not this control has the same font as it's default. * * @param control * Control * @return boolean */ private static boolean hasDefaultFont(Control control) { FontData[] controlFontData = control.getFont().getFontData(); FontData[] defaultFontData = getDefaultFont(control).getFontData(); if (controlFontData.length == defaultFontData.length) { for (int i = 0; i < controlFontData.length; i++) { if (controlFontData[i].equals(defaultFontData[i])) { continue; } return false; } return true; } return false; } /** * Get the default font for this type of control. * * @return the default font */ private static Font getDefaultFont(Control control) { String fontName = "DEFAULT_FONT_" + control.getClass().getName(); //$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 boolean if the two are the same */ protected static boolean dialogFontIsDefault() { FontData[] dialogFontData = JFaceResources.getFontRegistry() .getFontData(JFaceResources.DIALOG_FONT); FontData[] defaultFontData = JFaceResources.getFontRegistry() .getFontData(JFaceResources.DEFAULT_FONT); return Arrays.equals(dialogFontData, defaultFontData); } @Override public 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 null 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 != null) { Point shellLocation = shell.getLocation(); Point shellSize = shell.getSize(); Shell parent = getParentShell(); if (parent != null) { Point parentLocation = parent.getLocation(); shellLocation.x -= parentLocation.x; shellLocation.y -= parentLocation.y; } int strategy = getDialogBoundsStrategy(); if ((strategy & DIALOG_PERSISTLOCATION) != 0) { settings.put(DIALOG_ORIGIN_X, shellLocation.x); settings.put(DIALOG_ORIGIN_Y, shellLocation.y); } if ((strategy & DIALOG_PERSISTSIZE) != 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() */ @Override protected Point getInitialSize() { Point result = super.getInitialSize(); // Check the dialog settings for a stored size. if ((getDialogBoundsStrategy() & DIALOG_PERSISTSIZE)!= 0) { IDialogSettings settings = getDialogBoundsSettings(); if (settings != 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 boolean 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 != 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 != DIALOG_DEFAULT_BOUNDS) { result.x = width; } int height = settings.getInt(DIALOG_HEIGHT); if (height != 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 * getInitialSize. * @return the initial location of the shell * * @since 3.2 * @see #getDialogBoundsSettings() * @see #getDialogBoundsStrategy() */ @Override protected Point getInitialLocation(Point initialSize) { Point result = super.getInitialLocation(initialSize); if ((getDialogBoundsStrategy() & DIALOG_PERSISTLOCATION)!= 0) { IDialogSettings settings = getDialogBoundsSettings(); if (settings != 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 != 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 boolean 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 false, but also sets a style * bit for a SWT.RESIZE border, the style bit will be honored. *

* * @return a boolean indicating whether the dialog is resizable and should have * the default style bits for resizable dialogs * * @since 3.4 */ protected boolean isResizable() { return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy