    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.io.InputStream;
    018import java.math.BigInteger;
    019import java.net.URL;
    020import java.net.URLClassLoader;
    021import java.util.Iterator;
    022import java.util.List;
    023import java.util.Scanner;
    024import java.util.StringTokenizer;
    025
    026import org.slf4j.Logger;
    027import org.slf4j.LoggerFactory;
    028
    029import org.eclipse.swt.SWT;
    030import org.eclipse.swt.browser.Browser;
    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.Dialog;
    043import org.eclipse.swt.widgets.Display;
    044import org.eclipse.swt.widgets.Label;
    045import org.eclipse.swt.widgets.Shell;
    046import org.eclipse.swt.widgets.Text;
    047
    048import hdf.object.Attribute;
    049import hdf.object.Datatype;
    050import hdf.object.FileFormat;
    051import hdf.object.Group;
    052import hdf.object.HObject;
    053import hdf.object.MetaDataContainer;
    054
    055import hdf.view.Tools;
    056import hdf.view.ViewProperties;
    057
    058/**
    059 * NewStringAttributeDialog displays components for adding a new attribute.
    060 *
    061 * @author Jordan T. Henderson
    062 * @version 2.4 1/7/2016
    063 */
    064public class NewStringAttributeDialog extends NewDataObjectDialog {
    065
    066    private static final Logger log = LoggerFactory.getLogger(NewStringAttributeDialog.class);
    067
    068    /** the default length of a string attribute */
    069    public static final int   DEFAULT_STRING_ATTRIBUTE_LENGTH = 256;
    070
    071    /** TextField for entering the name of the dataset */
    072    private Text              nameField;
    073
    074    /** TextField for entering the attribute value. */
    075    private Text              valueField;
    076
    077    /** The Choice of the object list */
    078    private Combo             objChoice;
    079
    080    private Button            h4GrAttrRadioButton;
    081
    082    private Label             arrayLengthLabel;
    083
    084    /** If the attribute should be attached to a hdf4 object */
    085    protected boolean isH4;
    086    /** If the attribute should be attached to a netcdf object */
    087    protected boolean isN3;
    088
    089    /**
    090     * Constructs a NewStringAttributeDialog with specified object (dataset, group, or
    091     * image) for the new attribute to be attached to.
    092     *
    093     * @param parent
    094     *            the parent shell of the dialog
    095     * @param pObject
    096     *            the parent object which the new attribute is attached to.
    097     * @param objs
    098     *            the list of all objects.
    099     */
    100    public NewStringAttributeDialog(Shell parent, HObject pObject, List<HObject> objs) {
    101        super(parent, pObject, objs);
    102        isH4 = pObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4));
    103        isN3 = pObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_NC3));
    104    }
    105
    106    /**
    107     * Open the NewStringAttributeDialog for adding a new attribute.
    108     */
    109    public void open() {
    110        Shell parent = getParent();
    111        shell = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);
    112        shell.setFont(curFont);
    113        shell.setText("New Attribute...");
    114        shell.setImages(ViewProperties.getHdfIcons());
    115        shell.setLayout(new GridLayout(1, true));
    116
    117
    118        // Create content region
    119        Composite content = new Composite(shell, SWT.NONE);
    120        content.setLayout(new GridLayout(2, false));
    121        content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    122
    123        Label label = new Label(content, SWT.LEFT);
    124        label.setFont(curFont);
    125        label.setText("Name: ");
    126
    127        nameField = new Text(content, SWT.SINGLE | SWT.BORDER);
    128        nameField.setFont(curFont);
    129        nameField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    130
    131        label = new Label(content, SWT.LEFT);
    132        label.setFont(curFont);
    133        label.setText("Type: ");
    134
    135        Composite optionsComposite = new Composite(content, SWT.NONE);
    136        optionsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    137        optionsComposite.setLayout(new GridLayout(
    138                (!isH5 && (parentObj instanceof Group) && ((Group) parentObj).isRoot()) ? 5 : 3,
    139                        false)
    140                );
    141
    142        // Dummy label
    143        label = new Label(optionsComposite, SWT.LEFT);
    144        label.setFont(curFont);
    145        label.setText("");
    146
    147        if (!isH5 && (parentObj instanceof Group) && ((Group) parentObj).isRoot()) {
    148            label = new Label(optionsComposite, SWT.LEFT);
    149            label.setFont(curFont);
    150            label.setText("");
    151
    152            label = new Label(optionsComposite, SWT.LEFT);
    153            label.setFont(curFont);
    154            label.setText("");
    155        }
    156
    157        createDatatypeWidget();
    158
    159        if (!isH5 && (parentObj instanceof Group) && ((Group) parentObj).isRoot()) {
    160            Button h4SdAttrRadioButton = new Button(optionsComposite, SWT.RADIO);
    161            h4SdAttrRadioButton.setFont(curFont);
    162            h4SdAttrRadioButton.setText("SD");
    163            h4SdAttrRadioButton.setSelection(true);
    164
    165            h4GrAttrRadioButton = new Button(optionsComposite, SWT.RADIO);
    166            h4GrAttrRadioButton.setFont(curFont);
    167            h4GrAttrRadioButton.setText("GR");
    168        }
    169
    170        arrayLengthLabel = new Label(content, SWT.LEFT);
    171        arrayLengthLabel.setFont(curFont);
    172        arrayLengthLabel.setText("Array Size: ");
    173
    174        lengthField = new Text(content, SWT.SINGLE | SWT.BORDER);
    175        lengthField.setFont(curFont);
    176        lengthField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    177        lengthField.setTextLimit(30);
    178        lengthField.setText("1");
    179
    180        label = new Label(content, SWT.LEFT);
    181        label.setFont(curFont);
    182        label.setText("Value: ");
    183
    184        valueField = new Text(content, SWT.SINGLE | SWT.BORDER);
    185        valueField.setFont(curFont);
    186        valueField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    187        valueField.setText("0");
    188
    189        label = new Label(content, SWT.LEFT);
    190        label.setFont(curFont);
    191        label.setText("Object List: ");
    192
    193        objChoice = new Combo(content, SWT.DROP_DOWN | SWT.READ_ONLY);
    194        objChoice.setFont(curFont);
    195        objChoice.setEnabled(true);
    196        objChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    197        objChoice.addSelectionListener(new SelectionAdapter() {
    198            @Override
    199            public void widgetSelected(SelectionEvent e) {
    200                String objName = objChoice.getItem(objChoice.getSelectionIndex());
    201
    202                long[] ref = null;
    203                try {
    204                    HObject obj = fileFormat.get(objName);
    205                    ref = obj.getOID();
    206                }
    207                catch (Exception ex) {
    208                    log.debug("object id:", ex);
    209                }
    210
    211                if (ref != null) {
    212                    if (valueField.getText().length() > 1) {
    213                        valueField.setText(valueField.getText() + "," + ref);
    214                        StringTokenizer st = new StringTokenizer(valueField.getText(), ",");
    215                        lengthField.setText(String.valueOf(st.countTokens()));
    216                    }
    217                    else {
    218                        valueField.setText(String.valueOf(ref));
    219                        lengthField.setText("1");
    220                    }
    221                }
    222            }
    223        });
    224
    225        Iterator<?> it = objList.iterator();
    226        HObject hobj;
    227        while (it.hasNext()) {
    228            hobj = (HObject) it.next();
    229
    230            if (hobj instanceof Group) {
    231                if (((Group) hobj).isRoot()) continue;
    232            }
    233
    234            objChoice.add(hobj.getFullName());
    235        }
    236
    237        // Add label to take up extra space when resizing dialog
    238        label = new Label(content, SWT.LEFT);
    239        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    240
    241        // Create Ok/Cancel/Help button region
    242        Composite buttonComposite = new Composite(shell, SWT.NONE);
    243        buttonComposite.setLayout(new GridLayout(3, false));
    244        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    245
    246        Button okButton = new Button(buttonComposite, SWT.PUSH);
    247        okButton.setFont(curFont);
    248        okButton.setText("   &OK   ");
    249        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
    250        okButton.addSelectionListener(new SelectionAdapter() {
    251            @Override
    252            public void widgetSelected(SelectionEvent e) {
    253                if (createAttribute()) {
    254                    shell.dispose();
    255                }
    256            }
    257        });
    258
    259        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
    260        cancelButton.setFont(curFont);
    261        cancelButton.setText(" &Cancel ");
    262        cancelButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false));
    263        cancelButton.addSelectionListener(new SelectionAdapter() {
    264            @Override
    265            public void widgetSelected(SelectionEvent e) {
    266                newObject = null;
    267                shell.dispose();
    268            }
    269        });
    270
    271        Button helpButton = new Button(buttonComposite, SWT.PUSH);
    272        helpButton.setFont(curFont);
    273        helpButton.setText(" &Help ");
    274        helpButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
    275        helpButton.addSelectionListener(new SelectionAdapter() {
    276            @Override
    277            public void widgetSelected(SelectionEvent e) {
    278                new HelpDialog(shell).open();
    279            }
    280        });
    281
    282        shell.pack();
    283
    284        shell.addDisposeListener(new DisposeListener() {
    285            @Override
    286            public void widgetDisposed(DisposeEvent e) {
    287                if (curFont != null) curFont.dispose();
    288            }
    289        });
    290
    291        shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    292
    293        Rectangle parentBounds = parent.getBounds();
    294        Point shellSize = shell.getSize();
    295        shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
    296                          (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
    297
    298        shell.open();
    299
    300        Display display = shell.getDisplay();
    301        while (!shell.isDisposed())
    302            if (!display.readAndDispatch())
    303                display.sleep();
    304    }
    305
    306    @SuppressWarnings("unchecked")
    307    private boolean createAttribute() {
    308        Object value = null;
    309        String strValue = valueField.getText();
    310
    311        String attrName = nameField.getText();
    312        if (attrName != null) {
    313            attrName = attrName.trim();
    314        }
    315
    316        if ((attrName == null) || (attrName.length() < 1)) {
    317            Tools.showError(shell, "Create", "No attribute name specified.");
    318            return false;
    319        }
    320
    321        String lengthStr = lengthField.getText();
    322        log.trace("Name is {} : Length={} and Value={}", attrName, lengthStr, strValue);
    323
    324        int arraySize = 0;
    325        if ((lengthStr == null) || (lengthStr.length() <= 0)) {
    326            arraySize = 1;
    327        }
    328        else {
    329            try {
    330                arraySize = Integer.parseInt(lengthStr);
    331            }
    332            catch (Exception e) {
    333                arraySize = -1;
    334            }
    335        }
    336
    337        if (arraySize <= 0) {
    338            Tools.showError(shell, "Create", "Invalid attribute length.");
    339            return false;
    340        }
    341
    342        StringTokenizer st = new StringTokenizer(strValue, ",");
    343        int count = Math.min(arraySize, st.countTokens());
    344        String theToken;
    345        log.trace("Count of Values is {}", count);
    346
    347        // set datatype class
    348        Datatype datatype = super.createNewDatatype(null);
    349        if (isVLen) {
    350            log.trace("Attribute isVLen={} and tsize={}", isVLen, tsize);
    351            String[] strArray = { strValue };
    352            value = strArray;
    353        }
    354        else {
    355            if (tclass == Datatype.CLASS_STRING) {
    356                if (!isVlenStr) {
    357                    if (strValue.length() > tsize) {
    358                        strValue = strValue.substring(0, tsize);
    359                    }
    360                }
    361
    362                String[] strArray = { strValue };
    363                value = strArray;
    364
    365                if (isH5) {
    366                    arraySize = 1; // support string type
    367                }
    368                else {
    369                    arraySize = tsize; // array of characters
    370                }
    371                log.trace("Attribute CLASS_STRING: isVlenStr={} and tsize={} and arraySize={}", isVlenStr, tsize, arraySize);
    372            }
    373            else if (tclass == Datatype.CLASS_REFERENCE) {
    374                arraySize = st.countTokens();
    375                long[] ref = new long[arraySize];
    376                for (int j = 0; j < arraySize; j++) {
    377                    theToken = st.nextToken().trim();
    378                    try {
    379                        ref[j] = Long.parseLong(theToken);
    380                    }
    381                    catch (NumberFormatException ex) {
    382                        Tools.showError(shell, "Create", ex.getMessage());
    383                        return false;
    384                    }
    385                }
    386
    387                value = ref;
    388                log.trace("Attribute CLASS_REFERENCE: tsize={} and arraySize={}", tsize, arraySize);
    389            }
    390            else if (tclass == Datatype.CLASS_INTEGER) {
    391                if (tsign == Datatype.SIGN_NONE) {
    392                    if (tsize == 1) {
    393                        byte[] b = new byte[arraySize];
    394                        short sv = 0;
    395                        for (int j = 0; j < count; j++) {
    396                            theToken = st.nextToken().trim();
    397                            try {
    398                                sv = Short.parseShort(theToken);
    399                            }
    400                            catch (NumberFormatException ex) {
    401                                Tools.showError(shell, "Create", ex.getMessage());
    402                                return false;
    403                            }
    404                            if (sv < 0) {
    405                                sv = 0;
    406                            }
    407                            else if (sv > 255) {
    408                                sv = 255;
    409                            }
    410                            b[j] = (byte) sv;
    411                        }
    412                        value = b;
    413                    }
    414                    else if (tsize == 2) {
    415                        short[] s = new short[arraySize];
    416                        int iv = 0;
    417                        for (int j = 0; j < count; j++) {
    418                            theToken = st.nextToken().trim();
    419                            try {
    420                                iv = Integer.parseInt(theToken);
    421                            }
    422                            catch (NumberFormatException ex) {
    423                                Tools.showError(shell, "Create", ex.getMessage());
    424                                return false;
    425                            }
    426                            if (iv < 0) {
    427                                iv = 0;
    428                            }
    429                            else if (iv > 65535) {
    430                                iv = 65535;
    431                            }
    432                            s[j] = (short) iv;
    433                        }
    434                        value = s;
    435                    }
    436                    else if ((tsize == 4) || (tsize == -1)) {
    437                        int[] i = new int[arraySize];
    438                        long lv = 0;
    439                        for (int j = 0; j < count; j++) {
    440                            theToken = st.nextToken().trim();
    441                            try {
    442                                lv = Long.parseLong(theToken);
    443                            }
    444                            catch (NumberFormatException ex) {
    445                                Tools.showError(shell, "Create", ex.getMessage());
    446                                return false;
    447                            }
    448                            if (lv < 0) {
    449                                lv = 0;
    450                            }
    451                            if (lv > 4294967295L) {
    452                                lv = 4294967295L;
    453                            }
    454                            i[j] = (int) lv;
    455                        }
    456                        value = i;
    457                    }
    458                    else if (tsize == 8) {
    459                        long[] i = new long[arraySize];
    460                        BigInteger lv = BigInteger.valueOf(0);
    461                        for (int j = 0; j < count; j++) {
    462                            theToken = st.nextToken().trim();
    463                            try {
    464                                lv = new BigInteger(theToken);
    465                            }
    466                            catch (NumberFormatException ex) {
    467                                Tools.showError(shell, "Create", ex.getMessage());
    468                                return false;
    469                            }
    470                            i[j] = lv.longValue();
    471                        }
    472                        value = i;
    473                    }
    474                }
    475                else {
    476                    if (tsize == 1) {
    477                        byte[] b = new byte[arraySize];
    478                        for (int j = 0; j < count; j++) {
    479                            theToken = st.nextToken().trim();
    480                            try {
    481                                b[j] = Byte.parseByte(theToken);
    482                            }
    483                            catch (NumberFormatException ex) {
    484                                Tools.showError(shell, "Create", ex.getMessage());
    485                                return false;
    486                            }
    487                        }
    488                        value = b;
    489                    }
    490                    else if (tsize == 2) {
    491                        short[] s = new short[arraySize];
    492
    493                        for (int j = 0; j < count; j++) {
    494                            theToken = st.nextToken().trim();
    495                            try {
    496                                s[j] = Short.parseShort(theToken);
    497                            }
    498                            catch (NumberFormatException ex) {
    499                                Tools.showError(shell, "Create", ex.getMessage());
    500                                return false;
    501                            }
    502                        }
    503                        value = s;
    504                    }
    505                    else if ((tsize == 4) || (tsize == -1)) {
    506                        int[] i = new int[arraySize];
    507
    508                        for (int j = 0; j < count; j++) {
    509                            theToken = st.nextToken().trim();
    510                            try {
    511                                i[j] = Integer.parseInt(theToken);
    512                            }
    513                            catch (NumberFormatException ex) {
    514                                Tools.showError(shell, "Create", ex.getMessage());
    515                                return false;
    516                            }
    517                        }
    518                        value = i;
    519                    }
    520                    else if (tsize == 8) {
    521                        long[] l = new long[arraySize];
    522                        for (int j = 0; j < count; j++) {
    523                            theToken = st.nextToken().trim();
    524                            try {
    525                                l[j] = Long.parseLong(theToken);
    526                            }
    527                            catch (NumberFormatException ex) {
    528                                Tools.showError(shell, "Create", ex.getMessage());
    529                                return false;
    530                            }
    531                        }
    532                        value = l;
    533                    }
    534                }
    535            }
    536
    537            if (tclass == Datatype.CLASS_FLOAT) {
    538                if ((tsize == 4) || (tsize == -1)) {
    539                    float[] f = new float[arraySize];
    540                    for (int j = 0; j < count; j++) {
    541                        theToken = st.nextToken().trim();
    542                        try {
    543                            f[j] = Float.parseFloat(theToken);
    544                        }
    545                        catch (NumberFormatException ex) {
    546                            Tools.showError(shell, "Create", ex.getMessage());
    547                            return false;
    548                        }
    549                        if (Float.isInfinite(f[j]) || Float.isNaN(f[j])) {
    550                            f[j] = 0;
    551                        }
    552                    }
    553                    value = f;
    554                }
    555                else if (tsize == 8) {
    556                    double[] d = new double[arraySize];
    557                    for (int j = 0; j < count; j++) {
    558                        theToken = st.nextToken().trim();
    559                        try {
    560                            d[j] = Double.parseDouble(theToken);
    561                        }
    562                        catch (NumberFormatException ex) {
    563                            Tools.showError(shell, "Create", ex.getMessage());
    564                            return false;
    565                        }
    566                        if (Double.isInfinite(d[j]) || Double.isNaN(d[j])) {
    567                            d[j] = 0;
    568                        }
    569                    }
    570                    value = d;
    571                }
    572            }
    573        }
    574
    575        long[] dims = { arraySize };
    576        Attribute attr = null;
    577        try {
    578            if (isH4)
    579                attr = new hdf.object.h4.H4ScalarAttribute(parentObj, attrName, datatype, dims);
    580            else
    581                attr = new hdf.object.nc2.NC2Attribute(parentObj, attrName, datatype, dims);
    582        }
    583        catch (Exception ex) {
    584            Tools.showError(shell, "Create", ex.getMessage());
    585            log.debug("createAttribute(): ", ex);
    586            return false;
    587        }
    588        if (attr ==null) {
    589            Tools.showError(shell, "Create", "Attribute could not be created");
    590            log.debug("createAttribute(): failed");
    591            return false;
    592        }
    593        attr.setAttributeData(value);
    594
    595        try {
    596            if (!isH5 && (parentObj instanceof Group) && ((Group) parentObj).isRoot() && h4GrAttrRadioButton.getSelection()) {
    597                parentObj.getFileFormat().writeAttribute(parentObj, attr, false);
    598                // don't find a good way to write HDF4 global
    599                // attribute. Use the isExisted to separate the
    600                // global attribute is GR or SD
    601
    602                if (((MetaDataContainer) parentObj).getMetadata() == null) {
    603                    ((MetaDataContainer) parentObj).getMetadata().add(attr);
    604                }
    605            }
    606            else {
    607                log.trace("writeMetadata() via write()");
    608                attr.writeAttribute();
    609            }
    610        }
    611        catch (Exception ex) {
    612            Tools.showError(shell, "Create", ex.getMessage());
    613            log.debug("createAttribute(): ", ex);
    614            return false;
    615        }
    616
    617        newObject = (HObject)attr;
    618
    619        return true;
    620    }
    621
    622    private class HelpDialog extends Dialog {
    623        private Shell helpShell;
    624
    625        public HelpDialog(Shell parent) {
    626            super(parent, SWT.APPLICATION_MODAL);
    627        }
    628
    629        public void open() {
    630            Shell parent = getParent();
    631            helpShell = new Shell(parent, SWT.TITLE | SWT.CLOSE |
    632                    SWT.RESIZE | SWT.BORDER | SWT.APPLICATION_MODAL);
    633            helpShell.setFont(curFont);
    634            helpShell.setText("Create New Attribute");
    635            helpShell.setImages(ViewProperties.getHdfIcons());
    636            helpShell.setLayout(new GridLayout(1, true));
    637
    638            // Try to create a Browser on platforms that support it
    639            try {
    640                Browser browser = new Browser(helpShell, SWT.NONE);
    641                browser.setFont(curFont);
    642                browser.setBounds(0, 0, 500, 500);
    643                browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    644
    645                if (ClassLoader.getSystemResource("hdf/view/HDFView.class").toString().startsWith("jar")) {
    646                    // Attempt to load HTML help file from jar
    647                    try (InputStream in = getClass().getClassLoader().getResourceAsStream("hdf/view/NewAttrHelp.html")) {
    648                        Scanner scan = new Scanner(in);
    649                        StringBuilder buffer = new StringBuilder();
    650                        while(scan.hasNextLine()) {
    651                            buffer.append(scan.nextLine());
    652                        }
    653
    654                        browser.setText(buffer.toString());
    655
    656                        scan.close();
    657                    }
    658                    catch (Exception e) {
    659                        StringBuilder buff = new StringBuilder();
    660                        buff.append("<html>")
    661                            .append("<body>")
    662                            .append("ERROR: cannot load help information.")
    663                            .append("</body>")
    664                            .append("</html>");
    665                        browser.setText(buff.toString(), true);
    666                    }
    667                }
    668                else {
    669                    try {
    670                        URL url = null, url2 = null, url3 = null;
    671                        String rootPath = ViewProperties.getViewRoot();
    672
    673                        try {
    674                            url = new URL("file://" + rootPath + "/HDFView.jar");
    675                        }
    676                        catch (java.net.MalformedURLException mfu) {
    677                            log.debug("help information:", mfu);
    678                        }
    679
    680                        try {
    681                            url2 = new URL("file://" + rootPath + "/");
    682                        }
    683                        catch (java.net.MalformedURLException mfu) {
    684                            log.debug("help information:", mfu);
    685                        }
    686
    687                        try {
    688                            url3 = new URL("file://" + rootPath + "/src/");
    689                        }
    690                        catch (java.net.MalformedURLException mfu) {
    691                            log.debug("help information:", mfu);
    692                        }
    693
    694                        URL uu[] = { url, url2, url3 };
    695                        try (URLClassLoader cl = new URLClassLoader(uu)) {
    696                            URL u = cl.findResource("hdf/view/NewAttrHelp.html");
    697
    698                            browser.setUrl(u.toString());
    699                        }
    700                        catch (Exception ex) {
    701                            log.trace("URLClassLoader failed:", ex);
    702                        }
    703                    }
    704                    catch (Exception e) {
    705                        StringBuilder buff = new StringBuilder();
    706                        buff.append("<html>")
    707                            .append("<body>")
    708                            .append("ERROR: cannot load help information.")
    709                            .append("</body>")
    710                            .append("</html>");
    711                        browser.setText(buff.toString(), true);
    712                    }
    713                }
    714
    715                Button okButton = new Button(helpShell, SWT.PUSH);
    716                okButton.setFont(curFont);
    717                okButton.setText("   &OK   ");
    718                okButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
    719                okButton.addSelectionListener(new SelectionAdapter() {
    720                    @Override
    721                    public void widgetSelected(SelectionEvent e) {
    722                        helpShell.dispose();
    723                    }
    724                });
    725
    726                helpShell.pack();
    727
    728                helpShell.setSize(new Point(500, 500));
    729
    730                Rectangle parentBounds = parent.getBounds();
    731                Point shellSize = helpShell.getSize();
    732                helpShell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
    733                                      (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
    734
    735                helpShell.open();
    736
    737                Display display = parent.getDisplay();
    738                while(!helpShell.isDisposed()) {
    739                    if (!display.readAndDispatch())
    740                        display.sleep();
    741                }
    742            }
    743            catch (Error er) {
    744                // Try opening help link in external browser if platform
    745                // doesn't support SWT browser
    746                Tools.showError(shell, "Browser support",
    747                        "Platform doesn't support Browser. Opening external link in web browser...");
    748
    749                //TODO: Add support for launching in external browser
    750            }
    751            catch (Exception ex) {
    752                log.debug("Open New Attribute Help failure: ", ex);
    753            }
    754        }
    755    }
    756
    757    /** @return the new attribute created. */
    758    public Attribute getAttribute() {
    759        return (Attribute)newObject;
    760    }
    761}