diff options
Diffstat (limited to 'altosui')
71 files changed, 1539 insertions, 9099 deletions
diff --git a/altosui/.gitignore b/altosui/.gitignore index 4ee3f4ad..10b600e4 100644 --- a/altosui/.gitignore +++ b/altosui/.gitignore @@ -14,8 +14,10 @@ altosui-jdb classaltosui.stamp altos-windows.nsi Altos-Linux-*.tar.bz2 +Altos-Linux-*.sh Altos-Mac-*.zip Altos-Windows-*.exe +altos.desktop *.dll *.dylib *.so diff --git a/altosui/Altos.java b/altosui/Altos.java index 4b171fa7..28038ad6 100644 --- a/altosui/Altos.java +++ b/altosui/Altos.java @@ -20,8 +20,8 @@ package altosui; import java.awt.*; import libaltosJNI.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class Altos extends AltosUILib { diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 3f74fdd1..3bc80406 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -17,385 +17,151 @@ package altosui; +import java.util.*; import java.awt.*; +import java.awt.event.*; import javax.swing.*; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; -public class AltosAscent extends JComponent implements AltosFlightDisplay { - GridBagLayout layout; - JLabel cur, max; +public class AltosAscent extends AltosUIFlightTab { + JLabel cur, max; - public class AscentStatus { - JLabel label; - JTextField value; - AltosLights lights; + class Height extends AltosUIUnitsIndicator { - void show() { - value.setVisible(true); - lights.setVisible(true); - label.setVisible(true); - } - - void hide() { - value.setVisible(false); - lights.setVisible(false); - label.setVisible(false); - } - - void show(AltosState state, AltosListenerState listener_state) {} - - void show(String s) { - show(); - value.setText(s); - } - - void show(AltosUnits units, double v) { - show(units.show(8, v)); - } - - void show(String format, double v) { - show(String.format(format, v)); - } - - void reset() { - value.setText(""); - lights.set(false); - } - - void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); + public double value(AltosState state, int i) { + if (i == 0) + return state.height(); + else + return state.max_height(); } - public AscentStatus (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - lights = new AltosLights(); - c.gridx = 0; c.gridy = y; - c.anchor = GridBagConstraints.CENTER; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(lights, c); - add(lights); - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 2; c.gridy = y; - c.gridwidth = 2; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); - + public Height(Container container, int y) { + super(container, y, AltosConvert.height, "Height", 2, false, 1); } } - public class AscentValue { - JLabel label; - JTextField value; - void show(AltosState state, AltosListenerState listener_state) {} - - void reset() { - value.setText(""); + class Speed extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { + if (i == 0) + return state.speed(); + else + return state.max_speed(); } - void show() { - label.setVisible(true); - value.setVisible(true); + public Speed(Container container, int y) { + super(container, y, AltosConvert.speed, "Speed", 2, false, 1); } + } - void show(String s) { - show(); - value.setText(s); - } - - void show(AltosUnits units, double v) { - show(units.show(8, v)); - } + class Accel extends AltosUIUnitsIndicator { + public boolean hide(double v) { return v == AltosLib.MISSING; } - void show(String format, double v) { - show(String.format(format, v)); - } - - void hide() { - label.setVisible(false); - value.setVisible(false); - } - void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); + public double value(AltosState state, int i) { + if (i == 0) + return state.acceleration(); + else + return state.max_acceleration(); } - public AscentValue (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 2; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.gridwidth = 2; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); + public Accel(Container container, int y) { + super(container, y, AltosConvert.accel, "Acceleration", 2, false, 1); } } - public class AscentValueHold { - JLabel label; - JTextField value; - JTextField max_value; - double max; + class Orient extends AltosUIUnitsIndicator { - void show(AltosState state, AltosListenerState listener_state) {} + public boolean hide(double v) { return v == AltosLib.MISSING; } - void reset() { - value.setText(""); - max_value.setText(""); - max = AltosLib.MISSING; + public double value(AltosState state, int i) { + if (i == 0) + return state.orient(); + else + return state.max_orient(); } - void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); - max_value.setFont(Altos.value_font); + public Orient(Container container, int y) { + super(container, y, AltosConvert.orient, "Tilt Angle", 2, false, 1); } - void show(AltosUnits units, double v) { - if (v == AltosLib.MISSING) { - value.setText("Missing"); - max_value.setText("Missing"); - } else { - value.setText(units.show(8, v)); - if (v > max || max == AltosLib.MISSING) { - max_value.setText(units.show(8, v)); - max = v; - } - } - } - public AscentValueHold (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 2; c.gridy = y; - c.anchor = GridBagConstraints.EAST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); - - max_value = new JTextField(Altos.text_width); - max_value.setFont(Altos.value_font); - max_value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 3; c.gridy = y; - c.anchor = GridBagConstraints.EAST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(max_value, c); - add(max_value); - } } + class Apogee extends AltosUIUnitsIndicator { - class Height extends AscentValueHold { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.height()); + public double value(AltosState state, int i) { + return state.apogee_voltage; } - public Height (GridBagLayout layout, int y) { - super (layout, y, "Height"); - } - } - Height height; + public boolean good(double v) { return v >= AltosLib.ao_igniter_good; } + public boolean hide(double v) { return v == AltosLib.MISSING; } - class Speed extends AscentValueHold { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.speed()); - } - public Speed (GridBagLayout layout, int y) { - super (layout, y, "Speed"); + public Apogee (Container container, int y) { + super(container, y, AltosConvert.voltage, "Apogee Igniter Voltage", 1, true, 2); } } - Speed speed; - - class Accel extends AscentValueHold { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.accel, state.acceleration()); + class Main extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { + return state.main_voltage; } - public Accel (GridBagLayout layout, int y) { - super (layout, y, "Acceleration"); - } - } - Accel accel; + public boolean good(double v) { return v >= AltosLib.ao_igniter_good; } + public boolean hide(double v) { return v == AltosLib.MISSING; } - class Orient extends AscentValueHold { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.orient, state.orient()); - } - public Orient (GridBagLayout layout, int y) { - super (layout, y, "Tilt Angle"); + public Main (Container container, int y) { + super(container, y, AltosConvert.voltage, "Main Igniter Voltage", 1, true, 2); } } - Orient orient; + class Lat extends AltosUIUnitsIndicator { - String pos(double p, String pos, String neg) { - String h = pos; - if (p < 0) { - h = neg; - p = -p; + public boolean hide(AltosState state, int i) { + return state.gps == null || !state.gps.connected; } - int deg = (int) Math.floor(p); - double min = (p - Math.floor(p)) * 60.0; - return String.format("%s %4d° %9.6f", h, deg, min); - } - class Apogee extends AscentStatus { - void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.apogee_voltage); - lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good); - } - public Apogee (GridBagLayout layout, int y) { - super(layout, y, "Apogee Igniter Voltage"); + public double value(AltosState state, int i) { + if (state.gps == null) + return AltosLib.MISSING; + if (!state.gps.connected) + return AltosLib.MISSING; + return state.gps.lat; } - } - Apogee apogee; - - class Main extends AscentStatus { - void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_voltage); - lights.set(state.main_voltage >= AltosLib.ao_igniter_good); - } - public Main (GridBagLayout layout, int y) { - super(layout, y, "Main Igniter Voltage"); + Lat (Container container, int y) { + super (container, y, AltosConvert.latitude, "Latitude", 1, false, 2); } } - Main main; + class Lon extends AltosUIUnitsIndicator { - class Lat extends AscentValue { - void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) - show(pos(state.gps.lat,"N", "S")); - else - show("???"); + public boolean hide(AltosState state, int i) { + return state.gps == null || !state.gps.connected; } - public Lat (GridBagLayout layout, int y) { - super (layout, y, "Latitude"); - } - } - - Lat lat; - class Lon extends AscentValue { - void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) - show(pos(state.gps.lon,"E", "W")); - else - show("???"); - } - public Lon (GridBagLayout layout, int y) { - super (layout, y, "Longitude"); + public double value(AltosState state, int i) { + if (state.gps == null) + return AltosLib.MISSING; + if (!state.gps.connected) + return AltosLib.MISSING; + return state.gps.lon; } - } - Lon lon; - - public void reset() { - lat.reset(); - lon.reset(); - main.reset(); - apogee.reset(); - height.reset(); - speed.reset(); - accel.reset(); - orient.reset(); - } - - public void set_font() { - cur.setFont(Altos.label_font); - max.setFont(Altos.label_font); - lat.set_font(); - lon.set_font(); - main.set_font(); - apogee.set_font(); - height.set_font(); - speed.set_font(); - accel.set_font(); - orient.set_font(); + Lon (Container container, int y) { + super (container, y, AltosConvert.longitude, "Longitude", 1, false, 2); + } } - public void show(AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) { - lat.show(state, listener_state); - lon.show(state, listener_state); - } else { - lat.hide(); - lon.hide(); - } - height.show(state, listener_state); - if (state.main_voltage != AltosLib.MISSING) - main.show(state, listener_state); - else - main.hide(); - if (state.apogee_voltage != AltosLib.MISSING) - apogee.show(state, listener_state); - else - apogee.hide(); - speed.show(state, listener_state); - accel.show(state, listener_state); - orient.show(state, listener_state); + public void font_size_changed(int font_size) { + super.font_size_changed(font_size); + cur.setFont(AltosUILib.label_font); + max.setFont(AltosUILib.label_font); } public void labels(GridBagLayout layout, int y) { GridBagConstraints c; cur = new JLabel("Current"); - cur.setFont(Altos.label_font); + cur.setFont(AltosUILib.label_font); c = new GridBagConstraints(); c.gridx = 2; c.gridy = y; c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); @@ -403,7 +169,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { add(cur); max = new JLabel("Maximum"); - max.setFont(Altos.label_font); + max.setFont(AltosUILib.label_font); c.gridx = 3; c.gridy = y; layout.setConstraints(max, c); add(max); @@ -414,25 +180,15 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { } public AltosAscent() { - layout = new GridBagLayout(); - - setLayout(layout); - - /* Elements in ascent display: - * - * lat - * lon - * height - */ int y = 0; labels(layout, y++); - height = new Height(layout, y++); - speed = new Speed(layout, y++); - accel = new Accel(layout, y++); - orient = new Orient(layout, y++); - lat = new Lat(layout, y++); - lon = new Lon(layout, y++); - apogee = new Apogee(layout, y++); - main = new Main(layout, y++); + add(new Height(this, y++)); + add(new Speed(this, y++)); + add(new Accel(this, y++)); + add(new Orient(this, y++)); + add(new Lat(this, y++)); + add(new Lon(this, y++)); + add(new Apogee(this, y++)); + add(new Main(this, y++)); } } diff --git a/altosui/AltosBTDevice.java b/altosui/AltosBTDevice.java deleted file mode 100644 index 727a9f66..00000000 --- a/altosui/AltosBTDevice.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; -import libaltosJNI.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosBTDevice extends altos_bt_device implements AltosDevice { - - public String getProductName() { - String name = getName(); - if (name == null) - return "Altus Metrum"; - int dash = name.lastIndexOf("-"); - if (dash < 0) - return name; - return name.substring(0,dash); - } - - public int getProduct() { - if (Altos.bt_product_telebt.equals(getProductName())) - return Altos.product_telebt; - return 0; - } - - public String getPath() { - return getAddr(); - } - - public String getErrorString() { - altos_error error = new altos_error(); - - libaltos.altos_get_last_error(error); - return String.format("%s (%d)", error.getString(), error.getCode()); - } - - public int getSerial() { - String name = getName(); - if (name == null) - return 0; - int dash = name.lastIndexOf("-"); - if (dash < 0 || dash >= name.length()) - return 0; - String sn = name.substring(dash + 1, name.length()); - try { - return Integer.parseInt(sn); - } catch (NumberFormatException ne) { - return 0; - } - } - - public String toString() { - return String.format("%-20.20s %4d %s", - getProductName(), getSerial(), getAddr()); - } - - public String toShortString() { - return String.format("%s %d %s", - getProductName(), getSerial(), getAddr()); - - } - - public SWIGTYPE_p_altos_file open() { - return libaltos.altos_bt_open(this); - } - - /* - private boolean isAltusMetrum() { - if (getName().startsWith(Altos.bt_product_telebt)) - return true; - return false; - } - */ - - public boolean matchProduct(int want_product) { - -// if (!isAltusMetrum()) -// return false; - - if (want_product == Altos.product_any) - return true; - - if (want_product == Altos.product_basestation) - return matchProduct(Altos.product_telebt); - - if (want_product == getProduct()) - return true; - - return false; - } - - public boolean equals(Object o) { - if (!(o instanceof AltosBTDevice)) - return false; - AltosBTDevice other = (AltosBTDevice) o; - return getName().equals(other.getName()) && getAddr().equals(other.getAddr()); - } - - public int hashCode() { - return getName().hashCode() ^ getAddr().hashCode(); - } - - public AltosBTDevice(String name, String addr) { - Altos.load_library(); - libaltos.altos_bt_fill_in(name, addr,this); - } - - public AltosBTDevice() { - } -}
\ No newline at end of file diff --git a/altosui/AltosBTDeviceIterator.java b/altosui/AltosBTDeviceIterator.java deleted file mode 100644 index 4be5edf5..00000000 --- a/altosui/AltosBTDeviceIterator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; -import java.util.*; -import libaltosJNI.*; - -public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> { - AltosBTDevice current; - boolean done; - SWIGTYPE_p_altos_bt_list list; - - public boolean hasNext() { - if (list == null) - return false; - if (current != null) - return true; - if (done) - return false; - current = new AltosBTDevice(); - while (libaltos.altos_bt_list_next(list, current) != 0) { -// if (current.matchProduct(product)) - return true; - } - current = null; - done = true; - return false; - } - - public AltosBTDevice next() { - if (hasNext()) { - AltosBTDevice next = current; - current = null; - return next; - } - return null; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public AltosBTDeviceIterator(int inquiry_time) { - done = false; - current = null; - list = libaltos.altos_bt_list_start(inquiry_time); - } -} diff --git a/altosui/AltosBTKnown.java b/altosui/AltosBTKnown.java deleted file mode 100644 index 968d72d5..00000000 --- a/altosui/AltosBTKnown.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; -import java.util.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosBTKnown implements Iterable<AltosBTDevice> { - LinkedList<AltosBTDevice> devices = new LinkedList<AltosBTDevice>(); - AltosPreferencesBackend bt_pref = AltosUIPreferences.bt_devices(); - - private String get_address(String name) { - return bt_pref.getString(name, ""); - } - - private void set_address(String name, String addr) { - bt_pref.putString(name, addr); - } - - private void remove(String name) { - bt_pref.remove(name); - } - - private void load() { - try { - String[] names = bt_pref.keys(); - for (int i = 0; i < names.length; i++) { - String name = names[i]; - String addr = get_address(name); - devices.add(new AltosBTDevice(name, addr)); - } - } catch (IllegalStateException ie) { - } - } - - public Iterator<AltosBTDevice> iterator() { - return devices.iterator(); - } - - private void flush() { - AltosUIPreferences.flush_preferences(); - } - - public void set(Iterable<AltosBTDevice> new_devices) { - for (AltosBTDevice old : devices) { - boolean found = false; - for (AltosBTDevice new_device : new_devices) { - if (new_device.equals(old)) { - found = true; - break; - } - } - if (!found) - remove(old.getName()); - } - devices = new LinkedList<AltosBTDevice>(); - for (AltosBTDevice new_device : new_devices) { - devices.add(new_device); - set_address(new_device.getName(), new_device.getAddr()); - } - flush(); - } - - public List<AltosDevice> list(int product) { - LinkedList<AltosDevice> list = new LinkedList<AltosDevice>(); - for (AltosBTDevice device : devices) { - if (device.matchProduct(product)) - list.add(device); - } - return list; - } - - public AltosBTKnown() { - devices = new LinkedList<AltosBTDevice>(); - bt_pref = AltosUIPreferences.bt_devices(); - load(); - } - - static AltosBTKnown known; - - static public AltosBTKnown bt_known() { - if (known == null) - known = new AltosBTKnown(); - return known; - } -} diff --git a/altosui/AltosBTManage.java b/altosui/AltosBTManage.java deleted file mode 100644 index 1015f7c3..00000000 --- a/altosui/AltosBTManage.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.plaf.basic.*; -import java.util.*; -import java.util.concurrent.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> { - LinkedBlockingQueue<AltosBTDevice> found_devices; - Frame frame; - LinkedList<ActionListener> listeners; - AltosBTKnown bt_known; - - class DeviceList extends JList implements Iterable<AltosBTDevice> { - LinkedList<AltosBTDevice> devices; - DefaultListModel list_model; - - public void add (AltosBTDevice device) { - if (!devices.contains(device)) { - devices.add(device); - list_model.addElement(device); - } - } - - public void remove (AltosBTDevice device) { - if (devices.contains(device)) { - devices.remove(device); - list_model.removeElement(device); - } - } - - public boolean contains(AltosBTDevice device) { - return devices.contains(device); - } - - //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 - //of the JScrollBar to a fixed value. You wouldn't get the nice - //aligned scrolling, but it should work. - public int getScrollableUnitIncrement(Rectangle visibleRect, - int orientation, - int direction) { - int row; - if (orientation == SwingConstants.VERTICAL && - direction < 0 && (row = getFirstVisibleIndex()) != -1) { - Rectangle r = getCellBounds(row, row); - if ((r.y == visibleRect.y) && (row != 0)) { - Point loc = r.getLocation(); - loc.y--; - int prevIndex = locationToIndex(loc); - Rectangle prevR = getCellBounds(prevIndex, prevIndex); - - if (prevR == null || prevR.y >= r.y) { - return 0; - } - return prevR.height; - } - } - return super.getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - - public Iterator<AltosBTDevice> iterator() { - return devices.iterator(); - } - - public java.util.List<AltosBTDevice> selected_list() throws InterruptedException { - java.util.LinkedList<AltosBTDevice> l = new java.util.LinkedList<AltosBTDevice>(); - Object[] a = getSelectedValues(); - for (int i = 0; i < a.length; i++) - l.add((AltosBTDevice)a[i]); - return l; - } - - public DeviceList() { - devices = new LinkedList<AltosBTDevice>(); - list_model = new DefaultListModel(); - setModel(list_model); - setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - setLayoutOrientation(JList.HORIZONTAL_WRAP); - setVisibleRowCount(-1); - } - } - - DeviceList visible_devices; - - DeviceList known_devices; - Thread bt_thread; - - public Iterator<AltosBTDevice> iterator() { - return known_devices.iterator(); - } - - public void commit() { - bt_known.set(this); - } - - public void add_known() { - try { - for (AltosBTDevice device : visible_devices.selected_list()) { - known_devices.add(device); - visible_devices.remove(device); - } - } catch (InterruptedException ie) { - } - } - - public void remove_known() { - try { - for (AltosBTDevice device : known_devices.selected_list()) { - known_devices.remove(device); - visible_devices.add(device); - } - } catch (InterruptedException ie) { - } - } - - public void addActionListener(ActionListener l) { - listeners.add(l); - } - - private void forwardAction(ActionEvent e) { - for (ActionListener l : listeners) - l.actionPerformed(e); - } - - public void actionPerformed(ActionEvent e) { - String command = e.getActionCommand(); - if ("ok".equals(command)) { - bt_thread.interrupt(); - commit(); - setVisible(false); - forwardAction(e); - } else if ("cancel".equals(command)) { - bt_thread.interrupt(); - setVisible(false); - forwardAction(e); - } else if ("select".equals(command)) { - add_known(); - } else if ("deselect".equals(command)) { - remove_known(); - } - } - - public void got_visible_device() { - while (!found_devices.isEmpty()) { - AltosBTDevice device = found_devices.remove(); - if (!known_devices.contains(device)) - visible_devices.add(device); - } - } - - class BTGetVisibleDevices implements Runnable { - public void run () { - for (;;) - for (int time = 1; time <= 8; time <<= 1) { - AltosBTDeviceIterator i = new AltosBTDeviceIterator(time); - AltosBTDevice device; - - if (Thread.interrupted()) - return; - try { - while ((device = i.next()) != null) { - Runnable r; - - if (Thread.interrupted()) - return; - found_devices.add(device); - r = new Runnable() { - public void run() { - got_visible_device(); - } - }; - SwingUtilities.invokeLater(r); - } - } catch (Exception e) { - System.out.printf("uh-oh, exception %s\n", e.toString()); - } - } - } - } - - public static void show(Component frameComp, AltosBTKnown known) { - Frame frame = JOptionPane.getFrameForComponent(frameComp); - AltosBTManage dialog; - - dialog = new AltosBTManage(frame, known); - dialog.setVisible(true); - } - - public AltosBTManage(Frame in_frame, AltosBTKnown in_known) { - super(in_frame, "Manage Bluetooth Devices", true); - - frame = in_frame; - bt_known = in_known; - BTGetVisibleDevices get_visible_devices = new BTGetVisibleDevices(); - bt_thread = new Thread(get_visible_devices); - bt_thread.start(); - - listeners = new LinkedList<ActionListener>(); - - found_devices = new LinkedBlockingQueue<AltosBTDevice>(); - - Container pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - GridBagConstraints c = new GridBagConstraints(); - c.insets = new Insets(4,4,4,4); - - /* - * Known devices label and list - */ - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(new JLabel("Known Devices"), c); - - known_devices = new DeviceList(); - for (AltosBTDevice device : bt_known) - known_devices.add(device); - - JScrollPane known_list_scroller = new JScrollPane(known_devices); - known_list_scroller.setPreferredSize(new Dimension(400, 80)); - known_list_scroller.setAlignmentX(LEFT_ALIGNMENT); - c.fill = GridBagConstraints.BOTH; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 1; - c.gridwidth = 1; - c.gridheight = 2; - c.weightx = 1; - c.weighty = 1; - pane.add(known_list_scroller, c); - - /* - * Visible devices label and list - */ - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 2; - c.gridy = 0; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - - pane.add(new JLabel("Visible Devices"), c); - - visible_devices = new DeviceList(); - JScrollPane visible_list_scroller = new JScrollPane(visible_devices); - visible_list_scroller.setPreferredSize(new Dimension(400, 80)); - visible_list_scroller.setAlignmentX(LEFT_ALIGNMENT); - c.fill = GridBagConstraints.BOTH; - c.anchor = GridBagConstraints.WEST; - c.gridx = 2; - c.gridy = 1; - c.gridheight = 2; - c.gridwidth = 1; - c.weightx = 1; - c.weighty = 1; - pane.add(visible_list_scroller, c); - - /* - * Arrows between the two lists - */ - BasicArrowButton select_arrow = new BasicArrowButton(SwingConstants.WEST); - select_arrow.setActionCommand("select"); - select_arrow.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.SOUTH; - c.gridx = 1; - c.gridy = 1; - c.gridheight = 1; - c.gridwidth = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(select_arrow, c); - - BasicArrowButton deselect_arrow = new BasicArrowButton(SwingConstants.EAST); - deselect_arrow.setActionCommand("deselect"); - deselect_arrow.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.NORTH; - c.gridx = 1; - c.gridy = 2; - c.gridheight = 1; - c.gridwidth = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(deselect_arrow, c); - - JButton cancel_button = new JButton("Cancel"); - cancel_button.setActionCommand("cancel"); - cancel_button.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; - c.gridy = 3; - c.gridheight = 1; - c.gridwidth = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(cancel_button, c); - - JButton ok_button = new JButton("OK"); - ok_button.setActionCommand("ok"); - ok_button.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 2; - c.gridy = 3; - c.gridheight = 1; - c.gridwidth = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(ok_button, c); - - getRootPane().setDefaultButton(ok_button); - - pack(); - setLocationRelativeTo(frame); - setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - bt_thread.interrupt(); - setVisible(false); - } - }); - } -} diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java deleted file mode 100644 index 13f29f07..00000000 --- a/altosui/AltosCSV.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.io.*; -import java.util.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosCSV implements AltosWriter { - File name; - PrintStream out; - boolean header_written; - boolean seen_boost; - int boost_tick; - LinkedList<AltosState> pad_states; - AltosState state; - - static final int ALTOS_CSV_VERSION = 5; - - /* Version 4 format: - * - * General info - * version number - * serial number - * flight number - * callsign - * time (seconds since boost) - * clock (tick count / 100) - * rssi - * link quality - * - * Flight status - * state - * state name - * - * Basic sensors - * acceleration (m/s²) - * pressure (mBar) - * altitude (m) - * height (m) - * accelerometer speed (m/s) - * barometer speed (m/s) - * temp (°C) - * battery (V) - * drogue (V) - * main (V) - * - * Advanced sensors (if available) - * accel_x (m/s²) - * accel_y (m/s²) - * accel_z (m/s²) - * gyro_x (d/s) - * gyro_y (d/s) - * gyro_z (d/s) - * mag_x (g) - * mag_y (g) - * mag_z (g) - * - * GPS data (if available) - * connected (1/0) - * locked (1/0) - * nsat (used for solution) - * latitude (°) - * longitude (°) - * altitude (m) - * year (e.g. 2010) - * month (1-12) - * day (1-31) - * hour (0-23) - * minute (0-59) - * second (0-59) - * from_pad_dist (m) - * from_pad_azimuth (deg true) - * from_pad_range (m) - * from_pad_elevation (deg from horizon) - * hdop - * - * GPS Sat data - * C/N0 data for all 32 valid SDIDs - * - * Companion data - * companion_id (1-255. 10 is TeleScience) - * time of last companion data (seconds since boost) - * update_period (0.1-2.55 minimum telemetry interval) - * channels (0-12) - * channel data for all 12 possible channels - */ - - void write_general_header() { - out.printf("version,serial,flight,call,time,clock,rssi,lqi"); - } - - void write_general(AltosState state) { - out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", - ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, - (double) state.time, (double) state.tick / 100.0, - state.rssi, - state.status & 0x7f); - } - - void write_flight_header() { - out.printf("state,state_name"); - } - - void write_flight(AltosState state) { - out.printf("%d,%8s", state.state, state.state_name()); - } - - void write_basic_header() { - out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage"); - } - - void write_basic(AltosState state) { - out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", - state.acceleration(), - state.pressure(), - state.altitude(), - state.height(), - state.speed(), - state.speed(), - state.temperature, - state.battery_voltage, - state.apogee_voltage, - state.main_voltage); - } - - void write_advanced_header() { - out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z"); - } - - void write_advanced(AltosState state) { - AltosIMU imu = state.imu; - AltosMag mag = state.mag; - - if (imu == null) - imu = new AltosIMU(); - if (mag == null) - mag = new AltosMag(); - out.printf("%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d", - imu.accel_x, imu.accel_y, imu.accel_z, - imu.gyro_x, imu.gyro_y, imu.gyro_z, - mag.x, mag.y, mag.z); - } - - void write_gps_header() { - out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,hdop"); - } - - void write_gps(AltosState state) { - AltosGPS gps = state.gps; - if (gps == null) - gps = new AltosGPS(); - - AltosGreatCircle from_pad = state.from_pad; - if (from_pad == null) - from_pad = new AltosGreatCircle(); - - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", - gps.connected?1:0, - gps.locked?1:0, - gps.nsat, - gps.lat, - gps.lon, - gps.alt, - gps.year, - gps.month, - gps.day, - gps.hour, - gps.minute, - gps.second, - from_pad.distance, - state.range, - from_pad.bearing, - state.elevation, - gps.hdop); - } - - void write_gps_sat_header() { - for(int i = 1; i <= 32; i++) { - out.printf("sat%02d", i); - if (i != 32) - out.printf(","); - } - } - - void write_gps_sat(AltosState state) { - AltosGPS gps = state.gps; - for(int i = 1; i <= 32; i++) { - int c_n0 = 0; - if (gps != null && gps.cc_gps_sat != null) { - for(int j = 0; j < gps.cc_gps_sat.length; j++) - if (gps.cc_gps_sat[j].svid == i) { - c_n0 = gps.cc_gps_sat[j].c_n0; - break; - } - } - out.printf ("%3d", c_n0); - if (i != 32) - out.printf(","); - } - } - - void write_companion_header() { - out.printf("companion_id,companion_time,companion_update,companion_channels"); - for (int i = 0; i < 12; i++) - out.printf(",companion_%02d", i); - } - - void write_companion(AltosState state) { - AltosCompanion companion = state.companion; - - int channels_written = 0; - if (companion == null) { - out.printf("0,0,0,0"); - } else { - out.printf("%3d,%5.2f,%5.2f,%2d", - companion.board_id, - (companion.tick - boost_tick) / 100.0, - companion.update_period / 100.0, - companion.channels); - for (; channels_written < companion.channels; channels_written++) - out.printf(",%5d", companion.companion_data[channels_written]); - } - for (; channels_written < 12; channels_written++) - out.printf(",0"); - } - - void write_header(boolean advanced, boolean gps, boolean companion) { - out.printf("#"); write_general_header(); - out.printf(","); write_flight_header(); - out.printf(","); write_basic_header(); - if (advanced) - out.printf(","); write_advanced_header(); - if (gps) { - out.printf(","); write_gps_header(); - out.printf(","); write_gps_sat_header(); - } - if (companion) { - out.printf(","); write_companion_header(); - } - out.printf ("\n"); - } - - void write_one(AltosState state) { - write_general(state); out.printf(","); - write_flight(state); out.printf(","); - write_basic(state); out.printf(","); - if (state.imu != null || state.mag != null) - write_advanced(state); - if (state.gps != null) { - out.printf(","); - write_gps(state); out.printf(","); - write_gps_sat(state); - } - if (state.companion != null) { - out.printf(","); - write_companion(state); - } - out.printf ("\n"); - } - - void flush_pad() { - while (!pad_states.isEmpty()) { - write_one (pad_states.remove()); - } - } - - public void write(AltosState state) { - if (state.state == Altos.ao_flight_startup) - return; - if (!header_written) { - write_header(state.imu != null || state.mag != null, - state.gps != null, state.companion != null); - header_written = true; - } - if (!seen_boost) { - if (state.state >= Altos.ao_flight_boost) { - seen_boost = true; - boost_tick = state.tick; - flush_pad(); - } - } - if (seen_boost) - write_one(state); - else - pad_states.add(state); - } - - public PrintStream out() { - return out; - } - - public void close() { - if (!pad_states.isEmpty()) { - boost_tick = pad_states.element().tick; - flush_pad(); - } - out.close(); - } - - public void write(AltosStateIterable states) { - states.write_comments(out()); - for (AltosState state : states) - write(state); - } - - public AltosCSV(PrintStream in_out, File in_name) { - name = in_name; - out = in_out; - pad_states = new LinkedList<AltosState>(); - } - - public AltosCSV(File in_name) throws FileNotFoundException { - this(new PrintStream(in_name), in_name); - } - - public AltosCSV(String in_string) throws FileNotFoundException { - this(new File(in_string)); - } -} diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java deleted file mode 100644 index 05cabcdf..00000000 --- a/altosui/AltosCSVUI.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import java.io.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosCSVUI - extends AltosUIDialog - implements ActionListener -{ - JFileChooser csv_chooser; - JPanel accessory; - JComboBox combo_box; - Iterable<AltosState> states; - AltosWriter writer; - - static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" }; - - void set_default_file() { - File current = csv_chooser.getSelectedFile(); - String current_name = current.getName(); - String new_name = null; - String selected = (String) combo_box.getSelectedItem(); - - if (selected.contains("CSV")) - new_name = Altos.replace_extension(current_name, ".csv"); - else if (selected.contains("KML")) - new_name = Altos.replace_extension(current_name, ".kml"); - if (new_name != null) - csv_chooser.setSelectedFile(new File(new_name)); - } - - public void actionPerformed(ActionEvent e) { - if (e.getActionCommand().equals("comboBoxChanged")) - set_default_file(); - } - - public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) { - this.states = states; - csv_chooser = new JFileChooser(source_file); - - accessory = new JPanel(); - accessory.setLayout(new GridBagLayout()); - - GridBagConstraints c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.weightx = 1; - c.weighty = 0; - c.insets = new Insets (4, 4, 4, 4); - - JLabel accessory_label = new JLabel("Export File Type"); - c.gridx = 0; - c.gridy = 0; - accessory.add(accessory_label, c); - - combo_box = new JComboBox(combo_box_items); - combo_box.addActionListener(this); - c.gridx = 0; - c.gridy = 1; - accessory.add(combo_box, c); - - csv_chooser.setAccessory(accessory); - csv_chooser.setSelectedFile(source_file); - set_default_file(); - int ret = csv_chooser.showSaveDialog(frame); - if (ret == JFileChooser.APPROVE_OPTION) { - File file = csv_chooser.getSelectedFile(); - String type = (String) combo_box.getSelectedItem(); - try { - if (type.contains("CSV")) - writer = new AltosCSV(file); - else - writer = new AltosKML(file); - writer.write(states); - writer.close(); - } catch (FileNotFoundException ee) { - JOptionPane.showMessageDialog(frame, - ee.getMessage(), - "Cannot open file", - JOptionPane.ERROR_MESSAGE); - } - } - } -} diff --git a/altosui/AltosChannelMenu.java b/altosui/AltosChannelMenu.java index f90a11c0..382b6ae4 100644 --- a/altosui/AltosChannelMenu.java +++ b/altosui/AltosChannelMenu.java @@ -20,7 +20,7 @@ package altosui; import java.awt.event.*; import javax.swing.*; -public class AltosChannelMenu extends JComboBox implements ActionListener { +public class AltosChannelMenu extends JComboBox<String> implements ActionListener { int channel; public AltosChannelMenu(int current_channel) { diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index 4cc6c462..e7b335ac 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -19,9 +19,10 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; -public class AltosCompanionInfo extends JTable { +public class AltosCompanionInfo extends JTable implements AltosFlightDisplay { private AltosFlightInfoTableModel model; static final int info_columns = 2; @@ -32,25 +33,28 @@ public class AltosCompanionInfo extends JTable { return (infoValueMetrics.getHeight() + infoValueMetrics.getLeading()) * 18 / 10; } - public void set_font() { + public void font_size_changed(int font_size) { setFont(Altos.table_value_font); setRowHeight(desired_row_height()); doLayout(); } + public void units_changed(boolean imperial_units) { + } + public AltosCompanionInfo() { super(new AltosFlightInfoTableModel(info_rows, info_columns)); model = (AltosFlightInfoTableModel) getModel(); setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS); setShowGrid(true); - set_font(); + font_size_changed(AltosUIPreferences.font_size()); } public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } - void info_reset() { + public void reset() { model.reset(); } @@ -82,13 +86,15 @@ public class AltosCompanionInfo extends JTable { return String.format("%02x\n", companion.board_id); } } - + + public String getName() { return "Companion"; } + public void show(AltosState state, AltosListenerState listener_state) { if (state == null) return; if (state.companion != null) companion = state.companion; - info_reset(); + reset(); info_add_row(0, "Companion board", "%s", board_name()); if (companion != null) { info_add_row(0, "Last Data", "%5d", companion.tick); diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index e1805fc1..6eb7d40c 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -22,8 +22,8 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.text.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosConfig implements ActionListener { @@ -229,22 +229,28 @@ public class AltosConfig implements ActionListener { void save_data() { - /* bounds check stuff */ - if (config_ui.flight_log_max() > data.log_limit()) { + try { + /* bounds check stuff */ + if (config_ui.flight_log_max() > data.log_space() / 1024) { + JOptionPane.showMessageDialog(owner, + String.format("Requested flight log, %dk, is larger than the available space, %dk.\n", + config_ui.flight_log_max(), + data.log_space() / 1024), + "Maximum Flight Log Too Large", + JOptionPane.ERROR_MESSAGE); + return; + } + + /* Pull data out of the UI and stuff back into our local data record */ + + data.get_values(config_ui); + run_serial_thread(serial_mode_save); + } catch (AltosConfigDataException ae) { JOptionPane.showMessageDialog(owner, - String.format("Requested flight log, %dk, is larger than the available space, %dk.\n", - config_ui.flight_log_max(), - data.log_limit()), - "Maximum Flight Log Too Large", + ae.getMessage(), + "Configuration Data Error", JOptionPane.ERROR_MESSAGE); - return; } - - /* Pull data out of the UI and stuff back into our local data record */ - - data.get_values(config_ui); - - run_serial_thread(serial_mode_save); } public void actionPerformed(ActionEvent e) { @@ -298,4 +304,4 @@ public class AltosConfig implements ActionListener { } } } -}
\ No newline at end of file +} diff --git a/altosui/AltosConfigFreqUI.java b/altosui/AltosConfigFreqUI.java deleted file mode 100644 index e9923a32..00000000 --- a/altosui/AltosConfigFreqUI.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import java.util.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -class AltosEditFreqUI extends AltosUIDialog implements ActionListener { - Frame frame; - JTextField frequency; - JTextField description; - JButton ok_button, cancel_button; - boolean got_ok; - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - - if ("ok".equals(cmd)) { - got_ok = true; - setVisible(false); - } - if ("cancel".equals(cmd)) { - got_ok = false; - setVisible(false); - } - } - - public AltosFrequency get() { - if (!got_ok) - return null; - - String f_s = frequency.getText(); - String d_s = description.getText(); - - try { - double f_d = Double.parseDouble(f_s); - - return new AltosFrequency(f_d, d_s); - } catch (NumberFormatException ne) { - } - return null; - } - - public AltosEditFreqUI(Frame in_frame, AltosFrequency existing) { - super(in_frame, true); - - got_ok = false; - frame = in_frame; - - Container pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - GridBagConstraints c = new GridBagConstraints(); - c.insets = new Insets (4,4,4,4); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(new JLabel("Frequency"), c); - - frequency = new JTextField(12); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 1; - c.gridy = 0; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(frequency, c); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 1; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(new JLabel("Description"), c); - - description = new JTextField(12); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 1; - c.gridy = 1; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(description, c); - - ok_button = new JButton("OK"); - ok_button.setActionCommand("ok"); - ok_button.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 2; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(ok_button, c); - - cancel_button = new JButton("Cancel"); - cancel_button.setActionCommand("cancel"); - cancel_button.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 1; - c.gridy = 2; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(cancel_button, c); - - if (existing == null) - setTitle("Add New Frequency"); - else { - setTitle("Edit Existing Frequency"); - frequency.setText(String.format("%7.3f", existing.frequency)); - description.setText(existing.description); - } - getRootPane().setDefaultButton(ok_button); - - pack(); - setLocationRelativeTo(frame); - - } - - public AltosEditFreqUI(Frame in_frame) { - this(in_frame, (AltosFrequency) null); - } -} - -public class AltosConfigFreqUI extends AltosUIDialog implements ActionListener { - - Frame frame; - LinkedList<ActionListener> listeners; - - class FrequencyList extends JList { - DefaultListModel list_model; - - public void add(AltosFrequency frequency) { - int i; - for (i = 0; i < list_model.size(); i++) { - AltosFrequency f = (AltosFrequency) list_model.get(i); - if (frequency.frequency == f.frequency) - return; - if (frequency.frequency < f.frequency) - break; - } - list_model.insertElementAt(frequency, i); - } - - public void remove(AltosFrequency frequency) { - list_model.removeElement(frequency); - } - - //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 - //of the JScrollBar to a fixed value. You wouldn't get the nice - //aligned scrolling, but it should work. - public int getScrollableUnitIncrement(Rectangle visibleRect, - int orientation, - int direction) { - int row; - if (orientation == SwingConstants.VERTICAL && - direction < 0 && (row = getFirstVisibleIndex()) != -1) { - Rectangle r = getCellBounds(row, row); - if ((r.y == visibleRect.y) && (row != 0)) { - Point loc = r.getLocation(); - loc.y--; - int prevIndex = locationToIndex(loc); - Rectangle prevR = getCellBounds(prevIndex, prevIndex); - - if (prevR == null || prevR.y >= r.y) { - return 0; - } - return prevR.height; - } - } - return super.getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - - public AltosFrequency selected() { - AltosFrequency f = (AltosFrequency) getSelectedValue(); - return f; - } - - public AltosFrequency[] frequencies() { - AltosFrequency[] ret; - - ret = new AltosFrequency[list_model.size()]; - for (int i = 0; i < list_model.size(); i++) - ret[i] = (AltosFrequency) list_model.get(i); - return ret; - } - - public FrequencyList(AltosFrequency[] in_frequencies) { - list_model = new DefaultListModel(); - setModel(list_model); - setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - setLayoutOrientation(JList.HORIZONTAL_WRAP); - for (int i = 0; i < in_frequencies.length; i++) { - add(in_frequencies[i]); - } - setVisibleRowCount(in_frequencies.length); - } - } - - FrequencyList frequencies; - - void save_frequencies() { - AltosUIPreferences.set_common_frequencies(frequencies.frequencies()); - } - - JButton add, edit, remove; - - JButton cancel, ok; - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - - if ("ok".equals(cmd)) { - save_frequencies(); - setVisible(false); - } else if ("cancel".equals(cmd)) { - setVisible(false); - } else if ("add".equals(cmd)) { - AltosEditFreqUI ui = new AltosEditFreqUI(frame); - ui.setVisible(true); - AltosFrequency f = ui.get(); - if (f != null) - frequencies.add(f); - } else if ("edit".equals(cmd)) { - AltosFrequency old_f = frequencies.selected(); - if (old_f == null) - return; - AltosEditFreqUI ui = new AltosEditFreqUI(frame, old_f); - ui.setVisible(true); - AltosFrequency new_f = ui.get(); - if (new_f != null) { - if (old_f != null) - frequencies.remove(old_f); - frequencies.add(new_f); - } - } else if ("remove".equals(cmd)) { - AltosFrequency old_f = frequencies.selected(); - if (old_f == null) - return; - int ret = JOptionPane.showConfirmDialog(this, - String.format("Remove frequency \"%s\"?", - old_f.toShortString()), - "Remove Frequency", - JOptionPane.YES_NO_OPTION); - if (ret == JOptionPane.YES_OPTION) - frequencies.remove(old_f); - } - } - - public AltosFrequency[] frequencies() { - return frequencies.frequencies(); - } - - public AltosConfigFreqUI(Frame in_frame, - AltosFrequency[] in_frequencies) { - super(in_frame, "Manage Frequencies", true); - - frame = in_frame; - - listeners = new LinkedList<ActionListener>(); - - frequencies = new FrequencyList(in_frequencies); - - Container pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - GridBagConstraints c = new GridBagConstraints(); - c.insets = new Insets(4,4,4,4); - - /* - * Frequencies label and list - */ - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 1; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(new JLabel("Frequencies"), c); - - JScrollPane list_scroller = new JScrollPane(frequencies); - list_scroller.setAlignmentX(LEFT_ALIGNMENT); - c.fill = GridBagConstraints.BOTH; - c.anchor = GridBagConstraints.WEST; - c.gridx = 0; - c.gridy = 1; - c.gridwidth = 6; - c.gridheight = 2; - c.weightx = 1; - c.weighty = 1; - pane.add(list_scroller, c); - - add = new JButton("Add"); - add.setActionCommand("add"); - add.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; - c.gridy = 3; - c.gridwidth = 2; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(add, c); - - edit = new JButton("Edit"); - edit.setActionCommand("edit"); - edit.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 2; - c.gridy = 3; - c.gridwidth = 2; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(edit, c); - - remove = new JButton("Remove"); - remove.setActionCommand("remove"); - remove.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 4; - c.gridy = 3; - c.gridwidth = 2; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(remove, c); - - ok = new JButton("OK"); - ok.setActionCommand("ok"); - ok.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; - c.gridy = 4; - c.gridwidth = 3; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(ok, c); - - cancel = new JButton("Cancel"); - cancel.setActionCommand("cancel"); - cancel.addActionListener(this); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 3; - c.gridy = 4; - c.gridwidth = 3; - c.gridheight = 1; - c.weightx = 0; - c.weighty = 0; - pane.add(cancel, c); - - pack(); - setLocationRelativeTo(frame); - } - - public static void show(Component frameComp) { - Frame frame = JOptionPane.getFrameForComponent(frameComp); - AltosConfigFreqUI dialog; - - dialog = new AltosConfigFreqUI(frame, AltosUIPreferences.common_frequencies()); - dialog.setVisible(true); - } - -} diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java index b14c39ab..f0b4f0f9 100644 --- a/altosui/AltosConfigPyroUI.java +++ b/altosui/AltosConfigPyroUI.java @@ -21,8 +21,8 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosConfigPyroUI extends AltosUIDialog @@ -50,7 +50,7 @@ public class AltosConfigPyroUI public int flag; public JCheckBox enable; public JTextField value; - public JComboBox combo; + public JComboBox<String> combo; AltosConfigPyroUI ui; boolean setting; @@ -63,22 +63,22 @@ public class AltosConfigPyroUI public void itemStateChanged(ItemEvent e) { set_enable(enable.isSelected()); - if (!setting) + if (!setting) ui.set_dirty(); } public void changedUpdate(DocumentEvent e) { - if (!setting) + if (!setting) ui.set_dirty(); } public void insertUpdate(DocumentEvent e) { - if (!setting) + if (!setting) ui.set_dirty(); } public void removeUpdate(DocumentEvent e) { - if (!setting) + if (!setting) ui.set_dirty(); } @@ -105,11 +105,13 @@ public class AltosConfigPyroUI AltosUnits units = AltosPyro.pyro_to_units(flag); if (units != null) unit_value = units.value(new_value); - String format = "%6.0f"; - if (scale >= 10) - format = "%6.1f"; - else if (scale >= 100) + String format; + if (scale >= 100) format = "%6.2f"; + else if (scale >= 10) + format = "%6.1f"; + else + format = "%6.0f"; value.setText(String.format(format, unit_value)); } if (combo != null) @@ -122,12 +124,16 @@ public class AltosConfigPyroUI return enable.isSelected(); } - public double value() { + public double value() throws AltosConfigDataException { if (value != null) { AltosUnits units = AltosPyro.pyro_to_units(flag); - if (units != null) - return units.parse(value.getText()); - return Double.parseDouble(value.getText()); + try { + if (units != null) + return units.parse(value.getText()); + return Double.parseDouble(value.getText()); + } catch (NumberFormatException e) { + throw new AltosConfigDataException("\"%s\": %s\n", value.getText(), e.getMessage()); + } } if (combo != null) return combo.getSelectedIndex() + AltosLib.ao_flight_boost; @@ -149,7 +155,7 @@ public class AltosConfigPyroUI enable = new JCheckBox(); enable.addItemListener(this); pane.add(enable, c); - + if ((flag & AltosPyro.pyro_no_value) == 0) { c = new GridBagConstraints(); c.gridx = x+1; c.gridy = y; @@ -159,7 +165,7 @@ public class AltosConfigPyroUI c.insets = il; if ((flag & AltosPyro.pyro_state_value) != 0) { make_state_names(); - combo = new JComboBox(state_names); + combo = new JComboBox<String>(state_names); combo.addItemListener(this); pane.add(combo, c); } else { @@ -187,15 +193,21 @@ public class AltosConfigPyroUI } } - public AltosPyro get() { + public AltosPyro get() throws AltosConfigDataException { AltosPyro p = new AltosPyro(channel); int row = 0; for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { if ((AltosPyro.pyro_all & flag) != 0) { if (items[row].enabled()) { + try { p.flags |= flag; p.set_value(flag, items[row].value()); + } catch (AltosConfigDataException ae) { + throw new AltosConfigDataException("%s, %s", + AltosPyro.pyro_to_name(flag), + ae.getMessage()); + } } row++; } @@ -224,7 +236,7 @@ public class AltosConfigPyroUI items = new PyroItem[nrow]; int row = 0; - + GridBagConstraints c; c = new GridBagConstraints(); c.gridx = x; c.gridy = y; @@ -254,13 +266,40 @@ public class AltosConfigPyroUI } } - public AltosPyro[] get_pyros() { + public AltosPyro[] get_pyros() throws AltosConfigDataException { AltosPyro[] pyros = new AltosPyro[columns.length]; - for (int c = 0; c < columns.length; c++) - pyros[c] = columns[c].get(); + for (int c = 0; c < columns.length; c++) { + try { + pyros[c] = columns[c].get(); + } catch (AltosConfigDataException ae) { + throw new AltosConfigDataException ("Channel %c, %s", c + 'A', ae.getMessage()); + } + } return pyros; } + JLabel pyro_firing_time_label; + JComboBox<String> pyro_firing_time_value; + + static String[] pyro_firing_time_values = { + "0.050", "0.100", "0.250", "0.500", "1.0", "2.0" + }; + + public void set_pyro_firing_time(double new_pyro_firing_time) { + pyro_firing_time_value.setSelectedItem(Double.toString(new_pyro_firing_time)); + pyro_firing_time_value.setEnabled(new_pyro_firing_time >= 0); + } + + public double get_pyro_firing_time() throws AltosConfigDataException { + String v = pyro_firing_time_value.getSelectedItem().toString(); + + try { + return Double.parseDouble(v); + } catch (NumberFormatException e) { + throw new AltosConfigDataException("Invalid pyro firing time \"%s\"", v); + } + } + public void set_dirty() { owner.set_dirty(); } @@ -317,7 +356,7 @@ public class AltosConfigPyroUI setVisible(false); } - public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) { + public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros, double pyro_firing_time) { super(in_owner, "Configure Pyro Channels", false); @@ -362,6 +401,32 @@ public class AltosConfigPyroUI columns[i].set(pyros[i]); } + /* Pyro firing time */ + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 2; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + pyro_firing_time_label = new JLabel("Pyro Firing Time(s):"); + pane.add(pyro_firing_time_label, c); + + c = new GridBagConstraints(); + c.gridx = 2; c.gridy = row; + c.gridwidth = 7; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + c.ipady = 5; + pyro_firing_time_value = new JComboBox<String>(pyro_firing_time_values); + pyro_firing_time_value.setEditable(true); + pyro_firing_time_value.addItemListener(this); + set_pyro_firing_time(pyro_firing_time); + pane.add(pyro_firing_time_value, c); + pyro_firing_time_value.setToolTipText("Length of extra pyro channel firing pulse"); + c = new GridBagConstraints(); c.gridx = pyros.length*2-1; c.fill = GridBagConstraints.HORIZONTAL; @@ -371,7 +436,7 @@ public class AltosConfigPyroUI pane.add(close, c); close.addActionListener(this); close.setActionCommand("Close"); - + addWindowListener(new ConfigListener(this, owner)); AltosPreferences.register_units_listener(this); } diff --git a/altosui/AltosConfigTD.java b/altosui/AltosConfigTD.java index ad9ebbfa..bfbd2c77 100644 --- a/altosui/AltosConfigTD.java +++ b/altosui/AltosConfigTD.java @@ -21,8 +21,8 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosConfigTD implements ActionListener { diff --git a/altosui/AltosConfigTDUI.java b/altosui/AltosConfigTDUI.java index 3ce0d98c..22b3384d 100644 --- a/altosui/AltosConfigTDUI.java +++ b/altosui/AltosConfigTDUI.java @@ -21,8 +21,8 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosConfigTDUI extends AltosUIDialog @@ -311,7 +311,7 @@ public class AltosConfigTDUI int i; for (i = 0; i < radio_frequency_value.getItemCount(); i++) { AltosFrequency f = (AltosFrequency) radio_frequency_value.getItemAt(i); - + if (f.close(new_radio_frequency)) { radio_frequency_value.setSelectedIndex(i); return; @@ -319,7 +319,7 @@ public class AltosConfigTDUI } for (i = 0; i < radio_frequency_value.getItemCount(); i++) { AltosFrequency f = (AltosFrequency) radio_frequency_value.getItemAt(i); - + if (new_radio_frequency < f.frequency) break; } diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 21ea50e6..1b5ff988 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -21,102 +21,130 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosConfigUI extends AltosUIDialog implements ActionListener, ItemListener, DocumentListener, AltosConfigValues, AltosUnitsListener { - Container pane; - JLabel product_label; - JLabel version_label; - JLabel serial_label; - JLabel main_deploy_label; - JLabel apogee_delay_label; - JLabel apogee_lockout_label; - JLabel frequency_label; - JLabel radio_calibration_label; - JLabel radio_frequency_label; - JLabel radio_enable_label; - JLabel aprs_interval_label; - JLabel flight_log_max_label; - JLabel ignite_mode_label; - JLabel pad_orientation_label; - JLabel callsign_label; + Container pane; + JLabel product_label; + JLabel version_label; + JLabel serial_label; + JLabel main_deploy_label; + JLabel apogee_delay_label; + JLabel apogee_lockout_label; + JLabel frequency_label; + JLabel radio_calibration_label; + JLabel radio_frequency_label; + JLabel radio_enable_label; + JLabel aprs_interval_label; + JLabel flight_log_max_label; + JLabel ignite_mode_label; + JLabel pad_orientation_label; + JLabel callsign_label; + JLabel beep_label; + JLabel tracker_motion_label; + JLabel tracker_interval_label; public boolean dirty; - JFrame owner; - JLabel product_value; - JLabel version_value; - JLabel serial_value; - JComboBox main_deploy_value; - JComboBox apogee_delay_value; - JComboBox apogee_lockout_value; - AltosFreqList radio_frequency_value; - JTextField radio_calibration_value; - JRadioButton radio_enable_value; - JComboBox aprs_interval_value; - JComboBox flight_log_max_value; - JComboBox ignite_mode_value; - JComboBox pad_orientation_value; - JTextField callsign_value; - - JButton pyro; - - JButton save; - JButton reset; - JButton reboot; - JButton close; - - AltosPyro[] pyros; - - ActionListener listener; - - static String[] main_deploy_values_m = { + JFrame owner; + JLabel product_value; + JLabel version_value; + JLabel serial_value; + JComboBox<String> main_deploy_value; + JComboBox<String> apogee_delay_value; + JComboBox<String> apogee_lockout_value; + AltosFreqList radio_frequency_value; + JTextField radio_calibration_value; + JRadioButton radio_enable_value; + JComboBox<String> aprs_interval_value; + JComboBox<String> flight_log_max_value; + JComboBox<String> ignite_mode_value; + JComboBox<String> pad_orientation_value; + JTextField callsign_value; + JComboBox<String> beep_value; + JComboBox<String> tracker_motion_value; + JComboBox<String> tracker_interval_value; + + JButton pyro; + + JButton save; + JButton reset; + JButton reboot; + JButton close; + + AltosPyro[] pyros; + double pyro_firing_time; + + ActionListener listener; + + static String[] main_deploy_values_m = { "100", "150", "200", "250", "300", "350", "400", "450", "500" }; - static String[] main_deploy_values_ft = { + static String[] main_deploy_values_ft = { "250", "500", "750", "1000", "1250", "1500", "1750", "2000" }; - static String[] apogee_delay_values = { + static String[] apogee_delay_values = { "0", "1", "2", "3", "4", "5" }; - static String[] apogee_lockout_values = { + static String[] apogee_lockout_values = { "0", "5", "10", "15", "20" }; - static String[] flight_log_max_values = { - "64", "128", "192", "256", "320", - "384", "448", "512", "576", "640", - "704", "768", "832", "896", "960", - }; - - static String[] ignite_mode_values = { + static String[] ignite_mode_values = { "Dual Deploy", "Redundant Apogee", "Redundant Main", }; - static String[] aprs_interval_values = { + static String[] aprs_interval_values = { "Disabled", "2", "5", "10" }; - static String[] pad_orientation_values = { + static String[] beep_values = { + "3750", + "4000", + "4250", + }; + + static String[] pad_orientation_values = { "Antenna Up", "Antenna Down", }; + static String[] tracker_motion_values_m = { + "2", + "5", + "10", + "25", + }; + + static String[] tracker_motion_values_ft = { + "5", + "20", + "50", + "100" + }; + + static String[] tracker_interval_values = { + "1", + "2", + "5", + "10" + }; + /* A window listener to catch closing events and tell the config code */ class ConfigListener extends WindowAdapter { AltosConfigUI ui; @@ -132,11 +160,21 @@ public class AltosConfigUI } } + boolean is_telemini_v1() { + String product = product_value.getText(); + return product != null && product.startsWith("TeleMini-v1"); + } + boolean is_telemini() { String product = product_value.getText(); return product != null && product.startsWith("TeleMini"); } + boolean is_easymini() { + String product = product_value.getText(); + return product != null && product.startsWith("EasyMini"); + } + boolean is_telemetrum() { String product = product_value.getText(); return product != null && product.startsWith("TeleMetrum"); @@ -167,12 +205,10 @@ public class AltosConfigUI if (flight_log_max_value.isEnabled()) flight_log_max_value.setToolTipText("Size reserved for each flight log (in kB)"); else { - if (is_telemetrum()) - flight_log_max_value.setToolTipText("Cannot set max value with flight logs in memory"); - else if (is_telemini()) - flight_log_max_value.setToolTipText("TeleMini stores only one flight"); + if (is_telemini_v1()) + flight_log_max_value.setToolTipText("TeleMini-v1 stores only one flight"); else - flight_log_max_value.setToolTipText("Cannot set max flight log value"); + flight_log_max_value.setToolTipText("Cannot set max value with flight logs in memory"); } } @@ -189,13 +225,20 @@ public class AltosConfigUI else { if (is_telemetrum()) pad_orientation_value.setToolTipText("Older TeleMetrum firmware must fly antenna forward"); - else if (is_telemini()) - pad_orientation_value.setToolTipText("TeleMini doesn't care how it is mounted"); + else if (is_telemini() || is_easymini()) + pad_orientation_value.setToolTipText("TeleMini and EasyMini don't care how they are mounted"); else pad_orientation_value.setToolTipText("Can't select orientation"); } } + void set_beep_tool_tip() { + if (beep_value.isEnabled()) + beep_value.setToolTipText("What frequency the beeper will sound at"); + else + beep_value.setToolTipText("Older firmware could not select beeper frequency"); + } + /* Build the UI using a grid bag */ public AltosConfigUI(JFrame in_owner, boolean remote) { super (in_owner, "Configure Flight Computer", false); @@ -296,7 +339,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - main_deploy_value = new JComboBox(main_deploy_values()); + main_deploy_value = new JComboBox<String>(main_deploy_values()); main_deploy_value.setEditable(true); main_deploy_value.addItemListener(this); pane.add(main_deploy_value, c); @@ -322,7 +365,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - apogee_delay_value = new JComboBox(apogee_delay_values); + apogee_delay_value = new JComboBox<String>(apogee_delay_values); apogee_delay_value.setEditable(true); apogee_delay_value.addItemListener(this); pane.add(apogee_delay_value, c); @@ -348,7 +391,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - apogee_lockout_value = new JComboBox(apogee_lockout_values); + apogee_lockout_value = new JComboBox<String>(apogee_lockout_values); apogee_lockout_value.setEditable(true); apogee_lockout_value.addItemListener(this); pane.add(apogee_lockout_value, c); @@ -451,7 +494,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - aprs_interval_value = new JComboBox(aprs_interval_values); + aprs_interval_value = new JComboBox<String>(aprs_interval_values); aprs_interval_value.setEditable(true); aprs_interval_value.addItemListener(this); pane.add(aprs_interval_value, c); @@ -491,7 +534,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = il; c.ipady = 5; - flight_log_max_label = new JLabel("Maximum Flight Log Size:"); + flight_log_max_label = new JLabel("Maximum Flight Log Size (kB):"); pane.add(flight_log_max_label, c); c = new GridBagConstraints(); @@ -502,7 +545,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - flight_log_max_value = new JComboBox(flight_log_max_values); + flight_log_max_value = new JComboBox<String>(); flight_log_max_value.setEditable(true); flight_log_max_value.addItemListener(this); pane.add(flight_log_max_value, c); @@ -528,7 +571,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - ignite_mode_value = new JComboBox(ignite_mode_values); + ignite_mode_value = new JComboBox<String>(ignite_mode_values); ignite_mode_value.setEditable(false); ignite_mode_value.addItemListener(this); pane.add(ignite_mode_value, c); @@ -554,13 +597,90 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - pad_orientation_value = new JComboBox(pad_orientation_values); + pad_orientation_value = new JComboBox<String>(pad_orientation_values); pad_orientation_value.setEditable(false); pad_orientation_value.addItemListener(this); pane.add(pad_orientation_value, c); set_pad_orientation_tool_tip(); row++; + /* Beeper */ + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + beep_label = new JLabel("Beeper Frequency:"); + pane.add(beep_label, c); + + c = new GridBagConstraints(); + c.gridx = 4; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + c.ipady = 5; + beep_value = new JComboBox<String>(beep_values); + beep_value.setEditable(true); + beep_value.addItemListener(this); + pane.add(beep_value, c); + set_beep_tool_tip(); + row++; + + /* Tracker triger horiz distances */ + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + tracker_motion_label = new JLabel(get_tracker_motion_label()); + pane.add(tracker_motion_label, c); + + c = new GridBagConstraints(); + c.gridx = 4; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + c.ipady = 5; + tracker_motion_value = new JComboBox<String>(tracker_motion_values()); + tracker_motion_value.setEditable(true); + tracker_motion_value.addItemListener(this); + pane.add(tracker_motion_value, c); + row++; + + /* Tracker triger vert distances */ + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + tracker_interval_label = new JLabel("Position Reporting Interval(s):"); + pane.add(tracker_interval_label, c); + + c = new GridBagConstraints(); + c.gridx = 4; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + c.ipady = 5; + tracker_interval_value = new JComboBox<String>(tracker_interval_values); + tracker_interval_value.setEditable(true); + tracker_interval_value.addItemListener(this); + pane.add(tracker_interval_value, c); + set_tracker_tool_tip(); + row++; + /* Pyro channels */ c = new GridBagConstraints(); c.gridx = 4; c.gridy = row; @@ -673,7 +793,7 @@ public class AltosConfigUI if (cmd.equals("Pyro")) { if (pyro_ui == null && pyros != null) - pyro_ui = new AltosConfigPyroUI(this, pyros); + pyro_ui = new AltosConfigPyroUI(this, pyros, pyro_firing_time); if (pyro_ui != null) pyro_ui.make_visible(); return; @@ -742,14 +862,14 @@ public class AltosConfigUI String get_main_deploy_label() { return String.format("Main Deploy Altitude(%s):", AltosConvert.height.show_units()); } - + String[] main_deploy_values() { if (AltosConvert.imperial_units) return main_deploy_values_ft; else return main_deploy_values_m; } - + void set_main_deploy_values() { String[] v = main_deploy_values(); while (main_deploy_value.getItemCount() > 0) @@ -758,13 +878,20 @@ public class AltosConfigUI main_deploy_value.addItem(v[i]); main_deploy_value.setMaximumRowCount(v.length); } - + public void units_changed(boolean imperial_units) { String v = main_deploy_value.getSelectedItem().toString(); main_deploy_label.setText(get_main_deploy_label()); set_main_deploy_values(); int m = (int) (AltosConvert.height.parse(v, !imperial_units) + 0.5); set_main_deploy(m); + + if (tracker_motion_value.isEnabled()) { + String motion = tracker_motion_value.getSelectedItem().toString(); + tracker_motion_label.setText(get_tracker_motion_label()); + set_tracker_motion_values(); + set_tracker_motion((int) (AltosConvert.height.parse(motion, !imperial_units) + 0.5)); + } } public void set_apogee_delay(int new_apogee_delay) { @@ -772,8 +899,19 @@ public class AltosConfigUI apogee_delay_value.setEnabled(new_apogee_delay >= 0); } - public int apogee_delay() { - return Integer.parseInt(apogee_delay_value.getSelectedItem().toString()); + private int parse_int(String name, String s, boolean split) throws AltosConfigDataException { + String v = s; + if (split) + v = s.split("\\s+")[0]; + try { + return Integer.parseInt(v); + } catch (NumberFormatException ne) { + throw new AltosConfigDataException("Invalid %s \"%s\"", name, s); + } + } + + public int apogee_delay() throws AltosConfigDataException { + return parse_int("apogee delay", apogee_delay_value.getSelectedItem().toString(), false); } public void set_apogee_lockout(int new_apogee_lockout) { @@ -781,8 +919,8 @@ public class AltosConfigUI apogee_lockout_value.setEnabled(new_apogee_lockout >= 0); } - public int apogee_lockout() { - return Integer.parseInt(apogee_lockout_value.getSelectedItem().toString()); + public int apogee_lockout() throws AltosConfigDataException { + return parse_int("apogee lockout", apogee_lockout_value.getSelectedItem().toString(), false); } public void set_radio_frequency(double new_radio_frequency) { @@ -801,8 +939,8 @@ public class AltosConfigUI radio_calibration_value.setText(String.format("%d", new_radio_calibration)); } - public int radio_calibration() { - return Integer.parseInt(radio_calibration_value.getText()); + public int radio_calibration() throws AltosConfigDataException { + return parse_int("radio calibration", radio_calibration_value.getText(), false); } public void set_radio_enable(int new_radio_enable) { @@ -833,9 +971,22 @@ public class AltosConfigUI return callsign_value.getText(); } + int flight_log_max_limit; + int flight_log_max; + + public String flight_log_max_label(int flight_log_max) { + if (flight_log_max_limit != 0) { + int nflight = flight_log_max_limit / flight_log_max; + String plural = nflight > 1 ? "s" : ""; + + return String.format("%d (%d flight%s)", flight_log_max, nflight, plural); + } + return String.format("%d", flight_log_max); + } + public void set_flight_log_max(int new_flight_log_max) { - flight_log_max_value.setEnabled(new_flight_log_max > 0); - flight_log_max_value.setSelectedItem(Integer.toString(new_flight_log_max)); + flight_log_max_value.setSelectedItem(flight_log_max_label(new_flight_log_max)); + flight_log_max = new_flight_log_max; set_flight_log_max_tool_tip(); } @@ -844,20 +995,19 @@ public class AltosConfigUI set_flight_log_max_tool_tip(); } - public int flight_log_max() { - return Integer.parseInt(flight_log_max_value.getSelectedItem().toString()); + public int flight_log_max() throws AltosConfigDataException { + return parse_int("flight log max", flight_log_max_value.getSelectedItem().toString(), true); } - public void set_flight_log_max_limit(int flight_log_max_limit) { - //boolean any_added = false; + public void set_flight_log_max_limit(int new_flight_log_max_limit) { + flight_log_max_limit = new_flight_log_max_limit; flight_log_max_value.removeAllItems(); - for (int i = 0; i < flight_log_max_values.length; i++) { - if (Integer.parseInt(flight_log_max_values[i]) < flight_log_max_limit){ - flight_log_max_value.addItem(flight_log_max_values[i]); - //any_added = true; - } + for (int i = 8; i >= 1; i--) { + int size = flight_log_max_limit / i; + flight_log_max_value.addItem(String.format("%d (%d flights)", size, i)); } - flight_log_max_value.addItem(String.format("%d", flight_log_max_limit)); + if (flight_log_max != 0) + set_flight_log_max(flight_log_max); } public void set_ignite_mode(int new_ignite_mode) { @@ -901,6 +1051,87 @@ public class AltosConfigUI return -1; } + public void set_beep(int new_beep) { + int new_freq = (int) Math.floor (AltosConvert.beep_value_to_freq(new_beep) + 0.5); + for (int i = 0; i < beep_values.length; i++) + if (new_beep == AltosConvert.beep_freq_to_value(Integer.parseInt(beep_values[i]))) { + beep_value.setSelectedIndex(i); + set_beep_tool_tip(); + return; + } + beep_value.setSelectedItem(String.format("%d", new_freq)); + beep_value.setEnabled(new_beep >= 0); + set_beep_tool_tip(); + } + + public int beep() { + if (beep_value.isEnabled()) + return AltosConvert.beep_freq_to_value(Integer.parseInt(beep_value.getSelectedItem().toString())); + else + return -1; + } + + String[] tracker_motion_values() { + if (AltosConvert.imperial_units) + return tracker_motion_values_ft; + else + return tracker_motion_values_m; + } + + void set_tracker_motion_values() { + String[] v = tracker_motion_values(); + while (tracker_motion_value.getItemCount() > 0) + tracker_motion_value.removeItemAt(0); + for (int i = 0; i < v.length; i++) + tracker_motion_value.addItem(v[i]); + tracker_motion_value.setMaximumRowCount(v.length); + } + + String get_tracker_motion_label() { + return String.format("Logging Trigger Motion (%s):", AltosConvert.height.show_units()); + } + + void set_tracker_tool_tip() { + if (tracker_motion_value.isEnabled()) + tracker_motion_value.setToolTipText("How far the device must move before logging"); + else + tracker_motion_value.setToolTipText("This device doesn't disable logging when stationary"); + if (tracker_interval_value.isEnabled()) + tracker_interval_value.setToolTipText("How often to report GPS position"); + else + tracker_interval_value.setToolTipText("This device can't configure interval"); + } + + public void set_tracker_motion(int tracker_motion) { + if (tracker_motion < 0) { + tracker_motion_label.setVisible(false); + tracker_motion_value.setVisible(false); + } else { + tracker_motion_label.setVisible(true); + tracker_motion_value.setVisible(true); + tracker_motion_value.setSelectedItem(AltosConvert.height.say(tracker_motion)); + } + } + + public int tracker_motion() throws AltosConfigDataException { + return (int) AltosConvert.height.parse(tracker_motion_value.getSelectedItem().toString()); + } + + public void set_tracker_interval(int tracker_interval) { + if (tracker_interval< 0) { + tracker_interval_label.setVisible(false); + tracker_interval_value.setVisible(false); + } else { + tracker_interval_label.setVisible(true); + tracker_interval_value.setVisible(true); + tracker_interval_value.setSelectedItem(String.format("%d", tracker_interval)); + } + } + + public int tracker_interval() throws AltosConfigDataException { + return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false); + } + public void set_pyros(AltosPyro[] new_pyros) { pyros = new_pyros; pyro.setVisible(pyros != null); @@ -908,12 +1139,25 @@ public class AltosConfigUI pyro_ui.set_pyros(pyros); } - public AltosPyro[] pyros() { + public AltosPyro[] pyros() throws AltosConfigDataException { if (pyro_ui != null) pyros = pyro_ui.get_pyros(); return pyros; } + public void set_pyro_firing_time(double new_pyro_firing_time) { + pyro_firing_time = new_pyro_firing_time; + pyro.setVisible(pyro_firing_time >= 0); + if (pyro_firing_time >= 0 && pyro_ui != null) + pyro_ui.set_pyro_firing_time(pyro_firing_time); + } + + public double pyro_firing_time() throws AltosConfigDataException { + if (pyro_ui != null) + pyro_firing_time = pyro_ui.get_pyro_firing_time(); + return pyro_firing_time; + } + public void set_aprs_interval(int new_aprs_interval) { String s; @@ -926,11 +1170,11 @@ public class AltosConfigUI set_aprs_interval_tool_tip(); } - public int aprs_interval() { + public int aprs_interval() throws AltosConfigDataException { String s = aprs_interval_value.getSelectedItem().toString(); if (s.equals("Disabled")) return 0; - return Integer.parseInt(s); + return parse_int("aprs interval", s, false); } } diff --git a/altosui/AltosConfigureUI.java b/altosui/AltosConfigureUI.java index 5e42f430..e61a4a5b 100644 --- a/altosui/AltosConfigureUI.java +++ b/altosui/AltosConfigureUI.java @@ -22,7 +22,7 @@ import java.awt.event.*; import java.beans.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altosuilib_2.*; public class AltosConfigureUI extends AltosUIConfigure @@ -31,7 +31,7 @@ public class AltosConfigureUI AltosVoice voice; public JTextField callsign_value; - public JComboBox position_value; + public JComboBox<String> position_value; /* DocumentListener interface methods */ public void insertUpdate(DocumentEvent e) { @@ -123,11 +123,11 @@ public class AltosConfigureUI "Bottom", "Bottom right", }; - + public void add_position() { pane.add(new JLabel ("Menu position"), constraints(0, 1)); - - position_value = new JComboBox (position_names); + + position_value = new JComboBox<String>(position_names); position_value.setMaximumRowCount(position_names.length); int position = AltosUIPreferences.position(); position_value.setSelectedIndex(position); diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java deleted file mode 100644 index a9344a01..00000000 --- a/altosui/AltosDataChooser.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.*; -import javax.swing.filechooser.FileNameExtensionFilter; -import java.io.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosDataChooser extends JFileChooser { - JFrame frame; - String filename; - File file; - - public String filename() { - return filename; - } - - public File file() { - return file; - } - - public AltosStateIterable runDialog() { - int ret; - - ret = showOpenDialog(frame); - if (ret == APPROVE_OPTION) { - file = getSelectedFile(); - if (file == null) - return null; - filename = file.getName(); - try { - if (filename.endsWith("eeprom")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromFile(in); - } else if (filename.endsWith("telem")) { - FileInputStream in = new FileInputStream(file); - return new AltosTelemetryFile(in); - } else { - throw new FileNotFoundException(); - } - } catch (FileNotFoundException fe) { - JOptionPane.showMessageDialog(frame, - fe.getMessage(), - "Cannot open file", - JOptionPane.ERROR_MESSAGE); - } - } - return null; - } - - public AltosDataChooser(JFrame in_frame) { - frame = in_frame; - setDialogTitle("Select Flight Record File"); - setFileFilter(new FileNameExtensionFilter("TeleMetrum eeprom file", - "eeprom")); - setFileFilter(new FileNameExtensionFilter("Telemetry file", - "telem")); - setFileFilter(new FileNameExtensionFilter("TeleMega eeprom file", - "mega")); - setFileFilter(new FileNameExtensionFilter("EasyMini eeprom file", - "mini")); - setFileFilter(new FileNameExtensionFilter("Flight data file", - "telem", "eeprom", "mega", "mini")); - setCurrentDirectory(AltosUIPreferences.logdir()); - } -} diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index d1379083..36fc1613 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -17,446 +17,148 @@ package altosui; +import java.util.*; import java.awt.*; +import java.awt.event.*; import javax.swing.*; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; -public class AltosDescent extends JComponent implements AltosFlightDisplay { - GridBagLayout layout; +public class AltosDescent extends AltosUIFlightTab { - public abstract class DescentStatus { - JLabel label; - JTextField value; - AltosLights lights; - - abstract void show(AltosState state, AltosListenerState listener_state); - - void show() { - label.setVisible(true); - value.setVisible(true); - lights.setVisible(true); - } - - void show(String s) { - show(); - value.setText(s); - } - - void show(String format, double value) { - show(String.format(format, value)); - } - - void hide() { - label.setVisible(false); - value.setVisible(false); - lights.setVisible(false); - } - - void reset() { - value.setText(""); - lights.set(false); - } - - void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); - } - - public DescentStatus (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - lights = new AltosLights(); - c.gridx = 0; c.gridy = y; - c.anchor = GridBagConstraints.CENTER; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(lights, c); - add(lights); - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.gridwidth = 3; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 4; c.gridy = y; - c.gridwidth = 1; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); + class Height extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { return state.height(); } + public Height (Container container, int x, int y) { + super (container, x, y, AltosConvert.height, "Height"); } } - public abstract class DescentValue { - JLabel label; - JTextField value; - - void reset() { - value.setText(""); - } - - abstract void show(AltosState state, AltosListenerState listener_state); - - void show() { - label.setVisible(true); - value.setVisible(true); - } - - void hide() { - label.setVisible(false); - value.setVisible(false); - } + class Speed extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { return state.speed(); } - void show(String v) { - show(); - value.setText(v); - } - - void show(AltosUnits units, double v) { - show(units.show(8, v)); - } - - void show(String format, double v) { - show(String.format(format, v)); - } - - void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); - } - - public DescentValue (GridBagLayout layout, int x, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = x + 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - add(label, c); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = x + 2; c.gridy = y; - c.gridwidth = 1; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - add(value, c); + public Speed (Container container, int x, int y) { + super (container, x, y, AltosConvert.speed, "Speed"); } } - public abstract class DescentDualValue { - JLabel label; - JTextField value1; - JTextField value2; - - void reset() { - value1.setText(""); - value2.setText(""); - } - - void show() { - label.setVisible(true); - value1.setVisible(true); - value2.setVisible(true); - } - - void hide() { - label.setVisible(false); - value1.setVisible(false); - value2.setVisible(false); - } - - void set_font() { - label.setFont(Altos.label_font); - value1.setFont(Altos.value_font); - value2.setFont(Altos.value_font); - } - - abstract void show(AltosState state, AltosListenerState listener_state); - - void show(String v1, String v2) { - show(); - value1.setText(v1); - value2.setText(v2); - } - void show(String f1, double v1, String f2, double v2) { - show(); - value1.setText(String.format(f1, v1)); - value2.setText(String.format(f2, v2)); - } - - public DescentDualValue (GridBagLayout layout, int x, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = x + 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); + class Lat extends AltosUIUnitsIndicator { - value1 = new JTextField(Altos.text_width); - value1.setFont(Altos.value_font); - value1.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = x + 2; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value1, c); - add(value1); + public boolean hide (AltosState state, int i) { return state.gps == null || !state.gps.connected; } - value2 = new JTextField(Altos.text_width); - value2.setFont(Altos.value_font); - value2.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = x + 4; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - c.gridwidth = 1; - layout.setConstraints(value2, c); - add(value2); + public double value(AltosState state, int i) { + if (state.gps == null) + return AltosLib.MISSING; + if (!state.gps.connected) + return AltosLib.MISSING; + return state.gps.lat; } - } - class Height extends DescentValue { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.height()); - } - public Height (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Height"); + public Lat (Container container, int x, int y) { + super (container, x, y, AltosConvert.latitude, "Latitude"); } } - Height height; + class Lon extends AltosUIUnitsIndicator { + public boolean hide (AltosState state, int i) { return state.gps == null || !state.gps.connected; } - class Speed extends DescentValue { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.speed()); - } - public Speed (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Speed"); + public double value(AltosState state, int i) { + if (state.gps == null) + return AltosLib.MISSING; + if (!state.gps.connected) + return AltosLib.MISSING; + return state.gps.lon; } - } - - Speed speed; - String pos(double p, String pos, String neg) { - String h = pos; - if (p < 0) { - h = neg; - p = -p; + public Lon (Container container, int x, int y) { + super (container, x, y, AltosConvert.longitude, "Longitude"); } - int deg = (int) Math.floor(p); - double min = (p - Math.floor(p)) * 60.0; - return String.format("%s %d° %9.6f", h, deg, min); } - class Lat extends DescentValue { - void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) - show(pos(state.gps.lat,"N", "S")); - else - show("???"); - } - public Lat (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Latitude"); + class Apogee extends AltosUIUnitsIndicator { + public boolean hide(double v) { return v == AltosLib.MISSING; } + public double value(AltosState state, int i) { return state.apogee_voltage; } + public double good() { return AltosLib.ao_igniter_good; } + + public Apogee (Container container, int y) { + super(container, 0, y, 3, AltosConvert.voltage, "Apogee Igniter Voltage", 1, true, 3); } } - Lat lat; + class Main extends AltosUIUnitsIndicator { + public boolean hide(double v) { return v == AltosLib.MISSING; } + public double value(AltosState state, int i) { return state.main_voltage; } + public double good() { return AltosLib.ao_igniter_good; } - class Lon extends DescentValue { - void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) - show(pos(state.gps.lon,"W", "E")); - else - show("???"); - } - public Lon (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Longitude"); + public Main (Container container, int y) { + super(container, 0, y, 3, AltosConvert.voltage, "Main Igniter Voltage", 1, true, 3); } } - Lon lon; - - class Distance extends DescentValue { - void show(AltosState state, AltosListenerState listener_state) { + class Distance extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { if (state.from_pad != null) - show(AltosConvert.distance, state.from_pad.distance); + return state.from_pad.distance; else - show("???"); - } - - public Distance (GridBagLayout layout, int x, int y) { - super(layout, x, y, "Ground Distance"); + return AltosLib.MISSING; } - } - - Distance distance; - - class Apogee extends DescentStatus { - void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.apogee_voltage); - lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good); - } - public Apogee (GridBagLayout layout, int y) { - super(layout, y, "Apogee Igniter Voltage"); + public Distance(Container container, int x, int y) { + super(container, x, y, AltosConvert.distance, "Ground Distance"); } } - Apogee apogee; - - class Main extends DescentStatus { - void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_voltage); - lights.set(state.main_voltage >= AltosLib.ao_igniter_good); + class Range extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { + return state.range; } - public Main (GridBagLayout layout, int y) { - super(layout, y, "Main Igniter Voltage"); + public Range (Container container, int x, int y) { + super (container, x, y, AltosConvert.distance, "Range"); } } - Main main; - - class Bearing extends DescentDualValue { - void show (AltosState state, AltosListenerState listener_state) { - if (state.from_pad != null) { + class Bearing extends AltosUIIndicator { + public void show (AltosState state, AltosListenerState listener_state) { + if (state.from_pad != null && state.from_pad.bearing != AltosLib.MISSING) { show( String.format("%3.0f°", state.from_pad.bearing), state.from_pad.bearing_words( AltosGreatCircle.BEARING_LONG)); } else { - show("???", "???"); + show("Missing", "Missing"); } } - public Bearing (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Bearing"); + public Bearing (Container container, int x, int y) { + super (container, x, y, 1, "Bearing", 2, false, 1, 2); } } - Bearing bearing; - - class Range extends DescentValue { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.distance, state.range); - } - public Range (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Range"); - } - } - - Range range; - - class Elevation extends DescentValue { - void show (AltosState state, AltosListenerState listener_state) { - show("%3.0f°", state.elevation); + class Elevation extends AltosUIIndicator { + public void show (AltosState state, AltosListenerState listener_state) { + if (state.elevation == AltosLib.MISSING) + show("Missing"); + else + show("%3.0f°", state.elevation); } - public Elevation (GridBagLayout layout, int x, int y) { - super (layout, x, y, "Elevation"); + public Elevation (Container container, int x, int y) { + super (container, x, y, "Elevation", 1, false, 1); } } - Elevation elevation; - - public void reset() { - lat.reset(); - lon.reset(); - height.reset(); - speed.reset(); - bearing.reset(); - range.reset(); - distance.reset(); - elevation.reset(); - main.reset(); - apogee.reset(); - } - - public void set_font() { - lat.set_font(); - lon.set_font(); - height.set_font(); - speed.set_font(); - bearing.set_font(); - range.set_font(); - distance.set_font(); - elevation.set_font(); - main.set_font(); - apogee.set_font(); - } - - public void show(AltosState state, AltosListenerState listener_state) { - height.show(state, listener_state); - speed.show(state, listener_state); - if (state.gps != null && state.gps.connected) { - bearing.show(state, listener_state); - range.show(state, listener_state); - distance.show(state, listener_state); - elevation.show(state, listener_state); - lat.show(state, listener_state); - lon.show(state, listener_state); - } else { - bearing.hide(); - range.hide(); - distance.hide(); - elevation.hide(); - lat.hide(); - lon.hide(); - } - if (state.main_voltage != AltosLib.MISSING) - main.show(state, listener_state); - else - main.hide(); - if (state.apogee_voltage != AltosLib.MISSING) - apogee.show(state, listener_state); - else - apogee.hide(); - } - public String getName() { return "Descent"; } public AltosDescent() { - layout = new GridBagLayout(); - - setLayout(layout); - /* Elements in descent display */ - speed = new Speed(layout, 0, 0); - height = new Height(layout, 2, 0); - elevation = new Elevation(layout, 0, 1); - range = new Range(layout, 2, 1); - bearing = new Bearing(layout, 0, 2); - distance = new Distance(layout, 0, 3); - lat = new Lat(layout, 0, 4); - lon = new Lon(layout, 2, 4); - - apogee = new Apogee(layout, 5); - main = new Main(layout, 6); + add(new Speed(this, 0, 0)); + add(new Height(this, 2, 0)); + add(new Elevation(this, 0, 1)); + add(new Range(this, 2, 1)); + add(new Bearing(this, 0, 2)); + add(new Distance(this, 0, 3)); + add(new Lat(this, 0, 4)); + add(new Lon(this, 2, 4)); + add(new Apogee(this, 5)); + add(new Main(this, 6)); } } diff --git a/altosui/AltosDeviceUIDialog.java b/altosui/AltosDeviceUIDialog.java deleted file mode 100644 index ceabe843..00000000 --- a/altosui/AltosDeviceUIDialog.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosDeviceUIDialog extends AltosDeviceDialog { - - public AltosDevice[] devices() { - java.util.List<AltosDevice> usb_devices = AltosUSBDevice.list(product); - int num_devices = usb_devices.size(); - java.util.List<AltosDevice> bt_devices = AltosBTKnown.bt_known().list(product); - num_devices += bt_devices.size(); - AltosDevice[] devices = new AltosDevice[num_devices]; - - for (int i = 0; i < usb_devices.size(); i++) - devices[i] = usb_devices.get(i); - int off = usb_devices.size(); - for (int j = 0; j < bt_devices.size(); j++) - devices[off + j] = bt_devices.get(j); - return devices; - } - - public void add_bluetooth() { - JButton manage_bluetooth_button = new JButton("Manage Bluetooth"); - manage_bluetooth_button.setActionCommand("manage"); - manage_bluetooth_button.addActionListener(this); - buttonPane.add(manage_bluetooth_button); - buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); - } - - public void actionPerformed(ActionEvent e) { - super.actionPerformed(e); - if ("manage".equals(e.getActionCommand())) { - AltosBTManage.show(frame, AltosBTKnown.bt_known()); - update_devices(); - } - } - - public AltosDeviceUIDialog (Frame in_frame, Component location, int in_product) { - super(in_frame, location, in_product); - } - - public static AltosDevice show (Component frameComp, int product) { - Frame frame = JOptionPane.getFrameForComponent(frameComp); - AltosDeviceUIDialog dialog; - - dialog = new AltosDeviceUIDialog(frame, frameComp, product); - dialog.setVisible(true); - return dialog.getValue(); - } -} diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java deleted file mode 100644 index 2a33f996..00000000 --- a/altosui/AltosDisplayThread.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import javax.swing.*; -import java.io.*; -import java.text.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosDisplayThread extends Thread { - - Frame parent; - IdleThread idle_thread; - AltosVoice voice; - AltosFlightReader reader; - AltosState old_state, state; - AltosListenerState listener_state; - AltosFlightDisplay display; - - synchronized void show_safely() { - final AltosState my_state = state; - final AltosListenerState my_listener_state = listener_state; - Runnable r = new Runnable() { - public void run() { - try { - display.show(my_state, my_listener_state); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - void reading_error_internal() { - JOptionPane.showMessageDialog(parent, - String.format("Error reading from \"%s\"", reader.name), - "Telemetry Read Error", - JOptionPane.ERROR_MESSAGE); - } - - void reading_error_safely() { - Runnable r = new Runnable() { - public void run() { - try { - reading_error_internal(); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - class IdleThread extends Thread { - - boolean started; - int reported_landing; - int report_interval; - long report_time; - - public synchronized void report(boolean last) { - if (state == null) - return; - - /* reset the landing count once we hear about a new flight */ - if (state.state < Altos.ao_flight_drogue) - reported_landing = 0; - - /* Shut up once the rocket is on the ground */ - if (reported_landing > 2) { - return; - } - - /* If the rocket isn't on the pad, then report height */ - if (Altos.ao_flight_drogue <= state.state && - state.state < Altos.ao_flight_landed && - state.from_pad != null && - state.range >= 0) - { - voice.speak("Height %s, bearing %s %d, elevation %d, range %s.\n", - AltosConvert.height.say(state.height()), - state.from_pad.bearing_words( - AltosGreatCircle.BEARING_VOICE), - (int) (state.from_pad.bearing + 0.5), - (int) (state.elevation + 0.5), - AltosConvert.distance.say(state.range)); - } else if (state.state > Altos.ao_flight_pad) { - voice.speak(AltosConvert.height.say_units(state.height())); - } else { - reported_landing = 0; - } - - /* If the rocket is coming down, check to see if it has landed; - * either we've got a landed report or we haven't heard from it in - * a long time - */ - if (state.state >= Altos.ao_flight_drogue && - (last || - System.currentTimeMillis() - state.received_time >= 15000 || - state.state == Altos.ao_flight_landed)) - { - if (Math.abs(state.speed()) < 20 && state.height() < 100) - voice.speak("rocket landed safely"); - else - voice.speak("rocket may have crashed"); - if (state.from_pad != null) - voice.speak("Bearing %d degrees, range %s.", - (int) (state.from_pad.bearing + 0.5), - AltosConvert.distance.say_units(state.from_pad.distance)); - ++reported_landing; - if (state.state != Altos.ao_flight_landed) { - state.state = Altos.ao_flight_landed; - show_safely(); - } - } - } - - long now () { - return System.currentTimeMillis(); - } - - void set_report_time() { - report_time = now() + report_interval; - } - - public void run () { - try { - for (;;) { - if (reader.has_monitor_battery()) { - listener_state.battery = reader.monitor_battery(); - show_safely(); - } - set_report_time(); - for (;;) { - voice.drain(); - synchronized (this) { - long sleep_time = report_time - now(); - if (sleep_time <= 0) - break; - wait(sleep_time); - } - } - - report(false); - } - } catch (InterruptedException ie) { - try { - voice.drain(); - } catch (InterruptedException iie) { } - } - } - - public synchronized void notice(boolean spoken) { - if (old_state != null && old_state.state != state.state) { - report_time = now(); - this.notify(); - } else if (spoken) - set_report_time(); - } - - public IdleThread() { - reported_landing = 0; - report_interval = 10000; - } - } - - synchronized boolean tell() { - boolean ret = false; - if (old_state == null || old_state.state != state.state) { - voice.speak(state.state_name()); - if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && - state.state > Altos.ao_flight_boost) { - voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_speed() + 0.5)); - ret = true; - } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && - state.state >= Altos.ao_flight_drogue) { - voice.speak("max height: %s.", - AltosConvert.height.say_units(state.max_height() + 0.5)); - ret = true; - } - } - if (old_state == null || old_state.gps_ready != state.gps_ready) { - if (state.gps_ready) { - voice.speak("GPS ready"); - ret = true; - } - else if (old_state != null) { - voice.speak("GPS lost"); - ret = true; - } - } - old_state = state; - return ret; - } - - public void run() { - boolean interrupted = false; - boolean told; - - idle_thread = new IdleThread(); - idle_thread.start(); - - try { - for (;;) { - try { - state = reader.read(); - if (state == null) - break; - reader.update(state); - show_safely(); - told = tell(); - idle_thread.notice(told); - } catch (ParseException pp) { - System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage()); - } catch (AltosCRCException ce) { - ++listener_state.crc_errors; - show_safely(); - } - } - } catch (InterruptedException ee) { - interrupted = true; - } catch (IOException ie) { - reading_error_safely(); - } finally { - if (!interrupted) - idle_thread.report(true); - reader.close(interrupted); - idle_thread.interrupt(); - try { - idle_thread.join(); - } catch (InterruptedException ie) {} - } - } - - public AltosDisplayThread(Frame in_parent, AltosVoice in_voice, AltosFlightDisplay in_display, AltosFlightReader in_reader) { - listener_state = new AltosListenerState(); - parent = in_parent; - voice = in_voice; - display = in_display; - reader = in_reader; - display.reset(); - } -} diff --git a/altosui/AltosEepromDelete.java b/altosui/AltosEepromDelete.java deleted file mode 100644 index b2d2e291..00000000 --- a/altosui/AltosEepromDelete.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.event.*; -import javax.swing.*; -import java.io.*; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosEepromDelete implements Runnable { - AltosEepromList flights; - Thread eeprom_thread; - AltosSerial serial_line; - boolean remote; - JFrame frame; - ActionListener listener; - boolean success; - - private void DeleteLog (AltosEepromLog log) - throws IOException, InterruptedException, TimeoutException { - - if (flights.config_data.flight_log_max != 0 || flights.config_data.log_format != 0) { - - /* Devices with newer firmware can erase the - * flash blocks containing each flight - */ - serial_line.flush_input(); - serial_line.printf("d %d\n", log.flight); - for (;;) { - /* It can take a while to erase the flash... */ - String line = serial_line.get_reply(20000); - if (line == null) - throw new TimeoutException(); - if (line.equals("Erased")) - break; - if (line.startsWith("No such")) - throw new IOException(line); - } - } - } - - private void show_error_internal(String message, String title) { - JOptionPane.showMessageDialog(frame, - message, - title, - JOptionPane.ERROR_MESSAGE); - } - - private void show_error(String in_message, String in_title) { - final String message = in_message; - final String title = in_title; - Runnable r = new Runnable() { - public void run() { - try { - show_error_internal(message, title); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - public void run () { - success = false; - try { - if (remote) - serial_line.start_remote(); - - for (AltosEepromLog log : flights) { - if (log.selected) { - DeleteLog(log); - } - } - success = true; - } catch (IOException ee) { - show_error (ee.getLocalizedMessage(), - serial_line.device.toShortString()); - } catch (InterruptedException ie) { - } catch (TimeoutException te) { - show_error (String.format("Connection to \"%s\" failed", - serial_line.device.toShortString()), - "Connection Failed"); - } finally { - try { - if (remote) - serial_line.stop_remote(); - } catch (InterruptedException ie) { - } finally { - serial_line.flush_output(); - serial_line.close(); - } - } - if (listener != null) { - Runnable r = new Runnable() { - public void run() { - try { - listener.actionPerformed(new ActionEvent(this, - success ? 1 : 0, - "delete")); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - } - - public void start() { - eeprom_thread = new Thread(this); - eeprom_thread.start(); - } - - public void addActionListener(ActionListener l) { - listener = l; - } - - public AltosEepromDelete(JFrame given_frame, - AltosSerial given_serial_line, - boolean given_remote, - AltosEepromList given_flights) { - frame = given_frame; - serial_line = given_serial_line; - remote = given_remote; - flights = given_flights; - success = false; - } -}
\ No newline at end of file diff --git a/altosui/AltosEepromManage.java b/altosui/AltosEepromManage.java deleted file mode 100644 index e3635571..00000000 --- a/altosui/AltosEepromManage.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.event.*; -import javax.swing.*; -import java.io.*; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosEepromManage implements ActionListener { - - JFrame frame; - boolean remote; - AltosDevice device; - AltosSerial serial_line; - AltosEepromList flights; - AltosEepromDownload download; - AltosEepromDelete delete; - - public void finish() { - if (serial_line != null) { - try { - serial_line.flush_input(); - } catch (InterruptedException ie) { - } - serial_line.close(); - serial_line = null; - } - } - - private int countDeletedFlights() { - int count = 0; - for (AltosEepromLog flight : flights) { - if (flight.selected) - count++; - } - return count; - } - - private String showDeletedFlights() { - String result = ""; - - for (AltosEepromLog flight : flights) { - if (flight.selected) { - if (result.equals("")) - result = String.format("%d", flight.flight); - else - result = String.format("%s, %d", result, flight.flight); - } - } - 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; - } - } - return false; - } - - 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(); - } else if (cmd.equals("delete")) { - if (success) { - JOptionPane.showMessageDialog(frame, - String.format("%d flights erased: %s", - countDeletedFlights(), - showDeletedFlights()), - serial_line.device.toShortString(), - JOptionPane.INFORMATION_MESSAGE); - } - } - if (!running) - finish(); - } - - public void got_flights(AltosEepromList in_flights) { - boolean running = false;; - - flights = in_flights; - try { - if (flights.size() == 0) { - JOptionPane.showMessageDialog(frame, - String.format("No flights available on %d", - device.getSerial()), - serial_line.device.toShortString(), - JOptionPane.INFORMATION_MESSAGE); - } else { - AltosEepromSelect select = new AltosEepromSelect(frame, flights, "Download"); - - if (select.run()) { - boolean any_selected = false; - for (AltosEepromLog flight : flights) - any_selected = any_selected || flight.selected; - if (any_selected) { - AltosEepromMonitorUI monitor = new AltosEepromMonitorUI(frame); - monitor.addActionListener(this); - serial_line.set_frame(frame); - download = new AltosEepromDownload(monitor, - serial_line, - remote, - flights); - /* - * Start flight log download - */ - - download.start(); - running = true; - } else { - running = download_done(); - } - } - } - if (!running) - finish(); - } catch (Exception e) { - got_exception(e); - } - } - - public void got_exception(Exception e) { - if (e instanceof IOException) { - IOException ee = (IOException) e; - JOptionPane.showMessageDialog(frame, - device.toShortString(), - ee.getLocalizedMessage(), - JOptionPane.ERROR_MESSAGE); - } else if (e instanceof TimeoutException) { - //TimeoutException te = (TimeoutException) e; - JOptionPane.showMessageDialog(frame, - String.format("Communications failed with \"%s\"", - device.toShortString()), - "Cannot open target device", - JOptionPane.ERROR_MESSAGE); - } - finish(); - } - - class EepromGetList implements Runnable { - - AltosEepromManage manage; - - public void run () { - Runnable r; - try { - flights = new AltosEepromList(serial_line, remote); - r = new Runnable() { - public void run() { - got_flights(flights); - } - }; - } catch (Exception e) { - final Exception f_e = e; - r = new Runnable() { - public void run() { - got_exception(f_e); - } - }; - } - SwingUtilities.invokeLater(r); - } - - public EepromGetList(AltosEepromManage in_manage) { - manage = in_manage; - } - } - - public AltosEepromManage(JFrame given_frame) { - - //boolean running = false; - - frame = given_frame; - device = AltosDeviceUIDialog.show(frame, Altos.product_any); - - remote = false; - - if (device != null) { - try { - serial_line = new AltosSerial(device); - if (device.matchProduct(Altos.product_basestation)) - remote = true; - - serial_line.set_frame(frame); - - EepromGetList get_list = new EepromGetList(this); - Thread t = new Thread(get_list); - t.start(); - } catch (FileNotFoundException ee) { - JOptionPane.showMessageDialog(frame, - ee.getMessage(), - "Cannot open target device", - JOptionPane.ERROR_MESSAGE); - } catch (AltosSerialInUseException si) { - JOptionPane.showMessageDialog(frame, - String.format("Device \"%s\" already in use", - device.toShortString()), - "Device in use", - JOptionPane.ERROR_MESSAGE); - } - } - } -} diff --git a/altosui/AltosEepromMonitor.java b/altosui/AltosEepromMonitor.java deleted file mode 100644 index 50921da1..00000000 --- a/altosui/AltosEepromMonitor.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosEepromMonitor extends AltosUIDialog { - - Container pane; - Box box; - JLabel serial_label; - JLabel flight_label; - JLabel file_label; - JLabel serial_value; - JLabel flight_value; - JLabel file_value; - JButton cancel; - JProgressBar pbar; - int min_state, max_state; - - public AltosEepromMonitor(JFrame owner, int in_min_state, int in_max_state) { - super (owner, "Download Flight Data", false); - - GridBagConstraints c; - Insets il = new Insets(4,4,4,4); - Insets ir = new Insets(4,4,4,4); - - pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 0; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - serial_label = new JLabel("Serial:"); - pane.add(serial_label, c); - - c = new GridBagConstraints(); - c.gridx = 1; c.gridy = 0; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - serial_value = new JLabel(""); - pane.add(serial_value, c); - - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.gridx = 0; c.gridy = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - flight_label = new JLabel("Flight:"); - pane.add(flight_label, c); - - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridx = 1; c.gridy = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - 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); - - min_state = in_min_state; - max_state = in_max_state; - pbar = new JProgressBar(); - pbar.setMinimum(0); - pbar.setMaximum(1000); - pbar.setValue(0); - pbar.setString("startup"); - pbar.setStringPainted(true); - pbar.setPreferredSize(new Dimension(600, 20)); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; c.gridy = 3; - c.gridwidth = GridBagConstraints.REMAINDER; - Insets ib = new Insets(4,4,4,4); - c.insets = ib; - pane.add(pbar, c); - - - cancel = new JButton("Cancel"); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; c.gridy = 4; - c.gridwidth = GridBagConstraints.REMAINDER; - Insets ic = new Insets(4,4,4,4); - c.insets = ic; - pane.add(cancel, c); - - pack(); - setLocationRelativeTo(owner); - setVisible(true); - } - - public void addActionListener (ActionListener l) { - cancel.addActionListener(l); - } - - private void set_value_internal(String state_name, int state, int state_block, int block) { - if (state_block > 100) - state_block = 100; - if (state < min_state) state = min_state; - if (state >= max_state) state = max_state - 1; - state -= min_state; - - int pos = state * 100 + state_block; - - pbar.setString(String.format("block %d state %s", block, state_name)); - pbar.setValue(pos); - } - - public void set_value(String in_state_name, int in_state, int in_state_block, int in_block) { - final String state_name = in_state_name; - final int state = in_state; - final int state_block = in_state_block; - final int block = in_block; - Runnable r = new Runnable() { - public void run() { - try { - set_value_internal(state_name, state, state_block, block); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void set_serial_internal(int serial) { - serial_value.setText(String.format("%d", serial)); - } - - public void set_serial(int in_serial) { - final int serial = in_serial; - Runnable r = new Runnable() { - public void run() { - try { - set_serial_internal(serial); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void set_flight_internal(int flight) { - flight_value.setText(String.format("%d", flight)); - } - - public void set_flight(int in_flight) { - final int flight = in_flight; - Runnable r = new Runnable() { - public void run() { - try { - set_flight_internal(flight); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void set_file_internal(String file) { - file_value.setText(String.format("%s", file)); - } - - public void set_file(String in_file) { - final String file = in_file; - Runnable r = new Runnable() { - public void run() { - try { - set_file_internal(file); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void done_internal() { - setVisible(false); - dispose(); - } - - public void done() { - Runnable r = new Runnable() { - public void run() { - try { - done_internal(); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void reset_internal() { - set_value_internal("startup",min_state,0, 0); - set_flight_internal(0); - set_file_internal(""); - } - - public void reset() { - Runnable r = new Runnable() { - public void run() { - try { - reset_internal(); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } -} diff --git a/altosui/AltosEepromMonitorUI.java b/altosui/AltosEepromMonitorUI.java deleted file mode 100644 index c2e925a2..00000000 --- a/altosui/AltosEepromMonitorUI.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import org.altusmetrum.altosuilib_1.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor { - JFrame owner; - Container pane; - Box box; - JLabel serial_label; - JLabel flight_label; - JLabel file_label; - JLabel serial_value; - JLabel flight_value; - JLabel file_value; - JButton cancel; - JProgressBar pbar; - int min_state, max_state; - ActionListener listener; - - public AltosEepromMonitorUI(JFrame owner) { - super (owner, "Download Flight Data", false); - - this.owner = owner; - - GridBagConstraints c; - Insets il = new Insets(4,4,4,4); - Insets ir = new Insets(4,4,4,4); - - pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 0; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - serial_label = new JLabel("Serial:"); - pane.add(serial_label, c); - - c = new GridBagConstraints(); - c.gridx = 1; c.gridy = 0; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - serial_value = new JLabel(""); - pane.add(serial_value, c); - - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.gridx = 0; c.gridy = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - flight_label = new JLabel("Flight:"); - pane.add(flight_label, c); - - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridx = 1; c.gridy = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - 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(1000); - pbar.setValue(0); - pbar.setString("startup"); - pbar.setStringPainted(true); - pbar.setPreferredSize(new Dimension(600, 20)); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; c.gridy = 3; - c.gridwidth = GridBagConstraints.REMAINDER; - Insets ib = new Insets(4,4,4,4); - c.insets = ib; - pane.add(pbar, c); - - - cancel = new JButton("Cancel"); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; c.gridy = 4; - c.gridwidth = GridBagConstraints.REMAINDER; - Insets ic = new Insets(4,4,4,4); - c.insets = ic; - pane.add(cancel, c); - - pack(); - setLocationRelativeTo(owner); - } - - public void addActionListener(ActionListener l) { - listener = l; - } - - public void set_states(int min_state, int max_state) { - this.min_state = min_state; - this.max_state = max_state; - } - - public void set_thread(Thread in_eeprom_thread) { - final Thread eeprom_thread = in_eeprom_thread; - cancel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (eeprom_thread != null) - eeprom_thread.interrupt(); - } - }); - } - - public void start() { - setVisible(true); - } - - private void set_value_internal(String state_name, int state, int state_block, int block) { - if (state_block > 100) - state_block = 100; - if (state < min_state) state = min_state; - if (state >= max_state) state = max_state - 1; - state -= min_state; - - int pos = state * 100 + state_block; - - pbar.setString(String.format("block %d state %s", block, state_name)); - pbar.setValue(pos); - } - - public void set_value(String in_state_name, int in_state, int in_state_block, int in_block) { - final String state_name = in_state_name; - final int state = in_state; - final int state_block = in_state_block; - final int block = in_block; - Runnable r = new Runnable() { - public void run() { - try { - set_value_internal(state_name, state, state_block, block); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void set_serial_internal(int serial) { - serial_value.setText(String.format("%d", serial)); - } - - public void set_serial(int in_serial) { - final int serial = in_serial; - Runnable r = new Runnable() { - public void run() { - try { - set_serial_internal(serial); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void set_flight_internal(int flight) { - flight_value.setText(String.format("%d", flight)); - } - - public void set_flight(int in_flight) { - final int flight = in_flight; - Runnable r = new Runnable() { - public void run() { - try { - set_flight_internal(flight); - } catch (Exception ex) { - } - } - }; - 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, - "download")); - setVisible(false); - dispose(); - } - - public void done(boolean in_success) { - final boolean success = in_success; - Runnable r = new Runnable() { - public void run() { - try { - done_internal(success); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void reset_internal() { - set_value_internal("startup",min_state,0, 0); - set_flight_internal(0); - set_filename_internal(""); - } - - public void reset() { - Runnable r = new Runnable() { - public void run() { - try { - reset_internal(); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - private void show_message_internal(String message, String title, int message_type) { - int joption_message_type = JOptionPane.ERROR_MESSAGE; - - switch (message_type) { - case INFO_MESSAGE: - joption_message_type = JOptionPane.INFORMATION_MESSAGE; - break; - case WARNING_MESSAGE: - joption_message_type = JOptionPane.WARNING_MESSAGE; - break; - case ERROR_MESSAGE: - joption_message_type = JOptionPane.ERROR_MESSAGE; - break; - } - JOptionPane.showMessageDialog(owner, - message, - title, - joption_message_type); - } - - public void show_message(String in_message, String in_title, int in_message_type) { - final String message = in_message; - final String title = in_title; - final int message_type = in_message_type; - Runnable r = new Runnable() { - public void run() { - try { - show_message_internal(message, title, message_type); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } -} diff --git a/altosui/AltosEepromSelect.java b/altosui/AltosEepromSelect.java deleted file mode 100644 index b7cdbb72..00000000 --- a/altosui/AltosEepromSelect.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.*; -import javax.swing.border.*; -import java.awt.*; -import java.awt.event.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -class AltosEepromItem implements ActionListener { - AltosEepromLog log; - JLabel label; - JCheckBox action; - JCheckBox delete; - - public void actionPerformed(ActionEvent e) { - log.selected = action.isSelected(); - } - - public AltosEepromItem(AltosEepromLog in_log) { - log = in_log; - - String text; - if (log.year != 0) - text = String.format("Flight #%02d - %04d-%02d-%02d", - log.flight, log.year, log.month, log.day); - else - text = String.format("Flight #%02d", log.flight); - - label = new JLabel(text); - - action = new JCheckBox("", log.selected); - action.addActionListener(this); - } -} - -public class AltosEepromSelect extends AltosUIDialog implements ActionListener { - //private JList list; - private JFrame frame; - JButton ok; - JButton cancel; - boolean success; - - /* Listen for events from our buttons */ - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - - if (cmd.equals("ok")) - success = true; - setVisible(false); - } - - public boolean run() { - success = false; - setLocationRelativeTo(frame); - setVisible(true); - return success; - } - - public AltosEepromSelect (JFrame in_frame, - AltosEepromList flights, - String action) { - - super(in_frame, String.format("Flight list for serial %d", flights.config_data.serial), true); - frame = in_frame; - - /* Create the container for the dialog */ - 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); - - JPanel labelPane = new JPanel(); - labelPane.setLayout(new BoxLayout(labelPane, BoxLayout.X_AXIS)); - labelPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - labelPane.add(Box.createHorizontalGlue()); - labelPane.add(selectLabel); - labelPane.add(Box.createHorizontalGlue()); - - /* Add the header to the container. */ - contentPane.add(labelPane, BorderLayout.PAGE_START); - - - /* Now we create the evilness that is a GridBag for the flight details */ - GridBagConstraints c; - Insets i = new Insets(4,4,4,4); - JPanel flightPane = new JPanel(); - flightPane.setLayout(new GridBagLayout()); - flightPane.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - - /* Flight Header */ - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 0; - c.fill = GridBagConstraints.NONE; - c.weightx = 0.5; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - JLabel flightHeaderLabel = new JLabel("Flight"); - flightPane.add(flightHeaderLabel, c); - - /* Download Header */ - c = new GridBagConstraints(); - c.gridx = 1; c.gridy = 0; - c.fill = GridBagConstraints.NONE; - c.weightx = 0.5; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - JLabel downloadHeaderLabel = new JLabel(action); - flightPane.add(downloadHeaderLabel, c); - - /* Add the flights to the GridBag */ - AltosEepromItem item; - int itemNumber = 1; - for (AltosEepromLog flight : flights) { - /* Create a flight object with handlers and - * appropriate UI items - */ - item = new AltosEepromItem(flight); - - /* Add a decriptive label for the flight */ - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = itemNumber; - c.fill = GridBagConstraints.NONE; - c.weightx = 0.5; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - flightPane.add(item.label, c); - - /* Add action 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); - - itemNumber++; - } - - /* Add the GridBag to the container */ - contentPane.add(flightPane, BorderLayout.CENTER); - - /* Create the dialog buttons */ - ok = new JButton("OK"); - ok.addActionListener(this); - ok.setActionCommand("ok"); - - cancel = new JButton("Cancel"); - cancel.addActionListener(this); - cancel.setActionCommand("cancel"); - - JPanel buttonPane = new JPanel(); - buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); - buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - buttonPane.add(Box.createHorizontalGlue()); - buttonPane.add(cancel); - buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); - buttonPane.add(ok); - - /* Add the buttons to the container */ - contentPane.add(buttonPane, BorderLayout.PAGE_END); - - /* Pack the window! */ - pack(); - } -} diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java deleted file mode 100644 index 5913e506..00000000 --- a/altosui/AltosFlashUI.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.filechooser.FileNameExtensionFilter; -import java.io.*; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosFlashUI - extends AltosUIDialog - implements ActionListener -{ - Container pane; - Box box; - JLabel serial_label; - JLabel serial_value; - JLabel file_label; - JLabel file_value; - JProgressBar pbar; - JButton cancel; - - JFrame frame; - - // Hex file with rom image - File file; - - // Debug connection - AltosDevice device; - - AltosLink link; - - // Desired Rom configuration - AltosRomconfig rom_config; - - // Flash controller - AltosProgrammer programmer; - - private static String[] pair_programmed = { - "teleballoon", - "telebt", - "teledongle", - "telefire", - "telemetrum-v0", - "telemetrum-v1", - "telemini", - "telenano", - "teleshield", - "teleterra" - }; - - private boolean is_pair_programmed() { - - if (file != null) { - String name = file.getName(); - for (int i = 0; i < pair_programmed.length; i++) { - if (name.startsWith(pair_programmed[i])) - return true; - } - } - if (device != null) { - if (!device.matchProduct(AltosLib.product_altusmetrum) && - (device.matchProduct(AltosLib.product_teledongle) || - device.matchProduct(AltosLib.product_telebt))) - return true; - } - return false; - } - - public void actionPerformed(ActionEvent e) { - if (e.getSource() == cancel) { - if (programmer != null) - programmer.abort(); - setVisible(false); - dispose(); - } else { - String cmd = e.getActionCommand(); - if (e.getID() == -1) { - JOptionPane.showMessageDialog(frame, - e.getActionCommand(), - file.toString(), - JOptionPane.ERROR_MESSAGE); - setVisible(false); - dispose(); - } else if (cmd.equals("done")) { - setVisible(false); - dispose(); - } else if (cmd.equals("start")) { - setVisible(true); - } else { - pbar.setValue(e.getID()); - pbar.setString(cmd); - } - } - } - - public void build_dialog() { - GridBagConstraints c; - Insets il = new Insets(4,4,4,4); - Insets ir = new Insets(4,4,4,4); - - pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 0; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - serial_label = new JLabel("Serial:"); - pane.add(serial_label, c); - - c = new GridBagConstraints(); - c.gridx = 1; c.gridy = 0; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - serial_value = new JLabel(""); - pane.add(serial_value, c); - - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.gridx = 0; c.gridy = 1; - 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 = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - file_value = new JLabel(file.toString()); - pane.add(file_value, c); - - pbar = new JProgressBar(); - pbar.setMinimum(0); - pbar.setMaximum(100); - pbar.setValue(0); - pbar.setString(""); - pbar.setStringPainted(true); - pbar.setPreferredSize(new Dimension(600, 20)); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; c.gridy = 2; - c.gridwidth = GridBagConstraints.REMAINDER; - Insets ib = new Insets(4,4,4,4); - c.insets = ib; - pane.add(pbar, c); - - cancel = new JButton("Cancel"); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 0; c.gridy = 3; - c.gridwidth = GridBagConstraints.REMAINDER; - Insets ic = new Insets(4,4,4,4); - c.insets = ic; - pane.add(cancel, c); - cancel.addActionListener(this); - pack(); - setLocationRelativeTo(frame); - } - - void set_serial(int serial_number) { - serial_value.setText(String.format("%d", serial_number)); - } - - static class AltosHexfileFilter extends javax.swing.filechooser.FileFilter { - int product; - String head; - String description; - - public AltosHexfileFilter(int product, String head, String description) { - this.product = product; - this.head = head; - this.description = description; - } - - public boolean accept(File file) { - return !file.isFile() || (file.getName().startsWith(head) && file.getName().endsWith(".ihx")); - } - - public String getDescription() { - return description; - } - } - - static AltosHexfileFilter[] filters = { - new AltosHexfileFilter(AltosLib.product_telemetrum, "telemetrum", "TeleMetrum Image"), - new AltosHexfileFilter(AltosLib.product_teledongle, "teledongle", "TeleDongle Image"), - new AltosHexfileFilter(AltosLib.product_telemega, "telemega", "TeleMega Image"), - new AltosHexfileFilter(AltosLib.product_easymini, "easymini", "EasyMini Image"), - }; - - boolean select_source_file() { - JFileChooser hexfile_chooser = new JFileChooser(); - - File firmwaredir = AltosUIPreferences.firmwaredir(); - if (firmwaredir != null) - hexfile_chooser.setCurrentDirectory(firmwaredir); - - hexfile_chooser.setDialogTitle("Select Flash Image"); - - for (int i = 0; i < filters.length; i++) { - hexfile_chooser.addChoosableFileFilter(filters[i]); - } - javax.swing.filechooser.FileFilter ihx_filter = new FileNameExtensionFilter("Flash Image", "ihx"); - hexfile_chooser.addChoosableFileFilter(ihx_filter); - hexfile_chooser.setFileFilter(ihx_filter); - - if (!is_pair_programmed() && !device.matchProduct(AltosLib.product_altusmetrum)) { - for (int i = 0; i < filters.length; i++) { - if (device != null && device.matchProduct(filters[i].product)) - hexfile_chooser.setFileFilter(filters[i]); - } - } - - int returnVal = hexfile_chooser.showOpenDialog(frame); - - if (returnVal != JFileChooser.APPROVE_OPTION) - return false; - file = hexfile_chooser.getSelectedFile(); - if (file == null) - return false; - AltosUIPreferences.set_firmwaredir(file.getParentFile()); - - return true; - } - - boolean select_device() { - int product = Altos.product_any; - - device = AltosDeviceUIDialog.show(frame, Altos.product_any); - - if (device == null) - return false; - return true; - } - - boolean update_rom_config_info(AltosRomconfig existing_config) { - AltosRomconfig new_config; - new_config = AltosRomconfigUI.show(frame, existing_config); - if (new_config == null) - return false; - rom_config = new_config; - set_serial(rom_config.serial_number); - setVisible(true); - return true; - } - - void exception (Exception e) { - if (e instanceof FileNotFoundException) { - JOptionPane.showMessageDialog(frame, - ((FileNotFoundException) e).getMessage(), - "Cannot open file", - JOptionPane.ERROR_MESSAGE); - } else if (e instanceof AltosSerialInUseException) { - JOptionPane.showMessageDialog(frame, - String.format("Device \"%s\" already in use", - device.toShortString()), - "Device in use", - JOptionPane.ERROR_MESSAGE); - } else if (e instanceof IOException) { - JOptionPane.showMessageDialog(frame, - e.getMessage(), - file.toString(), - JOptionPane.ERROR_MESSAGE); - } - } - - class flash_task implements Runnable, AltosFlashListener { - AltosFlashUI ui; - Thread t; - AltosProgrammer programmer; - - public void position(String in_s, int in_percent) { - final String s = in_s; - final int percent = in_percent; - Runnable r = new Runnable() { - public void run() { - try { - ui.actionPerformed(new ActionEvent(this, - percent, - s)); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - - public void run () { - try { - if (ui.is_pair_programmed()) - programmer = new AltosFlash(ui.file, link, this); - else - programmer = new AltosSelfFlash(ui.file, link, this); - - final AltosRomconfig current_config = programmer.romconfig(); - - final Semaphore await_rom_config = new Semaphore(0); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - ui.programmer = programmer; - ui.update_rom_config_info(current_config); - await_rom_config.release(); - } - }); - await_rom_config.acquire(); - - if (ui.rom_config != null) { - programmer.set_romconfig(ui.rom_config); - programmer.flash(); - } - } catch (InterruptedException ee) { - final Exception e = ee; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - ui.exception(e); - } - }); - } catch (IOException ee) { - final Exception e = ee; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - ui.exception(e); - } - }); - } finally { - if (programmer != null) - programmer.close(); - } - } - - public flash_task(AltosFlashUI in_ui) { - ui = in_ui; - t = new Thread(this); - t.start(); - } - } - - flash_task flasher; - - private boolean open_device() throws InterruptedException { - try { - link = new AltosSerial(device); - if (is_pair_programmed()) - return true; - - if (link == null) - throw new IOException(String.format("%s: open failed", device.toShortString())); - - while (!link.is_loader()) { - link.to_loader(); - - java.util.List<AltosDevice> devices = AltosUSBDevice.list(AltosLib.product_altusmetrum); - if (devices.size() == 1) - device = devices.get(0); - else { - device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum); - if (device == null) - return false; - } - link = new AltosSerial(device); - } - return true; - } catch (AltosSerialInUseException ee) { - exception(ee); - } catch (FileNotFoundException fe) { - exception(fe); - } catch (IOException ie) { - exception (ie); - } - return false; - } - - /* - * Execute the steps for flashing - * a device. Note that this returns immediately; - * this dialog is not modal - */ - void showDialog() { - if (!select_device()) - return; - if (!select_source_file()) - return; - try { - if (!open_device()) - return; - } catch (InterruptedException ie) { - return; - } - build_dialog(); - flash_task f = new flash_task(this); - } - - static void show(JFrame frame) { - AltosFlashUI ui = new AltosFlashUI(frame); - - ui.showDialog(); - } - - public AltosFlashUI(JFrame in_frame) { - super(in_frame, "Program Altusmetrum Device", false); - - frame = in_frame; - } -}
\ No newline at end of file diff --git a/altosui/AltosFlightDisplay.java b/altosui/AltosFlightDisplay.java deleted file mode 100644 index c1264259..00000000 --- a/altosui/AltosFlightDisplay.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import org.altusmetrum.altoslib_3.*; - -public interface AltosFlightDisplay { - void reset(); - - void show(AltosState state, AltosListenerState listener_state); - - void set_font(); -} diff --git a/altosui/AltosFlightInfoTableModel.java b/altosui/AltosFlightInfoTableModel.java deleted file mode 100644 index 249f6497..00000000 --- a/altosui/AltosFlightInfoTableModel.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.table.*; - -public class AltosFlightInfoTableModel extends AbstractTableModel { - final static private String[] columnNames = {"Field", "Value"}; - - int rows; - int cols; - private String[][] data; - - public int getColumnCount() { return cols; } - public int getRowCount() { return rows; } - public String getColumnName(int col) { return columnNames[col & 1]; } - - public Object getValueAt(int row, int col) { - if (row >= rows || col >= cols) - return ""; - return data[row][col]; - } - - int[] current_row; - - public void reset() { - for (int i = 0; i < cols / 2; i++) - current_row[i] = 0; - } - - public void clear() { - reset(); - for (int c = 0; c < cols; c++) - for (int r = 0; r < rows; r++) - data[r][c] = ""; - fireTableDataChanged(); - } - - public void addRow(int col, String name, String value) { - if (current_row[col] < rows) { - data[current_row[col]][col * 2] = name; - data[current_row[col]][col * 2 + 1] = value; - } - current_row[col]++; - } - - public void finish() { - for (int c = 0; c < cols / 2; c++) - while (current_row[c] < rows) - addRow(c, "", ""); - fireTableDataChanged(); - } - - public AltosFlightInfoTableModel (int in_rows, int in_cols) { - rows = in_rows; - cols = in_cols * 2; - data = new String[rows][cols]; - current_row = new int[in_cols]; - } -} diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java deleted file mode 100644 index 0be49c2f..00000000 --- a/altosui/AltosFlightStats.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.io.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosFlightStats { - double max_height; - double max_gps_height; - double max_speed; - double max_acceleration; - double[] state_speed = new double[Altos.ao_flight_invalid + 1]; - double[] state_accel = new double[Altos.ao_flight_invalid + 1]; - int[] state_count = new int[Altos.ao_flight_invalid + 1]; - double[] state_start = new double[Altos.ao_flight_invalid + 1]; - double[] state_end = new double[Altos.ao_flight_invalid + 1]; - int serial; - int flight; - int year, month, day; - int hour, minute, second; - double lat, lon; - double pad_lat, pad_lon; - boolean has_gps; - boolean has_other_adc; - boolean has_rssi; - boolean has_imu; - boolean has_mag; - boolean has_orient; - - double landed_time(AltosStateIterable states) { - AltosState state = null; - - for (AltosState s : states) { - state = s; - if (state.state == Altos.ao_flight_landed) - break; - } - - if (state == null) - return 0; - - double landed_height = state.height(); - - state = null; - - boolean above = true; - - double landed_time = -1000; - - for (AltosState s : states) { - state = s; - - if (state.height() > landed_height + 10) { - above = true; - } else { - if (above && state.height() < landed_height + 2) { - above = false; - landed_time = state.time; - } - } - } - if (landed_time == -1000) - landed_time = state.time; - return landed_time; - } - - double boost_time(AltosStateIterable states) { - double boost_time = AltosLib.MISSING; - AltosState state = null; - - for (AltosState s : states) { - state = s; - if (state.acceleration() < 1) - boost_time = state.time; - if (state.state >= AltosLib.ao_flight_boost && state.state <= AltosLib.ao_flight_landed) - break; - } - if (state == null) - return 0; - - if (boost_time == AltosLib.MISSING) - boost_time = state.time; - return boost_time; - } - - - public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException { - double boost_time = boost_time(states); - double end_time = 0; - double landed_time = landed_time(states); - - year = month = day = AltosLib.MISSING; - hour = minute = second = AltosLib.MISSING; - serial = flight = AltosLib.MISSING; - lat = lon = AltosLib.MISSING; - has_gps = false; - has_other_adc = false; - has_rssi = false; - has_imu = false; - has_mag = false; - has_orient = false; - for (AltosState state : states) { - if (serial == AltosLib.MISSING && state.serial != AltosLib.MISSING) - serial = state.serial; - if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING) - flight = state.flight; - if (state.battery_voltage != AltosLib.MISSING) - has_other_adc = true; - if (state.rssi != AltosLib.MISSING) - has_rssi = true; - end_time = state.time; - - int state_id = state.state; - if (state.time >= boost_time && state_id < Altos.ao_flight_boost) - state_id = Altos.ao_flight_boost; - if (state.time >= landed_time && state_id < Altos.ao_flight_landed) - state_id = Altos.ao_flight_landed; - if (state.gps != null && state.gps.locked) { - year = state.gps.year; - month = state.gps.month; - day = state.gps.day; - hour = state.gps.hour; - minute = state.gps.minute; - second = state.gps.second; - } - if (0 <= state_id && state_id < Altos.ao_flight_invalid) { - double acceleration = state.acceleration(); - double speed = state.speed(); - if (acceleration != AltosLib.MISSING && speed != AltosLib.MISSING) { - state_accel[state_id] += acceleration; - state_speed[state_id] += speed; - state_count[state_id]++; - } - if (state_start[state_id] == 0.0) - state_start[state_id] = state.time; - if (state_end[state_id] < state.time) - state_end[state_id] = state.time; - max_height = state.max_height(); - max_speed = state.max_speed(); - max_acceleration = state.max_acceleration(); - max_gps_height = state.max_gps_height(); - } - if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { - if (state_id <= Altos.ao_flight_pad) { - pad_lat = state.gps.lat; - pad_lon = state.gps.lon; - } - lat = state.gps.lat; - lon = state.gps.lon; - has_gps = true; - } - if (state.imu != null) - has_imu = true; - if (state.mag != null) - has_mag = true; - if (state.orient() != AltosLib.MISSING) - has_orient = true; - } - for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) { - if (state_count[s] > 0) { - state_speed[s] /= state_count[s]; - state_accel[s] /= state_count[s]; - } - if (state_start[s] == 0) - state_start[s] = end_time; - if (state_end[s] == 0) - state_end[s] = end_time; - } - } -} diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java deleted file mode 100644 index cb0c1562..00000000 --- a/altosui/AltosFlightStatsTable.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import javax.swing.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosFlightStatsTable extends JComponent { - GridBagLayout layout; - - class FlightStat { - JLabel label; - JTextField value; - - public FlightStat(GridBagLayout layout, int y, String label_text, String ... values) { - GridBagConstraints c = new GridBagConstraints(); - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.weighty = 1; - - label = new JLabel(label_text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 0; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - for (int j = 0; j < values.length; j++) { - value = new JTextField(values[j]); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = j+1; c.gridy = y; - c.anchor = GridBagConstraints.EAST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); - } - } - - } - - static String pos(double p, String pos, String neg) { - String h = pos; - if (p < 0) { - h = neg; - p = -p; - } - int deg = (int) Math.floor(p); - double min = (p - Math.floor(p)) * 60.0; - return String.format("%s %4d° %9.6f'", h, deg, min); - } - - public AltosFlightStatsTable(AltosFlightStats stats) { - layout = new GridBagLayout(); - - setLayout(layout); - int y = 0; - new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); - new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); - if (stats.year != AltosLib.MISSING && stats.hour != AltosLib.MISSING) - new FlightStat(layout, y++, "Date/Time", - String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), - String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); - else { - if (stats.year != AltosLib.MISSING) - new FlightStat(layout, y++, "Date", - String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); - if (stats.hour != AltosLib.MISSING) - new FlightStat(layout, y++, "Time", - String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); - } - new FlightStat(layout, y++, "Maximum height", - String.format("%5.0f m", stats.max_height), - String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); - if (stats.max_gps_height != AltosLib.MISSING) { - new FlightStat(layout, y++, "Maximum GPS height", - String.format("%5.0f m", stats.max_gps_height), - String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_gps_height))); - } - new FlightStat(layout, y++, "Maximum speed", - String.format("%5.0f m/s", stats.max_speed), - String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), - String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); - if (stats.max_acceleration != AltosLib.MISSING) { - new FlightStat(layout, y++, "Maximum boost acceleration", - String.format("%5.0f m/s²", stats.max_acceleration), - String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), - String.format("%5.0f G", AltosConvert.meters_to_g(stats.max_acceleration))); - new FlightStat(layout, y++, "Average boost acceleration", - String.format("%5.0f m/s²", stats.state_accel[Altos.ao_flight_boost]), - String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[Altos.ao_flight_boost])), - String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[Altos.ao_flight_boost]))); - } - new FlightStat(layout, y++, "Drogue descent rate", - String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_drogue]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]))); - new FlightStat(layout, y++, "Main descent rate", - String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_main]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]))); - new FlightStat(layout, y++, "Ascent time", - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], - AltosLib.state_name(Altos.ao_flight_boost)), - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_fast] - stats.state_start[AltosLib.ao_flight_fast], - AltosLib.state_name(Altos.ao_flight_fast)), - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_coast] - stats.state_start[AltosLib.ao_flight_coast], - AltosLib.state_name(Altos.ao_flight_coast))); - new FlightStat(layout, y++, "Descent time", - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_drogue] - stats.state_start[AltosLib.ao_flight_drogue], - AltosLib.state_name(Altos.ao_flight_drogue)), - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_main] - stats.state_start[AltosLib.ao_flight_main], - AltosLib.state_name(Altos.ao_flight_main))); - new FlightStat(layout, y++, "Flight time", - String.format("%6.1f s", stats.state_end[Altos.ao_flight_main] - - stats.state_start[Altos.ao_flight_boost])); - if (stats.has_gps) { - new FlightStat(layout, y++, "Pad location", - pos(stats.pad_lat,"N","S"), - pos(stats.pad_lon,"E","W")); - new FlightStat(layout, y++, "Last reported location", - pos(stats.lat,"N","S"), - pos(stats.lon,"E","W")); - } - } - -}
\ No newline at end of file diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index c6d75420..46c0b387 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -19,16 +19,27 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosFlightStatus extends JComponent implements AltosFlightDisplay { GridBagLayout layout; - public class FlightValue { + public abstract class FlightValue { JLabel label; JTextField value; - void show(AltosState state, AltosListenerState listener_state) {} + void show() { + label.setVisible(true); + value.setVisible(true); + } + + void hide() { + label.setVisible(false); + value.setVisible(false); + } + + abstract void show(AltosState state, AltosListenerState listener_state); void reset() { value.setText(""); @@ -39,6 +50,11 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay value.setFont(Altos.status_font); } + void setVisible(boolean visible) { + label.setVisible(visible); + value.setVisible(visible); + } + public FlightValue (GridBagLayout layout, int x, String text) { GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(5, 5, 5, 5); @@ -55,6 +71,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay add(label); value = new JTextField(""); + value.setEditable(false); value.setFont(Altos.status_font); value.setHorizontalAlignment(SwingConstants.CENTER); c.gridx = x; c.gridy = 1; @@ -64,9 +81,33 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay } class Call extends FlightValue { + + String last_call = ""; + + boolean same_call(String call) { + if (last_call == null) + return call == null; + else + return last_call.equals(call); + } + void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.callsign); + if (!same_call(state.callsign)) { + show(); + value.setText(state.callsign); + if (state.callsign == null) + setVisible(false); + else + setVisible(true); + last_call = state.callsign; + } } + + public void reset() { + super.reset(); + last_call = ""; + } + public Call (GridBagLayout layout, int x) { super (layout, x, "Callsign"); } @@ -75,12 +116,24 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay Call call; class Serial extends FlightValue { + + int last_serial = -1; void show(AltosState state, AltosListenerState listener_state) { - if (state.serial == AltosLib.MISSING) - value.setText("none"); - else - value.setText(String.format("%d", state.serial)); + if (state.serial != last_serial) { + show(); + if (state.serial == AltosLib.MISSING) + value.setText("none"); + else + value.setText(String.format("%d", state.serial)); + last_serial = state.serial; + } } + + public void reset() { + super.reset(); + last_serial = -1; + } + public Serial (GridBagLayout layout, int x) { super (layout, x, "Serial"); } @@ -89,12 +142,25 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay Serial serial; class Flight extends FlightValue { + + int last_flight = -1; + void show(AltosState state, AltosListenerState listener_state) { - if (state.flight == AltosLib.MISSING) - value.setText("none"); - else - value.setText(String.format("%d", state.flight)); + if (state.flight != last_flight) { + show(); + if (state.flight == AltosLib.MISSING) + value.setText("none"); + else + value.setText(String.format("%d", state.flight)); + last_flight = state.flight; + } } + + public void reset() { + super.reset(); + last_flight = -1; + } + public Flight (GridBagLayout layout, int x) { super (layout, x, "Flight"); } @@ -103,9 +169,26 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay Flight flight; class FlightState extends FlightValue { + + int last_state = -1; + void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.state_name()); + if (state.state != last_state) { + if (state.state == AltosLib.ao_flight_stateless) + hide(); + else { + show(); + value.setText(state.state_name()); + } + last_state = state.state; + } } + + public void reset() { + super.reset(); + last_state = -1; + } + public FlightState (GridBagLayout layout, int x) { super (layout, x, "State"); } @@ -114,9 +197,26 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay FlightState flight_state; class RSSI extends FlightValue { + + int last_rssi = 10000; + void show(AltosState state, AltosListenerState listener_state) { - value.setText(String.format("%d", state.rssi())); + if (state.rssi() != last_rssi) { + show(); + value.setText(String.format("%d", state.rssi())); + if (state.rssi == AltosLib.MISSING) + setVisible(false); + else + setVisible(true); + last_rssi = state.rssi(); + } } + + public void reset() { + super.reset(); + last_rssi = 10000; + } + public RSSI (GridBagLayout layout, int x) { super (layout, x, "RSSI"); } @@ -125,10 +225,22 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay RSSI rssi; class LastPacket extends FlightValue { + + long last_secs = -1; + void show(AltosState state, AltosListenerState listener_state) { long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000; - value.setText(String.format("%d", secs)); + if (secs != last_secs) { + value.setText(String.format("%d", secs)); + last_secs = secs; + } + } + + public void reset() { + super.reset(); + last_secs = -1; } + public LastPacket(GridBagLayout layout, int x) { super (layout, x, "Age"); } @@ -145,7 +257,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay last_packet.reset(); } - public void set_font () { + public void font_size_changed(int font_size) { call.set_font(); serial.set_font(); flight.set_font(); @@ -154,6 +266,9 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay last_packet.set_font(); } + public void units_changed(boolean imperial_units) { + } + public void show (AltosState state, AltosListenerState listener_state) { call.show(state, listener_state); serial.show(state, listener_state); @@ -168,6 +283,8 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay return d.height; } + public String getName() { return "Flight Status"; } + public AltosFlightStatus() { layout = new GridBagLayout(); diff --git a/altosui/AltosFlightStatusTableModel.java b/altosui/AltosFlightStatusTableModel.java index e372d401..b33f40a4 100644 --- a/altosui/AltosFlightStatusTableModel.java +++ b/altosui/AltosFlightStatusTableModel.java @@ -27,7 +27,7 @@ import java.util.*; import java.text.*; import java.util.prefs.*; import java.util.concurrent.LinkedBlockingQueue; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; public class AltosFlightStatusTableModel extends AbstractTableModel { private String[] columnNames = { diff --git a/altosui/AltosFlightStatusUpdate.java b/altosui/AltosFlightStatusUpdate.java index 93399a13..0daec04e 100644 --- a/altosui/AltosFlightStatusUpdate.java +++ b/altosui/AltosFlightStatusUpdate.java @@ -18,7 +18,7 @@ package altosui; import java.awt.event.*; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; public class AltosFlightStatusUpdate implements ActionListener { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index e8cf7f08..43deb631 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -20,26 +20,31 @@ package altosui; import java.awt.*; import java.awt.event.*; import javax.swing.*; +import java.util.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; -public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener { +public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay { AltosVoice voice; AltosFlightReader reader; AltosDisplayThread thread; + LinkedList<AltosFlightDisplay> displays; + JTabbedPane pane; AltosPad pad; + AltosIgnitor ignitor; AltosAscent ascent; AltosDescent descent; AltosLanded landed; AltosCompanionInfo companion; - AltosSiteMap sitemap; + AltosUIMap sitemap; boolean has_map; boolean has_companion; boolean has_state; + boolean has_ignitor; private AltosFlightStatus flightStatus; private AltosInfoTable flightInfo; @@ -54,6 +59,8 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A return ascent; if (state.state <= Altos.ao_flight_main) return descent; + if (state.state == AltosLib.ao_flight_stateless) + return descent; return landed; } @@ -72,29 +79,19 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A } public void reset() { - pad.reset(); - ascent.reset(); - descent.reset(); - landed.reset(); - flightInfo.clear(); - sitemap.reset(); - } - - public void set_font() { - pad.set_font(); - ascent.set_font(); - descent.set_font(); - landed.set_font(); - flightStatus.set_font(); - flightInfo.set_font(); - sitemap.set_font(); - companion.set_font(); + for (AltosFlightDisplay d : displays) + d.reset(); } public void font_size_changed(int font_size) { - set_font(); + for (AltosFlightDisplay d : displays) + d.font_size_changed(font_size); } + public void units_changed(boolean imperial_units) { + for (AltosFlightDisplay d : displays) + d.units_changed(imperial_units); + } AltosFlightStatusUpdate status_update; @@ -104,8 +101,6 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A if (state == null) state = new AltosState(); - pad.show(state, listener_state); - if (state.state != Altos.ao_flight_startup) { if (!has_state) { pane.setTitleAt(0, "Launch Pad"); @@ -116,10 +111,6 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A } } - ascent.show(state, listener_state); - descent.show(state, listener_state); - landed.show(state, listener_state); - JComponent tab = which_tab(state); if (tab != cur_tab) { if (cur_tab == pane.getSelectedComponent()) { @@ -127,33 +118,51 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A } cur_tab = tab; } - flightStatus.show(state, listener_state); - flightInfo.show(state, listener_state); + + if (ignitor.should_show(state)) { + if (!has_ignitor) { + pane.add("Ignitor", ignitor); + has_ignitor = true; + } + } else { + if (has_ignitor) { + pane.remove(ignitor); + has_ignitor = false; + } + } if (state.companion != null) { if (!has_companion) { pane.add("Companion", companion); has_companion= true; } - companion.show(state, listener_state); } else { if (has_companion) { pane.remove(companion); has_companion = false; } } + if (state.gps != null && state.gps.connected) { if (!has_map) { pane.add("Site Map", sitemap); has_map = true; } - sitemap.show(state, listener_state); } else { if (has_map) { pane.remove(sitemap); has_map = false; } } + + for (AltosFlightDisplay d : displays) { + try { + d.show(state, listener_state); + } catch (Exception e) { + System.out.printf("Exception showing %s\n", d.getName()); + e.printStackTrace(); + } + } } public void set_exit_on_close() { @@ -162,7 +171,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A Container bag; AltosFreqList frequencies; - JComboBox telemetries; + JComboBox<String> telemetries; JLabel telemetry; ActionListener show_timer; @@ -170,6 +179,8 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A public AltosFlightUI(AltosVoice in_voice, AltosFlightReader in_reader, final int serial) { AltosUIPreferences.set_component(this); + displays = new LinkedList<AltosFlightDisplay>(); + voice = in_voice; reader = in_reader; @@ -208,8 +219,8 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A // Telemetry format menu if (reader.supports_telemetry(Altos.ao_telemetry_standard)) { - telemetries = new JComboBox(); - for (int i = 1; i <= Altos.ao_telemetry_max; i++) + telemetries = new JComboBox<String>(); + for (int i = 1; i <= Altos.ao_telemetry_max; i++) telemetries.addItem(Altos.telemetry_name(i)); int telemetry = AltosPreferences.telemetry(serial); if (telemetry <= Altos.ao_telemetry_off || @@ -258,6 +269,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A /* Flight status is always visible */ flightStatus = new AltosFlightStatus(); + displays.add(flightStatus); c.gridx = 0; c.gridy = 1; c.fill = GridBagConstraints.HORIZONTAL; @@ -272,20 +284,29 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A pane = new JTabbedPane(); pad = new AltosPad(); + displays.add(pad); pane.add("Status", pad); + ignitor = new AltosIgnitor(); + displays.add(ignitor); ascent = new AltosAscent(); + displays.add(ascent); descent = new AltosDescent(); + displays.add(descent); landed = new AltosLanded(reader); + displays.add(landed); flightInfo = new AltosInfoTable(); + displays.add(flightInfo); pane.add("Table", new JScrollPane(flightInfo)); companion = new AltosCompanionInfo(); + displays.add(companion); has_companion = false; has_state = false; - sitemap = new AltosSiteMap(); + sitemap = new AltosUIMap(); + displays.add(sitemap); has_map = false; /* Make the tabbed pane use the rest of the window space */ @@ -300,6 +321,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); AltosUIPreferences.register_font_listener(this); + AltosPreferences.register_units_listener(this); addWindowListener(new WindowAdapter() { @Override @@ -308,6 +330,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A setVisible(false); dispose(); AltosUIPreferences.unregister_font_listener(AltosFlightUI.this); + AltosPreferences.unregister_units_listener(AltosFlightUI.this); if (exit_on_close) System.exit(0); } diff --git a/altosui/AltosFreqList.java b/altosui/AltosFreqList.java deleted file mode 100644 index 039b5f22..00000000 --- a/altosui/AltosFreqList.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosFreqList extends JComboBox { - - String product; - int serial; - int calibrate; - - public void set_frequency(double new_frequency) { - int i; - - if (new_frequency < 0) { - setVisible(false); - return; - } - - for (i = 0; i < getItemCount(); i++) { - AltosFrequency f = (AltosFrequency) getItemAt(i); - - if (f.close(new_frequency)) { - setSelectedIndex(i); - return; - } - } - for (i = 0; i < getItemCount(); i++) { - AltosFrequency f = (AltosFrequency) getItemAt(i); - - if (new_frequency < f.frequency) - break; - } - String description = String.format("%s serial %d", product, serial); - AltosFrequency frequency = new AltosFrequency(new_frequency, description); - AltosUIPreferences.add_common_frequency(frequency); - insertItemAt(frequency, i); - setMaximumRowCount(getItemCount()); - } - - public void set_product(String new_product) { - product = new_product; - } - - public void set_serial(int new_serial) { - serial = new_serial; - } - - public double frequency() { - AltosFrequency f = (AltosFrequency) getSelectedItem(); - if (f != null) - return f.frequency; - return 434.550; - } - - public AltosFreqList () { - super(AltosUIPreferences.common_frequencies()); - setMaximumRowCount(getItemCount()); - setEditable(false); - product = "Unknown"; - serial = 0; - } - - public AltosFreqList(double in_frequency) { - this(); - set_frequency(in_frequency); - } -} diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java deleted file mode 100644 index 42334e31..00000000 --- a/altosui/AltosGraph.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright © 2013 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.io.*; -import java.util.ArrayList; - -import java.awt.*; -import javax.swing.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -import org.jfree.ui.*; -import org.jfree.chart.*; -import org.jfree.chart.plot.*; -import org.jfree.chart.axis.*; -import org.jfree.chart.renderer.*; -import org.jfree.chart.renderer.xy.*; -import org.jfree.chart.labels.*; -import org.jfree.data.xy.*; -import org.jfree.data.*; - -class AltosVoltage extends AltosUnits { - - public double value(double v, boolean imperial_units) { - return v; - } - - public double inverse(double v, boolean imperial_units) { - return v; - } - - public String show_units(boolean imperial_units) { - return "V"; - } - - public String say_units(boolean imperial_units) { - return "volts"; - } - - public int show_fraction(int width, boolean imperial_units) { - return width / 2; - } -} - -class AltosNsat extends AltosUnits { - - public double value(double v, boolean imperial_units) { - return v; - } - - public double inverse(double v, boolean imperial_units) { - return v; - } - - public String show_units(boolean imperial_units) { - return "Sats"; - } - - public String say_units(boolean imperial_units) { - return "Satellites"; - } - - public int show_fraction(int width, boolean imperial_units) { - return 0; - } -} - -class AltosPressure extends AltosUnits { - - public double value(double p, boolean imperial_units) { - return p; - } - - public double inverse(double p, boolean imperial_units) { - return p; - } - - public String show_units(boolean imperial_units) { - return "Pa"; - } - - public String say_units(boolean imperial_units) { - return "pascals"; - } - - public int show_fraction(int width, boolean imperial_units) { - return 0; - } -} - -class AltosDbm extends AltosUnits { - - public double value(double d, boolean imperial_units) { - return d; - } - - public double inverse(double d, boolean imperial_units) { - return d; - } - - public String show_units(boolean imperial_units) { - return "dBm"; - } - - public String say_units(boolean imperial_units) { - return "D B M"; - } - - public int show_fraction(int width, boolean imperial_units) { - return 0; - } -} - -class AltosGyroUnits extends AltosUnits { - - public double value(double p, boolean imperial_units) { - return p; - } - - public double inverse(double p, boolean imperial_units) { - return p; - } - - public String show_units(boolean imperial_units) { - return "°/sec"; - } - - public String say_units(boolean imperial_units) { - return "degrees per second"; - } - - public int show_fraction(int width, boolean imperial_units) { - return 1; - } -} - -class AltosMagUnits extends AltosUnits { - - public double value(double p, boolean imperial_units) { - return p; - } - - public double inverse(double p, boolean imperial_units) { - return p; - } - - public String show_units(boolean imperial_units) { - return "Ga"; - } - - public String say_units(boolean imperial_units) { - return "gauss"; - } - - public int show_fraction(int width, boolean imperial_units) { - return 2; - } -} - -public class AltosGraph extends AltosUIGraph { - - static final private Color height_color = new Color(194,31,31); - static final private Color gps_height_color = new Color(150,31,31); - static final private Color pressure_color = new Color (225,31,31); - static final private Color range_color = new Color(100, 31, 31); - static final private Color distance_color = new Color(100, 31, 194); - static final private Color speed_color = new Color(31,194,31); - static final private Color accel_color = new Color(31,31,194); - static final private Color voltage_color = new Color(194, 194, 31); - static final private Color battery_voltage_color = new Color(194, 194, 31); - static final private Color drogue_voltage_color = new Color(150, 150, 31); - static final private Color main_voltage_color = new Color(100, 100, 31); - static final private Color gps_nsat_color = new Color (194, 31, 194); - static final private Color gps_nsat_solution_color = new Color (194, 31, 194); - static final private Color gps_nsat_view_color = new Color (150, 31, 150); - static final private Color temperature_color = new Color (31, 194, 194); - static final private Color dbm_color = new Color(31, 100, 100); - static final private Color state_color = new Color(0,0,0); - static final private Color accel_x_color = new Color(255, 0, 0); - static final private Color accel_y_color = new Color(0, 255, 0); - static final private Color accel_z_color = new Color(0, 0, 255); - static final private Color gyro_x_color = new Color(192, 0, 0); - static final private Color gyro_y_color = new Color(0, 192, 0); - static final private Color gyro_z_color = new Color(0, 0, 192); - static final private Color mag_x_color = new Color(128, 0, 0); - static final private Color mag_y_color = new Color(0, 128, 0); - static final private Color mag_z_color = new Color(0, 0, 128); - static final private Color orient_color = new Color(31, 31, 31); - - static AltosVoltage voltage_units = new AltosVoltage(); - static AltosPressure pressure_units = new AltosPressure(); - static AltosNsat nsat_units = new AltosNsat(); - static AltosDbm dbm_units = new AltosDbm(); - static AltosGyroUnits gyro_units = new AltosGyroUnits(); - static AltosOrient orient_units = new AltosOrient(); - static AltosMagUnits mag_units = new AltosMagUnits(); - - AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; - AltosUIAxis distance_axis, pressure_axis; - AltosUIAxis gyro_axis, orient_axis, mag_axis; - - public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) { - super(enable); - - height_axis = newAxis("Height", AltosConvert.height, height_color); - pressure_axis = newAxis("Pressure", pressure_units, pressure_color, 0); - speed_axis = newAxis("Speed", AltosConvert.speed, speed_color); - accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color); - voltage_axis = newAxis("Voltage", voltage_units, voltage_color); - temperature_axis = newAxis("Temperature", AltosConvert.temperature, temperature_color, 0); - nsat_axis = newAxis("Satellites", nsat_units, gps_nsat_color, - AltosUIAxis.axis_include_zero | AltosUIAxis.axis_integer); - dbm_axis = newAxis("Signal Strength", dbm_units, dbm_color, 0); - distance_axis = newAxis("Distance", AltosConvert.distance, range_color); - - gyro_axis = newAxis("Rotation Rate", gyro_units, gyro_z_color, 0); - orient_axis = newAxis("Tilt Angle", orient_units, orient_color, 0); - mag_axis = newAxis("Magnetic Field", mag_units, mag_x_color, 0); - - addMarker("State", AltosGraphDataPoint.data_state, state_color); - addSeries("Height", - AltosGraphDataPoint.data_height, - AltosConvert.height, - height_color, - true, - height_axis); - addSeries("Pressure", - AltosGraphDataPoint.data_pressure, - pressure_units, - pressure_color, - false, - pressure_axis); - addSeries("Speed", - AltosGraphDataPoint.data_speed, - AltosConvert.speed, - speed_color, - true, - speed_axis); - addSeries("Acceleration", - AltosGraphDataPoint.data_accel, - AltosConvert.accel, - accel_color, - true, - accel_axis); - if (stats.has_gps) { - addSeries("Range", - AltosGraphDataPoint.data_range, - AltosConvert.distance, - range_color, - false, - distance_axis); - addSeries("Distance", - AltosGraphDataPoint.data_distance, - AltosConvert.distance, - distance_color, - false, - distance_axis); - addSeries("GPS Height", - AltosGraphDataPoint.data_gps_height, - AltosConvert.height, - gps_height_color, - false, - height_axis); - addSeries("GPS Satellites in Solution", - AltosGraphDataPoint.data_gps_nsat_solution, - nsat_units, - gps_nsat_solution_color, - false, - nsat_axis); - addSeries("GPS Satellites in View", - AltosGraphDataPoint.data_gps_nsat_view, - nsat_units, - gps_nsat_view_color, - false, - nsat_axis); - } - if (stats.has_rssi) - addSeries("Received Signal Strength", - AltosGraphDataPoint.data_rssi, - dbm_units, - dbm_color, - false, - dbm_axis); - if (stats.has_other_adc) { - addSeries("Temperature", - AltosGraphDataPoint.data_temperature, - AltosConvert.temperature, - temperature_color, - false, - temperature_axis); - addSeries("Battery Voltage", - AltosGraphDataPoint.data_battery_voltage, - voltage_units, - battery_voltage_color, - false, - voltage_axis); - addSeries("Drogue Voltage", - AltosGraphDataPoint.data_drogue_voltage, - voltage_units, - drogue_voltage_color, - false, - voltage_axis); - addSeries("Main Voltage", - AltosGraphDataPoint.data_main_voltage, - voltage_units, - main_voltage_color, - false, - voltage_axis); - } - - if (stats.has_imu) { - addSeries("Acceleration X", - AltosGraphDataPoint.data_accel_x, - AltosConvert.accel, - accel_x_color, - false, - accel_axis); - addSeries("Acceleration Y", - AltosGraphDataPoint.data_accel_y, - AltosConvert.accel, - accel_y_color, - false, - accel_axis); - addSeries("Acceleration Z", - AltosGraphDataPoint.data_accel_z, - AltosConvert.accel, - accel_z_color, - false, - accel_axis); - addSeries("Rotation Rate X", - AltosGraphDataPoint.data_gyro_x, - gyro_units, - gyro_x_color, - false, - gyro_axis); - addSeries("Rotation Rate Y", - AltosGraphDataPoint.data_gyro_y, - gyro_units, - gyro_y_color, - false, - gyro_axis); - addSeries("Rotation Rate Z", - AltosGraphDataPoint.data_gyro_z, - gyro_units, - gyro_z_color, - false, - gyro_axis); - } - if (stats.has_mag) { - addSeries("Magnetometer X", - AltosGraphDataPoint.data_mag_x, - mag_units, - mag_x_color, - false, - mag_axis); - addSeries("Magnetometer Y", - AltosGraphDataPoint.data_mag_y, - mag_units, - mag_y_color, - false, - mag_axis); - addSeries("Magnetometer Z", - AltosGraphDataPoint.data_mag_z, - mag_units, - mag_z_color, - false, - mag_axis); - } - if (stats.has_orient) - addSeries("Tilt Angle", - AltosGraphDataPoint.data_orient, - orient_units, - orient_color, - false, - orient_axis); - - setDataSet(dataSet); - } -}
\ No newline at end of file diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java deleted file mode 100644 index 61a1a227..00000000 --- a/altosui/AltosGraphDataPoint.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright © 2013 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import org.altusmetrum.altosuilib_1.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosGraphDataPoint implements AltosUIDataPoint { - - AltosState state; - - public static final int data_height = 0; - public static final int data_speed = 1; - public static final int data_accel = 2; - public static final int data_temp = 3; - public static final int data_battery_voltage = 4; - public static final int data_drogue_voltage = 5; - public static final int data_main_voltage = 6; - public static final int data_rssi = 7; - public static final int data_state = 8; - public static final int data_gps_height = 9; - public static final int data_gps_nsat_solution = 10; - public static final int data_gps_nsat_view = 11; - public static final int data_temperature = 12; - public static final int data_range = 13; - public static final int data_distance = 14; - public static final int data_pressure = 15; - public static final int data_accel_x = 16; - public static final int data_accel_y = 17; - public static final int data_accel_z = 18; - public static final int data_gyro_x = 19; - public static final int data_gyro_y = 20; - public static final int data_gyro_z = 21; - public static final int data_mag_x = 22; - public static final int data_mag_y = 23; - public static final int data_mag_z = 24; - public static final int data_orient = 25; - - public double x() throws AltosUIDataMissing { - double time = state.time_since_boost(); - if (time < -2) - throw new AltosUIDataMissing(-1); - return time; - } - - public double y(int index) throws AltosUIDataMissing { - double y = AltosLib.MISSING; - switch (index) { - case data_height: - y = state.height(); - break; - case data_speed: - y = state.speed(); - break; - case data_accel: - y = state.acceleration(); - break; - case data_temp: - y = state.temperature; - break; - case data_battery_voltage: - y = state.battery_voltage; - break; - case data_drogue_voltage: - y = state.apogee_voltage; - break; - case data_main_voltage: - y = state.main_voltage; - break; - case data_rssi: - y = state.rssi; - break; - case data_gps_height: - y = state.gps_height; - break; - case data_gps_nsat_solution: - if (state.gps != null) - y = state.gps.nsat; - break; - case data_gps_nsat_view: - if (state.gps != null && state.gps.cc_gps_sat != null) - y = state.gps.cc_gps_sat.length; - break; - case data_temperature: - y = state.temperature; - break; - case data_range: - y = state.range; - break; - case data_distance: - if (state.from_pad != null) - y = state.from_pad.distance; - break; - case data_pressure: - y = state.pressure(); - break; - - case data_accel_x: - case data_accel_y: - case data_accel_z: - case data_gyro_x: - case data_gyro_y: - case data_gyro_z: - AltosIMU imu = state.imu; - if (imu == null) - break; - switch (index) { - case data_accel_x: - y = imu.accel_x; - break; - case data_accel_y: - y = imu.accel_y; - break; - case data_accel_z: - y = imu.accel_z; - break; - case data_gyro_x: - y = imu.gyro_x; - break; - case data_gyro_y: - y = imu.gyro_y; - break; - case data_gyro_z: - y = imu.gyro_z; - break; - } - break; - case data_mag_x: - case data_mag_y: - case data_mag_z: - AltosMag mag = state.mag; - if (mag == null) - break; - switch (index) { - case data_mag_x: - y = mag.x; - break; - case data_mag_y: - y = mag.y; - break; - case data_mag_z: - y = mag.z; - break; - } - break; - case data_orient: - y = state.orient(); - break; - } - if (y == AltosLib.MISSING) - throw new AltosUIDataMissing(index); - return y; - } - - public int id(int index) { - if (index == data_state) { - int s = state.state; - if (s < Altos.ao_flight_boost || s > Altos.ao_flight_landed) - return -1; - return s; - } - return 0; - } - - public String id_name(int index) { - if (index == data_state) - return state.state_name(); - return ""; - } - - public AltosGraphDataPoint (AltosState state) { - this.state = state; - } -}
\ No newline at end of file diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java deleted file mode 100644 index d2773a3f..00000000 --- a/altosui/AltosGraphDataSet.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright © 2013 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.lang.*; -import java.io.*; -import java.util.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -class AltosGraphIterator implements Iterator<AltosUIDataPoint> { - AltosGraphDataSet dataSet; - Iterator<AltosState> iterator; - - public boolean hasNext() { - return iterator.hasNext(); - } - - public AltosUIDataPoint next() { - AltosState state = iterator.next(); - - if (state.flight != AltosLib.MISSING) { - if (dataSet.callsign == null && state.callsign != null) - dataSet.callsign = state.callsign; - - if (dataSet.serial == 0 && state.serial != 0) - dataSet.serial = state.serial; - - if (dataSet.flight == 0 && state.flight != 0) - dataSet.flight = state.flight; - } - - return new AltosGraphDataPoint(state); - } - - public AltosGraphIterator (Iterator<AltosState> iterator, AltosGraphDataSet dataSet) { - this.iterator = iterator; - this.dataSet = dataSet; - } - - public void remove() { - } -} - -class AltosGraphIterable implements Iterable<AltosUIDataPoint> { - AltosGraphDataSet dataSet; - - public Iterator<AltosUIDataPoint> iterator() { - return new AltosGraphIterator(dataSet.states.iterator(), dataSet); - } - - public AltosGraphIterable(AltosGraphDataSet dataSet) { - this.dataSet = dataSet; - } -} - -public class AltosGraphDataSet implements AltosUIDataSet { - String callsign; - int serial; - int flight; - AltosStateIterable states; - - public String name() { - if (callsign != null) - return String.format("%s - %d/%d", callsign, serial, flight); - else - return String.format("%d/%d", serial, flight); - } - - public Iterable<AltosUIDataPoint> dataPoints() { - return new AltosGraphIterable(this); - } - - public AltosGraphDataSet (AltosStateIterable states) { - this.states = states; - this.callsign = null; - this.serial = 0; - this.flight = 0; - } -} diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 40d2f7f4..07fe9317 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -1,6 +1,19 @@ - -// Copyright (c) 2010 Anthony Towns -// GPL v2 or later +/* + * Copyright © 2010 Anthony Towns + * + * 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 or any later version of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ package altosui; @@ -8,20 +21,21 @@ import java.io.*; import java.util.ArrayList; import java.awt.*; +import java.awt.event.*; import javax.swing.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.ui.RefineryUtilities; -public class AltosGraphUI extends AltosUIFrame +public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener { JTabbedPane pane; AltosGraph graph; AltosUIEnable enable; - AltosSiteMap map; + AltosUIMap map; AltosState state; AltosGraphDataSet graphDataSet; AltosFlightStats stats; @@ -33,13 +47,22 @@ public class AltosGraphUI extends AltosUIFrame for (AltosState state : states) { if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { if (map == null) - map = new AltosSiteMap(); + map = new AltosUIMap(); map.show(state, null); has_gps = true; } } } + public void font_size_changed(int font_size) { + map.font_size_changed(font_size); + statsTable.font_size_changed(font_size); + } + + public void units_changed(boolean imperial_units) { + map.units_changed(imperial_units); + } + AltosGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException { super(file.getName()); state = null; @@ -66,9 +89,20 @@ public class AltosGraphUI extends AltosUIFrame setContentPane (pane); + AltosUIPreferences.register_font_listener(this); + AltosPreferences.register_units_listener(this); + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + AltosUIPreferences.unregister_font_listener(AltosGraphUI.this); + AltosPreferences.unregister_units_listener(AltosGraphUI.this); + } + }); pack(); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); setVisible(true); if (state != null && has_gps) map.centre(state); diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index 7ca935b6..042111ec 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -24,10 +24,10 @@ import javax.swing.event.*; import java.io.*; import java.util.concurrent.*; import java.util.Arrays; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; -public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener, DocumentListener { +public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosIdleMonitorListener, DocumentListener { AltosDevice device; JTabbedPane pane; AltosPad pad; @@ -56,13 +56,14 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl flightInfo.clear(); } - public void set_font() { - pad.set_font(); - flightInfo.set_font(); + public void font_size_changed(int font_size) { + pad.font_size_changed(font_size); + flightInfo.font_size_changed(font_size); } - public void font_size_changed(int font_size) { - set_font(); + public void units_changed(boolean imperial_units) { + pad.units_changed(imperial_units); + flightInfo.units_changed(imperial_units); } AltosFlightStatusUpdate status_update; @@ -234,7 +235,9 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl try { disconnect(); } catch (Exception ex) { - System.out.println(Arrays.toString(ex.getStackTrace())); + System.out.printf("Exception %s\n", ex.toString()); + for (StackTraceElement el : ex.getStackTrace()) + System.out.printf("%s\n", el.toString()); } setVisible(false); dispose(); diff --git a/altosui/AltosIgniteUI.java b/altosui/AltosIgniteUI.java index 2e69249f..c251bbe2 100644 --- a/altosui/AltosIgniteUI.java +++ b/altosui/AltosIgniteUI.java @@ -24,8 +24,8 @@ import java.io.*; import java.text.*; import java.util.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosIgniteUI extends AltosUIDialog @@ -486,7 +486,7 @@ public class AltosIgniteUI pane.add(close, c); close.addActionListener(this); close.setActionCommand("close"); - + pack(); setLocationRelativeTo(owner); diff --git a/altosui/AltosIgnitor.java b/altosui/AltosIgnitor.java new file mode 100644 index 00000000..990a87e6 --- /dev/null +++ b/altosui/AltosIgnitor.java @@ -0,0 +1,91 @@ +/* + * Copyright © 2014 Keith Packard <keithp@keithp.com> + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; + +public class AltosIgnitor extends AltosUIFlightTab { + + public class Ignitor extends AltosUIUnitsIndicator { + int ignitor; + + public double value(AltosState state, int i) { + if (state.ignitor_voltage == null || + state.ignitor_voltage.length < ignitor) + return AltosLib.MISSING; + return state.ignitor_voltage[ignitor]; + } + + public double good() { return AltosLib.ao_igniter_good; } + + public Ignitor (AltosUIFlightTab container, int y) { + super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.ignitor_name(y)), 1, true, 1); + ignitor = y; + } + } + + Ignitor[] ignitors; + + public void show(AltosState state, AltosListenerState listener_state) { + if (isShowing()) + make_ignitors(state); + super.show(state, listener_state); + } + + public boolean should_show(AltosState state) { + if (state == null) + return false; + if (state.ignitor_voltage == null) + return false; + return state.ignitor_voltage.length > 0; + } + + void make_ignitors(AltosState state) { + int n = (state == null || state.ignitor_voltage == null) ? 0 : state.ignitor_voltage.length; + int old_n = ignitors == null ? 0 : ignitors.length; + + if (n != old_n) { + + if (ignitors != null) { + for (int i = 0; i < ignitors.length; i++) { + remove(ignitors[i]); + ignitors[i].remove(this); + ignitors = null; + } + } + + if (n > 0) { + setVisible(true); + ignitors = new Ignitor[n]; + for (int i = 0; i < n; i++) { + ignitors[i] = new Ignitor(this, i); + add(ignitors[i]); + } + } else + setVisible(false); + } + } + + public String getName() { + return "Ignitors"; + } +} diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java deleted file mode 100644 index 158b61f0..00000000 --- a/altosui/AltosInfoTable.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import javax.swing.*; -import javax.swing.table.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosInfoTable extends JTable { - private AltosFlightInfoTableModel model; - - static final int info_columns = 3; - static final int info_rows = 17; - - int desired_row_height() { - FontMetrics infoValueMetrics = getFontMetrics(Altos.table_value_font); - return (infoValueMetrics.getHeight() + infoValueMetrics.getLeading()) * 18 / 10; - } - - int text_width(String t) { - FontMetrics infoValueMetrics = getFontMetrics(Altos.table_value_font); - - return infoValueMetrics.stringWidth(t); - } - - void set_layout() { - setRowHeight(desired_row_height()); - for (int i = 0; i < info_columns * 2; i++) - { - TableColumn column = getColumnModel().getColumn(i); - - if ((i & 1) == 0) - column.setPreferredWidth(text_width(" Satellites Visible")); - else - column.setPreferredWidth(text_width("W 179°59.99999' ")); - } - } - - public AltosInfoTable() { - super(new AltosFlightInfoTableModel(info_rows, info_columns)); - model = (AltosFlightInfoTableModel) getModel(); - setFont(Altos.table_value_font); - setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS); - setShowGrid(true); - set_layout(); - doLayout(); - } - - public void set_font() { - setFont(Altos.table_value_font); - set_layout(); - doLayout(); - } - - public Dimension getPreferredScrollableViewportSize() { - return getPreferredSize(); - } - - void info_reset() { - model.reset(); - } - - void info_add_row(int col, String name, String value) { - model.addRow(col, name, value); - } - - void info_add_row(int col, String name, String format, Object... parameters) { - info_add_row (col, name, String.format(format, parameters)); - } - - void info_add_deg(int col, String name, double v, int pos, int neg) { - int c = pos; - if (v < 0) { - c = neg; - v = -v; - } - double deg = Math.floor(v); - double min = (v - deg) * 60; - - info_add_row(col, name, String.format("%c %3.0f°%08.5f'", c, deg, min)); - } - - void info_finish() { - model.finish(); - } - - public void clear() { - model.clear(); - } - - public void show(AltosState state, AltosListenerState listener_state) { - info_reset(); - if (state != null) { - if (state.device_type != AltosLib.MISSING) - info_add_row(0, "Device", "%s", AltosLib.product_name(state.device_type)); - if (state.altitude() != AltosLib.MISSING) - info_add_row(0, "Altitude", "%6.0f m", state.altitude()); - if (state.ground_altitude() != AltosLib.MISSING) - info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude()); - if (state.height() != AltosLib.MISSING) - info_add_row(0, "Height", "%6.0f m", state.height()); - if (state.max_height() != AltosLib.MISSING) - info_add_row(0, "Max height", "%6.0f m", state.max_height()); - if (state.acceleration() != AltosLib.MISSING) - info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration()); - if (state.max_acceleration() != AltosLib.MISSING) - info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration()); - if (state.speed() != AltosLib.MISSING) - info_add_row(0, "Speed", "%8.1f m/s", state.speed()); - if (state.max_speed() != AltosLib.MISSING) - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed()); - if (state.orient() != AltosLib.MISSING) - info_add_row(0, "Tilt", "%4.0f °", state.orient()); - if (state.max_orient() != AltosLib.MISSING) - info_add_row(0, "Max Tilt", "%4.0f °", state.max_orient()); - if (state.temperature != AltosLib.MISSING) - info_add_row(0, "Temperature", "%9.2f °C", state.temperature); - if (state.battery_voltage != AltosLib.MISSING) - info_add_row(0, "Battery", "%9.2f V", state.battery_voltage); - if (state.apogee_voltage != AltosLib.MISSING) - info_add_row(0, "Drogue", "%9.2f V", state.apogee_voltage); - if (state.main_voltage != AltosLib.MISSING) - info_add_row(0, "Main", "%9.2f V", state.main_voltage); - } - if (listener_state != null) { - info_add_row(0, "CRC Errors", "%6d", listener_state.crc_errors); - - if (listener_state.battery != AltosLib.MISSING) - info_add_row(0, "Receiver Battery", "%9.2f", listener_state.battery); - } - - if (state != null) { - if (state.gps == null || !state.gps.connected) { - info_add_row(1, "GPS", "not available"); - } else { - if (state.gps_ready) - info_add_row(1, "GPS state", "%s", "ready"); - else - info_add_row(1, "GPS state", "wait (%d)", - state.gps_waiting); - if (state.gps.locked) - info_add_row(1, "GPS", " locked"); - else if (state.gps.connected) - info_add_row(1, "GPS", " unlocked"); - else - info_add_row(1, "GPS", " missing"); - info_add_row(1, "Satellites", "%6d", state.gps.nsat); - if (state.gps.lat != AltosLib.MISSING) - info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); - if (state.gps.lon != AltosLib.MISSING) - info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); - if (state.gps.alt != AltosLib.MISSING) - info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt); - if (state.gps_height != AltosLib.MISSING) - info_add_row(1, "GPS height", "%8.1f", state.gps_height); - - /* The SkyTraq GPS doesn't report these values */ - /* - if (false) { - info_add_row(1, "GPS ground speed", "%8.1f m/s %3d°", - state.gps.ground_speed, - state.gps.course); - info_add_row(1, "GPS climb rate", "%8.1f m/s", - state.gps.climb_rate); - info_add_row(1, "GPS error", "%6d m(h)%3d m(v)", - state.gps.h_error, state.gps.v_error); - } - */ - - info_add_row(1, "GPS hdop", "%8.1f", state.gps.hdop); - - if (state.npad > 0) { - if (state.from_pad != null) { - info_add_row(1, "Distance from pad", "%6d m", - (int) (state.from_pad.distance + 0.5)); - info_add_row(1, "Direction from pad", "%6d°", - (int) (state.from_pad.bearing + 0.5)); - info_add_row(1, "Elevation from pad", "%6d°", - (int) (state.elevation + 0.5)); - info_add_row(1, "Range from pad", "%6d m", - (int) (state.range + 0.5)); - } else { - info_add_row(1, "Distance from pad", "unknown"); - info_add_row(1, "Direction from pad", "unknown"); - info_add_row(1, "Elevation from pad", "unknown"); - info_add_row(1, "Range from pad", "unknown"); - } - info_add_deg(1, "Pad latitude", state.pad_lat, 'N', 'S'); - info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); - info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt); - } - if (state.gps.year != AltosLib.MISSING) - info_add_row(1, "GPS date", "%04d-%02d-%02d", - state.gps.year, - state.gps.month, - state.gps.day); - if (state.gps.hour != AltosLib.MISSING) - info_add_row(1, "GPS time", " %02d:%02d:%02d", - state.gps.hour, - state.gps.minute, - state.gps.second); - //int nsat_vis = 0; - int c; - - if (state.gps.cc_gps_sat == null) - info_add_row(2, "Satellites Visible", "%4d", 0); - else { - info_add_row(2, "Satellites Visible", "%4d", state.gps.cc_gps_sat.length); - for (c = 0; c < state.gps.cc_gps_sat.length; c++) { - info_add_row(2, "Satellite id,C/N0", - "%4d, %4d", - state.gps.cc_gps_sat[c].svid, - state.gps.cc_gps_sat[c].c_n0); - } - } - } - } - info_finish(); - } -} diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java deleted file mode 100644 index ae1f8259..00000000 --- a/altosui/AltosKML.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.io.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosKML implements AltosWriter { - - File name; - PrintStream out; - int flight_state = -1; - AltosState prev = null; - double gps_start_altitude; - - static final String[] kml_state_colors = { - "FF000000", - "FF000000", - "FF000000", - "FF0000FF", - "FF4080FF", - "FF00FFFF", - "FFFF0000", - "FF00FF00", - "FF000000", - "FFFFFFFF" - }; - - static final String kml_header_start = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + - "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" + - "<Document>\n" + - " <name>AO Flight#%d S/N: %03d</name>\n" + - " <description>\n"; - static final String kml_header_end = - " </description>\n" + - " <open>0</open>\n"; - - static final String kml_style_start = - " <Style id=\"ao-flightstate-%s\">\n" + - " <LineStyle><color>%s</color><width>4</width></LineStyle>\n" + - " <BalloonStyle>\n" + - " <text>\n"; - - static final String kml_style_end = - " </text>\n" + - " </BalloonStyle>\n" + - " </Style>\n"; - - static final String kml_placemark_start = - " <Placemark>\n" + - " <name>%s</name>\n" + - " <styleUrl>#ao-flightstate-%s</styleUrl>\n" + - " <LineString>\n" + - " <tessellate>1</tessellate>\n" + - " <altitudeMode>absolute</altitudeMode>\n" + - " <coordinates>\n"; - - static final String kml_coord_fmt = - " %.7f,%.7f,%.7f <!-- alt %12.7f time %12.7f sats %d -->\n"; - - static final String kml_placemark_end = - " </coordinates>\n" + - " </LineString>\n" + - " </Placemark>\n"; - - static final String kml_footer = - "</Document>\n" + - "</kml>\n"; - - void start (AltosState record) { - out.printf(kml_header_start, record.flight, record.serial); - out.printf("Date: %04d-%02d-%02d\n", - record.gps.year, record.gps.month, record.gps.day); - out.printf("Time: %2d:%02d:%02d\n", - record.gps.hour, record.gps.minute, record.gps.second); - out.printf("%s", kml_header_end); - } - - boolean started = false; - - void state_start(AltosState state) { - String state_name = Altos.state_name(state.state); - out.printf(kml_style_start, state_name, kml_state_colors[state.state]); - out.printf("\tState: %s\n", state_name); - out.printf("%s", kml_style_end); - out.printf(kml_placemark_start, state_name, state_name); - } - - void state_end(AltosState state) { - out.printf("%s", kml_placemark_end); - } - - void coord(AltosState state) { - AltosGPS gps = state.gps; - double altitude; - - if (state.height() != AltosLib.MISSING) - altitude = state.height() + gps_start_altitude; - else - altitude = gps.alt; - out.printf(kml_coord_fmt, - gps.lon, gps.lat, - altitude, (double) gps.alt, - state.time, gps.nsat); - } - - void end() { - out.printf("%s", kml_footer); - } - - public void close() { - if (prev != null) { - state_end(prev); - end(); - prev = null; - } - } - - public void write(AltosState state) { - AltosGPS gps = state.gps; - - if (gps == null) - return; - - if (gps.lat == AltosLib.MISSING) - return; - if (gps.lon == AltosLib.MISSING) - return; - if (!started) { - start(state); - started = true; - gps_start_altitude = gps.alt; - } - if (prev != null && prev.gps_sequence == state.gps_sequence) - return; - if (state.state != flight_state) { - flight_state = state.state; - if (prev != null) { - coord(state); - state_end(prev); - } - state_start(state); - } - coord(state); - prev = state; - } - - public void write(AltosStateIterable states) { - for (AltosState state : states) { - if ((state.set & AltosState.set_gps) != 0) - write(state); - } - } - - public AltosKML(File in_name) throws FileNotFoundException { - name = in_name; - out = new PrintStream(name); - } - - public AltosKML(String in_string) throws FileNotFoundException { - this(new File(in_string)); - } -} diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 74177753..dd5cf9ab 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -21,216 +21,94 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; -import org.altusmetrum.altoslib_3.*; - -public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener { - GridBagLayout layout; - - public class LandedValue { - JLabel label; - JTextField value; - void show(AltosState state, AltosListenerState listener_state) {} - - void reset() { - value.setText(""); - } - - void show() { - label.setVisible(true); - value.setVisible(true); - } - - void show(String s) { - show(); - value.setText(s); - } - - void show(AltosUnits units, double v) { - show(units.show(8, v)); - } - - void show(String format, double v) { - show(String.format(format, v)); - } - - public void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); - } - - void hide() { - label.setVisible(false); - value.setVisible(false); - } - - public LandedValue (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 0; c.gridy = y; - c.insets = new Insets(10, 10, 10, 10); - c.anchor = GridBagConstraints.WEST; - c.weightx = 0; - c.fill = GridBagConstraints.VERTICAL; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 1; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.weightx = 1; - c.fill = GridBagConstraints.BOTH; - layout.setConstraints(value, c); - add(value); +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; + +public class AltosLanded extends AltosUIFlightTab implements ActionListener { + + class Bearing extends AltosUIIndicator { + public void show (AltosState state, AltosListenerState listener_state) { + if (state.from_pad != null && state.from_pad.bearing != AltosLib.MISSING) { + show( String.format("%3.0f°", state.from_pad.bearing), + state.from_pad.bearing_words( + AltosGreatCircle.BEARING_LONG)); + } else { + show("Missing", "Missing"); + } } - } - - String pos(double p, String pos, String neg) { - String h = pos; - if (p < 0) { - h = neg; - p = -p; + public Bearing (Container container, int y) { + super (container, y, "Bearing", 2); } - int deg = (int) Math.floor(p); - double min = (p - Math.floor(p)) * 60.0; - return String.format("%s %4d° %9.6f", h, deg, min); } - class Lat extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(); - if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) - show(pos(state.gps.lat,"N", "S")); + class Distance extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { + if (state.from_pad != null) + return state.from_pad.distance; else - show("???"); - } - public Lat (GridBagLayout layout, int y) { - super (layout, y, "Latitude"); + return AltosLib.MISSING; } - } - - Lat lat; - class Lon extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(); - if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) - show(pos(state.gps.lon,"E", "W")); - else - show("???"); - } - public Lon (GridBagLayout layout, int y) { - super (layout, y, "Longitude"); + public Distance(Container container, int y) { + super(container, y, AltosConvert.distance, "Ground Distance", 2); } } - Lon lon; + class Lat extends AltosUIUnitsIndicator { - class Bearing extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(); - if (state.from_pad != null) - show("%3.0f°", state.from_pad.bearing); - else - show("???"); - } - public Bearing (GridBagLayout layout, int y) { - super (layout, y, "Bearing"); - } - } + public boolean hide (AltosState state, int i) { return state.gps == null || !state.gps.connected; } - Bearing bearing; - - class Distance extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(); - if (state.from_pad != null) - show(AltosConvert.distance, state.from_pad.distance); - else - show("???"); - } - public Distance (GridBagLayout layout, int y) { - super (layout, y, "Distance"); + public double value(AltosState state, int i) { + if (state.gps == null) + return AltosLib.MISSING; + if (!state.gps.connected) + return AltosLib.MISSING; + return state.gps.lat; } - } - Distance distance; - - class Height extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.max_height()); - } - public Height (GridBagLayout layout, int y) { - super (layout, y, "Maximum Height"); + public Lat (Container container, int y) { + super (container, y, AltosConvert.latitude, "Latitude", 2); } } - Height height; + class Lon extends AltosUIUnitsIndicator { + public boolean hide (AltosState state, int i) { return state.gps == null || !state.gps.connected; } - class Speed extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.max_speed()); + public double value(AltosState state, int i) { + if (state.gps == null) + return AltosLib.MISSING; + if (!state.gps.connected) + return AltosLib.MISSING; + return state.gps.lon; } - public Speed (GridBagLayout layout, int y) { - super (layout, y, "Maximum Speed"); + + public Lon (Container container, int y) { + super (container, y, AltosConvert.longitude, "Longitude", 2); } } - Speed speed; + class MaxHeight extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { return state.max_height(); } - class Accel extends LandedValue { - void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.accel, state.max_acceleration()); - } - public Accel (GridBagLayout layout, int y) { - super (layout, y, "Maximum Acceleration"); + public MaxHeight (Container container, int y) { + super (container, y, AltosConvert.height, "Maximum Height", 2); } } - Accel accel; + class MaxSpeed extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { return state.max_speed(); } - public void reset() { - lat.reset(); - lon.reset(); - bearing.reset(); - distance.reset(); - height.reset(); - speed.reset(); - accel.reset(); + public MaxSpeed (Container container, int y) { + super (container, y, AltosConvert.speed, "Maximum Speed", 2); + } } - public void set_font() { - lat.set_font(); - lon.set_font(); - bearing.set_font(); - distance.set_font(); - height.set_font(); - speed.set_font(); - accel.set_font(); - } + class MaxAccel extends AltosUIUnitsIndicator { + public double value(AltosState state, int i) { return state.max_acceleration(); } - public void show(AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) { - bearing.show(state, listener_state); - distance.show(state, listener_state); - lat.show(state, listener_state); - lon.show(state, listener_state); - } else { - bearing.hide(); - distance.hide(); - lat.hide(); - lon.hide(); + public MaxAccel (Container container, int y) { + super (container, y, AltosConvert.speed, "Maximum acceleration", 2); } - height.show(state, listener_state); - speed.show(state, listener_state); - accel.show(state, listener_state); - if (reader.backing_file() != null) - graph.setEnabled(true); } JButton graph; @@ -274,20 +152,16 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio } public AltosLanded(AltosFlightReader in_reader) { - layout = new GridBagLayout(); - reader = in_reader; - setLayout(layout); - /* Elements in descent display */ - bearing = new Bearing(layout, 0); - distance = new Distance(layout, 1); - lat = new Lat(layout, 2); - lon = new Lon(layout, 3); - height = new Height(layout, 4); - speed = new Speed(layout, 5); - accel = new Accel(layout, 6); + add(new Bearing(this, 0)); + add(new Distance(this, 1)); + add(new Lat(this, 2)); + add(new Lon(this, 3)); + add(new MaxHeight(this, 4)); + add(new MaxSpeed(this, 5)); + add(new MaxAccel(this, 6)); graph = new JButton ("Graph Flight"); graph.setActionCommand("graph"); @@ -296,12 +170,13 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio GridBagConstraints c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 7; + c.gridx = 1; c.gridy = 7; c.insets = new Insets(10, 10, 10, 10); c.anchor = GridBagConstraints.WEST; c.weightx = 0; c.weighty = 0; c.fill = GridBagConstraints.VERTICAL; add(graph, c); + addHierarchyListener(this); } } diff --git a/altosui/AltosLaunch.java b/altosui/AltosLaunch.java index 04948ee6..9ac1e44c 100644 --- a/altosui/AltosLaunch.java +++ b/altosui/AltosLaunch.java @@ -20,7 +20,7 @@ package altosui; import java.io.*; import java.util.concurrent.*; import java.awt.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altosuilib_2.*; public class AltosLaunch { AltosDevice device; diff --git a/altosui/AltosLaunchUI.java b/altosui/AltosLaunchUI.java index 4d9fbda5..cc082542 100644 --- a/altosui/AltosLaunchUI.java +++ b/altosui/AltosLaunchUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altosuilib_2.*; class FireButton extends JButton { protected void processMouseEvent(MouseEvent e) { diff --git a/altosui/AltosLed.java b/altosui/AltosLed.java deleted file mode 100644 index 93064f1e..00000000 --- a/altosui/AltosLed.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.*; - -public class AltosLed extends JLabel { - ImageIcon on, off; - - ImageIcon create_icon(String path) { - java.net.URL imgURL = AltosUI.class.getResource(path); - if (imgURL != null) - return new ImageIcon(imgURL); - System.err.printf("Cannot find icon \"%s\"\n", path); - return null; - } - - public void set(boolean set) { - if (set) - setIcon(on); - else - setIcon(off); - } - - public AltosLed(String on_path, String off_path) { - on = create_icon(on_path); - off = create_icon(off_path); - setIcon(off); - } -} diff --git a/altosui/AltosLights.java b/altosui/AltosLights.java deleted file mode 100644 index 7ad22f3e..00000000 --- a/altosui/AltosLights.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import javax.swing.*; - -public class AltosLights extends JComponent { - - GridBagLayout gridbag; - - AltosLed red, green; - - ImageIcon create_icon(String path, String description) { - java.net.URL imgURL = AltosUI.class.getResource(path); - if (imgURL != null) - return new ImageIcon(imgURL, description); - System.err.printf("Cannot find icon \"%s\"\n", path); - return null; - } - - public void set (boolean on) { - if (on) { - red.set(false); - green.set(true); - } else { - red.set(true); - green.set(false); - } - } - - public AltosLights() { - GridBagConstraints c; - gridbag = new GridBagLayout(); - setLayout(gridbag); - - c = new GridBagConstraints(); - red = new AltosLed("/redled.png", "/grayled.png"); - c.gridx = 0; c.gridy = 0; - c.insets = new Insets (0, 5, 0, 5); - gridbag.setConstraints(red, c); - add(red); - red.set(true); - green = new AltosLed("/greenled.png", "/grayled.png"); - c.gridx = 1; c.gridy = 0; - gridbag.setConstraints(green, c); - add(green); - green.set(false); - } -} diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index 7baf0eb2..6b5fd150 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -17,253 +17,73 @@ package altosui; -import java.awt.*; -import javax.swing.*; -import org.altusmetrum.altoslib_3.*; +import java.util.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; -public class AltosPad extends JComponent implements AltosFlightDisplay { - GridBagLayout layout; +public class AltosPad extends AltosUIFlightTab { - public class LaunchStatus { - JLabel label; - JTextField value; - AltosLights lights; - - void show(AltosState state, AltosListenerState listener_state) {} - - void reset() { - value.setText(""); - lights.set(false); - } - - public void show() { - label.setVisible(true); - value.setVisible(true); - lights.setVisible(true); - } - - void show(String s) { - show(); - value.setText(s); - } - - void show(String format, double value) { - show(String.format(format, value)); - } - - void show(String format, int value) { - show(String.format(format, value)); - } - - public void hide() { - label.setVisible(false); - value.setVisible(false); - lights.setVisible(false); - } - - public void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); - } - - public void set_label(String text) { - label.setText(text); - } - - public LaunchStatus (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.weighty = 1; - - lights = new AltosLights(); - c.gridx = 0; c.gridy = y; - c.anchor = GridBagConstraints.CENTER; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(lights, c); - add(lights); - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 1; c.gridy = y; - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 2; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); - - } + class Battery extends AltosUIVoltageIndicator { + public double voltage(AltosState state) { return state.battery_voltage; } + public double good() { return AltosLib.ao_battery_good; } + public Battery (AltosUIFlightTab container, int y) { super(container, y, "Battery Voltage", 2); } } - public class LaunchValue { - JLabel label; - JTextField value; - void show(AltosState state, AltosListenerState listener_state) {} - - void show() { - label.setVisible(true); - value.setVisible(true); - } - - void hide() { - label.setVisible(false); - value.setVisible(false); - } - - public void set_font() { - label.setFont(Altos.label_font); - value.setFont(Altos.value_font); - } - - void show(String s) { - show(); - value.setText(s); - } - - void show(AltosUnits units, double v) { - show(units.show(8, v)); - } - - void show(String format, double v) { - show(String.format(format, v)); - } - - public void set_label(String text) { - label.setText(text); - } - - void reset() { - value.setText(""); - } - - public LaunchValue (GridBagLayout layout, int y, String text) { - GridBagConstraints c = new GridBagConstraints(); - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.weighty = 1; - - label = new JLabel(text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 1; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - value = new JTextField(Altos.text_width); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = 2; c.gridy = y; - c.anchor = GridBagConstraints.EAST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); - } + class Apogee extends AltosUIVoltageIndicator { + public boolean hide(double v) { return v == AltosLib.MISSING; } + public double voltage(AltosState state) { return state.apogee_voltage; } + public double good() { return AltosLib.ao_igniter_good; } + public Apogee (AltosUIFlightTab container, int y) { super(container, y, "Apogee Igniter Voltage", 2); } } - class Battery extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.battery_voltage == AltosLib.MISSING) - hide(); - else { - show("%4.2f V", state.battery_voltage); - lights.set(state.battery_voltage >= AltosLib.ao_battery_good); - } - } - public Battery (GridBagLayout layout, int y) { - super(layout, y, "Battery Voltage"); - } + class Main extends AltosUIVoltageIndicator { + public boolean hide(double v) { return v == AltosLib.MISSING; } + public double voltage(AltosState state) { return state.main_voltage; } + public double good() { return AltosLib.ao_igniter_good; } + public Main (AltosUIFlightTab container, int y) { super(container, y, "Main Igniter Voltage", 2); } } - Battery battery; - - class Apogee extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.apogee_voltage == AltosLib.MISSING) - hide(); - else { - show("%4.2f V", state.apogee_voltage); - lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good); - } - } - public Apogee (GridBagLayout layout, int y) { - super(layout, y, "Apogee Igniter Voltage"); - } - } - - Apogee apogee; - - class Main extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.main_voltage == AltosLib.MISSING) - hide(); - else { - show("%4.2f V", state.main_voltage); - lights.set(state.main_voltage >= AltosLib.ao_igniter_good); - } - } - public Main (GridBagLayout layout, int y) { - super(layout, y, "Main Igniter Voltage"); - } - } - - Main main; - - class LoggingReady extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { + class LoggingReady extends AltosUIIndicator { + public void show (AltosState state, AltosListenerState listener_state) { if (state == null || state.flight == AltosLib.MISSING) { hide(); } else { if (state.flight != 0) { if (state.state <= Altos.ao_flight_pad) show("Ready to record"); - else if (state.state < Altos.ao_flight_landed) + else if (state.state < Altos.ao_flight_landed || + state.state == AltosLib.ao_flight_stateless) show("Recording data"); else show("Recorded data"); } else show("Storage full"); - lights.set(state.flight != 0); + set_lights(state.flight != 0); } } - public LoggingReady (GridBagLayout layout, int y) { - super(layout, y, "On-board Data Logging"); + public LoggingReady (AltosUIFlightTab container, int y) { + super(container, y, "On-board Data Logging", 1, true, 2); } } - LoggingReady logging_ready; - - class GPSLocked extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { + class GPSLocked extends AltosUIIndicator { + public void show (AltosState state, AltosListenerState listener_state) { if (state == null || state.gps == null) hide(); else { - show("%4d sats", state.gps.nsat); - lights.set(state.gps.locked && state.gps.nsat >= 4); + int sol = state.gps.nsat; + int sat = state.gps.cc_gps_sat == null ? 0 : state.gps.cc_gps_sat.length; + show("%d in solution", sol, "%d in view", sat); + set_lights(state.gps.locked && sol >= 4); } } - public GPSLocked (GridBagLayout layout, int y) { - super (layout, y, "GPS Locked"); + public GPSLocked (AltosUIFlightTab container, int y) { + super (container, y, "GPS Locked", 2, true, 1); } } - GPSLocked gps_locked; - - class GPSReady extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { + class GPSReady extends AltosUIIndicator { + public void show (AltosState state, AltosListenerState listener_state) { if (state == null || state.gps == null) hide(); else { @@ -271,45 +91,37 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { show("Ready"); else show("Waiting %d", state.gps_waiting); - lights.set(state.gps_ready); + set_lights(state.gps_ready); } } - public GPSReady (GridBagLayout layout, int y) { - super (layout, y, "GPS Ready"); + public GPSReady (AltosUIFlightTab container, int y) { + super (container, y, "GPS Ready", 1, true, 2); } } - GPSReady gps_ready; + class ReceiverBattery extends AltosUIVoltageIndicator { - class ReceiverBattery extends LaunchStatus { - void show (AltosState state, AltosListenerState listener_state) { - if (listener_state == null || listener_state.battery == AltosLib.MISSING) - hide(); - else { - show("%4.2f V", listener_state.battery); - lights.set(listener_state.battery > AltosLib.ao_battery_good); - } + public double voltage(AltosState state) { return AltosLib.MISSING; } + + public boolean hide(double v) { return v == AltosLib.MISSING; } + public double good() { return AltosLib.ao_battery_good; } + + public double value(AltosState state, AltosListenerState listener_state, int i) { + if (listener_state == null) + return AltosLib.MISSING; + return listener_state.battery; } - public ReceiverBattery (GridBagLayout layout, int y) { - super(layout, y, "Receiver Battery"); + + public ReceiverBattery (AltosUIFlightTab container, int y) { + super(container, y, "Receiver Battery", 2); } } - ReceiverBattery receiver_battery; + class PadLat extends AltosUIIndicator { - String pos(double p, String pos, String neg) { - String h = pos; - if (p < 0) { - h = neg; - p = -p; - } - int deg = (int) Math.floor(p); - double min = (p - Math.floor(p)) * 60.0; - return String.format("%s %4d° %9.6f", h, deg, min); - } + double last_lat = AltosLib.MISSING - 1; - class PadLat extends LaunchValue { - void show (AltosState state, AltosListenerState listener_state) { + public void show (AltosState state, AltosListenerState listener_state) { double lat = AltosLib.MISSING; String label = null; @@ -322,21 +134,31 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Latitude"; } } - if (lat != AltosLib.MISSING) { - show(pos(lat,"N", "S")); - set_label(label); - } else - hide(); + if (lat != last_lat) { + if (lat != AltosLib.MISSING) { + show(AltosConvert.latitude.show(10, lat)); + set_label(label); + } else + hide(); + last_lat = lat; + } + } + + public void reset() { + super.reset(); + last_lat = AltosLib.MISSING - 1; } - public PadLat (GridBagLayout layout, int y) { - super (layout, y, "Pad Latitude"); + + public PadLat (AltosUIFlightTab container, int y) { + super (container, y, "Pad Latitude", 1, false, 2); } } - PadLat pad_lat; + class PadLon extends AltosUIIndicator { + + double last_lon = AltosLib.MISSING - 1; - class PadLon extends LaunchValue { - void show (AltosState state, AltosListenerState listener_state) { + public void show (AltosState state, AltosListenerState listener_state) { double lon = AltosLib.MISSING; String label = null; @@ -349,21 +171,31 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Longitude"; } } - if (lon != AltosLib.MISSING) { - show(pos(lon,"E", "W")); - set_label(label); - } else - hide(); + if (lon != last_lon) { + if (lon != AltosLib.MISSING) { + show(AltosConvert.longitude.show(10, lon)); + set_label(label); + } else + hide(); + last_lon = lon; + } + } + + public void reset() { + super.reset(); + last_lon = AltosLib.MISSING - 1; } - public PadLon (GridBagLayout layout, int y) { - super (layout, y, "Pad Longitude"); + + public PadLon (AltosUIFlightTab container, int y) { + super (container, y, "Pad Longitude", 1, false, 2); } } - PadLon pad_lon; + class PadAlt extends AltosUIIndicator { + + double last_alt = AltosLib.MISSING - 1; - class PadAlt extends LaunchValue { - void show (AltosState state, AltosListenerState listener_state) { + public void show (AltosState state, AltosListenerState listener_state) { double alt = AltosLib.MISSING; String label = null; @@ -376,83 +208,38 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Altitude"; } } - if (alt != AltosLib.MISSING) { - show("%4.0f m", state.gps.alt); - set_label(label); - } else - hide(); - } - public PadAlt (GridBagLayout layout, int y) { - super (layout, y, "Pad Altitude"); + if (alt != last_alt) { + if (alt != AltosLib.MISSING) { + show(AltosConvert.height.show(5, alt)); + set_label(label); + } else + hide(); + last_alt = alt; + } } - } - PadAlt pad_alt; - - public void reset() { - battery.reset(); - apogee.reset(); - main.reset(); - logging_ready.reset(); - gps_locked.reset(); - gps_ready.reset(); - receiver_battery.reset(); - pad_lat.reset(); - pad_lon.reset(); - pad_alt.reset(); - } + public void reset() { + super.reset(); + last_alt = AltosLib.MISSING - 1; + } - public void set_font() { - battery.set_font(); - apogee.set_font(); - main.set_font(); - logging_ready.set_font(); - gps_locked.set_font(); - gps_ready.set_font(); - receiver_battery.set_font(); - pad_lat.set_font(); - pad_lon.set_font(); - pad_alt.set_font(); - } - - public void show(AltosState state, AltosListenerState listener_state) { - battery.show(state, listener_state); - apogee.show(state, listener_state); - main.show(state, listener_state); - logging_ready.show(state, listener_state); - pad_alt.show(state, listener_state); - receiver_battery.show(state, listener_state); - gps_locked.show(state, listener_state); - gps_ready.show(state, listener_state); - pad_lat.show(state, listener_state); - pad_lon.show(state, listener_state); + public PadAlt (AltosUIFlightTab container, int y) { + super (container, y, "Pad Altitude", 1, false, 2); + } } + public String getName() { return "Pad"; } public AltosPad() { - layout = new GridBagLayout(); - - setLayout(layout); - - /* Elements in pad display: - * - * Battery voltage - * Igniter continuity - * GPS lock status - * GPS ready status - * GPS location - * Pad altitude - * RSSI - */ - battery = new Battery(layout, 0); - apogee = new Apogee(layout, 1); - main = new Main(layout, 2); - logging_ready = new LoggingReady(layout, 3); - gps_locked = new GPSLocked(layout, 4); - gps_ready = new GPSReady(layout, 5); - receiver_battery = new ReceiverBattery(layout, 6); - pad_lat = new PadLat(layout, 7); - pad_lon = new PadLon(layout, 8); - pad_alt = new PadAlt(layout, 9); - show(null, null); + int y = 0; + add(new Battery(this, y++)); + add(new Apogee(this, y++)); + add(new Main(this, y++)); + add(new LoggingReady(this, y++)); + add(new GPSLocked(this, y++)); + add(new GPSReady(this, y++)); + add(new ReceiverBattery(this, y++)); + add(new PadLat(this, y++)); + add(new PadLon(this, y++)); + add(new PadAlt(this, y++)); } } diff --git a/altosui/AltosRomconfigUI.java b/altosui/AltosRomconfigUI.java deleted file mode 100644 index 89994679..00000000 --- a/altosui/AltosRomconfigUI.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosRomconfigUI - extends AltosUIDialog - implements ActionListener -{ - Container pane; - Box box; - JLabel serial_label; - JLabel radio_calibration_label; - - JFrame owner; - JTextField serial_value; - JTextField radio_calibration_value; - - JButton ok; - JButton cancel; - - /* Build the UI using a grid bag */ - public AltosRomconfigUI(JFrame in_owner) { - super (in_owner, "Configure TeleMetrum Rom Values", true); - - owner = in_owner; - GridBagConstraints c; - - Insets il = new Insets(4,4,4,4); - Insets ir = new Insets(4,4,4,4); - - pane = getContentPane(); - pane.setLayout(new GridBagLayout()); - - /* Serial */ - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 0; - c.gridwidth = 3; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - serial_label = new JLabel("Serial:"); - pane.add(serial_label, c); - - c = new GridBagConstraints(); - c.gridx = 3; c.gridy = 0; - c.gridwidth = 3; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - serial_value = new JTextField("00000000"); - pane.add(serial_value, c); - - /* Radio calibration value */ - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 1; - c.gridwidth = 3; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - c.ipady = 5; - radio_calibration_label = new JLabel("Radio Calibration:"); - pane.add(radio_calibration_label, c); - - c = new GridBagConstraints(); - c.gridx = 3; c.gridy = 1; - c.gridwidth = 3; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - c.ipady = 5; - radio_calibration_value = new JTextField("00000000"); - pane.add(radio_calibration_value, c); - - /* Buttons */ - c = new GridBagConstraints(); - c.gridx = 0; c.gridy = 2; - c.gridwidth = 3; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = il; - ok = new JButton("OK"); - pane.add(ok, c); - ok.addActionListener(this); - ok.setActionCommand("ok"); - - c = new GridBagConstraints(); - c.gridx = 3; c.gridy = 2; - c.gridwidth = 3; - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = il; - cancel = new JButton("Cancel"); - pane.add(cancel, c); - cancel.addActionListener(this); - cancel.setActionCommand("cancel"); - - pack(); - setLocationRelativeTo(owner); - } - - public AltosRomconfigUI(JFrame frame, AltosRomconfig config) { - this(frame); - set(config); - } - - boolean selected; - - /* Listen for events from our buttons */ - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - - if (cmd.equals("ok")) { - AltosRomconfig romconfig = romconfig(); - if (romconfig == null || !romconfig.valid()) { - JOptionPane.showMessageDialog(this, - "Invalid serial number or radio calibration value", - "Invalid rom configuration", - JOptionPane.ERROR_MESSAGE); - return; - } - selected = true; - } - setVisible(false); - } - - int serial() { - return Integer.parseInt(serial_value.getText()); - } - - void set_serial(int serial) { - serial_value.setText(String.format("%d", serial)); - } - - int radio_calibration() { - return Integer.parseInt(radio_calibration_value.getText()); - } - - void set_radio_calibration(int calibration) { - radio_calibration_value.setText(String.format("%d", calibration)); - } - - public void set(AltosRomconfig config) { - if (config != null && config.valid()) { - set_serial(config.serial_number); - set_radio_calibration(config.radio_calibration); - } - } - - AltosRomconfig romconfig() { - try { - return new AltosRomconfig(serial(), radio_calibration()); - } catch (NumberFormatException ne) { - return null; - } - } - - public AltosRomconfig showDialog() { - setVisible(true); - if (selected) - return romconfig(); - return null; - } - - public static AltosRomconfig show(JFrame frame, AltosRomconfig config) { - AltosRomconfigUI ui = new AltosRomconfigUI(frame, config); - return ui.showDialog(); - } -} diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java deleted file mode 100644 index e4a93362..00000000 --- a/altosui/AltosScanUI.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; -import java.io.*; -import java.util.*; -import java.text.*; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -class AltosScanResult { - 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 (%s %s)", - callsign, serial, flight, frequency.toShortString(), Altos.telemetry_name(telemetry)); - } - - public String toShortString() { - 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, AltosFrequency in_frequency, int in_telemetry) { - callsign = in_callsign; - serial = in_serial; - flight = in_flight; - frequency = in_frequency; - telemetry = in_telemetry; - } - - public boolean equals(AltosScanResult other) { - 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<AltosScanResult> implements ListModel { - - LinkedList<ListDataListener> listeners = new LinkedList<ListDataListener>(); - - void changed(ListDataEvent de) { - for (ListDataListener l : listeners) - l.contentsChanged(de); - } - - public boolean add(AltosScanResult 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); - 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); - } - - public AltosScanResult getElementAt(int i) { - return this.get(i); - } - - public int getSize() { - return this.size(); - } -} - -public class AltosScanUI - extends AltosUIDialog - implements ActionListener -{ - AltosUI owner; - AltosDevice device; - AltosConfigData config_data; - AltosTelemetryReader reader; - 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; - - 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, - ((FileNotFoundException) e).getMessage(), - "Cannot open target device", - JOptionPane.ERROR_MESSAGE); - } else if (e instanceof AltosSerialInUseException) { - JOptionPane.showMessageDialog(owner, - String.format("Device \"%s\" already in use", - device.toShortString()), - "Device in use", - JOptionPane.ERROR_MESSAGE); - } else if (e instanceof IOException) { - IOException ee = (IOException) e; - JOptionPane.showMessageDialog(owner, - device.toShortString(), - ee.getLocalizedMessage(), - JOptionPane.ERROR_MESSAGE); - } else { - JOptionPane.showMessageDialog(owner, - String.format("Connection to \"%s\" failed", - device.toShortString()), - "Connection Failed", - JOptionPane.ERROR_MESSAGE); - } - close(); - } - - class TelemetryHandler implements Runnable { - - public void run() { - - boolean interrupted = false; - - try { - for (;;) { - try { - AltosState state = reader.read(); - if (state == null) - continue; - 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() { - results.add(result); - } - }; - SwingUtilities.invokeLater(r); - } - } catch (ParseException pp) { - } catch (AltosCRCException ce) { - } - } - } catch (InterruptedException ee) { - interrupted = true; - } catch (IOException ie) { - } finally { - reader.close(interrupted); - } - } - } - - void set_label() { - frequency_label.setText(String.format("Frequency: %s", frequencies[frequency_index].toString())); - telemetry_label.setText(String.format("Telemetry: %s", Altos.telemetry_name(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(); - } - set_frequency(); - set_label(); - reader.set_monitor(true); - } - - - void close() { - if (thread != null && thread.isAlive()) { - thread.interrupt(); - try { - thread.join(); - } catch (InterruptedException ie) {} - } - thread = null; - if (timer != null) - timer.stop(); - setVisible(false); - dispose(); - } - - void tick_timer() throws InterruptedException, TimeoutException { - next(); - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - - 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_frequency(r.frequency.frequency); - reader.save_frequency(); - owner.telemetry_window(device); - } - } - } - } - } catch (TimeoutException te) { - close(); - } catch (InterruptedException ie) { - close(); - } - } - - /* A window listener to catch closing events and tell the config code */ - class ConfigListener extends WindowAdapter { - AltosScanUI ui; - - public ConfigListener(AltosScanUI this_ui) { - ui = this_ui; - } - - public void windowClosing(WindowEvent e) { - ui.actionPerformed(new ActionEvent(e.getSource(), - ActionEvent.ACTION_PERFORMED, - "close")); - } - } - - private boolean open() { - device = AltosDeviceUIDialog.show(owner, Altos.product_basestation); - if (device == null) - return false; - try { - reader = new AltosTelemetryReader(new AltosSerial(device)); - set_frequency(); - set_telemetry(); - try { - Thread.sleep(100); - } catch (InterruptedException ie) { - } - reader.flush(); - handler = new TelemetryHandler(); - thread = new Thread(handler); - thread.start(); - return true; - } catch (FileNotFoundException ee) { - JOptionPane.showMessageDialog(owner, - ee.getMessage(), - "Cannot open target device", - JOptionPane.ERROR_MESSAGE); - } catch (AltosSerialInUseException si) { - JOptionPane.showMessageDialog(owner, - String.format("Device \"%s\" already in use", - device.toShortString()), - "Device in use", - JOptionPane.ERROR_MESSAGE); - } catch (IOException ee) { - JOptionPane.showMessageDialog(owner, - 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); - return false; - } - - public AltosScanUI(AltosUI in_owner) { - - owner = in_owner; - - frequencies = AltosUIPreferences.common_frequencies(); - frequency_index = 0; - telemetry = Altos.ao_telemetry_min; - - if (!open()) - return; - - Container pane = getContentPane(); - GridBagConstraints c = new GridBagConstraints(); - Insets i = new Insets(4,4,4,4); - - timer = new javax.swing.Timer(timeout, this); - timer.setActionCommand("tick"); - timer.restart(); - - owner = in_owner; - - pane.setLayout(new GridBagLayout()); - - scanning_label = new JLabel("Scanning:"); - frequency_label = new JLabel(""); - telemetry_label = new JLabel(""); - - set_label(); - - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.WEST; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 2; - - 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) { - //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 - //of the JScrollBar to a fixed value. You wouldn't get the nice - //aligned scrolling, but it should work. - public int getScrollableUnitIncrement(Rectangle visibleRect, - int orientation, - int direction) { - int row; - if (orientation == SwingConstants.VERTICAL && - direction < 0 && (row = getFirstVisibleIndex()) != -1) { - Rectangle r = getCellBounds(row, row); - if ((r.y == visibleRect.y) && (row != 0)) { - Point loc = r.getLocation(); - loc.y--; - int prevIndex = locationToIndex(loc); - Rectangle prevR = getCellBounds(prevIndex, prevIndex); - - if (prevR == null || prevR.y >= r.y) { - return 0; - } - return prevR.height; - } - } - return super.getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - }; - - list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - list.setLayoutOrientation(JList.HORIZONTAL_WRAP); - list.setVisibleRowCount(-1); - - list.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - monitor_button.doClick(); //emulate button click - } - } - }); - JScrollPane listScroller = new JScrollPane(list); - listScroller.setPreferredSize(new Dimension(400, 80)); - listScroller.setAlignmentX(LEFT_ALIGNMENT); - - //Create a container so that we can add a title around - //the scroll pane. Can't add a title directly to the - //scroll pane because its background would be white. - //Lay out the label and scroll pane from top to bottom. - JPanel listPane = new JPanel(); - listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS)); - - JLabel label = new JLabel("Select Device"); - label.setLabelFor(list); - listPane.add(label); - listPane.add(Box.createRigidArea(new Dimension(0,5))); - listPane.add(listScroller); - listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); - - c.fill = GridBagConstraints.BOTH; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 0; - c.gridy = y_offset; - c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; - - pane.add(listPane, c); - - cancel_button = new JButton("Cancel"); - cancel_button.addActionListener(this); - cancel_button.setActionCommand("cancel"); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 0; - c.gridy = y_offset + 1; - c.gridwidth = 1; - c.anchor = GridBagConstraints.CENTER; - - pane.add(cancel_button, c); - - monitor_button = new JButton("Monitor"); - monitor_button.addActionListener(this); - monitor_button.setActionCommand("monitor"); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 1; - c.gridy = y_offset + 1; - c.gridwidth = 1; - c.anchor = GridBagConstraints.CENTER; - - pane.add(monitor_button, c); - - pack(); - setLocationRelativeTo(owner); - - addWindowListener(new ConfigListener(this)); - - setVisible(true); - } -}
\ No newline at end of file diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java deleted file mode 100644 index 2c5d2dfd..00000000 --- a/altosui/AltosSerial.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -/* - * Deal with TeleDongle on a serial port - */ - -package altosui; - -import java.io.*; -import java.util.*; -import java.awt.*; -import javax.swing.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -import libaltosJNI.*; - -/* - * This class reads from the serial port and places each received - * line in a queue. Dealing with that queue is left up to other - * threads. - */ - -public class AltosSerial extends AltosLink { - - static java.util.List<String> devices_opened = Collections.synchronizedList(new LinkedList<String>()); - - AltosDevice device; - SWIGTYPE_p_altos_file altos; - Thread input_thread; - String line; - byte[] line_bytes; - int line_count; - Frame frame; - - public int getchar() { - if (altos == null) - return ERROR; - return libaltos.altos_getchar(altos, 0); - } - - public void flush_output() { - super.flush_output(); - if (altos != null) { - if (libaltos.altos_flush(altos) != 0) - close_serial(); - } - } - - JDialog timeout_dialog; - - private void start_timeout_dialog_internal() { - - Object[] options = { "Cancel" }; - - JOptionPane pane = new JOptionPane(); - pane.setMessage(String.format("Connecting to %s, %7.3f MHz as %s", device.toShortString(), frequency, callsign)); - pane.setOptions(options); - pane.setInitialValue(null); - - timeout_dialog = pane.createDialog(frame, "Connecting..."); - - timeout_dialog.setVisible(true); - - Object o = pane.getValue(); - if (o == null) - return; - if (options[0].equals(o)) - reply_abort = true; - timeout_dialog.dispose(); - timeout_dialog = null; - } - - /* - * These are required by the AltosLink implementation - */ - - public boolean can_cancel_reply() { - /* - * Can cancel any replies not called from the dispatch thread - */ - return !SwingUtilities.isEventDispatchThread(); - } - - public boolean show_reply_timeout() { - if (!SwingUtilities.isEventDispatchThread() && frame != null) { - Runnable r = new Runnable() { - public void run() { - start_timeout_dialog_internal(); - } - }; - SwingUtilities.invokeLater(r); - return true; - } - return false; - } - - public void hide_reply_timeout() { - Runnable r = new Runnable() { - public void run() { - timeout_dialog.setVisible(false); - } - }; - SwingUtilities.invokeLater(r); - } - - private void close_serial() { - synchronized (devices_opened) { - devices_opened.remove(device.getPath()); - } - if (altos != null) { - libaltos.altos_free(altos); - altos = null; - } - abort_reply(); - } - - public void close() { - if (remote) { - try { - stop_remote(); - } catch (InterruptedException ie) { - } - } - if (in_reply != 0) - System.out.printf("Uh-oh. Closing active serial device\n"); - - close_serial(); - - if (input_thread != null) { - try { - input_thread.interrupt(); - input_thread.join(); - } catch (InterruptedException ie) { - } - input_thread = null; - } - if (debug) - System.out.printf("Closing %s\n", device.getPath()); - } - - private void putc(char c) { - if (altos != null) - if (libaltos.altos_putchar(altos, c) != 0) - close_serial(); - } - - public void putchar(byte c) { - if (altos != null) { - if (debug) - System.out.printf(" %02x", (int) c & 0xff); - if (libaltos.altos_putchar(altos, (char) c) != 0) - close_serial(); - } - } - - public void print(String data) { - for (int i = 0; i < data.length(); i++) - putc(data.charAt(i)); - } - - private void open() throws FileNotFoundException, AltosSerialInUseException { - synchronized (devices_opened) { - if (devices_opened.contains(device.getPath())) - throw new AltosSerialInUseException(device); - devices_opened.add(device.getPath()); - } - altos = device.open(); - if (altos == null) { - final String message = device.getErrorString(); - close(); - throw new FileNotFoundException(String.format("%s (%s)", - device.toShortString(), message)); - } - if (debug) - System.out.printf("Open %s\n", device.getPath()); - input_thread = new Thread(this); - input_thread.start(); - print("~\nE 0\n"); - set_monitor(false); - flush_output(); - } - - public void set_frame(Frame in_frame) { - frame = in_frame; - } - - public AltosSerial(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { - device = in_device; - frame = null; - serial = device.getSerial(); - name = device.toShortString(); - open(); - } -} diff --git a/altosui/AltosSerialInUseException.java b/altosui/AltosSerialInUseException.java deleted file mode 100644 index b45d9157..00000000 --- a/altosui/AltosSerialInUseException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; -import org.altusmetrum.altosuilib_1.*; - -public class AltosSerialInUseException extends Exception { - public AltosDevice device; - - public AltosSerialInUseException (AltosDevice in_device) { - device = in_device; - } -} diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java deleted file mode 100644 index 105afade..00000000 --- a/altosui/AltosSiteMap.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright © 2010 Anthony Towns <aj@erisian.com.au> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import javax.swing.*; -import java.io.*; -import java.lang.Math; -import java.awt.geom.Point2D; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; - -public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { - // preferred vertical step in a tile in naut. miles - // will actually choose a step size between x and 2x, where this - // is 1.5x - static final double tile_size_nmi = 0.75; - - static final int px_size = 512; - - static final int MAX_TILE_DELTA = 100; - - private static Point2D.Double translatePoint(Point2D.Double p, - Point2D.Double d) - { - return new Point2D.Double(p.x + d.x, p.y + d.y); - } - - static class LatLng { - public double lat, lng; - public LatLng(double lat, double lng) { - this.lat = lat; - this.lng = lng; - } - } - - // based on google js - // http://maps.gstatic.com/intl/en_us/mapfiles/api-3/2/10/main.js - // search for fromLatLngToPoint and fromPointToLatLng - /* - private static Point2D.Double pt(LatLng latlng, int zoom) { - double scale_x = 256/360.0 * Math.pow(2, zoom); - double scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); - return pt(latlng, scale_x, scale_y); - } - */ - - private static Point2D.Double pt(LatLng latlng, - double scale_x, double scale_y) - { - Point2D.Double res = new Point2D.Double(); - double e; - - res.x = latlng.lng * scale_x; - - e = Math.sin(Math.toRadians(latlng.lat)); - e = Math.max(e,-(1-1.0E-15)); - e = Math.min(e, 1-1.0E-15 ); - - res.y = 0.5*Math.log((1+e)/(1-e))*-scale_y; - return res; - } - - static private LatLng latlng(Point2D.Double pt, - double scale_x, double scale_y) - { - double lat, lng; - double rads; - - lng = pt.x/scale_x; - rads = 2 * Math.atan(Math.exp(-pt.y/scale_y)); - lat = Math.toDegrees(rads - Math.PI/2); - - return new LatLng(lat,lng); - } - - int zoom; - double scale_x, scale_y; - - int radius; /* half width/height of tiles to load */ - - private Point2D.Double pt(double lat, double lng) { - return pt(new LatLng(lat, lng), scale_x, scale_y); - } - - private LatLng latlng(double x, double y) { - return latlng(new Point2D.Double(x,y), scale_x, scale_y); - } - /* - private LatLng latlng(Point2D.Double pt) { - return latlng(pt, scale_x, scale_y); - } - */ - - ConcurrentHashMap<Point,AltosSiteMapTile> mapTiles = new ConcurrentHashMap<Point,AltosSiteMapTile>(); - Point2D.Double centre; - - private Point2D.Double tileCoordOffset(Point p) { - return new Point2D.Double(centre.x - p.x*px_size, - centre.y - p.y * px_size); - } - - private Point tileOffset(Point2D.Double p) { - return new Point((int)Math.floor((centre.x+p.x)/px_size), - (int)Math.floor((centre.y+p.y)/px_size)); - } - - private Point2D.Double getBaseLocation(double lat, double lng) { - Point2D.Double locn, north_step; - - zoom = 2; - // stupid loop structure to please Java's control flow analysis - do { - zoom++; - scale_x = 256/360.0 * Math.pow(2, zoom); - scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom); - locn = pt(lat, lng); - north_step = pt(lat+tile_size_nmi*4/3/60.0, lng); - if (locn.y - north_step.y > px_size) - break; - } while (zoom < 22); - locn.x = -px_size * Math.floor(locn.x/px_size); - locn.y = -px_size * Math.floor(locn.y/px_size); - return locn; - } - - public void reset() { - // nothing - } - - public void set_font() { - // nothing - } - - private void loadMap(final AltosSiteMapTile tile, - File pngfile, String pngurl) - { - final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl); - if (res != null) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - tile.loadMap(res); - } - }); - } else { - System.out.printf("# Failed to fetch file %s\n", pngfile); - System.out.printf(" wget -O '%s' '%s'\n", pngfile, pngurl); - } - } - - File pngfile; - String pngurl; - - public int prefetchMap(int x, int y) { - LatLng map_latlng = latlng( - -centre.x + x*px_size + px_size/2, - -centre.y + y*px_size + px_size/2); - pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom); - pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom); - if (pngfile.exists()) { - return 1; - } else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) { - return 0; - } else { - return -1; - } - } - - public static void prefetchMaps(double lat, double lng) { - int w = AltosSiteMapPreload.width; - int h = AltosSiteMapPreload.height; - AltosSiteMap asm = new AltosSiteMap(true); - asm.centre = asm.getBaseLocation(lat, lng); - - //Point2D.Double p = new Point2D.Double(); - //Point2D.Double p2; - int dx = -w/2, dy = -h/2; - for (int y = dy; y < h+dy; y++) { - for (int x = dx; x < w+dx; x++) { - int r = asm.prefetchMap(x, y); - switch (r) { - case 1: - System.out.printf("Already have %s\n", asm.pngfile); - break; - case 0: - System.out.printf("Fetched map %s\n", asm.pngfile); - break; - case -1: - System.out.printf("# Failed to fetch file %s\n", asm.pngfile); - System.out.printf(" wget -O '%s' ''\n", asm.pngfile, asm.pngurl); - break; - } - } - } - } - - public String initMap(Point offset) { - AltosSiteMapTile tile = mapTiles.get(offset); - Point2D.Double coord = tileCoordOffset(offset); - - LatLng map_latlng = latlng(px_size/2-coord.x, px_size/2-coord.y); - - File pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom); - String pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom); - loadMap(tile, pngfile, pngurl); - return pngfile.toString(); - } - - public void initAndFinishMapAsync (final AltosSiteMapTile tile, final Point offset) { - Thread thread = new Thread() { - public void run() { - initMap(offset); - finishTileLater(tile, offset); - } - }; - thread.start(); - } - - public void setBaseLocation(double lat, double lng) { - for (Point k : mapTiles.keySet()) { - AltosSiteMapTile tile = mapTiles.get(k); - tile.clearMap(); - } - - centre = getBaseLocation(lat, lng); - scrollRocketToVisible(pt(lat,lng)); - } - - private void initMaps(double lat, double lng) { - setBaseLocation(lat, lng); - - Thread thread = new Thread() { - public void run() { - for (Point k : mapTiles.keySet()) - initMap(k); - } - }; - thread.start(); - } - - private static File MapFile(double lat, double lng, int zoom) { - char chlat = lat < 0 ? 'S' : 'N'; - char chlng = lng < 0 ? 'W' : 'E'; - if (lat < 0) lat = -lat; - if (lng < 0) lng = -lng; - return new File(AltosUIPreferences.mapdir(), - String.format("map-%c%.6f,%c%.6f-%d.png", - chlat, lat, chlng, lng, zoom)); - } - - private static String MapURL(double lat, double lng, int zoom) { - return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&sensor=false&maptype=hybrid&format=png32", lat, lng, zoom, px_size, px_size); - } - - boolean initialised = false; - Point2D.Double last_pt = null; - int last_state = -1; - - public void show(double lat, double lon) { - System.out.printf ("show %g %g\n", lat, lon); - return; -// initMaps(lat, lon); -// scrollRocketToVisible(pt(lat, lon)); - } - public void show(final AltosState state, final AltosListenerState listener_state) { - // if insufficient gps data, nothing to update - AltosGPS gps = state.gps; - - if (gps == null) - return; - - if (!gps.locked && gps.nsat < 4) - return; - - if (!initialised) { - if (state.pad_lat != AltosLib.MISSING && state.pad_lon != AltosLib.MISSING) { - initMaps(state.pad_lat, state.pad_lon); - initialised = true; - } else if (gps.lat != AltosLib.MISSING && gps.lon != AltosLib.MISSING) { - initMaps(gps.lat, gps.lon); - initialised = true; - } else { - return; - } - } - - final Point2D.Double pt = pt(gps.lat, gps.lon); - if (last_pt == pt && last_state == state.state) - return; - - if (last_pt == null) { - last_pt = pt; - } - boolean in_any = false; - for (Point offset : mapTiles.keySet()) { - AltosSiteMapTile tile = mapTiles.get(offset); - Point2D.Double ref, lref; - ref = translatePoint(pt, tileCoordOffset(offset)); - lref = translatePoint(last_pt, tileCoordOffset(offset)); - tile.show(state, listener_state, lref, ref); - if (0 <= ref.x && ref.x < px_size) - if (0 <= ref.y && ref.y < px_size) - in_any = true; - } - - Point offset = tileOffset(pt); - if (!in_any) { - Point2D.Double ref, lref; - ref = translatePoint(pt, tileCoordOffset(offset)); - lref = translatePoint(last_pt, tileCoordOffset(offset)); - - AltosSiteMapTile tile = createTile(offset); - tile.show(state, listener_state, lref, ref); - initAndFinishMapAsync(tile, offset); - } - - scrollRocketToVisible(pt); - - if (offset != tileOffset(last_pt)) { - ensureTilesAround(offset); - } - - last_pt = pt; - last_state = state.state; - } - - public void centre(Point2D.Double pt) { - Rectangle r = comp.getVisibleRect(); - Point2D.Double copt = translatePoint(pt, tileCoordOffset(topleft)); - int dx = (int)copt.x - r.width/2 - r.x; - int dy = (int)copt.y - r.height/2 - r.y; - r.x += dx; - r.y += dy; - comp.scrollRectToVisible(r); - } - - public void centre(AltosState state) { - if (!state.gps.locked && state.gps.nsat < 4) - return; - centre(pt(state.gps.lat, state.gps.lon)); - } - - public void draw_circle(double lat, double lon) { - final Point2D.Double pt = pt(lat, lon); - - for (Point offset : mapTiles.keySet()) { - AltosSiteMapTile tile = mapTiles.get(offset); - Point2D.Double ref = translatePoint(pt, tileCoordOffset(offset)); - tile.draw_circle(ref); - } - } - - private AltosSiteMapTile createTile(Point offset) { - AltosSiteMapTile tile = new AltosSiteMapTile(px_size); - mapTiles.put(offset, tile); - return tile; - } - private void finishTileLater(final AltosSiteMapTile tile, - final Point offset) - { - SwingUtilities.invokeLater( new Runnable() { - public void run() { - addTileAt(tile, offset); - } - } ); - } - - private void ensureTilesAround(Point base_offset) { - for (int x = -radius; x <= radius; x++) { - for (int y = -radius; y <= radius; y++) { - Point offset = new Point(base_offset.x + x, base_offset.y + y); - if (mapTiles.containsKey(offset)) - continue; - AltosSiteMapTile tile = createTile(offset); - initAndFinishMapAsync(tile, offset); - } - } - } - - private Point topleft = new Point(0,0); - private void scrollRocketToVisible(Point2D.Double pt) { - Rectangle r = comp.getVisibleRect(); - Point2D.Double copt = translatePoint(pt, tileCoordOffset(topleft)); - int dx = (int)copt.x - r.width/2 - r.x; - int dy = (int)copt.y - r.height/2 - r.y; - if (Math.abs(dx) > r.width/4 || Math.abs(dy) > r.height/4) { - r.x += dx; - r.y += dy; - comp.scrollRectToVisible(r); - } - } - - private void addTileAt(AltosSiteMapTile tile, Point offset) { - if (Math.abs(offset.x) >= MAX_TILE_DELTA || - Math.abs(offset.y) >= MAX_TILE_DELTA) - { - System.out.printf("Rocket too far away from pad (tile %d,%d)\n", - offset.x, offset.y); - return; - } - - boolean review = false; - Rectangle r = comp.getVisibleRect(); - if (offset.x < topleft.x) { - r.x += (topleft.x - offset.x) * px_size; - topleft.x = offset.x; - review = true; - } - if (offset.y < topleft.y) { - r.y += (topleft.y - offset.y) * px_size; - topleft.y = offset.y; - review = true; - } - GridBagConstraints c = new GridBagConstraints(); - c.anchor = GridBagConstraints.CENTER; - c.fill = GridBagConstraints.BOTH; - // put some space between the map tiles, debugging only - // c.insets = new Insets(5, 5, 5, 5); - - c.gridx = offset.x + MAX_TILE_DELTA; - c.gridy = offset.y + MAX_TILE_DELTA; - layout.setConstraints(tile, c); - - comp.add(tile); - if (review) { - comp.scrollRectToVisible(r); - } - } - - private AltosSiteMap(boolean knowWhatYouAreDoing) { - if (!knowWhatYouAreDoing) { - throw new RuntimeException("Arggh."); - } - } - - JComponent comp = new JComponent() { }; - private GridBagLayout layout = new GridBagLayout(); - - public AltosSiteMap(int in_radius) { - radius = in_radius; - - GrabNDrag scroller = new GrabNDrag(comp); - - comp.setLayout(layout); - - for (int x = -radius; x <= radius; x++) { - for (int y = -radius; y <= radius; y++) { - Point offset = new Point(x, y); - AltosSiteMapTile t = createTile(offset); - addTileAt(t, offset); - } - } - setViewportView(comp); - setPreferredSize(new Dimension(500,500)); - } - - public AltosSiteMap() { - this(1); - } -} diff --git a/altosui/AltosSiteMapCache.java b/altosui/AltosSiteMapCache.java deleted file mode 100644 index 03dc3cf5..00000000 --- a/altosui/AltosSiteMapCache.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright © 2010 Anthony Towns <aj@erisian.com.au> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import javax.swing.*; -import javax.imageio.ImageIO; -import java.awt.image.*; -import java.io.*; -import java.net.URL; -import java.net.URLConnection; - -public class AltosSiteMapCache extends JLabel { - static final long google_maps_ratelimit_ms = 1200; - // Google limits static map queries to 50 per minute per IP, so - // each query should take at least 1.2 seconds. - - public static boolean fetchMap(File file, String url) { - URL u; - long startTime = System.nanoTime(); - - try { - u = new URL(url); - } catch (java.net.MalformedURLException e) { - return false; - } - - byte[] data; - try { - URLConnection uc = u.openConnection(); - int contentLength = uc.getContentLength(); - InputStream in = new BufferedInputStream(uc.getInputStream()); - int bytesRead = 0; - int offset = 0; - data = new byte[contentLength]; - while (offset < contentLength) { - bytesRead = in.read(data, offset, data.length - offset); - if (bytesRead == -1) - break; - offset += bytesRead; - } - in.close(); - - if (offset != contentLength) { - return false; - } - } catch (IOException e) { - return false; - } - - try { - FileOutputStream out = new FileOutputStream(file); - out.write(data); - out.flush(); - out.close(); - } catch (FileNotFoundException e) { - return false; - } catch (IOException e) { - if (file.exists()) { - file.delete(); - } - return false; - } - - long duration_ms = (System.nanoTime() - startTime) / 1000000; - if (duration_ms < google_maps_ratelimit_ms) { - try { - Thread.sleep(google_maps_ratelimit_ms - duration_ms); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - return true; - } - - public static ImageIcon fetchAndLoadMap(File pngfile, String url) { - if (!pngfile.exists()) { - if (!fetchMap(pngfile, url)) { - return null; - } - } - return loadMap(pngfile, url); - } - - public static ImageIcon loadMap(File pngfile, String url) { - if (!pngfile.exists()) { - return null; - } - - try { - BufferedImage img; - - img = ImageIO.read(pngfile); - if (img == null) { - System.out.printf("# Can't read pngfile %s\n", pngfile); - return null; - } - return new ImageIcon(img); - } catch (IOException e) { - System.out.printf("# IO error trying to load %s\n", pngfile); - return null; - } - } -} diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java deleted file mode 100644 index 66399557..00000000 --- a/altosui/AltosSiteMapPreload.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright © 2011 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import java.io.*; -import java.util.*; -import java.text.*; -import java.lang.Math; -import java.net.URL; -import java.net.URLConnection; -import org.altusmetrum.altosuilib_1.*; - -class AltosMapPos extends Box { - AltosUI owner; - JLabel label; - JComboBox hemi; - JTextField deg; - JLabel deg_label; - JTextField min; - JLabel min_label; - - public void set_value(double new_value) { - double d, m; - int h; - - h = 0; - if (new_value < 0) { - h = 1; - new_value = -new_value; - } - d = Math.floor(new_value); - deg.setText(String.format("%3.0f", d)); - m = (new_value - d) * 60.0; - min.setText(String.format("%7.4f", m)); - hemi.setSelectedIndex(h); - } - - public double get_value() throws NumberFormatException { - int h = hemi.getSelectedIndex(); - String d_t = deg.getText(); - String m_t = min.getText(); - double d, m, v; - try { - d = Double.parseDouble(d_t); - } catch (NumberFormatException ne) { - JOptionPane.showMessageDialog(owner, - String.format("Invalid degrees \"%s\"", - d_t), - "Invalid number", - JOptionPane.ERROR_MESSAGE); - throw ne; - } - try { - if (m_t.equals("")) - m = 0; - else - m = Double.parseDouble(m_t); - } catch (NumberFormatException ne) { - JOptionPane.showMessageDialog(owner, - String.format("Invalid minutes \"%s\"", - m_t), - "Invalid number", - JOptionPane.ERROR_MESSAGE); - throw ne; - } - v = d + m/60.0; - if (h == 1) - v = -v; - return v; - } - - public AltosMapPos(AltosUI in_owner, - String label_value, - String[] hemi_names, - double default_value) { - super(BoxLayout.X_AXIS); - owner = in_owner; - label = new JLabel(label_value); - hemi = new JComboBox(hemi_names); - hemi.setEditable(false); - deg = new JTextField(5); - deg.setMinimumSize(deg.getPreferredSize()); - deg.setHorizontalAlignment(JTextField.RIGHT); - deg_label = new JLabel("°"); - min = new JTextField(9); - min.setMinimumSize(min.getPreferredSize()); - min_label = new JLabel("'"); - set_value(default_value); - add(label); - add(Box.createRigidArea(new Dimension(5, 0))); - add(hemi); - add(Box.createRigidArea(new Dimension(5, 0))); - add(deg); - add(Box.createRigidArea(new Dimension(5, 0))); - add(deg_label); - add(Box.createRigidArea(new Dimension(5, 0))); - add(min); - add(Box.createRigidArea(new Dimension(5, 0))); - add(min_label); - } -} - -class AltosSite { - String name; - double latitude; - double longitude; - - public String toString() { - return name; - } - - public AltosSite(String in_name, double in_latitude, double in_longitude) { - name = in_name; - latitude = in_latitude; - longitude = in_longitude; - } - - public AltosSite(String line) throws ParseException { - String[] elements = line.split(":"); - - if (elements.length < 3) - throw new ParseException(String.format("Invalid site line %s", line), 0); - - name = elements[0]; - - try { - latitude = Double.parseDouble(elements[1]); - longitude = Double.parseDouble(elements[2]); - } catch (NumberFormatException ne) { - throw new ParseException(String.format("Invalid site line %s", line), 0); - } - } -} - -class AltosSites extends Thread { - AltosSiteMapPreload preload; - URL url; - LinkedList<AltosSite> sites; - - void notify_complete() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - preload.set_sites(); - } - }); - } - - void add(AltosSite site) { - sites.add(site); - } - - void add(String line) { - try { - add(new AltosSite(line)); - } catch (ParseException pe) { - } - } - - public void run() { - try { - URLConnection uc = url.openConnection(); - //int length = uc.getContentLength(); - - InputStreamReader in_stream = new InputStreamReader(uc.getInputStream(), Altos.unicode_set); - BufferedReader in = new BufferedReader(in_stream); - - for (;;) { - String line = in.readLine(); - if (line == null) - break; - add(line); - } - } catch (IOException e) { - } finally { - notify_complete(); - } - } - - public AltosSites(AltosSiteMapPreload in_preload) { - sites = new LinkedList<AltosSite>(); - preload = in_preload; - try { - url = new URL(Altos.launch_sites_url); - } catch (java.net.MalformedURLException e) { - notify_complete(); - } - start(); - } -} - -public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener, ItemListener { - AltosUI owner; - AltosSiteMap map; - - AltosMapPos lat; - AltosMapPos lon; - - final static int radius = 5; - final static int width = (radius * 2 + 1); - final static int height = (radius * 2 + 1); - - JProgressBar pbar; - - AltosSites sites; - JLabel site_list_label; - JComboBox site_list; - - JToggleButton load_button; - boolean loading; - JButton close_button; - - static final String[] lat_hemi_names = { "N", "S" }; - static final String[] lon_hemi_names = { "E", "W" }; - - class updatePbar implements Runnable { - int n; - String s; - - public updatePbar(int x, int y, String in_s) { - n = (x + radius) + (y + radius) * width + 1; - s = in_s; - } - - public void run() { - pbar.setValue(n); - pbar.setString(s); - if (n < width * height) { - pbar.setValue(n); - pbar.setString(s); - } else { - pbar.setValue(0); - pbar.setString(""); - load_button.setSelected(false); - loading = false; - } - } - } - - class bgLoad extends Thread { - - AltosSiteMap map; - - public bgLoad(AltosSiteMap in_map) { - map = in_map; - } - - public void run() { - for (int y = -map.radius; y <= map.radius; y++) { - for (int x = -map.radius; x <= map.radius; x++) { - String pngfile; - pngfile = map.initMap(new Point(x,y)); - SwingUtilities.invokeLater(new updatePbar(x, y, pngfile)); - } - } - } - } - - public void set_sites() { - int i = 1; - for (AltosSite site : sites.sites) { - site_list.insertItemAt(site, i); - i++; - } - } - - public void itemStateChanged(ItemEvent e) { - int state = e.getStateChange(); - - if (state == ItemEvent.SELECTED) { - Object o = e.getItem(); - if (o instanceof AltosSite) { - AltosSite site = (AltosSite) o; - lat.set_value(site.latitude); - lon.set_value(site.longitude); - } - } - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - - if (cmd.equals("close")) - setVisible(false); - - if (cmd.equals("load")) { - if (!loading) { - try { - final double latitude = lat.get_value(); - final double longitude = lon.get_value(); - map.setBaseLocation(latitude,longitude); - map.draw_circle(latitude,longitude); - loading = true; - bgLoad thread = new bgLoad(map); - thread.start(); - } catch (NumberFormatException ne) { - load_button.setSelected(false); - } - } - } - } - - public AltosSiteMapPreload(AltosUI in_owner) { - owner = in_owner; - - Container pane = getContentPane(); - GridBagConstraints c = new GridBagConstraints(); - Insets i = new Insets(4,4,4,4); - - pane.setLayout(new GridBagLayout()); - - map = new AltosSiteMap(radius); - - c.fill = GridBagConstraints.BOTH; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 1; - - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; - - pane.add(map, c); - - pbar = new JProgressBar(); - pbar.setMinimum(0); - pbar.setMaximum(width * height); - pbar.setValue(0); - pbar.setString(""); - pbar.setStringPainted(true); - - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 0; - - c.gridx = 0; - c.gridy = 1; - c.gridwidth = 2; - - pane.add(pbar, c); - - site_list_label = new JLabel ("Known Launch Sites:"); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 0; - - c.gridx = 0; - c.gridy = 2; - c.gridwidth = 1; - - pane.add(site_list_label, c); - - site_list = new JComboBox(new String[] { "Site List" }); - site_list.addItemListener(this); - - sites = new AltosSites(this); - - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 0; - - c.gridx = 1; - c.gridy = 2; - c.gridwidth = 1; - - pane.add(site_list, c); - - lat = new AltosMapPos(owner, - "Latitude:", - lat_hemi_names, - 37.167833333); - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 0; - c.weighty = 0; - - c.gridx = 0; - c.gridy = 3; - c.gridwidth = 1; - c.anchor = GridBagConstraints.CENTER; - - pane.add(lat, c); - - lon = new AltosMapPos(owner, - "Longitude:", - lon_hemi_names, - -97.73975); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 0; - c.weighty = 0; - - c.gridx = 1; - c.gridy = 3; - c.gridwidth = 1; - c.anchor = GridBagConstraints.CENTER; - - pane.add(lon, c); - - load_button = new JToggleButton("Load Map"); - load_button.addActionListener(this); - load_button.setActionCommand("load"); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 0; - - c.gridx = 0; - c.gridy = 4; - c.gridwidth = 1; - c.anchor = GridBagConstraints.CENTER; - - pane.add(load_button, c); - - close_button = new JButton("Close"); - close_button.addActionListener(this); - close_button.setActionCommand("close"); - - c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.insets = i; - c.weightx = 1; - c.weighty = 0; - - c.gridx = 1; - c.gridy = 4; - c.gridwidth = 1; - c.anchor = GridBagConstraints.CENTER; - - pane.add(close_button, c); - - pack(); - setLocationRelativeTo(owner); - setVisible(true); - } -} diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java deleted file mode 100644 index 7d5b65e1..00000000 --- a/altosui/AltosSiteMapTile.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright © 2010 Anthony Towns <aj@erisian.com.au> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.image.*; -import javax.swing.*; -import java.awt.geom.Point2D; -import java.awt.geom.Line2D; -import org.altusmetrum.altoslib_3.*; - -public class AltosSiteMapTile extends JLayeredPane { - JLabel mapLabel; - JLabel draw; - Graphics2D g2d; - int px_size; - - public void loadMap(ImageIcon icn) { - mapLabel.setIcon(icn); - } - - public void clearMap() { - fillLabel(mapLabel, Color.GRAY, px_size); - g2d = fillLabel(draw, new Color(127,127,127,0), px_size); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); - } - - static Color stateColors[] = { - Color.WHITE, // startup - Color.WHITE, // idle - Color.WHITE, // pad - Color.RED, // boost - Color.PINK, // fast - Color.YELLOW, // coast - Color.CYAN, // drogue - Color.BLUE, // main - Color.BLACK // landed - }; - - private boolean drawn_landed_circle = false; - private boolean drawn_boost_circle = false; - public synchronized void show(AltosState state, AltosListenerState listener_state, - Point2D.Double last_pt, Point2D.Double pt) - { - if (0 <= state.state && state.state < stateColors.length) { - g2d.setColor(stateColors[state.state]); - } - g2d.draw(new Line2D.Double(last_pt, pt)); - - if (state.state == 3 && !drawn_boost_circle) { - drawn_boost_circle = true; - g2d.setColor(Color.RED); - g2d.drawOval((int)last_pt.x-5, (int)last_pt.y-5, 10, 10); - g2d.drawOval((int)last_pt.x-20, (int)last_pt.y-20, 40, 40); - g2d.drawOval((int)last_pt.x-35, (int)last_pt.y-35, 70, 70); - } - if (state.state == 8 && !drawn_landed_circle) { - drawn_landed_circle = true; - g2d.setColor(Color.BLACK); - g2d.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10); - g2d.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40); - g2d.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70); - } - - repaint(); - } - - public void draw_circle(Point2D.Double pt) { - g2d.setColor(Color.RED); - g2d.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10); - g2d.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40); - g2d.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70); - } - - public static Graphics2D fillLabel(JLabel l, Color c, int px_size) { - BufferedImage img = new BufferedImage(px_size, px_size, - BufferedImage.TYPE_INT_ARGB); - Graphics2D g = img.createGraphics(); - g.setColor(c); - g.fillRect(0, 0, px_size, px_size); - l.setIcon(new ImageIcon(img)); - return g; - } - - public AltosSiteMapTile(int in_px_size) { - px_size = in_px_size; - setPreferredSize(new Dimension(px_size, px_size)); - - mapLabel = new JLabel(); - fillLabel(mapLabel, Color.GRAY, px_size); - mapLabel.setOpaque(true); - mapLabel.setBounds(0, 0, px_size, px_size); - add(mapLabel, new Integer(0)); - - draw = new JLabel(); - g2d = fillLabel(draw, new Color(127, 127, 127, 0), px_size); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); - draw.setBounds(0, 0, px_size, px_size); - draw.setOpaque(false); - - add(draw, new Integer(1)); - } -} diff --git a/altosui/AltosUI.app/Contents/Resources/AltosUIIcon.icns b/altosui/AltosUI.app/Contents/Resources/AltosUIIcon.icns Binary files differdeleted file mode 100644 index fe49f362..00000000 --- a/altosui/AltosUI.app/Contents/Resources/AltosUIIcon.icns +++ /dev/null diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 5d459947..6137487c 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -22,8 +22,8 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_3.*; -import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; public class AltosUI extends AltosUIFrame { public AltosVoice voice = new AltosVoice(); @@ -74,6 +74,10 @@ public class AltosUI extends AltosUIFrame { } } + public void scan_device_selected(AltosDevice device) { + telemetry_window(device); + } + Container pane; GridBagLayout gridbag; @@ -233,7 +237,7 @@ public class AltosUI extends AltosUIFrame { }); setLocationByPlatform(false); - + /* Insets aren't set before the window is visible */ setVisible(true); } @@ -272,11 +276,11 @@ public class AltosUI extends AltosUIFrame { } void ScanChannels() { - new AltosScanUI(AltosUI.this); + new AltosScanUI(AltosUI.this, true); } void LoadMaps() { - new AltosSiteMapPreload(AltosUI.this); + new AltosUIMapPreload(AltosUI.this); } void LaunchController() { @@ -302,7 +306,7 @@ public class AltosUI extends AltosUIFrame { * a TeleDongle over the packet link */ private void SaveFlightData() { - new AltosEepromManage(AltosUI.this); + new AltosEepromManage(AltosUI.this, AltosLib.product_any); } /* Load a flight log file and write out a CSV file containing @@ -468,7 +472,7 @@ public class AltosUI extends AltosUIFrame { } return false; } - + static boolean process_summary(File file) { AltosStateIterable states = record_iterable(file); if (states == null) @@ -547,7 +551,7 @@ public class AltosUI extends AltosUIFrame { System.out.printf(" --kml\tgenerate KML output for use with Google Earth\n"); System.exit(code); } - + public static void main(final String[] args) { int errors = 0; load_library(null); @@ -574,7 +578,7 @@ public class AltosUI extends AltosUIFrame { } else { double lat = Double.parseDouble(args[i+1]); double lon = Double.parseDouble(args[i+2]); - AltosSiteMap.prefetchMaps(lat, lon); +// AltosSiteMap.prefetchMaps(lat, lon); i += 2; } } else if (args[i].equals("--replay")) diff --git a/altosui/AltosUIPreferencesBackend.java b/altosui/AltosUIPreferencesBackend.java index 697d9902..28047086 100644 --- a/altosui/AltosUIPreferencesBackend.java +++ b/altosui/AltosUIPreferencesBackend.java @@ -19,13 +19,13 @@ package altosui; import java.io.File; import java.util.prefs.*; -import org.altusmetrum.altoslib_3.*; +import org.altusmetrum.altoslib_4.*; import javax.swing.filechooser.FileSystemView; public class AltosUIPreferencesBackend implements AltosPreferencesBackend { private Preferences _preferences = null; - + public AltosUIPreferencesBackend() { _preferences = Preferences.userRoot().node("/org/altusmetrum/altosui"); } diff --git a/altosui/AltosVoice.java b/altosui/AltosVoice.java deleted file mode 100644 index 2ed6a8c2..00000000 --- a/altosui/AltosVoice.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import com.sun.speech.freetts.Voice; -import com.sun.speech.freetts.VoiceManager; -import java.util.concurrent.LinkedBlockingQueue; -import org.altusmetrum.altosuilib_1.*; - -public class AltosVoice implements Runnable { - VoiceManager voice_manager; - Voice voice; - LinkedBlockingQueue<String> phrases; - Thread thread; - boolean busy; - - final static String voice_name = "kevin16"; - - public void run() { - try { - for (;;) { - String s = phrases.take(); - voice.speak(s); - synchronized(this) { - if (phrases.isEmpty()) { - busy = false; - notifyAll(); - } - } - } - } catch (InterruptedException e) { - } - } - - public synchronized void drain() throws InterruptedException { - while (busy) - wait(); - } - - public void speak_always(String s) { - try { - if (voice != null) { - synchronized(this) { - busy = true; - phrases.put(s); - } - } - } catch (InterruptedException e) { - } - } - - public void speak(String s) { - if (AltosUIPreferences.voice()) - speak_always(s); - } - - public void speak(String format, Object... parameters) { - speak(String.format(format, parameters)); - } - - public AltosVoice () { - busy = false; - voice_manager = VoiceManager.getInstance(); - voice = voice_manager.getVoice(voice_name); - if (voice != null) { - voice.allocate(); - phrases = new LinkedBlockingQueue<String> (); - thread = new Thread(this); - thread.start(); - } else { - System.out.printf("Voice manager failed to open %s\n", voice_name); - Voice[] voices = voice_manager.getVoices(); - System.out.printf("Available voices:\n"); - for (int i = 0; i < voices.length; i++) { - System.out.println(" " + voices[i].getName() - + " (" + voices[i].getDomain() + " domain)"); - } - } - } -} diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java deleted file mode 100644 index 5ff44584..00000000 --- a/altosui/AltosWriter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright © 2010 Keith Packard <keithp@keithp.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import org.altusmetrum.altoslib_3.*; - - -public interface AltosWriter { - - public void write(AltosState state); - - public void write(AltosStateIterable states); - - public void close(); -} diff --git a/altosui/GrabNDrag.java b/altosui/GrabNDrag.java deleted file mode 100644 index 2fd6c4da..00000000 --- a/altosui/GrabNDrag.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2010 Anthony Towns <aj@erisian.com.au> - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.MouseInputAdapter; - -class GrabNDrag extends MouseInputAdapter { - private JComponent scroll; - private Point startPt = new Point(); - - public GrabNDrag(JComponent scroll) { - this.scroll = scroll; - scroll.addMouseMotionListener(this); - scroll.addMouseListener(this); - scroll.setAutoscrolls(true); - } - - public void mousePressed(MouseEvent e) { - startPt.setLocation(e.getPoint()); - } - public void mouseDragged(MouseEvent e) { - int xd = e.getX() - startPt.x; - int yd = e.getY() - startPt.y; - - Rectangle r = scroll.getVisibleRect(); - r.x -= xd; - r.y -= yd; - scroll.scrollRectToVisible(r); - } -} diff --git a/altosui/Makefile-standalone b/altosui/Makefile-standalone index 23163e40..cbaf9743 100644 --- a/altosui/Makefile-standalone +++ b/altosui/Makefile-standalone @@ -181,7 +181,7 @@ $(DARWIN_ZIP): $(DARWIN_FILES) cp $(DARWIN_EXTRA) darwin/AltOS cd darwin && zip -r ../$@ AltosUI.app AltOS -WINDOWS_FILES = $(FAT_FILES) libaltos/altos.dll ../telemetrum.inf $(WINDOWS_ICON) +WINDOWS_FILES = $(FAT_FILES) libaltos/altos.dll ../altusmetrum.inf $(WINDOWS_ICON) $(WINDOWS_EXE): $(WINDOWS_FILES) altos-windows.nsi rm -f $@ diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 32a3df97..98a5e193 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -1,6 +1,6 @@ JAVAROOT=classes -AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6 man_MANS=altosui.1 @@ -10,71 +10,31 @@ CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="$(JAVAROOT):../altoslib/*:../alto bin_SCRIPTS=altosui -altosui_BT = \ - AltosBTDevice.java \ - AltosBTDeviceIterator.java \ - AltosBTManage.java \ - AltosBTKnown.java - altosui_JAVA = \ - GrabNDrag.java \ AltosAscent.java \ AltosChannelMenu.java \ AltosCompanionInfo.java \ AltosConfig.java \ - AltosConfigFreqUI.java \ AltosConfigUI.java \ AltosConfigPyroUI.java \ AltosConfigureUI.java \ AltosConfigTD.java \ AltosConfigTDUI.java \ - AltosCSV.java \ - AltosCSVUI.java \ AltosDescent.java \ - AltosDeviceUIDialog.java \ - AltosDisplayThread.java \ - AltosEepromDelete.java \ - AltosEepromManage.java \ - AltosEepromMonitorUI.java \ - AltosEepromSelect.java \ - AltosFlashUI.java \ - AltosFlightDisplay.java \ - AltosFlightInfoTableModel.java \ - AltosFlightStats.java \ - AltosFlightStatsTable.java \ AltosFlightStatus.java \ AltosFlightStatusUpdate.java \ AltosFlightUI.java \ - AltosFreqList.java \ Altos.java \ AltosIdleMonitorUI.java \ AltosIgniteUI.java \ + AltosIgnitor.java \ AltosLaunch.java \ AltosLaunchUI.java \ - AltosInfoTable.java \ - AltosKML.java \ AltosLanded.java \ - AltosLed.java \ - AltosLights.java \ AltosPad.java \ AltosUIPreferencesBackend.java \ - AltosRomconfigUI.java \ - AltosScanUI.java \ - AltosSerial.java \ - AltosSerialInUseException.java \ - AltosSiteMap.java \ - AltosSiteMapPreload.java \ - AltosSiteMapCache.java \ - AltosSiteMapTile.java \ AltosUI.java \ - AltosWriter.java \ - AltosGraph.java \ - AltosGraphDataPoint.java \ - AltosGraphDataSet.java \ - AltosGraphUI.java \ - AltosDataChooser.java \ - AltosVoice.java \ - $(altosui_BT) + AltosGraphUI.java JFREECHART_CLASS= \ jfreechart.jar @@ -103,6 +63,10 @@ LIBALTOS= \ libaltos.dylib \ altos.dll +desktopdir = $(datadir)/applications +desktop_file = altos.desktop +desktop_SCRIPTS = $(desktop_file) + JAR=altosui.jar FATJAR=altosui-fat.jar @@ -118,22 +82,16 @@ JAVA_ICONS=\ $(ICONDIR)/altus-metrum-128.png \ $(ICONDIR)/altus-metrum-256.png -ICONS= $(ICONDIR)/redled.png $(ICONDIR)/redoff.png \ - $(ICONDIR)/greenled.png $(ICONDIR)/greenoff.png \ - $(ICONDIR)/grayled.png $(ICONDIR)/grayoff.png - # icon base names for jar ICONJAR= -C $(ICONDIR) altus-metrum-16.png \ -C $(ICONDIR) altus-metrum-32.png \ -C $(ICONDIR) altus-metrum-48.png \ -C $(ICONDIR) altus-metrum-64.png \ -C $(ICONDIR) altus-metrum-128.png \ - -C $(ICONDIR) altus-metrum-256.png \ - -C $(ICONDIR) redled.png -C $(ICONDIR) redoff.png \ - -C $(ICONDIR) greenled.png -C $(ICONDIR) greenoff.png \ - -C $(ICONDIR) grayon.png -C $(ICONDIR) grayled.png + -C $(ICONDIR) altus-metrum-256.png WINDOWS_ICON=$(ICONDIR)/altus-metrum.ico +MACOSX_ICON=$(ICONDIR)/AltosUIIcon.icns # Firmware FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx @@ -156,7 +114,10 @@ FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx FIRMWARE_EMINI=$(FIRMWARE_EMINI_1_0) -FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) +FIRMWARE_TGPS_1_0=$(top_srcdir)/src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx +FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) + +FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf ALTOS_DOC=$(top_srcdir)/doc/altos.pdf @@ -171,6 +132,7 @@ DOC=$(ALTUSMETRUM_DOC) $(ALTOS_DOC) $(TELEMETRY_DOC) $(TEMPLATE_DOC) # Distribution targets LINUX_DIST=Altos-Linux-$(VERSION).tar.bz2 +LINUX_SH=Altos-Linux-$(VERSION).sh MACOSX_DIST=Altos-Mac-$(VERSION).dmg WINDOWS_DIST=Altos-Windows-$(VERSION_DASH).exe @@ -178,37 +140,48 @@ FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFR LINUX_LIBS=libaltos32.so libaltos64.so -LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) +LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) altos.desktop.in ../icon/altusmetrum.svg LINUX_EXTRA=altosui-fat MACOSX_INFO_PLIST=Info.plist -MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(DOC) ReadMe-Mac.rtf +MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(DOC) ReadMe-Mac.rtf $(MACOSX_ICON) MACOSX_EXTRA=$(FIRMWARE) -WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON) +WINDOWS_FILES=$(FAT_FILES) $(FIRMWARE) altos.dll altos64.dll $(top_srcdir)/altusmetrum.inf $(top_srcdir)/altusmetrum.cat $(WINDOWS_ICON) all-local: classes/altosui $(JAR) altosui altosui-test altosui-jdb clean-local: -rm -rf classes $(JAR) $(FATJAR) \ - $(LINUX_DIST) $(MACOSX_DIST) windows $(WINDOWS_DIST) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) \ + $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) windows $(WINDOWS_DIST) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) \ $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt altos-windows.log altos-windows.nsi \ altosui altosui-test altosui-jdb macosx linux +EXTRA_DIST = $(desktop_file).in + +$(desktop_file): $(desktop_file).in + sed -e 's#%bindir%#@bindir@#' -e 's#%icondir%#$(datadir)/icons/hicolor/scalable/apps#' ${srcdir}/altos.desktop.in > $@ + chmod +x $@ + if FATINSTALL FATTARGET=$(FATDIR)/$(VERSION) LINUX_DIST_TARGET=$(FATTARGET)/$(LINUX_DIST) +LINUX_SH_TARGET=$(FATTARGET)/$(LINUX_SH) MACOSX_DIST_TARGET=$(FATTARGET)/$(MACOSX_DIST) WINDOWS_DIST_TARGET=$(FATTARGET)/$(WINDOWS_DIST) -fat: $(LINUX_DIST_TARGET) $(MACOSX_DIST_TARGET) $(WINDOWS_DIST_TARGET) +fat: $(LINUX_DIST_TARGET) $(LINUX_SH_TARGET) $(MACOSX_DIST_TARGET) $(WINDOWS_DIST_TARGET) $(LINUX_DIST_TARGET): $(LINUX_DIST) mkdir -p $(FATTARGET) cp -p $< $@ +$(LINUX_SH_TARGET): $(LINUX_SH) + mkdir -p $(FATTARGET) + cp -p $< $@ + $(MACOSX_DIST_TARGET): $(MACOSX_DIST) mkdir -p $(FATTARGET) cp -p $< $@ @@ -218,7 +191,7 @@ $(WINDOWS_DIST_TARGET): $(WINDOWS_DIST) cp -p $< $@ else -fat: $(LINUX_DIST) $(MACOSX_DIST) $(WINDOWS_DIST) +fat: $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) $(WINDOWS_DIST) endif @@ -259,8 +232,12 @@ altosui: Makefile chmod +x $@ altosui-test: Makefile - echo "#!/bin/sh" > $@ - echo 'exec java -Djava.library.path="../libaltos/.libs" -jar altosui.jar "$$@"' >> $@ + echo '#!/bin/sh' > $@ + echo 'dir="$$(dirname $$0)"' >> $@ + echo 'cd "$$dir"' >> $@ + echo 'altosui="$$(pwd -P)"' >> $@ + echo 'altos="$$(dirname $$altosui)"' >> $@ + echo 'exec java -Djava.library.path="$$altos/libaltos/.libs" -jar "$$altosui/altosui.jar" "$$@"' >> $@ chmod +x $@ altosui-jdb: Makefile @@ -333,6 +310,10 @@ $(LINUX_DIST): $(LINUX_FILES) $(LINUX_EXTRA) chmod +x linux/AltOS/altosui tar cjf $@ -C linux AltOS +$(LINUX_SH): $(LINUX_DIST) linux-install.sh + cat linux-install.sh $(LINUX_DIST) > $@ + chmod +x $@ + $(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile -rm -f $@ -rm -rf macosx @@ -343,6 +324,7 @@ $(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile cp -a $(DOC) macosx/Doc cp -p Info.plist macosx/AltosUI.app/Contents mkdir -p macosx/AltOS-$(VERSION) macosx/AltosUI.app/Contents/Resources/Java + cp -p $(MACOSX_ICON) macosx/AltosUI.app/Contents/Resources cp -p $(FATJAR) macosx/AltosUI.app/Contents/Resources/Java/altosui.jar cp -p libaltos.dylib macosx/AltosUI.app/Contents/Resources/Java cp -p $(ALTOSLIB_CLASS) macosx/AltosUI.app/Contents/Resources/Java @@ -355,5 +337,4 @@ $(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile $(WINDOWS_DIST): $(WINDOWS_FILES) altos-windows.nsi -rm -f $@ - makensis -Oaltos-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" altos-windows.nsi - + makensis -Oaltos-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" altos-windows.nsi || (cat altos-windows.log && exit 1) diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index 3832e901..b72772e2 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -1,8 +1,10 @@ !addplugindir Instdrv/NSIS/Plugins -; Definitions for Java 1.6 Detection -!define JRE_VERSION "1.6" -!define JRE_ALTERNATE "1.7" -!define JRE_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=52247&/jre-6u27-windows-i586-p.exe" +!include x64.nsh +; Definitions for Java 1.7 Detection +!define JRE_VERSION "1.7" +!define JRE_ALTERNATE "1.6" +!define JRE32_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=83383&/jre-7u51-windows-i586.exe" +!define JRE64_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=83385&/jre-7u51-windows-x64.exe" !define PRODUCT_NAME "Altus Metrum Windows Software" Name "Altus Metrum Installer" @@ -23,12 +25,34 @@ ShowInstDetails Show ComponentText "Altus Metrum Software and Driver Installer" +Function .onInit + DetailPrint "Checking host operating system" + ${If} ${RunningX64} + DetailPrint "Installer running on 64-bit host" + SetRegView 64 + StrCpy $INSTDIR "$PROGRAMFILES64\AltusMetrum" + ${DisableX64FSRedirection} + ${EndIf} +FunctionEnd + +Var JavaDownload +Var JavaBits + Function GetJRE - MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \ - be downloaded and installed" + ${If} ${RunningX64} + StrCpy $JavaDownload ${JRE64_URL} + StrCpy $JavaBits "64" + ${Else} + StrCpy $JavaDownload ${JRE32_URL} + StrCpy $JavaBits "32" + ${EndIf} + + MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION}, \ + $JavaBits bits, it will now \ + be downloaded and installed" StrCpy $2 "$TEMP\Java Runtime Environment.exe" - nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2 + nsisdl::download /TIMEOUT=30000 $JavaDownload $2 Pop $R0 ;Get the return value StrCmp $R0 "success" +3 MessageBox MB_OK "Download failed: $R0" @@ -37,10 +61,10 @@ Function GetJRE Delete $2 FunctionEnd - Function DetectJRE ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \ "CurrentVersion" + StrCmp $2 ${JRE_VERSION} done StrCmp $2 ${JRE_ALTERNATE} done @@ -70,15 +94,18 @@ Section "Install Driver" InstDriver InstDrv::DeleteOemInfFiles /NOUNLOAD InstDrv::CreateDevice /NOUNLOAD - SetOutPath $TEMP - File "../telemetrum.inf" - InstDrv::InstallDriver /NOUNLOAD "$TEMP\telemetrum.inf" - SetOutPath $INSTDIR - File "../telemetrum.inf" - - SetOutPath $WINDIR\Inf - File "../telemetrum.inf" + File "../altusmetrum.inf" + File "../altusmetrum.cat" + + ${DisableX64FSRedirection} + IfFileExists $WINDIR\System32\PnPutil.exe 0 nopnp + ${DisableX64FSRedirection} + nsExec::ExecToLog '"$WINDIR\System32\PnPutil.exe" -i -a "$INSTDIR\altusmetrum.inf"' + Goto done +nopnp: + InstDrv::InstallDriver /NOUNLOAD "$INSTDIR\altusmetrum.inf" +done: SectionEnd @@ -119,6 +146,7 @@ Section "TeleMetrum, TeleDongle and TeleBT Firmware" File "../src/telemetrum-v1.1/telemetrum-v1.1-${VERSION}.ihx" File "../src/telemetrum-v1.2/telemetrum-v1.2-${VERSION}.ihx" File "../src/telemini-v1.0/telemini-v1.0-${VERSION}.ihx" + File "../src/telegps-v1.0/telegps-v1.0-${VERSION}.ihx" File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx" File "../src/telebt-v1.0/telebt-v1.0-${VERSION}.ihx" File "../src/telemega-v1.0/telemega-v1.0-${VERSION}.ihx" @@ -164,9 +192,6 @@ Section "Uninstall" Delete "$INSTDIR\*.*" RMDir "$INSTDIR" - ; Remove .inf file - Delete "$WINDIR\Inf\telemetrum.inf" - ; Remove devices InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} AltusMetrumSerial InstDrv::DeleteOemInfFiles /NOUNLOAD diff --git a/altosui/altos.desktop.in b/altosui/altos.desktop.in new file mode 100644 index 00000000..66114348 --- /dev/null +++ b/altosui/altos.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Name=AltOS UI +GenericName=Altus Metrum Ground Station +Comment=View and log downlink data from Altus Metrum products +Icon=%icondir%/altusmetrum.svg +Exec=%bindir%/altosui %f +Terminal=false +MimeType=text/plain; +Categories=Education;Electronics;Science; diff --git a/altosui/linux-install.sh b/altosui/linux-install.sh new file mode 100644 index 00000000..957b1aad --- /dev/null +++ b/altosui/linux-install.sh @@ -0,0 +1,239 @@ +#!/bin/sh + +can_ask=y + +finish() +{ + if [ "$can_ask" = "y" ]; then + echo "" + echo -n "Press enter to continue..." + read foo + fi + exit $1 +} + +# +# Make sure we have a terminal to talk to +# + +if tty -s; then + : +else + case "$DISPLAY" in + "") + echo 'No user input available' + can_ask=n + ;; + *) + GUESS_XTERMS="x-terminal-emulator xterm rxvt roxterm gnome-terminal dtterm eterm Eterm kvt konsole aterm" + for a in $GUESS_XTERMS; do + if type $a >/dev/null 2>&1; then + XTERM=$a + break + fi + done + case "$XTERM" in + "") + echo 'No terminal emulator available' + can_ask=n + ;; + *) + exec "$XTERM" -e "sh '$0'" + ;; + esac + ;; + esac +fi + +# +# Make sure we can run java +# + +echo -n "Checking for java..." + +if java -version > /dev/null 2>&1; then + echo " found it." +else + echo " java isn't working." + echo "" + echo "You'll need to install a java runtime system" + echo "on this computer before AltOS will work properly." + finish 1 +fi + +# +# Pick an installation target +# + +if [ '(' -d /opt -a -w /opt ')' -o '(' -d /opt/AltOS -a -w /opt/AltOS ')' ]; then + target_default=/opt +else + target_default="$HOME" +fi + +case "$#" in +0) + echo -n "Installation location [default: $target_default] " + if [ "$can_ask" = "y" ]; then + read target + else + echo "" + target="" + fi + case "$target" in + "") + target="$target_default" + ;; + esac + ;; +*) + target="$1" + ;; +esac + +target_altos="$target"/AltOS + +echo -n "Installing to $target..." + +# +# Make sure the target exists +# +mkdir -p "$target_altos" + +if [ ! -d "$target_altos" ]; then + echo "$target_altos does not exist and cannot be created" + finish 1 +fi + +if [ ! -w "$target_altos" ]; then + echo "$target_altos cannot be written" + finish 1 +fi + +# +# Unpack the tar archive appended to the end of this script +# +archive_line=`awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' "$0"` + +tail -n+$archive_line "$0" | tar xjf - -C "$target" + +case $? in +0) + echo " done." + ;; +*) + echo "Install failed." + finish 1 + ;; +esac + +# +# Create the .desktop file by editing the paths +# +case "$target" in +/*) + target_abs="$target" + ;; +*) + target_abs=`pwd`/$target + ;; +esac + +BIN="$target_abs"/AltOS + +for infile in "$target"/AltOS/*.desktop.in; do + desktop="$target"/AltOS/`basename "$infile" .in` + rm -f "$desktop" + sed -e "s;%bindir%;$BIN;" -e "s;%icondir%;$BIN;" "$infile" > "$desktop" + chmod +x "$desktop" +done + +# +# Figure out where to install the .desktop files. If we can, write it +# to the public /usr/share/applications, otherwise, write it to the +# per-user ~/.local/share/applications +# + +public=/usr/share/applications +private=$HOME/.local/share/applications +apps="" + +if [ -d "$public" -a -w "$public" ]; then + apps="$public" +else + mkdir -p "$private" >/dev/null 2>&1 + if [ -d "$private" -a -w "$private" ]; then + apps="$private" + fi +fi + +case "$apps" in +"") + echo "Cannot install application icon" + finish 1 + ;; +esac + +echo -n "Installing .desktop files to $apps..." + +cp "$target"/AltOS/*.desktop "$apps" + +case "$?" in +0) + echo " done." + ;; +*) + echo " failed." + ;; +esac + +# +# Install icon to desktop if desired +# + +if [ -d $HOME/Desktop ]; then + default_desktop=n + if [ "$can_ask" = "y" ]; then + : + else + default_desktop=y + fi + + answered=n + while [ "$answered" = "n" ]; do + echo -n "Install icons to desktop? [default: $default_desktop] " + if [ "$can_ask" = "y" ]; then + read do_desktop + else + echo + do_desktop="" + fi + + case "$do_desktop" in + "") + do_desktop=$default_desktop + ;; + esac + + case "$do_desktop" in + [yYnN]*) + answered=y + ;; + esac + done + + echo -n "Installing desktop icons..." + case "$do_desktop" in + [yY]*) + for d in "$target"/AltOS/*.desktop; do + ln -f -s "$d" "$HOME/Desktop/" + done + ;; + esac + + echo " done." +fi + +finish 0 + +__ARCHIVE_BELOW__ |
