summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/dive.c b/dive.c
index b61166569..fe9ce3a20 100644
--- a/dive.c
+++ b/dive.c
@@ -1323,7 +1323,24 @@ static int same_dc(struct divecomputer *a, struct divecomputer *b)
return eva == evb;
}
-static void remove_redundant_dc(struct divecomputer *dc)
+static int might_be_same_device(struct divecomputer *a, struct divecomputer *b)
+{
+ /* No dive computer model? That matches anything */
+ if (!a->model || !b->model)
+ return 1;
+
+ /* Otherwise at least the model names have to match */
+ if (strcasecmp(a->model, b->model))
+ return 0;
+
+ /* No device ID? Match */
+ if (!a->deviceid || !b->deviceid)
+ return 1;
+
+ return a->deviceid == b->deviceid;
+}
+
+static void remove_redundant_dc(struct divecomputer *dc, int prefer_downloaded)
{
do {
struct divecomputer **p = &dc->next;
@@ -1331,7 +1348,7 @@ static void remove_redundant_dc(struct divecomputer *dc)
/* Check this dc against all the following ones.. */
while (*p) {
struct divecomputer *check = *p;
- if (same_dc(dc, check)) {
+ if (same_dc(dc, check) || (prefer_downloaded && might_be_same_device(dc, check))) {
*p = check->next;
check->next = NULL;
free_dc(check);
@@ -1340,7 +1357,8 @@ static void remove_redundant_dc(struct divecomputer *dc)
p = &check->next;
}
- /* .. and then continue down the chain */
+ /* .. and then continue down the chain, but we */
+ prefer_downloaded = 0;
dc = dc->next;
} while (dc);
}
@@ -1357,19 +1375,7 @@ static struct divecomputer *find_matching_computer(struct divecomputer *match, s
while ((p = list) != NULL) {
list = list->next;
- /* No dive computer model? That matches anything */
- if (!match->model || !p->model)
- break;
-
- /* Otherwise at least the model names have to match */
- if (strcasecmp(match->model, p->model))
- continue;
-
- /* No device ID? Match */
- if (!match->deviceid || !p->deviceid)
- break;
-
- if (match->deviceid == p->deviceid)
+ if (might_be_same_device(match, p))
break;
}
return p;
@@ -1422,9 +1428,13 @@ static void interleave_dive_computers(struct divecomputer *res,
* name etc), we will prefer a new-style one and just throw
* away the old. We're assuming it's a re-download.
*
- * Otherwise, we'll just try to keep all the information.
+ * Otherwise, we'll just try to keep all the information,
+ * unless the user has specified that they prefer the
+ * downloaded computer, in which case we'll aggressively
+ * try to throw out old information that *might* be from
+ * that one.
*/
-static void join_dive_computers(struct divecomputer *res, struct divecomputer *a, struct divecomputer *b)
+static void join_dive_computers(struct divecomputer *res, struct divecomputer *a, struct divecomputer *b, int prefer_downloaded)
{
struct divecomputer *tmp;
@@ -1449,7 +1459,7 @@ static void join_dive_computers(struct divecomputer *res, struct divecomputer *a
*tmp->next = *b;
clear_dc(b);
- remove_redundant_dc(res);
+ remove_redundant_dc(res, prefer_downloaded);
}
struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded)
@@ -1490,18 +1500,12 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean pr
MERGE_MIN_PREFDL(res, dl, a, b, watertemp.mkelvin);
merge_equipment(res, a, b);
if (dl) {
- res->dc = dl->dc;
- /*
- * Since we copied the events and samples,
- * we can't free them from the source when
- * we free it - so make sure the source
- * dive computer data is cleared out.
- */
- clear_dc(&dl->dc);
+ /* If we prefer downloaded, do those first, and get rid of "might be same" computers */
+ join_dive_computers(&res->dc, &dl->dc, &a->dc, 1);
} else if (offset)
interleave_dive_computers(&res->dc, &a->dc, &b->dc, offset);
else
- join_dive_computers(&res->dc, &a->dc, &b->dc);
+ join_dive_computers(&res->dc, &a->dc, &b->dc, 0);
fixup_dive(res);
return res;