Compare commits

..

130 Commits

Author SHA1 Message Date
Gareth Coco
c436ff4305 Website updates to release version 2.1.0 2012-03-06 17:16:46 -05:00
Gareth Coco
abb7ab9869 Added v2.0.0 information. 2012-03-05 10:21:49 -05:00
Gareth Coco
5d5054d64d Update documentation 2012-03-05 09:50:55 -05:00
Mark Liversedge
d70cf5aae4 Merge branch 'master' of github.com:/srhea/GoldenCheetah 2012-02-12 19:18:29 +00:00
Damien
6e0f769b26 Correct intialisation of altitude for TCX without altitude
modified:   src/TcxParser.cpp
2012-02-12 19:17:46 +00:00
Damien
86fa671858 Correct intialisation of altitude for TCX without altitude
modified:   src/TcxParser.cpp
2012-02-12 09:51:54 -05:00
Damien
7fcc83f62c Change speed to double in Bin parser
Fixes #636.
2012-02-11 12:32:49 +00:00
LukeNRG
fff37e524c German Translations 2012-02-05 10:47:22 -05:00
Mark Liversedge
ab03dd3637 Fix SEGV on empty/dodgy FIT files
Fixes #633.
2012-02-05 10:31:59 -05:00
Mark Liversedge
1ad2228b84 Fix PWX file intervals
Fixes #624.
2012-02-03 19:37:00 +00:00
Gareth Coco
57fbf65b23 v2.1dev - Allow ride to be added with no Average HR
Removed setPlaceholderText("") as not in Qt4.6.x
Replaced tabs with spaces

Fixes #626
2012-02-02 11:02:12 -05:00
gcoco
d6ba7b0cb3 Merge pull request #8 from gcoco/master
Fixes for Manual Ride Dialog
2012-02-01 07:12:18 -08:00
Gareth Coco
3ad5401b0b Comment added and replace tabs with spaces 2012-02-01 10:10:12 -05:00
Gareth Coco
d9e54c2be0 Fixes for Manual Ride Entry
Includes:
- Resize dialog for Mac users to display all fields
- Modify display of data in fields
- Add Average HR check
- Base code formatting to remove tabs

Fixes #622
2012-01-31 23:18:07 -05:00
Gareth Coco
eeadc688bf Ordered build - qwt then src 2012-01-31 15:18:38 -05:00
Damien
ed9baf6fa3 Update french translation for rho estimator
modified:   src/translations/gc_fr.qm
	modified:   src/translations/gc_fr.ts

Fixes #616
2012-01-31 13:47:51 -05:00
Alejandro Martinez
3115bec92f Rho Estimator Translation 2012-01-27 15:32:48 -05:00
Gareth Coco
2294b85e3b Update translation files 2012-01-26 13:19:16 -05:00
Gareth Coco
d1a1d56d6f Allow CdA to lowest possible in AerolabWindow.cpp
Fixes #475
2012-01-26 12:59:12 -05:00
gcoco
cd576a4e27 Merge pull request #7 from rodericj/patch-1
There was what looked like a copy paste error. I changed the zone 7 labe...
2012-01-26 07:12:18 -08:00
Steven Gribble
03a221c558 This patch adds an air density (rho) calculator feature to GoldenCheetah.
Users supply the estimator with measurements of temperature,
air pressure, and dew point, and the estimator uses Herman Wobus'
model for vapor pressure, plus the standard equations for
calculating air density, to estimate Rho. This feature is
useful for dialing in the Rho value in aerolab.

The patch hooks the estimator into the Tools menu as another dialog
box, similar to the CP estimator that's also under the tools menu.
2012-01-26 09:27:56 -05:00
Mark Liversedge
9ed9f7a6d0 Fix crash if TRIMP zones > 5
Fixes #483.
2012-01-24 16:23:59 -05:00
Jamie Kimberley
a78bd5d919 update French Translation
William Juban noted that we are incorrectly translating "Peak" as "Pique".
I have changes all occurences to the correct tranlation "Pic".

Fixes #613
2012-01-23 09:11:37 -05:00
Roderic Campbell
e4ece50af2 There was what looked like a copy paste error. I changed the zone 7 label to the appropriate 7 instead of 1 2012-01-22 16:49:37 -08:00
Jamie Kimberley
7611a44a54 Add other TRIMP metrics to performance manager.
Add the ability to use the TRIMP 100 and TRIMP ZONAL metrics in the
performace manager.

Fixes #535.
2012-01-22 15:42:28 +00:00
Gareth Coco
8e43eb31aa Fix interpolation of lat/lon when missing or 0/0
Fixes #597.
2012-01-22 14:55:00 +00:00
Mark Liversedge
a3f643e11c Support TrainerRoad.com TCX Files/Tcx speed in meters/sec The TCX parser ignored samples where distance is zero even when speed and time are available.
This broke reading files from TrainerRoad.com.
Thanks to Walter Bürki for pointing out speed is m/s and not km/h

Fixes #580 & #598.
2012-01-20 00:58:01 -05:00
Gareth Coco
d348344e0e Add a TCX ride exporter 2012-01-19 23:35:29 -05:00
LukeNRG
7b0fa7680d Updated German Translations 2012-01-19 23:35:19 -05:00
Mark Liversedge
565ba3f219 Fix zero speed in TxtRideFile for Imperial units
When importing files with imperial units the importer
does not set distance data and the speed is reset to zero.

This patch fixes that.
Please enter the commit message for your changes. Lines starting
2012-01-17 15:58:31 -05:00
Damien
db2b68bd9d Remove Joule warnings
Remove warnings for new format identifiers in the last Joule firmware.

Fixes #524
2012-01-17 15:41:36 -05:00
Mark Liversedge
d746dde5a3 Disable roch text in metadata
It causes significant performance issues when pasting complex font information,
we only allow plain text since we only serialise the plain text elements anyway.

Fixes #599.
2012-01-17 15:41:30 -05:00
Damien
ac43bccd6f Correct bug #496 for longitude < -65
Fixes #496.
2012-01-17 15:40:40 -05:00
Damien
ac2e202af4 Correct encoding in json parser
Fixes #408.

	modified:   src/JsonRideFile.y
2012-01-14 20:11:23 -05:00
Mark Liversedge
b107c4a1e6 FitRideFile distance of zero bug
Fit ride file contains samples where the distance
is set to zero, even if the previous sample is
non-zero.

The parser has been adjusted to keep the previous
distance used when a zero value is encountered.

Fixes #544.
2012-01-12 13:17:10 -05:00
Thomas Irps
dcb441b7e5 Portuguese translation 2011-12-22 10:24:41 -05:00
Gareth Coco
dae942a2f7 Add a Portuguese translation 2011-12-22 10:24:35 -05:00
Mark Liversedge
97cedad044 Add Virtual Power for 1UP USA bike trainer
Fixes #560.
2011-12-22 09:38:15 -05:00
Mark Liversedge
8fec614a5e Forward support in .json for temp/slope
But it will be unused in v2.1 since there is nowhere
to store the data. But at least the json parser won't
break.
2011-12-03 23:33:59 +00:00
David
5463be1a2f Updated Czech translations 2011-11-28 13:57:14 -05:00
Gareth Coco
e2e063015e Updated Spanish Translation
Co-authored by:

  Alejandro Martinez <amtriathlon@gmail.com>
  Arturo <argmac@gmail.com>
2011-11-28 09:56:12 -05:00
LukeNRG
7b7ff9622e Updated German Translation 2011-11-28 09:55:32 -05:00
Mark Liversedge
cd6b86c3eb Better Bounds Checking in RideFile::intervalBegin()
Return value when out of bounds had a fencepost error. Annoyingly
it is exactly the same fencepost error that was fixed in a line
of code 10 lines lower in the source.

This fixes rare issues with rides where intervals start at the
end of the ride file. This can happen with rides that have been
split.
2011-11-28 09:29:07 -05:00
Gareth Coco
b01c007ed2 Initialise LAT/LON to zero (0.0) in the parser
If there is no LAT/LON data often GC will set really small numbers
to LAT/LON which the map functions will try to map.

Fixes #522
2011-11-25 20:57:39 -05:00
Mark Liversedge
acdde3e02a Merge branch 'master' of github.com:/srhea/GoldenCheetah 2011-11-25 16:56:28 +00:00
Mark Liversedge
6b07997791 Fix FTDI Adaptor on Linux and Mac
Eric Brandt provided a fix for the new FTDI adaptor
sold with Computrainers from late 2009. It only fixed
the problem under Windows.

This fix applies the same modification to turn off
hardware flow-control for Linux and Mac.

Fixes #523.
2011-11-25 16:44:23 +00:00
Mark Liversedge
440a0b8404 Use strtod() to convert text to double
To get improved precision when parsing pasted
data in the ride editor.

Fixes #477.
2011-11-22 10:04:11 -05:00
Gareth Coco
d3f16313bb Fixes for RealtimeController
Adds in missing breaks.
Set power to zero when no cadence.

All this from v3 code base.
2011-10-27 23:14:03 -04:00
Mark Liversedge
fa0aa3fd75 Add virtual power for LeMond Revolution
The LeMond revolution trainer has been analysed in
some depth by Tom Anhalt and as a happy by-product
idenitfied the power/speed curve.

Since Darren Hague had already added the ability to
approximate power from Speed when training on a turbo
this patch extends that to include the LeMond device.

All the analysis Tom performed can be read over on
wattagetraining.com here:
http://wattagetraining.com/forum/viewtopic.php?t=335

Fixes #498.
2011-10-27 23:13:44 -04:00
Mark Liversedge
0d811ba4ba Updated translation files.
To include latest translations and also the update
from Keisuke Yamaguchi.

Fixes 489.
2011-10-26 16:50:55 +01:00
Mark Liversedge
9dff6e0cf6 Summary fixups
* Show time in zone as a percent
* Annotate heading to show units

Fixes #473.
Fixes #474.
2011-10-11 20:48:46 -04:00
Mark Liversedge
b04e308d9f Check Date/Time unique
Issue a warning if the user changes the ride date/time
to the same as an existing ride.

They can still go ahead, but when saving it will overwrite
the existing file.

Fixing the save routines to check would require significant
refactoring and can be fixed at a later date.

Fixes #466.

[code refactored from commit dfaf151 release3 and folded in manually]
2011-10-06 20:09:02 +01:00
Mark Liversedge
63fe2fb443 Merge branch 'master' of github.com:/srhea/GoldenCheetah 2011-10-06 19:02:55 +01:00
Mark Liversedge
34001d30b5 Fix Split Ride file loss bug
In some instances split ride will refuse to overwrite existing
ride files (where they have the same date/time). This patch
increments the start time by one (or more) seconds to ensure
there is no conflict.

Fixes #165.
2011-10-06 19:00:02 +01:00
Keisuke Yamaguchi
769fd633e2 Update Japanese translation files
Fixes #459
2011-09-28 22:27:53 -04:00
Gareth Coco
eb456cee63 Update gc_fr.qm for updated French translation 2011-09-14 21:57:11 -04:00
lemaitre
afe4710bf5 Updating of the French translation
Updating of the French translation file ts
2011-09-14 21:56:35 -04:00
Gareth Coco
b977abffcc Update translation .qm files
Needed for the translation changes from #451
2011-09-13 16:23:20 -04:00
Alejandro Martinez
8e1ec66820 Enable 3d Plot Translation and include spanish translation
Fixes #451
2011-09-13 16:22:29 -04:00
Gareth Coco
adc8430e0e Changed KPH to km/h in displays
To match International Standards
2011-09-13 12:51:10 -04:00
Gareth Coco
65109d95fd Changed kph to km/h in displays
International standards show metric speed as km/h
2011-09-13 11:57:35 -04:00
Mark Liversedge
189f11d80f Revert "SplitRide overwrites existing file"
This reverts commit 183564d1ea.

Small risk of losing data, reverting to previous behaviour.
2011-09-07 07:01:00 +01:00
Mark Liversedge
183564d1ea SplitRide overwrites existing file
Fixes #165.
2011-09-02 18:20:52 +01:00
Jamie Kimberley
076190161f clean up wishlist web page 2011-09-01 11:45:57 -04:00
Jamie Kimberley
f43a71f3a4 Update user guide steps 1 and 2
Updated the user guide to reflect the fact taht the FTDI drivers are
optional for most systems.  Changed the instructions for linux install to
reflect that we are now distributing gzipped archives.  I also added a in
page link to the wiki.

Fixes #259
2011-09-01 11:44:08 -04:00
Mark Liversedge
c383ee75fb Merge branch 'master' of github.com:/srhea/GoldenCheetah 2011-08-30 22:26:04 +01:00
Mark Liversedge
e0711b4bb7 Fix Download Ride Dialog instructions refresh
When changing the device type in the Download
Ride dilaog the instructions do not change to
reflect the device selected. This patch fixes
that.

Fixes #434.
2011-08-30 22:23:22 +01:00
Gareth Coco
5ce1617667 Comment out QwtDesigner build in qwtconfig.pri.in 2011-08-30 10:32:01 -04:00
Alejandro Martinez
0091defb6c Update Spanish Translation
- Summary Metrics
 - Move up/Move down/Include/Exclude Buttons in Metric Selection
 - Hr Peak Power xx min
 - Macro download instructions
 - Elevation Offset in Aerolab
2011-08-30 10:21:50 -04:00
Gareth Coco
3d93c0ca52 Reorder liboauth includes
Depending on how libcurl is built, it must appear before libcrypto
2011-08-29 12:31:28 -04:00
Jamie Kimberley
8fcbe81daf force use of no elide and scrollbars in main tab
depending on the style used on a given system the text in the tab bar for
selection of different charts (summary, ride plot...) may be elided on
screens with small resoulution.   This overrides the use of scrollbars
which is set  explicitly in the code. this one line patch forces the use of
non-elided text in the the tabs so that scroll bars appear.
2011-08-28 23:14:02 +01:00
Mark Liversedge
524ab81a08 Fix FitRideFile for header change
The header size in FitRideFile has increased from
12 to 14 bytes, but the new field is at the end of
the header, not in the middle.

Additionally, there is a new global record (79) which
we now silently ignore.
2011-08-27 23:52:56 +01:00
Mark Liversedge
ad9a76a172 Support FR310xt latest firmware
Fit file format can now have a 12 and 14 byte header. This
patch adds support for 14 byte headers since this is required
by the latest 310xt firmware.

Fixes #430.
2011-08-27 09:07:45 +01:00
Damien
5b838d99c2 Correct bug in the peakPowerHr formula 2011-08-23 23:24:18 -04:00
Damien
b7bfb98dc8 Aerolab : Change LCD display to LineEdit
Also fixes v3 crash when changing CdA.

Fixes #423.
2011-08-23 22:18:24 +01:00
Mark Liversedge
7352245a91 Fix Macro device data crash
If you attempt to download from a Macro device
and use wrong device or initial read fails then
it crashes, this patch fixes that.

It does not fix more general data errors but should
at least mean incorrect user selections do not result
in GC crashing.

Fixes #366.
2011-08-21 21:16:41 +01:00
Mark Liversedge
bfa68faeda Update .gitignore for Lex/yacc
Ignore temporary files generated when lex
and yacc generate parsers from a grammar.
2011-08-21 16:51:18 +01:00
Mark Liversedge
95d6a40ecd Fix date/time handling when importing rides
The ride import wizard would only allow the user to
change the ride date/time if it was a .gc .json or
.csv file. This was (wrongly) because we could not
update the date/time defined within the ride file itself
(we cannot write in other formats e.g. wko).

Of course, we encode the ride date/time in the filename
and so it could be changed. However, not all the RideFile
readers supported this.

To get around this, the import wizard now does let you
change the date and time for any file type and the ride
file factory method openRideFile() will override whatever
date and time is returned by examining the filename. The
user needs to double click the date or time to edit it.

Additionally, the select date... combo would only register
when you changed the selection, it now defaults back to
the 'select date..' option after each selection.

Lastly, the 'choose date' function now works as advertised
and triggers editing the date for the ride selected.

[commit cd86521 cherry picked into master from release_3.0.0dev]

Fixes #11
2011-08-21 15:43:06 +01:00
Mark Liversedge
3a4b782a16 Merge branch 'master' of github.com:/srhea/GoldenCheetah 2011-08-21 15:17:45 +01:00
Mark Liversedge
7331775e40 Add JSON support to v2.1
Patch to allow v2.1 to read v3.1 .json ridefiles.

Version 3 introduces a new GC file format
using Javascript object notation (json). In
version 3 files are written in this format
as a local, native format thus deprecating the
XML .gc notation.

This backport to 2.1 does not;
* write in json format, it just reads files
* set RideFile::rideId, since it is not present in v2

To build you will need lex/yacc (or flex/bison) the
instructions are within gcconfig.pri.in but are the
same as for version 3.

Fixes #395.
2011-08-21 15:12:01 +01:00
Damien
0c7abe9755 Modify Aerolab to add interval highlight and zoom + auto offset
Fixes #241
Fixes #147
2011-08-17 13:50:08 -04:00
Mark Liversedge
9ab5fb26e2 Guess ride date time for Poweragent CSV files
File name is in the format "name yyyy-mm-dd hh-mm-ss.csv".

[cherry picked into master from c08dae in release_3.0.0dev]

Fixes #281.
2011-08-07 22:53:30 +01:00
Mark Liversedge
a641ec7e0a Fit files sometimes go backwards
FIT record type '253' occasionally causes time to go
backwards, this might be a decoding error, but for now
we force time to go forward anyway.

Looking at bad files GPS data with this patch suggests
this is the correct behaviour.

Fixes #104.
2011-08-06 17:58:12 +01:00
Damien
c513a47e07 Modify TRIMP formula to use time_riding instead of workout time
Fixes #355.
2011-08-06 12:08:44 +01:00
Mark Liversedge
a562d2f73b Fix LogY Intervals on Histogram
The LogY function for histograms was overlooked
when implementing intervals. The baseline and
start/end values of the interval curve needed to
be set to non-zero values to match the main curve.

Fixes #396.
2011-08-06 11:48:18 +01:00
Damien
dfbb1c29f8 Correct interval 2011-08-05 22:40:05 +01:00
Damien
b0cca3c2fa Modification to handle odd start page and compatible with qt 4.6 2011-08-05 17:01:16 +01:00
Damien
8c2eac427b Add a setFocus on the Treelist to correct a MacOs Bug of Qt
Fixes #255.
2011-08-05 15:14:38 +01:00
Mark Liversedge
880c97c639 Don't allow Nan or Inf sample values
I thought this was introduced previously and was not. When
appendPoint adds a new sample it now sets non-finite values
to zero.
2011-08-05 15:03:34 +01:00
Mark Liversedge
614f267a5e Merge branch 'master' of github.com:/srhea/GoldenCheetah 2011-08-05 14:54:37 +01:00
Mark Liversedge
14f7924c28 Fix SummaryWindow crash
When a large number of intervals are defined (>50 or so)
then the RideSummary window crashes.

It appears to be a bug in QTextEdit. It does a double free
when setHtml is called, after a 'large' text item was
set. It may be a QString bug.

To avoid the issue we use a QWebView instead of a QTextEdit
to display the summary and then try and set fonts to match
the application.

[cherry-picked and merged from release_3.0.0dev]
2011-08-05 14:53:58 +01:00
Gareth Coco
7a501a9699 Make interval period on map user defineable
Previously the map track was broken up into 30 second intervals.
This patch allows the user to define a time interval they want.

Fixes #273
2011-08-04 23:30:36 -04:00
Mark Liversedge
f1238fcce6 Fix Save when old .bak exists
If you save a ride and then delete it. The re-import and save
you will end up with two copies of the ride in the ride list.

This is because when we save the first time the original file
is renamed to e.g. ride.tcx.bak and the new ride.json is then
created. All is well.

But then delete the ride and it will rename ride.json to
ride.json.bak. Again, All is well.

Now, re-import the ride. We now have; ride.tcx.bak and
ride.json.bak and ride.tcx. Again, all is well.

But now, if you make changes and save it will attempt to
rename ride.tcx to ride.tcx.bak AND FAIL. This is because
the old ride.tcx.bak file is there. It will then create
ride.json. All is NOT well, since we have two rides with
the same date and time but different extensions.

This patch fixes this by unlinking ride.ext.bak before
trying to rename the file.

