altoslib: Improve EEprom download
authorKeith Packard <keithp@keithp.com>
Sun, 12 Nov 2017 04:49:20 +0000 (20:49 -0800)
committerKeith Packard <keithp@keithp.com>
Sun, 12 Nov 2017 04:49:20 +0000 (20:49 -0800)
* Catch and report CRC errors
* Deal with corrupted flight records
* Add ability to immediately graph new data
* Check before overwriting existing files

Signed-off-by: Keith Packard <keithp@keithp.com>
14 files changed:
altoslib/AltosEeprom.java
altoslib/AltosEepromDownload.java
altoslib/AltosEepromList.java
altoslib/AltosEepromLog.java
altoslib/AltosEepromMonitor.java
altoslib/AltosEepromRecord.java
altoslib/AltosEepromRecordSet.java
altoslib/AltosFile.java
altosui/AltosUI.java
altosuilib/AltosEepromDelete.java
altosuilib/AltosEepromManage.java
altosuilib/AltosEepromMonitorUI.java
altosuilib/AltosEepromSelect.java
telegps/TeleGPS.java

index ad7bf88..124bd47 100644 (file)
@@ -22,6 +22,7 @@ public class AltosEeprom {
        private AltosJson       config;
        ArrayList<Byte>         data;
        private AltosConfigData config_data;
+       int                     errors = 0;
 
        /*
         * Public accessor APIs
index 3df8a5b..547b523 100644 (file)
@@ -200,25 +200,47 @@ public class AltosEepromDownload implements Runnable {
 
                AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data);
 
-               monitor.set_filename(f.toString());
+               log.set_file(f);
 
-               FileWriter w = new FileWriter(f);
+               boolean do_write = true;
 
-               eeprom.write(w);
-               w.close();
+               if (f.exists())
+                       do_write = monitor.check_overwrite(f);
+
+               if (do_write) {
+                       FileWriter w = new FileWriter(f);
+
+                       eeprom.write(w);
+                       w.close();
+               }
+
+               if (eeprom.errors != 0)
+                       throw new ParseException(String.format("%d CRC Errors", eeprom.errors), 0);
+       }
+
+       static String label(int flight) {
+               if (flight < 0)
+                       return "Corrupt";
+               else
+                       return "Flight";
+       }
+
+       static int flight(int flight) {
+               if (flight < 0)
+                       return -flight;
+               return flight;
        }
 
        public void run () {
                boolean success = false;
 
                try {
-                       boolean failed = false;
                        if (remote)
                                link.start_remote();
 
                        for (AltosEepromLog log : flights) {
                                parse_errors = null;
-                               if (log.selected) {
+                               if (log.download_selected) {
                                        monitor.reset();
                                        try {
                                                CaptureLog(log);
@@ -226,16 +248,16 @@ public class AltosEepromDownload implements Runnable {
                                                LogError(e.getMessage());
                                        }
                                }
+                               success = true;
                                if (parse_errors != null) {
-                                       failed = true;
-                                       monitor.show_message(String.format("Flight %d download error. Valid log data saved\n%s",
-                                                                          log.flight,
+                                       monitor.show_message(String.format("%s %d download error. Valid log data saved\n%s",
+                                                                          label(log.flight),
+                                                                          flight(log.flight),
                                                                           parse_errors),
                                                             link.name,
                                                             AltosEepromMonitor.WARNING_MESSAGE);
                                }
                        }
-                       success = !failed;
                } catch (IOException ee) {
                        monitor.show_message(ee.getLocalizedMessage(),
                                             link.name,
index 55d47e2..c55bcaa 100644 (file)
@@ -87,7 +87,7 @@ public class AltosEepromList extends ArrayList<AltosEepromLog> {
                                                        start = AltosParse.parse_hex(tokens[3]);
                                                if (tokens[4].equals("end"))
                                                        end = AltosParse.parse_hex(tokens[5]);
-                                               if (flight > 0 && start >= 0 && end > 0)
+                                               if (flight != 0 && start >= 0 && end > 0)
                                                        flights.add(new AltosEepromFlight(flight, start, end));
                                        } catch (ParseException pe) { System.out.printf("Parse error %s\n", pe.toString()); }
                                }
@@ -115,4 +115,4 @@ public class AltosEepromList extends ArrayList<AltosEepromLog> {
                        link.flush_output();
                }
        }
-}
\ No newline at end of file
+}
index 8d1f3fc..ba722b8 100644 (file)
@@ -18,6 +18,7 @@
 
 package org.altusmetrum.altoslib_12;
 
+import java.io.*;
 import java.text.*;
 import java.util.concurrent.*;
 
@@ -32,7 +33,15 @@ public class AltosEepromLog {
        public int              start_block;
        public int              end_block;
 
-       public boolean          selected;
+       public boolean          download_selected;
+       public boolean          delete_selected;
+       public boolean          graph_selected;
+
+       public File             file;
+
+       public void set_file(File file) {
+               this.file = file;
+       }
 
        public AltosEepromLog(AltosConfigData config_data,
                              AltosLink link,
@@ -50,8 +59,11 @@ public class AltosEepromLog {
                serial = config_data.serial;
 
                /*
-                * Select all flights for download
+                * Select all flights for download and graph, but not
+                * for delete
                 */
-               selected = true;
+               download_selected = true;
+               delete_selected = false;
+               graph_selected = true;
        }
 }
