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.ArrayList;
018import java.util.Iterator;
019import java.util.List;
020import java.util.Vector;
021
022import hdf.object.Dataset;
023import hdf.object.Datatype;
024import hdf.object.Group;
025import hdf.object.HObject;
026import hdf.object.ScalarDS;
027import hdf.view.Tools;
028import hdf.view.ViewProperties;
029
030import org.eclipse.swt.SWT;
031import org.eclipse.swt.events.DisposeEvent;
032import org.eclipse.swt.events.DisposeListener;
033import org.eclipse.swt.events.SelectionAdapter;
034import org.eclipse.swt.events.SelectionEvent;
035import org.eclipse.swt.graphics.Point;
036import org.eclipse.swt.graphics.Rectangle;
037import org.eclipse.swt.layout.GridData;
038import org.eclipse.swt.layout.GridLayout;
039import org.eclipse.swt.widgets.Button;
040import org.eclipse.swt.widgets.Combo;
041import org.eclipse.swt.widgets.Composite;
042import org.eclipse.swt.widgets.Display;
043import org.eclipse.swt.widgets.Label;
044import org.eclipse.swt.widgets.Shell;
045import org.eclipse.swt.widgets.Text;
046
047/**
048 * NewImageDialog shows a message dialog requesting user input for creating a
049 * new HDF4/5 Image.
050 *
051 * @author Jordan T. Henderson
052 * @version 2.4 1/1/2016
053 */
054public class NewImageDialog extends NewDataObjectDialog {
055
056    private Text nameField, widthField, heightField;
057
058    private Combo parentChoice;
059
060    private Button checkIndex, checkTrueColor, checkInterlacePixel, checkInterlacePlane;
061
062    /** A list of current groups */
063    private List<Group> groupList;
064
065    /**
066     * Constructs a NewImageDialog with specified list of possible parent groups.
067     *
068     * @param parent
069     *            the parent shell of the dialog
070     * @param pGroup
071     *            the parent group which the new group is added to.
072     * @param objs
073     *            the list of all objects.
074     */
075    public NewImageDialog(Shell parent, Group pGroup, List<?> objs) { super(parent, pGroup, objs); }
076
077    /**
078     * Open the NewImageDialog for adding a new image.
079     */
080    public void open()
081    {
082        Shell parent = getParent();
083        shell        = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);
084        shell.setFont(curFont);
085        shell.setText("New HDF Image...");
086        shell.setImages(ViewProperties.getHdfIcons());
087        shell.setLayout(new GridLayout(1, true));
088
089        // Create main content region
090        Composite content = new Composite(shell, SWT.BORDER);
091        content.setLayout(new GridLayout(2, false));
092        content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
093
094        Label label = new Label(content, SWT.LEFT);
095        label.setFont(curFont);
096        label.setText("Image name: ");
097
098        nameField = new Text(content, SWT.SINGLE | SWT.BORDER);
099        nameField.setFont(curFont);
100        GridData fieldData     = new GridData(SWT.FILL, SWT.FILL, true, false);
101        fieldData.minimumWidth = 300;
102        nameField.setLayoutData(fieldData);
103
104        label = new Label(content, SWT.LEFT);
105        label.setFont(curFont);
106        label.setText("Parent Group: ");
107
108        parentChoice = new Combo(content, SWT.DROP_DOWN | SWT.READ_ONLY);
109        parentChoice.setFont(curFont);
110        parentChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
111        parentChoice.addSelectionListener(new SelectionAdapter() {
112            @Override
113            public void widgetSelected(SelectionEvent e)
114            {
115                parentObj = groupList.get(parentChoice.getSelectionIndex());
116            }
117        });
118
119        groupList            = new ArrayList<>();
120        Object obj           = null;
121        Iterator<?> iterator = objList.iterator();
122        while (iterator.hasNext()) {
123            obj = iterator.next();
124            if (obj instanceof Group) {
125                Group g = (Group)obj;
126                groupList.add(g);
127                if (g.isRoot()) {
128                    parentChoice.add(HObject.SEPARATOR);
129                }
130                else {
131                    parentChoice.add(g.getPath() + g.getName() + HObject.SEPARATOR);
132                }
133            }
134        }
135
136        if (((Group)parentObj).isRoot()) {
137            parentChoice.select(parentChoice.indexOf(HObject.SEPARATOR));
138        }
139        else {
140            parentChoice.select(
141                parentChoice.indexOf(parentObj.getPath() + parentObj.getName() + HObject.SEPARATOR));
142        }
143
144        label = new Label(content, SWT.LEFT);
145        label.setFont(curFont);
146        label.setText("Height: ");
147
148        heightField = new Text(content, SWT.SINGLE | SWT.BORDER);
149        heightField.setFont(curFont);
150        heightField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
151
152        label = new Label(content, SWT.LEFT);
153        label.setFont(curFont);
154        label.setText("Width: ");
155
156        widthField = new Text(content, SWT.SINGLE | SWT.BORDER);
157        widthField.setFont(curFont);
158        widthField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
159
160        label = new Label(content, SWT.LEFT);
161        label.setFont(curFont);
162        label.setText("Image type: ");
163
164        Composite typeComposite = new Composite(content, SWT.BORDER);
165        typeComposite.setLayout(new GridLayout(2, true));
166        typeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
167
168        checkIndex = new Button(typeComposite, SWT.RADIO);
169        checkIndex.setFont(curFont);
170        checkIndex.setText("Indexed colormap");
171        checkIndex.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
172        checkIndex.addSelectionListener(new SelectionAdapter() {
173            @Override
174            public void widgetSelected(SelectionEvent e)
175            {
176                checkInterlacePixel.setSelection(true);
177                checkInterlacePlane.setSelection(false);
178                checkInterlacePixel.setEnabled(false);
179                checkInterlacePlane.setEnabled(false);
180            }
181        });
182
183        checkTrueColor = new Button(typeComposite, SWT.RADIO);
184        checkTrueColor.setFont(curFont);
185        checkTrueColor.setText("24-bit truecolor");
186        checkTrueColor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
187        checkTrueColor.addSelectionListener(new SelectionAdapter() {
188            @Override
189            public void widgetSelected(SelectionEvent e)
190            {
191                checkInterlacePixel.setEnabled(true);
192                checkInterlacePlane.setEnabled(true);
193            }
194        });
195
196        label = new Label(content, SWT.LEFT);
197        label.setFont(curFont);
198        label.setText("Data layout: ");
199
200        Composite layoutComposite = new Composite(content, SWT.BORDER);
201        layoutComposite.setLayout(new GridLayout(2, true));
202        layoutComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
203
204        checkInterlacePixel = new Button(layoutComposite, SWT.RADIO);
205        checkInterlacePixel.setFont(curFont);
206        checkInterlacePixel.setText("Pixel interlace");
207        checkInterlacePixel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
208
209        checkInterlacePlane = new Button(layoutComposite, SWT.RADIO);
210        checkInterlacePlane.setFont(curFont);
211        checkInterlacePlane.setText("Plane interlace");
212        checkInterlacePlane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
213
214        // Create Ok/Cancel button region
215        Composite buttonComposite = new Composite(shell, SWT.NONE);
216        buttonComposite.setLayout(new GridLayout(2, true));
217        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
218
219        Button okButton = new Button(buttonComposite, SWT.PUSH);
220        okButton.setFont(curFont);
221        okButton.setText("   &OK   ");
222        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
223        okButton.addSelectionListener(new SelectionAdapter() {
224            @Override
225            public void widgetSelected(SelectionEvent e)
226            {
227                newObject = createHDFimage();
228                if (newObject != null) {
229                    shell.dispose();
230                }
231            }
232        });
233
234        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
235        cancelButton.setFont(curFont);
236        cancelButton.setText(" &Cancel ");
237        cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
238        cancelButton.addSelectionListener(new SelectionAdapter() {
239            @Override
240            public void widgetSelected(SelectionEvent e)
241            {
242                newObject = null;
243                shell.dispose();
244                ((Vector<Group>)groupList).setSize(0);
245            }
246        });
247
248        checkIndex.setSelection(true);
249        checkInterlacePixel.setSelection(true);
250        checkInterlacePixel.setEnabled(false);
251        checkInterlacePlane.setEnabled(false);
252
253        shell.pack();
254
255        shell.addDisposeListener(new DisposeListener() {
256            @Override
257            public void widgetDisposed(DisposeEvent e)
258            {
259                if (curFont != null)
260                    curFont.dispose();
261            }
262        });
263
264        shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
265
266        Rectangle parentBounds = parent.getBounds();
267        Point shellSize        = shell.getSize();
268        shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
269                          (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
270
271        shell.open();
272
273        Display display = shell.getDisplay();
274        while (!shell.isDisposed())
275            if (!display.readAndDispatch())
276                display.sleep();
277    }
278
279    private Dataset createHDFimage()
280    {
281        Dataset dataset = null;
282
283        String name = nameField.getText();
284        if (name != null) {
285            name = name.trim();
286        }
287        if ((name == null) || (name.length() <= 0)) {
288            shell.getDisplay().beep();
289            Tools.showError(shell, "Create", "Image name is not specified.");
290            return null;
291        }
292
293        if (name.indexOf(HObject.SEPARATOR) >= 0) {
294            shell.getDisplay().beep();
295            Tools.showError(shell, "Create", "Image name cannot contain path.");
296            return null;
297        }
298
299        Group pgroup = groupList.get(parentChoice.getSelectionIndex());
300
301        if (pgroup == null) {
302            shell.getDisplay().beep();
303            Tools.showError(shell, "Create", "Select a parent group.");
304            return null;
305        }
306
307        int w = 0, h = 0;
308        try {
309            w = Integer.parseInt(widthField.getText());
310            h = Integer.parseInt(heightField.getText());
311        }
312        catch (Exception ex) {
313            shell.getDisplay().beep();
314            Tools.showError(shell, "Create", ex.getMessage());
315            return null;
316        }
317
318        long[] dims   = null;
319        int tclass    = Datatype.CLASS_CHAR;
320        int tsign     = Datatype.SIGN_NONE;
321        int tsize     = 1;
322        int torder    = Datatype.NATIVE;
323        int interlace = ScalarDS.INTERLACE_PIXEL;
324        int ncomp     = 2;
325
326        if (checkIndex.getSelection()) {
327            // indexed colormap
328            if (isH5) {
329                long[] tmpdims = {h, w};
330                dims           = tmpdims;
331            }
332            else {
333                long[] tmpdims = {w, h};
334                dims           = tmpdims;
335            }
336        }
337        else {
338            // true color image
339            if (isH5) {
340                // HDF5 true color image
341                if (checkInterlacePixel.getSelection()) {
342                    long[] tmpdims = {h, w, 3};
343                    dims           = tmpdims;
344                }
345                else {
346                    interlace      = ScalarDS.INTERLACE_PLANE;
347                    long[] tmpdims = {3, h, w};
348                    dims           = tmpdims;
349                }
350            }
351            else {
352                // HDF4 true color image
353                ncomp          = 3;
354                long[] tmpdims = {w, h};
355                dims           = tmpdims;
356                if (checkInterlacePlane.getSelection()) {
357                    interlace = ScalarDS.INTERLACE_PLANE;
358                }
359            }
360        }
361
362        try {
363            Datatype datatype = fileFormat.createDatatype(tclass, tsize, torder, tsign);
364            dataset =
365                fileFormat.createImage(name, pgroup, datatype, dims, dims, null, -1, ncomp, interlace, null);
366            dataset.init();
367        }
368        catch (Exception ex) {
369            shell.getDisplay().beep();
370            Tools.showError(shell, "Create", ex.getMessage());
371            return null;
372        }
373
374        return dataset;
375    }
376}