diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-05-31 16:09:14 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-06-19 13:11:10 -0700 |
commit | 7f4d9db962e73aa5d5089c43c99b78b3690ffb87 (patch) | |
tree | 87e143b80ed394fc321765885a75cac229bf9f18 /core/divelist.c | |
parent | f1c2cd375e295730d92e23093e44777baf838f1d (diff) | |
download | subsurface-7f4d9db962e73aa5d5089c43c99b78b3690ffb87.tar.gz |
Cleanup: move trip-related functions into own translation unit
These functions were spread out over dive.c and divelist.c.
Move them into their own file to make all this a bit less monolithic.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/divelist.c')
-rw-r--r-- | core/divelist.c | 364 |
1 files changed, 5 insertions, 359 deletions
diff --git a/core/divelist.c b/core/divelist.c index aeabdb89b..3da17c79a 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -19,6 +19,7 @@ #include "qthelper.h" #include "git-access.h" #include "table.h" +#include "trip.h" /* This flag is set to true by operations that are not implemented in the * undo system. It is therefore only cleared on save and load. */ @@ -26,8 +27,6 @@ static bool dive_list_changed = false; bool autogroup = false; -struct trip_table trip_table; - unsigned int amount_selected; #if DEBUG_SELECTION_TRACKING @@ -679,72 +678,6 @@ char *get_dive_gas_string(const struct dive *dive) return buffer; } -/* - * helper functions for dive_trip handling - */ -#ifdef DEBUG_TRIP -void dump_trip_list(void) -{ - dive_trip_t *trip; - int i = 0; - timestamp_t last_time = 0; - - for (i = 0; i < trip_table.nr; ++i) { - struct tm tm; - trip = trip_table.trips[i]; - utc_mkdate(trip_date(trip), &tm); - if (trip_date(trip) < last_time) - printf("\n\ntrip_table OUT OF ORDER!!!\n\n\n"); - printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n", - trip->autogen ? "autogen " : "", - i + 1, trip->location, - tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, - trip->dives.nr, trip); - last_time = trip_date(trip); - } - printf("-----\n"); -} -#endif - -/* free resources associated with a trip structure */ -void free_trip(dive_trip_t *trip) -{ - if (trip) { - free(trip->location); - free(trip->notes); - free(trip->dives.dives); - free(trip); - } -} - -timestamp_t trip_date(const struct dive_trip *trip) -{ - if (!trip || trip->dives.nr == 0) - return 0; - return trip->dives.dives[0]->when; -} - -static timestamp_t trip_enddate(const struct dive_trip *trip) -{ - if (!trip || trip->dives.nr == 0) - return 0; - return dive_endtime(trip->dives.dives[trip->dives.nr - 1]); -} - -/* check if we have a trip right before / after this dive */ -bool is_trip_before_after(const struct dive *dive, bool before) -{ - int idx = get_idx_by_uniq_id(dive->id); - if (before) { - if (idx > 0 && get_dive(idx - 1)->divetrip) - return true; - } else { - if (idx < dive_table.nr - 1 && get_dive(idx + 1)->divetrip) - return true; - } - return false; -} - struct dive *first_selected_dive() { int idx; @@ -809,7 +742,7 @@ static int comp_dc(const struct divecomputer *dc1, const struct divecomputer *dc * We might also consider sorting by end-time and other criteria, * but see the caveat above (editing means rearrangement of the dives). */ -static int comp_dives(const struct dive *a, const struct dive *b) +int comp_dives(const struct dive *a, const struct dive *b) { int cmp; if (a->when < b->when) @@ -839,222 +772,21 @@ static int comp_dives(const struct dive *a, const struct dive *b) return 0; /* this should not happen for a != b */ } -/* Trips are compared according to the first dive in the trip. */ -static int comp_trips(const struct dive_trip *a, const struct dive_trip *b) -{ - /* This should never happen, nevertheless don't crash on trips - * with no (or worse a negative number of) dives. */ - if (a->dives.nr <= 0) - return b->dives.nr <= 0 ? 0 : -1; - if (b->dives.nr <= 0) - return 1; - return comp_dives(a->dives.dives[0], b->dives.dives[0]); -} - +/* Dive table functions */ MAKE_GROW_TABLE(dive_table, struct dive *, dives) -static MAKE_GROW_TABLE(trip_table, struct dive_trip *, trips) - MAKE_GET_INSERTION_INDEX(dive_table, struct dive *, dives, dive_less_than) -static MAKE_GET_INSERTION_INDEX(trip_table, struct dive_trip *, trips, trip_less_than) - MAKE_ADD_TO(dive_table, struct dive *, dives) -static MAKE_ADD_TO(trip_table, struct dive_trip *, trips) - static MAKE_REMOVE_FROM(dive_table, dives) -static MAKE_REMOVE_FROM(trip_table, trips) - static MAKE_GET_IDX(dive_table, struct dive *, dives) -static MAKE_GET_IDX(trip_table, struct dive_trip *, trips) - MAKE_SORT(dive_table, struct dive *, dives, comp_dives) -MAKE_SORT(trip_table, struct dive_trip *, trips, comp_trips) - MAKE_REMOVE(dive_table, struct dive *, dive) -MAKE_REMOVE(trip_table, struct dive_trip *, trip) -static void insert_dive(struct dive_table *table, struct dive *d) +void insert_dive(struct dive_table *table, struct dive *d) { int idx = dive_table_get_insertion_index(table, d); add_to_dive_table(table, idx, d); } -/* remove a dive from the trip it's associated to, but don't delete the - * trip if this was the last dive in the trip. the caller is responsible - * for removing the trip, if the trip->dives.nr went to 0. - */ -struct dive_trip *unregister_dive_from_trip(struct dive *dive) -{ - dive_trip_t *trip = dive->divetrip; - - if (!trip) - return NULL; - - remove_dive(dive, &trip->dives); - dive->divetrip = NULL; - return trip; -} - -static void delete_trip(dive_trip_t *trip, struct trip_table *trip_table_arg) -{ - remove_trip(trip, trip_table_arg); - free_trip(trip); -} - -void remove_dive_from_trip(struct dive *dive, struct trip_table *trip_table_arg) -{ - struct dive_trip *trip = unregister_dive_from_trip(dive); - if (trip && trip->dives.nr == 0) - delete_trip(trip, trip_table_arg); -} - -/* Add dive to a trip. Caller is responsible for removing dive - * from trip beforehand. */ -void add_dive_to_trip(struct dive *dive, dive_trip_t *trip) -{ - if (dive->divetrip == trip) - return; - if (dive->divetrip) - fprintf(stderr, "Warning: adding dive to trip that has trip set\n"); - insert_dive(&trip->dives, dive); - dive->divetrip = trip; -} - -dive_trip_t *alloc_trip(void) -{ - return calloc(1, sizeof(dive_trip_t)); -} - -/* insert the trip into the trip table */ -void insert_trip(dive_trip_t *dive_trip, struct trip_table *trip_table_arg) -{ - int idx = trip_table_get_insertion_index(trip_table_arg, dive_trip); - add_to_trip_table(trip_table_arg, idx, dive_trip); -#ifdef DEBUG_TRIP - dump_trip_list(); -#endif -} - -dive_trip_t *create_trip_from_dive(struct dive *dive) -{ - dive_trip_t *trip; - - trip = alloc_trip(); - trip->location = copy_string(get_dive_location(dive)); - - return trip; -} - -dive_trip_t *create_and_hookup_trip_from_dive(struct dive *dive, struct trip_table *trip_table_arg) -{ - dive_trip_t *dive_trip = alloc_trip(); - - dive_trip = create_trip_from_dive(dive); - - add_dive_to_trip(dive, dive_trip); - insert_trip(dive_trip, trip_table_arg); - return dive_trip; -} - -/* random threshold: three days without diving -> new trip - * this works very well for people who usually dive as part of a trip and don't - * regularly dive at a local facility; this is why trips are an optional feature */ -#define TRIP_THRESHOLD 3600 * 24 * 3 - -/* - * Find a trip a new dive should be autogrouped with. If no such trips - * exist, allocate a new trip. The bool "*allocated" is set to true - * if a new trip was allocated. - */ -dive_trip_t *get_trip_for_new_dive(struct dive *new_dive, bool *allocated) -{ - struct dive *d; - dive_trip_t *trip; - int i; - - /* Find dive that is within TRIP_THRESHOLD of current dive */ - for_each_dive(i, d) { - /* Check if we're past the range of possible dives */ - if (d->when >= new_dive->when + TRIP_THRESHOLD) - break; - - if (d->when + TRIP_THRESHOLD >= new_dive->when && d->divetrip) { - /* Found a dive with trip in the range */ - *allocated = false; - return d->divetrip; - } - } - - /* Didn't find a trip -> allocate a new one */ - trip = create_trip_from_dive(new_dive); - trip->autogen = true; - *allocated = true; - return trip; -} - -/* - * Collect dives for auto-grouping. Pass in first dive which should be checked. - * Returns range of dives that should be autogrouped and trip it should be - * associated to. If the returned trip was newly allocated, the last bool - * is set to true. Caller still has to register it in the system. Note - * whereas this looks complicated - it is needed by the undo-system, which - * manually injects the new trips. If there are no dives to be autogrouped, - * return NULL. - */ -dive_trip_t *get_dives_to_autogroup(struct dive_table *table, int start, int *from, int *to, bool *allocated) -{ - int i; - struct dive *lastdive = NULL; - - /* Find first dive that should be merged and remember any previous - * dive that could be merged into. - */ - for (i = start; i < table->nr; i++) { - struct dive *dive = table->dives[i]; - dive_trip_t *trip; - - if (dive->divetrip) { - lastdive = dive; - continue; - } - - /* Only consider dives that have not been explicitly removed from - * a dive trip by the user. */ - if (dive->notrip) { - lastdive = NULL; - continue; - } - - /* We found a dive, let's see if we have to allocate a new trip */ - if (!lastdive || dive->when >= lastdive->when + TRIP_THRESHOLD) { - /* allocate new trip */ - trip = create_trip_from_dive(dive); - trip->autogen = true; - *allocated = true; - } else { - /* use trip of previous dive */ - trip = lastdive->divetrip; - *allocated = false; - } - - // Now, find all dives that will be added to this trip - lastdive = dive; - *from = i; - for (*to = *from + 1; *to < table->nr; (*to)++) { - dive = table->dives[*to]; - if (dive->divetrip || dive->notrip || - dive->when >= lastdive->when + TRIP_THRESHOLD) - break; - if (get_dive_location(dive) && !trip->location) - trip->location = copy_string(get_dive_location(dive)); - lastdive = dive; - } - return trip; - } - - /* Did not find anyhting - mark as end */ - return NULL; -} - /* * Walk the dives from the oldest dive in the given table, and see if we * can autogroup them. But only do this when the user selected autogrouping. @@ -1195,26 +927,6 @@ void deselect_dive(struct dive *dive) } } -void deselect_dives_in_trip(struct dive_trip *trip) -{ - if (!trip) - return; - for (int i = 0; i < trip->dives.nr; ++i) - deselect_dive(trip->dives.dives[i]); -} - -void select_dives_in_trip(struct dive_trip *trip) -{ - struct dive *dive; - if (!trip) - return; - for (int i = 0; i < trip->dives.nr; ++i) { - dive = trip->dives.dives[i]; - if (!dive->hidden_by_filter) - select_dive(dive); - } -} - void filter_dive(struct dive *d, bool shown) { if (!d) @@ -1224,26 +936,6 @@ void filter_dive(struct dive *d, bool shown) deselect_dive(d); } - -/* Out of two strings, copy the string that is not empty (if any). */ -static char *copy_non_empty_string(const char *a, const char *b) -{ - return copy_string(empty_string(b) ? a : b); -} - -/* This combines the information of two trips, generating a - * new trip. To support undo, we have to preserve the old trips. */ -dive_trip_t *combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b) -{ - dive_trip_t *trip; - - trip = alloc_trip(); - trip->location = copy_non_empty_string(trip_a->location, trip_b->location); - trip->notes = copy_non_empty_string(trip_a->notes, trip_b->notes); - - return trip; -} - void mark_divelist_changed(bool changed) { if (dive_list_changed == changed) @@ -1315,7 +1007,7 @@ static void merge_imported_dives(struct dive_table *table) } /* - * Clear a dive_table, trip_table and dive_site_table. Think about generating these with macros. + * Clear a dive_table and dive_site_table. Think about generating these with macros. */ void clear_table(struct dive_table *table) { @@ -1324,13 +1016,6 @@ void clear_table(struct dive_table *table) table->nr = 0; } -void clear_trip_table(struct trip_table *table) -{ - for (int i = 0; i < table->nr; i++) - free_trip(table->trips[i]); - table->nr = 0; -} - void clear_dive_site_table(struct dive_site_table *ds_table) { for (int i = 0; i < ds_table->nr; i++) @@ -1837,11 +1522,6 @@ bool dive_less_than(const struct dive *a, const struct dive *b) return comp_dives(a, b) < 0; } -bool trip_less_than(const struct dive_trip *a, const struct dive_trip *b) -{ - return comp_trips(a, b) < 0; -} - /* When comparing a dive to a trip, use the first dive of the trip. */ static int comp_dive_to_trip(struct dive *a, struct dive_trip *b) { @@ -1925,37 +1605,3 @@ struct dive *find_next_visible_dive(timestamp_t when) return NULL; } - -static bool is_same_day(timestamp_t trip_when, timestamp_t dive_when) -{ - static timestamp_t twhen = (timestamp_t) 0; - static struct tm tmt; - struct tm tmd; - - utc_mkdate(dive_when, &tmd); - - if (twhen != trip_when) { - twhen = trip_when; - utc_mkdate(twhen, &tmt); - } - - return (tmd.tm_mday == tmt.tm_mday) && (tmd.tm_mon == tmt.tm_mon) && (tmd.tm_year == tmt.tm_year); -} - -bool trip_is_single_day(const struct dive_trip *trip) -{ - if (trip->dives.nr <= 1) - return true; - return is_same_day(trip->dives.dives[0]->when, - trip->dives.dives[trip->dives.nr - 1]->when); -} - -int trip_shown_dives(const struct dive_trip *trip) -{ - int res = 0; - for (int i = 0; i < trip->dives.nr; ++i) { - if (!trip->dives.dives[i]->hidden_by_filter) - res++; - } - return res; -} |