mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Undo: implement rudimentary support for undo of dive-splitting
For this, the core functionality of the split_dive() and split_dive_at_time() functions were split out into new split_dive_dont_insert() and split_dive_at_time_dont_insert(), which do not add the new dives to the log. Thus, the undo-command can take ownership of these dives, without having to remove them first. The split-dive functionality is temporarily made desktop-only until mobile also supports "UndoObjects". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
12df9faaa2
commit
302f6adb79
6 changed files with 145 additions and 36 deletions
76
core/dive.c
76
core/dive.c
|
@ -3388,7 +3388,7 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer
|
|||
}
|
||||
|
||||
// copy_dive(), but retaining the new ID for the copied dive
|
||||
static struct dive *create_new_copy(struct dive *from)
|
||||
static struct dive *create_new_copy(const struct dive *from)
|
||||
{
|
||||
struct dive *to = alloc_dive();
|
||||
int id;
|
||||
|
@ -3450,9 +3450,11 @@ static void force_fixup_dive(struct dive *d)
|
|||
|
||||
/*
|
||||
* Split a dive that has a surface interval from samples 'a' to 'b'
|
||||
* into two dives.
|
||||
* into two dives, but don't add them to the log yet.
|
||||
* Returns the nr of the old dive or <0 on failure.
|
||||
* On success, the newly allocated dives are returned in out1 and out2.
|
||||
*/
|
||||
static int split_dive_at(struct dive *dive, int a, int b)
|
||||
static int split_dive_at(const struct dive *dive, int a, int b, struct dive **out1, struct dive **out2)
|
||||
{
|
||||
int i, nr;
|
||||
uint32_t t;
|
||||
|
@ -3462,15 +3464,16 @@ static int split_dive_at(struct dive *dive, int a, int b)
|
|||
|
||||
/* if we can't find the dive in the dive list, don't bother */
|
||||
if ((nr = get_divenr(dive)) < 0)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
/* Splitting should leave at least 3 samples per dive */
|
||||
if (a < 3 || b > dive->dc.samples - 4)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
/* We're not trying to be efficient here.. */
|
||||
d1 = create_new_copy(dive);
|
||||
d2 = create_new_copy(dive);
|
||||
d1->divetrip = d2->divetrip = 0;
|
||||
|
||||
/* now unselect the first first segment so we don't keep all
|
||||
* dives selected by mistake. But do keep the second one selected
|
||||
|
@ -3544,15 +3547,6 @@ static int split_dive_at(struct dive *dive, int a, int b)
|
|||
force_fixup_dive(d1);
|
||||
force_fixup_dive(d2);
|
||||
|
||||
if (dive->divetrip) {
|
||||
d1->divetrip = d2->divetrip = 0;
|
||||
add_dive_to_trip(d1, dive->divetrip);
|
||||
add_dive_to_trip(d2, dive->divetrip);
|
||||
}
|
||||
|
||||
delete_single_dive(nr);
|
||||
add_single_dive(nr, d1);
|
||||
|
||||
/*
|
||||
* Was the dive numbered? If it was the last dive, then we'll
|
||||
* increment the dive number for the tail part that we split off.
|
||||
|
@ -3564,16 +3558,28 @@ static int split_dive_at(struct dive *dive, int a, int b)
|
|||
else
|
||||
d2->number = 0;
|
||||
}
|
||||
add_single_dive(nr + 1, d2);
|
||||
|
||||
mark_divelist_changed(true);
|
||||
|
||||
return 1;
|
||||
*out1 = d1;
|
||||
*out2 = d2;
|
||||
return nr;
|
||||
}
|
||||
|
||||
static void finish_split(int nr, struct dive *old, struct dive *d1, struct dive *d2)
|
||||
{
|
||||
if (old->divetrip) {
|
||||
add_dive_to_trip(d1, old->divetrip);
|
||||
add_dive_to_trip(d2, old->divetrip);
|
||||
}
|
||||
delete_single_dive(nr);
|
||||
add_single_dive(nr, d1);
|
||||
add_single_dive(nr + 1, d2);
|
||||
}
|
||||
|
||||
/* in freedive mode we split for as little as 10 seconds on the surface,
|
||||
* otherwise we use a minute */
|
||||
static bool should_split(struct divecomputer *dc, int t1, int t2)
|
||||
static bool should_split(const struct divecomputer *dc, int t1, int t2)
|
||||
{
|
||||
int threshold = dc->divemode == FREEDIVE ? 10 : 60;
|
||||
|
||||
|
@ -3590,14 +3596,14 @@ static bool should_split(struct divecomputer *dc, int t1, int t2)
|
|||
*
|
||||
* In other words, this is a (simplified) reversal of the dive merging.
|
||||
*/
|
||||
int split_dive(struct dive *dive)
|
||||
int split_dive_dont_insert(const struct dive *dive, struct dive **new1, struct dive **new2)
|
||||
{
|
||||
int i;
|
||||
int at_surface, surface_start;
|
||||
struct divecomputer *dc;
|
||||
const struct divecomputer *dc;
|
||||
|
||||
if (!dive)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
dc = &dive->dc;
|
||||
surface_start = 0;
|
||||
|
@ -3627,25 +3633,43 @@ int split_dive(struct dive *dive)
|
|||
if (!should_split(dc, dc->sample[surface_start].time.seconds, sample[-1].time.seconds))
|
||||
continue;
|
||||
|
||||
return split_dive_at(dive, surface_start, i-1);
|
||||
return split_dive_at(dive, surface_start, i-1, new1, new2);
|
||||
}
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void split_dive_at_time(struct dive *dive, duration_t time)
|
||||
void split_dive(struct dive *dive)
|
||||
{
|
||||
int nr;
|
||||
struct dive *new1, *new2;
|
||||
|
||||
if ((nr = split_dive_dont_insert(dive, &new1, &new2)) >= 0)
|
||||
finish_split(nr, dive, new1, new2);
|
||||
}
|
||||
|
||||
int split_dive_at_time_dont_insert(const struct dive *dive, duration_t time, struct dive **new1, struct dive **new2)
|
||||
{
|
||||
int i = 0;
|
||||
struct sample *sample = dive->dc.sample;
|
||||
|
||||
if (!dive)
|
||||
return;
|
||||
return -1;
|
||||
while(sample->time.seconds < time.seconds) {
|
||||
++sample;
|
||||
++i;
|
||||
if (dive->dc.samples == i)
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
split_dive_at(dive, i, i - 1);
|
||||
return split_dive_at(dive, i, i - 1, new1, new2);
|
||||
}
|
||||
|
||||
void split_dive_at_time(struct dive *dive, duration_t time)
|
||||
{
|
||||
int nr;
|
||||
struct dive *new1, *new2;
|
||||
|
||||
if ((nr = split_dive_at_time_dont_insert(dive, time, &new1, &new2)) >= 0)
|
||||
finish_split(nr, dive, new1, new2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue