]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/save/GpsSaver.java
Version 7, February 2009
[GpsPrune.git] / tim / prune / save / GpsSaver.java
1 package tim.prune.save;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.FlowLayout;
6 import java.awt.GridLayout;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.io.BufferedReader;
10 import java.io.InputStreamReader;
11 import java.io.OutputStreamWriter;
12
13 import javax.swing.BorderFactory;
14 import javax.swing.BoxLayout;
15 import javax.swing.JButton;
16 import javax.swing.JCheckBox;
17 import javax.swing.JDialog;
18 import javax.swing.JLabel;
19 import javax.swing.JOptionPane;
20 import javax.swing.JPanel;
21 import javax.swing.JProgressBar;
22 import javax.swing.JTextField;
23 import javax.swing.SwingConstants;
24 import javax.swing.event.ChangeEvent;
25 import javax.swing.event.ChangeListener;
26
27 import tim.prune.App;
28 import tim.prune.Config;
29 import tim.prune.ExternalTools;
30 import tim.prune.GenericFunction;
31 import tim.prune.I18nManager;
32
33 /**
34  * Class to manage the loading of GPS data using GpsBabel
35  */
36 public class GpsSaver extends GenericFunction implements Runnable
37 {
38         private boolean _gpsBabelChecked = false;
39         private JDialog _dialog = null;
40         private JTextField _deviceField = null, _formatField = null;
41         private JTextField _trackNameField = null;
42         private JCheckBox _waypointCheckbox = null, _trackCheckbox = null;
43         private JButton _okButton = null;
44         private JProgressBar _progressBar = null;
45         private boolean _cancelled = false;
46
47
48         /**
49          * Constructor
50          * @param inApp app object
51          */
52         public GpsSaver(App inApp)
53         {
54                 super(inApp);
55         }
56
57         /** get name key */
58         public String getNameKey() {
59                 return "function.sendtogps";
60         }
61
62         /**
63          * Open the GUI to select options and start the load
64          */
65         public void begin()
66         {
67                 // Check if gpsbabel looks like it's installed
68                 if (_gpsBabelChecked || ExternalTools.isGpsbabelInstalled()
69                         || JOptionPane.showConfirmDialog(_dialog,
70                                 I18nManager.getText("dialog.gpsload.nogpsbabel"),
71                                 I18nManager.getText(getNameKey()),
72                                 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION)
73                 {
74                         _gpsBabelChecked = true;
75                         // Make dialog window
76                         if (_dialog == null)
77                         {
78                                 _dialog = new JDialog(_parentFrame, I18nManager.getText("function.sendtogps"), true);
79                                 _dialog.setLocationRelativeTo(_parentFrame);
80                                 _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
81                                 _dialog.getContentPane().add(makeDialogComponents());
82                                 _dialog.pack();
83                         }
84                         // Initialise progress bars, buttons
85                         enableOkButton();
86                         setupProgressBar(true);
87                         _dialog.setVisible(true);
88                 }
89         }
90
91
92         /**
93          * @return a panel containing the main dialog components
94          */
95         private JPanel makeDialogComponents()
96         {
97                 JPanel outerPanel = new JPanel();
98                 outerPanel.setLayout(new BorderLayout());
99                 // Main panel with options etc
100                 JPanel mainPanel = new JPanel();
101                 mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
102
103                 // text fields for options
104                 JPanel gridPanel = new JPanel();
105                 gridPanel.setLayout(new GridLayout(0, 2, 10, 3));
106                 JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device"));
107                 deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT);
108                 gridPanel.add(deviceLabel);
109                 _deviceField = new JTextField(Config.getGpsDevice(), 12);
110                 gridPanel.add(_deviceField);
111                 JLabel formatLabel = new JLabel(I18nManager.getText("dialog.gpsload.format"));
112                 formatLabel.setHorizontalAlignment(SwingConstants.RIGHT);
113                 gridPanel.add(formatLabel);
114                 _formatField = new JTextField(Config.getGpsFormat(), 12);
115                 gridPanel.add(_formatField);
116                 JLabel nameLabel = new JLabel(I18nManager.getText("dialog.gpssend.trackname"));
117                 nameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
118                 gridPanel.add(nameLabel);
119                 _trackNameField = new JTextField("", 12);
120                 gridPanel.add(_trackNameField);
121                 gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
122                 gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20));
123                 mainPanel.add(gridPanel);
124
125                 // checkboxes
126                 ChangeListener checkboxListener = new ChangeListener() {
127                         public void stateChanged(ChangeEvent e)
128                         {
129                                 enableOkButton();
130                         }
131                 };
132                 _waypointCheckbox = new JCheckBox(I18nManager.getText("dialog.gpssend.sendwaypoints"), true);
133                 _waypointCheckbox.addChangeListener(checkboxListener);
134                 _waypointCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT);
135                 mainPanel.add(_waypointCheckbox);
136                 _trackCheckbox = new JCheckBox(I18nManager.getText("dialog.gpssend.sendtracks"), true);
137                 _trackCheckbox.addChangeListener(checkboxListener);
138                 _trackCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT);
139                 mainPanel.add(_trackCheckbox);
140
141                 // progress bar (initially invisible)
142                 _progressBar = new JProgressBar(0, 10);
143                 mainPanel.add(_progressBar);
144                 outerPanel.add(mainPanel, BorderLayout.NORTH);
145
146                 // Lower panel with ok and cancel buttons
147                 JPanel buttonPanel = new JPanel();
148                 buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
149                 _okButton = new JButton(I18nManager.getText("button.ok"));
150                 _okButton.addActionListener(new ActionListener() {
151                         public void actionPerformed(ActionEvent e)
152                         {
153                                 // start thread to call gpsbabel
154                                 _cancelled = false;
155                                 new Thread(GpsSaver.this).start();
156                         }
157                 });
158                 buttonPanel.add(_okButton);
159                 JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
160                 cancelButton.addActionListener(new ActionListener() {
161                         public void actionPerformed(ActionEvent e)
162                         {
163                                 _cancelled = true;
164                                 _dialog.dispose();
165                         }
166                 });
167                 buttonPanel.add(cancelButton);
168                 outerPanel.add(buttonPanel, BorderLayout.SOUTH);
169                 return outerPanel;
170         }
171
172
173         /**
174          * @param inStart true if the dialog is restarting
175          */
176         private void setupProgressBar(boolean inStart)
177         {
178                 // set visibility
179                 _progressBar.setVisible(!inStart);
180                 // set indeterminate flags, initial value
181                 _progressBar.setIndeterminate(false);
182                 _progressBar.setValue(0);
183         }
184
185
186         /**
187          * Enable or disable the ok button
188          */
189         private void enableOkButton()
190         {
191                 _okButton.setEnabled(_waypointCheckbox.isSelected() || _trackCheckbox.isSelected());
192         }
193
194
195         /**
196          * Run method for performing tasks in separate thread
197          */
198         public void run()
199         {
200                 _okButton.setEnabled(false);
201                 setupProgressBar(false);
202
203                 _progressBar.setIndeterminate(true);
204                 try
205                 {
206                         callGpsBabel();
207                 }
208                 catch (Exception e)
209                 {
210                         JOptionPane.showMessageDialog(_dialog, e.getMessage(),
211                                 I18nManager.getText("function.sendtogps"), JOptionPane.ERROR_MESSAGE);
212                         _cancelled = true;
213                 }
214
215                 setupProgressBar(true);
216                 enableOkButton();
217
218                 // Close dialog
219                 if (!_cancelled) {
220                         _dialog.dispose();
221                 }
222         }
223
224
225         /**
226          * Execute the call to gpsbabel
227          */
228         private void callGpsBabel() throws Exception
229         {
230                 // Set up command to call gpsbabel
231                 String[] commands = null;
232                 if (_waypointCheckbox.isSelected() && _trackCheckbox.isSelected()) {
233                         // Both waypoints and track points selected
234                         commands = new String[] {"gpsbabel", "-w", "-t", "-i", "gpx", "-f", "-", "-o", _formatField.getText(),
235                                 "-F", _deviceField.getText()};
236                 }
237                 else
238                 {
239                         // Only waypoints OR trackpoints selected
240                         commands = new String[] {"gpsbabel", "-w", "-i", "gpx", "-f", "-", "-o", _formatField.getText(),
241                                 "-F", _deviceField.getText()};
242                         if (_trackCheckbox.isSelected()) {
243                                 commands[1] = "-t";
244                         }
245                 }
246
247                 String errorMessage = "";
248                 Process process = Runtime.getRuntime().exec(commands);
249
250                 String trackName = _trackNameField.getText();
251                 if (trackName == null || trackName.equals("")) {trackName = "prune";}
252                 // Generate the GPX file and send to the GPS
253                 OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream());
254                 GpxExporter.exportData(writer, _app.getTrackInfo().getTrack(), trackName, null, true);
255                 writer.close();
256
257                 // Read the error stream to see if there's a better error message there
258                 BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream()));
259                 String line = null;
260                 String errorMessage2 = "";
261                 while ((line = r.readLine()) != null) {
262                         errorMessage2 += line + "\n";
263                 }
264                 // Close error stream
265                 try {
266                         r.close();
267                 } catch (Exception e) {}
268                 if (errorMessage2.length() > 0) {errorMessage = errorMessage2;}
269                 if (errorMessage.length() > 0) {throw new Exception(errorMessage);}
270         }
271 }