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 java.util.Iterator;
018import java.util.List;
019import java.util.Vector;
020
021import hdf.object.Datatype;
022import hdf.object.Group;
023import hdf.object.HObject;
024import hdf.view.Tools;
025import hdf.view.ViewProperties;
026
027import org.eclipse.swt.SWT;
028import org.eclipse.swt.events.DisposeEvent;
029import org.eclipse.swt.events.DisposeListener;
030import org.eclipse.swt.events.SelectionAdapter;
031import org.eclipse.swt.events.SelectionEvent;
032import org.eclipse.swt.events.TraverseEvent;
033import org.eclipse.swt.events.TraverseListener;
034import org.eclipse.swt.graphics.Point;
035import org.eclipse.swt.graphics.Rectangle;
036import org.eclipse.swt.layout.GridData;
037import org.eclipse.swt.layout.GridLayout;
038import org.eclipse.swt.widgets.Button;
039import org.eclipse.swt.widgets.Combo;
040import org.eclipse.swt.widgets.Composite;
041import org.eclipse.swt.widgets.Display;
042import org.eclipse.swt.widgets.Label;
043import org.eclipse.swt.widgets.Shell;
044import org.eclipse.swt.widgets.Text;
045
046/**
047 * NewDatatypeDialog shows a message dialog requesting user input for creating a
048 * new HDF5 datatype.
049 *
050 * @author Jordan T. Henderson
051 * @version 2.4 1/1/2016
052 */
053public class NewDatatypeDialog extends NewDataObjectDialog {
054
055    private Combo parentChoice;
056
057    /** TextField for entering the name of the object */
058    protected Text nameField;
059
060    /** a list of current groups */
061    private List<Group> groupList;
062
063    /**
064     * Constructs a NewDatatypeDialog with specified list of possible parent
065     * groups.
066     *
067     * @param parent
068     *            the parent shell of the dialog
069     * @param pGroup
070     *            the parent group which the new group is added to.
071     * @param objs
072     *            the list of all objects.
073     */
074    public NewDatatypeDialog(Shell parent, Group pGroup, List<?> objs) { super(parent, pGroup, objs); }
075
076    /**
077     * Open the NewDatatypeDialog for adding a new datatype.
078     */
079    public void open()
080    {
081        Shell parent = getParent();
082        shell        = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);
083        shell.setFont(curFont);
084        shell.setText("New Datatype...");
085        shell.setImages(ViewProperties.getHdfIcons());
086        shell.setLayout(new GridLayout(1, false));
087
088        // Create Datatype name / Parent group region
089        Composite fieldComposite = new Composite(shell, SWT.NONE);
090        fieldComposite.setLayout(new GridLayout(2, false));
091        fieldComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
092
093        Label label = new Label(fieldComposite, SWT.LEFT);
094        label.setFont(curFont);
095        label.setText("Datatype name: ");
096
097        nameField = new Text(fieldComposite, SWT.SINGLE | SWT.BORDER);
098        nameField.setFont(curFont);
099        nameField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
100        nameField.addTraverseListener(new TraverseListener() {
101            @Override
102            public void keyTraversed(TraverseEvent e)
103            {
104                if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
105                    e.doit = true;
106                }
107            }
108        });
109
110        label = new Label(fieldComposite, SWT.LEFT);
111        label.setFont(curFont);
112        label.setText("Parent Group: ");
113
114        parentChoice = new Combo(fieldComposite, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);
115        parentChoice.setFont(curFont);
116        parentChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
117        parentChoice.addSelectionListener(new SelectionAdapter() {
118            @Override
119            public void widgetSelected(SelectionEvent e)
120            {
121                parentObj = groupList.get(parentChoice.getSelectionIndex());
122            }
123        });
124
125        groupList            = new Vector<>(objList.size());
126        Object obj           = null;
127        Iterator<?> iterator = objList.iterator();
128        while (iterator.hasNext()) {
129            obj = iterator.next();
130            if (obj instanceof Group) {
131                Group g = (Group)obj;
132                groupList.add(g);
133                if (g.isRoot()) {
134                    parentChoice.add(HObject.SEPARATOR);
135                }
136                else {
137                    parentChoice.add(g.getPath() + g.getName() + HObject.SEPARATOR);
138                }
139            }
140        }
141
142        if (((Group)parentObj).isRoot()) {
143            parentChoice.select(parentChoice.indexOf(HObject.SEPARATOR));
144        }
145        else {
146            parentChoice.select(
147                parentChoice.indexOf(parentObj.getPath() + parentObj.getName() + HObject.SEPARATOR));
148        }
149
150        // Create Datatype settings region
151        createDatatypeWidget();
152
153        // Create Ok/Cancel button region
154        Composite buttonComposite = new Composite(shell, SWT.NONE);
155        buttonComposite.setLayout(new GridLayout(2, true));
156        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
157
158        Button okButton = new Button(buttonComposite, SWT.PUSH);
159        okButton.setFont(curFont);
160        okButton.setText("   &OK   ");
161        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
162        okButton.addSelectionListener(new SelectionAdapter() {
163            @Override
164            public void widgetSelected(SelectionEvent e)
165            {
166                newObject = createNewDatatype();
167
168                if (newObject != null) {
169                    shell.dispose();
170                }
171            }
172        });
173
174        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
175        cancelButton.setFont(curFont);
176        cancelButton.setText(" &Cancel ");
177        cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
178        cancelButton.addSelectionListener(new SelectionAdapter() {
179            @Override
180            public void widgetSelected(SelectionEvent e)
181            {
182                newObject = null;
183                shell.dispose();
184            }
185        });
186
187        // Control[] controls = new Control[] { okButton, cancelButton };
188        // shell.setTabList(controls);
189        shell.pack();
190
191        shell.addDisposeListener(new DisposeListener() {
192            @Override
193            public void widgetDisposed(DisposeEvent e)
194            {
195                if (curFont != null)
196                    curFont.dispose();
197            }
198        });
199
200        shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
201
202        Rectangle parentBounds = parent.getBounds();
203        Point shellSize        = shell.getSize();
204        shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
205                          (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
206
207        shell.open();
208
209        Display display = shell.getDisplay();
210        while (!shell.isDisposed())
211            if (!display.readAndDispatch())
212                display.sleep();
213    }
214
215    /**
216     * Create the datatype specified by the settings.
217     *
218     * @return the new object created.
219     */
220    public Datatype createNewDatatype()
221    {
222        String name  = null;
223        Group pgroup = null;
224
225        name = nameField.getText().trim();
226        if ((name == null) || (name.length() < 1)) {
227            shell.getDisplay().beep();
228            Tools.showError(shell, "Create", "Datatype name is not specified.");
229            return null;
230        }
231
232        if (name.indexOf(HObject.SEPARATOR) >= 0) {
233            shell.getDisplay().beep();
234            Tools.showError(shell, "Create", "Datatype name cannot contain path.");
235            return null;
236        }
237
238        pgroup = groupList.get(parentChoice.getSelectionIndex());
239
240        if (pgroup == null) {
241            shell.getDisplay().beep();
242            Tools.showError(shell, "Create", "Parent group is null.");
243            return null;
244        }
245
246        Datatype datatype = null;
247        try {
248            String fullPath = HObject.SEPARATOR;
249            if (pgroup.isRoot()) {
250                fullPath += name;
251            }
252            else {
253                fullPath = pgroup.getPath() + HObject.SEPARATOR + pgroup.getName() + HObject.SEPARATOR + name;
254            }
255            datatype = super.createNewDatatype(fullPath);
256        }
257        catch (Exception ex) {
258            shell.getDisplay().beep();
259            Tools.showError(shell, "Create", ex.getMessage());
260            return null;
261        }
262
263        return datatype;
264    }
265}