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