diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | core/dive.c | 43 |
2 files changed, 40 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b9095728..e8edf7268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ - desktop: allow adding dives to arbitrary trips +- core: improve merging of cylinder pressures [#2884] - desktop: respect page-up, page-down, home and end keys for selection change [#2957] - Use pO2 from prefernces for MOD display in equipment tab - filter: more flexible filtering system based on individual constraints diff --git a/core/dive.c b/core/dive.c index c3fd95bf1..2c9de41a3 100644 --- a/core/dive.c +++ b/core/dive.c @@ -2228,6 +2228,39 @@ static int match_cylinder(const cylinder_t *cyl, const struct dive *dive, const } /* + * Function used to merge manually set start or end pressures. This + * is used to merge cylinders when merging dives. We store up to two + * values for start _and_ end pressures: one derived from samples and + * one entered manually, whereby the latter takes precedence. It may + * happen that the user merges two dives where one has a manual, + * the other only a sample-derived pressure. In such a case we want to + * supplement the non-existing manual value by a sample derived one. + * Otherwise, the merged dive would end up with incomplete pressure + * information. + * The last argument to the function specifies whether the larger + * or smaller value of the two dives should be returned. Obviously, + * for the starting pressure we want the larger and for the ending + * pressure the smaller value. + */ +static pressure_t merge_pressures(pressure_t a, pressure_t sample_a, pressure_t b, pressure_t sample_b, bool take_min) +{ + if (!a.mbar && !b.mbar) + return a; + if (!a.mbar) + a = sample_a; + if (!b.mbar) + b = sample_b; + if (!a.mbar) + a = b; + if (!b.mbar) + b = a; + if (take_min && a.mbar < b.mbar) + return a; + else + return b; +} + +/* * We matched things up so that they have the same gasmix and * use, but we might want to fill in any missing cylinder details * in 'a' if we had it from 'b'. @@ -2240,10 +2273,12 @@ static void merge_one_cylinder(cylinder_t *a, const cylinder_t *b) a->type.workingpressure.mbar = b->type.workingpressure.mbar; if (empty_string(a->type.description)) a->type.description = copy_string(b->type.description); - if (!a->start.mbar) - a->start.mbar = b->start.mbar; - if (!a->end.mbar) - a->end.mbar = b->end.mbar; + + /* If either cylinder has manually entered pressures, try to merge them. + * Use pressures from divecomputer samples if only one cylinder has such a value. + * Yes, this is an actual use case we encountered. */ + a->start = merge_pressures(a->start, a->sample_start, b->start, b->sample_start, false); + a->end = merge_pressures(a->end, a->sample_end, b->end, b->sample_end, true); if (a->sample_start.mbar && b->sample_start.mbar) a->sample_start.mbar = a->sample_start.mbar > b->sample_start.mbar ? a->sample_start.mbar : b->sample_start.mbar; |