2 * Copyright © 2010 Keith Packard <keithp@keithp.com>
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.
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.
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.
21 import java.awt.event.*;
23 import javax.swing.event.*;
24 import org.altusmetrum.altoslib_6.*;
25 import org.altusmetrum.altosuilib_6.*;
27 public class AltosConfigUI
29 implements ActionListener, ItemListener, DocumentListener, AltosConfigValues, AltosUnitsListener
36 JLabel main_deploy_label;
37 JLabel apogee_delay_label;
38 JLabel apogee_lockout_label;
39 JLabel frequency_label;
40 JLabel radio_calibration_label;
41 JLabel radio_frequency_label;
42 JLabel radio_enable_label;
44 JLabel aprs_interval_label;
45 JLabel aprs_ssid_label;
46 JLabel aprs_format_label;
47 JLabel flight_log_max_label;
48 JLabel ignite_mode_label;
49 JLabel pad_orientation_label;
50 JLabel callsign_label;
52 JLabel tracker_motion_label;
53 JLabel tracker_interval_label;
61 JComboBox<String> main_deploy_value;
62 JComboBox<String> apogee_delay_value;
63 JComboBox<String> apogee_lockout_value;
64 AltosUIFreqList radio_frequency_value;
65 JTextField radio_calibration_value;
66 JRadioButton radio_enable_value;
67 AltosUIRateList rate_value;
68 JComboBox<String> aprs_interval_value;
69 JComboBox<Integer> aprs_ssid_value;
70 JComboBox<String> aprs_format_value;
71 JComboBox<String> flight_log_max_value;
72 JComboBox<String> ignite_mode_value;
73 JComboBox<String> pad_orientation_value;
74 JTextField callsign_value;
75 JComboBox<String> beep_value;
76 JComboBox<String> tracker_motion_value;
77 JComboBox<String> tracker_interval_value;
87 double pyro_firing_time;
89 ActionListener listener;
91 static String[] main_deploy_values_m = {
92 "100", "150", "200", "250", "300", "350",
96 static String[] main_deploy_values_ft = {
97 "250", "500", "750", "1000", "1250", "1500",
101 static String[] apogee_delay_values = {
102 "0", "1", "2", "3", "4", "5"
105 static String[] apogee_lockout_values = {
106 "0", "5", "10", "15", "20"
109 static String[] ignite_mode_values = {
115 static String[] aprs_interval_values = {
122 static Integer[] aprs_ssid_values = {
123 0, 1, 2 ,3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
126 static String[] beep_values = {
132 static String[] pad_orientation_values = {
137 static String[] tracker_motion_values_m = {
144 static String[] tracker_motion_values_ft = {
151 static String[] tracker_interval_values = {
158 /* A window listener to catch closing events and tell the config code */
159 class ConfigListener extends WindowAdapter {
162 public ConfigListener(AltosConfigUI this_ui) {
166 public void windowClosing(WindowEvent e) {
167 ui.actionPerformed(new ActionEvent(e.getSource(),
168 ActionEvent.ACTION_PERFORMED,
173 boolean is_telemini_v1() {
174 String product = product_value.getText();
175 return product != null && product.startsWith("TeleMini-v1");
178 boolean is_telemini() {
179 String product = product_value.getText();
180 return product != null && product.startsWith("TeleMini");
183 boolean is_easymini() {
184 String product = product_value.getText();
185 return product != null && product.startsWith("EasyMini");
188 boolean is_telemetrum() {
189 String product = product_value.getText();
190 return product != null && product.startsWith("TeleMetrum");
193 void set_radio_calibration_tool_tip() {
194 if (radio_calibration_value.isEnabled())
195 radio_calibration_value.setToolTipText("Tune radio output to match desired frequency");
197 radio_calibration_value.setToolTipText("Cannot tune radio while connected over packet mode");
200 void set_radio_enable_tool_tip() {
201 if (radio_enable_value.isEnabled())
202 radio_enable_value.setToolTipText("Enable/Disable telemetry and RDF transmissions");
204 radio_enable_value.setToolTipText("Firmware version does not support disabling radio");
207 void set_rate_tool_tip() {
208 if (rate_value.isEnabled())
209 rate_value.setToolTipText("Select telemetry baud rate");
211 rate_value.setToolTipText("Firmware version does not support variable telemetry rates");
214 void set_aprs_interval_tool_tip() {
215 if (aprs_interval_value.isEnabled())
216 aprs_interval_value.setToolTipText("Enable APRS and set the interval between APRS reports");
218 aprs_interval_value.setToolTipText("Hardware doesn't support APRS");
221 void set_aprs_ssid_tool_tip() {
222 if (aprs_ssid_value.isEnabled())
223 aprs_ssid_value.setToolTipText("Set the APRS SSID (secondary station identifier)");
224 else if (aprs_ssid_value.isEnabled())
225 aprs_ssid_value.setToolTipText("Software version doesn't support setting the APRS SSID");
227 aprs_ssid_value.setToolTipText("Hardware doesn't support APRS");
230 void set_aprs_format_tool_tip() {
231 if (aprs_format_value.isEnabled())
232 aprs_format_value.setToolTipText("Set the APRS format (compressed/uncompressed)");
233 else if (aprs_format_value.isEnabled())
234 aprs_format_value.setToolTipText("Software version doesn't support setting the APRS format");
236 aprs_format_value.setToolTipText("Hardware doesn't support APRS");
239 void set_flight_log_max_tool_tip() {
240 if (flight_log_max_value.isEnabled())
241 flight_log_max_value.setToolTipText("Size reserved for each flight log (in kB)");
243 if (is_telemini_v1())
244 flight_log_max_value.setToolTipText("TeleMini-v1 stores only one flight");
246 flight_log_max_value.setToolTipText("Cannot set max value with flight logs in memory");
250 void set_ignite_mode_tool_tip() {
251 if (ignite_mode_value.isEnabled())
252 ignite_mode_value.setToolTipText("Select when igniters will be fired");
254 ignite_mode_value.setToolTipText("Older firmware could not select ignite mode");
257 void set_pad_orientation_tool_tip() {
258 if (pad_orientation_value.isEnabled())
259 pad_orientation_value.setToolTipText("How will the computer be mounted in the airframe");
262 pad_orientation_value.setToolTipText("Older TeleMetrum firmware must fly antenna forward");
263 else if (is_telemini() || is_easymini())
264 pad_orientation_value.setToolTipText("TeleMini and EasyMini don't care how they are mounted");
266 pad_orientation_value.setToolTipText("Can't select orientation");
270 void set_beep_tool_tip() {
271 if (beep_value.isEnabled())
272 beep_value.setToolTipText("What frequency the beeper will sound at");
274 beep_value.setToolTipText("Older firmware could not select beeper frequency");
277 /* Build the UI using a grid bag */
278 public AltosConfigUI(JFrame in_owner, boolean remote) {
279 super (in_owner, "Configure Flight Computer", false);
282 GridBagConstraints c;
285 Insets il = new Insets(4,4,4,4);
286 Insets ir = new Insets(4,4,4,4);
288 pane = getContentPane();
289 pane.setLayout(new GridBagLayout());
292 c = new GridBagConstraints();
293 c.gridx = 0; c.gridy = row;
295 c.fill = GridBagConstraints.NONE;
296 c.anchor = GridBagConstraints.LINE_START;
298 product_label = new JLabel("Product:");
299 pane.add(product_label, c);
301 c = new GridBagConstraints();
302 c.gridx = 4; c.gridy = row;
304 c.fill = GridBagConstraints.HORIZONTAL;
306 c.anchor = GridBagConstraints.LINE_START;
308 product_value = new JLabel("");
309 pane.add(product_value, c);
313 c = new GridBagConstraints();
314 c.gridx = 0; c.gridy = row;
316 c.fill = GridBagConstraints.NONE;
317 c.anchor = GridBagConstraints.LINE_START;
320 version_label = new JLabel("Software version:");
321 pane.add(version_label, c);
323 c = new GridBagConstraints();
324 c.gridx = 4; c.gridy = row;
326 c.fill = GridBagConstraints.HORIZONTAL;
328 c.anchor = GridBagConstraints.LINE_START;
331 version_value = new JLabel("");
332 pane.add(version_value, c);
336 c = new GridBagConstraints();
337 c.gridx = 0; c.gridy = row;
339 c.fill = GridBagConstraints.NONE;
340 c.anchor = GridBagConstraints.LINE_START;
343 serial_label = new JLabel("Serial:");
344 pane.add(serial_label, c);
346 c = new GridBagConstraints();
347 c.gridx = 4; c.gridy = row;
349 c.fill = GridBagConstraints.HORIZONTAL;
351 c.anchor = GridBagConstraints.LINE_START;
354 serial_value = new JLabel("");
355 pane.add(serial_value, c);
359 c = new GridBagConstraints();
360 c.gridx = 0; c.gridy = row;
362 c.fill = GridBagConstraints.NONE;
363 c.anchor = GridBagConstraints.LINE_START;
366 main_deploy_label = new JLabel(get_main_deploy_label());
367 pane.add(main_deploy_label, c);
369 c = new GridBagConstraints();
370 c.gridx = 4; c.gridy = row;
372 c.fill = GridBagConstraints.HORIZONTAL;
374 c.anchor = GridBagConstraints.LINE_START;
377 main_deploy_value = new JComboBox<String>(main_deploy_values());
378 main_deploy_value.setEditable(true);
379 main_deploy_value.addItemListener(this);
380 pane.add(main_deploy_value, c);
381 main_deploy_value.setToolTipText("Height above pad altitude to fire main charge");
385 c = new GridBagConstraints();
386 c.gridx = 0; c.gridy = row;
388 c.fill = GridBagConstraints.NONE;
389 c.anchor = GridBagConstraints.LINE_START;
392 apogee_delay_label = new JLabel("Apogee Delay(s):");
393 pane.add(apogee_delay_label, c);
395 c = new GridBagConstraints();
396 c.gridx = 4; c.gridy = row;
398 c.fill = GridBagConstraints.HORIZONTAL;
400 c.anchor = GridBagConstraints.LINE_START;
403 apogee_delay_value = new JComboBox<String>(apogee_delay_values);
404 apogee_delay_value.setEditable(true);
405 apogee_delay_value.addItemListener(this);
406 pane.add(apogee_delay_value, c);
407 apogee_delay_value.setToolTipText("Delay after apogee before charge fires");
411 c = new GridBagConstraints();
412 c.gridx = 0; c.gridy = row;
414 c.fill = GridBagConstraints.NONE;
415 c.anchor = GridBagConstraints.LINE_START;
418 apogee_lockout_label = new JLabel("Apogee Lockout(s):");
419 pane.add(apogee_lockout_label, c);
421 c = new GridBagConstraints();
422 c.gridx = 4; c.gridy = row;
424 c.fill = GridBagConstraints.HORIZONTAL;
426 c.anchor = GridBagConstraints.LINE_START;
429 apogee_lockout_value = new JComboBox<String>(apogee_lockout_values);
430 apogee_lockout_value.setEditable(true);
431 apogee_lockout_value.addItemListener(this);
432 pane.add(apogee_lockout_value, c);
433 apogee_lockout_value.setToolTipText("Time after boost while apogee detection is locked out");
437 c = new GridBagConstraints();
438 c.gridx = 0; c.gridy = row;
440 c.fill = GridBagConstraints.NONE;
441 c.anchor = GridBagConstraints.LINE_START;
444 radio_frequency_label = new JLabel("Frequency:");
445 pane.add(radio_frequency_label, c);
447 c = new GridBagConstraints();
448 c.gridx = 4; c.gridy = row;
450 c.fill = GridBagConstraints.HORIZONTAL;
452 c.anchor = GridBagConstraints.LINE_START;
455 radio_frequency_value = new AltosUIFreqList();
456 radio_frequency_value.addItemListener(this);
457 pane.add(radio_frequency_value, c);
458 radio_frequency_value.setToolTipText("Telemetry, RDF and packet frequency");
461 /* Radio Calibration */
462 c = new GridBagConstraints();
463 c.gridx = 0; c.gridy = row;
465 c.fill = GridBagConstraints.NONE;
466 c.anchor = GridBagConstraints.LINE_START;
469 radio_calibration_label = new JLabel("RF Calibration:");
470 pane.add(radio_calibration_label, c);
472 c = new GridBagConstraints();
473 c.gridx = 4; c.gridy = row;
475 c.fill = GridBagConstraints.HORIZONTAL;
477 c.anchor = GridBagConstraints.LINE_START;
480 radio_calibration_value = new JTextField(String.format("%d", 1186611));
481 radio_calibration_value.getDocument().addDocumentListener(this);
483 radio_calibration_value.setEnabled(false);
484 pane.add(radio_calibration_value, c);
485 set_radio_calibration_tool_tip();
489 c = new GridBagConstraints();
490 c.gridx = 0; c.gridy = row;
492 c.fill = GridBagConstraints.NONE;
493 c.anchor = GridBagConstraints.LINE_START;
496 radio_enable_label = new JLabel("Telemetry/RDF/APRS Enable:");
497 pane.add(radio_enable_label, c);
499 c = new GridBagConstraints();
500 c.gridx = 4; c.gridy = row;
502 c.fill = GridBagConstraints.HORIZONTAL;
504 c.anchor = GridBagConstraints.LINE_START;
507 radio_enable_value = new JRadioButton("Enabled");
508 radio_enable_value.addItemListener(this);
509 pane.add(radio_enable_value, c);
510 set_radio_enable_tool_tip();
514 c = new GridBagConstraints();
515 c.gridx = 0; c.gridy = row;
517 c.fill = GridBagConstraints.NONE;
518 c.anchor = GridBagConstraints.LINE_START;
521 rate_label = new JLabel("Telemetry baud rate:");
522 pane.add(rate_label, c);
524 c = new GridBagConstraints();
525 c.gridx = 4; c.gridy = row;
527 c.fill = GridBagConstraints.HORIZONTAL;
529 c.anchor = GridBagConstraints.LINE_START;
532 rate_value = new AltosUIRateList();
533 rate_value.addItemListener(this);
534 pane.add(rate_value, c);
539 c = new GridBagConstraints();
540 c.gridx = 0; c.gridy = row;
542 c.fill = GridBagConstraints.NONE;
543 c.anchor = GridBagConstraints.LINE_START;
546 aprs_interval_label = new JLabel("APRS Interval(s):");
547 pane.add(aprs_interval_label, c);
549 c = new GridBagConstraints();
550 c.gridx = 4; c.gridy = row;
552 c.fill = GridBagConstraints.HORIZONTAL;
554 c.anchor = GridBagConstraints.LINE_START;
557 aprs_interval_value = new JComboBox<String>(aprs_interval_values);
558 aprs_interval_value.setEditable(true);
559 aprs_interval_value.addItemListener(this);
560 pane.add(aprs_interval_value, c);
561 set_aprs_interval_tool_tip();
565 c = new GridBagConstraints();
566 c.gridx = 0; c.gridy = row;
568 c.fill = GridBagConstraints.NONE;
569 c.anchor = GridBagConstraints.LINE_START;
572 aprs_ssid_label = new JLabel("APRS SSID:");
573 pane.add(aprs_ssid_label, c);
575 c = new GridBagConstraints();
576 c.gridx = 4; c.gridy = row;
578 c.fill = GridBagConstraints.HORIZONTAL;
580 c.anchor = GridBagConstraints.LINE_START;
583 aprs_ssid_value = new JComboBox<Integer>(aprs_ssid_values);
584 aprs_ssid_value.setEditable(false);
585 aprs_ssid_value.addItemListener(this);
586 aprs_ssid_value.setMaximumRowCount(aprs_ssid_values.length);
587 pane.add(aprs_ssid_value, c);
588 set_aprs_ssid_tool_tip();
592 c = new GridBagConstraints();
593 c.gridx = 0; c.gridy = row;
595 c.fill = GridBagConstraints.NONE;
596 c.anchor = GridBagConstraints.LINE_START;
599 aprs_format_label = new JLabel("APRS format:");
600 pane.add(aprs_format_label, c);
602 c = new GridBagConstraints();
603 c.gridx = 4; c.gridy = row;
605 c.fill = GridBagConstraints.HORIZONTAL;
607 c.anchor = GridBagConstraints.LINE_START;
610 aprs_format_value = new JComboBox<String>(AltosLib.ao_aprs_format_name);
611 aprs_format_value.setEditable(false);
612 aprs_format_value.addItemListener(this);
613 aprs_format_value.setMaximumRowCount(AltosLib.ao_aprs_format_name.length);
614 pane.add(aprs_format_value, c);
615 set_aprs_format_tool_tip();
619 c = new GridBagConstraints();
620 c.gridx = 0; c.gridy = row;
622 c.fill = GridBagConstraints.NONE;
623 c.anchor = GridBagConstraints.LINE_START;
626 callsign_label = new JLabel("Callsign:");
627 pane.add(callsign_label, c);
629 c = new GridBagConstraints();
630 c.gridx = 4; c.gridy = row;
632 c.fill = GridBagConstraints.HORIZONTAL;
634 c.anchor = GridBagConstraints.LINE_START;
637 callsign_value = new JTextField(AltosUIPreferences.callsign());
638 callsign_value.getDocument().addDocumentListener(this);
639 pane.add(callsign_value, c);
640 callsign_value.setToolTipText("Callsign reported in telemetry data");
644 c = new GridBagConstraints();
645 c.gridx = 0; c.gridy = row;
647 c.fill = GridBagConstraints.NONE;
648 c.anchor = GridBagConstraints.LINE_START;
651 flight_log_max_label = new JLabel("Maximum Flight Log Size (kB):");
652 pane.add(flight_log_max_label, c);
654 c = new GridBagConstraints();
655 c.gridx = 4; c.gridy = row;
657 c.fill = GridBagConstraints.HORIZONTAL;
659 c.anchor = GridBagConstraints.LINE_START;
662 flight_log_max_value = new JComboBox<String>();
663 flight_log_max_value.setEditable(true);
664 flight_log_max_value.addItemListener(this);
665 pane.add(flight_log_max_value, c);
666 set_flight_log_max_tool_tip();
670 c = new GridBagConstraints();
671 c.gridx = 0; c.gridy = row;
673 c.fill = GridBagConstraints.NONE;
674 c.anchor = GridBagConstraints.LINE_START;
677 ignite_mode_label = new JLabel("Igniter Firing Mode:");
678 pane.add(ignite_mode_label, c);
680 c = new GridBagConstraints();
681 c.gridx = 4; c.gridy = row;
683 c.fill = GridBagConstraints.HORIZONTAL;
685 c.anchor = GridBagConstraints.LINE_START;
688 ignite_mode_value = new JComboBox<String>(ignite_mode_values);
689 ignite_mode_value.setEditable(false);
690 ignite_mode_value.addItemListener(this);
691 pane.add(ignite_mode_value, c);
692 set_ignite_mode_tool_tip();
695 /* Pad orientation */
696 c = new GridBagConstraints();
697 c.gridx = 0; c.gridy = row;
699 c.fill = GridBagConstraints.NONE;
700 c.anchor = GridBagConstraints.LINE_START;
703 pad_orientation_label = new JLabel("Pad Orientation:");
704 pane.add(pad_orientation_label, c);
706 c = new GridBagConstraints();
707 c.gridx = 4; c.gridy = row;
709 c.fill = GridBagConstraints.HORIZONTAL;
711 c.anchor = GridBagConstraints.LINE_START;
714 pad_orientation_value = new JComboBox<String>(pad_orientation_values);
715 pad_orientation_value.setEditable(false);
716 pad_orientation_value.addItemListener(this);
717 pane.add(pad_orientation_value, c);
718 set_pad_orientation_tool_tip();
722 c = new GridBagConstraints();
723 c.gridx = 0; c.gridy = row;
725 c.fill = GridBagConstraints.NONE;
726 c.anchor = GridBagConstraints.LINE_START;
729 beep_label = new JLabel("Beeper Frequency:");
730 pane.add(beep_label, c);
732 c = new GridBagConstraints();
733 c.gridx = 4; c.gridy = row;
735 c.fill = GridBagConstraints.HORIZONTAL;
737 c.anchor = GridBagConstraints.LINE_START;
740 beep_value = new JComboBox<String>(beep_values);
741 beep_value.setEditable(true);
742 beep_value.addItemListener(this);
743 pane.add(beep_value, c);
747 /* Tracker triger horiz distances */
748 c = new GridBagConstraints();
749 c.gridx = 0; c.gridy = row;
751 c.fill = GridBagConstraints.NONE;
752 c.anchor = GridBagConstraints.LINE_START;
755 tracker_motion_label = new JLabel(get_tracker_motion_label());
756 pane.add(tracker_motion_label, c);
758 c = new GridBagConstraints();
759 c.gridx = 4; c.gridy = row;
761 c.fill = GridBagConstraints.HORIZONTAL;
763 c.anchor = GridBagConstraints.LINE_START;
766 tracker_motion_value = new JComboBox<String>(tracker_motion_values());
767 tracker_motion_value.setEditable(true);
768 tracker_motion_value.addItemListener(this);
769 pane.add(tracker_motion_value, c);
772 /* Tracker triger vert distances */
773 c = new GridBagConstraints();
774 c.gridx = 0; c.gridy = row;
776 c.fill = GridBagConstraints.NONE;
777 c.anchor = GridBagConstraints.LINE_START;
780 tracker_interval_label = new JLabel("Position Reporting Interval(s):");
781 pane.add(tracker_interval_label, c);
783 c = new GridBagConstraints();
784 c.gridx = 4; c.gridy = row;
786 c.fill = GridBagConstraints.HORIZONTAL;
788 c.anchor = GridBagConstraints.LINE_START;
791 tracker_interval_value = new JComboBox<String>(tracker_interval_values);
792 tracker_interval_value.setEditable(true);
793 tracker_interval_value.addItemListener(this);
794 pane.add(tracker_interval_value, c);
795 set_tracker_tool_tip();
799 c = new GridBagConstraints();
800 c.gridx = 4; c.gridy = row;
802 c.fill = GridBagConstraints.HORIZONTAL;
803 c.anchor = GridBagConstraints.LINE_START;
806 pyro = new JButton("Configure Pyro Channels");
808 pyro.addActionListener(this);
809 pyro.setActionCommand("Pyro");
813 c = new GridBagConstraints();
814 c.gridx = 0; c.gridy = row;
816 c.fill = GridBagConstraints.NONE;
817 c.anchor = GridBagConstraints.LINE_START;
819 save = new JButton("Save");
821 save.addActionListener(this);
822 save.setActionCommand("Save");
824 c = new GridBagConstraints();
825 c.gridx = 2; c.gridy = row;
827 c.fill = GridBagConstraints.NONE;
828 c.anchor = GridBagConstraints.CENTER;
830 reset = new JButton("Reset");
832 reset.addActionListener(this);
833 reset.setActionCommand("Reset");
835 c = new GridBagConstraints();
836 c.gridx = 4; c.gridy = row;
838 c.fill = GridBagConstraints.NONE;
839 c.anchor = GridBagConstraints.CENTER;
841 reboot = new JButton("Reboot");
843 reboot.addActionListener(this);
844 reboot.setActionCommand("Reboot");
846 c = new GridBagConstraints();
847 c.gridx = 6; c.gridy = row;
849 c.fill = GridBagConstraints.NONE;
850 c.anchor = GridBagConstraints.LINE_END;
852 close = new JButton("Close");
854 close.addActionListener(this);
855 close.setActionCommand("Close");
857 addWindowListener(new ConfigListener(this));
858 AltosPreferences.register_units_listener(this);
861 /* Once the initial values are set, the config code will show the dialog */
862 public void make_visible() {
864 setLocationRelativeTo(owner);
868 /* If any values have been changed, confirm before closing */
869 public boolean check_dirty(String operation) {
871 Object[] options = { String.format("%s anyway", operation), "Keep editing" };
873 i = JOptionPane.showOptionDialog(this,
874 String.format("Configuration modified. %s anyway?", operation),
875 "Configuration Modified",
876 JOptionPane.DEFAULT_OPTION,
877 JOptionPane.WARNING_MESSAGE,
878 null, options, options[1]);
887 save.setEnabled(true);
890 public void set_clean() {
892 save.setEnabled(false);
895 AltosConfigPyroUI pyro_ui;
897 public void dispose() {
900 AltosPreferences.unregister_units_listener(this);
904 /* Listen for events from our buttons */
905 public void actionPerformed(ActionEvent e) {
906 String cmd = e.getActionCommand();
908 if (cmd.equals("Pyro")) {
909 if (pyro_ui == null && pyros != null)
910 pyro_ui = new AltosConfigPyroUI(this, pyros, pyro_firing_time);
912 pyro_ui.make_visible();
916 if (cmd.equals("Close") || cmd.equals("Reboot"))
917 if (!check_dirty(cmd))
919 listener.actionPerformed(e);
920 if (cmd.equals("Close") || cmd.equals("Reboot")) {
927 /* ItemListener interface method */
928 public void itemStateChanged(ItemEvent e) {
932 /* DocumentListener interface methods */
933 public void changedUpdate(DocumentEvent e) {
937 public void insertUpdate(DocumentEvent e) {
941 public void removeUpdate(DocumentEvent e) {
945 /* Let the config code hook on a listener */
946 public void addActionListener(ActionListener l) {
950 /* set and get all of the dialog values */
951 public void set_product(String product) {
952 radio_frequency_value.set_product(product);
953 product_value.setText(product);
954 set_pad_orientation_tool_tip();
955 set_flight_log_max_tool_tip();
958 public void set_version(String version) {
959 version_value.setText(version);
962 public void set_serial(int serial) {
963 radio_frequency_value.set_serial(serial);
964 serial_value.setText(String.format("%d", serial));
967 public void set_altitude_32(int altitude_32) {
970 public void set_main_deploy(int new_main_deploy) {
971 main_deploy_value.setSelectedItem(AltosConvert.height.say(new_main_deploy));
972 main_deploy_value.setEnabled(new_main_deploy >= 0);
974 main_deploy_value.setVisible(new_main_deploy >= 0);
975 main_deploy_label.setVisible(new_main_deploy >= 0);
979 public int main_deploy() {
980 return (int) (AltosConvert.height.parse(main_deploy_value.getSelectedItem().toString()) + 0.5);
983 String get_main_deploy_label() {
984 return String.format("Main Deploy Altitude(%s):", AltosConvert.height.show_units_name(AltosLib.MISSING));
987 String[] main_deploy_values() {
988 if (AltosConvert.imperial_units)
989 return main_deploy_values_ft;
991 return main_deploy_values_m;
994 void set_main_deploy_values() {
995 String[] v = main_deploy_values();
996 while (main_deploy_value.getItemCount() > 0)
997 main_deploy_value.removeItemAt(0);
998 for (int i = 0; i < v.length; i++)
999 main_deploy_value.addItem(v[i]);
1000 main_deploy_value.setMaximumRowCount(v.length);
1003 public void units_changed(boolean imperial_units) {
1004 boolean was_dirty = dirty;
1006 String v = main_deploy_value.getSelectedItem().toString();
1007 main_deploy_label.setText(get_main_deploy_label());
1008 set_main_deploy_values();
1009 int m = (int) (AltosConvert.height.parse(v, !imperial_units) + 0.5);
1012 if (tracker_motion_value.isEnabled()) {
1013 String motion = tracker_motion_value.getSelectedItem().toString();
1014 tracker_motion_label.setText(get_tracker_motion_label());
1015 set_tracker_motion_values();
1016 set_tracker_motion((int) (AltosConvert.height.parse(motion, !imperial_units) + 0.5));
1023 public void set_apogee_delay(int new_apogee_delay) {
1024 apogee_delay_value.setVisible(new_apogee_delay >= 0);
1025 apogee_delay_label.setVisible(new_apogee_delay >= 0);
1027 apogee_delay_value.setSelectedItem(Integer.toString(new_apogee_delay));
1028 apogee_delay_value.setEnabled(new_apogee_delay >= 0);
1031 private int parse_int(String name, String s, boolean split) throws AltosConfigDataException {
1034 v = s.split("\\s+")[0];
1036 return Integer.parseInt(v);
1037 } catch (NumberFormatException ne) {
1038 throw new AltosConfigDataException("Invalid %s \"%s\"", name, s);
1042 public int apogee_delay() throws AltosConfigDataException {
1043 return parse_int("apogee delay", apogee_delay_value.getSelectedItem().toString(), false);
1046 public void set_apogee_lockout(int new_apogee_lockout) {
1047 apogee_lockout_value.setSelectedItem(Integer.toString(new_apogee_lockout));
1048 apogee_lockout_value.setEnabled(new_apogee_lockout >= 0);
1050 apogee_lockout_value.setVisible(new_apogee_lockout >= 0);
1051 apogee_lockout_label.setVisible(new_apogee_lockout >= 0);
1054 public int apogee_lockout() throws AltosConfigDataException {
1055 return parse_int("apogee lockout", apogee_lockout_value.getSelectedItem().toString(), false);
1058 public void set_radio_frequency(double new_radio_frequency) {
1059 radio_frequency_label.setVisible(new_radio_frequency >= 0);
1060 radio_frequency_value.set_frequency(new_radio_frequency);
1063 public double radio_frequency() {
1064 return radio_frequency_value.frequency();
1067 public void set_radio_calibration(int new_radio_calibration) {
1068 radio_calibration_value.setVisible(new_radio_calibration >= 0);
1069 radio_calibration_label.setVisible(new_radio_calibration >= 0);
1071 if (new_radio_calibration < 0)
1072 radio_calibration_value.setText("Disabled");
1074 radio_calibration_value.setText(String.format("%d", new_radio_calibration));
1077 public int radio_calibration() throws AltosConfigDataException {
1078 return parse_int("radio calibration", radio_calibration_value.getText(), false);
1081 public void set_radio_enable(int new_radio_enable) {
1082 radio_enable_label.setVisible(new_radio_enable >= 0);
1083 radio_enable_value.setVisible(new_radio_enable >= 0);
1085 if (new_radio_enable >= 0) {
1086 radio_enable_value.setSelected(new_radio_enable > 0);
1087 radio_enable_value.setEnabled(true);
1089 radio_enable_value.setSelected(true);
1090 radio_enable_value.setEnabled(false);
1092 set_radio_enable_tool_tip();
1095 public int radio_enable() {
1096 if (radio_enable_value.isEnabled())
1097 return radio_enable_value.isSelected() ? 1 : 0;
1102 public void set_telemetry_rate(int new_rate) {
1103 rate_label.setVisible(new_rate >= 0);
1105 rate_value.set_rate(new_rate);
1108 public int telemetry_rate() {
1109 return rate_value.rate();
1112 public void set_callsign(String new_callsign) {
1113 callsign_value.setVisible(new_callsign != null);
1114 callsign_label.setVisible(new_callsign != null);
1116 callsign_value.setText(new_callsign);
1119 public String callsign() {
1120 return callsign_value.getText();
1123 int flight_log_max_limit;
1126 public String flight_log_max_label(int flight_log_max) {
1127 if (flight_log_max_limit != 0) {
1128 int nflight = flight_log_max_limit / flight_log_max;
1129 String plural = nflight > 1 ? "s" : "";
1131 return String.format("%d (%d flight%s)", flight_log_max, nflight, plural);
1133 return String.format("%d", flight_log_max);
1136 public void set_flight_log_max(int new_flight_log_max) {
1137 flight_log_max_value.setVisible(new_flight_log_max >= 0);
1138 flight_log_max_label.setVisible(new_flight_log_max >= 0);
1140 flight_log_max_value.setSelectedItem(flight_log_max_label(new_flight_log_max));
1141 flight_log_max = new_flight_log_max;
1142 set_flight_log_max_tool_tip();
1145 public void set_flight_log_max_enabled(boolean enable) {
1146 flight_log_max_value.setEnabled(enable);
1147 set_flight_log_max_tool_tip();
1150 public int flight_log_max() throws AltosConfigDataException {
1151 return parse_int("flight log max", flight_log_max_value.getSelectedItem().toString(), true);
1154 public void set_flight_log_max_limit(int new_flight_log_max_limit) {
1155 flight_log_max_limit = new_flight_log_max_limit;
1156 flight_log_max_value.removeAllItems();
1157 for (int i = 8; i >= 1; i--) {
1158 int size = flight_log_max_limit / i;
1159 flight_log_max_value.addItem(String.format("%d (%d flights)", size, i));
1161 if (flight_log_max != 0)
1162 set_flight_log_max(flight_log_max);
1165 public void set_ignite_mode(int new_ignite_mode) {
1166 ignite_mode_value.setVisible(new_ignite_mode >= 0);
1167 ignite_mode_label.setVisible(new_ignite_mode >= 0);
1169 if (new_ignite_mode >= ignite_mode_values.length)
1170 new_ignite_mode = 0;
1171 if (new_ignite_mode < 0) {
1172 ignite_mode_value.setEnabled(false);
1173 new_ignite_mode = 0;
1175 ignite_mode_value.setEnabled(true);
1177 ignite_mode_value.setSelectedIndex(new_ignite_mode);
1178 set_ignite_mode_tool_tip();
1181 public int ignite_mode() {
1182 if (ignite_mode_value.isEnabled())
1183 return ignite_mode_value.getSelectedIndex();
1189 public void set_pad_orientation(int new_pad_orientation) {
1190 pad_orientation_value.setVisible(new_pad_orientation >= 0);
1191 pad_orientation_label.setVisible(new_pad_orientation >= 0);
1193 if (new_pad_orientation >= pad_orientation_values.length)
1194 new_pad_orientation = 0;
1195 if (new_pad_orientation < 0)
1196 new_pad_orientation = 0;
1197 pad_orientation_value.setSelectedIndex(new_pad_orientation);
1198 set_pad_orientation_tool_tip();
1201 public int pad_orientation() {
1202 if (pad_orientation_value.isEnabled())
1203 return pad_orientation_value.getSelectedIndex();
1208 public void set_beep(int new_beep) {
1209 beep_value.setVisible(new_beep >= 0);
1210 beep_label.setVisible(new_beep >= 0);
1212 int new_freq = (int) Math.floor (AltosConvert.beep_value_to_freq(new_beep) + 0.5);
1213 for (int i = 0; i < beep_values.length; i++)
1214 if (new_beep == AltosConvert.beep_freq_to_value(Integer.parseInt(beep_values[i]))) {
1215 beep_value.setSelectedIndex(i);
1216 set_beep_tool_tip();
1219 beep_value.setSelectedItem(String.format("%d", new_freq));
1220 beep_value.setEnabled(new_beep >= 0);
1221 set_beep_tool_tip();
1225 if (beep_value.isEnabled())
1226 return AltosConvert.beep_freq_to_value(Integer.parseInt(beep_value.getSelectedItem().toString()));
1231 String[] tracker_motion_values() {
1232 if (AltosConvert.imperial_units)
1233 return tracker_motion_values_ft;
1235 return tracker_motion_values_m;
1238 void set_tracker_motion_values() {
1239 String[] v = tracker_motion_values();
1240 while (tracker_motion_value.getItemCount() > 0)
1241 tracker_motion_value.removeItemAt(0);
1242 for (int i = 0; i < v.length; i++)
1243 tracker_motion_value.addItem(v[i]);
1244 tracker_motion_value.setMaximumRowCount(v.length);
1247 String get_tracker_motion_label() {
1248 return String.format("Logging Trigger Motion (%s):", AltosConvert.height.show_units_name(AltosLib.MISSING));
1251 void set_tracker_tool_tip() {
1252 if (tracker_motion_value.isEnabled())
1253 tracker_motion_value.setToolTipText("How far the device must move before logging");
1255 tracker_motion_value.setToolTipText("This device doesn't disable logging when stationary");
1256 if (tracker_interval_value.isEnabled())
1257 tracker_interval_value.setToolTipText("How often to report GPS position");
1259 tracker_interval_value.setToolTipText("This device can't configure interval");
1262 public void set_tracker_motion(int tracker_motion) {
1263 tracker_motion_label.setVisible(tracker_motion >= 0);
1264 tracker_motion_value.setVisible(tracker_motion >= 0);
1266 if (tracker_motion < 0) {
1267 tracker_motion_value.setEnabled(false);
1269 tracker_motion_value.setEnabled(true);
1270 tracker_motion_value.setSelectedItem(AltosConvert.height.say(tracker_motion));
1274 public int tracker_motion() throws AltosConfigDataException {
1275 return (int) AltosConvert.height.parse(tracker_motion_value.getSelectedItem().toString());
1278 public void set_tracker_interval(int tracker_interval) {
1279 tracker_interval_label.setVisible(tracker_interval >= 0);
1280 tracker_interval_value.setVisible(tracker_interval >= 0);
1282 if (tracker_interval< 0) {
1283 tracker_interval_value.setEnabled(false);
1285 tracker_interval_value.setEnabled(true);
1286 tracker_interval_value.setSelectedItem(String.format("%d", tracker_interval));
1290 public int tracker_interval() throws AltosConfigDataException {
1291 return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false);
1294 public void set_pyros(AltosPyro[] new_pyros) {
1296 pyro.setVisible(pyros != null);
1297 if (pyros != null && pyro_ui != null)
1298 pyro_ui.set_pyros(pyros);
1301 public AltosPyro[] pyros() throws AltosConfigDataException {
1302 if (pyro_ui != null)
1303 pyros = pyro_ui.get_pyros();
1307 public void set_pyro_firing_time(double new_pyro_firing_time) {
1308 pyro_firing_time = new_pyro_firing_time;
1309 pyro.setVisible(pyro_firing_time >= 0);
1310 if (pyro_firing_time >= 0 && pyro_ui != null)
1311 pyro_ui.set_pyro_firing_time(pyro_firing_time);
1314 public double pyro_firing_time() throws AltosConfigDataException {
1315 if (pyro_ui != null)
1316 pyro_firing_time = pyro_ui.get_pyro_firing_time();
1317 return pyro_firing_time;
1320 public void set_aprs_interval(int new_aprs_interval) {
1321 aprs_interval_value.setVisible(new_aprs_interval >= 0);
1322 aprs_interval_label.setVisible(new_aprs_interval >= 0);
1326 if (new_aprs_interval <= 0)
1329 s = Integer.toString(new_aprs_interval);
1330 aprs_interval_value.setSelectedItem(s);
1331 set_aprs_interval_tool_tip();
1334 public int aprs_interval() throws AltosConfigDataException {
1335 String s = aprs_interval_value.getSelectedItem().toString();
1337 if (s.equals("Disabled"))
1339 return parse_int("aprs interval", s, false);
1342 public void set_aprs_ssid(int new_aprs_ssid) {
1343 aprs_ssid_value.setVisible(new_aprs_ssid >= 0);
1344 aprs_ssid_label.setVisible(new_aprs_ssid >= 0);
1346 aprs_ssid_value.setSelectedItem(Math.max(0,new_aprs_ssid));
1347 set_aprs_ssid_tool_tip();
1350 public int aprs_ssid() throws AltosConfigDataException {
1351 Integer i = (Integer) aprs_ssid_value.getSelectedItem();
1355 public void set_aprs_format(int new_aprs_format) {
1356 aprs_format_value.setVisible(new_aprs_format >= 0);
1357 aprs_format_label.setVisible(new_aprs_format >= 0);
1359 aprs_format_value.setSelectedIndex(Math.max(0,new_aprs_format));
1360 set_aprs_format_tool_tip();
1363 public int aprs_format() throws AltosConfigDataException {
1364 return aprs_format_value.getSelectedIndex();