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;
016
017import java.io.File;
018import java.io.IOException;
019import java.io.InputStream;
020import java.net.MalformedURLException;
021import java.net.URL;
022import java.net.URLClassLoader;
023import java.util.ArrayList;
024import java.util.Arrays;
025import java.util.Enumeration;
026import java.util.List;
027import java.util.jar.JarEntry;
028import java.util.jar.JarFile;
029
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033import org.eclipse.jface.preference.PreferenceStore;
034import org.eclipse.swt.graphics.Image;
035
036import hdf.HDFVersions;
037import hdf.object.FileFormat;
038import hdf.view.ImageView.ImageViewFactory;
039import hdf.view.MetaDataView.MetaDataViewFactory;
040import hdf.view.PaletteView.PaletteViewFactory;
041import hdf.view.TableView.TableViewFactory;
042import hdf.view.TreeView.TreeViewFactory;
043
044/** A class to maintain the list of preferences for data and display */
045public class ViewProperties extends PreferenceStore
046{
047    private static final long   serialVersionUID     = -6411465283887959066L;
048
049    private static final Logger log = LoggerFactory.getLogger(ViewProperties.class);
050
051    /** the version of the HDFViewer */
052    public static final String  VERSION              = HDFVersions.getPropertyVersionView();
053
054    /** the local property file name */
055    private static final String USER_PROPERTY_FILE   = ".hdfview" + VERSION;
056
057    /** the maximum number of most recent files */
058    public static final int     MAX_RECENT_FILES     = 15;
059
060    /** name of the tab delimiter */
061    public static final String  DELIMITER_TAB        = "Tab";
062
063    /** name of the tab delimiter */
064    public static final String  DELIMITER_COMMA      = "Comma";
065
066    /** name of the tab delimiter */
067    public static final String  DELIMITER_SPACE      = "Space";
068
069    /** name of the tab delimiter */
070    public static final String  DELIMITER_COLON      = "Colon";
071
072    /** image origin: UpperLeft */
073    public static final String  ORIGIN_UL            = "UpperLeft";
074
075    /** image origin: LowerLeft */
076    public static final String  ORIGIN_LL            = "LowerLeft";
077
078    /** image origin: UpperRight */
079    public static final String  ORIGIN_UR            = "UpperRight";
080
081    /** image origin: LowerRight */
082    public static final String  ORIGIN_LR            = "LowerRight";
083
084    /** name of the tab delimiter */
085    public static final String  DELIMITER_SEMI_COLON = "Semi-Colon";
086
087    /**
088     * The names of the various default classes for each HDFView module interface
089     */
090
091    /** Text for default selection of modules */
092    public static final String DEFAULT_MODULE_TEXT = "Default";
093
094    /** Default TreeView class names */
095    public static final String DEFAULT_TREEVIEW_NAME = "hdf.view.TreeView.DefaultTreeView";
096
097    /** Default Scalar TableView class names */
098    public static final String DEFAULT_SCALAR_DATASET_TABLEVIEW_NAME = "hdf.view.TableView.DefaultScalarDSTableView";
099    /** Default Compound TableView class names */
100    public static final String DEFAULT_COMPOUND_DATASET_TABLEVIEW_NAME = "hdf.view.TableView.DefaultCompoundDSTableView";
101
102    /** Default Group MetaDataView class names */
103    public static final String DEFAULT_GROUP_METADATAVIEW_NAME = "hdf.view.MetaDataView.DefaultGroupMetaDataView";
104    /** Default Dataset MetaDataView class names */
105    public static final String DEFAULT_DATASET_METADATAVIEW_NAME = "hdf.view.MetaDataView.DefaultDatasetMetaDataView";
106    /** Default Datatype MetaDataView class names */
107    public static final String DEFAULT_DATATYPE_METADATAVIEW_NAME = "hdf.view.MetaDataView.DefaultDatatypeMetaDataView";
108    /** Default Link MetaDataView class names */
109    public static final String DEFAULT_LINK_METADATAVIEW_NAME = "hdf.view.MetaDataView.DefaultLinkMetaDataView";
110
111    /** Default ImageView class names */
112    public static final String DEFAULT_IMAGEVIEW_NAME = "hdf.view.ImageView.DefaultImageView";
113
114    /** Default PaletteView class names */
115    public static final String DEFAULT_PALETTEVIEW_NAME = "hdf.view.PaletteView.DefaultPaletteView";
116
117    /**
118     * Used to create different DataViews for a given HObject.
119     */
120    public static enum DataViewType {
121        /** */
122        TABLE,
123        /** */
124        IMAGE,
125        /** */
126        PALETTE,
127        /** */
128        METADATA,
129        /** */
130        TREEVIEW
131    }
132
133    /**
134     * Property keys control how the data is displayed.
135     */
136    public static enum DATA_VIEW_KEY {
137        /** */
138        CHAR,
139        /** */
140        CONVERTBYTE,
141        /** */
142        TRANSPOSED,
143        /** */
144        READONLY,
145        /** */
146        OBJECT,
147        /** */
148        BITMASK,
149        /** */
150        BITMASKOP,
151        /** */
152        BORDER,
153        /** */
154        INFO,
155        /** */
156        INDEXBASE1,
157        /** */
158        VIEW_NAME
159    }
160
161    /**
162     * Property keys control how the data is displayed.
163     */
164    public static enum BITMASK_OP {
165        /** */
166        AND,
167        /** */
168        EXTRACT
169    }
170
171    /** the root directory of the HDFView */
172    private static String            rootDir                = System.getProperty("user.dir");
173
174    /** user's guide */
175    private static String            usersGuide             = "/share/doc/UsersGuide/index.html";
176
177    /** the font size */
178    private static int               fontSize               = 12;
179
180    /** the font type */
181    private static String            fontType               = "Serif";
182
183    /** the full path of H4toH5 converter */
184    private static String            h4toh5                 = "";
185
186    /** data delimiter */
187    private static String            delimiter              = DELIMITER_TAB;
188
189    /** image origin */
190    private static String            origin                 = ORIGIN_UL;
191
192    /** default index type */
193    private static String            indexType              = "H5_INDEX_NAME";
194
195    /** default index order */
196    private static String            indexOrder             = "H5_ITER_INC";
197
198    /** a list of most recent files */
199    private static ArrayList<String> recentFiles            = new ArrayList<>(MAX_RECENT_FILES + 5);
200
201    /** default starting file directory */
202    private static String            workDir                = System.getProperty("user.dir");
203
204    /** default HDF file extensions */
205    private static String            fileExt                = "hdf, h4, hdf4, h5, hdf5, he2, he5";
206
207    private static ClassLoader       extClassLoader         = null;
208
209    /** a list of srb accounts */
210    private static ArrayList<String[]> srbAccountList       = new ArrayList<>(5);
211
212    /** the timer refreshrate in msec */
213    private static int               timerRefresh           = 10000;
214
215    private static boolean           isMac                  = System.getProperty("os.name").toLowerCase().contains("mac");
216
217    /**
218     * flag to indicate if auto contrast is used in image processing. Do not use
219     * autocontrast by default (2.6 change).
220     */
221    private static boolean           isAutoContrast         = false;
222
223    private static boolean           showImageValues        = false;
224
225    private static boolean           showRegRefValues       = false;
226
227    /**
228     * flag to indicate if default open file mode is read only. By default, use read
229     * only to prevent accidental modifications to the file.
230     */
231    private static boolean           isReadOnly             = true;
232
233    /**
234     * flag to indicate if default open file mode is read SWMR.
235     */
236    private static boolean           isReadSWMR             = true;
237
238    private static String            EarlyLib               = "Latest";
239
240    private static String            LateLib                = "Latest";
241
242    /** a list of palette files */
243    private static ArrayList<String> paletteList            = new ArrayList<>(5);
244
245    /** flag to indicate if enum data is converted to strings */
246    private static boolean           convertEnum            = true;
247
248    /** flag to indicate if data is 1-based index */
249    private static boolean           isIndexBase1           = false;
250
251    /**
252     * Current Java applications such as HDFView cannot handle files with a large
253     * number of objects such as 1,000,000 objects. max_members defines the maximum
254     * number of objects that will be loaded into memory.
255     */
256    private static int               maxMembers            = Integer.MAX_VALUE;   // load all by default
257    /**
258     * Current Java applications such as HDFView cannot handle files with a large
259     * number of objects such 1,000,000 objects. start_members defines the
260     * starting index of objects that will be loaded into memory.
261     */
262    private static int               startMembers          = 0;
263
264    private static Image
265    hdfviewIcon,
266    h4Icon, h4IconR, h5Icon, h5IconR, ncIcon, ncIconR,
267    blankIcon, helpIcon, fileopenIcon, filesaveIcon, filenewIcon, filecloseIcon, foldercloseIcon,
268    folderopenIcon, foldercloseIconA, folderopenIconA, datasetIcon, imageIcon, tableIcon, textIcon, datasetIconA,
269    imageIconA, tableIconA, textIconA, zoominIcon, zoomoutIcon, paletteIcon, chartIcon, brightIcon, autocontrastIcon,
270    copyIcon, cutIcon, pasteIcon, previousIcon, nextIcon, firstIcon, lastIcon, animationIcon, datatypeIcon,
271    datatypeIconA, linkIcon, iconAPPS, iconURL, iconVIDEO, iconXLS, iconPDF, iconAUDIO, questionIcon;
272
273    private static Image[] hdfIcons = new Image[6];
274    
275    private static String            propertyFile;
276
277    /** a list of treeview modules */
278    private static ArrayList<String> moduleListTreeView = new ArrayList<>(5);
279
280    /** a list of metaview modules */
281    private static ArrayList<String> moduleListMetaDataView = new ArrayList<>(5);
282
283    /** a list of tableview modules */
284    private static ArrayList<String> moduleListTableView = new ArrayList<>(5);
285
286    /** a list of imageview modules */
287    private static ArrayList<String> moduleListImageView = new ArrayList<>(5);
288
289    /** a list of paletteview modules */
290    private static ArrayList<String> moduleListPaletteView = new ArrayList<>(5);
291
292    /** a list of helpview modules */
293    private static ArrayList<String> moduleListHelpView = new ArrayList<>(5);
294
295    /**
296     * Creates a property list with given root directory of the HDFView.
297     *
298     * @param viewRoot
299     *            the root directory of the HDFView
300     * @param viewStart
301     *            the starting directory for file searches
302     */
303    public ViewProperties(String viewRoot, String viewStart) {
304        super();
305
306        // look for the property file in the user's home directory
307        String propertyFileName = USER_PROPERTY_FILE;
308        String userHomeFile = System.getProperty("user.home") + File.separator + propertyFileName;
309        String userDirFile = System.getProperty("user.dir") + File.separator + propertyFileName;
310
311        setFilename(createPropertyFile(userHomeFile, userDirFile));
312
313        setRootDir(viewRoot);
314        log.trace("rootDir is {}", rootDir);
315        if (viewStart != null)
316            setWorkDir(viewStart);
317        setDefault("work.dir", getWorkDir());
318
319        setUsersGuide(rootDir + usersGuide);
320
321        setDefault("users.guide", viewRoot + "/UsersGuide/index.html");
322        setDefault("image.contrast", false);
323        setDefault("image.showvalues", false);
324        setDefault("file.mode", "r");
325        setDefault("lib.lowversion", "Earliest");
326        setDefault("lib.highversion", "Latest");
327        setDefault("enum.conversion", false);
328        setDefault("regref.showvalues", false);
329        setDefault("index.base1", false);
330        setDefault("image.origin", ORIGIN_UL);
331        setDefault("h5file.indexType", "H5_INDEX_NAME");
332        setDefault("h5file.indexOrder", "H5_ITER_INC");
333        setDefault("h4toh5.converter", "");
334        setDefault("file.extension", "hdf, h4, hdf4, h5, hdf5, he2, he5");
335        setDefault("timer.refresh", 1000);
336        setDefault("font.size", 12);
337        setDefault("font.type", "Serif");
338        setDefault("max.members", Integer.MAX_VALUE);
339        setDefault("recent.file", "");
340        setDefault("palette.file", "");
341        setDefault("data.delimiter", DELIMITER_TAB);
342    }
343
344    /**
345     * Creates a property list file in a directory.
346     *
347     * @param userHomeFile
348     *            the user home directory
349     * @param userDirFile
350     *            the user directory
351     *
352     * @return property list file
353     */
354    public static String createPropertyFile(String userHomeFile, String userDirFile) {
355        String propFile = System.getProperty("hdfview.propfile");
356
357        if ((propFile != null) && ((new File(propFile)).exists()))
358            propertyFile = propFile;
359        else if ((new File(userHomeFile)).exists())
360            propertyFile = userHomeFile;
361        else if ((new File(userDirFile)).exists())
362            propertyFile = userDirFile;
363        else {
364            File pFile = null;
365
366            // If the user specified a property file, but it didn't exist,
367            // try to create a new one where specified.
368            if (propFile != null) {
369                pFile = new File(propFile);
370
371                try {
372                    pFile.createNewFile();
373                    propertyFile = propFile;
374                }
375                catch (Exception ex) {
376                    log.debug("createPropertyFile(): unable to create property file {}", propFile);
377                    pFile = null;
378                }
379            }
380
381            if (pFile == null) {
382                // Create new property file at user home directory
383                pFile = new File(userHomeFile);
384                try {
385                    pFile.createNewFile();
386                    propertyFile = userHomeFile;
387                }
388                catch (Exception ex) {
389                    log.debug("createPropertyFile(): unable to create property file in home directory");
390                    propertyFile = null;
391                }
392            }
393        }
394
395        log.trace("propertyFile is {}", propertyFile);
396        return propertyFile;
397    }
398
399    /**
400     * load module classes
401     *
402     * @return the ClassLoader
403     */
404    public static ClassLoader loadExtClass() {
405        if (extClassLoader != null)
406            return extClassLoader;
407        else
408            // default classloader
409            extClassLoader = ClassLoader.getSystemClassLoader();
410        log.trace("loadExtClass: default classloader is {}", extClassLoader);
411
412        String rootPath = System.getProperty("hdfview.root");
413        if (rootPath == null) {
414            rootPath = rootDir;
415            log.debug("loadExtClass: rootDir rootPath is {}", rootPath);
416        }
417        log.debug("loadExtClass: rootPath is {}", rootPath);
418
419        String dirname = rootPath + File.separator + "lib" + File.separator + "ext" + File.separator;
420        String[] jars = null;
421        File extdir = null;
422        try {
423            extdir = new File(dirname);
424            jars = extdir.list();
425        }
426        catch (Exception ex0) {
427            log.debug("loadExtClass: load dirname: {}+lib/ext failed", rootPath, ex0);
428        }
429
430        if ((jars == null) || (jars.length <= 0))
431            return extClassLoader;
432
433        ArrayList<String> jarList = new ArrayList<>(50);
434        ArrayList<String> classList = new ArrayList<>(50);
435        for (int i = 0; i < jars.length; i++) {
436            log.trace("loadExtClass: load jar[{}]", i);
437            if (jars[i].endsWith(".jar")) {
438                jarList.add(jars[i]);
439                // add class names to the list of classes
440                File tmpFile = new File(extdir, jars[i]);
441                try (JarFile jarFile = new JarFile(tmpFile, false, JarFile.OPEN_READ)) {
442                    Enumeration<?> emu = jarFile.entries();
443                    while (emu.hasMoreElements()) {
444                        JarEntry jarEntry = (JarEntry) emu.nextElement();
445                        String entryName = jarEntry.getName();
446                        log.trace("loadExtClass: reading jar[{}] class={}", i, entryName);
447                        int idx = entryName.indexOf(".class");
448                        if ((idx > 0) && (entryName.indexOf('$') <= 0)) {
449                            entryName = entryName.replace('/', '.');
450                            classList.add(entryName.substring(0, idx));
451                        }
452                    }
453                }
454                catch (Exception ex) {
455                    log.debug("loadExtClass: load jar[{}] failed", i, ex);
456                }
457            } // (jars[i].endsWith(".jar"))
458        } // (int i=0; i<jars.length; i++)
459
460        int n = jarList.size();
461        if (n <= 0) {
462            log.debug("loadExtClass: jarList empty");
463            return extClassLoader;
464        }
465
466        URL[] urls = new URL[n];
467        for (int i = 0; i < n; i++) {
468            try {
469                urls[i] = new URL("file:///" + rootPath + "/lib/ext/" + jarList.get(i));
470                log.trace("loadExtClass: load urls[{}] is {}", i, urls[i]);
471            }
472            catch (MalformedURLException mfu) {
473                log.debug("loadExtClass: load urls[{}] failed", i, mfu);
474            }
475        }
476
477        try {
478            extClassLoader = URLClassLoader.newInstance(urls);
479        }
480        catch (Exception ex) {
481            ex.printStackTrace();
482        }
483
484        // load user modules into their list
485        n = classList.size();
486        for (int i = 0; i < n; i++) {
487            String theName = classList.get(i);
488            log.trace("loadExtClass: load classList[{}] is {}", i, theName);
489            try {
490                // enables use of JHDF5 in JNLP (Web Start) applications, the
491                // system class loader with reflection first.
492                Class<?> theClass = null;
493                try {
494                    theClass = Class.forName(theName);
495                }
496                catch (Exception ex) {
497                    try {
498                        theClass = extClassLoader.loadClass(theName);
499                    }
500                    catch (Exception exc) {
501                        log.debug("load: loadClass({}) failed", theName, ex);
502                    }
503                }
504
505                if(theClass != null) {
506                    if (TableViewFactory.class.isAssignableFrom(theClass)) {
507                        if (!moduleListTableView.contains(theName))
508                            moduleListTableView.add(theName);
509                        log.trace("loadExtClass: TableViewFactory class {}", theName);
510                    }
511                    else if (MetaDataViewFactory.class.isAssignableFrom(theClass)) {
512                        if (!moduleListMetaDataView.contains(theName))
513                            moduleListMetaDataView.add(theName);
514                        log.trace("loadExtClass: MetaDataViewFactory class {}", theName);
515                    }
516                    else if (ImageViewFactory.class.isAssignableFrom(theClass)) {
517                        if (!moduleListImageView.contains(theName))
518                            moduleListImageView.add(theName);
519                        log.trace("loadExtClass: ImageViewFactory class {}", theName);
520                    }
521                    else if (TreeViewFactory.class.isAssignableFrom(theClass)) {
522                        if (!moduleListTreeView.contains(theName))
523                            moduleListTreeView.add(theName);
524                        log.trace("loadExtClass: TreeViewFactory class {}", theName);
525                    }
526                    else if (PaletteViewFactory.class.isAssignableFrom(theClass)) {
527                        if (!moduleListPaletteView.contains(theName))
528                            moduleListPaletteView.add(theName);
529                        log.trace("loadExtClass: PaletteViewFactory class {}", theName);
530                    }
531                }
532            }
533            catch (Exception ex) {
534                log.debug("loadExtClass: load classList[{}] of {} failed", i, theName, ex);
535            }
536        } //  (int i=0; i<n; i++)
537
538        return extClassLoader;
539    }
540
541    /** @return the Folder Close Icon */
542    public static Image getFoldercloseIcon() {
543        return foldercloseIcon;
544    }
545
546    /** @return the Folder Close with Attribute Icon */
547    public static Image getFoldercloseIconA() {
548        return foldercloseIconA;
549    }
550
551    /** @return the Folder Open Icon */
552    public static Image getFolderopenIcon() {
553        return folderopenIcon;
554    }
555
556    /** @return the Folder Open with Attribute Icon */
557    public static Image getFolderopenIconA() {
558        return folderopenIconA;
559    }
560
561    /** @return the HDF Icon */
562    public static Image getHdfIcon() {
563        return hdfIcons[1];
564    }
565
566    /** @return the HDF Icons */
567    public static Image[] getHdfIcons() {
568        return hdfIcons;
569    }
570
571    /** @return the HDF4 Icon */
572    public static Image getH4Icon() {
573        return h4Icon;
574    }
575
576    /** @return the read-only HDF4 Icon */
577    public static Image getH4IconR() {
578        return h4IconR;
579    }
580
581    /** @return the HDF5 Icon */
582    public static Image getH5Icon() {
583        return h5Icon;
584    }
585
586    /** @return the read-only HDF5 Icon */
587    public static Image getH5IconR() {
588        return h5IconR;
589    }
590
591    /** @return the netcdf Icon */
592    public static Image getNC3Icon() {
593        return ncIcon;
594    }
595
596    /** @return the read-only netcdf Icon */
597    public static Image getNC3IconR() {
598        return ncIconR;
599    }
600
601    /** @return the Dataset Icon */
602    public static Image getDatasetIcon() {
603        return datasetIcon;
604    }
605
606    /** @return the Dataset with Attribute Icon */
607    public static Image getDatasetIconA() {
608        return datasetIconA;
609    }
610
611    /** @return the Datatype Icon */
612    public static Image getDatatypeIcon() {
613        return datatypeIcon;
614    }
615
616    /** @return the Datatype with Attribute Icon */
617    public static Image getDatatypeIconA() {
618        return datatypeIconA;
619    }
620
621    /** @return the Link Icon */
622    public static Image getLinkIcon() {
623        return linkIcon;
624    }
625
626    /** @return the File Open Icon */
627    public static Image getFileopenIcon() {
628        return fileopenIcon;
629    }
630
631    /** @return the File Save Icon */
632    public static Image getFilesaveIcon() {
633        return filesaveIcon;
634    }
635
636    /** @return the File New Icon */
637    public static Image getFilenewIcon() {
638        return filenewIcon;
639    }
640
641    /** @return the File Close Icon */
642    public static Image getFilecloseIcon() {
643        return filecloseIcon;
644    }
645
646    /** @return the Palette Icon */
647    public static Image getPaletteIcon() {
648        return paletteIcon;
649    }
650
651    /** @return the Bright Icon */
652    public static Image getBrightIcon() {
653        return brightIcon;
654    }
655
656    /** @return the Autocontrast Icon */
657    public static Image getAutocontrastIcon() {
658        return autocontrastIcon;
659    }
660
661    /** @return the Image Icon */
662    public static Image getImageIcon() {
663        return imageIcon;
664    }
665
666    /** @return the Table Icon */
667    public static Image getTableIcon() {
668        return tableIcon;
669    }
670
671    /** @return the Text Icon */
672    public static Image getTextIcon() {
673        return textIcon;
674    }
675
676    /** @return the Image with Attribute Icon */
677    public static Image getImageIconA() {
678        return imageIconA;
679    }
680
681    /** @return the Table with Attribute Icon */
682    public static Image getTableIconA() {
683        return tableIconA;
684    }
685
686    /** @return the Text with Attribute Icon */
687    public static Image getTextIconA() {
688        return textIconA;
689    }
690
691    /** @return the Zoom In Icon */
692    public static Image getZoominIcon() {
693        return zoominIcon;
694    }
695
696    /** @return the Zoom Out Icon */
697    public static Image getZoomoutIcon() {
698        return zoomoutIcon;
699    }
700
701    /** @return the Blank Icon */
702    public static Image getBlankIcon() {
703        return blankIcon;
704    }
705
706    /** @return the Help Icon */
707    public static Image getHelpIcon() {
708        return helpIcon;
709    }
710
711    /** @return the Copy Icon */
712    public static Image getCopyIcon() {
713        return copyIcon;
714    }
715
716    /** @return the Cut Icon */
717    public static Image getCutIcon() {
718        return cutIcon;
719    }
720
721    /** @return the Paste Icon */
722    public static Image getPasteIcon() {
723        return pasteIcon;
724    }
725
726    /** @return the HDFView Icon */
727    public static Image getHDFViewIcon() {
728        return hdfviewIcon;
729    }
730
731    /** @return the Large HDF Icon */
732    public static Image getLargeHdfIcon() {
733        return hdfIcons[2];
734    }
735
736    /** @return the Previous Icon */
737    public static Image getPreviousIcon() {
738        return previousIcon;
739    }
740
741    /** @return the Next Icon */
742    public static Image getNextIcon() {
743        return nextIcon;
744    }
745
746    /** @return the First Icon */
747    public static Image getFirstIcon() {
748        return firstIcon;
749    }
750
751    /** @return the Last Icon */
752   public static Image getLastIcon() {
753        return lastIcon;
754    }
755
756    /** @return the Chart Icon */
757    public static Image getChartIcon() {
758        return chartIcon;
759    }
760
761    /** @return the Animation Icon */
762    public static Image getAnimationIcon() {
763        return animationIcon;
764    }
765
766    /** @return the Apps Icon */
767    public static Image getAppsIcon() {
768        return iconAPPS;
769    }
770
771    /** @return the Url Icon */
772    public static Image getUrlIcon() {
773        return iconURL;
774    }
775
776    /** @return the Video Icon */
777    public static Image getVideoIcon() {
778        return iconVIDEO;
779    }
780
781    /** @return the Xls Icon */
782    public static Image getXlsIcon() {
783        return iconXLS;
784    }
785
786    /** @return the Pdf Icon */
787    public static Image getPdfIcon() {
788        return iconPDF;
789    }
790
791    /** @return the Audio Icon */
792    public static Image getAudioIcon() {
793        return iconAUDIO;
794    }
795
796    /** @return the Question Icon */
797    public static Image getQuestionIcon() {
798        return questionIcon;
799    }
800
801    /** Load the Icons */
802    public static void loadIcons() {
803        InputStream s = null;
804        // load icon images
805        try {
806            s = ViewProperties.class.getResourceAsStream("icons/hdfview.gif");
807            hdfviewIcon = new Image(null, s);
808        }
809        catch (Exception ex) {
810            hdfviewIcon = null;
811            log.trace("hdfviewIcon: null");
812        }
813
814        try {
815            s = ViewProperties.class.getResourceAsStream("icons/hdfview16.png");
816            hdfIcons[0] = new Image(null, s);            
817        }
818        catch (Exception ex) {
819            hdfIcons[0] = null;
820            log.trace("hdfIcons[0]: null");
821        }
822
823        try {
824            s = ViewProperties.class.getResourceAsStream("icons/hdfview32.png");
825            hdfIcons[1] = new Image(null, s);
826        }
827        catch (Exception ex) {
828            hdfIcons[1] = null;
829            log.trace("hdfIcons[1]: null");
830        }
831
832        try {
833            s = ViewProperties.class.getResourceAsStream("icons/hdfview64.png");
834            hdfIcons[2] = new Image(null, s);
835        }
836        catch (Exception ex) {
837            hdfIcons[2] = null;
838            log.trace("hdfIcons[3]: null");
839        }
840
841        try {
842            s = ViewProperties.class.getResourceAsStream("icons/hdfview128.png");
843            hdfIcons[3] = new Image(null, s);
844        }
845        catch (Exception ex) {
846            hdfIcons[3] = null;
847            log.trace("hdfIcons[3]: null");
848        }
849
850        try {
851            s = ViewProperties.class.getResourceAsStream("icons/hdfview512.png");
852            hdfIcons[4] = new Image(null, s);
853        }
854        catch (Exception ex) {
855            hdfIcons[4] = null;
856            log.trace("hdfIcons[4]: null");
857        }
858
859        try {
860            s = ViewProperties.class.getResourceAsStream("icons/hdfview1024.png");
861            hdfIcons[5] = new Image(null, s);
862        }
863        catch (Exception ex) {
864            hdfIcons[5] = null;
865            log.trace("hdfIcons[5]: null");
866        }
867
868        try {
869            s = ViewProperties.class.getResourceAsStream("icons/hdf4.gif");
870            h4Icon = new Image(null, s);
871        }
872        catch (Exception ex) {
873            h4Icon = null;
874            log.trace("h4Icon: null");
875        }
876
877        try {
878            s = ViewProperties.class.getResourceAsStream("icons/hdf4R.gif");
879            h4IconR = new Image(null, s);
880        }
881        catch (Exception ex) {
882            h4IconR = null;
883            log.trace("h4IconR: null");
884        }
885
886        try {
887            s = ViewProperties.class.getResourceAsStream("icons/hdf5.gif");
888            h5Icon = new Image(null, s);
889        }
890        catch (Exception ex) {
891            h5Icon = null;
892            log.trace("h5Icon: null");
893        }
894
895        try {
896            s = ViewProperties.class.getResourceAsStream("icons/hdf5R.gif");
897            h5IconR = new Image(null, s);
898        }
899        catch (Exception ex) {
900            h5IconR = null;
901            log.trace("h5IconR: null");
902        }
903
904        try {
905            s = ViewProperties.class.getResourceAsStream("icons/hdfnc.gif");
906            ncIcon = new Image(null, s);
907        }
908        catch (Exception ex) {
909            ncIcon = null;
910            log.trace("ncIcon: null");
911        }
912
913        try {
914            s = ViewProperties.class.getResourceAsStream("icons/hdfncR.gif");
915            ncIconR = new Image(null, s);
916        }
917        catch (Exception ex) {
918            ncIconR = null;
919            log.trace("ncIconR: null");
920        }
921
922        try {
923            s = ViewProperties.class.getResourceAsStream("icons/folderclose.gif");
924            foldercloseIcon = new Image(null, s);
925        }
926        catch (Exception ex) {
927            foldercloseIcon = null;
928            log.trace("foldercloseIcon: null");
929        }
930
931        try {
932            s = ViewProperties.class.getResourceAsStream("icons/foldercloseA.gif");
933            foldercloseIconA = new Image(null, s);
934        }
935        catch (Exception ex) {
936            foldercloseIconA = null;
937            log.trace("foldercloseIconA: null");
938        }
939
940        try {
941            s = ViewProperties.class.getResourceAsStream("icons/folderopen.gif");
942            folderopenIcon = new Image(null, s);
943        }
944        catch (Exception ex) {
945            folderopenIcon = null;
946            log.trace("folderopenIcon: null");
947        }
948
949        try {
950            s = ViewProperties.class.getResourceAsStream("icons/folderopenA.gif");
951            folderopenIconA = new Image(null, s);
952        }
953        catch (Exception ex) {
954            folderopenIconA = null;
955            log.trace("folderopenIconA: null");
956        }
957
958        try {
959            s = ViewProperties.class.getResourceAsStream("icons/dataset.gif");
960            datasetIcon = new Image(null, s);
961        }
962        catch (Exception ex) {
963            datasetIcon = null;
964            log.trace("datasetIcon: null");
965        }
966
967        try {
968            s = ViewProperties.class.getResourceAsStream("icons/datasetA.gif");
969            datasetIconA = new Image(null, s);
970        }
971        catch (Exception ex) {
972            datasetIconA = null;
973            log.trace("datasetIconA: null");
974        }
975
976        try {
977            s = ViewProperties.class.getResourceAsStream("icons/datatype.gif");
978            datatypeIcon = new Image(null, s);
979        }
980        catch (Exception ex) {
981            datatypeIcon = null;
982            log.trace("datatypeIcon: null");
983        }
984
985        try {
986            s = ViewProperties.class.getResourceAsStream("icons/datatypeA.gif");
987            datatypeIconA = new Image(null, s);
988        }
989        catch (Exception ex) {
990            datatypeIconA = null;
991            log.trace("datatypeIconA: null");
992        }
993
994        try {
995            s = ViewProperties.class.getResourceAsStream("icons/link.gif");
996            linkIcon = new Image(null, s);
997        }
998        catch (Exception ex) {
999            linkIcon = null;
1000            log.trace("linkIcon: null");
1001        }
1002
1003        try {
1004            s = ViewProperties.class.getResourceAsStream("icons/fileopen.gif");
1005            fileopenIcon = new Image(null, s);
1006        }
1007        catch (Exception ex) {
1008            fileopenIcon = null;
1009            log.trace("fileopenIcon: null");
1010        }
1011
1012        try {
1013            s = ViewProperties.class.getResourceAsStream("icons/filesave.gif");
1014            filesaveIcon = new Image(null, s);
1015        }
1016        catch (Exception ex) {
1017            filesaveIcon = null;
1018            log.trace("filesaveIcon: null");
1019        }
1020
1021        try {
1022            s = ViewProperties.class.getResourceAsStream("icons/filenew.gif");
1023            filenewIcon = new Image(null, s);
1024        }
1025        catch (Exception ex) {
1026            filenewIcon = null;
1027            log.trace("filenewIcon: null");
1028        }
1029
1030        try {
1031            s = ViewProperties.class.getResourceAsStream("icons/fileclose.gif");
1032            filecloseIcon = new Image(null, s);
1033        }
1034        catch (Exception ex) {
1035            filecloseIcon = null;
1036            log.trace("filecloseIcon: null");
1037        }
1038
1039        try {
1040            s = ViewProperties.class.getResourceAsStream("icons/palette.gif");
1041            paletteIcon = new Image(null, s);
1042        }
1043        catch (Exception ex) {
1044            paletteIcon = null;
1045            log.trace("paletteIcon: null");
1046        }
1047
1048        try {
1049            s = ViewProperties.class.getResourceAsStream("icons/brightness.gif");
1050            brightIcon = new Image(null, s);
1051        }
1052        catch (Exception ex) {
1053            brightIcon = null;
1054            log.trace("brightIcon: null");
1055        }
1056
1057        try {
1058            s = ViewProperties.class.getResourceAsStream("icons/autocontrast.gif");
1059            autocontrastIcon = new Image(null, s);
1060        }
1061        catch (Exception ex) {
1062            autocontrastIcon = null;
1063            log.trace("autocontrastIcon: null");
1064        }
1065
1066        try {
1067            s = ViewProperties.class.getResourceAsStream("icons/image.gif");
1068            imageIcon = new Image(null, s);
1069        }
1070        catch (Exception ex) {
1071            imageIcon = null;
1072            log.trace("imageIcon: null");
1073        }
1074
1075        try {
1076            s = ViewProperties.class.getResourceAsStream("icons/imageA.gif");
1077            imageIconA = new Image(null, s);
1078        }
1079        catch (Exception ex) {
1080            imageIconA = null;
1081            log.trace("imageIconA: null");
1082        }
1083
1084        try {
1085            s = ViewProperties.class.getResourceAsStream("icons/table.gif");
1086            tableIcon = new Image(null, s);
1087        }
1088        catch (Exception ex) {
1089            tableIcon = null;
1090            log.trace("tableIcon: null");
1091        }
1092
1093        try {
1094            s = ViewProperties.class.getResourceAsStream("icons/tableA.gif");
1095            tableIconA = new Image(null, s);
1096        }
1097        catch (Exception ex) {
1098            tableIconA = null;
1099            log.trace("tableIconA: null");
1100        }
1101
1102        try {
1103            s = ViewProperties.class.getResourceAsStream("icons/text.gif");
1104            textIcon = new Image(null, s);
1105        }
1106        catch (Exception ex) {
1107            textIcon = null;
1108            log.trace("textIcon: null");
1109        }
1110
1111        try {
1112            s = ViewProperties.class.getResourceAsStream("icons/textA.gif");
1113            textIconA = new Image(null, s);
1114        }
1115        catch (Exception ex) {
1116            textIconA = null;
1117            log.trace("textIconA: null");
1118        }
1119
1120        try {
1121            s = ViewProperties.class.getResourceAsStream("icons/zoomin.gif");
1122            zoominIcon = new Image(null, s);
1123        }
1124        catch (Exception ex) {
1125            zoominIcon = null;
1126            log.trace("iconAUzoominIconDIO: null");
1127        }
1128
1129        try {
1130            s = ViewProperties.class.getResourceAsStream("icons/zoomout.gif");
1131            zoomoutIcon = new Image(null, s);
1132        }
1133        catch (Exception ex) {
1134            zoomoutIcon = null;
1135            log.trace("zoomoutIcon: null");
1136        }
1137
1138        try {
1139            s = ViewProperties.class.getResourceAsStream("icons/blank.gif");
1140            blankIcon = new Image(null, s);
1141        }
1142        catch (Exception ex) {
1143            blankIcon = null;
1144            log.trace("blankIcon: null");
1145        }
1146
1147        try {
1148            s = ViewProperties.class.getResourceAsStream("icons/help.gif");
1149            helpIcon = new Image(null, s);
1150        }
1151        catch (Exception ex) {
1152            helpIcon = null;
1153            log.trace("helpIcon: null");
1154        }
1155
1156        try {
1157            s = ViewProperties.class.getResourceAsStream("icons/copy.gif");
1158            copyIcon = new Image(null, s);
1159        }
1160        catch (Exception ex) {
1161            copyIcon = null;
1162            log.trace("copyIcon: null");
1163        }
1164
1165        try {
1166            s = ViewProperties.class.getResourceAsStream("icons/cut.gif");
1167            cutIcon = new Image(null, s);
1168        }
1169        catch (Exception ex) {
1170            cutIcon = null;
1171            log.trace("cutIcon: null");
1172        }
1173
1174        try {
1175            s = ViewProperties.class.getResourceAsStream("icons/paste.gif");
1176            pasteIcon = new Image(null, s);
1177        }
1178        catch (Exception ex) {
1179            pasteIcon = null;
1180            log.trace("pasteIcon: null");
1181        }
1182
1183
1184        try {
1185            s = ViewProperties.class.getResourceAsStream("icons/previous.gif");
1186            previousIcon = new Image(null, s);
1187        }
1188        catch (Exception ex) {
1189            previousIcon = null;
1190            log.trace("previousIcon: null");
1191        }
1192
1193        try {
1194            s = ViewProperties.class.getResourceAsStream("icons/next.gif");
1195            nextIcon = new Image(null, s);
1196        }
1197        catch (Exception ex) {
1198            nextIcon = null;
1199            log.trace("nextIcon: null");
1200        }
1201
1202        try {
1203            s = ViewProperties.class.getResourceAsStream("icons/first.gif");
1204            firstIcon = new Image(null, s);
1205        }
1206        catch (Exception ex) {
1207            firstIcon = null;
1208            log.trace("firstIcon: null");
1209        }
1210
1211        try {
1212            s = ViewProperties.class.getResourceAsStream("icons/last.gif");
1213            lastIcon = new Image(null, s);
1214        }
1215        catch (Exception ex) {
1216            lastIcon = null;
1217            log.trace("lastIcon: null");
1218        }
1219
1220        try {
1221            s = ViewProperties.class.getResourceAsStream("icons/chart.gif");
1222            chartIcon = new Image(null, s);
1223        }
1224        catch (Exception ex) {
1225            chartIcon = null;
1226            log.trace("chartIcon: null");
1227        }
1228
1229        try {
1230            s = ViewProperties.class.getResourceAsStream("icons/animation.gif");
1231            animationIcon = new Image(null, s);
1232        }
1233        catch (Exception ex) {
1234            animationIcon = null;
1235            log.trace("animationIcon: null");
1236        }
1237
1238        try {
1239            s = ViewProperties.class.getResourceAsStream("icons/question.gif");
1240            questionIcon = new Image(null, s);
1241        }
1242        catch (Exception ex) {
1243            questionIcon = null;
1244            log.trace("questionIcon: null");
1245        }
1246
1247        try {
1248            s = ViewProperties.class.getResourceAsStream("icons/audio.gif");
1249            iconAUDIO = new Image(null, s);
1250        }
1251        catch (Exception ex) {
1252            iconAUDIO = null;
1253            log.trace("iconAUDIO: null");
1254        }
1255
1256        try {
1257            s = ViewProperties.class.getResourceAsStream("icons/xls.gif");
1258            iconXLS = new Image(null, s);
1259        }
1260        catch (Exception ex) {
1261            iconXLS = null;
1262            log.trace("iconXLS: null");
1263        }
1264
1265        try {
1266            s = ViewProperties.class.getResourceAsStream("icons/pdf.gif");
1267            iconPDF = new Image(null, s);
1268        }
1269        catch (Exception ex) {
1270            iconPDF = null;
1271            log.trace("iconPDF: null");
1272        }
1273
1274        try {
1275            s = ViewProperties.class.getResourceAsStream("icons/apps.gif");
1276            iconAPPS = new Image(null, s);
1277        }
1278        catch (Exception ex) {
1279            iconAPPS = null;
1280            log.trace("iconAPPS: null");
1281        }
1282
1283        try {
1284            s = ViewProperties.class.getResourceAsStream("icons/url.gif");
1285            iconURL = new Image(null, s);
1286        }
1287        catch (Exception ex) {
1288            iconURL = null;
1289            log.trace("iconURL: null");
1290        }
1291
1292        try {
1293            s = ViewProperties.class.getResourceAsStream("icons/video.gif");
1294            iconVIDEO = new Image(null, s);
1295        }
1296        catch (Exception ex) {
1297            iconVIDEO = null;
1298            log.trace("iconVIDEO: null");
1299        }
1300    }
1301
1302    /**
1303     * Load user properties from property file
1304     *
1305     * @throws IOException
1306     *             if a failure occurred
1307     */
1308    @Override
1309    @SuppressWarnings({ "rawtypes", "unchecked" })
1310    public void load() throws IOException {
1311        super.load();
1312
1313        if (propertyFile == null)
1314            return;
1315
1316        String propVal = null;
1317
1318        // add default module.
1319        log.trace("load user properties: add default modules");
1320        String[] moduleKeys = { "module.treeview", "module.metadataview", "module.tableview",
1321                "module.imageview", "module.paletteview" };
1322        ArrayList[] moduleList = { moduleListTreeView, moduleListMetaDataView, moduleListTableView,
1323                moduleListImageView, moduleListPaletteView };
1324        String[] moduleNames = { DEFAULT_MODULE_TEXT, DEFAULT_MODULE_TEXT, DEFAULT_MODULE_TEXT,
1325                DEFAULT_MODULE_TEXT, DEFAULT_MODULE_TEXT };
1326
1327        // add default implementation of modules
1328        log.trace("load user properties: modules");
1329        for (int i = 0; i < moduleNames.length; i++) {
1330            if (!moduleList[i].contains(moduleNames[i]))
1331                moduleList[i].add(moduleNames[i]);
1332            log.trace("load: add default moduleList[{}] is {}", i, moduleNames[i]);
1333        }
1334        log.trace("load Ext Class modules");
1335        if (extClassLoader == null) loadExtClass();
1336
1337        // set default selection of data views
1338        log.trace("load user properties: set default selection of data views");
1339        for (int i = 0; i < moduleNames.length; i++) {
1340            ArrayList<String> theList = moduleList[i];
1341            propVal = getString(moduleKeys[i]);
1342            if (log.isTraceEnabled()) {
1343                log.trace("load: default theList is {}", Arrays.toString(theList.toArray()));
1344            }
1345
1346            if ((propVal != null) && (propVal.length() > 0)) {
1347                // set default to the module specified in property file
1348                if (theList.size() > 1) {
1349                    if (theList.contains(propVal))
1350                        theList.remove(propVal);
1351                    theList.add(0, propVal);
1352                }
1353                log.trace("load user properties: module[{}]={}", i, propVal);
1354            }
1355            else {
1356                // use default module
1357                if (theList.size() > 1) {
1358                    if (theList.contains(moduleNames[i]))
1359                        theList.remove(moduleNames[i]);
1360                    theList.add(0, moduleNames[i]);
1361                }
1362                log.trace("load user properties: default module[{}]={}", i, moduleNames[i]);
1363            }
1364            if (log.isTraceEnabled()) {
1365                log.trace("load: final theList is {}", Arrays.toString(theList.toArray()));
1366            }
1367        }
1368
1369        // add fileformat modules
1370        log.trace("load user properties: fileformat modules");
1371        String[] localEnum = this.preferenceNames();
1372        String fExt = null;
1373        for (String theKey : localEnum) {
1374            log.trace("load: add prop {}", theKey);
1375            if (theKey.startsWith("module.fileformat")) {
1376                fExt = theKey.substring(18);
1377                try {
1378                    // enables use of JHDF5 in JNLP (Web Start) applications,
1379                    // the system class loader with reflection first.
1380                    String className = getString(theKey);
1381                    Class theClass = null;
1382                    try {
1383                        theClass = Class.forName(className);
1384                    }
1385                    catch (Exception ex) {
1386                        try {
1387                            theClass = extClassLoader.loadClass(className);
1388                        }
1389                        catch (Exception ex2) {
1390                            log.debug("load: extClassLoader.loadClass({}) failed", className, ex2);
1391                        }
1392                    }
1393
1394                    Object theObject = theClass.newInstance();
1395                    if (theObject instanceof FileFormat) {
1396                        FileFormat.addFileFormat(fExt, (FileFormat) theObject);
1397                    }
1398                }
1399                catch (Exception err) {
1400                    log.debug("load: load file format failed", err);
1401                }
1402            }
1403        }
1404
1405        propVal = getString("users.guide");
1406        if (!isDefault("users.guide"))
1407            setUsersGuide(propVal);
1408
1409        propVal = getString("image.contrast");
1410        if (!isDefault("image.contrast"))
1411            setAutoContrast("auto".equalsIgnoreCase(propVal));
1412
1413        setShowImageValue(getBoolean("image.showvalues"));
1414
1415        propVal = getString("file.mode");
1416        if (!isDefault("file.mode"))
1417            setReadOnly("r".equalsIgnoreCase(propVal));
1418
1419        setEarlyLib(getString("lib.lowversion"));
1420
1421        setLateLib(getString("lib.highversion"));
1422
1423        setConvertEnum(getBoolean("enum.conversion"));
1424
1425        setShowRegRefValue(getBoolean("regref.showvalues"));
1426
1427        setIndexBase1(getBoolean("index.base1"));
1428
1429        propVal = getString("data.delimiter");
1430        if (!isDefault("data.delimiter"))
1431            setDataDelimiter(propVal);
1432
1433        propVal = getString("image.origin");
1434        if (!isDefault("image.origin"))
1435            setImageOrigin(propVal);
1436
1437        propVal = getString("h5file.indexType");
1438        if (!isDefault("h5file.indexType"))
1439            setIndexType(propVal);
1440
1441        propVal = getString("h5file.indexOrder");
1442        if (!isDefault("h5file.indexOrder"))
1443            setIndexOrder(propVal);
1444
1445        propVal = getString("h4toh5.converter");
1446        if (!isDefault("h4toh5.converter"))
1447            setH4toH5(propVal);
1448
1449        propVal = getString("work.dir");
1450        if (!isDefault("work.dir"))
1451            setWorkDir(propVal);
1452
1453        propVal = getString("file.extension");
1454        if (!isDefault("file.extension")) {
1455            setFileExtension(propVal);
1456            FileFormat.addFileExtension(fileExt);
1457        }
1458
1459        setTimerRefresh(getInt("timer.refresh"));
1460
1461        setFontSize(getInt("font.size"));
1462
1463        propVal = getString("font.type");
1464        if (!isDefault("font.type"))
1465            setFontType(propVal.trim());
1466
1467        setMaxMembers(getInt("max.members"));
1468
1469        // load the most recent file list from the property file
1470        log.trace("load user properties: most recent file list with {}", getWorkDir());
1471        String theFile = null;
1472        // first entry should be the working dir
1473        recentFiles.add(getWorkDir());
1474        for (int i = 0; i < MAX_RECENT_FILES; i++) {
1475            theFile = getString("recent.file" + i);
1476            if ((theFile != null) && !recentFiles.contains(theFile)) {
1477                if (theFile.startsWith("http://") || theFile.startsWith("ftp://") || (new File(theFile)).exists()) {
1478                    recentFiles.add(theFile);
1479                }
1480            }
1481        }
1482
1483        // load the most recent palette file list from the property file
1484        log.trace("load user properties: most recent palette file list");
1485        for (int i = 0; i < MAX_RECENT_FILES; i++) {
1486            theFile = getString("palette.file" + i);
1487            if (theFile != null) theFile = theFile.trim();
1488
1489            if ((theFile != null && theFile.length() > 0) && !paletteList.contains(theFile)) {
1490                if ((new File(theFile)).exists()) {
1491                    paletteList.add(theFile);
1492                }
1493            }
1494        }
1495    }
1496
1497    /**
1498     * Save user properties into property file
1499     *
1500     * @throws IOException
1501     *             if a failure occurred
1502     */
1503    @Override
1504    public void save() throws IOException {
1505        if (propertyFile == null)
1506            return;
1507
1508        // update data saving options
1509        if (delimiter == null)
1510            setDefault("data.delimiter", DELIMITER_TAB);
1511        else
1512            setValue("data.delimiter", delimiter);
1513
1514        if (origin == null)
1515            setDefault("image.origin", ORIGIN_UL);
1516        else
1517            setValue("image.origin", origin);
1518
1519        if (indexType != null) setValue("h5file.indexType", indexType);
1520
1521        if (indexOrder != null) setValue("h5file.indexOrder", indexOrder);
1522
1523        if (usersGuide != null) setValue("users.guide", usersGuide);
1524
1525        if (workDir != null) setValue("work.dir", workDir);
1526
1527        if (fileExt != null) setValue("file.extension", fileExt);
1528
1529        if (h4toh5 != null) setValue("h4toh5.converter", h4toh5);
1530
1531        setValue("timer.refresh", timerRefresh);
1532
1533        setValue("font.size", fontSize);
1534
1535        if (fontType != null) setValue("font.type", fontType);
1536
1537        setValue("max.members", maxMembers);
1538
1539        if (isAutoContrast)
1540            setValue("image.contrast", "auto");
1541        else
1542            setValue("image.contrast", "general");
1543
1544        setValue("image.showvalues", showImageValues);
1545
1546        if (isReadOnly)
1547            setValue("file.mode", "r");
1548        else if (isReadSWMR)
1549            setValue("file.mode", "rs");
1550        else
1551            setValue("file.mode", "rw");
1552
1553        log.trace("save user properties: lib.lowversion={}", EarlyLib);
1554        setValue("lib.lowversion", EarlyLib);
1555        log.trace("save user properties: lib.highversion={}", LateLib);
1556        setValue("lib.highversion", LateLib);
1557
1558        setValue("enum.conversion", convertEnum);
1559        setValue("regref.showvalues", showRegRefValues);
1560        setValue("index.base1", isIndexBase1);
1561
1562        // save the list of most recent files
1563        log.trace("save user properties: most recent files");
1564        String theFile;
1565        int size = recentFiles.size();
1566        int minSize = Math.min(size, MAX_RECENT_FILES);
1567        log.trace("save user properties: most recent files size={}", size);
1568        // The first entry is always the working dir
1569        for (int i = 0; i < minSize - 1; i++) {
1570            theFile = recentFiles.get(i+1);
1571            log.trace("save user properties: save recent file={}", theFile);
1572            if ((theFile != null) && (theFile.length() > 0)) setValue("recent.file" + i, theFile);
1573        }
1574
1575        // save the list of most recent palette files
1576        log.trace("save user properties: most recent palette files");
1577        size = paletteList.size();
1578        minSize = Math.min(size, MAX_RECENT_FILES);
1579        for (int i = 0; i < minSize; i++) {
1580            theFile = paletteList.get(i);
1581            if ((theFile != null) && (theFile.length() > 0)) setValue("palette.file" + i, theFile);
1582        }
1583
1584        // save default modules
1585        log.trace("save user properties: default modules");
1586        String moduleName = moduleListTreeView.get(0);
1587        if ((moduleName != null) && (moduleName.length() > 0)) setValue("module.treeview", moduleName);
1588        log.trace("save user properties: module.treeview={}", moduleName);
1589
1590        moduleName = moduleListMetaDataView.get(0);
1591        if ((moduleName != null) && (moduleName.length() > 0)) setValue("module.metadataview", moduleName);
1592        log.trace("save user properties: module.metadataview={}", moduleName);
1593
1594        moduleName = moduleListTableView.get(0);
1595        if ((moduleName != null) && (moduleName.length() > 0)) setValue("module.tableview", moduleName);
1596        log.trace("save user properties: module.tableview={}", moduleName);
1597
1598        moduleName = moduleListImageView.get(0);
1599        if ((moduleName != null) && (moduleName.length() > 0)) setValue("module.imageview", moduleName);
1600        log.trace("save user properties: module.imageview={}", moduleName);
1601
1602        moduleName = moduleListPaletteView.get(0);
1603        if ((moduleName != null) && (moduleName.length() > 0)) setValue("module.paletteview", moduleName);
1604        log.trace("save user properties: module.paletteview={}", moduleName);
1605
1606        // save the current supported fileformat
1607        log.trace("save user properties: supported fileformat");
1608        Enumeration<?> keys = FileFormat.getFileFormatKeys();
1609        String theKey = null;
1610        while (keys.hasMoreElements()) {
1611            theKey = (String) keys.nextElement();
1612            FileFormat theformat = FileFormat.getFileFormat(theKey);
1613            setValue("module.fileformat." + theKey, theformat.getClass().getName());
1614        }
1615
1616        super.save();
1617    }
1618
1619    /** @return the name of the user property file */
1620    public static String getPropertyFile() {
1621        return propertyFile;
1622    }
1623
1624    /** @return the root directory where the HDFView is installed. */
1625    public static String getViewRoot() {
1626        return rootDir;
1627    }
1628
1629    /** @return the default work directory, where the open file starts. */
1630    public static String getWorkDir() {
1631        String workPath = workDir;
1632        log.trace("getWorkDir: workDir={}", workDir);
1633        if (workPath == null) {
1634            workPath = System.getProperty("hdfview.workdir");
1635            log.trace("getWorkDir: hdfview.workdir={}", workPath);
1636            if (workPath == null) {
1637                workPath = System.getProperty("user.dir");
1638            }
1639        }
1640        log.trace("getWorkDir: final workPath={}", workPath);
1641        return workPath;
1642    }
1643
1644    /** @return the maximum number of the most recent file */
1645    public static int getMaxRecentFiles() {
1646        return MAX_RECENT_FILES;
1647    }
1648
1649    /** @return the path of the HDFView users guide */
1650    public static String getUsersGuide() {
1651        return usersGuide;
1652    };
1653
1654    /** @return the delimiter of data values */
1655    public static String getDataDelimiter() {
1656        return delimiter;
1657    }
1658
1659    /** @return the image origin */
1660    public static String getImageOrigin() {
1661        return origin;
1662    }
1663
1664    /** @return the default index type for display */
1665    public static String getIndexType() {
1666        return indexType;
1667    }
1668
1669    /** @return the default index order for display */
1670    public static String getIndexOrder() {
1671        return indexOrder;
1672    }
1673
1674    /** @return the timer refresh size */
1675    public static int getTimerRefresh() {
1676        return timerRefresh;
1677    }
1678
1679    /** sets the timer refresh
1680     *
1681     * @param trefresh
1682     *            the timer refresh
1683     */
1684    public static void setTimerRefresh(int trefresh) {
1685        timerRefresh = trefresh;
1686    }
1687
1688    /** @return the font size */
1689    public static int getFontSize() {
1690        return fontSize;
1691    }
1692
1693    /** @return the font type */
1694    public static String getFontType() {
1695        return fontType;
1696    }
1697
1698    /** @return the file extensions of supported file formats */
1699    public static String getFileExtension() {
1700        return fileExt;
1701    }
1702
1703    /** sets the font size
1704     *
1705     * @param fsize
1706     *            the font size
1707     */
1708    public static void setFontSize(int fsize) {
1709        fontSize = (fsize / 2) * 2;
1710
1711        if (fontSize < 8) {
1712            fontSize = 8;
1713        }
1714    }
1715
1716    /** sets the font type
1717     *
1718     * @param ftype
1719     *            the font type
1720     */
1721    public static void setFontType(String ftype) {
1722        if (ftype != null) {
1723            fontType = ftype.trim();
1724        }
1725    }
1726
1727    /** @return the path of the H5toH5 converter */
1728    public static String getH4toH5() {
1729        return h4toh5;
1730    }
1731
1732    /** @return the list of most recent files */
1733    public static List<String> getMRF() {
1734        return recentFiles;
1735    }
1736
1737    /** @return the list of palette files */
1738    public static List<String> getPaletteList() {
1739        return paletteList;
1740    }
1741
1742    /** @return the SRB account list */
1743    public static List<String[]> getSrbAccount() {
1744        return srbAccountList;
1745    }
1746
1747    /** @return a list of treeview modules */
1748    public static List<String> getTreeViewList() {
1749        return moduleListTreeView;
1750    }
1751
1752    /** @return a list of metadataview modules */
1753    public static List<String> getMetaDataViewList() {
1754        return moduleListMetaDataView;
1755    }
1756
1757    /** @return a list of tableview modules */
1758    public static List<String> getTableViewList() {
1759        return moduleListTableView;
1760    }
1761
1762    /** @return a list of imageview modules */
1763    public static List<String> getImageViewList() {
1764        return moduleListImageView;
1765    }
1766
1767    /** @return a list of paletteview modules */
1768    public static List<String> getPaletteViewList() {
1769        return moduleListPaletteView;
1770    }
1771
1772    /** @return a list of helpview modules */
1773    public static List<String> getHelpViewList() {
1774        return moduleListHelpView;
1775    }
1776
1777    /** set the path of H5View User's guide
1778     *
1779     * @param str
1780     *            the path
1781     */
1782    public static void setUsersGuide(String str) {
1783        if ((str == null) || (str.length() <= 0)) {
1784            return;
1785        }
1786        usersGuide = str;
1787    }
1788
1789    /** set the path of the H4 to H5 converter
1790     *
1791     * @param tool
1792     *            the path of the H4 to H5 converter
1793     */
1794    public static void setH4toH5(String tool) {
1795        h4toh5 = tool;
1796    }
1797
1798    /**
1799     * set the path of the default root directory
1800     *
1801     * @param rDir
1802     *            the default root directory
1803     */
1804    public static void setRootDir(String rDir) {
1805        log.trace("ViewProperties:setRootDir rDir={}", rDir);
1806        rootDir = rDir;
1807    }
1808
1809    /** set the path of the default work directory
1810     *
1811     * @param wDir
1812     *            the default work directory
1813     */
1814    public static void setWorkDir(String wDir) {
1815        log.trace("ViewProperties:setWorkDir wDir={}", wDir);
1816        workDir = wDir;
1817    }
1818
1819    /** set the file extension
1820     *
1821     * @param ext
1822     *            the file extension
1823     */
1824    public static void setFileExtension(String ext) {
1825        fileExt = ext;
1826    }
1827
1828    /** set the delimiter of data values
1829     *
1830     * @param delim
1831     *            the delimiter of data values
1832     */
1833    public static void setDataDelimiter(String delim) {
1834        delimiter = delim;
1835    }
1836
1837    /** set the image origin
1838     *
1839     * @param o
1840     *            the image origin
1841     */
1842    public static void setImageOrigin(String o) {
1843        origin = o;
1844    }
1845
1846    /** set the index type
1847     *
1848     * @param idxType
1849     *            the index type
1850     */
1851    public static void setIndexType(String idxType) {
1852        indexType = idxType;
1853    }
1854
1855    /** set the index order
1856     *
1857     * @param idxOrder
1858     *            the index order
1859     */
1860    public static void setIndexOrder(String idxOrder) {
1861        indexOrder = idxOrder;
1862    }
1863
1864    /**
1865     * Current Java applications such as HDFView cannot handle files with large
1866     * number of objects such as 1,000,000 objects. setMaxMembers() sets the
1867     * maximum number of objects that will be loaded into memory.
1868     *
1869     * @param n
1870     *            the maximum number of objects to load into memory
1871     */
1872    public static void setMaxMembers(int n) {
1873        maxMembers = n;
1874    }
1875
1876    /**
1877     * Current Java applications such as HDFView cannot handle files with large
1878     * number of objects such as 1,000,000 objects. setStartMember() sets the
1879     * starting index of objects that will be loaded into memory.
1880     *
1881     * @param idx
1882     *            the maximum number of objects to load into memory
1883     */
1884    public static void setStartMembers(int idx) {
1885        if (idx < 0) {
1886            idx = 0;
1887        }
1888
1889        startMembers = idx;
1890    }
1891
1892    /**
1893     * Current Java applications such as HDFView cannot handle files with large
1894     * number of objects such as 1,000,000 objects. getMaxMembers() returns the
1895     * maximum number of objects that will be loaded into memory.
1896     *
1897     * @return the maximum members
1898     */
1899    public static int getMaxMembers() {
1900        if (maxMembers < 0)
1901            return Integer.MAX_VALUE; // load the whole file
1902
1903        return maxMembers;
1904    }
1905
1906    /**
1907     * Current Java applications such as HDFView cannot handle files with large
1908     * number of objects such as 1,000,000 objects. getStartMembers() returns the
1909     * starting index of objects that will be loaded into memory.
1910     *
1911     * @return the start members
1912     */
1913    public static int getStartMembers() {
1914        return startMembers;
1915    }
1916
1917    /**
1918     * Returns true if auto contrast is used in image processing.
1919     *
1920     * @return true if auto contrast is used in image processing; otherwise,
1921     *         returns false.
1922     */
1923    public static boolean isAutoContrast() {
1924        return isAutoContrast;
1925    }
1926
1927    /**
1928     * Returns true if "show image values" is set.
1929     *
1930     * @return true if "show image values" is set; otherwise, returns false.
1931     */
1932    public static boolean showImageValues() {
1933        return showImageValues;
1934    }
1935
1936    /**
1937     * Set the flag to indicate if auto contrast is used in image process.
1938     *
1939     * @param b
1940     *            the flag to indicate if auto contrast is used in image
1941     *            process.
1942     */
1943    public static void setAutoContrast(boolean b) {
1944        isAutoContrast = b;
1945    }
1946
1947    /**
1948     * Set the flag to indicate if "show image values" is set.
1949     *
1950     * @param b
1951     *            the flag to indicate if if "show image values" is set.
1952     */
1953    public static void setShowImageValue(boolean b) {
1954        showImageValues = b;
1955    }
1956
1957    /**
1958     * Returns true if default file access is read only.
1959     *
1960     * @return true if default file access is read only; otherwise, returns
1961     *         false.
1962     */
1963    public static boolean isReadOnly() {
1964        return isReadOnly;
1965    }
1966
1967    /**
1968     * Set the flag to indicate if default file access is read only.
1969     *
1970     * @param b
1971     *            the flag to indicate if default file access is read only.
1972     */
1973    public static void setReadOnly(boolean b) {
1974        isReadOnly = b;
1975    }
1976
1977    /**
1978     * Returns true if default file access is read SWMR.
1979     *
1980     * @return true if default file access is read SWMR; otherwise, returns
1981     *         false.
1982     */
1983    public static boolean isReadSWMR() {
1984        return isReadSWMR;
1985    }
1986
1987    /**
1988     * Set the flag to indicate if default file access is read SWMR.
1989     *
1990     * @param b
1991     *            the flag to indicate if default file access is read SWMR.
1992     */
1993    public static void setReadSWMR(boolean b) {
1994        isReadSWMR = b;
1995    }
1996
1997    /**
1998     * Returns value of default lib version for the earliest.
1999     *
2000     * @return value of default lib version for the earliest.
2001     */
2002    public static String getEarlyLib() {
2003        return EarlyLib;
2004    }
2005
2006    /**
2007     * Set the value of default lib version for the earliest.
2008     *
2009     * @param vers
2010     *            the value of default lib version for the earliest.
2011     */
2012    public static void setEarlyLib(String vers) {
2013        EarlyLib = vers;
2014    }
2015
2016    /**
2017     * Returns value of default lib version for the latest.
2018     *
2019     * @return value of default lib version for the latest.
2020     */
2021    public static String getLateLib() {
2022        return LateLib;
2023    }
2024
2025    /**
2026     * Set the value of default lib version for the latest.
2027     *
2028     * @param vers
2029     *            the value of default lib version for the latest.
2030     */
2031    public static void setLateLib(String vers) {
2032        LateLib = vers;
2033    }
2034
2035    /**
2036     * @return the convertEnum
2037     */
2038    public static boolean isConvertEnum() {
2039        return convertEnum;
2040    }
2041
2042    /**
2043     * Returns true if "show regref values" is set.
2044     *
2045     * @return true if "show regref values" is set; otherwise, returns false.
2046     */
2047    public static boolean showRegRefValues() {
2048        return showRegRefValues;
2049    }
2050
2051    /**
2052     * @return the isIndexBase1
2053     */
2054    public static boolean isIndexBase1() {
2055        return isIndexBase1;
2056    }
2057
2058    /**
2059     * @param convertEnum
2060     *            the convertEnum to set
2061     */
2062    public static void setConvertEnum(boolean convertEnum) {
2063        ViewProperties.convertEnum = convertEnum;
2064    }
2065
2066    /**
2067     * Set the flag to indicate if "show RegRef values" is set.
2068     *
2069     * @param b
2070     *            the flag to indicate if if "show RegRef values" is set.
2071     */
2072    public static void setShowRegRefValue(boolean b) {
2073        showRegRefValues = b;
2074    }
2075
2076    /**
2077     * Set the flag to indicate if IndexBase should start at 1.
2078     *
2079     * @param b
2080     *            the flag to indicate if IndexBase should start at 1.
2081     */
2082    public static void setIndexBase1(boolean b) {
2083        ViewProperties.isIndexBase1 = b;
2084    }
2085
2086    /**
2087     * Sets the list of most recently accessed files.
2088     *
2089     * @param recentFilesList
2090     *               The list of most recently accessed files.
2091     */
2092    public static void setRecentFiles(ArrayList<String> recentFilesList) {
2093        recentFiles = recentFilesList;
2094    }
2095}