altosui: Add EasyMega v2.0 firmware to release
[fw/altos] / micropeak / MicroPeak.java
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 package org.altusmetrum.micropeak;
20
21 import java.awt.*;
22 import java.awt.event.*;
23 import javax.swing.*;
24 import java.io.*;
25 import java.util.concurrent.*;
26 import java.util.*;
27 import org.altusmetrum.altoslib_13.*;
28 import org.altusmetrum.altosuilib_13.*;
29
30 public class MicroPeak extends MicroFrame implements ActionListener, ItemListener, AltosFilterListener {
31
32         File            filename;
33         AltosGraph      graph;
34         AltosUIEnable   enable;
35         AltosFlightStatsTable   statsTable;
36         MicroRaw        raw;
37         MicroData       data;
38         Container       container;
39         JTabbedPane     pane;
40         static int      number_of_windows;
41
42         MicroPeak SetData(MicroData data) {
43                 MicroPeak       mp = this;
44                 if (this.data != null) {
45                         mp = new MicroPeak();
46                         return mp.SetData(data);
47                 }
48                 this.data = data;
49                 if (data.flight_series == null)
50                         System.out.printf("no data in flight\n");
51                 if (data.flight_stats == null)
52                         System.out.printf("no stats in flight\n");
53                 graph.set_data(data.flight_stats, data.flight_series);
54                 statsTable.set_stats(data.flight_stats);
55                 raw.setData(data);
56                 setTitle(data.name);
57                 return this;
58         }
59
60         void SetName(String name) {
61                 graph.setName(name);
62                 setTitle(name);
63         }
64
65         private static MicroData ReadFile(File filename) throws IOException, FileNotFoundException {
66                 MicroData       data = null;
67                 FileInputStream fis = new FileInputStream(filename);
68                 try {
69                         data = new MicroData((InputStream) fis, filename.getName());
70                         AltosUIPreferences.set_last_logdir(filename);
71                 } catch (MicroData.NonHexcharException nhe) {
72                         data = null;
73                 } catch (MicroData.FileEndedException nhe) {
74                         data = null;
75                 } catch (InterruptedException ie) {
76                         data = null;
77                 } finally {
78                         fis.close();
79                 }
80                 return data;
81         }
82
83         private void OpenFile(File filename) {
84                 try {
85                         SetData(ReadFile(filename));
86                 } catch (FileNotFoundException fne) {
87                         JOptionPane.showMessageDialog(this,
88                                                       fne.getMessage(),
89                                                       "Cannot open file",
90                                                       JOptionPane.ERROR_MESSAGE);
91                 } catch (IOException ioe) {
92                         JOptionPane.showMessageDialog(this,
93                                                       ioe.getMessage(),
94                                                       "File Read Error",
95                                                       JOptionPane.ERROR_MESSAGE);
96                 }
97         }
98
99         private void SelectFile() {
100                 MicroFileChooser        chooser = new MicroFileChooser(this);
101                 File                    file = chooser.runDialog();
102
103                 if (file != null)
104                         OpenFile(file);
105         }
106
107         private void Preferences() {
108                 new AltosUIConfigure(this);
109         }
110
111         private void DownloadData() {
112                 AltosDevice     device = MicroDeviceDialog.show(this);
113
114                 if (device != null)
115                         new MicroDownload(this, device);
116         }
117
118         private void no_data() {
119                         JOptionPane.showMessageDialog(this,
120                                                       "No data available",
121                                                       "No data",
122                                                       JOptionPane.INFORMATION_MESSAGE);
123         }
124
125         private void Save() {
126                 if (data == null) {
127                         no_data();
128                         return;
129                 }
130                 MicroSave       save = new MicroSave (this, data);
131                 if (save.runDialog())
132                         SetName(data.name);
133         }
134
135         private void Export() {
136                 if (data == null) {
137                         no_data();
138                         return;
139                 }
140                 MicroExport     export = new MicroExport (this, data);
141                 export.runDialog();
142         }
143
144         private static void CommandGraph(File file) {
145                 MicroPeak m = new MicroPeak();
146                 m.OpenFile(file);
147         }
148
149         private static void CommandExport(File file) {
150                 try {
151                         MicroData d = ReadFile(file);
152                         if (d != null) {
153                                 File    csv = new File(AltosLib.replace_extension(file.getPath(), ".csv"));
154                                 try {
155                                         System.out.printf ("Export \"%s\" to \"%s\"\n", file.getPath(), csv.getPath());
156                                         MicroExport.export(csv, d);
157                                 } catch (FileNotFoundException fe) {
158                                         System.err.printf("Cannot create file \"%s\" (%s)\n", csv.getName(), fe.getMessage());
159                                 } catch (IOException ie) {
160                                         System.err.printf("Cannot write file \"%s\" (%s)\n", csv.getName(), ie.getMessage());
161                                 }
162                         }
163                 } catch (IOException ie) {
164                         System.err.printf("Cannot read file \"%s\" (%s)\n", file.getName(), ie.getMessage());
165                 }
166         }
167
168         private void Close() {
169                 setVisible(false);
170                 dispose();
171                 --number_of_windows;
172                 if (number_of_windows == 0)
173                         System.exit(0);
174         }
175
176         public void actionPerformed(ActionEvent ev) {
177                 if ("Exit".equals(ev.getActionCommand()))
178                         System.exit(0);
179                 else if ("Close".equals(ev.getActionCommand()))
180                         Close();
181                 else if ("Open".equals(ev.getActionCommand()))
182                         SelectFile();
183                 else if ("Download".equals(ev.getActionCommand()))
184                         DownloadData();
185                 else if ("Export".equals(ev.getActionCommand()))
186                         Export();
187                 else if ("Preferences".equals(ev.getActionCommand()))
188                         Preferences();
189                 else if ("Save a Copy".equals(ev.getActionCommand()))
190                         Save();
191         }
192
193         public void itemStateChanged(ItemEvent e) {
194         }
195
196         /* OSXAdapter interfaces */
197         public void macosx_file_handler(String path) {
198                 CommandGraph(new File(path));
199         }
200
201         public void macosx_quit_handler() {
202                 System.exit(0);
203         }
204
205         public void macosx_preferences_handler() {
206                 Preferences();
207         }
208
209         public void filter_changed(double speed_filter, double accel_filter) {
210                 data.flight_series.set_filter(speed_filter, accel_filter);
211                 graph.filter_changed();
212                 data.flight_stats = new AltosFlightStats(data.flight_series);
213                 statsTable.filter_changed(data.flight_stats);
214         }
215
216         public double speed_filter() {
217                 if (data != null && data.flight_series != null)
218                         return data.flight_series.speed_filter_width;
219                 return 4.0;
220         }
221
222         public double accel_filter() {
223                 if (data != null && data.flight_series != null)
224                         return data.flight_series.accel_filter_width;
225                 return 1.0;
226         }
227
228         public MicroPeak() {
229
230                 ++number_of_windows;
231
232                 register_for_macosx_events();
233
234                 AltosUIPreferences.set_component(this);
235
236                 container = getContentPane();
237                 pane = new JTabbedPane();
238
239                 setTitle("MicroPeak");
240
241                 JMenuBar menuBar = new JMenuBar();
242                 setJMenuBar(menuBar);
243
244                 JMenu fileMenu = new JMenu("File");
245                 menuBar.add(fileMenu);
246
247                 JMenuItem openAction = new JMenuItem("Open");
248                 fileMenu.add(openAction);
249                 openAction.addActionListener(this);
250
251                 JMenuItem downloadAction = new JMenuItem("Download");
252                 fileMenu.add(downloadAction);
253                 downloadAction.addActionListener(this);
254
255                 JMenuItem saveAction = new JMenuItem("Save a Copy");
256                 fileMenu.add(saveAction);
257                 saveAction.addActionListener(this);
258
259                 JMenuItem exportAction = new JMenuItem("Export");
260                 fileMenu.add(exportAction);
261                 exportAction.addActionListener(this);
262
263                 JMenuItem preferencesAction = new JMenuItem("Preferences");
264                 fileMenu.add(preferencesAction);
265                 preferencesAction.addActionListener(this);
266
267                 JMenuItem closeAction = new JMenuItem("Close");
268                 fileMenu.add(closeAction);
269                 closeAction.addActionListener(this);
270
271                 JMenuItem exitAction = new JMenuItem("Exit");
272                 fileMenu.add(exitAction);
273                 exitAction.addActionListener(this);
274
275                 JButton downloadButton = new JButton ("Download");
276                 downloadButton.addActionListener(this);
277                 menuBar.add(downloadButton);
278
279                 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
280                 addWindowListener(new WindowAdapter() {
281                         @Override
282                         public void windowClosing(WindowEvent e) {
283                                 statsTable.tell_closing();
284                                 raw.tell_closing();
285                                 Close();
286                         }
287                 });
288
289                 enable = new AltosUIEnable(this);
290
291                 graph = new AltosGraph(enable);
292                 statsTable = new AltosFlightStatsTable();
293                 raw = new MicroRaw();
294                 pane.add(graph.panel, "Graph");
295                 pane.add(enable, "Configure Graph");
296                 pane.add(statsTable, "Statistics");
297                 JScrollPane scroll = new JScrollPane(raw);
298                 pane.add(scroll, "Raw Data");
299                 pane.doLayout();
300                 pane.validate();
301                 container.add(pane);
302                 container.doLayout();
303                 container.validate();
304                 doLayout();
305                 validate();
306                 Insets i = getInsets();
307                 Dimension ps = pane.getPreferredSize();
308                 ps.width += i.left + i.right;
309                 ps.height += i.top + i.bottom;
310 //              setPreferredSize(ps);
311                 setSize(ps);
312                 setVisible(true);
313         }
314
315         public static void help(int code) {
316                 System.out.printf("Usage: micropeak [OPTION] ... [FILE]...\n");
317                 System.out.printf("  Options:\n");
318                 System.out.printf("    --csv\tgenerate comma separated output for spreadsheets, etc\n");
319                 System.out.printf("    --graph\tgraph a flight\n");
320                 System.exit(code);
321         }
322
323         public static void main(final String[] args) {
324                 boolean opened = false;
325                 boolean graphing = true;
326
327                 try {
328                         UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel());
329                 } catch (Exception e) {
330                 }
331
332                 for (int i = 0; i < args.length; i++) {
333                         if (args[i].equals("--help"))
334                                 help(0);
335                         else if (args[i].equals("--export"))
336                                 graphing = false;
337                         else if (args[i].equals("--graph"))
338                                 graphing = true;
339                         else if (args[i].startsWith("--"))
340                                 help(1);
341                         else {
342                                 File    file = new File(args[i]);
343                                 try {
344                                         if (graphing)
345                                                 CommandGraph(file);
346                                         else
347                                                 CommandExport(file);
348                                         opened = true;
349                                 } catch (Exception e) {
350                                         System.err.printf("Error processing \"%s\": %s %s\n",
351                                                           file.getName(), e.toString(), e.getMessage());
352                                         e.printStackTrace();
353                                 }
354                         }
355                 }
356                 if (!opened)
357                         new MicroPeak();
358         }
359 }