001    /*
002     * This file is part of McIDAS-V
003     *
004     * Copyright 2007-2013
005     * Space Science and Engineering Center (SSEC)
006     * University of Wisconsin - Madison
007     * 1225 W. Dayton Street, Madison, WI 53706, USA
008     * https://www.ssec.wisc.edu/mcidas
009     * 
010     * All Rights Reserved
011     * 
012     * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013     * some McIDAS-V source code is based on IDV and VisAD source code.  
014     * 
015     * McIDAS-V is free software; you can redistribute it and/or modify
016     * it under the terms of the GNU Lesser Public License as published by
017     * the Free Software Foundation; either version 3 of the License, or
018     * (at your option) any later version.
019     * 
020     * McIDAS-V is distributed in the hope that it will be useful,
021     * but WITHOUT ANY WARRANTY; without even the implied warranty of
022     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023     * GNU Lesser Public License for more details.
024     * 
025     * You should have received a copy of the GNU Lesser Public License
026     * along with this program.  If not, see http://www.gnu.org/licenses.
027     */
028    
029    package edu.wisc.ssec.mcidasv.chooser;
030    
031    
032    import edu.wisc.ssec.mcidasv.*;
033    
034    import java.awt.*;
035    import java.awt.event.*;
036    
037    import java.io.File;
038    
039    import java.util.ArrayList;
040    import java.util.List;
041    import java.util.Hashtable;
042    import java.util.Vector;
043    
044    import javax.swing.*;
045    import javax.swing.event.*;
046    import javax.swing.filechooser.FileFilter;
047    
048    import org.w3c.dom.Element;
049    
050    import ucar.unidata.data.DataSourceResults;
051    
052    import ucar.unidata.idv.*;
053    
054    import ucar.unidata.idv.chooser.FileChooser;
055    import ucar.unidata.idv.chooser.IdvChooser;
056    import ucar.unidata.idv.chooser.IdvChooserManager;
057    
058    import ucar.unidata.ui.ChooserPanel;
059    
060    import ucar.unidata.util.FileManager;
061    import ucar.unidata.util.GuiUtils;
062    import ucar.unidata.util.PatternFileFilter;
063    import ucar.unidata.util.PreferenceList;
064    import ucar.unidata.util.StringUtil;
065    
066    import ucar.unidata.xml.XmlResourceCollection;
067    import ucar.unidata.xml.XmlUtil;
068    
069    
070    public class HydraChooser extends IdvChooser {
071    
072        private Element chooserNode;
073    
074        private JFileChooser fileChooser;
075    
076        private IntegratedDataViewer idv = getIdv();
077    
078        /**
079         *  The chooser xml can specify a datasourceid attribute.
080         */
081        private String dfltDataSourceId = "HYDRA";
082    
083        /**
084         * Create the chooser with the given manager and xml
085         *
086         * @param mgr The manager
087         * @param root The xml
088         *
089         */
090        public HydraChooser(IdvChooserManager mgr, Element root) {
091            super(mgr, root);
092            this.chooserNode = root;
093        }
094    
095    
096        /**
097         * Get the tooltip for the load button
098         *
099         * @return The tooltip for the load button
100         */
101        protected String getLoadToolTip() {
102            return "";
103        }
104    
105    
106        /**
107         * Get the tooltip for the update button
108         *
109         * @return The tooltip for the update button
110         */
111        protected String getUpdateToolTip() {
112            return "Rescan the directory";
113        }
114    
115    
116        /**
117         * Make the GUI
118         *
119         * @return The GUI for HYDRA Chooser
120         */
121        protected JComponent doMakeContents() {
122            String path = (String) idv.getPreference(PREF_DEFAULTDIR + getId());
123            if (path == null) {
124                path = XmlUtil.getAttribute(this.chooserNode, FileChooser.ATTR_PATH,
125                                            (String) null);
126            }
127            //System.out.println("path=" + path);
128            fileChooser = doMakeFileChooser(path);
129            fileChooser.setPreferredSize(new Dimension(300, 300));
130            fileChooser.setMultiSelectionEnabled(true);
131            fileChooser.setApproveButtonText(ChooserPanel.CMD_LOAD);
132    
133            PatternFileFilter ff = new PatternFileFilter(".hdf", "*.hdf files");
134            //fileChooser.setFileFilter(ff);
135    
136            JComponent chooserPanel = fileChooser;
137            JPanel filePanel = GuiUtils.vbox(chooserPanel, getDefaultButtons());
138            return filePanel;
139        }
140    
141    
142        /**
143         * Make the file chooser
144         *
145         * @param path   the initial path
146         *
147         * @return  the file chooser
148         */
149        protected JFileChooser doMakeFileChooser(String path) {
150            return new MyFileChooser(path);
151        }
152    
153        /**
154         * An extension of JFileChooser
155         *
156         * @author IDV Development Team
157         * @version $Revision$
158         */
159        public class MyFileChooser extends JFileChooser {
160    
161            /**
162             * Create the file chooser
163             *
164             * @param path   the initial path
165             */
166            public MyFileChooser(String path) {
167                super(path);
168                setControlButtonsAreShown(false);
169                setMultiSelectionEnabled(true);
170            }
171    
172            /**
173             * Approve the selection
174             */
175            public void approveSelection() {
176                HydraChooser.this.doLoad();
177            }
178    
179            /**
180             * Cancel the selection
181             */
182            public void cancelSelection() {
183                closeChooser();
184            }
185    
186            /**
187             * Set the selected files
188             *
189             * @param selectedFiles  the selected files
190             */
191            public void setSelectedFiles(File[] selectedFiles) {
192                super.setSelectedFiles(selectedFiles);
193                setHaveData( !((selectedFiles == null)
194                               || (selectedFiles.length == 0)));
195            }
196        }
197    
198    
199        /**
200         * Handle the selection of the set of files
201         *
202         * @param files The files the user chose
203         * @param directory The directory they chose them from
204         */
205        protected final void selectFiles(File[] files, File directory) {
206            try {
207                if (selectFilesInner(files, directory)) {
208                    idv.getStateManager().writePreference(PREF_DEFAULTDIR
209                            + getId(), directory.getPath());
210                }
211            } catch (Exception excp) {
212                logException("File selection", excp);
213            }
214        }
215    
216        /**
217         * Get the file chooser
218         *
219         * @return  the chooser for this instance
220         */
221        protected JFileChooser getFileChooser() {
222            return fileChooser;
223        }
224    
225        /**
226         * Override the base class method to catch the do load
227         */
228        public void doLoadInThread() {
229            selectFiles(fileChooser.getSelectedFiles(),
230                        fileChooser.getCurrentDirectory());
231        }
232    
233    
234    
235        /**
236         * Override the base class method to catch the do update
237         */
238        public void doUpdate() {
239            fileChooser.rescanCurrentDirectory();
240        }
241    
242    
243        /**
244         * Handle the selection of the set of files
245         *
246         * @param files The files the user chose
247         * @param directory The directory they chose them from
248         * @return True if the file was successful
249         * @throws Exception
250         */
251        protected boolean selectFilesInner(File[] files, File directory)
252                throws Exception {
253            if ((files == null) || (files.length == 0)) {
254                userMessage("Please select a file");
255                return false;
256            }
257            FileManager.addToHistory(files[0]);
258            List    selectedFiles      = new ArrayList();
259            String  fileNotExistsError = "";
260            boolean didXidv            = false;
261    
262            for (int i = 0; i < files.length; i++) {
263                if ( !files[i].exists()) {
264                    fileNotExistsError += "File does not exist: " + files[i]
265                                          + "\n";
266                } else {
267                    String filename = files[i].toString();
268                    //Check for the bundle or jnlp file
269                    if (idv.getArgsManager().isXidvFile(filename)
270                            || idv.getArgsManager().isZidvFile(filename)
271                            || idv.getArgsManager().isJnlpFile(filename)) {
272                        didXidv = idv.handleAction(filename, null);
273                    } else {
274                        selectedFiles.add(filename);
275                    }
276                }
277            }
278    
279            if (didXidv) {
280                closeChooser();
281                return true;
282            }
283    
284    
285            if (selectedFiles.size() == 0) {
286                return false;
287            }
288    
289            if (fileNotExistsError.length() > 0) {
290                userMessage(fileNotExistsError);
291                return false;
292            }
293    
294            Object definingObject = selectedFiles;
295            if (selectedFiles.size() == 1) {
296                definingObject = selectedFiles.get(0);
297            }
298    
299            String dataSourceId = getDataSourceId();
300            if (dataSourceId == null) {
301                dataSourceId = dfltDataSourceId;
302            }
303    
304            //If the user specifically selected a data source type then pass all files to that data source and be done.
305            DataSourceResults results;
306            if (dataSourceId == null) {
307                //If they selected one directory then ask if they want to load all the files
308                if (selectedFiles.size() == 1) {
309                    File file = new File(selectedFiles.get(0).toString());
310                    if (file.isDirectory()) {
311                        if ( !GuiUtils.showYesNoDialog(null,
312                                "Do you want to load all of the files in the selected directory: "
313                                + file, "Directory Load")) {
314                            return false;
315                        }
316                        selectedFiles  = new ArrayList();
317                        definingObject = selectedFiles;
318                        File[] subFiles = file.listFiles();
319                        for (int i = 0; i < subFiles.length; i++) {
320                            if ( !subFiles[i].isDirectory()) {
321                                selectedFiles.add(subFiles[i].toString());
322                            }
323                        }
324                    }
325                }
326            }
327    
328            Hashtable   properties  = new Hashtable();
329            return makeDataSource(definingObject, dataSourceId, properties);
330        }
331    
332    
333        /**
334         * Convert the given array of File objects
335         * to an array of String file names. Only
336         * include the files that actually exist.
337         *
338         * @param files Selected files
339         * @return Selected files as Strings
340         */
341        protected String[] getFileNames(File[] files) {
342            if (files == null) {
343                return (String[]) null;
344            }
345            Vector v                  = new Vector();
346            String fileNotExistsError = "";
347    
348            // NOTE:  If multiple files are selected, then missing files
349            // are not in the files array.  If one file is selected and
350            // it is not there, then it is in the array and file.exists()
351            // is false
352            for (int i = 0; i < files.length; i++) {
353                if ((files[i] != null) && !files[i].isDirectory()) {
354                    if ( !files[i].exists()) {
355                        fileNotExistsError += "File does not exist: " + files[i]
356                                              + "\n";
357                    } else {
358                        v.add(files[i].toString());
359                    }
360                }
361            }
362    
363            if (fileNotExistsError.length() > 0) {
364                userMessage(fileNotExistsError);
365                return null;
366            }
367    
368            return v.isEmpty()
369                   ? null
370                   : StringUtil.listToStringArray(v);
371        }
372    }