diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-11-11 14:29:26 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-11-11 14:29:26 +0100 |
commit | fe4f13f184ffb97ee4b6dbd4138a9d8ae3aabd14 (patch) | |
tree | ae127ca3591cb72b86bd1b512134086902e140cd /dive.c | |
parent | 78ad07c72ed37928020cdbf4842e24690ce35f81 (diff) | |
download | subsurface-fe4f13f184ffb97ee4b6dbd4138a9d8ae3aabd14.tar.gz |
Add special download modes to force updates from the divecomputer
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'dive.c')
-rw-r--r-- | dive.c | 61 |
1 files changed, 45 insertions, 16 deletions
@@ -590,6 +590,9 @@ struct dive *fixup_dive(struct dive *dive) #define MERGE_TXT(res, a, b, n) res->n = merge_text(a->n, b->n) #define MERGE_NONZERO(res, a, b, n) res->n = a->n ? a->n : b->n +#define MERGE_MAX_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : MAX(a->n, b->n) +#define MERGE_MIN_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n) + static struct dive *add_sample(struct sample *sample, int time, struct dive *dive) { struct sample *p = prepare_sample(&dive); @@ -684,6 +687,20 @@ add_sample_b: } } +static struct dive *copy_samples(struct dive *res, struct dive *src) +{ + int samples = src->samples; + struct sample *s = src->sample; + while (samples) { + if (!res) + return NULL; + res = add_sample(s, s->time.seconds, res); + s++; + samples--; + } + return fixup_dive(res); +} + static char *merge_text(const char *a, const char *b) { char *res; @@ -1027,9 +1044,9 @@ static int find_sample_offset(struct dive *a, struct dive *b) * merges almost exact duplicates - something that happens easily * with overlapping dive downloads. */ -struct dive *try_to_merge(struct dive *a, struct dive *b) +struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer_downloaded) { - int offset; + int offset = 0; /* * This assumes that the clocks on the dive computers are @@ -1037,19 +1054,26 @@ struct dive *try_to_merge(struct dive *a, struct dive *b) */ if ((a->when >= b->when + 60) || (a->when <= b->when - 60)) return NULL; - - /* Dive 'a' is 'offset' seconds before dive 'b' */ - offset = find_sample_offset(a, b); - if (offset > 120 || offset < -120) + if (prefer_downloaded && a->when != b->when) return NULL; - - return merge_dives(a, b, offset); + if (!prefer_downloaded) { + /* Dive 'a' is 'offset' seconds before dive 'b' */ + offset = find_sample_offset(a, b); + if (offset > 120 || offset < -120) + return NULL; + } + return merge_dives(a, b, offset, prefer_downloaded); } -struct dive *merge_dives(struct dive *a, struct dive *b, int offset) +struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded) { struct dive *res = alloc_dive(); + struct dive *dl = NULL; + if (a->downloaded) + dl = a; + else if (b->downloaded) + dl = b; res->when = a->when; res->selected = a->selected || b->selected; merge_trip(res, a, b); @@ -1062,16 +1086,21 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset) MERGE_MAX(res, a, b, rating); MERGE_TXT(res, a, b, suit); MERGE_MAX(res, a, b, number); - MERGE_MAX(res, a, b, maxdepth.mm); + MERGE_MAX_PREFDL(res, dl, a, b, maxdepth.mm); res->meandepth.mm = 0; MERGE_NONZERO(res, a, b, salinity); MERGE_NONZERO(res, a, b, visibility); MERGE_NONZERO(res, a, b, surface_pressure.mbar); - MERGE_MAX(res, a, b, duration.seconds); - MERGE_MAX(res, a, b, surfacetime.seconds); - MERGE_MAX(res, a, b, airtemp.mkelvin); - MERGE_MIN(res, a, b, watertemp.mkelvin); + MERGE_MAX_PREFDL(res, dl, a, b, duration.seconds); + MERGE_MAX_PREFDL(res, dl, a, b, surfacetime.seconds); + MERGE_MAX_PREFDL(res, dl, a, b, airtemp.mkelvin); + MERGE_MIN_PREFDL(res, dl, a, b, watertemp.mkelvin); merge_equipment(res, a, b); - merge_events(res, a, b, offset); - return merge_samples(res, a, b, offset); + if (dl) { + res->events = dl->events; + return copy_samples(res, dl); + } else { + merge_events(res, a, b, offset); + return merge_samples(res, a, b, offset); + } } |