[folded in manually from commit #1d135a in branch release_3.0.0dev]
2011-08-03 20:19:19 +01:00
Mark Liversedge
4784408106 Fix annoying gap in CP curve. 2011-08-03 14:25:24 -04:00
Damien
182208c145 Bug #178 TRIMP is not updated after modification in Rest Hr Tag -> compute metric after save
Fixes #178
2011-08-03 13:59:51 -04:00
Mark Liversedge
00959bed8c Better support for Negative, Inf, NaN and High Values
Some ride file formats use -1 to indicate sensor not
present or data loss (e.g. TPX) and on occasion a NaN
or Infinite value will be presented.

This patch handles this by converting negative data sample
values to zero and handling out of bounds values when
selecting zone ranges.

This is not a substitute for better handling of poor ride
data but it reduces the effect.

Also fixes #311.
2011-08-03 13:40:20 -04:00
Mark Liversedge
57c7260a19 Fix .man crash in CP plot
Old .man files contain insufficient data to
compute a CP curve and caused an array bound
crash.

Fixes #205.
2011-08-02 02:14:57 +01:00
Mark Liversedge
a70cf8ebc0 Fix RideEditor find dialog for 'between'
The find dialog expected the between values
to be small and high, this patch will find
values between regardless of whether the
search values are lo/hi or hi/lo.

Fixes #351.
2011-08-01 23:52:36 +01:00
Frank Zschockelt
0f9b82a750 Included 4 sample sigma files in the test/rides directory 2011-08-01 23:41:30 +01:00
Frank Zschockelt
8cca3c088a Support for Sigma SLF/SMF file formats
A ridefile reader for Sigma .slf/.smf format files.

Fixes #90.
2011-08-01 23:39:54 +01:00
Mark Liversedge
d84ffec0a6 Fix RideSummaryWindow crash
The recent patch to allow users to configure which
metrics to display on the ride summary window is not
forwards compatible. If metrics referenced no longer
exist (i.e. they are from a future release or have
been deprecated) GC will crash.
2011-08-01 23:36:49 +01:00
Damien
20477e1670 Altitude scale present with no altitude data.
Uncheck the channel if not present. Fixes #295.
2011-08-01 22:17:20 +01:00
Mark Liversedge
610b2ea2d0 Remove console error for seasons.xml
There is no need to warn about seasons.xml missing, it
is quite acceptable to have none set. Worse still sending
to the console log is next to useless for users that
don't launch from the command line.

Partial cherry pick from 4972f2472e (v3.0.0dev)
2011-08-01 13:22:23 -04:00
Mark Liversedge
e7a7803f09 Fix WKO+ file reader GPS 'drops'
The WKO+ file format appears to record drops in
recording of GPS data with a latlon of 180,180. We
expect this to be 0,0.

This makes the WKO+ file reader consistent with the
GoogleMapControl and removes the need to clean data
there.

If it is found that 180,180 is the standard way of
recording drops in GPS signal then we can change the
code. We use 0,0 since it is conveniently at sea off
the west coast of Africa.

Cherry pick d06c9e97c9 (From v3.0.0dev)
2011-08-01 13:14:31 -04:00
Damien
c6a376b89f Add PeakPowerHr metric (average HR during peak power) 2011-07-28 21:12:20 +01:00
Damien
65c4d89890 Correct crash with truncated files
Fixes #337
Fixes #354
2011-07-28 12:41:55 -04:00
Rainer Clasen
1674558dbb FitRideFile: turned assertions into graceful fail
reading Fit files with Smart recording and a certain pattern of timestamps
could cause assertions. This shouldn't happen, as it's no Programming error.

Changed the checks into graceful failures.

Unfortunatly I don't have any files to test this.

fixes #364
2011-07-25 14:07:14 -04:00
Rainer Clasen
ee79a86c1f SrmRideFile: turned assertions into graceful fail
reading unsupported SRM files caused assertions. This shouldn't happen, as
it's no Programming error.

Changed the checks into graceful failures.

fixes #364
2011-07-25 14:07:07 -04:00
Mark Liversedge
92897a966b Better rounding of time in AllPlot
With realtime data there will often be samples with
timestamps like 940.002 and 940.998. This cuases an
issue on the ride plot, where it believes there is
no sample for 941 and therefore plots a zero value.

This patch rounds the timestamps to the nearest 100th
of a second, which is consistent with the mechanism
used in the ride editor.
2011-07-24 21:36:21 -04:00
Damien Grauser
ca1c4def3a O_Sync Macro X device support
Adds support for the Macro X bike computer for downloading rides
and reading/writing in the native file format (sync).

For more information on this new bike computer see:
http://www.o-synce.com/en/products/bike/macro-series/macrohigh-x.html

Fixes #357.
2011-07-24 10:44:46 +01:00
Damien
05346eda24 Add summary metrics list to preferences
Fixes #317.
2011-07-23 17:41:37 +01:00
Rainer Clasen
bea79092ab Fit: handle unknown fields gracefully
So far the FIT parser bailed out, whenever it found something
unknown/uninterested to GC. This is quite orthogonal to the FIT design, as
it's supposed to be extended.

renamed read_<foo> functions to match the FIT base_type names.

unified handling of "unavailable/invalid" values - i.e. if sensor data is
temporary unavailable. This allows easier and consistent handling -
especially for the uintXz base_types, which only differ by a different
"invalid" value. Had to change the type of the "values" list to int64 to
fit uint32/int32, as well.

added proper support for signed integer types. I'm wondering, why lon, lat
+ temperature were decoded properly...

added support for currently unsupported base types by just skipping their
bytes. This allows us to continue reading.
2011-07-23 13:57:49 +01:00
Rainer Clasen
e478c24650 Fit: support big/little endian data
... on both, big and little endian machines.

Fit reader only supported little endian data on little endian machines.

All values read from FIT files are now swapped (if neccessary) according
to file and system endianess.

fixes #287
2011-07-23 13:57:49 +01:00
Rainer Clasen
96bb21d04d Fit: ignore unknown message types
do not bail out on unknown message types. This violates the design of the
Fit format of being extensible.

As this was the last thing using the global_msg_names QMap, I've nuked
this, aswell.
2011-07-23 13:57:49 +01:00
Alejandro Martinez
65615295c2 Add HrZones to Weekly Summary and Fix Spanish Translation
Fixes 344.
2011-07-23 12:09:18 +01:00
Rainer Clasen
b21d24039c fix reading signed values from srm files
seems, the assumption for "speed" in SRM7 files being unsigned was wrong.
Powercontrol/SRMWIN seem to use negative speed as "invalid".

Furthermore altitude may become negative, as well.

To address this, QDataStream now does the bit-swapping and speed +
altitude are read as signed values.

Fixes 346.
2011-07-23 12:08:56 +01:00
Rainer Clasen
c25f920062 whitespace cleanup
unfortunatly my latest patches introduced some tabs. Replaced them with
spaces to meet GC indent style.

Fixes 347.
2011-07-23 12:08:56 +01:00
Alejandro Martinez
7f2b6dd793 Set UTF-8 in charts,metadata and seasons xml files
Fixes 345
2011-07-23 12:08:56 +01:00
Damien
148390ea61 handle showHr/Speed/Cad/Alt state for stacked view
Fixes 130.
2011-07-23 12:08:56 +01:00
Gareth Coco
c525a36ea5 Change start date from UTC to localtime for bin ride file
Fixes 338.
2011-07-23 12:08:56 +01:00
Damien Grauser
627595175f Update French translation. 2011-06-07 22:31:47 +01:00
Alejandro Martinez
09365a8b24 Add Spanish Translation & Fix Translation Issues
This patch:
* Add Spanish Translation
* Enable default Zone Descriptions Translation
* Enable Color Selection Translation
* Enable PM Metrics and Metric Detail Dialog Translation
* Enable Data Processor Translation
* Enable Metrics Translation
* Enable Metadata Translation
* Enable Several Incomplete Translations
* Add default lang selection based on locale
* Fix Trend-Watts translation Add units default
* Translate Download Instructions
* Add default charts translation

Notes:
1. If ENABLE_METRICS_TRANSLATION is defined, the code setting metric names
   and units is moved from constructors to initialize method, to be called
   after translator initialization, English Name is preserved as InternalName
   for metadata.xlm compatibility in metric override.

2. Q_DECLARE_TR_FUNCTIONS(class-name) macro is used to set tr() context
   when class-name is not QObject sub-class.
2011-06-05 17:46:46 +01:00
Mark Liversedge
8ae7a3f738 Fix WKO parser for Ergomo users
The WKO ride file reader used wrong constants for the bit
field size of the sample data when decoding files from
Ergomo devices.

Fixes #335.
2011-05-25 20:04:19 +01:00
Mark Liversedge
2ef0533ec3 Revert "Add Spanish Translation and Enable Metrics Translation"
This reverts commit 1fbaeae611.

Accidentally pushed to the main repository along with recent
patch fixups. Ale is working on a complete solution for
supporting translations in metrics, metadata and configuration
settings. This patch was an initial version and should not
have been pushed to master.
2011-05-23 21:37:08 +01:00
Mark Liversedge
b7632a4173 Fix Virtual Power for Fluid2
Fix was applied to v3 but not v2, an oversight on my part.
The patch is now applied to the current master for v2 users.

Fixes #270.
2011-05-23 21:09:51 +01:00
Mark Liversedge
29fa978b8f Fix Wko GPS parsing on 64bit
This bug recently fixed in v3 is also present in the
v2 code.

Fixes #214.
2011-05-23 20:24:57 +01:00
Alejandro Martinez
1fbaeae611 Add Spanish Translation and Enable Metrics Translation
Add Spanish Translation.
If ENABLE_METRICS_TRANSLATION is defined, the code setting metric names
and units is moved from constructors to initialize method to be called
after translator initialization and QObject::tr(s) calls are replaced by
QApplication::translate("class name",s) to set appropiate context.
Metric symbol is used for symbol override instead of metric name.
2011-05-17 19:28:56 +01:00
Tim Shaffer
d91337e18d Make the default date range for Performance Manager a user preference. 2011-03-02 21:07:50 +00:00
Gareth Coco
88967c1588 Set default Smoothing (secs) in Ride Plot to one (1) second
Fixes #145
2011-03-01 21:30:12 +00:00
Mark Liversedge
dd7af03785 Updated Czech translation
Thanks to David Kramar for an updated version of the
Czech translation files. This provides 100% of texts
translated.
2011-03-01 21:08:31 +00:00
1952 changed files with 75534 additions and 1661281 deletions

25
.gitignore vendored
View File

@@ -1,33 +1,8 @@
Makefile
.qmake.stash
# old skool
.svn
*.pri
# osx noise
.DS_Store
profile
moc/
obj/
lib/
bin/
plugins/
resources/
src/debug/
src/release/
qwt/src/debug/
qwt/src/release/
src/Makefile.Debug
src/Makefile.Release
src/object_script.GoldenCheetah.Debug
src/object_script.GoldenCheetah.Release
qwt/src/object_script.libqwt.Release
qwt/src/object_script.libqwtd.Debug
qwt/src/Makefile.Release
qwt/src/Makefile.Debug
qwt/textengines/mathml/debug/
qwt/textengines/mathml/release/
build.pro.user

View File

@@ -1,116 +0,0 @@
branches:
- master
language:
- objective-c
compiler:
- clang
- gcc
env:
matrix:
## Test 4.8 or 5.4.2
- BRANCH=master QT=qt4 QT_PATH=qt
- BRANCH=master QT=qt5 QT_PATH=qt5
global:
- secure: iqYW7f3//ZkMVzeCEarYn0S0DqKjFU9juBh0KF6WTlUsKX902Jtsk7dFoJlNDYBf63HLgV+wW2Hc6MxI9sGiUkom0gY9/To/aeGIJFGEX2sLm/e0Ok3qN521FA0Q/OiCFsD0RC6J+yrHxzI+rf8Z1rujceUsz2KgsrfAjYYv+BY=
- secure: C6f58PXwvvHeVOjCLbyDRjgyF0tk+bXjCNUDur8VJLhJEGNdnrt+rH+d3azYaX0n348ZnQZ14as4M4rHjN1A/3DRbdUdOS7PQZrkj/n363ck1tvYOG/tzYqkEcVoQyjIJ7ZoTuBXDQry/VJmLxQjM0glTa2upNFHMOMwqZNkF+I=
- secure: mgf181ok4rJTHxAdSaeIb/OzUx7PQc6UjJYfhJQcZDjN1Nou+Um6OHpnooMHeEq0CdGuLSiv2xVmuQnRjI5MfG5re/a3l39hSzi9tPLWi1y7uOLCtQFooJw3H+LhiKZcgAtEnkTmEhUCEu5uZ7cp4lWhrQZWCR5mCDNtJrGHjiw=
- secure: UkW6SpgeACb6enGZADTAtPPRe23Tffne/SRQoBsZ3kGbKzgv8kTCLY0G5N71B1xEGdLB/36piOa0yji2SMW1jbflxR7tdOsiNpfd9R5qYqWVZRulY0qite8ZCwU5dqgy87pp4ECC1hNSOTq17aa4Sc4G4egg9AOy8cntLBTtxJA=
- secure: rb/MKPHEK8yOK5uYpXq2o+MQ7h65ft+c/xE9XmLFk1jLnK0oxe6+KeoSFlQ0n5UwLSsHrytMXVaUHex6EEt0TheXFlohi7BcNFWRWXr+wLucuaPjMnU49VErrSigjJ5VW/rcR7fORmnDwn5y06r3Rer9SC1hImCxf/pqF8hFZps=
- secure: FXJzm98lwbc1R2eh9/CvVReVRHEPLDm+sCRjiV9HJgeCveIUauLasp9Skamz0c6OKLmkjLY8JERPT491ZgCG8YcQ9x1bM8HGbmRqnn9xSUxINIRzVmyTiLMBoT/ibHHeFjFpyiGfukOAkHwMNNsrSrbaekhiJuekaXo7iTwYQB0=
before_install:
- date
- brew update
##- sh travis/install-qt.sh
- brew install $QT
- brew install libical
- brew install libusb libusb-compat
- brew install srmio
- brew install libsamplerate
## Disable KML for now
##- brew install --HEAD travis/libkml.rb
- sudo chmod -R +w /usr/local
- curl -O http://www.ftdichip.com/Drivers/D2XX/MacOSX/D2XX1.2.2.dmg
- git clone --depth 1 https://github.com/sintegrial/qwtplot3d.git qwtplot3d
- cd qwtplot3d
- CC=clang CXX=clang++ /usr/local/opt/$QT_PATH/bin/qmake -makefile -recursive QMAKE_CXXFLAGS_WARN_ON+=-Wno-unused-private-field
- CC=clang CXX=clang++ make -j2
- cd ..
- git clone --branch 0.98 https://github.com/kypeli/kQOAuth.git kQOAuth-0.98
- cd kQOAuth-0.98
- CC=clang CXX=clang++ /usr/local/opt/$QT_PATH/bin/qmake -makefile -recursive QMAKE_CXXFLAGS_WARN_ON+=-Wno-unused-private-field
- CC=clang CXX=clang++ make -j2 qmake_all
- CC=clang CXX=clang++ sudo make install
- cd ..
- hdiutil mount D2XX1.2.2.dmg
before_script:
- mkdir D2XX
- cp /Volumes/release/D2XX/Object/10.5-10.7/x86_64/libftd2xx.1.2.2.dylib D2XX
- sudo cp /Volumes/release/D2XX/Object/10.5-10.7/x86_64/libftd2xx.1.2.2.dylib /usr/local/lib
- cp /Volumes/release/D2XX/bin/*.h D2XX
- sed -i "" "s|libftd2xx.dylib|@executable_path/../Frameworks/libftd2xx.1.2.2.dylib|"
src/D2XX.cpp
- cp qwt/qwtconfig.pri.in qwt/qwtconfig.pri
- cp src/gcconfig.pri.in src/gcconfig.pri
- /usr/local/opt/$QT_PATH/bin/lupdate src/src.pro
- sed -i "" "s|#\(CONFIG += release.*\)|\1 static |" src/gcconfig.pri
- sed -i "" "s|#\(QMAKE_LRELEASE\).*|\1 += /usr/local/opt/$QT_PATH/bin/lrelease|"
src/gcconfig.pri
- sed -i "" "s|#\(QMAKE_CXXFLAGS\).*|\1_RELEASE += -mmacosx-version-min=10.7 -arch
x86_64|" src/gcconfig.pri
- sed -i "" "s|#\(SRMIO_INSTALL =.*\)|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(D2XX_INCLUDE =.*\)|\1 ../D2XX|" src/gcconfig.pri
- sed -i "" "s|#\(D2XX_LIBS =.*\)|\1 -L../D2XX -lftd2xx.1.2.2|" src/gcconfig.pri
- sed -i "" "s|#\(KQOAUTH_INSTALL =.*\)|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(KQOAUTH_INCLUDE =.*\)|\1 \$\$[QT_INSTALL_LIBS]/kqoauth.framework/Headers|"
src/gcconfig.pri
- sed -i "" "s|#\(KQOAUTH_LIBS =.*\)|\1 -F\$\$[QT_INSTALL_LIBS] -framework kqoauth|"
src/gcconfig.pri
- sed -i "" "s|#\(QWT3D_INSTALL =.*\)|\1 ../qwtplot3d|" src/gcconfig.pri
## Disable KML for now
##- sed -i "" "s|#\(KML_INSTALL =\).*|\1 /usr/local|" src/gcconfig.pri
##- sed -i "" "s|#\(KML_LIBS =.*\)|\1 -L/usr/local/lib -lkmlxsd -lkmlregionator -lkmldom
## -lkmlconvenience -lkmlengine -lkmlbase|" src/gcconfig.pri
- sed -i "" "s|#\(ICAL_INSTALL =.*\)|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(ICAL_LIBS =.*\)|\1 -L/usr/local/lib -lical|" src/gcconfig.pri
- sed -i "" "s|#\(LIBUSB_INSTALL =\).*|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(LIBUSB_LIBS =.*\)|\1 -L/usr/local/lib -lusb|" src/gcconfig.pri
- sed -i "" "s|#\(SAMPLERATE_INSTALL =\).*|\1 /usr/local|" src/gcconfig.pri
- sed -i "" "s|#\(SAMPLERATE_LIBS =\).*|\1 -L/usr/local/lib -lsamplerate|" src/gcconfig.pri
- sed -i "" "s|#\(DEFINES += GC_HAVE_LION*\)|\1|" src/gcconfig.pri
- sed -i "" "s|#\(HTPATH = ../httpserver.*\)|\1 |" src/gcconfig.pri
- sed -i "" "s|#\(DEFINES += GC_WANT_ROBOT.*\)|\1 |" src/gcconfig.pri
- sed -i "" "s|\(DEFINES += GC_VIDEO_NONE.*\)|#\1 |" src/gcconfig.pri
- sed -i "" "s|#\(DEFINES += GC_VIDEO_QUICKTIME.*\)|\1 |" src/gcconfig.pri
- echo "QMAKE_CFLAGS_RELEASE += -mmacosx-version-min=10.7 -arch x86_64" >> src/gcconfig.pri
- sed -i "" "s/__GC_GOOGLE_CALENDAR_CLIENT_SECRET__/"$GC_GOOGLE_CALENDAR_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_STRAVA_CLIENT_SECRET__/"$GC_STRAVA_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_DROPBOX_CLIENT_SECRET__/"$GC_DROPBOX_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_CYCLINGANALYTICS_CLIENT_SECRET__/"$GC_CYCLINGANALYTICS_CLIENT_SECRET"/" src/Secrets.h
- sed -i "" "s/__GC_TWITTER_CONSUMER_SECRET__/"$GC_TWITTER_CONSUMER_SECRET"/" src/Secrets.h
- cat src/gcconfig.pri
script:
- CC=clang CXX=clang++ /usr/local/opt/$QT_PATH/bin/qmake -makefile -recursive QMAKE_CXXFLAGS_WARN_ON+=-Wno-unused-private-field
- CC=clang CXX=clang++ make qmake_all
- CC=clang CXX=clang++ make -j4 sub-qwt --silent
- CC=clang CXX=clang++ make -j4 sub-src
after_success:
- cd src
- ls -laR GoldenCheetah.app
- GoldenCheetah.app/Contents/MacOS/GoldenCheetah --help
- /usr/local/opt/$QT_PATH/bin/macdeployqt GoldenCheetah.app -verbose=2 -dmg
## fix up the bundle with macdeployqtfix
- python ../travis/macdeployqtfix.py GoldenCheetah.app /usr/local/opt/$QT_PATH
- brew remove $QT
- mv GoldenCheetah.dmg GoldenCheetah_$QT.dmg
- hdiutil mount GoldenCheetah_$QT.dmg
- cd /Volumes/GoldenCheetah
- ls -laR GoldenCheetah.app
- GoldenCheetah.app/Contents/MacOS/GoldenCheetah --help
deploy:
provider: releases
api_key: $GH_OAUTH_TOKEN
file: GoldenCheetah_$QT.dmg
skip_cleanup: true
on:
tags: true

View File

@@ -1,373 +0,0 @@
+++++++++++++++++++++++
LINUX BUILD WALKTHROUGH
+++++++++++++++++++++++
Mark Liversedge
John Ehrlinger
Jan 2015
Version 1.2
A walkthrough of building GoldenCheetah from scratch on Ubuntu linux. This walkthrough
should be largely the same for any Linux distro.
CONTENTS
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
- QT
- git
2. ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 2
- FTDI D2XX
- SRMIO
- liboauth
- QwtPlot3d
- libkml
3. ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 3
- checking out the release 3 branch & building with MANDATORY dependencies
- flex
- bison
- libical - Diary window and CalDAV support (google/mobileme calendar integration)
- libvlc - Video playback in training mode
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
=================================================
Installed Ubuntu 11.04 from CD image amd-64.iso. You will not need to do this if you
already have a Linux distribution installed. Left this step in to highlight the
Linux distribution the commands below were executed on.
login and open a terminal to get a shell prompt
Download MANDATORY DEPENDENCIES (browser)
-----------------------------------------
Download and install the Qt 4.8 SDK from http://qt-project.org/
Once that is completed test qmake is ok with: qmake --version (should report 4.7.0 or higher)
Install git with:
$ sudo apt-get install git
Said Y to prompt about all git files installed (git-gui et al)
Install FLEX and BISON
----------------------
You will need flex v2.5.9 or later
$ sudo apt-get install bison
$ sudo apt-get install flex
$ vi gcconfig.pri
Ensure you have the following lines (which are now also in gcconfig.pri.in which has
been updated to reflect the new dependencies in version 3)
QMAKE_LEX = flex
QMAKE_YACC = bison
win32 {
QMAKE_YACC = bison --file-prefix=y -t
QMAKE_MOVE = cmd /c move
QMAKE_DEL_FILE = rm -f
}
Build!
------
$ make clean
$ qmake
$ make
You will now have a release3 binary but with none of the release3 dependencies compiled in.
Get latest GOLDEN CHEETAH source files
--------------------------------------
$ mkdir -p ~/Projects/Live
$ cd ~/Projects/Live
$ git clone git://github.com/GoldenCheetah/GoldenCheetah.git
$ cd GoldenCheetah
Configure MANDATORY DEPENDENCIES
--------------------------------
$ cd qwt
$ cp qwtconfig.pri.in qwtconfig.pri
$ cd ../src
$ cp gcconfig.pri.in gcconfig.pri
$ vi gcconfig.pri
Comment out the D2XX_INCLUDE and SRMIO_INSTALL lines for now (put # in first character of the line
to comment out), we will install that in a moment, if we need to.
If you are building for your local host you may find that you get better performance if
compiling with gcc -O3 (tree vectorization can have a significat impact) [or -Ofast]
If so you might like to uncomment:
QMAKE_CXXFLAGS += -O3
Save and exit
$ cd ..
BUILD WITH BASIC CONFIGURATION
$ qmake -recursive
$ make
Congratulations you have now build a basic GoldenCheetah and can run this safely. See below for
optional dependencies you can install to support other features.
ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 2
====================================================
D2XX - For Powertap downloads via USB
-------------------------------------
Download the FTDI drivers from http://www.ftdichip.com/Drivers/D2XX.htm (e.g. I used Linux
64-bit drivers from http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx1.0.4.tar.gz)
Extract into your home directory (I put mine into ~/Projects/ with archive manager which
created a sub-directory ~/Projects/libftd2xx1.0.4
$ cd src
$ vi gcconfig.pri
Uncomment the D2XX_INCLUDE entry and make it match (my home is /home/markl)
D2XX_INCLUDE = /home/markl/libftd2xx1.0.4
Make clean is needed if you have previouslt built, since source files examine #defines before
including this feature. You can skip it if you know why ;)
$ make clean
$ qmake
$ make
You now have D2XX support, for downloading from a PT via a USB cradle.
SRMIO - For SRM powercontrol V downloads via Serial
---------------------------------------------------
$ cd ~/Projects
$ git clone git://github.com/rclasen/srmio srmio
$ cd srmio
Get automake and tools, if you don't already have them (I didn't after a fresh install)
$ sudo apt-get install automake
$ sudo apt-get install libtool
Generate the configure script, run it, build and install srmio
$ sh genautomake.sh
$ ./configure
$ make
$ sudo make install
Lets go config GC and build with SRMIO
$ cd ~/Projects/Live/GoldenCheetah/src
$ vi gcconfig.pri
Uncomment the SRMIO_INSTALL and replace with the target used from srmio install:
SRMIO_INSTALL = /usr/local/
At the bottom of gcconfig.pri you will see the include directory should reference from
the base install location (/usr/local) make sure it says:
SRMIO_INCLUDE = $${SRMIO_INSTALL}/include
SRMIO_LIB = $${SRMIO_INSTALL}/lib/libsrmio.a
Make clean is needed if you have previouslt built, since source files examine #defines before
including this feature. You can skip it if you know why ;)
$ make clean
$ qmake
$ make
You now have SRM support built in.
OAUTH/CRYPT - For Tweet my ride (twitter) support
-------------------------------------------------
You should be able to install liboauth and dependencies
directly with:
$ sudo apt-get install liboauth-dev
If this does not work then:
Download the source from: http://sourceforge.net/projects/liboauth/files/liboauth-0.9.4.tar.gz/download and
unpack it into ~/Projects/liboauth-0.9.4 using archive manager
$ cd ~/Projects/liboauth-0.9.4
You may find that libcurl is not installed (which liboauth depends upon) so download it
from http://curl.haxx.se/download/curl-7.21.6.tar.gz and unpack it into ~/Projects/curl-7.21.6
using archive manager to drag and drop into your Projects folder
$ cd ~/Projects/curl-7.21.6
$ ./configure
$ make
$ sudo make install
You should now have libcurl and friends installed in /usr/local
You may find that liboauth also requires the openssl libs installed, these are available
pre-packaged thankfully so:
$ sudo apt-get install libssl-dev
This will also install zlibg which liboauth also desires.
$ cd ~/Projects/liboauth-0.9.4
$ ./configure
$ make
$ sudo make install
Now we have liboauth and libcurl in /usr/local and libssl in /usr/lib, so we can go back to
GoldenCheetah and update the gcconfig.pri to point at the right places:
$ cd ~/Projects/Live/GoldenCheetah/src
$ vi gcconfig.pri
Make sure the following are set:
LIBOAUTH_INSTALL = /usr/local
LIBCRYPTO_INSTALL = -lcrypto
LIBCURL_INSTALL=-lcurl
Make clean is needed if you have previously built, since source files examine #defines before
including this feature. You can skip it if you know why ;)
$ make clean
$ qmake
$ make
You can now tweet your rides and amaze your friends, or alternatively tweet your rides but
omit to mention average power to hide your weaknesses.
LIBQWTPLOT3D - For 3D plot
--------------------------
Download the tarball from http://qwtplot3d.svn.sourceforge.net/viewvc/qwtplot3d/branches/maintain_0_2_x/qwtplot3d/?view=tar
and unarchive it into your Projects directory using archive manager. There is no version number it just creates a
subdirectory called qwtplot3d
You will need to install libgl and extensions, this can be done with;
$ sudo apt-get install libgl1-mesa-dev
$ sudo apt-get install libglu-dev
On Ubuntu 12.10 I also ran
$ sudo apt-get install freeglut3 freeglut3-dev
$ cd ~/Projects/qwtplot3d
Edit the qwtplot3d.pri and add
CONFIG += staticlib
You will find that on modern Linuxes you also need to fix include/qwt3d_global.h by adding the line:
#include <GL/glu.h>
then build
$ qmake
$ make
Then to let gc know where the qwtplot3d libs are you need to edit gcconfig.pri;
$ cd ~/Projects/Live/GoldenCheetah/src
$ vi gcconfig.pri
And uncomment the following line and set the install directory to where you build
QWT3D_INSTALL = ~/Projects/qwtplot3d
LIBKML - For export to Google Earth
-----------------------------------
You will need Google Earth 5.2 or later and therefore libkml that supports this. Unfortunately at the time of writing
the officially packaged libkml is too old, so you will need to install from source, which means you will need to have
subversion installed and expat. You may be able to use the currently packaged libkml with
$ sudo apt-get install libkml-dev
if this does not work you will need to build from source:
$ sudo apt-get install subversion
$ sudo apt-get install expat libexpat1 libexpat1-dev
Once svn is installed you can grab the libkml source and configure build etc:
$ cd ~/Projects
$ svn checkout http://libkml.googlecode.com/svn/trunk/ libkml
$ cd libkml
You will need automake and friends (see SRMIO above)
$ sh autogen.sh
$ ./configure
$ make
$ make install
$ sudo make install
If you get errors about use of 'long long' then edit:
- src/kml/{convenience,dom,engine,regionator,xsd}/Makefile
- examples/{engine,gpx,gx,hellonet,helloworld,regionator,xsd}/Makefile
- and look for the flag -pedantic and remove it. I got this on Linux 64bit builds ymmv.
Once libkml is installed and built:
$ cd ~/Projects/Live/GoldenCheetah/src
$ vi gcconfig.pri
Ensure KML_INSTALL=/usr/local
Make clean is needed if you have previously built, since source files examine #defines before
including this feature. You can skip it if you know why ;)
$ make clean
$ qmake
$ make
You can now export rides to Google Earth kml format.
ADDING OPTIONAL DEPENDENCIES WHEN BUILDING VERSION 3
====================================================
NOTE: When you run version 3 it will refresh ride metrics and CP files -- this only occurs the
first time it runs (and will refresh only rides that change after that). I find it is best
to import ride files once your build where you want it. i.e. don't import until you have
got all your dependencies sorted.
NOTE: To reduce the dependencies on 'dormant' code there are a number of new pieces of source
that are included in the release3 tree. Notably; qtsoap from qt-solutions, since they
work but are likely to be archived and deprecated. If and when that happens we may well
adopt whatever classes Trolltech introduce.
LIBICAL - Diary integration with Google or MobileMe calendars
-------------------------------------------------------------
$ cd ~/Projects/Live/GoldenCheetah/src
$ sudo apt-get install libical-dev
$ vi gcconfig.pri
ICAL_INSTALL=/usr/include
ICAL_LIBS=-lical
Since the src.pro wants ICAL installed in a different place we need to hack it, *** this will
be fixed shortly ***
$ vi src.pro
Comment out the ICAL_LIBS entry:
#ICAL_LIBS = $${ICAL_INSTALL}/lib/libical.a
$ make clean
$ qmake
$ make
You should now have diary functions.
NOTE: That upload to MobileMe and Google requires a functioning https lib in QT. Depending
upon the version installed this might not be the case and will need to be built and
configured -- this is beyond the scope of this walkthough. Sorry.
LIBVLC - Video playback in Realtime (Experimental)
--------------------------------------------------
You will need libvlc 1.1.9 or higher (1.1.8 is ok but will segv on exit)
$ sudo apt-get install libvlc-dev
$ vi gcconfig.pri
Comment out VLC_INSTALL and it should read:
VLC_INSTALL = /usr/include/vlc/
$ make clean
$ qmake
$ make

View File

@@ -1,299 +0,0 @@
+++++++++++++++++++++++
MAC OSX BUILD WALKTHROUGH
+++++++++++++++++++++++
Mark Liversedge
Jan 2015
Version 1.2
A walkthrough of building GoldenCheetah from scratch on Mac OSX. This was performed
on Mac OSX Lion (10.7) but the instructions are largely the same for all versions of
Mac OS X.
CONTENTS
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
- Xcode
- Qt
2. ADDING OPTIONAL DEPENDENCIES
- FTDI D2XX
- SRMIO
- kQOAuth
- QwtPlot3d
- libkml
- libusb
- libical
1. BASIC INSTALLATION WITH MANDATORY DEPENDENCIES
=================================================
Depending upon the speed of your internet connection and availability of the
required software the steps in section 1 will take approximately 1 hour.
1.1 Ensure OS X is up-to-date
-----------------------------
Make sure you have applied all the latest updates to Mac OS X. This can be
found from the system menu, apple, about this mac, software update.
This walkthrough was performed on an iMac running 10.7.2 (Lion)
1.2 Install XCode from App Store
--------------------------------
If you are building on 10.6 or higher you should install Xcode4, for earlier
releases you will need Xcode 3.1.4. If you have capable hardware you should
consider upgrading to Lion to get the latest bug fixes and capabilities.
To install Xcode on Lion you need to download it via the App Store. You can
launch the App Store from launchpad, or it may be already in your dock.
Under the search box type in Xcode and it will return a few optios, generally
Xcode is the first item and shows a blueprint with a hammer icon. Click on
this to install it. It should be free. The usual app store process will apply
as the application is downloaded and installed. The download is about 2GB
so do bear this in mind if you have limits on your internet bandwidth or cap.
1.3 Run the Xcode installer
---------------------------
The app store download will have added an Install Xcode icon in the launchpad.
Go ahead and run it.
Xcode includes all the development tools such as a compiler, debugger and
SDKs. It also installs the 'git' tool for working with Git repositories.
It will run through a wizard to install, just read and then accept the license
agreement and let it get on with it. If you don't like the license then quit
and use the development builds from goldencheetah.stand2surtf.net.
You may find it borks at iTunes helper running, you will
need to force quit the iTunes helper via Finder, Applications, Utilities,
Activity Monitor if this happens.
1.4 Get the source code
-----------------------
We store all the Golden Cheetah source code on github.com, it is a great
site holding repositories for many open source projects.
First open up a terminal session, then;
$ cd
$ mkdir Projects
$ cd Projects
$ git clone git://github.com/GoldenCheetah/GoldenCheetah.git
You will now have the GoldenCheetah sources downloaded into a 'GoldenCheetah'
directory in your home directory, under another folder called 'Projects'.
$ cd GoldenCheetah
$ ls
You should see a number of directories such as doc, qwt, src etc. If you are
wanting to build a particular release you need to checkout the release. To
build a release you need to checkout the code at the tag for the release.
A list of releases can be found at: https://github.com/GoldenCheetah/GoldenCheetah/tags
$ git checkout V3.3-RC1
$ ls
You will now see an updated version of this walkthrough, please jump to using
that since it may be more up-to-date than this walkthrough (depending upon
where you got it from of course!).
1.5 Install the QT SDK
----------------------
GoldenCheetah is developed using the Nokia QT toolkit, it is large and will
need to be downloaded and installed from their website. Alternatively, you
can intall qt via macports (http://www.macports.org) as described in section
1.5.1.
As of today, the latest stable release is 4.7.4, we need 4.7 or higher so
go ahead and download the offline installer - it has everything you need
but is about 1.3GB. Please make sure you download the installer for Mac
OS X 10.6 or later, 64-bit.
The url for QT downloads is: http://qt.nokia.com/downloads and whilst the
offline installer is only 12mb it will still call back and download the
required objects as you install, I think it is better to get it all in
one hit (and you can save it to reinstall on another computer or if you
want to rebuild/reinstall for any other reason).
Once the QT SDK is downloaded you will have a .dmg (disk image) that you
need to mount by double clicking on it. You will then get a volume mounted
and shown on your desktop. Go ahead and double click that to start the install
process. It is probably called something like 'Qt SDK Installer'.
It will popup with a dialog warning that this is downloaded from the internet
and are you sure you want to open it? Go ahead and click Open.
A wizard will now guide you through the QT install process. Go ahead and accept
all the defaults, it will install in your home directory and avoid updating the
system directories, this means you are less likely to bork your Mac OSX installation.
Read and accept the license agreement and then continue and install.
We need to make sure that a program called qmake is installed in a directory where
it can be found. So, we need to create a link from what we just installed in the
user programs folder. For QT SDK1.1 (4.7.4) we need to:
$ sudo ln -s ~/QtSDK/Desktop/Qt/474/gcc/bin/qmake /usr/bin/qmake
1.5.1 Install via Mac Ports
---------------------------
If you have macports installed, you can install the qt dependices
with the following commands:
$ sudo port install qt4-mac
$ sudo port install qt4-mac-sqlite3-plugin
1.6 DEPRECATED
--------------
No longer need this step (install boost)
1.7 Configure and Build GoldenCheetah (with no optional dependencies)
---------------------------------------------------------------------
First thing we need to do is set the build configuration, this means editing the
private build profile settings. There is one for qwt (a charting library) and
there is another for GoldenCheetah itself.
$ cd ~/Projects/GoldenCheetah/qwt
$ cp qwtconfig.pri.in qwtconfig.pri
$ cd ../src
$ cp gcconfig.pri.in gcconfig.pri
$ vi gcconfig.pri
In that last step you can use whatever editor you feel most comfortable with.
For now we will comment out some of the dependencies we have not installed
support for yet:
#SRMIO_INSTALL = /usr/local/srmio
#D2XX_INCLUDE = /usr/local/include/D2XX
we may need to additionally configure to use the local compression
libraries (at least I did), by adding the following line:
LIBS += -lz
Lastly, since we are on Lion, we can also uncomment and change the following line:
DEFINES += GC_HAVE_LION
Once the changes have been made we are now ready to build for the first time. You
may notice a lot of warning messages about the version of O/S not being supported.
This is because QT does not officially support Lion at this point in time (but it
does work). You can either ignore the warning messages or (like me) go and edit out
the warning (once you have seen the message once you don't need reminding every
time you compile).
To do this, edit the file in question as an administrator:
$ sudo vi ~/QtSDK/Desktop/Qt/474/gcc/include/QtCore/qglobal.h
And comment out line 320 (or thereabouts):
//# warning "This version of Mac OS X is unsupported"
Once this is done you can kick off the build:
$ cd .. #this should put you in the top level dir containing this file
$ qmake -recursive
$ make
If make fails to find a Makefile then qmake is configured, by default, to create
an xcode project file. You will need to change the qmake command above to tell it
to create a makefile with the following:
$ qmake -spec macx-g++ -recursive
$ make
Once this completes you will have a GoldenCheetah.app in the src directory which
can be launched:
$ open src/GoldenCheetah.app
And you're up and running.
2. ADDING OPTIONAL DEPENDENCIES
===============================
- SRMIO
- kQOAuth
- QwtPlot3d
- libkml
- libusb
- libical
Since these optional dependencies are more complex and require more advanced
technical skills we do not provide a walkthrough for building them all but
instead provide the configure settings and any special considerations that
should be taken into account.
2.1 SRMIO - For working with PC 5/6/7
-------------------------------------
SRMIO (git)
./configure CFLAGS="-isysroot /Developer/SDKs/MacOSX10.7.sdk -arch x86_64" CPPFLAGS=-I/usr/local/D2XX/ --disable-dependency-tracking
2.2 kQOAuth - For OAuth Authentication
--------------------------------------
kQOauth (0.98)
qmake
2.3 QwtPlot3d - For 3d plot support
-----------------------------------
qwtplot3d (maintain_0_2_x)
Add the following to qwtplot3d.pro:
CONFIG += x86_64 static
QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.7.sdk
2.4 libkml - For export to Google Earth
---------------------------------------
expat (2.0.1)
./configure CFLAGS="-isysroot /Developer/SDKs/MacOSX10.7.sdk -arch x86_64" --disable-dependency-tracking
libkml (pulled down from the svn repo)
./configure CFLAGS="-isysroot /Developer/SDKs/MacOSX10.7.sdk -arch x86_64" --disable-dependency-tracking --with-expat-include-dir=/usr/local/include --with-expat-lib-dir=/usr/local/lib --disable-swig CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.7.sdk -arch x86_64"
note: the added CXXFLAGS helped clear the -Werror flag that stopped compilation.
2.5 libusb - For Garmin USB2 stick support
------------------------------------------
libusb (0.1.12)
To compile on OSX you need to apply the patch here:
https://trac.macports.org/browser/trunk/dports/devel/libusb-legacy/files?rev=97840
Then:
./configure --prefix=/opt/libusb/ CFLAGS="-arch x86_64" CXXFLAGS="-arch x86_64" --disable-dependency-tracking
then
sed -i 'bak' 's|CC -dynamiclib|CC -dynamiclib -arch x86_64|g' libtool
make
make install
note: that the sed line updates some commands in libtool. not sure why the arch clags are not getting passed.
2.6 libical
-----------
libical (0.46)
first run autogen.sh
then
./configure CFLAGS="-isysroot /Developer/SDKs/MacOSX10.7.sdk -arch x86_64" --disable-dependency-tracking

View File

@@ -1,117 +0,0 @@
Please note: This is an old build instruction set for Version 2.x.
Most of it is still fairly valid for version 3.x.
Minimum build requirements are: Qt 4.8 with Qt.4.8.4 recommended.
All other libs are find the best that you can except for libusb which requires 0.1.12.
I have found that the cross compiler at http://mxe.cc/ to be great for building GC and SRMIO.
+++++++++++++++++++++++
WIN32 BUILD WALKTHROUGH
+++++++++++++++++++++++
Gareth Coco
May 2011
For my install, I am installing all my files into the directory: d:\coding.
You can use any directory structure you like, youll just have to change paths.
Just ensure that any folder path you use does not have a space in it.
Download the NSI installer application. I use the Portable Apps version from:
http://portableapps.com/apps/development/nsis_portable
- Install in D:\Coding\NSISPortable\
Download Qt SDK from:
http://qt.nokia.com/downloads/sdk-windows-cpp
(File I am using is qt-sdk-win-opensource-2010.02.1.exe)
- Install in D:\Coding\Qt
Download the D2XX drivers:
http://www.ftdichip.com/Drivers/D2XX.htm
(File I am using is: CDM 202.06.00 WHQL Certified.zip)
- Install in D:\Coding\D2XX
Download qwt-plot3d from:
http://sourceforge.net/projects/qwtplot3d/files/
(File I am using is qwtplot3d-0.2.7.zip)
- Install in D:\Coding\qwtplot3d
Edit D:\coding\qwtplot3d\src\qwt3d_function.cpp
- Add at top of file: #include <cstdio>
Edit D:\coding\qwtplot3d\qwtplot3d.pro
- Comment out: #win32:TEMPLATE = vclib
Then I start the “Qt Command Prompt” from the Qt SDK folder.
d:
cd d:\coding\qwtplot3d\
qmake -win32
mingw32-make release
Now check out your favourite web sites until the code is built.
Leave the Qt Command Prompt window open as we use it later.
Download GoldenCheetah source
(Either use GIT git://github.com/GoldenCheetah/GoldenCheetah.git
or download the zip file:
http://github.com/GoldenCheetah/GoldenCheetah/zipball/master)
- Install in D:\Coding\GoldenCheetah
Copy D:\Coding\GoldenCheetah\src\gccconfig.pri.in
to D:\Coding\GoldenCheetah\src\gccconfig.pri and edit
- Set: D2XX_INCLUDE = d:/coding/D2XX
- Comment out #SRMIO_INSTALL
- Comment out: CONFIG += debug
- Uncomment: CONFIG += static
Copy D:\Coding\GoldenCheetah\qwt\qwtconfig.pri.in
to D:\Coding\GoldenCheetah\qwt\qwtconfig.pri and edit
- Set win32 { INSTALLBASE = D:/Coding/Qt }
- In #Qt4 win32 { section
Comment out: #CONFIG += debug # release/debug/debug_and_release
Add in: CONFIG += release
Using the “Qt Command Prompt” window from before:
cd d:\coding\GoldenCheetah
qmake -win32 -recursive
mingw32-make release
Go back to checking your email or favourite web sites while this builds.
When all is finished, you should have a release version in:
D:\Coding\GoldenCheetah\src\release\
Next , move required build files into the d:\coding\GoldenCheetah\src\release directory.
cd d:\coding\GoldenCheetah
copy /y ..\Qt\qt\bin\mingwm10.dll src\release\
copy /y ..\Qt\qt\bin\QtCore4.dll src\release\
copy /y ..\Qt\qt\bin\QtGui4.dll src\release\
copy /y ..\Qt\qt\bin\QtSql4.dll src\release\
copy /y ..\Qt\qt\bin\QtXml4.dll src\release\
copy /y ..\Qt\qt\bin\QtNetwork4.dll src\release\
copy /y ..\Qt\qt\bin\QtOpenGL4.dll src\release\
copy /y ..\Qt\qt\bin\QtWebKit4.dll src\release\
copy /y ..\Qt\qt\bin\QtXmlPatterns4.dll src\release\
copy /y ..\Qt\qt\bin\phonon4.dll src\release\
copy /y ..\Qt\qt\bin\libgcc_s_dw2-1.dll src\release\
copy /y ..\qwtplot3d\lib\qwtplot3d.dll src\release\
mkdir src\release\sqldrivers
copy /y ..\Qt\qt\plugins\sqldrivers\qsqlite4.dll src\release\sqldrivers\
mkdir src\release\imageformats
copy /y ..\Qt\qt\plugins\imageformats\qjpeg4.dll src\release\imageformats\
To build the self installer:
cd d:\coding\GoldenCheetah\src\win32
d:\coding\NSISPortable\App\NSIS\makensis.exe GoldenCheetahInstall.nsi
You should find the installer file in the directory you are in.
Install and enjoy.

15
README Normal file
View File

@@ -0,0 +1,15 @@
To build
cp src/gcconfig.pri.in src/gcconfig.pri
cp qwt/qwtconfig.pri.in qwt/qwtconfig.pri
Edit both src/gcconfig.pri and qwt/qwtconfig.pri as necessary, then
qmake
make
To uninstall the older FTDI VCP drivers on Mac OS X, open a Terminal and type:
sudo mv /System/Library/Extensions/FTDIUSBSerialDriver.kext /tmp
Type your password when prompted, then restart your computer.

View File

@@ -1,15 +0,0 @@
Golden Cheetah install and build instructions are documented
for each platform;
INSTALL-WIN32 For building on Microsoft Windows
INSTALL-LINUX For building on Ubuntu Linux
INSTALL-MAC For building on Apple OS X
[![Build Status](https://travis-ci.org/GoldenCheetah/GoldenCheetah.svg?branch=master)](https://travis-ci.org/GoldenCheetah/GoldenCheetah)
Alternatively official builds are available from http://www.goldencheetah.org
whilst latest developer builds are available from http://goldencheetah.stand2surf.net

View File

@@ -1,7 +1,3 @@
TEMPLATE = subdirs
SUBDIRS = qwt
unix:!macx {
SUBDIRS += kqoauth
}
SUBDIRS += src
SUBDIRS = qwt src
CONFIG += ordered

View File

@@ -1,316 +0,0 @@
From 7be04e65a53b22ce382d640a6c409b5d3bfe5645 Mon Sep 17 00:00:00 2001
From: Joern <joern.rm@gmail.com>
Date: Sat, 20 Dec 2014 12:42:37 +0100
Subject: [PATCH] Patch-Windows-MingGW-subset for GC
... reduce the libs in Make to what GoldenCheetah needs
... add two functions missing in MingGW standard libs
---
Makefile.am | 2 +-
configure.ac | 44 -------------------
src/Makefile.am | 2 +-
src/kml/base/file_posix.cc | 102 ++++++++++++++++++++++++++++++++++++++++++++
src/kml/base/string_util.cc | 17 ++++++++
third_party/Makefile.am | 42 +++---------------
6 files changed, 126 insertions(+), 83 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2be0803..e29201e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
ACLOCAL_AMFLAGS = -I m4
# Order is important:
-SUBDIRS = third_party src testdata examples msvc xcode
+SUBDIRS = third_party src
EXTRA_DIST = \
AUTHORS \
diff --git a/configure.ac b/configure.ac
index d5fa75f..033128b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -203,23 +203,6 @@ AC_CHECK_LIB(pthread, pthread_create,,
AC_CONFIG_FILES([
Makefile
- examples/Makefile
- examples/domviewer/Makefile
- examples/engine/Makefile
- examples/gpx/Makefile
- examples/gx/Makefile
- examples/hellonet/Makefile
- examples/helloworld/Makefile
- examples/java/Makefile
- examples/kml/Makefile
- examples/python/Makefile
- examples/regionator/Makefile
- examples/wxregionator/Makefile
- examples/wxviewer/Makefile
- examples/xsd/Makefile
- msvc/Makefile
- msvc/examples/Makefile
- msvc/tests/Makefile
src/Makefile
src/kml/Makefile
src/kml/convenience/Makefile
@@ -228,34 +211,7 @@ AC_CONFIG_FILES([
src/kml/regionator/Makefile
src/kml/base/Makefile
src/kml/xsd/Makefile
- src/swig/Makefile
- src/swig/java/Makefile
- src/swig/python/Makefile
- testdata/Makefile
- testdata/atom/Makefile
- testdata/balloon/Makefile
- testdata/csv/Makefile
- testdata/deprecated/Makefile
- testdata/gdata/Makefile
- testdata/gmaps/Makefile
- testdata/gpx/Makefile
- testdata/gx/Makefile
- testdata/kml/Makefile
- testdata/kmz/Makefile
- testdata/kmz/files/Makefile
- testdata/kmz/kmzfiles/Makefile
- testdata/kmz/rumsey/Makefile
- testdata/kmz/rumsey/kml/Makefile
- testdata/kmz/rumsey/imagery/Makefile
- testdata/links/Makefile
- testdata/style/Makefile
- testdata/style/weather/Makefile
- testdata/update/Makefile
- testdata/xal/Makefile
- testdata/xsd/Makefile
third_party/Makefile
- xcode/Makefile
- xcode/LibKML/Makefile
])
AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 0bf15ac..721209e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = kml swig
+SUBDIRS = kml
# TODO: use the phc files in msvc.
EXTRA_DIST = \
diff --git a/src/kml/base/file_posix.cc b/src/kml/base/file_posix.cc
index b9461c0..920a996 100644
--- a/src/kml/base/file_posix.cc
+++ b/src/kml/base/file_posix.cc
@@ -33,8 +33,110 @@
#include <sys/stat.h>
#include <unistd.h> // For unlink, close.
+// START PATCH
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+// END PATCH
+
namespace kmlbase {
+// START PATCH
+// Implementation of missing functions
+
+/* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright
+ (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version. */
+
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
+ does not exist at the time of the call to mkstemp. TMPL is
+ overwritten with the result. */
+int
+mkstemp (char *tmpl)
+{
+ int len;
+ char *XXXXXX;
+ static unsigned long value;
+ unsigned long random_time_bits;
+ unsigned int count;
+ int fd = -1;
+ int save_errno = errno;
+
+ /* A lower bound on the number of temporary files to attempt to
+ generate. The maximum total number of temporary file names that
+ can exist for a given template is 62**6. It should never be
+ necessary to try all these combinations. Instead if a reasonable
+ number of names is tried (we define reasonable as 62**3) fail to
+ give the system administrator the chance to remove the problems. */
+#define ATTEMPTS_MIN (62 * 62 * 62)
+
+ /* The number of times to attempt to generate a temporary file. To
+ conform to POSIX, this must be no smaller than TMP_MAX. */
+#if ATTEMPTS_MIN < TMP_MAX
+ unsigned int attempts = TMP_MAX;
+#else
+ unsigned int attempts = ATTEMPTS_MIN;
+#endif
+
+ len = strlen (tmpl);
+ if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+/* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6];
+
+ /* Get some more or less random data. */
+ {
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+ }
+ value += random_time_bits ^ getpid ();
+
+ for (count = 0; count < attempts; value += 7777, ++count)
+ {
+ unsigned long v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
+ if (fd >= 0)
+ {
+ errno = save_errno;
+ return fd;
+ }
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ errno = EEXIST;
+ return -1;
+}
+// END PATCH
+
// Internal to the POSIX File class.
static bool StatFile(const char* path, struct stat* stat_data) {
struct stat tmp;
diff --git a/src/kml/base/string_util.cc b/src/kml/base/string_util.cc
index b3a9654..3fdba2b 100644
--- a/src/kml/base/string_util.cc
+++ b/src/kml/base/string_util.cc
@@ -31,6 +31,23 @@
namespace kmlbase {
+// START PATCH
+int strncasecmp(const char *s1, const char *s2, size_t n) {
+ while (*s1 != 0 && tolower(*s1) == tolower(*s2)) {
+ ++s1;
+ ++s2;
+ }
+
+ return
+ (*s2 == 0)
+ ? (*s1 != 0)
+ : (*s1 == 0)
+ ? -1
+ : (tolower(*s1) - tolower(*s2));
+}
+
+// ENDPATCH
+
void b2a_hex(uint32_t i, char* out) {
char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
diff --git a/third_party/Makefile.am b/third_party/Makefile.am
index b73dec3..fe34dea 100644
--- a/third_party/Makefile.am
+++ b/third_party/Makefile.am
@@ -12,7 +12,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/third_party/zlib-1.2.3/contrib \
-I$(top_srcdir)/third_party/gtest-1.7.0/include
lib_LTLIBRARIES = libminizip.la liburiparser.la
-noinst_LTLIBRARIES = libgtest.la libgtest_main.la
+#noinst_LTLIBRARIES = libgtest.la libgtest_main.la
libminizip_la_SOURCES = \
zlib-1.2.3/contrib/minizip/unzip.c \
@@ -83,11 +83,11 @@ libboostconfigplatforminclude_HEADERS = \
$(boost)/config/platform/linux.hpp \
$(boost)/config/platform/macos.hpp
-libgtest_la_SOURCES = \
- gtest-1.7.0/src/gtest-all.cc
+#libgtest_la_SOURCES = \
+# gtest-1.7.0/src/gtest-all.cc
-libgtest_main_la_SOURCES = gtest-1.7.0/src/gtest_main.cc
-libgtest_main_la_LIBADD = libgtest.la
+#libgtest_main_la_SOURCES = gtest-1.7.0/src/gtest_main.cc
+#libgtest_main_la_LIBADD = libgtest.la
# TODO: add the new gtest libs for windows.
# gtest-1.7.0.win32/debug/gtest.lib \
@@ -149,38 +149,6 @@ EXTRA_DIST = \
$(boost)/config/stdlib/sgi.hpp \
$(boost)/config/stdlib/stlport.hpp \
$(boost)/config/stdlib/vacpp.hpp \
- gtest-1.7.0/include/gtest/gtest-death-test.h \
- gtest-1.7.0/include/gtest/gtest-message.h \
- gtest-1.7.0/include/gtest/gtest-param-test.h \
- gtest-1.7.0/include/gtest/gtest-param-test.h.pump \
- gtest-1.7.0/include/gtest/gtest-printers.h \
- gtest-1.7.0/include/gtest/gtest-spi.h \
- gtest-1.7.0/include/gtest/gtest-test-part.h \
- gtest-1.7.0/include/gtest/gtest-typed-test.h \
- gtest-1.7.0/include/gtest/gtest.h \
- gtest-1.7.0/include/gtest/gtest_pred_impl.h \
- gtest-1.7.0/include/gtest/gtest_prod.h \
- gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
- gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
- gtest-1.7.0/include/gtest/internal/gtest-internal.h \
- gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
- gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
- gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump \
- gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
- gtest-1.7.0/include/gtest/internal/gtest-port.h \
- gtest-1.7.0/include/gtest/internal/gtest-string.h \
- gtest-1.7.0/include/gtest/internal/gtest-tuple.h \
- gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump \
- gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
- gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump \
- gtest-1.7.0/src/gtest-death-test.cc \
- gtest-1.7.0/src/gtest-filepath.cc \
- gtest-1.7.0/src/gtest-internal-inl.h \
- gtest-1.7.0/src/gtest-port.cc \
- gtest-1.7.0/src/gtest-printers.cc \
- gtest-1.7.0/src/gtest-test-part.cc \
- gtest-1.7.0/src/gtest-typed-test.cc \
- gtest-1.7.0/src/gtest.cc \
uriparser-0.7.5/COPYING \
uriparser-0.7.5.win32/debug/uriparser.lib \
uriparser-0.7.5.win32/release/uriparser.lib \
--
1.9.5.github.0

View File

@@ -1,107 +0,0 @@
From 44a403d45ae049e7ade3e9b47a39778dcacf4382 Mon Sep 17 00:00:00 2001
From: Mark Liversedge <liversedge@gmail.com>
Date: Thu, 28 Mar 2013 22:03:35 +0000
Subject: [PATCH] Fixup no threads for GC
---
src/core/CLucene/debug/lucenebase.h | 2 +-
src/shared/CLucene/LuceneThreads.h | 21 ++++++++++++++++++---
src/shared/CLucene/util/Misc.cpp | 2 ++
src/shared/CLucene/util/Misc.h | 2 ++
4 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/core/CLucene/debug/lucenebase.h b/src/core/CLucene/debug/lucenebase.h
index c053f11..9732ce6 100644
--- a/src/core/CLucene/debug/lucenebase.h
+++ b/src/core/CLucene/debug/lucenebase.h
@@ -6,7 +6,7 @@
------------------------------------------------------------------------------*/
#ifndef _lucene_debug_lucenebase_
#define _lucene_debug_lucenebase_
-
+#define _CL_DISABLE_MULTITHREADING
#include "CLucene/LuceneThreads.h"
CL_NS_DEF(debug)
diff --git a/src/shared/CLucene/LuceneThreads.h b/src/shared/CLucene/LuceneThreads.h
index 97072ee..662ff2f 100644
--- a/src/shared/CLucene/LuceneThreads.h
+++ b/src/shared/CLucene/LuceneThreads.h
@@ -13,10 +13,10 @@ class CLuceneThreadIdCompare;
#if defined(_CL_DISABLE_MULTITHREADING)
#define SCOPED_LOCK_MUTEX(theMutex)
- #define DEFINE_MUTEX(x)
+ //#define DEFINE_MUTEX(x)
#define DEFINE_MUTABLE_MUTEX(x)
#define DEFINE_CONDITION(x)
- #define STATIC_DEFINE_MUTEX(x)
+ //#define STATIC_DEFINE_MUTEX(x)
#define CONDITION_WAIT(theMutex, theCondition)
#define CONDITION_NOTIFYALL(theCondition)
#define _LUCENE_CURRTHREADID 1
@@ -25,11 +25,26 @@ class CLuceneThreadIdCompare;
#define _LUCENE_THREAD_FUNC_RETURN(val) return (int)val;
#define _LUCENE_THREAD_CREATE(func, arg) (*func)(arg)
#define _LUCENE_THREAD_JOIN(value) //nothing to do...
- #define _LUCENE_THREADMUTEX void*
+ //#define _LUCENE_THREADMUTEX void*
#define _LUCENE_ATOMIC_INC(theInteger) (++(*theInteger))
#define _LUCENE_ATOMIC_DEC(theInteger) (--(*theInteger))
#define _LUCENE_ATOMIC_INT int
+#define _LUCENE_ATOMIC_INT_SET(x,v) x=v
+#define _LUCENE_ATOMIC_INT_GET(x) x
+
+struct CLUCENE_SHARED_EXPORT mutex_thread
+{
+ void lock() {}
+ void unlock() {}
+};
+#define _LUCENE_THREADMUTEX CL_NS(util)::mutex_thread
+
+#define DEFINE_MUTEX(theMutex) _LUCENE_THREADMUTEX theMutex;
+#define STATIC_DEFINE_MUTEX(theMutex) static _LUCENE_THREADMUTEX theMutex;
+
+#define CONDITION_WAIT(theMutex, theCondition)
+#define CONDITION_NOTIFYALL(theCondition)
#else
#if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX)
//do nothing
diff --git a/src/shared/CLucene/util/Misc.cpp b/src/shared/CLucene/util/Misc.cpp
index 240b827..ec9eabd 100644
--- a/src/shared/CLucene/util/Misc.cpp
+++ b/src/shared/CLucene/util/Misc.cpp
@@ -466,6 +466,7 @@ bool Misc::listFiles(const char* directory, std::vector<std::string>& files, boo
std::string Misc::toString(const bool value){
return value ? "true" : "false";
}
+#ifndef _CL_DISABLE_MULTITHREADING
std::string Misc::toString(_LUCENE_THREADID_TYPE value){
static int32_t nextindex = 0;
static std::map<_LUCENE_THREADID_TYPE, int32_t> ids;
@@ -474,6 +475,7 @@ std::string Misc::toString(_LUCENE_THREADID_TYPE value){
}
return toString(ids[value]);
}
+#endif
std::string Misc::toString(const int32_t value){
char buf[20];
TCHAR tbuf[20];
diff --git a/src/shared/CLucene/util/Misc.h b/src/shared/CLucene/util/Misc.h
index aea7c42..4196e24 100644
--- a/src/shared/CLucene/util/Misc.h
+++ b/src/shared/CLucene/util/Misc.h
@@ -67,7 +67,9 @@ CL_NS_DEF(util)
static std::string toString(const int32_t value);
static std::string toString(const int64_t value);
+#ifndef _CL_DISABLE_MULTITHREADING
static std::string toString(const _LUCENE_THREADID_TYPE value);
+#endif
static std::string toString(const bool value);
static std::string toString(const float_t value);
static std::string toString(const TCHAR* s, int32_t len=-1);
--
1.7.8.msysgit.0

Binary file not shown.

View File

@@ -1,5 +0,0 @@
Clucene-2.3.3.4-NoThreads.patch - To patch Clucene on Windows to remove patching
Fortius USB Driver Stubs.zip - Drivers for use with Fortius without Tacx software
Install_D2XX_drivers.mpkg.zip - D2XX installer for Windows
Universal_D2XX0.1.6.dmg - D2XX installer for Mac OSX
libusb-0.1.12.tar.gz - Libusb (patched) to work with GoldenCheetah

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -1,12 +0,0 @@
# Ignores for Eclipse
/.settings/
# Ignores for Android Projects
/bin/
/gen/
/publish/
/local.properties
/secure.properties
# Ignores for Mac machines
.DS_Store

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AndroidXML>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto"
package="com.ridelogger"
android:versionCode="040000"
android:versionName="4.0.0"
android:icon="@drawable/ic_launcher" >
<uses-sdk android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault.Light" >
<service
android:name="com.ridelogger.RideService"
android:icon="@drawable/ic_launcher"
android:label="@string/service_name" >
</service>
<activity
android:name="com.ridelogger.StartActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.ridelogger.SettingsActivity"
android:label="@string/setting_title" >
</activity>
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>

View File

@@ -1,68 +0,0 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
# Optimizations: If you don't want to optimize, use the
# proguard-android.txt configuration file instead of this one, which
# turns off the optimization flags. Adding optimization introduces
# certain risks, since for example not all optimizations performed by
# ProGuard works on all versions of Dalvik. The following flags turn
# off various optimizations known to have issues, but the list may not
# be complete or up to date. (The "arithmetic" optimization can be
# used if you are only targeting Android 2.0 or later.) Make sure you
# test thoroughly if you go this route.
-optimizations code/simplification/arithmetic,code/simplification/cast,field/*,class/merging/*
-optimizationpasses 24
-allowaccessmodification
-dontpreverify
# The remainder of this file is identical to the non-optimized version
# of the Proguard configuration file (except that the other file has
# flags to turn off optimization).
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
-keep public class com.ridelogger.SettingsActivity$GeneralFragment
-keep public class com.ridelogger.SettingsActivity$AntFragment
-keep public class com.ridelogger.SettingsActivity$SensorsFragment

View File

@@ -1,15 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=proguard-android-optimize.txt
# Project target.
target=android-21
min=android-14

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AndroidXML>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LayoutData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:gravity="right"
/>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header android:fragment="com.ridelogger.SettingsActivity$GeneralFragment"
android:title="@string/setting_general_title"
android:summary="@string/setting_general_note" />
<header android:fragment="com.ridelogger.SettingsActivity$AntFragment"
android:title="@string/setting_ant_title"
android:summary="@string/setting_ant_note" />
<header android:fragment="com.ridelogger.SettingsActivity$SensorsFragment"
android:title="@string/setting_sensors_title"
android:summary="@string/setting_sensors_note" />
</preference-headers>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/Start"
android:title="@string/start" />
<item android:id="@+id/Stop"
android:title="@string/stop" />
<item android:id="@+id/Settings"
android:title="@string/edit_settings"
android:showAsAction="never" />
</menu>

View File

@@ -1,97 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AndroidXML>
<resources>
<string name="app_name">Ride Logger</string>
<string name="service_name">Logging Ride</string>
<string name="emergency_contact_dialog_title">Emergency Contact</string>
<string name="emergency_contact_dialog_note">Should a text messesage be sent on ride start and periodically to let your emergency contact know you are alright?</string>
<string name="sms_period_dialog_title">Emergency Contact SMS Period</string>
<string name="sms_period_dialog_note">Period in Minutes:</string>
<string name="crash_detection_dialog_title">Crash Detection</string>
<string name="crash_detection_dialog_note">Should a text messesage be sent on crash detction to your emergency contact?</string>
<string name="emergency_contact_number_dialog_title">Emergency Contact Number</string>
<string name="emergency_contact_number_dialog_note">Emergency phone number to update position on crash detection</string>
<string name="ant_setup_title">Set Ant+</string>
<string name="ant_setup_note">Pair your Ant+ devices now?</string>
<string name="ant_pair_dialog_title">Select Ant Devices</string>
<string name="ant_pair_dialog_button_note">Pair</string>
<string name="gc_rider_name_dialog_title">Enter Rider Name</string>
<string name="gc_rider_name_dialog_note">What is your Golder Cheata Rider Name?</string>
<string name="save_setting_button">Next</string>
<string name="skip_setting_button">Skip</string>
<string name="boolean_dialog_yes">Yes</string>
<string name="boolean_dialog_no">No</string>
<string name="starting_ride">Starting Ride!</string>
<string name="stopping_ride">Stoping Ride!</string>
<string name="ride_on">Ride On</string>
<string name="building_ride">Building ride: </string>
<string name="click_to_stop"> Click to stop ride.</string>
<string name="ride_start_title">Start Ride</string>
<string name="ride_start_note">Make sure locations is turned on. Internet connection is NOT required.</string>
<string name="start">Start Logging</string>
<string name="edit_settings">Settings</string>
<string name="ride_stop_title">Ride in Progress</string>
<string name="ride_stop_note">Would you like to stop the ride or view current values.</string>
<string name="stop">Stop Logging</string>
<string name="view">View</string>
<string name="crash_warning">WARNING CRASH!</string>
<string name="crash_confirm">CRASH CONFIRMED!</string>
<string name="crash_unknow_location">Unknow location.</string>
<string name="crash_magnitude">Mag</string>
<string name="ride_start_sms">I\'m starting my ride.</string>
<string name="ride_stop_sms">I have finished my ride.</string>
<string name="riding_ok_sms">I\'m ok.</string>
<string name="setting_title">Settings</string>
<string name="setting_general_title">General</string>
<string name="setting_general_note">Settings</string>
<string name="setting_ant_title">Ant+</string>
<string name="setting_ant_note">Setup your Ant+ Devices</string>
<string name="searching_for_ants">Searching for Ant+ Devices...</string>
<string name="found_ants">Found Ant+ Devices, Press to Pair.</string>
<string name="no_found_ants">Nothing found to pair.</string>
<string name="setting_sensors_title">Display Sensors</string>
<string name="setting_sensors_note">List of Sensors Display</string>
<string name="setting_wheel_size">Wheel Circumference in Meters</string>
<string name="imperial_units_title">Imperial Units</string>
<string name="imperial_units_note">Show Measurements in Imperial Units</string>
<string name="setting_size_title">Display Text Size</string>
<string name="PREFS_NAME">RideLogger</string>
<string name="PREF_RIDER_NAME">RiderName</string>
<string name="PREF_EMERGENCY_NUMBER">EmergencyNumbuer</string>
<string name="PREF_DETECT_CRASH">DetectCrash</string>
<string name="PREF_PHONE_HOME">PhoneHome</string>
<string name="PREF_PAIRED_ANTS">PairedAnts</string>
<string name="PREF_PHONE_HOME_PERIOD">PhoneHomePeriod</string>
<string name="PREF_TRACKING_SENSORS">TrackingSensors</string>
<string name="PREF_TRACKING_SIZE">TrackingSize</string>
<string name="PREF_TRACKING_IMPERIAL_UNITS">TrackingImperialUnits</string>
<string name="PREF_WHEEL_SIZE">WheelSize</string>
</resources>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/PREFS_NAME">
<MultiSelectListPreference
android:key="@string/PREF_PAIRED_ANTS"
android:title="@string/ant_pair_dialog_title"
android:summary="@string/ant_pair_dialog_button_note"
/>
<EditTextPreference
android:key="@string/PREF_WHEEL_SIZE"
android:title="@string/setting_wheel_size"
android:defaultValue="2.096"
/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/PREFS_NAME"
android:persistent="true">
<EditTextPreference
android:key="@string/PREF_RIDER_NAME"
android:title="@string/gc_rider_name_dialog_title"
android:summary="@string/gc_rider_name_dialog_note" />
<EditTextPreference
android:key="@string/PREF_EMERGENCY_NUMBER"
android:title="@string/emergency_contact_number_dialog_title"
android:summary="@string/emergency_contact_number_dialog_note" />
<CheckBoxPreference
android:layout="?android:attr/preferenceLayoutChild"
android:dependency="@string/PREF_EMERGENCY_NUMBER"
android:key="@string/PREF_DETECT_CRASH"
android:title="@string/crash_detection_dialog_title"
android:summary="@string/crash_detection_dialog_note" />
<!-- The visual style of a child is defined by this styled theme attribute. -->
<CheckBoxPreference
android:layout="?android:attr/preferenceLayoutChild"
android:dependency="@string/PREF_EMERGENCY_NUMBER"
android:key="@string/PREF_PHONE_HOME"
android:title="@string/emergency_contact_dialog_title"
android:summary="@string/emergency_contact_dialog_note" />
<EditTextPreference
android:layout="?android:attr/preferenceLayoutChild"
android:dependency="@string/PREF_PHONE_HOME"
android:key="@string/PREF_PHONE_HOME_PERIOD"
android:title="@string/sms_period_dialog_title"
android:summary="@string/sms_period_dialog_note"
android:defaultValue="20" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/PREFS_NAME">
<MultiSelectListPreference
android:key="@string/PREF_TRACKING_SENSORS"
android:title="@string/setting_sensors_title"
android:summary="@string/setting_sensors_note"
/>
<CheckBoxPreference
android:key="@string/PREF_TRACKING_IMPERIAL_UNITS"
android:title="@string/imperial_units_title"
android:summary="@string/imperial_units_note"
/>
<EditTextPreference
android:key="@string/PREF_TRACKING_SIZE"
android:title="@string/setting_size_title"
android:defaultValue="20"
/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,281 +0,0 @@
package com.ridelogger;
import java.util.Set;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.preference.PreferenceManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CurrentValuesAdapter extends BaseAdapter {
private StartActivity context;
private int[] keys;
private String[] values;
private String[] keyLabels;
private int size = 20;
private boolean imperial = false;
private SharedPreferences settings = null;
private GridView layout;
public CurrentValuesAdapter(StartActivity c, GridView pLayout) {
context = c;
layout = pLayout;
layout.setBackgroundColor(Color.BLACK);
layout.setVerticalSpacing(4);
layout.setHorizontalSpacing(4);
settings = PreferenceManager.getDefaultSharedPreferences(context);
Set<String> sensors = settings.getStringSet(context.getString(R.string.PREF_TRACKING_SENSORS), null);
size = Integer.valueOf(settings.getString(context.getString(R.string.PREF_TRACKING_SIZE), "20"));
imperial = settings.getBoolean(context.getString(R.string.PREF_TRACKING_IMPERIAL_UNITS), false);
initKeys(sensors);
initKeyLables();
initValues();
settings.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String pkey) {
if(pkey == context.getString(R.string.PREF_TRACKING_SIZE)) {
size = Integer.valueOf(sharedPreferences.getString(context.getString(R.string.PREF_TRACKING_SIZE), "20"));
setupWidth();
notifyDataSetChanged();
} else if (pkey == context.getString(R.string.PREF_TRACKING_SENSORS)) {
Set<String> sensors = sharedPreferences.getStringSet(context.getString(R.string.PREF_TRACKING_SENSORS), null);
initKeys(sensors);
initKeyLables();
initValues();
layout.setAdapter(CurrentValuesAdapter.this);
notifyDataSetChanged();
} else if (pkey == context.getString(R.string.PREF_TRACKING_IMPERIAL_UNITS)) {
imperial = sharedPreferences.getBoolean(pkey, false);
initKeyLables();
initValues();
notifyDataSetChanged();
}
}
}
);
}
private void initKeys(Set<String> sensors) {
if(sensors != null && sensors.size() > 0) {
keys = new int[sensors.size()];
int i = 0;
for(String sensor : sensors) {
keys[i] = Integer.parseInt(sensor);
i++;
}
} else {
keys = new int[RideService.KEYS.length];
for (int i = 0; i < RideService.KEYS.length; i++) {
keys[i] = i;
}
}
}
private void initKeyLables() {
keyLabels = new String[keys.length];
if(!imperial) {
for(int key : keys) {
keyLabels[key] = RideService.KEYS[key].toString().toLowerCase();
}
} else {
for(int key : keys) {
switch (key) {
case RideService.ALTITUDE:
keyLabels[key] = "ft";
break;
case RideService.KPH:
keyLabels[key] = "mph";
break;
case RideService.KM:
keyLabels[key] = "m";
break;
default:
keyLabels[key] = RideService.KEYS[key].toString().toLowerCase();
break;
}
}
}
}
private void initValues() {
values = new String[keys.length];
for (int key : keys) {
if(key == RideService.SECS) {
values[key] = "00:00:00";
} else {
values[key] = "0.0";
}
}
}
private RelativeLayout newRelativeLayout(int key) {
RelativeLayout view = new RelativeLayout(context);
view.setBackgroundColor(Color.WHITE);
TextView valueView = newValueTv(key);
TextView keyView = newKeyTv(key);
RelativeLayout.LayoutParams valueLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
valueLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
valueLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
view.addView(valueView, valueLayoutParams);
RelativeLayout.LayoutParams keyLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
keyLayoutParams.addRule(RelativeLayout.BELOW, valueView.getId());
keyLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
keyLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
view.addView(keyView, keyLayoutParams);
return view;
}
private TextView newValueTv(int key){
TextView tv = new TextView(context);
tv.setTextAppearance(context, android.R.attr.textAppearanceLarge);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
tv.setText(values[key]);
tv.setId(key + 1);
return tv;
}
private TextView newKeyTv(int key){
TextView tv = new TextView(context);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
tv.setBackgroundColor(Color.LTGRAY);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv.setPadding(4, 1, 4, 1);
tv.setText(keyLabels[key]);
return tv;
}
@Override
public int getCount() {
return keys.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
return newRelativeLayout(keys[position]);
} else {
RelativeLayout view = (RelativeLayout) convertView;
TextView valueView = (TextView) (view.getChildAt(0));
TextView valueKey = (TextView) (view.getChildAt(1));
if(valueView.getText() != values[keys[position]])
valueView.setText(values[keys[position]]);
valueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
if(valueKey.getText() != keyLabels[keys[position]])
valueKey.setText(keyLabels[keys[position]]);
return convertView;
}
}
public void update(float[] current_float_values) {
for (int key: keys) {
if(key == RideService.SECS) {
int hr = (int) (current_float_values[key]/3600);
int rem = (int) (current_float_values[key]%3600);
int mn = rem/60;
int sec = rem%60;
values[key] = (hr<10 ? "0" : "") + hr + ":" + (mn<10 ? "0" : "") + mn + ":" + (sec<10 ? "0" : "")+sec;
} else if(!imperial) {
values[key] = String.format("%.1f", current_float_values[key]);
} else {
switch (key) {
case RideService.ALTITUDE:
values[key] = String.format("%.1f", current_float_values[key] * 3.28084);
break;
case RideService.KPH:
values[key] = String.format("%.1f", current_float_values[key] * 0.621371);
break;
case RideService.KM:
values[key] = String.format("%.1f", current_float_values[key] * 0.621371);
break;
default:
values[key] = String.format("%.1f", current_float_values[key]);
break;
}
}
}
notifyDataSetChanged();
}
/**
* returns the size of the cell basted on 8 chars wide and the configured size param
* @return int
*/
private void setupWidth() {
TextView tv = new TextView(context);
tv.setTextAppearance(context, android.R.attr.textAppearanceLarge);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
tv.setText(String.format("%.1f", 1111.11));
Rect bounds = new Rect();
tv.getPaint().getTextBounds("00:00:00", 0, "00:00:00".length(), bounds);
layout.setColumnWidth(bounds.width() + 16);
}
}

View File

@@ -1,28 +0,0 @@
package com.ridelogger;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
public class GzipWriter extends GZIPOutputStream {
public GzipWriter(OutputStream os) throws IOException {
super(os);
}
public void write(String data) throws IOException {
super.write(data.getBytes());
}
public void write(float data) throws IOException {
super.write(Float.floatToIntBits(data));
}
public void write(CharSequence data) throws IOException {
byte[] barr = new byte[data.length()];
for (int i = 0; i < barr.length; i++) {
barr[i] = (byte) data.charAt(i);
}
super.write(barr);
}
}

View File

@@ -1,417 +0,0 @@
package com.ridelogger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceType;
import com.dsi.ant.plugins.utility.log.LogAnt;
import com.ridelogger.formats.BaseFormat;
import com.ridelogger.formats.JsonFormat;
import com.ridelogger.listners.Base;
import com.ridelogger.listners.Gps;
import com.ridelogger.listners.HeartRate;
import com.ridelogger.listners.Power;
import com.ridelogger.listners.Sensors;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
/**
* RideService
* @author Chet Henry
* Performs ride logging from sensors as an android service
*/
public class RideService extends Service
{
public static final int notifyID = 1; //Id of the notification in the top android bar that this class creates and alters
public static final int SECS = 0;
public static final int KPH = 1;
public static final int ALTITUDE = 2;
public static final int bearing = 3;
public static final int gpsa = 4;
public static final int LAT = 5;
public static final int LON = 6;
public static final int HR = 7;
public static final int WATTS = 8;
public static final int NM = 9;
public static final int CAD = 10;
public static final int KM = 11;
public static final int LTE = 12;
public static final int RTE = 13;
public static final int SNPLC = 14;
public static final int SNPR = 15;
public static final int ms2x = 16;
public static final int ms2y = 17;
public static final int ms2z = 18;
public static final int temp = 19;
public static final int uTx = 20;
public static final int uTy = 21;
public static final int uTz = 22;
public static final int press = 23;
public static final int lux = 24;
public static CharSequence[] KEYS = {
"SECS",
"KPH",
"ALTITUDE",
"bearing",
"gpsa",
"LAT",
"LON",
"HR",
"WATTS",
"NM",
"CAD",
"KM",
"LTE",
"RTE",
"SNPLC",
"SNPR",
"ms2x",
"ms2y",
"ms2z",
"temp",
"uTx",
"uTy",
"uTz",
"press",
"lux"
};
public GzipWriter buf; //writes to log file buffered
public long startTime; //start time of the ride
public float[] currentValues = new float[RideService.KEYS.length]; //float array of current values
private Messenger mMessenger = null; //class to send back current values if needed
private boolean rideStarted = false; //have we started logging the ride
private int sensor_index = 0; //current index of sensors
private String emergencyNumbuer; //the number to send the messages to
private Timer timer; //timer class to control the periodic messages
private Timer timerUI; //timer class to control the periodic messages
private Base<?>[] sensors; //list of sensors tracking
public BaseFormat<?> fileFormat;
/**
* starts the ride on service start
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startRide();
return Service.START_NOT_STICKY;
}
/**
* returns the messenger to talk to the app with
*/
@Override
public IBinder onBind(Intent arg0) {
mMessenger = new Messenger(new Handler() { // Handler of incoming messages from clients.
Messenger replyTo;
@Override
public void handleMessage(Message msg) {
if(timerUI != null) {
timerUI.cancel();
timerUI = null;
}
timerUI = new Timer();
if(msg.replyTo != null) {
replyTo = msg.replyTo;
timerUI.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
Message msg = Message.obtain(null, 2, 0, 0);
Bundle bundle = new Bundle();
bundle.putSerializable("currentValues", currentValues);
msg.setData(bundle);
try {
replyTo.send(msg);
} catch (RemoteException e) {}
}
},
1000,
1000
); //every second update the screen
}
}
}); // Target we publish for clients to send messages to IncomingHandler.
return mMessenger.getBinder();
}
/**
* releases the timer that sends messages to the app
*/
@Override
public boolean onUnbind (Intent intent) {
if(timerUI != null) {
timerUI.cancel();
timerUI = null;
}
mMessenger = null;
return true;
}
/**
* stop the ride on service stop
*/
@Override
public void onDestroy() {
stopRide();
super.onDestroy();
}
/**
* start a ride if there is not one started yet
*/
protected void startRide() {
if(rideStarted) return;
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
emergencyNumbuer = settings.getString(getString(R.string.PREF_EMERGENCY_NUMBER), "");
currentValues[SECS] = (float) 0.0;
startTime = System.currentTimeMillis();
Date startDate = new Date(startTime);
SimpleDateFormat startTimef = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
SimpleDateFormat filef = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
SimpleDateFormat month = new SimpleDateFormat("MMMMM");
SimpleDateFormat year = new SimpleDateFormat("yyyy");
SimpleDateFormat day = new SimpleDateFormat("EEEEE");
startTimef.setTimeZone(TimeZone.getTimeZone("UTC"));
filef.setTimeZone(TimeZone.getTimeZone("UTC"));
month.setTimeZone(TimeZone.getTimeZone("UTC"));
year.setTimeZone(TimeZone.getTimeZone("UTC"));
day.setTimeZone(TimeZone.getTimeZone("UTC"));
final String fileName = filef.format(startDate) + ".json.gz";
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
fileFormat = new JsonFormat(this);
fileFormat.createFile();
fileFormat.writeHeader();
LogAnt.setDebugLevel(LogAnt.DebugLevel.NONE, this);
final Set<String> pairedAnts = settings.getStringSet(getString(R.string.PREF_PAIRED_ANTS), null);
if(pairedAnts != null && !pairedAnts.isEmpty()){
sensors = new Base<?>[pairedAnts.size() + 2];
for(String deviceNumber: pairedAnts) {
DeviceType deviceType = DeviceType.getValueFromInt(settings.getInt(deviceNumber, 0));
switch (deviceType) {
case BIKE_CADENCE:
break;
case BIKE_POWER:
sensors[sensor_index++] = new Power(Integer.valueOf(deviceNumber), this);
break;
case BIKE_SPD:
break;
case BIKE_SPDCAD:
break;
case BLOOD_PRESSURE:
break;
case ENVIRONMENT:
break;
case WEIGHT_SCALE:
break;
case HEARTRATE:
sensors[sensor_index++] = new HeartRate(Integer.valueOf(deviceNumber), this);
break;
case STRIDE_SDM:
break;
case FITNESS_EQUIPMENT:
break;
case GEOCACHE:
case CONTROLLABLE_DEVICE:
break;
case UNKNOWN:
break;
default:
break;
}
}
} else {
sensors = new Base<?>[4];
sensors[sensor_index++] = new HeartRate(0, this);
sensors[sensor_index++] = new Power(0, this);
}
sensors[sensor_index++] = new Gps(this);
sensors[sensor_index++] = new Sensors(this);
}
rideStarted = true;
if(settings.getBoolean(getString(R.string.PREF_PHONE_HOME), false)) {
timer = new Timer();
int period = Integer.parseInt(settings.getString(getString(R.string.PREF_PHONE_HOME_PERIOD), "10"));
timer.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
phoneHome();
}
},
60000 * period,
60000 * period
); //every ten min let them know where you are at
phoneStart();
}
//build the notification in the top android drawer
NotificationCompat.Builder mBuilder = new NotificationCompat
.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getString(R.string.ride_on))
.setContentText(getString(R.string.building_ride) + " " + fileName + " " + getString(R.string.click_to_stop))
.setProgress(0, 0, true)
.setContentIntent(
TaskStackBuilder
.create(this)
.addParentStack(StartActivity.class)
.addNextIntent(new Intent(this, StartActivity.class))
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
);
startForeground(notifyID, mBuilder.build());
}
/**
* let a love one know where you are at about every 10 min
*/
public void phoneCrash(double mag) {
smsHome(
getString(R.string.crash_warning) + "\n" + getLocationLink()
+ "\n " + getString(R.string.crash_magnitude) + ": " + String.valueOf(mag)
);
}
/**
* confirm the crash if we are not moving
*/
public void phoneCrashConfirm() {
smsHome(getString(R.string.crash_confirm) + "!\n" + getLocationLink());
}
/**
* let them know we are starting
*/
public void phoneStart() {
smsWithLocation(getString(R.string.ride_start_sms));
}
/**
* let them know we are stopping
*/
public void phoneStop() {
smsWithLocation(getString(R.string.ride_stop_sms));
}
/**
* send an sms with location
*/
public void smsWithLocation(String body) {
smsHome(body + "\n " + getLocationLink());
}
/**
* let a love one know where you are at about every 10 min
*/
public void phoneHome() {
smsWithLocation(getString(R.string.riding_ok_sms));
}
/**
* send a sms message
*/
public void smsHome(String body) {
SmsManager smsManager = SmsManager.getDefault();
if(emergencyNumbuer != null && PhoneNumberUtils.isWellFormedSmsAddress(emergencyNumbuer)) {
smsManager.sendTextMessage(emergencyNumbuer, null, body, null, null);
}
}
public String getLocationLink() {
if(currentValues[LAT] != 0.0 || currentValues[LON] != 0.0) {
return "https://www.google.com/maps/place/" + currentValues[LAT] + "," + currentValues[LON];
}
return getString(R.string.crash_unknow_location);
}
//stop the ride and clean up resources
protected void stopRide() {
if(!rideStarted) return;
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
if(settings.getBoolean(getString(R.string.PREF_PHONE_HOME), false)) {
phoneStop();
}
for(Base<?> sensor: sensors) {
if(sensor != null) {
sensor.onDestroy();
}
}
//stop the phoneHome timer if we need to.
if(timer != null) {
timer.cancel();
timer = null;
}
if(timerUI != null) {
timerUI.cancel();
timerUI = null;
}
fileFormat.writeFooter();
rideStarted = false;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(notifyID);
}
}

