Switch from GPLv2 to GPLv2+
[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_11.*;
28 import org.altusmetrum.altosuilib_11.*;
29
30 public class MicroPeak extends MicroFrame implements ActionListener, ItemListener {
31
32         File            filename;
33         MicroGraph      graph;
34         AltosUIEnable   enable;
35         MicroStatsTable statsTable;
36         MicroRaw        raw;
37         MicroData       data;
38         MicroStats      stats;
39         Container       container;
40         JTabbedPane     pane;
41         static int      number_of_windows;
42
43         MicroPeak SetData(MicroData data) {
44                 MicroPeak       mp = this;
45                 if (this.data != null) {
46                         mp = new MicroPeak();
47                         return mp.SetData(data);
48                 }
49                 this.data = data;
50                 stats = new MicroStats(data);
51                 graph.setDataSet(data);
52                 statsTable.setStats(stats);
53                 raw.setData(data);
54                 setTitle(data.name);
55                 return this;
56         }
57
58         void SetName(String name) {
59                 graph.setName(name);
60                 setTitle(name);
61         }
62
63         private static MicroData ReadFile(File filename) throws IOException, FileNotFoundException {
64                 MicroData       data = null;
65                 FileInputStream fis = new FileInputStream(filename);
66                 try {
67                         data = new MicroData((InputStream) fis, filename.getName());
68                         AltosUIPreferences.set_last_logdir(filename);
69                 } catch (MicroData.NonHexcharException nhe) {
70                         data = null;
71                 } catch (MicroData.FileEndedException nhe) {
72                         data = null;
73                 } catch (InterruptedException ie) {
74                         data = null;
75                 } finally {
76                         fis.close();
77                 }
78                 return data;
79         }
80
81         private void OpenFile(File filename) {
82                 try {
83                         SetData(ReadFile(filename));
84                 } catch (FileNotFoundException fne) {
85                         JOptionPane.showMessageDialog(this,
86                                                       fne.getMessage(),
87                                                       "Cannot open file",
88                                                       JOptionPane.ERROR_MESSAGE);
89                 } catch (IOException ioe) {
90                         JOptionPane.showMessageDialog(this,
91                                                       ioe.getMessage(),
92                                                       "File Read Error",
93                                                       JOptionPane.ERROR_MESSAGE);
94                 }
95         }
96
97         private void SelectFile() {
98                 MicroFileChooser        chooser = new MicroFileChooser(this);
99                 File                    file = chooser.runDialog();
100
101                 if (file != null)
102                         OpenFile(file);
103         }
104
105         private void Preferences() {
106                 new AltosUIConfigure(this);
107         }
108
109         private void DownloadData() {
110                 AltosDevice     device = MicroDeviceDialog.show(this);
111
112                 if (device != null)
113                         new MicroDownload(this, device);
114         }
115
116         private void no_data() {
117                         JOptionPane.showMessageDialog(this,
118                                                       "No data available",
119                                                       "No data",
120                                                       JOptionPane.INFORMATION_MESSAGE);
121         }
122
123         private void Save() {
124                 if (data == null) {
125                         no_data();
126                         return;
127                 }
128                 MicroSave       save = new MicroSave (this, data);
129                 if (save.runDialog())
130                         SetName(data.name);
131         }
132
133         private void Export() {
134                 if (data == null) {
135                         no_data();
136                         return;
137                 }
138                 MicroExport     export = new MicroExport (this, data);
139                 export.runDialog();
140         }
141
142         private static void CommandGraph(File file) {
143                 MicroPeak m = new MicroPeak();
144                 m.OpenFile(file);
145         }
146
147         private static void CommandExport(File file) {
148                 try {
149                         MicroData d = ReadFile(file);
150                         if (d != null) {
151                                 File    csv = new File(AltosLib.replace_extension(file.getPath(), ".csv"));
152                                 try {
153                                         System.out.printf ("Export \"%s\" to \"%s\"\n", file.getPath(), csv.getPath());
154                                         MicroExport.export(csv, d);
155                                 } catch (FileNotFoundException fe) {
156                                         System.err.printf("Cannot create file \"%s\" (%s)\n", csv.getName(), fe.getMessage());
157                                 } catch (IOException ie) {
158                                         System.err.printf("Cannot write file \"%s\" (%s)\n", csv.getName(), ie.getMessage());
159                                 }
160                         }
161                 } catch (IOException ie) {
162                         System.err.printf("Cannot read file \"%s\" (%s)\n", file.getName(), ie.getMessage());
163                 }
164         }
165
166         private void Close() {
167                 setVisible(false);
168                 dispose();
169                 --number_of_windows;
170                 if (number_of_windows == 0)
171                         System.exit(0);
172         }
173
174         public void actionPerformed(ActionEvent ev) {
175                 if ("Exit".equals(ev.getActionCommand()))
176                         System.exit(0);
177                 else if ("Close".equals(ev.getActionCommand()))
178                         Close();
179                 else if ("Open".equals(ev.getActionCommand()))
180                         SelectFile();
181                 else if ("Download".equals(ev.getActionCommand()))
182                         DownloadData();
183                 else if ("Export".equals(ev.getActionCommand()))
184                         Export();
185                 else if ("Preferences".equals(ev.getActionCommand()))
186                         Preferences();
187                 else if ("Save a Copy".equals(ev.getActionCommand()))
188                         Save();
189         }
190
191         public void itemStateChanged(ItemEvent e) {
192         }
193
194         /* OSXAdapter interfaces */
195         public void macosx_file_handler(String path) {
196                 CommandGraph(new File(path));
197         }
198
199         public void macosx_quit_handler() {
200                 System.exit(0);
201         }
202
203         public void macosx_preferences_handler() {
204                 Preferences();
205         }
206
207         public MicroPeak() {
208
209                 ++number_of_windows;
210
211                 register_for_macosx_events();
212
213                 AltosUIPreferences.set_component(this);
214
215                 container = getContentPane();
216                 pane = new JTabbedPane();
217
218                 setTitle("MicroPeak");
219
220                 JMenuBar menuBar = new JMenuBar();
221                 setJMenuBar(menuBar);
222
223                 JMenu fileMenu = new JMenu("File");
224                 menuBar.add(fileMenu);
225
226                 JMenuItem openAction = new JMenuItem("Open");
227                 fileMenu.add(openAction);
228                 openAction.addActionListener(this);
229
230                 JMenuItem downloadAction = new JMenuItem("Download");
231                 fileMenu.add(downloadAction);
232                 downloadAction.addActionListener(this);
233
234                 JMenuItem saveAction = new JMenuItem("Save a Copy");
235                 fileMenu.add(saveAction);
236                 saveAction.addActionListener(this);
237
238                 JMenuItem exportAction = new JMenuItem("Export");
239                 fileMenu.add(exportAction);
240                 exportAction.addActionListener(this);
241
242                 JMenuItem preferencesAction = new JMenuItem("Preferences");
243                 fileMenu.add(preferencesAction);
244                 preferencesAction.addActionListener(this);
245
246                 JMenuItem closeAction = new JMenuItem("Close");
247                 fileMenu.add(closeAction);
248                 closeAction.addActionListener(this);
249
250                 JMenuItem exitAction = new JMenuItem("Exit");
251                 fileMenu.add(exitAction);
252                 exitAction.addActionListener(this);
253
254                 JButton downloadButton = new JButton ("Download");
255                 downloadButton.addActionListener(this);
256                 menuBar.add(downloadButton);
257
258                 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
259                 addWindowListener(new WindowAdapter() {
260                         @Override
261                         public void windowClosing(WindowEvent e) {
262                                 statsTable.tell_closing();
263                                 Close();
264                         }
265                 });
266
267                 enable = new AltosUIEnable();
268                 graph = new MicroGraph(enable);
269                 statsTable = new MicroStatsTable();
270                 raw = new MicroRaw();
271                 pane.add(graph.panel, "Graph");
272                 pane.add(enable, "Configure Graph");
273                 pane.add(statsTable, "Statistics");
274                 JScrollPane scroll = new JScrollPane(raw);
275                 pane.add(scroll, "Raw Data");
276                 pane.doLayout();
277                 pane.validate();
278                 container.add(pane);
279                 container.doLayout();
280                 container.validate();
281                 doLayout();
282                 validate();
283                 Insets i = getInsets();
284                 Dimension ps = pane.getPreferredSize();
285                 ps.width += i.left + i.right;
286                 ps.height += i.top + i.bottom;
287 //              setPreferredSize(ps);
288                 setSize(ps);
289                 setVisible(true);
290         }
291
292         public static void help(int code) {
293                 System.out.printf("Usage: micropeak [OPTION] ... [FILE]...\n");
294                 System.out.printf("  Options:\n");
295                 System.out.printf("    --csv\tgenerate comma separated output for spreadsheets, etc\n");
296                 System.out.printf("    --graph\tgraph a flight\n");
297                 System.exit(code);
298         }
299
300         public static void main(final String[] args) {
301                 boolean opened = false;
302                 boolean graphing = true;
303
304                 try {
305                         UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel());
306                 } catch (Exception e) {
307                 }
308
309                 for (int i = 0; i < args.length; i++) {
310                         if (args[i].equals("--help"))
311                                 help(0);
312                         else if (args[i].equals("--export"))
313                                 graphing = false;
314                         else if (args[i].equals("--graph"))
315                                 graphing = true;
316                         else if (args[i].startsWith("--"))
317                                 help(1);
318                         else {
319                                 File    file = new File(args[i]);
320                                 try {
321                                         if (graphing)
322                                                 CommandGraph(file);
323                                         else
324                                                 CommandExport(file);
325                                         opened = true;
326                                 } catch (Exception e) {
327                                         System.err.printf("Error processing \"%s\": %s\n",
328                                                           file.getName(), e.getMessage());
329                                 }
330                         }
331                 }
332                 if (!opened)
333                         new MicroPeak();
334         }
335 }