Merge branch 'branch-1.6' into debian
authorBdale Garbee <bdale@gag.com>
Fri, 17 Jun 2016 16:02:00 +0000 (10:02 -0600)
committerBdale Garbee <bdale@gag.com>
Fri, 17 Jun 2016 16:02:00 +0000 (10:02 -0600)
299 files changed:
ChangeLog
Makefile.am
Releasing
altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDebug.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapInterface.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOnline.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosUsb.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java
altosdroid/src/org/altusmetrum/AltosDroid/IdleModeActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/ManageFrequenciesActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/MapTypeActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/PreloadMapActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/SetupActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/TabFlight.java
altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
altosdroid/src/org/altusmetrum/AltosDroid/TabRecover.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryState.java
altoslib/AltosAccel.java
altoslib/AltosCRCException.java
altoslib/AltosCSV.java
altoslib/AltosCompanion.java
altoslib/AltosConfigData.java
altoslib/AltosConfigDataException.java
altoslib/AltosConfigValues.java
altoslib/AltosConvert.java
altoslib/AltosDebug.java
altoslib/AltosDistance.java
altoslib/AltosEeprom.java
altoslib/AltosEepromChunk.java
altoslib/AltosEepromDownload.java
altoslib/AltosEepromFile.java
altoslib/AltosEepromGPS.java
altoslib/AltosEepromHeader.java
altoslib/AltosEepromIterable.java
altoslib/AltosEepromList.java
altoslib/AltosEepromLog.java
altoslib/AltosEepromMega.java
altoslib/AltosEepromMetrum2.java
altoslib/AltosEepromMini.java
altoslib/AltosEepromMonitor.java
altoslib/AltosEepromTM.java
altoslib/AltosEepromTMini.java
altoslib/AltosFile.java
altoslib/AltosFlash.java
altoslib/AltosFlashListener.java
altoslib/AltosFlightDisplay.java
altoslib/AltosFlightReader.java
altoslib/AltosFlightStats.java
altoslib/AltosFontListener.java
altoslib/AltosFrequency.java
altoslib/AltosGPS.java
altoslib/AltosGPSSat.java
altoslib/AltosGreatCircle.java
altoslib/AltosHeight.java
altoslib/AltosHexfile.java
altoslib/AltosHexsym.java
altoslib/AltosIMU.java
altoslib/AltosIdle.java
altoslib/AltosIdleFetch.java
altoslib/AltosIdleMonitor.java
altoslib/AltosIdleMonitorListener.java
altoslib/AltosIdleReader.java [new file with mode: 0644]
altoslib/AltosIgnite.java
altoslib/AltosImage.java
altoslib/AltosJson.java [new file with mode: 0644]
altoslib/AltosKML.java
altoslib/AltosLatLon.java
altoslib/AltosLatitude.java
altoslib/AltosLaunchSite.java
altoslib/AltosLaunchSiteListener.java
altoslib/AltosLaunchSites.java
altoslib/AltosLib.java
altoslib/AltosLine.java
altoslib/AltosLink.java
altoslib/AltosListenerState.java
altoslib/AltosLocation.java
altoslib/AltosLog.java
altoslib/AltosLongitude.java
altoslib/AltosMag.java
altoslib/AltosMap.java
altoslib/AltosMapCache.java
altoslib/AltosMapCacheListener.java
altoslib/AltosMapInterface.java
altoslib/AltosMapLine.java
altoslib/AltosMapLoader.java
altoslib/AltosMapLoaderListener.java
altoslib/AltosMapMark.java
altoslib/AltosMapPath.java
altoslib/AltosMapPathPoint.java
altoslib/AltosMapRectangle.java
altoslib/AltosMapStore.java
altoslib/AltosMapStoreListener.java
altoslib/AltosMapTile.java
altoslib/AltosMapTileListener.java
altoslib/AltosMapTransform.java
altoslib/AltosMapTypeListener.java
altoslib/AltosMapZoomListener.java
altoslib/AltosMma655x.java
altoslib/AltosMs5607.java
altoslib/AltosNoSymbol.java
altoslib/AltosOrient.java
altoslib/AltosParse.java
altoslib/AltosPointDouble.java
altoslib/AltosPointInt.java
altoslib/AltosPreferences.java
altoslib/AltosPreferencesBackend.java
altoslib/AltosProgrammer.java
altoslib/AltosPyro.java
altoslib/AltosQuaternion.java
altoslib/AltosRectangle.java
altoslib/AltosReplayReader.java
altoslib/AltosRomconfig.java
altoslib/AltosRotation.java
altoslib/AltosSavedState.java
altoslib/AltosSelfFlash.java
altoslib/AltosSensorEMini.java
altoslib/AltosSensorMM.java
altoslib/AltosSensorMega.java
altoslib/AltosSensorMetrum.java
altoslib/AltosSensorTGPS.java
altoslib/AltosSensorTM.java
altoslib/AltosSensorTMini.java
altoslib/AltosSpeed.java
altoslib/AltosState.java
altoslib/AltosStateIterable.java
altoslib/AltosStateUpdate.java
altoslib/AltosTelemetry.java
altoslib/AltosTelemetryCompanion.java
altoslib/AltosTelemetryConfiguration.java
altoslib/AltosTelemetryFile.java
altoslib/AltosTelemetryIterable.java
altoslib/AltosTelemetryLegacy.java
altoslib/AltosTelemetryLocation.java
altoslib/AltosTelemetryMap.java
altoslib/AltosTelemetryMegaData.java
altoslib/AltosTelemetryMegaSensor.java
altoslib/AltosTelemetryMetrumData.java
altoslib/AltosTelemetryMetrumSensor.java
altoslib/AltosTelemetryMini.java
altoslib/AltosTelemetryRaw.java
altoslib/AltosTelemetryReader.java
altoslib/AltosTelemetrySatellite.java
altoslib/AltosTelemetrySensor.java
altoslib/AltosTelemetryStandard.java
altoslib/AltosTemperature.java
altoslib/AltosUnits.java
altoslib/AltosUnitsListener.java
altoslib/AltosUnitsRange.java [new file with mode: 0644]
altoslib/AltosUnknownProduct.java
altoslib/AltosVersion.java.in
altoslib/AltosVoltage.java
altoslib/AltosWriter.java
altoslib/Makefile.am
altosui/Altos.java
altosui/AltosAscent.java
altosui/AltosCompanionInfo.java
altosui/AltosConfig.java
altosui/AltosConfigPyroUI.java
altosui/AltosConfigTD.java
altosui/AltosConfigTDUI.java
altosui/AltosConfigUI.java
altosui/AltosConfigureUI.java
altosui/AltosDescent.java
altosui/AltosFlightStatus.java
altosui/AltosFlightStatusTableModel.java
altosui/AltosFlightStatusUpdate.java
altosui/AltosFlightUI.java
altosui/AltosGraphUI.java
altosui/AltosIdleMonitorUI.java
altosui/AltosIgniteUI.java
altosui/AltosIgnitor.java
altosui/AltosLanded.java
altosui/AltosLaunch.java
altosui/AltosLaunchUI.java
altosui/AltosPad.java
altosui/AltosUI.java
altosui/Makefile.am
altosuilib/AltosBTDevice.java
altosuilib/AltosBTDeviceIterator.java
altosuilib/AltosBTKnown.java
altosuilib/AltosBTManage.java
altosuilib/AltosCSVUI.java
altosuilib/AltosConfigFreqUI.java
altosuilib/AltosDataChooser.java
altosuilib/AltosDevice.java
altosuilib/AltosDeviceDialog.java
altosuilib/AltosDeviceUIDialog.java
altosuilib/AltosDisplayThread.java
altosuilib/AltosEepromDelete.java
altosuilib/AltosEepromManage.java
altosuilib/AltosEepromMonitor.java
altosuilib/AltosEepromMonitorUI.java
altosuilib/AltosEepromSelect.java
altosuilib/AltosFlashUI.java
altosuilib/AltosFlightInfoTableModel.java
altosuilib/AltosFlightStatsTable.java
altosuilib/AltosGraph.java
altosuilib/AltosGraphDataPoint.java
altosuilib/AltosGraphDataSet.java
altosuilib/AltosInfoTable.java
altosuilib/AltosLed.java
altosuilib/AltosLights.java
altosuilib/AltosPositionListener.java
altosuilib/AltosRomconfigUI.java
altosuilib/AltosScanUI.java
altosuilib/AltosSerial.java
altosuilib/AltosSerialInUseException.java
altosuilib/AltosUIAxis.java
altosuilib/AltosUIConfigure.java
altosuilib/AltosUIDataMissing.java
altosuilib/AltosUIDataPoint.java
altosuilib/AltosUIDataSet.java
altosuilib/AltosUIDialog.java
altosuilib/AltosUIEnable.java
altosuilib/AltosUIFlightTab.java
altosuilib/AltosUIFrame.java
altosuilib/AltosUIFreqList.java
altosuilib/AltosUIGraph.java
altosuilib/AltosUIGrapher.java
altosuilib/AltosUIImage.java
altosuilib/AltosUIIndicator.java
altosuilib/AltosUILib.java
altosuilib/AltosUIListener.java
altosuilib/AltosUIMap.java [new file with mode: 0644]
altosuilib/AltosUIMapNew.java [deleted file]
altosuilib/AltosUIMapPreload.java [new file with mode: 0644]
altosuilib/AltosUIMapPreloadNew.java [deleted file]
altosuilib/AltosUIMarker.java
altosuilib/AltosUIPreferences.java
altosuilib/AltosUIPreferencesBackend.java
altosuilib/AltosUIRateList.java
altosuilib/AltosUISeries.java
altosuilib/AltosUITelemetryList.java
altosuilib/AltosUIUnitsIndicator.java
altosuilib/AltosUIVoltageIndicator.java
altosuilib/AltosUSBDevice.java
altosuilib/AltosVoice.java
altosuilib/GrabNDrag.java
altosuilib/Makefile.am
altosuilib/OSXAdapter.java
ao-tools/ao-test-baro/ao-test-baro.c
configure.ac
doc/Makefile
doc/altusmetrum-docinfo.xml
doc/release-notes-1.6.4.inc [new file with mode: 0644]
doc/release-notes.inc
doc/specs.inc
doc/telegps-docinfo.xml
doc/telegps-specs.inc
doc/usage.inc
micropeak/Makefile.am
micropeak/MicroData.java
micropeak/MicroDataPoint.java
micropeak/MicroDeviceDialog.java
micropeak/MicroDownload.java
micropeak/MicroExport.java
micropeak/MicroFile.java
micropeak/MicroFileChooser.java
micropeak/MicroFrame.java
micropeak/MicroGraph.java
micropeak/MicroPeak.java
micropeak/MicroRaw.java
micropeak/MicroSave.java
micropeak/MicroSerial.java
micropeak/MicroSerialLog.java
micropeak/MicroStats.java
micropeak/MicroStatsTable.java
micropeak/MicroUSB.java
src/cc1111/ao_serial.c
src/drivers/ao_cc115l.c
src/drivers/ao_trng_send.c
src/lpc/ao_usb_lpc.c
src/stm/ao_usb_stm.c
src/stmf0/ao_arch_funcs.h
src/stmf0/ao_usb_stm.c
src/telegps-v1.0/ao_pins.h
telegps/Makefile.am
telegps/TeleGPS.java
telegps/TeleGPSConfig.java
telegps/TeleGPSConfigUI.java
telegps/TeleGPSDisplayThread.java
telegps/TeleGPSGraphUI.java
telegps/TeleGPSInfo.java
telegps/TeleGPSPreferences.java
telegps/TeleGPSState.java
telegps/TeleGPSStatus.java
telegps/TeleGPSStatusUpdate.java

index 3353ea3df15c52e61237a0a15065283ad965b9ae..dd00283b0f306491b582653df84f50c418fd484a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,688 @@
+commit 31cf047113ec72a78f4b500223a2c6be23bc86fd
+Merge: 2f0c977 afe74c0
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Fri Jun 17 10:00:10 2016 -0600
+
+    Merge branch 'master' into branch-1.6
+
+commit afe74c067a31ce420d0d4cdac2069c1d258a5114
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 08:58:06 2016 -0700
+
+    Bump version to 1.6.4
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 0c5a1bea3ffa7c4b6b1503733e33911cbfcb3e80
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 08:54:19 2016 -0700
+
+    altoslib: Stop reflective JSON class walk at Object instead of null
+    
+    Android has classes above Object which are all tied together which
+    cause the object walking to fail in pretty spectacular ways. As Object
+    has no interesting fields, that serves as a fine barrier to the super
+    class walk and works on both android and real java.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 383dec4449f8160c06804fba06290e7a07335934
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 08:27:12 2016 -0700
+
+    altosui: Print filename before attempting to parse in --summary mode
+    
+    Any problems handling the file are easier to debug if the filename is
+    visible above the error message.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit e8250fcb267a34fbbd8b88c6dcc8eec419bbcc68
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 08:26:31 2016 -0700
+
+    altoslib: Add back some JSON exception debugging printfs
+    
+    These make it possible to figure out where the JSON code went wrong.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit a46df4f69984e3ef0064c2b211438c8d8ffaab68
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 08:17:57 2016 -0700
+
+    altoslib: Add construction for remaining primitive array types to JSON
+    
+    AltosCompanion has an array of ints, which was missed until I tried a
+    telemetry file with companion data.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1ed6a3fb6356415c0d57ce2ce556435c6ff06e73
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 08:17:15 2016 -0700
+
+    altoslib: Add null constructor for AltosCompanion
+    
+    This lets it be used by the JSON code.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1dce20f7eee56166ac61798ca26eeb323dc8f012
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 00:52:38 2016 -0700
+
+    altoslib: Get rid of manual JSON encoding stuff
+    
+    Now that the reflective JSON stuff is working, we can delete all of
+    the manual code.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7175774c4f60ed3efd54417f2035b50ea0108c7b
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 00:02:05 2016 -0700
+
+    altoslib: Improve AltosState save/restore debugging
+    
+    When save/restore generate different values, write out the two
+    versions to one.json and two.json for easy comparison.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 8df6afe843e184e98e5d965cee3af562dfa30a3b
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 00:01:15 2016 -0700
+
+    altoslib: Use reflection JSON code for frequency preferences
+    
+    This replaces the non-reflective JSON code with reflective code, which
+    is much shorter.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 93de1d7ec841c55f5a1a63d34b422780a6fbe3c3
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 17 00:00:09 2016 -0700
+
+    altoslib: Add JSON-based object saving/restoring code
+    
+    This uses Java reflection to construct JSON strings for
+    most Java objects.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2a1b7c6c509d4d19de21abf02b63aeacba269d13
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu Jun 16 23:59:06 2016 -0700
+
+    altoslib: Add null constructors to AltosQuaternion and AltosRotation
+    
+    These will be used in the reflection-based JSON code
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f7e2f7f430e612c682bf55478860054ce94b995f
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:52:08 2016 -0700
+
+    altoslib: Remove AltosHashSet code
+    
+    Everything has switched to JSON now.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1b5ea911049a8afae6af475a4a2bf62a6e3aa57b
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:40:27 2016 -0700
+
+    altoslib: Switch preserved state format to JSON
+    
+    This is much easier to debug than the icky strings with backslashes everywhere.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1de8b6c340cec0b5a327392686c5a4e00f201e98
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:39:31 2016 -0700
+
+    doc: Updates to 1.6.4 release notes.
+    
+    Note USB fixes for host reboot and other changes.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f28db1102685c87b9f4278268f7e91f5df18374a
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:38:32 2016 -0700
+
+    altosui: Don't open command window when --graph is provided
+    
+    When the user explicitly asks to open a graph, don't bring up the
+    command button window too.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2a4d741872449b5332f28e018fa3acc53ed7d891
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:37:39 2016 -0700
+
+    altosuilib: Track open frames, exit when none remain
+    
+    This will let us not have the altosui window open by causing the
+    application to shut down when the last frame closes.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 04c6f4c54ac10f6464ffb8cab2186ac2b2eafb00
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:36:35 2016 -0700
+
+    altosui: Remove missing items from --summary output
+    
+    Check all values for MISSING before printing them.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7fd28830b6f7a20b35d85a92047ccb94c965fe29
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 15 22:33:55 2016 -0700
+
+    altosdroid: Auto save freq changes on 'ok'
+    
+    Add any pending changes in the edit entries to the frequency set when
+    the user selects 'ok'.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 96eb350d3dfc83f6dfb31bbab1427f9206acde79
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Sun Jun 12 09:23:36 2016 -0600
+
+    extend "ok" temp range to 40C, since battery charger on bench can drive temp above
+    35C at times in Bdale and Robert's production testing
+
+commit eee7fa303fb0d80ac5d7b9c5a86af60333f61951
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jun 11 22:17:01 2016 -0700
+
+    altos/stmf0: Remove ao_usb_free
+    
+    This can't work without a lot more effort.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1704d27248f1845c545ec61cf1bad58bf41189af
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jun 11 22:16:12 2016 -0700
+
+    altos/stmf0: Rework the sram allocation to save a few text bytes
+    
+    Boot loaders were going over 4096 bytes of ROM. I suspect we'll need
+    more serious work soon.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 36a08dc89ece6e2a2f0f69e3b31da17d66ceb2e2
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 10 14:40:26 2016 -0700
+
+    altos/cc1115l: Reduce trace buffer size
+    
+    A 32-element trace buffer is all the larger we can fit in teledongle.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7d21ff641a7bc35318f0f637589eabb5bb6c5152
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 10 14:39:25 2016 -0700
+
+    altos/stm: Handle USB reset in STM32L usb driver
+    
+    Just like lpc and stmf0, deal with the host resetting the bus while
+    rebooting by restoring all usb-related data to the initial values.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 54f8d53584d0a902676b441cd122c01cd54f2283
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 10 14:33:50 2016 -0700
+
+    altos/lpc: Handle USB reset by resetting internal state
+    
+    Just like stmf0, this clears internal state at USB reset time so the
+    driver can survive host OS reboots.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 36ba97fabbed2f2a4a89da5be221c630ea3ff66f
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu Jun 9 22:06:30 2016 -0700
+
+    stmf0: Do not send more data than requested for GET_DESCRIPTOR
+    
+    When Linux boots, it asks for only the first 8 bytes of the device
+    descriptor; we must limit the amount of data sent back to that amount
+    or USB will get wedged.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2970de9f92243b11d3beef56f3b1df3ef3579b95
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu Jun 9 22:05:24 2016 -0700
+
+    stmf0: Clear all USB state when resetting chip. Wakeup all sleepers
+    
+    When USB is reset, but the board is not power cycled, all of the
+    internal USB state needs to be reset, and any tasks blocked on sending
+    or receiving packets need to be awoken so they can go wait for USB to
+    start running again.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 55c8e5aff2cc7b941503a04970f7d368261af52a
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu Jun 9 22:03:45 2016 -0700
+
+    telegps-v1.0: Document how SN 1959 was fixed
+    
+    SN1959 was fixed by jumpering pin 8 to pin 10 so that the DONE_INT_PIN
+    could be switched from PIO 2 to PIO 4 as pin 8 appeared to have failed.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 4d57c8b87f29f23beb0d88f1cef179209b1c5992
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun Jun 5 09:17:12 2016 -0700
+
+    altosuilib: Only display map debugging when serial_debug is enabled
+    
+    This keeps the application quiet for most users.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f982248573c1b646ac53fde980a60ada5404f6aa
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri May 27 20:30:18 2016 -0700
+
+    altosuilib: Fill preload map on site or lat/lon change
+    
+    This loads the map view with the selected area when the site entry is
+    changed or the user hits return in the lat/lon fields. This lets you
+    see the target launch site without having to load the whole preload set.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f5944ba4eb3f419f8cad461872d048b5adf7b566
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 26 14:33:44 2016 -0700
+
+    doc: pad/idle indicator table was busted
+    
+    I stuck a pile of extra '|' characters in the table by mistake.
+    
+    Reported-by: Stan <stanleyosmith@gmail.com>
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 0d966b74f756e88e5dffa92400b105f540429262
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 24 23:44:50 2016 -0700
+
+    altosuilib: Rename AltosUIMap*New.java to AltosUIMap*.java
+    
+    This code isn't really new anymore...
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 59a9bdd73b580a9c934a574be7bf45c5033e14b5
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 24 23:40:47 2016 -0700
+
+    altosuilib: Have map preload respond to units and font size changes
+    
+    Just add suitable listeners so that the display updates when
+    preferences change.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7b5521966119fcc290591bf1b397506ef44cedea
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 24 23:40:03 2016 -0700
+
+    altoslib: use miles for distances > 1000ft.
+    
+    This makes both the map line and the other distance displays use miles
+    for distances greater than 1000 feet.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1ea855f95772a8a394407e0070be1ed9cc0f6650
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun May 15 13:59:12 2016 -0700
+
+    telegps: Add monitor idle mode
+    
+    This monitors directly connected devices. No support for doing monitor
+    idle using packet mode, as TeleGPS doesn't support that.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit df276262900551a5eecd94903eefe9a264b161ec
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun May 15 13:58:41 2016 -0700
+
+    telegps: Use log_space when flight_log_max is missing
+    
+    TeleGPS has this, but not flight_log_max
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 9287122edc0e2dec6b2542f4cc8cb9cf2900bb33
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun May 15 13:57:28 2016 -0700
+
+    altoslib: Add AltosIdleReader
+    
+    This provides an AltosFlightReader interface for monitor idle mode,
+    making that easier to provide in TeleGPS
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 3c4278a29082a2af5911e22e59f8f52549f549e3
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun May 15 13:56:21 2016 -0700
+
+    altoslib: Add log_space to AltosState
+    
+    TeleGPS doesn't have flight_log_max value, but does have log_space
+    which we can use for the same thing in monitor idle mode.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f484216e72f81decb2aaa7289d6f69678990b7af
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun May 15 13:55:12 2016 -0700
+
+    altoslib: Set version and log space from AltosIdleFetch
+    
+    Just more data for monitor idle mode
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 29123a60272777916e5aae08369d0f03c2f135b6
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun May 15 13:53:38 2016 -0700
+
+    altoslib: Allow empty values in AltosHashSet representation
+    
+    Check for value termination before appending the first character.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b1a90adac9f6e2a609ce1ccd6749462bb5c9adbe
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 12 23:33:53 2016 -0700
+
+    altoslib: Store saved state in version-independent format
+    
+    Use AltosHashSet for AltosState so that AltosDroid doesn't lose
+    tracker information when the application is upgraded.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b13037fad0905c5933d1ff579122ba1357b02eea
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 12 19:13:05 2016 -0700
+
+    altoslib: Store common frequencies in library version-independent form
+    
+    Serializable Objects in java are very specific to the class being
+    serialized. As we bump the name of the library on a regular basis to
+    note API/ABI issues, this mean a saved a Serializable object in
+    the preferences database will fail to load across library version
+    upgrades.
+    
+    The saved tracker state and saved common frequencies were the only
+    objects saved in this form; this patch adds infrastructure for writing
+    objects in a version-independent form, and then adds support for
+    saving frequencies in that form.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2f4903f903223312d0a3a03dfd413059f24a07f5
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 12 19:10:19 2016 -0700
+
+    altosui/telegps/micropeak: Handle both MULTI_LIB and non-MULTI_LIB builds
+    
+    On x86 systems with -m32 and -m64 compilers, both libaltos32.so and
+    libaltos64.so are built. Otherwise, we should use libaltos.so
+    
+    altosui only dealt with libaltos32.so and libaltos64.so, so it only
+    worked on MULTI_LIB systems. telegps and micropeak only used
+    libaltos.so, so they wouldn't work correctly on multi-lib systems.
+    
+    Fix all of them to work either way.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 64ed56fe3132faa8585c9cd7b0261ac85f70a7bd
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 12 18:05:14 2016 -0700
+
+    Automatically run 'git submodule update' if necessary
+    
+    This makes sure pdclib exists by updating for the all and
+    all-recursive targets
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 97adfff4cfb67c17a96f3ff46606b4e439422b01
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 12 12:14:03 2016 -0700
+
+    Bump java library versions
+    
+    Prepare for 1.6.4 release
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 3450efdf8bd736a33900493eeda348ec2dacf7e8
+Author: Keith Packard <keithp@keithp.com>
+Date:   Thu May 12 12:13:45 2016 -0700
+
+    Bump android app version
+    
+    Prepare for 1.6.4 release
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit ba84b9c908d5909ea5a148c249709b21640f1eac
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed May 11 23:31:53 2016 -0700
+
+    telegps: Adapt to distance units switching changes
+    
+    'show_units' is no longer available; use 'parse_units' instead
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2ec7e14f0104e3a227ff566fa2fc1f6286ddd9d0
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed May 11 12:48:10 2016 -0700
+
+    altoslib: Get rid of AltosMap from AltosMapLoader
+    
+    Cleans up the loader API and eliminates a AltosMapTile for every chunk
+    of map data.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit ab905d2f7d8929080042cfd16cc418ea5792c3cb
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed May 11 12:43:51 2016 -0700
+
+    altosdroid: make disconnect stick past pause/restart
+    
+    Clear the active_device preference on disconnect so we don't reconnect
+    anytime the service gets activated.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 0a50669b1fde3e3c1cbc08c4836613b58ead219b
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed May 11 10:47:31 2016 -0700
+
+    altoslib: Clean up map file and url handling
+    
+    move it all to AltosMapStore.java
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 471091d0fddf09ed69df75e4f2fdd92e5f57b9c5
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 23:13:14 2016 -0700
+
+    doc: Start update for 1.6.4
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b2710128a715a109745ec40553a3d4149a7f49ab
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 23:04:23 2016 -0700
+
+    altosuilib: Don't flicker missing voltages when changing units
+    
+    For some reason, a value of MISSING -1 was getting used, which caused
+    displays to light up briefly with a weird value when switching between
+    metric and imperial units.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 895cb58a6cd7424ee63c24d791b5988f41f85d31
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 23:03:45 2016 -0700
+
+    altosdroid: Rate limit map loading pacifier
+    
+    Just like in altosui.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit c5f49d0ac254047f13c6c1ecfb5520eff72109ac
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 23:02:09 2016 -0700
+
+    altoslib: Allow map preloading to be aborted
+    
+    Close the map preload dialog and it would be nice to stop loading map
+    bits.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2e551e7c5f82a7e35d39e8f73e8e526e5484cd5d
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 22:50:23 2016 -0700
+
+    altosuilib: Rate limit map loading pacifier updates
+    
+    Just updating the pacifier was consuming a huge amount of CPU. Update
+    no more than once every 100ms.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 42021d9fdc6f7a74cc9b20ebf3cf60b4c5f4ea82
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 22:49:04 2016 -0700
+
+    altoslib: Remove some debug printf calls
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 60f4d69592c440ab7bb67a04f4c07fc7279d2c20
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 22:46:58 2016 -0700
+
+    altoslib: Switch distance from m/ft to km/miles for large values
+    
+    This adds lots of infrastructure to deal with making the unit used
+    depend on the value itself, and then uses it only for distances.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 6a6da23335e6e5864387c7a22946f80f51056a4f
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 12:29:14 2016 -0700
+
+    Add TeleMega to spec list. Add TeleGPS RF output.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit d92ca1cd4dfbacebd7aa1bbcfc671daee35dc808
+Author: Keith Packard <keithp@keithp.com>
+Date:   Tue May 10 12:28:51 2016 -0700
+
+    Publish firmware with keithp-fat
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit a371253bb5fc25e34d87507dc9b814530f4e28f6
+Author: Keith Packard <keithp@keithp.com>
+Date:   Mon May 9 17:57:12 2016 -0700
+
+    altosdroid: Check for closed before writing/reading bluetooth
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit c57d86f6c9b56e90c986f460f93663a3e16cdf7a
+Author: Keith Packard <keithp@keithp.com>
+Date:   Mon May 9 17:56:28 2016 -0700
+
+    altosui/telegps: Ship firmware for new hardware
+    
+    TBT v3.0 and Tmega v2.0
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f078235803a80403014b3e54039fd2d0e0704367
+Merge: 04759dd c457c82
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Mon May 9 15:52:38 2016 -0600
+
+    Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
+
+commit 04759dddeb29e4de9f7e6b3673dc06c633fa2369
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Mon May 9 15:52:21 2016 -0600
+
+    process updates made during 1.6.3 release cycle
+
+commit c457c827a7445098ba5effd410de754ff5c65843
+Author: Keith Packard <keithp@keithp.com>
+Date:   Mon May 9 11:48:42 2016 -0700
+
+    Bump version to 1.6.3.1
+    
+    Post 1.6.3 release
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b25785ee0afebaf516b8a1b8d08d36fbdadd74ca
+Author: Keith Packard <keithp@keithp.com>
+Date:   Mon May 9 11:33:48 2016 -0700
+
+    altos/cc1111: Use SW to drive UART RTS pin
+    
+    Can't get the hw to work.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2f0c977c747824d0798550ac64eceb1d66c50efd
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Fri May 6 18:12:20 2016 -0600
+
+    releasing 1.6.3
+
 commit 15ae97fbdb4e75a74ea2e716194661d19dec46ff
 Merge: ac7be4a 1216c0c
 Author: Bdale Garbee <bdale@gag.com>
index 0bb01619603f3974703cb306221fe18808b370f4..4145946ee5e2d03f84229cfadae1cc8baeadce8b 100644 (file)
@@ -6,6 +6,12 @@ MAINTAINERCLEANFILES = ChangeLog
 
 .PHONY: ChangeLog
 
