    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 files COPYING and Copyright.html. *
    009 * COPYING can be found at the root of the source code distribution tree.    *
    010 * Or, see https://support.hdfgroup.org/products/licenses.html               *
    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.MetaDataView;
    016
    017import java.lang.reflect.Array;
    018
    019import org.eclipse.swt.SWT;
    020import org.eclipse.swt.events.SelectionAdapter;
    021import org.eclipse.swt.events.SelectionEvent;
    022import org.eclipse.swt.layout.FillLayout;
    023import org.eclipse.swt.layout.GridData;
    024import org.eclipse.swt.layout.GridLayout;
    025import org.eclipse.swt.widgets.Button;
    026import org.eclipse.swt.widgets.Composite;
    027import org.eclipse.swt.widgets.Label;
    028import org.eclipse.swt.widgets.Table;
    029import org.eclipse.swt.widgets.TableColumn;
    030import org.eclipse.swt.widgets.TableItem;
    031import org.eclipse.swt.widgets.Text;
    032
    033import hdf.object.CompoundDS;
    034import hdf.object.Dataset;
    035import hdf.object.Datatype;
    036import hdf.object.HObject;
    037import hdf.object.ScalarDS;
    038import hdf.view.Tools;
    039import hdf.view.DataView.DataViewManager;
    040
    041public class DefaultDatasetMetaDataView extends DefaultLinkMetaDataView implements MetaDataView {
    042
    043    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultDatasetMetaDataView.class);
    044
    045    public DefaultDatasetMetaDataView(Composite parentComposite, DataViewManager viewer, HObject theObj) {
    046        super(parentComposite, viewer, theObj);
    047    }
    048
    049    @Override
    050    protected void addObjectSpecificContent() {
    051
    052        super.addObjectSpecificContent();
    053
    054        String labelInfo;
    055        Label label;
    056        Text text;
    057
    058        Dataset d = (Dataset) dataObject;
    059        if (!d.isInited()) {
    060            d.init();
    061        }
    062
    063        org.eclipse.swt.widgets.Group datasetInfoGroup = new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
    064        datasetInfoGroup.setFont(curFont);
    065        datasetInfoGroup.setText("Dataset Dataspace and Datatype");
    066        datasetInfoGroup.setLayout(new GridLayout(2, false));
    067        datasetInfoGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
    068
    069        /* Dataset Rank section */
    070        label = new Label(datasetInfoGroup, SWT.LEFT);
    071        label.setFont(curFont);
    072        label.setText("No. of Dimension(s): ");
    073
    074        text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
    075        text.setEditable(false);
    076        text.setFont(curFont);
    077        labelInfo = "" + d.getRank();
    078        text.setText(labelInfo);
    079        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    080
    081        /* Dataset dimension size section */
    082        label = new Label(datasetInfoGroup, SWT.LEFT);
    083        label.setFont(curFont);
    084        label.setText("Dimension Size(s): ");
    085
    086        // Set Dimension Size
    087        String dimStr = null;
    088        String maxDimStr = null;
    089        long dims[] = d.getDims();
    090        long maxDims[] = d.getMaxDims();
    091        if (dims != null) {
    092            String[] dimNames = d.getDimNames();
    093            boolean hasDimNames = ((dimNames != null) && (dimNames.length == dims.length));
    094            StringBuilder sb = new StringBuilder();
    095            StringBuilder sb2 = new StringBuilder();
    096
    097            sb.append(dims[0]);
    098            if (hasDimNames) {
    099                sb.append(" (").append(dimNames[0]).append(")");
    100            }
    101
    102            if (maxDims[0] < 0)
    103                sb2.append("Unlimited");
    104            else
    105                sb2.append(maxDims[0]);
    106
    107            for (int i = 1; i < dims.length; i++) {
    108                sb.append(" x ");
    109                sb.append(dims[i]);
    110                if (hasDimNames) {
    111                    sb.append(" (").append(dimNames[i]).append(")");
    112                }
    113
    114                sb2.append(" x ");
    115                if (maxDims[i] < 0)
    116                    sb2.append("Unlimited");
    117                else
    118                    sb2.append(maxDims[i]);
    119
    120            }
    121            dimStr = sb.toString();
    122            maxDimStr = sb2.toString();
    123        }
    124
    125        text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
    126        text.setEditable(false);
    127        text.setFont(curFont);
    128        text.setText((dimStr == null) ? "null" : dimStr);
    129        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    130
    131        label = new Label(datasetInfoGroup, SWT.LEFT);
    132        label.setFont(curFont);
    133        label.setText("Max Dimension Size(s): ");
    134
    135        text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
    136        text.setEditable(false);
    137        text.setFont(curFont);
    138        text.setText((maxDimStr == null) ? "null" : maxDimStr);
    139        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    140
    141        /* Dataset datatype section */
    142        label = new Label(datasetInfoGroup, SWT.LEFT);
    143        label.setFont(curFont);
    144        label.setText("Data Type: ");
    145
    146        Datatype t = d.getDatatype();
    147        String type = (t == null) ? "null" : t.getDescription();
    148        if (d instanceof CompoundDS) {
    149            if (isH4) {
    150                type = "Vdata";
    151            }
    152            else {
    153                /*
    154                 * For Compounds, Arrays of Compounds, Vlens of Compounds, etc. we want to show
    155                 * the fully-qualified type, minus the compound members, since we already show
    156                 * the Compound datatype's members in a table.
    157                 */
    158                int bracketIndex = type.indexOf('{');
    159                int lastBracketIndex = type.lastIndexOf('}');
    160                if (bracketIndex >= 0 && lastBracketIndex >= 0) {
    161                    type = type.replace(type.substring(bracketIndex, lastBracketIndex + 1), "");
    162                }
    163            }
    164        }
    165
    166        text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
    167        text.setEditable(false);
    168        text.setFont(curFont);
    169        text.setText(type);
    170        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    171
    172        /* Add a dummy label to take up some vertical space between sections */
    173        label = new Label(generalObjectInfoPane, SWT.LEFT);
    174        label.setText("");
    175        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
    176
    177        /*
    178         * Dataset storage layout, compression, filters, storage type, fill value, etc.
    179         * section
    180         */
    181        org.eclipse.swt.widgets.Group datasetLayoutGroup = new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
    182        datasetLayoutGroup.setFont(curFont);
    183        datasetLayoutGroup.setText("Miscellaneous Dataset Information");
    184        datasetLayoutGroup.setLayout(new GridLayout(2, false));
    185        datasetLayoutGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    186
    187        /* Dataset Storage Layout section */
    188        label = new Label(datasetLayoutGroup, SWT.LEFT);
    189        label.setFont(curFont);
    190        label.setText("Storage Layout: ");
    191
    192        label = new Label(datasetLayoutGroup, SWT.RIGHT);
    193        label.setFont(curFont);
    194        labelInfo = d.getStorageLayout();
    195        if (labelInfo == null) labelInfo = "UNKNOWN";
    196        label.setText(labelInfo);
    197
    198        /* Dataset Compression section */
    199        label = new Label(datasetLayoutGroup, SWT.LEFT);
    200        label.setFont(curFont);
    201        label.setText("Compression: ");
    202
    203        label = new Label(datasetLayoutGroup, SWT.RIGHT);
    204        label.setFont(curFont);
    205        labelInfo = d.getCompression();
    206        if (labelInfo == null) labelInfo = "UNKNOWN";
    207        label.setText(labelInfo);
    208
    209        /* Dataset filters section */
    210        label = new Label(datasetLayoutGroup, SWT.LEFT);
    211        label.setFont(curFont);
    212        label.setText("Filters: ");
    213
    214        label = new Label(datasetLayoutGroup, SWT.RIGHT);
    215        label.setFont(curFont);
    216        labelInfo = d.getFilters();
    217        if (labelInfo == null) labelInfo = "UNKNOWN";
    218        label.setText(labelInfo);
    219
    220        /* Dataset extra storage information section */
    221        label = new Label(datasetLayoutGroup, SWT.LEFT);
    222        label.setFont(curFont);
    223        label.setText("Storage: ");
    224
    225        label = new Label(datasetLayoutGroup, SWT.RIGHT);
    226        label.setFont(curFont);
    227        labelInfo = d.getStorage();
    228        if (labelInfo == null) labelInfo = "UNKNOWN";
    229        label.setText(labelInfo);
    230
    231        /* Dataset fill value info section */
    232        label = new Label(datasetLayoutGroup, SWT.LEFT);
    233        label.setFont(curFont);
    234        label.setText("Fill value: ");
    235
    236        Object fillValue = null;
    237        String fillValueInfo = "NONE";
    238        if (d instanceof ScalarDS) fillValue = ((ScalarDS) d).getFillValue();
    239        if (fillValue != null) {
    240            if (fillValue.getClass().isArray()) {
    241                int len = Array.getLength(fillValue);
    242                fillValueInfo = Array.get(fillValue, 0).toString();
    243                for (int i = 1; i < len; i++) {
    244                    fillValueInfo += ", ";
    245                    fillValueInfo += Array.get(fillValue, i).toString();
    246                }
    247            }
    248            else
    249                fillValueInfo = fillValue.toString();
    250        }
    251
    252        label = new Label(datasetLayoutGroup, SWT.RIGHT);
    253        label.setFont(curFont);
    254        label.setText(fillValueInfo);
    255
    256        /* Button to open Data Option dialog */
    257        Button showDataOptionButton = new Button(datasetInfoGroup, SWT.PUSH);
    258        showDataOptionButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false, 2, 1));
    259        showDataOptionButton.setText("Show Data with Options");
    260        showDataOptionButton.addSelectionListener(new SelectionAdapter() {
    261            @Override
    262            public void widgetSelected(SelectionEvent e) {
    263                try {
    264                    viewManager.getTreeView().setDefaultDisplayMode(false);
    265                    viewManager.getTreeView().showDataContent(dataObject);
    266                }
    267                catch (Exception ex) {
    268                    display.beep();
    269                    Tools.showError(display.getShells()[0], "Select", ex.getMessage());
    270                }
    271            }
    272        });
    273
    274        /*
    275         * If this is a Compound Dataset, add a table which displays all of the members
    276         * in the Compound Datatype.
    277         */
    278        if (d instanceof CompoundDS) {
    279            log.trace("addObjectSpecificContent(): add member table for Compound Datatype Dataset");
    280
    281            CompoundDS compound = (CompoundDS) d;
    282
    283            int n = compound.getMemberCount();
    284            log.trace("addObjectSpecificContent(): number of compound members={}", n);
    285
    286            // Add a dummy label to take up some vertical space between sections
    287            label = new Label(generalObjectInfoPane, SWT.LEFT);
    288            label.setText("");
    289            label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
    290
    291            org.eclipse.swt.widgets.Group compoundMembersGroup = new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
    292            compoundMembersGroup.setFont(curFont);
    293            compoundMembersGroup.setText("Compound Dataset Members");
    294            compoundMembersGroup.setLayout(new FillLayout(SWT.VERTICAL));
    295            compoundMembersGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    296
    297            Table memberTable = new Table(compoundMembersGroup, SWT.BORDER);
    298            memberTable.setLinesVisible(true);
    299            memberTable.setHeaderVisible(true);
    300            memberTable.setFont(curFont);
    301
    302            String[] columnNames = { "Name", "Type", "Array Size" };
    303
    304            for (int i = 0; i < columnNames.length; i++) {
    305                TableColumn column = new TableColumn(memberTable, SWT.NONE);
    306                column.setText(columnNames[i]);
    307                column.setMoveable(false);
    308            }
    309
    310            if (n > 0) {
    311                String rowData[][] = new String[n][3];
    312                final String names[] = compound.getMemberNames();
    313                Datatype types[] = compound.getMemberTypes();
    314                int orders[] = compound.getMemberOrders();
    315
    316                for (int i = 0; i < n; i++) {
    317                    rowData[i][0] = new String(names[i]);
    318
    319                    if (rowData[i][0].contains(CompoundDS.SEPARATOR)) {
    320                        rowData[i][0] = rowData[i][0].replaceAll(CompoundDS.SEPARATOR, "->");
    321                    }
    322
    323                    int mDims[] = compound.getMemberDims(i);
    324                    if (mDims == null) {
    325                        rowData[i][2] = String.valueOf(orders[i]);
    326
    327                        if (isH4 && types[i].isString()) {
    328                            rowData[i][2] = String.valueOf(types[i].getDatatypeSize());
    329                        }
    330                    }
    331                    else {
    332                        String mStr = String.valueOf(mDims[0]);
    333                        int m = mDims.length;
    334                        for (int j = 1; j < m; j++) {
    335                            mStr += " x " + mDims[j];
    336                        }
    337                        rowData[i][2] = mStr;
    338                    }
    339                    rowData[i][1] = (types[i] == null) ? "null" : types[i].getDescription();
    340                }
    341
    342                for (int i = 0; i < rowData.length; i++) {
    343                    TableItem item = new TableItem(memberTable, SWT.NONE);
    344                    item.setFont(curFont);
    345                    item.setText(0, rowData[i][0]);
    346                    item.setText(1, rowData[i][1]);
    347                    item.setText(2, rowData[i][2]);
    348                }
    349
    350                for (int i = 0; i < columnNames.length; i++) {
    351                    memberTable.getColumn(i).pack();
    352                }
    353
    354                // set cell height for large fonts
    355                // int cellRowHeight = Math.max(16,
    356                // table.getFontMetrics(table.getFont()).getHeight());
    357                // table.setRowHeight(cellRowHeight);
    358            } //  (n > 0)
    359
    360            // Prevent conflict from equal vertical grabbing
    361            datasetLayoutGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
    362        }
    363    }
    364
    365}