| /******************************************************************************* |
| * Copyright (c) 2000, 2016 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 |
| * Lars Vogel <Lars.Vogel@vogella.com> - Bug 472690 |
| *******************************************************************************/ |
| package org.eclipse.jface.dialogs; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| 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; |
| |
| /** |
| * The PlainMessageDialog represents a message dialog with a clear, simple API |
| * to create dialogs with message, buttons and image. |
| * |
| * <p> |
| * Instances of this class can be created using the {@link Builder}. An instance |
| * of the builder can be retrieved by calling the static method |
| * {@link #getBuilder(Shell, String)} |
| * </p> |
| * |
| * <p> |
| * This class has to be favored over {@link MessageDialog}, which has an |
| * evolved, non-clear API. |
| * </p> |
| * |
| * @since 3.23 |
| * |
| */ |
| public class PlainMessageDialog extends IconAndMessageDialog { |
| |
| private final String title; |
| private final Image titleImage; |
| private final Image image; |
| private final List<String> buttonLabels; |
| private final int defaultButtonIndex; |
| private Control customArea; |
| |
| /** |
| * The Builder to create PlainMessageDialog instances. It has a fluent API |
| * (every method returns the same builder instance). |
| * |
| * @since 3.23 |
| * |
| */ |
| public static class Builder { |
| private Shell shell; |
| private String dialogTitle; |
| private Image titleImage; |
| private Image image; |
| |
| private int iconId = -1; |
| private String message; |
| private List<String> buttonLabels = Arrays.asList(IDialogConstants.OK_LABEL); |
| private int defaultButtonIndex = 0; |
| |
| private Builder(Shell shell, String dialogTitle) { |
| this.shell = shell; |
| this.dialogTitle = dialogTitle; |
| } |
| |
| /** |
| * Sets the shell's image. |
| * |
| * @see Shell#setImage(Image) |
| * @param image the image |
| * @return this |
| */ |
| public Builder titleImage(Image image) { |
| this.titleImage = image; |
| return this; |
| } |
| |
| /** |
| * Sets the dialog's image (e.g. information icon). |
| * |
| * @param image the image |
| * @return this |
| */ |
| public Builder image(Image image) { |
| this.image = image; |
| return this; |
| } |
| |
| /** |
| * Sets the dialog's image (e.g. information icon). |
| * |
| * @param iconId SWT style of the image, see below for support styles |
| * |
| * @return this |
| * @see SWT#ICON_ERROR |
| * @see SWT#ICON_INFORMATION |
| * @see SWT#ICON_QUESTION |
| * @see SWT#ICON_WARNING |
| * @see SWT#ICON_WORKING |
| */ |
| public Builder image(int iconId) { |
| this.iconId = iconId; |
| return this; |
| } |
| |
| /** |
| * Sets the dialog's message. |
| * |
| * @param message the message |
| * @return this |
| */ |
| public Builder message(String message) { |
| this.message = message; |
| return this; |
| } |
| |
| /** |
| * Sets the dialog's button labels. Without calling |
| * {@link #defaultButtonIndex(int)} the first entry is used for the default |
| * button. |
| * <p> |
| * {@link List#of(Object...)} can be used to call this method in a handy way. |
| * </p> |
| * |
| * @param buttonLabels the button labels |
| * @return this |
| */ |
| public Builder buttonLabels(List<String> buttonLabels) { |
| this.buttonLabels = buttonLabels; |
| return this; |
| } |
| |
| /** |
| * Sets another (other than 0) button as default button. |
| * |
| * @param defaultButtonIndex the default button index |
| * @return this |
| */ |
| public Builder defaultButtonIndex(int defaultButtonIndex) { |
| this.defaultButtonIndex = defaultButtonIndex; |
| return this; |
| } |
| |
| /** |
| * Create the dialog with all the parameters set in the builder. |
| * |
| * @return the PlainMessageDialog instance |
| */ |
| public PlainMessageDialog build() { |
| return new PlainMessageDialog(this); |
| } |
| } |
| |
| /** |
| * Creates a new Builder instance. |
| * |
| * @param shell the parent shell |
| * @param dialogTitle the shell title |
| * @return the builder |
| */ |
| public static Builder getBuilder(Shell shell, String dialogTitle) { |
| return new Builder(shell, dialogTitle); |
| } |
| |
| private PlainMessageDialog(Builder builder) { |
| super(builder.shell); |
| |
| this.title = builder.dialogTitle; |
| this.titleImage = builder.titleImage; |
| if (builder.image == null && builder.iconId != -1) { |
| this.image = builder.shell.getDisplay().getSystemImage(builder.iconId); |
| } else { |
| this.image = builder.image; |
| } |
| this.message = builder.message; |
| this.buttonLabels = builder.buttonLabels; |
| this.defaultButtonIndex = builder.defaultButtonIndex; |
| } |
| |
| @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) { |
| for (int id = 0; id < buttonLabels.size(); id++) { |
| createButton(parent, id, buttonLabels.get(id), defaultButtonIndex == id); |
| } |
| } |
| |
| /** |
| * 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) { |
| Label dummyLabelForSpacingPurposes = new Label(parent, SWT.NULL); |
| return dummyLabelForSpacingPurposes; |
| } |
| |
| /** |
| * 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); |
| return composite; |
| } |
| |
| /** |
| * 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); |
| } |
| |
| /** |
| * Open |
| * |
| * @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.23 |
| */ |
| public int open(int style) { |
| style &= SWT.SHEET; |
| this.setShellStyle(this.getShellStyle() | style); |
| return this.open(); |
| } |
| |
| @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 |
| */ |
| private boolean customShouldTakeFocus() { |
| if (customArea instanceof Label) { |
| return false; |
| } |
| if (customArea instanceof CLabel) { |
| return (customArea.getStyle() & SWT.NO_FOCUS) > 0; |
| } |
| return true; |
| } |
| |
| @Override |
| protected Image getImage() { |
| return image; |
| } |
| } |