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.dialog; 016 017import java.io.InputStream; 018import java.net.URL; 019import java.net.URLClassLoader; 020import java.util.Iterator; 021import java.util.List; 022import java.util.Scanner; 023import java.util.StringTokenizer; 024import java.util.Vector; 025 026import hdf.object.Dataset; 027import hdf.object.Datatype; 028import hdf.object.Group; 029import hdf.object.HObject; 030import hdf.object.ScalarDS; 031import hdf.view.DataView.DataView; 032import hdf.view.ImageView.ImageView; 033import hdf.view.TableView.TableView; 034import hdf.view.Tools; 035import hdf.view.ViewProperties; 036 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040import org.eclipse.swt.SWT; 041import org.eclipse.swt.browser.Browser; 042import org.eclipse.swt.events.DisposeEvent; 043import org.eclipse.swt.events.DisposeListener; 044import org.eclipse.swt.events.SelectionAdapter; 045import org.eclipse.swt.events.SelectionEvent; 046import org.eclipse.swt.graphics.Point; 047import org.eclipse.swt.graphics.Rectangle; 048import org.eclipse.swt.layout.GridData; 049import org.eclipse.swt.layout.GridLayout; 050import org.eclipse.swt.widgets.Button; 051import org.eclipse.swt.widgets.Combo; 052import org.eclipse.swt.widgets.Composite; 053import org.eclipse.swt.widgets.Dialog; 054import org.eclipse.swt.widgets.Display; 055import org.eclipse.swt.widgets.Label; 056import org.eclipse.swt.widgets.Shell; 057import org.eclipse.swt.widgets.Text; 058 059/** 060 * NewDatasetDialog shows a message dialog requesting user input for creating a 061 * new HDF4/5 dataset. 062 * 063 * @author Jordan T. Henderson 064 * @version 2.4 12/31/2015 065 */ 066public class NewDatasetDialog extends NewDataObjectDialog { 067 068 private static final Logger log = LoggerFactory.getLogger(NewDatasetDialog.class); 069 070 private String maxSize; 071 072 private Text currentSizeField, chunkSizeField, fillValueField; 073 074 private Combo parentChoice, rankChoice, compressionLevel; 075 076 private Button checkCompression, checkFillValue; 077 078 private Button checkContiguous, checkChunked; 079 080 /** TextField for entering the name of the object */ 081 protected Text nameField; 082 083 /** A list of current groups */ 084 private List<Group> groupList; 085 086 private final DataView dataView; 087 088 /** 089 * Constructs a NewDatasetDialog with specified list of possible parent 090 * groups. 091 * 092 * @param parent 093 * the parent shell of the dialog 094 * @param pGroup 095 * the parent group which the new group is added to. 096 * @param objs 097 * the list of all objects. 098 */ 099 public NewDatasetDialog(Shell parent, Group pGroup, List<?> objs) 100 { 101 super(parent, pGroup, objs); 102 103 dataView = null; 104 } 105 106 /** 107 * Constructs a NewDatasetDialog with specified list of possible parent 108 * groups. 109 * 110 * @param parent 111 * the parent shell of the dialog 112 * @param pGroup 113 * the parent group which the new group is added to. 114 * @param objs 115 * the list of all objects. 116 * @param observer 117 * the Dataview attached to this dialog. 118 */ 119 public NewDatasetDialog(Shell parent, Group pGroup, List<?> objs, DataView observer) 120 { 121 super(parent, pGroup, objs); 122 123 dataView = observer; 124 } 125 126 /** 127 * Open the NewDataseteDialog for adding a new dataset. 128 */ 129 public void open() 130 { 131 Shell parent = getParent(); 132 shell = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL); 133 shell.setFont(curFont); 134 shell.setText("New Dataset..."); 135 shell.setImages(ViewProperties.getHdfIcons()); 136 shell.setLayout(new GridLayout(1, true)); 137 138 // Create Dataset name / Parent Group region 139 Composite fieldComposite = new Composite(shell, SWT.NONE); 140 fieldComposite.setLayout(new GridLayout(2, false)); 141 fieldComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 142 143 Label datasetNameLabel = new Label(fieldComposite, SWT.LEFT); 144 datasetNameLabel.setFont(curFont); 145 datasetNameLabel.setText("Dataset name: "); 146 147 nameField = new Text(fieldComposite, SWT.SINGLE | SWT.BORDER); 148 nameField.setFont(curFont); 149 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); 150 151 data.minimumWidth = 250; 152 nameField.setLayoutData(data); 153 154 Label parentGroupLabel = new Label(fieldComposite, SWT.LEFT); 155 parentGroupLabel.setFont(curFont); 156 parentGroupLabel.setText("Parent group: "); 157 158 parentChoice = new Combo(fieldComposite, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); 159 parentChoice.setFont(curFont); 160 parentChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 161 parentChoice.addSelectionListener(new SelectionAdapter() { 162 @Override 163 public void widgetSelected(SelectionEvent e) 164 { 165 parentObj = groupList.get(parentChoice.getSelectionIndex()); 166 } 167 }); 168 169 groupList = new Vector<>(); 170 Object obj = null; 171 Iterator<?> iterator = objList.iterator(); 172 173 while (iterator.hasNext()) { 174 obj = iterator.next(); 175 if (obj instanceof Group) { 176 Group g = (Group)obj; 177 groupList.add(g); 178 if (g.isRoot()) { 179 parentChoice.add(HObject.SEPARATOR); 180 } 181 else { 182 parentChoice.add(g.getPath() + g.getName() + HObject.SEPARATOR); 183 } 184 } 185 } 186 187 if (((Group)parentObj).isRoot()) { 188 parentChoice.select(parentChoice.indexOf(HObject.SEPARATOR)); 189 } 190 else { 191 parentChoice.select( 192 parentChoice.indexOf(parentObj.getPath() + parentObj.getName() + HObject.SEPARATOR)); 193 } 194 195 // Create New Dataset from scratch 196 if (dataView == null) { 197 // Create Datatype region 198 createDatatypeWidget(); 199 200 // Create Dataspace region 201 org.eclipse.swt.widgets.Group dataspaceGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE); 202 dataspaceGroup.setFont(curFont); 203 dataspaceGroup.setText("Dataspace"); 204 dataspaceGroup.setLayout(new GridLayout(3, true)); 205 dataspaceGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 206 207 Label label = new Label(dataspaceGroup, SWT.LEFT); 208 label.setFont(curFont); 209 label.setText("No. of dimensions"); 210 211 label = new Label(dataspaceGroup, SWT.LEFT); 212 label.setFont(curFont); 213 label.setText("Current size"); 214 215 // Dummy label 216 label = new Label(dataspaceGroup, SWT.LEFT); 217 label.setFont(curFont); 218 label.setText(""); 219 220 rankChoice = new Combo(dataspaceGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 221 rankChoice.setFont(curFont); 222 rankChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 223 rankChoice.addSelectionListener(new SelectionAdapter() { 224 @Override 225 public void widgetSelected(SelectionEvent e) 226 { 227 int rank = rankChoice.getSelectionIndex() + 1; 228 StringBuilder currentSizeStr = new StringBuilder("1"); 229 230 for (int i = 1; i < rank; i++) { 231 currentSizeStr.append(" x 1"); 232 } 233 234 currentSizeField.setText(currentSizeStr.toString()); 235 236 String currentStr = currentSizeField.getText(); 237 int idx = currentStr.lastIndexOf('x'); 238 239 StringBuilder chunkStr = new StringBuilder(); 240 241 if (rank <= 1) { 242 chunkStr.append(currentStr); 243 } 244 else { 245 chunkStr.append("1"); 246 for (int i = 1; i < rank - 1; i++) { 247 chunkStr.append(" x 1"); 248 } 249 if (idx > 0) { 250 chunkStr.append(" x "); 251 chunkStr.append(currentStr.substring(idx + 1)); 252 } 253 } 254 255 chunkSizeField.setText(chunkStr.toString()); 256 } 257 }); 258 259 for (int i = 1; i < 33; i++) { 260 rankChoice.add(String.valueOf(i)); 261 } 262 rankChoice.select(1); 263 264 currentSizeField = new Text(dataspaceGroup, SWT.SINGLE | SWT.BORDER); 265 currentSizeField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 266 currentSizeField.setFont(curFont); 267 currentSizeField.setText("1 x 1"); 268 269 Button setMaxSizeButton = new Button(dataspaceGroup, SWT.PUSH); 270 setMaxSizeButton.setFont(curFont); 271 setMaxSizeButton.setText("Set Max Size"); 272 setMaxSizeButton.setLayoutData(new GridData(SWT.END, SWT.FILL, false, false)); 273 setMaxSizeButton.addSelectionListener(new SelectionAdapter() { 274 @Override 275 public void widgetSelected(SelectionEvent e) 276 { 277 if (maxSize == null || maxSize.length() < 1) 278 maxSize = currentSizeField.getText(); 279 280 String msg = new InputDialog(shell, "Set Max Size", 281 "Enter max dimension sizes. \n" 282 + "Use \"unlimited\" for unlimited dimension size.\n\n" 283 + "For example,\n" 284 + " 200 x 100\n" 285 + " 100 x unlimited\n\n", 286 maxSize) 287 .open(); 288 289 if (msg == null || msg.length() < 1) 290 maxSize = currentSizeField.getText(); 291 else 292 maxSize = msg; 293 294 checkMaxSize(); 295 } 296 }); 297 298 // Create Storage Properties region 299 org.eclipse.swt.widgets.Group storagePropertiesGroup = 300 new org.eclipse.swt.widgets.Group(shell, SWT.NONE); 301 storagePropertiesGroup.setFont(curFont); 302 storagePropertiesGroup.setText("Storage Properties"); 303 storagePropertiesGroup.setLayout(new GridLayout(5, true)); 304 storagePropertiesGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 305 306 label = new Label(storagePropertiesGroup, SWT.LEFT); 307 label.setFont(curFont); 308 label.setText("Storage layout: "); 309 310 checkContiguous = new Button(storagePropertiesGroup, SWT.RADIO); 311 checkContiguous.setFont(curFont); 312 checkContiguous.setText("Contiguous"); 313 checkContiguous.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 314 checkContiguous.setSelection(true); 315 checkContiguous.addSelectionListener(new SelectionAdapter() { 316 @Override 317 public void widgetSelected(SelectionEvent e) 318 { 319 chunkSizeField.setEnabled(false); 320 } 321 }); 322 323 // Dummy label 324 label = new Label(storagePropertiesGroup, SWT.LEFT); 325 label.setFont(curFont); 326 label.setText(""); 327 label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 328 329 checkChunked = new Button(storagePropertiesGroup, SWT.RADIO); 330 checkChunked.setFont(curFont); 331 checkChunked.setText("Chunked (size) "); 332 checkChunked.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 333 checkChunked.addSelectionListener(new SelectionAdapter() { 334 @Override 335 public void widgetSelected(SelectionEvent e) 336 { 337 chunkSizeField.setEnabled(true); 338 StringBuilder chunkStr = new StringBuilder(); 339 StringTokenizer st = new StringTokenizer(currentSizeField.getText(), "x"); 340 int rank = rankChoice.getSelectionIndex() + 1; 341 while (st.hasMoreTokens()) { 342 long l = Math.max(1, Long.valueOf(st.nextToken().trim()) / (2 * rank)); 343 chunkStr.append(String.valueOf(l)); 344 chunkStr.append("x"); 345 } 346 String chunkString = chunkStr.substring(0, chunkStr.lastIndexOf("x")); 347 chunkSizeField.setText(chunkString); 348 } 349 }); 350 351 chunkSizeField = new Text(storagePropertiesGroup, SWT.SINGLE | SWT.BORDER); 352 chunkSizeField.setFont(curFont); 353 chunkSizeField.setText("1 x 1"); 354 chunkSizeField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 355 chunkSizeField.setEnabled(false); 356 357 label = new Label(storagePropertiesGroup, SWT.LEFT); 358 label.setFont(curFont); 359 label.setText("Compression: "); 360 361 checkCompression = new Button(storagePropertiesGroup, SWT.CHECK); 362 checkCompression.setFont(curFont); 363 checkCompression.setText("gzip (level) "); 364 checkCompression.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 365 checkCompression.addSelectionListener(new SelectionAdapter() { 366 @Override 367 public void widgetSelected(SelectionEvent e) 368 { 369 boolean isCompressed = checkCompression.getSelection(); 370 371 if (isCompressed && isH5) { 372 if (!checkChunked.getSelection()) { 373 int rank = rankChoice.getSelectionIndex() + 1; 374 String currentStr = currentSizeField.getText(); 375 int idx = currentStr.lastIndexOf('x'); 376 StringBuilder chunkStr = new StringBuilder(); 377 378 if (rank <= 1) { 379 chunkStr.append(currentStr); 380 } 381 else { 382 chunkStr.append("1"); 383 for (int i = 1; i < rank - 1; i++) { 384 chunkStr.append(" x 1"); 385 } 386 if (idx > 0) { 387 chunkStr.append(" x "); 388 chunkStr.append(currentStr.substring(idx + 1)); 389 } 390 } 391 392 chunkSizeField.setText(chunkStr.toString()); 393 } 394 compressionLevel.setEnabled(true); 395 checkContiguous.setEnabled(false); 396 checkContiguous.setSelection(false); 397 checkChunked.setSelection(true); 398 chunkSizeField.setEnabled(true); 399 } 400 else { 401 compressionLevel.setEnabled(isCompressed); 402 checkContiguous.setEnabled(true); 403 } 404 } 405 }); 406 407 compressionLevel = new Combo(storagePropertiesGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 408 compressionLevel.setFont(curFont); 409 compressionLevel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 410 411 for (int i = 0; i < 10; i++) { 412 compressionLevel.add(String.valueOf(i)); 413 } 414 compressionLevel.select(6); 415 compressionLevel.setEnabled(false); 416 417 if (isH5) { 418 checkFillValue = new Button(storagePropertiesGroup, SWT.CHECK); 419 checkFillValue.setFont(curFont); 420 checkFillValue.setText("Fill Value"); 421 checkFillValue.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 422 checkFillValue.setSelection(false); 423 checkFillValue.addSelectionListener(new SelectionAdapter() { 424 @Override 425 public void widgetSelected(SelectionEvent e) 426 { 427 fillValueField.setEnabled(checkFillValue.getSelection()); 428 } 429 }); 430 431 fillValueField = new Text(storagePropertiesGroup, SWT.SINGLE | SWT.BORDER); 432 fillValueField.setFont(curFont); 433 fillValueField.setText("0"); 434 fillValueField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 435 fillValueField.setEnabled(false); 436 } 437 else { 438 // Add two dummy labels 439 label = new Label(storagePropertiesGroup, SWT.LEFT); 440 label.setFont(curFont); 441 label.setText(""); 442 label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 443 444 label = new Label(storagePropertiesGroup, SWT.LEFT); 445 label.setFont(curFont); 446 label.setText(""); 447 label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 448 } 449 } 450 451 // Create Ok/Cancel/Help button region 452 Composite buttonComposite = new Composite(shell, SWT.NONE); 453 buttonComposite.setLayout(new GridLayout((dataView == null) ? 3 : 2, false)); 454 buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 455 456 Button okButton = new Button(buttonComposite, SWT.PUSH); 457 okButton.setFont(curFont); 458 okButton.setText(" &OK "); 459 okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); 460 okButton.addSelectionListener(new SelectionAdapter() { 461 @Override 462 public void widgetSelected(SelectionEvent e) 463 { 464 if (dataView instanceof TableView) { 465 newObject = createFromTable(); 466 } 467 else if (dataView instanceof ImageView) { 468 newObject = createFromImage(); 469 } 470 else if (dataView == null) { 471 newObject = createFromScratch(); 472 } 473 474 if (newObject != null) { 475 shell.dispose(); 476 } 477 } 478 }); 479 480 Button cancelButton = new Button(buttonComposite, SWT.PUSH); 481 cancelButton.setFont(curFont); 482 cancelButton.setText(" &Cancel "); 483 cancelButton.setLayoutData(new GridData((dataView == null) ? SWT.CENTER : SWT.BEGINNING, SWT.FILL, 484 (dataView == null) ? false : true, false)); 485 cancelButton.addSelectionListener(new SelectionAdapter() { 486 @Override 487 public void widgetSelected(SelectionEvent e) 488 { 489 newObject = null; 490 shell.dispose(); 491 ((Vector<Group>)groupList).setSize(0); 492 } 493 }); 494 495 if (dataView == null) { 496 Button helpButton = new Button(buttonComposite, SWT.PUSH); 497 helpButton.setFont(curFont); 498 helpButton.setText(" &Help "); 499 helpButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false)); 500 helpButton.addSelectionListener(new SelectionAdapter() { 501 @Override 502 public void widgetSelected(SelectionEvent e) 503 { 504 new HelpDialog(shell).open(); 505 } 506 }); 507 } 508 509 shell.pack(); 510 511 shell.addDisposeListener(new DisposeListener() { 512 @Override 513 public void widgetDisposed(DisposeEvent e) 514 { 515 if (curFont != null) 516 curFont.dispose(); 517 } 518 }); 519 520 shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 521 522 Rectangle parentBounds = parent.getBounds(); 523 Point shellSize = shell.getSize(); 524 shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2), 525 (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2)); 526 527 shell.open(); 528 529 Display display = shell.getDisplay(); 530 while (!shell.isDisposed()) 531 if (!display.readAndDispatch()) 532 display.sleep(); 533 } 534 535 /** Check if the max size is valid */ 536 private void checkMaxSize() 537 { 538 boolean isChunkNeeded = false; 539 String dimStr = currentSizeField.getText(); 540 String maxSizeStr = maxSize; 541 StringTokenizer stMax = new StringTokenizer(maxSizeStr, "x"); 542 StringTokenizer stDim = new StringTokenizer(dimStr, "x"); 543 544 if (stMax.countTokens() != stDim.countTokens()) { 545 shell.getDisplay().beep(); 546 Tools.showError(shell, "Check", "Wrong number of values in the max dimension size " + maxSize); 547 maxSize = null; 548 return; 549 } 550 551 int rank = stDim.countTokens(); 552 long max = 0, dim = 0; 553 long[] maxdims = new long[rank]; 554 for (int i = 0; i < rank; i++) { 555 String token = stMax.nextToken().trim(); 556 557 token = token.toLowerCase(); 558 if (token.startsWith("u")) { 559 max = -1; 560 isChunkNeeded = true; 561 } 562 else { 563 try { 564 max = Long.parseLong(token); 565 } 566 catch (NumberFormatException ex) { 567 shell.getDisplay().beep(); 568 Tools.showError(shell, "Check", "Invalid max dimension size: " + maxSize); 569 maxSize = null; 570 return; 571 } 572 } 573 574 token = stDim.nextToken().trim(); 575 try { 576 dim = Long.parseLong(token); 577 } 578 catch (NumberFormatException ex) { 579 shell.getDisplay().beep(); 580 Tools.showError(shell, "Check", "Invalid dimension size: " + dimStr); 581 return; 582 } 583 584 if (max != -1 && max < dim) { 585 shell.getDisplay().beep(); 586 Tools.showError(shell, "Check", "Invalid max dimension size: " + maxSize); 587 maxSize = null; 588 return; 589 } 590 else if (max > dim) { 591 isChunkNeeded = true; 592 } 593 594 maxdims[i] = max; 595 } // (int i = 0; i < rank; i++) 596 597 if (isH5) { 598 if (isChunkNeeded && !checkChunked.getSelection()) { 599 shell.getDisplay().beep(); 600 Tools.showError(shell, "Check", "Chunking is required for the max dimensions of " + maxSize); 601 checkChunked.setSelection(true); 602 } 603 } 604 else { 605 for (int i = 1; i < rank; i++) { 606 if (maxdims[i] <= 0) { 607 maxSize = currentSizeField.getText(); 608 shell.getDisplay().beep(); 609 Tools.showError(shell, "Check", "Only dim[0] can be unlimited." + maxSize); 610 return; 611 } 612 } 613 } 614 } 615 616 private HObject createFromScratch() 617 { 618 String name = null; 619 Group pgroup = null; 620 int rank = -1; 621 int gzip = -1; 622 long[] dims; 623 long[] maxdims = null; 624 long[] chunks = null; 625 626 name = nameField.getText().trim(); 627 if ((name == null) || (name.length() < 1)) { 628 shell.getDisplay().beep(); 629 Tools.showError(shell, "Create", "Dataset name is not specified."); 630 return null; 631 } 632 633 if (name.indexOf(HObject.SEPARATOR) >= 0) { 634 shell.getDisplay().beep(); 635 Tools.showError(shell, "Create", "Dataset name cannot contain path."); 636 return null; 637 } 638 639 pgroup = groupList.get(parentChoice.getSelectionIndex()); 640 641 if (pgroup == null) { 642 shell.getDisplay().beep(); 643 Tools.showError(shell, "Create", "Parent group is null."); 644 return null; 645 } 646 647 rank = rankChoice.getSelectionIndex() + 1; 648 StringTokenizer st = new StringTokenizer(currentSizeField.getText(), "x"); 649 if (st.countTokens() < rank) { 650 shell.getDisplay().beep(); 651 Tools.showError(shell, "Create", 652 "Number of values in the current dimension size is less than " + rank); 653 return null; 654 } 655 656 long l = 0; 657 dims = new long[rank]; 658 String token = null; 659 for (int i = 0; i < rank; i++) { 660 token = st.nextToken().trim(); 661 try { 662 l = Long.parseLong(token); 663 } 664 catch (NumberFormatException ex) { 665 shell.getDisplay().beep(); 666 Tools.showError(shell, "Create", "Invalid dimension size: " + currentSizeField.getText()); 667 return null; 668 } 669 670 if (l <= 0) { 671 shell.getDisplay().beep(); 672 Tools.showError(shell, "Create", "Dimension size must be greater than zero."); 673 return null; 674 } 675 676 dims[i] = l; 677 } 678 679 String maxSizeStr = maxSize; 680 if (maxSizeStr != null && maxSizeStr.length() > 1) { 681 st = new StringTokenizer(maxSizeStr, "x"); 682 if (st.countTokens() < rank) { 683 shell.getDisplay().beep(); 684 Tools.showError(shell, "Create", 685 "Number of values in the max dimension size is less than " + rank); 686 return null; 687 } 688 689 l = 0; 690 maxdims = new long[rank]; 691 for (int i = 0; i < rank; i++) { 692 token = st.nextToken().trim(); 693 694 token = token.toLowerCase(); 695 if (token.startsWith("u")) 696 l = -1; 697 else { 698 try { 699 l = Long.parseLong(token); 700 } 701 catch (NumberFormatException ex) { 702 shell.getDisplay().beep(); 703 Tools.showError(shell, "Create", "Invalid max dimension size: " + maxSize); 704 return null; 705 } 706 } 707 708 if (l < -1) { 709 shell.getDisplay().beep(); 710 Tools.showError(shell, "Create", "Dimension size cannot be less than -1."); 711 return null; 712 } 713 else if (l == 0) { 714 l = dims[i]; 715 } 716 717 maxdims[i] = l; 718 } 719 } 720 721 chunks = null; 722 if (checkChunked.getSelection()) { 723 st = new StringTokenizer(chunkSizeField.getText(), "x"); 724 if (st.countTokens() < rank) { 725 shell.getDisplay().beep(); 726 Tools.showError(shell, "Create", "Number of values in the chunk size is less than " + rank); 727 return null; 728 } 729 730 l = 0; 731 chunks = new long[rank]; 732 for (int i = 0; i < rank; i++) { 733 token = st.nextToken().trim(); 734 try { 735 l = Long.parseLong(token); 736 } 737 catch (NumberFormatException ex) { 738 shell.getDisplay().beep(); 739 Tools.showError(shell, "Create", 740 "Invalid chunk dimension size: " + chunkSizeField.getText()); 741 return null; 742 } 743 744 if (l < 1) { 745 shell.getDisplay().beep(); 746 Tools.showError(shell, "Create", "Chunk size cannot be less than 1."); 747 return null; 748 } 749 750 chunks[i] = l; 751 } // (int i=0; i<rank; i++) 752 753 long tchunksize = 1; 754 long tdimsize = 1; 755 for (int i = 0; i < rank; i++) { 756 tchunksize *= chunks[i]; 757 tdimsize *= dims[i]; 758 } 759 760 if (tchunksize >= tdimsize) { 761 shell.getDisplay().beep(); 762 if (!Tools.showConfirm(shell, "Create", 763 "Chunk size is equal/greater than the current size. " 764 + "\nAre you sure you want to set chunk size to " + 765 chunkSizeField.getText() + "?")) { 766 return null; 767 } 768 } 769 770 if (tchunksize == 1) { 771 shell.getDisplay().beep(); 772 if (!Tools.showConfirm( 773 shell, "Create", 774 "Chunk size is one, which may cause large memory overhead for large dataset." 775 + "\nAre you sure you want to set chunk size to " + chunkSizeField.getText() + 776 "?")) { 777 return null; 778 } 779 } 780 } // (checkChunked.isSelected()) 781 782 if (checkCompression.getSelection()) { 783 gzip = compressionLevel.getSelectionIndex(); 784 } 785 else { 786 gzip = 0; 787 } 788 789 HObject obj = null; 790 try { 791 Datatype datatype = createNewDatatype(null); 792 793 String fillValue = null; 794 795 if (fillValueField != null) { 796 if (fillValueField.isEnabled()) 797 fillValue = fillValueField.getText(); 798 } 799 800 obj = fileFormat.createScalarDS(name, pgroup, datatype, dims, maxdims, chunks, gzip, fillValue, 801 null); 802 } 803 catch (Exception ex) { 804 shell.getDisplay().beep(); 805 Tools.showError(shell, "Create", ex.getMessage()); 806 return null; 807 } 808 809 return obj; 810 } 811 812 private HObject createFromTable() 813 { 814 HObject obj = null; 815 816 String name = null; 817 Group pgroup = null; 818 819 name = nameField.getText(); 820 if (name == null || name.length() == 0) { 821 shell.getDisplay().beep(); 822 Tools.showError(shell, "Create", "Dataset name is not specified."); 823 return null; 824 } 825 826 if (name.indexOf(HObject.SEPARATOR) >= 0) { 827 shell.getDisplay().beep(); 828 Tools.showError(shell, "Create", "Dataset name cannot contain path."); 829 return null; 830 } 831 832 pgroup = groupList.get(parentChoice.getSelectionIndex()); 833 if (pgroup == null) { 834 shell.getDisplay().beep(); 835 Tools.showError(shell, "Create", "Parent group is null."); 836 return null; 837 } 838 839 TableView tableView = (TableView)dataView; 840 Object theData = tableView.getSelectedData(); 841 if (theData == null) { 842 return null; 843 } 844 845 int w = tableView.getSelectedColumnCount(); 846 int h = tableView.getSelectedRowCount(); 847 Dataset dataset = (Dataset)tableView.getDataObject(); 848 if (dataset instanceof ScalarDS) { 849 ScalarDS sd = (ScalarDS)dataset; 850 if (sd.getDatatype().isUnsigned()) { 851 theData = Dataset.convertToUnsignedC(theData, null); 852 } 853 } 854 855 try { 856 long[] dims = {h, w}; 857 obj = dataset.copy(pgroup, name, dims, theData); 858 } 859 catch (Exception ex) { 860 shell.getDisplay().beep(); 861 Tools.showError(shell, "Create", ex.getMessage()); 862 return null; 863 } 864 865 return obj; 866 } 867 868 private HObject createFromImage() 869 { 870 HObject obj = null; 871 String name = null; 872 Group pgroup = null; 873 874 name = nameField.getText(); 875 if (name == null || name.length() == 0) { 876 shell.getDisplay().beep(); 877 Tools.showError(shell, "Create", "Dataset name is not specified."); 878 return null; 879 } 880 881 if (name.indexOf(HObject.SEPARATOR) >= 0) { 882 shell.getDisplay().beep(); 883 Tools.showError(shell, "Create", "Dataset name cannot contain path."); 884 return null; 885 } 886 887 pgroup = groupList.get(parentChoice.getSelectionIndex()); 888 if (pgroup == null) { 889 shell.getDisplay().beep(); 890 Tools.showError(shell, "Create", "Parent group is null."); 891 return null; 892 } 893 894 ImageView imageView = (ImageView)dataView; 895 ScalarDS dataset = (ScalarDS)imageView.getDataObject(); 896 Object theData = imageView.getSelectedData(); 897 898 if (theData == null) { 899 return null; 900 } 901 902 // in version 2.4, unsigned image data is converted to signed data 903 // to write data, the data needs to be converted back to unsigned. 904 if (dataset.getDatatype().isUnsigned()) { 905 theData = Dataset.convertToUnsignedC(theData, null); 906 } 907 908 int w = imageView.getSelectedArea().width; 909 int h = imageView.getSelectedArea().height; 910 911 try { 912 long[] dims = null; 913 if (isH5) { 914 if (imageView.isTrueColor()) { 915 dims = new long[3]; 916 if (imageView.isPlaneInterlace()) { 917 dims[0] = 3; 918 dims[1] = h; 919 dims[2] = w; 920 } 921 else { 922 dims[0] = h; 923 dims[1] = w; 924 dims[2] = 3; 925 } 926 } 927 else { 928 dims = new long[2]; 929 dims[0] = h; 930 dims[1] = w; 931 } 932 } 933 else { 934 dims = new long[2]; 935 dims[0] = w; 936 dims[1] = h; 937 } 938 939 obj = dataset.copy(pgroup, name, dims, theData); 940 } 941 catch (Exception ex) { 942 shell.getDisplay().beep(); 943 Tools.showError(shell, "Create", ex.getMessage()); 944 return null; 945 } 946 947 return obj; 948 } 949 950 private class HelpDialog extends Dialog { 951 private Shell helpShell; 952 953 public HelpDialog(Shell parent) { super(parent, SWT.APPLICATION_MODAL); } 954 955 public void open() 956 { 957 Shell parent = getParent(); 958 helpShell = 959 new Shell(parent, SWT.TITLE | SWT.CLOSE | SWT.RESIZE | SWT.BORDER | SWT.APPLICATION_MODAL); 960 helpShell.setFont(curFont); 961 helpShell.setText("Create New Dataset"); 962 helpShell.setImages(ViewProperties.getHdfIcons()); 963 helpShell.setLayout(new GridLayout(1, true)); 964 965 // Try to create a Browser on platforms that support it 966 try { 967 Browser browser = new Browser(helpShell, SWT.NONE); 968 browser.setFont(curFont); 969 browser.setBounds(0, 0, 500, 500); 970 browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 971 972 if (ClassLoader.getSystemResource("hdf/view/HDFView.class").toString().startsWith("jar")) { 973 // Attempt to load HTML help file from jar 974 try (InputStream in = getClass().getClassLoader().getResourceAsStream( 975 "hdf/view/NewDatasetHelp.html")) { 976 Scanner scan = new Scanner(in); 977 StringBuilder buffer = new StringBuilder(); 978 while (scan.hasNextLine()) { 979 buffer.append(scan.nextLine()); 980 } 981 982 browser.setText(buffer.toString()); 983 984 scan.close(); 985 } 986 catch (Exception e) { 987 StringBuilder buff = new StringBuilder(); 988 buff.append("<html>") 989 .append("<body>") 990 .append("ERROR: cannot load help information.") 991 .append("</body>") 992 .append("</html>"); 993 browser.setText(buff.toString(), true); 994 } 995 } 996 else { 997 try { 998 URL url = null, url2 = null, url3 = null; 999 String rootPath = ViewProperties.getViewRoot(); 1000 1001 try { 1002 url = new URL("file://" + rootPath + "/HDFView.jar"); 1003 } 1004 catch (java.net.MalformedURLException mfu) { 1005 log.debug("help information:", mfu); 1006 } 1007 1008 try { 1009 url2 = new URL("file://" + rootPath + "/"); 1010 } 1011 catch (java.net.MalformedURLException mfu) { 1012 log.debug("help information:", mfu); 1013 } 1014 1015 try { 1016 url3 = new URL("file://" + rootPath + "/src/"); 1017 } 1018 catch (java.net.MalformedURLException mfu) { 1019 log.debug("help information:", mfu); 1020 } 1021 1022 URL uu[] = {url, url2, url3}; 1023 try (URLClassLoader cl = new URLClassLoader(uu)) { 1024 URL u = cl.findResource("hdf/view/NewDatasetHelp.html"); 1025 1026 browser.setUrl(u.toString()); 1027 } 1028 catch (Exception ex) { 1029 log.trace("URLClassLoader failed:", ex); 1030 } 1031 } 1032 catch (Exception e) { 1033 StringBuilder buff = new StringBuilder(); 1034 buff.append("<html>") 1035 .append("<body>") 1036 .append("ERROR: cannot load help information.") 1037 .append("</body>") 1038 .append("</html>"); 1039 browser.setText(buff.toString(), true); 1040 } 1041 } 1042 1043 Button okButton = new Button(helpShell, SWT.PUSH); 1044 okButton.setFont(curFont); 1045 okButton.setText(" &OK "); 1046 okButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false)); 1047 okButton.addSelectionListener(new SelectionAdapter() { 1048 @Override 1049 public void widgetSelected(SelectionEvent e) 1050 { 1051 helpShell.dispose(); 1052 } 1053 }); 1054 1055 helpShell.pack(); 1056 1057 helpShell.setSize(new Point(500, 500)); 1058 1059 Rectangle parentBounds = parent.getBounds(); 1060 Point shellSize = helpShell.getSize(); 1061 helpShell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2), 1062 (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2)); 1063 1064 helpShell.open(); 1065 1066 Display display = parent.getDisplay(); 1067 while (!helpShell.isDisposed()) { 1068 if (!display.readAndDispatch()) 1069 display.sleep(); 1070 } 1071 } 1072 catch (Error er) { 1073 // Try opening help link in external browser if platform 1074 // doesn't support SWT browser 1075 Tools.showError(shell, "Browser support", 1076 "Platform doesn't support Browser. Opening external link in web browser..."); 1077 1078 // TODO: Add support for launching in external browser 1079 } 1080 catch (Exception ex) { 1081 log.debug("Open New Dataset Help failure: ", ex); 1082 } 1083 } 1084 } 1085}