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