altosui: Output recorded clock tick in CSV files
[fw/altos] / altosui / AltosConfigTDUI.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.LinkedBlockingQueue;
31
32 import libaltosJNI.*;
33
34 public class AltosConfigTDUI
35         extends AltosDialog
36         implements ActionListener, ItemListener, DocumentListener
37 {
38
39         Container       pane;
40         Box             box;
41         JLabel          product_label;
42         JLabel          version_label;
43         JLabel          serial_label;
44         JLabel          frequency_label;
45         JLabel          radio_calibration_label;
46         JLabel          radio_frequency_label;
47
48         public boolean          dirty;
49
50         JFrame          owner;
51         JLabel          product_value;
52         JLabel          version_value;
53         JLabel          serial_value;
54         AltosFreqList   radio_frequency_value;
55         JLabel          radio_calibration_value;
56
57         JButton         save;
58         JButton         reset;
59         JButton         reboot;
60         JButton         close;
61
62         ActionListener  listener;
63
64
65         /* A window listener to catch closing events and tell the config code */
66         class ConfigListener extends WindowAdapter {
67                 AltosConfigTDUI ui;
68
69                 public ConfigListener(AltosConfigTDUI this_ui) {
70                         ui = this_ui;
71                 }
72
73                 public void windowClosing(WindowEvent e) {
74                         ui.actionPerformed(new ActionEvent(e.getSource(),
75                                                            ActionEvent.ACTION_PERFORMED,
76                                                            "Close"));
77                 }
78         }
79
80         /* Build the UI using a grid bag */
81         public AltosConfigTDUI(JFrame in_owner) {
82                 super (in_owner, "Configure TeleDongle", false);
83
84                 owner = in_owner;
85                 GridBagConstraints c;
86
87                 Insets il = new Insets(4,4,4,4);
88                 Insets ir = new Insets(4,4,4,4);
89
90                 pane = getContentPane();
91                 pane.setLayout(new GridBagLayout());
92
93                 /* Product */
94                 c = new GridBagConstraints();
95                 c.gridx = 0; c.gridy = 0;
96                 c.gridwidth = 4;
97                 c.fill = GridBagConstraints.NONE;
98                 c.anchor = GridBagConstraints.LINE_START;
99                 c.insets = il;
100                 product_label = new JLabel("Product:");
101                 pane.add(product_label, c);
102
103                 c = new GridBagConstraints();
104                 c.gridx = 4; c.gridy = 0;
105                 c.gridwidth = 4;
106                 c.fill = GridBagConstraints.HORIZONTAL;
107                 c.weightx = 1;
108                 c.anchor = GridBagConstraints.LINE_START;
109                 c.insets = ir;
110                 product_value = new JLabel("");
111                 pane.add(product_value, c);
112
113                 /* Version */
114                 c = new GridBagConstraints();
115                 c.gridx = 0; c.gridy = 1;
116                 c.gridwidth = 4;
117                 c.fill = GridBagConstraints.NONE;
118                 c.anchor = GridBagConstraints.LINE_START;
119                 c.insets = il;
120                 c.ipady = 5;
121                 version_label = new JLabel("Software version:");
122                 pane.add(version_label, c);
123
124                 c = new GridBagConstraints();
125                 c.gridx = 4; c.gridy = 1;
126                 c.gridwidth = 4;
127                 c.fill = GridBagConstraints.HORIZONTAL;
128                 c.weightx = 1;
129                 c.anchor = GridBagConstraints.LINE_START;
130                 c.insets = ir;
131                 c.ipady = 5;
132                 version_value = new JLabel("");
133                 pane.add(version_value, c);
134
135                 /* Serial */
136                 c = new GridBagConstraints();
137                 c.gridx = 0; c.gridy = 2;
138                 c.gridwidth = 4;
139                 c.fill = GridBagConstraints.NONE;
140                 c.anchor = GridBagConstraints.LINE_START;
141                 c.insets = il;
142                 c.ipady = 5;
143                 serial_label = new JLabel("Serial:");
144                 pane.add(serial_label, c);
145
146                 c = new GridBagConstraints();
147                 c.gridx = 4; c.gridy = 2;
148                 c.gridwidth = 4;
149                 c.fill = GridBagConstraints.HORIZONTAL;
150                 c.weightx = 1;
151                 c.anchor = GridBagConstraints.LINE_START;
152                 c.insets = ir;
153                 c.ipady = 5;
154                 serial_value = new JLabel("");
155                 pane.add(serial_value, c);
156
157                 /* Frequency */
158                 c = new GridBagConstraints();
159                 c.gridx = 0; c.gridy = 5;
160                 c.gridwidth = 4;
161                 c.fill = GridBagConstraints.NONE;
162                 c.anchor = GridBagConstraints.LINE_START;
163                 c.insets = il;
164                 c.ipady = 5;
165                 radio_frequency_label = new JLabel("Frequency:");
166                 pane.add(radio_frequency_label, c);
167
168                 c = new GridBagConstraints();
169                 c.gridx = 4; c.gridy = 5;
170                 c.gridwidth = 4;
171                 c.fill = GridBagConstraints.HORIZONTAL;
172                 c.weightx = 1;
173                 c.anchor = GridBagConstraints.LINE_START;
174                 c.insets = ir;
175                 c.ipady = 5;
176                 radio_frequency_value = new AltosFreqList();
177                 radio_frequency_value.addItemListener(this);
178                 pane.add(radio_frequency_value, c);
179                 radio_frequency_value.setToolTipText("Telemetry, RDF and packet frequency");
180
181                 /* Radio Calibration */
182                 c = new GridBagConstraints();
183                 c.gridx = 0; c.gridy = 6;
184                 c.gridwidth = 4;
185                 c.fill = GridBagConstraints.NONE;
186                 c.anchor = GridBagConstraints.LINE_START;
187                 c.insets = il;
188                 c.ipady = 5;
189                 radio_calibration_label = new JLabel("RF Calibration:");
190                 pane.add(radio_calibration_label, c);
191
192                 c = new GridBagConstraints();
193                 c.gridx = 4; c.gridy = 6;
194                 c.gridwidth = 4;
195                 c.fill = GridBagConstraints.HORIZONTAL;
196                 c.weightx = 1;
197                 c.anchor = GridBagConstraints.LINE_START;
198                 c.insets = ir;
199                 c.ipady = 5;
200                 radio_calibration_value = new JLabel(String.format("%d", 1186611));
201                 pane.add(radio_calibration_value, c);
202
203                 /* Buttons */
204                 c = new GridBagConstraints();
205                 c.gridx = 0; c.gridy = 12;
206                 c.gridwidth = 2;
207                 c.fill = GridBagConstraints.NONE;
208                 c.anchor = GridBagConstraints.LINE_START;
209                 c.insets = il;
210                 save = new JButton("Save");
211                 pane.add(save, c);
212                 save.addActionListener(this);
213                 save.setActionCommand("Save");
214
215                 c = new GridBagConstraints();
216                 c.gridx = 2; c.gridy = 12;
217                 c.gridwidth = 2;
218                 c.fill = GridBagConstraints.NONE;
219                 c.anchor = GridBagConstraints.CENTER;
220                 c.insets = il;
221                 reset = new JButton("Reset");
222                 pane.add(reset, c);
223                 reset.addActionListener(this);
224                 reset.setActionCommand("Reset");
225
226                 c = new GridBagConstraints();
227                 c.gridx = 6; c.gridy = 12;
228                 c.gridwidth = 2;
229                 c.fill = GridBagConstraints.NONE;
230                 c.anchor = GridBagConstraints.LINE_END;
231                 c.insets = il;
232                 close = new JButton("Close");
233                 pane.add(close, c);
234                 close.addActionListener(this);
235                 close.setActionCommand("Close");
236
237                 addWindowListener(new ConfigListener(this));
238         }
239
240         /* Once the initial values are set, the config code will show the dialog */
241         public void make_visible() {
242                 pack();
243                 setLocationRelativeTo(owner);
244                 setVisible(true);
245         }
246
247         /* If any values have been changed, confirm before closing */
248         public boolean check_dirty(String operation) {
249                 if (dirty) {
250                         Object[] options = { String.format("%s anyway", operation), "Keep editing" };
251                         int i;
252                         i = JOptionPane.showOptionDialog(this,
253                                                          String.format("Configuration modified. %s anyway?", operation),
254                                                          "Configuration Modified",
255                                                          JOptionPane.DEFAULT_OPTION,
256                                                          JOptionPane.WARNING_MESSAGE,
257                                                          null, options, options[1]);
258                         if (i != 0)
259                                 return false;
260                 }
261                 return true;
262         }
263
264         /* Listen for events from our buttons */
265         public void actionPerformed(ActionEvent e) {
266                 String  cmd = e.getActionCommand();
267
268                 if (cmd.equals("Close") || cmd.equals("Reboot"))
269                         if (!check_dirty(cmd))
270                                 return;
271                 listener.actionPerformed(e);
272                 if (cmd.equals("Close") || cmd.equals("Reboot")) {
273                         setVisible(false);
274                         dispose();
275                 }
276                 dirty = false;
277         }
278
279         /* ItemListener interface method */
280         public void itemStateChanged(ItemEvent e) {
281                 dirty = true;
282         }
283
284         /* DocumentListener interface methods */
285         public void changedUpdate(DocumentEvent e) {
286                 dirty = true;
287         }
288
289         public void insertUpdate(DocumentEvent e) {
290                 dirty = true;
291         }
292
293         public void removeUpdate(DocumentEvent e) {
294                 dirty = true;
295         }
296
297         /* Let the config code hook on a listener */
298         public void addActionListener(ActionListener l) {
299                 listener = l;
300         }
301
302         /* set and get all of the dialog values */
303         public void set_product(String product) {
304                 radio_frequency_value.set_product(product);
305                 product_value.setText(product);
306         }
307
308         public void set_version(String version) {
309                 version_value.setText(version);
310         }
311
312         public void set_serial(int serial) {
313                 radio_frequency_value.set_serial(serial);
314                 serial_value.setText(String.format("%d", serial));
315         }
316
317         public void set_radio_frequency(double new_radio_frequency) {
318                 int i;
319                 for (i = 0; i < radio_frequency_value.getItemCount(); i++) {
320                         AltosFrequency  f = (AltosFrequency) radio_frequency_value.getItemAt(i);
321                         
322                         if (f.close(new_radio_frequency)) {
323                                 radio_frequency_value.setSelectedIndex(i);
324                                 return;
325                         }
326                 }
327                 for (i = 0; i < radio_frequency_value.getItemCount(); i++) {
328                         AltosFrequency  f = (AltosFrequency) radio_frequency_value.getItemAt(i);
329                         
330                         if (new_radio_frequency < f.frequency)
331                                 break;
332                 }
333                 String  description = String.format("%s serial %s",
334                                                     product_value.getText(),
335                                                     serial_value.getText());
336                 AltosFrequency  new_frequency = new AltosFrequency(new_radio_frequency, description);
337                 AltosPreferences.add_common_frequency(new_frequency);
338                 radio_frequency_value.insertItemAt(new_frequency, i);
339                 radio_frequency_value.setSelectedIndex(i);
340         }
341
342         public double radio_frequency() {
343                 return radio_frequency_value.frequency();
344         }
345
346         public void set_radio_calibration(int calibration) {
347                 radio_calibration_value.setText(String.format("%d", calibration));
348         }
349
350         public void set_clean() {
351                 dirty = false;
352         }
353 }