View File

@@ -1,274 +0,0 @@
package com.ridelogger;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceType;
import com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult;
import com.dsi.ant.plugins.antplus.pccbase.MultiDeviceSearch;
import com.dsi.ant.plugins.antplus.pccbase.MultiDeviceSearch.MultiDeviceSearchResult;
import com.dsi.ant.plugins.utility.log.LogAnt;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
public class SettingsActivity extends PreferenceActivity {
static ArrayList<MultiDeviceSearchResult> foundDevices = new ArrayList<MultiDeviceSearchResult>();
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class GeneralFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.general_settings);
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(((SettingsActivity) getActivity()).getServiceRunning(RideService.class) != null) {
Preference pref = findPreference(getString(R.string.PREF_RIDER_NAME));
pref.setEnabled(false);
pref = findPreference(getString(R.string.PREF_EMERGENCY_NUMBER));
pref.setEnabled(false);
}
}
}
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class SensorsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.sensors_settings);
MultiSelectListPreference mMultiSelectListPreference = (MultiSelectListPreference) findPreference(getString(R.string.PREF_TRACKING_SENSORS));
mMultiSelectListPreference.setEntries( RideService.KEYS );
CharSequence[] keys = new CharSequence[RideService.KEYS.length];
for (int i = 0; i < RideService.KEYS.length; i++) {
keys[i] = String.valueOf(i);
}
mMultiSelectListPreference.setEntryValues(keys);
}
}
@Override
public boolean isValidFragment(String fragment) {
return true;
}
/**
* This fragment contains a second-level set of preference that you
* can get to by tapping an item in the first preferences fragment.
*/
public static class AntFragment extends PreferenceFragment {
private MultiDeviceSearch mSearch;
private MultiSelectListPreference mMultiSelectListPreference;
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.ant_settings);
mMultiSelectListPreference = (MultiSelectListPreference) findPreference(getString(R.string.PREF_PAIRED_ANTS));
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
initAntSearch();
}
/**
* search for ant+ if we are not recording
*/
public void initAntSearch() {
mMultiSelectListPreference.setEnabled(false);
if(((SettingsActivity) getActivity()).getServiceRunning(RideService.class) == null) {
mMultiSelectListPreference.setSummary(R.string.searching_for_ants);
setupAnt();
Timer timer = new Timer();
final Handler handler = new Handler();
timer.schedule(
new TimerTask() {
@Override
public void run() {
if(mMultiSelectListPreference.getEntryValues().length > 0) {
handler.post(new Runnable() {
public void run() {
mMultiSelectListPreference.setEnabled(true);
mMultiSelectListPreference.setSummary(R.string.found_ants);
}
});
} else {
handler.post(new Runnable() {
public void run() {
mMultiSelectListPreference.setEnabled(true);
mMultiSelectListPreference.setSummary(R.string.no_found_ants);
}
});
}
}
},
5000
);
}
}
/**
* try to pair some ant+ devices
*/
protected void setupAnt() {
MultiDeviceSearch.SearchCallbacks mCallback;
MultiDeviceSearch.RssiCallback mRssiCallback;
updateList(foundDevices);
LogAnt.setDebugLevel(LogAnt.DebugLevel.NONE, this.getActivity());
mCallback = new MultiDeviceSearch.SearchCallbacks(){
public void onDeviceFound(final MultiDeviceSearchResult deviceFound)
{
if(!foundDevices.contains(deviceFound)) {
foundDevices.add(deviceFound);
updateList(foundDevices);
}
}
@Override
public void onSearchStopped(RequestAccessResult arg0) {}
};
mRssiCallback = new MultiDeviceSearch.RssiCallback() {
@Override
public void onRssiUpdate(final int resultId, final int rssi){}
};
// start the multi-device search
mSearch = new MultiDeviceSearch(this.getActivity(), EnumSet.allOf(DeviceType.class), mCallback, mRssiCallback);
}
/**
* dialog of soon to be paired ant devices
* @param foundDevices
*/
protected void updateList(final ArrayList<MultiDeviceSearchResult> foundDevices) {
ArrayList<CharSequence> foundDevicesString = new ArrayList<CharSequence>();
ArrayList<CharSequence> foundDevicesValues = new ArrayList<CharSequence>();
for(MultiDeviceSearchResult device : foundDevices) {
foundDevicesString.add(device.getAntDeviceType() + ": " + String.valueOf(device.getAntDeviceNumber()));
}
for(MultiDeviceSearchResult device : foundDevices) {
foundDevicesValues.add(String.valueOf(device.getAntDeviceNumber()));
}
if(mMultiSelectListPreference != null) {
mMultiSelectListPreference.setEntries(
foundDevicesString.toArray(new CharSequence[foundDevicesString.size()])
);
mMultiSelectListPreference.setEntryValues(
foundDevicesValues.toArray(new CharSequence[foundDevicesValues.size()])
);
}
}
@Override
public void onDestroy() {
if(mSearch != null) mSearch.close();
super.onDestroy();
}
}
/**
* Populate the activity with the top-level headers.
*/
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.layout.settings, target);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
settings.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String pkey) {
if (pkey == getString(R.string.PREF_PAIRED_ANTS)) {
Set<String> sensors = sharedPreferences.getStringSet(pkey, null);
if(sensors != null && sensors.size() > 0) {
Editor editor = sharedPreferences.edit();
for(MultiDeviceSearchResult result : foundDevices) {
sensors.contains(String.valueOf(result.getAntDeviceNumber()));
editor.putInt(String.valueOf(result.getAntDeviceNumber()), result.getAntDeviceType().getIntValue());
}
editor.commit();
}
}
}
}
);
}
/**
* is a service running or not
* @param serviceClass
* @return
*/
public RunningServiceInfo getServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return service;
}
}
return null;
}
}

