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