X-Git-Url: https://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fload%2FGpsLoader.java;h=2196e0c3ff29695a13ac72f8abdf3e8bf528dcea;hb=140e9d165f85c3d4f0435a311e091209313faa2a;hp=b803844ea142a0857d997cf8570182779e407032;hpb=52bf9e8686c916be37a26a0b75340393d4478b05;p=GpsPrune.git diff --git a/tim/prune/load/GpsLoader.java b/tim/prune/load/GpsLoader.java index b803844..2196e0c 100644 --- a/tim/prune/load/GpsLoader.java +++ b/tim/prune/load/GpsLoader.java @@ -6,79 +6,88 @@ import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.io.BufferedReader; +import java.io.File; import java.io.InputStreamReader; +import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JTextField; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import tim.prune.App; -import tim.prune.Config; import tim.prune.ExternalTools; +import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.Altitude; +import tim.prune.data.SourceInfo; import tim.prune.load.xml.XmlFileLoader; import tim.prune.load.xml.XmlHandler; +import tim.prune.save.GpxExporter; /** * Class to manage the loading of GPS data using GpsBabel */ -public class GpsLoader implements Runnable +public class GpsLoader extends GenericFunction implements Runnable { - private App _app = null; - private JFrame _parentFrame = null; private boolean _gpsBabelChecked = false; private JDialog _dialog = null; private JTextField _deviceField = null, _formatField = null; private JCheckBox _waypointCheckbox = null, _trackCheckbox = null; + private JCheckBox _saveCheckbox = null; private JButton _okButton = null; - private JProgressBar _waypointProgressBar = null, _trackProgressBar = null; + private JProgressBar _progressBar = null; + private File _saveFile = null; private boolean _cancelled = false; /** * Constructor * @param inApp Application object to inform of data load - * @param inParentFrame parent frame to reference for dialogs */ - public GpsLoader(App inApp, JFrame inParentFrame) + public GpsLoader(App inApp) { - _app = inApp; - _parentFrame = inParentFrame; + super(inApp); } + /** Get the name key */ + public String getNameKey() { + return "function.loadfromgps"; + } /** * Open the GUI to select options and start the load */ - public void openDialog() + public void begin() { // Check if gpsbabel looks like it's installed - if (_gpsBabelChecked || ExternalTools.isGpsbabelInstalled() + if (_gpsBabelChecked || ExternalTools.isToolInstalled(ExternalTools.TOOL_GPSBABEL) || JOptionPane.showConfirmDialog(_dialog, I18nManager.getText("dialog.gpsload.nogpsbabel"), - I18nManager.getText("dialog.gpsload.title"), + I18nManager.getText(getNameKey()), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) { _gpsBabelChecked = true; // Make dialog window if (_dialog == null) { - _dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.gpsload.title"), true); + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); _dialog.setLocationRelativeTo(_parentFrame); _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); _dialog.getContentPane().add(makeDialogComponents()); @@ -86,8 +95,8 @@ public class GpsLoader implements Runnable } // Initialise progress bars, buttons enableOkButton(); - setupProgressBars(true); - _dialog.show(); + setupProgressBar(true); + _dialog.setVisible(true); } } @@ -109,12 +118,21 @@ public class GpsLoader implements Runnable JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device")); deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT); gridPanel.add(deviceLabel); - _deviceField = new JTextField(Config.getGpsDevice(), 12); + _deviceField = new JTextField(Config.getConfigString(Config.KEY_GPS_DEVICE), 12); + _deviceField.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent e) + { + // close dialog if escape pressed + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }); gridPanel.add(_deviceField); JLabel formatLabel = new JLabel(I18nManager.getText("dialog.gpsload.format")); formatLabel.setHorizontalAlignment(SwingConstants.RIGHT); gridPanel.add(formatLabel); - _formatField = new JTextField(Config.getGpsFormat(), 12); + _formatField = new JTextField(Config.getConfigString(Config.KEY_GPS_FORMAT), 12); gridPanel.add(_formatField); gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT); gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20)); @@ -135,11 +153,14 @@ public class GpsLoader implements Runnable _trackCheckbox.addChangeListener(checkboxListener); _trackCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); mainPanel.add(_trackCheckbox); - // progress bars (initially invisible) - _waypointProgressBar = new JProgressBar(0, 10); - mainPanel.add(_waypointProgressBar); - _trackProgressBar = new JProgressBar(0, 10); - mainPanel.add(_trackProgressBar); + // Checkbox for immediately saving to file + _saveCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.save")); + _saveCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_saveCheckbox); + + // progress bar (initially invisible) + _progressBar = new JProgressBar(0, 10); + mainPanel.add(_progressBar); outerPanel.add(mainPanel, BorderLayout.NORTH); // Lower panel with ok and cancel buttons @@ -172,16 +193,13 @@ public class GpsLoader implements Runnable /** * @param inStart true if the dialog is restarting */ - private void setupProgressBars(boolean inStart) + private void setupProgressBar(boolean inStart) { // set visibility - _waypointProgressBar.setVisible(!inStart && _waypointCheckbox.isSelected()); - _trackProgressBar.setVisible(!inStart && _trackCheckbox.isSelected()); + _progressBar.setVisible(!inStart); // set indeterminate flags, initial value - _waypointProgressBar.setIndeterminate(false); - _waypointProgressBar.setValue(0); - _trackProgressBar.setIndeterminate(false); - _trackProgressBar.setValue(0); + _progressBar.setIndeterminate(false); + _progressBar.setValue(0); } @@ -200,45 +218,22 @@ public class GpsLoader implements Runnable public void run() { _okButton.setEnabled(false); - setupProgressBars(false); - if (_waypointCheckbox.isSelected()) + setupProgressBar(false); + if (_waypointCheckbox.isSelected() || _trackCheckbox.isSelected()) { - _waypointProgressBar.setIndeterminate(true); - _trackProgressBar.setIndeterminate(false); + _progressBar.setIndeterminate(true); + _saveFile = null; try { - callGpsBabel(true); + callGpsBabel(); } catch (Exception e) { - JOptionPane.showMessageDialog(_dialog, e.getMessage(), - I18nManager.getText("dialog.gpsload.title"), JOptionPane.ERROR_MESSAGE); + _app.showErrorMessageNoLookup(getNameKey(), e.getMessage()); _cancelled = true; } } - // Exit if cancelled or failed - if (_cancelled) { - setupProgressBars(true); - enableOkButton(); - return; - } - if (_trackCheckbox.isSelected()) - { - _waypointProgressBar.setIndeterminate(false); - _waypointProgressBar.setValue(10); - _trackProgressBar.setIndeterminate(true); - try - { - callGpsBabel(false); - } - catch (Exception e) - { - JOptionPane.showMessageDialog(_dialog, e.getMessage(), - I18nManager.getText("dialog.gpsload.title"), JOptionPane.ERROR_MESSAGE); - _cancelled = true; - } - } - setupProgressBars(true); + setupProgressBar(true); enableOkButton(); // Close dialog @@ -250,46 +245,127 @@ public class GpsLoader implements Runnable /** * Execute the call to gpsbabel and pass the results back to the app - * @param inWaypoints true to get waypoints, false to get track data */ - private void callGpsBabel(boolean inWaypoints) throws Exception + private void callGpsBabel() throws Exception { // Set up command to call gpsbabel - String[] commands = {"gpsbabel", null, "-i", _formatField.getText(), "-f", _deviceField.getText(), "-o", "gpx", "-F", "-"}; - commands[1] = inWaypoints?"-w":"-t"; + final String device = _deviceField.getText().trim(); + final String format = _formatField.getText().trim(); + String[] commands = getCommandArray(device, format); + // Save GPS settings in config + Config.setConfigString(Config.KEY_GPS_DEVICE, device); + Config.setConfigString(Config.KEY_GPS_FORMAT, format); - String errorMessage = ""; + String errorMessage = "", errorMessage2 = ""; XmlHandler handler = null; Process process = Runtime.getRuntime().exec(commands); + String line = null; - // Pass input stream to try to parse the xml - try + if (_saveFile != null) { - XmlFileLoader xmlLoader = new XmlFileLoader(_app, _parentFrame); - SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - saxParser.parse(process.getInputStream(), xmlLoader); - handler = xmlLoader.getHandler(); - if (handler == null) { - errorMessage = "Null handler"; + // data is being saved to file, so need to wait for it to finish + process.waitFor(); + // try to read error message, if any + try { + BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); + while ((line = r.readLine()) != null) { + errorMessage += line + "\n"; + } + // Close error stream + try { + r.close(); + } catch (Exception e) {} } + catch (Exception e) {} // couldn't get error message + + // Trigger it to be loaded by app + if (process.exitValue() == 0) + { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ArrayList fileList = new ArrayList(); + fileList.add(_saveFile); + _app.loadDataFiles(fileList); + } + }); + } + else if (errorMessage.length() > 0) { + throw new Exception(errorMessage); + } + else throw new Exception(I18nManager.getText("error.gpsload.unknown")); } - catch (Exception e) { - errorMessage = e.getMessage(); - } + else + { + // Pass input stream to try to parse the xml + try + { + XmlFileLoader xmlLoader = new XmlFileLoader(_app); + SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); + saxParser.parse(process.getInputStream(), xmlLoader); + handler = xmlLoader.getHandler(); + if (handler == null) { + errorMessage = "Null handler"; + } + } + catch (Exception e) { + errorMessage = e.getMessage(); + } - // Read the error stream to see if there's a better error message there - BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line = null; - String errorMessage2 = ""; - while ((line = r.readLine()) != null) { - errorMessage2 += line + "\n"; + // Read the error stream to see if there's a better error message there + BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); + while ((line = r.readLine()) != null) { + errorMessage2 += line + "\n"; + } + // Close error stream + try { + r.close(); + } catch (Exception e) {} + + if (errorMessage2.length() > 0) {errorMessage = errorMessage2;} + if (errorMessage.length() > 0) {throw new Exception(errorMessage);} + + // Send data back to app + _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), Altitude.Format.METRES, + new SourceInfo(_deviceField.getText(), SourceInfo.FILE_TYPE.GPSBABEL), + handler.getTrackNameList()); } - if (errorMessage2.length() > 0) {errorMessage = errorMessage2;} - if (errorMessage.length() > 0) {throw new Exception(errorMessage);} + } - // Send data back to app - boolean append = _waypointCheckbox.isSelected() && !inWaypoints; - _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), - Altitude.FORMAT_METRES, _deviceField.getText(), append); + + /** + * Get the commands to call + * @param inDevice device name to use + * @param inFormat format to use + * @return String array containing commands + */ + private String[] getCommandArray(String inDevice, String inFormat) + { + String[] commands = null; + final String command = Config.getConfigString(Config.KEY_GPSBABEL_PATH); + final boolean loadWaypoints = _waypointCheckbox.isSelected(); + final boolean loadTrack = _trackCheckbox.isSelected(); + if (loadWaypoints && loadTrack) { + // Both waypoints and track points selected + commands = new String[] {command, "-w", "-t", "-i", inFormat, + "-f", inDevice, "-o", "gpx", "-F", "-"}; + } + else + { + // Only waypoints OR track points selected + commands = new String[] {command, "-w", "-i", inFormat, + "-f", inDevice, "-o", "gpx", "-F", "-"}; + if (loadTrack) { + commands[1] = "-t"; + } + } + // Do we want to save the gpx straight to file? + if (_saveCheckbox.isSelected()) { + // Select file to save to + _saveFile = GpxExporter.chooseGpxFile(_parentFrame); + if (_saveFile != null) { + commands[commands.length-1] = _saveFile.getAbsolutePath(); + } + } + return commands; } }