+all: pdclib/Makefile
+all-recursive: pdclib/Makefile
+
+pdclib/Makefile:
+       git submodule update
+
 ChangeLog:
        (GIT_DIR=$(top_srcdir)/.git git log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \
        (touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)
@@ -42,9 +48,25 @@ fat_android = \
        altosdroid/bin/AltosDroid-debug.apk \
        altosdroid/bin/AltosDroid-release.apk
 
+fat_altos = \
+       src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx \
+       src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx \
+       src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx \
+       src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \
+       src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx \
+       src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx \
+       src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx \
+       src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx \
+       src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx \
+       src/telemetrum-v1.0/telemetrum-v1.0-$(VERSION).ihx \
+       src/telemetrum-v1.1/telemetrum-v1.1-$(VERSION).ihx \
+       src/telemetrum-v1.2/telemetrum-v1.2-$(VERSION).ihx \
+       src/telemetrum-v2.0/telemetrum-v2.0-$(VERSION).ihx \
+       src/telemini-v1.0/telemini-v1.0-$(VERSION).ihx
+
 keithp-fat: fat
        ssh keithp.com mkdir -p public_html/altos-$(VERSION)
-       scp -p $(fat_linux) $(fat_mac) $(fat_windows) $(fat_android) keithp.com:public_html/altos-$(VERSION)
+       scp -p $(fat_linux) $(fat_mac) $(fat_windows) $(fat_android) $(fat_altos) keithp.com:public_html/altos-$(VERSION)
 
 set-java-versions:
        $(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION)
index fd5227978b4f821cc828ec64e2180a90bd1b83ef..d95339b51a2e333ff043c496e4d7a919e9fec30e 100644 (file)
--- a/Releasing
+++ b/Releasing
@@ -21,10 +21,10 @@ These are Bdale's notes on how to do a release.
                git checkout branch-<version>           # the x.y parts only
                - cherry-pick or merge appropriate content from master
        
-       - make sure there is a doc/release-notes-<version>.xsl
-       - make sure that doc/altusmetrum.xsl has the right copyright year,
-         and add release to the revision history at the front (release notes
-         will be pulled in automatically)
+       - make sure there is a doc/release-notes-<version>.inc
+       - make sure that doc/altusmetrum-docinfo.xml has the right copyright 
+         year, and add release to the revision history at the front (release 
+         notes will be pulled in automatically)
        - make absolutely sure checked-out tree is "clean" 
        - make absolutely sure the pdclib/ submodule is on the master branch,
          up to date, and "clean"
@@ -89,7 +89,7 @@ These are Bdale's notes on how to do a release.
        (cd ~/altusmetrumllc ; git add Binaries ; git commit -a) 
        (cd ~/altusmetrumllc ; git push) 
 
-       - copy the relevant release notes file from doc/ to 
+       - copy the relevant release notes .html file from doc/ to 
            /home/bdale/web/altusmetrum/AltOS/releases/<rev>
 
        (cd ~/web/altusmetrum/AltOS/releases/<rev> ; rm *.tar.bz2)
index 15efc0e2a72294765626ce97fa5ace879f4b8702..246fb0b049d4789522616f96cf389d8041c16cbf 100644 (file)
@@ -30,7 +30,7 @@ import android.bluetooth.BluetoothSocket;
 import android.os.Handler;
 //import android.os.Message;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosBluetooth extends AltosDroidLink {
 
@@ -199,6 +199,8 @@ public class AltosBluetooth extends AltosDroidLink {
        }
 
        int write(byte[] buffer, int len) {
+               if (output == null)
+                       return -1;
                try {
                        output.write(buffer, 0, len);
                } catch (IOException ie) {
@@ -208,6 +210,8 @@ public class AltosBluetooth extends AltosDroidLink {
        }
 
        int read(byte[] buffer, int len) {
+               if (input == null)
+                       return -1;
                try {
                        return input.read(buffer, 0, len);
                } catch (IOException ie) {
index 64980dc7af020ded43140768249b2ec14d59aafb..eddc83b95c58bdd09f07a4072e828dc01fbb3b40 100644 (file)
@@ -20,7 +20,7 @@ import java.util.Arrays;
 import java.io.*;
 import java.lang.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.app.Activity;
 import android.graphics.*;
index 026e836df1e4f8c10038f0bb1879ad84b5089643..a62bf7fe0d051f818762dcfc02f1c301ca6d53c3 100644 (file)
@@ -51,7 +51,7 @@ import android.hardware.usb.*;
 import android.graphics.*;
 import android.graphics.drawable.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener {
 
@@ -825,9 +825,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
        }
 
-       private void disconnectDevice() {
+       private void disconnectDevice(boolean remember) {
                try {
-                       mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, null));
+                       mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, (Boolean) remember));
                } catch (RemoteException e) {
                }
        }
@@ -978,11 +978,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                case R.id.disconnect:
                        /* Disconnect the device
                         */
-                       disconnectDevice();
+                       disconnectDevice(false);
                        return true;
                case R.id.quit:
                        AltosDebug.debug("R.id.quit");
-                       disconnectDevice();
+                       disconnectDevice(true);
                        finish();
                        return true;
                case R.id.setup:
index 0fd9af75bf1f76302663eb7e30f98e665aaf6b4c..bca70d69d2de3331d08dfda93399334370db2831 100644 (file)
@@ -24,7 +24,7 @@ import java.util.UUID;
 
 import android.os.Handler;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public abstract class AltosDroidLink extends AltosLink {
 
index 43abef0fad6d92515550eb87e524f90d502436d8..b9b4b50f777d3d7c738784845dd4ebfbe9873ed9 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.AltosDroid;
 import java.util.*;
 import java.io.*;
 import android.location.Location;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public interface AltosDroidMapInterface {
        public void onCreateView(AltosDroid altos_droid);
index dd86c818b06b5822af48335ca465e23ec69c7fdf..446bbf041ef402e689b557df7c3ab49d1261aefa 100644 (file)
@@ -21,7 +21,7 @@ import java.util.*;
 import java.text.*;
 
 import android.content.Context;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosDroidPreferences extends AltosPreferences {
 
@@ -57,8 +57,13 @@ public class AltosDroidPreferences extends AltosPreferences {
        public static void set_active_device(DeviceAddress address) {
                synchronized(backend) {
                        active_device_address = address;
-                       backend.putString(activeDeviceAddressPreference, active_device_address.address);
-                       backend.putString(activeDeviceNamePreference, active_device_address.name);
+                       if (active_device_address != null) {
+                               backend.putString(activeDeviceAddressPreference, active_device_address.address);
+                               backend.putString(activeDeviceNamePreference, active_device_address.name);
+                       } else {
+                               backend.remove(activeDeviceAddressPreference);
+                               backend.remove(activeDeviceNamePreference);
+                       }
                        flush_preferences();
                }
        }
index 5c7ec513eb19f78e55f5c3c670d97378094c87dd..e48b7b2aa3202ec6e1acc1c8bf29444955a43eac 100644 (file)
@@ -24,7 +24,7 @@ import android.content.SharedPreferences;
 import android.os.Environment;
 import android.util.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        public final static String        NAME    = "org.altusmetrum.AltosDroid";
index 77dbbcb117935f96ae3cbfc5f4e62dfdcc1d4715..3e10d3a4a5329bc3ce5fb0cc0a183c048cdb183f 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 import android.location.Location;
 import android.app.Activity;
 import android.graphics.Color;
index ab142b175c43f4ba4a4e6d2cb23d46778bac835c..0061eba1c304aa1b1b7d01283f56eedb0f4dc869 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.AltosDroid;
 import java.util.*;
 import java.io.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.app.Activity;
 import android.graphics.*;
@@ -85,6 +85,8 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
        AltosMap                map;
        AltosDroid              altos_droid;
 
+       static int scale = 2;
+
        AltosLatLon     here;
        AltosLatLon     there;
        AltosLatLon     pad;
@@ -181,14 +183,14 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                        }
                }
 
-               public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(cache, upper_left, center, zoom, maptype, px_size, 2);
+               public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+                       super(cache, upper_left, center, zoom, maptype, px_size, scale);
                }
 
        }
 
-       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new MapTile(cache, upper_left, center, zoom, maptype, px_size);
+       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               return new MapTile(cache, upper_left, center, zoom, maptype, px_size, scale);
        }
 
        public AltosMapPath new_path() {
@@ -492,7 +494,7 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
 
        public void onCreateView(AltosDroid altos_droid) {
                this.altos_droid = altos_droid;
-               map = new AltosMap(this);
+               map = new AltosMap(this, scale);
                AltosPreferences.register_map_type_listener(this);
                map.set_maptype(AltosPreferences.map_type());
 
index fcdb930b4e688600df4bd9660227dc86c20f0887..9a828df51c29f3e1d05d1785bb1ec046e97332a6 100644 (file)
@@ -19,7 +19,7 @@ package org.altusmetrum.AltosDroid;
 
 import java.util.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import com.google.android.gms.maps.*;
 import com.google.android.gms.maps.model.*;
index 4660512a7067e96aa12d17e043a005fc532b1a44..4b007cb158ed3459e594dac59dbf7935253a7929 100644 (file)
@@ -28,7 +28,7 @@ import android.hardware.usb.*;
 import android.app.*;
 import android.os.Handler;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosUsb extends AltosDroidLink {
 
index 542ba1f581f1d24b698149ef882164c053a56584..d7c0f6237c4843a551e0451c4ecca3110117e9e7 100644 (file)
@@ -22,7 +22,7 @@ import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeech.OnInitListener;
 import android.location.Location;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosVoice {
 
index ec12c1925b98e0c07eff7e44d85b25d01b3c90c2..c4e950b66bfff99b3b6f0c772911dbda92bce20f 100644 (file)
@@ -34,7 +34,7 @@ import android.view.View.OnClickListener;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class IdleModeActivity extends Activity {
        private EditText callsign;
index 931c3cfd7a36ab3b478b08ec97408170a8392552..d9229ad6b03213f4ef4106b5cc28ed317b0166bd 100644 (file)
@@ -32,7 +32,7 @@ import android.view.View.*;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class IgniterItem {
        public String name;
index 401cdc9d1559dd88a1090bf08508e13411a2ac50..d8fd92df740e1139daa0a86d7bd20c7929785303 100644 (file)
@@ -32,7 +32,7 @@ import android.view.inputmethod.*;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class FrequencyItem {
        public AltosFrequency frequency;
@@ -125,6 +125,8 @@ public class ManageFrequenciesActivity extends Activity {
 
        private void done() {
 
+               set();
+
                if (changed) {
                        AltosFrequency[] frequencies = new AltosFrequency[frequencies_adapter.count()];
                        for (int i = 0; i < frequencies.length; i++)
@@ -164,6 +166,16 @@ public class ManageFrequenciesActivity extends Activity {
                load_item();
        }
 
+       private int find(AltosFrequency frequency) {
+               for (int pos = 0; pos < frequencies_adapter.getCount(); pos++) {
+                       FrequencyItem   item = frequencies_adapter.getItem(pos);
+                       if (item.frequency.frequency == frequency.frequency &&
+                           item.frequency.description.equals(frequency.description))
+                               return pos;
+               }
+               return -1;
+       }
+
        private int insert_item(AltosFrequency frequency) {
                FrequencyItem new_item = new FrequencyItem(frequency);
                int     pos;
@@ -200,11 +212,16 @@ public class ManageFrequenciesActivity extends Activity {
 
                try {
                        double  f = AltosParse.parse_double_locale(frequency_text);
+                       AltosFrequency frequency = new AltosFrequency(f, description_text);
+                       int pos;
 
-                       int pos = insert_item(new AltosFrequency(f, description_text));
+                       pos = find(frequency);
+                       if (pos < 0) {
+                               pos = insert_item(frequency);
+                               changed = true;
+                       }
                        frequencies_adapter.selected_item = -1;
                        select_item(pos);
-                       changed = true;
                } catch (ParseException pe) {
                }
                hide_keyboard();
index cfbcdafc3b6e4e195c41de12fdf80bcb8ff0a4bd..d8bcad753e689c91fb9501aa0a18b46e5e98a4aa 100644 (file)
@@ -34,7 +34,7 @@ import android.view.View.OnClickListener;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class MapTypeActivity extends Activity {
        private Button hybrid;
index 13a44e1f6902f3def172a88c8b31adb776729860..8e3e7b01c2822737a0e9fc778edc473e3e49f0c4 100644 (file)
@@ -41,7 +41,7 @@ import android.location.LocationManager;
 import android.location.LocationListener;
 import android.location.Criteria;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 /**
  * This Activity appears as a dialog. It lists any paired devices and
@@ -49,7 +49,7 @@ import org.altusmetrum.altoslib_10.*;
  * by the user, the MAC address of the device is sent back to the parent
  * Activity in the result Intent.
  */
-public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapInterface, AltosMapLoaderListener, LocationListener {
+public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapLoaderListener, LocationListener {
 
        private ArrayAdapter<AltosLaunchSite> known_sites_adapter;
 
@@ -69,8 +69,14 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
 
        private ProgressBar     progress;
 
+       private AltosMapLoader  loader;
+
+       long    loader_notify_time;
+
        /* AltosMapLoaderListener interfaces */
        public void loader_start(final int max) {
+               loader_notify_time = System.currentTimeMillis();
+
                this.runOnUiThread(new Runnable() {
                                public void run() {
                                        progress.setMax(max);
@@ -80,6 +86,13 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        public void loader_notify(final int cur, final int max, final String name) {
+               long    now = System.currentTimeMillis();
+
+               if (now - loader_notify_time < 100)
+                       return;
+
+               loader_notify_time = now;
+
                this.runOnUiThread(new Runnable() {
                                public void run() {
                                        progress.setProgress(cur);
@@ -88,6 +101,7 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        public void loader_done(int max) {
+               loader = null;
                this.runOnUiThread(new Runnable() {
                                public void run() {
                                        progress.setProgress(0);
@@ -96,7 +110,12 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                        });
        }
 
+       public void debug(String format, Object ... arguments) {
+               AltosDebug.debug(format, arguments);
+       }
+
        /* AltosLaunchSiteListener interface */
+
        public void notify_launch_sites(final List<AltosLaunchSite> sites) {
                this.runOnUiThread(new Runnable() {
                                public void run() {
@@ -106,70 +125,6 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                        });
        }
 
-       AltosMap        map;
-
-       class PreloadMapImage implements AltosImage {
-               public void flush() {
-               }
-
-               public PreloadMapImage(File file) {
-               }
-       }
-
-       public AltosMapPath new_path() {
-               return null;
-       }
-
-       public AltosMapLine new_line() {
-               return null;
-       }
-
-       public AltosImage load_image(File file) throws Exception {
-               return new PreloadMapImage(file);
-       }
-
-       public AltosMapMark new_mark(double lat, double lon, int state) {
-               return null;
-       }
-
-       class PreloadMapTile extends AltosMapTile {
-               public void paint(AltosMapTransform t) {
-               }
-
-               public PreloadMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(cache, upper_left, center, zoom, maptype, px_size, 2);
-               }
-
-       }
-
-       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new PreloadMapTile(cache, upper_left, center, zoom, maptype, px_size);
-       }
-
-       public int width() {
-               return AltosMap.px_size;
-       }
-
-       public int height() {
-               return AltosMap.px_size;
-       }
-
-       public void repaint() {
-       }
-
-       public void repaint(AltosRectangle damage) {
-       }
-
-       public void set_zoom_label(String label) {
-       }
-
-       public void select_object(AltosLatLon latlon) {
-       }
-
-       public void debug(String format, Object ... arguments) {
-               AltosDebug.debug(format, arguments);
-       }
-
        /* LocationProvider interface */
 
        AltosLaunchSite current_location_site;
@@ -234,7 +189,7 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        private double radius() {
                double r = value_distance(radius);
                if (AltosPreferences.imperial_units())
-                       r = AltosConvert.distance.inverse(r);
+                       r = AltosConvert.miles_to_meters(r);
                else
                        r = r * 1000;
                return r;
@@ -254,6 +209,9 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        private void load() {
+               if (loader != null)
+                       return;
+
                try {
                        double  lat = latitude();
                        double  lon = longitude();
@@ -264,7 +222,7 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
 
                        AltosDebug.debug("PreloadMap load %f %f %d %d %f %d\n",
                                         lat, lon, min, max, r, t);
-                       new AltosMapLoader(map, this, lat, lon, min, max, r, t);
+                       loader = new AltosMapLoader(this, lat, lon, min, max, r, t, AltosMapOffline.scale);
                } catch (ParseException e) {
                        AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
                }
@@ -395,8 +353,6 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                known_sites_spinner.setAdapter(known_sites_adapter);
                known_sites_spinner.setOnItemSelectedListener(new SiteListListener());
 
-               map = new AltosMap(this);
-
                // Listen for GPS and Network position updates
                LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 
@@ -409,6 +365,9 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        protected void onDestroy() {
                super.onDestroy();
 
+               if (loader != null)
+                       loader.abort();
+
                // Stop listening for location updates
                ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
        }
index fdffc2b0c7242316267ea14b3680b2efd4577f1a..06e74d9be7dbe8c62df9b41038424e28223d685b 100644 (file)
@@ -30,7 +30,7 @@ import android.view.View.*;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class SetupActivity extends Activity {
        private Spinner select_rate;
index 9bbdc0605dfcfcf6e9d93152ab0a823282b6a5bf..dc8390e3dcd8b2041b42b1a7249c98e5ce30a04a 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.app.Activity;
 import android.os.Bundle;
index 19ce86c9f75c5e80448486e8ab11174c95a94c69..9e3cb530cc3a821ddd796ca2212c69cdf978c688 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.AltosDroid;
 import java.util.*;
 import java.io.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.app.Activity;
 import android.graphics.*;
index 1194eb002665d011e538cc932092677c0eef5959..fffc426a1bf99156320a1c6e9f8294407e819b54 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.app.Activity;
 import android.os.Bundle;
index 8742227b7507130fd036e82b3d2e9d73c411df83..b0fe9e5fe4001c1aeb0ce9b08a39ff2432ca8cbf 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.app.Activity;
 import android.os.Bundle;
index bdea0986cf62d605b842afa2bd6035ad9daca6e8..c379d3d84af153f77bd68f32eb5866d62eea4c52 100644 (file)
@@ -1,6 +1,6 @@
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
index 0ac6bb5c1429938676feb24e5418a7ffd19a21db..21ac0fbfb3dfea3594524648900dd092db982612 100644 (file)
@@ -25,7 +25,7 @@ import java.util.*;
 import java.util.concurrent.*;
 import android.os.Handler;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 
 public class TelemetryReader extends Thread {
index 3c1a17823d595c681cfa61a938e6537093df173f..dc39c899822ef9ad995ae52c2658f2e21b37e29e 100644 (file)
@@ -40,7 +40,7 @@ import android.os.Looper;
 import android.widget.Toast;
 import android.location.Criteria;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class TelemetryService extends Service implements AltosIdleMonitorListener {
 
@@ -129,6 +129,8 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
                        case MSG_DISCONNECT:
                                AltosDebug.debug("Disconnect command received");
                                s.address = null;
+                               if (!(Boolean) msg.obj)
+                                       AltosDroidPreferences.set_active_device(null);
                                s.disconnect(true);
                                break;
                        case MSG_DELETE_SERIAL:
@@ -612,6 +614,8 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
 
                telemetry_state.latest_serial = AltosPreferences.latest_state();
 
+               AltosDebug.debug("latest serial %d\n", telemetry_state.latest_serial);
+
                for (int serial : serials) {
                        AltosState saved_state = AltosPreferences.state(serial);
                        if (saved_state != null) {
@@ -628,6 +632,7 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
                                telemetry_state.states.put(serial, saved_state);
                        } else {
                                AltosDebug.debug("Failed to recover state for %d", serial);
+                               AltosPreferences.remove_state(serial);
                        }
                }
        }
index d3ccf0a9d8e576bab5e75c5cb96f2d0906790677..e7bef92c27648ff7702e33e35cc961b6009b06d4 100644 (file)
@@ -18,7 +18,7 @@
 package org.altusmetrum.AltosDroid;
 
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 import android.location.Location;
 
 public class TelemetryState {
index 2c563f66153c1e361e7aaa094a107b246f80a6a4..c6a2da114f5446f3e1abc938bd16cb02154cbb48 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosAccel extends AltosUnits implements Serializable {
+public class AltosAccel extends AltosUnits {
 
        public double value(double v, boolean imperial_units) {
                if (imperial_units)
index 03dad1375c1857172d57af9a36a188f3d1c4217d..87d84370ac60495c0048b2050998ab2c0f08d0b3 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosCRCException extends Exception {
        public int rssi;
index fa515b311858c4bb7fe6280be5f6b018740c7768..b38ed8dad3cdc3cfd1303e1a31347125d653f43c 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index dc33daccf907bd46d2507ae7eccde1dd722af472..e228b074d8f5729ae77e822e081efa7ebdb16972 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosCompanion implements Serializable {
+public class AltosCompanion {
        public final static int board_id_telescience = 0x0a;
        public final static int MAX_CHANNELS = 12;
 
@@ -37,4 +37,9 @@ public class AltosCompanion implements Serializable {
                        channels = MAX_CHANNELS;
                companion_data = new int[channels];
        }
+
+       public AltosCompanion() {
+               channels = 0;
+               companion_data = new int[0];
+       }
 }
index 812296f33dff04483f08d8ed9ebfb78102096920..ce430d7a9137f082ddffcf667acd7f7c805f1dd8 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.*;
 import java.text.*;
@@ -204,7 +204,7 @@ public class AltosConfigData implements Iterable<String> {
 
                for (int i = 0; i < parts.length; i++) {
                        try {
-                               r[i] = AltosLib.fromdec(parts[i]);
+                               r[i] = (int) AltosLib.fromdec(parts[i]);
                        } catch (NumberFormatException n) {
                                r[i] = 0;
                        }
index 75cd1695543ff11714d838d03ff729317d00673f..a55f75c2610bbeae680638954c7e6de576a00e28 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosConfigDataException extends Exception {
 
index aab0892a0537218810debbc68cb9b298028c21bb..babd7a4d98f5c9465db5cbc9801efc7b66ca0676 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosConfigValues {
        /* set and get all of the dialog values */
index 265b5f0f633e26a544203d83b188a52971166468..5498ae98cb855f66d42cd858bf275a71ad830b08 100644 (file)
@@ -18,7 +18,7 @@
 /*
  * Sensor data conversion functions
  */
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosConvert {
        /*
index e93c2d2de74720a8d81783f1249545714fc4164c..0bb126881fb757e1e7df260885e395e73a24ccfb 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
index b68a4525d79c8565951930b91c2b1db0b8f020fb..1ade5abbe354b3356ceddd6b3f5667d04d24acbd 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosDistance extends AltosUnits {
 
@@ -54,4 +54,58 @@ public class AltosDistance extends AltosUnits {
                        return 1;
                return 0;
        }
-}
\ No newline at end of file
+
+       public AltosDistance() {
+               range_metric = new AltosUnitsRange[2];
+
+               range_metric[0] = new AltosUnitsRange(0, "m", "meters") {
+                               double value(double v) {
+                                       return v;
+                               }
+                               int show_fraction(int width) {
+                                       return width / 9;
+                               }
+                               int say_fraction() {
+                                       return 0;
+                               }
+                       };
+               range_metric[1] = new AltosUnitsRange(2000, "km", "kilometers") {
+                               double value(double v) {
+                                       return v / 1000;
+                               }
+                               int show_fraction(int width) {
+                                       return width / 5;
+                               }
+                               int say_fraction() {
+                                       return 1;
+                               }
+                       };
+
+               range_imperial = new AltosUnitsRange[2];
+
+               range_imperial[0] = new AltosUnitsRange(0, "ft", "feet") {
+                               double value(double v) {
+                                       return AltosConvert.meters_to_feet(v);
+                               }
+                               int show_fraction(int width) {
+                                       return width / 9;
+                               }
+                               int say_fraction() {
+                                       return 0;
+                               }
+                       };
+
+               range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(1000),
+                                                       "mi", "miles") {
+                               double value(double v) {
+                                       return AltosConvert.meters_to_miles(v);
+                               }
+                               int show_fraction(int width) {
+                                       return width / 5;
+                               }
+                               int say_fraction() {
+                                       return 1;
+                               }
+                       };
+       }
+}
index 5f0a349fb8207f6ba769040ab499cd749b46b864..94009b57ab30f3770cd94428d9b65d4507f68e92 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 7a80e29489df6e7ba60ff34915f19224325f8f32..4f95663690ab43edbd3cd0e40f5acbe4c56a154e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 import java.util.concurrent.*;
index 1a02cb9c1baf14ea2993af1416407f3d5cb10249..fa76574cb568528ee8e8352967611e2440ff7e61 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 000bb1be4d33c7530c03bdcf9a652af348be6622..d23116a66a71bb57866ca641a1461bf63e0fe3d6 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index a0a074ee2533ce396da4a0fb88105091111b6a8c..a6d2ef32dc307ccb2081535c551a8b00ad507812 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 6c8c56d45c403a25f61fc889216c3f414c207e6c..1f94ac07c2a16df90ab8e4f21b092481bf0c9c2c 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 97bb9285667fd703ab337615f76794a7eed2f5eb..c0311b99c586c8ed92e4c0501f5a4e50a5f9c84e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 4d511ead917d3002688c3919d85031094e052c9e..abc30a710e16f1058fc29b9f8668a9d5b4d2e66b 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index f0ed2db4c91f663862848e2d16d9a55d0e8da6cc..9eb5d23093abd13804ea07bcb6a23c1fdee693dc 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 import java.util.concurrent.*;
index 29f0aa905dc51442d1ec3878d8d8df85de4e4349..09fb4288e45871f897987ba01a2d1fe5772b3623 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 5662c8e56e00939915c66f384436770ab63d566e..f23bffd263bbd620148e111d19c44b07886af1ff 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index f429a0e8d73908bd295d5d3d7fa0ee526c08de7a..b06e6c84e9127090ed29051b2ecae70f84907041 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index a966c63165524f7fff3e8093ec53867f223c5210..9f6094a55e30288b460c998f37725b583f48d9d8 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosEepromMonitor {
 
index 7a27a234cf16148ab8b3f94ab783e8b5162b6937..a65bd11ef3495554f2c2f4dce2f611417cae243b 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 8f01c08880b2ebf2b83f3552f9daf8cb7d5878ba..82f5aedf73dd2fd05963c263530ecac8490c04fc 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index d1d1761072cb4ecfde8a2e8877ee7478c56b969d..dc2dba82b925b5fa8eac5a7a4074f641f205097f 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.File;
 import java.util.*;
index d79edf686ee0a801093852139879798b309ef57c..285e31d59811e7eec725c7ac743f4f24673456e7 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
index 8d171baf32abe5a686e5bcbff409815cccb0da5c..170bf0b089bde31534a275b26bf6e6a6dff37365 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosFlashListener {
        public void position(String label, int percent);
index 4b57526a219d35734c5de773f9f274e1efa40559..5a6d88d17f810f4b3efe2e4d57e65b7e69be6437 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener {
        void reset();
index 62f24e9f5aa98cc79ad63268afc8b6247e9f47c9..77711a4cc8f3c90fce1e5b8899561ce2e3b8f3aa 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 import java.io.*;
index 1c7d67e0719d3d7c3a7df5b091423da1b81ceace..32314b2becab8ac0031e2a1e407f173ac020bc88 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
index 565f50e41b110f3347b1f5523f79ea1af88e794d..9a1622d9c495880c30b87478cb134a15b20c66d7 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosFontListener {
        void font_size_changed(int font_size);
index 9542fe333858cdac0cbe715db08b1b4001cc41ed..874a9bccb5a41f8682056eb626b47bb6d73720e6 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
 import java.text.*;
 
-public class AltosFrequency implements Serializable {
+public class AltosFrequency {
        public double   frequency;
        public String   description;
 
@@ -57,7 +57,6 @@ public class AltosFrequency implements Serializable {
 
                return diff < 0.010;
        }
-
        public AltosFrequency(double f, String d) {
                frequency = f;
                description = d;
index c5290a3a0be52afa70d1dbf967dc459508264e5a..d29ccdd1fbe0f6d0e035a50f1cd4aacecad797fd 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosGPS implements Cloneable, Serializable {
+public class AltosGPS implements Cloneable {
 
        public final static int MISSING = AltosLib.MISSING;
 
index c853b634f49514c1827600ff3470d2d139ffe896..8b95c150a4e6a594eb986892db2dd84e332da557 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
+
+import java.io.*;
 import java.text.*;
+import java.util.*;
 import java.util.concurrent.*;
-import java.io.*;
 
-public class AltosGPSSat implements Serializable {
+public class AltosGPSSat {
        public int      svid;
        public int      c_n0;
 
index de3904bff1cbadd38489115d3ac0ccfe9bebe9bd..a2f128074c89ebe29b446f7af027683762acf9b4 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.lang.Math;
 import java.io.*;
 
-public class AltosGreatCircle implements Cloneable, Serializable {
+public class AltosGreatCircle implements Cloneable {
        public double   distance;
        public double   bearing;
        public double   range;
@@ -71,7 +71,10 @@ public class AltosGreatCircle implements Cloneable, Serializable {
                                course = 2 * Math.PI-course;
                }
                distance = d * earth_radius;
-               bearing = course * 180/Math.PI;
+               if (Double.isNaN(course) || Double.isInfinite(course))
+                       bearing = 0;
+               else
+                       bearing = course * 180/Math.PI;
 
                double height_diff = end_alt - start_alt;
                range = Math.sqrt(distance * distance + height_diff * height_diff);
index 2bae25664975b161ce7f2e1992be4504c05cdd0f..01bd4a6b84462e6b607c5283785f69675f2a4bb7 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosHeight extends AltosUnits {
 
index f72d4183fa307a1b4abdcf3131fcc27a4f12ccdc..e7f900c48defa17deca930ef6fb905b33e61a830 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.LinkedList;
index 1d9cbb186cc30d49b8b5824f837e47a7ce7da0cf..ab2beff50599663374bc878dbc4f9e164b8beb1a 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosHexsym {
        String  name;
index 62539e08cd3531342af6b1aae3180a9a53481851..dbadcf898efbab85db95d47f5579df9686f9ea56 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosIMU implements Cloneable, Serializable {
+public class AltosIMU implements Cloneable {
        public int              accel_along;
        public int              accel_across;
        public int              accel_through;
@@ -29,13 +29,13 @@ public class AltosIMU implements Cloneable, Serializable {
        public int              gyro_pitch;
        public int              gyro_yaw;
 
-       public static double    counts_per_g = 2048.0;
+       public static final double      counts_per_g = 2048.0;
 
        public static double convert_accel(double counts) {
                return counts / counts_per_g * (-AltosConvert.GRAVITATIONAL_ACCELERATION);
        }
 
-       public static double    counts_per_degsec = 16.4;
+       public static final double      counts_per_degsec = 16.4;
 
        public static double convert_gyro(double counts) {
                return counts / counts_per_degsec;
index 07a628c314abcf3b3afe66bc1e1bf2ebb6f56ec9..36a3ca0474bc9f85c4f32fe17cb70d107452959a 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 0095bb732899d81ffa445db1049bc5aece33efcb..5102c16b3f6f92f0cb50478d26500944899a0dff 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
@@ -134,9 +134,6 @@ public class AltosIdleFetch implements AltosStateUpdate {
 
        AltosLink               link;
 
-       double                  frequency;
-       String                  callsign;
-
        public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct {
                try {
                        boolean matched = false;
@@ -148,6 +145,8 @@ public class AltosIdleFetch implements AltosStateUpdate {
                        state.set_ground_accel(config_data.accel_cal_plus);
                        state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
                        state.set_product(config_data.product);
+                       state.set_firmware_version(config_data.version);
+                       state.set_log_space(config_data.log_space);
                        for (AltosIdler idler : idlers) {
                                if (idler.matches(config_data)) {
                                        idler.update_state(state, link, config_data);
index c67b4d8aa6b5f08e696959323bd0af1aef28d851..fde8c101a5df382968d93099a97d60f91090ceed 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.concurrent.*;
index 36857f588d5e98fcb634a4d257a3c464a112ba99..27a5146673d8271cea730234418d6384d6490f00 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosIdleMonitorListener {
        public void update(AltosState state, AltosListenerState listener_state);
diff --git a/altoslib/AltosIdleReader.java b/altoslib/AltosIdleReader.java
new file mode 100644 (file)
index 0000000..795593f
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright Â© 2016 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.altoslib_11;
+
+import java.text.*;
+import java.io.*;
+import java.util.concurrent.*;
+
+public class AltosIdleReader extends AltosFlightReader {
+       AltosLink       link;
+       boolean         remote;
+       AltosState      state = null;
+       AltosIdleFetch  fetch;
+       long            next_millis;
+       static final long       report_interval = 5 * 1000;
+       static final long       minimum_delay = 1 * 1000;
+
+       private void start_link() throws InterruptedException, TimeoutException {
+               if (remote) {
+                       link.start_remote();
+               } else
+                       link.flush_input();
+       }
+
+       private boolean stop_link() throws InterruptedException, TimeoutException {
+               if (remote)
+                       link.stop_remote();
+               return link.reply_abort;
+       }
+
+       public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException {
+               boolean worked = false;
+               boolean aborted = false;
+
+               if (state == null)
+                       state = new AltosState();
+               else
+                       state = state.clone();
+
+               long    delay = next_millis - System.currentTimeMillis();
+
+               if (delay > 0)
+                       Thread.sleep(delay);
+               next_millis = System.currentTimeMillis() + report_interval;
+               try {
+                       try {
+                               start_link();
+                               fetch.update_state(state);
+                               if (!link.has_error && !link.reply_abort)
+                                       worked = true;
+                       } catch (TimeoutException te) {
+                       } catch (AltosUnknownProduct ue) {
+                               worked = true;
+                       }
+               } finally {
+                       try {
+                               aborted = stop_link();
+                       } catch (TimeoutException te) {
+                               aborted = true;
+                       }
+                       if (worked) {
+                               if (remote) {
+                                       try {
+                                               state.set_rssi(link.rssi(), 0);
+                                       } catch (TimeoutException te) {
+                                               state.set_rssi(0, 0);
+                                       }
+                               }
+                       }
+               }
+
+               long    finish = System.currentTimeMillis();
+
+               if (next_millis - finish < minimum_delay)
+                       next_millis = finish + minimum_delay;
+
+               return state;
+       }
+
+       public void close(boolean interrupted) {
+               try {
+                       link.close();
+               } catch (InterruptedException ie) {
+               }
+       }
+
+       public void set_frequency(double frequency) throws InterruptedException, TimeoutException {
+               link.set_radio_frequency(frequency);
+       }
+
+       public void save_frequency() {
+               AltosPreferences.set_frequency(link.serial, link.frequency);
+       }
+
+       public void set_callsign(String callsign) throws InterruptedException, TimeoutException {
+               link.set_callsign(callsign);
+       }
+
+       public AltosIdleReader (AltosLink link, boolean remote)
+               throws IOException, InterruptedException, TimeoutException {
+               this.link = link;
+               this.remote = remote;
+               this.next_millis = System.currentTimeMillis();
+               fetch = new AltosIdleFetch(link);
+       }
+}
index ab9c2da667b72991d976b505324869382bd3865c..f3c07339b0fc411ec52ef195723a9f1b05869db5 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.*;
 import java.io.*;
index d54335c7f18b87fe1e9edc10ecd17958c6b2d9ca..9a0751b672cc3d71f289ec19de30c4fd6640f95e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
diff --git a/altoslib/AltosJson.java b/altoslib/AltosJson.java
new file mode 100644 (file)
index 0000000..67f3a00
--- /dev/null
@@ -0,0 +1,1314 @@
+/*
+ * Copyright Â© 2016 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.altoslib_11;
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.*;
+import java.lang.reflect.*;
+
+class JsonUtil {
+       StringBuffer quote(StringBuffer result, String a) {
+               result.append("\"");
+               for (int i = 0; i < a.length(); i++) {
+                       char c = a.charAt(i);
+
+                       switch (c) {
+                       case '"':
+                       case '\\':
+                               result.append('\\').append(c);
+                               break;
+                       case '\n':
+                               result.append("\\n");
+                               break;
+                       default:
+                               result.append(c);
+                               break;
+                       }
+               }
+               result.append("\"");
+               return result;
+       }
+
+       StringBuffer append(StringBuffer result, AltosJson value, int indent, boolean pretty) {
+               value.append(result, indent, pretty);
+               return result;
+       }
+
+       StringBuffer append(StringBuffer result, String string) {
+               result.append(string);
+               return result;
+       }
+
+       StringBuffer indent(StringBuffer result, int indent) {
+               result.append("\n");
+               for (int i = 0; i < indent; i++)
+                       result.append("\t");
+               return result;
+       }
+       static NumberFormat get_nf_json() {
+               DecimalFormat nf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
+               nf.setParseIntegerOnly(false);
+               nf.setGroupingUsed(false);
+               nf.setMaximumFractionDigits(17);
+               nf.setMinimumFractionDigits(0);
+               nf.setMinimumIntegerDigits(1);
+               nf.setDecimalSeparatorAlwaysShown(false);
+               return nf;
+       }
+
+       static NumberFormat nf_json = get_nf_json();
+}
+
+class JsonHash extends JsonUtil {
+       Hashtable<String,AltosJson> hash;
+
+       void append_hash(StringBuffer result, int indent, boolean pretty) {
+               boolean         first = true;
+
+               result.append("{");
+
+               ArrayList<String> key_list = new ArrayList<String>(hash.keySet());
+
+               Collections.sort(key_list, new Comparator<String>() {
+                               @Override
+                               public int compare(String a, String b) { return a.compareTo(b); }
+                       });
+
+               for (String key : key_list) {
+                       AltosJson       value = hash.get(key);
+
+                       if (!first)
+                               result.append(",");
+                       first = false;
+                       if (pretty)
+                               indent(result, indent+1);
+                       quote(result, key);
+                       append(result, ": ");
+                       append(result, value, indent+1, pretty);
+               }
+               if (pretty)
+                       indent(result, indent);
+               append(result, "}");
+       }
+
+       void put(String key, AltosJson value) {
+               hash.put(key, value);
+       }
+
+       AltosJson get(String key) {
+               return hash.get(key);
+       }
+
+       JsonHash() {
+               hash = new Hashtable<String,AltosJson>();
+       }
+}
+
+class JsonArray extends JsonUtil {
+       ArrayList<AltosJson> array;
+
+       void append_array(StringBuffer result, int indent, boolean pretty) {
+               boolean first = true;
+
+               append(result, "[");
+               for (int i = 0; i < array.size(); i++) {
+                       AltosJson       value = array.get(i);
+
+                       if (!first)
+                               append(result, ",");
+                       first = false;
+                       if (pretty)
+                               indent(result, indent+1);
+                       append(result, value, indent+1, pretty);
+               }
+               if (pretty)
+                       indent(result, indent);
+               append(result, "]");
+       }
+
+       void put(int index, AltosJson value) {
+               if (index >= array.size())
+                       array.add(index, value);
+               else
+                       array.set(index, value);
+       }
+
+       AltosJson get(int index) {
+               if (index < 0 || index > array.size())
+                       return null;
+               return array.get(index);
+       }
+
+       int size() {
+               return array.size();
+       }
+
+       JsonArray() {
+               array = new ArrayList<AltosJson>();
+       }
+}
+
+class JsonToken {
+       double  dval;
+       long    lval;
+       String  sval;
+       boolean bval;
+       int     token;
+
+       static final int _string = 0;
+       static final int _double = 1;
+       static final int _long = 2;
+       static final int _boolean = 3;
+       static final int _oc = 4;
+       static final int _cc = 5;
+       static final int _os = 6;
+       static final int _cs = 7;
+       static final int _comma = 8;
+       static final int _colon = 9;
+       static final int _end = 10;
+       static final int _error = 11;
+
+       static String token_name(int token) {
+               switch (token) {
+               case _string:
+                       return "string";
+               case _double:
+                       return "number";
+               case _long:
+                       return "number";
+               case _boolean:
+                       return "boolean";
+               case _oc:
+                       return "{";
+               case _cc:
+                       return "}";
+               case _os:
+                       return "[";
+               case _cs:
+                       return "]";
+               case _comma:
+                       return ",";
+               case _colon:
+                       return ":";
+               case _end:
+                       return "<EOF>";
+               case _error:
+                       return "<ERROR>";
+               default:
+                       return "<UNKNOWN>";
+               }
+       }
+
+       String token_name() {
+               return token_name(token);
+       }
+
+       JsonToken(int token) {
+               this.token = token;
+       }
+
+       JsonToken(int token, boolean bval) {
+               this.token = token;
+               this.bval = bval;
+       }
+
+       JsonToken(int token, double dval) {
+               this.token = token;
+               this.dval = dval;
+       }
+
+       JsonToken(int token, long lval) {
+               this.token = token;
+               this.lval = lval;
+       }
+
+       JsonToken(int token, String sval) {
+               this.token = token;
+               this.sval = sval;
+       }
+
+       JsonToken(int token, StringBuffer bval) {
+               this(token, bval.toString());
+       }
+}
+
+/*
+ * Lexer for json
+ */
+class JsonLexer extends JsonUtil {
+       StringReader    f;
+       int             line;
+       int             ungot = -2;
+       StringBuffer    pending_token;
+       JsonToken       token;
+
+       static class keyword {
+               String          word;
+               JsonToken       token;
+
+               JsonToken match(String value) {
+                       if (word.equals(value))
+                               return token;
+                       return null;
+               }
+
+               keyword(String word, JsonToken token) {
+                       this.word = word;
+                       this.token = token;
+               }
+       }
+
+       /* boolean values are the only keywords in json
+        */
+       static keyword[] keywords = {
+               new keyword("true", new JsonToken(JsonToken._boolean, true)),
+               new keyword("false", new JsonToken(JsonToken._boolean, false)),
+               new keyword("NegInfinity", new JsonToken(JsonToken._double, Double.NEGATIVE_INFINITY)),
+               new keyword("Infinity", new JsonToken(JsonToken._double, Double.POSITIVE_INFINITY)),
+               new keyword("NaN", new JsonToken(JsonToken._double, Double.NaN))
+       };
+
+       static JsonToken keyword(String word) {
+               for (int i = 0; i < keywords.length; i++) {
+                       JsonToken token = keywords[i].match(word);
+                       if (token != null)
+                               return token;
+               }
+               return null;
+       }
+
+       /* Get the next char (-1 for EOF) */
+       int ch() throws IOException {
+               int c;
+               if (ungot != -2) {
+                       c = ungot;
+                       ungot = -2;
+               } else
+                       c = f.read();
+               if (c != -1)
+                       pending_token.append((char) c);
+               if (c == '\n')
+                       ++line;
+               return c;
+       }
+
+       void unch(int c) {
+               if (ungot != -2)
+                       throw new IllegalArgumentException("ungot buffer full");
+               pending_token.deleteCharAt( pending_token.length()-1);
+               if (c == '\n')
+                       --line;
+               ungot = c;
+       }
+
+       String last_token_string() {
+               if (pending_token == null)
+                       return null;
+
+               return pending_token.toString();
+       }
+
+       static boolean is_long_range(double d) {
+               return -9223372036854775808.0 <= d && d <= 9223372036854775807.0;
+       }
+
+       JsonToken lex() {
+               pending_token = new StringBuffer();
+
+               try {
+                       for (;;) {
+                               int c = ch();
+
+                               switch (c) {
+                               case -1:
+                                       return new JsonToken(JsonToken._end);
+                               case '\n':
+                               case ' ':
+                               case '\t':
+                                       continue;
+                               case '{':
+                                       return new JsonToken(JsonToken._oc);
+                               case '}':
+                                       return new JsonToken(JsonToken._cc);
+                               case '[':
+                                       return new JsonToken(JsonToken._os);
+                               case ']':
+                                       return new JsonToken(JsonToken._cs);
+                               case ',':
+                                       return new JsonToken(JsonToken._comma);
+                               case ':':
+                                       return new JsonToken(JsonToken._colon);
+                               case '0': case '1': case '2': case '3': case '4':
+                               case '5': case '6': case '7': case '8': case '9':
+                               case '.': case '-': case '+':
+                                       StringBuffer dbuf = new StringBuffer();
+                                       boolean is_double = false;
+                                       while (Character.isDigit(c) || c == '.' || c == '+' || c == '-' || c == 'e' || c == 'E') {
+                                               if (c == '.' || c == 'E')
+                                                       is_double = true;
+                                               dbuf.appendCodePoint(c);
+                                               c = ch();
+                                       }
+                                       unch(c);
+                                       String dstr = dbuf.toString();
+                                       double dval;
+                                       try {
+                                               dval = nf_json.parse(dstr).doubleValue();
+                                       } catch (ParseException pe) {
+                                               return new JsonToken(JsonToken._error, dstr);
+                                       }
+                                       if (is_double || !is_long_range(dval))
+                                               return new JsonToken(JsonToken._double, dval);
+                                       else {
+                                               long lval = Long.parseLong(dstr);
+                                               return new JsonToken(JsonToken._long, lval);
+                                       }
+                               case '"':
+                                       StringBuffer bval = new StringBuffer();
+                                       for (;;) {
+                                               c = ch();
+                                               if (c == '"')
+                                                       break;
+                                               if (c == '\\') {
+                                                       c = ch();
+                                                       switch (c) {
+                                                       case 'n':
+                                                               c = '\n';
+                                                               break;
+                                                       case 't':
+                                                               c = '\t';
+                                                               break;
+                                                       default:
+                                                               break;
+                                                       }
+                                               }
+                                               bval.appendCodePoint(c);
+                                       }
+                                       return new JsonToken(JsonToken._string, bval);
+                               default:
+                                       if (Character.isLetter(c)) {
+                                               StringBuffer tbuf = new StringBuffer();
+                                               do {
+                                                       tbuf.appendCodePoint(c);
+                                                       c = ch();
+                                               } while (Character.isLetter(c));
+                                               unch(c);
+                                               JsonToken token = keyword(tbuf.toString());
+                                               if (token != null)
+                                                       return token;
+                                       }
+                                       break;
+                               }
+                       }
+               } catch (IOException ie) {
+                       return new JsonToken(JsonToken._error, "<EIO>");
+               }
+       }
+
+       void next() {
+               token = lex();
+       }
+
+       JsonToken expect(int e) {
+               JsonToken t = token;
+               if (t.token != e)
+                       throw new IllegalArgumentException(String.format("got \"%s\" while expecting \"%s\"",
+                                                                        token.token_name(),
+                                                                        JsonToken.token_name(e)));
+               next();
+               return t;
+       }
+
+       JsonLexer(String s) {
+               f = new StringReader(s);
+               line = 1;
+               token = null;
+       }
+}
+
+/*
+ * Parse a json string into a AltosJson object
+ */
+class JsonParse {
+       JsonLexer       lexer;
+
+       void parse_error(String format, Object ... arguments) {
+               throw new IllegalArgumentException(String.format("line %d: JSON parse error %s\n",
+                                                                lexer.line,
+                                                                String.format(format, arguments)));
+       }
+
+       /* Hashes are { string: value ... } */
+       JsonHash hash() {
+               JsonHash        hash = new JsonHash();
+
+               /* skip the open brace */
+               lexer.next();
+               for (;;) {
+                       /* Allow for empty hashes */
+                       if (lexer.token.token == JsonToken._cc) {
+                               lexer.next();
+                               return hash;
+                       }
+
+                       /* string : value */
+                       String key = lexer.expect(JsonToken._string).sval;
+                       lexer.expect(JsonToken._colon);
+                       AltosJson value = value();
+                       hash.put(key, value);
+
+                       switch (lexer.token.token) {
+                       case JsonToken._comma:
+                               lexer.next();
+                               break;
+                       case JsonToken._cc:
+                               lexer.next();
+                               return hash;
+                       default:
+                               parse_error("got %s expect \",\" or \"}\"", lexer.token.token_name());
+                               return null;
+                       }
+               }
+       }
+
+       /* Arrays are [ value ... ] */
+       JsonArray array() {
+               JsonArray       array = new JsonArray();
+
+               lexer.next();
+               for (int i = 0;; i++) {
+                       /* Allow for empty arrays */
+                       if (lexer.token.token == JsonToken._cs) {
+                               lexer.next();
+                               return array;
+                       }
+
+                       AltosJson value = value();
+                       array.put(i, value);
+                       switch (lexer.token.token) {
+                       case JsonToken._comma:
+                               lexer.next();
+                               break;
+                       case JsonToken._cs:
+                               lexer.next();
+                               return array;
+                       default:
+                               parse_error("got %s expect \",\" or \"]\"", lexer.token.token_name());
+                               return null;
+                       }
+               }
+       }
+
+       /* Json is a simple LL language; one token is sufficient to
+        * identify the next object in the input
+        */
+       AltosJson value() {
+               switch (lexer.token.token) {
+               case JsonToken._oc:
+                       return new AltosJson(hash());
+               case JsonToken._os:
+                       return new AltosJson(array());
+               case JsonToken._double:
+                       double dval = lexer.token.dval;
+                       lexer.next();
+                       return new AltosJson(dval);
+               case JsonToken._long:
+                       long lval = lexer.token.lval;
+                       lexer.next();
+                       return new AltosJson(lval);
+               case JsonToken._string:
+                       String sval = lexer.token.sval;
+                       lexer.next();
+                       return new AltosJson(sval);
+               case JsonToken._boolean:
+                       boolean bval = lexer.token.bval;
+                       lexer.next();
+                       return new AltosJson(bval);
+               default:
+                       parse_error("Unexpected token \"%s\"", lexer.token.token_name());
+               }
+               return null;
+       }
+
+       AltosJson parse() {
+               lexer.next();
+               return value();
+       }
+
+       JsonParse(String s) {
+               lexer = new JsonLexer(s);
+       }
+}
+
+public class AltosJson extends JsonUtil {
+       private static final int        type_none = 0;
+       private static final int        type_hash = 1;
+       private static final int        type_array = 2;
+       private static final int        type_double = 3;
+       private static final int        type_long = 4;
+       private static final int        type_string = 5;
+       private static final int        type_boolean = 6;
+
+       private int             type;
+
+       private JsonHash        hash;
+       private JsonArray       array;
+       private double          d_number;
+       private long            l_number;
+       private String          string;
+       private boolean         bool;
+
+       /* Generate string representation of the value
+        */
+       StringBuffer append(StringBuffer result, int indent, boolean pretty) {
+               switch (type) {
+               case type_hash:
+                       hash.append_hash(result, indent, pretty);
+                       break;
+               case type_array:
+                       array.append_array(result, indent, pretty);
+                       break;
+               case type_double:
+                       if (Double.isInfinite(d_number)) {
+                               if (d_number < 0)
+                                       result.append("NegInfinity");
+                               else
+                                       result.append("Infinity");
+                       } else if (Double.isNaN(d_number)) {
+                               result.append("NaN");
+                       } else {
+                               String dval = nf_json.format(d_number);
+                               if (dval.equals("-0"))
+                                       dval = "0";
+                               result.append(dval);
+                       }
+                       break;
+               case type_long:
+                       result.append(new Long(l_number).toString());
+                       break;
+               case type_string:
+                       quote(result, string);
+                       break;
+               case type_boolean:
+                       result.append(bool ? "true" : "false");
+                       break;
+               }
+               return result;
+       }
+
+       private String toString(int indent, boolean pretty) {
+               StringBuffer result = new StringBuffer();
+               append(result, indent, pretty);
+               return result.toString();
+       }
+
+       public String toString() {
+               return toString(0, false);
+       }
+
+       public String toPrettyString() {
+               return toString(0, true);
+       }
+
+       /* Parse string representation to a value
+        */
+
+       public static AltosJson fromString(String string) {
+               JsonParse       parse = new JsonParse(string);
+               try {
+                       return parse.parse();
+               } catch (IllegalArgumentException ie) {
+                       System.out.printf("json:\n%s\n%s\n", string, ie.getMessage());
+                       return null;
+               }
+       }
+
+       /* Accessor functions
+        */
+       private boolean assert_type(boolean setting, int type, int other_type, String error) {
+               if (setting && this.type == type_none) {
+                       this.type = type;
+                       return false;
+               }
+               if (this.type != type && this.type != other_type)
+                       throw new IllegalArgumentException(error);
+               return true;
+       }
+
+       private boolean assert_type(boolean setting, int type, String error) {
+               return assert_type(setting, type, type, error);
+       }
+
+       private void assert_hash(boolean setting) {
+               if (!assert_type(setting, type_hash, "not a hash"))
+                       hash = new JsonHash();
+       }
+
+       private void assert_array(boolean setting) {
+               if (!assert_type(setting, type_array, "not an array"))
+                       array = new JsonArray();
+       }
+
+       private void assert_number() {
+               assert_type(false, type_double, type_long, "not a number");
+       }
+
+       private void assert_double() {
+               assert_type(true, type_double, type_long, "not a number");
+       }
+
+       private void assert_long() {
+               assert_type(true, type_long, type_double, "not a number");
+       }
+
+       private void assert_string(boolean setting) {
+               assert_type(setting, type_string, "not a string");
+       }
+
+       private void assert_boolean(boolean setting) {
+               assert_type(setting, type_boolean, "not a boolean");
+       }
+
+       /* Primitive accessors
+        */
+       public double number() {
+               assert_number();
+               if (type == type_double)
+                       return d_number;
+               else
+                       return (double) l_number;
+       }
+
+       public long l_number() {
+               assert_number();
+               if (type == type_double)
+                       return (long) d_number;
+               else
+                       return l_number;
+       }
+
+       public String string() {
+               assert_string(false);
+               return string;
+       }
+
+       public boolean bool() {
+               assert_boolean(false);
+               return bool;
+       }
+
+       public AltosJson get(int index) {
+               assert_array(false);
+               return array.get(index);
+       }
+
+       public AltosJson get(String key) {
+               assert_hash(false);
+               return hash.get(key);
+       }
+
+       public int size() {
+               assert_array(false);
+               return array.size();
+       }
+
+       /* Typed accessors with defaulting
+        */
+       public double get_double(String key, double def) {
+               AltosJson value = get(key);
+               if (value != null) {
+                       return value.number();
+               }
+               return def;
+       }
+
+       public long get_long(String key, long def) {
+               AltosJson value = get(key);
+               if (value != null)
+                       return value.l_number();
+               return def;
+       }
+
+       public int get_int(String key, int def) {
+               AltosJson value = get(key);
+               if (value != null)
+                       return (int) value.l_number();
+               return def;
+       }
+
+       public String get_string(String key, String def) {
+               AltosJson value = get(key);
+               if (value != null)
+                       return value.string();
+               return def;
+       }
+
+       public boolean get_boolean(String key, boolean def) {
+               AltosJson value = get(key);
+               if (value != null)
+                       return value.bool();
+               return def;
+       }
+
+       public double get_double(int index, double def) {
+               AltosJson value = get(index);
+               if (value != null)
+                       return value.number();
+               return def;
+       }
+
+       public long get_long(int index, long def) {
+               AltosJson value = get(index);
+               if (value != null)
+                       return value.l_number();
+               return def;
+       }
+
+       public int get_int(int index, int def) {
+               AltosJson value = get(index);
+               if (value != null)
+                       return (int) value.l_number();
+               return def;
+       }
+
+       public String get_string(int index, String def) {
+               AltosJson value = get(index);
+               if (value != null)
+                       return value.string();
+               return def;
+       }
+
+       public boolean get_boolean(int index, boolean def) {
+               AltosJson value = get(index);
+               if (value != null)
+                       return value.bool();
+               return def;
+       }
+
+       public double[] get_double_array(String key, double[] def) {
+               AltosJson value = get(key);
+               if (value != null) {
+                       double[] ret = new double[value.size()];
+                       for (int i = 0; i < value.size(); i++)
+                               ret[i] = value.get_double(i, def == null ? 0 : def[i]);
+                       return ret;
+               }
+               return def;
+       }
+
+       public int[] get_int_array(String key, int[] def) {
+               AltosJson value = get(key);
+               if (value != null) {
+                       int[] ret = new int[value.size()];
+                       for (int i = 0; i < value.size(); i++)
+                               ret[i] = value.get_int(i, def == null ? 0 : def[i]);
+                       return ret;
+               }
+               return def;
+       }
+
+       /* Array setter functions
+        */
+       public AltosJson put(int index, AltosJson value) {
+               assert_array(true);
+               array.put(index, value);
+               return value;
+       }
+
+       public Object put(int index, Object value) {
+               assert_array(true);
+               if (value != null)
+                       array.put(index, new AltosJson(value));
+               return value;
+       }
+
+       public double put(int index, double value) {
+               assert_array(true);
+               array.put(index, new AltosJson(value));
+               return value;
+       }
+
+       public AltosJson put(int index, double[] value) {
+               if (value != null) {
+                       assert_array(true);
+                       array.put(index, new AltosJson(value));
+               }
+               return this;
+       }
+
+       public int[] put(int index, int[] value) {
+               if (value != null) {
+                       assert_array(true);
+                       array.put(index, new AltosJson(value));
+               }
+               return value;
+       }
+
+       public String put(int index, String value) {
+               if (value != null) {
+                       assert_array(true);
+                       array.put(index, new AltosJson(value));
+               }
+               return value;
+       }
+
+       public boolean put(int index, boolean value) {
+               assert_array(true);
+               array.put(index, new AltosJson(value));
+               return value;
+       }
+
+       /* Hash setter functions
+        */
+       public AltosJson put(String key, AltosJson value) {
+               assert_hash(true);
+               hash.put(key, value);
+               return value;
+       }
+
+       public Object put(String key, Object value) {
+               assert_hash(true);
+               if (value != null)
+                       hash.put(key, new AltosJson(value));
+               return value;
+       }
+
+       public double put(String key, double value) {
+               assert_hash(true);
+               hash.put(key, new AltosJson(value));
+               return value;
+       }
+
+       public String put(String key, String value) {
+               if (value != null) {
+                       assert_hash(true);
+                       hash.put(key, new AltosJson(value));
+               }
+               return value;
+       }
+
+       public boolean put(String key, boolean value) {
+               assert_hash(true);
+               hash.put(key, new AltosJson(value));
+               return value;
+       }
+
+       public AltosJson[] put(String key, AltosJson[] value) {
+               if (value != null) {
+                       assert_hash(true);
+                       hash.put(key, new AltosJson(value));
+               }
+               return value;
+       }
+
+       public double[] put(String key, double[] value) {
+               if (value != null) {
+                       assert_hash(true);
+                       hash.put(key, new AltosJson(value));
+               }
+               return value;
+       }
+
+       public int[] put(String key, int[] value) {
+               if (value != null) {
+                       assert_hash(true);
+                       hash.put(key, new AltosJson(value));
+               }
+               return value;
+       }
+
+       /* Primitive setter functions
+        */
+       public double put(double value) {
+               assert_double();
+               d_number = value;
+               return value;
+       }
+
+       public byte put(byte value) {
+               assert_long();
+               l_number = value;
+               return value;
+       }
+
+       public char put(char value) {
+               assert_long();
+               l_number = value;
+               return value;
+       }
+
+       public int put(int value) {
+               assert_long();
+               l_number = value;
+               return value;
+       }
+
+       public long put(long value) {
+               assert_long();
+               l_number = value;
+               return value;
+       }
+
+       public String put(String value) {
+               assert_string(true);
+               string = value;
+               return value;
+       }
+
+       public boolean put(boolean value) {
+               assert_boolean(true);
+               bool = value;
+               return value;
+       }
+
+       private boolean isInnerClass(Class c) {
+               for (Field field : c.getDeclaredFields())
+                       if (field.isSynthetic())
+                               return true;
+               return false;
+       }
+
+       /* Construct an object of the specified class from the JSON
+        * representation.
+        *
+        * This works as long as the structure is non-recursive, and
+        * all inner classes are only members of their immediate outer
+        * class
+        */
+       private Object make(Class c, Class enclosing_class, Object enclosing_object) {
+               Object  ret;
+               if (c == Boolean.TYPE) {
+                       ret = bool();
+               } else if (c == Byte.TYPE) {
+                       ret = (Byte) (byte) l_number();
+               } else if (c == Character.TYPE) {
+                       ret = (Character) (char) l_number();
+               } else if (c == Integer.TYPE) {
+                       ret = (Integer) (int) l_number();
+               } else if (c == Long.TYPE) {
+                       ret = l_number();
+               } else if (c == Double.TYPE) {
+                       ret = number();
+               } else if (c == String.class) {
+                       ret = string();
+               } else if (c.isArray()) {
+                       assert_array(false);
+
+                       Class element_class = c.getComponentType();
+                       if (element_class == Boolean.TYPE) {
+                               boolean[] array = (boolean[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Boolean) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Byte.TYPE) {
+                               byte[] array = (byte[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Byte) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Character.TYPE) {
+                               char[] array = (char[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Character) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Integer.TYPE) {
+                               int[] array = (int[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Integer) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Long.TYPE) {
+                               long[] array = (long[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Long) get(i).make(element_class);
+                               ret = array;
+                       } else if (element_class == Double.TYPE) {
+                               double[] array = (double[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = (Double) get(i).make(element_class);
+                               ret = array;
+                       } else {
+                               Object[] array = (Object[]) Array.newInstance(element_class, size());
+                               for (int i = 0; i < array.length; i++)
+                                       array[i] = get(i).make(element_class);
+                               ret = array;
+                       }
+               } else {
+                       assert_hash(false);
+                       Object object = null;
+                       try {
+                               /* Inner classes have a hidden extra parameter
+                                * to the constructor. Assume that the enclosing object is
+                                * of the enclosing class and construct the object
+                                * based on that.
+                                */
+                               if (enclosing_class != null && isInnerClass(c)) {
+                                       Constructor<?> ctor = ((Class<?>)c).getDeclaredConstructor((Class<?>) enclosing_class);
+                                       object = ctor.newInstance(enclosing_object);
+                               } else {
+                                       object = c.newInstance();
+                               }
+                               for (; c != Object.class; c = c.getSuperclass()) {
+                                       for (Field field : c.getDeclaredFields()) {
+                                               String  fieldName = field.getName();
+                                               Class   fieldClass = field.getType();
+
+                                               if (Modifier.isStatic(field.getModifiers()))
+                                                       continue;
+                                               if (field.isSynthetic())
+                                                       continue;
+                                               try {
+                                                       AltosJson json = get(fieldName);
+                                                       if (json != null) {
+                                                               Object val = json.make(fieldClass, c, object);
+                                                               field.setAccessible(true);
+                                                               field.set(object, val);
+                                                       }
+                                               } catch (IllegalAccessException ie) {
+                                                       System.out.printf("%s:%s %s\n",
+                                                                         c.getName(), fieldName, ie.toString());
+                                               }
+                                       }
+                               }
+                               ret = object;
+                       } catch (InvocationTargetException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
+                               ret = null;
+                       } catch (NoSuchMethodException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
+                               ret = null;
+                       } catch (InstantiationException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
+                               ret = null;
+                       } catch (IllegalAccessException ie) {
+                               System.out.printf("%s: %s\n",
+                                                 c.getName(), ie.toString());
+                               ret = null;
+                       }
+               }
+               return ret;
+       }
+
+       /* This is the public API for the
+        * above function which doesn't handle
+        * inner classes
+        */
+       public Object make(Class c) {
+               return make(c, null, null);
+       }
+
+       /* Constructors, one for each primitive type, String and Object */
+       public AltosJson(boolean bool) {
+               type = type_boolean;
+               this.bool = bool;
+       }
+
+       public AltosJson(byte number) {
+               type = type_long;
+               this.l_number = number;
+       }
+
+       public AltosJson(char number) {
+               type = type_long;
+               this.l_number = number;
+       }
+
+       public AltosJson(int number) {
+               type = type_long;
+               this.l_number = number;
+       }
+
+       public AltosJson(long number) {
+               type = type_long;
+               this.l_number = number;
+       }
+
+       public AltosJson(double number) {
+               type = type_double;
+               this.d_number = number;
+       }
+
+       public AltosJson(String string) {
+               type = type_string;
+               this.string = string;
+       }
+
+       public AltosJson(Object object) {
+               if (object instanceof Boolean) {
+                       type = type_boolean;
+                       bool = (Boolean) object;
+               } else if (object instanceof Byte) {
+                       type = type_long;
+                       l_number = (Byte) object;
+               } else if (object instanceof Character) {
+                       type = type_long;
+                       l_number = (Character) object;
+               } else if (object instanceof Integer) {
+                       type = type_long;
+                       l_number = (Integer) object;
+               } else if (object instanceof Long) {
+                       type = type_long;
+                       l_number = (Long) object;
+               } else if (object instanceof Double) {
+                       type = type_double;
+                       d_number = (Double) object;
+               } else if (object instanceof String) {
+                       type = type_string;
+                       string = (String) object;
+               } else if (object.getClass().isArray()) {
+                       assert_array(true);
+
+                       Class component_class = object.getClass().getComponentType();
+                       if (component_class == Boolean.TYPE) {
+                               boolean[] array = (boolean[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       } else if (component_class == Byte.TYPE) {
+                               byte[] array = (byte[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       } else if (component_class == Character.TYPE) {
+                               char[] array = (char[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       } else if (component_class == Integer.TYPE) {
+                               int[] array = (int[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       } else if (component_class == Long.TYPE) {
+                               long[] array = (long[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       } else if (component_class == Double.TYPE) {
+                               double[] array = (double[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       } else {
+                               Object[] array = (Object[]) object;
+                               for (int i = 0; i < array.length; i++)
+                                       put(i, new AltosJson(array[i]));
+                       }
+               } else {
+                       assert_hash(true);
+                       for (Class c = object.getClass(); c != Object.class; c = c.getSuperclass()) {
+                               for (Field field : c.getDeclaredFields()) {
+                                       String  fieldName = field.getName();
+
+                                       /* Skip static fields */
+                                       if (Modifier.isStatic(field.getModifiers()))
+                                               continue;
+
+                                       /* Skip synthetic fields. We're assuming
+                                        * those are always an inner class reference
+                                        * to the outer class object
+                                        */
+                                       if (field.isSynthetic())
+                                               continue;
+                                       try {
+                                               /* We may need to force the field to be accessible if
+                                                * it is private
+                                                */
+                                               field.setAccessible(true);
+                                               Object val = field.get(object);
+                                               if (val != null) {
+                                                       AltosJson json = new AltosJson(val);
+                                                       put(fieldName, json);
+                                               }
+                                       } catch (IllegalAccessException ie) {
+                                               System.out.printf("%s:%s %s\n",
+                                                                 c.getName(), fieldName, ie.toString());
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* Array constructors, one for each primitive type, String and Object */
+       public AltosJson(boolean[] bools) {
+               assert_array(true);
+               for(int i = 0; i < bools.length; i++)
+                       put(i, new AltosJson(bools[i]));
+       }
+
+       public AltosJson(byte[] numbers) {
+               assert_array(true);
+               for(int i = 0; i < numbers.length; i++)
+                       put(i, new AltosJson(numbers[i]));
+       }
+
+       public AltosJson(char[] numbers) {
+               assert_array(true);
+               for(int i = 0; i < numbers.length; i++)
+                       put(i, new AltosJson(numbers[i]));
+       }
+
+       public AltosJson(int[] numbers) {
+               assert_array(true);
+               for(int i = 0; i < numbers.length; i++)
+                       put(i, new AltosJson(numbers[i]));
+       }
+
+       public AltosJson(long[] numbers) {
+               assert_array(true);
+               for(int i = 0; i < numbers.length; i++)
+                       put(i, new AltosJson(numbers[i]));
+       }
+
+       public AltosJson(double[] numbers) {
+               assert_array(true);
+               for(int i = 0; i < numbers.length; i++)
+                       put(i, new AltosJson(numbers[i]));
+       }
+
+       public AltosJson(String[] strings) {
+               assert_array(true);
+               for(int i = 0; i < strings.length; i++)
+                       put(i, new AltosJson(strings[i]));
+       }
+
+       public AltosJson(AltosJson[] jsons) {
+               assert_array(true);
+               for (int i = 0; i < jsons.length; i++)
+                       put(i, jsons[i]);
+       }
+
+       public AltosJson(Object[] array) {
+               assert_array(true);
+               for (int i = 0; i < array.length; i++)
+                       put(i, new AltosJson(array[i]));
+       }
+
+       /* Empty constructor
+        */
+       public AltosJson() {
+               type = type_none;
+       }
+
+       public AltosJson(JsonHash hash) {
+               type = type_hash;
+               this.hash = hash;
+       }
+
+       public AltosJson(JsonArray array) {
+               type = type_array;
+               this.array = array;
+       }
+}
index ac5e0257cec482e7bc9ba2980cbd8dd7ad5d6c6a..ba0530151dde79d8204b8fae6afa1b89c44904eb 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index d39fe15f38feaf71468cd6c2c42caeb4bd77b8e5..ed1dd64e99d247068ac69683ed6094c796547732 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosLatLon {
        public double   lat;
index e0deb504dfe0a93427136cff44703633798d7444..04931ece1794176284dbdb68a43b12109a73b749 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosLatitude extends AltosLocation {
        public String pos() { return "N"; }
index ee2a60e9c9b16559e0ea328d5f379e1d9a88beed..831fdf64b713620b60ff4000fd22148806301c92 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.*;
index c77eadc5e7cad800af54ab7502875b406ac76708..6167b7cf957c34b1f775e1c9eb7ee06948f15f48 100644 (file)
@@ -14,7 +14,7 @@
  * 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.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.*;
index 3ebac60142889b4eebd81154efaf6c1862417244..db6a1f80a018448e40de53cd45f80dd286edd4e2 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.*;
index a73a7759b6a26422d9877e8c865e4d506998908d..044caf8de1ca2d144de41bb20e44544b8d0e1e84 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.*;
 import java.io.*;
@@ -493,9 +493,10 @@ public class AltosLib {
                return r;
        }
 
-       public static int fromdec(String s) throws NumberFormatException {
-               int c, v = 0;
-               int sign = 1;
+       public static long fromdec(String s) throws NumberFormatException {
+               int c;
+               long v = 0;
+               long sign = 1;
                for (int i = 0; i < s.length(); i++) {
                        c = s.charAt(i);
                        if (i == 0 && c == '-') {
index 876cb7dfb491f4069a1a2eb12fb7321251209023..90490192b323914583a8b6e9ebe3296a703a8a26 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosLine {
        public String   line;
index cd8609c037a00dac6d81eddde1c0ce806ddca80d..327666743396ef0ce21b9ef97f7180c6d718cadd 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.concurrent.*;
index 389e392f115916f4a30a6e7c38934f8162ba40e4..7d9ec2a49760019f40fe8bcb0d1c9d69a5971a96 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosListenerState implements Serializable {
+public class AltosListenerState {
        public int      crc_errors;
        public double   battery;
        public boolean  running;
index df1c9d6382f557263f03d4fdfd8c3cc04d9b7703..2ab07ebb01bc1e43048f20302d33bcc5b9ddd205 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public abstract class AltosLocation extends AltosUnits {
 
index a6e042151f99227fb9cd4de46298faa85966faea..74017a299cf16a0d5c51b3d4f482690f44367224 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.text.*;
index 61d74afc63b12cea777b02eeb5505ae947a3bcf9..77fe9c9a5ee2ae9305e7cab7b7e70cdd25e84cc3 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosLongitude extends AltosLocation {
        public String pos() { return "E"; }
index ce5a48c305aaa18bb6006dc8f8dbfc622600577d..5864529fe4f175683ef04149c9812443506b7a37 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosMag implements Cloneable, Serializable {
+public class AltosMag implements Cloneable {
        public int              along;
        public int              across;
        public int              through;
 
-       public static double counts_per_gauss = 1090;
+       public static final double counts_per_gauss = 1090;
 
        public static double convert_gauss(double counts) {
                return counts / counts_per_gauss;
index 1841277f8bd61889390f0d5802dff09a7584b603..0c775f333ee79aacf9ffb08a4c11c243fd9910e5 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.*;
@@ -51,6 +51,7 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
        };
 
        AltosMapInterface       map_interface;
+       int                     scale;
 
        AltosMapCache           cache;
 
@@ -328,7 +329,8 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                                if (!tiles.containsKey(point)) {
                                        AltosLatLon     ul = transform.lat_lon(point);
                                        AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
-                                       AltosMapTile tile = map_interface.new_tile(cache, ul, center, zoom, maptype, px_size);
+                                       AltosMapTile tile = map_interface.new_tile(cache, ul, center, zoom, maptype, px_size, scale);
+                                       debug("show state %s url %s\n", AltosMapTile.status_name(tile.store.status()), tile.store.url);
                                        tile.add_listener(this);
                                        tiles.put(point, tile);
                                }
@@ -475,11 +477,16 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                        drag_stop(x, y);
        }
 
-       public AltosMap(AltosMapInterface map_interface) {
+       public AltosMap(AltosMapInterface map_interface, int scale) {
                this.map_interface = map_interface;
+               this.scale = scale;
                cache = new AltosMapCache(map_interface);
                line = map_interface.new_line();
                path = map_interface.new_path();
                set_zoom_label();
        }
+
+       public AltosMap(AltosMapInterface map_interface) {
+               this(map_interface, 1);
+       }
 }
index 38e0f769871a186d4ae434ce4d24668ba32e2e4c..28f6b1163f6323a8286d6f310944cffdb2a60fa3 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.net.*;
@@ -60,7 +60,6 @@ public class AltosMapCache implements AltosMapCacheListener {
 
                public synchronized void notify_tile(AltosMapTile tile, int status) {
                        if (status == AltosMapTile.fetched) {
-                               System.out.printf("tile fetched, loading image\n");
                                load();
                        }
                }
@@ -139,8 +138,6 @@ public class AltosMapCache implements AltosMapCacheListener {
                                elements[oldest].flush();
 
                        elements[oldest] = element;
-                       System.out.printf("AltosMapCache.get image ? %s\n",
-                                         element.image == null ? "false" : "true");
                        return element.image;
                }
        }
index 4984d9e568ace788b94ae760259ade3b511637f3..b010d12f0a59187e802a24743901f0265098b9f7 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosMapCacheListener {
        public void map_cache_changed(int map_cache);
index 756a78f20e88c437d9fef8c2bd9767c2b47d104e..78cd70ebf4b7a7b886fd0dcb5158cf107f3ca9b0 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.net.*;
@@ -29,7 +29,7 @@ public interface AltosMapInterface {
 
        public abstract AltosMapMark new_mark(double lat, double lon, int state);
 
-       public abstract AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size);
+       public abstract AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale);
 
        public abstract int width();
 
index bd5901367fae2a7a1ddcee938cda18b188bb6637..187aa6d9e01f124ff7eea364e14a40e69fdf6115 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.Math;
@@ -50,7 +50,7 @@ public abstract class AltosMapLine {
 
                if (AltosConvert.imperial_units) {
                        distance = AltosConvert.meters_to_feet(distance);
-                       if (distance < 10000) {
+                       if (distance < 1000) {
                                format = "%4.0fft";
                        } else {
                                distance /= 5280;
@@ -64,7 +64,7 @@ public abstract class AltosMapLine {
                                        format = "%5.0fmi";
                        }
                } else {
-                       if (distance < 10000) {
+                       if (distance < 1000) {
                                format = "%4.0fm";
                        } else {
                                distance /= 1000;
index 7112a1c4d22f06e8c7af078ff8b4ef2c93957fe7..d715df38ea0ce4e1a64e662da723a7707b8fdf16 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
+import java.util.concurrent.*;
 import java.text.*;
 import java.lang.Math;
 import java.net.URL;
 import java.net.URLConnection;
 
-public class AltosMapLoader extends Thread implements AltosMapTileListener {
+public class AltosMapLoader extends Thread implements AltosMapStoreListener {
        AltosMapLoaderListener  listener;
 
        double  latitude, longitude;
@@ -34,6 +35,7 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
        int     all_types;
        int     cur_type;
        double  radius;
+       int     scale;
 
        int     tiles_loaded_layer;
        int     tiles_loaded_total;
@@ -42,7 +44,11 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
        int     layers_total;
        int     layers_loaded;
 
-       AltosMap        map;
+       private static final int        MAX_LOADING = 200;
+
+       private Semaphore       loading = new Semaphore(MAX_LOADING);
+
+       boolean abort;
 
        int tile_radius(int zoom) {
                double  delta_lon = AltosMapTransform.lon_from_distance(latitude, radius);
@@ -62,7 +68,7 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
                return (tile_radius * 2 + 1) * (tile_radius * 2 + 1);
        }
 
-       public void do_load() {
+       private boolean do_load() {
                tiles_this_layer = tiles_per_layer(cur_z);
                tiles_loaded_layer = 0;
                listener.debug("tiles_this_layer %d (zoom %d)\n", tiles_this_layer, cur_z);
@@ -73,8 +79,6 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
                AltosLatLon load_centre = new AltosLatLon(latitude, longitude);
                AltosMapTransform transform = new AltosMapTransform(256, 256, zoom, load_centre);
 
-               map.centre(load_centre);
-
                AltosPointInt   upper_left;
                AltosPointInt   lower_right;
 
@@ -88,16 +92,25 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
 
                for (int y = (int) upper_left.y; y <= lower_right.y; y += AltosMap.px_size) {
                        for (int x = (int) upper_left.x; x <= lower_right.x; x += AltosMap.px_size) {
+                               try {
+                                       loading.acquire();
+                               } catch (InterruptedException ie) {
+                                       return false;
+                               }
                                AltosPointInt   point = new AltosPointInt(x, y);
                                AltosLatLon     ul = transform.lat_lon(point);
                                AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
-                               AltosMapTile    tile = map.map_interface.new_tile(null, ul, center, zoom, maptype, AltosMap.px_size);
-                               tile.add_listener(this);
+                               AltosMapStore   store = AltosMapStore.get(center, zoom, maptype, AltosMap.px_size, scale);
+                               listener.debug("load state %s url %s\n", AltosMapTile.status_name(store.status()), store.url);
+                               store.add_listener(this);
+                               if (abort)
+                                       return false;
                        }
                }
+               return true;
        }
 
-       public int next_type(int start) {
+       private int next_type(int start) {
                int next_type;
                for (next_type = start;
                     next_type <= AltosMap.maptype_terrain && (all_types & (1 << next_type)) == 0;
@@ -106,19 +119,19 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
                return next_type;
        }
 
-       public void next_load() {
+       private boolean next_load() {
                int next_type = next_type(cur_type + 1);
 
                if (next_type > AltosMap.maptype_terrain) {
                        if (cur_z == max_z) {
-                               return;
+                               return false;
                        } else {
                                cur_z++;
                        }
                        next_type = next_type(0);
                }
                cur_type = next_type;
-               do_load();
+               return true;
        }
 
        public void run() {
@@ -147,15 +160,22 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
                listener.debug("total tiles %d layers %d\n", tiles_total, layers_total);
 
                listener.loader_start(tiles_total);
-               do_load();
+               do {
+                       if (!do_load())
+                               break;
+               } while (next_load());
+               if (abort)
+                       listener.loader_done(tiles_total);
        }
 
-       public synchronized void notify_tile(AltosMapTile tile, int status) {
+       public synchronized void notify_store(AltosMapStore store, int status) {
                boolean do_next = false;
                if (status == AltosMapTile.fetching)
                        return;
 
-               tile.remove_listener(this);
+               loading.release();
+
+               store.remove_listener(this);
 
                if (layers_loaded >= layers_total)
                        return;
@@ -163,7 +183,7 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
                ++tiles_loaded_total;
                ++tiles_loaded_layer;
 
-               listener.debug("AltosMapLoader.notify_tile status %d total %d of %d layer %d of %d\n",
+               listener.debug("AltosMapLoader.notify_store status %d total %d of %d layer %d of %d\n",
                               status, tiles_loaded_total, tiles_total, tiles_loaded_layer, tiles_this_layer);
 
                if (tiles_loaded_layer == tiles_this_layer) {
@@ -174,19 +194,19 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
 
                if (tiles_loaded_total == tiles_total)
                        listener.loader_done(tiles_total);
-               else {
+               else
                        listener.loader_notify(tiles_loaded_total,
-                                              tiles_total, tile.store.file.toString());
-                       if (do_next)
-                               next_load();
-               }
+                                              tiles_total, store.file.toString());
+       }
+
+       public void abort() {
+               this.abort = true;
        }
 
-       public AltosMapLoader(AltosMap map, AltosMapLoaderListener listener,
-                             double latitude, double longitude, int min_z, int max_z, double radius, int all_types) {
+       public AltosMapLoader(AltosMapLoaderListener listener,
+                             double latitude, double longitude, int min_z, int max_z, double radius, int all_types, int scale) {
                listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n",
                               latitude, longitude, min_z, max_z, radius, all_types);
-               this.map = map;
                this.listener = listener;
                this.latitude = latitude;
                this.longitude = longitude;
@@ -194,6 +214,8 @@ public class AltosMapLoader extends Thread implements AltosMapTileListener {
                this.max_z = max_z;
                this.radius = radius;
                this.all_types = all_types;
+               this.scale = scale;
+               this.abort = false;
                start();
        }
 }
index 47d7b858b3e18bdabbee2e221d249ded86ebb87f..97c8b7f5b5d7910212602cc307717c9c38cb04ab 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosMapLoaderListener {
        public abstract void loader_start(int max);
index db714922ece808f740d2d4efbd124d414f9292a5..0fac5b37eb79d2c4d78a833964118a3a03f9f298 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.Math;
index 6f6db4f4149dbbb6e6e6d0689771d725c25e6d0a..75664f8396a21789de311a11e680d30b23722d87 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.Math;
index 5b46cb19cb58927f7bae2b10057869f5fdb5abcb..89494408cd2da0b8de36a909a963a3da099176d1 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.Math;
index b6294a4e7e31af5a08f09cae72c720c66d5a0e74..566e414fc37f0457f6ea8c5ab62878393fc24079 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosMapRectangle {
        AltosLatLon     ul, lr;
index aed365ca175e07ea81abe05b7535b707227887dd..53bfd5170afd401ef629e5dbf436574b8bb451dd 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.net.*;
@@ -28,6 +28,45 @@ public class AltosMapStore {
 
        int                                     status;
 
+       private static File map_file(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               double lat = center.lat;
+               double lon = center.lon;
+               char chlat = lat < 0 ? 'S' : 'N';
+               char chlon = lon < 0 ? 'W' : 'E';
+
+               if (lat < 0) lat = -lat;
+               if (lon < 0) lon = -lon;
+               String maptype_string = String.format("%s-", AltosMap.maptype_names[maptype]);
+               String format_string;
+               if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
+                       format_string = "jpg";
+               else
+                       format_string = "png";
+               return new File(AltosPreferences.mapdir(),
+                               String.format("map-%c%.6f,%c%.6f-%s%d%s.%s",
+                                             chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string));
+       }
+
+       private static String map_url(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               String format_string;
+               int z = zoom;
+
+               if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
+                       format_string = "jpg";
+               else
+                       format_string = "png32";
+
+               for (int s = 1; s < scale; s <<= 1)
+                       z--;
+
+               if (AltosVersion.has_google_maps_api_key())
+                       return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
+                                            center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key);
+               else
+                       return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s",
+                                            center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string);
+       }
+
        public int status() {
                return status;
        }
@@ -229,16 +268,19 @@ public class AltosMapStore {
 
        static HashMap<String,AltosMapStore> stores = new HashMap<String,AltosMapStore>();
 
-       public static AltosMapStore get(String url, File file) {
+       public static AltosMapStore get(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               String url = map_url(center, zoom, maptype, px_size, scale);
+
                AltosMapStore   store;
                synchronized(stores) {
                        if (stores.containsKey(url)) {
                                store = stores.get(url);
                        } else {
-                               store = new AltosMapStore(url, file);
+                               store = new AltosMapStore(url, map_file(center, zoom, maptype, px_size, scale));
                                stores.put(url, store);
                        }
                }
                return store;
        }
+
 }
index 65bd6ef8480545d6a9273414a2a6981d35cb5e19..bfee5f5c9779a733760b50d04eda84a0862d74d6 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosMapStoreListener {
        abstract void notify_store(AltosMapStore store, int status);
index fdc8ff65995ab0752843e88ad3f58b62afd52049..b65f6fc14632562ab4c46a181bf5bf11baf01e33 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
 
-public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreListener {
+public class AltosMapTile implements AltosFontListener, AltosMapStoreListener {
        LinkedList<AltosMapTileListener>        listeners = new LinkedList<AltosMapTileListener>();
        public AltosLatLon      upper_left, center;
        public int              px_size;
@@ -38,43 +38,23 @@ public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreLi
        static public final int bad_request = 4;/* downloading failed */
        static public final int forbidden = 5;  /* downloading failed */
 
-       private File map_file() {
-               double lat = center.lat;
-               double lon = center.lon;
-               char chlat = lat < 0 ? 'S' : 'N';
-               char chlon = lon < 0 ? 'W' : 'E';
-
-               if (lat < 0) lat = -lat;
-               if (lon < 0) lon = -lon;
-               String maptype_string = String.format("%s-", AltosMap.maptype_names[maptype]);
-               String format_string;
-               if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
-                       format_string = "jpg";
-               else
-                       format_string = "png";
-               return new File(AltosPreferences.mapdir(),
-                               String.format("map-%c%.6f,%c%.6f-%s%d%s.%s",
-                                             chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string));
-       }
-
-       private String map_url() {
-               String format_string;
-               int z = zoom;
-
-               if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
-                       format_string = "jpg";
-               else
-                       format_string = "png32";
-
-               for (int s = 1; s < scale; s <<= 1)
-                       z--;
-
-               if (AltosVersion.has_google_maps_api_key())
-                       return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
-                                            center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key);
-               else
-                       return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s",
-                                            center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string);
+       static public String status_name(int status) {
+               switch (status) {
+               case loaded:
+                       return "loaded";
+               case fetched:
+                       return "fetched";
+               case fetching:
+                       return "fetching";
+               case failed:
+                       return "failed";
+               case bad_request:
+                       return "bad_request";
+               case forbidden:
+                       return "forbidden";
+               default:
+                       return "unknown";
+               }
        }
 
        public void font_size_changed(int font_size) {
@@ -87,7 +67,6 @@ public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreLi
        }
 
        public void notify_store(AltosMapStore store, int status) {
-//             System.out.printf("AltosMapTile.notify_store %d\n", status);
                notify_listeners(status);
        }
 
@@ -99,7 +78,8 @@ public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreLi
                notify_listeners(status);
        }
 
-       public abstract void paint(AltosMapTransform t);
+       public void paint(AltosMapTransform t) {
+       }
 
        public AltosImage get_image() {
                if (cache == null)
@@ -132,11 +112,7 @@ public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreLi
                this.px_size = px_size;
                this.scale = scale;
 
-               store = AltosMapStore.get(map_url(), map_file());
+               store = AltosMapStore.get(center, zoom, maptype, px_size, scale);
                store.add_listener(this);
        }
-
-       public AltosMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               this(cache, upper_left, center, zoom, maptype, px_size, 1);
-       }
 }
index 6d78b205207a4cfaf62c2f10af81edb6b60fe542..7939e4bd3b484d2f90872d0cff7469e34b7defe2 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosMapTileListener {
        abstract public void notify_tile(AltosMapTile tile, int status);
index b8901127366a7dc38930e9f173bd00c64bbd7cc0..53f3abac1e7c83c65b9f46cc7929091fa08f6528 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.lang.Math;
index b82bda3f5b7f29b6b44bcd3137c4851b4d174524..20740e7d160fdbd22f40bd3d371883e8f8791b6f 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosMapTypeListener {
        public void map_type_changed(int map_type);
index 51f8c3c5e83cf6329607ace9481e67fcb9b8d409..59c91e8e3d09f4890af074520a0f897c982970fb 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosMapZoomListener {
        abstract public void zoom_changed(int zoom);
index b09ec74b250e4a46c2cf377768130f2f15282af2..57bc7b9163d9ecda3c43f3dc7f7a728b967261da 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.*;
 
index 1277f2672f9e34463e95bbd4752d219dee649872..e40479b188fbd4162a545cd0290a1a4a553c7211 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosMs5607 implements Serializable {
+public class AltosMs5607 {
        public int      reserved;
        public int      sens;
        public int      off;
index 5451047e73b79468d6aa9f2c34329ae55d45a7f7..3f3cbbe7eb81fec82c1a673a7ef9b354683e48dc 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosNoSymbol extends Exception {
        public AltosNoSymbol(String name) {
index 8b22c1313f89b221d08abfe02d7b757e5eb0e7be..edaa304cb854e6dbe8344d853ebac590a1ca12c7 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosOrient extends AltosUnits {
 
index 1cbddcf9ef9dfbc4c68cf7c20a6c3a5cb84b30f5..45ef7dac843cf265e1fb7309136d8a757e1c36e2 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.*;
 import java.text.*;
@@ -26,6 +26,14 @@ public class AltosParse {
        }
 
        public static int parse_int(String v) throws ParseException {
+               try {
+                       return (int) AltosLib.fromdec(v);
+               } catch (NumberFormatException e) {
+                       throw new ParseException("error parsing int " + v, 0);
+               }
+       }
+
+       public static long parse_long(String v) throws ParseException {
                try {
                        return AltosLib.fromdec(v);
                } catch (NumberFormatException e) {
@@ -41,9 +49,23 @@ public class AltosParse {
                }
        }
 
-       static NumberFormat nf_locale = NumberFormat.getInstance();
+       static NumberFormat get_nf_locale() {
+               NumberFormat nf = NumberFormat.getInstance();
+               nf.setParseIntegerOnly(false);
+               nf.setGroupingUsed(false);
+               return nf;
+       }
+
+       static NumberFormat nf_locale = get_nf_locale();
+
+       static NumberFormat get_nf_net() {
+               NumberFormat nf = NumberFormat.getInstance(Locale.ROOT);
+               nf.setParseIntegerOnly(false);
+               nf.setGroupingUsed(false);
+               return nf;
+       }
 
-       static NumberFormat nf_net = NumberFormat.getInstance(Locale.ROOT);
+       static NumberFormat nf_net = get_nf_net();
 
        public static double parse_double_locale(String str) throws ParseException {
                try {
@@ -53,14 +75,26 @@ public class AltosParse {
                }
        }
 
+       public static String format_double_locale(double number) {
+               return nf_locale.format(number);
+       }
+
        public static double parse_double_net(String str) throws ParseException {
                try {
-                       return nf_net.parse(str.trim()).doubleValue();
+                       String t = str.trim();
+//                     System.out.printf("Parse string \"%s\" trim \"%s\"\n", str, t);
+                       return nf_net.parse(t).doubleValue();
                } catch (ParseException pe) {
                        throw new ParseException("error parsing double " + str, 0);
                }
        }
 
+       public static String format_double_net(double number) {
+               String ret = nf_net.format(number);
+//             System.out.printf("format double %f \"%s\"\n", number, ret);
+               return ret;
+       }
+
        public static double parse_coord(String coord) throws ParseException {
                String[]        dsf = coord.split("\\D+");
 
index 65bad427c779b4e81472f215827758d3c787da8d..b18c4b48af41d65709e34b0b8d7789f5d271ce17 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosPointDouble {
        public double   x, y;
index 34eb6fd3a4b07bf5f980cd37d083605164754528..14b0dabf438cedf5b088122d4c70a76239ca1729 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosPointInt {
        public int      x, y;
index fb3026a4c0a55b2b8d5abe1aca145826fa1d4980..569aaa5481f863f9e8558fe8207aaff0f8ef89f1 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
@@ -116,7 +116,7 @@ public class AltosPreferences {
        public final static String      frequency_count = "COUNT";
        public final static String      frequency_format = "FREQUENCY-%d";
        public final static String      description_format = "DESCRIPTION-%d";
-       public final static String      frequenciesPreference = "FREQUENCIES";
+       public final static String      frequenciesPreference = "FREQUENCIES-1";
 
        /* Units preference */
 
@@ -133,24 +133,30 @@ public class AltosPreferences {
        static int      map_type;
 
        public static AltosFrequency[] load_common_frequencies() {
-
                AltosFrequency[] frequencies = null;
 
-               frequencies = (AltosFrequency[]) backend.getSerializable(frequenciesPreference, null);
+               try {
+                       AltosJson json = AltosJson.fromString(backend.getString(frequenciesPreference,
+                                                                               null));
+                       frequencies = (AltosFrequency[]) json.make(frequencies.getClass());
+               } catch (Exception e) {
+               }
 
                if (frequencies == null) {
                        if (backend.nodeExists(common_frequencies_node_name)) {
                                AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
                                int             count = node.getInt(frequency_count, 0);
 
-                               frequencies = new AltosFrequency[count];
-                               for (int i = 0; i < count; i++) {
-                                       double  frequency;
-                                       String  description;
+                               if (count > 0) {
+                                       frequencies = new AltosFrequency[count];
+                                       for (int i = 0; i < count; i++) {
+                                               double  frequency;
+                                               String  description;
 
-                                       frequency = node.getDouble(String.format(frequency_format, i), 0.0);
-                                       description = node.getString(String.format(description_format, i), null);
-                                       frequencies[i] = new AltosFrequency(frequency, description);
+                                               frequency = node.getDouble(String.format(frequency_format, i), 0.0);
+                                               description = node.getString(String.format(description_format, i), null);
+                                               frequencies[i] = new AltosFrequency(frequency, description);
+                                       }
                                }
                        }
                }
@@ -165,6 +171,12 @@ public class AltosPreferences {
                return frequencies;
        }
 
+       public static void save_common_frequencies() {
+               AltosJson       json = new AltosJson(common_frequencies);
+               backend.putString(frequenciesPreference, json.toString());
+               flush_preferences();
+       }
+
        public static int launcher_serial;
 
        public static int launcher_channel;
@@ -353,7 +365,7 @@ public class AltosPreferences {
        public static void set_state(AltosState state) {
 
                synchronized(backend) {
-                       backend.putSerializable(String.format(statePreferenceFormat, state.serial), state);
+                       backend.putJson(String.format(statePreferenceFormat, state.serial), new AltosJson(state));
                        backend.putInt(statePreferenceLatest, state.serial);
                        flush_preferences();
                }
@@ -378,6 +390,7 @@ public class AltosPreferences {
        public static void remove_state(int serial) {
                synchronized(backend) {
                        backend.remove(String.format(statePreferenceFormat, serial));
+                       flush_preferences();
                }
        }
 
@@ -392,10 +405,12 @@ public class AltosPreferences {
        public static AltosState state(int serial) {
                synchronized(backend) {
                        try {
-                               return (AltosState) backend.getSerializable(String.format(statePreferenceFormat, serial), null);
+                               AltosJson json = backend.getJson(String.format(statePreferenceFormat, serial));
+                               if (json != null)
+                                       return (AltosState) (json.make(AltosState.class));
                        } catch (Exception e) {
-                               return null;
                        }
+                       return null;
                }
        }
 
@@ -512,8 +527,8 @@ public class AltosPreferences {
        public static void set_common_frequencies(AltosFrequency[] frequencies) {
                synchronized(backend) {
                        common_frequencies = frequencies;
-                       backend.putSerializable(frequenciesPreference, frequencies);
-                       flush_preferences();
+
+                       save_common_frequencies();
                }
        }
 
index 6e1124e24e5462574c431d841000bf680222cdc6..0580652e8ab4a4fcc1c4b48d4b4fe61698a85dcc 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
@@ -38,40 +38,20 @@ public abstract class AltosPreferencesBackend {
        public abstract byte[]  getBytes(String key, byte[] def);
        public abstract void    putBytes(String key, byte[] value);
 
-       public Serializable getSerializable(String key, Serializable def) {
-               byte[] bytes = null;
-
-               bytes = getBytes(key, null);
-               if (bytes == null)
-                       return def;
-
-               ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+       public AltosJson        getJson(String key) {
+               String  value = getString(key, null);
 
+               if (value == null)
+                       return null;
                try {
-                       ObjectInputStream ois = new ObjectInputStream(bais);
-                       Serializable object = (Serializable) ois.readObject();
-                       return object;
-               } catch (IOException ie) {
-                       debug("IO exception %s\n", ie.toString());
-               } catch (ClassNotFoundException ce) {
-                       debug("ClassNotFoundException %s\n", ce.toString());
+                       return AltosJson.fromString(value);
+               } catch (IllegalArgumentException ie) {
+                       return null;
                }
-               return def;
        }
 
-       public void putSerializable(String key, Serializable object) {
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
-               try {
-                       ObjectOutputStream oos = new ObjectOutputStream(baos);
-
-                       oos.writeObject(object);
-                       byte[] bytes = baos.toByteArray();
-
-                       putBytes(key, bytes);
-               } catch (IOException ie) {
-                       debug("set_state failed %s\n", ie.toString());
-               }
+       public void             putJson(String key, AltosJson j) {
+               putString(key, j.toString());
        }
 
        public abstract boolean nodeExists(String key);
index 2f8e3bd0ebad5979d840d0a14b4df09180f78561..78be82822f3ae6818efefcdacba9b0b298ba1a41 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
index 28e65bc2f9b52de27de4d0051b1e08d53ec4dc89..c948ce21b1bf4d8cefd8b839c03cd8c05b492182 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.*;
 import java.text.*;
@@ -138,7 +138,7 @@ public class AltosPyro {
                        units = pyro_to_units.get(flag);
                if (units == null)
                        return name;
-               return String.format ("%s (%s)", name, units.show_units());
+               return String.format ("%s (%s)", name, units.parse_units());
        }
 
        public static AltosUnits pyro_to_units(int flag) {
@@ -277,7 +277,7 @@ public class AltosPyro {
                                int     value = 0;
                                ++i;
                                try {
-                                       value = AltosLib.fromdec(tokens[i]);
+                                       value = (int) AltosLib.fromdec(tokens[i]);
                                } catch (NumberFormatException n) {
                                        throw new ParseException(String.format("Invalid pyro value \"%s\"",
                                                                               tokens[i]), i);
index bc471c9c83149ed778e23542441ff71e74fe8eed..795594294e92591a22984383dba050a76b61517f 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosQuaternion {
        double  r;              /* real bit */
@@ -115,10 +115,17 @@ public class AltosQuaternion {
        }
 
        public AltosQuaternion(AltosQuaternion q) {
-               this.r = q.r;
-               this.x = q.x;
-               this.y = q.y;
-               this.z = q.z;
+               r = q.r;
+               x = q.x;
+               y = q.y;
+               z = q.z;
+       }
+
+       public AltosQuaternion() {
+               r = 1;
+               x = 0;
+               y = 0;
+               z = 0;
        }
 
        static public AltosQuaternion vector(double x, double y, double z) {
index 4757687d05b28ac949fc463bd8e66f8254392005..e1705548204a976bfb73e74e750488374e00f5d4 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosRectangle {
        public int      x, y, width, height;
index 0f77c979417901e267ec4b7694aa188408950ce5..f420c9589d8d3b1c326560b469d3e941d337c10e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index af201939f2d639aa7ae1beff3427beff8dcc0b34..375858798ab6a9f2fc39a77b5bcb6688cc94ab26 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
index e53a3a49d46a65e95af505ff90989f2f51fb09ae..97cf78967921f8bb10bc1c0d45bb8c7bc0969345 100644 (file)
@@ -15,9 +15,9 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
-public class AltosRotation {
+public class AltosRotation extends AltosQuaternion {
        private AltosQuaternion         rotation;
 
        public double tilt() {
@@ -47,4 +47,8 @@ public class AltosRotation {
                AltosQuaternion up = new AltosQuaternion(0, 0, 0, sky);
                rotation = up.vectors_to_rotation(orient);
        }
+
+       public AltosRotation() {
+               rotation = new AltosQuaternion();
+       }
 }
index 3dbf59a5b98adef2b5c269178366fc41f555d9c0..f1d3e9936c37e2631638c7104bdcbb8a08b4992f 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosSavedState implements Serializable {
+public class AltosSavedState {
        public AltosState               state;
        public AltosListenerState       listener_state;
 
index f996d7b121620cb4b4bcd1c90d2e25fabc7afe8f..b6056c9ce90b7a1ed644b8ad3d6b88633325e178 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
index 884800f87adb004e392bcab82f73a63ce290104e..875dad0b0a07ff6d24d77968df75e1b0084b07e4 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index 99eca9d87cea4dd9e7352dbf0ba8642602ddcc6a..654f85bd38b847cdb5efe5fe6ebca4bb188de86b 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index a4224311d8abbe7be997c9b30a2f2b29c79a4e96..18474e18d0947248c59d749cdb49768ef46d4e04 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index 1b09647f60893f0d4d34c2c45a619271967c72f5..5f56a899566d6e08cf47432e128e3857f848df75 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index 9f572eca7bee30cda87e4c79351b96ef0f85a543..80b278247e03b6297effcf64ed7c2226267b47e3 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index bb842b52169740aedeed2c7f9109d1bef94b6b4c..e80bac6aa4efd88e18ff45fbb98188ae2b7b8d98 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index 9e01b50c85922188e4ef2cdf9c6c3fd4120ad5d5..739670f5b7a8d4e259bf119e35588fcec89c40f5 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.util.concurrent.TimeoutException;
 
index e09bbb7a0754b28ad8ed44fd9ab403fec2c632f1..738519792bf79aa4f88fa1dc18e22f989cb49f2e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosSpeed extends AltosUnits {
 
index 7b41e98dcbe50daea61776a6cc8265ea1545edab..15cf7d641b0f68a3248de98c443096579fe5938b 100644 (file)
  * Track flight state from telemetry or eeprom data stream
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosState implements Cloneable, Serializable {
+public class AltosState implements Cloneable {
 
        public static final int set_position = 1;
        public static final int set_gps = 2;
@@ -46,7 +46,7 @@ public class AltosState implements Cloneable, Serializable {
        private int     prev_tick;
        public int      boost_tick;
 
-       class AltosValue implements Serializable{
+       class AltosValue {
                double  value;
                double  prev_value;
                private double  max_value;
@@ -182,14 +182,19 @@ public class AltosState implements Cloneable, Serializable {
                        prev_value = AltosLib.MISSING;
                        max_value = AltosLib.MISSING;
                }
+
        }
 
-       class AltosCValue implements Serializable {
+       class AltosCValue {
 
-               class AltosIValue extends AltosValue implements Serializable {
+               class AltosIValue extends AltosValue {
                        boolean can_max() {
                                return c_can_max();
                        }
+
+                       AltosIValue() {
+                               super();
+                       }
                };
 
                public AltosIValue      measured;
@@ -278,7 +283,7 @@ public class AltosState implements Cloneable, Serializable {
                        computed.finish_update();
                }
 
-               AltosCValue() {
+               public AltosCValue() {
                        measured = new AltosIValue();
                        computed = new AltosIValue();
                }
@@ -317,7 +322,7 @@ public class AltosState implements Cloneable, Serializable {
                ground_altitude.set_measured(a, time);
        }
 
-       class AltosGpsGroundAltitude extends AltosValue implements Serializable {
+       class AltosGpsGroundAltitude extends AltosValue {
                void set(double a, double t) {
                        super.set(a, t);
                        pad_alt = value();
@@ -329,6 +334,10 @@ public class AltosState implements Cloneable, Serializable {
                        pad_alt = value();
                        gps_altitude.set_gps_height();
                }
+
+               AltosGpsGroundAltitude() {
+                       super();
+               }
        }
 
        private AltosGpsGroundAltitude gps_ground_altitude;
@@ -341,7 +350,7 @@ public class AltosState implements Cloneable, Serializable {
                gps_ground_altitude.set(a, time);
        }
 
-       class AltosGroundPressure extends AltosCValue implements Serializable {
+       class AltosGroundPressure extends AltosCValue {
                void set_filtered(double p, double time) {
                        computed.set_filtered(p, time);
                        if (!is_measured())
@@ -352,6 +361,10 @@ public class AltosState implements Cloneable, Serializable {
                        super.set_measured(p, time);
                        ground_altitude.set_computed(pressure_to_altitude(p), time);
                }
+
+               AltosGroundPressure () {
+                       super();
+               }
        }
 
        private AltosGroundPressure ground_pressure;
@@ -364,7 +377,7 @@ public class AltosState implements Cloneable, Serializable {
                ground_pressure.set_measured(pressure, time);
        }
 
-       class AltosAltitude extends AltosCValue implements Serializable {
+       class AltosAltitude extends AltosCValue {
 
                private void set_speed(AltosValue v) {
                        if (!acceleration.is_measured() || !ascent)
@@ -382,11 +395,15 @@ public class AltosState implements Cloneable, Serializable {
                        set_speed(measured);
                        set |= set_position;
                }
+
+               AltosAltitude() {
+                       super();
+               }
        }
 
        private AltosAltitude   altitude;
 
-       class AltosGpsAltitude extends AltosValue implements Serializable {
+       class AltosGpsAltitude extends AltosValue {
 
                private void set_gps_height() {
                        double  a = value();
@@ -402,6 +419,10 @@ public class AltosState implements Cloneable, Serializable {
                        super.set(a, t);
                        set_gps_height();
                }
+
+               AltosGpsAltitude() {
+                       super();
+               }
        }
 
        private AltosGpsAltitude        gps_altitude;
@@ -469,7 +490,7 @@ public class AltosState implements Cloneable, Serializable {
                return gps_speed.max();
        }
 
-       class AltosPressure extends AltosValue implements Serializable {
+       class AltosPressure extends AltosValue {
                void set(double p, double time) {
                        super.set(p, time);
                        if (state == AltosLib.ao_flight_pad)
@@ -477,6 +498,10 @@ public class AltosState implements Cloneable, Serializable {
                        double a = pressure_to_altitude(p);
                        altitude.set_computed(a, time);
                }
+
+               AltosPressure() {
+                       super();
+               }
        }
 
        private AltosPressure   pressure;
@@ -539,7 +564,7 @@ public class AltosState implements Cloneable, Serializable {
                return AltosLib.MISSING;
        }
 
-       class AltosSpeed extends AltosCValue implements Serializable {
+       class AltosSpeed extends AltosCValue {
 
                boolean can_max() {
                        return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless;
@@ -563,6 +588,10 @@ public class AltosState implements Cloneable, Serializable {
                        super.set_measured(new_value, time);
                        set_accel();
                }
+
+               AltosSpeed() {
+                       super();
+               }
        }
 
        private AltosSpeed speed;
@@ -593,7 +622,7 @@ public class AltosState implements Cloneable, Serializable {
                return AltosLib.MISSING;
        }
 
-       class AltosAccel extends AltosCValue implements Serializable {
+       class AltosAccel extends AltosCValue {
 
                boolean can_max() {
                        return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless;
@@ -604,6 +633,10 @@ public class AltosState implements Cloneable, Serializable {
                        if (ascent)
                                speed.set_integral(this.measured);
                }
+
+               AltosAccel() {
+                       super();
+               }
        }
 
        AltosAccel acceleration;
@@ -684,6 +717,7 @@ public class AltosState implements Cloneable, Serializable {
        public double   ground_accel_avg;
 
        public int      log_format;
+       public int      log_space;
        public String   product;
 
        public AltosMs5607      baro;
@@ -801,6 +835,7 @@ public class AltosState implements Cloneable, Serializable {
                ground_accel_avg = AltosLib.MISSING;
 
                log_format = AltosLib.MISSING;
+               log_space = AltosLib.MISSING;
                product = null;
                serial = AltosLib.MISSING;
                receiver_serial = AltosLib.MISSING;
@@ -960,6 +995,7 @@ public class AltosState implements Cloneable, Serializable {
                ground_accel_avg = old.ground_accel_avg;
 
                log_format = old.log_format;
+               log_space = old.log_space;
                product = old.product;
                serial = old.serial;
                receiver_serial = old.receiver_serial;
@@ -1078,6 +1114,10 @@ public class AltosState implements Cloneable, Serializable {
                }
        }
 
+       public void set_log_space(int log_space) {
+               this.log_space = log_space;
+       }
+
        public void set_flight_params(int apogee_delay, int main_deploy) {
                this.apogee_delay = apogee_delay;
                this.main_deploy = main_deploy;
@@ -1483,6 +1523,31 @@ public class AltosState implements Cloneable, Serializable {
        public AltosState clone() {
                AltosState s = new AltosState();
                s.copy(this);
+
+               /* Code to test state save/restore. Enable only for that purpose
+                */
+               if (false) {
+                       AltosJson       json = new AltosJson(this);
+                       String          onetrip = json.toPrettyString();
+                       AltosJson       back = AltosJson.fromString(onetrip);
+                       AltosState      tripstate = (AltosState) back.make(this.getClass());
+                       AltosJson       tripjson = new AltosJson(tripstate);
+                       String          twotrip = tripjson.toPrettyString();
+
+                       if (!onetrip.equals(twotrip)) {
+                               try {
+                                       FileWriter one_file = new FileWriter("one.json", true);
+                                       one_file.write(onetrip);
+                                       one_file.flush();
+                                       FileWriter two_file = new FileWriter("two.json", true);
+                                       two_file.write(twotrip);
+                                       two_file.flush();
+                               } catch (Exception e) {
+                               }
+                               System.out.printf("json error\n");
+                               System.exit(1);
+                       }
+               }
                return s;
        }
 
index a7baa85eae3404978945d7ce529a73b9942ed914..bce2a8d96efdca47961b5e08454ac6111c32f561 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
@@ -32,7 +32,6 @@ public abstract class AltosStateIterable implements Iterable<AltosState> {
                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"))
index 12d4dd41fad8856bf5b4dc983b35f90526058e6c..1209c2a0ba0550f19888f1fe1870d48bef97c51e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosStateUpdate {
        public void     update_state(AltosState state) throws InterruptedException, AltosUnknownProduct;
index 67caa60cd8da0794d36e5c92083b23669c31a17f..d526e6e51cee26a34cbc88eb3f825114968fd07b 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 
index b9d32f4890759c8e916437c4d9a0206d189d0489..8f0d06b0d229e13a0369d1f2852572ea9de4724d 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosTelemetryCompanion extends AltosTelemetryStandard {
        AltosCompanion  companion;
index cd2cb8ca3681f467cc7f92b8faabc3012ed1299c..352f180836b1f4a61732197420421baa32b05fa5 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 
 public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
index b80c2dc90b094dded90ad99a5af3caa85f491ffb..5f512e1485ccff844a793c92ca9ebbf355474965 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index ff3958682177974c5d1463cb79e2d3f7ed6cbb16..256626f340aff28a0b5809cea57c231b2734835d 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 import java.util.*;
index 6c0fcfeb4ac390a266a1a7837eb5df80dd0863b8..df41b7d9f2ca926a340dac4b67c309682c281df7 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 
index 33c3644948c58dc86f990b4351e5c1a39ac7db09..1cff3cd4a052cb5320deb98e31caa097a01a9a56 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 
 public class AltosTelemetryLocation extends AltosTelemetryStandard {
index 13b5dbeacbbec26892f46c3ada658331b679d297..8e5bcd1c6688ce2d7d9874e0a0b9da7c4956b96d 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 import java.text.*;
 import java.util.HashMap;
 
index d71f2802d86f582247929c3410df75ad9f69d292..ed0211a9fd78f7dee145f768d95a8a1c95a46d99 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosTelemetryMegaData extends AltosTelemetryStandard {
        int     state;
index f0d16f1925fce78144843d6da8953e3f0429a165..365db92dbc8750c827d2b71ef21f95333d29bf70 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
        int     accel;
index a4e9116fa5b21b304ccdd5cc63d1226165747a70..0d94383601dcaac67e81dfaceb78df70a7db52aa 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 
 public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
index 1b405f2b509a0bcd96f73f37c21d6efbbd4224ea..0ccc4e152d15a9e1d3b292171197d5f3fd4c8d90 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 
 public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
index 8996d66235f2617589b4c8da62a70176aaa33526..8bca55fa6c3be3ffbbe62456eef7c4c3cd1f1b1f 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 
 public class AltosTelemetryMini extends AltosTelemetryStandard {
index 8cf023a49378bd6d2bdf5b0eb8d0c1c4020ed7c7..c28d04d368b326d1cb93133bef15097b1c10226e 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosTelemetryRaw extends AltosTelemetryStandard {
        public AltosTelemetryRaw(int[] bytes) {
index 2b0a443c3559d08378e2256338cc42c8dbfd729b..370610b168039e936fae1c9af04eb1a2b6924fb9 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 import java.io.*;
index de60e63cd70fffcd1c7c3c8c8ead873c60264556..d88e6cac941310e395606f0813dfcd5aa20a99a0 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosTelemetrySatellite extends AltosTelemetryStandard {
        int             channels;
index 74b61d3c919c36363a29872f7d8b4a4f9ac380e3..7a4a9f35fc433cfa5c3bdb1a4e7516e935899613 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 
 public class AltosTelemetrySensor extends AltosTelemetryStandard {
index 7086abfc7ffcee3b2bd361d4b7875f74c748bd16..dea9c29e16950f9f138490bc6927505976f3be25 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public abstract class AltosTelemetryStandard extends AltosTelemetry {
        int[]   bytes;
index a1e485b399bfe857badbaee04f91d8522f50b4c5..2b261b708e54fdc3c15b9df3a7cadea133623f52 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosTemperature extends AltosUnits {
 
index 13b9dbe6ab3f21e0afb7adc96e2dfb9ba5982844..b46b30ad7fc28d95f21fac1693c90048140821fe 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import java.text.*;
 
 public abstract class AltosUnits {
 
+       AltosUnitsRange[]       range_metric, range_imperial;
+
+       private AltosUnitsRange range(double v, boolean imperial_units) {
+               AltosUnitsRange[]       ranges = imperial_units ? range_imperial : range_metric;
+
+               for (int i = ranges.length - 1; i > 0; i--)
+                       if (v >= ranges[i].lower_limit)
+                               return ranges[i];
+               return ranges[0];
+       }
+
+       private AltosUnitsRange first_range(boolean imperial_units) {
+               return imperial_units ? range_imperial[0] : range_metric[0];
+       }
+
        public abstract double value(double v, boolean imperial_units);
 
        public abstract double inverse(double v, boolean imperial_units);
@@ -31,89 +46,168 @@ public abstract class AltosUnits {
 
        public abstract int show_fraction(int width, boolean imperial_units);
 
-       public double parse_locale(String s, boolean imperial_units) throws ParseException {
-               double v = AltosParse.parse_double_locale(s);
-               return inverse(v, imperial_units);
+       private double value(double v) {
+               return value(v, AltosConvert.imperial_units);
        }
 
-       public double parse_net(String s, boolean imperial_units) throws ParseException {
-               double v = AltosParse.parse_double_net(s);
-               return inverse(v, imperial_units);
+       private double inverse(double v) {
+               return inverse(v, AltosConvert.imperial_units);
        }
 
-       public double parse_locale(String s) throws ParseException {
-               return parse_locale(s, AltosConvert.imperial_units);
+       private String show_units() {
+               return show_units(AltosConvert.imperial_units);
        }
 
-       public double parse_net(String s) throws ParseException {
-               return parse_net(s, AltosConvert.imperial_units);
+       private String say_units() {
+               return say_units(AltosConvert.imperial_units);
        }
 
-       public double value(double v) {
-               return value(v, AltosConvert.imperial_units);
+       private int show_fraction(int width) {
+               return show_fraction(width, AltosConvert.imperial_units);
        }
 
-       public double inverse(double v) {
-               return inverse(v, AltosConvert.imperial_units);
+       private int say_fraction(boolean imperial_units) {
+               return 0;
        }
 
-       public String show_units() {
-               return show_units(AltosConvert.imperial_units);
+       private String show_format(AltosUnitsRange range, int width) {
+               return String.format("%%%d.%df %s", width, range.show_fraction(width), range.show_units);
        }
 
-       public String say_units() {
-               return say_units(AltosConvert.imperial_units);
+       private String say_format(AltosUnitsRange range) {
+               return String.format("%%1.%df", range.say_fraction());
        }
 
-       public int show_fraction(int width) {
-               return show_fraction(width, AltosConvert.imperial_units);
+       private String say_units_format(AltosUnitsRange range)  {
+               return String.format("%%1.%df %s", range.say_fraction(), range.say_units);
        }
 
-       int say_fraction(boolean imperial_units) {
-               return 0;
+       public String show(int width, double v, boolean imperial_units) {
+               AltosUnitsRange range = range(v, imperial_units);
+
+               return String.format(show_format(range, width), range.value(v));
+       }
+
+       public String say(double v, boolean imperial_units) {
+               AltosUnitsRange range = range(v, imperial_units);
+
+               return String.format(say_format(range), range.value(v));
+       }
+
+       public String say_units(double v, boolean imperial_units) {
+               AltosUnitsRange range = range(v, imperial_units);
+
+               return String.format(say_units_format(range), range.value(v));
+       }
+
+       public String show(int width, double v) {
+               return show(width, v, AltosConvert.imperial_units);
+       }
+
+       public String say(double v) {
+               return say(v, AltosConvert.imperial_units);
+       }
+
+       public String say_units(double v) {
+               return say_units(v, AltosConvert.imperial_units);
+       }
+
+       /* Parsing functions. Use the first range of the type */
+       public String parse_units(boolean imperial_units) {
+               return first_range(imperial_units).show_units;
+       }
+
+       public String parse_units() {
+               return parse_units(AltosConvert.imperial_units);
+       }
+
+       public double parse_value(double v, boolean imperial_units) {
+               return first_range(imperial_units).value(v);
+       }
+
+       public double parse_value(double v) {
+               return parse_value(v, AltosConvert.imperial_units);
        }
 
-       private String show_format(int width, boolean imperial_units) {
-               return String.format("%%%d.%df %s", width, show_fraction(width, imperial_units), show_units(imperial_units));
+       /* Graphing functions. Use the first range of the type */
+       public String graph_units(boolean imperial_units) {
+               return first_range(imperial_units).show_units;
        }
 
-       private String say_format(boolean imperial_units) {
-               return String.format("%%1.%df", say_fraction(imperial_units));
+       public String graph_units() {
+               return graph_units(AltosConvert.imperial_units);
        }
 
-       private String say_units_format(boolean imperial_units) {
-               return String.format("%%1.%df %s", say_fraction(imperial_units), say_units(imperial_units));
+       public double graph_value(double v, boolean imperial_units) {
+               return first_range(imperial_units).value(v);
+       }
+
+       public double graph_value(double v) {
+               return graph_value(v, AltosConvert.imperial_units);
+       }
+
+       private String graph_format(AltosUnitsRange range, int width) {
+               return String.format(String.format("%%%d.%df", width, range.show_fraction(width)), 0.0);
        }
 
        public String graph_format(int width, boolean imperial_units) {
-               return String.format(String.format("%%%d.%df", width, show_fraction(width, imperial_units)), 0.0);
+               return graph_format(first_range(imperial_units), width);
        }
 
        public String graph_format(int width) {
                return graph_format(width, AltosConvert.imperial_units);
        }
 
-       public String show(int width, double v, boolean imperial_units) {
-               return String.format(show_format(width, imperial_units), value(v, imperial_units));
+       /* Parsing functions. */
+       public double parse_locale(String s, boolean imperial_units) throws ParseException {
+               double v = AltosParse.parse_double_locale(s);
+               return inverse(v, imperial_units);
        }
 
-       public String show(int width, double v) {
-               return show(width, v, AltosConvert.imperial_units);
+       public double parse_net(String s, boolean imperial_units) throws ParseException {
+               double v = AltosParse.parse_double_net(s);
+               return inverse(v, imperial_units);
        }
 
-       public String say(double v, boolean imperial_units) {
-               return String.format(say_format(imperial_units), value(v, imperial_units));
+       public double parse_locale(String s) throws ParseException {
+               return parse_locale(s, AltosConvert.imperial_units);
        }
 
-       public String say(double v) {
-               return say(v, AltosConvert.imperial_units);
+       public double parse_net(String s) throws ParseException {
+               return parse_net(s, AltosConvert.imperial_units);
        }
 
-       public String say_units(double v, boolean imperial_units) {
-               return String.format(say_units_format(imperial_units), value(v, imperial_units));
-       }
+       public AltosUnits() {
+               range_metric = new AltosUnitsRange[1];
 
-       public String say_units(double v) {
-               return say_units(v, AltosConvert.imperial_units);
+               range_metric[0] = new AltosUnitsRange(this, false) {
+                               double value(double v) {
+                                       return units.value(v, false);
+                               }
+
+                               int show_fraction(int width) {
+                                       return units.show_fraction(width, false);
+                               }
+
+                               int say_fraction() {
+                                       return units.say_fraction(false);
+                               }
+                       };
+
+               range_imperial = new AltosUnitsRange[1];
+
+               range_imperial[0] = new AltosUnitsRange(this, true) {
+                               double value(double v) {
+                                       return units.value(v, true);
+                               }
+
+                               int show_fraction(int width) {
+                                       return units.show_fraction(width, true);
+                               }
+
+                               int say_fraction() {
+                                       return units.say_fraction(true);
+                               }
+                       };
        }
 }
index bb8451b791170001146d5cb68419762cb6e6d80b..89dbdf77ca30f5b8d7fc2796ef849325e99bfff9 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosUnitsListener {
        public void units_changed(boolean imperial_units);
diff --git a/altoslib/AltosUnitsRange.java b/altoslib/AltosUnitsRange.java
new file mode 100644 (file)
index 0000000..f376a46
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright Â© 2016 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.altoslib_11;
+
+import java.text.*;
+
+public abstract class AltosUnitsRange {
+
+       AltosUnits      units;
+
+       double          lower_limit;
+       String          show_units;
+       String          say_units;
+
+       abstract double value(double v);
+       abstract int show_fraction(int width);
+       abstract int say_fraction();
+
+       AltosUnitsRange(AltosUnits units, boolean imperial_units) {
+               this.units = units;
+               this.show_units = units.show_units(imperial_units);
+               this.say_units = units.say_units(imperial_units);
+       }
+
+       AltosUnitsRange(double lower_limit, String show_units, String say_units) {
+               this.units = null;
+               this.lower_limit = lower_limit;
+               this.show_units = show_units;
+               this.say_units = say_units;
+       }
+}
index ff536f57bfea1661b040c104658679b7aacd2447..fe16f4414c12ba86ae58fee3737fcea3de7e66ff 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosUnknownProduct extends Exception {
        public String product;
index 9ac94dcdec88acee9bf8b5fb67529e5066dacf47..12fecaa00a7efcd52b4c29583316c859f29191d5 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosVersion {
        public final static String version = "@VERSION@";
index 1738dd867b3398a3a79c797f4dbb06449512cd0c..5c9cea28a9db46235dc5e7811e67a1e31ad7e615 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public class AltosVoltage extends AltosUnits {
 
index 02b5d669aed9a383fa55ffc40f56c85f3e6ffa48..a3a394d31f674ff1fc0b3dc26a7ba9ea3cc4cb24 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 public interface AltosWriter {
 
index dc9da8fdbb9fb00f66102fefb8904019e11b292a..2a9eb9c99e6150d090bb82821048a7cca01eb24f 100644 (file)
@@ -64,6 +64,7 @@ altoslib_JAVA = \
        AltosIdleFetch.java \
        AltosIdleMonitor.java \
        AltosIdleMonitorListener.java \
+       AltosIdleReader.java \
        AltosIgnite.java \
        AltosIMU.java \
        AltosKML.java \
@@ -118,6 +119,7 @@ altoslib_JAVA = \
        AltosIMU.java \
        AltosMag.java \
        AltosUnits.java \
+       AltosUnitsRange.java \
        AltosDistance.java \
        AltosHeight.java \
        AltosSpeed.java \
@@ -159,6 +161,7 @@ altoslib_JAVA = \
        AltosMapLoaderListener.java \
        AltosMapLoader.java \
        AltosMapTypeListener.java \
+       AltosJson.java \
        AltosVersion.java
 
 JAR=altoslib_$(ALTOSLIB_VERSION).jar
index 81bc8c28542cc1a797926b4c24a33b711e9f6020..1c8bfdb79402af700f02009d0685e002818f3165 100644 (file)
@@ -20,8 +20,8 @@ package altosui;
 import java.awt.*;
 import libaltosJNI.*;
 
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class Altos extends AltosUILib {
 
index 85260a70c2d9499c3c49bd69e9d4e4f2822964b5..99f7e5ad72d49184e082ab6041cf077ce4f9cb04 100644 (file)
@@ -21,8 +21,8 @@ import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosAscent extends AltosUIFlightTab {
        JLabel  cur, max;
index 251982ad2778aceb490756dae3d1146906e04127..8bf257150802eeab11282c74c0d3caf42e5cd8f6 100644 (file)
@@ -19,8 +19,8 @@ package altosui;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosCompanionInfo extends JTable implements AltosFlightDisplay {
        private AltosFlightInfoTableModel model;
index e47b0e22e6cd1b0af79192bae9f360a6c822cad0..63f502062d03e24be2e754baece5c35c4f6bf316 100644 (file)
@@ -22,8 +22,8 @@ import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosConfig implements ActionListener {
 
index e0915a17b898a4d9a3b5bcb090677f8ef451d5bc..4bfdb663d596a62101ddcd695d04d3dc6c70950a 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosConfigPyroUI
        extends AltosUIDialog
@@ -105,7 +105,7 @@ public class AltosConfigPyroUI
                                double  unit_value = new_value;
                                AltosUnits units = AltosPyro.pyro_to_units(flag);
                                if (units != null)
-                                       unit_value = units.value(new_value);
+                                       unit_value = units.parse_value(new_value);
                                String  format;
                                if (scale >= 100)
                                        format = "%6.2f";
index eedc18c51715fdca82b4b0c6a0e3c0899e6bac5e..6172749857d3eb9664d86394960db4af9eb2c79f 100644 (file)
@@ -21,8 +21,8 @@ import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosConfigTD implements ActionListener {
 
index 9a76fbe2acb2d42224107f44bd9b03e82add480c..1c0e0fef60685281cf988dddc3289a62958a386b 100644 (file)
@@ -21,8 +21,8 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosConfigTDUI
        extends AltosUIDialog
index 24167df36635d058c11284b969512ebbd2488fa6..cb7af82971d163ed06772711739c6be8b618af5c 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.event.*;
 import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosConfigUI
        extends AltosUIDialog
@@ -976,7 +976,7 @@ public class AltosConfigUI
        }
 
        String get_main_deploy_label() {
-               return String.format("Main Deploy Altitude(%s):", AltosConvert.height.show_units());
+               return String.format("Main Deploy Altitude(%s):", AltosConvert.height.parse_units());
        }
 
        String[] main_deploy_values() {
@@ -1243,7 +1243,7 @@ public class AltosConfigUI
        }
 
        String get_tracker_motion_label() {
-               return String.format("Logging Trigger Motion (%s):", AltosConvert.height.show_units());
+               return String.format("Logging Trigger Motion (%s):", AltosConvert.height.parse_units());
        }
 
        void set_tracker_tool_tip() {
index 52c503524a13133719eaa0d9011356b10be5cf08..b4f423d91694e247bbf5a7b1f87b821699140e55 100644 (file)
@@ -22,7 +22,7 @@ import java.awt.event.*;
 import java.beans.*;
 import javax.swing.*;
 import javax.swing.event.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosConfigureUI
        extends AltosUIConfigure
index eeaed19ebfe4d91a1210d85f38b16434667b42a9..44bceceee5dd6539ae4ef8c4083c2f35b5ce6166 100644 (file)
@@ -21,8 +21,8 @@ import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosDescent extends AltosUIFlightTab {
 
index 4229e4fcb6730e08c1eefd8168bbb4f414354519..82c63396a7ae724ff9ddd1d1d7185959c06bfc77 100644 (file)
@@ -19,8 +19,8 @@ package altosui;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {
        GridBagLayout   layout;
index 7bf2bb781ba5a7611072d48679010397ae0a0842..dc5b96a9719192bfc5fad5a02d20bf61c22060b6 100644 (file)
@@ -27,7 +27,7 @@ import java.util.*;
 import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosFlightStatusTableModel extends AbstractTableModel {
        private String[] columnNames = {
index d39366da4291bf152bd20dc90f1347fb0fd360fe..88d6f0ff143191b7ad155a614dc108f43707f3c9 100644 (file)
@@ -18,7 +18,7 @@
 package altosui;
 
 import java.awt.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosFlightStatusUpdate implements ActionListener {
 
index a1526cb50751063d0d4456bcc808f93cd09726ef..63f8c670762794c174946dc27f834dfb151f6906 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.event.*;
 import javax.swing.*;
 import java.util.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
        AltosVoice              voice;
@@ -40,7 +40,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
        AltosDescent    descent;
        AltosLanded     landed;
        AltosCompanionInfo      companion;
-       AltosUIMapNew      sitemap;
+       AltosUIMap      sitemap;
        boolean         has_map;
        boolean         has_companion;
        boolean         has_state;
@@ -289,7 +289,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
                has_companion = false;
                has_state = false;
 
-               sitemap = new AltosUIMapNew();
+               sitemap = new AltosUIMap();
                displays.add(sitemap);
                has_map = false;
 
index 34d56b24f0d625716d4f69235a2c94efae78de2c..4f394d73fb932a617bc62a806e7b1ab313640768 100644 (file)
@@ -23,8 +23,8 @@ import java.util.ArrayList;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 import org.jfree.chart.ChartPanel;
 import org.jfree.chart.JFreeChart;
@@ -35,7 +35,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
        JTabbedPane             pane;
        AltosGraph              graph;
        AltosUIEnable           enable;
-       AltosUIMapNew           map;
+       AltosUIMap              map;
        AltosState              state;
        AltosGraphDataSet       graphDataSet;
        AltosFlightStats        stats;
@@ -47,7 +47,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                for (AltosState state : states) {
                        if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
                                if (map == null)
-                                       map = new AltosUIMapNew();
+                                       map = new AltosUIMap();
                                map.show(state, null);
                                has_gps = true;
                        }
@@ -100,8 +100,6 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                addWindowListener(new WindowAdapter() {
                                @Override
                                public void windowClosing(WindowEvent e) {
-                                       setVisible(false);
-                                       dispose();
                                        AltosUIPreferences.unregister_font_listener(AltosGraphUI.this);
                                        AltosPreferences.unregister_units_listener(AltosGraphUI.this);
                                }
index d789de77191319de63c00b7a0ac3a346ff516dfc..1a992946aed33ede8b5bff1806293b45c45c8077 100644 (file)
@@ -24,8 +24,8 @@ import javax.swing.event.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.Arrays;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosIdleMonitorListener, DocumentListener {
        AltosDevice             device;
@@ -35,7 +35,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
        AltosFlightStatus       flightStatus;
        AltosIgnitor            ignitor;
        AltosIdleMonitor        thread;
-       AltosUIMapNew           sitemap;
+       AltosUIMap              sitemap;
        int                     serial;
        boolean                 remote;
        boolean                 has_ignitor;
@@ -275,7 +275,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
 
                ignitor = new AltosIgnitor();
 
-               sitemap = new AltosUIMapNew();
+               sitemap = new AltosUIMap();
 
                /* Make the tabbed pane use the rest of the window space */
                bag.add(pane, constraints(0, 4, GridBagConstraints.BOTH));
index eca2a66808c301efa62f367bd9efdb155b7502a5..84dc54dbe52e6d42c13843caf093e3208ed5cd75 100644 (file)
@@ -24,8 +24,8 @@ import java.io.*;
 import java.text.*;
 import java.util.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosIgniteUI
        extends AltosUIDialog
index 903da5a91a6637c02f901fbcdd3f832b1961da14..13d99124528ba598062c160f8ab599649e939852 100644 (file)
@@ -20,8 +20,8 @@ package altosui;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosIgnitor extends AltosUIFlightTab {
 
index b704651da53632b0e10fb7de2f7d22410b423efd..77c504b83792279b28c98e4424c6c28f0e7f0e00 100644 (file)
@@ -21,8 +21,8 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosLanded extends AltosUIFlightTab implements ActionListener {
 
index 503b062184276f049ac9b53fdd04ef93881392b8..fb2cd883fa97f37d9476e77c76c3fa6cbb0dd693 100644 (file)
@@ -20,7 +20,7 @@ package altosui;
 import java.io.*;
 import java.util.concurrent.*;
 import java.awt.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosLaunch {
        AltosDevice     device;
@@ -91,7 +91,7 @@ public class AltosLaunch {
                                throw new TimeoutException();
                        if (get_string(line, "Rssi: ", status_name)) {
                                try {
-                                       rssi = Altos.fromdec(status_name.get());
+                                       rssi = (int) Altos.fromdec(status_name.get());
                                } catch (NumberFormatException ne) {
                                }
                                break;
@@ -194,4 +194,4 @@ public class AltosLaunch {
                device = in_device;
                serial = new AltosSerial(device);
        }
-}
\ No newline at end of file
+}
index 127a33a38da8de9643c39e4170b6f50d1956ded5..22608c1b74066a0f8bafd9bf4ba5461ccb919062 100644 (file)
@@ -23,7 +23,7 @@ import javax.swing.*;
 import java.io.*;
 import java.text.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 class FireButton extends JButton {
        protected void processMouseEvent(MouseEvent e) {
index 4f55636db23c706f2ec7a4fafd3894811b6e30ab..b6f1f3c9b0ec8a4f1f6fdc0e8e23be29029a0fad 100644 (file)
@@ -18,8 +18,8 @@
 package altosui;
 
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosPad extends AltosUIFlightTab {
 
@@ -101,7 +101,11 @@ public class AltosPad extends AltosUIFlightTab {
 
        class ReceiverBattery extends AltosUIVoltageIndicator {
 
-               public double voltage(AltosState state) { return AltosLib.MISSING; }
+               double  last_voltage = AltosLib.MISSING;
+
+               public double voltage(AltosState state) {
+                       return last_voltage;
+               }
 
                public double good() { return AltosLib.ao_battery_good; }
 
@@ -111,8 +115,10 @@ public class AltosPad extends AltosUIFlightTab {
 
                public double value(AltosState state, AltosListenerState listener_state, int i) {
                        if (listener_state == null)
-                               return AltosLib.MISSING;
-                       return listener_state.battery;
+                               last_voltage = AltosLib.MISSING;
+                       else
+                               last_voltage = listener_state.battery;
+                       return last_voltage;
                }
 
                public ReceiverBattery (AltosUIFlightTab container, int y) {
@@ -205,40 +211,26 @@ public class AltosPad extends AltosUIFlightTab {
                }
        }
 
-       class PadAlt extends AltosUIIndicator {
+       class PadAlt extends AltosUIUnitsIndicator {
 
-               double  last_alt = AltosLib.MISSING - 1;
+               public double value(AltosState state, int i) {
+                       if (report_pad(state))
+                               return state.pad_alt;
+                       else
+                               return state.gps.alt;
+               }
 
                public void show (AltosState state, AltosListenerState listener_state) {
-                       double alt = AltosLib.MISSING;
-                       String label = null;
+                       String label = "Altitude";
 
-                       if (state != null) {
-                               if (report_pad(state)) {
-                                       alt = state.pad_alt;
-                                       label = "Pad Altitude";
-                               } else {
-                                       alt = state.gps.alt;
-                                       label = "Altitude";
-                               }
-                       }
-                       if (alt != last_alt) {
-                               if (alt != AltosLib.MISSING) {
-                                       show(AltosConvert.height.show(5, alt));
-                                       set_label(label);
-                               } else
-                                       hide();
-                               last_alt = alt;
-                       }
-               }
-
-               public void reset() {
-                       super.reset();
-                       last_alt =  AltosLib.MISSING - 1;
+                       if (state != null && report_pad(state))
+                               label = "Pad Altitude";
+                       set_label(label);
+                       super.show(state, listener_state);
                }
 
                public PadAlt (AltosUIFlightTab container, int y) {
-                       super (container, y, "Pad Altitude", 1, false, 2);
+                       super (container, y, AltosConvert.height, "Pad Altitude", 1, false, 2);
                }
        }
        public String getName() { return "Pad"; }
index 4a390ee62ee16c16090014941c0cd8bf64463bbc..fa259906769a9da7101c9bf1c064ce43a21bab93 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class AltosUI extends AltosUIFrame {
        public AltosVoice voice = new AltosVoice();
@@ -295,7 +295,7 @@ public class AltosUI extends AltosUIFrame {
        }
 
        void LoadMaps() {
-               new AltosUIMapPreloadNew(AltosUI.this);
+               new AltosUIMapPreload(AltosUI.this);
        }
 
        void LaunchController() {
@@ -492,39 +492,47 @@ public class AltosUI extends AltosUIFrame {
                if (states == null)
                        return false;
                try {
+                       System.out.printf("%s:\n", file.toString());
                        AltosFlightStats stats = new AltosFlightStats(states);
-                       if (stats.serial > 0)
+                       if (stats.serial != AltosLib.MISSING)
                                System.out.printf("Serial:       %5d\n", stats.serial);
-                       if (stats.flight > 0)
+                       if (stats.flight != AltosLib.MISSING)
                                System.out.printf("Flight:       %5d\n", stats.flight);
-                       if (stats.year > 0)
+                       if (stats.year != AltosLib.MISSING)
                                System.out.printf("Date:    %04d-%02d-%02d\n",
                                                  stats.year, stats.month, stats.day);
-                       if (stats.hour > 0)
+                       if (stats.hour != AltosLib.MISSING)
                                System.out.printf("Time:      %02d:%02d:%02d UTC\n",
                                                  stats.hour, stats.minute, stats.second);
-                       System.out.printf("Max height:  %6.0f m    %6.0f ft\n",
-                                         stats.max_height,
-                                         AltosConvert.meters_to_feet(stats.max_height));
-                       System.out.printf("Max speed:   %6.0f m/s  %6.0f ft/s  %6.4f Mach\n",
-                                         stats.max_speed,
-                                         AltosConvert.meters_to_feet(stats.max_speed),
-                                         AltosConvert.meters_to_mach(stats.max_speed));
+                       if (stats.max_height != AltosLib.MISSING)
+                               System.out.printf("Max height:  %6.0f m    %6.0f ft\n",
+                                                 stats.max_height,
+                                                 AltosConvert.meters_to_feet(stats.max_height));
+                       if (stats.max_speed != AltosLib.MISSING)
+                               System.out.printf("Max speed:   %6.0f m/s  %6.0f ft/s  %6.4f Mach\n",
+                                                 stats.max_speed,
+                                                 AltosConvert.meters_to_feet(stats.max_speed),
+                                                 AltosConvert.meters_to_mach(stats.max_speed));
                        if (stats.max_acceleration != AltosLib.MISSING) {
                                System.out.printf("Max accel:   %6.0f m/s² %6.0f ft/s² %6.2f g\n",
                                                  stats.max_acceleration,
                                                  AltosConvert.meters_to_feet(stats.max_acceleration),
                                                  AltosConvert.meters_to_g(stats.max_acceleration));
                        }
-                       System.out.printf("Drogue rate: %6.0f m/s  %6.0f ft/s\n",
-                                         stats.state_speed[Altos.ao_flight_drogue],
-                                         AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]));
-                       System.out.printf("Main rate:   %6.0f m/s  %6.0f ft/s\n",
-                                         stats.state_speed[Altos.ao_flight_main],
-                                         AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]));
-                       System.out.printf("Flight time: %6.0f s\n",
-                                         stats.state_end[Altos.ao_flight_main] -
-                                         stats.state_start[Altos.ao_flight_boost]);
+                       if (stats.state_speed[Altos.ao_flight_drogue] != AltosLib.MISSING)
+                               System.out.printf("Drogue rate: %6.0f m/s  %6.0f ft/s\n",
+                                                 stats.state_speed[Altos.ao_flight_drogue],
+                                                 AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]));
+                       if (stats.state_speed[Altos.ao_flight_main] != AltosLib.MISSING)
+                               System.out.printf("Main rate:   %6.0f m/s  %6.0f ft/s\n",
+                                                 stats.state_speed[Altos.ao_flight_main],
+                                                 AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]));
+                       if (stats.state_end[Altos.ao_flight_main] != AltosLib.MISSING &&
+                           stats.state_start[Altos.ao_flight_boost] != AltosLib.MISSING)
+                               System.out.printf("Flight time: %6.0f s\n",
+                                                 stats.state_end[Altos.ao_flight_main] -
+                                                 stats.state_start[Altos.ao_flight_boost]);
+                       System.out.printf("\n");
                        return true;
                } catch (InterruptedException ie) {
                } catch (IOException ie) {
@@ -536,7 +544,6 @@ public class AltosUI extends AltosUIFrame {
                try {
                        AltosStateIterable eef = record_iterable(file);
 
-                       System.out.printf ("process cat\n");
                        for (AltosState state : eef) {
                                System.out.printf ("tick %d state %d height %g\n",
                                                   state.tick, state.state(), state.height());
@@ -605,15 +612,13 @@ public class AltosUI extends AltosUIFrame {
                                        File file = new File(args[i]);
                                        switch (process) {
                                        case process_none:
-                                       case process_graph:
                                                if (altosui == null)
                                                        altosui = new AltosUI();
+                                       case process_graph:
                                                if (!process_graph(file))
                                                        ++errors;
                                                break;
                                        case process_replay:
-                                               if (altosui == null)
-                                                       altosui = new AltosUI();
                                                if (!process_replay(file))
                                                        ++errors;
                                                break;
index dce8420ed6923c6ba20320f935d4f00b92b95e31..cfe3bb5b54c39654e7e0b16747661a39d03dd6f7 100644 (file)
@@ -56,11 +56,17 @@ ALTOSLIB_CLASS=\
 ALTOSUILIB_CLASS=\
        altosuilib_$(ALTOSUILIB_VERSION).jar
 
+if MULTI_ARCH
+LIBALTOS_LINUX=libaltos32.so libaltos64.so
+else
+LIBALTOS_LINUX=libaltos.so
+endif
+
 LIBALTOS= \
-       libaltos32.so \
-       libaltos64.so \
+       $(LIBALTOS_LINUX) \
        libaltos.dylib \
-       altos.dll
+       altos.dll \
+       altos64.dll
 
 desktopdir = $(datadir)/applications
 desktop_file = altusmetrum-altosui.desktop
@@ -126,10 +132,12 @@ FIRMWARE_TELEMINI_1_0=$(top_srcdir)/src/telemini-v1.0/telemini-v1.0-$(VERSION).i
 FIRMWARE_TELEMINI=$(FIRMWARE_TELEMINI_1_0)
 
 FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx
-FIRMWARE_TBT=$(FIRMWARE_TBT_1_0)
+FIRMWARE_TBT_3_0=$(top_srcdir)/src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx
+FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) $(FIRMWARE_TBT_3_0)
 
 FIRMWARE_TMEGA_1_0=$(top_srcdir)/src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx
-FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0)
+FIRMWARE_TMEGA_2_0=$(top_srcdir)/src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx
+FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0)
 
 FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx
 FIRMWARE_EMINI=$(FIRMWARE_EMINI_1_0)
@@ -161,7 +169,7 @@ WINDOWS_DIST=Altos-Windows-$(VERSION_DASH).exe
 
 FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
 
-LINUX_LIBS=libaltos32.so libaltos64.so
+LINUX_LIBS=$(LIBALTOS_LINUX)
 
 LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
 LINUX_EXTRA=altosui-fat
@@ -176,7 +184,8 @@ all-local: classes/altosui $(JAR) altosui altosui-test altosui-jdb
 
 clean-local:
        -rm -rf classes $(JAR) $(FATJAR) \
-               $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) windows $(WINDOWS_DIST) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) \
+               Altos-Linux-*.tar.bz2 Altos-Linux-*.sh Altos-Mac-*.dmg Altos-Windows-*.exe \
+               windows altoslib_*.jar altosuilib_*.jar $(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 *.desktop
 
@@ -267,6 +276,10 @@ altosui-jdb: Makefile
        echo 'exec jdb -classpath "classes:./*:../libaltos:$(FREETTS)/freetts.jar:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" altosui/AltosUI "$$@"' >> $@
        chmod +x $@
 
+libaltos.so: build-libaltos
+       -rm -f "$@"
+       $(LN_S) ../libaltos/.libs/"$@" .
+
 libaltos32.so: build-libaltos
        -rm -f "$@"
        $(LN_S) ../libaltos/.libs/"$@" .
@@ -291,6 +304,8 @@ altos64.dll: ../libaltos/altos64.dll
 
 ../libaltos/.libs/libaltos32.so: build-libaltos
 
+../libaltos/.libs/libaltos.so: build-libaltos
+
 ../libaltos/altos.dll: build-altos-dll
 
 ../libaltos/altos64.dll: build-altos64-dll
index 8c2e0d753fecc27f3cea9c67677385803b4ea824..df00bcee7e6861ad959bc936b1d77d26e5792d94 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosBTDevice extends altos_bt_device implements AltosDevice {
 
index ea29b0556939402c08445a5e2fdd7d8c4e2c7218..75ca18ed11738695dbefcdf889fee92b3f9a07e1 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.util.*;
 import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
        AltosBTDevice   current;
index 8ae11f679139486e34ce9c5843392cbac2b2fb9d..11b0d48dfd06d312778804b6acd5944e43dfbd86 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosBTKnown implements Iterable<AltosBTDevice> {
        LinkedList<AltosBTDevice>       devices = new LinkedList<AltosBTDevice>();
index e6a1ef6446c464cabcbcd772b95551b201783f55..bdb35d499bb62fa597e782399f7390e188226904 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
@@ -23,7 +23,7 @@ import javax.swing.*;
 import javax.swing.plaf.basic.*;
 import java.util.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> {
        LinkedBlockingQueue<AltosBTDevice> found_devices;
index 3846d3fd19ec9c1f119c07b33f97a7e3cf491f37..9d67ce8dacbbf4226cfe2663b7f84a7d2d9494bc 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosCSVUI
        extends AltosUIDialog
index 5a689a396f3d51a672fa940b9925575cd724eabe..b8477ecd82f6b07e82978311c8697d251a69946e 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.text.*;
 import java.awt.event.*;
 import javax.swing.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class AltosEditFreqUI extends AltosUIDialog implements ActionListener {
        Frame           frame;
index 3dfadfe138f27b4965226bc3520bc17554162b63..f1a5610e5a57108d9379c04d756f95afab2a38eb 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import java.io.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosDataChooser extends JFileChooser {
        JFrame  frame;
index dbaf2e36be273f4f2e4f373a5a867bc8dd253054..f51c76c2e0e34d2abea602dda82afb9b54162056 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import libaltosJNI.*;
 
index 21a8a23f6a28292d76714db0ee3a18fb993aff64..0cd658c0f57385933912b5a9d9be6dbf5989759d 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
 import java.awt.*;
index 75c3e69142acd09d27309cf63cf66128ae3f9682..7d1e361816c60eb7f307946dad680a34f1ea5ca6 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
 import java.awt.*;
index 968a0b75fbb971d9341401e5ac6958a01f9d0ec3..ba48ab820b4c4e209910ad4172fa5e3a7b1c0a63 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import javax.swing.*;
 import java.io.*;
 import java.text.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosDisplayThread extends Thread {
 
index 442cee889676917015d8c4b5cc74f89cc6d4a528..026b5da497bf2f7b9987503eb5b5d75135de96db 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosEepromDelete implements Runnable {
        AltosEepromList         flights;
index 5f83e6f4b3620dc605b3b6618ea728a04fbcf2ee..a4b62ff0a18d09c95513f8375dc630c190153391 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosEepromManage implements ActionListener {
 
index 508e3e3f5938bb16c263c0b2643e8753665c326e..7fe5be1837dd51d71ee94f07aef9275a99f6b7e4 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
index 905780a5bdabb264bfcd00cb52cf52ddbd3098ed..9492bc311d39b4570ba221fd1cdf20568f404dab 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor {
        JFrame          owner;
index 67bff7105189f3d9ddb56223ae70ae7a054afed8..28b3982b8a2c4cfa9060924e2b22959c0c2f9ade 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
 import javax.swing.border.*;
 import java.awt.*;
 import java.awt.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class AltosEepromItem implements ActionListener {
        AltosEepromLog  log;
index 07f04c3e828a091c760f835f836619771dcf6226..6574bd9913175b6d76185d088b6b964615a40495 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
@@ -23,7 +23,7 @@ import javax.swing.*;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import java.io.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosFlashUI
        extends AltosUIDialog
index 9a4307430cb61637106cb4456d66d5896647121e..ca3728a557268f969fdabd6ef1521536bf195fa6 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.table.*;
 
index 6171f61ac5d3c4ae1b8d8d518146cdc3ff50a85f..c0f1ecb6aebebcf603fc74209248bb150924178f 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import javax.swing.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosFlightStatsTable extends JComponent implements AltosFontListener {
        GridBagLayout   layout;
index a4334cc6b8211553584b7cd09f39dad0a4ff8111..ad843f7fe86e0376787ec1218a169e8f9eae4387 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
index e4a065c6d000f89ec60fe2cfc65862dd65b0efc8..fcb883886f553c690932e16792bb8a1693bc2846 100644 (file)
@@ -15,9 +15,9 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosGraphDataPoint implements AltosUIDataPoint {
 
index 673d1de929ca5b47238d04932ded82e815d41f66..3e3bf479a70435a09d1f2dc43f8dbaf2b50e49f0 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.lang.*;
 import java.io.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class AltosGraphIterator implements Iterator<AltosUIDataPoint> {
        AltosGraphDataSet       dataSet;
index 3833b37ae38e13e16933894dd1b5c56dd04260bc..3509f65da60400f9b5e4623602cae9c8cb24f6f0 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.table.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosInfoTable extends JTable implements AltosFlightDisplay, HierarchyListener {
        private AltosFlightInfoTableModel model;
index 07485cc4a06daf4a4f3b840d9141a058e4f751a0..b1dc32209a527c9d585b5ed9eaeba7e684124192 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
 
index f445199c7bac5d2f5909951c8cb003ae507f6c75..34293bb49ce3c13a99f91c64009dc80a6c3be67f 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import javax.swing.*;
index 06ba41886172ef4692be0d786e6b272e58d6c8a2..8eb4594aa02174aa2bceed2d1bf8eb6bf717654f 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 public interface AltosPositionListener {
        public void position_changed(int position);
index 3a5188f832815723071cedadc106eda746534177..33686b4f53f0fdf405d7271b150595bfad97779f 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosRomconfigUI
        extends AltosUIDialog
index 1d176e821e913d6dd334425c9cc8c14b8f8b183b..ee68fbc94754951de52234307f0c2bcc66353543 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
@@ -25,7 +25,7 @@ import java.io.*;
 import java.util.*;
 import java.text.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class AltosScanResult {
        String          callsign;
index 85ab4654c013922d0cf7d485d66eb5f85e0f20a2..1bf4dbbee721df5ea9d6dc208f88b4ceeaaa3898 100644 (file)
  * Deal with TeleDongle on a serial port
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.*;
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 import libaltosJNI.*;
 
 /*
index af7edb65845799e9c35dd7ae9dcc54893f0f4055..cba5cac0c19e6891b885554b53f3c03c4d5dadd1 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 public class AltosSerialInUseException extends Exception {
        public AltosDevice      device;
index e307874a4ade4842ef3a246ae8cc870e4c048df8..8ec8a11488876b22816ebcb09ec38149a220f8de 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
@@ -48,7 +48,7 @@ public class AltosUIAxis extends NumberAxis {
        public final static int axis_default = axis_include_zero;
 
        public void set_units() {
-               String u = units.show_units();
+               String u = units.parse_units();
                if (u != null)
                        setLabel(String.format("%s (%s)", label, u));
                else
index 89114c7eb654423115636a1c2be6f681462baf20..de07047354af50cac2c8e469eebea4809cde3a3a 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
 import java.beans.*;
 import javax.swing.*;
 import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 class DelegatingRenderer implements ListCellRenderer<Object> {
 
index 585289ed63732d4ef27992c661d231da16cbbfc5..44668dff64b2e275c864399ebcbb7ce63da6f1c6 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 public class AltosUIDataMissing extends Exception {
        public int      id;
index 7feb6d8ee7906a19d2f91ff902f9832d1a1b3a73..7d905b4623d49e3a6809e218e0ee33be9b0a2fbd 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 public interface AltosUIDataPoint {
        public abstract double x() throws AltosUIDataMissing;
index 82809aa539cca55fb45e95371d2b81c285906f76..8c7bcf03af62b2be351993c7fe5e04fb4ae8f2b6 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 public interface AltosUIDataSet {
        public abstract String name();
index a262597517e8953a95f6dca4c7a68e477a5f9329..2fd464984312fcb949fd97da19f8b0dbf945da5b 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
index 7bb80bc100d127ead14be817e832ba26197fc651..74de4bf556e769ee59aa15f0d2d3bda128cf6f05 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
@@ -23,7 +23,7 @@ import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
index e098b76f9492a31bba56ed9d2508027d0ec49c6f..1e32445005eaf0741ddf1b580de89dca10b785db 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public abstract class AltosUIFlightTab extends JComponent implements AltosFlightDisplay, HierarchyListener {
        public GridBagLayout    layout;
index 295225d604366ec4a92e871a57a257d51af9e8c0..ac440190b69e8ec3c47a38f8a963a5599589b20a 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
@@ -23,8 +23,13 @@ import javax.swing.*;
 import java.util.*;
 
 class AltosUIFrameListener extends WindowAdapter {
+       @Override
        public void windowClosing (WindowEvent e) {
-               AltosUIPreferences.unregister_ui_listener((AltosUIFrame) e.getWindow());
+               AltosUIFrame frame = (AltosUIFrame) e.getWindow();
+               AltosUIPreferences.unregister_ui_listener(frame);
+               AltosUIFrame.frame_closed();
+               frame.setVisible(false);
+               frame.dispose();
        }
 }
 
@@ -263,10 +268,23 @@ public class AltosUIFrame extends JFrame implements AltosUIListener, AltosPositi
                return constraints(x, width, GridBagConstraints.NONE);
        }
 
+       static int open_frames;
+
+       public static void frame_opened() {
+               ++open_frames;
+       }
+
+       public static void frame_closed() {
+               --open_frames;
+               if (open_frames == 0)
+                       System.exit(0);
+       }
+
        void init() {
                AltosUIPreferences.register_ui_listener(this);
                AltosUIPreferences.register_position_listener(this);
                position = AltosUIPreferences.position();
+               frame_opened();
                addWindowListener(new AltosUIFrameListener());
 
                /* Try to make menus live in the menu bar like regular Mac apps */
index 7d49e6928bf856e1636fc49f6094b3d19a00f87f..c770f65458bf46328a61f25077022e6c20fdccb2 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosUIFreqList extends JComboBox<AltosFrequency> {
 
index dca12854dc2b60b9d070ff7ce9d92a1bb765da58..9c2577637caa59fa0ecd12a8d5e5942686747a97 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
index a30609fd5abdc7a4b1dc75e80efcac123fa6c63d..1acf5c4653ca4114920f4be1564d465892e37506 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
index 1907e15574b71543c00efd5f3ba2aea781a26a82..700e095f97c9dcbe5ca96e0a1c734d229eb60479 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
 
 import javax.swing.*;
 import javax.imageio.ImageIO;
index 819123a78f93470fc335aa5b76ca6d341dd72e73..a91a7e660dc4d859c5226ca63b08342610a25015 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public abstract class AltosUIIndicator implements AltosFontListener, AltosUnitsListener {
        JLabel          label;
index ff9fd72ad378bc4bdbc2192c29d714eaa93aa7cb..5eefdc98ecfd78c84127bdce18faadd85cbcdac5 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import libaltosJNI.*;
 
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosUILib extends AltosLib {
 
index 98d7452fcbd9b451ba41cd2823088cc917ed67b4..581711adc58dbe5e07eeb0866c70de889c204aee 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 public interface AltosUIListener {
        public void ui_changed(String look_and_feel);
diff --git a/altosuilib/AltosUIMap.java b/altosuilib/AltosUIMap.java
new file mode 100644 (file)
index 0000000..8c90bcd
--- /dev/null
@@ -0,0 +1,537 @@
+/*
+ * 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 org.altusmetrum.altosuilib_11;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import javax.swing.*;
+import java.io.*;
+import java.lang.Math;
+import java.awt.geom.*;
+import java.util.*;
+import java.util.concurrent.*;
+import javax.imageio.*;
+import org.altusmetrum.altoslib_11.*;
+
+public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosMapInterface {
+
+       AltosMap        map;
+       Graphics2D      g;
+       Font            tile_font;
+       Font            line_font;
+
+       static Point2D.Double point2d(AltosPointDouble pt) {
+               return new Point2D.Double(pt.x, pt.y);
+       }
+
+       static final AltosPointDouble point_double(Point pt) {
+               return new AltosPointDouble(pt.x, pt.y);
+       }
+
+       class MapMark extends AltosMapMark {
+               public void paint(AltosMapTransform t) {
+                       AltosPointDouble pt = t.screen(lat_lon);
+
+                       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                          RenderingHints.VALUE_ANTIALIAS_ON);
+                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+
+                       if (0 <= state && state < AltosUIMap.stateColors.length)
+                               g.setColor(AltosUIMap.stateColors[state]);
+                       else
+                               g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
+
+                       g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
+                       g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
+                       g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
+               }
+
+               MapMark(double lat, double lon, int state) {
+                       super(lat, lon, state);
+               }
+       }
+
+       class MapView extends JComponent implements MouseMotionListener, MouseListener, ComponentListener, MouseWheelListener {
+
+               private VolatileImage create_back_buffer() {
+                       return getGraphicsConfiguration().createCompatibleVolatileImage(getWidth(), getHeight());
+               }
+
+               private void do_paint(Graphics my_g) {
+                       g = (Graphics2D) my_g;
+
+                       map.paint();
+               }
+
+               public void paint(Graphics my_g) {
+                       VolatileImage   back_buffer = create_back_buffer();
+
+                       Graphics2D      top_g = (Graphics2D) my_g;
+
+                       do {
+                               GraphicsConfiguration gc = getGraphicsConfiguration();
+                               int code = back_buffer.validate(gc);
+                               if (code == VolatileImage.IMAGE_INCOMPATIBLE)
+                                       back_buffer = create_back_buffer();
+
+                               Graphics g_back = back_buffer.getGraphics();
+                               g_back.setClip(top_g.getClip());
+                               do_paint(g_back);
+                               g_back.dispose();
+
+                               top_g.drawImage(back_buffer, 0, 0, this);
+                       } while (back_buffer.contentsLost());
+                       back_buffer.flush();
+               }
+
+               public void repaint(AltosRectangle damage) {
+                       repaint(damage.x, damage.y, damage.width, damage.height);
+               }
+
+               private boolean is_drag_event(MouseEvent e) {
+                       return e.getModifiers() == InputEvent.BUTTON1_MASK;
+               }
+
+               /* MouseMotionListener methods */
+
+               public void mouseDragged(MouseEvent e) {
+                       map.touch_continue(e.getPoint().x, e.getPoint().y, is_drag_event(e));
+               }
+
+               public void mouseMoved(MouseEvent e) {
+               }
+
+               /* MouseListener methods */
+               public void mouseClicked(MouseEvent e) {
+               }
+
+               public void mouseEntered(MouseEvent e) {
+               }
+
+               public void mouseExited(MouseEvent e) {
+               }
+
+               public void mousePressed(MouseEvent e) {
+                       map.touch_start(e.getPoint().x, e.getPoint().y, is_drag_event(e));
+               }
+
+               public void mouseReleased(MouseEvent e) {
+               }
+
+               /* MouseWheelListener methods */
+
+               public void mouseWheelMoved(MouseWheelEvent e) {
+                       int     zoom_change = e.getWheelRotation();
+
+                       map.set_zoom_centre(map.get_zoom() - zoom_change, new AltosPointInt(e.getPoint().x, e.getPoint().y));
+               }
+
+               /* ComponentListener methods */
+
+               public void componentHidden(ComponentEvent e) {
+               }
+
+               public void componentMoved(ComponentEvent e) {
+               }
+
+               public void componentResized(ComponentEvent e) {
+                       map.set_transform();
+               }
+
+               public void componentShown(ComponentEvent e) {
+                       map.set_transform();
+               }
+
+               MapView() {
+                       addComponentListener(this);
+                       addMouseMotionListener(this);
+                       addMouseListener(this);
+                       addMouseWheelListener(this);
+               }
+       }
+
+       class MapLine extends AltosMapLine {
+
+               public void paint(AltosMapTransform t) {
+
+                       if (start == null || end == null)
+                               return;
+
+                       g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+                       Line2D.Double line = new Line2D.Double(point2d(t.screen(start)),
+                                                              point2d(t.screen(end)));
+
+                       g.setColor(Color.WHITE);
+                       g.setStroke(new BasicStroke(stroke_width+4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+                       g.draw(line);
+
+                       g.setColor(Color.BLUE);
+                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+                       g.draw(line);
+
+                       String  message = line_dist();
+                       Rectangle2D     bounds;
+                       bounds = line_font.getStringBounds(message, g.getFontRenderContext());
+
+                       float x = (float) line.x1;
+                       float y = (float) line.y1 + (float) bounds.getHeight() / 2.0f;
+
+                       if (line.x1 < line.x2) {
+                               x -= (float) bounds.getWidth() + 2.0f;
+                       } else {
+                               x += 2.0f;
+                       }
+
+                       g.setFont(line_font);
+                       g.setColor(Color.WHITE);
+                       for (int dy = -2; dy <= 2; dy += 2)
+                               for (int dx = -2; dx <= 2; dx += 2)
+                                       g.drawString(message, x + dx, y + dy);
+                       g.setColor(Color.BLUE);
+                       g.drawString(message, x, y);
+               }
+
+               public MapLine() {
+               }
+       }
+
+       class MapPath extends AltosMapPath {
+               public void paint(AltosMapTransform t) {
+                       Point2D.Double  prev = null;
+
+                       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                          RenderingHints.VALUE_ANTIALIAS_ON);
+                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+
+                       for (AltosMapPathPoint point : points) {
+                               Point2D.Double  cur = point2d(t.screen(point.lat_lon));
+                               if (prev != null) {
+                                       Line2D.Double   line = new Line2D.Double (prev, cur);
+                                       Rectangle       bounds = line.getBounds();
+
+                                       if (g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height)) {
+                                               if (0 <= point.state && point.state < AltosUIMap.stateColors.length)
+                                                       g.setColor(AltosUIMap.stateColors[point.state]);
+                                               else
+                                                       g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
+
+                                               g.draw(line);
+                                       }
+                               }
+                               prev = cur;
+                       }
+               }
+       }
+
+       class MapTile extends AltosMapTile {
+               public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+                       super(cache, upper_left, center, zoom, maptype, px_size, scale);
+               }
+
+               public void paint(AltosMapTransform t) {
+
+                       AltosPointDouble        point_double = t.screen(upper_left);
+                       Point                   point = new Point((int) (point_double.x + 0.5),
+                                                                 (int) (point_double.y + 0.5));
+
+                       if (!g.hitClip(point.x, point.y, px_size, px_size))
+                               return;
+
+                       AltosImage      altos_image = get_image();
+                       AltosUIImage    ui_image = (AltosUIImage) altos_image;
+                       Image           image = null;
+
+                       if (ui_image != null)
+                               image = ui_image.image;
+
+                       if (image != null) {
+                               g.drawImage(image, point.x, point.y, null);
+                       } else {
+                               g.setColor(Color.GRAY);
+                               g.fillRect(point.x, point.y, px_size, px_size);
+
+                               if (t.has_location()) {
+                                       String  message = null;
+                                       switch (status) {
+                                       case AltosMapTile.fetching:
+                                               message = "Fetching...";
+                                               break;
+                                       case AltosMapTile.bad_request:
+                                               message = "Internal error";
+                                               break;
+                                       case AltosMapTile.failed:
+                                               message = "Network error, check connection";
+                                               break;
+                                       case AltosMapTile.forbidden:
+                                               message = "Too many requests, try later";
+                                               break;
+                                       }
+                                       if (message != null && tile_font != null) {
+                                               g.setFont(tile_font);
+                                               g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+                                               Rectangle2D bounds = tile_font.getStringBounds(message, g.getFontRenderContext());
+
+                                               float x = px_size / 2.0f;
+                                               float y = px_size / 2.0f;
+                                               x = x - (float) bounds.getWidth() / 2.0f;
+                                               y = y + (float) bounds.getHeight() / 2.0f;
+                                               g.setColor(Color.BLACK);
+                                               g.drawString(message, (float) point_double.x + x, (float) point_double.y + y);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public static final 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
+               Color.BLACK,  // invalid
+               Color.CYAN,   // stateless
+       };
+
+       /* AltosMapInterface functions */
+
+       public AltosMapPath new_path() {
+               return new MapPath();
+       }
+
+       public AltosMapLine new_line() {
+               return new MapLine();
+       }
+
+       public AltosImage load_image(File file) throws Exception {
+               return new AltosUIImage(ImageIO.read(file));
+       }
+
+       public AltosMapMark new_mark(double lat, double lon, int state) {
+               return new MapMark(lat, lon, state);
+       }
+
+       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               return new MapTile(cache, upper_left, center, zoom, maptype, px_size, scale);
+       }
+
+       public int width() {
+               return view.getWidth();
+       }
+
+       public int height() {
+               return view.getHeight();
+       }
+
+       public void repaint() {
+               view.repaint();
+       }
+
+       public void repaint(AltosRectangle damage) {
+               view.repaint(damage);
+       }
+
+       public void set_zoom_label(String label) {
+               zoom_label.setText(label);
+       }
+
+       public void select_object(AltosLatLon latlon) {
+               debug("select at %f,%f\n", latlon.lat, latlon.lon);
+       }
+
+       public void debug(String format, Object ... arguments) {
+               if (AltosUIPreferences.serial_debug())
+                       System.out.printf(format, arguments);
+       }
+
+
+       /* AltosFlightDisplay interface */
+
+       public void set_font() {
+               tile_font = AltosUILib.value_font;
+               line_font = AltosUILib.status_font;
+       }
+
+       public void font_size_changed(int font_size) {
+               set_font();
+               repaint();
+       }
+
+       public void units_changed(boolean imperial_units) {
+               repaint();
+       }
+
+       JLabel  zoom_label;
+
+       public void set_maptype(int type) {
+               map.set_maptype(type);
+               maptype_combo.setSelectedIndex(type);
+       }
+
+       /* AltosUIMapPreload functions */
+
+       public void set_zoom(int zoom) {
+               map.set_zoom(zoom);
+       }
+
+       public void add_mark(double lat, double lon, int status) {
+               map.add_mark(lat, lon, status);
+       }
+
+       public void clear_marks() {
+               map.clear_marks();
+       }
+
+       /* AltosFlightDisplay interface */
+       public void reset() {
+               // nothing
+       }
+
+       public void show(AltosState state, AltosListenerState listener_state) {
+               map.show(state, listener_state);
+       }
+
+       public String getName() {
+               return "Map";
+       }
+
+       /* AltosGraphUI interface */
+       public void centre(AltosState state) {
+               map.centre(state);
+       }
+
+       /* internal layout bits */
+       private GridBagLayout layout = new GridBagLayout();
+
+       JComboBox<String>       maptype_combo;
+
+       MapView view;
+
+       public AltosUIMap() {
+
+               set_font();
+
+               view = new MapView();
+
+               view.setPreferredSize(new Dimension(500,500));
+               view.setVisible(true);
+               view.setEnabled(true);
+
+               GridBagLayout   my_layout = new GridBagLayout();
+
+               setLayout(my_layout);
+
+               GridBagConstraints c = new GridBagConstraints();
+               c.anchor = GridBagConstraints.CENTER;
+               c.fill = GridBagConstraints.BOTH;
+               c.gridx = 0;
+               c.gridy = 0;
+               c.gridwidth = 1;
+               c.gridheight = 10;
+               c.weightx = 1;
+               c.weighty = 1;
+               add(view, c);
+
+               int     y = 0;
+
+               zoom_label = new JLabel("", JLabel.CENTER);
+
+               c = new GridBagConstraints();
+               c.anchor = GridBagConstraints.CENTER;
+               c.fill = GridBagConstraints.HORIZONTAL;
+               c.gridx = 1;
+               c.gridy = y++;
+               c.weightx = 0;
+               c.weighty = 0;
+               add(zoom_label, c);
+
+               JButton zoom_reset = new JButton("0");
+               zoom_reset.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       map.set_zoom(map.default_zoom);
+                               }
+                       });
+
+               c = new GridBagConstraints();
+               c.anchor = GridBagConstraints.CENTER;
+               c.fill = GridBagConstraints.HORIZONTAL;
+               c.gridx = 1;
+               c.gridy = y++;
+               c.weightx = 0;
+               c.weighty = 0;
+               add(zoom_reset, c);
+
+               JButton zoom_in = new JButton("+");
+               zoom_in.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       map.set_zoom(map.get_zoom() + 1);
+                               }
+                       });
+
+               c = new GridBagConstraints();
+               c.anchor = GridBagConstraints.CENTER;
+               c.fill = GridBagConstraints.HORIZONTAL;
+               c.gridx = 1;
+               c.gridy = y++;
+               c.weightx = 0;
+               c.weighty = 0;
+               add(zoom_in, c);
+
+               JButton zoom_out = new JButton("-");
+               zoom_out.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       map.set_zoom(map.get_zoom() - 1);
+                               }
+                       });
+               c = new GridBagConstraints();
+               c.anchor = GridBagConstraints.CENTER;
+               c.fill = GridBagConstraints.HORIZONTAL;
+               c.gridx = 1;
+               c.gridy = y++;
+               c.weightx = 0;
+               c.weighty = 0;
+               add(zoom_out, c);
+
+               maptype_combo = new JComboBox<String>(map.maptype_labels);
+
+               maptype_combo.setEditable(false);
+               maptype_combo.setMaximumRowCount(maptype_combo.getItemCount());
+               maptype_combo.addItemListener(new ItemListener() {
+                               public void itemStateChanged(ItemEvent e) {
+                                       map.set_maptype(maptype_combo.getSelectedIndex());
+                               }
+                       });
+
+               c = new GridBagConstraints();
+               c.anchor = GridBagConstraints.CENTER;
+               c.fill = GridBagConstraints.HORIZONTAL;
+               c.gridx = 1;
+               c.gridy = y++;
+               c.weightx = 0;
+               c.weighty = 0;
+               add(maptype_combo, c);
+
+               map = new AltosMap(this);
+       }
+}
diff --git a/altosuilib/AltosUIMapNew.java b/altosuilib/AltosUIMapNew.java
deleted file mode 100644 (file)
index a90e8c9..0000000
+++ /dev/null
@@ -1,536 +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 org.altusmetrum.altosuilib_10;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import javax.swing.*;
-import java.io.*;
-import java.lang.Math;
-import java.awt.geom.*;
-import java.util.*;
-import java.util.concurrent.*;
-import javax.imageio.*;
-import org.altusmetrum.altoslib_10.*;
-
-public class AltosUIMapNew extends JComponent implements AltosFlightDisplay, AltosMapInterface {
-
-       AltosMap        map;
-       Graphics2D      g;
-       Font            tile_font;
-       Font            line_font;
-
-       static Point2D.Double point2d(AltosPointDouble pt) {
-               return new Point2D.Double(pt.x, pt.y);
-       }
-
-       static final AltosPointDouble point_double(Point pt) {
-               return new AltosPointDouble(pt.x, pt.y);
-       }
-
-       class MapMark extends AltosMapMark {
-               public void paint(AltosMapTransform t) {
-                       AltosPointDouble pt = t.screen(lat_lon);
-
-                       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                                          RenderingHints.VALUE_ANTIALIAS_ON);
-                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-
-                       if (0 <= state && state < AltosUIMapNew.stateColors.length)
-                               g.setColor(AltosUIMapNew.stateColors[state]);
-                       else
-                               g.setColor(AltosUIMapNew.stateColors[AltosLib.ao_flight_invalid]);
-
-                       g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
-                       g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
-                       g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
-               }
-
-               MapMark(double lat, double lon, int state) {
-                       super(lat, lon, state);
-               }
-       }
-
-       class MapView extends JComponent implements MouseMotionListener, MouseListener, ComponentListener, MouseWheelListener {
-
-               private VolatileImage create_back_buffer() {
-                       return getGraphicsConfiguration().createCompatibleVolatileImage(getWidth(), getHeight());
-               }
-
-               private void do_paint(Graphics my_g) {
-                       g = (Graphics2D) my_g;
-
-                       map.paint();
-               }
-
-               public void paint(Graphics my_g) {
-                       VolatileImage   back_buffer = create_back_buffer();
-
-                       Graphics2D      top_g = (Graphics2D) my_g;
-
-                       do {
-                               GraphicsConfiguration gc = getGraphicsConfiguration();
-                               int code = back_buffer.validate(gc);
-                               if (code == VolatileImage.IMAGE_INCOMPATIBLE)
-                                       back_buffer = create_back_buffer();
-
-                               Graphics g_back = back_buffer.getGraphics();
-                               g_back.setClip(top_g.getClip());
-                               do_paint(g_back);
-                               g_back.dispose();
-
-                               top_g.drawImage(back_buffer, 0, 0, this);
-                       } while (back_buffer.contentsLost());
-                       back_buffer.flush();
-               }
-
-               public void repaint(AltosRectangle damage) {
-                       repaint(damage.x, damage.y, damage.width, damage.height);
-               }
-
-               private boolean is_drag_event(MouseEvent e) {
-                       return e.getModifiers() == InputEvent.BUTTON1_MASK;
-               }
-
-               /* MouseMotionListener methods */
-
-               public void mouseDragged(MouseEvent e) {
-                       map.touch_continue(e.getPoint().x, e.getPoint().y, is_drag_event(e));
-               }
-
-               public void mouseMoved(MouseEvent e) {
-               }
-
-               /* MouseListener methods */
-               public void mouseClicked(MouseEvent e) {
-               }
-
-               public void mouseEntered(MouseEvent e) {
-               }
-
-               public void mouseExited(MouseEvent e) {
-               }
-
-               public void mousePressed(MouseEvent e) {
-                       map.touch_start(e.getPoint().x, e.getPoint().y, is_drag_event(e));
-               }
-
-               public void mouseReleased(MouseEvent e) {
-               }
-
-               /* MouseWheelListener methods */
-
-               public void mouseWheelMoved(MouseWheelEvent e) {
-                       int     zoom_change = e.getWheelRotation();
-
-                       map.set_zoom_centre(map.get_zoom() - zoom_change, new AltosPointInt(e.getPoint().x, e.getPoint().y));
-               }
-
-               /* ComponentListener methods */
-
-               public void componentHidden(ComponentEvent e) {
-               }
-
-               public void componentMoved(ComponentEvent e) {
-               }
-
-               public void componentResized(ComponentEvent e) {
-                       map.set_transform();
-               }
-
-               public void componentShown(ComponentEvent e) {
-                       map.set_transform();
-               }
-
-               MapView() {
-                       addComponentListener(this);
-                       addMouseMotionListener(this);
-                       addMouseListener(this);
-                       addMouseWheelListener(this);
-               }
-       }
-
-       class MapLine extends AltosMapLine {
-
-               public void paint(AltosMapTransform t) {
-
-                       if (start == null || end == null)
-                               return;
-
-                       g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-
-                       Line2D.Double line = new Line2D.Double(point2d(t.screen(start)),
-                                                              point2d(t.screen(end)));
-
-                       g.setColor(Color.WHITE);
-                       g.setStroke(new BasicStroke(stroke_width+4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-                       g.draw(line);
-
-                       g.setColor(Color.BLUE);
-                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-                       g.draw(line);
-
-                       String  message = line_dist();
-                       Rectangle2D     bounds;
-                       bounds = line_font.getStringBounds(message, g.getFontRenderContext());
-
-                       float x = (float) line.x1;
-                       float y = (float) line.y1 + (float) bounds.getHeight() / 2.0f;
-
-                       if (line.x1 < line.x2) {
-                               x -= (float) bounds.getWidth() + 2.0f;
-                       } else {
-                               x += 2.0f;
-                       }
-
-                       g.setFont(line_font);
-                       g.setColor(Color.WHITE);
-                       for (int dy = -2; dy <= 2; dy += 2)
-                               for (int dx = -2; dx <= 2; dx += 2)
-                                       g.drawString(message, x + dx, y + dy);
-                       g.setColor(Color.BLUE);
-                       g.drawString(message, x, y);
-               }
-
-               public MapLine() {
-               }
-       }
-
-       class MapPath extends AltosMapPath {
-               public void paint(AltosMapTransform t) {
-                       Point2D.Double  prev = null;
-
-                       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                                          RenderingHints.VALUE_ANTIALIAS_ON);
-                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-
-                       for (AltosMapPathPoint point : points) {
-                               Point2D.Double  cur = point2d(t.screen(point.lat_lon));
-                               if (prev != null) {
-                                       Line2D.Double   line = new Line2D.Double (prev, cur);
-                                       Rectangle       bounds = line.getBounds();
-
-                                       if (g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height)) {
-                                               if (0 <= point.state && point.state < AltosUIMapNew.stateColors.length)
-                                                       g.setColor(AltosUIMapNew.stateColors[point.state]);
-                                               else
-                                                       g.setColor(AltosUIMapNew.stateColors[AltosLib.ao_flight_invalid]);
-
-                                               g.draw(line);
-                                       }
-                               }
-                               prev = cur;
-                       }
-               }
-       }
-
-       class MapTile extends AltosMapTile {
-               public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(cache, upper_left, center, zoom, maptype, px_size);
-               }
-
-               public void paint(AltosMapTransform t) {
-
-                       AltosPointDouble        point_double = t.screen(upper_left);
-                       Point                   point = new Point((int) (point_double.x + 0.5),
-                                                                 (int) (point_double.y + 0.5));
-
-                       if (!g.hitClip(point.x, point.y, px_size, px_size))
-                               return;
-
-                       AltosImage      altos_image = get_image();
-                       AltosUIImage    ui_image = (AltosUIImage) altos_image;
-                       Image           image = null;
-
-                       if (ui_image != null)
-                               image = ui_image.image;
-
-                       if (image != null) {
-                               g.drawImage(image, point.x, point.y, null);
-                       } else {
-                               g.setColor(Color.GRAY);
-                               g.fillRect(point.x, point.y, px_size, px_size);
-
-                               if (t.has_location()) {
-                                       String  message = null;
-                                       switch (status) {
-                                       case AltosMapTile.fetching:
-                                               message = "Fetching...";
-                                               break;
-                                       case AltosMapTile.bad_request:
-                                               message = "Internal error";
-                                               break;
-                                       case AltosMapTile.failed:
-                                               message = "Network error, check connection";
-                                               break;
-                                       case AltosMapTile.forbidden:
-                                               message = "Too many requests, try later";
-                                               break;
-                                       }
-                                       if (message != null && tile_font != null) {
-                                               g.setFont(tile_font);
-                                               g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-                                               Rectangle2D bounds = tile_font.getStringBounds(message, g.getFontRenderContext());
-
-                                               float x = px_size / 2.0f;
-                                               float y = px_size / 2.0f;
-                                               x = x - (float) bounds.getWidth() / 2.0f;
-                                               y = y + (float) bounds.getHeight() / 2.0f;
-                                               g.setColor(Color.BLACK);
-                                               g.drawString(message, (float) point_double.x + x, (float) point_double.y + y);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       public static final 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
-               Color.BLACK,  // invalid
-               Color.CYAN,   // stateless
-       };
-
-       /* AltosMapInterface functions */
-
-       public AltosMapPath new_path() {
-               return new MapPath();
-       }
-
-       public AltosMapLine new_line() {
-               return new MapLine();
-       }
-
-       public AltosImage load_image(File file) throws Exception {
-               return new AltosUIImage(ImageIO.read(file));
-       }
-
-       public AltosMapMark new_mark(double lat, double lon, int state) {
-               return new MapMark(lat, lon, state);
-       }
-
-       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new MapTile(cache, upper_left, center, zoom, maptype, px_size);
-       }
-
-       public int width() {
-               return view.getWidth();
-       }
-
-       public int height() {
-               return view.getHeight();
-       }
-
-       public void repaint() {
-               view.repaint();
-       }
-
-       public void repaint(AltosRectangle damage) {
-               view.repaint(damage);
-       }
-
-       public void set_zoom_label(String label) {
-               zoom_label.setText(label);
-       }
-
-       public void select_object(AltosLatLon latlon) {
-               debug("select at %f,%f\n", latlon.lat, latlon.lon);
-       }
-
-       public void debug(String format, Object ... arguments) {
-               System.out.printf(format, arguments);
-       }
-
-
-       /* AltosFlightDisplay interface */
-
-       public void set_font() {
-               tile_font = AltosUILib.value_font;
-               line_font = AltosUILib.status_font;
-       }
-
-       public void font_size_changed(int font_size) {
-               set_font();
-               repaint();
-       }
-
-       public void units_changed(boolean imperial_units) {
-               repaint();
-       }
-
-       JLabel  zoom_label;
-
-       public void set_maptype(int type) {
-               map.set_maptype(type);
-               maptype_combo.setSelectedIndex(type);
-       }
-
-       /* AltosUIMapPreload functions */
-
-       public void set_zoom(int zoom) {
-               map.set_zoom(zoom);
-       }
-
-       public void add_mark(double lat, double lon, int status) {
-               map.add_mark(lat, lon, status);
-       }
-
-       public void clear_marks() {
-               map.clear_marks();
-       }
-
-       /* AltosFlightDisplay interface */
-       public void reset() {
-               // nothing
-       }
-
-       public void show(AltosState state, AltosListenerState listener_state) {
-               map.show(state, listener_state);
-       }
-
-       public String getName() {
-               return "Map";
-       }
-
-       /* AltosGraphUI interface */
-       public void centre(AltosState state) {
-               map.centre(state);
-       }
-
-       /* internal layout bits */
-       private GridBagLayout layout = new GridBagLayout();
-
-       JComboBox<String>       maptype_combo;
-
-       MapView view;
-
-       public AltosUIMapNew() {
-
-               set_font();
-
-               view = new MapView();
-
-               view.setPreferredSize(new Dimension(500,500));
-               view.setVisible(true);
-               view.setEnabled(true);
-
-               GridBagLayout   my_layout = new GridBagLayout();
-
-               setLayout(my_layout);
-
-               GridBagConstraints c = new GridBagConstraints();
-               c.anchor = GridBagConstraints.CENTER;
-               c.fill = GridBagConstraints.BOTH;
-               c.gridx = 0;
-               c.gridy = 0;
-               c.gridwidth = 1;
-               c.gridheight = 10;
-               c.weightx = 1;
-               c.weighty = 1;
-               add(view, c);
-
-               int     y = 0;
-
-               zoom_label = new JLabel("", JLabel.CENTER);
-
-               c = new GridBagConstraints();
-               c.anchor = GridBagConstraints.CENTER;
-               c.fill = GridBagConstraints.HORIZONTAL;
-               c.gridx = 1;
-               c.gridy = y++;
-               c.weightx = 0;
-               c.weighty = 0;
-               add(zoom_label, c);
-
-               JButton zoom_reset = new JButton("0");
-               zoom_reset.addActionListener(new ActionListener() {
-                               public void actionPerformed(ActionEvent e) {
-                                       map.set_zoom(map.default_zoom);
-                               }
-                       });
-
-               c = new GridBagConstraints();
-               c.anchor = GridBagConstraints.CENTER;
-               c.fill = GridBagConstraints.HORIZONTAL;
-               c.gridx = 1;
-               c.gridy = y++;
-               c.weightx = 0;
-               c.weighty = 0;
-               add(zoom_reset, c);
-
-               JButton zoom_in = new JButton("+");
-               zoom_in.addActionListener(new ActionListener() {
-                               public void actionPerformed(ActionEvent e) {
-                                       map.set_zoom(map.get_zoom() + 1);
-                               }
-                       });
-
-               c = new GridBagConstraints();
-               c.anchor = GridBagConstraints.CENTER;
-               c.fill = GridBagConstraints.HORIZONTAL;
-               c.gridx = 1;
-               c.gridy = y++;
-               c.weightx = 0;
-               c.weighty = 0;
-               add(zoom_in, c);
-
-               JButton zoom_out = new JButton("-");
-               zoom_out.addActionListener(new ActionListener() {
-                               public void actionPerformed(ActionEvent e) {
-                                       map.set_zoom(map.get_zoom() - 1);
-                               }
-                       });
-               c = new GridBagConstraints();
-               c.anchor = GridBagConstraints.CENTER;
-               c.fill = GridBagConstraints.HORIZONTAL;
-               c.gridx = 1;
-               c.gridy = y++;
-               c.weightx = 0;
-               c.weighty = 0;
-               add(zoom_out, c);
-
-               maptype_combo = new JComboBox<String>(map.maptype_labels);
-
-               maptype_combo.setEditable(false);
-               maptype_combo.setMaximumRowCount(maptype_combo.getItemCount());
-               maptype_combo.addItemListener(new ItemListener() {
-                               public void itemStateChanged(ItemEvent e) {
-                                       map.set_maptype(maptype_combo.getSelectedIndex());
-                               }
-                       });
-
-               c = new GridBagConstraints();
-               c.anchor = GridBagConstraints.CENTER;
-               c.fill = GridBagConstraints.HORIZONTAL;
-               c.gridx = 1;
-               c.gridy = y++;
-               c.weightx = 0;
-               c.weighty = 0;
-               add(maptype_combo, c);
-
-               map = new AltosMap(this);
-       }
-}
diff --git a/altosuilib/AltosUIMapPreload.java b/altosuilib/AltosUIMapPreload.java
new file mode 100644 (file)
index 0000000..3269003
--- /dev/null
@@ -0,0 +1,546 @@
+/*
+ * 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 org.altusmetrum.altosuilib_11;
+
+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.altoslib_11.*;
+
+class AltosUIMapPos extends Box implements ActionListener {
+       AltosUIMapPreload       preload;
+       AltosUIFrame    owner;
+       JLabel          label;
+       JComboBox       hemi;
+       JTextField      deg;
+       JLabel          deg_label;
+       JTextField      min;
+       JLabel          min_label;
+
+       /* ActionListener interface */
+       public void actionPerformed(ActionEvent e) {
+               preload.center_map();
+       }
+
+       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 ParseException {
+               int     h = hemi.getSelectedIndex();
+               String  d_t = deg.getText();
+               String  m_t = min.getText();
+               double  d, m, v;
+               try {
+                       d = AltosParse.parse_double_locale(d_t);
+               } catch (ParseException pe) {
+                       JOptionPane.showMessageDialog(owner,
+                                                     String.format("Invalid degrees \"%s\"",
+                                                                   d_t),
+                                                     "Invalid number",
+                                                     JOptionPane.ERROR_MESSAGE);
+                       throw pe;
+               }
+               try {
+                       if (m_t.equals(""))
+                               m = 0;
+                       else
+                               m = AltosParse.parse_double_locale(m_t);
+               } catch (ParseException pe) {
+                       JOptionPane.showMessageDialog(owner,
+                                                     String.format("Invalid minutes \"%s\"",
+                                                                   m_t),
+                                                     "Invalid number",
+                                                     JOptionPane.ERROR_MESSAGE);
+                       throw pe;
+               }
+               v = d + m/60.0;
+               if (h == 1)
+                       v = -v;
+               return v;
+       }
+
+       public AltosUIMapPos(AltosUIFrame in_owner,
+                            AltosUIMapPreload preload,
+                            String label_value,
+                            String[] hemi_names,
+                            double default_value) {
+               super(BoxLayout.X_AXIS);
+               owner = in_owner;
+               this.preload = preload;
+               label = new JLabel(label_value);
+               hemi = new JComboBox<String>(hemi_names);
+               hemi.setEditable(false);
+               deg = new JTextField(5);
+               deg.addActionListener(this);
+               deg.setMinimumSize(deg.getPreferredSize());
+               deg.setHorizontalAlignment(JTextField.RIGHT);
+               deg_label = new JLabel("°");
+               min = new JTextField(9);
+               min.addActionListener(this);
+               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);
+       }
+}
+
+public class AltosUIMapPreload extends AltosUIFrame implements ActionListener, ItemListener, AltosLaunchSiteListener, AltosMapLoaderListener, AltosUnitsListener, AltosFontListener  {
+       AltosUIFrame    owner;
+       AltosUIMap      map;
+
+       AltosUIMapPos   lat;
+       AltosUIMapPos   lon;
+
+       JProgressBar    pbar;
+
+       JLabel          site_list_label;
+       JComboBox<AltosLaunchSite>      site_list;
+
+       JToggleButton   load_button;
+       JButton         close_button;
+
+       JCheckBox[]     maptypes = new JCheckBox[AltosMap.maptype_terrain - AltosMap.maptype_hybrid + 1];
+
+       JComboBox<Integer>      min_zoom;
+       JComboBox<Integer>      max_zoom;
+       JLabel                  radius_label;
+       JComboBox<Double>       radius;
+       int scale = 1;
+
+       Integer[]               zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
+
+       Double[]        radius_mi = { 1.0, 2.0, 5.0, 10.0, 20.0 };
+       Double          radius_def_mi = 5.0;
+       Double[]        radius_km = { 2.0, 5.0, 10.0, 20.0, 30.0 };
+       Double          radius_def_km = 10.0;
+
+       AltosMapLoader  loader;
+
+       static final String[]   lat_hemi_names = { "N", "S" };
+       static final String[]   lon_hemi_names = { "E", "W" };
+
+       double  latitude, longitude;
+
+       long    loader_notify_time;
+
+       /* AltosMapLoaderListener interfaces */
+       public void loader_start(final int max) {
+               loader_notify_time = System.currentTimeMillis();
+
+               SwingUtilities.invokeLater(new Runnable() {
+                               public void run() {
+                                       pbar.setMaximum(max);
+                                       pbar.setValue(0);
+                                       pbar.setString("");
+                               }
+                       });
+       }
+
+       public void loader_notify(final int cur, final int max, final String name) {
+               long    now = System.currentTimeMillis();
+
+               if (now - loader_notify_time < 100)
+                       return;
+
+               loader_notify_time = now;
+
+               SwingUtilities.invokeLater(new Runnable() {
+                               public void run() {
+                                       pbar.setValue(cur);
+                                       pbar.setString(name);
+                               }
+                       });
+       }
+
+       public void loader_done(int max) {
+               loader = null;
+               SwingUtilities.invokeLater(new Runnable() {
+                               public void run() {
+                                       pbar.setValue(0);
+                                       pbar.setString("");
+                                       load_button.setSelected(false);
+                               }
+                       });
+       }
+
+       public void debug(String format, Object ... arguments) {
+               if (AltosSerial.debug)
+                       System.out.printf(format, arguments);
+       }
+
+
+       private int all_types() {
+               int all_types = 0;
+               for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
+                       if (maptypes[t].isSelected())
+                               all_types |= (1 << t);
+               return all_types;
+       }
+
+       void center_map(double latitude, double longitude) {
+               map.map.centre(new AltosLatLon(latitude, longitude));
+               map.clear_marks();
+               map.add_mark(latitude, longitude, AltosLib.ao_flight_boost);
+       }
+
+       void center_map() {
+               try {
+                       center_map(lat.get_value(), lon.get_value());
+               } catch (ParseException pe) {
+               }
+       }
+
+       public void itemStateChanged(ItemEvent e) {
+               int             state = e.getStateChange();
+
+               if (state == ItemEvent.SELECTED) {
+                       Object  o = e.getItem();
+                       if (o instanceof AltosLaunchSite) {
+                               AltosLaunchSite site = (AltosLaunchSite) o;
+                               lat.set_value(site.latitude);
+                               lon.set_value(site.longitude);
+                               center_map(site.latitude, site.longitude);
+                       }
+               }
+       }
+
+       public void actionPerformed(ActionEvent e) {
+               String  cmd = e.getActionCommand();
+
+               if (cmd.equals("close")) {
+                       if (loader != null)
+                               loader.abort();
+                       setVisible(false);
+               }
+
+               if (cmd.equals("load")) {
+                       if (loader == null) {
+                               try {
+                                       latitude = lat.get_value();
+                                       longitude = lon.get_value();
+                                       int min_z = (Integer) min_zoom.getSelectedItem();
+                                       int max_z = (Integer) max_zoom.getSelectedItem();
+                                       if (max_z < min_z)
+                                               max_z = min_z;
+                                       Double r = (Double) radius.getSelectedItem();
+
+                                       if (AltosPreferences.imperial_units())
+                                               r = AltosConvert.miles_to_meters(r);
+                                       else
+                                               r = r * 1000;
+
+                                       center_map(latitude, longitude);
+
+                                       loader = new AltosMapLoader(this,
+                                                                   latitude, longitude,
+                                                                   min_z, max_z, r,
+                                                                   all_types(), scale);
+
+                               } catch (ParseException pe) {
+                                       load_button.setSelected(false);
+                               }
+                       }
+               }
+       }
+
+       public void notify_launch_sites(final java.util.List<AltosLaunchSite> sites) {
+               SwingUtilities.invokeLater(new Runnable() {
+                               public void run() {
+                                       int     i = 1;
+                                       for (AltosLaunchSite site : sites) {
+                                               site_list.insertItemAt(site, i);
+                                               i++;
+                                       }
+                               }
+                       });
+       }
+
+       private void set_radius_values() {
+               radius_label.setText(String.format("Map Radius (%s)",
+                                                  AltosPreferences.imperial_units() ? "mi" : "km"));
+
+               Double[]        radii;
+
+               if (AltosPreferences.imperial_units())
+                       radii = radius_mi;
+               else
+                       radii = radius_km;
+
+               radius.removeAllItems();
+               for (Double r : radii) {
+                       radius.addItem(r);
+               }
+               radius.setSelectedItem(radii[2]);
+               radius.setMaximumRowCount(radii.length);
+       }
+
+       public void units_changed(boolean imperial_units) {
+               map.units_changed(imperial_units);
+               set_radius_values();
+       }
+
+       public void font_size_changed(int font_size) {
+               map.font_size_changed(font_size);
+       }
+
+       public AltosUIMapPreload(AltosUIFrame in_owner) {
+               owner = in_owner;
+
+               Container               pane = getContentPane();
+               GridBagConstraints      c = new GridBagConstraints();
+               Insets                  i = new Insets(4,4,4,4);
+
+               setTitle("AltOS Load Maps");
+
+               pane.setLayout(new GridBagLayout());
+
+               addWindowListener(new WindowAdapter() {
+                               @Override
+                               public void windowClosing(WindowEvent e) {
+                                       AltosUIPreferences.unregister_font_listener(AltosUIMapPreload.this);
+                                       AltosPreferences.unregister_units_listener(AltosUIMapPreload.this);
+                               }
+                       });
+
+
+               AltosPreferences.register_units_listener(this);
+               AltosUIPreferences.register_font_listener(this);
+
+               map = new AltosUIMap();
+
+               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 = 10;
+               c.anchor = GridBagConstraints.CENTER;
+
+               pane.add(map, c);
+
+               pbar = new JProgressBar();
+               pbar.setMinimum(0);
+               pbar.setMaximum(1);
+               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 = 10;
+
+               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<AltosLaunchSite>(new AltosLaunchSite[] { new AltosLaunchSite("Site List", 0, 0) });
+               site_list.addItemListener(this);
+
+               new AltosLaunchSites(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 AltosUIMapPos(owner, this,
+                                       "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 AltosUIMapPos(owner, this,
+                                       "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);
+
+               JLabel  types_label = new JLabel("Map Types");
+               c.gridx = 2;
+               c.gridwidth = 2;
+               c.gridy = 2;
+               pane.add(types_label, c);
+
+               c.gridwidth = 1;
+
+               for (int type = AltosMap.maptype_hybrid; type <= AltosMap.maptype_terrain; type++) {
+                       maptypes[type] = new JCheckBox(AltosMap.maptype_labels[type],
+                                                      type == AltosMap.maptype_hybrid);
+                       c.gridx = 2 + (type >> 1);
+                       c.fill = GridBagConstraints.HORIZONTAL;
+                       c.gridy = (type & 1) + 3;
+                       pane.add(maptypes[type], c);
+               }
+
+               JLabel  min_zoom_label = new JLabel("Minimum Zoom");
+               c.gridx = 4;
+               c.gridy = 2;
+               pane.add(min_zoom_label, c);
+
+               min_zoom = new JComboBox<Integer>(zooms);
+               min_zoom.setSelectedItem(zooms[10]);
+               min_zoom.setEditable(false);
+               c.gridx = 5;
+               c.gridy = 2;
+               pane.add(min_zoom, c);
+
+               JLabel  max_zoom_label = new JLabel("Maximum Zoom");
+               c.gridx = 4;
+               c.gridy = 3;
+               pane.add(max_zoom_label, c);
+
+               max_zoom = new JComboBox<Integer>(zooms);
+               max_zoom.setSelectedItem(zooms[14]);
+               max_zoom.setEditable(false);
+               c.gridx = 5;
+               c.gridy = 3;
+               pane.add(max_zoom, c);
+
+               radius_label = new JLabel();
+
+               c.gridx = 4;
+               c.gridy = 4;
+               pane.add(radius_label, c);
+
+               radius = new JComboBox<Double>();
+               radius.setEditable(true);
+               c.gridx = 5;
+               c.gridy = 4;
+               pane.add(radius, c);
+
+               set_radius_values();
+
+               pack();
+               setLocationRelativeTo(owner);
+               setVisible(true);
+       }
+}
diff --git a/altosuilib/AltosUIMapPreloadNew.java b/altosuilib/AltosUIMapPreloadNew.java
deleted file mode 100644 (file)
index 3269bbd..0000000
+++ /dev/null
@@ -1,472 +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 org.altusmetrum.altosuilib_10;
-
-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.altoslib_10.*;
-
-class AltosUIMapPos extends Box {
-       AltosUIFrame    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 ParseException {
-               int     h = hemi.getSelectedIndex();
-               String  d_t = deg.getText();
-               String  m_t = min.getText();
-               double  d, m, v;
-               try {
-                       d = AltosParse.parse_double_locale(d_t);
-               } catch (ParseException pe) {
-                       JOptionPane.showMessageDialog(owner,
-                                                     String.format("Invalid degrees \"%s\"",
-                                                                   d_t),
-                                                     "Invalid number",
-                                                     JOptionPane.ERROR_MESSAGE);
-                       throw pe;
-               }
-               try {
-                       if (m_t.equals(""))
-                               m = 0;
-                       else
-                               m = AltosParse.parse_double_locale(m_t);
-               } catch (ParseException pe) {
-                       JOptionPane.showMessageDialog(owner,
-                                                     String.format("Invalid minutes \"%s\"",
-                                                                   m_t),
-                                                     "Invalid number",
-                                                     JOptionPane.ERROR_MESSAGE);
-                       throw pe;
-               }
-               v = d + m/60.0;
-               if (h == 1)
-                       v = -v;
-               return v;
-       }
-
-       public AltosUIMapPos(AltosUIFrame 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<String>(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);
-       }
-}
-
-public class AltosUIMapPreloadNew extends AltosUIFrame implements ActionListener, ItemListener, AltosLaunchSiteListener, AltosMapLoaderListener  {
-       AltosUIFrame    owner;
-       AltosUIMapNew   map;
-
-       AltosUIMapPos   lat;
-       AltosUIMapPos   lon;
-
-       JProgressBar    pbar;
-
-       JLabel          site_list_label;
-       JComboBox<AltosLaunchSite>      site_list;
-
-       JToggleButton   load_button;
-       boolean         loading;
-       JButton         close_button;
-
-       JCheckBox[]     maptypes = new JCheckBox[AltosMap.maptype_terrain - AltosMap.maptype_hybrid + 1];
-
-       JComboBox<Integer>      min_zoom;
-       JComboBox<Integer>      max_zoom;
-       JComboBox<Double>       radius;
-
-       Integer[]               zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
-
-       Double[]        radius_mi = { 1.0, 2.0, 5.0, 10.0, 20.0 };
-       Double          radius_def_mi = 5.0;
-       Double[]        radius_km = { 2.0, 5.0, 10.0, 20.0, 30.0 };
-       Double          radius_def_km = 10.0;
-
-
-       static final String[]   lat_hemi_names = { "N", "S" };
-       static final String[]   lon_hemi_names = { "E", "W" };
-
-       double  latitude, longitude;
-
-       /* AltosMapLoaderListener interfaces */
-       public void loader_start(final int max) {
-               SwingUtilities.invokeLater(new Runnable() {
-                               public void run() {
-                                       pbar.setMaximum(max);
-                                       pbar.setValue(0);
-                                       pbar.setString("");
-                                       map.clear_marks();
-                                       map.add_mark(latitude, longitude, AltosLib.ao_flight_boost);
-                               }
-                       });
-       }
-
-       public void loader_notify(final int cur, final int max, final String name) {
-               SwingUtilities.invokeLater(new Runnable() {
-                               public void run() {
-                                       pbar.setValue(cur);
-                                       pbar.setString(name);
-                               }
-                       });
-       }
-
-       public void loader_done(int max) {
-               SwingUtilities.invokeLater(new Runnable() {
-                               public void run() {
-                                       pbar.setValue(0);
-                                       pbar.setString("");
-                                       load_button.setSelected(false);
-                                       loading = false;
-                               }
-                       });
-       }
-
-       public void debug(String format, Object ... arguments) {
-               if (AltosSerial.debug)
-                       System.out.printf(format, arguments);
-       }
-
-
-       private int all_types() {
-               int all_types = 0;
-               for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
-                       if (maptypes[t].isSelected())
-                               all_types |= (1 << t);
-               return all_types;
-       }
-
-       public void itemStateChanged(ItemEvent e) {
-               int             state = e.getStateChange();
-
-               if (state == ItemEvent.SELECTED) {
-                       Object  o = e.getItem();
-                       if (o instanceof AltosLaunchSite) {
-                               AltosLaunchSite site = (AltosLaunchSite) 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 {
-                                       latitude = lat.get_value();
-                                       longitude = lon.get_value();
-                                       int min_z = (Integer) min_zoom.getSelectedItem();
-                                       int max_z = (Integer) max_zoom.getSelectedItem();
-                                       if (max_z < min_z)
-                                               max_z = min_z;
-                                       Double r = (Double) radius.getSelectedItem();
-
-                                       if (AltosPreferences.imperial_units())
-                                               r = AltosConvert.distance.inverse(r);
-                                       else
-                                               r = r * 1000;
-                                       loading = true;
-
-                                       new AltosMapLoader(map.map, this,
-                                                          latitude, longitude,
-                                                          min_z, max_z, r, all_types());
-
-                               } catch (ParseException pe) {
-                                       load_button.setSelected(false);
-                               }
-                       }
-               }
-       }
-
-       public void notify_launch_sites(final java.util.List<AltosLaunchSite> sites) {
-               SwingUtilities.invokeLater(new Runnable() {
-                               public void run() {
-                                       int     i = 1;
-                                       for (AltosLaunchSite site : sites) {
-                                               site_list.insertItemAt(site, i);
-                                               i++;
-                                       }
-                               }
-                       });
-       }
-
-       public AltosUIMapPreloadNew(AltosUIFrame in_owner) {
-               owner = in_owner;
-
-               Container               pane = getContentPane();
-               GridBagConstraints      c = new GridBagConstraints();
-               Insets                  i = new Insets(4,4,4,4);
-
-               setTitle("AltOS Load Maps");
-
-               pane.setLayout(new GridBagLayout());
-
-               map = new AltosUIMapNew();
-
-               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 = 10;
-               c.anchor = GridBagConstraints.CENTER;
-
-               pane.add(map, c);
-
-               pbar = new JProgressBar();
-               pbar.setMinimum(0);
-               pbar.setMaximum(1);
-               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 = 10;
-
-               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<AltosLaunchSite>(new AltosLaunchSite[] { new AltosLaunchSite("Site List", 0, 0) });
-               site_list.addItemListener(this);
-
-               new AltosLaunchSites(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 AltosUIMapPos(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 AltosUIMapPos(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);
-
-               JLabel  types_label = new JLabel("Map Types");
-               c.gridx = 2;
-               c.gridwidth = 2;
-               c.gridy = 2;
-               pane.add(types_label, c);
-
-               c.gridwidth = 1;
-
-               for (int type = AltosMap.maptype_hybrid; type <= AltosMap.maptype_terrain; type++) {
-                       maptypes[type] = new JCheckBox(AltosMap.maptype_labels[type],
-                                                      type == AltosMap.maptype_hybrid);
-                       c.gridx = 2 + (type >> 1);
-                       c.fill = GridBagConstraints.HORIZONTAL;
-                       c.gridy = (type & 1) + 3;
-                       pane.add(maptypes[type], c);
-               }
-
-               JLabel  min_zoom_label = new JLabel("Minimum Zoom");
-               c.gridx = 4;
-               c.gridy = 2;
-               pane.add(min_zoom_label, c);
-
-               min_zoom = new JComboBox<Integer>(zooms);
-               min_zoom.setSelectedItem(zooms[10]);
-               min_zoom.setEditable(false);
-               c.gridx = 5;
-               c.gridy = 2;
-               pane.add(min_zoom, c);
-
-               JLabel  max_zoom_label = new JLabel("Maximum Zoom");
-               c.gridx = 4;
-               c.gridy = 3;
-               pane.add(max_zoom_label, c);
-
-               max_zoom = new JComboBox<Integer>(zooms);
-               max_zoom.setSelectedItem(zooms[14]);
-               max_zoom.setEditable(false);
-               c.gridx = 5;
-               c.gridy = 3;
-               pane.add(max_zoom, c);
-
-               JLabel radius_label = new JLabel(String.format("Map Radius (%s)",
-                                                              AltosPreferences.imperial_units() ? "miles" : "km"));
-               c.gridx = 4;
-               c.gridy = 4;
-               pane.add(radius_label, c);
-
-               Double[]        radii;
-               Double          radius_default;
-
-               if (AltosPreferences.imperial_units())
-                       radii = radius_mi;
-               else
-                       radii = radius_km;
-               radius = new JComboBox<Double>(radii);
-               radius.setSelectedItem(radii[2]);
-               radius.setEditable(true);
-               c.gridx = 5;
-               c.gridy = 4;
-               pane.add(radius, c);
-
-               pack();
-               setLocationRelativeTo(owner);
-               setVisible(true);
-       }
-}
index dc96357a5bf5f4e084ca089617c6fcc3b0cb749a..84130562d447b210f05593f6775c27b77278dcf7 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
index 5fc5f15e6c07861823272d1bcee829e27aadaa10..841727115902280fd1a6bb3ba0ac2730102b5cb8 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.*;
 import java.awt.Component;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosUIPreferences extends AltosPreferences {
 
index d232edf7a373bd496b83467c75dd96f96c15fd57..3d212dc5af61adaed24b3c6c516ac09ab362b940 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.File;
 import java.util.prefs.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 import javax.swing.filechooser.FileSystemView;
 
 public class AltosUIPreferencesBackend extends AltosPreferencesBackend {
index 5a18b32fe4effae2db52fdbf0232ba823898c51e..8919804e760e6d1c0f3442ec9e0ee9ac838ec840 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class AltosUIRateList extends JComboBox<String> {
 
index b16f046be51b97fb3e85ae4ba31a0eecef24fb01..3a1dde03c73c24a76367c5210085f3a2824a9b6d 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.io.*;
 import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
@@ -69,7 +69,7 @@ public class AltosUISeries extends XYSeries implements AltosUIGrapher {
                String  example = units.graph_format(7);
 
                ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})",
-                                                                  units.show_units()),
+                                                                  units.graph_units()),
                                                     new java.text.DecimalFormat(time_example),
                                                     new java.text.DecimalFormat(example));
                renderer.setBaseToolTipGenerator(ttg);
@@ -85,7 +85,7 @@ public class AltosUISeries extends XYSeries implements AltosUIGrapher {
 
        public void add(AltosUIDataPoint dataPoint) {
                try {
-                       super.add(dataPoint.x(), units.value(dataPoint.y(fetch)));
+                       super.add(dataPoint.x(), units.graph_value(dataPoint.y(fetch)));
                } catch (AltosUIDataMissing dm) {
                }
        }
index bba14678be0f6fa08148f73762bd13015e5b52d0..a2599acde5d39d7f01d109a39387b6f1b1542049 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.util.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 
 public class AltosUITelemetryList extends JComboBox<String> {
index a84bd0b2f1cd985fda652f8825e6d257f2feb456..63af57257c8c4dfcb94bf72940a1d835c3652b0b 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
 
@@ -46,10 +46,10 @@ public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
 
        public double[] last_values;
 
-       public void show(double... v) {
+       private void show(boolean force, double... v) {
                show();
                for (int i = 0; i < values.length; i++) {
-                       if (v[i] != last_values[i]) {
+                       if (force || v[i] != last_values[i]) {
                                String  value_text;
                                boolean good = false;
 
@@ -68,13 +68,19 @@ public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
                }
        }
 
+       boolean hide = false;
+
+       public void show(double... v) {
+               show(false, v);
+       }
+
        public void units_changed(boolean imperial_units) {
-               show(last_values);
+               if (!hide)
+                       show(true, last_values);
        }
 
        public void show (AltosState state, AltosListenerState listener_state) {
                double[] v = new double[values.length];
-               boolean hide = false;
 
                for (int i = 0; i < values.length; i++) {
                        if (state != null)
@@ -93,7 +99,7 @@ public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
 
        public void reset() {
                for (int i = 0; i < last_values.length; i++)
-                       last_values[i] = AltosLib.MISSING - 1;
+                       last_values[i] = AltosLib.MISSING;
        }
 
        public AltosUIUnitsIndicator (Container container, int x, int y, int label_width, AltosUnits units, String name, int number_values, boolean has_lights, int width) {
@@ -101,7 +107,7 @@ public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
                this.units = units;
                last_values = new double[values.length];
                for (int i = 0; i < last_values.length; i++)
-                       last_values[i] = AltosLib.MISSING - 1;
+                       last_values[i] = AltosLib.MISSING;
        }
 
        public AltosUIUnitsIndicator (Container container, int x, int y, AltosUnits units, String name, int number_values, boolean has_lights, int width) {
index d753b759e61d1b2a205f76639ba6cff120322eeb..852b594d25adbab2a941fe5739f158f5d6e5356f 100644 (file)
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public abstract class AltosUIVoltageIndicator extends AltosUIUnitsIndicator {
 
@@ -30,7 +30,7 @@ public abstract class AltosUIVoltageIndicator extends AltosUIUnitsIndicator {
                return voltage(state);
        }
 
-       double last_voltage = -1;
+       double last_voltage = AltosLib.MISSING;
 
        public AltosUIVoltageIndicator (Container container, int x, int y, String name, int width) {
                super(container, x, y, AltosConvert.voltage, name, 1, true, width);
index c93a32114cb688bc6a79980b2007aa96ffb7adb9..ea4f9f3c5ce54bb90abee486e283720742c48aa8 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.util.*;
 import libaltosJNI.*;
index 1b65acdc7e335e1a3039adfb5519c60f43f3ffc9..33a06a4e80ba1660d58b077a04855bc265699ad8 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import com.sun.speech.freetts.Voice;
 import com.sun.speech.freetts.VoiceManager;
index 725bbab62a590faef7694321f5fe14fd441df9f7..804425a32a613f099ac563804db23260c74ae8a1 100644 (file)
@@ -15,7 +15,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.awt.*;
 import java.awt.event.*;
index a00e4a12f1fdc78a0e9b5dc927a3993e7ad3b627..d18006b584bc0a6797c1d9603848f61a243b1470 100644 (file)
@@ -57,8 +57,8 @@ altosuilib_JAVA = \
        AltosBTDeviceIterator.java \
        AltosBTManage.java \
        AltosBTKnown.java \
-       AltosUIMapNew.java \
-       AltosUIMapPreloadNew.java \
+       AltosUIMap.java \
+       AltosUIMapPreload.java \
        AltosUIFlightTab.java \
        AltosUIIndicator.java \
        AltosUIUnitsIndicator.java \
index c2915081e47ec0bac188c587ed0fd02b58ab5d16..de5d58362127ddcd745ade547c350474955cbde6 100755 (executable)
@@ -55,7 +55,7 @@ Copyright Â© 2003-2007 Apple, Inc., All Rights Reserved
 
 */
 
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
 
 import java.lang.reflect.*;
 import java.util.HashMap;
index e883de4a47d3fc6ae346c7e7f8fcfc7556d9f5ec..b3058b80fefbb9290ad6c761505868e4fa66e38e 100644 (file)
@@ -169,7 +169,7 @@ do_baro(struct cc_usb *usb) {
                return 0;
        }
 
-       if (temperature < 20 || 35 < temperature) {
+       if (temperature < 20 || 40 < temperature) {
                printf ("weird temperature %f\n", temperature);
                free_baro(b);
                return 0;
index ee3d4225f84d85fb58a7876fce82550a34554339..6745b0123722a4427e8c551057fa1c345dc16f43 100644 (file)
@@ -18,8 +18,8 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([altos], 1.6.3)
-ANDROID_VERSION=11
+AC_INIT([altos], 1.6.4)
+ANDROID_VERSION=12
 AC_CONFIG_SRCDIR([src/kernel/ao.h])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
@@ -31,8 +31,8 @@ AC_SUBST(ANDROID_VERSION)
 dnl ==========================================================================
 dnl Java library versions
 
-ALTOSUILIB_VERSION=10
-ALTOSLIB_VERSION=10
+ALTOSUILIB_VERSION=11
+ALTOSLIB_VERSION=11
 
 AC_SUBST(ALTOSLIB_VERSION)
 AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package])
index ed06006a1f44d8ffe698423d80798001b06a0233..31bc08d820a25bd709eeba9ff479ef9fc22f3c15 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 RELNOTES_INC=\
+       release-notes-1.6.4.inc \
        release-notes-1.6.3.inc \
        release-notes-1.6.2.inc \
        release-notes-1.6.1.inc \
index 5473dd66f9779c2ec5ef1dacea747b7a9e474c25..1b8ff68d1a0fdf948597049a0d44850ac07badc4 100644 (file)
 </legalnotice>
 <revhistory>
   <?dbhtml filename="altusmetrum-revhistory.html"?>
+  <revision>
+    <revnumber>1.6.4</revnumber>
+    <date>10 May 2016</date>
+    <revremark>
+      Minor release fixing TeleBT v1.0 flow control and a few minor
+      application bugs.
+    </revremark>
+  </revision>
   <revision>
     <revnumber>1.6.3</revnumber>
     <date>21 April 2016</date>
diff --git a/doc/release-notes-1.6.4.inc b/doc/release-notes-1.6.4.inc
new file mode 100644 (file)
index 0000000..f976a69
--- /dev/null
@@ -0,0 +1,42 @@
+= Release Notes for Version 1.6.4
+:toc!:
+:doctype: article
+
+       Version 1.6.4 fixes a bluetooth communication problem with
+       TeleBT v1.0 devices, along with some altosui and altosdroid
+       minor nits. It also now ships firmware for some newer devices.
+
+       == AltOS
+
+       AltOS fixes:
+
+       * Fix hardware flow control on TeleBT v1.0. Hardware RTS/CTS
+         doesn't seem to work, switch from using the hardware to
+         driving these pins with software.
+
+       * Fix ARM USB drivers to deal with OS restarts. Needed to
+         reset all USB-related state when the USB bus is reset. These
+         fixes affect all STM32L, STM32F0 and LPC11U14 based devices.
+
+       == AltosUI, TeleGPS and AltosDroid Applications
+
+       AltosUI, TeleGPS and AltosDroid New Features:
+
+       * Automatically switch from meters or feet to kilometers or
+          miles for distance units.
+
+       * Add Monitor Idle mode to TeleGPS application.
+
+       AltosUI, TeleGPS and AltosDroid Fixes:
+
+       * Abort map preloading when the preload map dialog is closed.
+
+       * In AltosDroid, Don't reconnect to last device if the user
+          had disconnected it the last time the application was
+          active.
+
+       == Documentation
+
+       * Mention TeleMega v2.0 in hardware specs table.
+
+       * Document TeleGPS RF output in telegps manual.
index 35ffa0d1ecda1376af707ee4c064bdb6dcb75168..6ac90cfd6a4feeac70f493f0a06d2438063baa4f 100644 (file)
@@ -1,6 +1,11 @@
 [appendix]
 == Release Notes
 
+       :leveloffset: 2
+       include::release-notes-1.6.4.raw[]
+
+       <<<<
+
        :leveloffset: 2
        include::release-notes-1.6.3.raw[]
 
index a6c7b69a6f55058dbe4831c502991ee087322707..c335b081e0a42c6e1f063d029417a652dfa620da 100644 (file)
        |8MB
        |40mW
        |3.7V
+
+       |TeleMega v2.0
+       |MS5607 30km (100k')
+       |MMA6555 102g
+       |uBlox Max-7Q
+       |MPU6000 HMC5883
+       |8MB
+       |40mW
+       |3.7V
        endif::telemega[]
 
        ifdef::easymega[]
index 4ba3f73ce75940a719c14989163ee4a99d003f0b..1ef088fe882332457ee15830bd4c79bf329605b6 100644 (file)
 </legalnotice>
 <revhistory>
   <?dbhtml filename="telegps-revhistory.html"?>
+  <revision>
+    <revnumber>1.6.4</revnumber>
+    <date>10 May 2016</date>
+    <revremark>
+      Minor release fixing TeleBT v1.0 flow control and a few minor
+      application bugs.
+    </revremark>
+  </revision>
   <revision>
     <revnumber>1.6.1</revnumber>
     <date>15 July 2015</date>
index 6ff8c76fc842df63be7c09aa4f66461c98d23b54..417a9708c568b43f7dd153805c907412248c8cd8 100644 (file)
@@ -5,6 +5,11 @@
       
                TeleGPS uses the u-Blox Max-7Q GPS receiver.
       
+       === 70cm Transmitter
+
+               TeleGPS uses a TI CC115L transmitter. This radio
+               produces 10mW of RF output.
+
        === Micro-controller
       
                TeleGPS uses an NXP LPC11U14 micro-controller. This
index 25fdd6d32899af59e183f941e7a892e2bfdc3eb9..29587b7e7e4f4afc3d16f3af307a8bddbdd849d2 100644 (file)
                 signals, but no record of the flight will be
                 stored in on-board flash.
 
+               ifdef::easymega,telemega[]
                |Additional Igniters
                |four very short beeps
                |Continuity indication for the four additional pyro
-               |channels on TeleMega and EasyMega. One high tone for
-               |no continuity, one low tone for continuity. These are
-               |produced after the continuity indicators for the two
-               |primary igniter channels.
+                channels on TeleMega and EasyMega. One high tone for
+                no continuity, one low tone for continuity. These are
+                produced after the continuity indicators for the two
+                primary igniter channels.
+               endif::easymega,telemega[]
 
                |====
 
index a8834a66e6c0bd5b16384a888d6fa0e52b968939..7ad2c102c191271e976bd32e5cd7a7b20ca6b00b 100644 (file)
@@ -40,8 +40,14 @@ JAR=micropeak.jar
 
 FATJAR=micropeak-fat.jar
 
+if MULTI_ARCH
+LIBALTOS_LINUX=libaltos32.so libaltos64.so
+else
+LIBALTOS_LINUX=libaltos.so
+endif
+
 LIBALTOS= \
-       libaltos.so \
+       $(LIBALTOS_LINUX) \
        libaltos.dylib \
        altos64.dll \
        altos.dll
@@ -98,8 +104,7 @@ all-local: micropeak-test micropeak-jdb $(JAR)
 clean-local:
        -rm -rf classes $(JAR) $(FATJAR) \
                MicroPeak-Linux-*.tar.bz2 MicroPeak-Mac-*.dmg MicroPeak-Windows-*.exe \
-               $(ALTOSLIB_CLASS) \
-               $(ALTOSUILIB_CLASS) \
+               altoslib_*.jar altosuilib_*.jar \
                $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
                micropeak micropeak-test micropeak-jdb macosx linux windows micropeak-windows.log \
                micropeak-windows.nsi *.desktop
@@ -121,7 +126,7 @@ DOC=$(MICROPEAK_DOC)
 
 FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
 
-LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
+LINUX_FILES=$(FAT_FILES) $(LIBALTOS_LINUX) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
 LINUX_EXTRA=micropeak-fat $(desktop_file).in
 
 MACOSX_DRIVER_0_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg
@@ -220,6 +225,14 @@ libaltos.so: build-libaltos
        -rm -f "$@"
        $(LN_S) ../libaltos/.libs/"$@" .
 
+libaltos32.so: build-libaltos
+       -rm -f "$@"
+       $(LN_S) ../libaltos/.libs/"$@" .
+
+libaltos64.so: build-libaltos
+       -rm -f "$@"
+       $(LN_S) ../libaltos/.libs/"$@" .
+
 libaltos.dylib:
        -rm -f "$@"
        $(LN_S) ../libaltos/"$@" .
@@ -232,6 +245,10 @@ altos64.dll: ../libaltos/altos64.dll
        -rm -f "$@"
        $(LN_S) ../libaltos/"$@" .
 
+../libaltos/.libs/libaltos64.so: ../libaltos/.libs/libaltos32.so
+
+../libaltos/.libs/libaltos32.so: build-libaltos
+
 ../libaltos/.libs/libaltos.so: build-libaltos
 
 ../libaltos/altos.dll: build-altos-dll
index 60bf8ad7f52bd61ee1110b8879082a0f91d4900a..e763be27a8bdc6e10250b9abcdb1785b56c635ca 100644 (file)
@@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;
 import java.lang.*;
 import java.io.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 class MicroIterator implements Iterator<MicroDataPoint> {
        int             i;
index 2775165f690bab88634f293dc7fda5b375715df2..fd6b4a8bd2029b00ec17726085fd57a6540ff1ea 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.micropeak;
 
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroDataPoint implements AltosUIDataPoint {
        public double           time;
index 005e154e08a505c20570e9adf742b03e70146cb8..8b2c747f674b53aed96603980b425421aeef5e48 100644 (file)
@@ -21,7 +21,7 @@ import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;
 import java.util.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroDeviceDialog extends AltosDeviceDialog {
 
index 49bcaf54e4ef994b034f30c8348208efa384fa28..9e0299b083625fd9830324511851ffc03c7c3cf9 100644 (file)
@@ -23,8 +23,8 @@ import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog, WindowListener {
        MicroPeak       owner;
index 1c48a0d3dfd48a8f0035ecfffeb46311db7cc549..406f7286386943ac98d8ad0e6845d1e33a4fe84e 100644 (file)
@@ -23,8 +23,8 @@ import java.util.ArrayList;
 import java.awt.*;
 import javax.swing.*;
 import javax.swing.filechooser.FileNameExtensionFilter;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroExport extends JFileChooser {
 
index 0ef021a1de38f415d09b49d36af3a364e9a61143..00c59931ca635d84313ff2751ec0b5af3951b73c 100644 (file)
@@ -19,8 +19,8 @@ package org.altusmetrum.micropeak;
 
 import java.io.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroFile {
 
index 013d1128c784b838e019e1e60e24c15cb32d2f60..394b431727367da547b1971c32612b0e6ad4ffd2 100644 (file)
@@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;
 import javax.swing.*;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import java.io.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroFileChooser extends JFileChooser {
        JFrame  frame;
index 9f3c0426597bb96120cb3aca96f233f7f1a2cfe1..618c839e80fdd75ee16a1d5bbbde6836773aaadc 100644 (file)
@@ -21,7 +21,7 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import java.util.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroFrame extends AltosUIFrame {
        static String[] micro_icon_names = {
index 4941070cc1e860089cfe88891766e4796383d660..bc9fb0dcbee1e08ba3887ccf3b47ba403254ee91 100644 (file)
@@ -22,8 +22,8 @@ import java.util.ArrayList;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 import org.jfree.ui.*;
 import org.jfree.chart.*;
index fb4fe1cb721a797b49a325be07c1ba0f26d13f80..c624246f6bbc72b53561dc31083bc8ae7d1f16ce 100644 (file)
@@ -23,8 +23,8 @@ import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroPeak extends MicroFrame implements ActionListener, ItemListener {
 
index 767ff9e133dd7f82a46dad6a5afe108f59802d57..8857958fc754709ab53e6231f42fb42d1af91ede 100644 (file)
@@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;
 import java.awt.*;
 import java.io.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroRaw extends JTextArea {
 
index a38e2b46710a6bb8bad88eca0760fe7a452b085f..6822a96114afea8cf5ab8bf325b5200fba6a56d0 100644 (file)
@@ -24,8 +24,8 @@ import javax.swing.filechooser.FileNameExtensionFilter;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroSave extends JFileChooser {
 
index ea68aa1ad1441072b4b6b9867186788925052e0b..93c40d712a34650115689b0219690105163d8080 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.micropeak;
 import java.util.*;
 import java.io.*;
 import libaltosJNI.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroSerial extends InputStream {
        SWIGTYPE_p_altos_file   file;
index e8accaeb81d9e8835af42ea8b3fa5d00a1eebef5..55d759e5f5eff652b574a9abb940b58bd31d307e 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.micropeak;
 import java.util.*;
 import java.io.*;
 import libaltosJNI.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public interface MicroSerialLog {
 
index d2f80a8f561c904d904e14ccc91e93871b2042a0..754804450228eabd0efcc9888b23379603ef3b9b 100644 (file)
@@ -18,8 +18,8 @@
 package org.altusmetrum.micropeak;
 
 import java.io.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroStats {
        double          coast_height;
index 1adef54aba3b089697227bf1e72fde1fa2b03412..7ffae2f280b3b408756d1d806454534eea047036 100644 (file)
@@ -19,8 +19,8 @@ package org.altusmetrum.micropeak;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroStatsTable extends JComponent implements AltosFontListener {
        GridBagLayout   layout;
index 9ceae1cb2dd47599ed18381bd00f9385ba854c49..4a72ba581a1bb5ca0447a96b2c6e9e829bbbc1a7 100644 (file)
@@ -19,8 +19,8 @@ package org.altusmetrum.micropeak;
 
 import java.util.*;
 import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class MicroUSB extends altos_device implements AltosDevice {
 
index 81727836d260e84ab88f3a1ae78c559296d9a525..b4f57908a4bd984da45fdcedfc596c72e3687623 100644 (file)
@@ -42,6 +42,18 @@ const __code struct ao_serial_speed ao_serial_speeds[] = {
 
 #define AO_SERIAL_SPEED_MAX    AO_SERIAL_SPEED_115200
 
+#if HAS_SERIAL_1_ALT_1
+#define SERIAL_1_RTS P0_3
+#else
+#define SERIAL_1_RTS P1_5
+#endif
+
+#if HAS_SERIAL_0_ALT_1
+#define SERIAL_0_RTS P0_5
+#else
+#define SERIAL_0_RTS P1_3
+#endif
+
 #if HAS_SERIAL_0
 
 volatile __xdata struct ao_fifo        ao_serial0_rx_fifo;
@@ -56,6 +68,10 @@ ao_serial0_rx_isr(void) __interrupt 2
 #if USE_SERIAL_0_STDIN
        ao_wakeup(&ao_stdin_ready);
 #endif
+#if HAS_SERIAL_0_HW_FLOW
+       if (ao_fifo_mostly(ao_serial0_rx_fifo))
+               SERIAL_0_RTS = 1;
+#endif
 }
 
 static __xdata uint8_t ao_serial0_tx_started;
@@ -87,6 +103,10 @@ ao_serial0_getchar(void) __critical
        while (ao_fifo_empty(ao_serial0_rx_fifo))
                ao_sleep(&ao_serial0_rx_fifo);
        ao_fifo_remove(ao_serial0_rx_fifo, c);
+#if HAS_SERIAL_0_HW_FLOW
+       if (ao_fifo_barely(ao_serial0_rx_fifo))
+               SERIAL_0_RTS = 0;
+#endif
        return c;
 }
 
@@ -98,6 +118,10 @@ _ao_serial0_pollchar(void)
        if (ao_fifo_empty(ao_serial0_rx_fifo))
                return AO_READ_AGAIN;
        ao_fifo_remove(ao_serial0_rx_fifo,c);
+#if HAS_SERIAL_0_HW_FLOW
+       if (ao_fifo_barely(ao_serial0_rx_fifo))
+               SERIAL_0_RTS = 0;
+#endif
        return c;
 }
 #endif
@@ -144,6 +168,10 @@ ao_serial1_rx_isr(void) __interrupt 3
 #if USE_SERIAL_1_STDIN
        ao_wakeup(&ao_stdin_ready);
 #endif
+#if HAS_SERIAL_1_HW_FLOW
+       if (ao_fifo_mostly(ao_serial1_rx_fifo))
+               SERIAL_1_RTS = 1;
+#endif
 }
 
 static __xdata uint8_t ao_serial1_tx_started;
@@ -175,6 +203,10 @@ ao_serial1_getchar(void) __critical
        while (ao_fifo_empty(ao_serial1_rx_fifo))
                ao_sleep(&ao_serial1_rx_fifo);
        ao_fifo_remove(ao_serial1_rx_fifo, c);
+#if HAS_SERIAL_1_HW_FLOW
+       if (ao_fifo_barely(ao_serial1_rx_fifo))
+               SERIAL_1_RTS = 0;
+#endif
        return c;
 }
 
@@ -186,6 +218,10 @@ _ao_serial1_pollchar(void)
        if (ao_fifo_empty(ao_serial1_rx_fifo))
                return AO_READ_AGAIN;
        ao_fifo_remove(ao_serial1_rx_fifo,c);
+#if HAS_SERIAL_1_HW_FLOW
+       if (ao_fifo_barely(ao_serial1_rx_fifo))
+               SERIAL_1_RTS = 0;
+#endif
        return c;
 }
 #endif
@@ -232,7 +268,11 @@ ao_serial_init(void)
        /* Make the USART pins be controlled by the USART */
        P0SEL |= (1 << 2) | (1 << 3);
 #if HAS_SERIAL_0_HW_FLOW
-       P0SEL |= (1 << 4) | (1 << 5);
+       SERIAL_0_RTS = 0;
+       P0DIR |= (1 << 5);
+
+       P0SEL |= (1 << 4);
+       P0INP |= (1 << 4);
 #endif
 #else
        /* Set up the USART pin assignment */
@@ -244,7 +284,11 @@ ao_serial_init(void)
        /* Make the USART pins be controlled by the USART */
        P1SEL |= (1 << 5) | (1 << 4);
 #if HAS_SERIAL_0_HW_FLOW
-       P1SEL |= (1 << 3) | (1 << 2);
+       SERIAL_0_RTS = 0;
+       P1DIR |= (1 << 3);
+
+       P1SEL |= (1 << 2);
+       P1INP |= (1 << 2);
 #endif
 #endif
 
@@ -287,7 +331,13 @@ ao_serial_init(void)
        /* Make the USART pins be controlled by the USART */
        P0SEL |= (1 << 5) | (1 << 4);
 #if HAS_SERIAL_1_HW_FLOW
-       P0SEL |= (1 << 3) | (1 << 2);
+       /* SW RTS control (hw doesn't work) */
+       SERIAL_1_RTS = 0;
+       P0DIR |= 1 << 3;
+
+       /* HW CTS. Maybe this works? */
+       P0SEL |= 1 << 2;
+       P0INP |= 1 << 2;
 #endif
 #else
        /* Set up the USART pin assignment */
@@ -299,7 +349,13 @@ ao_serial_init(void)
        /* Make the USART pins be controlled by the USART */
        P1SEL |= (1 << 6) | (1 << 7);
 #if HAS_SERIAL_1_HW_FLOW
-       P1SEL |= (1 << 5) | (1 << 4);
+       /* SW RTS control (hw doesn't work) */
+       SERIAL_1_RTS = 0;
+       P1DIR |= (1 << 5);
+
+       /* HW CTS. Maybe this works? */
+       P1SEL |= (1 << 4);
+       P1INP |= (1 << 4);
 #endif
 #endif
 
index 0246ba02ddfce5a4f5925a2ac080fbbcb9bad563..24180f345cc6905856ad097884f83e386c113bef 100644 (file)
@@ -70,7 +70,7 @@ struct ao_cc115l_trace {
        const char                      *comment;
 };
 
-#define NUM_TRACE      256
+#define NUM_TRACE      32
 
 static struct ao_cc115l_trace  trace[NUM_TRACE];
 static int                     trace_i;
index 171a345fbe2db047feebaab19c25a55ba03410e9..4ac6ee5e991ada7dfacb82fdc0f5a51cdb6485a9 100644 (file)
@@ -22,7 +22,7 @@
 #include <ao_exti.h>
 #include <ao_power.h>
 
-static struct ao_task  ao_trng_send_task, ao_trng_send_raw_task;
+static struct ao_task  ao_trng_send_task;
 static uint8_t         trng_running;
 static AO_TICK_TYPE    trng_power_time;
 
@@ -30,6 +30,10 @@ static AO_TICK_TYPE  trng_power_time;
 
 static uint8_t         random_mutex;
 
+#if AO_USB_HAS_IN2
+
+static struct ao_task  ao_trng_send_raw_task;
+
 static void
 ao_trng_get_raw(uint16_t *buf)
 {
@@ -90,6 +94,8 @@ ao_trng_send_raw(void)
        }
 }
 
+#endif
+
 /* Make sure there's at least 8 bits of variance in the samples */
 #define MIN_VARIANCE           (128 * 128)
 
@@ -181,7 +187,9 @@ ao_trng_send(void)
        if (failed > AO_TRNG_START_CHECK / 4)
                ao_panic(AO_PANIC_DMA);
 
+#if AO_USB_HAS_IN2
        ao_add_task(&ao_trng_send_raw_task, ao_trng_send_raw, "trng_send_raw");
+#endif
 
 #ifdef AO_USB_START_DISABLED
        ao_usb_enable();
index 0dfaece480dc0f60f0b2bcb245b1e3578395ccc2..3b3226adac357161453ed3aabce5579a664a8bd5 100644 (file)
@@ -269,13 +269,10 @@ ao_usb_epn_in_count(uint8_t n)
        return ao_usb_ep_count(ao_usb_epn_in(n, 0));
 }
 
-static uint8_t *
-ao_usb_enable_ep(vuint32_t *ep, uint16_t nbytes, uint16_t set_nbytes)
+static void
+ao_usb_enable_ep(vuint32_t *ep, uint8_t *addr, uint16_t set_nbytes)
 {
-       uint8_t *addr = ao_usb_alloc_sram(nbytes);
-
        ao_usb_set_ep(ep, addr, set_nbytes);
-       return addr;
 }
 
 static void
@@ -293,23 +290,13 @@ ao_usb_disable_ep(vuint32_t *ep)
 
 static void
 ao_usb_enable_epn(uint8_t n,
-                 uint16_t out_bytes, uint8_t *out_addrs[2],
-                 uint16_t in_bytes, uint8_t *in_addrs[2])
+                 uint16_t out_bytes, uint8_t *out_addr,
+                 uint8_t *in_addr)
 {
-       uint8_t *addr;
-
-       addr = ao_usb_enable_ep(ao_usb_epn_out(n, 0), out_bytes * 2, out_bytes);
-       if (out_addrs) {
-               out_addrs[0] = addr;
-               out_addrs[1] = addr + out_bytes;
-       }
+       ao_usb_enable_ep(ao_usb_epn_out(n, 0), out_addr, out_bytes);
        ao_usb_disable_ep(ao_usb_epn_out(n, 1));
 
-       addr = ao_usb_enable_ep(ao_usb_epn_in(n, 0), in_bytes * 2, 0);
-       if (in_addrs) {
-               in_addrs[0] = addr;
-               in_addrs[1] = addr + in_bytes;
-       }
+       ao_usb_enable_ep(ao_usb_epn_in(n, 0), in_addr, 0);
        ao_usb_disable_ep(ao_usb_epn_in(n, 1));
 }
 
@@ -327,6 +314,14 @@ ao_usb_reset(void)
 {
        ao_usb_set_address(0);
        ao_usb_configuration = 0;
+
+       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+       ao_usb_ep0_in_data = NULL;
+       ao_usb_ep0_in_len = 0;
+       ao_usb_ep0_in_max = 0;
+
+       ao_usb_ep0_out_data = NULL;
+       ao_usb_ep0_out_len = 0;
 }
 
 static void
@@ -341,17 +336,14 @@ ao_usb_set_ep0(void)
 
        lpc_usb.intstat = 0xc00003ff;
 
-       ao_usb_sram = lpc_usb_sram;
-
        lpc_usb.epliststart = (uint32_t) (intptr_t) &lpc_usb_endpoint;
        lpc_usb.databufstart = ((uint32_t) (intptr_t) ao_usb_sram) & 0xffc00000;
 
        /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */
 
-       ao_usb_ep0_rx_buffer = ao_usb_enable_ep(ao_usb_ep0_out(), AO_USB_CONTROL_SIZE, AO_USB_CONTROL_SIZE);
-       ao_usb_ep0_setup_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+       ao_usb_enable_ep(ao_usb_ep0_out(), ao_usb_ep0_rx_buffer, AO_USB_CONTROL_SIZE);
        lpc_usb_endpoint.setup = ao_usb_sram_offset(ao_usb_ep0_setup_buffer);
-       ao_usb_ep0_tx_buffer = ao_usb_enable_ep(ao_usb_ep0_in(), AO_USB_CONTROL_SIZE, 0);
+       ao_usb_enable_ep(ao_usb_ep0_in(), ao_usb_ep0_tx_buffer, 0);
 
        /* Clear all of the other endpoints */
        for (e = 1; e <= 4; e++)
@@ -365,10 +357,10 @@ ao_usb_set_configuration(void)
        debug ("ao_usb_set_configuration\n");
 
        /* Set up the INT end point */
-       ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, 0, NULL);
+       ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, NULL);
 
        /* Set up the OUT end point */
-       ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, ao_usb_out_rx_buffer, 0, NULL);
+       ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, ao_usb_out_rx_buffer[0], NULL);
 
        /* Set the current RX pointer to the *other* buffer so that when buffer 0 gets
         * data, we'll switch to it and pull bytes from there
@@ -376,10 +368,18 @@ ao_usb_set_configuration(void)
        ao_usb_out_rx_cur = 1;
 
        /* Set up the IN end point */
-       ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, ao_usb_in_tx_buffer);
+       ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, ao_usb_in_tx_buffer[0]);
        ao_usb_in_tx_cur = 0;
 
+       ao_usb_in_flushed = 0;
+       ao_usb_in_pending = 0;
+       ao_wakeup(&ao_usb_in_pending);
+
+       ao_usb_out_avail = 0;
+       ao_usb_configuration = 0;
+
        ao_usb_running = 1;
+       ao_wakeup(&ao_usb_running);
 }
 
 /* Send an IN data packet */
@@ -481,7 +481,7 @@ static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
 /* Walk through the list of descriptors and find a match
  */
 static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
 {
        const uint8_t           *descriptor;
        uint8_t         type = value >> 8;
@@ -495,6 +495,8 @@ ao_usb_get_descriptor(uint16_t value)
                                len = descriptor[2];
                        else
                                len = descriptor[0];
+                       if (len > length)
+                               len = length;
                        ao_usb_ep0_in_set(descriptor, len);
                        break;
                }
@@ -539,7 +541,7 @@ ao_usb_ep0_setup(void)
                                break;
                        case AO_USB_REQ_GET_DESCRIPTOR:
                                debug ("get descriptor %d\n", ao_usb_setup.value);
-                               ao_usb_get_descriptor(ao_usb_setup.value);
+                               ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
                                break;
                        case AO_USB_REQ_GET_CONFIGURATION:
                                debug ("get configuration %d\n", ao_usb_configuration);
@@ -958,6 +960,17 @@ ao_usb_enable(void)
        for (t = 0; t < 1000; t++)
                ao_arch_nop();
 
+       ao_usb_sram = lpc_usb_sram;
+
+       ao_usb_ep0_rx_buffer    = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+       ao_usb_ep0_tx_buffer    = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+       ao_usb_ep0_setup_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+
+       ao_usb_out_rx_buffer[0] = ao_usb_alloc_sram(AO_USB_OUT_SIZE);
+       ao_usb_out_rx_buffer[1] = ao_usb_alloc_sram(AO_USB_OUT_SIZE);
+       ao_usb_in_tx_buffer[0]  = ao_usb_alloc_sram(AO_USB_IN_SIZE);
+       ao_usb_in_tx_buffer[1]  = ao_usb_alloc_sram(AO_USB_IN_SIZE);
+
        ao_usb_set_ep0();
 
 #if HAS_USB_PULLUP
@@ -1001,7 +1014,6 @@ ao_usb_init(void)
 #if HAS_USB_PULLUP
        ao_enable_output(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
 #endif
-
        ao_usb_enable();
 
        debug ("ao_usb_init\n");
index 4e9d1f145cd98001e4378d3f8ea12050fc034e91..3d26466b4deee8c607d440a61e372f9e09139a5b 100644 (file)
@@ -349,6 +349,19 @@ ao_usb_set_ep0(void)
        }
 
        ao_usb_set_address(0);
+
+       ao_usb_running = 0;
+
+       /* Reset our internal state
+        */
+
+       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+
+       ao_usb_ep0_in_data = NULL;
+       ao_usb_ep0_in_len = 0;
+
+       ao_usb_ep0_out_data = 0;
+       ao_usb_ep0_out_len = 0;
 }
 
 static void
@@ -393,7 +406,15 @@ ao_usb_set_configuration(void)
                       STM_USB_EPR_STAT_RX_DISABLED,
                       STM_USB_EPR_STAT_TX_NAK);
 
+       ao_usb_in_flushed = 0;
+       ao_usb_in_pending = 0;
+       ao_wakeup(&ao_usb_in_pending);
+
+       ao_usb_out_avail = 0;
+       ao_usb_configuration = 0;
+
        ao_usb_running = 1;
+       ao_wakeup(&ao_usb_running);
 }
 
 static uint16_t        control_count;
@@ -581,7 +602,7 @@ static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
 /* Walk through the list of descriptors and find a match
  */
 static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
 {
        const uint8_t           *descriptor;
        uint8_t         type = value >> 8;
@@ -595,6 +616,8 @@ ao_usb_get_descriptor(uint16_t value)
                                len = descriptor[2];
                        else
                                len = descriptor[0];
+                       if (len > length)
+                               len = length;
                        ao_usb_ep0_in_set(descriptor, len);
                        break;
                }
@@ -639,7 +662,7 @@ ao_usb_ep0_setup(void)
                                break;
                        case AO_USB_REQ_GET_DESCRIPTOR:
                                debug ("get descriptor %d\n", ao_usb_setup.value);
-                               ao_usb_get_descriptor(ao_usb_setup.value);
+                               ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
                                break;
                        case AO_USB_REQ_GET_CONFIGURATION:
                                debug ("get configuration %d\n", ao_usb_configuration);
index ccfa3fc78d5dc4905a3e640d4058dbd11534bc7f..64311b23bf6fb6bd17ce96268776f42bcf6de484 100644 (file)
@@ -408,9 +408,6 @@ static inline void ao_arch_start_scheduler(void) {
 uint16_t *
 ao_usb_alloc(void);
 
-void
-ao_usb_free(uint16_t *buffer);
-
 void
 ao_usb_write(uint16_t *buffer, uint16_t len);
 
index 253506d59800623a5884e3f90f8814a2a19f71e4..fb3d8c85af6c56da3ce610f17f74c67a29b4298c 100644 (file)
@@ -83,7 +83,9 @@ static uint8_t        ao_usb_ep0_out_len;
 /* Buffer description tables */
 static union stm_usb_bdt       *ao_usb_bdt;
 /* USB address of end of allocated storage */
+#if AO_USB_DIRECTIO
 static uint16_t        ao_usb_sram_addr;
+#endif
 
 /* Pointer to ep0 tx/rx buffers in USB memory */
 static uint16_t        *ao_usb_ep0_tx_buffer;
@@ -362,39 +364,43 @@ ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint3
 static void
 ao_usb_alloc_buffers(void)
 {
-       ao_usb_sram_addr = 0;
+       uint16_t sram_addr = 0;
 
        ao_usb_bdt = (void *) stm_usb_sram;
-       ao_usb_sram_addr += 8 * STM_USB_BDT_SIZE;
+       sram_addr += 8 * STM_USB_BDT_SIZE;
 
-       ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
-       ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
+       ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+       sram_addr += AO_USB_CONTROL_SIZE;
 
-       ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
-       ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
+       ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+       sram_addr += AO_USB_CONTROL_SIZE;
 
 
 #if AO_USB_HAS_INT
-       ao_usb_int_tx_offset = ao_usb_sram_addr;
-       ao_usb_sram_addr += AO_USB_INT_SIZE;
+       ao_usb_int_tx_offset = sram_addr;
+       sram_addr += AO_USB_INT_SIZE;
 #endif
 
 #if AO_USB_HAS_OUT
-       ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
-       ao_usb_out_rx_offset = ao_usb_sram_addr;
-       ao_usb_sram_addr += AO_USB_OUT_SIZE;
+       ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+       ao_usb_out_rx_offset = sram_addr;
+       sram_addr += AO_USB_OUT_SIZE;
 #endif
 
 #if AO_USB_HAS_IN
-       ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
-       ao_usb_in_tx_offset = ao_usb_sram_addr;
-       ao_usb_sram_addr += AO_USB_IN_SIZE;
+       ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+       ao_usb_in_tx_offset = sram_addr;
+       sram_addr += AO_USB_IN_SIZE;
 #endif
 
 #if AO_USB_HAS_IN2
-       ao_usb_in2_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
-       ao_usb_in2_tx_offset = ao_usb_sram_addr;
-       ao_usb_sram_addr += AO_USB_IN_SIZE;
+       ao_usb_in2_tx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+       ao_usb_in2_tx_offset = sram_addr;
+       sram_addr += AO_USB_IN_SIZE;
+#endif
+
+#if AO_USB_DIRECTIO
+       ao_usb_sram_addr = sram_addr;
 #endif
 }
 
@@ -437,6 +443,17 @@ ao_usb_set_ep0(void)
        ao_usb_set_address(0);
 
        ao_usb_running = 0;
+
+       /* Reset our internal state
+        */
+
+       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+
+       ao_usb_ep0_in_data = NULL;
+       ao_usb_ep0_in_len = 0;
+
+       ao_usb_ep0_out_data = 0;
+       ao_usb_ep0_out_len = 0;
 }
 
 static void
@@ -493,6 +510,20 @@ ao_usb_set_configuration(void)
                       STM_USB_EPR_STAT_TX_NAK);
 #endif
 
+       ao_usb_in_flushed = 0;
+       ao_usb_in_pending = 0;
+       ao_wakeup(&ao_usb_in_pending);
+#if AO_USB_HAS_IN2
+       ao_usb_in2_flushed = 0;
+       ao_usb_in2_pending = 0;
+       ao_wakeup(&ao_usb_in2_pending);
+#endif
+
+       ao_usb_out_avail = 0;
+       ao_usb_configuration = 0;
+
+       ao_wakeup(AO_USB_OUT_SLEEP_ADDR);
+
        ao_usb_running = 1;
 #if AO_USB_DIRECTIO
        ao_wakeup(&ao_usb_running);
@@ -658,7 +689,7 @@ ao_usb_serial_init(void)
 /* Walk through the list of descriptors and find a match
  */
 static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
 {
        const uint8_t           *descriptor;
        uint8_t         type = value >> 8;
@@ -679,6 +710,8 @@ ao_usb_get_descriptor(uint16_t value)
                                len = sizeof (ao_usb_serial);
                        }
 #endif
+                       if (len > length)
+                               len = length;
                        ao_usb_ep0_in_set(descriptor, len);
                        break;
                }
@@ -723,7 +756,7 @@ ao_usb_ep0_setup(void)
                                break;
                        case AO_USB_REQ_GET_DESCRIPTOR:
                                debug ("get descriptor %d\n", ao_usb_setup.value);
-                               ao_usb_get_descriptor(ao_usb_setup.value);
+                               ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
                                break;
                        case AO_USB_REQ_GET_CONFIGURATION:
                                debug ("get configuration %d\n", ao_usb_configuration);
@@ -1158,14 +1191,6 @@ ao_usb_alloc(void)
        return buffer;
 }
 
-void
-ao_usb_free(uint16_t *addr)
-{
-       uint16_t        offset = ao_usb_packet_buffer_offset(addr);
-       if (offset < ao_usb_sram_addr)
-               ao_usb_sram_addr = offset;
-}
-
 void
 ao_usb_write(uint16_t *buffer, uint16_t len)
 {
index d2382a56318c3075e76f636a8cddb1164a346ff9..eb1033da7dbc34361fb6603ae27fc920a41dfeef 100644 (file)
 #define AO_CC115L_DONE_INT_PORT                0
 #define AO_CC115L_DONE_INT_PIN         2
 
+/* SN 1959, owned by J. Patrick Bowers, had a hard landing and appears to have broken the
+ * internal connection between pin 8 and the chip. This board
+ * has been fixed by jumpering pin 8 to pin 10, which means that
+ * the DONE_INT_PIN is now 4 instead of 2. When building custom firmware for
+ * this board, just adjust the ao_pins.h value before compiling
+
+ #define AO_CC115L_DONE_INT_PIN_SN_1959        4
+
+ */
+
 /*
  * Flash (M25)
  */
index 4caf43f4c3766558c05027ff980a2f3b7ae062d1..3484b951f97d49553e83f3c58eb0daf6cfae0e51 100644 (file)
@@ -42,8 +42,14 @@ JAR=telegps.jar
 
 FATJAR=telegps-fat.jar
 
+if MULTI_ARCH
+LIBALTOS_LINUX=libaltos32.so libaltos64.so
+else
+LIBALTOS_LINUX=libaltos.so
+endif
+
 LIBALTOS= \
-       libaltos.so \
+       $(LIBALTOS_LINUX) \
        libaltos.dylib \
        altos64.dll \
        altos.dll
@@ -101,7 +107,8 @@ FIRMWARE_TD_3_0=$(top_srcdir)/src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx
 FIRMWARE_TD=$(FIRMWARE_TD_0_2) $(FIRMWARE_TD_3_0)
 
 FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx
-FIRMWARE_TBT=$(FIRMWARE_TBT_1_0)
+FIRMWARE_TBT_3_0=$(top_srcdir)/src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx
+FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) $(FIRMWARE_TBT_3_0)
 
 FIRMWARE_TG_1_0=$(top_srcdir)/src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx
 FIRMWARE_TG=$(FIRMWARE_TG_1_0)
@@ -117,9 +124,8 @@ 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 \
+               altoslib_*.jar altosuilib_*.jar \
+               $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(FREETTS_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
                telegps telegps-test telegps-jdb macosx linux windows telegps-windows.log \
                telegps-windows.nsi *.desktop
 
@@ -140,7 +146,7 @@ DOC=$(TELEGPS_DOC)
 
 FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
 
-LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
+LINUX_FILES=$(FAT_FILES) $(LIBALTOS_LINUX) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
 LINUX_EXTRA=telegps-fat $(desktop_file).in
 
 MACOSX_INFO_PLIST=Info.plist
@@ -218,6 +224,14 @@ libaltos.so: build-libaltos
        -rm -f "$@"
        $(LN_S) ../libaltos/.libs/"$@" .
 
+libaltos32.so: build-libaltos
+       -rm -f "$@"
+       $(LN_S) ../libaltos/.libs/"$@" .
+
+libaltos64.so: build-libaltos
+       -rm -f "$@"
+       $(LN_S) ../libaltos/.libs/"$@" .
+
 libaltos.dylib:
        -rm -f "$@"
        $(LN_S) ../libaltos/"$@" .
@@ -230,6 +244,10 @@ altos64.dll: ../libaltos/altos64.dll
        -rm -f "$@"
        $(LN_S) ../libaltos/"$@" .
 
+../libaltos/.libs/libaltos64.so: ../libaltos/.libs/libaltos32.so
+
+../libaltos/.libs/libaltos32.so: build-libaltos
+
 ../libaltos/.libs/libaltos.so: build-libaltos
 
 ../libaltos/altos.dll: build-altos-dll
index 122b1182c1801d122fce66ff9bd39b06805094d2..2897e06a321cf6e0ac7a547e36c65a1e59985dc0 100644 (file)
@@ -24,8 +24,8 @@ import java.io.*;
 import java.util.concurrent.*;
 import java.util.*;
 import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPS
        extends AltosUIFrame
@@ -53,6 +53,7 @@ public class TeleGPS
 
        AltosFlightReader       reader;
        TeleGPSDisplayThread    thread;
+       boolean                 idle_mode;
 
        JMenuBar                menu_bar;
 
@@ -71,7 +72,7 @@ public class TeleGPS
 
        JTabbedPane             pane;
 
-       AltosUIMapNew           map;
+       AltosUIMap              map;
        TeleGPSInfo             gps_info;
        TeleGPSState            gps_state;
        AltosInfoTable          info_table;
@@ -173,7 +174,7 @@ public class TeleGPS
        }
 
        void load_maps() {
-               new AltosUIMapPreloadNew(this);
+               new AltosUIMapPreload(this);
        }
 
        void disconnect() {
@@ -186,12 +187,43 @@ public class TeleGPS
                disable_rate_menu();
        }
 
-       void connect(AltosDevice device) {
-               if (reader != null)
-                       disconnect();
+       void connect_flight(AltosDevice device) {
                try {
                        AltosFlightReader       reader = new AltosTelemetryReader(new AltosSerial(device));
-                       set_reader(reader, device);
+                       set_reader(reader, device, false);
+               } catch (FileNotFoundException ee) {
+                       JOptionPane.showMessageDialog(this,
+                                                     ee.getMessage(),
+                                                     String.format ("Cannot open %s", device.toShortString()),
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (AltosSerialInUseException si) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format("Device \"%s\" already in use",
+                                                                   device.toShortString()),
+                                                     "Device in use",
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (IOException ee) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format ("Unknown I/O error on %s", device.toShortString()),
+                                                     "Unknown I/O error",
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (TimeoutException te) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format ("Timeout on %s", device.toShortString()),
+                                                     "Timeout error",
+                                                     JOptionPane.ERROR_MESSAGE);
+               } catch (InterruptedException ie) {
+                       JOptionPane.showMessageDialog(this,
+                                                     String.format("Interrupted %s", device.toShortString()),
+                                                     "Interrupted exception",
+                                                     JOptionPane.ERROR_MESSAGE);
+               }
+       }
+
+       void connect_idle(AltosDevice device) {
+               try {
+                               AltosFlightReader       reader = new AltosIdleReader(new AltosSerial(device), false);
+                       set_reader(reader, device, true);
                } catch (FileNotFoundException ee) {
                        JOptionPane.showMessageDialog(this,
                                                      ee.getMessage(),
@@ -221,9 +253,18 @@ public class TeleGPS
                }
        }
 
+       void connect(AltosDevice device) {
+               if (reader != null)
+                       disconnect();
+               if (device.matchProduct(AltosLib.product_basestation))
+                       connect_flight(device);
+               else
+                       connect_idle(device);
+       }
+
        void connect() {
                AltosDevice     device = AltosDeviceUIDialog.show(this,
-                                                                 AltosLib.product_basestation);
+                                                                 AltosLib.product_any);
                if (device == null)
                        return;
                connect(device);
@@ -397,7 +438,8 @@ public class TeleGPS
 
        }
 
-       public void set_reader(AltosFlightReader reader, AltosDevice device) {
+       public void set_reader(AltosFlightReader reader, AltosDevice device, boolean idle_mode) {
+               this.idle_mode = idle_mode;
                status_update = new TeleGPSStatusUpdate(telegps_status);
 
                telegps_status.start(status_update);
@@ -407,8 +449,13 @@ public class TeleGPS
                thread.start();
 
                if (device != null) {
-                       enable_frequency_menu(device.getSerial(), reader);
-                       enable_rate_menu(device.getSerial(), reader);
+                       if (idle_mode) {
+                               disable_frequency_menu();
+                               disable_rate_menu();
+                       } else {
+                               enable_frequency_menu(device.getSerial(), reader);
+                               enable_rate_menu(device.getSerial(), reader);
+                       }
                }
        }
 
@@ -520,7 +567,7 @@ public class TeleGPS
                /* Make the tabbed pane use the rest of the window space */
                bag.add(pane, constraints(0, 3, GridBagConstraints.BOTH));
 
-               map = new AltosUIMapNew();
+               map = new AltosUIMap();
                pane.add(map.getName(), map);
                displays.add(map);
 
@@ -554,9 +601,9 @@ public class TeleGPS
                add_window();
        }
 
-       public TeleGPS(AltosFlightReader reader) {
+       public TeleGPS(AltosFlightReader reader, boolean idle_mode) {
                this();
-               set_reader(reader, null);
+               set_reader(reader, null, idle_mode);
        }
 
        public TeleGPS(AltosDevice device) {
@@ -602,7 +649,7 @@ public class TeleGPS
                if (new_reader == null)
                        return false;
 
-               new TeleGPS(new_reader);
+               new TeleGPS(new_reader, true);
                return true;
        }
 
index daef1cac5f031f284ae29cfc042884167376b71e..f8bb1cf18f754b34d1e87f60725d14d596a66c3f 100644 (file)
@@ -22,8 +22,8 @@ import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSConfig implements ActionListener {
 
index 0f8a3d25756351c1301098a24fecc7d18e410c4d..fcba619526b564c99d29abe9797a492c9d863eec 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSConfigUI
        extends AltosUIDialog
@@ -854,7 +854,7 @@ public class TeleGPSConfigUI
        }
 
        String get_tracker_motion_label() {
-               return String.format("Logging Trigger Motion (%s):", AltosConvert.height.show_units());
+               return String.format("Logging Trigger Motion (%s):", AltosConvert.height.parse_units());
        }
 
        void set_tracker_tool_tip() {
index e44b4fedd5d81d477d96b3b58bd0c7f7452ffafa..0daccc20108a3eb93d54185a62fa4efa31e58383 100644 (file)
@@ -21,8 +21,8 @@ import java.awt.*;
 import javax.swing.*;
 import java.io.*;
 import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSDisplayThread extends Thread {
 
index 233c8c1ae475b8cbbe3473eb92399d76f2d4033e..8e2f6627d8a369d98f60157478d1452964fe52d6 100644 (file)
@@ -26,8 +26,8 @@ import javax.swing.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 import org.jfree.chart.ChartPanel;
 import org.jfree.chart.JFreeChart;
@@ -38,7 +38,7 @@ public class TeleGPSGraphUI extends AltosUIFrame
        JTabbedPane             pane;
        AltosGraph              graph;
        AltosUIEnable           enable;
-       AltosUIMapNew           map;
+       AltosUIMap              map;
        AltosState              state;
        AltosFlightStats        stats;
        AltosGraphDataSet       graphDataSet;
@@ -69,7 +69,7 @@ public class TeleGPSGraphUI extends AltosUIFrame
                graph = new AltosGraph(enable, stats, graphDataSet);
                statsTable = new AltosFlightStatsTable(stats);
 
-               map = new AltosUIMapNew();
+               map = new AltosUIMap();
 
                pane.add("Graph", graph.panel);
                pane.add("Configure Graph", enable);
index 590f1d1acafdeb95cc14142b3089442ece7cec67..e17bdbaaae5aef0c1d065be706c063e4e8fb9f40 100644 (file)
@@ -21,8 +21,8 @@ import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSInfo extends AltosUIFlightTab {
 
index c03b42d32eabb73f58421ec8ef45bda626b7f29b..2a5b2b69e3f9295fbde4f3aee21ece137d07e73f 100644 (file)
@@ -22,7 +22,7 @@ import java.awt.event.*;
 import java.beans.*;
 import javax.swing.*;
 import javax.swing.event.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSPreferences
        extends AltosUIConfigure
index 46e48fc43d697e5d05b33105a304ebc6350bea16..e01ef47e46e64d12bb32e14051adba8b91908d6e 100644 (file)
@@ -21,8 +21,8 @@ import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSState extends AltosUIFlightTab {
 
@@ -136,10 +136,13 @@ public class TeleGPSState extends AltosUIFlightTab {
 
        class FlightLogMax extends AltosUIIndicator {
                public void show(AltosState state, AltosListenerState listener_state) {
-                       if (state.flight_log_max == AltosLib.MISSING)
+                       int storage = state.flight_log_max;
+                       if (storage == AltosLib.MISSING)
+                               storage = state.log_space >> 10;
+                       if (storage == AltosLib.MISSING)
                                show("Missing");
                        else
-                               show(String.format("%dkB", state.flight_log_max));
+                               show(String.format("%dkB", storage));
                }
 
                public FlightLogMax(Container container, int y) {
index 81a1b305d062cfb757e09f1040bd5bf1e2a82409..765a8ce4f6e0e62985dd2f26110b9435116dc3f5 100644 (file)
@@ -19,8 +19,8 @@ package org.altusmetrum.telegps;
 
 import java.awt.*;
 import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
 
 public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
        GridBagLayout   layout;
index 6740ff70b912ec8d483bfc7da9da1386abab2b00..6cd440c54b2c86f1141f2585edeee4aab6f44e02 100644 (file)
@@ -18,7 +18,7 @@
 package org.altusmetrum.telegps;
 
 import java.awt.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
 
 public class TeleGPSStatusUpdate implements ActionListener {