X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=telegps%2FTeleGPS.java;h=cf2cbd4fefce4e114fb8605cbdda3a2a5ff535cb;hp=d30d8dc53e632b6e98d4a75ec295275501fab4e3;hb=238e56e0f6ab2f623e0faf25298b38dc3a4aff74;hpb=71715337eb532a1fbe1a753240e7417d5223489f diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java index d30d8dc5..cf2cbd4f 100644 --- a/telegps/TeleGPS.java +++ b/telegps/TeleGPS.java @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,18 +24,22 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_4.*; -import org.altusmetrum.altosuilib_2.*; +import java.text.*; +import org.altusmetrum.altoslib_11.*; +import org.altusmetrum.altosuilib_11.*; -public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, ActionListener { +public class TeleGPS + extends AltosUIFrame + implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener +{ static String[] telegps_icon_names = { - "/telegps-16.png", - "/telegps-32.png", - "/telegps-48.png", - "/telegps-64.png", - "/telegps-128.png", - "/telegps-256.png" + "/altusmetrum-telegps-16.png", + "/altusmetrum-telegps-32.png", + "/altusmetrum-telegps-48.png", + "/altusmetrum-telegps-64.png", + "/altusmetrum-telegps-128.png", + "/altusmetrum-telegps-256.png" }; static { set_icon_names(telegps_icon_names); } @@ -48,14 +53,18 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } AltosFlightReader reader; - AltosDisplayThread thread; + TeleGPSDisplayThread thread; + boolean idle_mode; JMenuBar menu_bar; JMenu file_menu; JMenu monitor_menu; JMenu device_menu; - AltosFreqList frequencies; + AltosUIFreqList frequencies; + ActionListener frequency_listener; + AltosUIRateList rates; + ActionListener rate_listener; Container bag; @@ -64,50 +73,51 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo JTabbedPane pane; - AltosSiteMap sitemap; + AltosUIMap map; TeleGPSInfo gps_info; + TeleGPSState gps_state; AltosInfoTable info_table; LinkedList displays; /* File menu */ final static String new_command = "new"; - final static String preferences_command = "preferences"; + final static String graph_command = "graph"; + final static String export_command = "export"; final static String load_maps_command = "loadmaps"; + final static String preferences_command = "preferences"; final static String close_command = "close"; final static String exit_command = "exit"; static final String[][] file_menu_entries = new String[][] { { "New Window", new_command }, - { "Preferences", preferences_command }, + { "Graph Data", graph_command }, + { "Export Data", export_command }, { "Load Maps", load_maps_command }, + { "Preferences", preferences_command }, { "Close", close_command }, { "Exit", exit_command }, }; /* Monitor menu */ - final static String monitor_command = "monitor"; + final static String connect_command = "connect"; final static String disconnect_command = "disconnect"; final static String scan_command = "scan"; static final String[][] monitor_menu_entries = new String[][] { - { "Monitor Device", monitor_command }, + { "Connect Device", connect_command }, { "Disconnect", disconnect_command }, { "Scan Channels", scan_command }, }; /* Device menu */ final static String download_command = "download"; - final static String export_command = "export"; - final static String graph_command = "graph"; final static String configure_command = "configure"; final static String flash_command = "flash"; static final String[][] device_menu_entries = new String[][] { { "Download Data", download_command }, { "Configure Device", configure_command }, - { "Export Data", export_command }, - { "Graph Data", graph_command }, { "Flash Device", flash_command }, }; @@ -126,18 +136,20 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo display.reset(); } - public void set_font() { + public void font_size_changed(int font_size) { for (AltosFlightDisplay display : displays) - display.set_font(); + display.font_size_changed(font_size); } - public void font_size_changed(int font_size) { - set_font(); + public void units_changed(boolean imperial_units) { + for (AltosFlightDisplay display : displays) + display.units_changed(imperial_units); } public void show(AltosState state, AltosListenerState listener_state) { try { status_update.saved_state = state; + status_update.saved_listener_state = listener_state; if (state == null) state = new AltosState(); @@ -163,22 +175,23 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } void load_maps() { - new AltosSiteMapPreload(this); + new AltosUIMapPreload(this); } void disconnect() { setTitle("TeleGPS"); stop_display(); - remove_frequency_menu(); + telegps_status.stop(); + + telegps_status.disable_receive(); + disable_frequency_menu(); + disable_rate_menu(); } - void connect(AltosDevice device) { - if (reader != null) - disconnect(); + void connect_flight(AltosDevice device) { try { AltosFlightReader reader = new AltosTelemetryReader(new AltosSerial(device)); - set_reader(reader); - add_frequency_menu(device.getSerial(), reader); + set_reader(reader, device, false); } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(this, ee.getMessage(), @@ -208,9 +221,51 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } } - void monitor() { + void connect_idle(AltosDevice device) { + try { + AltosFlightReader reader = new AltosIdleReader(new AltosSerial(device), false); + set_reader(reader, device, true); + } catch (FileNotFoundException ee) { + JOptionPane.showMessageDialog(this, + ee.getMessage(), + String.format ("Cannot open %s", device.toShortString()), + JOptionPane.ERROR_MESSAGE); + } catch (AltosSerialInUseException si) { + JOptionPane.showMessageDialog(this, + String.format("Device \"%s\" already in use", + device.toShortString()), + "Device in use", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ee) { + JOptionPane.showMessageDialog(this, + String.format ("Unknown I/O error on %s", device.toShortString()), + "Unknown I/O error", + JOptionPane.ERROR_MESSAGE); + } catch (TimeoutException te) { + JOptionPane.showMessageDialog(this, + String.format ("Timeout on %s", device.toShortString()), + "Timeout error", + JOptionPane.ERROR_MESSAGE); + } catch (InterruptedException ie) { + JOptionPane.showMessageDialog(this, + String.format("Interrupted %s", device.toShortString()), + "Interrupted exception", + JOptionPane.ERROR_MESSAGE); + } + } + + void connect(AltosDevice device) { + if (reader != null) + disconnect(); + if (device.matchProduct(AltosLib.product_basestation)) + connect_flight(device); + else + connect_idle(device); + } + + void connect() { AltosDevice device = AltosDeviceUIDialog.show(this, - AltosLib.product_basestation); + AltosLib.product_any); if (device == null) return; connect(device); @@ -242,6 +297,16 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } void graph() { + AltosDataChooser chooser; + chooser = new AltosDataChooser(this); + AltosStateIterable states = chooser.runDialog(); + if (states == null) + return; + try { + new TeleGPSGraphUI(states, chooser.file()); + } catch (InterruptedException ie) { + } catch (IOException ie) { + } } void flash() { @@ -271,8 +336,8 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo System.exit(0); /* Monitor menu */ - if (monitor_command.equals(ev.getActionCommand())) { - monitor(); + if (connect_command.equals(ev.getActionCommand())) { + connect(); return; } if (disconnect_command.equals(ev.getActionCommand())) { @@ -307,12 +372,12 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } } - void add_frequency_menu(int serial, final AltosFlightReader reader) { - // Channel menu - frequencies = new AltosFreqList(AltosUIPreferences.frequency(serial)); - frequencies.set_product("Monitor"); - frequencies.set_serial(serial); - frequencies.addActionListener(new ActionListener() { + void enable_frequency_menu(int serial, final AltosFlightReader reader) { + + if (frequency_listener != null) + disable_frequency_menu(); + + frequency_listener = new ActionListener() { public void actionPerformed(ActionEvent e) { double frequency = frequencies.frequency(); try { @@ -322,32 +387,98 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } reader.save_frequency(); } - }); - menu_bar.add(frequencies); + }; + + frequencies.addActionListener(frequency_listener); + frequencies.set_product("Monitor"); + frequencies.set_serial(serial); + frequencies.set_frequency(AltosUIPreferences.frequency(serial)); + frequencies.setEnabled(true); + } - void remove_frequency_menu() { - if (frequencies != null) { - menu_bar.remove(frequencies); - frequencies = null; + void disable_frequency_menu() { + if (frequency_listener != null) { + frequencies.removeActionListener(frequency_listener); + frequencies.setEnabled(false); + frequency_listener = null; } + } - public void set_reader(AltosFlightReader reader) { + void enable_rate_menu(int serial, final AltosFlightReader reader) { + + if (rate_listener != null) + disable_rate_menu(); + + rate_listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + int rate = rates.rate(); + try { + reader.set_telemetry_rate(rate); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + reader.save_telemetry_rate(); + } + }; + + rates.addActionListener(rate_listener); + rates.set_product("Monitor"); + rates.set_serial(serial); + rates.set_rate(AltosUIPreferences.telemetry_rate(serial)); + rates.setEnabled(reader.supports_telemetry_rate(AltosLib.ao_telemetry_rate_2400)); + } + + void disable_rate_menu() { + if (rate_listener != null) { + rates.removeActionListener(rate_listener); + rates.setEnabled(false); + rate_listener = null; + } + + } + + public void set_reader(AltosFlightReader reader, AltosDevice device, boolean idle_mode) { + this.idle_mode = idle_mode; + status_update = new TeleGPSStatusUpdate(telegps_status); + + telegps_status.start(status_update); + setTitle(String.format("TeleGPS %s", reader.name)); - thread = new AltosDisplayThread(this, voice(), this, reader); + thread = new TeleGPSDisplayThread(this, voice(), this, reader); thread.start(); + + if (device != null) { + if (idle_mode) { + disable_frequency_menu(); + disable_rate_menu(); + } else { + enable_frequency_menu(device.getSerial(), reader); + enable_rate_menu(device.getSerial(), reader); + } + } } static int number_of_windows; + static public void add_window() { + ++number_of_windows; + } + + static public void subtract_window() { + --number_of_windows; + if (number_of_windows == 0) + System.exit(0); + } + private void close() { + disconnect(); AltosUIPreferences.unregister_font_listener(this); + AltosPreferences.unregister_units_listener(this); setVisible(false); dispose(); - --number_of_windows; - if (number_of_windows == 0) - System.exit(0); + subtract_window(); } private void add_menu(JMenu menu, String label, String action) { @@ -360,23 +491,43 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo private JMenu make_menu(String label, String[][] items) { JMenu menu = new JMenu(label); - for (int i = 0; i < items.length; i++) + for (int i = 0; i < items.length; i++) { + if (MAC_OS_X) { + if (items[i][1].equals("exit")) + continue; + if (items[i][1].equals("preferences")) + continue; + } add_menu(menu, items[i][0], items[i][1]); + } menu_bar.add(menu); return menu; } + /* OSXAdapter interfaces */ + public void macosx_file_handler(String path) { + process_graph(new File(path)); + } + + public void macosx_quit_handler() { + System.exit(0); + } + + public void macosx_preferences_handler() { + preferences(); + } + public TeleGPS() { AltosUIPreferences.set_component(this); + register_for_macosx_events(); + reader = null; bag = getContentPane(); bag.setLayout(new GridBagLayout()); - GridBagConstraints c = new GridBagConstraints(); - setTitle("TeleGPS"); menu_bar = new JMenuBar(); @@ -385,19 +536,27 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo file_menu = make_menu("File", file_menu_entries); monitor_menu = make_menu("Monitor", monitor_menu_entries); device_menu = make_menu("Device", device_menu_entries); + + set_inset(3); + frequencies = new AltosUIFreqList(); + frequencies.setEnabled(false); + bag.add(frequencies, constraints (0, 1)); + + rates = new AltosUIRateList(); + rates.setEnabled(false); + bag.add(rates, constraints(1, 1)); + next_row(); + set_inset(0); + displays = new LinkedList(); int serial = -1; /* TeleGPS status is always visible */ telegps_status = new TeleGPSStatus(); - c.gridx = 0; - c.gridy = 1; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridwidth = 2; - bag.add(telegps_status, c); - c.gridwidth = 1; + bag.add(telegps_status, constraints(0, 3, GridBagConstraints.HORIZONTAL)); + next_row(); + displays.add(telegps_status); @@ -407,22 +566,20 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo pane = new JTabbedPane(); /* Make the tabbed pane use the rest of the window space */ - c.gridx = 0; - c.gridy = 2; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - c.weighty = 1; - c.gridwidth = 2; - bag.add(pane, c); - - sitemap = new AltosSiteMap(); - pane.add("Site Map", sitemap); - displays.add(sitemap); + bag.add(pane, constraints(0, 3, GridBagConstraints.BOTH)); + + map = new AltosUIMap(); + pane.add(map.getName(), map); + displays.add(map); gps_info = new TeleGPSInfo(); - pane.add("Info", gps_info); + pane.add(gps_info.getName(), gps_info); displays.add(gps_info); + gps_state = new TeleGPSState(); + pane.add(gps_state.getName(), gps_state); + displays.add(gps_state); + info_table = new AltosInfoTable(); pane.add("Table", info_table); displays.add(info_table); @@ -430,6 +587,7 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); AltosUIPreferences.register_font_listener(this); + AltosPreferences.register_units_listener(this); addWindowListener(new WindowAdapter() { @Override @@ -441,16 +599,12 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo pack(); setVisible(true); - ++number_of_windows; - - status_update = new TeleGPSStatusUpdate(telegps_status); - - new javax.swing.Timer(100, status_update).start(); + add_window(); } - public TeleGPS(AltosFlightReader reader) { + public TeleGPS(AltosFlightReader reader, boolean idle_mode) { this(); - set_reader(reader); + set_reader(reader, null, idle_mode); } public TeleGPS(AltosDevice device) { @@ -460,16 +614,23 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo static AltosStateIterable record_iterable(File file) { FileInputStream in; - try { - in = new FileInputStream(file); - } catch (Exception e) { - System.out.printf("Failed to open file '%s'\n", file); - return null; - } - if (file.getName().endsWith("telem")) - return new AltosTelemetryFile(in); - else - return new AltosEepromFile(in); + if (file.getName().endsWith("telem")) { + try { + in = new FileInputStream(file); + return new AltosTelemetryFile(in); + } catch (Exception e) { + System.out.printf("Failed to open file '%s'\n", file); + } + } else { + + try { + AltosEepromFile f = new AltosEepromFile(new FileReader(file)); + return f; + } catch (Exception e) { + System.out.printf("Failed to open file '%s'\n", file); + } + } + return null; } static AltosReplayReader replay_file(File file) { @@ -479,12 +640,24 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo return new AltosReplayReader(states.iterator(), file); } + static boolean process_graph(File file) { + AltosStateIterable states = record_iterable(file); + if (states == null) + return false; + try { + new TeleGPSGraphUI(states, file); + } catch (Exception e) { + return false; + } + return true; + } + static boolean process_replay(File file) { AltosReplayReader new_reader = replay_file(file); if (new_reader == null) return false; - new TeleGPS(new_reader); + new TeleGPS(new_reader, true); return true; } @@ -511,7 +684,6 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo public static void help(int code) { System.out.printf("Usage: altosui [OPTION]... [FILE]...\n"); System.out.printf(" Options:\n"); - System.out.printf(" --fetchmaps \tpre-fetch maps for site map view\n"); System.out.printf(" --replay \t\trelive the glory of past flights \n"); System.out.printf(" --graph \t\tgraph a flight\n"); System.out.printf(" --csv\tgenerate comma separated output for spreadsheets, etc\n"); @@ -536,16 +708,7 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo for (int i = 0; i < args.length; i++) { if (args[i].equals("--help")) help(0); - else if (args[i].equals("--fetchmaps")) { - if (args.length < i + 3) { - help(1); - } else { - double lat = Double.parseDouble(args[i+1]); - double lon = Double.parseDouble(args[i+2]); - AltosSiteMap.prefetchMaps(lat, lon); - i += 2; - } - } else if (args[i].equals("--replay")) + else if (args[i].equals("--replay")) process = process_replay; else if (args[i].equals("--kml")) process = process_kml; @@ -562,10 +725,11 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo else { File file = new File(args[i]); switch (process) { + case process_none: case process_graph: - ++errors; + if (!process_graph(file)) + ++errors; break; - case process_none: case process_replay: if (!process_replay(file)) ++errors; @@ -587,14 +751,14 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } if (errors != 0) System.exit(errors); - if (!any_created) { + if (number_of_windows == 0) { java.util.List devices = AltosUSBDevice.list(AltosLib.product_basestation); if (devices != null) for (AltosDevice device : devices) { new TeleGPS(device); any_created = true; } - if (!any_created) + if (number_of_windows == 0) new TeleGPS(); } }