    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.awt.Image;
    018import java.awt.Rectangle;
    019import java.awt.Toolkit;
    020import java.awt.image.BufferedImage;
    021import java.awt.image.ComponentColorModel;
    022import java.awt.image.DirectColorModel;
    023import java.awt.image.FilteredImageSource;
    024import java.awt.image.ImageFilter;
    025import java.awt.image.ImageProducer;
    026import java.awt.image.IndexColorModel;
    027import java.awt.image.WritableRaster;
    028import java.util.BitSet;
    029import java.util.StringTokenizer;
    030import java.util.Vector;
    031
    032import org.eclipse.swt.SWT;
    033import org.eclipse.swt.events.DisposeEvent;
    034import org.eclipse.swt.events.DisposeListener;
    035import org.eclipse.swt.events.MouseEvent;
    036import org.eclipse.swt.events.MouseListener;
    037import org.eclipse.swt.events.MouseMoveListener;
    038import org.eclipse.swt.events.PaintEvent;
    039import org.eclipse.swt.events.PaintListener;
    040import org.eclipse.swt.events.SelectionAdapter;
    041import org.eclipse.swt.events.SelectionEvent;
    042import org.eclipse.swt.graphics.Font;
    043import org.eclipse.swt.graphics.GC;
    044import org.eclipse.swt.graphics.ImageData;
    045import org.eclipse.swt.graphics.PaletteData;
    046import org.eclipse.swt.graphics.Point;
    047import org.eclipse.swt.graphics.RGB;
    048import org.eclipse.swt.layout.GridData;
    049import org.eclipse.swt.layout.GridLayout;
    050import org.eclipse.swt.widgets.Button;
    051import org.eclipse.swt.widgets.Canvas;
    052import org.eclipse.swt.widgets.Combo;
    053import org.eclipse.swt.widgets.Composite;
    054import org.eclipse.swt.widgets.Dialog;
    055import org.eclipse.swt.widgets.Display;
    056import org.eclipse.swt.widgets.Event;
    057import org.eclipse.swt.widgets.Label;
    058import org.eclipse.swt.widgets.List;
    059import org.eclipse.swt.widgets.Listener;
    060import org.eclipse.swt.widgets.Shell;
    061import org.eclipse.swt.widgets.Text;
    062
    063import hdf.object.CompoundDS;
    064import hdf.object.DataFormat;
    065import hdf.object.Dataset;
    066import hdf.object.Datatype;
    067import hdf.object.FileFormat;
    068import hdf.object.HObject;
    069import hdf.object.ScalarDS;
    070import hdf.view.HDFView;
    071import hdf.view.Tools;
    072import hdf.view.ViewProperties;
    073import hdf.view.ImageView.DefaultImageView;
    074import hdf.view.ImageView.DefaultImageView.FlipFilter;
    075import hdf.view.ImageView.DefaultImageView.Rotate90Filter;
    076
    077/**
    078 * DataOptionDialog is an dialog window used to select display options. Display options include
    079 * selection of subset, display type (image, text, or spreadsheet).
    080 *
    081 * @author Jordan T. Henderson
    082 * @version 2.4 3/26/2016
    083 */
    084public class DataOptionDialog extends Dialog {
    085
    086    private Shell               shell;
    087
    088    private Font                curFont;
    089
    090    /** the rank of the dataset/image */
    091    private int                 rank;
    092
    093    /** the starting point of selected subset */
    094    private long[]              start;
    095
    096    /** the sizes of all dimensions */
    097    private long[]              dims;
    098
    099    /** the selected sizes of all dimensions */
    100    private long[]              selected;
    101
    102    /** the stride */
    103    private long[]              stride;
    104
    105    /** the indices of the selected dimensions. */
    106    private int[]               selectedIndex;
    107    private int[]               currentIndex;
    108
    109    private BitSet              bitmask;
    110
    111    private Button              spreadsheetButton;
    112    private Button              imageButton;
    113    private Button              base1Button;
    114    private Button              base0Button;
    115    private Button              charCheckbox;
    116    private Button              bitmaskHelp;
    117    private Button              applyBitmaskButton;
    118    private Button              extractBitButton;
    119    private Button[]            bitmaskButtons;
    120
    121    private Combo               choiceTableView;
    122    private Combo               choiceImageView;
    123    private Combo               choicePalette;
    124    private Combo               transposeChoice;
    125    private Combo[]             choices;
    126
    127    private boolean             isSelectionCancelled;
    128    private boolean             isTrueColorImage;
    129    private boolean             isH5;
    130    private boolean             isImageDisplay = false;
    131    private boolean             isDisplayTypeChar = false;
    132    private boolean             isTransposed = false;
    133    private boolean             isIndexBase1 = false;
    134    private boolean             isApplyBitmaskOnly = false;
    135
    136    private String              dataViewName;
    137
    138    private Label[]             maxLabels;
    139
    140    private Text[]              startFields;
    141    private Text[]              endFields;
    142    private Text[]              strideFields;
    143
    144    private Text                dataRangeField;
    145    private Text                fillValueField;
    146
    147    private List                fieldList;
    148
    149    private PreviewNavigator    navigator;
    150
    151    private int                 numberOfPalettes;
    152
    153    /** the selected dataset/image */
    154    private DataFormat          dataObject;
    155
    156
    157    /**
    158     * Constructs a DataOptionDialog with the given HDFView.
    159     *
    160     * @param parent
    161     *            the parent of this dialog
    162     * @param dataObject
    163     *            the data object associated with this dialog
    164     */
    165    public DataOptionDialog(Shell parent, DataFormat dataObject) {
    166        super(parent, SWT.APPLICATION_MODAL);
    167
    168        if (dataObject == null) return;
    169
    170        this.dataObject = dataObject;
    171
    172        try {
    173            curFont = new Font(
    174                    Display.getCurrent(),
    175                    ViewProperties.getFontType(),
    176                    ViewProperties.getFontSize(),
    177                    SWT.NORMAL);
    178        }
    179        catch (Exception ex) {
    180            curFont = null;
    181        }
    182
    183        isSelectionCancelled = true;
    184        isTrueColorImage = false;
    185        bitmask = null;
    186        numberOfPalettes = 1;
    187
    188        if (!dataObject.isInited())
    189            dataObject.init();
    190
    191        if (isH5 && (dataObject instanceof ScalarDS)) {
    192            byte[] palRefs = ((ScalarDS) dataObject).getPaletteRefs();
    193            if ((palRefs != null) && (palRefs.length > 8)) {
    194                numberOfPalettes = palRefs.length / 8;
    195            }
    196        }
    197
    198        rank = dataObject.getRank();
    199        dims = dataObject.getDims();
    200        selected = dataObject.getSelectedDims();
    201        start = dataObject.getStartDims();
    202        selectedIndex = dataObject.getSelectedIndex();
    203        stride = dataObject.getStride();
    204        currentIndex = new int[Math.min(3, rank)];
    205
    206        maxLabels = new Label[3];
    207        startFields = new Text[3];
    208        endFields = new Text[3];
    209        strideFields = new Text[3];
    210        choices = new Combo[3];
    211
    212        isH5 = ((HObject) dataObject).getFileFormat().isThisType(
    213                FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5));
    214    }
    215
    216    public void open() {
    217        Shell parent = getParent();
    218        shell = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);
    219        shell.setFont(curFont);
    220        shell.setText("Dataset Selection - " + ((HObject) dataObject).getPath() + ((HObject) dataObject).getName());
    221        shell.setImage(ViewProperties.getHdfIcon());
    222        shell.setLayout(new GridLayout(1, true));
    223
    224        if (dataObject instanceof ScalarDS) {
    225            createScalarDSContents();
    226        }
    227        else if (dataObject instanceof CompoundDS) {
    228            createCompoundDSContents();
    229        }
    230
    231        // Create Ok/Cancel button region
    232        Composite buttonComposite = new Composite(shell, SWT.NONE);
    233        buttonComposite.setLayout(new GridLayout(2, true));
    234        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
    235
    236        Button okButton = new Button(buttonComposite, SWT.PUSH);
    237        okButton.setFont(curFont);
    238        okButton.setText("   &OK   ");
    239        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
    240        okButton.addSelectionListener(new SelectionAdapter() {
    241            @Override
    242            public void widgetSelected(SelectionEvent e) {
    243                // set palette for image view
    244                if(imageButton != null) {
    245                    if ((dataObject instanceof ScalarDS) && imageButton.getSelection()) {
    246                        setPalette();
    247                    }
    248                }
    249
    250                isSelectionCancelled = !setSelection();
    251
    252                if (isSelectionCancelled) {
    253                    return;
    254                }
    255
    256                if(imageButton != null) {
    257                    if (dataObject instanceof ScalarDS) {
    258                        ((ScalarDS) dataObject).setIsImageDisplay(imageButton.getSelection());
    259                    }
    260                }
    261
    262                shell.notifyListeners(SWT.Close, null);
    263
    264                shell.dispose();
    265            }
    266        });
    267
    268        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
    269        cancelButton.setFont(curFont);
    270        cancelButton.setText(" &Cancel ");
    271        cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
    272        cancelButton.addSelectionListener(new SelectionAdapter() {
    273            @Override
    274            public void widgetSelected(SelectionEvent e) {
    275                shell.notifyListeners(SWT.Close, null);
    276
    277                shell.dispose();
    278            }
    279        });
    280
    281        shell.pack();
    282
    283        init();
    284
    285        shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    286
    287        org.eclipse.swt.graphics.Rectangle parentBounds = parent.getBounds();
    288        Point shellSize = shell.getSize();
    289        shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
    290                (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
    291
    292        shell.addListener(SWT.Close, new Listener() {
    293            @Override
    294            public void handleEvent(Event e) {
    295                if (imageButton == null) {
    296                    isImageDisplay = false;
    297                }
    298                else {
    299                    isImageDisplay = imageButton.getSelection();
    300                }
    301
    302                if (charCheckbox == null) {
    303                    isDisplayTypeChar = false;
    304                }
    305                else {
    306                    isDisplayTypeChar = charCheckbox.getSelection();
    307                }
    308
    309                if (transposeChoice == null) {
    310                    isTransposed = false;
    311                }
    312                else {
    313                    isTransposed = transposeChoice.isEnabled() && transposeChoice.getSelectionIndex() == 0;
    314                }
    315
    316                if (base1Button == null) {
    317                    isIndexBase1 = false;
    318                }
    319                else {
    320                    isIndexBase1 = base1Button.getSelection();
    321                }
    322
    323                if (applyBitmaskButton == null) {
    324                    isApplyBitmaskOnly = false;
    325                }
    326                else {
    327                    isApplyBitmaskOnly = applyBitmaskButton.getSelection();
    328                }
    329
    330                if (isImageDisplay()) {
    331                    dataViewName = choiceImageView.getItem(choiceImageView.getSelectionIndex());
    332                }
    333                else {
    334                    dataViewName = choiceTableView.getItem(choiceTableView.getSelectionIndex());
    335                }
    336            }
    337        });
    338
    339        shell.addDisposeListener(new DisposeListener() {
    340            @Override
    341            public void widgetDisposed(DisposeEvent e) {
    342                if (curFont != null) curFont.dispose();
    343            }
    344        });
    345
    346        shell.open();
    347
    348        // Prevent SWT from selecting TableView button by
    349        // default if dataset is an image
    350        if (dataObject instanceof ScalarDS) {
    351            if (((ScalarDS) dataObject).isImageDisplay()) {
    352                spreadsheetButton.setSelection(false);
    353            }
    354        }
    355
    356        Display display = parent.getDisplay();
    357        while(!shell.isDisposed()) {
    358            if (!display.readAndDispatch())
    359                display.sleep();
    360        }
    361    }
    362
    363    /**
    364     * Set the initial state of all the variables
    365     */
    366    private void init() {
    367        // set the imagebutton state
    368        boolean isImage = false;
    369
    370        if (dataObject instanceof ScalarDS) {
    371            if (!dataObject.getDatatype().isText()) {
    372                ScalarDS sd = (ScalarDS) dataObject;
    373                isImage = sd.isImageDisplay();
    374                isTrueColorImage = sd.isTrueColor();
    375                // compound datasets don't have data range or fill values
    376                // (JAVA-1825)
    377                dataRangeField.setEnabled(isImage);
    378                fillValueField.setEnabled(isImage);
    379            }
    380        }
    381
    382        if(choiceTableView != null) {
    383            choiceTableView.setEnabled(!isImage);
    384        }
    385
    386        if(choiceImageView != null) {
    387            choiceImageView.setEnabled(isImage);
    388        }
    389
    390        if(imageButton != null) {
    391            imageButton.setSelection(isImage);
    392        }
    393
    394        if(choicePalette != null) {
    395            choicePalette.setEnabled(isImage && !isTrueColorImage);
    396        }
    397
    398        int n = Math.min(3, rank);
    399        long endIdx = 0;
    400        for (int i = 0; i < n; i++) {
    401            choices[i].setEnabled(true);
    402            startFields[i].setEnabled(true);
    403            endFields[i].setEnabled(true);
    404            strideFields[i].setEnabled(true);
    405            maxLabels[i].setEnabled(true);
    406
    407            int idx = selectedIndex[i];
    408            endIdx = start[idx] + selected[idx] * stride[idx];
    409            if (endIdx >= dims[idx]) {
    410                endIdx = dims[idx];
    411            }
    412
    413            choices[i].select(idx);
    414            maxLabels[i].setText(String.valueOf(dims[idx]));
    415            startFields[i].setText(String.valueOf(start[idx]));
    416            endFields[i].setText(String.valueOf(endIdx - 1));
    417
    418            if (!isH5 && (dataObject instanceof CompoundDS)) {
    419                strideFields[i].setEnabled(false);
    420            }
    421            else {
    422                strideFields[i].setText(String.valueOf(stride[idx]));
    423            }
    424        }
    425
    426        if (rank > 1) {
    427            transposeChoice.setEnabled((choices[0].getSelectionIndex() > choices[1]
    428                    .getSelectionIndex()));
    429
    430            if (rank > 2) {
    431                endFields[2].setEnabled(false);
    432                strideFields[2].setEnabled(false);
    433
    434                if (isTrueColorImage && imageButton != null) {
    435                    if(imageButton.getSelection()) {
    436                        choices[0].setEnabled(false);
    437                        choices[1].setEnabled(false);
    438                        choices[2].setEnabled(false);
    439                        startFields[2].setEnabled(false);
    440                        startFields[2].setText("0");
    441                        endFields[2].setEnabled(false);
    442                        endFields[2].setText("0");
    443                    }
    444                }
    445                else {
    446                    endFields[2].setText(startFields[2].getText());
    447                }
    448            }
    449        }
    450
    451        for (int i = 0; i < n; i++) {
    452            currentIndex[i] = choices[i].getSelectionIndex();
    453        }
    454
    455        // reset show char button
    456        Datatype dtype = dataObject.getDatatype();
    457        if (dtype.isChar() || dtype.isInteger()) {
    458            int tsize = (int) dtype.getDatatypeSize();
    459
    460            if(charCheckbox != null) {
    461                charCheckbox.setEnabled((tsize == 1) && spreadsheetButton.getSelection());
    462            }
    463
    464            if(extractBitButton != null) {
    465                extractBitButton.setEnabled(tsize <= 8);
    466            }
    467
    468            if(applyBitmaskButton != null) {
    469                applyBitmaskButton.setEnabled(tsize <= 8);
    470            }
    471        }
    472        else {
    473            if(charCheckbox != null) {
    474                charCheckbox.setEnabled(false);
    475                charCheckbox.setSelection(false);
    476            }
    477
    478            if(extractBitButton != null) {
    479                extractBitButton.setEnabled(false);
    480            }
    481
    482            if(applyBitmaskButton != null) {
    483                applyBitmaskButton.setEnabled(false);
    484            }
    485        }
    486    }
    487
    488    private void setPalette() {
    489        if (!(dataObject instanceof ScalarDS)) {
    490            return;
    491        }
    492
    493        byte[][] pal = null;
    494        int palChoice = choicePalette.getSelectionIndex();
    495
    496        if (palChoice == 0) {
    497            return; /* using default palette */
    498        }
    499
    500        if (palChoice == numberOfPalettes + 1) {
    501            pal = Tools.createGrayPalette();
    502        }
    503        else if (palChoice == numberOfPalettes + 2) {
    504            pal = Tools.createReverseGrayPalette();
    505        }
    506        else if (palChoice == numberOfPalettes + 3) {
    507            pal = Tools.createGrayWavePalette();
    508        }
    509        else if (palChoice == numberOfPalettes + 4) {
    510            pal = Tools.createRainbowPalette();
    511        }
    512        else if (palChoice == numberOfPalettes + 5) {
    513            pal = Tools.createNaturePalette();
    514        }
    515        else if (palChoice == numberOfPalettes + 6) {
    516            pal = Tools.createWavePalette();
    517        }
    518        else if ((palChoice > 0) && (palChoice <= numberOfPalettes)) {
    519            // multiple palettes attached
    520            pal = ((ScalarDS) dataObject).readPalette(palChoice - 1);
    521        }
    522
    523        ((ScalarDS) dataObject).setPalette(pal);
    524    }
    525
    526    private boolean setSelection() {
    527        long[] n0 = { 0, 0, 0 }; // start
    528        long[] n1 = { 0, 0, 0 }; // end
    529        long[] n2 = { 1, 1, 1 }; // stride
    530        int[] sIndex = { 0, 1, 2 };
    531        boolean retVal = true;
    532
    533        int n = Math.min(3, rank);
    534        for (int i = 0; i < n; i++) {
    535            sIndex[i] = choices[i].getSelectionIndex();
    536
    537            try {
    538                n0[i] = Long.parseLong(startFields[i].getText());
    539                if (i < 2) {
    540                    n1[i] = Long.parseLong(endFields[i].getText());
    541                    n2[i] = Long.parseLong(strideFields[i].getText());
    542                }
    543            }
    544            catch (NumberFormatException ex) {
    545                shell.getDisplay().beep();
    546                Tools.showError(shell, "Set", ex.getMessage());
    547                return false;
    548            }
    549
    550            // silently correct errors
    551            if (n0[i] < 0) {
    552                n0[i] = 0; // start
    553            }
    554            if (n0[i] >= dims[sIndex[i]]) {
    555                n0[i] = dims[sIndex[i]] - 1;
    556            }
    557            if (n1[i] < 0) {
    558                n1[i] = 0; // end
    559            }
    560            if (n1[i] >= dims[sIndex[i]]) {
    561                n1[i] = dims[sIndex[i]] - 1;
    562            }
    563            if (n0[i] > n1[i]) {
    564                n1[i] = n0[i]; // end <= start
    565            }
    566            if (n2[i] > dims[sIndex[i]]) {
    567                n2[i] = dims[sIndex[i]];
    568            }
    569            if (n2[i] <= 0) {
    570                n2[i] = 1; // stride cannot be zero
    571            }
    572        } //  (int i=0; i<n; i++)
    573
    574        if (dataObject instanceof CompoundDS) {
    575            CompoundDS d = (CompoundDS) dataObject;
    576            int[] selectedFieldIndices = fieldList.getSelectionIndices();
    577            if ((selectedFieldIndices == null)
    578                    || (selectedFieldIndices.length < 1)) {
    579                shell.getDisplay().beep();
    580                Tools.showError(shell, "Set", "No member/field is selected.");
    581                return false;
    582            }
    583
    584            d.setAllMemberSelection(false); // deselect all members
    585            for (int i = 0; i < selectedFieldIndices.length; i++) {
    586                d.selectMember(selectedFieldIndices[i]);
    587            }
    588        }
    589        else {
    590            ScalarDS ds = (ScalarDS) dataObject;
    591
    592            if (!ds.getDatatype().isText()) {
    593                StringTokenizer st = new StringTokenizer(dataRangeField.getText(), ",");
    594                if (st.countTokens() == 2) {
    595                    double min = 0, max = 0;
    596                    try {
    597                        min = Double.valueOf(st.nextToken());
    598                        max = Double.valueOf(st.nextToken());
    599                    }
    600                    catch (Exception ex) {
    601                    }
    602                    if (max > min)
    603                        ds.setImageDataRange(min, max);
    604                }
    605                st = new StringTokenizer(fillValueField.getText(), ",");
    606                while (st.hasMoreTokens()) {
    607                    double x = 0;
    608                    try {
    609                        x = Double.valueOf(st.nextToken());
    610                        ds.addFilteredImageValue(x);
    611                    }
    612                    catch (Exception ex) {
    613                    }
    614                }
    615            }
    616        }
    617
    618        // reset selected size
    619        for (int i = 0; i < rank; i++) {
    620            selected[i] = 1;
    621            stride[i] = 1;
    622        }
    623
    624        // find no error, set selection the the dataset object
    625        for (int i = 0; i < n; i++) {
    626            long selectedSize = ((n1[i] - n0[i]) / n2[i]) + 1;
    627
    628            /*
    629             * Since Java does not allow array indices to be larger than int type, check the
    630             * given value to see if it is within the valid range of a Java int.
    631             */
    632            if (!Tools.checkValidJavaArrayIndex(selectedSize)) {
    633                shell.getDisplay().beep();
    634                Tools.showError(shell, "Set", "Subset selection too large to display.");
    635                return false;
    636            }
    637
    638            selectedIndex[i] = sIndex[i];
    639            start[selectedIndex[i]] = n0[i];
    640            selected[selectedIndex[i]] = (int) selectedSize;
    641            stride[selectedIndex[i]] = n2[i];
    642        }
    643
    644        if ((rank > 2) && isTrueColorImage && imageButton.getSelection()) {
    645            start[selectedIndex[2]] = 0;
    646            selected[selectedIndex[2]] = 3;
    647        }
    648
    649        // clear the old data
    650        dataObject.clearData();
    651
    652        setBitmask();
    653
    654        return retVal;
    655    }
    656
    657    private void setBitmask() {
    658        boolean isAll = true;
    659        boolean isNothing = true;
    660
    661        if (bitmaskButtons == null) {
    662            bitmask = null;
    663            return;
    664        }
    665
    666        if (!(applyBitmaskButton.getSelection() || extractBitButton.getSelection())) {
    667            bitmask = null;
    668            return;
    669        }
    670
    671        int len = bitmaskButtons.length;
    672        for (int i = 0; i < len; i++) {
    673            isAll = (isAll && bitmaskButtons[i].getSelection());
    674            isNothing = (isNothing && !bitmaskButtons[i].getSelection());
    675        }
    676
    677        if (isAll || isNothing) {
    678            bitmask = null;
    679            return;
    680        }
    681
    682        if (bitmask == null)
    683            bitmask = new BitSet(len);
    684
    685        for (int i = 0; i < len; i++) {
    686            /* Bitmask buttons are indexed from highest to lowest */
    687            bitmask.set(i, bitmaskButtons[len - i - 1].getSelection());
    688        }
    689    }
    690
    691    /** @return true if the display option is image. */
    692    public boolean isImageDisplay() {
    693        return isImageDisplay;
    694    }
    695
    696    /** @return true if the index starts with 0. */
    697    public boolean isIndexBase1() {
    698        return isIndexBase1;
    699    }
    700
    701    /**
    702     * @return the bitmask.
    703     */
    704    public BitSet getBitmask() {
    705        if (bitmask == null)
    706            return null;
    707
    708        // do not use bitmask if it is empty (all bits are zero)
    709        if (bitmask.isEmpty())
    710            return null;
    711
    712        boolean isAllSelected = true;
    713        int size = bitmask.size();
    714        for (int i = 0; i < size; i++)
    715            isAllSelected = (bitmask.get(i) && isAllSelected);
    716
    717        // do not use bitmask if it is full (all bits are one)
    718        if (isAllSelected)
    719            return null;
    720
    721        return bitmask;
    722    }
    723
    724    /** @return the name of the selected dataview */
    725    public String getDataViewName() {
    726        return dataViewName;
    727    }
    728
    729    /**
    730     *
    731     * @return true if display the data as characters; otherwise, display as numbers.
    732     */
    733    public boolean isDisplayTypeChar() {
    734        return isDisplayTypeChar;
    735    }
    736
    737    /**
    738     * @return if it only apply bitmask.
    739     */
    740    public boolean isApplyBitmaskOnly() {
    741        return isApplyBitmaskOnly;
    742    }
    743
    744    /**
    745     *
    746     * @return true if transpose the data in 2D table; otherwise, do not transpose the data.
    747     */
    748    public boolean isTransposed() {
    749        return isTransposed;
    750    }
    751
    752    /** @return true if the data selection is cancelled. */
    753    public boolean isCancelled() {
    754        return isSelectionCancelled;
    755    }
    756
    757    private void createScalarDSContents() {
    758        // Create display type region
    759        org.eclipse.swt.widgets.Group displayAsGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE);
    760        displayAsGroup.setFont(curFont);
    761        displayAsGroup.setText("Display As");
    762        displayAsGroup.setLayout(new GridLayout(1, true));
    763        displayAsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    764
    765        Composite spreadsheetComposite = new Composite(displayAsGroup, SWT.BORDER);
    766        spreadsheetComposite.setLayout(new GridLayout(2, false));
    767        spreadsheetComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    768
    769        spreadsheetButton = new Button(spreadsheetComposite, SWT.RADIO);
    770        spreadsheetButton.setFont(curFont);
    771        spreadsheetButton.setText("&Spreadsheet");
    772        spreadsheetButton.setSelection(true);
    773        spreadsheetButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    774        spreadsheetButton.addSelectionListener(new SelectionAdapter() {
    775            @Override
    776            public void widgetSelected(SelectionEvent e) {
    777                imageButton.setSelection(!spreadsheetButton.getSelection());
    778                choicePalette.setEnabled(false);
    779                choiceImageView.setEnabled(false);
    780                choiceTableView.setEnabled(true);
    781                dataRangeField.setEnabled(false);
    782                fillValueField.setEnabled(false);
    783                Datatype dtype = dataObject.getDatatype();
    784                charCheckbox.setEnabled((dtype.isChar() || dtype.isInteger()) &&
    785                        (dtype.getDatatypeSize() == 1));
    786            }
    787        });
    788
    789        charCheckbox = new Button(spreadsheetComposite, SWT.CHECK);
    790        charCheckbox.setFont(curFont);
    791        charCheckbox.setText("Show As &Char");
    792        charCheckbox.setSelection(false);
    793        charCheckbox.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false));
    794
    795        if (dataObject.getDatatype().isChar()
    796                || (dataObject.getDatatype().isInteger() && dataObject.getDatatype().getDatatypeSize() == 1)) {
    797            charCheckbox.setEnabled(false);
    798        }
    799
    800        Label label = new Label(spreadsheetComposite, SWT.RIGHT);
    801        label.setFont(curFont);
    802        label.setText("TableView: ");
    803
    804        choiceTableView = new Combo(spreadsheetComposite, SWT.SINGLE | SWT.DROP_DOWN | SWT.READ_ONLY);
    805        choiceTableView.setFont(curFont);
    806        choiceTableView.setItems(HDFView.getListOfTableViews().toArray(new String[0]));
    807        choiceTableView.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    808        choiceTableView.select(0);
    809
    810
    811        Composite imageComposite = new Composite(displayAsGroup, SWT.BORDER);
    812        imageComposite.setLayout(new GridLayout(4, false));
    813        imageComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    814
    815        imageButton = new Button(imageComposite, SWT.RADIO);
    816        imageButton.setFont(curFont);
    817        imageButton.setText("&Image");
    818        imageButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    819        imageButton.addSelectionListener(new SelectionAdapter() {
    820            @Override
    821            public void widgetSelected(SelectionEvent e) {
    822                spreadsheetButton.setSelection(!imageButton.getSelection());
    823                choicePalette.setEnabled(!isTrueColorImage);
    824                dataRangeField.setEnabled(true);
    825                fillValueField.setEnabled(true);
    826                choiceImageView.setEnabled(true);
    827                choiceTableView.setEnabled(false);
    828                charCheckbox.setSelection(false);
    829                charCheckbox.setEnabled(false);
    830            }
    831        });
    832
    833        choicePalette = new Combo(imageComposite, SWT.SINGLE | SWT.DROP_DOWN | SWT.READ_ONLY);
    834        choicePalette.setFont(curFont);
    835        choicePalette.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    836
    837        choicePalette.add("Select palette");
    838
    839        if (dataObject instanceof ScalarDS) {
    840            String paletteName = ((ScalarDS) dataObject).getPaletteName(0);
    841            if (paletteName == null) {
    842                paletteName = "Default";
    843            }
    844            choicePalette.add(paletteName);
    845            for (int i = 2; i <= numberOfPalettes; i++) {
    846                paletteName = ((ScalarDS) dataObject).getPaletteName(i - 1);
    847                choicePalette.add(paletteName);
    848            }
    849        }
    850        choicePalette.add("Gray");
    851        choicePalette.add("ReverseGray");
    852        choicePalette.add("GrayWave");
    853        choicePalette.add("Rainbow");
    854        choicePalette.add("Nature");
    855        choicePalette.add("Wave");
    856
    857        choicePalette.select(0);
    858
    859        label = new Label(imageComposite, SWT.RIGHT);
    860        label.setFont(curFont);
    861        label.setText("Valid Range: ");
    862
    863        dataRangeField = new Text(imageComposite, SWT.SINGLE | SWT.BORDER);
    864        dataRangeField.setFont(curFont);
    865        dataRangeField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    866
    867        String minmaxStr = "min, max";
    868
    869        double[] minmax = ((ScalarDS) dataObject).getImageDataRange();
    870        if (minmax != null) {
    871            if (dataObject.getDatatype().isFloat())
    872                minmaxStr = minmax[0] + "," + minmax[1];
    873            else
    874                minmaxStr = ((long) minmax[0]) + "," + ((long) minmax[1]);
    875        }
    876
    877        dataRangeField.setText(minmaxStr);
    878
    879        label = new Label(imageComposite, SWT.RIGHT);
    880        label.setFont(curFont);
    881        label.setText("ImageView: ");
    882
    883        choiceImageView = new Combo(imageComposite, SWT.SINGLE | SWT.DROP_DOWN | SWT.READ_ONLY);
    884        choiceImageView.setFont(curFont);
    885        choiceImageView.setItems(HDFView.getListOfImageViews().toArray(new String[0]));
    886        choiceImageView.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    887        choiceImageView.select(0);
    888
    889        label = new Label(imageComposite, SWT.RIGHT);
    890        label.setFont(curFont);
    891        label.setText("Invalid Values: ");
    892
    893        fillValueField = new Text(imageComposite, SWT.SINGLE | SWT.BORDER);
    894        fillValueField.setFont(curFont);
    895        fillValueField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    896
    897        String fillStr = "val1, val2, ...";
    898
    899        java.util.List<Number> fillValue = ((ScalarDS) dataObject).getFilteredImageValues();
    900        int n = fillValue.size();
    901        if (n > 0) {
    902            fillStr = fillValue.get(0).toString();
    903            for (int i = 1; i < n; i++) {
    904                fillStr += ", " + fillValue.get(i);
    905            }
    906        }
    907
    908        fillValueField.setText(fillStr);
    909
    910        // Create Index Base region
    911        org.eclipse.swt.widgets.Group indexBaseGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE);
    912        indexBaseGroup.setFont(curFont);
    913        indexBaseGroup.setText("Index Base");
    914        indexBaseGroup.setLayout(new GridLayout(2, true));
    915        indexBaseGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    916
    917        base0Button = new Button(indexBaseGroup, SWT.RADIO);
    918        base0Button.setFont(curFont);
    919        base0Button.setText("0-based");
    920        base0Button.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
    921
    922        base1Button = new Button(indexBaseGroup, SWT.RADIO);
    923        base1Button.setFont(curFont);
    924        base1Button.setText("1-based");
    925        base1Button.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
    926
    927        if(ViewProperties.isIndexBase1()) {
    928            base0Button.setSelection(false);
    929            base1Button.setSelection(true);
    930        }
    931        else {
    932            base0Button.setSelection(true);
    933            base1Button.setSelection(false);
    934        }
    935
    936
    937        // Create Bitmask region
    938        org.eclipse.swt.widgets.Group bitmaskGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE);
    939        bitmaskGroup.setFont(curFont);
    940        bitmaskGroup.setText("Bitmask");
    941        bitmaskGroup.setLayout(new GridLayout(2, false));
    942        bitmaskGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    943
    944        extractBitButton = new Button(bitmaskGroup, SWT.CHECK);
    945        extractBitButton.setFont(curFont);
    946        extractBitButton.setText("Show &Value of Selected Bits");
    947        extractBitButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
    948        extractBitButton.setSelection(false);
    949        extractBitButton.addSelectionListener(new SelectionAdapter() {
    950            @Override
    951            public void widgetSelected(SelectionEvent e) {
    952                boolean selected = extractBitButton.getSelection();
    953
    954                if(selected) {
    955                    if(applyBitmaskButton.getSelection()) {
    956                        applyBitmaskButton.setSelection(false);
    957                    }
    958
    959                    if(!bitmaskButtons[0].getEnabled()) {
    960                        for(int i = 0; i < bitmaskButtons.length; i++) {
    961                            bitmaskButtons[i].setEnabled(true);
    962                        }
    963                    }
    964
    965                    int n = 0;
    966
    967                    if(bitmaskButtons[0].getSelection()) n = 1;
    968
    969                    for(int i = 1; i < bitmaskButtons.length; i++) {
    970                        if(bitmaskButtons[i].getSelection() && !bitmaskButtons[i - 1].getSelection()) {
    971                            n++;
    972                        }
    973                    }
    974
    975                    if(n > 1) {
    976                        extractBitButton.setSelection(false);
    977                        applyBitmaskButton.setSelection(true);
    978
    979                        Tools.showError(shell, "Select",
    980                                "Selecting non-adjacent bits is only allowed \nfor the \"Apply Bitmask\" option.");
    981                        return;
    982                    }
    983                }
    984                else {
    985                    for(int i = 0; i < bitmaskButtons.length; i++) {
    986                        bitmaskButtons[i].setEnabled(false);
    987                    }
    988                }
    989            }
    990        });
    991
    992        bitmaskHelp = new Button(bitmaskGroup, SWT.PUSH);
    993        bitmaskHelp.setImage(ViewProperties.getHelpIcon());
    994        bitmaskHelp.setToolTipText("Help on how to set bitmask");
    995        bitmaskHelp.setLayoutData(new GridData(SWT.END, SWT.FILL, false, false));
    996        bitmaskHelp.setEnabled(false);
    997        bitmaskHelp.addSelectionListener(new SelectionAdapter() {
    998            @Override
    999            public void widgetSelected(SelectionEvent e) {
    1000                String msg = ""
    1001                        + "\"Apply Bitmask\" applies bitwise \"AND\" to the original data.\n"
    1002                        + "For example, bits 2, 3, and 4 are selected for the bitmask\n"
    1003                        + "         10010101 (data)\n"
    1004                        + "AND 00011100 (mask)  \n"
    1005                        + "  =     00010100 (result) ==> the decimal value is 20. \n"
    1006                        + "\n"
    1007                        + "\"Extract Bit(s)\" removes all the bits from the result above where\n"
    1008                        + "their corresponding bits in the bitmask are 0. \nFor the same example above, "
    1009                        + "the result is \n101 ==> the decimal value is 5.\n\n";
    1010
    1011                Tools.showInformation(shell, "Help", msg);
    1012            }
    1013        });
    1014
    1015        applyBitmaskButton = new Button(bitmaskGroup, SWT.CHECK);
    1016        applyBitmaskButton.setFont(curFont);
    1017        applyBitmaskButton.setText("&Apply Bitmask");
    1018        applyBitmaskButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
    1019        applyBitmaskButton.setSelection(false);
    1020        applyBitmaskButton.addSelectionListener(new SelectionAdapter() {
    1021            @Override
    1022            public void widgetSelected(SelectionEvent e) {
    1023                if(extractBitButton.getSelection()) {
    1024                    extractBitButton.setSelection(false);
    1025                }
    1026                else if (!applyBitmaskButton.getSelection()) {
    1027                    for(int i = 0; i < bitmaskButtons.length; i++) {
    1028                        bitmaskButtons[i].setEnabled(false);
    1029                    }
    1030                }
    1031                else {
    1032                    if(!bitmaskButtons[0].getEnabled()) {
    1033                        for(int i = 0; i < bitmaskButtons.length; i++) {
    1034                            bitmaskButtons[i].setEnabled(true);
    1035                        }
    1036                    }
    1037                }
    1038            }
    1039        });
    1040
    1041        new Label(bitmaskGroup, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1042
    1043        Composite buttonComposite = new Composite(bitmaskGroup, SWT.NO_RADIO_GROUP);
    1044        buttonComposite.setLayout(new GridLayout(16, true));
    1045        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
    1046
    1047        int tsize;
    1048
    1049        if (dataObject.getDatatype().isArray()) {
    1050            Datatype baseType = dataObject.getDatatype().getDatatypeBase();
    1051
    1052            while (baseType.isArray()) {
    1053                baseType = baseType.getDatatypeBase();
    1054            }
    1055
    1056            tsize = (int) baseType.getDatatypeSize();
    1057        }
    1058        else {
    1059            tsize = (int) dataObject.getDatatype().getDatatypeSize();
    1060        }
    1061
    1062        bitmaskButtons = (tsize >= 0 && !dataObject.getDatatype().isText()) ? new Button[8 * tsize] : new Button[0];
    1063
    1064        for (int i = 0; i < bitmaskButtons.length; i++) {
    1065            bitmaskButtons[i] = new Button(buttonComposite, SWT.RADIO);
    1066            bitmaskButtons[i].setFont(curFont);
    1067            bitmaskButtons[i].setText(String.valueOf(bitmaskButtons.length - i - 1));
    1068            bitmaskButtons[i].setEnabled(false);
    1069            bitmaskButtons[i].addSelectionListener(
    1070                new SelectionAdapter() {
    1071                    @Override
    1072                    public void widgetSelected(SelectionEvent e) {
    1073                        if(extractBitButton.getSelection()) {
    1074                            Button source = (Button) e.widget;
    1075
    1076                            // Don't allow non-adjacent selection of bits when extracting bits
    1077                            int n = 0;
    1078
    1079                            if(bitmaskButtons[0].getSelection()) n = 1;
    1080
    1081                            for(int i = 1; i < bitmaskButtons.length; i++) {
    1082                                if(bitmaskButtons[i].getSelection() && !bitmaskButtons[i - 1].getSelection()) {
    1083                                    n++;
    1084                                }
    1085                            }
    1086
    1087                            if(n > 1) {
    1088                                Tools.showError(shell, "Select",
    1089                                        "Please select contiguous bits \nwhen the \"Show Value of Selected Bits\" option is checked.");
    1090
    1091                                source.setSelection(false);
    1092                                return;
    1093                            }
    1094                        }
    1095                    }
    1096                }
    1097            );
    1098        }
    1099
    1100        if (dataObject.getDatatype().isChar() || (dataObject.getDatatype().isInteger() && tsize <= 8)) {
    1101            extractBitButton.setEnabled(true);
    1102            applyBitmaskButton.setEnabled(true);
    1103            bitmaskHelp.setEnabled(true);
    1104        }
    1105
    1106
    1107        // Create Dimension/Subset selection region
    1108        org.eclipse.swt.widgets.Group dimSubGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE);
    1109        dimSubGroup.setFont(curFont);
    1110        dimSubGroup.setText("Dimension and Subset Selection");
    1111        dimSubGroup.setLayout(new GridLayout(2, false));
    1112        dimSubGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    1113
    1114        int h = 1, w = 1;
    1115        h = (int) dims[selectedIndex[0]];
    1116        if (rank > 1) {
    1117            w = (int) dims[selectedIndex[1]];
    1118        }
    1119
    1120        if (rank > 1) {
    1121            navigator = new PreviewNavigator(dimSubGroup, SWT.DOUBLE_BUFFERED | SWT.BORDER, w, h);
    1122        }
    1123        else {
    1124            dimSubGroup.setLayout(new GridLayout(1, true));
    1125        }
    1126
    1127        createDimSubSelectionComposite(dimSubGroup);
    1128    }
    1129
    1130    private void createCompoundDSContents() {
    1131        Composite content = new Composite(shell, SWT.NONE);
    1132        content.setLayout(new GridLayout(2, false));
    1133        content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    1134
    1135        org.eclipse.swt.widgets.Group membersGroup = new org.eclipse.swt.widgets.Group(content, SWT.NONE);
    1136        membersGroup.setFont(curFont);
    1137        membersGroup.setText("Select Members");
    1138        membersGroup.setLayout(new GridLayout(1, true));
    1139        membersGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
    1140
    1141        final String[] names = ((CompoundDS) dataObject).getMemberNames();
    1142        String[] columnNames = new String[names.length];
    1143        for (int i = 0; i < names.length; i++) {
    1144            columnNames[i] = new String(names[i]);
    1145            columnNames[i] = columnNames[i].replaceAll(CompoundDS.SEPARATOR, "->");
    1146        }
    1147        fieldList = new List(membersGroup, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
    1148        fieldList.setFont(curFont);
    1149        fieldList.setItems(columnNames);
    1150        fieldList.selectAll();
    1151
    1152        GridData data = new GridData(SWT.FILL, SWT.FILL, false, true);
    1153        data.heightHint = fieldList.getItemHeight() * 10;
    1154        data.widthHint = fieldList.computeSize(SWT.DEFAULT, SWT.DEFAULT).x + 10;
    1155        fieldList.setLayoutData(data);
    1156
    1157        org.eclipse.swt.widgets.Group dimSubGroup = new org.eclipse.swt.widgets.Group(content, SWT.NONE);
    1158        dimSubGroup.setFont(curFont);
    1159        dimSubGroup.setText("Dimension and Subset Selection");
    1160        dimSubGroup.setLayout(new GridLayout());
    1161        dimSubGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    1162
    1163        createDimSubSelectionComposite(dimSubGroup);
    1164
    1165        Composite tableViewComposite = new Composite(dimSubGroup, SWT.BORDER);
    1166        tableViewComposite.setLayout(new GridLayout(2, false));
    1167        tableViewComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1168
    1169        Label label = new Label(tableViewComposite, SWT.RIGHT);
    1170        label.setFont(curFont);
    1171        label.setText("TableView: ");
    1172
    1173        choiceTableView = new Combo(tableViewComposite, SWT.SINGLE | SWT.DROP_DOWN | SWT.READ_ONLY);
    1174        choiceTableView.setFont(curFont);
    1175        choiceTableView.setItems(HDFView.getListOfTableViews().toArray(new String[0]));
    1176        choiceTableView.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1177        choiceTableView.select(0);
    1178    }
    1179
    1180    private void createDimSubSelectionComposite(Composite parent) {
    1181        String[] dimNames = ((Dataset) dataObject).getDimNames();
    1182
    1183        Composite selectionComposite = new Composite(parent, SWT.BORDER);
    1184        selectionComposite.setLayout(new GridLayout(6, true));
    1185        selectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    1186
    1187        new Label(selectionComposite, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    1188
    1189        if (rank > 1) {
    1190            transposeChoice = new Combo(selectionComposite, SWT.SINGLE | SWT.READ_ONLY);
    1191            transposeChoice.setFont(curFont);
    1192            transposeChoice.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
    1193
    1194            transposeChoice.add("Transpose");
    1195            transposeChoice.add("Reshape");
    1196
    1197            transposeChoice.select(0);
    1198        }
    1199        else {
    1200            new Label(selectionComposite, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    1201        }
    1202
    1203        Label label = new Label(selectionComposite, SWT.RIGHT);
    1204        label.setFont(curFont);
    1205        label.setText("Start: ");
    1206        label.setLayoutData(new GridData(SWT.CENTER, SWT.END, true, true));
    1207
    1208        label = new Label(selectionComposite, SWT.RIGHT);
    1209        label.setFont(curFont);
    1210        label.setText("End: ");
    1211        label.setLayoutData(new GridData(SWT.CENTER, SWT.END, true, true));
    1212
    1213        label = new Label(selectionComposite, SWT.RIGHT);
    1214        label.setFont(curFont);
    1215        label.setText("Stride: ");
    1216        label.setLayoutData(new GridData(SWT.CENTER, SWT.END, true, true));
    1217
    1218        label = new Label(selectionComposite, SWT.RIGHT);
    1219        label.setFont(curFont);
    1220        label.setText("Max Size");
    1221        label.setLayoutData(new GridData(SWT.CENTER, SWT.END, true, true));
    1222
    1223
    1224        // Create Height selection row
    1225        label = new Label(selectionComposite, SWT.RIGHT);
    1226        label.setFont(curFont);
    1227        label.setText("Height: ");
    1228        label.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, true));
    1229
    1230        choices[0] = new Combo(selectionComposite, SWT.SINGLE | SWT.READ_ONLY);
    1231        choices[0].setFont(curFont);
    1232        choices[0].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1233        choices[0].addSelectionListener(new SelectionAdapter() {
    1234            @Override
    1235            public void widgetSelected(SelectionEvent e) {
    1236                Combo source = (Combo) e.widget;
    1237
    1238                processComboBoxEvent(source);
    1239            }
    1240        });
    1241
    1242        for (int j = 0; j < rank; j++) {
    1243            if (dimNames == null) {
    1244                choices[0].add("dim " + j);
    1245            }
    1246            else {
    1247                choices[0].add(dimNames[j]);
    1248            }
    1249        }
    1250
    1251        choices[0].select(0);
    1252
    1253        startFields[0] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1254        startFields[0].setFont(curFont);
    1255        startFields[0].setText("0");
    1256        startFields[0].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1257
    1258        endFields[0] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1259        endFields[0].setFont(curFont);
    1260        endFields[0].setText("0");
    1261        endFields[0].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1262
    1263        strideFields[0] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1264        strideFields[0].setFont(curFont);
    1265        strideFields[0].setText("1");
    1266        strideFields[0].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1267
    1268        maxLabels[0] = new Label(selectionComposite, SWT.NONE);
    1269        maxLabels[0].setFont(curFont);
    1270        maxLabels[0].setText("1");
    1271        maxLabels[0].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1272
    1273
    1274        // Create Width selection row
    1275        label = new Label(selectionComposite, SWT.RIGHT);
    1276        label.setFont(curFont);
    1277        label.setText("Width: ");
    1278        label.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, true));
    1279
    1280        choices[1] = new Combo(selectionComposite, SWT.SINGLE | SWT.READ_ONLY);
    1281        choices[1].setFont(curFont);
    1282        choices[1].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1283        choices[1].addSelectionListener(new SelectionAdapter() {
    1284            @Override
    1285            public void widgetSelected(SelectionEvent e) {
    1286                Combo source = (Combo) e.widget;
    1287
    1288                processComboBoxEvent(source);
    1289            }
    1290        });
    1291
    1292        for (int j = 0; j < rank; j++) {
    1293            if (dimNames == null) {
    1294                choices[1].add("dim " + j);
    1295            }
    1296            else {
    1297                choices[1].add(dimNames[j]);
    1298            }
    1299        }
    1300
    1301        choices[1].select(0);
    1302
    1303        startFields[1] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1304        startFields[1].setFont(curFont);
    1305        startFields[1].setText("0");
    1306        startFields[1].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1307
    1308        endFields[1] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1309        endFields[1].setFont(curFont);
    1310        endFields[1].setText("0");
    1311        endFields[1].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1312
    1313        strideFields[1] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1314        strideFields[1].setFont(curFont);
    1315        strideFields[1].setText("1");
    1316        strideFields[1].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1317
    1318        maxLabels[1] = new Label(selectionComposite, SWT.NONE);
    1319        maxLabels[1].setFont(curFont);
    1320        maxLabels[1].setText("1");
    1321        maxLabels[1].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1322
    1323
    1324        // Create Depth selection row
    1325        label = new Label(selectionComposite, SWT.RIGHT);
    1326        label.setFont(curFont);
    1327        label.setText("Depth: ");
    1328        label.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, true));
    1329
    1330        choices[2] = new Combo(selectionComposite, SWT.SINGLE | SWT.READ_ONLY);
    1331        choices[2].setFont(curFont);
    1332        choices[2].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1333        choices[2].addSelectionListener(new SelectionAdapter() {
    1334            @Override
    1335            public void widgetSelected(SelectionEvent e) {
    1336                Combo source = (Combo) e.widget;
    1337
    1338                processComboBoxEvent(source);
    1339            }
    1340        });
    1341
    1342        for (int j = 0; j < rank; j++) {
    1343            if (dimNames == null) {
    1344                choices[2].add("dim " + j);
    1345            }
    1346            else {
    1347                choices[2].add(dimNames[j]);
    1348            }
    1349        }
    1350
    1351        choices[2].select(0);
    1352
    1353        startFields[2] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1354        startFields[2].setFont(curFont);
    1355        startFields[2].setText("0");
    1356        startFields[2].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1357
    1358        endFields[2] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1359        endFields[2].setFont(curFont);
    1360        endFields[2].setText("0");
    1361        endFields[2].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1362
    1363        strideFields[2] = new Text(selectionComposite, SWT.SINGLE | SWT.BORDER);
    1364        strideFields[2].setFont(curFont);
    1365        strideFields[2].setText("1");
    1366        strideFields[2].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1367
    1368        maxLabels[2] = new Label(selectionComposite, SWT.NONE);
    1369        maxLabels[2].setFont(curFont);
    1370        maxLabels[2].setText("1");
    1371        maxLabels[2].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    1372
    1373
    1374        // Create row for Dims and reset button
    1375        new Label(selectionComposite, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1376
    1377        Button dimsButton = new Button(selectionComposite, SWT.PUSH);
    1378        dimsButton.setFont(curFont);
    1379        dimsButton.setText("Dims...");
    1380        dimsButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1381        dimsButton.setEnabled((rank > 3));
    1382        dimsButton.addSelectionListener(new SelectionAdapter() {
    1383            @Override
    1384            public void widgetSelected(SelectionEvent e) {
    1385                if (rank < 4) {
    1386                    return;
    1387                }
    1388
    1389                int idx = 0;
    1390                Vector<Object> choice4 = new Vector<>(rank);
    1391                int[] choice4Index = new int[rank - 3];
    1392                for (int i = 0; i < rank; i++) {
    1393                    if ((i != currentIndex[0]) && (i != currentIndex[1])
    1394                            && (i != currentIndex[2])) {
    1395                        choice4.add(choices[0].getItem(i));
    1396                        choice4Index[idx++] = i;
    1397                    }
    1398                }
    1399
    1400                String msg = "Select slice location for dimension(s):\n\""
    1401                        + choice4.get(0) + " [0 .. " + (dims[choice4Index[0]] - 1)
    1402                        + "]\"";
    1403                String initValue = String.valueOf(start[choice4Index[0]]);
    1404                int n = choice4.size();
    1405                for (int i = 1; i < n; i++) {
    1406                    msg += " x \"" + choice4.get(i) + " [0 .. "
    1407                            + (dims[choice4Index[i]] - 1) + "]\"";
    1408                    initValue += " x " + String.valueOf(start[choice4Index[i]]);
    1409                }
    1410
    1411                String result = new InputDialog(shell, shell.getText(), msg, initValue).open();
    1412                if ((result == null) || ((result = result.trim()) == null)
    1413                        || (result.length() < 1)) {
    1414                    return;
    1415                }
    1416
    1417                StringTokenizer st = new StringTokenizer(result, "x");
    1418                if (st.countTokens() < n) {
    1419                    Tools.showError(shell, "Select", "Number of dimension(s) is less than " + n + "\n" + result);
    1420                    return;
    1421                }
    1422
    1423                long[] start4 = new long[n];
    1424                for (int i = 0; i < n; i++) {
    1425                    try {
    1426                        start4[i] = Long.parseLong(st.nextToken().trim());
    1427                    }
    1428                    catch (Exception ex) {
    1429                        Tools.showError(shell, "Select", ex.getMessage());
    1430                        return;
    1431                    }
    1432
    1433                    if ((start4[i] < 0) || (start4[i] >= dims[choice4Index[i]])) {
    1434                        Tools.showError(shell, "Select",
    1435                                "Slice location is out of range.\n" + start4[i] + " >= " + dims[choice4Index[i]]);
    1436
    1437                        return;
    1438                    }
    1439
    1440                }
    1441
    1442                for (int i = 0; i < n; i++) {
    1443                    start[choice4Index[i]] = start4[i];
    1444                }
    1445            }
    1446        });
    1447
    1448        new Label(selectionComposite, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1449
    1450        new Label(selectionComposite, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1451
    1452        Button resetButton = new Button(selectionComposite, SWT.PUSH);
    1453        resetButton.setFont(curFont);
    1454        resetButton.setText("Reset");
    1455        resetButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1456        resetButton.addSelectionListener(new SelectionAdapter() {
    1457            @Override
    1458            public void widgetSelected(SelectionEvent e) {
    1459                int n = startFields.length;
    1460
    1461                for (int i = 0; i < n; i++) {
    1462                    startFields[i].setText("0");
    1463                    strideFields[i].setText("1");
    1464                    long l = Long.valueOf(maxLabels[i].getText()) - 1;
    1465                    endFields[i].setText(String.valueOf(l));
    1466                }
    1467            }
    1468        });
    1469
    1470        new Label(selectionComposite, SWT.RIGHT).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    1471
    1472
    1473        for (int i = 0; i < 3; i++) {
    1474            // Disable the selection components
    1475            // init() will set them appropriately
    1476            choices[i].setEnabled(false);
    1477            startFields[i].setEnabled(false);
    1478            endFields[i].setEnabled(false);
    1479            strideFields[i].setEnabled(false);
    1480            maxLabels[i].setEnabled(false);
    1481        }
    1482    }
    1483
    1484    private void processComboBoxEvent(Combo source) {
    1485        int theSelectedChoice = -1;
    1486
    1487        int n = Math.min(3, rank);
    1488        for (int i = 0; i < n; i++) {
    1489            if (source.equals(choices[i])) {
    1490                theSelectedChoice = i;
    1491            }
    1492        }
    1493
    1494        if (theSelectedChoice < 0) {
    1495            return; // the selected ComboBox is not a dimension choice
    1496        }
    1497
    1498        int theIndex = source.getSelectionIndex();
    1499        if (theIndex == currentIndex[theSelectedChoice]) {
    1500            return; // select the same item, no change
    1501        }
    1502
    1503        start[currentIndex[theSelectedChoice]] = 0;
    1504
    1505        // reset the selected dimension choice
    1506        startFields[theSelectedChoice].setText("0");
    1507        endFields[theSelectedChoice].setText(String
    1508                .valueOf(dims[theIndex] - 1));
    1509        strideFields[theSelectedChoice].setText("1");
    1510        maxLabels[theSelectedChoice]
    1511                .setText(String.valueOf(dims[theIndex]));
    1512
    1513        // if the selected choice selects the dimension that is selected by
    1514        // other dimension choice, exchange the dimensions
    1515        for (int i = 0; i < n; i++) {
    1516            if (i == theSelectedChoice) {
    1517                continue; // don't exchange itself
    1518            }
    1519            else if (theIndex == choices[i].getSelectionIndex()) {
    1520                choices[i].select(currentIndex[theSelectedChoice]);
    1521                startFields[i].setText("0");
    1522                endFields[i]
    1523                        .setText(String
    1524                                .valueOf(dims[currentIndex[theSelectedChoice]] - 1));
    1525                strideFields[i].setText("1");
    1526                maxLabels[i].setText(String
    1527                        .valueOf(dims[currentIndex[theSelectedChoice]]));
    1528            }
    1529        }
    1530
    1531        for (int i = 0; i < n; i++) {
    1532            currentIndex[i] = choices[i].getSelectionIndex();
    1533        }
    1534
    1535        // update the navigator
    1536        if (rank > 1) {
    1537            int hIdx = choices[0].getSelectionIndex();
    1538            int wIdx = choices[1].getSelectionIndex();
    1539            transposeChoice.select(0);
    1540
    1541            // Use transpose option only if the dims are not in original
    1542            // order
    1543            if (hIdx < wIdx)
    1544                transposeChoice.setEnabled(false);
    1545            else
    1546                transposeChoice.setEnabled(true);
    1547
    1548            long dims[] = dataObject.getDims();
    1549            int w = (int) dims[wIdx];
    1550            int h = (int) dims[hIdx];
    1551
    1552            if (navigator != null) {
    1553                navigator.setDimensionSize(w, h);
    1554                navigator.redraw();
    1555            }
    1556        }
    1557
    1558        if (rank > 2) {
    1559            endFields[2].setText(startFields[2].getText());
    1560        }
    1561    }
    1562
    1563    /** PreviewNavigator draws a selection rectangle for selecting a subset
    1564     *  of the data to be displayed. */
    1565    private class PreviewNavigator extends Canvas {
    1566        private final int         NAVIGATOR_SIZE   = 150;
    1567        private int               dimX, dimY, x, y;
    1568        private double            r;
    1569        private Point             startPosition; // mouse clicked position
    1570        private Rectangle         selectedArea;
    1571        private Image             previewImage     = null;
    1572        private String            selStr;
    1573
    1574        private PreviewNavigator(Composite parent, int style, int w, int h) {
    1575            super(parent, style);
    1576
    1577            GridData data = new GridData(SWT.FILL, SWT.FILL, false, true);
    1578            data.widthHint = NAVIGATOR_SIZE;
    1579            data.heightHint = NAVIGATOR_SIZE;
    1580            this.setLayoutData(data);
    1581
    1582            dimX = w;
    1583            dimY = h;
    1584            if (dimX > dimY) {
    1585                x = NAVIGATOR_SIZE;
    1586                r = dimX / (double) x;
    1587                y = (int) (dimY / r);
    1588            }
    1589            else {
    1590                y = NAVIGATOR_SIZE;
    1591                r = dimY / (double) y;
    1592                x = (int) (dimX / r);
    1593            }
    1594
    1595            selectedArea = new Rectangle();
    1596
    1597            selStr = "";
    1598
    1599            try {
    1600                previewImage = createPreviewImage();
    1601
    1602                String origStr = ViewProperties.getImageOrigin();
    1603                if (ViewProperties.ORIGIN_LL.equalsIgnoreCase(origStr))
    1604                    flip(DefaultImageView.FLIP_VERTICAL);
    1605                else if (ViewProperties.ORIGIN_UR.equalsIgnoreCase(origStr))
    1606                    flip(DefaultImageView.FLIP_HORIZONTAL);
    1607                else if (ViewProperties.ORIGIN_LR.equalsIgnoreCase(origStr)) {
    1608                    rotate(DefaultImageView.ROTATE_CW_90);
    1609                    rotate(DefaultImageView.ROTATE_CW_90);
    1610                }
    1611            }
    1612            catch (Exception ex) {
    1613                ex.printStackTrace();
    1614            }
    1615
    1616            this.addMouseListener(new MouseListener() {
    1617                @Override
    1618                public void mouseDoubleClick(MouseEvent e) {
    1619
    1620                }
    1621
    1622                @Override
    1623                public void mouseDown(MouseEvent e) {
    1624                    startPosition = new Point(e.x, e.y);
    1625                    selectedArea.setBounds(startPosition.x, startPosition.y, 0, 0);
    1626                }
    1627
    1628                @Override
    1629                public void mouseUp(MouseEvent e) {
    1630                    if(startPosition.x == e.x && startPosition.y == e.y) {
    1631                        selectedArea.setBounds(startPosition.x, startPosition.y, 0, 0);
    1632                        redraw();
    1633                    }
    1634                }
    1635            });
    1636
    1637            this.addMouseMoveListener(new MouseMoveListener() {
    1638                @Override
    1639                public void mouseMove(MouseEvent e) {
    1640                    if(e.stateMask == SWT.BUTTON1 || e.stateMask == SWT.BUTTON3) {
    1641                        Point p0 = startPosition;
    1642                        Point p1 = new Point(e.x, e.y);
    1643
    1644                        int x0 = Math.max(0, Math.min(p0.x, p1.x));
    1645                        int y0 = Math.max(0, Math.min(p0.y, p1.y));
    1646                        int x1 = Math.min(x, Math.max(p0.x, p1.x));
    1647                        int y1 = Math.min(y, Math.max(p0.y, p1.y));
    1648
    1649                        int w = x1 - x0;
    1650                        int h = y1 - y0;
    1651
    1652                        selectedArea.setBounds(x0, y0, w, h);
    1653
    1654                        try {
    1655                            updateSelection(x0, y0, w, h);
    1656                        }
    1657                        catch (Exception ex) {
    1658                        }
    1659
    1660                        redraw();
    1661                    }
    1662                }
    1663            });
    1664
    1665            this.addPaintListener(new PaintListener() {
    1666                @Override
    1667                public void paintControl(PaintEvent e) {
    1668                    GC gc = e.gc;
    1669
    1670                    gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE));
    1671
    1672                    if (previewImage != null) {
    1673                        gc.drawImage(convertBufferedImageToSWTImage((BufferedImage) previewImage), 0, 0);
    1674                    }
    1675                    else {
    1676                        gc.fillRectangle(0, 0, x, y);
    1677                    }
    1678
    1679                    int w = selectedArea.width;
    1680                    int h = selectedArea.height;
    1681                    if ((w > 0) && (h > 0)) {
    1682                        gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
    1683                        gc.drawRectangle(selectedArea.x, selectedArea.y, w, h);
    1684                    }
    1685
    1686                    org.eclipse.swt.graphics.Rectangle bounds = ((Canvas) e.widget).getBounds();
    1687                    Point textSize = gc.stringExtent(selStr);
    1688                    gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
    1689                    gc.drawString(selStr, (bounds.width / 2) - (textSize.x / 2), bounds.height - textSize.y - 4);
    1690                }
    1691            });
    1692        }
    1693
    1694        private Image createPreviewImage ( ) throws Exception {
    1695            if ((rank <= 1) || !(dataObject instanceof ScalarDS)) {
    1696                return null;
    1697            }
    1698
    1699            Image preImage = null;
    1700            ScalarDS sd = (ScalarDS) dataObject;
    1701
    1702            if (sd.getDatatype().isText()) {
    1703                return null;
    1704            }
    1705
    1706            // backup the selection
    1707            long[] strideBackup = new long[rank];
    1708            long[] selectedBackup = new long[rank];
    1709            long[] startBackup = new long[rank];
    1710            int[] selectedIndexBackup = new int[3];
    1711            System.arraycopy(stride, 0, strideBackup, 0, rank);
    1712            System.arraycopy(selected, 0, selectedBackup, 0, rank);
    1713            System.arraycopy(start, 0, startBackup, 0, rank);
    1714            System.arraycopy(selectedIndex, 0, selectedIndexBackup, 0, 3);
    1715
    1716            // set the selection for preview
    1717            for (int i = 0; i < rank; i++) {
    1718                start[i] = 0;
    1719                stride[i] = 1;
    1720                selected[i] = 1;
    1721            }
    1722
    1723            if (choices != null) {
    1724                try {
    1725                    selectedIndex[0] = choices[0].getSelectionIndex();
    1726                    selectedIndex[1] = choices[1].getSelectionIndex();
    1727                } catch (Exception ex) {
    1728                }
    1729            }
    1730            long steps = (long) Math.ceil(r);
    1731            selected[selectedIndex[0]] = (dims[selectedIndex[0]] / steps);
    1732            selected[selectedIndex[1]] = (dims[selectedIndex[1]] / steps);
    1733            stride[selectedIndex[0]] = stride[selectedIndex[1]] = steps;
    1734
    1735            if (selected[selectedIndex[0]] == 0) {
    1736                selected[selectedIndex[0]] = 1;
    1737            }
    1738            if (selected[selectedIndex[1]] == 0) {
    1739                selected[selectedIndex[1]] = 1;
    1740            }
    1741
    1742            if (isTrueColorImage && (start.length > 2)) {
    1743                start[selectedIndex[2]] = 0;
    1744                selected[selectedIndex[2]] = 3;
    1745                stride[selectedIndex[2]] = 1;
    1746            }
    1747
    1748            // update the ratio of preview image size to the real dataset
    1749            y = (int) selected[selectedIndex[0]];
    1750            x = (int) selected[selectedIndex[1]];
    1751            r = Math.min((double) dims[selectedIndex[0]]
    1752                    / (double) selected[selectedIndex[0]],
    1753                    (double) dims[selectedIndex[1]]
    1754                            / (double) selected[selectedIndex[1]]);
    1755
    1756            try {
    1757                Object data = sd.read();
    1758                int h = (int)sd.getHeight();
    1759                int w = (int)sd.getWidth();
    1760
    1761                byte[] bData = Tools.getBytes(data, sd.getImageDataRange(), w, h, false, sd.getFilteredImageValues(), null);
    1762
    1763                if (isTrueColorImage) {
    1764                    boolean isPlaneInterlace = (sd.getInterlace() == ScalarDS.INTERLACE_PLANE);
    1765                    preImage = Tools.createTrueColorImage(bData,
    1766                            isPlaneInterlace, w, h);
    1767                }
    1768                else {
    1769                    byte[][] imagePalette = sd.getPalette();
    1770                    if (imagePalette == null) {
    1771                        imagePalette = Tools.createGrayPalette();
    1772                    }
    1773
    1774                    if ((isH5 || (rank > 2))
    1775                            && (selectedIndex[0] > selectedIndex[1])) {
    1776                        // transpose data
    1777                        int n = bData.length;
    1778                        byte[] bData2 = new byte[n];
    1779                        for (int i = 0; i < h; i++) {
    1780                            for (int j = 0; j < w; j++) {
    1781                                bData[i * w + j] = bData2[j * h + i];
    1782                            }
    1783                        }
    1784                    }
    1785                    if (!isH5 && !sd.isDefaultImageOrder() && (selectedIndex[1] > selectedIndex[0])) {
    1786                        // transpose data for hdf4 images where selectedIndex[1]
    1787                        // > selectedIndex[0]
    1788                        int n = bData.length;
    1789                        byte[] bData2 = new byte[n];
    1790                        for (int i = 0; i < h; i++) {
    1791                            for (int j = 0; j < w; j++) {
    1792                                bData[i * w + j] = bData2[j * h + i];
    1793                            }
    1794                        }
    1795                    }
    1796                    preImage = Tools.createIndexedImage(null, bData, imagePalette, w, h);
    1797                }
    1798            }
    1799            finally {
    1800                // set back the original selection
    1801                System.arraycopy(strideBackup, 0, stride, 0, rank);
    1802                System.arraycopy(selectedBackup, 0, selected, 0, rank);
    1803                System.arraycopy(startBackup, 0, start, 0, rank);
    1804                System.arraycopy(selectedIndexBackup, 0, selectedIndex, 0, 3);
    1805            }
    1806
    1807            return preImage;
    1808        }
    1809
    1810        private void updateSelection (int x0, int y0, int w, int h) {
    1811            int i0 = 0, i1 = 0;
    1812
    1813            i0 = (int) (y0 * r);
    1814            if (i0 > dims[currentIndex[0]]) {
    1815                i0 = (int) dims[currentIndex[0]];
    1816            }
    1817            startFields[0].setText(String.valueOf(i0));
    1818
    1819            i1 = (int) ((y0 + h) * r);
    1820
    1821            if (i1 < i0) {
    1822                i1 = i0;
    1823            }
    1824            endFields[0].setText(String.valueOf(i1));
    1825
    1826            selStr = String.valueOf((int) (h * r));
    1827
    1828            if (rank > 1) {
    1829                i0 = (int) (x0 * r);
    1830                if (i0 > dims[currentIndex[1]]) {
    1831                    i0 = (int) dims[currentIndex[1]];
    1832                }
    1833                startFields[1].setText(String.valueOf(i0));
    1834
    1835                i1 = (int) ((x0 + w) * r);
    1836                if (i1 < i0) {
    1837                    i1 = i0;
    1838                }
    1839                endFields[1].setText(String.valueOf(i1));
    1840
    1841                selStr += " x " + ((int) (w * r));
    1842            }
    1843        }
    1844
    1845        private void setDimensionSize (int w, int h) {
    1846            dimX = w;
    1847            dimY = h;
    1848            if (dimX > dimY) {
    1849                x = NAVIGATOR_SIZE;
    1850                r = dimX / (double) x;
    1851                y = (int) (dimY / r);
    1852            }
    1853            else {
    1854                y = NAVIGATOR_SIZE;
    1855                r = dimY / (double) y;
    1856                x = (int) (dimX / r);
    1857            }
    1858
    1859            selectedArea.setSize(0, 0);
    1860
    1861            try {
    1862                previewImage = createPreviewImage();
    1863            }
    1864            catch (Exception ex) {
    1865            }
    1866
    1867            this.redraw();
    1868        }
    1869
    1870        private boolean applyImageFilter(ImageFilter filter) {
    1871            boolean status = true;
    1872            ImageProducer imageProducer = previewImage.getSource();
    1873
    1874            try {
    1875                previewImage = Tools.toBufferedImage(Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(imageProducer, filter)));
    1876            }
    1877            catch (Exception err) {
    1878                shell.getDisplay().beep();
    1879                Tools.showError(shell, "Apply Image Filter", err.getMessage());
    1880                status = false;
    1881            }
    1882
    1883            return status;
    1884        }
    1885
    1886        private void flip(int direction) {
    1887            applyImageFilter(new FlipFilter(direction));
    1888        }
    1889
    1890        private void rotate(int direction) {
    1891            if (!(direction == DefaultImageView.ROTATE_CW_90 || direction == DefaultImageView.ROTATE_CCW_90)) return;
    1892
    1893            applyImageFilter(new Rotate90Filter(direction));
    1894        }
    1895
    1896        /**
    1897         * Converts a given BufferedImage to ImageData for a SWT-readable Image
    1898         *
    1899         * @param image The BufferedImage to be converted
    1900         *
    1901         * @return the Image
    1902         */
    1903        private org.eclipse.swt.graphics.Image convertBufferedImageToSWTImage(BufferedImage image) {
    1904            Display display = this.getDisplay();
    1905
    1906            if (image.getColorModel() instanceof DirectColorModel) {
    1907                DirectColorModel colorModel = (DirectColorModel) image
    1908                        .getColorModel();
    1909                PaletteData palette = new PaletteData(colorModel.getRedMask(),
    1910                        colorModel.getGreenMask(), colorModel.getBlueMask());
    1911                ImageData data = new ImageData(image.getWidth(),
    1912                        image.getHeight(), colorModel.getPixelSize(),
    1913                        palette);
    1914
    1915                for (int y = 0; y < data.height; y++) {
    1916                    for (int x = 0; x < data.width; x++) {
    1917                        int rgb = image.getRGB(x, y);
    1918                        int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
    1919                        data.setPixel(x, y, pixel);
    1920                        if (colorModel.hasAlpha()) {
    1921                            data.setAlpha(x, y, (rgb >> 24) & 0xFF);
    1922                        }
    1923                    }
    1924                }
    1925
    1926                return new org.eclipse.swt.graphics.Image(display, data);
    1927            }
    1928            else if (image.getColorModel() instanceof IndexColorModel) {
    1929                IndexColorModel colorModel = (IndexColorModel) image
    1930                        .getColorModel();
    1931                int size = colorModel.getMapSize();
    1932                byte[] reds = new byte[size];
    1933                byte[] greens = new byte[size];
    1934                byte[] blues = new byte[size];
    1935                colorModel.getReds(reds);
    1936                colorModel.getGreens(greens);
    1937                colorModel.getBlues(blues);
    1938                RGB[] rgbs = new RGB[size];
    1939                for (int i = 0; i < rgbs.length; i++) {
    1940                    rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF,
    1941                            blues[i] & 0xFF);
    1942                }
    1943                PaletteData palette = new PaletteData(rgbs);
    1944                ImageData data = new ImageData(image.getWidth(),
    1945                        image.getHeight(), colorModel.getPixelSize(),
    1946                        palette);
    1947                data.transparentPixel = colorModel.getTransparentPixel();
    1948                WritableRaster raster = image.getRaster();
    1949                int[] pixelArray = new int[1];
    1950                for (int y = 0; y < data.height; y++) {
    1951                    for (int x = 0; x < data.width; x++) {
    1952                        raster.getPixel(x, y, pixelArray);
    1953                        data.setPixel(x, y, pixelArray[0]);
    1954                    }
    1955                }
    1956
    1957                return new org.eclipse.swt.graphics.Image(display, data);
    1958            }
    1959            else if (image.getColorModel() instanceof ComponentColorModel) {
    1960                ComponentColorModel colorModel = (ComponentColorModel) image.getColorModel();
    1961                //ASSUMES: 3 BYTE BGR IMAGE TYPE
    1962                PaletteData palette = new PaletteData(0x0000FF, 0x00FF00,0xFF0000);
    1963                ImageData data = new ImageData(image.getWidth(), image.getHeight(),
    1964                        colorModel.getPixelSize(), palette);
    1965                //This is valid because we are using a 3-byte Data model with no transparent pixels
    1966                data.transparentPixel = -1;
    1967                WritableRaster raster = image.getRaster();
    1968                int[] pixelArray = new int[3];
    1969                for (int y = 0; y < data.height; y++) {
    1970                    for (int x = 0; x < data.width; x++) {
    1971                        raster.getPixel(x, y, pixelArray);
    1972                        int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
    1973                        data.setPixel(x, y, pixel);
    1974                    }
    1975                }
    1976                return new org.eclipse.swt.graphics.Image(display, data);
    1977            }
    1978
    1979            return null;
    1980        }
    1981    }
    1982}