View File

@@ -1,215 +0,0 @@
package com.ridelogger;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.GridView;
import android.widget.Toast;
public class StartActivity extends FragmentActivity
{
private MenuItem startMenu;
private MenuItem stopMenu;
private ServiceConnection mConnection;
static CurrentValuesAdapter currentValuesAdapter;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.start_activity, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
if(item.getItemId() == R.id.Settings) {
setupSettings();
} else if(item.getItemId() == R.id.Start) {
startRide();
} else {
stopRide();
}
return true;
}
/**
* start up our class
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
GridView layout = (GridView) findViewById(R.id.LayoutData);
currentValuesAdapter = new CurrentValuesAdapter(this, layout);
layout.setAdapter(currentValuesAdapter);
}
@Override
protected void onResume() {
super.onResume();
bindToService();
}
@Override
protected void onPause() {
super.onPause();
unBindToService();
}
@Override
protected void onStop() {
super.onStop();
unBindToService();
}
/**
* setup the settings for the user
*/
private void setupSettings() {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
/**
* stop ride and clean up references
*/
private void stopRide() {
Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.stopping_ride), Toast.LENGTH_LONG);
toast.show();
Intent rsi = new Intent(this, RideService.class);
this.stopService(rsi);
finish();
}
static final Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg_internal) {
updateValues(msg_internal.getData());
}
};
/**
* tell the service to start sending us messages with current values
*/
private void bindToService() {
RunningServiceInfo service = getServiceRunning(RideService.class);
if(service != null) {
mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Messenger mService = new Messenger(service);
try {
Message msg = Message.obtain();
msg.replyTo = new Messenger(mHandler);
mService.send(msg);
} catch (RemoteException e) {
// In this case the service has crashed before we could even do anything with it
}
}
public void onServiceDisconnected(ComponentName className) {}
};
bindService(new Intent(StartActivity.this, RideService.class), mConnection, Context.BIND_AUTO_CREATE);
}
}
/**
* tell the service to stop sending us messages with current values
*/
private void unBindToService() {
if (mConnection != null) {
// Detach our existing connection.
unbindService(mConnection);
mConnection = null;
}
}
/**
* update the text fields with current values
* @param bundle
*/
private static void updateValues(Bundle bundle) {
currentValuesAdapter.update((float[]) bundle.getSerializable("currentValues"));
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
RunningServiceInfo service = getServiceRunning(RideService.class);
startMenu = menu.findItem(R.id.Start);
stopMenu = menu.findItem(R.id.Stop);
if(service == null) {
startMenu.setVisible(true);
stopMenu.setVisible(false);
} else {
startMenu.setVisible(false);
stopMenu.setVisible(true);
}
return true;
}
/**
* start the ride and notify the user of success
*/
private void startRide() {
Intent rsi = new Intent(this, RideService.class);
this.startService(rsi);
startMenu.setVisible(false);
stopMenu.setVisible(true);
bindToService();
Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.starting_ride), Toast.LENGTH_LONG);
toast.show();
}
/**
* is a service running or not
* @param serviceClass
* @return
*/
private RunningServiceInfo getServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return service;
}
}
return null;
}
}

