X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altosui%2FAltosScanUI.java;h=5cc74a7796b6a91cad6068b1d6ff3f0f3938b05d;hp=96cab73b5d85c2435882ce8acb74940b85912036;hb=4ac7797d3efb9cc2d9fae88519f55e40b1050224;hpb=f7cd8317bf78ece334e1ceb0263b875ca43bbbd2 diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 96cab73b..5cc74a77 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -20,74 +20,94 @@ package altosui; import java.awt.*; import java.awt.event.*; import javax.swing.*; -import javax.swing.filechooser.FileNameExtensionFilter; -import javax.swing.table.*; import javax.swing.event.*; import java.io.*; import java.util.*; import java.text.*; -import java.util.prefs.*; import java.util.concurrent.*; +import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altosuilib_1.*; class AltosScanResult { - String callsign; - int serial; - int flight; - int channel; - int telemetry; - + String callsign; + int serial; + int flight; + AltosFrequency frequency; + int telemetry; + boolean interrupted = false; - + public String toString() { - return String.format("%-9.9s serial %-4d flight %-4d (channel %-2d %s)", - callsign, serial, flight, channel, Altos.telemetry_name(telemetry)); + return String.format("%-9.9s serial %-4d flight %-4d (%s %s)", + callsign, serial, flight, frequency.toShortString(), Altos.telemetry_name(telemetry)); } public String toShortString() { - return String.format("%s %d %d %d %d", - callsign, serial, flight, channel, telemetry); + return String.format("%s %d %d %7.3f %d", + callsign, serial, flight, frequency, telemetry); } public AltosScanResult(String in_callsign, int in_serial, - int in_flight, int in_channel, int in_telemetry) { + int in_flight, AltosFrequency in_frequency, int in_telemetry) { callsign = in_callsign; serial = in_serial; flight = in_flight; - channel = in_channel; + frequency = in_frequency; telemetry = in_telemetry; } public boolean equals(AltosScanResult other) { - return (callsign.equals(other.callsign) && - serial == other.serial && - flight == other.flight && - channel == other.channel && + return (serial == other.serial && + frequency.frequency == other.frequency.frequency && telemetry == other.telemetry); } + + public boolean up_to_date(AltosScanResult other) { + if (flight == 0 && other.flight != 0) { + flight = other.flight; + return false; + } + if (callsign.equals("N0CALL") && !other.callsign.equals("N0CALL")) { + callsign = other.callsign; + return false; + } + return true; + } } -class AltosScanResults extends LinkedList implements ListModel { - +class AltosScanResults extends LinkedList implements ListModel { + LinkedList listeners = new LinkedList(); + void changed(ListDataEvent de) { + for (ListDataListener l : listeners) + l.contentsChanged(de); + } + public boolean add(AltosScanResult r) { - for (AltosScanResult old : this) - if (old.equals(r)) + int i = 0; + for (AltosScanResult old : this) { + if (old.equals(r)) { + if (!old.up_to_date(r)) + changed (new ListDataEvent(this, + ListDataEvent.CONTENTS_CHANGED, + i, i)); return true; + } + i++; + } super.add(r); - ListDataEvent de = new ListDataEvent(this, - ListDataEvent.INTERVAL_ADDED, - this.size() - 2, this.size() - 1); - for (ListDataListener l : listeners) - l.contentsChanged(de); + changed(new ListDataEvent(this, + ListDataEvent.INTERVAL_ADDED, + this.size() - 2, this.size() - 1)); return true; } public void addListDataListener(ListDataListener l) { listeners.add(l); } - + public void removeListDataListener(ListDataListener l) { listeners.remove(l); } @@ -102,31 +122,35 @@ class AltosScanResults extends LinkedList implements ListModel } public class AltosScanUI - extends JDialog + extends AltosUIDialog implements ActionListener { AltosUI owner; AltosDevice device; + AltosConfigData config_data; AltosTelemetryReader reader; - private JList list; + private JList list; private JLabel scanning_label; + private JLabel frequency_label; + private JLabel telemetry_label; private JButton cancel_button; private JButton monitor_button; + private JCheckBox[] telemetry_boxes; javax.swing.Timer timer; AltosScanResults results = new AltosScanResults(); int telemetry; - int channel; final static int timeout = 1200; TelemetryHandler handler; Thread thread; + AltosFrequency[] frequencies; + int frequency_index; void scan_exception(Exception e) { if (e instanceof FileNotFoundException) { JOptionPane.showMessageDialog(owner, - String.format("Cannot open device \"%s\"", - device.toShortString()), + ((FileNotFoundException) e).getMessage(), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } else if (e instanceof AltosSerialInUseException) { @@ -160,14 +184,14 @@ public class AltosScanUI try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + AltosState state = reader.read(); + if (state == null) continue; - if ((record.seen & AltosRecord.seen_flight) != 0) { - final AltosScanResult result = new AltosScanResult(record.callsign, - record.serial, - record.flight, - channel, + if (state.flight != AltosLib.MISSING) { + final AltosScanResult result = new AltosScanResult(state.callsign, + state.serial, + state.flight, + frequencies[frequency_index], telemetry); Runnable r = new Runnable() { public void run() { @@ -190,28 +214,37 @@ public class AltosScanUI } void set_label() { - scanning_label.setText(String.format("Scanning: channel %d %s", - channel, - Altos.telemetry_name(telemetry))); + frequency_label.setText(String.format("Frequency: %s", frequencies[frequency_index].toString())); + telemetry_label.setText(String.format("Telemetry: %s", Altos.telemetry_name(telemetry))); } - void next() { - reader.serial.set_monitor(false); - try { - Thread.sleep(100); - } catch (InterruptedException ie){ - } - ++channel; - if (channel > 9) { - channel = 0; - ++telemetry; - if (telemetry > Altos.ao_telemetry_max) - telemetry = Altos.ao_telemetry_min; - reader.serial.set_telemetry(telemetry); + void set_telemetry() { + reader.set_telemetry(telemetry); + } + + void set_frequency() throws InterruptedException, TimeoutException { + reader.set_frequency(frequencies[frequency_index].frequency); + reader.reset(); + } + + void next() throws InterruptedException, TimeoutException { + reader.set_monitor(false); + Thread.sleep(100); + ++frequency_index; + if (frequency_index >= frequencies.length || + !telemetry_boxes[telemetry - Altos.ao_telemetry_min].isSelected()) + { + frequency_index = 0; + do { + ++telemetry; + if (telemetry > Altos.ao_telemetry_max) + telemetry = Altos.ao_telemetry_min; + } while (!telemetry_boxes[telemetry - Altos.ao_telemetry_min].isSelected()); + set_telemetry(); } - reader.serial.set_channel(channel); + set_frequency(); set_label(); - reader.serial.set_monitor(true); + reader.set_monitor(true); } @@ -229,31 +262,53 @@ public class AltosScanUI dispose(); } - void tick_timer() { + void tick_timer() throws InterruptedException, TimeoutException { next(); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); - if (cmd.equals("cancel")) - close(); - - if (cmd.equals("tick")) - tick_timer(); + try { + if (cmd.equals("cancel")) + close(); + + if (cmd.equals("tick")) + tick_timer(); + + if (cmd.equals("telemetry")) { + int k; + int scanning_telemetry = 0; + for (k = Altos.ao_telemetry_min; k <= Altos.ao_telemetry_max; k++) { + int j = k - Altos.ao_telemetry_min; + if (telemetry_boxes[j].isSelected()) + scanning_telemetry |= (1 << k); + } + if (scanning_telemetry == 0) { + scanning_telemetry |= (1 << Altos.ao_telemetry_standard); + telemetry_boxes[Altos.ao_telemetry_standard - Altos.ao_telemetry_min].setSelected(true); + } + AltosUIPreferences.set_scanning_telemetry(scanning_telemetry); + } - if (cmd.equals("monitor")) { - close(); - AltosScanResult r = (AltosScanResult) (list.getSelectedValue()); - if (r != null) { - if (device != null) { - if (reader != null) { - reader.set_telemetry(r.telemetry); - reader.set_channel(r.channel); - owner.telemetry_window(device); + if (cmd.equals("monitor")) { + close(); + AltosScanResult r = (AltosScanResult) (list.getSelectedValue()); + if (r != null) { + if (device != null) { + if (reader != null) { + reader.set_telemetry(r.telemetry); + reader.set_frequency(r.frequency.frequency); + reader.save_frequency(); + owner.telemetry_window(device); + } } } } + } catch (TimeoutException te) { + close(); + } catch (InterruptedException ie) { + close(); } } @@ -273,13 +328,13 @@ public class AltosScanUI } private boolean open() { - device = AltosDeviceDialog.show(owner, Altos.product_basestation); + device = AltosDeviceUIDialog.show(owner, Altos.product_basestation); if (device == null) return false; try { - reader = new AltosTelemetryReader(device); - reader.serial.set_channel(channel); - reader.serial.set_telemetry(telemetry); + reader = new AltosTelemetryReader(new AltosSerial(device)); + set_frequency(); + set_telemetry(); try { Thread.sleep(100); } catch (InterruptedException ie) { @@ -291,8 +346,7 @@ public class AltosScanUI return true; } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(owner, - String.format("Cannot open device \"%s\"", - device.toShortString()), + ee.getMessage(), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { @@ -306,6 +360,16 @@ public class AltosScanUI device.toShortString(), "Unkonwn I/O error", JOptionPane.ERROR_MESSAGE); + } catch (TimeoutException te) { + JOptionPane.showMessageDialog(owner, + device.toShortString(), + "Timeout error", + JOptionPane.ERROR_MESSAGE); + } catch (InterruptedException ie) { + JOptionPane.showMessageDialog(owner, + device.toShortString(), + "Interrupted exception", + JOptionPane.ERROR_MESSAGE); } if (reader != null) reader.close(false); @@ -316,7 +380,8 @@ public class AltosScanUI owner = in_owner; - channel = 0; + frequencies = AltosUIPreferences.common_frequencies(); + frequency_index = 0; telemetry = Altos.ao_telemetry_min; if (!open()) @@ -335,11 +400,13 @@ public class AltosScanUI pane.setLayout(new GridBagLayout()); scanning_label = new JLabel("Scanning:"); - + frequency_label = new JLabel(""); + telemetry_label = new JLabel(""); + set_label(); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.WEST; c.insets = i; c.weightx = 1; c.weighty = 1; @@ -347,11 +414,28 @@ public class AltosScanUI c.gridx = 0; c.gridy = 0; c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; pane.add(scanning_label, c); + c.gridy = 1; + pane.add(frequency_label, c); + c.gridy = 2; + pane.add(telemetry_label, c); + + int scanning_telemetry = AltosUIPreferences.scanning_telemetry(); + telemetry_boxes = new JCheckBox[Altos.ao_telemetry_max - Altos.ao_telemetry_min + 1]; + for (int k = Altos.ao_telemetry_min; k <= Altos.ao_telemetry_max; k++) { + int j = k - Altos.ao_telemetry_min; + telemetry_boxes[j] = new JCheckBox(AltosLib.telemetry_name(k)); + c.gridy = 3 + j; + pane.add(telemetry_boxes[j], c); + telemetry_boxes[j].setActionCommand("telemetry"); + telemetry_boxes[j].addActionListener(this); + telemetry_boxes[j].setSelected((scanning_telemetry & (1 << k)) != 0); + } + + int y_offset = 3 + (Altos.ao_telemetry_max - Altos.ao_telemetry_min + 1); - list = new JList(results) { + list = new JList(results) { //Subclass JList to workaround bug 4832765, which can cause the //scroll pane to not let the user easily scroll up to the beginning //of the list. An alternative would be to set the unitIncrement @@ -417,7 +501,7 @@ public class AltosScanUI c.weighty = 1; c.gridx = 0; - c.gridy = 1; + c.gridy = y_offset; c.gridwidth = 2; c.anchor = GridBagConstraints.CENTER; @@ -434,7 +518,7 @@ public class AltosScanUI c.weighty = 1; c.gridx = 0; - c.gridy = 2; + c.gridy = y_offset + 1; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER; @@ -451,7 +535,7 @@ public class AltosScanUI c.weighty = 1; c.gridx = 1; - c.gridy = 2; + c.gridy = y_offset + 1; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER; @@ -464,4 +548,4 @@ public class AltosScanUI setVisible(true); } -} \ No newline at end of file +}