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; either version 2 of the License, or
7 * (at your option) any later version.
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.
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.
19 package org.altusmetrum.telegps;
23 import java.awt.event.*;
25 import javax.swing.event.*;
26 import org.altusmetrum.altoslib_14.*;
27 import org.altusmetrum.altosuilib_14.*;
29 public class TeleGPSConfigUI
31 implements ActionListener, ItemListener, DocumentListener, AltosConfigValues, AltosUnitsListener
38 JLabel frequency_label;
39 JLabel radio_calibration_label;
40 JLabel radio_frequency_label;
41 JLabel radio_enable_label;
42 JLabel radio_10mw_label;
44 JLabel aprs_interval_label;
45 JLabel aprs_ssid_label;
46 JLabel aprs_format_label;
47 JLabel aprs_offset_label;
48 JLabel flight_log_max_label;
49 JLabel callsign_label;
50 JLabel tracker_motion_label;
51 JLabel tracker_interval_label;
59 AltosUIFreqList radio_frequency_value;
60 JLabel radio_calibration_value;
61 JRadioButton radio_enable_value;
62 JRadioButton radio_10mw_value;
63 AltosUIRateList rate_value;
64 JComboBox<String> aprs_interval_value;
65 JComboBox<Integer> aprs_ssid_value;
66 JComboBox<String> aprs_format_value;
67 JComboBox<Integer> aprs_offset_value;
68 JComboBox<String> flight_log_max_value;
69 JTextField callsign_value;
70 JComboBox<String> tracker_motion_value;
71 JComboBox<String> tracker_interval_value;
78 ActionListener listener;
80 static String[] aprs_interval_values = {
87 static Integer[] aprs_ssid_values = {
88 0, 1, 2 ,3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
91 static Integer[] aprs_offset_values = {
92 0, 2, 4, 6, 8, 10, 12, 14, 16, 18
95 static String[] tracker_motion_values_m = {
102 static String[] tracker_motion_values_ft = {
109 static String[] tracker_interval_values = {
116 /* A window listener to catch closing events and tell the config code */
117 class ConfigListener extends WindowAdapter {
120 public ConfigListener(TeleGPSConfigUI this_ui) {
124 public void windowClosing(WindowEvent e) {
125 ui.actionPerformed(new ActionEvent(e.getSource(),
126 ActionEvent.ACTION_PERFORMED,
131 public void set_pyros(AltosPyro[] new_pyros) {
134 public AltosPyro[] pyros() {
138 public void set_pyro_firing_time(double new_pyro_firing_time) {
141 public double pyro_firing_time() {
142 return AltosLib.MISSING;
145 boolean is_telemetrum() {
146 String product = product_value.getText();
147 return product != null && product.startsWith("TeleGPS");
150 void set_radio_enable_tool_tip() {
151 if (radio_enable_value.isVisible())
152 radio_enable_value.setToolTipText("Enable/Disable telemetry and RDF transmissions");
154 radio_enable_value.setToolTipText("Firmware version does not support disabling radio");
157 void set_radio_10mw_tool_tip() {
158 if (radio_10mw_value.isVisible())
159 radio_10mw_value.setToolTipText("Should transmitter power be limited to 10mW");
161 radio_10mw_value.setToolTipText("Older firmware could not limit radio power");
164 void set_rate_tool_tip() {
165 if (rate_value.isVisible())
166 rate_value.setToolTipText("Select telemetry baud rate");
168 rate_value.setToolTipText("Firmware version does not support variable telemetry rates");
171 void set_aprs_interval_tool_tip() {
172 if (aprs_interval_value.isVisible())
173 aprs_interval_value.setToolTipText("Enable APRS and set the interval between APRS reports");
175 aprs_interval_value.setToolTipText("Hardware doesn't support APRS");
178 void set_aprs_ssid_tool_tip() {
179 if (aprs_ssid_value.isVisible())
180 aprs_ssid_value.setToolTipText("Set the APRS SSID (secondary station identifier)");
181 else if (aprs_ssid_value.isVisible())
182 aprs_ssid_value.setToolTipText("Software version doesn't support setting the APRS SSID");
184 aprs_ssid_value.setToolTipText("Hardware doesn't support APRS");
187 void set_aprs_format_tool_tip() {
188 if (aprs_format_value.isVisible())
189 aprs_format_value.setToolTipText("Set the APRS format (compressed/uncompressed)");
190 else if (aprs_format_value.isVisible())
191 aprs_format_value.setToolTipText("Software version doesn't support setting the APRS format");
193 aprs_format_value.setToolTipText("Hardware doesn't support APRS");
196 void set_aprs_offset_tool_tip() {
197 if (aprs_offset_value.isVisible())
198 aprs_offset_value.setToolTipText("Set the APRS offset from top of minute");
199 else if (aprs_offset_value.isVisible())
200 aprs_offset_value.setToolTipText("Software version doesn't support setting the APRS offset");
202 aprs_offset_value.setToolTipText("Hardware doesn't support APRS");
205 void set_flight_log_max_tool_tip() {
206 if (flight_log_max_value.isVisible())
207 flight_log_max_value.setToolTipText("Size reserved for each flight log (in kB)");
209 flight_log_max_value.setToolTipText("Cannot set max value with flight logs in memory");
212 /* Build the UI using a grid bag */
213 public TeleGPSConfigUI(JFrame in_owner) {
214 super (in_owner, "Configure Device", false);
217 GridBagConstraints c;
220 Insets il = new Insets(4,4,4,4);
221 Insets ir = new Insets(4,4,4,4);
223 pane = getScrollablePane();
224 pane.setLayout(new GridBagLayout());
227 c = new GridBagConstraints();
228 c.gridx = 0; c.gridy = row;
230 c.fill = GridBagConstraints.NONE;
231 c.anchor = GridBagConstraints.LINE_START;
233 product_label = new JLabel("Product:");
234 pane.add(product_label, c);
236 c = new GridBagConstraints();
237 c.gridx = 4; c.gridy = row;
239 c.fill = GridBagConstraints.HORIZONTAL;
241 c.anchor = GridBagConstraints.LINE_START;
243 product_value = new JLabel("");
244 pane.add(product_value, c);
248 c = new GridBagConstraints();
249 c.gridx = 0; c.gridy = row;
251 c.fill = GridBagConstraints.NONE;
252 c.anchor = GridBagConstraints.LINE_START;
255 version_label = new JLabel("Software version:");
256 pane.add(version_label, c);
258 c = new GridBagConstraints();
259 c.gridx = 4; c.gridy = row;
261 c.fill = GridBagConstraints.HORIZONTAL;
263 c.anchor = GridBagConstraints.LINE_START;
266 version_value = new JLabel("");
267 pane.add(version_value, c);
271 c = new GridBagConstraints();
272 c.gridx = 0; c.gridy = row;
274 c.fill = GridBagConstraints.NONE;
275 c.anchor = GridBagConstraints.LINE_START;
278 serial_label = new JLabel("Serial:");
279 pane.add(serial_label, c);
281 c = new GridBagConstraints();
282 c.gridx = 4; c.gridy = row;
284 c.fill = GridBagConstraints.HORIZONTAL;
286 c.anchor = GridBagConstraints.LINE_START;
289 serial_value = new JLabel("");
290 pane.add(serial_value, c);
294 c = new GridBagConstraints();
295 c.gridx = 0; c.gridy = row;
297 c.fill = GridBagConstraints.NONE;
298 c.anchor = GridBagConstraints.LINE_START;
301 radio_frequency_label = new JLabel("Frequency:");
302 pane.add(radio_frequency_label, c);
304 c = new GridBagConstraints();
305 c.gridx = 4; c.gridy = row;
307 c.fill = GridBagConstraints.HORIZONTAL;
309 c.anchor = GridBagConstraints.LINE_START;
312 radio_frequency_value = new AltosUIFreqList();
313 radio_frequency_value.addItemListener(this);
314 pane.add(radio_frequency_value, c);
315 radio_frequency_value.setToolTipText("Telemetry, RDF and packet frequency");
318 /* Radio Calibration */
319 c = new GridBagConstraints();
320 c.gridx = 0; c.gridy = row;
322 c.fill = GridBagConstraints.NONE;
323 c.anchor = GridBagConstraints.LINE_START;
326 radio_calibration_label = new JLabel("RF Calibration:");
327 pane.add(radio_calibration_label, c);
329 c = new GridBagConstraints();
330 c.gridx = 4; c.gridy = row;
332 c.fill = GridBagConstraints.HORIZONTAL;
334 c.anchor = GridBagConstraints.LINE_START;
337 radio_calibration_value = new JLabel(String.format("%d", 1186611));
338 pane.add(radio_calibration_value, c);
342 c = new GridBagConstraints();
343 c.gridx = 0; c.gridy = row;
345 c.fill = GridBagConstraints.NONE;
346 c.anchor = GridBagConstraints.LINE_START;
349 radio_enable_label = new JLabel("Telemetry/RDF/APRS Enable:");
350 pane.add(radio_enable_label, c);
352 c = new GridBagConstraints();
353 c.gridx = 4; c.gridy = row;
355 c.fill = GridBagConstraints.HORIZONTAL;
357 c.anchor = GridBagConstraints.LINE_START;
360 radio_enable_value = new JRadioButton("Enabled");
361 radio_enable_value.addItemListener(this);
362 pane.add(radio_enable_value, c);
363 set_radio_enable_tool_tip();
366 /* Radio 10mW limit */
367 c = new GridBagConstraints();
368 c.gridx = 0; c.gridy = row;
370 c.fill = GridBagConstraints.NONE;
371 c.anchor = GridBagConstraints.LINE_START;
374 radio_10mw_label = new JLabel("Limit transmit to 10mW:");
375 pane.add(radio_10mw_label, c);
377 c = new GridBagConstraints();
378 c.gridx = 4; c.gridy = row;
380 c.fill = GridBagConstraints.HORIZONTAL;
382 c.anchor = GridBagConstraints.LINE_START;
385 radio_10mw_value = new JRadioButton("Limited");
386 radio_10mw_value.addItemListener(this);
387 pane.add(radio_10mw_value, c);
388 set_radio_10mw_tool_tip();
392 c = new GridBagConstraints();
393 c.gridx = 0; c.gridy = row;
395 c.fill = GridBagConstraints.NONE;
396 c.anchor = GridBagConstraints.LINE_START;
399 rate_label = new JLabel("Telemetry baud rate:");
400 pane.add(rate_label, c);
402 c = new GridBagConstraints();
403 c.gridx = 4; c.gridy = row;
405 c.fill = GridBagConstraints.HORIZONTAL;
407 c.anchor = GridBagConstraints.LINE_START;
410 rate_value = new AltosUIRateList();
411 rate_value.addItemListener(this);
412 pane.add(rate_value, c);
417 c = new GridBagConstraints();
418 c.gridx = 0; c.gridy = row;
420 c.fill = GridBagConstraints.NONE;
421 c.anchor = GridBagConstraints.LINE_START;
424 aprs_interval_label = new JLabel("APRS Interval(s):");
425 pane.add(aprs_interval_label, c);
427 c = new GridBagConstraints();
428 c.gridx = 4; c.gridy = row;
430 c.fill = GridBagConstraints.HORIZONTAL;
432 c.anchor = GridBagConstraints.LINE_START;
435 aprs_interval_value = new JComboBox<String>(aprs_interval_values);
436 aprs_interval_value.setEditable(true);
437 aprs_interval_value.addItemListener(this);
438 pane.add(aprs_interval_value, c);
439 set_aprs_interval_tool_tip();
443 c = new GridBagConstraints();
444 c.gridx = 0; c.gridy = row;
446 c.fill = GridBagConstraints.NONE;
447 c.anchor = GridBagConstraints.LINE_START;
450 aprs_ssid_label = new JLabel("APRS SSID:");
451 pane.add(aprs_ssid_label, c);
453 c = new GridBagConstraints();
454 c.gridx = 4; c.gridy = row;
456 c.fill = GridBagConstraints.HORIZONTAL;
458 c.anchor = GridBagConstraints.LINE_START;
461 aprs_ssid_value = new JComboBox<Integer>(aprs_ssid_values);
462 aprs_ssid_value.setEditable(false);
463 aprs_ssid_value.addItemListener(this);
464 aprs_ssid_value.setMaximumRowCount(aprs_ssid_values.length);
465 pane.add(aprs_ssid_value, c);
466 set_aprs_ssid_tool_tip();
470 c = new GridBagConstraints();
471 c.gridx = 0; c.gridy = row;
473 c.fill = GridBagConstraints.NONE;
474 c.anchor = GridBagConstraints.LINE_START;
477 aprs_format_label = new JLabel("APRS format:");
478 pane.add(aprs_format_label, c);
480 c = new GridBagConstraints();
481 c.gridx = 4; c.gridy = row;
483 c.fill = GridBagConstraints.HORIZONTAL;
485 c.anchor = GridBagConstraints.LINE_START;
488 aprs_format_value = new JComboBox<String>(AltosLib.ao_aprs_format_name);
489 aprs_format_value.setEditable(false);
490 aprs_format_value.addItemListener(this);
491 aprs_format_value.setMaximumRowCount(AltosLib.ao_aprs_format_name.length);
492 pane.add(aprs_format_value, c);
493 set_aprs_format_tool_tip();
497 c = new GridBagConstraints();
498 c.gridx = 0; c.gridy = row;
500 c.fill = GridBagConstraints.NONE;
501 c.anchor = GridBagConstraints.LINE_START;
504 aprs_offset_label = new JLabel("APRS offset:");
505 pane.add(aprs_offset_label, c);
507 c = new GridBagConstraints();
508 c.gridx = 4; c.gridy = row;
510 c.fill = GridBagConstraints.HORIZONTAL;
512 c.anchor = GridBagConstraints.LINE_START;
515 aprs_offset_value = new JComboBox<Integer>(aprs_offset_values);
516 aprs_offset_value.setEditable(false);
517 aprs_offset_value.addItemListener(this);
518 aprs_offset_value.setMaximumRowCount(aprs_offset_values.length);
519 pane.add(aprs_offset_value, c);
520 set_aprs_offset_tool_tip();
524 c = new GridBagConstraints();
525 c.gridx = 0; c.gridy = row;
527 c.fill = GridBagConstraints.NONE;
528 c.anchor = GridBagConstraints.LINE_START;
531 callsign_label = new JLabel("Callsign:");
532 pane.add(callsign_label, c);
534 c = new GridBagConstraints();
535 c.gridx = 4; c.gridy = row;
537 c.fill = GridBagConstraints.HORIZONTAL;
539 c.anchor = GridBagConstraints.LINE_START;
542 callsign_value = new JTextField(AltosUIPreferences.callsign());
543 callsign_value.getDocument().addDocumentListener(this);
544 pane.add(callsign_value, c);
545 callsign_value.setToolTipText("Callsign reported in telemetry data");
549 c = new GridBagConstraints();
550 c.gridx = 0; c.gridy = row;
552 c.fill = GridBagConstraints.NONE;
553 c.anchor = GridBagConstraints.LINE_START;
556 flight_log_max_label = new JLabel("Maximum Log Size (kB):");
557 pane.add(flight_log_max_label, c);
559 c = new GridBagConstraints();
560 c.gridx = 4; c.gridy = row;
562 c.fill = GridBagConstraints.HORIZONTAL;
564 c.anchor = GridBagConstraints.LINE_START;
567 flight_log_max_value = new JComboBox<String>();
568 flight_log_max_value.setEditable(true);
569 flight_log_max_value.addItemListener(this);
570 pane.add(flight_log_max_value, c);
571 set_flight_log_max_tool_tip();
574 /* Tracker triger horiz distances */
575 c = new GridBagConstraints();
576 c.gridx = 0; c.gridy = row;
578 c.fill = GridBagConstraints.NONE;
579 c.anchor = GridBagConstraints.LINE_START;
582 tracker_motion_label = new JLabel(get_tracker_motion_label());
583 pane.add(tracker_motion_label, c);
585 c = new GridBagConstraints();
586 c.gridx = 4; c.gridy = row;
588 c.fill = GridBagConstraints.HORIZONTAL;
590 c.anchor = GridBagConstraints.LINE_START;
593 tracker_motion_value = new JComboBox<String>(tracker_motion_values());
594 tracker_motion_value.setEditable(true);
595 tracker_motion_value.addItemListener(this);
596 pane.add(tracker_motion_value, c);
599 /* Tracker triger vert distances */
600 c = new GridBagConstraints();
601 c.gridx = 0; c.gridy = row;
603 c.fill = GridBagConstraints.NONE;
604 c.anchor = GridBagConstraints.LINE_START;
607 tracker_interval_label = new JLabel("Position Reporting Interval (s):");
608 pane.add(tracker_interval_label, c);
610 c = new GridBagConstraints();
611 c.gridx = 4; c.gridy = row;
613 c.fill = GridBagConstraints.HORIZONTAL;
615 c.anchor = GridBagConstraints.LINE_START;
618 tracker_interval_value = new JComboBox<String>(tracker_interval_values);
619 tracker_interval_value.setEditable(true);
620 tracker_interval_value.addItemListener(this);
621 pane.add(tracker_interval_value, c);
622 set_tracker_tool_tip();
626 c = new GridBagConstraints();
627 c.gridx = 0; c.gridy = row;
629 c.fill = GridBagConstraints.NONE;
630 c.anchor = GridBagConstraints.LINE_START;
632 save = new JButton("Save");
634 save.addActionListener(this);
635 save.setActionCommand("Save");
637 c = new GridBagConstraints();
638 c.gridx = 2; c.gridy = row;
640 c.fill = GridBagConstraints.NONE;
641 c.anchor = GridBagConstraints.CENTER;
643 reset = new JButton("Reset");
645 reset.addActionListener(this);
646 reset.setActionCommand("Reset");
648 c = new GridBagConstraints();
649 c.gridx = 4; c.gridy = row;
651 c.fill = GridBagConstraints.NONE;
652 c.anchor = GridBagConstraints.CENTER;
654 reboot = new JButton("Reboot");
656 reboot.addActionListener(this);
657 reboot.setActionCommand("Reboot");
659 c = new GridBagConstraints();
660 c.gridx = 6; c.gridy = row;
662 c.fill = GridBagConstraints.NONE;
663 c.anchor = GridBagConstraints.LINE_END;
665 close = new JButton("Close");
667 close.addActionListener(this);
668 close.setActionCommand("Close");
670 addWindowListener(new ConfigListener(this));
671 AltosPreferences.register_units_listener(this);
674 /* Once the initial values are set, the config code will show the dialog */
675 public void make_visible() {
677 setLocationRelativeTo(owner);
681 /* If any values have been changed, confirm before closing */
682 public boolean check_dirty(String operation) {
684 Object[] options = { String.format("%s anyway", operation), "Keep editing" };
686 i = JOptionPane.showOptionDialog(this,
687 String.format("Configuration modified. %s anyway?", operation),
688 "Configuration Modified",
689 JOptionPane.DEFAULT_OPTION,
690 JOptionPane.WARNING_MESSAGE,
691 null, options, options[1]);
698 public void set_dirty() {
700 save.setEnabled(true);
703 public void set_clean() {
705 save.setEnabled(false);
708 public void dispose() {
709 AltosPreferences.unregister_units_listener(this);
713 public int accel_cal_plus() {
714 return AltosLib.MISSING;
717 public int accel_cal_minus() {
718 return AltosLib.MISSING;
721 public void set_accel_cal(int accel_plus, int accel_minus) {
724 /* Listen for events from our buttons */
725 public void actionPerformed(ActionEvent e) {
726 String cmd = e.getActionCommand();
728 if (cmd.equals("Close") || cmd.equals("Reboot"))
729 if (!check_dirty(cmd))
731 listener.actionPerformed(e);
732 if (cmd.equals("Close") || cmd.equals("Reboot")) {
739 /* ItemListener interface method */
740 public void itemStateChanged(ItemEvent e) {
744 /* DocumentListener interface methods */
745 public void changedUpdate(DocumentEvent e) {
749 public void insertUpdate(DocumentEvent e) {
753 public void removeUpdate(DocumentEvent e) {
757 /* Let the config code hook on a listener */
758 public void addActionListener(ActionListener l) {
762 public void units_changed(boolean imperial_units) {
763 boolean was_dirty = dirty;
765 if (tracker_motion_value.isVisible()) {
766 String motion = tracker_motion_value.getSelectedItem().toString();
767 tracker_motion_label.setText(get_tracker_motion_label());
768 set_tracker_motion_values();
770 int m = (int) (AltosConvert.height.parse_locale(motion, !imperial_units) + 0.5);
771 set_tracker_motion(m);
772 } catch (ParseException pe) {
779 /* set and get all of the dialog values */
780 public void set_product(String product) {
781 radio_frequency_value.set_product(product);
782 product_value.setText(product);
783 set_flight_log_max_tool_tip();
786 public void set_version(String version) {
787 version_value.setText(version);
790 public void set_serial(int serial) {
791 radio_frequency_value.set_serial(serial);
792 serial_value.setText(String.format("%d", serial));
795 public void set_altitude_32(int altitude_32) {
798 public void set_main_deploy(int new_main_deploy) {
801 public int main_deploy() {
802 return AltosLib.MISSING;
805 public void set_apogee_delay(int new_apogee_delay) { }
807 public int apogee_delay() {
808 return AltosLib.MISSING;
811 public void set_apogee_lockout(int new_apogee_lockout) { }
813 public int apogee_lockout() { return AltosLib.MISSING; }
815 public void set_radio_frequency(double new_radio_frequency) {
816 if (new_radio_frequency != AltosLib.MISSING)
817 radio_frequency_value.set_frequency(new_radio_frequency);
818 radio_frequency_label.setVisible(new_radio_frequency != AltosLib.MISSING);
819 radio_frequency_value.setVisible(new_radio_frequency != AltosLib.MISSING);
822 public double radio_frequency() {
823 return radio_frequency_value.frequency();
826 public void set_radio_calibration(int new_radio_calibration) {
827 if (new_radio_calibration != AltosLib.MISSING)
828 radio_calibration_value.setText(String.format("%d", new_radio_calibration));
829 radio_calibration_value.setVisible(new_radio_calibration == AltosLib.MISSING);
830 radio_calibration_label.setVisible(new_radio_calibration == AltosLib.MISSING);
833 public void set_radio_enable(int new_radio_enable) {
834 if (new_radio_enable != AltosLib.MISSING)
835 radio_enable_value.setSelected(new_radio_enable != 0);
836 radio_enable_label.setVisible(new_radio_enable != AltosLib.MISSING);
837 radio_enable_value.setVisible(new_radio_enable != AltosLib.MISSING);
838 set_radio_enable_tool_tip();
841 public int radio_enable() {
842 if (radio_enable_value.isVisible())
843 return radio_enable_value.isSelected() ? 1 : 0;
845 return AltosLib.MISSING;
848 public void set_radio_10mw(int new_radio_10mw) {
849 if (new_radio_10mw != AltosLib.MISSING) {
850 radio_10mw_value.setSelected(new_radio_10mw != 0);
852 radio_10mw_value.setVisible(new_radio_10mw != AltosLib.MISSING);
853 radio_10mw_label.setVisible(new_radio_10mw != AltosLib.MISSING);
854 set_radio_10mw_tool_tip();
857 public int radio_10mw() {
858 if (radio_10mw_value.isVisible())
859 return radio_10mw_value.isSelected() ? 1 : 0;
861 return AltosLib.MISSING;
864 public void set_telemetry_rate(int new_rate) {
865 if (new_rate != AltosLib.MISSING)
866 rate_value.set_rate(new_rate);
867 rate_label.setVisible(new_rate != AltosLib.MISSING);
868 rate_value.setVisible(new_rate != AltosLib.MISSING);
871 public int telemetry_rate() {
872 return rate_value.rate();
875 public void set_callsign(String new_callsign) {
876 if (new_callsign != null)
877 callsign_value.setText(new_callsign);
878 callsign_value.setVisible(new_callsign != null);
879 callsign_label.setVisible(new_callsign != null);
882 public String callsign() {
883 if (callsign_value.isVisible())
884 return callsign_value.getText();
888 private int parse_int(String name, String s, boolean split) throws AltosConfigDataException {
891 v = s.split("\\s+")[0];
893 return Integer.parseInt(v);
894 } catch (NumberFormatException ne) {
895 throw new AltosConfigDataException("Invalid %s \"%s\"", name, s);
899 int flight_log_max_limit;
902 public String flight_log_max_label(int flight_log_max) {
903 if (flight_log_max_limit != 0) {
904 int nflight = flight_log_max_limit / flight_log_max;
905 String plural = nflight > 1 ? "s" : "";
907 return String.format("%d (%d flight%s)", flight_log_max, nflight, plural);
909 return String.format("%d", flight_log_max);
912 public void set_flight_log_max(int new_flight_log_max) {
913 flight_log_max_value.setSelectedItem(flight_log_max_label(new_flight_log_max));
914 flight_log_max = new_flight_log_max;
915 set_flight_log_max_tool_tip();
918 public void set_flight_log_max_enabled(boolean enable) {
919 flight_log_max_value.setEnabled(enable);
920 set_flight_log_max_tool_tip();
923 public int flight_log_max() throws AltosConfigDataException {
924 return parse_int("flight log max", flight_log_max_value.getSelectedItem().toString(), true);
927 public void set_flight_log_max_limit(int new_flight_log_max_limit, int new_storage_erase_unit) {
928 flight_log_max_limit = new_flight_log_max_limit;
929 if (new_flight_log_max_limit != AltosLib.MISSING) {
930 flight_log_max_value.removeAllItems();
931 for (int i = 8; i >= 1; i--) {
932 int size = flight_log_max_limit / i;
933 if (new_storage_erase_unit != 0)
934 size &= ~(new_storage_erase_unit - 1);
935 flight_log_max_value.addItem(String.format("%d (%d flights)", size, i));
938 if (flight_log_max != 0 && flight_log_max != AltosLib.MISSING)
939 set_flight_log_max(flight_log_max);
942 public void set_ignite_mode(int new_ignite_mode) { }
943 public int ignite_mode() { return AltosLib.MISSING; }
946 public void set_pad_orientation(int new_pad_orientation) { }
947 public int pad_orientation() { return AltosLib.MISSING; }
949 public void set_beep(int new_beep) { }
951 public int beep() { return AltosLib.MISSING; }
953 String[] tracker_motion_values() {
954 if (AltosConvert.imperial_units)
955 return tracker_motion_values_ft;
957 return tracker_motion_values_m;
960 void set_tracker_motion_values() {
961 String[] v = tracker_motion_values();
962 while (tracker_motion_value.getItemCount() > 0)
963 tracker_motion_value.removeItemAt(0);
964 for (int i = 0; i < v.length; i++)
965 tracker_motion_value.addItem(v[i]);
966 tracker_motion_value.setMaximumRowCount(v.length);
969 String get_tracker_motion_label() {
970 return String.format("Logging Trigger Motion (%s):", AltosConvert.height.parse_units());
973 void set_tracker_tool_tip() {
974 if (tracker_motion_value.isVisible())
975 tracker_motion_value.setToolTipText("How far the device must move before logging");
977 tracker_motion_value.setToolTipText("This device doesn't disable logging when stationary");
978 if (tracker_interval_value.isVisible())
979 tracker_interval_value.setToolTipText("How often to report GPS position");
981 tracker_interval_value.setToolTipText("This device can't configure interval");
984 public void set_tracker_motion(int tracker_motion) {
985 if (tracker_motion != AltosLib.MISSING)
986 tracker_motion_value.setSelectedItem(AltosConvert.height.say(tracker_motion));
987 tracker_motion_label.setVisible(tracker_motion != AltosLib.MISSING);
988 tracker_motion_value.setVisible(tracker_motion != AltosLib.MISSING);
991 public int tracker_motion() throws AltosConfigDataException {
992 if (tracker_motion_value.isVisible()) {
993 String str = tracker_motion_value.getSelectedItem().toString();
995 return (int) (AltosConvert.height.parse_locale(str) + 0.5);
996 } catch (ParseException pe) {
997 throw new AltosConfigDataException("invalid tracker motion %s", str);
1000 return AltosLib.MISSING;
1003 public void set_tracker_interval(int tracker_interval) {
1004 if (tracker_interval != AltosLib.MISSING)
1005 tracker_interval_value.setSelectedItem(String.format("%d", tracker_interval));
1006 tracker_interval_label.setVisible(tracker_interval != AltosLib.MISSING);
1007 tracker_interval_value.setVisible(tracker_interval != AltosLib.MISSING);
1010 public int tracker_interval() throws AltosConfigDataException {
1011 if (tracker_interval_value.isVisible())
1012 return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false);
1013 return AltosLib.MISSING;
1016 public void set_aprs_interval(int new_aprs_interval) {
1017 if (new_aprs_interval != AltosLib.MISSING)
1018 aprs_interval_value.setSelectedItem(Integer.toString(new_aprs_interval));
1019 aprs_interval_value.setVisible(new_aprs_interval != AltosLib.MISSING);
1020 aprs_interval_label.setVisible(new_aprs_interval != AltosLib.MISSING);
1021 set_aprs_interval_tool_tip();
1024 public int aprs_interval() throws AltosConfigDataException {
1025 if (aprs_interval_value.isVisible()) {
1026 String s = aprs_interval_value.getSelectedItem().toString();
1028 return parse_int("aprs interval", s, false);
1030 return AltosLib.MISSING;
1033 public void set_aprs_ssid(int new_aprs_ssid) {
1034 if (new_aprs_ssid != AltosLib.MISSING)
1035 aprs_ssid_value.setSelectedItem(new_aprs_ssid);
1036 aprs_ssid_value.setVisible(new_aprs_ssid != AltosLib.MISSING);
1037 aprs_ssid_label.setVisible(new_aprs_ssid != AltosLib.MISSING);
1038 set_aprs_ssid_tool_tip();
1041 public int aprs_ssid() throws AltosConfigDataException {
1042 if (aprs_ssid_value.isVisible()) {
1043 Integer i = (Integer) aprs_ssid_value.getSelectedItem();
1046 return AltosLib.MISSING;
1049 public void set_aprs_format(int new_aprs_format) {
1050 if (new_aprs_format != AltosLib.MISSING)
1051 aprs_format_value.setSelectedIndex(new_aprs_format);
1052 aprs_format_value.setVisible(new_aprs_format != AltosLib.MISSING);
1053 aprs_format_label.setVisible(new_aprs_format != AltosLib.MISSING);
1054 set_aprs_format_tool_tip();
1057 public int aprs_format() throws AltosConfigDataException {
1058 if (aprs_format_value.isVisible())
1059 return aprs_format_value.getSelectedIndex();
1060 return AltosLib.MISSING;
1062 public void set_aprs_offset(int new_aprs_offset) {
1063 if (new_aprs_offset != AltosLib.MISSING)
1064 aprs_offset_value.setSelectedItem(new_aprs_offset);
1065 aprs_offset_value.setVisible(new_aprs_offset != AltosLib.MISSING);
1066 aprs_offset_label.setVisible(new_aprs_offset != AltosLib.MISSING);
1067 set_aprs_offset_tool_tip();
1070 public int aprs_offset() throws AltosConfigDataException {
1071 if (aprs_offset_value.isVisible()) {
1072 Integer i = (Integer) aprs_offset_value.getSelectedItem();
1075 return AltosLib.MISSING;