001 /*
002 * $Id: HRITChooser.java,v 1.18 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 import java.awt.Component;
034 import java.awt.Container;
035 import java.awt.event.ActionEvent;
036 import java.awt.event.ActionListener;
037 import java.beans.PropertyChangeEvent;
038 import java.beans.PropertyChangeListener;
039 import java.io.File;
040 import java.util.ArrayList;
041 import java.util.Collections;
042 import java.util.Vector;
043
044 import javax.swing.JComboBox;
045 import javax.swing.JFileChooser;
046 import javax.swing.JLabel;
047 import javax.swing.JPanel;
048 import javax.swing.filechooser.FileFilter;
049
050 import org.w3c.dom.Element;
051
052 import ucar.unidata.idv.chooser.IdvChooserManager;
053 import ucar.unidata.util.GuiUtils;
054 import edu.wisc.ssec.mcidasv.util.McVGuiUtils;
055
056 public class HRITChooser extends FileChooser {
057
058 private static final long serialVersionUID = 1L;
059
060 private HRITFilter hf = null;
061
062 private JLabel channelLabel = McVGuiUtils.makeLabelRight("Data Channel:");
063
064 /**
065 * Create the chooser with the given manager and xml
066 *
067 * @param mgr The manager
068 * @param root The xml
069 *
070 */
071
072 public HRITChooser(IdvChooserManager mgr, Element root) {
073 super(mgr, root);
074 }
075
076 /**
077 * Make the file chooser
078 *
079 * @param path the initial path
080 *
081 * @return the file chooser
082 */
083
084 protected JFileChooser doMakeFileChooser(String path) {
085 return new HRITFileChooser(path);
086 }
087
088 protected Vector<String> getAvailableHRITTypes(String path) {
089 if (path == null) path = ".";
090
091 ArrayList<String> al = new ArrayList<String>();
092 Vector<String> v = new Vector<String>();
093 File f = new File(path);
094 File [] files = null;
095 if (f.isDirectory()) {
096 files = f.listFiles(
097 new java.io.FileFilter() {
098 public boolean accept(File f) {
099 if ((f.getName().endsWith("__")) && (f.getName().contains("MSG2"))) {
100 return true;
101 } else {
102 return false;
103 }
104 }
105 }
106 );
107 }
108 if (files != null) {
109 for (int i = 0; i < files.length; i++) {
110 String channelStr = files[i].getName().substring(26, 32);
111 if (channelStr.equals("______")) continue;
112 channelStr = channelStr.replace("___", "");
113 if (! al.contains(channelStr)) {
114 al.add(channelStr);
115 }
116 }
117 }
118 Collections.sort(al);
119 for (int i = 0; i < al.size(); i++) {
120 v.add(al.get(i));
121 }
122 return v;
123 }
124
125 public class ImageTypeChooser extends JComboBox implements ActionListener, PropertyChangeListener {
126
127 private static final long serialVersionUID = 1L;
128 JFileChooser jfc = null;
129
130 public ImageTypeChooser(JFileChooser fc, String path) {
131 jfc = fc;
132 Vector<String> availableTypes = getAvailableHRITTypes(path);
133 if (availableTypes.size() == 1 && availableTypes.get(0) == ".") {
134 availableTypes.removeAllElements();
135 }
136 reloadComboBox(availableTypes);
137 addActionListener(this);
138 McVGuiUtils.setComponentWidth(this, McVGuiUtils.Width.DOUBLE);
139 }
140
141 public void actionPerformed(ActionEvent e) {
142 JComboBox cb = (JComboBox) e.getSource();
143 String newFilter = (String) cb.getSelectedItem();
144 HRITFilter hFilter = (HRITFilter) jfc.getFileFilter();
145 hFilter.setExtraFilter(newFilter);
146 jfc.rescanCurrentDirectory();
147 }
148
149 public void reloadComboBox(Vector<String> v) {
150 removeAllItems();
151 if (v != null) {
152 for (int i = 0; i < v.size(); i++) {
153 addItem(v.get(i));
154 }
155 }
156 if (v == null || v.size() == 0) {
157 setEnabled(false);
158 channelLabel.setEnabled(false);
159 }
160 else {
161 setEnabled(true);
162 channelLabel.setEnabled(true);
163 }
164 }
165
166 public void propertyChange(PropertyChangeEvent e) {
167 String prop = e.getPropertyName();
168
169 //If the directory changed, reload the combo box with new image type choices.
170 if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
171 Vector<String> availableTypes = getAvailableHRITTypes(jfc.getCurrentDirectory().getPath());
172 reloadComboBox(availableTypes);
173 }
174
175 }
176
177 }
178
179 /* HRITFilter */
180 public class HRITFilter extends FileFilter {
181
182 String extraFilter = null;
183
184 public HRITFilter(String extraFilter) {
185 super();
186 if (extraFilter != null) {
187 this.extraFilter = extraFilter;
188 }
189 }
190
191 // Accept all directories and all HRIT files.
192 public boolean accept(File f) {
193
194 if (f.isDirectory()) {
195 return true;
196 }
197
198 // XXX TJJ - at present, we are ONLY allowing MSG2 segment data files
199 // through the filter which have already bee Wavelet decompressed
200 // (i.e., they end with __ and not C_ )
201 String fileName = f.getName();
202 if ((fileName.endsWith("__")) && (fileName.contains("MSG2")) && (fileName.length() >= 58)) {
203 if (extraFilter != null) {
204 if (fileName.contains(extraFilter)) {
205 return true;
206 } else {
207 return false;
208 }
209 }
210 } else {
211 return false;
212 }
213 return false;
214
215 }
216
217 //The description of this filter
218 public String getDescription() {
219 return "HRIT Data";
220 }
221
222 // change the additional filter string
223 public void setExtraFilter(String newFilter) {
224 if (newFilter != null) {
225 extraFilter = newFilter;
226 //seenPatterns.clear();
227 }
228 }
229
230 }
231
232 /**
233 * HRITFileChooser, an extension of JFileChooser
234 *
235 * @author Tommy Jasmin
236 */
237
238 public class HRITFileChooser extends JFileChooser {
239
240 /**
241 * default for serializable class
242 */
243 private static final long serialVersionUID = 1L;
244
245 /**
246 * Create the file chooser
247 *
248 * @param path the initial path
249 */
250
251 public HRITFileChooser(String path) {
252 super(path);
253 setControlButtonsAreShown(false);
254 setMultiSelectionEnabled(false);
255 setAcceptAllFileFilterUsed(false);
256 processChildren(this);
257 }
258
259 private void processChildren(Container c) {
260 Component [] components = c.getComponents();
261 if (components != null) {
262 // loop through all components, looking for the JLabel children of
263 // components we want to remove
264 for (int i = 0; i < components.length; i++) {
265 if (components[i] instanceof JLabel) {
266 String text = ((JLabel) components[i]).getText();
267 if (text.equals("File Name:")) {
268 hideChildren((Container) components[i].getParent());
269 continue;
270 }
271 if (text.equals("Files of Type:")) {
272 hideChildren((Container) components[i].getParent());
273 continue;
274 }
275 }
276 // now check this component for any children
277 processChildren((Container) components[i]);
278 }
279 }
280 }
281
282 private void hideChildren(Container c) {
283 Component [] components = c.getComponents();
284 for (int i = 0; i < components.length; i++) {
285 components[i].setVisible(false);
286 }
287 c.setVisible(false);
288 }
289
290 /**
291 * Approve the selection
292 */
293
294 public void approveSelection() {
295 HRITChooser.this.doLoad();
296 }
297
298 /**
299 * Cancel the selection
300 */
301
302 public void cancelSelection() {
303 closeChooser();
304 }
305
306 /**
307 * Set the selected files
308 *
309 * @param selectedFiles the selected files
310 */
311
312 public void setSelectedFiles(File[] selectedFiles) {
313 String channelStr = null;
314 String timeStr = null;
315 if (selectedFiles != null) {
316 for (int i = 0; i < selectedFiles.length; i++) {
317 if (! selectedFiles[i].isDirectory()) {
318 if (selectedFiles[i].getName().length() >= 58) {
319 channelStr = selectedFiles[i].getName().substring(26, 32);
320 timeStr = selectedFiles[i].getName().substring(46, 58);
321 }
322 }
323 }
324 }
325 File curDir = getCurrentDirectory();
326 File [] fileList = curDir.listFiles();
327 String tmpChannel = null;
328 String tmpTime = null;
329 ArrayList<File> matches = new ArrayList<File>();
330 for (int i = 0; i < fileList.length; i++) {
331 if ((fileList[i].getName().endsWith("__")) &&
332 (fileList[i].getName().contains("MSG2")) &&
333 (fileList[i].getName().length() >= 58)) {
334 tmpChannel = fileList[i].getName().substring(26, 32);
335 tmpTime = fileList[i].getName().substring(46, 58);
336 if ((tmpChannel.equals(channelStr)) && (tmpTime.equals(timeStr))) {
337 matches.add(fileList[i]);
338 }
339 }
340 }
341 Collections.sort(matches);
342
343 // make new file array from ArrayList matches
344 File [] fileSet = new File[matches.size()];
345 for (int i = 0; i < matches.size(); i++) {
346 fileSet[i] = (File) matches.get(i);
347 }
348 //super.setSelectedFiles(selectedFiles);
349 super.setSelectedFiles(fileSet);
350 setHaveData( !((selectedFiles == null)
351 || (selectedFiles.length == 0)));
352 }
353 }
354
355 /**
356 * Handle the selection of the set of files
357 *
358 * @param files The files the user chose
359 * @param directory The directory they chose them from
360 * @return True if the file was successful
361 * @throws Exception
362 */
363
364 protected boolean selectFilesInner(File[] files, File directory)
365 throws Exception {
366 if ((files == null) || (files.length == 0)) {
367 userMessage("Please select a file");
368 return false;
369 }
370
371 // only allow selection of files that make sense as a "set"
372 // for now, that means all part of single image for a single channel
373 String channelStr = files[0].getName().substring(26, 32);
374 String timeStr = files[0].getName().substring(46, 58);
375 int prvSegment = -1;
376 int curSegment = -1;
377 for (int i = 0; i < files.length; i++) {
378 try {
379 curSegment = Integer.parseInt(files[i].getName().substring(40, 42));
380 } catch (NumberFormatException nfe) {
381 userMessage("Problem determining image segment number for file: " + files[i].getName());
382 return false;
383 }
384 if (!files[i].getName().substring(26, 32).equals(channelStr)) {
385 userMessage("Selected data must be for a single channel and time");
386 return false;
387 }
388 if (!files[i].getName().substring(46, 58).equals(timeStr)) {
389 userMessage("Selected data must be for a single channel and time");
390 return false;
391 }
392 if (prvSegment >= 0) {
393 if (curSegment != (prvSegment + 1)) {
394 userMessage("Selected data must be a contiguous set of image segment files");
395 return false;
396 }
397 }
398 prvSegment = curSegment;
399 }
400
401 // XXX TJJ - until HRITAdapter can handle the fact that HRV data can
402 // alter geographic coverage in mid-transmission, we deal with this by
403 // only allowing display of HRV segments one at a time.
404
405 // commenting out for now - will deal with it in field selector window
406 /* if (files.length > 1) {
407 int hrvCount = 0;
408 for (int i = 0; i < files.length; i++) {
409 if (files[i].getName().contains("HRV")) {
410 hrvCount++;
411 }
412 if (hrvCount > 1) {
413 userMessage("At present, HRV data can only be displayed one file at a time");
414 return false;
415 }
416 }
417 }*/
418
419 return super.selectFilesInner(files, directory);
420 }
421
422 /**
423 * Get the bottom panel for the chooser
424 * @return the bottom panel
425 */
426
427 protected JPanel getBottomPanel() {
428 // If we don't have a fileChooser yet, this won't do any good
429 // This happens when Unidata's FileChooser is instantiated
430 // We instantiate ours right after that
431 if (fileChooser == null) {
432 return null;
433 }
434
435 ImageTypeChooser itc = new ImageTypeChooser(fileChooser, path);
436 fileChooser.addPropertyChangeListener(itc);
437 JPanel bottomPanel = GuiUtils.left(itc);
438 bottomPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
439
440 return McVGuiUtils.makeLabeledComponent(channelLabel, itc);
441 }
442
443 /**
444 * Get the center panel for the chooser
445 * @return the center panel
446 */
447
448 protected JPanel getCenterPanel() {
449 JPanel centerPanel = super.getCenterPanel();
450
451 fileChooser.setAcceptAllFileFilterUsed(false);
452
453 // see what HRIT data is available in this directory,
454 Vector<String> availableTypes = getAvailableHRITTypes(path);
455 String extraFilter = null;
456 if ((availableTypes != null) && (availableTypes.size() > 0)) {
457 extraFilter = (String) availableTypes.get(0);
458 }
459
460 hf = new HRITFilter(extraFilter);
461 fileChooser.setFileFilter(hf);
462
463 return centerPanel;
464 }
465
466 }