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());
}
// Initialise progress bars, buttons
enableOkButton();
- setupProgressBars(true);
- _dialog.show();
+ setupProgressBar(true);
+ _dialog.setVisible(true);
}
}
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));
_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
/**
* @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);
}
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
/**
* 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<File> fileList = new ArrayList<File>();
+ 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;
}
}