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