update changelogs for Debian build
[fw/altos] / altosui / AltosIgniteUI.java
1 /*
2  * Copyright © 2010 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; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package altosui;
19
20 import java.awt.*;
21 import java.awt.event.*;
22 import javax.swing.*;
23 import javax.swing.filechooser.FileNameExtensionFilter;
24 import javax.swing.table.*;
25 import javax.swing.event.*;
26 import java.io.*;
27 import java.util.*;
28 import java.text.*;
29 import java.util.prefs.*;
30 import java.util.concurrent.*;
31
32 public class AltosIgniteUI
33         extends JDialog
34         implements ActionListener
35 {
36         AltosDevice     device;
37         AltosIgnite     ignite;
38         JFrame          owner;
39         JLabel          label;
40         JRadioButton    apogee;
41         JLabel          apogee_status_label;
42         JRadioButton    main;
43         JLabel          main_status_label;
44         JToggleButton   arm;
45         JButton         fire;
46         javax.swing.Timer       timer;
47
48         int             apogee_status;
49         int             main_status;
50
51         final static int        timeout = 1 * 1000;
52
53         int             time_remaining;
54         boolean         timer_running;
55
56         void set_arm_text() {
57                 if (arm.isSelected())
58                         arm.setText(String.format("%d", time_remaining));
59                 else
60                         arm.setText("Arm");
61         }
62
63         void start_timer() {
64                 time_remaining = 10;
65                 set_arm_text();
66                 timer_running = true;
67         }
68
69         void stop_timer() {
70                 time_remaining = 0;
71                 arm.setSelected(false);
72                 arm.setEnabled(false);
73                 fire.setEnabled(false);
74                 timer_running = false;
75                 set_arm_text();
76         }
77
78         void cancel () {
79                 apogee.setSelected(false);
80                 main.setSelected(false);
81                 fire.setEnabled(false);
82                 stop_timer();
83         }
84
85         void get_ignite_status() throws InterruptedException, TimeoutException {
86                 apogee_status = ignite.status(AltosIgnite.Apogee);
87                 main_status = ignite.status(AltosIgnite.Main);
88         }
89
90         void set_ignite_status() throws InterruptedException, TimeoutException {
91                 get_ignite_status();
92                 apogee_status_label.setText(String.format("\"%s\"", ignite.status_string(apogee_status)));
93                 main_status_label.setText(String.format("\"%s\"", ignite.status_string(main_status)));
94         }
95
96         void close() {
97                 timer.stop();
98                 setVisible(false);
99                 ignite.close();
100         }
101
102         void abort() {
103                 close();
104                 JOptionPane.showMessageDialog(owner,
105                                               String.format("Connection to \"%s\" failed",
106                                                             device.toShortString()),
107                                               "Connection Failed",
108                                               JOptionPane.ERROR_MESSAGE);
109         }
110
111         void tick_timer() {
112                 if (timer_running) {
113                         --time_remaining;
114                         if (time_remaining <= 0)
115                                 cancel();
116                         else
117                                 set_arm_text();
118                 }
119                 try {
120                         set_ignite_status();
121                 } catch (InterruptedException ie) {
122                         abort();
123                 } catch (TimeoutException te) {
124                         abort();
125                 }
126         }
127
128         void fire() {
129                 if (arm.isEnabled() && arm.isSelected() && time_remaining > 0) {
130                         int     igniter = AltosIgnite.None;
131                         if (apogee.isSelected() && !main.isSelected())
132                                 igniter = AltosIgnite.Apogee;
133                         else if (main.isSelected() && !apogee.isSelected())
134                                 igniter = AltosIgnite.Main;
135                         ignite.fire(igniter);
136                         cancel();
137                 }
138         }
139
140         public void actionPerformed(ActionEvent e) {
141                 String cmd = e.getActionCommand();
142                 if (cmd.equals("apogee") || cmd.equals("main")) {
143                         stop_timer();
144                 }
145
146                 if (cmd.equals("apogee") && apogee.isSelected()) {
147                         main.setSelected(false);
148                         arm.setEnabled(true);
149                 }
150                 if (cmd.equals("main") && main.isSelected()) {
151                         apogee.setSelected(false);
152                         arm.setEnabled(true);
153                 }
154
155                 if (cmd.equals("arm")) {
156                         if (arm.isSelected()) {
157                                 fire.setEnabled(true);
158                                 start_timer();
159                         } else
160                                 cancel();
161                 }
162                 if (cmd.equals("fire"))
163                         fire();
164                 if (cmd.equals("tick"))
165                         tick_timer();
166                 if (cmd.equals("close")) {
167                         close();
168                 }
169         }
170
171         /* A window listener to catch closing events and tell the config code */
172         class ConfigListener extends WindowAdapter {
173                 AltosIgniteUI   ui;
174
175                 public ConfigListener(AltosIgniteUI this_ui) {
176                         ui = this_ui;
177                 }
178
179                 public void windowClosing(WindowEvent e) {
180                         ui.actionPerformed(new ActionEvent(e.getSource(),
181                                                            ActionEvent.ACTION_PERFORMED,
182                                                            "close"));
183                 }
184         }
185
186         private boolean open() {
187                 device = AltosDeviceDialog.show(owner, AltosDevice.product_any);
188                 if (device != null) {
189                         try {
190                                 ignite = new AltosIgnite(device);
191                                 return true;
192                         } catch (FileNotFoundException ee) {
193                                 JOptionPane.showMessageDialog(owner,
194                                                               String.format("Cannot open device \"%s\"",
195                                                                             device.toShortString()),
196                                                               "Cannot open target device",
197                                                               JOptionPane.ERROR_MESSAGE);
198                         } catch (AltosSerialInUseException si) {
199                                 JOptionPane.showMessageDialog(owner,
200                                                               String.format("Device \"%s\" already in use",
201                                                                             device.toShortString()),
202                                                               "Device in use",
203                                                               JOptionPane.ERROR_MESSAGE);
204                         } catch (IOException ee) {
205                                 JOptionPane.showMessageDialog(owner,
206                                                               device.toShortString(),
207                                                               ee.getLocalizedMessage(),
208                                                               JOptionPane.ERROR_MESSAGE);
209                         }
210                 }
211                 return false;
212         }
213
214         public AltosIgniteUI(JFrame in_owner) {
215
216                 owner = in_owner;
217                 apogee_status = AltosIgnite.Unknown;
218                 main_status = AltosIgnite.Unknown;
219
220                 if (!open())
221                         return;
222
223                 Container               pane = getContentPane();
224                 GridBagConstraints      c = new GridBagConstraints();
225                 Insets                  i = new Insets(4,4,4,4);
226
227                 timer = new javax.swing.Timer(timeout, this);
228                 timer.setActionCommand("tick");
229                 timer_running = false;
230                 timer.restart();
231
232                 owner = in_owner;
233
234                 pane.setLayout(new GridBagLayout());
235
236                 c.fill = GridBagConstraints.NONE;
237                 c.anchor = GridBagConstraints.CENTER;
238                 c.insets = i;
239                 c.weightx = 1;
240                 c.weighty = 1;
241
242                 c.gridx = 0;
243                 c.gridy = 0;
244                 c.gridwidth = 2;
245                 c.anchor = GridBagConstraints.CENTER;
246                 label = new JLabel ("Fire Igniter");
247                 pane.add(label, c);
248
249                 c.gridx = 0;
250                 c.gridy = 1;
251                 c.gridwidth = 1;
252                 c.anchor = GridBagConstraints.WEST;
253                 apogee = new JRadioButton ("Apogee");
254                 pane.add(apogee, c);
255                 apogee.addActionListener(this);
256                 apogee.setActionCommand("apogee");
257
258                 c.gridx = 1;
259                 c.gridy = 1;
260                 c.gridwidth = 1;
261                 c.anchor = GridBagConstraints.WEST;
262                 apogee_status_label = new JLabel();
263                 pane.add(apogee_status_label, c);
264
265                 c.gridx = 0;
266                 c.gridy = 2;
267                 c.gridwidth = 1;
268                 c.anchor = GridBagConstraints.WEST;
269                 main = new JRadioButton ("Main");
270                 pane.add(main, c);
271                 main.addActionListener(this);
272                 main.setActionCommand("main");
273
274                 c.gridx = 1;
275                 c.gridy = 2;
276                 c.gridwidth = 1;
277                 c.anchor = GridBagConstraints.WEST;
278                 main_status_label = new JLabel();
279                 pane.add(main_status_label, c);
280
281                 try {
282                         set_ignite_status();
283                 } catch (InterruptedException ie) {
284                         abort();
285                         return;
286                 } catch (TimeoutException te) {
287                         abort();
288                         return;
289                 }
290
291                 c.gridx = 0;
292                 c.gridy = 3;
293                 c.gridwidth = 1;
294                 c.anchor = GridBagConstraints.CENTER;
295                 arm = new JToggleButton ("Arm");
296                 pane.add(arm, c);
297                 arm.addActionListener(this);
298                 arm.setActionCommand("arm");
299                 arm.setEnabled(false);
300
301                 c.gridx = 1;
302                 c.gridy = 3;
303                 c.gridwidth = 1;
304                 c.anchor = GridBagConstraints.CENTER;
305                 fire = new JButton ("Fire");
306                 fire.setEnabled(false);
307                 pane.add(fire, c);
308                 fire.addActionListener(this);
309                 fire.setActionCommand("fire");
310
311                 pack();
312                 setLocationRelativeTo(owner);
313                 setVisible(true);
314
315                 addWindowListener(new ConfigListener(this));
316         }
317 }