749d0f64b8f18fbc76698d50dba7e68c97648d0d
[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_12.*;
28 import org.altusmetrum.altosuilib_12.*;
29
30 public class MicroPeak extends MicroFrame implements ActionListener, ItemListener {
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 MicroPeak() {
210
211                 ++number_of_windows;
212
213                 register_for_macosx_events();
214
215                 AltosUIPreferences.set_component(this);
216
217                 container = getContentPane();
218                 pane = new JTabbedPane();
219
220                 setTitle("MicroPeak");
221
222                 JMenuBar menuBar = new JMenuBar();
223                 setJMenuBar(menuBar);
224
225                 JMenu fileMenu = new JMenu("File");
226                 menuBar.add(fileMenu);
227
228                 JMenuItem openAction = new JMenuItem("Open");
229                 fileMenu.add(openAction);
230                 openAction.addActionListener(this);
231
232                 JMenuItem downloadAction = new JMenuItem("Download");
233                 fileMenu.add(downloadAction);
234                 downloadAction.addActionListener(this);
235
236                 JMenuItem saveAction = new JMenuItem("Save a Copy");
237                 fileMenu.add(saveAction);
238                 saveAction.addActionListener(this);
239
240                 JMenuItem exportAction = new JMenuItem("Export");
241                 fileMenu.add(exportAction);
242                 exportAction.addActionListener(this);
243
244                 JMenuItem preferencesAction = new JMenuItem("Preferences");
245                 fileMenu.add(preferencesAction);
246                 preferencesAction.addActionListener(this);
247
248                 JMenuItem closeAction = new JMenuItem("Close");
249                 fileMenu.add(closeAction);
250                 closeAction.addActionListener(this);
251
252                 JMenuItem exitAction = new JMenuItem("Exit");
253                 fileMenu.add(exitAction);
254                 exitAction.addActionListener(this);
255
256                 JButton downloadButton = new JButton ("Download");
257                 downloadButton.addActionListener(this);
258                 menuBar.add(downloadButton);
259
260                 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
261                 addWindowListener(new WindowAdapter() {
262                         @Override
263                         public void windowClosing(WindowEvent e) {
264                                 statsTable.tell_closing();
265                                 raw.tell_closing();
266                                 Close();
267                         }
268                 });
269
270                 enable = new AltosUIEnable();
271
272                 graph = new AltosGraph(enable);
273                 statsTable = new AltosFlightStatsTable();
274                 raw = new MicroRaw();
275                 pane.add(graph.panel, "Graph");
276                 pane.add(enable, "Configure Graph");
277                 pane.add(statsTable, "Statistics");
278                 JScrollPane scroll = new JScrollPane(raw);
279                 pane.add(scroll, "Raw Data");
280                 pane.doLayout();
281                 pane.validate();
282                 container.add(pane);
283                 container.doLayout();
284                 container.validate();
285                 doLayout();
286                 validate();
287                 Insets i = getInsets();
288                 Dimension ps = pane.getPreferredSize();
289                 ps.width += i.left + i.right;
290                 ps.height += i.top + i.bottom;
291 //              setPreferredSize(ps);
292                 setSize(ps);
293                 setVisible(true);
294         }
295
296         public static void help(int code) {
297                 System.out.printf("Usage: micropeak [OPTION] ... [FILE]...\n");
298                 System.out.printf("  Options:\n");
299                 System.out.printf("    --csv\tgenerate comma separated output for spreadsheets, etc\n");
300                 System.out.printf("    --graph\tgraph a flight\n");
301                 System.exit(code);
302         }
303
304         public static void main(final String[] args) {
305                 boolean opened = false;
306                 boolean graphing = true;
307
308                 try {
309                         UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel());
310                 } catch (Exception e) {
311                 }
312
313                 for (int i = 0; i < args.length; i++) {
314                         if (args[i].equals("--help"))
315                                 help(0);
316                         else if (args[i].equals("--export"))
317                                 graphing = false;
318                         else if (args[i].equals("--graph"))
319                                 graphing = true;
320                         else if (args[i].startsWith("--"))
321                                 help(1);
322                         else {
323                                 File    file = new File(args[i]);
324                                 try {
325                                         if (graphing)
326                                                 CommandGraph(file);
327                                         else
328                                                 CommandExport(file);
329                                         opened = true;
330                                 } catch (Exception e) {
331                                         System.err.printf("Error processing \"%s\": %s %s\n",
332                                                           file.getName(), e.toString(), e.getMessage());
333                                         e.printStackTrace();
334                                 }
335                         }
336                 }
337                 if (!opened)
338                         new MicroPeak();
339         }
340 }