View File

@@ -1,71 +0,0 @@
package com.ridelogger.formats;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Environment;
import com.ridelogger.GzipWriter;
import com.ridelogger.RideService;
public class BaseFormat<T> {
protected GzipWriter buf;
protected RideService context;
protected String subExt = "";
public BaseFormat(RideService rideService) {
context = rideService;
}
public void createFile() {
File dir = new File(
Environment.getExternalStorageDirectory(),
"Rides"
);
dir.mkdirs();
Date startDate = new Date(context.startTime);
SimpleDateFormat filef = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
String fileName = filef.format(startDate) + subExt + ".gz";
try {
buf = new GzipWriter(new BufferedOutputStream(new FileOutputStream(new File(dir, fileName))));
} catch (Exception e) {}
}
public void writeHeader(){
try {
synchronized (buf) {
for(CharSequence key : RideService.KEYS) {
buf.write(key);
buf.write(",");
}
}
} catch (Exception e) {}
}
public void writeValues() {
try {
synchronized (buf) {
for(float value : context.currentValues) {
buf.write(value);
}
}
} catch (Exception e) {}
}
public void writeFooter() {
try {
buf.close();
} catch (Exception e) {}
}
}

View File

@@ -1,93 +0,0 @@
package com.ridelogger.formats;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import com.ridelogger.R;
import com.ridelogger.RideService;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class JsonFormat extends BaseFormat<Object> {
public JsonFormat(RideService rideService) {
super(rideService);
subExt = ".json";
}
public void writeHeader() {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
Date startDate = new Date(context.startTime);
SimpleDateFormat startTimef = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
SimpleDateFormat filef = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
SimpleDateFormat month = new SimpleDateFormat("MMMMM");
SimpleDateFormat year = new SimpleDateFormat("yyyy");
SimpleDateFormat day = new SimpleDateFormat("EEEEE");
startTimef.setTimeZone(TimeZone.getTimeZone("UTC"));
filef.setTimeZone(TimeZone.getTimeZone("UTC"));
month.setTimeZone(TimeZone.getTimeZone("UTC"));
year.setTimeZone(TimeZone.getTimeZone("UTC"));
day.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
buf.write("{" +
"\"RIDE\":{" +
"\"STARTTIME\":\"" + startTimef.format(startDate) + " UTC\"," +
"\"RECINTSECS\":1," +
"\"DEVICETYPE\":\"Android\"," +
"\"IDENTIFIER\":\"\"," +
"\"TAGS\":{" +
"\"Athlete\":\"" + settings.getString(context.getString(R.string.PREF_RIDER_NAME), "") + "\"," +
"\"Calendar Text\":\"Auto Recored Android Ride\"," +
"\"Change History\":\"\"," +
"\"Data\":\"\"," +
"\"Device\":\"\"," +
"\"Device Info\":\"\"," +
"\"File Format\":\"\"," +
"\"Filename\":\"\"," +
"\"Month\":\"" + month.format(startDate) +"\"," +
"\"Notes\":\"\"," +
"\"Objective\":\"\"," +
"\"Sport\":\"Bike\"," +
"\"Weekday\":\"" + day.format(startDate) + "\"," +
"\"Workout Code\":\"\"," +
"\"Year\":\"" + year.format(startDate) + "\"" +
"}," +
"\"SAMPLES\":[{\"SECS\":0}");
} catch (Exception e) {}
}
public void writeValues() {
try {
synchronized (buf) {
buf.write(",{");
buf.write("\"");
buf.write(RideService.KEYS[0]);
buf.write("\":");
buf.write(String.format("%f", context.currentValues[0]));
for (int i = 1; i < context.currentValues.length; i++) {
buf.write(",\"");
buf.write(RideService.KEYS[i]);
buf.write("\":");
buf.write(String.format("%f", context.currentValues[i]));
}
buf.write("}");
}
} catch (Exception e) {}
}
public void writeFooter() {
try {
buf.write("]}}");
} catch (Exception e) {}
super.writeFooter();
}
}

View File

@@ -1,54 +0,0 @@
package com.ridelogger.listners;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceState;
import com.dsi.ant.plugins.antplus.pccbase.PccReleaseHandle;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IDeviceStateChangeReceiver;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IPluginAccessResultReceiver;
import com.ridelogger.RideService;
/**
* Ant
* @author Chet Henry
* Listen to and log Ant+ events base class
*/
public abstract class Ant extends Base<Object>
{
protected PccReleaseHandle<?> releaseHandle; //Handle class
public IPluginAccessResultReceiver<?> mResultReceiver; //Receiver class
protected int deviceNumber = 0;
//setup listeners and logging
public Ant(int pDeviceNumber, RideService mContext)
{
super(mContext);
deviceNumber = pDeviceNumber;
}
public IDeviceStateChangeReceiver mDeviceStateChangeReceiver = new IDeviceStateChangeReceiver()
{
@Override
public void onDeviceStateChange(final DeviceState newDeviceState){
//if we lose a device zero out its values
if(newDeviceState.equals(DeviceState.DEAD)) {
zeroReadings();
}
}
};
abstract protected void requestAccess();
@Override
public void onDestroy()
{
if(releaseHandle != null) {
releaseHandle.close();
}
}
}

View File

@@ -1,58 +0,0 @@
package com.ridelogger.listners;
import com.ridelogger.RideService;
/**
* Base
* @author Chet Henry
* Base sensor class that has methods to time stamp are write to buffer
*/
public class Base<T>
{
public RideService context;
public Base(RideService mContext) {
context = mContext;
}
public void alterCurrentData(int key, float value)
{
synchronized (context.currentValues) {
context.currentValues[RideService.SECS] = getTs();
context.currentValues[key] = value;
context.fileFormat.writeValues();
}
}
public void alterCurrentData(int[] keys, float[] values)
{
synchronized (context.currentValues) {
context.currentValues[RideService.SECS] = getTs();
int i = 0;
for (int key : keys) {
context.currentValues[key] = values[i];
i++;
}
context.fileFormat.writeValues();
}
}
//get current time stamp
public float getTs() {
return (float) ((System.currentTimeMillis() - context.startTime) / 1000.0);
}
//Clean up my listeners here
public void onDestroy() {}
//zero any of my values
public void zeroReadings() {}
}

View File

@@ -1,61 +0,0 @@
package com.ridelogger.listners;
import com.ridelogger.RideService;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
/**
* Gps
* @author henry
* Listen and log gps events
*/
public class Gps extends Base<Gps>
{
public Gps(RideService mContext)
{
super(mContext);
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//listen to gps events and log them
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
int[] keys = {
RideService.ALTITUDE,
RideService.KPH,
RideService.bearing,
RideService.gpsa,
RideService.LAT,
RideService.LON
};
float[] values = {
(float) location.getAltitude(),
location.getSpeed(),
location.getBearing(),
location.getAccuracy(),
(float) location.getLatitude(),
(float) location.getLongitude()
};
alterCurrentData(keys, values);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
}

View File

@@ -1,69 +0,0 @@
package com.ridelogger.listners;
import com.dsi.ant.plugins.antplus.pcc.AntPlusHeartRatePcc;
import com.dsi.ant.plugins.antplus.pcc.AntPlusHeartRatePcc.DataState;
import com.dsi.ant.plugins.antplus.pcc.AntPlusHeartRatePcc.IHeartRateDataReceiver;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceState;
import com.dsi.ant.plugins.antplus.pcc.defines.EventFlag;
import com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IPluginAccessResultReceiver;
import com.ridelogger.RideService;
import java.math.BigDecimal;
import java.util.EnumSet;
/**
* HeartRate
* @author Chet Henry
* Listen to and log Ant+ HearRate events
*/
public class HeartRate extends Ant
{
public IPluginAccessResultReceiver<AntPlusHeartRatePcc> mResultReceiver;
public HeartRate(int pDeviceNumber, RideService mContext) {
super(pDeviceNumber, mContext);
mResultReceiver = new IPluginAccessResultReceiver<AntPlusHeartRatePcc>() {
//Handle the result, connecting to events on success or reporting failure to user.
@Override
public void onResultReceived(AntPlusHeartRatePcc result, RequestAccessResult resultCode, DeviceState initialDeviceState)
{
if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SUCCESS) {
deviceNumber = result.getAntDeviceNumber();
result.subscribeHeartRateDataEvent(
new IHeartRateDataReceiver() {
@Override
public void onNewHeartRateData(final long estTimestamp, EnumSet<EventFlag> eventFlags, final int computedHeartRate, final long heartBeatCount, final BigDecimal heartBeatEventTime, final DataState dataState) {
alterCurrentData(RideService.HR, (float) computedHeartRate);
}
}
);
} else if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SEARCH_TIMEOUT) {
if(deviceNumber != 0) {
requestAccess();
}
}
}
};
requestAccess();
}
@Override
protected void requestAccess() {
releaseHandle = AntPlusHeartRatePcc.requestAccess(context, deviceNumber, 0, mResultReceiver, mDeviceStateChangeReceiver);
}
@Override
public void zeroReadings()
{
alterCurrentData(RideService.HR, (float) 0.0);
}
}

