| /******************************************************************************* |
| * Copyright (c) 2000, 2016 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 |
| * Lars Vogel <Lars.Vogel@vogella.com> - Bug 472690 |
| *******************************************************************************/ |
| package org.eclipse.jface.dialogs; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CLabel; |
| import org.eclipse.swt.graphics.Image; |
| 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.Label; |
| import org.eclipse.swt.widgets.Shell; |
| |
| /** |
| * A dialog for showing messages to the user. |
| * <p> |
| * This concrete dialog class can be instantiated as is, or further subclassed |
| * as required. |
| * </p> |
| * <p> |
| * <strong>Note:</strong> This class does not use button IDs from |
| * IDialogConstants. Instead, the ID is the index of the button in the supplied |
| * array. |
| * </p> |
| */ |
| public class MessageDialog extends IconAndMessageDialog { |
| /** |
| * Constant for no image (value 0). |
| * |
| * @see #MessageDialog(Shell, String, Image, String, int, int, String...) |
| */ |
| public final static int NONE = 0; |
| |
| /** |
| * Constant for the error image, or a simple dialog with the error image and |
| * a single OK button (value 1). |
| * |
| * @see #MessageDialog(Shell, String, Image, String, int, int, String...) |
| * @see #open(int, Shell, String, String, int) |
| */ |
| public final static int ERROR = 1; |
| |
| /** |
| * Constant for the info image, or a simple dialog with the info image and a |
| * single OK button (value 2). |
| * |
| * @see #MessageDialog(Shell, String, Image, String, int, int, String...) |
| * @see #open(int, Shell, String, String, int) |
| */ |
| public final static int INFORMATION = 2; |
| |
| /** |
| * Constant for the question image, or a simple dialog with the question |
| * image and Yes/No buttons (value 3). |
| * |
| * @see #MessageDialog(Shell, String, Image, String, int, int, String...) |
| * @see #open(int, Shell, String, String, int) |
| */ |
| public final static int QUESTION = 3; |
| |
| /** |
| * Constant for the warning image, or a simple dialog with the warning image |
| * and a single OK button (value 4). |
| * |
| * @see #MessageDialog(Shell, String, Image, String, int, int, String...) |
| * @see #open(int, Shell, String, String, int) |
| */ |
| public final static int WARNING = 4; |
| |
| /** |
| * Constant for a simple dialog with the question image and OK/Cancel buttons (value 5). |
| * |
| * @see #open(int, Shell, String, String, int) |
| * @since 3.5 |
| */ |
| public final static int CONFIRM = 5; |
| |
| /** |
| * Constant for a simple dialog with the question image and Yes/No/Cancel buttons (value 6). |
| * |
| * @see #open(int, Shell, String, String, int) |
| * @since 3.5 |
| */ |
| public final static int QUESTION_WITH_CANCEL = 6; |
| |
| /** |
| * Labels for buttons in the button bar (localized strings). |
| */ |
| private String[] buttonLabels; |
| |
| /** |
| * The buttons. Parallels <code>buttonLabels</code>. |
| */ |
| private Button[] buttons; |
| |
| /** |
| * Index into <code>buttonLabels</code> of the default button. |
| */ |
| private int defaultButtonIndex; |
| |
| /** |
| * Dialog title (a localized string). |
| */ |
| private String title; |
| |
| /** |
| * Dialog title image. |
| */ |
| private Image titleImage; |
| |
| /** |
| * Image, or <code>null</code> if none. |
| */ |
| private Image image = null; |
| |
| /** |
| * The custom dialog area. |
| */ |
| private Control customArea; |
| |
| /** |
| * Create a message dialog. Note that the dialog will have no visual |
| * representation (no widgets) until it is told to open. |
| * <p> |
| * The labels of the buttons to appear in the button bar are supplied in |
| * this constructor as an array. The <code>open</code> method will return |
| * the index of the label in this array corresponding to the button that was |
| * pressed to close the dialog. |
| * </p> |
| * <p> |
| * <strong>Note:</strong> If the dialog was dismissed without pressing a |
| * button (ESC key, close box, etc.) then {@link SWT#DEFAULT} is returned. |
| * Note that the <code>open</code> method blocks. |
| * </p> |
| * |
| * As of 3.11 you can also use the other constructor which is based on |
| * varargs |
| * |
| * @param parentShell |
| * the parent shell, or <code>null</code> to create a top-level |
| * shell |
| * @param dialogTitle |
| * the dialog title, or <code>null</code> if none |
| * @param dialogTitleImage |
| * the dialog title image, or <code>null</code> if none |
| * @param dialogMessage |
| * 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 |
| * |
| */ |
| public MessageDialog(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, |
| int dialogImageType, String[] dialogButtonLabels, int defaultIndex) { |
| super(parentShell); |
| init(dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, defaultIndex, dialogButtonLabels); |
| } |
| |
| /** |
| * Create a message dialog. Note that the dialog will have no visual |
| * representation (no widgets) until it is told to open. |
| * <p> |
| * The labels of the buttons to appear in the button bar are supplied in |
| * this constructor as a varargs of Strings. The <code>open</code> method |
| * will return the index of the label in this array corresponding to the |
| * button that was pressed to close the dialog. |
| * </p> |
| * <p> |
| * <strong>Note:</strong> If the dialog was dismissed without pressing a |
| * button (ESC key, close box, etc.) then {@link SWT#DEFAULT} is returned. |
| * Note that the <code>open</code> method blocks. |
| * </p> |
| * |
| * @param parentShell |
| * the parent shell, or <code>null</code> to create a top-level |
| * shell |
| * @param dialogTitle |
| * the dialog title, or <code>null</code> if none |
| * @param dialogTitleImage |
| * the dialog title image, or <code>null</code> if none |
| * @param dialogMessage |
| * 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 defaultIndex |
| * the index in the button label array of the default button |
| * |
| * @param dialogButtonLabels |
| * varargs of Strings for the button labels in the button bar |
| * |
| * @since 3.12 |
| */ |
| public MessageDialog(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, |
| int dialogImageType, int defaultIndex, String... dialogButtonLabels) { |
| super(parentShell); |
| init(dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, defaultIndex, dialogButtonLabels); |
| } |
| |
| private void init(String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, |
| int defaultIndex, String... dialogButtonLabels) { |
| this.title = dialogTitle; |
| this.titleImage = dialogTitleImage; |
| this.message = dialogMessage; |
| |
| switch (dialogImageType) { |
| case ERROR: { |
| this.image = getErrorImage(); |
| break; |
| } |
| case INFORMATION: { |
| this.image = getInfoImage(); |
| break; |
| } |
| case QUESTION: |
| case QUESTION_WITH_CANCEL: |
| case CONFIRM: { |
| this.image = getQuestionImage(); |
| break; |
| } |
| case WARNING: { |
| this.image = getWarningImage(); |
| break; |
| } |
| } |
| this.buttonLabels = dialogButtonLabels; |
| this.defaultButtonIndex = defaultIndex; |
| } |
| |
| @Override |
| protected void buttonPressed(int buttonId) { |
| setReturnCode(buttonId); |
| close(); |
| } |
| |
| @Override |
| protected void configureShell(Shell shell) { |
| super.configureShell(shell); |
| if (title != null) { |
| shell.setText(title); |
| } |
| if (titleImage != null) { |
| shell.setImage(titleImage); |
| } |
| } |
| |
| @Override |
| protected void createButtonsForButtonBar(Composite parent) { |
| buttons = new Button[buttonLabels.length]; |
| for (int i = 0; i < buttonLabels.length; i++) { |
| String label = buttonLabels[i]; |
| Button button = createButton(parent, i, label, defaultButtonIndex == i); |
| buttons[i] = button; |
| } |
| } |
| |
| /** |
| * Creates and returns the contents of an area of the dialog which appears |
| * below the message and above the button bar. |
| * <p> |
| * The default implementation of this framework method returns |
| * <code>null</code>. Subclasses may override. |
| * </p> |
| * |
| * @param parent |
| * parent composite to contain the custom area |
| * @return the custom area control, or <code>null</code> |
| */ |
| protected Control createCustomArea(Composite parent) { |
| return null; |
| } |
| |
| /** |
| * This implementation of the <code>Dialog</code> framework method creates |
| * and lays out a composite and calls <code>createMessageArea</code> and |
| * <code>createCustomArea</code> to populate it. Subclasses should |
| * override <code>createCustomArea</code> to add contents below the |
| * message. |
| */ |
| @Override |
| protected Control createDialogArea(Composite parent) { |
| // create message area |
| createMessageArea(parent); |
| // create the top level composite for the dialog area |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| composite.setLayout(layout); |
| GridData data = new GridData(GridData.FILL_BOTH); |
| data.horizontalSpan = 2; |
| composite.setLayoutData(data); |
| // allow subclasses to add custom controls |
| customArea = createCustomArea(composite); |
| //If it is null create a dummy label for spacing purposes |
| if (customArea == null) { |
| customArea = new Label(composite, SWT.NULL); |
| } |
| return composite; |
| } |
| |
| /** |
| * Gets a button in this dialog's button bar. |
| * |
| * @param index |
| * the index of the button in the dialog's button bar |
| * @return a button in the dialog's button bar, or <code>null</code> if there's no button with that index |
| */ |
| @Override |
| protected Button getButton(int index) { |
| if (buttons == null || index < 0 || index >= buttons.length) { |
| return null; |
| } |
| return buttons[index]; |
| } |
| |
| /** |
| * Returns the minimum message area width in pixels This determines the |
| * minimum width of the dialog. |
| * <p> |
| * Subclasses may override. |
| * </p> |
| * |
| * @return the minimum message area width (in pixels) |
| */ |
| protected int getMinimumMessageWidth() { |
| return convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); |
| } |
| |
| /** |
| * Handle the shell close. Set the return code to <code>SWT.DEFAULT</code> |
| * as there has been no explicit close by the user. |
| * |
| * @see org.eclipse.jface.window.Window#handleShellCloseEvent() |
| */ |
| @Override |
| protected void handleShellCloseEvent() { |
| //Sets a return code of SWT.DEFAULT since none of the dialog buttons |
| // were pressed to close the dialog. |
| super.handleShellCloseEvent(); |
| setReturnCode(SWT.DEFAULT); |
| } |
| |
| /** |
| * Opens this message dialog, creating it first if it has not yet been created. |
| * <p> |
| * This method waits until the dialog is closed by the end user, and then it |
| * returns the dialog's return code. The dialog's return code is either the |
| * index of the button the user pressed, or {@link SWT#DEFAULT} if the dialog |
| * has been closed by other means. |
| * </p> |
| * |
| * @return the return code |
| * |
| * @see org.eclipse.jface.window.Window#open() |
| */ |
| @Override |
| public int open() { |
| return super.open(); |
| } |
| |
| /** |
| * Convenience method to open a simple dialog as specified by the |
| * <code>kind</code> flag. |
| * |
| * @param kind |
| * the kind of dialog to open, one of {@link #ERROR}, |
| * {@link #INFORMATION}, {@link #QUESTION}, {@link #WARNING}, |
| * {@link #CONFIRM}, or {@link #QUESTION_WITH_CANCEL}. |
| * @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 style |
| * {@link SWT#NONE} for a default dialog, or {@link SWT#SHEET} for |
| * a dialog with sheet behavior |
| * @return <code>true</code> if the user presses the OK or Yes button, |
| * <code>false</code> otherwise |
| * @since 3.5 |
| */ |
| public static boolean open(int kind, Shell parent, String title, String message, int style) { |
| MessageDialog dialog = new MessageDialog(parent, title, null, message, kind, 0, getButtonLabels(kind)); |
| style &= SWT.SHEET; |
| dialog.setShellStyle(dialog.getShellStyle() | style); |
| return dialog.open() == 0; |
| } |
| |
| static String[] getButtonLabels(int kind) { |
| String[] dialogButtonLabels; |
| switch (kind) { |
| case ERROR: |
| case INFORMATION: |
| case WARNING: { |
| dialogButtonLabels = new String[] { IDialogConstants.OK_LABEL }; |
| break; |
| } |
| case CONFIRM: { |
| dialogButtonLabels = new String[] { IDialogConstants.OK_LABEL, |
| IDialogConstants.CANCEL_LABEL }; |
| break; |
| } |
| case QUESTION: { |
| dialogButtonLabels = new String[] { IDialogConstants.YES_LABEL, |
| IDialogConstants.NO_LABEL }; |
| break; |
| } |
| case QUESTION_WITH_CANCEL: { |
| dialogButtonLabels = new String[] { IDialogConstants.YES_LABEL, |
| IDialogConstants.NO_LABEL, |
| IDialogConstants.CANCEL_LABEL }; |
| break; |
| } |
| default: { |
| throw new IllegalArgumentException("Illegal value for kind in MessageDialog.open()"); //$NON-NLS-1$ |
| } |
| } |
| return dialogButtonLabels; |
| } |
| |
| /** |
| * 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 |
| * @return <code>true</code> if the user presses the OK button, |
| * <code>false</code> otherwise |
| */ |
| public static boolean openConfirm(Shell parent, String title, String message) { |
| return open(CONFIRM, parent, title, message, SWT.NONE); |
| } |
| |
| /** |
| * 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 |
| */ |
| public static void openError(Shell parent, String title, String message) { |
| open(ERROR, parent, title, message, SWT.NONE); |
| } |
| |
| /** |
| * 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 |
| */ |
| public static void openInformation(Shell parent, String title, String message) { |
| open(INFORMATION, parent, title, message, SWT.NONE); |
| } |
| |
| /** |
| * 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 |
| * @return <code>true</code> if the user presses the Yes button, |
| * <code>false</code> otherwise |
| */ |
| public static boolean openQuestion(Shell parent, String title, String message) { |
| return open(QUESTION, parent, title, message, SWT.NONE); |
| } |
| |
| /** |
| * 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 |
| */ |
| public static void openWarning(Shell parent, String title, String message) { |
| open(WARNING, parent, title, message, SWT.NONE); |
| } |
| |
| @Override |
| protected Button createButton(Composite parent, int id, String label, boolean defaultButton) { |
| Button button = super.createButton(parent, id, label, defaultButton); |
| //Be sure to set the focus if the custom area cannot so as not |
| //to lose the defaultButton. |
| if (defaultButton && !customShouldTakeFocus()) { |
| button.setFocus(); |
| } |
| return button; |
| } |
| |
| /** |
| * Return whether or not we should apply the workaround where we take focus |
| * for the default button or if that should be determined by the dialog. By |
| * default only return true if the custom area is a label or CLabel that |
| * cannot take focus. |
| * |
| * @return boolean |
| */ |
| protected boolean customShouldTakeFocus() { |
| if (customArea instanceof Label) { |
| return false; |
| } |
| if (customArea instanceof CLabel) { |
| return (customArea.getStyle() & SWT.NO_FOCUS) > 0; |
| } |
| return true; |
| } |
| |
| @Override |
| public Image getImage() { |
| return image; |
| } |
| |
| /** |
| * An accessor for the labels to use on the buttons. |
| * |
| * @return The button labels to used; never <code>null</code>. |
| */ |
| protected String[] getButtonLabels() { |
| return buttonLabels; |
| } |
| |
| /** |
| * An accessor for the index of the default button in the button array. |
| * |
| * @return The default button index. |
| */ |
| protected int getDefaultButtonIndex() { |
| return defaultButtonIndex; |
| } |
| |
| /** |
| * A mutator for the array of buttons in the button bar. |
| * |
| * @param buttons |
| * The buttons in the button bar; must not be <code>null</code>. |
| */ |
| protected void setButtons(Button... buttons) { |
| if (buttons == null) { |
| throw new NullPointerException("The array of buttons cannot be null."); //$NON-NLS-1$ |
| } |
| this.buttons = buttons; |
| } |
| |
| /** |
| * A mutator for the button labels. |
| * |
| * @param buttonLabels |
| * The button labels to use; must not be <code>null</code>. |
| */ |
| protected void setButtonLabels(String... buttonLabels) { |
| if (buttonLabels == null) { |
| throw new NullPointerException("The array of button labels cannot be null."); //$NON-NLS-1$ |
| } |
| this.buttonLabels = buttonLabels; |
| } |
| } |