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 org.eclipse.swt.SWT;
018import org.eclipse.swt.events.DisposeEvent;
019import org.eclipse.swt.events.DisposeListener;
020import org.eclipse.swt.events.SelectionAdapter;
021import org.eclipse.swt.events.SelectionEvent;
022import org.eclipse.swt.graphics.Font;
023import org.eclipse.swt.graphics.Point;
024import org.eclipse.swt.graphics.Rectangle;
025import org.eclipse.swt.layout.GridData;
026import org.eclipse.swt.layout.GridLayout;
027import org.eclipse.swt.widgets.Button;
028import org.eclipse.swt.widgets.Composite;
029import org.eclipse.swt.widgets.Dialog;
030import org.eclipse.swt.widgets.Display;
031import org.eclipse.swt.widgets.Event;
032import org.eclipse.swt.widgets.Label;
033import org.eclipse.swt.widgets.Listener;
034import org.eclipse.swt.widgets.Shell;
035import org.eclipse.swt.widgets.Text;
036
037import hdf.HDFVersions;
038import hdf.view.ViewProperties;
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) {
061        this(parent, "HDFView " + HDFVersions.getPropertyVersionView(), "");
062    }
063
064    /**
065     * Custom SWT dialog to allow the user to input strings
066     * for a parent object with a title and message.
067     *
068     * @param parent
069     *        the dialog parent shell
070     * @param title
071     *        the dialog title
072     * @param message
073     *        the dialog message
074     */
075    public InputDialog(Shell parent, String title, String message) {
076        this(parent, title, message, "");
077    }
078
079    /**
080     * Custom SWT dialog to allow the user to input strings
081     * for a parent object with a title, message and style.
082     *
083     * @param parent
084     *        the dialog parent shell
085     * @param title
086     *        the dialog title
087     * @param message
088     *        the dialog message
089     * @param style
090     *        the dialog style
091     */
092    public InputDialog(Shell parent, String title, String message, int style) {
093        this(parent, title, message, "", style);
094    }
095
096    /**
097     * Custom SWT dialog to allow the user to input strings
098     * for a parent object with a title, message and initial text to be displayed.
099     *
100     * @param parent
101     *        the dialog parent shell
102     * @param title
103     *        the dialog title
104     * @param message
105     *        the dialog message
106     * @param initialText
107     *        the dialog initialText
108     */
109    public InputDialog(Shell parent, String title, String message, String initialText) {
110        this(parent, title, message, initialText, SWT.NONE);
111    }
112
113    /**
114     * Custom SWT dialog to allow the user to input strings
115     * for a parent object with a title, message, style and initial text to be displayed.
116     *
117     * @param parent
118     *        the dialog parent shell
119     * @param title
120     *        the dialog title
121     * @param message
122     *        the dialog message
123     * @param initialText
124     *        the dialog initialText
125     * @param style
126     *        the dialog style
127     */
128    public InputDialog(Shell parent, String title, String message, String initialText, int style) {
129        super(parent, style);
130        this.title = title;
131        this.message = message;
132        this.initialText = initialText;
133
134        try {
135            curFont = new Font(
136                    Display.getCurrent(),
137                    ViewProperties.getFontType(),
138                    ViewProperties.getFontSize(),
139                    SWT.NORMAL);
140        }
141        catch (Exception ex) {
142            curFont = null;
143        }
144    }
145
146    /**
147     * Opens the InputDialog and returns the user's input
148     * when the dialog closes.
149     *
150     * @return the user input data
151     */
152    public String open() {
153        Shell parent = getParent();
154        final Shell shell = new Shell(parent, SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE);
155        shell.setFont(curFont);
156        shell.setText(title);
157        shell.setLayout(new GridLayout(1, true));
158
159        Label label = new Label(shell, SWT.NULL);
160        label.setFont(curFont);
161        label.setText(message);
162
163        inputField = new Text(shell, SWT.SINGLE | SWT.BORDER);
164        inputField.setFont(curFont);
165        inputField.setText(initialText);
166        GridData fieldData = new GridData(SWT.FILL, SWT.FILL, true, false);
167        fieldData.minimumWidth = 300;
168        inputField.setLayoutData(fieldData);
169
170        // Dummy label to fill space as dialog is resized
171        new Label(shell, SWT.NONE).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
172
173        Composite buttonComposite = new Composite(shell, SWT.NONE);
174        buttonComposite.setLayout(new GridLayout(2, true));
175        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
176
177        Button okButton = new Button(buttonComposite, SWT.PUSH);
178        okButton.setFont(curFont);
179        okButton.setText("   &OK   ");
180        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
181        okButton.addSelectionListener(new SelectionAdapter() {
182            public void widgetSelected(SelectionEvent e) {
183                shell.dispose();
184            }
185        });
186
187        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
188        cancelButton.setFont(curFont);
189        cancelButton.setText(" &Cancel ");
190        cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
191        cancelButton.addSelectionListener(new SelectionAdapter() {
192            public void widgetSelected(SelectionEvent e) {
193                result = null;
194                shell.dispose();
195            }
196        });
197
198        inputField.addListener(SWT.Modify, new Listener() {
199            public void handleEvent(Event event) {
200                try {
201                    result = inputField.getText();
202                }
203                catch (Exception ex) {
204                    System.err.println("Error retrieving input value.");
205                }
206            }
207        });
208
209        shell.addListener(SWT.Traverse, new Listener() {
210            public void handleEvent(Event event) {
211                if(event.detail == SWT.TRAVERSE_ESCAPE)
212                    event.doit = false;
213            }
214        });
215
216        shell.pack();
217
218        shell.addDisposeListener(new DisposeListener() {
219            public void widgetDisposed(DisposeEvent e) {
220                if (curFont != null) 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}