View File

@@ -1,223 +0,0 @@
package com.ridelogger.listners;
import android.preference.PreferenceManager;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.CalculatedWheelDistanceReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.CalculatedWheelSpeedReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.DataSource;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.ICalculatedCrankCadenceReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.ICalculatedPowerReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.ICalculatedTorqueReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.IInstantaneousCadenceReceiver;
import com.dsi.ant.plugins.antplus.pcc.AntPlusBikePowerPcc.IRawPowerOnlyDataReceiver;
import com.dsi.ant.plugins.antplus.pcc.defines.DeviceState;
import com.dsi.ant.plugins.antplus.pcc.defines.EventFlag;
import com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult;
import com.dsi.ant.plugins.antplus.pccbase.AntPluginPcc.IPluginAccessResultReceiver;
import com.ridelogger.R;
import com.ridelogger.RideService;
import java.math.BigDecimal;
import java.util.EnumSet;
/**
* Power
* @author Chet Henry
* Listen to and log Ant+ Power events
*/
public class Power extends Ant
{
public BigDecimal wheelCircumferenceInMeters; //size of wheel to calculate speed
public IPluginAccessResultReceiver<AntPlusBikePowerPcc> mResultReceiver;
//setup listeners and logging
public Power(int pDeviceNumber, RideService mContext) {
super(pDeviceNumber, mContext);
wheelCircumferenceInMeters = new BigDecimal(
PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.PREF_WHEEL_SIZE), "2.096")
);
//Handle messages
mResultReceiver = new IPluginAccessResultReceiver<AntPlusBikePowerPcc>() {
//Handle the result, connecting to events on success or reporting failure to user.
@Override
public void onResultReceived(AntPlusBikePowerPcc result, RequestAccessResult resultCode, DeviceState initialDeviceState) {
if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SUCCESS) {
deviceNumber = result.getAntDeviceNumber();
result.subscribeCalculatedPowerEvent(new ICalculatedPowerReceiver() {
@Override
public void onNewCalculatedPower(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedPower) {
alterCurrentData(RideService.WATTS, calculatedPower.floatValue());
}
}
);
result.subscribeCalculatedTorqueEvent(
new ICalculatedTorqueReceiver() {
@Override
public void onNewCalculatedTorque(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedTorque) {
alterCurrentData(RideService.NM, calculatedTorque.floatValue());
}
}
);
result.subscribeCalculatedCrankCadenceEvent(
new ICalculatedCrankCadenceReceiver() {
@Override
public void onNewCalculatedCrankCadence(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedCrankCadence) {
alterCurrentData(RideService.CAD, calculatedCrankCadence.floatValue());
}
}
);
result.subscribeCalculatedWheelSpeedEvent(
new CalculatedWheelSpeedReceiver(wheelCircumferenceInMeters) {
@Override
public void onNewCalculatedWheelSpeed(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedWheelSpeed)
{
alterCurrentData(RideService.KPH, calculatedWheelSpeed.floatValue());
}
}
);
result.subscribeCalculatedWheelDistanceEvent(
new CalculatedWheelDistanceReceiver(wheelCircumferenceInMeters) {
@Override
public void onNewCalculatedWheelDistance(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final BigDecimal calculatedWheelDistance)
{
alterCurrentData(RideService.KM, calculatedWheelDistance.floatValue());
}
}
);
result.subscribeInstantaneousCadenceEvent(
new IInstantaneousCadenceReceiver() {
@Override
public void onNewInstantaneousCadence(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final DataSource dataSource, final int instantaneousCadence)
{
alterCurrentData(RideService.CAD, (float) instantaneousCadence);
}
}
);
result.subscribeRawPowerOnlyDataEvent(
new IRawPowerOnlyDataReceiver() {
@Override
public void onNewRawPowerOnlyData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final int instantaneousPower, final long accumulatedPower)
{
alterCurrentData(RideService.WATTS, (float) instantaneousPower);
}
}
);
/*result.subscribePedalPowerBalanceEvent(
new IPedalPowerBalanceReceiver() {
@Override
public void onNewPedalPowerBalance(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final boolean rightPedalIndicator, final int pedalPowerPercentage)
{
alterCurrentData(RideService.LTE, pedalPowerPercentage);
}
}
);
result.subscribeRawWheelTorqueDataEvent(
new IRawWheelTorqueDataReceiver() {
@Override
public void onNewRawWheelTorqueData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long wheelTorqueUpdateEventCount, final long accumulatedWheelTicks, final BigDecimal accumulatedWheelPeriod, final BigDecimal accumulatedWheelTorque)
{
alterCurrentData(RideService.NM, accumulatedWheelTorque);
}
}
);
result.subscribeRawCrankTorqueDataEvent(
new IRawCrankTorqueDataReceiver() {
@Override
public void onNewRawCrankTorqueData(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long crankTorqueUpdateEventCount, final long accumulatedCrankTicks, final BigDecimal accumulatedCrankPeriod, final BigDecimal accumulatedCrankTorque)
{
alterCurrentData(RideService.NM, accumulatedCrankTorque);
}
}
);
result.subscribeTorqueEffectivenessEvent(
new ITorqueEffectivenessReceiver() {
@Override
public void onNewTorqueEffectiveness(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final BigDecimal leftTorqueEffectiveness, final BigDecimal rightTorqueEffectiveness)
{
int[] keys = {
RideService.LTE,
RideService.RTE
};
float[] values = {
leftTorqueEffectiveness,
rightTorqueEffectiveness
}
alterCurrentData(keys, values);
}
}
);
result.subscribePedalSmoothnessEvent(new IPedalSmoothnessReceiver() {
@Override
public void onNewPedalSmoothness(final long estTimestamp, final EnumSet<EventFlag> eventFlags, final long powerOnlyUpdateEventCount, final boolean separatePedalSmoothnessSupport, final BigDecimal leftOrCombinedPedalSmoothness, final BigDecimal rightPedalSmoothness)
{
int[] keys = {
RideService.SNPLC,
RideService.SNPR
};
float[] values = {
leftOrCombinedPedalSmoothness,
rightPedalSmoothness
}
alterCurrentData(map);
}
}
);*/
} else if(resultCode == com.dsi.ant.plugins.antplus.pcc.defines.RequestAccessResult.SEARCH_TIMEOUT) {
if(deviceNumber != 0) {
requestAccess();
}
}
}
};
requestAccess();
}
protected void requestAccess() {
releaseHandle = AntPlusBikePowerPcc.requestAccess(context, deviceNumber, 0, mResultReceiver, mDeviceStateChangeReceiver);
}
@Override
public void zeroReadings()
{
int[] keys = {
RideService.WATTS,
RideService.NM,
RideService.CAD,
RideService.KPH,
RideService.KM
};
float[] values = {
(float) 0.0,
(float) 0.0,
(float) 0.0,
(float) 0.0,
(float) 0.0
};
alterCurrentData(keys, values);
}
}

View File

