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}