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