@@ -1,222 +0,0 @@
package com.ridelogger.listners;
import java.util.Timer;
import java.util.TimerTask;
import com.ridelogger.R;
import com.ridelogger.RideService;
import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.preference.PreferenceManager;
/**
* Sensors
* @author Chet Henry
* Listen to android sensor events and log them
*/
public class Sensors extends Base<Object>
{
public static final double CRASHMAGNITUDE = 30.0;
private SensorEventListener luxListner;
private SensorEventListener accelListner;
private SensorEventListener pressListner;
private SensorEventListener tempListner;
private SensorEventListener fieldListner;
public Sensors(RideService mContext)
{
super(mContext);
SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Sensor mAccel = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
Sensor mPress = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
Sensor mTemp = mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
Sensor mField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
if(mLight != null) {
luxListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
alterCurrentData(RideService.lux, event.values[0]);
}
};
mSensorManager.registerListener(luxListner, mLight, 3000000);
}
if(mAccel != null) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
if(settings.getBoolean(context.getString(R.string.PREF_DETECT_CRASH), false)) {
accelListner = new SensorEventListener() {
private boolean crashed = false;
private Timer timer = new Timer();
private double[] St = new double[3];
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
int[] keys = {
RideService.ms2x,
RideService.ms2y,
RideService.ms2z
};
alterCurrentData(keys, event.values);
if(St.length == 0) {
St[0] = event.values[0];
St[1] = event.values[1];
St[2] = event.values[2];
}
St[0] = 0.6 * event.values[0] + 0.4 * St[0];
St[1] = 0.6 * event.values[1] + 0.4 * St[1];
St[2] = 0.6 * event.values[2] + 0.4 * St[2];
double amag = Math.sqrt(St[0]*St[0] + St[1]*St[1] + St[2]*St[2]);
if(amag > CRASHMAGNITUDE && !crashed) {
crashed = true;
context.phoneCrash(amag);
if(!Float.isNaN(context.currentValues[RideService.KPH])) {
timer.schedule(
new TimerTask() {
@Override
public void run() {
//if we are traveling less then 1km/h at 5 seconds after crash detection
// confirm the crash
if(1.0 > context.currentValues[RideService.KPH]) {
context.phoneCrashConfirm();
} else {
crashed = false;
context.phoneHome();
}
}
},
5000
); //in five sec reset
} else {
timer.schedule(
new TimerTask() {
@Override
public void run() {
crashed = false;
}
},
180000
); //in three min reset
}
}
}
};
} else {
accelListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
int[] keys = {
RideService.ms2x,
RideService.ms2y,
RideService.ms2z
};
alterCurrentData(keys, event.values);
}
};
}
mSensorManager.registerListener(accelListner, mAccel, SensorManager.SENSOR_DELAY_NORMAL);
}
if(mPress != null) {
pressListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
alterCurrentData(RideService.press, event.values[0]);
}
};
mSensorManager.registerListener(pressListner, mPress, 3000000);
}
if(mTemp != null) {
tempListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
alterCurrentData(RideService.temp, event.values[0]);
}
};
mSensorManager.registerListener(tempListner, mTemp, 3000000);
}
if(mField != null) {
fieldListner = new SensorEventListener() {
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public final void onSensorChanged(SensorEvent event) {
int[] keys = {
RideService.uTx,
RideService.uTy,
RideService.uTz
};
alterCurrentData(keys, event.values);
}
};
mSensorManager.registerListener(fieldListner, mField, SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
public void onDestroy()
{
SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if(luxListner != null) {
mSensorManager.unregisterListener(luxListner);
}
if(accelListner != null) {
mSensorManager.unregisterListener(accelListner);
}
if(pressListner != null) {
mSensorManager.unregisterListener(pressListner);
}
if(tempListner != null) {
mSensorManager.unregisterListener(tempListner);
}
if(fieldListner != null) {
mSensorManager.unregisterListener(fieldListner);
}
}
}

Binary file not shown.

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View File

@@ -8,10 +8,10 @@ OTHER= 3d.png choose-a-cyclist.png cpint.gp cpint.png critical-power-plot.png cr
pm.png power.zones realtime.png ride-plot.png ride-plot2.png ride-summary.png sample.gp \
sample.png weekly-summary.png google-earth.png aerolab.png
BIN= GoldenCheetah_3.0.1_Mac_Universal.dmg \
GoldenCheetah-3.0.1-1.fc18.x86_64.rpm \
GoldenCheetah-3.0.1-1.fc19.x86_64.rpm \
GoldenCheetah_3.0.1_Windows_Installer.exe
BIN= GoldenCheetah_2.0.0_Linux_x86_64.gz \
GoldenCheetah_2.0.0_Linux_x86.gz \
GoldenCheetah_2.0.0_Mac_Universal.dmg \
GoldenCheetah_2.0.0_Windows_Installer.exe
all: $(HTML)
.PHONY: all clean install
@@ -21,11 +21,11 @@ clean:
install:
rsync -avz -e ssh $(HTML) $(TARBALLS) $(OTHER) \
goldencheetah.org:/home/srhea/wwwroot/goldencheetah.org/
liversedge@srhea.net:/home/srhea/wwwroot/goldencheetah.org/
install-bin:
rsync -avz -e ssh $(BIN) \
goldencheetah.org:/home/srhea/wwwroot/goldencheetah.org/
srhea.net:/home/srhea/wwwroot/goldencheetah.org/
bug-tracker.html: bug-tracker.content genpage.pl
./genpage.pl "Bug Tracker" $< > $@
@@ -51,15 +51,6 @@ download.html: download.content genpage.pl
release-notes.html: release-notes.content genpage.pl
./genpage.pl "Release Notes" $< > $@
release-notes_2.1.0.html: release-notes_2.1.0.content genpage.pl
./genpage.pl "Release Notes 2.1.0" $< > $@
release-notes_3.0.0.html: release-notes_3.0.0.content genpage.pl
./genpage.pl "Release Notes 3.0.0" $< > $@
release-notes_3.0.1.html: release-notes_3.0.1.content genpage.pl
./genpage.pl "Release Notes 3.0.1" $< > $@
faq.html: faq.content genpage.pl
./genpage.pl "Frequently Asked Questions" $< > $@
@@ -81,9 +72,6 @@ search.html: search.content genpage.pl
users-guide.html: users-guide.content genpage.pl
./genpage.pl "User's Guide" $< > $@
wiki.html: wiki.content genpage.pl
./genpage.pl "Wiki" $< > $@
wishlist.html: wishlist.content genpage.pl
./genpage.pl "Wish List" $< > $@

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

97
doc/bug-tracker.content Normal file
View File

@@ -0,0 +1,97 @@
<p>We have an issue tracker set up at
<a href=http://bugs.goldencheetah.org/projects/show/goldencheetah>
bugs.goldencheetah.org</a>. Below are some guidelines for users and
developers for working with the issue tracker.</p>
<big><font face="arial,helvetica,sanserif">
Report a new bug/feature
</font></big>
<p> If you think that you have found a bug in GoldenCheetah or would like
to request a new feature please report it by filing a new issue at our <a
href=http://bugs.goldencheetah.org/projects/show/goldencheetah>issue
tracker</a>. To report a bug/feature request go to the above link and
follow these steps:
<ol>
<li>Login or register for a new account.</li>
<li>Click the "new issue" link near the top of the page.</li>
<li>Select either "bug" or "feature" from the tracker drop-down menu.</li>
<li>Fill out the form including as much detail as possible.<br>
You can upload crashreports, problem files, or screenshots if they
help document the issue.</li>
<li>Click the create button to save your report.<br>
This will also send a copy of your report to the Golden-Cheetah-Users
mailing list.</li>
</ol>
<p>Thanks for helping to improve GoldenCheetah.</p>
<big><font face="arial,helvetica,sanserif">
Managing issues in the tracker
</font></big>
<p>To make it easier for all of us to track the status please try to
adhere to a few simple guidelines listed below.</p>
<font face="arial,helvetica,sanserif">
<b>Issue Status:</b>
</font>
<p>Depending on your account status (non-member, reporter, developer, or
manager) you may be able to update the status of an existing issue. When
working in the bug tracker please update the status appropriately.
Current status options are:</p>
<ul>
<li>New: Default status.
<li>Assigned: issue has been assigned to someone on the project. If you
are a Developer you can assign an issue to someone, including
yourself. If you are working on a fix, please change the status to
Assigned, and post a message stating your plan of attack etc.
<li>Feedback: This could be used to alert others that you have a
proposed fix that you want feed back on. Please attach patches and
make a note. Also remember to tag the issue in your patches.
<li>Resolved: The issue has been corrected. People that have tested the
patch or that submitted the bug should update to this status when
they feel that it has been fixed. If it turns out that it was not
resolved, most users can change the status back to "feedback". If
you do so, please leave a note.
<li>Tempfix: A workaround for the issue has been posted, but we may still be
working on a more long term solution.
<li>Closed: Those with commit access to Github are the only ones that
can mark an issue as closed. That said, if you are submitting a
patch that fixes and issue, please include the "fixes #<issuenum>"
tag to your commit as this will automatically close the issue when your
patch is accepted and pushed to github.
</ul>
<font face="arial,helvetica,sanserif">
<b>Tagging in messages</b>
</font>
<p>The tracker has a very basic tagging and markup scheme that is described in
detail <a href="http://bugs.goldencheetah.org/help/wiki_syntax.html">here</a>.
Perhaps the most useful feature is the ability to use tags to link issues,
commits, etc. When commenting on an issue please use the following tags
when appropriate to automatically create links when:</p>
<table align="center" width="600">
<tr>
<th>Tag</th>
<th>Effect</th>
</tr>
<tr>
<td>Issue #2</td>
<td>Creates a link to existing Issue #2</td>
</tr>
<tr>
<td>commit:e76247a</td>
<td>Creates a link to commit e76247a</td>
</tr>
<tr>
<td>source:src/MainWindow.cpp</td>
<td>Creates a link to src/Mainwindow.cpp in our git repo</td>
</tr>
</table>

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,18 +0,0 @@
@c gnupress.tex -- Common Texinfo macros for GNU Press books.
@c
@c Print in 7" x 9.25" format.
@smallbook
@advance@voffset by -0.25in
@special{papersize=7in,9.25in}
@c
@c Since we are using @smallbook, we ought to use @smallfonts
@tex
\global\let\lisporig=\lisp
\gdef\lisp{\smallexamplefonts\lisporig}%
\global\let\exampleorig=\example
\gdef\example{\smallexamplefonts\exampleorig}%
\global\let\displayorig=\display
\gdef\display{\smallexamplefonts\displayorig}%
\global\let\formatorig=\format
\gdef\format{\smallexamplefonts\formatorig}%
@end tex

View File

@@ -1,161 +0,0 @@
@c palatino.tex -- TeXinfo macros to set the default Roman font to Palatino
@c
@def@palatinoversion{2003-04-01.00}
@c
@c Copyright (C) 2003 Free Software Foundation, Inc.
@c
@c This palatino.tex file is free software; you can redistribute it and/or
@c modify it under the terms of the GNU General Public License as
@c published by the Free Software Foundation; either version 2, or (at
@c your option) any later version.
@c
@c This palatino.tex file is distributed in the hope that it will be
@c useful, but WITHOUT ANY WARRANTY; without even the implied warranty
@c of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@c General Public License for more details.
@c
@c You should have received a copy of the GNU General Public License
@c along with this texinfo.tex file; see the file COPYING. If not, write
@c to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@c Boston, MA 02111-1307, USA.
@c
@c You should use this module, go to your root .texi file and make sure
@c it reads like this:
@c \input texinfo @c -*-texinfo-*-
@c @input palatino
@message{Loading palatino [version @palatinoversion]:}
@c Turn on the normal TeX command characters.
@catcode`\=0
\catcode`\%=14
% Set the font macro #1 to the font named #2#3. #4 is the point size.
% We save \setfont as \setfontorig, so we can restore it at the end of this
% section.
\catcode`\#=6
\let\setfontorig=\setfont
\def\setfont#1#2#3#4{\font#1=#2#3 at #4}
\catcode`\#=\other
% Set Palatino as the default roman font face
\def\rmfontprefix{ppl}
% Only define roman font attributes here.
\def\rmshape{r}
\def\rmbshape{b}
\def\bfshape{b}
\def\bxshape{b}
\def\itshape{ri}
\def\itbshape{bi}
\def\slshape{ro}
\def\slbshape{bo}
\def\scshape{rc}
\def\scbshape{bc}
\ifx\bigger\relax
% not really supported.
\def\mainmagstep{12pt}
\setfont\textrm\rmfontprefix\rmshape{\mainmagstep}
\else
\def\mainmagstep{10pt}
\setfont\textrm\rmfontprefix\rmshape{\mainmagstep}
\fi
% Instead of cmb10, you many want to use cmbx10.
% cmbx10 is a prettier font on its own, but cmb10
% looks better when embedded in a line with cmr10.
\setfont\textbf\rmfontprefix\bfshape{\mainmagstep}
\setfont\textit\rmfontprefix\itshape{\mainmagstep}
\setfont\textsl\rmfontprefix\slshape{\mainmagstep}
\setfont\textsc\rmfontprefix\scshape{\mainmagstep}
\font\texti=zppler7m at \mainmagstep
\font\textsy=zppler7y at \mainmagstep
% A few fonts for \defun, etc.
\setfont\defbf\rmfontprefix\bxshape{10pt} %was 1314
\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
% Fonts for indices, footnotes, small examples (9pt).
\setfont\smallrm\rmfontprefix\rmshape{9pt}
\setfont\smallbf\rmfontprefix\bfshape{9pt}
\setfont\smallit\rmfontprefix\itshape{9pt}
\setfont\smallsl\rmfontprefix\slshape{9pt}
\setfont\smallsc\rmfontprefix\scshape{9pt}
\font\smalli=zppler7m at 9pt
\font\smallsy=zppler7y at 9pt
% Fonts for small examples (8pt).
\setfont\smallerrm\rmfontprefix\rmshape{8pt}
\setfont\smallerbf\rmfontprefix\bfshape{8pt}
\setfont\smallerit\rmfontprefix\itshape{8pt}
\setfont\smallersl\rmfontprefix\slshape{8pt}
\setfont\smallersc\rmfontprefix\scshape{8pt}
\font\smalleri=zppler7m at 8pt
\font\smallersy=zppler7y at 8pt
% Fonts for title page:
\setfont\titlerm\rmfontprefix\rmbshape{18pt}
\setfont\titleit\rmfontprefix\itbshape{18pt}
\setfont\titlesl\rmfontprefix\slbshape{18pt}
\let\titlebf=\titlerm
\setfont\titlesc\rmfontprefix\scbshape{18pt}
\font\titlei=zppler7m at 18pt
\font\titlesy=zppler7y at 18pt
\def\authorrm{\secrm}
\def\authortt{\sectt}
% Chapter (and unnumbered) fonts (17.28pt).
\setfont\chaprm\rmfontprefix\rmbshape{17.28pt}
\setfont\chapit\rmfontprefix\itbshape{17.28pt}
\setfont\chapsl\rmfontprefix\slbshape{17.28pt}
\let\chapbf=\chaprm
\setfont\chapsc\rmfontprefix\scbshape{17.28pt}
\font\chapi=zppler7m at 17.28pt
\font\chapsy=zppler7y at 17.28pt
% Section fonts (14.4pt).
\setfont\secrm\rmfontprefix\rmbshape{14.4pt}
\setfont\secit\rmfontprefix\itbshape{14.4pt}
\setfont\secsl\rmfontprefix\slbshape{14.4pt}
\let\secbf\secrm
\setfont\secsc\rmfontprefix\scbshape{14.4pt}
\font\seci=zppler7m at 14.4pt
\font\secsy=zppler7y at 14.4pt
% Subsection fonts (13.15pt).
\setfont\ssecrm\rmfontprefix\rmbshape{13.15pt}
\setfont\ssecit\rmfontprefix\itbshape{13.15pt}
\setfont\ssecsl\rmfontprefix\slbshape{13.15pt}
\let\ssecbf\ssecrm
\setfont\ssecsc\rmfontprefix\scbshape{13.15pt}
\font\sseci=zppler7m at 13.15pt
\font\ssecsy=zppler7y at 13.15pt
% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
% but that is not a standard magnification.
% Fonts for short table of contents.
\setfont\shortcontrm\rmfontprefix\rmshape{12pt}
\setfont\shortcontbf\rmfontprefix\bxshape{12pt}
\setfont\shortcontsl\rmfontprefix\slshape{12pt}
% Set keyfont as well.
\setfont\keyrm\rmfontprefix\rmshape{8pt}
\font\keysy=zppler7y at 9pt
\let\setfont=\setfontorig
\def\setfontorig{\relax}
% Restore the TeXinfo character set.
\catcode`\\=\active
@catcode`@%=@other
@c Set initial fonts (again)
@textfonts
@rm
@c Local variables:
@c eval: (add-hook 'write-file-hooks 'time-stamp)
@c page-delimiter: "^\\\\message"
@c time-stamp-start: "def\\\\palatinoversion{"
@c time-stamp-format: "%:y-%02m-%02d.%02H"
@c time-stamp-end: "}"
@c End:

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

View File

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

Before

Width:  |  Height:  |  Size: 195 KiB

After

Width:  |  Height:  |  Size: 195 KiB

View File

@@ -1,48 +0,0 @@
<mockup version="1.0" skin="sketch" fontFace="Balsamiq Sans" measuredW="591" measuredH="228" mockupW="566" mockupH="205">
<controls>
<control controlID="0" controlTypeID="com.balsamiq.mockups::Canvas" x="25" y="23" w="566" h="205" measuredW="100" measuredH="70" zOrder="0" locked="false" isInGroup="-1"/>
<control controlID="1" controlTypeID="com.balsamiq.mockups::HRule" x="31" y="37" w="560" h="-1" measuredW="100" measuredH="10" zOrder="1" locked="false" isInGroup="-1"/>
<control controlID="2" controlTypeID="com.balsamiq.mockups::Label" x="34" y="23" w="-1" h="-1" measuredW="110" measuredH="21" zOrder="2" locked="false" isInGroup="-1">
<controlProperties>
<text>Compare%20Intervals</text>
</controlProperties>
</control>
<control controlID="3" controlTypeID="com.balsamiq.mockups::CheckBox" x="40" y="191" w="-1" h="-1" measuredW="110" measuredH="22" zOrder="3" locked="false" isInGroup="-1">
<controlProperties>
<text>Compare%20Delta</text>
</controlProperties>
</control>
<control controlID="4" controlTypeID="com.balsamiq.mockups::Canvas" x="34" y="52" w="414" h="133" measuredW="100" measuredH="70" zOrder="4" locked="false" isInGroup="-1">
<controlProperties>
<borderStyle>roundedDotted</borderStyle>
</controlProperties>
</control>
<control controlID="6" controlTypeID="com.balsamiq.mockups::List" x="456" y="47" w="128" h="174" measuredW="100" measuredH="174" zOrder="5" locked="false" isInGroup="-1">
<controlProperties>
<text>May%202x20s%0ABarhatch%20Climbs%0ASub%204%20ToSH%0AMarmottes%0AAdH%20Ascents%0ABox%20Hill%202009%0ABox%20Hill%202013%0ABox%20Hill%20All</text>
</controlProperties>
</control>
<control controlID="7" controlTypeID="com.balsamiq.mockups::TextInput" x="170" y="189" w="225" h="-1" measuredW="138" measuredH="27" zOrder="6" locked="false" isInGroup="-1">
<controlProperties>
<text>Compare%20Set%20Name...</text>
</controlProperties>
</control>
<control controlID="8" controlTypeID="com.balsamiq.mockups::Button" x="402" y="189" w="-1" h="-1" measuredW="45" measuredH="27" zOrder="7" locked="false" isInGroup="-1">
<controlProperties>
<text>Add</text>
</controlProperties>
</control>
<control controlID="10" controlTypeID="com.balsamiq.mockups::RoundButton" x="569" y="24" w="15" h="18" measuredW="32" measuredH="32" zOrder="8" locked="false" isInGroup="-1">
<controlProperties>
<icon>CircledXIcon%7Cxsmall</icon>
<text/>
</controlProperties>
</control>
<control controlID="11" controlTypeID="com.balsamiq.mockups::Label" x="48" y="62" w="387" h="-1" measuredW="180" measuredH="21" zOrder="9" locked="false" isInGroup="-1">
<controlProperties>
<color>10066329</color>
<text>Drag%20and%20drop%20intervals%20here%20...</text>
</controlProperties>
</control>
</controls>
</mockup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

View File

@@ -1,610 +0,0 @@
<mockup version="1.0" skin="sketch" fontFace="Balsamiq Sans" measuredW="1997" measuredH="568" mockupW="1935" mockupH="553">
<controls>
<control controlID="0" controlTypeID="com.balsamiq.mockups::TitleWindow" x="62" y="61" w="355" h="400" measuredW="450" measuredH="400" zOrder="0" locked="false" isInGroup="-1">
<controlProperties>
<bottomheight>0</bottomheight>
<dragger>false</dragger>
<text>Chart%20Controls%20%5BLTM%20Chart%5D</text>
</controlProperties>
</control>
<control controlID="1" controlTypeID="com.balsamiq.mockups::TabBar" x="84" y="101" w="312" h="284" measuredW="219" measuredH="100" zOrder="1" locked="false" isInGroup="-1">
<controlProperties>
<text>Basic%2C%20Preset%2C%20Custom*</text>
</controlProperties>
</control>
<control controlID="2" controlTypeID="com.balsamiq.mockups::Button" x="321" y="413" w="75" h="27" measuredW="53" measuredH="27" zOrder="2" locked="false" isInGroup="-1">
<controlProperties>
<text>Done</text>
</controlProperties>
</control>
<control controlID="3" controlTypeID="com.balsamiq.mockups::List" x="101" y="164" w="-1" h="-1" measuredW="100" measuredH="126" zOrder="3" locked="false" isInGroup="-1">
<controlProperties>
<text>Best%0AFormula%0AMetric%0AMeasure</text>
</controlProperties>
</control>
<control controlID="4" controlTypeID="com.balsamiq.mockups::List" x="201" y="164" w="171" h="126" measuredW="100" measuredH="126" zOrder="4" locked="false" isInGroup="-1">
<controlProperties>
<text>Power%205s%0A%3D60m%20WPK%20*%20RPE%0AAverage_Power%0AWeight</text>
</controlProperties>
</control>
<control controlID="5" controlTypeID="com.balsamiq.mockups::TextInput" x="100" y="140" w="101" h="-1" measuredW="44" measuredH="27" zOrder="5" locked="false" isInGroup="-1">
<controlProperties>
<text>Type</text>
</controlProperties>
</control>
<control controlID="6" controlTypeID="com.balsamiq.mockups::TextInput" x="201" y="140" w="171" h="-1" measuredW="56" measuredH="27" zOrder="6" locked="false" isInGroup="-1">
<controlProperties>
<text>Details</text>
</controlProperties>
</control>
<control controlID="7" controlTypeID="com.balsamiq.mockups::Button" x="101" y="298" w="75" h="27" measuredW="46" measuredH="27" zOrder="7" locked="false" isInGroup="-1">
<controlProperties>
<text>Edit</text>
</controlProperties>
</control>
<control controlID="8" controlTypeID="com.balsamiq.mockups::Button" x="294" y="298" w="36" h="27" measuredW="31" measuredH="27" zOrder="8" locked="false" isInGroup="-1">
<controlProperties>
<text>+</text>
</controlProperties>
</control>
<control controlID="9" controlTypeID="com.balsamiq.mockups::Button" x="336" y="298" w="36" h="27" measuredW="27" measuredH="27" zOrder="9" locked="false" isInGroup="-1">
<controlProperties>
<text>-</text>
</controlProperties>
</control>
<control controlID="12" controlTypeID="com.balsamiq.mockups::Arrow" x="345" y="15" w="225" h="143" measuredW="150" measuredH="100" zOrder="10" locked="false" isInGroup="-1">
<controlProperties>
<backgroundAlpha>1</backgroundAlpha>
<direction>bottom</direction>
<rightArrow>false</rightArrow>
<text>Lists%20all%20data%20series%20that%20will%20be%20available%20on%20the%20chart</text>
</controlProperties>
</control>
<control controlID="13" controlTypeID="com.balsamiq.mockups::TitleWindow" x="481" y="55" w="489" h="507" measuredW="450" measuredH="400" zOrder="11" locked="false" isInGroup="-1">
<controlProperties>
<text>Edit%20Data%20Series%20%5BMetric/Measure%5D</text>
</controlProperties>
</control>
<control controlID="14" controlTypeID="com.balsamiq.mockups::RadioButton" x="497" y="156" w="136" h="22" measuredW="53" measuredH="22" zOrder="12" locked="false" isInGroup="-1">
<controlProperties>
<state>selected</state>
<text>Metric</text>
</controlProperties>
</control>
<control controlID="15" controlTypeID="com.balsamiq.mockups::RadioButton" x="497" y="184" w="136" h="22" measuredW="43" measuredH="22" zOrder="13" locked="false" isInGroup="-1">
<controlProperties>
<text>Best</text>
</controlProperties>
</control>
<control controlID="16" controlTypeID="com.balsamiq.mockups::RadioButton" x="497" y="212" w="136" h="22" measuredW="63" measuredH="22" zOrder="14" locked="false" isInGroup="-1">
<controlProperties>
<text>Formula</text>
</controlProperties>
</control>
<control controlID="17" controlTypeID="com.balsamiq.mockups::RadioButton" x="497" y="130" w="136" h="22" measuredW="68" measuredH="22" zOrder="15" locked="false" isInGroup="-1">
<controlProperties>
<state>selected</state>
<text>Measure</text>
</controlProperties>
</control>
<control controlID="18" controlTypeID="com.balsamiq.mockups::Arrow" x="155" y="242" w="326" h="69" measuredW="150" measuredH="100" zOrder="16" locked="false" isInGroup="-1">
<controlProperties>
<backgroundAlpha>0.25</backgroundAlpha>
<direction>bottom</direction>
<leftArrow>false</leftArrow>
<rightArrow>true</rightArrow>
<text/>
</controlProperties>
</control>
<control controlID="19" controlTypeID="com.balsamiq.mockups::Arrow" x="306" y="242" w="175" h="69" measuredW="150" measuredH="100" zOrder="17" locked="false" isInGroup="-1">
<controlProperties>
<backgroundAlpha>0.25</backgroundAlpha>
<direction>bottom</direction>
<leftArrow>false</leftArrow>
<rightArrow>false</rightArrow>
<text/>
</controlProperties>
</control>
<control controlID="20" controlTypeID="com.balsamiq.mockups::List" x="615" y="126" w="317" h="113" measuredW="100" measuredH="132" zOrder="18" locked="false" isInGroup="-1">
<controlProperties>
<text>Peak%201m%20Power%0APeak%201m%20WPK%0APeak%201s%20Power%0APeak%201s%20WPK%0APeak%205s%20Power%0APeak%205s%20WPK</text>
</controlProperties>
</control>
<control controlID="21" controlTypeID="com.balsamiq.mockups::TextInput" x="615" y="102" w="317" h="-1" measuredW="58" measuredH="27" zOrder="19" locked="false" isInGroup="-1">
<controlProperties>
<text>Metrics</text>
</controlProperties>
</control>
<control controlID="22" controlTypeID="com.balsamiq.mockups::VerticalScrollBar" x="916" y="126" w="-1" h="113" measuredW="16" measuredH="100" zOrder="20" locked="false" isInGroup="-1"/>
<control controlID="24" controlTypeID="com.balsamiq.mockups::Label" x="498" y="101" w="-1" h="-1" measuredW="30" measuredH="21" zOrder="21" locked="false" isInGroup="-1">
<controlProperties>
<text>Type</text>
</controlProperties>
</control>
<control controlID="26" controlTypeID="com.balsamiq.mockups::Label" x="497" y="264" w="104" h="-1" measuredW="35" measuredH="21" zOrder="22" locked="false" isInGroup="-1">
<controlProperties>
<text>Name</text>
</controlProperties>
</control>
<control controlID="27" controlTypeID="com.balsamiq.mockups::Label" x="497" y="304" w="131" h="-1" measuredW="106" measuredH="21" zOrder="23" locked="false" isInGroup="-1">
<controlProperties>
<text>Axis%20Label%20/%20Units</text>
</controlProperties>
</control>
<control controlID="28" controlTypeID="com.balsamiq.mockups::Label" x="497" y="342" w="131" h="-1" measuredW="36" measuredH="21" zOrder="24" locked="false" isInGroup="-1">
<controlProperties>
<text>Curve</text>
</controlProperties>
</control>
<control controlID="29" controlTypeID="com.balsamiq.mockups::Label" x="497" y="378" w="131" h="-1" measuredW="44" measuredH="21" zOrder="25" locked="false" isInGroup="-1">
<controlProperties>
<text>Symbol</text>
</controlProperties>
</control>
<control controlID="30" controlTypeID="com.balsamiq.mockups::Label" x="499" y="416" w="131" h="-1" measuredW="35" measuredH="21" zOrder="26" locked="false" isInGroup="-1">
<controlProperties>
<text>Stack</text>
</controlProperties>
</control>
<control controlID="31" controlTypeID="com.balsamiq.mockups::Label" x="499" y="448" w="131" h="-1" measuredW="32" measuredH="21" zOrder="27" locked="false" isInGroup="-1">
<controlProperties>
<text>Color</text>
</controlProperties>
</control>
<control controlID="32" controlTypeID="com.balsamiq.mockups::Label" x="499" y="484" w="111" h="-1" measuredW="55" measuredH="21" zOrder="28" locked="false" isInGroup="-1">
<controlProperties>
<text>Fill%20Curve</text>
</controlProperties>
</control>
<control controlID="33" controlTypeID="com.balsamiq.mockups::TextInput" x="618" y="261" w="97" h="-1" measuredW="79" measuredH="26" zOrder="29" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="34" controlTypeID="com.balsamiq.mockups::TextInput" x="616" y="301" w="97" h="-1" measuredW="79" measuredH="26" zOrder="30" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="35" controlTypeID="com.balsamiq.mockups::ComboBox" x="618" y="340" w="95" h="-1" measuredW="55" measuredH="24" zOrder="31" locked="false" isInGroup="-1">
<controlProperties>
<text>Line</text>
</controlProperties>
</control>
<control controlID="36" controlTypeID="com.balsamiq.mockups::ComboBox" x="618" y="378" w="95" h="-1" measuredW="64" measuredH="24" zOrder="32" locked="false" isInGroup="-1">
<controlProperties>
<text>Circle</text>
</controlProperties>
</control>
<control controlID="37" controlTypeID="com.balsamiq.mockups::CheckBox" x="627" y="417" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="33" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="38" controlTypeID="com.balsamiq.mockups::CheckBox" x="627" y="483" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="34" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="39" controlTypeID="com.balsamiq.mockups::ColorPicker" x="620" y="447" w="-1" h="-1" measuredW="26" measuredH="28" zOrder="35" locked="false" isInGroup="-1"/>
<control controlID="40" controlTypeID="com.balsamiq.mockups::Label" x="738" y="264" w="104" h="-1" measuredW="52" measuredH="21" zOrder="36" locked="false" isInGroup="-1">
<controlProperties>
<text>Highlight</text>
</controlProperties>
</control>
<control controlID="41" controlTypeID="com.balsamiq.mockups::Label" x="736" y="304" w="104" h="-1" measuredW="47" measuredH="21" zOrder="37" locked="false" isInGroup="-1">
<controlProperties>
<text>Outliers</text>
</controlProperties>
</control>
<control controlID="42" controlTypeID="com.balsamiq.mockups::Label" x="738" y="342" w="104" h="-1" measuredW="50" measuredH="21" zOrder="38" locked="false" isInGroup="-1">
<controlProperties>
<text>Baseline</text>
</controlProperties>
</control>
<control controlID="43" controlTypeID="com.balsamiq.mockups::Label" x="738" y="416" w="104" h="-1" measuredW="84" measuredH="21" zOrder="39" locked="false" isInGroup="-1">
<controlProperties>
<text>Smooth%20Curve</text>
</controlProperties>
</control>
<control controlID="44" controlTypeID="com.balsamiq.mockups::Label" x="738" y="446" w="104" h="-1" measuredW="63" measuredH="21" zOrder="40" locked="false" isInGroup="-1">
<controlProperties>
<text>Trend%20Line</text>
</controlProperties>
</control>
<control controlID="45" controlTypeID="com.balsamiq.mockups::CheckBox" x="842" y="417" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="41" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="46" controlTypeID="com.balsamiq.mockups::CheckBox" x="842" y="448" w="20" h="21" measuredW="20" measuredH="21" zOrder="42" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="47" controlTypeID="com.balsamiq.mockups::NumericStepper" x="837" y="263" w="95" h="-1" measuredW="41" measuredH="24" zOrder="43" locked="false" isInGroup="-1">
<controlProperties>
<text>0</text>
</controlProperties>
</control>
<control controlID="48" controlTypeID="com.balsamiq.mockups::NumericStepper" x="837" y="301" w="95" h="-1" measuredW="41" measuredH="24" zOrder="44" locked="false" isInGroup="-1">
<controlProperties>
<text>0</text>
</controlProperties>
</control>
<control controlID="49" controlTypeID="com.balsamiq.mockups::NumericStepper" x="837" y="341" w="95" h="-1" measuredW="61" measuredH="24" zOrder="45" locked="false" isInGroup="-1">
<controlProperties>
<text>-999</text>
</controlProperties>
</control>
<control controlID="50" controlTypeID="com.balsamiq.mockups::TitleWindow" x="991" y="57" w="489" h="507" measuredW="450" measuredH="400" zOrder="46" locked="false" isInGroup="-1">
<controlProperties>
<text>Edit%20Data%20Series%20%5BFormula%5D</text>
</controlProperties>
</control>
<control controlID="51" controlTypeID="com.balsamiq.mockups::RadioButton" x="1007" y="158" w="136" h="22" measuredW="53" measuredH="22" zOrder="47" locked="false" isInGroup="-1">
<controlProperties>
<state>up</state>
<text>Metric</text>
</controlProperties>
</control>
<control controlID="52" controlTypeID="com.balsamiq.mockups::RadioButton" x="1007" y="186" w="136" h="22" measuredW="43" measuredH="22" zOrder="48" locked="false" isInGroup="-1">
<controlProperties>
<text>Best</text>
</controlProperties>
</control>
<control controlID="53" controlTypeID="com.balsamiq.mockups::RadioButton" x="1007" y="214" w="136" h="22" measuredW="63" measuredH="22" zOrder="49" locked="false" isInGroup="-1">
<controlProperties>
<state>selected</state>
<text>Formula</text>
</controlProperties>
</control>
<control controlID="54" controlTypeID="com.balsamiq.mockups::RadioButton" x="1007" y="132" w="136" h="22" measuredW="68" measuredH="22" zOrder="50" locked="false" isInGroup="-1">
<controlProperties>
<text>Measure</text>
</controlProperties>
</control>
<control controlID="58" controlTypeID="com.balsamiq.mockups::Label" x="1008" y="103" w="-1" h="-1" measuredW="30" measuredH="21" zOrder="51" locked="false" isInGroup="-1">
<controlProperties>
<text>Type</text>
</controlProperties>
</control>
<control controlID="59" controlTypeID="com.balsamiq.mockups::Label" x="1007" y="266" w="104" h="-1" measuredW="35" measuredH="21" zOrder="52" locked="false" isInGroup="-1">
<controlProperties>
<text>Name</text>
</controlProperties>
</control>
<control controlID="60" controlTypeID="com.balsamiq.mockups::Label" x="1007" y="306" w="131" h="-1" measuredW="106" measuredH="21" zOrder="53" locked="false" isInGroup="-1">
<controlProperties>
<text>Axis%20Label%20/%20Units</text>
</controlProperties>
</control>
<control controlID="61" controlTypeID="com.balsamiq.mockups::Label" x="1007" y="344" w="131" h="-1" measuredW="36" measuredH="21" zOrder="54" locked="false" isInGroup="-1">
<controlProperties>
<text>Curve</text>
</controlProperties>
</control>
<control controlID="62" controlTypeID="com.balsamiq.mockups::Label" x="1007" y="380" w="131" h="-1" measuredW="44" measuredH="21" zOrder="55" locked="false" isInGroup="-1">
<controlProperties>
<text>Symbol</text>
</controlProperties>
</control>
<control controlID="63" controlTypeID="com.balsamiq.mockups::Label" x="1009" y="418" w="131" h="-1" measuredW="35" measuredH="21" zOrder="56" locked="false" isInGroup="-1">
<controlProperties>
<text>Stack</text>
</controlProperties>
</control>
<control controlID="64" controlTypeID="com.balsamiq.mockups::Label" x="1009" y="450" w="131" h="-1" measuredW="32" measuredH="21" zOrder="57" locked="false" isInGroup="-1">
<controlProperties>
<text>Color</text>
</controlProperties>
</control>
<control controlID="65" controlTypeID="com.balsamiq.mockups::Label" x="1009" y="486" w="111" h="-1" measuredW="55" measuredH="21" zOrder="58" locked="false" isInGroup="-1">
<controlProperties>
<text>Fill%20Curve</text>
</controlProperties>
</control>
<control controlID="66" controlTypeID="com.balsamiq.mockups::TextInput" x="1128" y="263" w="97" h="-1" measuredW="79" measuredH="26" zOrder="59" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="67" controlTypeID="com.balsamiq.mockups::TextInput" x="1126" y="303" w="97" h="-1" measuredW="79" measuredH="26" zOrder="60" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="68" controlTypeID="com.balsamiq.mockups::ComboBox" x="1128" y="342" w="95" h="-1" measuredW="55" measuredH="24" zOrder="61" locked="false" isInGroup="-1">
<controlProperties>
<text>Line</text>
</controlProperties>
</control>
<control controlID="69" controlTypeID="com.balsamiq.mockups::ComboBox" x="1128" y="380" w="95" h="-1" measuredW="64" measuredH="24" zOrder="62" locked="false" isInGroup="-1">
<controlProperties>
<text>Circle</text>
</controlProperties>
</control>
<control controlID="70" controlTypeID="com.balsamiq.mockups::CheckBox" x="1137" y="419" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="63" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="71" controlTypeID="com.balsamiq.mockups::CheckBox" x="1137" y="485" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="64" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="72" controlTypeID="com.balsamiq.mockups::ColorPicker" x="1130" y="449" w="-1" h="-1" measuredW="26" measuredH="28" zOrder="65" locked="false" isInGroup="-1"/>
<control controlID="73" controlTypeID="com.balsamiq.mockups::Label" x="1248" y="266" w="104" h="-1" measuredW="52" measuredH="21" zOrder="66" locked="false" isInGroup="-1">
<controlProperties>
<text>Highlight</text>
</controlProperties>
</control>
<control controlID="74" controlTypeID="com.balsamiq.mockups::Label" x="1246" y="306" w="104" h="-1" measuredW="47" measuredH="21" zOrder="67" locked="false" isInGroup="-1">
<controlProperties>
<text>Outliers</text>
</controlProperties>
</control>
<control controlID="75" controlTypeID="com.balsamiq.mockups::Label" x="1248" y="344" w="104" h="-1" measuredW="50" measuredH="21" zOrder="68" locked="false" isInGroup="-1">
<controlProperties>
<text>Baseline</text>
</controlProperties>
</control>
<control controlID="76" controlTypeID="com.balsamiq.mockups::Label" x="1248" y="418" w="104" h="-1" measuredW="84" measuredH="21" zOrder="69" locked="false" isInGroup="-1">
<controlProperties>
<text>Smooth%20Curve</text>
</controlProperties>
</control>
<control controlID="77" controlTypeID="com.balsamiq.mockups::Label" x="1248" y="448" w="104" h="-1" measuredW="63" measuredH="21" zOrder="70" locked="false" isInGroup="-1">
<controlProperties>
<text>Trend%20Line</text>
</controlProperties>
</control>
<control controlID="78" controlTypeID="com.balsamiq.mockups::CheckBox" x="1352" y="419" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="71" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="79" controlTypeID="com.balsamiq.mockups::CheckBox" x="1352" y="450" w="20" h="21" measuredW="20" measuredH="21" zOrder="72" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="80" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1347" y="265" w="95" h="-1" measuredW="41" measuredH="24" zOrder="73" locked="false" isInGroup="-1">
<controlProperties>
<text>0</text>
</controlProperties>
</control>
<control controlID="81" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1347" y="303" w="95" h="-1" measuredW="41" measuredH="24" zOrder="74" locked="false" isInGroup="-1">
<controlProperties>
<text>0</text>
</controlProperties>
</control>
<control controlID="82" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1347" y="343" w="95" h="-1" measuredW="61" measuredH="24" zOrder="75" locked="false" isInGroup="-1">
<controlProperties>
<text>-999</text>
</controlProperties>
</control>
<control controlID="83" controlTypeID="com.balsamiq.mockups::SearchBox" x="1128" y="103" w="315" h="-1" measuredW="120" measuredH="25" zOrder="76" locked="false" isInGroup="-1">
<controlProperties>
<text>%3D%20Formula...</text>
</controlProperties>
</control>
<control controlID="84" controlTypeID="com.balsamiq.mockups::TextArea" x="1135" y="125" w="293" h="124" measuredW="200" measuredH="140" zOrder="77" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="85" controlTypeID="com.balsamiq.mockups::VerticalScrollBar" x="1412" y="126" w="-1" h="123" measuredW="16" measuredH="100" zOrder="78" locked="false" isInGroup="-1"/>
<control controlID="87" controlTypeID="com.balsamiq.mockups::Label" x="1147" y="130" w="-1" h="-1" measuredW="35" measuredH="21" zOrder="79" locked="false" isInGroup="-1">
<controlProperties>
<text>Fields</text>
</controlProperties>
</control>
<control controlID="88" controlTypeID="com.balsamiq.mockups::Label" x="1308" y="131" w="70" h="-1" measuredW="59" measuredH="21" zOrder="80" locked="false" isInGroup="-1">
<controlProperties>
<text>Operators</text>
</controlProperties>
</control>
<control controlID="89" controlTypeID="com.balsamiq.mockups::Button" x="1147" y="151" w="-1" h="-1" measuredW="107" measuredH="27" zOrder="81" locked="false" isInGroup="-1">
<controlProperties>
<text>1s%20Peak%20Power</text>
</controlProperties>
</control>
<control controlID="90" controlTypeID="com.balsamiq.mockups::Button" x="1149" y="183" w="-1" h="-1" measuredW="107" measuredH="27" zOrder="82" locked="false" isInGroup="-1">
<controlProperties>
<text>1s%20Peak%20Power</text>
</controlProperties>
</control>
<control controlID="91" controlTypeID="com.balsamiq.mockups::Button" x="1149" y="215" w="-1" h="-1" measuredW="107" measuredH="27" zOrder="83" locked="false" isInGroup="-1">
<controlProperties>
<text>1s%20Peak%20Power</text>
</controlProperties>
</control>
<control controlID="92" controlTypeID="com.balsamiq.mockups::Button" x="1301" y="152" w="85" h="27" measuredW="49" measuredH="27" zOrder="84" locked="false" isInGroup="-1">
<controlProperties>
<text>AND</text>
</controlProperties>
</control>
<control controlID="93" controlTypeID="com.balsamiq.mockups::Button" x="1303" y="184" w="85" h="27" measuredW="42" measuredH="27" zOrder="85" locked="false" isInGroup="-1">
<controlProperties>
<text>OR</text>
</controlProperties>
</control>
<control controlID="94" controlTypeID="com.balsamiq.mockups::Button" x="1305" y="216" w="85" h="27" measuredW="40" measuredH="27" zOrder="86" locked="false" isInGroup="-1">
<controlProperties>
<text>%3E%3D</text>
</controlProperties>
</control>
<control controlID="95" controlTypeID="com.balsamiq.mockups::VerticalScrollBar" x="1266" y="126" w="-1" h="123" measuredW="16" measuredH="100" zOrder="87" locked="false" isInGroup="-1"/>
<control controlID="96" controlTypeID="com.balsamiq.mockups::TitleWindow" x="1508" y="61" w="489" h="507" measuredW="450" measuredH="400" zOrder="88" locked="false" isInGroup="-1">
<controlProperties>
<text>Edit%20Data%20Series%20%5BBests%5D</text>
</controlProperties>
</control>
<control controlID="97" controlTypeID="com.balsamiq.mockups::RadioButton" x="1524" y="162" w="136" h="22" measuredW="53" measuredH="22" zOrder="89" locked="false" isInGroup="-1">
<controlProperties>
<state>up</state>
<text>Metric</text>
</controlProperties>
</control>
<control controlID="98" controlTypeID="com.balsamiq.mockups::RadioButton" x="1524" y="190" w="136" h="22" measuredW="43" measuredH="22" zOrder="90" locked="false" isInGroup="-1">
<controlProperties>
<state>selected</state>
<text>Best</text>
</controlProperties>
</control>
<control controlID="99" controlTypeID="com.balsamiq.mockups::RadioButton" x="1524" y="218" w="136" h="22" measuredW="63" measuredH="22" zOrder="91" locked="false" isInGroup="-1">
<controlProperties>
<state>up</state>
<text>Formula</text>
</controlProperties>
</control>
<control controlID="100" controlTypeID="com.balsamiq.mockups::RadioButton" x="1524" y="136" w="136" h="22" measuredW="68" measuredH="22" zOrder="92" locked="false" isInGroup="-1">
<controlProperties>
<text>Measure</text>
</controlProperties>
</control>
<control controlID="101" controlTypeID="com.balsamiq.mockups::Label" x="1525" y="107" w="-1" h="-1" measuredW="30" measuredH="21" zOrder="93" locked="false" isInGroup="-1">
<controlProperties>
<text>Type</text>
</controlProperties>
</control>
<control controlID="102" controlTypeID="com.balsamiq.mockups::Label" x="1524" y="270" w="104" h="-1" measuredW="35" measuredH="21" zOrder="94" locked="false" isInGroup="-1">
<controlProperties>
<text>Name</text>
</controlProperties>
</control>
<control controlID="103" controlTypeID="com.balsamiq.mockups::Label" x="1524" y="310" w="131" h="-1" measuredW="106" measuredH="21" zOrder="95" locked="false" isInGroup="-1">
<controlProperties>
<text>Axis%20Label%20/%20Units</text>
</controlProperties>
</control>
<control controlID="104" controlTypeID="com.balsamiq.mockups::Label" x="1524" y="348" w="131" h="-1" measuredW="36" measuredH="21" zOrder="96" locked="false" isInGroup="-1">
<controlProperties>
<text>Curve</text>
</controlProperties>
</control>
<control controlID="105" controlTypeID="com.balsamiq.mockups::Label" x="1524" y="384" w="131" h="-1" measuredW="44" measuredH="21" zOrder="97" locked="false" isInGroup="-1">
<controlProperties>
<text>Symbol</text>
</controlProperties>
</control>
<control controlID="106" controlTypeID="com.balsamiq.mockups::Label" x="1526" y="422" w="131" h="-1" measuredW="35" measuredH="21" zOrder="98" locked="false" isInGroup="-1">
<controlProperties>
<text>Stack</text>
</controlProperties>
</control>
<control controlID="107" controlTypeID="com.balsamiq.mockups::Label" x="1526" y="454" w="131" h="-1" measuredW="32" measuredH="21" zOrder="99" locked="false" isInGroup="-1">
<controlProperties>
<text>Color</text>
</controlProperties>
</control>
<control controlID="108" controlTypeID="com.balsamiq.mockups::Label" x="1526" y="490" w="111" h="-1" measuredW="55" measuredH="21" zOrder="100" locked="false" isInGroup="-1">
<controlProperties>
<text>Fill%20Curve</text>
</controlProperties>
</control>
<control controlID="109" controlTypeID="com.balsamiq.mockups::TextInput" x="1645" y="267" w="97" h="-1" measuredW="79" measuredH="26" zOrder="101" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="110" controlTypeID="com.balsamiq.mockups::TextInput" x="1643" y="307" w="97" h="-1" measuredW="79" measuredH="26" zOrder="102" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="111" controlTypeID="com.balsamiq.mockups::ComboBox" x="1645" y="346" w="95" h="-1" measuredW="55" measuredH="24" zOrder="103" locked="false" isInGroup="-1">
<controlProperties>
<text>Line</text>
</controlProperties>
</control>
<control controlID="112" controlTypeID="com.balsamiq.mockups::ComboBox" x="1645" y="384" w="95" h="-1" measuredW="64" measuredH="24" zOrder="104" locked="false" isInGroup="-1">
<controlProperties>
<text>Circle</text>
</controlProperties>
</control>
<control controlID="113" controlTypeID="com.balsamiq.mockups::CheckBox" x="1654" y="423" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="105" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="114" controlTypeID="com.balsamiq.mockups::CheckBox" x="1654" y="489" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="106" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="115" controlTypeID="com.balsamiq.mockups::ColorPicker" x="1647" y="453" w="-1" h="-1" measuredW="26" measuredH="28" zOrder="107" locked="false" isInGroup="-1"/>
<control controlID="116" controlTypeID="com.balsamiq.mockups::Label" x="1765" y="270" w="104" h="-1" measuredW="52" measuredH="21" zOrder="108" locked="false" isInGroup="-1">
<controlProperties>
<text>Highlight</text>
</controlProperties>
</control>
<control controlID="117" controlTypeID="com.balsamiq.mockups::Label" x="1763" y="310" w="104" h="-1" measuredW="47" measuredH="21" zOrder="109" locked="false" isInGroup="-1">
<controlProperties>
<text>Outliers</text>
</controlProperties>
</control>
<control controlID="118" controlTypeID="com.balsamiq.mockups::Label" x="1765" y="348" w="104" h="-1" measuredW="50" measuredH="21" zOrder="110" locked="false" isInGroup="-1">
<controlProperties>
<text>Baseline</text>
</controlProperties>
</control>
<control controlID="119" controlTypeID="com.balsamiq.mockups::Label" x="1765" y="422" w="104" h="-1" measuredW="84" measuredH="21" zOrder="111" locked="false" isInGroup="-1">
<controlProperties>
<text>Smooth%20Curve</text>
</controlProperties>
</control>
<control controlID="120" controlTypeID="com.balsamiq.mockups::Label" x="1765" y="452" w="104" h="-1" measuredW="63" measuredH="21" zOrder="112" locked="false" isInGroup="-1">
<controlProperties>
<text>Trend%20Line</text>
</controlProperties>
</control>
<control controlID="121" controlTypeID="com.balsamiq.mockups::CheckBox" x="1869" y="423" w="-1" h="-1" measuredW="20" measuredH="21" zOrder="113" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="122" controlTypeID="com.balsamiq.mockups::CheckBox" x="1869" y="454" w="20" h="21" measuredW="20" measuredH="21" zOrder="114" locked="false" isInGroup="-1">
<controlProperties>
<text/>
</controlProperties>
</control>
<control controlID="123" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1864" y="269" w="95" h="-1" measuredW="41" measuredH="24" zOrder="115" locked="false" isInGroup="-1">
<controlProperties>
<text>0</text>
</controlProperties>
</control>
<control controlID="124" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1864" y="307" w="95" h="-1" measuredW="41" measuredH="24" zOrder="116" locked="false" isInGroup="-1">
<controlProperties>
<text>0</text>
</controlProperties>
</control>
<control controlID="125" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1864" y="347" w="95" h="-1" measuredW="61" measuredH="24" zOrder="117" locked="false" isInGroup="-1">
<controlProperties>
<text>-999</text>
</controlProperties>
</control>
<control controlID="126" controlTypeID="com.balsamiq.mockups::NumericStepper" x="1694" y="147" w="95" h="-1" measuredW="41" measuredH="24" zOrder="118" locked="false" isInGroup="-1">
<controlProperties>
<text>5</text>
</controlProperties>
</control>
<control controlID="127" controlTypeID="com.balsamiq.mockups::ComboBox" x="1797" y="145" w="95" h="-1" measuredW="69" measuredH="24" zOrder="119" locked="false" isInGroup="-1">
<controlProperties>
<text>Minute</text>
</controlProperties>
</control>
<control controlID="128" controlTypeID="com.balsamiq.mockups::Label" x="1694" y="177" w="95" h="-1" measuredW="30" measuredH="21" zOrder="120" locked="false" isInGroup="-1">
<controlProperties>
<text>Peak</text>
</controlProperties>
</control>
<control controlID="129" controlTypeID="com.balsamiq.mockups::ComboBox" x="1797" y="175" w="95" h="-1" measuredW="66" measuredH="24" zOrder="121" locked="false" isInGroup="-1">
<controlProperties>
<text>Power</text>
</controlProperties>
</control>
</controls>
</mockup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

View File

@@ -11,15 +11,12 @@ Installing dependencies
</font></big>
<p>GC requires a number of libraries. On Mac OS X, you can get most of these
through <a href="http://www.macports.org/">Mac Ports</a> or
<a href="http://www.brew.sh/">Homebrew</a>. On Linux and other
through <a href="http://www.macports.org/">Mac Ports</a>. On Linux and other
Unixes, you can use whatever package manager your distribution provides. (We
list the package names for MacPorts and Ubuntu below.) On Windows, you'll
probably need to download and install everything by hand. You might also want
to read <a href="old-mailing-list-archives/2009-September/002502.html">this
mailing list message</a> or check the
<a href="https://github.com/GoldenCheetah/GoldenCheetah">INSTALL</a> documents
on GitHub.</p>
mailing list message</a>.</p>
<p>You'll need the following:</p>
<table align="center" width="500">
@@ -31,10 +28,16 @@ on GitHub.</p>
</tr>
<tr>
<td><a href="http://qt.nokia.com/downloads">Qt</a></td>
<td>4.8.0 or later</td>
<td>4.6.0 or later</td>
<td>qt4-mac</td>
<td>libqt4-dev</td>
</tr>
<tr>
<td><a href="http://www.boost.org/users/download/">Boost</a></td>
<td>1.38.0 or later</td>
<td>boost</td>
<td>libboost-dev</td>
</tr>
<tr>
<td><a href="http://git-scm.com/download">git</a></td>
<td>any</td>
@@ -60,7 +63,7 @@ checkout the code, execute this command:</p>
<blockquote>
<pre>
git clone git://github.com/GoldenCheetah/GoldenCheetah.git
git clone git://github.com/srhea/GoldenCheetah.git
</pre>
</blockquote>
@@ -100,9 +103,9 @@ make
for the build process. We would too, but none of us know
<a href="http://www.gnu.org/software/autoconf/">autoconf</a> well
enough to integrate it with Qt on Mac, Linux, and Windows. If you can help
us out with that, please post a message on the
<a href="https://groups.google.com/forum/?fromgroups&hl=en#!forum/golden-cheetah-users">GoldenCheetah User's
Google Group</a>.</p>
us out with that, please email the
<a href="cgi-bin/mailman/listinfo/golden-cheetah-users">GoldenCheetah User's
Mailing List</a>.</p>
<big><font face="arial,helvetica,sanserif">
Making changes
@@ -132,16 +135,18 @@ git show --color abcd0123
variable, declare it <code>static</code> within a .cpp file.
<li>Only call C++'s operator <code>new</code> within the constructors and
<code>reset</code> functions of <code>std::auto_ptr</code> etc.
or when passing a parent pointer to a Qt class (so that the parent
deletes the child). Never call <code>delete</code> explicitly.
<code>reset</code> functions of <code>std::auto_ptr</code>,
<code>boost::scoped_pointer</code>, etc. or when passing a parent pointer to a
Qt class (so that the parent deletes the child). Never call
<code>delete</code> explicitly.
<li>Do not use <code>malloc</code> or <code>free</code> unless forced to by an
external C library.
<li>Allocate large buffers on the heap, not on the stack.
<li>When the Qt or C++ standard library has an appropriate function, use it.
<li>When the C++ standard library has an appropriate function, use it.
Likewise for Qt and Boost.
<li>Only use external libraries with GPL-compatible licenses.
@@ -481,13 +486,11 @@ file</em>, <code>0001-don-t-include-zero-metrics-in-ride-summary.patch</code>,
that other people can use to include my change in their own local git
repositories.</p>
<p>If you have a patch you'd like to share with others, we recommend that you
<a href="https://help.github.com/articles/fork-a-repo">fork</a> the main GIT
repository and submit a
<a href="https://help.github.com/articles/creating-a-pull-request">pull request</a>
with your patch. Alternatively you can join the
<a href="https://groups.google.com/forum/?fromgroups#!forum/golden-cheetah-developers">
Golden Cheetah Developer's Group</a> and post a patch there.</p>
<p>If you have a patch you'd like to share with others, you can email it to
the <a href="cgi-bin/mailman/listinfo/golden-cheetah-users">GoldenCheetah
User's Mailing List</a>, and it will be considered for inclusion in the next
release of GoldenCheetah. In fact, if you join the mailing list, you'll see
lots of patches like this. You may even want to try some of them.</p>
<big><font face="arial,helvetica,sanserif">
Applying patches

72
doc/download.content Normal file
View File

@@ -0,0 +1,72 @@
<!-- $Id: download.content,v 1.6 2009/01/09 20:45:03 rcarlsen Exp $ -->
<p>
Golden Cheetah is available in binary form for
Linux x86, Mac OS X (universal binary), and Windows.
It is also available as source code.
</p>
<p>
Golden Cheetah downloads data from all versions of the PowerTap
computer including the new Joule. If you're using the PowerTap USB cradle
(as opposed to the older, serial cable), you may need to install the
<a href="http://www.ftdichip.com/Drivers/D2XX.htm">FTDI USB driver</a>
before downloading.
</p>
<p>
On Linux and Mac OS X, Golden Cheetah also downloads from the SRM PCV. On Mac
OS X, you'll need to install <a href="http://osx-pl2303.sourceforge.net/">the
open source PL2303 driver</a> to download from an SRM. Please see the
<a href="http://bugs.goldencheetah.org/projects/goldencheetah/wiki/">WIKI</a> article
- <a href="http://bugs.goldencheetah.org/projects/goldencheetah/wiki/PCV_on_Mac_OS_X">
PCV on Mac OS X</a> for further information.
</p>
<p>
<font face="arial,helvetica,sanserif">
<big><strong>Download Release 2.1</strong></big>
</font>
</p>
<ul>
<li><a href="GoldenCheetah_2.1.0_Windows_Installer.exe">Windows 32-bit (runs on 64bit as well)</a>
<li><a href="GoldenCheetah_2.1.0_Mac_Universal.dmg">Mac OS X Universal 10.4->10.7</a><br>
<li><a href="GoldenCheetah_2.1.0_Linux_x86.tgz">Linux x86</a><br>
<li><a href="GoldenCheetah_2.1.0_Linux_x86_64.tgz">Linux x86_64</a><br>
</ul>
</p>
<p>
Please follow the <a href="/users-guid.html">User's Guide</a> on how to install
and use Golden Cheetah.
</p>
<p>
You can also <a href="release-notes.html">view the release notes</a> for 2.1
or <a href="older-releases.html">download older releases</a> of Golden Cheetah.
</p>
<p>
<font face="arial,helvetica,sanserif">
<big><strong>Development Releases</strong></big>
</font>
</p>
<p>Gareth Coco has also made
<a href="http://goldencheetah.stand2surf.net/">regular development builds</a>
available. These binaries are based on the latest source code, so they may have
more features and less (but sometime more) bugs than the stable release above.
</p>
<p>
<font face="arial,helvetica,sanserif">
<big><strong>Source Code</strong></big>
</font>
</p>
<p>
The Golden Cheetah source code is available via git. See the
<a href="developers-guide.html">Developer's Guide</a> for more information.
You can also <a href="http://github.com/srhea/GoldenCheetah/tree/master/">browse
the source on github</a>.
</p>

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

@@ -1,12 +1,5 @@
<!-- $Id: faq.content,v 1.4 2006/07/05 16:59:56 srhea Exp $ -->
<h2>Documentation</h2>
<p>
There is a <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Manual.pdf?raw=true">Manual</a>
and a <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-FAQ.pdf?raw=true">FAQ</a> that
you can use to help you use the program.
</p>
<p>
<b><i>GoldenCheetah doesn't find my PowerTap on Ubuntu Linux.</i></b>
<p>

View File

@@ -54,14 +54,14 @@ body {
<img src="logo.jpg" width="175" height="175" alt="Picture of Cheetah">
<p> <b><a href="index.html">Introduction</a></b>
<br> <b><a href="download.html">Download</a></b>
<br> <b><a href="screenshots.html">Screenshots</a>
<br> <b><a href="wiki.html">Wiki</a>
<br> <b><a href="http://bugs.goldencheetah.org/projects/goldencheetah/wiki">Wiki</a>
<br> <b><a href="users-guide.html">User's Guide</a>
<br> <b><a href="developers-guide.html">Developer's Guide</a>
<br> <b><a href="faq.html">FAQ</a>
<br> <b><a href="wishlist.html">Wish List</a>
<br> <b><a href="license.html">License</a></b>
<br> <b><a href="download.html">Download</a></b>
<br> <b><a href="contrib.html">Contributors</a></b>
<br> <b><a href="search.html">Search</a></b>
<br> <b><a href="mailing-list.html">Mailing List</a></b>

View File

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 311 KiB

View File

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 203 KiB

View File

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

@@ -13,7 +13,8 @@ GoldenCheetah is a software package that:
<ul>
<li>Downloads ride data directly from the CycleOps PowerTap and the SRM
PowerControl V, VI and VII.</p>
PowerControl V. Support for SRM PowerControl VI and VII is planned for the
future.<p>
<li>Imports ride data downloaded with other programs, including TrainingPeaks
WKO+ and the manufacturers' software for the Ergomo, Garmin, Polar, PowerTap,
@@ -23,7 +24,8 @@ and SRM devices.<p>
BikeScore calculation, histogram analysis, a best interval finder, and a pedal
force versus pedal velocity chart, to name just a few.<p>
<li>Is available for Linux, Mac OS X, and Windows.<p>
<li>Is available for Linux, Mac OS X, and Windows. (The Windows version
does not yet support direct downloads from the SRM PowerControl.)<p>
<li>Is released under an Open Source license.
</ul>

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 159 KiB

View File

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 203 KiB

View File

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 267 KiB

View File

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -18,122 +18,13 @@ please see <a href="download.html">the download page</a> instead.
<td><i>Description</i></td>
</tr>
<tr>
<td valign="top">3.0.1</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah_3.0.1_Mac_Universal.dmg">Mac OS X Intel Universal (10.6+)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah_3.0.1_Windows_Installer.exe">Windows 32-bit</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah-3.0.1-2.fc18.x86_64.rpm">Fedora 18 RPM (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0-SP1/GoldenCheetah-3.0.1-2.fc19.x86_64.rpm">Fedora 19 RPM (64bit)</a>
</td>
<td valign="top">
<a href="release-notes_3.0.1.html">Full Version 3.0.1 change log.</a><br>
</td>
</tr>
<tr>
<td valign="top">3.0.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0/GoldenCheetah_3.0.0_Mac_32bit.dmg">Mac OS X Intel (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0/GoldenCheetah_3.0.0_Mac_64bit.dmg">Mac OS X Intel (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v3.0/GoldenCheetah_3.0.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
New Features and Enhancements
<ul>
<li>See the full log below.</li>
<li>See the <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Release.pdf?raw=true">Release Notes</a> PDF on GitHub.</li>
<li>A PDF <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-Manual.pdf?raw=true">User's Manual</a></li>
<li>A PDF <a href="https://github.com/GoldenCheetah/GoldenCheetah/blob/master/doc/user/GC3-FAQ.pdf?raw=true">Frequently Asked Questions (FAQ)</a></li>
<li>Welcome Screens to help setup the program.</li>
</ul>
</p>
<p>
Internationalisation
<ul>
<li>German (Tilman Schmiedeberg)</li>
<li>Italian (Marco Piccirilli)</li>
<li>Japanese (Okano Takayoshi)</li>
<li>Spanish (Alejandro Martinez)</li>
</ul>
</p>
<p>
Development Builds
<ul>
<li>Gareth Coco</li>
<li>Jamie Kimberley</li>
</ul>
</p>
<p>
<a href="release-notes_3.0.0.html">Full Version 3.0.0 change log.</a><br>
</p>
</td>
</tr>
<tr>
<td valign="top">2.1.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Linux_x86.tgz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Linux_x86_64.tgz">Linux (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Mac_Universal.dmg">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.1/GoldenCheetah_2.1.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
New Features and Enhancements
<ul>
<li>FIT file support for Mac OSX - Rainer Clasen</li>
<li>SRM 5 - Rainer Clasen</li>
<li>Aerolab Improvements - Damien Grauser</li>
<li>O-Sync Macro X device support - Damien Grauser</li>
<li>Air density (RHO) Calculator - Steven Gribble</li>
<li>Virtual Power - Darren Hague</li>
<li>GoldenCheetah JSON - Mark Liversedge</li>
<li>Support TrainerRoad.com TCX Files - Mark Liversedge</li>
<li>Garmin GPX - Greg Lonnon</li>
<li>Sigma SLF/SMF - Frank Zschockelt</li>
</ul>
</p>
<p>
Internationalisation
<ul>
<li>Czech (David Kramar)</li>
<li>French (Damien Grauser, Guillaume LeMaitre)</li>
<li>German (Alexander Pietsch)</li>
<li>Italian (Robert Masso)</li>
<li>Portugese (Thomas Irps)</li>
<li>Portugese-Brazil (Bruno Assis)</li>
<li>Japanese (Mitsukuni Sato, Keisuke Yamaguchi)</li>
<li>Spanish (Alejandro Martinez)</li>
</ul>
</p>
<p>
Development Builds
<ul>
<li>Gareth Coco</li>
<li>Jamie Kimberley</li>
</ul>
</p>
<p>
<a href="release-notes_2.1.0.html">Full Version 2.1.0 change log.</a><br>
</p>
</td>
</tr>
<tr>
<td valign="top">2.0.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Linux_x86.gz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Linux_x86_64.gz">Linux (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Mac_Universal.dmg">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v2.0/GoldenCheetah_2.0.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_2.0.0_Linux_x86.gz">Linux x86</a><br>
<a href="GoldenCheetah_2.0.0_Linux_x86_64.gz">Linux x86_64</a><br>
<a href="GoldenCheetah_2.0.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="GoldenCheetah_2.0.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
@@ -216,10 +107,10 @@ Builds, testing and support
<tr>
<td valign="top">1.3.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Linux_x86.gz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Linux_x86_64.gz">Linux (64bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.3/GoldenCheetah_1.3.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_1.3.0_Linux_x86.gz">Linux x86</a><br>
<a href="GoldenCheetah_1.3.0_Linux_x86_64.gz">Linux x86_64</a><br>
<a href="GoldenCheetah_1.3.0_Mac_Universal.zip">Mac OS X Universal</a><br>
<a href="GoldenCheetah_1.3.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>
@@ -316,10 +207,10 @@ Other new features:
<tr>
<td valign="top">1.2.0</td>
<td valign="top">
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Linux_x86.tgz">Linux (32bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Linux_x86_64.tgz">Linux (6bit)</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Darwin_Universal.dmg">Mac OS X Universal</a><br>
<a href="https://github.com/GoldenCheetah/GoldenCheetah/releases/download/v1.2/GoldenCheetah_1.2.0_Windows_Installer.exe">Windows 32-bit</a>
<a href="GoldenCheetah_1.2.0_Linux_x86.tgz">Linux x86</a><br>
<a href="GoldenCheetah_1.2.0_Linux_x86_64.tgz">Linux x86_64</a><br>
<a href="GoldenCheetah_1.2.0_Darwin_Universal.dmg">Mac OS X Universal</a><br>
<a href="GoldenCheetah_1.2.0_Windows_Installer.exe">Windows 32-bit</a>
</td>
<td valign="top">
<p>

View File

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Some files were not shown because too many files have changed in this diff Show More