X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fsave%2FGpsSaver.java;fp=src%2Ftim%2Fprune%2Fsave%2FGpsSaver.java;h=6179a5c1346db75b829467e9e4925206776d0232;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/save/GpsSaver.java b/src/tim/prune/save/GpsSaver.java new file mode 100644 index 0000000..6179a5c --- /dev/null +++ b/src/tim/prune/save/GpsSaver.java @@ -0,0 +1,333 @@ +package tim.prune.save; + +import java.awt.BorderLayout; +import java.awt.Component; +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.InputStreamReader; +import java.io.OutputStreamWriter; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +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.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import tim.prune.App; +import tim.prune.ExternalTools; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; + +/** + * Class to manage the loading of GPS data using GpsBabel + */ +public class GpsSaver extends GenericFunction implements Runnable +{ + private boolean _gpsBabelChecked = false; + private JDialog _dialog = null; + private JTextField _deviceField = null, _formatField = null; + private JTextField _trackNameField = null; + private JCheckBox _waypointCheckbox = null, _trackCheckbox = null; + private boolean _switchedWaypointsOff = false, _switchedTrackpointsOff = false; + private JButton _okButton = null; + private JProgressBar _progressBar = null; + private boolean _cancelled = false; + + + /** + * Constructor + * @param inApp app object + */ + public GpsSaver(App inApp) + { + super(inApp); + } + + /** get name key */ + public String getNameKey() { + return "function.sendtogps"; + } + + /** + * Open the GUI to select options and start the load + */ + public void begin() + { + // Check if gpsbabel looks like it's installed + if (_gpsBabelChecked || ExternalTools.isToolInstalled(ExternalTools.TOOL_GPSBABEL) + || JOptionPane.showConfirmDialog(_dialog, + I18nManager.getText("dialog.gpsload.nogpsbabel"), + 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("function.sendtogps"), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // Initialise progress bars, buttons + enableCheckboxes(); + enableOkButton(); + setupProgressBar(true); + _trackNameField.requestFocus(); + _dialog.setVisible(true); + } + } + + + /** + * @return a panel containing the main dialog components + */ + private JPanel makeDialogComponents() + { + JPanel outerPanel = new JPanel(); + outerPanel.setLayout(new BorderLayout()); + // Main panel with options etc + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + // text fields for options + JPanel gridPanel = new JPanel(); + gridPanel.setLayout(new GridLayout(0, 2, 10, 3)); + JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device")); + deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(deviceLabel); + _deviceField = new JTextField(Config.getConfigString(Config.KEY_GPS_DEVICE), 12); + gridPanel.add(_deviceField); + JLabel formatLabel = new JLabel(I18nManager.getText("dialog.gpsload.format")); + formatLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(formatLabel); + _formatField = new JTextField(Config.getConfigString(Config.KEY_GPS_FORMAT), 12); + gridPanel.add(_formatField); + JLabel nameLabel = new JLabel(I18nManager.getText("dialog.gpssend.trackname")); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(nameLabel); + _trackNameField = new JTextField("", 12); + gridPanel.add(_trackNameField); + gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20)); + mainPanel.add(gridPanel); + // close dialog when escape pressed + KeyAdapter closer = new KeyAdapter() { + public void keyReleased(KeyEvent e) + { + // close dialog if escape pressed + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }; + _deviceField.addKeyListener(closer); + _formatField.addKeyListener(closer); + _trackNameField.addKeyListener(closer); + + // checkboxes + ChangeListener checkboxListener = new ChangeListener() { + public void stateChanged(ChangeEvent e) + { + enableOkButton(); + } + }; + _waypointCheckbox = new JCheckBox(I18nManager.getText("dialog.gpssend.sendwaypoints"), true); + _waypointCheckbox.addChangeListener(checkboxListener); + _waypointCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_waypointCheckbox); + _trackCheckbox = new JCheckBox(I18nManager.getText("dialog.gpssend.sendtracks"), true); + _trackCheckbox.addChangeListener(checkboxListener); + _trackCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_trackCheckbox); + + // progress bar (initially invisible) + _progressBar = new JProgressBar(0, 10); + mainPanel.add(_progressBar); + outerPanel.add(mainPanel, BorderLayout.NORTH); + + // Lower panel with ok and cancel buttons + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + _okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + // start thread to call gpsbabel + _cancelled = false; + new Thread(GpsSaver.this).start(); + } + }); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _cancelled = true; + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + outerPanel.add(buttonPanel, BorderLayout.SOUTH); + return outerPanel; + } + + + /** + * @param inStart true if the dialog is restarting + */ + private void setupProgressBar(boolean inStart) + { + // set visibility + _progressBar.setVisible(!inStart); + // set indeterminate flags, initial value + _progressBar.setIndeterminate(false); + _progressBar.setValue(0); + } + + /** + * Enable or disable the waypoints and trackpoints checkboxes + */ + private void enableCheckboxes() + { + // Enable or disable waypoints checkbox depending on whether data is available + if (_waypointCheckbox.isSelected()) + { + if (!_app.getTrackInfo().getTrack().hasWaypoints()) + { + _waypointCheckbox.setSelected(false); + _switchedWaypointsOff = true; + } + else _switchedWaypointsOff = false; + } + else if (_app.getTrackInfo().getTrack().hasWaypoints() && _switchedWaypointsOff) + { + _waypointCheckbox.setSelected(true); + _switchedWaypointsOff = false; + } + // ... and the same for track points + if (_trackCheckbox.isSelected()) + { + if (!_app.getTrackInfo().getTrack().hasTrackPoints()) + { + _trackCheckbox.setSelected(false); + _switchedTrackpointsOff = true; + } + else _switchedTrackpointsOff = false; + } + else if (_app.getTrackInfo().getTrack().hasTrackPoints() && _switchedTrackpointsOff) + { + _trackCheckbox.setSelected(true); + _switchedTrackpointsOff = false; + } + } + + /** + * Enable or disable the ok button + */ + private void enableOkButton() + { + _okButton.setEnabled(_waypointCheckbox.isSelected() || _trackCheckbox.isSelected()); + } + + + /** + * Run method for performing tasks in separate thread + */ + public void run() + { + _okButton.setEnabled(false); + setupProgressBar(false); + + _progressBar.setIndeterminate(true); + try + { + callGpsBabel(); + } + catch (Exception e) + { + JOptionPane.showMessageDialog(_dialog, e.getMessage(), + I18nManager.getText("function.sendtogps"), JOptionPane.ERROR_MESSAGE); + _cancelled = true; + } + + setupProgressBar(true); + enableOkButton(); + + // Close dialog + if (!_cancelled) { + _dialog.dispose(); + } + } + + + /** + * Execute the call to gpsbabel + */ + private void callGpsBabel() throws Exception + { + // Set up command to call gpsbabel + final String command = Config.getConfigString(Config.KEY_GPSBABEL_PATH); + String[] commands = null; + final String device = _deviceField.getText().trim(); + final String format = _formatField.getText().trim(); + if (_waypointCheckbox.isSelected() && _trackCheckbox.isSelected()) { + // Both waypoints and track points selected + commands = new String[] {command, "-w", "-t", "-i", "gpx", "-f", "-", "-o", format, + "-F", device}; + } + else + { + // Only waypoints OR trackpoints selected + commands = new String[] {command, "-w", "-i", "gpx", "-f", "-", "-o", format, + "-F", device}; + if (_trackCheckbox.isSelected()) { + commands[1] = "-t"; + } + } + // Save GPS settings in config + Config.setConfigString(Config.KEY_GPS_DEVICE, device); + Config.setConfigString(Config.KEY_GPS_FORMAT, format); + + String errorMessage = ""; + Process process = Runtime.getRuntime().exec(commands); + + String trackName = _trackNameField.getText(); + if (trackName == null || trackName.equals("")) {trackName = "gpsprune";} + // Generate the GPX file and send to the GPS + OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream()); + SettingsForExport settings = new SettingsForExport(); + settings.setExportMissingAltitudesAsZero(true); + GpxExporter.exportData(writer, _app.getTrackInfo(), trackName, null, settings, null); + writer.close(); + + // 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"; + } + // Close error stream + try { + r.close(); + } catch (Exception e) {} + if (errorMessage2.length() > 0) {errorMessage = errorMessage2;} + if (errorMessage.length() > 0) {throw new Exception(errorMessage);} + } +}