telegps: Add first version of telegps
authorKeith Packard <keithp@keithp.com>
Wed, 28 May 2014 23:08:30 +0000 (16:08 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 28 May 2014 23:08:30 +0000 (16:08 -0700)
Not much implemented yet, but a shell of the UI and the map

Signed-off-by: Keith Packard <keithp@keithp.com>
Makefile.am
configure.ac
telegps/Info.plist.in [new file with mode: 0644]
telegps/Makefile.am [new file with mode: 0644]
telegps/TeleGPS.java [new file with mode: 0644]
telegps/TeleGPSStatus.java [new file with mode: 0644]
telegps/TeleGPSStatusUpdate.java [new file with mode: 0644]
telegps/telegps-windows.nsi.in [new file with mode: 0644]
telegps/telegps.1 [new file with mode: 0644]
telegps/telegps.desktop.in [new file with mode: 0644]

index f035bb39f4bf5c4e162c9475796f4123dec0148b..919dc2a9586dd919d7ab9209601f8b6c0283bf8e 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS=ao-tools src doc icon altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid
+SUBDIRS=ao-tools src doc icon altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid telegps
 
 EXTRA_DIST = ChangeLog
 
 
 EXTRA_DIST = ChangeLog
 
@@ -22,4 +22,4 @@ fat:
        cd micropeak && $(MAKE) fat
 
 set-java-versions:
        cd micropeak && $(MAKE) fat
 
 set-java-versions:
-       $(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION)
\ No newline at end of file
+       $(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION)
index dfbe59bcc0e96543218c465a2930067dbdcf3250..4f7874bb51d19760f23a126285f1ff0ef8cc8970 100644 (file)
@@ -511,6 +511,9 @@ libaltos/Makefile
 micropeak/Makefile
 micropeak/Info.plist
 micropeak/micropeak-windows.nsi
 micropeak/Makefile
 micropeak/Info.plist
 micropeak/micropeak-windows.nsi
+telegps/Makefile
+telegps/Info.plist
+telegps/telegps-windows.nsi
 altosdroid/Makefile
 altosdroid/local.properties
 ao-tools/Makefile
 altosdroid/Makefile
 altosdroid/local.properties
 ao-tools/Makefile
diff --git a/telegps/Info.plist.in b/telegps/Info.plist.in
new file mode 100644 (file)
index 0000000..40984c5
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+       <key>CFBundleName</key>
+       <string>MicroPeak</string>
+       <key>CFBundleVersion</key>
+       <string>@VERSION@</string>
+       <key>CFBundleAllowMixedLocalizations</key>
+       <string>true</string>
+       <key>CFBundleExecutable</key>
+       <string>JavaApplicationStub</string>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleIdentifier</key>
+       <string>org.altusmetrum.micropeak</string>
+       <key>CFBundleSignature</key>
+       <string>Altu</string>
+       <key>CFBundleGetInfoString</key>
+       <string>MicroPeak UI version @VERSION@</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleIconFile</key>
+       <string>MicroPeak.icns</string>
+       <key>Java</key>
+       <dict>
+               <key>MainClass</key>
+               <string>org.altusmetrum.micropeak.MicroPeak</string>
+               <key>JVMVersion</key>
+               <string>1.5+</string>
+               <key>ClassPath</key>
+               <array>
+                       <string>$JAVAROOT/micropeak.jar</string>
+               </array>
+               <key>Properties</key>
+               <dict>
+                 <key>apple.laf.useScreenMenuBar</key>
+                 <string>true</string>
+               </dict>
+               <key>VMOptions</key>
+               <array>
+                 <string>-Xms512M</string>
+                 <string>-Xmx512M</string>
+                 <string>-Dosgi.clean=true</string>
+               </array>
+       </dict>
+</dict>
+</plist>
diff --git a/telegps/Makefile.am b/telegps/Makefile.am
new file mode 100644 (file)
index 0000000..cd2de1f
--- /dev/null
@@ -0,0 +1,268 @@
+JAVAROOT=classes
+AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6
+
+man_MANS=telegps.1
+
+altoslibdir=$(libdir)/altos
+
+CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../altosuilib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar"
+
+bin_SCRIPTS=telegps
+
+telegpsdir=$(datadir)/java
+
+telegps_JAVA= \
+       TeleGPS.java \
+       TeleGPSStatus.java \
+       TeleGPSStatusUpdate.java
+
+JFREECHART_CLASS= \
+    jfreechart.jar
+
+JCOMMON_CLASS=\
+    jcommon.jar
+
+JAR=telegps.jar
+
+FATJAR=telegps-fat.jar
+
+LIBALTOS= \
+       libaltos.so \
+       libaltos.dylib \
+       altos64.dll \
+       altos.dll
+
+ALTOSLIB_CLASS=\
+       altoslib_$(ALTOSLIB_VERSION).jar
+
+ALTOSUILIB_CLASS=\
+       altosuilib_$(ALTOSUILIB_VERSION).jar
+
+# Icons
+ICONDIR=$(top_srcdir)/icon
+
+JAVA_ICONS=\
+       $(ICONDIR)/telegps-16.png \
+       $(ICONDIR)/telegps-32.png \
+       $(ICONDIR)/telegps-48.png \
+       $(ICONDIR)/telegps-64.png \
+       $(ICONDIR)/telegps-128.png \
+       $(ICONDIR)/telegps-256.png
+
+# icon base names for jar
+ICONJAR= -C $(ICONDIR) telegps-16.png \
+       -C $(ICONDIR) telegps-32.png \
+       -C $(ICONDIR) telegps-48.png \
+       -C $(ICONDIR) telegps-64.png \
+       -C $(ICONDIR) telegps-128.png \
+       -C $(ICONDIR) telegps-256.png
+
+WINDOWS_ICON=$(ICONDIR)/telegps.ico
+
+desktopdir = $(datadir)/applications
+desktop_file = telegps.desktop
+desktop_SCRIPTS = $(desktop_file)
+
+all-local: telegps-test telegps-jdb $(JAR)
+
+clean-local:
+       -rm -rf classes $(JAR) $(FATJAR) \
+               TeleGPS-Linux-*.tar.bz2 TeleGPS-Mac-*.dmg TeleGPS-Windows-*.exe \
+               $(ALTOSLIB_CLASS) \
+               $(ALTOSUILIB_CLASS) \
+               $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
+               telegps telegps-test telegps-jdb macosx linux windows telegps-windows.log \
+               telegps-windows.nsi
+
+EXTRA_DIST = $(desktop_file).in
+
+$(desktop_file): $(desktop_file).in
+       sed -e 's#%bindir%#@bindir@#' -e 's#%icondir%#$(datadir)/icons/hicolor/scalable/apps#' ${srcdir}/telegps.desktop.in > $@
+       chmod +x $@
+
+LINUX_DIST=TeleGPS-Linux-$(VERSION).tar.bz2
+LINUX_SH=TeleGPS-Linux-$(VERSION).sh
+MACOSX_DIST=TeleGPS-Mac-$(VERSION).dmg
+WINDOWS_DIST=TeleGPS-Windows-$(VERSION_DASH).exe
+
+MICROPEAK_DOC=$(top_srcdir)/doc/telegps.pdf
+
+DOC=$(MICROPEAK_DOC)
+
+FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
+
+LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) telegps.desktop.in ../icon/telegps.svg
+LINUX_EXTRA=telegps-fat telegps.desktop.in
+
+MACOSX_DRIVER_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg
+MACOSX_DRIVER=FTDIUSBSerialDriver_v2_2_18.dmg
+MACOSX_INFO_PLIST=Info.plist
+MACOSX_README=ReadMe-Mac.rtf
+MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README) $(DOC)
+
+$(MACOSX_DRIVER):
+       wget $(MACOSX_DRIVER_URL)
+
+WINDOWS_DRIVER_URL=http://www.ftdichip.com/Drivers/CDM/CDM20824_Setup.exe
+WINDOWS_DRIVER=CDM20824_Setup.exe
+
+$(WINDOWS_DRIVER):
+       wget $(WINDOWS_DRIVER_URL)
+
+WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(DOC) $(WINDOWS_ICON) $(WINDOWS_DRIVER)
+
+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) $(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 $< $@
+
+$(WINDOWS_DIST_TARGET): $(WINDOWS_DIST)
+       mkdir -p $(FATTARGET)
+       cp -p $< $@
+
+else
+fat: $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) $(WINDOWS_DIST)
+endif
+
+telegps: Makefile
+       echo "#!/bin/sh" > $@
+       echo 'exec java  -Djava.library.path="$(altoslibdir)" -jar "$(telegpsdir)/telegps.jar" "$$@"' >> $@
+       chmod +x $@
+
+telegps-jdb: Makefile
+       echo "#!/bin/sh" > $@
+       echo 'exec jdb -classpath "classes:./*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" org.altusmetrum.telegps.TeleGPS "$$@"' >> $@
+       chmod +x $@
+
+telegps-test: Makefile
+       echo "#!/bin/sh" > $@
+       echo 'exec java -Djava.library.path="../libaltos/.libs" -jar telegps.jar "$$@"' >> $@
+       chmod +x $@
+
+install-telegpsJAVA: telegps.jar
+       @$(NORMAL_INSTALL)
+       test -z "$(telegpsdir)" || $(MKDIR_P) "$(DESTDIR)$(telegpsdir)"
+       echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(telegpsdir)/telegps.jar'"; \
+       $(INSTALL_DATA) "$<" "$(DESTDIR)$(telegpsdir)"
+
+$(JAR): classtelegps.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS)
+       jar cfm $@ Manifest.txt \
+               $(ICONJAR) \
+               -C classes org \
+               -C ../libaltos libaltosJNI
+
+$(FATJAR): classtelegps.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(JAVA_ICONS)
+       jar cfm $@ Manifest-fat.txt \
+               $(ICONJAR) \
+               -C classes org \
+               -C ../libaltos libaltosJNI
+
+classaltosui.stamp: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS)
+
+libaltos.so: build-libaltos
+       -rm -f "$@"
+       $(LN_S) ../libaltos/.libs/"$@" .
+
+libaltos.dylib:
+       -rm -f "$@"
+       $(LN_S) ../libaltos/"$@" .
+
+altos.dll: ../libaltos/altos.dll
+       -rm -f "$@"
+       $(LN_S) ../libaltos/"$@" .
+
+altos64.dll: ../libaltos/altos64.dll
+       -rm -f "$@"
+       $(LN_S) ../libaltos/"$@" .
+
+../libaltos/.libs/libaltos.so: build-libaltos
+
+../libaltos/altos.dll: build-altos-dll
+
+../libaltos/altos64.dll: build-altos64-dll
+
+build-libaltos:
+       +cd ../libaltos && make libaltos.la
+build-altos-dll:
+       +cd ../libaltos && make altos.dll
+
+build-altos64-dll:
+       +cd ../libaltos && make altos64.dll
+
+$(ALTOSLIB_CLASS):
+       -rm -f "$@"
+       $(LN_S) ../altoslib/"$@" .
+
+$(ALTOSUILIB_CLASS):
+       -rm -f "$@"
+       $(LN_S) ../altosuilib/"$@" .
+
+$(JFREECHART_CLASS):
+       -rm -f "$@"
+       $(LN_S) "$(JFREECHART)"/"$@" .
+
+$(JCOMMON_CLASS):
+       -rm -f "$@"
+       $(LN_S) "$(JCOMMON)"/"$@" .
+
+$(LINUX_DIST): $(LINUX_FILES) $(LINUX_EXTRA)
+       -rm -f $@
+       -rm -rf linux
+       mkdir -p linux/TeleGPS
+       cp -p $(LINUX_FILES) linux/TeleGPS
+       cp -p telegps-fat linux/TeleGPS/telegps
+       chmod +x linux/TeleGPS/telegps
+       tar cjf $@ -C linux TeleGPS
+
+$(LINUX_SH): $(LINUX_DIST) $(srcdir)/../altosui/linux-install.sh
+       sed 's/AltOS/TeleGPS/g' $(srcdir)/../altosui/linux-install.sh | cat - $(LINUX_DIST) > $@
+       chmod +x $@
+
+$(MACOSX_DIST): $(MACOSX_FILES)
+       -rm -f $@
+       -rm -rf macosx
+       mkdir macosx
+       cp -a TeleGPS.app macosx/
+       cp -a $(MACOSX_README) macosx/ReadMe.rtf
+       cp -a $(DOC) macosx
+       cp -p Info.plist macosx/TeleGPS.app/Contents
+       cp -p $(MACOSX_DRIVER) macosx
+       mkdir -p macosx/TeleGPS.app/Contents/Resources/Java
+       cp -p $(FATJAR) macosx/TeleGPS.app/Contents/Resources/Java/telegps.jar
+       cp -p libaltos.dylib macosx/TeleGPS.app/Contents/Resources/Java
+       cp -p $(ALTOSLIB_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
+       cp -p $(ALTOSUILIB_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
+       cp -p $(JFREECHART_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
+       cp -p $(JCOMMON_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
+       genisoimage -D -V TeleGPS-$(VERSION) -no-pad -r -apple -o $@ macosx
+
+$(WINDOWS_DIST): $(WINDOWS_FILES) telegps-windows.nsi
+       -rm -f $@
+       makensis -Otelegps-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" telegps-windows.nsi
+
+Manifest.txt: Makefile
+       echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@
+       echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS)/freetts.jar $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@
+
+Manifest-fat.txt:
+       echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@
+       echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) freetts.jar jcommon.jar jfreechart.jar" >> $@
+
diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java
new file mode 100644 (file)
index 0000000..45482de
--- /dev/null
@@ -0,0 +1,543 @@
+/*
+ * 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 org.altusmetrum.telegps;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.io.*;
+import java.util.concurrent.*;
+import java.util.*;
+import org.altusmetrum.altoslib_4.*;
+import org.altusmetrum.altosuilib_2.*;
+
+public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, ActionListener {
+
+       static String[] telegps_icon_names = {
+               "/telegps-16.png",
+               "/telegps-32.png",
+               "/telegps-48.png",
+               "/telegps-64.png",
+               "/telegps-128.png",
+               "/telegps-256.png"
+       };
+
+       static { set_icon_names(telegps_icon_names); }
+
+       static AltosVoice       voice;
+
+       static AltosVoice voice() {
+               if (voice == null)
+                       voice = new AltosVoice();
+               return voice;
+       }
+
+       AltosFlightReader       reader;
+       AltosDisplayThread      thread;
+
+       JTabbedPane     pane;
+
+       AltosSiteMap    sitemap;
+       boolean         has_map;
+
+       JMenuBar        menu_bar;
+       JMenu           file_menu;
+       JMenu           monitor_menu;
+       JMenu           device_menu;
+
+       /* File menu */
+       final static String     new_command = "new";
+       final static String     preferences_command = "preferences";
+       final static String     load_maps_command = "loadmaps";
+       final static String     close_command = "close";
+       final static String     exit_command = "exit";
+
+       static final String[][] file_menu_entries = new String[][] {
+               { "New Window",         new_command },
+               { "Preferences",        preferences_command },
+               { "Load Maps",          load_maps_command },
+               { "Close",              close_command },
+               { "Exit",               exit_command },
+       };
+
+       /* Monitor menu */
+       final static String     monitor_command = "monitor";
+       final static String     disconnect_command = "disconnect";
+       final static String     scan_command = "scan";
+
+       static final String[][] monitor_menu_entries = new String[][] {
+               { "Monitor Device",     monitor_command },
+               { "Disconnect",         disconnect_command },
+               { "Scan Channels",      scan_command },
+       };
+
+       /* Device menu */
+       final static String     download_command = "download";
+       final static String     configure_command = "configure";
+       final static String     export_command = "export";
+       final static String     graph_command = "graph";
+
+       static final String[][] device_menu_entries = new String[][] {
+               { "Download Data",      download_command },
+               { "Configure Device",   configure_command },
+               { "Export Data",        export_command },
+               { "Graph Data",         graph_command },
+       };
+
+//     private AltosInfoTable flightInfo;
+
+       boolean exit_on_close = false;
+
+       void stop_display() {
+               if (thread != null && thread.isAlive()) {
+                       thread.interrupt();
+                       try {
+                               thread.join();
+                       } catch (InterruptedException ie) {}
+               }
+               thread = null;
+       }
+
+       public void reset() {
+               sitemap.reset();
+       }
+
+       public void set_font() {
+               sitemap.set_font();
+       }
+
+       public void font_size_changed(int font_size) {
+               set_font();
+       }
+
+
+//     AltosFlightStatusUpdate status_update;
+
+       public void show(AltosState state, AltosListenerState listener_state) {
+//             status_update.saved_state = state;
+
+               if (state == null)
+                       state = new AltosState();
+
+               sitemap.show(state, listener_state);
+               telegps_status.show(state, listener_state);
+       }
+
+       Container               bag;
+       AltosFreqList           frequencies;
+       JLabel                  telemetry;
+       TeleGPSStatus           telegps_status;
+       TeleGPSStatusUpdate     status_update;
+
+       ActionListener          show_timer;
+
+       void new_window() {
+               new TeleGPS();
+       }
+
+       void preferences() {
+       }
+
+       void load_maps() {
+               new AltosSiteMapPreload(this);
+       }
+
+       void monitor() {
+               AltosDevice     device = AltosDeviceUIDialog.show(this,
+                                                                 AltosLib.product_basestation);
+               if (device == null)
+                       return;
+               if (reader != null)
+                       disconnect();
+               try {
+                       AltosFlightReader       reader = new AltosTelemetryReader(new AltosSerial(device));
+                       set_reader(reader);
+                       add_frequency_menu(device.getSerial(), reader);
+               } catch (FileNotFoundException ee) {
+                       JOptionPane.showMessageDialog(this,
+                                                     ee.getMessage(),
+                                                     String.format ("Cannot open %s", device.toShortString()),
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (AltosSerialInUseException si) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format("Device \"%s\" already in use",
+                                                                   device.toShortString()),
+                                                     "Device in use",
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (IOException ee) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format ("Unknown I/O error on %s", device.toShortString()),
+                                                     "Unknown I/O error",
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (TimeoutException te) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format ("Timeout on %s", device.toShortString()),
+                                                     "Timeout error",
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (InterruptedException ie) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format("Interrupted %s", device.toShortString()),
+                                                     "Interrupted exception",
+                                                     JOptionPane.ERROR_MESSAGE);
+               }
+       }
+
+       void disconnect() {
+               setTitle("TeleGPS");
+               stop_display();
+               remove_frequency_menu();
+       }
+
+       void scan() {
+       }
+
+       void download(){
+       }
+
+       void configure() {
+       }
+
+       void export() {
+       }
+
+       void graph() {
+       }
+
+       public void actionPerformed(ActionEvent ev) {
+
+               /* File menu */
+               if (new_command.equals(ev.getActionCommand())) {
+                       new_window();
+                       return;
+               }
+               if (preferences_command.equals(ev.getActionCommand())) {
+                       preferences();
+                       return;
+               }
+               if (load_maps_command.equals(ev.getActionCommand())) {
+                       load_maps();
+                       return;
+               }
+               if (close_command.equals(ev.getActionCommand())) {
+                       close();
+                       return;
+               }
+               if (exit_command.equals(ev.getActionCommand()))
+                       System.exit(0);
+
+               /* Monitor menu */
+               if (monitor_command.equals(ev.getActionCommand())) {
+                       monitor();
+                       return;
+               }
+               if (disconnect_command.equals(ev.getActionCommand())) {
+                       disconnect();
+                       return;
+               }
+               if (scan_command.equals(ev.getActionCommand())) {
+                       scan();
+                       return;
+               }
+
+               /* Device menu */
+               if (download_command.equals(ev.getActionCommand())) {
+                       download();
+                       return;
+               }
+               if (configure_command.equals(ev.getActionCommand())) {
+                       configure();
+                       return;
+               }
+               if (export_command.equals(ev.getActionCommand())) {
+                       export();
+                       return;
+               }
+               if (graph_command.equals(ev.getActionCommand())) {
+                       graph();
+                       return;
+               }
+       }
+
+       void add_frequency_menu(int serial, final AltosFlightReader reader) {
+               // Channel menu
+               frequencies = new AltosFreqList(AltosUIPreferences.frequency(serial));
+               frequencies.set_product("Monitor");
+               frequencies.set_serial(serial);
+               frequencies.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       double frequency = frequencies.frequency();
+                                       try {
+                                               reader.set_frequency(frequency);
+                                       } catch (TimeoutException te) {
+                                       } catch (InterruptedException ie) {
+                                       }
+                                       reader.save_frequency();
+                               }
+                       });
+               menu_bar.add(frequencies);
+       }
+
+       void remove_frequency_menu() {
+               if (frequencies != null) {
+                       menu_bar.remove(frequencies);
+                       frequencies = null;
+               }
+       }
+
+       public void set_reader(AltosFlightReader reader) {
+               setTitle(String.format("TeleGPS %s", reader.name));
+               thread = new AltosDisplayThread(this, voice(), this, reader);
+               thread.start();
+       }
+
+       static int      number_of_windows;
+
+       private void close() {
+               AltosUIPreferences.unregister_font_listener(this);
+               setVisible(false);
+               dispose();
+               --number_of_windows;
+               if (number_of_windows == 0)
+                       System.exit(0);
+       }
+
+       private void add_menu(JMenu menu, String label, String action) {
+               JMenuItem       item = new JMenuItem(label);
+               menu.add(item);
+               item.addActionListener(this);
+               item.setActionCommand(action);
+       }
+
+
+       private JMenu make_menu(String label, String[][] items) {
+               JMenu   menu = new JMenu(label);
+               for (int i = 0; i < items.length; i++)
+                       add_menu(menu, items[i][0], items[i][1]);
+               menu_bar.add(menu);
+               return menu;
+       }
+
+       public TeleGPS() {
+
+               AltosUIPreferences.set_component(this);
+
+               reader = null;
+
+               bag = getContentPane();
+               bag.setLayout(new GridBagLayout());
+
+               GridBagConstraints c = new GridBagConstraints();
+
+               setTitle("TeleGPS");
+
+               menu_bar = new JMenuBar();
+               setJMenuBar(menu_bar);
+
+               file_menu = make_menu("File", file_menu_entries);
+               monitor_menu = make_menu("Monitor", monitor_menu_entries);
+               device_menu = make_menu("Device", device_menu_entries);
+
+               int serial = -1;
+
+               /* TeleGPS status is always visible */
+               telegps_status = new TeleGPSStatus();
+               c.gridx = 0;
+               c.gridy = 1;
+               c.fill = GridBagConstraints.HORIZONTAL;
+               c.weightx = 1;
+               c.gridwidth = 2;
+               bag.add(telegps_status, c);
+               c.gridwidth = 1;
+
+
+               /* The rest of the window uses a tabbed pane to
+                * show one of the alternate data views
+                */
+               pane = new JTabbedPane();
+
+               /* Make the tabbed pane use the rest of the window space */
+               c.gridx = 0;
+               c.gridy = 2;
+               c.fill = GridBagConstraints.BOTH;
+               c.weightx = 1;
+               c.weighty = 1;
+               c.gridwidth = 2;
+               bag.add(pane, c);
+
+               sitemap = new AltosSiteMap();
+               pane.add("Site Map", sitemap);
+
+               setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+               AltosUIPreferences.register_font_listener(this);
+
+               addWindowListener(new WindowAdapter() {
+                               @Override
+                               public void windowClosing(WindowEvent e) {
+                                       close();
+                               }
+                       });
+
+               pack();
+               setVisible(true);
+
+               ++number_of_windows;
+
+               status_update = new TeleGPSStatusUpdate(telegps_status);
+
+               new javax.swing.Timer(100, status_update).start();
+       }
+
+       public TeleGPS(AltosFlightReader reader) {
+               this();
+               set_reader(reader);
+       }
+
+       static AltosStateIterable record_iterable(File file) {
+               FileInputStream in;
+               try {
+                       in = new FileInputStream(file);
+               } catch (Exception e) {
+                       System.out.printf("Failed to open file '%s'\n", file);
+                       return null;
+               }
+               if (file.getName().endsWith("telem"))
+                       return new AltosTelemetryFile(in);
+               else
+                       return new AltosEepromFile(in);
+       }
+
+       static AltosReplayReader replay_file(File file) {
+               AltosStateIterable states = record_iterable(file);
+               if (states == null)
+                       return null;
+               return new AltosReplayReader(states.iterator(), file);
+       }
+
+       static boolean process_replay(File file) {
+               AltosReplayReader new_reader = replay_file(file);
+               if (new_reader == null)
+                       return false;
+
+               new TeleGPS(new_reader);
+               return true;
+       }
+
+       static final int process_none = 0;
+       static final int process_csv = 1;
+       static final int process_kml = 2;
+       static final int process_graph = 3;
+       static final int process_replay = 4;
+       static final int process_summary = 5;
+       static final int process_cat = 6;
+
+       public static boolean load_library(Frame frame) {
+               if (!AltosUILib.load_library()) {
+                       JOptionPane.showMessageDialog(frame,
+                                                     String.format("No AltOS library in \"%s\"",
+                                                                   System.getProperty("java.library.path","<undefined>")),
+                                                     "Cannot load device access library",
+                                                     JOptionPane.ERROR_MESSAGE);
+                       return false;
+               }
+               return true;
+       }
+
+       public static void help(int code) {
+               System.out.printf("Usage: altosui [OPTION]... [FILE]...\n");
+               System.out.printf("  Options:\n");
+               System.out.printf("    --fetchmaps <lat> <lon>\tpre-fetch maps for site map view\n");
+               System.out.printf("    --replay <filename>\t\trelive the glory of past flights \n");
+               System.out.printf("    --graph <filename>\t\tgraph a flight\n");
+               System.out.printf("    --csv\tgenerate comma separated output for spreadsheets, etc\n");
+               System.out.printf("    --kml\tgenerate KML output for use with Google Earth\n");
+               System.exit(code);
+       }
+
+       public static void main(String[] args) {
+               int     errors = 0;
+
+               load_library(null);
+               try {
+                       UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel());
+               } catch (Exception e) {
+               }
+
+               boolean any_created = false;
+
+
+               /* Handle batch-mode */
+               int process = process_none;
+               for (int i = 0; i < args.length; i++) {
+                       if (args[i].equals("--help"))
+                               help(0);
+                       else if (args[i].equals("--fetchmaps")) {
+                               if (args.length < i + 3) {
+                                       help(1);
+                               } else {
+                                       double lat = Double.parseDouble(args[i+1]);
+                                       double lon = Double.parseDouble(args[i+2]);
+                                       AltosSiteMap.prefetchMaps(lat, lon);
+                                       i += 2;
+                               }
+                       } else if (args[i].equals("--replay"))
+                               process = process_replay;
+                       else if (args[i].equals("--kml"))
+                               process = process_kml;
+                       else if (args[i].equals("--csv"))
+                               process = process_csv;
+                       else if (args[i].equals("--graph"))
+                               process = process_graph;
+                       else if (args[i].equals("--summary"))
+                               process = process_summary;
+                       else if (args[i].equals("--cat"))
+                               process = process_cat;
+                       else if (args[i].startsWith("--"))
+                               help(1);
+                       else {
+                               File file = new File(args[i]);
+                               switch (process) {
+                               case process_graph:
+                                       ++errors;
+                                       break;
+                               case process_none:
+                               case process_replay:
+                                       if (!process_replay(file))
+                                               ++errors;
+                                       any_created = true;
+                                       break;
+                               case process_kml:
+                                       ++errors;
+                                       break;
+                               case process_csv:
+                                       ++errors;
+                                       break;
+                               case process_summary:
+                                       ++errors;
+                                       break;
+                               case process_cat:
+                                       ++errors;
+                               }
+                       }
+               }
+               if (errors != 0)
+                       System.exit(errors);
+               if (!any_created)
+                       new TeleGPS();
+       }
+}
diff --git a/telegps/TeleGPSStatus.java b/telegps/TeleGPSStatus.java
new file mode 100644 (file)
index 0000000..fd66b27
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * 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 org.altusmetrum.telegps;
+
+import java.awt.*;
+import javax.swing.*;
+import org.altusmetrum.altoslib_4.*;
+import org.altusmetrum.altosuilib_2.*;
+
+public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
+       GridBagLayout   layout;
+
+       public class FlightValue {
+               JLabel          label;
+               JTextField      value;
+
+               void show(AltosState state, AltosListenerState listener_state) {}
+
+               void reset() {
+                       value.setText("");
+               }
+
+               void set_font() {
+                       label.setFont(AltosUILib.status_font);
+                       value.setFont(AltosUILib.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);
+                       c.anchor = GridBagConstraints.CENTER;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
+                       c.weighty = 1;
+
+                       label = new JLabel(text);
+                       label.setFont(AltosUILib.status_font);
+                       label.setHorizontalAlignment(SwingConstants.CENTER);
+                       c.gridx = x; c.gridy = 0;
+                       layout.setConstraints(label, c);
+                       add(label);
+
+                       value = new JTextField("");
+                       value.setFont(AltosUILib.status_font);
+                       value.setHorizontalAlignment(SwingConstants.CENTER);
+                       c.gridx = x; c.gridy = 1;
+                       layout.setConstraints(value, c);
+                       add(value);
+               }
+       }
+
+       class Call extends FlightValue {
+               void show(AltosState state, AltosListenerState listener_state) {
+                       value.setText(state.callsign);
+                       if (state.callsign == null)
+                               setVisible(false);
+                       else
+                               setVisible(true);
+               }
+               public Call (GridBagLayout layout, int x) {
+                       super (layout, x, "Callsign");
+               }
+       }
+
+       Call call;
+
+       class Serial extends FlightValue {
+               void show(AltosState state, AltosListenerState listener_state) {
+                       if (state.serial == AltosLib.MISSING)
+                               value.setText("none");
+                       else
+                               value.setText(String.format("%d", state.serial));
+               }
+               public Serial (GridBagLayout layout, int x) {
+                       super (layout, x, "Serial");
+               }
+       }
+
+       Serial serial;
+
+       class RSSI extends FlightValue {
+               void show(AltosState state, AltosListenerState listener_state) {
+                       value.setText(String.format("%d", state.rssi()));
+                       if (state.rssi == AltosLib.MISSING)
+                               setVisible(false);
+                       else
+                               setVisible(true);
+               }
+               public RSSI (GridBagLayout layout, int x) {
+                       super (layout, x, "RSSI");
+               }
+       }
+
+       RSSI rssi;
+
+       class LastPacket extends FlightValue {
+               void show(AltosState state, AltosListenerState listener_state) {
+                       long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
+                       value.setText(String.format("%d", secs));
+               }
+               public LastPacket(GridBagLayout layout, int x) {
+                       super (layout, x, "Age");
+               }
+       }
+
+       LastPacket last_packet;
+
+       public void reset () {
+               call.reset();
+               serial.reset();
+               rssi.reset();
+               last_packet.reset();
+       }
+
+       public void set_font () {
+               call.set_font();
+               serial.set_font();
+               rssi.set_font();
+               last_packet.set_font();
+       }
+
+       public void show (AltosState state, AltosListenerState listener_state) {
+               call.show(state, listener_state);
+               serial.show(state, listener_state);
+               rssi.show(state, listener_state);
+               last_packet.show(state, listener_state);
+       }
+
+       public int height() {
+               Dimension d = layout.preferredLayoutSize(this);
+               return d.height;
+       }
+
+       public TeleGPSStatus() {
+               layout = new GridBagLayout();
+
+               setLayout(layout);
+
+               call = new Call(layout, 0);
+               serial = new Serial(layout, 1);
+               rssi = new RSSI(layout, 4);
+               last_packet = new LastPacket(layout, 5);
+       }
+}
diff --git a/telegps/TeleGPSStatusUpdate.java b/telegps/TeleGPSStatusUpdate.java
new file mode 100644 (file)
index 0000000..e7684d8
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2012 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 org.altusmetrum.telegps;
+
+import java.awt.event.*;
+import org.altusmetrum.altoslib_4.*;
+
+public class TeleGPSStatusUpdate implements ActionListener {
+
+       public AltosState               saved_state;
+       public AltosListenerState       saved_listener_state;
+       TeleGPSStatus                   status;
+
+       public void actionPerformed (ActionEvent e) {
+               if (saved_state != null) {
+                       if (saved_listener_state == null)
+                               saved_listener_state = new AltosListenerState();
+                       status.show(saved_state, saved_listener_state);
+               }
+       }
+
+       public TeleGPSStatusUpdate (TeleGPSStatus in_status) {
+               status = in_status;
+       }
+}
+
diff --git a/telegps/telegps-windows.nsi.in b/telegps/telegps-windows.nsi.in
new file mode 100644 (file)
index 0000000..656f8af
--- /dev/null
@@ -0,0 +1,132 @@
+!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"
+!define PRODUCT_NAME "Altus Metrum Windows Software"
+
+Name "Altus Metrum MicroPeak Installer"
+
+; Default install directory
+InstallDir "$PROGRAMFILES\AltusMetrum"
+
+; Tell the installer where to re-install a new version
+InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir"
+
+LicenseText "GNU General Public License Version 2"
+LicenseData "../COPYING"
+
+; Need admin privs for Vista or Win7
+RequestExecutionLevel admin
+
+ShowInstDetails Show
+
+ComponentText "Altus Metrum MicroPeak Software Installer"
+
+Function GetJRE
+        MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \
+                         be downloaded and installed"
+
+        StrCpy $2 "$TEMP\Java Runtime Environment.exe"
+        nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2
+        Pop $R0 ;Get the return value
+                StrCmp $R0 "success" +3
+                MessageBox MB_OK "Download failed: $R0"
+                Quit
+        ExecWait $2
+        Delete $2
+FunctionEnd
+
+
+Function DetectJRE
+  ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \
+             "CurrentVersion"
+  StrCmp $2 ${JRE_VERSION} done
+
+  StrCmp $2 ${JRE_ALTERNATE} done
+
+  Call GetJRE
+
+  done:
+FunctionEnd
+
+; Pages to present
+
+Page license
+Page components
+Page directory
+Page instfiles
+
+UninstPage uninstConfirm
+UninstPage instfiles
+
+; And the stuff to install
+
+Section "MicroPeak Application"
+       Call DetectJRE
+
+       SetOutPath $INSTDIR
+
+       File "micropeak-fat.jar"
+       File "altoslib_@ALTOSLIB_VERSION@.jar"
+       File "altosuilib_@ALTOSUILIB_VERSION@.jar"
+       File "jfreechart.jar"
+       File "jcommon.jar"
+
+       File "*.dll"
+
+       File "../icon/*.ico"
+
+       CreateShortCut "$SMPROGRAMS\MicroPeak.lnk" "$SYSDIR\javaw.exe" "-jar micropeak-fat.jar" "$INSTDIR\micro-peak.ico"
+SectionEnd
+
+Section "FTDI USB Driver"
+       SetOutPath $INSTDIR
+
+       File "CDM20824_Setup.exe"
+
+       StrCpy $2 "$INSTDIR\CDM20824_Setup.exe"
+       ExecWait $2
+SectionEnd
+
+Section "MicroPeak Desktop Shortcut"
+       CreateShortCut "$DESKTOP\MicroPeak.lnk" "$INSTDIR\micropeak-fat.jar"  "" "$INSTDIR\micro-peak.ico"
+SectionEnd
+
+Section "Documentation"
+
+       SetOutPath $INSTDIR
+
+       File "../doc/micropeak.pdf"
+SectionEnd
+
+Section "Uninstaller"
+
+       ; Deal with the uninstaller
+
+       SetOutPath $INSTDIR
+
+       ; Write the install path to the registry
+       WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR"
+
+       ; Write the uninstall keys for windows
+       WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum"
+       WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"'
+       WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1"
+       WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1"
+
+       WriteUninstaller "uninstall.exe"
+SectionEnd
+
+Section "Uninstall"
+       DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum"
+       DeleteRegKey HKLM "Software\AltusMetrum"
+
+       Delete "$INSTDIR\*.*"
+       RMDir "$INSTDIR"
+
+       ; Remove shortcuts, if any
+       Delete "$SMPROGRAMS\MicroPeak.lnk"
+       Delete "$DESKTOP\MicroPeak.lnk"
+       
+SectionEnd
diff --git a/telegps/telegps.1 b/telegps/telegps.1
new file mode 100644 (file)
index 0000000..57fa448
--- /dev/null
@@ -0,0 +1,46 @@
+.\"
+.\" Copyright © 2010 Bdale Garbee <bdale@gag.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; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" 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.
+.\"
+.\"
+.TH ALTOSUI 1 "altosui" ""
+.SH NAME
+altosui \- Rocket flight monitor
+.SH SYNOPSIS
+.B "altosui"
+.SH DESCRIPTION
+.I altosui
+connects to a TeleDongle or TeleMetrum device through a USB serial device.
+It provides a menu-oriented
+user interface to monitor, record and review rocket flight data.
+.SH USAGE
+When connected to a TeleDongle device, altosui turns on the radio
+receiver and listens for telemetry packets. It displays the received
+telemetry data, and reports flight status via voice synthesis. All
+received telemetry information is recorded to a file.
+.P
+When connected to a TeleMetrum device, altosui can be used to configure the
+TeleMetrum, and to downloads the eeprom data and store it in a file.
+.P
+A number of other menu options exist, including the ability to export flight
+data in different formats.
+.SH FILES
+All data log files are recorded into a user-specified directory
+(default ~/TeleMetrum). Files are named using the current date, the serial
+number of the reporting device, the flight number recorded in the data
+and either '.telem' for telemetry data or '.eeprom' for eeprom data.
+.SH AUTHOR
+Keith Packard
diff --git a/telegps/telegps.desktop.in b/telegps/telegps.desktop.in
new file mode 100644 (file)
index 0000000..abdf286
--- /dev/null
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Type=Application
+Name=MicroPeak
+GenericName=MicroPeak download and analysis
+Comment=View and log data from MicroPeak altimeters
+Icon=%icondir%/micropeak.svg
+Exec=%bindir%/micropeak %f
+Terminal=false
+MimeType=text/plain;
+Categories=Education;Electronics;Science;