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