altos: Set TeleGPS default log size to half of avaiable memory
[fw/altos] / telegps / TeleGPSConfigUI.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 org.altusmetrum.telegps;
19
20 import java.awt.*;
21 import java.awt.event.*;
22 import javax.swing.*;
23 import javax.swing.event.*;
24 import org.altusmetrum.altoslib_4.*;
25 import org.altusmetrum.altosuilib_2.*;
26
27 public class TeleGPSConfigUI
28         extends AltosUIDialog
29         implements ActionListener, ItemListener, DocumentListener, AltosConfigValues, AltosUnitsListener
30 {
31
32         Container               pane;
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         JLabel                  radio_enable_label;
40         JLabel                  aprs_interval_label;
41         JLabel                  flight_log_max_label;
42         JLabel                  callsign_label;
43         JLabel                  tracker_horiz_label;
44         JLabel                  tracker_vert_label;
45
46         public boolean          dirty;
47
48         JFrame                  owner;
49         JLabel                  product_value;
50         JLabel                  version_value;
51         JLabel                  serial_value;
52         AltosFreqList           radio_frequency_value;
53         JTextField              radio_calibration_value;
54         JRadioButton            radio_enable_value;
55         JComboBox<String>       aprs_interval_value;
56         JComboBox<String>       flight_log_max_value;
57         JTextField              callsign_value;
58         JComboBox<String>       tracker_horiz_value;
59         JComboBox<String>       tracker_vert_value;
60
61         JButton                 save;
62         JButton                 reset;
63         JButton                 reboot;
64         JButton                 close;
65
66         ActionListener          listener;
67
68         static String[]         flight_log_max_values = {
69                 "64", "128", "192", "256", "320",
70                 "384", "448", "512", "576", "640",
71                 "704", "768", "832", "896", "960",
72         };
73
74         static String[]         aprs_interval_values = {
75                 "Disabled",
76                 "2",
77                 "5",
78                 "10"
79         };
80
81         static String[]         tracker_horiz_values_m = {
82                 "250",
83                 "500",
84                 "1000",
85                 "2000"
86         };
87
88         static String[]         tracker_horiz_values_ft = {
89                 "500",
90                 "1000",
91                 "2500",
92                 "5000"
93         };
94
95         static String[]         tracker_vert_values_m = {
96                 "25",
97                 "50",
98                 "100",
99                 "200"
100         };
101
102         static String[]         tracker_vert_values_ft = {
103                 "50",
104                 "100",
105                 "250",
106                 "500"
107         };
108
109         /* A window listener to catch closing events and tell the config code */
110         class ConfigListener extends WindowAdapter {
111                 TeleGPSConfigUI ui;
112
113                 public ConfigListener(TeleGPSConfigUI this_ui) {
114                         ui = this_ui;
115                 }
116
117                 public void windowClosing(WindowEvent e) {
118                         ui.actionPerformed(new ActionEvent(e.getSource(),
119                                                            ActionEvent.ACTION_PERFORMED,
120                                                            "Close"));
121                 }
122         }
123
124         public void set_pyros(AltosPyro[] new_pyros) {
125         }
126
127         public AltosPyro[] pyros() {
128                 return null;
129         }
130
131         boolean is_telemetrum() {
132                 String  product = product_value.getText();
133                 return product != null && product.startsWith("TeleGPS");
134         }
135
136         void set_radio_calibration_tool_tip() {
137                 if (radio_calibration_value.isEnabled())
138                         radio_calibration_value.setToolTipText("Tune radio output to match desired frequency");
139                 else
140                         radio_calibration_value.setToolTipText("Cannot tune radio while connected over packet mode");
141         }
142
143         void set_radio_enable_tool_tip() {
144                 if (radio_enable_value.isEnabled())
145                         radio_enable_value.setToolTipText("Enable/Disable telemetry and RDF transmissions");
146                 else
147                         radio_enable_value.setToolTipText("Firmware version does not support disabling radio");
148         }
149
150         void set_aprs_interval_tool_tip() {
151                 if (aprs_interval_value.isEnabled())
152                         aprs_interval_value.setToolTipText("Enable APRS and set the interval between APRS reports");
153                 else
154                         aprs_interval_value.setToolTipText("Hardware doesn't support APRS");
155         }
156
157         void set_flight_log_max_tool_tip() {
158                 if (flight_log_max_value.isEnabled())
159                         flight_log_max_value.setToolTipText("Size reserved for each flight log (in kB)");
160                 else
161                         flight_log_max_value.setToolTipText("Cannot set max value with flight logs in memory");
162         }
163
164         /* Build the UI using a grid bag */
165         public TeleGPSConfigUI(JFrame in_owner) {
166                 super (in_owner, "Configure Flight Computer", false);
167
168                 owner = in_owner;
169                 GridBagConstraints c;
170                 int row = 0;
171
172                 Insets il = new Insets(4,4,4,4);
173                 Insets ir = new Insets(4,4,4,4);
174
175                 pane = getContentPane();
176                 pane.setLayout(new GridBagLayout());
177
178                 /* Product */
179                 c = new GridBagConstraints();
180                 c.gridx = 0; c.gridy = row;
181                 c.gridwidth = 4;
182                 c.fill = GridBagConstraints.NONE;
183                 c.anchor = GridBagConstraints.LINE_START;
184                 c.insets = il;
185                 product_label = new JLabel("Product:");
186                 pane.add(product_label, c);
187
188                 c = new GridBagConstraints();
189                 c.gridx = 4; c.gridy = row;
190                 c.gridwidth = 4;
191                 c.fill = GridBagConstraints.HORIZONTAL;
192                 c.weightx = 1;
193                 c.anchor = GridBagConstraints.LINE_START;
194                 c.insets = ir;
195                 product_value = new JLabel("");
196                 pane.add(product_value, c);
197                 row++;
198
199                 /* Version */
200                 c = new GridBagConstraints();
201                 c.gridx = 0; c.gridy = row;
202                 c.gridwidth = 4;
203                 c.fill = GridBagConstraints.NONE;
204                 c.anchor = GridBagConstraints.LINE_START;
205                 c.insets = il;
206                 c.ipady = 5;
207                 version_label = new JLabel("Software version:");
208                 pane.add(version_label, c);
209
210                 c = new GridBagConstraints();
211                 c.gridx = 4; c.gridy = row;
212                 c.gridwidth = 4;
213                 c.fill = GridBagConstraints.HORIZONTAL;
214                 c.weightx = 1;
215                 c.anchor = GridBagConstraints.LINE_START;
216                 c.insets = ir;
217                 c.ipady = 5;
218                 version_value = new JLabel("");
219                 pane.add(version_value, c);
220                 row++;
221
222                 /* Serial */
223                 c = new GridBagConstraints();
224                 c.gridx = 0; c.gridy = row;
225                 c.gridwidth = 4;
226                 c.fill = GridBagConstraints.NONE;
227                 c.anchor = GridBagConstraints.LINE_START;
228                 c.insets = il;
229                 c.ipady = 5;
230                 serial_label = new JLabel("Serial:");
231                 pane.add(serial_label, c);
232
233                 c = new GridBagConstraints();
234                 c.gridx = 4; c.gridy = row;
235                 c.gridwidth = 4;
236                 c.fill = GridBagConstraints.HORIZONTAL;
237                 c.weightx = 1;
238                 c.anchor = GridBagConstraints.LINE_START;
239                 c.insets = ir;
240                 c.ipady = 5;
241                 serial_value = new JLabel("");
242                 pane.add(serial_value, c);
243                 row++;
244
245                 /* Frequency */
246                 c = new GridBagConstraints();
247                 c.gridx = 0; c.gridy = row;
248                 c.gridwidth = 4;
249                 c.fill = GridBagConstraints.NONE;
250                 c.anchor = GridBagConstraints.LINE_START;
251                 c.insets = il;
252                 c.ipady = 5;
253                 radio_frequency_label = new JLabel("Frequency:");
254                 pane.add(radio_frequency_label, c);
255
256                 c = new GridBagConstraints();
257                 c.gridx = 4; c.gridy = row;
258                 c.gridwidth = 4;
259                 c.fill = GridBagConstraints.HORIZONTAL;
260                 c.weightx = 1;
261                 c.anchor = GridBagConstraints.LINE_START;
262                 c.insets = ir;
263                 c.ipady = 5;
264                 radio_frequency_value = new AltosFreqList();
265                 radio_frequency_value.addItemListener(this);
266                 pane.add(radio_frequency_value, c);
267                 radio_frequency_value.setToolTipText("Telemetry, RDF and packet frequency");
268                 row++;
269
270                 /* Radio Calibration */
271                 c = new GridBagConstraints();
272                 c.gridx = 0; c.gridy = row;
273                 c.gridwidth = 4;
274                 c.fill = GridBagConstraints.NONE;
275                 c.anchor = GridBagConstraints.LINE_START;
276                 c.insets = il;
277                 c.ipady = 5;
278                 radio_calibration_label = new JLabel("RF Calibration:");
279                 pane.add(radio_calibration_label, c);
280
281                 c = new GridBagConstraints();
282                 c.gridx = 4; c.gridy = row;
283                 c.gridwidth = 4;
284                 c.fill = GridBagConstraints.HORIZONTAL;
285                 c.weightx = 1;
286                 c.anchor = GridBagConstraints.LINE_START;
287                 c.insets = ir;
288                 c.ipady = 5;
289                 radio_calibration_value = new JTextField(String.format("%d", 1186611));
290                 radio_calibration_value.getDocument().addDocumentListener(this);
291                 pane.add(radio_calibration_value, c);
292                 set_radio_calibration_tool_tip();
293                 row++;
294
295                 /* Radio Enable */
296                 c = new GridBagConstraints();
297                 c.gridx = 0; c.gridy = row;
298                 c.gridwidth = 4;
299                 c.fill = GridBagConstraints.NONE;
300                 c.anchor = GridBagConstraints.LINE_START;
301                 c.insets = il;
302                 c.ipady = 5;
303                 radio_enable_label = new JLabel("Telemetry/RDF/APRS Enable:");
304                 pane.add(radio_enable_label, c);
305
306                 c = new GridBagConstraints();
307                 c.gridx = 4; c.gridy = row;
308                 c.gridwidth = 4;
309                 c.fill = GridBagConstraints.HORIZONTAL;
310                 c.weightx = 1;
311                 c.anchor = GridBagConstraints.LINE_START;
312                 c.insets = ir;
313                 c.ipady = 5;
314                 radio_enable_value = new JRadioButton("Enabled");
315                 radio_enable_value.addItemListener(this);
316                 pane.add(radio_enable_value, c);
317                 set_radio_enable_tool_tip();
318                 row++;
319
320                 /* APRS interval */
321                 c = new GridBagConstraints();
322                 c.gridx = 0; c.gridy = row;
323                 c.gridwidth = 4;
324                 c.fill = GridBagConstraints.NONE;
325                 c.anchor = GridBagConstraints.LINE_START;
326                 c.insets = il;
327                 c.ipady = 5;
328                 aprs_interval_label = new JLabel("APRS Interval(s):");
329                 pane.add(aprs_interval_label, c);
330
331                 c = new GridBagConstraints();
332                 c.gridx = 4; c.gridy = row;
333                 c.gridwidth = 4;
334                 c.fill = GridBagConstraints.HORIZONTAL;
335                 c.weightx = 1;
336                 c.anchor = GridBagConstraints.LINE_START;
337                 c.insets = ir;
338                 c.ipady = 5;
339                 aprs_interval_value = new JComboBox<String>(aprs_interval_values);
340                 aprs_interval_value.setEditable(true);
341                 aprs_interval_value.addItemListener(this);
342                 pane.add(aprs_interval_value, c);
343                 set_aprs_interval_tool_tip();
344                 row++;
345
346                 /* Callsign */
347                 c = new GridBagConstraints();
348                 c.gridx = 0; c.gridy = row;
349                 c.gridwidth = 4;
350                 c.fill = GridBagConstraints.NONE;
351                 c.anchor = GridBagConstraints.LINE_START;
352                 c.insets = il;
353                 c.ipady = 5;
354                 callsign_label = new JLabel("Callsign:");
355                 pane.add(callsign_label, c);
356
357                 c = new GridBagConstraints();
358                 c.gridx = 4; c.gridy = row;
359                 c.gridwidth = 4;
360                 c.fill = GridBagConstraints.HORIZONTAL;
361                 c.weightx = 1;
362                 c.anchor = GridBagConstraints.LINE_START;
363                 c.insets = ir;
364                 c.ipady = 5;
365                 callsign_value = new JTextField(AltosUIPreferences.callsign());
366                 callsign_value.getDocument().addDocumentListener(this);
367                 pane.add(callsign_value, c);
368                 callsign_value.setToolTipText("Callsign reported in telemetry data");
369                 row++;
370
371                 /* Flight log max */
372                 c = new GridBagConstraints();
373                 c.gridx = 0; c.gridy = row;
374                 c.gridwidth = 4;
375                 c.fill = GridBagConstraints.NONE;
376                 c.anchor = GridBagConstraints.LINE_START;
377                 c.insets = il;
378                 c.ipady = 5;
379                 flight_log_max_label = new JLabel("Maximum Flight Log Size:");
380                 pane.add(flight_log_max_label, c);
381
382                 c = new GridBagConstraints();
383                 c.gridx = 4; c.gridy = row;
384                 c.gridwidth = 4;
385                 c.fill = GridBagConstraints.HORIZONTAL;
386                 c.weightx = 1;
387                 c.anchor = GridBagConstraints.LINE_START;
388                 c.insets = ir;
389                 c.ipady = 5;
390                 flight_log_max_value = new JComboBox<String>(flight_log_max_values);
391                 flight_log_max_value.setEditable(true);
392                 flight_log_max_value.addItemListener(this);
393                 pane.add(flight_log_max_value, c);
394                 set_flight_log_max_tool_tip();
395                 row++;
396
397                 /* Tracker triger horiz distances */
398                 c = new GridBagConstraints();
399                 c.gridx = 0; c.gridy = row;
400                 c.gridwidth = 4;
401                 c.fill = GridBagConstraints.NONE;
402                 c.anchor = GridBagConstraints.LINE_START;
403                 c.insets = il;
404                 c.ipady = 5;
405                 tracker_horiz_label = new JLabel(get_tracker_horiz_label());
406                 pane.add(tracker_horiz_label, c);
407
408                 c = new GridBagConstraints();
409                 c.gridx = 4; c.gridy = row;
410                 c.gridwidth = 4;
411                 c.fill = GridBagConstraints.HORIZONTAL;
412                 c.weightx = 1;
413                 c.anchor = GridBagConstraints.LINE_START;
414                 c.insets = ir;
415                 c.ipady = 5;
416                 tracker_horiz_value = new JComboBox<String>(tracker_horiz_values());
417                 tracker_horiz_value.setEditable(true);
418                 tracker_horiz_value.addItemListener(this);
419                 pane.add(tracker_horiz_value, c);
420                 row++;
421
422                 /* Tracker triger vert distances */
423                 c = new GridBagConstraints();
424                 c.gridx = 0; c.gridy = row;
425                 c.gridwidth = 4;
426                 c.fill = GridBagConstraints.NONE;
427                 c.anchor = GridBagConstraints.LINE_START;
428                 c.insets = il;
429                 c.ipady = 5;
430                 tracker_vert_label = new JLabel(get_tracker_vert_label());
431                 pane.add(tracker_vert_label, c);
432
433                 c = new GridBagConstraints();
434                 c.gridx = 4; c.gridy = row;
435                 c.gridwidth = 4;
436                 c.fill = GridBagConstraints.HORIZONTAL;
437                 c.weightx = 1;
438                 c.anchor = GridBagConstraints.LINE_START;
439                 c.insets = ir;
440                 c.ipady = 5;
441                 tracker_vert_value = new JComboBox<String>(tracker_vert_values());
442                 tracker_vert_value.setEditable(true);
443                 tracker_vert_value.addItemListener(this);
444                 pane.add(tracker_vert_value, c);
445                 set_tracker_tool_tip();
446                 row++;
447
448                 /* Buttons */
449                 c = new GridBagConstraints();
450                 c.gridx = 0; c.gridy = row;
451                 c.gridwidth = 2;
452                 c.fill = GridBagConstraints.NONE;
453                 c.anchor = GridBagConstraints.LINE_START;
454                 c.insets = il;
455                 save = new JButton("Save");
456                 pane.add(save, c);
457                 save.addActionListener(this);
458                 save.setActionCommand("Save");
459
460                 c = new GridBagConstraints();
461                 c.gridx = 2; c.gridy = row;
462                 c.gridwidth = 2;
463                 c.fill = GridBagConstraints.NONE;
464                 c.anchor = GridBagConstraints.CENTER;
465                 c.insets = il;
466                 reset = new JButton("Reset");
467                 pane.add(reset, c);
468                 reset.addActionListener(this);
469                 reset.setActionCommand("Reset");
470
471                 c = new GridBagConstraints();
472                 c.gridx = 4; c.gridy = row;
473                 c.gridwidth = 2;
474                 c.fill = GridBagConstraints.NONE;
475                 c.anchor = GridBagConstraints.CENTER;
476                 c.insets = il;
477                 reboot = new JButton("Reboot");
478                 pane.add(reboot, c);
479                 reboot.addActionListener(this);
480                 reboot.setActionCommand("Reboot");
481
482                 c = new GridBagConstraints();
483                 c.gridx = 6; c.gridy = row;
484                 c.gridwidth = 2;
485                 c.fill = GridBagConstraints.NONE;
486                 c.anchor = GridBagConstraints.LINE_END;
487                 c.insets = il;
488                 close = new JButton("Close");
489                 pane.add(close, c);
490                 close.addActionListener(this);
491                 close.setActionCommand("Close");
492
493                 addWindowListener(new ConfigListener(this));
494                 AltosPreferences.register_units_listener(this);
495         }
496
497         /* Once the initial values are set, the config code will show the dialog */
498         public void make_visible() {
499                 pack();
500                 setLocationRelativeTo(owner);
501                 setVisible(true);
502         }
503
504         /* If any values have been changed, confirm before closing */
505         public boolean check_dirty(String operation) {
506                 if (dirty) {
507                         Object[] options = { String.format("%s anyway", operation), "Keep editing" };
508                         int i;
509                         i = JOptionPane.showOptionDialog(this,
510                                                          String.format("Configuration modified. %s anyway?", operation),
511                                                          "Configuration Modified",
512                                                          JOptionPane.DEFAULT_OPTION,
513                                                          JOptionPane.WARNING_MESSAGE,
514                                                          null, options, options[1]);
515                         if (i != 0)
516                                 return false;
517                 }
518                 return true;
519         }
520
521         void set_dirty() {
522                 dirty = true;
523                 save.setEnabled(true);
524         }
525
526         public void set_clean() {
527                 dirty = false;
528                 save.setEnabled(false);
529         }
530
531         public void dispose() {
532                 AltosPreferences.unregister_units_listener(this);
533                 super.dispose();
534         }
535
536         /* Listen for events from our buttons */
537         public void actionPerformed(ActionEvent e) {
538                 String  cmd = e.getActionCommand();
539
540                 if (cmd.equals("Close") || cmd.equals("Reboot"))
541                         if (!check_dirty(cmd))
542                                 return;
543                 listener.actionPerformed(e);
544                 if (cmd.equals("Close") || cmd.equals("Reboot")) {
545                         setVisible(false);
546                         dispose();
547                 }
548                 set_clean();
549         }
550
551         /* ItemListener interface method */
552         public void itemStateChanged(ItemEvent e) {
553                 set_dirty();
554         }
555
556         /* DocumentListener interface methods */
557         public void changedUpdate(DocumentEvent e) {
558                 set_dirty();
559         }
560
561         public void insertUpdate(DocumentEvent e) {
562                 set_dirty();
563         }
564
565         public void removeUpdate(DocumentEvent e) {
566                 set_dirty();
567         }
568
569         /* Let the config code hook on a listener */
570         public void addActionListener(ActionListener l) {
571                 listener = l;
572         }
573
574         public void units_changed(boolean imperial_units) {
575                 if (tracker_horiz_value.isEnabled() && tracker_vert_value.isEnabled()) {
576                         String th = tracker_horiz_value.getSelectedItem().toString();
577                         String tv = tracker_vert_value.getSelectedItem().toString();
578                         tracker_horiz_label.setText(get_tracker_horiz_label());
579                         tracker_vert_label.setText(get_tracker_vert_label());
580                         set_tracker_horiz_values();
581                         set_tracker_vert_values();
582                         int[] t = {
583                                 (int) (AltosConvert.height.parse(th, !imperial_units) + 0.5),
584                                 (int) (AltosConvert.height.parse(tv, !imperial_units) + 0.5)
585                         };
586                         set_tracker_distances(t);
587                 }
588         }
589
590         /* set and get all of the dialog values */
591         public void set_product(String product) {
592                 radio_frequency_value.set_product(product);
593                 product_value.setText(product);
594                 set_flight_log_max_tool_tip();
595         }
596
597         public void set_version(String version) {
598                 version_value.setText(version);
599         }
600
601         public void set_serial(int serial) {
602                 radio_frequency_value.set_serial(serial);
603                 serial_value.setText(String.format("%d", serial));
604         }
605
606         public void set_main_deploy(int new_main_deploy) {
607         }
608
609         public int main_deploy() {
610                 return -1;
611         }
612
613         public void set_apogee_delay(int new_apogee_delay) { }
614
615         public int apogee_delay() {
616                 return -1;
617         }
618
619         public void set_apogee_lockout(int new_apogee_lockout) { }
620
621         public int apogee_lockout() { return -1; }
622
623         public void set_radio_frequency(double new_radio_frequency) {
624                 radio_frequency_value.set_frequency(new_radio_frequency);
625         }
626
627         public double radio_frequency() {
628                 return radio_frequency_value.frequency();
629         }
630
631         public void set_radio_calibration(int new_radio_calibration) {
632                 radio_calibration_value.setVisible(new_radio_calibration >= 0);
633                 if (new_radio_calibration < 0)
634                         radio_calibration_value.setText("Disabled");
635                 else
636                         radio_calibration_value.setText(String.format("%d", new_radio_calibration));
637         }
638
639         public int radio_calibration() {
640                 return Integer.parseInt(radio_calibration_value.getText());
641         }
642
643         public void set_radio_enable(int new_radio_enable) {
644                 if (new_radio_enable >= 0) {
645                         radio_enable_value.setSelected(new_radio_enable > 0);
646                         radio_enable_value.setEnabled(true);
647                 } else {
648                         radio_enable_value.setSelected(true);
649                         radio_enable_value.setVisible(radio_frequency() > 0);
650                         radio_enable_value.setEnabled(false);
651                 }
652                 set_radio_enable_tool_tip();
653         }
654
655         public int radio_enable() {
656                 if (radio_enable_value.isEnabled())
657                         return radio_enable_value.isSelected() ? 1 : 0;
658                 else
659                         return -1;
660         }
661
662         public void set_callsign(String new_callsign) {
663                 callsign_value.setVisible(new_callsign != null);
664                 callsign_value.setText(new_callsign);
665         }
666
667         public String callsign() {
668                 return callsign_value.getText();
669         }
670
671         public void set_flight_log_max(int new_flight_log_max) {
672                 flight_log_max_value.setSelectedItem(Integer.toString(new_flight_log_max));
673                 set_flight_log_max_tool_tip();
674         }
675
676         public void set_flight_log_max_enabled(boolean enable) {
677                 flight_log_max_value.setEnabled(enable);
678                 set_flight_log_max_tool_tip();
679         }
680
681         public int flight_log_max() {
682                 return Integer.parseInt(flight_log_max_value.getSelectedItem().toString());
683         }
684
685         public void set_flight_log_max_limit(int flight_log_max_limit) {
686                 //boolean       any_added = false;
687                 flight_log_max_value.removeAllItems();
688                 for (int i = 0; i < flight_log_max_values.length; i++) {
689                         if (Integer.parseInt(flight_log_max_values[i]) < flight_log_max_limit){
690                                 flight_log_max_value.addItem(flight_log_max_values[i]);
691                                 //any_added = true;
692                         }
693                 }
694                 flight_log_max_value.addItem(String.format("%d", flight_log_max_limit));
695         }
696
697         public void set_ignite_mode(int new_ignite_mode) { }
698         public int ignite_mode() { return -1; }
699
700
701         public void set_pad_orientation(int new_pad_orientation) { }
702         public int pad_orientation() { return -1; }
703
704         public void set_beep(int new_beep) { }
705
706         public int beep() { return -1; }
707
708         String[] tracker_horiz_values() {
709                 if (AltosConvert.imperial_units)
710                         return tracker_horiz_values_ft;
711                 else
712                         return tracker_horiz_values_m;
713         }
714
715         void set_tracker_horiz_values() {
716                 String[]        v = tracker_horiz_values();
717                 while (tracker_horiz_value.getItemCount() > 0)
718                         tracker_horiz_value.removeItemAt(0);
719                 for (int i = 0; i < v.length; i++)
720                         tracker_horiz_value.addItem(v[i]);
721                 tracker_horiz_value.setMaximumRowCount(v.length);
722         }
723
724         String get_tracker_horiz_label() {
725                 return String.format("Logging Trigger Horizontal (%s):", AltosConvert.height.show_units());
726         }
727
728         String[] tracker_vert_values() {
729                 if (AltosConvert.imperial_units)
730                         return tracker_vert_values_ft;
731                 else
732                         return tracker_vert_values_m;
733         }
734
735         void set_tracker_vert_values() {
736                 String[]        v = tracker_vert_values();
737                 while (tracker_vert_value.getItemCount() > 0)
738                         tracker_vert_value.removeItemAt(0);
739                 for (int i = 0; i < v.length; i++)
740                         tracker_vert_value.addItem(v[i]);
741                 tracker_vert_value.setMaximumRowCount(v.length);
742         }
743
744         void set_tracker_tool_tip() {
745                 if (tracker_horiz_value.isEnabled())
746                         tracker_horiz_value.setToolTipText("How far the device must move before logging is enabled");
747                 else
748                         tracker_horiz_value.setToolTipText("This device doesn't disable logging before motion");
749                 if (tracker_vert_value.isEnabled())
750                         tracker_vert_value.setToolTipText("How far the device must move before logging is enabled");
751                 else
752                         tracker_vert_value.setToolTipText("This device doesn't disable logging before motion");
753         }
754
755         String get_tracker_vert_label() {
756                 return String.format("Logging Trigger Vertical (%s):", AltosConvert.height.show_units());
757         }
758
759         public void set_tracker_distances(int[] tracker_distances) {
760                 if (tracker_distances != null) {
761                         tracker_horiz_value.setSelectedItem(AltosConvert.height.say(tracker_distances[0]));
762                         tracker_vert_value.setSelectedItem(AltosConvert.height.say(tracker_distances[1]));
763                         tracker_horiz_value.setEnabled(true);
764                         tracker_vert_value.setEnabled(true);
765                 } else {
766                         tracker_horiz_value.setEnabled(false);
767                         tracker_vert_value.setEnabled(false);
768                 }
769         }
770
771         public int[] tracker_distances() {
772                 if (tracker_horiz_value.isEnabled() && tracker_vert_value.isEnabled()) {
773                         int[] t = {
774                                 (int) (AltosConvert.height.parse(tracker_horiz_value.getSelectedItem().toString()) + 0.5),
775                                 (int) (AltosConvert.height.parse(tracker_vert_value.getSelectedItem().toString()) + 0.5),
776                         };
777                         return t;
778                 }
779                 return null;
780         }
781
782         public void set_aprs_interval(int new_aprs_interval) {
783                 String  s;
784
785                 if (new_aprs_interval <= 0)
786                         s = "Disabled";
787                 else
788                         s = Integer.toString(new_aprs_interval);
789                 aprs_interval_value.setSelectedItem(s);
790                 aprs_interval_value.setVisible(new_aprs_interval >= 0);
791                 set_aprs_interval_tool_tip();
792         }
793
794         public int aprs_interval() {
795                 String  s = aprs_interval_value.getSelectedItem().toString();
796
797                 if (s.equals("Disabled"))
798                         return 0;
799                 return Integer.parseInt(s);
800         }
801 }