001/*****************************************************************************
002 * Copyright by The HDF Group.                                               *
003 * Copyright by the Board of Trustees of the University of Illinois.         *
004 * All rights reserved.                                                      *
005 *                                                                           *
006 * This file is part of the HDF Java Products distribution.                  *
007 * The full copyright notice, including terms governing use, modification,   *
008 * and redistribution, is contained in the COPYING file, which can be found  *
009 * at the root of the source code distribution tree,                         *
010 * or in https://www.hdfgroup.org/licenses.                                  *
011 * If you do not have access to either file, you may request a copy from     *
012 * help@hdfgroup.org.                                                        *
013 ****************************************************************************/
014
015package hdf.view.dialog;
016
017import hdf.HDFVersions;
018import hdf.view.ViewProperties;
019
020import org.eclipse.swt.SWT;
021import org.eclipse.swt.events.DisposeEvent;
022import org.eclipse.swt.events.DisposeListener;
023import org.eclipse.swt.events.SelectionAdapter;
024import org.eclipse.swt.events.SelectionEvent;
025import org.eclipse.swt.graphics.Font;
026import org.eclipse.swt.graphics.Point;
027import org.eclipse.swt.graphics.Rectangle;
028import org.eclipse.swt.layout.GridData;
029import org.eclipse.swt.layout.GridLayout;
030import org.eclipse.swt.widgets.Button;
031import org.eclipse.swt.widgets.Composite;
032import org.eclipse.swt.widgets.Dialog;
033import org.eclipse.swt.widgets.Display;
034import org.eclipse.swt.widgets.Event;
035import org.eclipse.swt.widgets.Label;
036import org.eclipse.swt.widgets.Listener;
037import org.eclipse.swt.widgets.Shell;
038import org.eclipse.swt.widgets.Text;
039
040/**
041 * Custom SWT dialog to allow the user to input strings
042 * for various uses.
043 */
044// TODO: Add ability to have custom HDF icons
045public class InputDialog extends Dialog {
046    private Text inputField;
047    private final String title;
048    private final String message;
049    private final String initialText;
050    private String result;
051    private Font curFont;
052
053    /**
054     * Custom SWT dialog to allow the user to input strings
055     * for a parent object.
056     *
057     * @param parent
058     *        the dialog parent shell
059     */
060    public InputDialog(Shell parent) { this(parent, "HDFView " + HDFVersions.getPropertyVersionView(), ""); }
061
062    /**
063     * Custom SWT dialog to allow the user to input strings
064     * for a parent object with a title and message.
065     *
066     * @param parent
067     *        the dialog parent shell
068     * @param title
069     *        the dialog title
070     * @param message
071     *        the dialog message
072     */
073    public InputDialog(Shell parent, String title, String message) { this(parent, title, message, ""); }
074
075    /**
076     * Custom SWT dialog to allow the user to input strings
077     * for a parent object with a title, message and style.
078     *
079     * @param parent
080     *        the dialog parent shell
081     * @param title
082     *        the dialog title
083     * @param message
084     *        the dialog message
085     * @param style
086     *        the dialog style
087     */
088    public InputDialog(Shell parent, String title, String message, int style)
089    {
090        this(parent, title, message, "", style);
091    }
092
093    /**
094     * Custom SWT dialog to allow the user to input strings
095     * for a parent object with a title, message and initial text to be displayed.
096     *
097     * @param parent
098     *        the dialog parent shell
099     * @param title
100     *        the dialog title
101     * @param message
102     *        the dialog message
103     * @param initialText
104     *        the dialog initialText
105     */
106    public InputDialog(Shell parent, String title, String message, String initialText)
107    {
108        this(parent, title, message, initialText, SWT.NONE);
109    }
110
111    /**
112     * Custom SWT dialog to allow the user to input strings
113     * for a parent object with a title, message, style and initial text to be displayed.
114     *
115     * @param parent
116     *        the dialog parent shell
117     * @param title
118     *        the dialog title
119     * @param message
120     *        the dialog message
121     * @param initialText
122     *        the dialog initialText
123     * @param style
124     *        the dialog style
125     */
126    public InputDialog(Shell parent, String title, String message, String initialText, int style)
127    {
128        super(parent, style);
129        this.title       = title;
130        this.message     = message;
131        this.initialText = initialText;
132
133        try {
134            curFont = new Font(Display.getCurrent(), ViewProperties.getFontType(),
135                               ViewProperties.getFontSize(), SWT.NORMAL);
136        }
137        catch (Exception ex) {
138            curFont = null;
139        }
140    }
141
142    /**
143     * Opens the InputDialog and returns the user's input
144     * when the dialog closes.
145     *
146     * @return the user input data
147     */
148    public String open()
149    {
150        Shell parent      = getParent();
151        final Shell shell = new Shell(parent, SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE);
152        shell.setFont(curFont);
153        shell.setText(title);
154        shell.setLayout(new GridLayout(1, true));
155
156        Label label = new Label(shell, SWT.NULL);
157        label.setFont(curFont);
158        label.setText(message);
159
160        inputField = new Text(shell, SWT.SINGLE | SWT.BORDER);
161        inputField.setFont(curFont);
162        inputField.setText(initialText);
163        GridData fieldData     = new GridData(SWT.FILL, SWT.FILL, true, false);
164        fieldData.minimumWidth = 300;
165        inputField.setLayoutData(fieldData);
166
167        // Dummy label to fill space as dialog is resized
168        new Label(shell, SWT.NONE).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
169
170        Composite buttonComposite = new Composite(shell, SWT.NONE);
171        buttonComposite.setLayout(new GridLayout(2, true));
172        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
173
174        Button okButton = new Button(buttonComposite, SWT.PUSH);
175        okButton.setFont(curFont);
176        okButton.setText("   &OK   ");
177        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
178        okButton.addSelectionListener(new SelectionAdapter() {
179            public void widgetSelected(SelectionEvent e) { shell.dispose(); }
180        });
181
182        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
183        cancelButton.setFont(curFont);
184        cancelButton.setText(" &Cancel ");
185        cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
186        cancelButton.addSelectionListener(new SelectionAdapter() {
187            public void widgetSelected(SelectionEvent e)
188            {
189                result = null;
190                shell.dispose();
191            }
192        });
193
194        inputField.addListener(SWT.Modify, new Listener() {
195            public void handleEvent(Event event)
196            {
197                try {
198                    result = inputField.getText();
199                }
200                catch (Exception ex) {
201                    System.err.println("Error retrieving input value.");
202                }
203            }
204        });
205
206        shell.addListener(SWT.Traverse, new Listener() {
207            public void handleEvent(Event event)
208            {
209                if (event.detail == SWT.TRAVERSE_ESCAPE)
210                    event.doit = false;
211            }
212        });
213
214        shell.pack();
215
216        shell.addDisposeListener(new DisposeListener() {
217            public void widgetDisposed(DisposeEvent e)
218            {
219                if (curFont != null)
220                    curFont.dispose();
221            }
222        });
223
224        shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
225
226        Rectangle parentBounds = parent.getBounds();
227        Point shellSize        = shell.getSize();
228        shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
229                          (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
230
231        shell.open();
232
233        Display display = parent.getDisplay();
234        while (!shell.isDisposed()) {
235            if (!display.readAndDispatch())
236                display.sleep();
237        }
238
239        // TODO: Display loop should not wait here, but we must wait until
240        // an input is given before returning
241        return result;
242    }
243}