index a99ec68..11144a3 100644 (file)
@@ -18,6 +18,8 @@
 
 package org.altusmetrum.altoslib_12;
 
+import java.io.*;
+
 public interface AltosEepromMonitor {
 
        public void set_block(int in_block);
@@ -28,8 +30,6 @@ public interface AltosEepromMonitor {
 
        public void set_flight(int in_flight);
 
-       public void set_filename(String in_file);
-
        public void set_thread(Thread eeprom_thread);
 
        final static int INFO_MESSAGE = 0;
@@ -38,6 +38,8 @@ public interface AltosEepromMonitor {
 
        public void show_message(String message, String title, int message_type);
 
+       public Boolean check_overwrite(File file);
+
        public void start();
 
        public void done(boolean success);
index 12519e6..43e8ea4 100644 (file)
@@ -50,8 +50,22 @@ public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord>
                return data8(i) | (data8(i+1) << 8) | (data8(i+2) << 16) | (data8(i+3) << 24);
        }
 
+       public boolean empty(int s) {
+               for (int i = 0; i < length; i++)
+                       if (eeprom.data8(s + i) != 0xff)
+                               return false;
+               return true;
+       }
+
        public boolean valid(int s) {
-               return AltosConvert.checksum(eeprom.data, s, length) == 0;
+               int     ck = AltosConvert.checksum(eeprom.data, s, length);
+
+               if (ck != 0) {
+                       ++eeprom.errors;
+                       System.out.printf("invalid checksum 0x%x at 0x%x\n", ck, s);
+                       return false;
+               }
+               return true;
        }
 
        public boolean valid() {
@@ -100,25 +114,18 @@ public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord>
                int     s = start + length;
 
                while (s + length <= eeprom.data.size()) {
-                       if (valid(s))
+                       if (!empty(s) && valid(s))
                                return s;
                        s += length;
                }
                return -1;
        }
 
-       public boolean hasNext() {
-               return next_start() >= 0;
-       }
-
        public abstract AltosEepromRecord next();
 
        public AltosEepromRecord(AltosEeprom eeprom, int start, int length) {
                this.eeprom = eeprom;
                this.start = start;
                this.length = length;
-
-               while (start + length < eeprom.data.size() && !valid())
-                       start += length;
        }
 }
index d91ae3a..82a5ea2 100644 (file)
@@ -97,7 +97,7 @@ public class AltosEepromRecordSet implements AltosRecordSet {
                int     tick = 0;
                boolean first = true;
 
-               for (;;) {
+               do {
                        int     t = record.tick();
 
                        if (first) {
@@ -110,10 +110,8 @@ public class AltosEepromRecordSet implements AltosRecordSet {
                        }
                        record.wide_tick = tick;
                        ordered.add(record);
-                       if (!record.hasNext())
-                               break;
                        record = record.next();
-               }
+               } while (record != null);
        }
 
        public AltosEepromRecordSet(InputStream input) throws IOException {
index 69f779c..6f98b87 100644 (file)
@@ -36,10 +36,23 @@ public class AltosFile extends File {
                return String.format("-via-%04d", receiver);
        }
 
+       static private String label(int flight) {
+               if (flight < 0)
+                       return "corrupt";
+               else
+                       return "flight";
+       }
+
+       static private int flight(int flight) {
+               if (flight < 0)
+                       return -flight;
+               return flight;
+       }
+
        public AltosFile(int year, int month, int day, int serial, int flight, int receiver, String extension) {
                super (AltosPreferences.logdir(),
-                      String.format("%04d-%02d-%02d-serial-%s-flight-%s%s.%s",
-                                    year, month, day, number(serial), number(flight), receiver(receiver), extension));
+                      String.format("%04d-%02d-%02d-serial-%s-%s-%s%s.%s",
+                                    year, month, day, number(serial), label(flight), number(flight(flight)), receiver(receiver), extension));
        }
 
        public AltosFile(int year, int month, int day, int serial, int flight, String extension) {
index bc8eaa7..02e49a9 100644 (file)
@@ -26,7 +26,7 @@ import java.util.concurrent.*;
 import org.altusmetrum.altoslib_12.*;
 import org.altusmetrum.altosuilib_12.*;
 
-public class AltosUI extends AltosUIFrame {
+public class AltosUI extends AltosUIFrame implements AltosEepromGrapher {
        public AltosVoice voice = new AltosVoice();
 
        public static boolean load_library(Frame frame) {
@@ -320,8 +320,17 @@ public class AltosUI extends AltosUIFrame {
        /* Connect to TeleMetrum, either directly or through
         * a TeleDongle over the packet link
         */
+
+       public void graph_flights(AltosEepromList flights) {
+               for (AltosEepromLog flight : flights) {
+                       if (flight.graph_selected && flight.file != null) {
+                               process_graph(flight.file);
+                       }
+               }
+       }
+
        private void SaveFlightData() {
-               new AltosEepromManage(AltosUI.this, AltosLib.product_any);
+               new AltosEepromManage(this, this, AltosLib.product_any);
        }
 
        private static AltosFlightSeries make_series(AltosRecordSet set) {
index 87e80a5..d7dde6d 100644 (file)
@@ -84,7 +84,7 @@ public class AltosEepromDelete implements Runnable {
                                serial_line.start_remote();
 
                        for (AltosEepromLog log : flights) {
-                               if (log.selected) {
+                               if (log.delete_selected) {
                                        DeleteLog(log);
                                }
                        }
index 9382713..1adf1f0 100644 (file)
@@ -33,6 +33,7 @@ public class AltosEepromManage implements ActionListener {
        AltosEepromList         flights;
        AltosEepromDownload     download;
        AltosEepromDelete       delete;
+       AltosEepromGrapher      grapher;
 
        public void finish() {
                if (serial_line != null) {
@@ -48,7 +49,7 @@ public class AltosEepromManage implements ActionListener {
        private int countDeletedFlights() {
                int count = 0;
                for (AltosEepromLog flight : flights) {
-                       if (flight.selected)
+                       if (flight.delete_selected)
                                count++;
                }
                return count;
@@ -58,7 +59,7 @@ public class AltosEepromManage implements ActionListener {
                String  result = "";
 
                for (AltosEepromLog flight : flights) {
-                       if (flight.selected) {
+                       if (flight.delete_selected) {
                                if (result.equals(""))
                                        result = String.format("%d", flight.flight);
                                else
@@ -68,38 +69,49 @@ public class AltosEepromManage implements ActionListener {
                return result;
        }
 
-       public boolean download_done() {
-               AltosEepromSelect       select = new AltosEepromSelect(frame, flights, "Delete");
-
-               if (select.run()) {
-                       boolean any_selected = false;
-                       for (AltosEepromLog flight : flights)
-                               any_selected = any_selected || flight.selected;
-                       if (any_selected) {
-                               delete = new AltosEepromDelete(frame,
-                                                              serial_line,
-                                                              remote,
-                                                              flights);
-                               delete.addActionListener(this);
-                               /*
-                                * Start flight log delete
-                                */
-
-                               delete.start();
-                               return true;
-                       }
+       public boolean delete_start() {
+
+               boolean any_selected = false;
+               for (AltosEepromLog flight : flights)
+                       any_selected = any_selected || flight.delete_selected;
+               if (any_selected) {
+                       delete = new AltosEepromDelete(frame,
+                                                      serial_line,
+                                                      remote,
+                                                      flights);
+                       delete.addActionListener(this);
+                       /*
+                        * Start flight log delete
+                        */
+
+                       delete.start();
+                       return true;
                }
                return false;
        }
 
+       public void graph_start() {
+               boolean any_selected = false;
+               for (AltosEepromLog flight : flights) {
+                       if (!flight.download_selected)
+                               flight.graph_selected = false;
+                       any_selected = any_selected || flight.graph_selected;
+               }
+               if (any_selected && grapher != null)
+                       grapher.graph_flights(flights);
+       }
+
        public void actionPerformed(ActionEvent e) {
                String  cmd = e.getActionCommand();
                boolean success = e.getID() != 0;
                boolean running = false;
 
                if (cmd.equals("download")) {
-                       if (success)
-                               running = download_done();
+                       if (success) {
+                               running = delete_start();
+                               if (!running)
+                                       graph_start();
+                       }
                } else if (cmd.equals("delete")) {
                        if (success) {
                                JOptionPane.showMessageDialog(frame,
@@ -108,6 +120,7 @@ public class AltosEepromManage implements ActionListener {
                                                                            showDeletedFlights()),
                                                              serial_line.device.toShortString(),
                                                              JOptionPane.INFORMATION_MESSAGE);
+                               graph_start();
                        }
                }
                if (!running)
@@ -126,12 +139,12 @@ public class AltosEepromManage implements ActionListener {
                                                              serial_line.device.toShortString(),
                                                              JOptionPane.INFORMATION_MESSAGE);
                        } else {
-                               AltosEepromSelect       select = new AltosEepromSelect(frame, flights, "Download");
+                               AltosEepromSelect       select = new AltosEepromSelect(frame, flights, grapher != null);
 
                                if (select.run()) {
                                        boolean any_selected = false;
                                        for (AltosEepromLog flight : flights)
-                                               any_selected = any_selected || flight.selected;
+                                               any_selected = any_selected || flight.download_selected;
                                        if (any_selected) {
                                                AltosEepromMonitorUI monitor = new AltosEepromMonitorUI(frame);
                                                monitor.addActionListener(this);
@@ -147,7 +160,9 @@ public class AltosEepromManage implements ActionListener {
                                                download.start();
                                                running = true;
                                        } else {
-                                               running = download_done();
+                                               running = delete_start();
+                                               if (!running)
+                                                       graph_start();
                                        }
                                }
                        }
@@ -205,11 +220,12 @@ public class AltosEepromManage implements ActionListener {
                }
        }
 
-       public AltosEepromManage(JFrame given_frame, int product) {
+       public AltosEepromManage(JFrame given_frame, AltosEepromGrapher grapher, int product) {
 
                //boolean       running = false;
 
                frame = given_frame;
+               this.grapher = grapher;
                device = AltosDeviceUIDialog.show(frame, product);
 
                remote = false;
index 3427fe0..fc6c95c 100644 (file)
 
 package org.altusmetrum.altosuilib_12;
 
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_12.*;
 
+       class result_holder {
+               static int result;
+       }
+
 public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor {
        JFrame          owner;
        Container       pane;
@@ -32,7 +39,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
        JLabel          file_label;
        JLabel          serial_value;
        JLabel          flight_value;
-       JLabel          file_value;
        JButton         cancel;
        JProgressBar    pbar;
        ActionListener  listener;
@@ -42,6 +48,8 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
        public AltosEepromMonitorUI(JFrame owner) {
                super (owner, "Download Flight Data", false);
 
+               setMinimumSize(new Dimension(600, 100));
+
                this.owner = owner;
 
                GridBagConstraints c;
@@ -85,30 +93,11 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                flight_value = new JLabel("");
                pane.add(flight_value, c);
 
-               c = new GridBagConstraints();
-               c.fill = GridBagConstraints.NONE;
-               c.gridx = 0; c.gridy = 2;
-               c.anchor = GridBagConstraints.LINE_START;
-               c.insets = il;
-               file_label = new JLabel("File:");
-               pane.add(file_label, c);
-
-               c = new GridBagConstraints();
-               c.fill = GridBagConstraints.HORIZONTAL;
-               c.weightx = 1;
-               c.gridx = 1; c.gridy = 2;
-               c.anchor = GridBagConstraints.LINE_START;
-               c.insets = ir;
-               file_value = new JLabel("");
-               pane.add(file_value, c);
-
                pbar = new JProgressBar();
                pbar.setMinimum(0);
                pbar.setMaximum(progress_max);
-               pbar.setValue(0);
-               pbar.setString("startup");
                pbar.setStringPainted(true);
-               pbar.setPreferredSize(new Dimension(600, 20));
+               set_block_internal(0);
                c = new GridBagConstraints();
                c.fill = GridBagConstraints.HORIZONTAL;
                c.anchor = GridBagConstraints.CENTER;
@@ -118,7 +107,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                c.insets = ib;
                pane.add(pbar, c);
 
-
                cancel = new JButton("Cancel");
                c = new GridBagConstraints();
                c.fill = GridBagConstraints.NONE;
@@ -141,8 +129,9 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                final Thread eeprom_thread = in_eeprom_thread;
                cancel.addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
-                                       if (eeprom_thread != null)
+                                       if (eeprom_thread != null) {
                                                eeprom_thread.interrupt();
+                                       }
                                }
                        });
        }
@@ -162,6 +151,7 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                s = String.format("block %d of %d", block, max_block);
 
                pbar.setString(s);
+               pbar.setStringPainted(true);
                pbar.setValue((int) (pos * progress_max));
        }
 
@@ -216,23 +206,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                SwingUtilities.invokeLater(r);
        }
 
-       private void set_filename_internal(String filename) {
-               file_value.setText(String.format("%s", filename));
-       }
-
-       public void set_filename(String in_filename) {
-               final String filename = in_filename;
-               Runnable r = new Runnable() {
-                               public void run() {
-                                       try {
-                                               set_filename_internal(filename);
-                                       } catch (Exception ex) {
-                                       }
-                               }
-                       };
-               SwingUtilities.invokeLater(r);
-       }
-
        private void done_internal(boolean success) {
                listener.actionPerformed(new ActionEvent(this,
                                                         success ? 1 : 0,
@@ -258,7 +231,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                set_max(1);
                set_block_internal(0);
                set_flight_internal(0);
-               set_filename_internal("");
        }
 
        public void reset() {
@@ -293,6 +265,29 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo
                                              joption_message_type);
        }
 
+       public Boolean check_overwrite(File in_file) {
+               final Semaphore check_overwrite_done = new Semaphore(0);
+               final File file = in_file;
+               final result_holder result = new result_holder();
+
+               Runnable r = new Runnable() {
+                               public void run() {
+                                       result_holder.result = JOptionPane.showConfirmDialog(owner,
+                                                                                            String.format("\"%s\" already exists, overwrite?",
+                                                                                                          file.toString()),
+                                                                                            "Overwrite Existing File?",
+                                                                                            JOptionPane.YES_NO_OPTION);
+                                       check_overwrite_done.release();
+                               }
+                       };
+
+               SwingUtilities.invokeLater(r);
+               try {
+                       check_overwrite_done.acquire();
+               } catch (Exception e) {}
+               return result_holder.result == JOptionPane.YES_OPTION;
+       }
+
        public void show_message(String in_message, String in_title, int in_message_type) {
                final String message = in_message;
                final String title = in_title;
index 0c890c8..f88f2bd 100644 (file)
@@ -27,23 +27,35 @@ import org.altusmetrum.altoslib_12.*;
 class AltosEepromItem implements ActionListener {
        AltosEepromLog  log;
        JLabel          label;
-       JCheckBox       action;
+       JCheckBox       download;
        JCheckBox       delete;
+       JCheckBox       graph;
 
        public void actionPerformed(ActionEvent e) {
-               log.selected = action.isSelected();
+               log.download_selected = download.isSelected();
+               log.delete_selected = delete.isSelected();
+               log.graph_selected = graph.isSelected();
        }
 
        public AltosEepromItem(AltosEepromLog in_log) {
                log = in_log;
 
                String  text;
-               text = String.format("Flight #%02d", log.flight);
+               if (log.flight >= 0)
+                       text = String.format("Flight #%02d", log.flight);
+               else
+                       text = String.format("Corrupt #%02d", -log.flight);
 
                label = new JLabel(text);
 
-               action = new JCheckBox("", log.selected);
-               action.addActionListener(this);
+               download = new JCheckBox("", log.download_selected);
+               download.addActionListener(this);
+
+               delete = new JCheckBox("", log.delete_selected);
+               delete.addActionListener(this);
+
+               graph = new JCheckBox("", log.graph_selected);
+               graph.addActionListener(this);
        }
 }
 
@@ -72,7 +84,7 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener {
 
        public AltosEepromSelect (JFrame in_frame,
                                  AltosEepromList flights,
-                                 String action) {
+                                 boolean has_graph) {
 
                super(in_frame, String.format("Flight list for serial %d", flights.config_data.serial), true);
                frame = in_frame;
@@ -81,7 +93,7 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener {
                Container contentPane = getContentPane();
 
                /* First, we create a pane containing the dialog's header/title */
-               JLabel  selectLabel = new JLabel(String.format ("Select flights to %s", action), SwingConstants.CENTER);
+               JLabel  selectLabel = new JLabel(String.format ("Select flights"), SwingConstants.CENTER);
 
                JPanel  labelPane = new JPanel();
                labelPane.setLayout(new BoxLayout(labelPane, BoxLayout.X_AXIS));
@@ -118,9 +130,31 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener {
                c.weightx = 0.5;
                c.anchor = GridBagConstraints.CENTER;
                c.insets = i;
-               JLabel downloadHeaderLabel = new JLabel(action);
+               JLabel downloadHeaderLabel = new JLabel("Download");
                flightPane.add(downloadHeaderLabel, c);
 
+               /* Delete Header */
+               c = new GridBagConstraints();
+               c.gridx = 2; c.gridy = 0;
+               c.fill = GridBagConstraints.NONE;
+               c.weightx = 0.5;
+               c.anchor = GridBagConstraints.CENTER;
+               c.insets = i;
+               JLabel deleteHeaderLabel = new JLabel("Delete");
+               flightPane.add(deleteHeaderLabel, c);
+
+               if (has_graph) {
+                       /* Graph Header */
+                       c = new GridBagConstraints();
+                       c.gridx = 3; c.gridy = 0;
+                       c.fill = GridBagConstraints.NONE;
+                       c.weightx = 0.5;
+                       c.anchor = GridBagConstraints.CENTER;
+                       c.insets = i;
+                       JLabel graphHeaderLabel = new JLabel("Graph");
+                       flightPane.add(graphHeaderLabel, c);
+               }
+
                /* Add the flights to the GridBag */
                AltosEepromItem item;
                int itemNumber = 1;
@@ -139,14 +173,34 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener {
                        c.insets = i;
                        flightPane.add(item.label, c);
 
-                       /* Add action checkbox for the flight */
+                       /* Add download checkbox for the flight */
                        c = new GridBagConstraints();
                        c.gridx = 1; c.gridy = itemNumber;
                        c.fill = GridBagConstraints.NONE;
                        c.weightx = 0.5;
                        c.anchor = GridBagConstraints.CENTER;
                        c.insets = i;
-                       flightPane.add(item.action, c);
+                       flightPane.add(item.download, c);
+
+                       /* Add delete checkbox for the flight */
+                       c = new GridBagConstraints();
+                       c.gridx = 2; c.gridy = itemNumber;
+                       c.fill = GridBagConstraints.NONE;
+                       c.weightx = 0.5;
+                       c.anchor = GridBagConstraints.CENTER;
+                       c.insets = i;
+                       flightPane.add(item.delete, c);
+
+                       if (has_graph) {
+                               /* Add graph checkbox for the flight */
+                               c = new GridBagConstraints();
+                               c.gridx = 3; c.gridy = itemNumber;
+                               c.fill = GridBagConstraints.NONE;
+                               c.weightx = 0.5;
+                               c.anchor = GridBagConstraints.CENTER;
+                               c.insets = i;
+                               flightPane.add(item.graph, c);
+                       }
 
                        itemNumber++;
                }
index 3646f00..1433c9e 100644 (file)
@@ -30,7 +30,7 @@ import org.altusmetrum.altosuilib_12.*;
 
 public class TeleGPS
        extends AltosUIFrame
-       implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener
+       implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener, AltosEepromGrapher
 {
 
        static String[] telegps_icon_names = {
@@ -280,7 +280,7 @@ public class TeleGPS
        }
 
        void download(){
-               new AltosEepromManage(this, AltosLib.product_telegps);
+               new AltosEepromManage(this, this, AltosLib.product_telegps);
        }
 
        void configure() {
@@ -316,6 +316,21 @@ public class TeleGPS
                }
        }
 
+       public void graph_flights(AltosEepromList list) {
+               for (AltosEepromLog log : list) {
+                       if (log.file != null) {
+                               AltosRecordSet set = record_set(log.file);
+                               if (set != null) {
+                                       try {
+                                               new TeleGPSGraphUI(set, log.file);
+                                       } catch (InterruptedException ie) {
+                                       } catch (IOException ie) {
+                                       }
+                               }
+                       }
+               }
+       }
+
        void flash() {
                AltosFlashUI.show(this);
        }