    001/*****************************************************************************
    002 * Copyright by The HDF Group.                                               *
    003 * Copyright by the Board of Trustees of the University of Illinois.         *
    004 * All rights reserved.                                                      *
    005 *                                                                           *
    006 * This file is part of the HDF Java Products distribution.                  *
    007 * The full copyright notice, including terms governing use, modification,   *
    008 * and redistribution, is contained in the COPYING file, which can be found  *
    009 * at the root of the source code distribution tree,                         *
    010 * or in https://www.hdfgroup.org/licenses.                                  *
    011 * If you do not have access to either file, you may request a copy from     *
    012 * help@hdfgroup.org.                                                        *
    013 ****************************************************************************/
    014
    015package hdf.view.dialog;
    016
    017import java.awt.GraphicsEnvironment;
    018import java.io.File;
    019
    020import org.slf4j.Logger;
    021import org.slf4j.LoggerFactory;
    022
    023import org.eclipse.swt.SWT;
    024import org.eclipse.swt.events.SelectionAdapter;
    025import org.eclipse.swt.events.SelectionEvent;
    026import org.eclipse.swt.graphics.Font;
    027import org.eclipse.swt.layout.GridData;
    028import org.eclipse.swt.layout.GridLayout;
    029import org.eclipse.swt.widgets.Button;
    030import org.eclipse.swt.widgets.Combo;
    031import org.eclipse.swt.widgets.Composite;
    032import org.eclipse.swt.widgets.Control;
    033import org.eclipse.swt.widgets.DirectoryDialog;
    034import org.eclipse.swt.widgets.Display;
    035import org.eclipse.swt.widgets.FileDialog;
    036import org.eclipse.swt.widgets.Label;
    037import org.eclipse.swt.widgets.Text;
    038
    039import hdf.view.Tools;
    040import hdf.view.ViewProperties;
    041
    042/**
    043 * UserOptionsGeneralPage.java - Configuration page for general application settings.
    044 */
    045public class UserOptionsGeneralPage extends UserOptionsDefaultPage {
    046    private static final Logger log = LoggerFactory.getLogger(UserOptionsGeneralPage.class);
    047
    048    private Text UGField, workField, maxMemberField, startMemberField, timerRefreshField;
    049
    050    private Combo fontSizeChoice, fontTypeChoice, delimiterChoice, imageOriginChoice, indexBaseChoice;
    051
    052    private Button checkCurrentUserDir, checkUserHomeDir, checkAutoContrast, checkShowValues;
    053    private Button currentDirButton, userHomeButton, rwButton, helpButton;
    054    private Button checkReadOnly, checkReadAll;
    055
    056    private boolean isFontChanged;
    057    private boolean isUserGuideChanged;
    058    private boolean isWorkDirChanged;
    059
    060    private String workDir;
    061
    062    private static String fontname;
    063
    064    /**
    065     * Configuration page for general application settings.
    066     */
    067    public UserOptionsGeneralPage() {
    068        super("General Settings");
    069        isFontChanged = false;
    070        isUserGuideChanged = false;
    071        isWorkDirChanged = false;
    072    }
    073
    074    /**
    075     * Performs special processing when this page's Defaults button has been pressed.
    076     */
    077    @Override
    078    public void performDefaults() {
    079        super.performDefaults();
    080    }
    081
    082    /**
    083     * Notifies that the OK button of this page's container has been pressed.
    084     *
    085     * @return <code>false</code> to abort the container's OK processing and
    086     * <code>true</code> to allow the OK to happen
    087     */
    088    @Override
    089    public boolean performOk() {
    090        getPreferenceStore();
    091
    092        if (UGField != null) {
    093            String UGPath = UGField.getText();
    094            if ((UGPath != null) && (UGPath.length() > 0)) {
    095                UGPath = UGPath.trim();
    096                isUserGuideChanged = !UGPath.equals(ViewProperties.getUsersGuide());
    097                ViewProperties.setUsersGuide(UGPath);
    098            }
    099        }
    100
    101        if (workField != null) {
    102            String workPath = workField.getText();
    103            if (checkCurrentUserDir.getSelection())
    104                workPath = System.getProperty("user.dir");
    105            else if (checkUserHomeDir.getSelection())
    106                workPath = System.getProperty("user.home");
    107
    108            if ((workPath != null) && (workPath.length() > 0)) {
    109                workPath = workPath.trim();
    110                isWorkDirChanged = !workPath.equals(ViewProperties.getWorkDir());
    111                ViewProperties.setWorkDir(workPath);
    112            }
    113        }
    114
    115        // set font size and type
    116        try {
    117            if (fontTypeChoice != null) {
    118                String ftype = fontTypeChoice.getItem(fontTypeChoice.getSelectionIndex());
    119                int fsize = Integer.parseInt(fontSizeChoice.getItem(fontSizeChoice.getSelectionIndex()));
    120                log.trace("performOk: save font options {} - {}", ftype, fsize);
    121
    122                if (ViewProperties.getFontSize() != fsize) {
    123                    ViewProperties.setFontSize(fsize);
    124                    isFontChanged = true;
    125                    log.trace("performOk: props font size {}", ViewProperties.getFontSize());
    126                }
    127
    128                if (!ftype.equalsIgnoreCase(ViewProperties.getFontType())) {
    129                    ViewProperties.setFontType(ftype);
    130                    isFontChanged = true;
    131                    log.trace("performOk: props font {}", ViewProperties.getFontType());
    132                }
    133            }
    134        }
    135        catch (Exception ex) {
    136            isFontChanged = false;
    137        }
    138
    139        // set file access
    140        if (checkReadOnly != null) {
    141            if (checkReadOnly.getSelection())
    142                ViewProperties.setReadOnly(true);
    143            else
    144                ViewProperties.setReadOnly(false);
    145        }
    146
    147        // set timer refresh value (msec)
    148        try {
    149            int timermsec = Integer.parseInt(timerRefreshField.getText());
    150            ViewProperties.setTimerRefresh(timermsec);
    151        }
    152        catch (Exception ex) {
    153        }
    154
    155        // set data delimiter
    156        if (delimiterChoice != null)
    157            ViewProperties.setDataDelimiter(delimiterChoice.getItem(delimiterChoice.getSelectionIndex()));
    158        if (imageOriginChoice != null)
    159            ViewProperties.setImageOrigin(imageOriginChoice.getItem(imageOriginChoice.getSelectionIndex()));
    160
    161        if (checkReadAll != null) {
    162            if (checkReadAll.getSelection()) {
    163                ViewProperties.setStartMembers(0);
    164                ViewProperties.setMaxMembers(-1);
    165            }
    166            else {
    167                try {
    168                    int maxsize = Integer.parseInt(maxMemberField.getText());
    169                    ViewProperties.setMaxMembers(maxsize);
    170                }
    171                catch (Exception ex) {
    172                }
    173
    174                try {
    175                    int startsize = Integer.parseInt(startMemberField.getText());
    176                    ViewProperties.setStartMembers(startsize);
    177                }
    178                catch (Exception ex) {
    179                }
    180            }
    181        }
    182
    183        if (checkAutoContrast != null)
    184            ViewProperties.setAutoContrast(checkAutoContrast.getSelection());
    185        if (checkShowValues != null)
    186            ViewProperties.setShowImageValue(checkShowValues.getSelection());
    187
    188        if (indexBaseChoice != null) {
    189            if (indexBaseChoice.getSelectionIndex() == 0)
    190                ViewProperties.setIndexBase1(false);
    191            else
    192                ViewProperties.setIndexBase1(true);
    193        }
    194
    195        return true;
    196    }
    197
    198    /**
    199     * Checks if the Font setting changed.
    200     *
    201     * @return true if the font changed.
    202     */
    203    public boolean isFontChanged() {
    204        return isFontChanged;
    205    }
    206
    207    /**
    208     * Checks if the location for the UserGuide changed.
    209     *
    210     * @return  true if the location of the UserGuide changed.
    211     */
    212    public boolean isUserGuideChanged() {
    213        return isUserGuideChanged;
    214    }
    215
    216    /**
    217     * Checks if the location of the WorkDir changed.
    218     *
    219     * @return  true if the working directory changed.
    220     */
    221    public boolean isWorkDirChanged() {
    222        return isWorkDirChanged;
    223    }
    224
    225    /**
    226     * Loads all stored values in the <code>FieldEditor</code>s.
    227     */
    228    protected void load() {
    229        getPreferenceStore();
    230
    231        try {
    232            curFont = new Font(
    233                    Display.getCurrent(),
    234                    ViewProperties.getFontType(),
    235                    ViewProperties.getFontSize(),
    236                    SWT.NORMAL);
    237        }
    238        catch (Exception ex) {
    239            curFont = null;
    240        }
    241
    242        workDir = ViewProperties.getWorkDir();
    243        if (workDir == null)
    244            workDir = rootDir;
    245
    246        workField.setText(workDir);
    247
    248        if (workDir.equals(System.getProperty("user.dir"))) {
    249            checkCurrentUserDir.setSelection(true);
    250            checkUserHomeDir.setSelection(false);
    251            workField.setEnabled(false);
    252        }
    253        else if (workDir.equals(System.getProperty("user.home"))) {
    254            checkCurrentUserDir.setSelection(false);
    255            checkUserHomeDir.setSelection(true);
    256            workField.setEnabled(false);
    257        }
    258        else {
    259            checkCurrentUserDir.setSelection(false);
    260            checkUserHomeDir.setSelection(false);
    261            workField.setEnabled(true);
    262        }
    263
    264        log.trace("UserOptionsGeneralPage: workDir={}", workDir);
    265
    266        UGField.setText(ViewProperties.getUsersGuide());
    267
    268        checkReadOnly.setSelection(ViewProperties.isReadOnly());
    269
    270        rwButton.setSelection(!ViewProperties.isReadOnly());
    271
    272        String fontsize = String.valueOf(ViewProperties.getFontSize());
    273        log.trace("performOk: load General options fontsize={}", fontsize);
    274        try {
    275            int selectionIndex = fontSizeChoice.indexOf(fontsize);
    276            fontSizeChoice.select(selectionIndex);
    277        }
    278        catch (Exception ex) {
    279            fontSizeChoice.select(0);
    280        }
    281
    282        fontname = ViewProperties.getFontType();
    283        log.trace("performOk: load General options fontname={}", fontname);
    284        try {
    285            int selectionIndex = fontTypeChoice.indexOf(fontname);
    286            fontTypeChoice.select(selectionIndex);
    287        }
    288        catch (Exception ex) {
    289            String sysFontName = Display.getDefault().getSystemFont().getFontData()[0].getName();
    290
    291            try {
    292                int selectionIndex = fontTypeChoice.indexOf(sysFontName);
    293                fontTypeChoice.select(selectionIndex);
    294            }
    295            catch (Exception ex2) {
    296                fontTypeChoice.select(0);
    297            }
    298        }
    299
    300        checkAutoContrast.setSelection(ViewProperties.isAutoContrast());
    301
    302        checkShowValues.setSelection(ViewProperties.showImageValues());
    303
    304        String[] imageOriginChoices = { ViewProperties.ORIGIN_UL, ViewProperties.ORIGIN_LL, ViewProperties.ORIGIN_UR,
    305                ViewProperties.ORIGIN_LR };
    306        imageOriginChoice.setItems(imageOriginChoices);
    307
    308        try {
    309            int selectionIndex = imageOriginChoice.indexOf(ViewProperties.getImageOrigin());
    310            imageOriginChoice.select(selectionIndex);
    311        }
    312        catch (Exception ex) {
    313            imageOriginChoice.select(0);
    314        }
    315
    316        //        helpButton.setImage(ViewProperties.getHelpIcon());
    317
    318        if (ViewProperties.isIndexBase1())
    319            indexBaseChoice.select(1);
    320        else
    321            indexBaseChoice.select(0);
    322
    323        String[] delimiterChoices = { ViewProperties.DELIMITER_TAB, ViewProperties.DELIMITER_COMMA,
    324                ViewProperties.DELIMITER_SPACE, ViewProperties.DELIMITER_COLON, ViewProperties.DELIMITER_SEMI_COLON };
    325        delimiterChoice.setItems(delimiterChoices);
    326
    327        try {
    328            int selectionIndex = delimiterChoice.indexOf(ViewProperties.getDataDelimiter());
    329            delimiterChoice.select(selectionIndex);
    330        }
    331        catch (Exception ex) {
    332            delimiterChoice.select(0);
    333        }
    334
    335        timerRefreshField.setText(String.valueOf(ViewProperties.getTimerRefresh()));
    336
    337        int nMax = ViewProperties.getMaxMembers();
    338        checkReadAll.setSelection((nMax<=0) || (nMax==Integer.MAX_VALUE));
    339
    340        startMemberField.setText(String.valueOf(ViewProperties.getStartMembers()));
    341
    342        maxMemberField.setText(String.valueOf(ViewProperties.getMaxMembers()));
    343    }
    344
    345    /**
    346     * Creates and returns the SWT control for the customized body of this
    347     * preference page under the given parent composite.
    348     *
    349     * @param parent
    350     *         the parent composite
    351     *
    352     * @return the new control
    353     */
    354    @Override
    355    protected Control createContents(Composite parent) {
    356        shell = parent.getShell();
    357        Composite composite = new Composite(parent, SWT.NONE);
    358        composite.setLayout(new GridLayout());
    359
    360        org.eclipse.swt.widgets.Group workingDirectoryGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    361        workingDirectoryGroup.setLayout(new GridLayout(3, false));
    362        workingDirectoryGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    363        workingDirectoryGroup.setFont(curFont);
    364        workingDirectoryGroup.setText("Default Working Directory");
    365
    366        checkCurrentUserDir = new Button(workingDirectoryGroup, SWT.CHECK);
    367        checkCurrentUserDir.setFont(curFont);
    368        checkCurrentUserDir.setText("\"User Work\" or");
    369        checkCurrentUserDir.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    370        checkCurrentUserDir.addSelectionListener(new SelectionAdapter() {
    371            @Override
    372            public void widgetSelected(SelectionEvent e) {
    373                boolean isCheckCurrentUserDirSelected = checkCurrentUserDir.getSelection();
    374                if (isCheckCurrentUserDirSelected)
    375                    checkUserHomeDir.setSelection(false);
    376                workField.setEnabled(!isCheckCurrentUserDirSelected);
    377                currentDirButton.setEnabled(!isCheckCurrentUserDirSelected);
    378            }
    379        });
    380
    381        checkUserHomeDir = new Button(workingDirectoryGroup, SWT.CHECK);
    382        checkUserHomeDir.setFont(curFont);
    383        checkUserHomeDir.setText("\"User Home\" or");
    384        checkUserHomeDir.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    385        checkUserHomeDir.addSelectionListener(new SelectionAdapter() {
    386            @Override
    387            public void widgetSelected(SelectionEvent e) {
    388                boolean isCheckUserHomeDirSelected = checkUserHomeDir.getSelection();
    389                if (isCheckUserHomeDirSelected)
    390                    checkCurrentUserDir.setSelection(false);
    391                workField.setEnabled(!isCheckUserHomeDirSelected);
    392                currentDirButton.setEnabled(!isCheckUserHomeDirSelected);
    393            }
    394        });
    395
    396        workField = new Text(workingDirectoryGroup, SWT.SINGLE | SWT.BORDER);
    397        workField.setFont(curFont);
    398        workField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    399
    400        currentDirButton = new Button(workingDirectoryGroup, SWT.PUSH);
    401        currentDirButton.setFont(curFont);
    402        currentDirButton.setText("Browse...");
    403        currentDirButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    404        currentDirButton.addSelectionListener(new SelectionAdapter() {
    405            @Override
    406            public void widgetSelected(SelectionEvent e) {
    407                final DirectoryDialog dChooser = new DirectoryDialog(shell);
    408                dChooser.setFilterPath(workDir);
    409                dChooser.setText("Select a Directory");
    410
    411                String dir = dChooser.open();
    412
    413                if(dir == null) return;
    414
    415                workField.setText(dir);
    416            }
    417        });
    418
    419        org.eclipse.swt.widgets.Group helpDocumentGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    420        helpDocumentGroup.setLayout(new GridLayout(3, false));
    421        helpDocumentGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    422        helpDocumentGroup.setFont(curFont);
    423        helpDocumentGroup.setText("Help Document");
    424
    425        Label label = new Label(helpDocumentGroup, SWT.RIGHT);
    426        label.setFont(curFont);
    427        label.setText("User's Guide:  ");
    428
    429        UGField = new Text(helpDocumentGroup, SWT.SINGLE | SWT.BORDER);
    430        UGField.setFont(curFont);
    431        UGField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    432
    433        Button browseButton = new Button(helpDocumentGroup, SWT.PUSH);
    434        browseButton.setFont(curFont);
    435        browseButton.setText("Browse...");
    436        browseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    437        browseButton.addSelectionListener(new SelectionAdapter() {
    438            @Override
    439            public void widgetSelected(SelectionEvent e) {
    440                final FileDialog fChooser = new FileDialog(shell, SWT.OPEN);
    441                fChooser.setFilterPath(rootDir);
    442                fChooser.setFilterExtensions(new String[] {"*"});
    443                fChooser.setFilterNames(new String[] {"All Files"});
    444                fChooser.setFilterIndex(0);
    445
    446                if(fChooser.open() == null) {
    447                    return;
    448                }
    449
    450                File chosenFile = new File(fChooser.getFilterPath() + File.separator + fChooser.getFileName());
    451
    452                if(!chosenFile.exists()) {
    453                    // Give an error
    454                    return;
    455                }
    456
    457                UGField.setText(chosenFile.getAbsolutePath());
    458            }
    459        });
    460
    461        org.eclipse.swt.widgets.Group fileAccessModeGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    462        fileAccessModeGroup.setLayout(new GridLayout(2, true));
    463        fileAccessModeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    464        fileAccessModeGroup.setFont(curFont);
    465        fileAccessModeGroup.setText("Default File Access Mode");
    466
    467        checkReadOnly = new Button(fileAccessModeGroup, SWT.RADIO);
    468        checkReadOnly.setFont(curFont);
    469        checkReadOnly.setText("Read Only");
    470        checkReadOnly.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false));
    471
    472        rwButton = new Button(fileAccessModeGroup, SWT.RADIO);
    473        rwButton.setFont(curFont);
    474        rwButton.setText("Read/Write");
    475        rwButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false));
    476
    477        org.eclipse.swt.widgets.Group textFontGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    478        textFontGroup.setLayout(new GridLayout(4, false));
    479        textFontGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    480        textFontGroup.setFont(curFont);
    481        textFontGroup.setText("Text Font");
    482
    483        label = new Label(textFontGroup, SWT.RIGHT);
    484        label.setFont(curFont);
    485        label.setText("Font Size: ");
    486
    487        String[] fontSizeChoices = { "8", "10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "30", "32", "34", "36", "48" };
    488        fontSizeChoice = new Combo(textFontGroup, SWT.SINGLE | SWT.READ_ONLY);
    489        fontSizeChoice.setFont(curFont);
    490        fontSizeChoice.setItems(fontSizeChoices);
    491        fontSizeChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    492
    493        label = new Label(textFontGroup, SWT.RIGHT);
    494        label.setFont(curFont);
    495        label.setText("Font Type: ");
    496
    497        String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
    498
    499        fontTypeChoice = new Combo(textFontGroup, SWT.SINGLE | SWT.READ_ONLY);
    500        fontTypeChoice.setFont(curFont);
    501        fontTypeChoice.setItems(fontNames);
    502        fontTypeChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    503
    504        org.eclipse.swt.widgets.Group imageGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    505        imageGroup.setLayout(new GridLayout(5, false));
    506        imageGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    507        imageGroup.setFont(curFont);
    508        imageGroup.setText("Image");
    509
    510        helpButton = new Button(imageGroup, SWT.PUSH);
    511        helpButton.setImage(ViewProperties.getHelpIcon());
    512        helpButton.setToolTipText("Help on Auto Contrast");
    513        helpButton.addSelectionListener(new SelectionAdapter() {
    514            @Override
    515            public void widgetSelected(SelectionEvent e) {
    516                final String msg = "Auto Contrast does the following to compute a gain/bias \n"
    517                        + "that will stretch the pixels in the image to fit the pixel \n"
    518                        + "values of the graphics system. For example, it stretches unsigned\n"
    519                        + "short data to fit the full range of an unsigned short. Later \n"
    520                        + "code simply takes the high order byte and passes it to the graphics\n"
    521                        + "system (which expects 0-255). It uses some statistics on the pixels \n"
    522                        + "to prevent outliers from throwing off the gain/bias calculations much.\n\n"
    523                        + "To compute the gain/bias we... \n"
    524                        + "Find the mean and std. deviation of the pixels in the image \n" + "min = mean - 3 * std.dev. \n"
    525                        + "max = mean + 3 * std.dev. \n" + "small fudge factor because this tends to overshoot a bit \n"
    526                        + "Stretch to 0-USHRT_MAX \n" + "        gain = USHRT_MAX / (max-min) \n"
    527                        + "        bias = -min \n" + "\n" + "To apply the gain/bias to a pixel, use the formula \n"
    528                        + "data[i] = (data[i] + bias) * gain \n" + "\n"
    529                        // +
    530                        // "Finally, for auto-ranging the sliders for gain/bias, we do the following \n"
    531                        // + "gain_min = 0 \n"
    532                        // + "gain_max = gain * 3.0 \n"
    533                        // + "bias_min = -fabs(bias) * 3.0 \n"
    534                        // + "bias_max = fabs(bias) * 3.0 \n"
    535                        + "\n\n";
    536
    537                Tools.showInformation(getShell(), "Help", msg);
    538            }
    539        });
    540
    541        checkAutoContrast = new Button(imageGroup, SWT.CHECK);
    542        checkAutoContrast.setFont(curFont);
    543        checkAutoContrast.setText("Autogain Image Contrast");
    544        checkAutoContrast.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    545
    546        checkShowValues = new Button(imageGroup, SWT.CHECK);
    547        checkShowValues.setFont(curFont);
    548        checkShowValues.setText("Show Values");
    549        checkShowValues.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    550
    551        label = new Label(imageGroup, SWT.RIGHT);
    552        label.setFont(curFont);
    553        label.setText("Image Origin: ");
    554
    555        imageOriginChoice = new Combo(imageGroup, SWT.SINGLE | SWT.READ_ONLY);
    556        imageOriginChoice.setFont(curFont);
    557        imageOriginChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    558
    559        org.eclipse.swt.widgets.Group dataGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    560        dataGroup.setLayout(new GridLayout(4, false));
    561        dataGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    562        dataGroup.setFont(curFont);
    563        dataGroup.setText("Data");
    564
    565        label = new Label(dataGroup, SWT.RIGHT);
    566        label.setFont(curFont);
    567        label.setText("Index Base: ");
    568
    569        String[] indexBaseChoices = { "0-based", "1-based" };
    570        indexBaseChoice = new Combo(dataGroup, SWT.SINGLE | SWT.READ_ONLY);
    571        indexBaseChoice.setFont(curFont);
    572        indexBaseChoice.setItems(indexBaseChoices);
    573        indexBaseChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    574
    575        Label delimLabel = new Label(dataGroup, SWT.RIGHT);
    576        delimLabel.setFont(curFont);
    577        delimLabel.setText("Data Delimiter: ");
    578        delimLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
    579
    580        delimiterChoice = new Combo(dataGroup, SWT.SINGLE | SWT.READ_ONLY);
    581        delimiterChoice.setFont(curFont);
    582        delimiterChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    583
    584        Label timerRefreshLabel = new Label(dataGroup, SWT.RIGHT);
    585        timerRefreshLabel.setFont(curFont);
    586        timerRefreshLabel.setText("Timer Refresh (ms): ");
    587
    588        timerRefreshField = new Text(dataGroup, SWT.SINGLE | SWT.BORDER);
    589        timerRefreshField.setFont(curFont);
    590        timerRefreshField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    591
    592        org.eclipse.swt.widgets.Group objectsGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE);
    593        objectsGroup.setLayout(new GridLayout(5, true));
    594        objectsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    595        objectsGroup.setFont(curFont);
    596        objectsGroup.setText("Objects to Open");
    597
    598        checkReadAll = new Button(objectsGroup, SWT.CHECK);
    599        checkReadAll.setFont(curFont);
    600        checkReadAll.setText("Open All");
    601        checkReadAll.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    602        checkReadAll.addSelectionListener(new SelectionAdapter() {
    603            @Override
    604            public void widgetSelected(SelectionEvent e) {
    605                startMemberField.setEnabled(!checkReadAll.getSelection());
    606                maxMemberField.setEnabled(!checkReadAll.getSelection());
    607            }
    608        });
    609
    610        label = new Label(objectsGroup, SWT.RIGHT);
    611        label.setFont(curFont);
    612        label.setText("Start Member: ");
    613
    614        startMemberField = new Text(objectsGroup, SWT.SINGLE | SWT.BORDER);
    615        startMemberField.setFont(curFont);
    616        startMemberField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    617
    618        label = new Label(objectsGroup, SWT.RIGHT);
    619        label.setFont(curFont);
    620        label.setText("Member Count: ");
    621
    622        maxMemberField = new Text(objectsGroup, SWT.SINGLE | SWT.BORDER);
    623        maxMemberField.setFont(curFont);
    624        maxMemberField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    625
    626        startMemberField.setEnabled(!checkReadAll.getSelection());
    627        maxMemberField.setEnabled(!checkReadAll.getSelection());
    628
    629        load();
    630        // return scroller;
    631        return composite;
    632    }
    633}