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