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.dialog; 016 017import java.util.Iterator; 018import java.util.List; 019import java.util.Vector; 020 021import org.eclipse.swt.SWT; 022import org.eclipse.swt.events.SelectionAdapter; 023import org.eclipse.swt.events.SelectionEvent; 024import org.eclipse.swt.graphics.Font; 025import org.eclipse.swt.layout.GridData; 026import org.eclipse.swt.layout.GridLayout; 027import org.eclipse.swt.widgets.Button; 028import org.eclipse.swt.widgets.Combo; 029import org.eclipse.swt.widgets.Dialog; 030import org.eclipse.swt.widgets.Display; 031import org.eclipse.swt.widgets.Label; 032import org.eclipse.swt.widgets.Shell; 033import org.eclipse.swt.widgets.Text; 034 035import hdf.object.Datatype; 036import hdf.object.FileFormat; 037import hdf.object.Group; 038import hdf.object.HObject; 039import hdf.object.h5.H5Datatype; 040import hdf.view.Tools; 041import hdf.view.ViewProperties; 042 043/** 044 * NewDataDialog is an intermediate class for creating data types. 045 */ 046public class NewDataObjectDialog extends Dialog { 047 048 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NewDataObjectDialog.class); 049 050 protected Shell shell; 051 052 protected Font curFont; 053 054 /** the object which the this object is attached */ 055 protected HObject parentObj; 056 057 /** the object referenced */ 058 protected HObject refObject; 059 060 /** the object created */ 061 protected HObject newObject; 062 063 /** TextField for entering the length of the data array or string. */ 064 protected Text lengthField; 065 066 /** The Choice of the datatypes */ 067 protected Combo namedChoice; 068 protected Combo classChoice; 069 protected Combo sizeChoice; 070 protected Combo endianChoice; 071 072 /** The Choice of the object list */ 073 protected Button useCommittedType; 074 protected Button checkUnsigned; 075 protected List<?> objList; 076 protected List<Datatype> namedList; 077 protected Label arrayLengthLabel; 078 079 /** The attributes of the datatype */ 080 public int tclass = Datatype.CLASS_NO_CLASS; 081 public int tsize = Datatype.NATIVE; 082 public int torder = Datatype.NATIVE; 083 public int tsign = Datatype.NATIVE; 084 public boolean isEnum = false; 085 public String strEnumMap = null; 086 public boolean isVLen = false; 087 public boolean isVlenStr = false; 088 089 protected FileFormat fileFormat; 090 091 protected boolean isH5; 092 093 public NewDataObjectDialog(Shell parent, HObject pGroup, List<?> objs) { 094 super(parent, SWT.APPLICATION_MODAL); 095 096 try { 097 curFont = new Font( 098 Display.getCurrent(), 099 ViewProperties.getFontType(), 100 ViewProperties.getFontSize(), 101 SWT.NORMAL); 102 } 103 catch (Exception ex) { 104 curFont = null; 105 } 106 107 newObject = null; 108 parentObj = pGroup; 109 objList = objs; 110 111 fileFormat = pGroup.getFileFormat(); 112 isH5 = pGroup.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 113 } 114 115 /* the new dataset properties to be created. */ 116 public void createDatatypeWidget() { 117 Label label; 118 119 // Create Datatype region 120 org.eclipse.swt.widgets.Group datatypeGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE); 121 datatypeGroup.setFont(curFont); 122 datatypeGroup.setText("Datatype"); 123 datatypeGroup.setLayout(new GridLayout(4, true)); 124 datatypeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 125 126 useCommittedType = new Button(datatypeGroup, SWT.CHECK); 127 useCommittedType.setFont(curFont); 128 useCommittedType.setText("Use Committed Datatype"); 129 useCommittedType.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); 130 useCommittedType.setEnabled(isH5); 131 132 if(isH5) { 133 label = new Label(datatypeGroup, SWT.LEFT); 134 label.setFont(curFont); 135 label.setText("Committed Datatype: "); 136 137 namedChoice = new Combo(datatypeGroup, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); 138 namedChoice.setFont(curFont); 139 namedChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 140 namedChoice.addSelectionListener(new SelectionAdapter() { 141 @Override 142 public void widgetSelected(SelectionEvent e) { 143 refObject = namedList.get(namedChoice.getSelectionIndex()); 144 } 145 }); 146 147 //Dummy label 148 label = new Label(datatypeGroup, SWT.LEFT); 149 label.setFont(curFont); 150 label.setText(""); 151 152 namedList = new Vector<>(objList.size()); 153 Object obj = null; 154 Iterator<?> iterator = objList.iterator(); 155 while (iterator.hasNext()) { 156 obj = iterator.next(); 157 if (obj instanceof Datatype) { 158 H5Datatype ndt = (H5Datatype) obj; 159 namedList.add(ndt); 160 namedChoice.add(((Datatype)obj).getFullName()); 161 } 162 } 163 164 if (refObject != null) 165 namedChoice.select(namedChoice.indexOf(((Datatype)refObject).getFullName())); 166 } 167 168 label = new Label(datatypeGroup, SWT.LEFT); 169 label.setFont(curFont); 170 label.setText("Datatype Class"); 171 172 label = new Label(datatypeGroup, SWT.LEFT); 173 label.setFont(curFont); 174 label.setText("Size (bits)"); 175 176 label = new Label(datatypeGroup, SWT.LEFT); 177 label.setFont(curFont); 178 label.setText("Byte Ordering"); 179 180 checkUnsigned = new Button(datatypeGroup, SWT.CHECK); 181 checkUnsigned.setFont(curFont); 182 checkUnsigned.setText("Unsigned"); 183 checkUnsigned.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); 184 185 classChoice = new Combo(datatypeGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 186 classChoice.setFont(curFont); 187 classChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 188 classChoice.addSelectionListener(new SelectionAdapter() { 189 @Override 190 public void widgetSelected(SelectionEvent e) { 191 int idx = classChoice.getSelectionIndex(); 192 sizeChoice.select(0); 193 endianChoice.select(0); 194 lengthField.setEnabled(false); 195 196 if ((idx == 0) || (idx == 6)) { // INTEGER 197 sizeChoice.setEnabled(true); 198 endianChoice.setEnabled(isH5); 199 checkUnsigned.setEnabled(true); 200 201 if (sizeChoice.getItemCount() == 3) { 202 sizeChoice.remove("32"); 203 sizeChoice.remove("64"); 204 sizeChoice.add("8"); 205 sizeChoice.add("16"); 206 sizeChoice.add("32"); 207 sizeChoice.add("64"); 208 } 209 } 210 else if ((idx == 1) || (idx == 7)) { // FLOAT 211 sizeChoice.setEnabled(true); 212 endianChoice.setEnabled(isH5); 213 checkUnsigned.setEnabled(false); 214 215 if (sizeChoice.getItemCount() == 5) { 216 sizeChoice.remove("16"); 217 sizeChoice.remove("8"); 218 } 219 } 220 else if (idx == 2) { // CHAR 221 sizeChoice.setEnabled(false); 222 endianChoice.setEnabled(isH5); 223 checkUnsigned.setEnabled(true); 224 } 225 else if (idx == 3) { // STRING 226 sizeChoice.setEnabled(false); 227 endianChoice.setEnabled(false); 228 checkUnsigned.setEnabled(false); 229 lengthField.setEnabled(true); 230 lengthField.setText("String length"); 231 } 232 else if (idx == 4) { // REFERENCE 233 sizeChoice.setEnabled(false); 234 endianChoice.setEnabled(false); 235 checkUnsigned.setEnabled(false); 236 lengthField.setEnabled(false); 237 } 238 else if (idx == 5) { // ENUM 239 sizeChoice.setEnabled(true); 240 checkUnsigned.setEnabled(true); 241 lengthField.setEnabled(true); 242 lengthField.setText("0=R,1=G,#=TXT,..."); 243 } 244 else if (idx == 8) { 245 sizeChoice.setEnabled(false); 246 endianChoice.setEnabled(false); 247 checkUnsigned.setEnabled(false); 248 lengthField.setEnabled(false); 249 } 250 } 251 }); 252 253 classChoice.add("INTEGER"); 254 classChoice.add("FLOAT"); 255 classChoice.add("CHAR"); 256 257 if(isH5) { 258 classChoice.add("STRING"); 259 classChoice.add("REFERENCE"); 260 classChoice.add("ENUM"); 261 classChoice.add("VLEN_INTEGER"); 262 classChoice.add("VLEN_FLOAT"); 263 classChoice.add("VLEN_STRING"); 264 } 265 266 sizeChoice = new Combo(datatypeGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 267 sizeChoice.setFont(curFont); 268 sizeChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 269 sizeChoice.addSelectionListener(new SelectionAdapter() { 270 @Override 271 public void widgetSelected(SelectionEvent e) { 272 if (classChoice.getSelectionIndex() == 0) { 273 checkUnsigned.setEnabled(true); 274 } 275 } 276 }); 277 278 if(isH5) { 279 sizeChoice.add("NATIVE"); 280 } 281 else { 282 sizeChoice.add("DEFAULT"); 283 } 284 285 sizeChoice.add("8"); 286 sizeChoice.add("16"); 287 sizeChoice.add("32"); 288 sizeChoice.add("64"); 289 290 endianChoice = new Combo(datatypeGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 291 endianChoice.setFont(curFont); 292 endianChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 293 endianChoice.setEnabled(isH5); 294 295 if(isH5) { 296 endianChoice.add("NATIVE"); 297 endianChoice.add("LITTLE ENDIAN"); 298 endianChoice.add("BIG ENDIAN"); 299 } 300 else { 301 endianChoice.add("DEFAULT"); 302 } 303 304 lengthField = new Text(datatypeGroup, SWT.SINGLE | SWT.BORDER); 305 lengthField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 306 lengthField.setFont(curFont); 307 lengthField.setText("String Length"); 308 lengthField.setEnabled(false); 309 310 classChoice.select(0); 311 sizeChoice.select(0); 312 endianChoice.select(0); 313 314 refObject = null; 315 classChoice.setEnabled(true); 316 sizeChoice.setEnabled(true); 317 endianChoice.setEnabled(isH5); 318 checkUnsigned.setEnabled(true); 319 } 320 321 public Datatype createNewDatatype(String name) { 322 Datatype datatype = null; 323 324 tclass = Datatype.CLASS_NO_CLASS; 325 tsize = Datatype.NATIVE; 326 torder = Datatype.NATIVE; 327 tsign = Datatype.NATIVE; 328 isEnum = false; 329 strEnumMap = null; 330 isVLen = false; 331 isVlenStr = false; 332 333 if (useCommittedType.getSelection()) { 334 datatype = (Datatype)refObject; 335 } 336 else { 337 // idx is set to datatype class 338 int idx = classChoice.getSelectionIndex(); 339 if (idx == 0) { 340 tclass = Datatype.CLASS_INTEGER; 341 if (checkUnsigned.getSelection()) { 342 tsign = Datatype.SIGN_NONE; 343 } 344 } 345 else if (idx == 1) { 346 tclass = Datatype.CLASS_FLOAT; 347 } 348 else if (idx == 2) { 349 tclass = Datatype.CLASS_CHAR; 350 if (checkUnsigned.getSelection()) { 351 tsign = Datatype.SIGN_NONE; 352 } 353 } 354 else if (idx == 3) { 355 tclass = Datatype.CLASS_STRING; 356 } 357 else if (idx == 4) { 358 tclass = Datatype.CLASS_REFERENCE; 359 } 360 else if (idx == 5) { 361 isEnum = true; 362 tclass = Datatype.CLASS_ENUM; 363 } 364 else if (idx == 6) { 365 isVLen = true; 366 tclass = Datatype.CLASS_INTEGER; 367 if (checkUnsigned.getSelection()) { 368 tsign = Datatype.SIGN_NONE; 369 } 370 } 371 else if (idx == 7) { 372 isVLen = true; 373 tclass = Datatype.CLASS_FLOAT; 374 } 375 else if (idx == 8) { 376 tclass = Datatype.CLASS_STRING; 377 isVlenStr = true; 378 tsize = -1; 379 } 380 381 // idx is set to datatype size 382 idx = sizeChoice.getSelectionIndex(); 383 if (tclass == Datatype.CLASS_STRING) { 384 if (!isVlenStr) { 385 int stringLength = 0; 386 try { 387 stringLength = Integer.parseInt(lengthField.getText()); 388 } 389 catch (NumberFormatException ex) { 390 stringLength = -1; 391 } 392 393 if (stringLength <= 0) { 394 shell.getDisplay().beep(); 395 Tools.showError(shell, "Create", "Invalid string length: " + lengthField.getText()); 396 return null; 397 } 398 tsize = stringLength; 399 } 400 } 401 else if (tclass == Datatype.CLASS_REFERENCE) { 402 tsize = 1; 403 torder = Datatype.NATIVE; 404 } 405 else if (idx == 0) { 406 tsize = Datatype.NATIVE; 407 } 408 else if (tclass == Datatype.CLASS_FLOAT) { 409 tsize = idx * 4; 410 } 411 else if (tclass == Datatype.CLASS_INTEGER || tclass == Datatype.CLASS_ENUM) { 412 // Note that idx == 0 is set to either 413 // "NATIVE" if isH5 is true 414 // "DEFAULT" otherwise 415 switch(idx) { 416 case 1: 417 tsize = 1; 418 break; 419 case 2: 420 tsize = 2; 421 break; 422 case 3: 423 tsize = 4; 424 break; 425 case 4: 426 tsize = 8; 427 break; 428 default: 429 break; 430 } 431 log.trace("CLASS_INTEGER or CLASS_ENUM: tsize={}", tsize); 432 } 433 else if (tclass == Datatype.CLASS_FLOAT) { 434 tsize = (idx + 1) * 4; 435 log.trace("CLASS_FLOAT: tsize={}", tsize); 436 } 437 else { 438 tsize = 1 << (idx - 1); 439 } 440 441 if ((tsize == 8) && !isH5 && (tclass == Datatype.CLASS_INTEGER)) { 442 shell.getDisplay().beep(); 443 Tools.showError(shell, "Create", "HDF4 does not support 64-bit integer."); 444 return null; 445 } 446 447 // set order 448 idx = endianChoice.getSelectionIndex(); 449 if (idx == 0) { 450 torder = Datatype.NATIVE; 451 } 452 else if (idx == 1) { 453 torder = Datatype.ORDER_LE; 454 } 455 else { 456 torder = Datatype.ORDER_BE; 457 } 458 459 Datatype thedatatype = null; 460 try { 461 Datatype basedatatype = null; 462 if (isVLen) { 463 basedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign); 464 tclass = Datatype.CLASS_VLEN; 465 thedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign, basedatatype); 466 } 467 else if (isEnum && isH5) { 468 strEnumMap = lengthField.getText(); 469 if ((strEnumMap == null) || (strEnumMap.length() < 1) || strEnumMap.endsWith("...")) { 470 shell.getDisplay().beep(); 471 Tools.showError(shell, "Create", "Invalid member values: " + lengthField.getText()); 472 return null; 473 } 474 log.trace("CLASS_ENUM enumStr={}", strEnumMap); 475 476 thedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign); 477 thedatatype.setEnumMembers(strEnumMap); 478 } 479 else 480 thedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign); 481 datatype = fileFormat.createNamedDatatype(thedatatype, name); 482 } 483 catch (Exception ex) { 484 shell.getDisplay().beep(); 485 Tools.showError(shell, "Create", ex.getMessage()); 486 return null; 487 } 488 } 489 return datatype; 490 } 491 492 /** @return the new object created. */ 493 public HObject getObject() { 494 return newObject; 495 } 496 497 /** @return the parent group of the new dataset. */ 498 public Group getParentGroup() { 499 return (Group) parentObj; 500 } 501}