summaryrefslogtreecommitdiffstats
path: root/core/divelist.c
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-05-31 16:09:14 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-06-19 13:11:10 -0700
commit7f4d9db962e73aa5d5089c43c99b78b3690ffb87 (patch)
tree87e143b80ed394fc321765885a75cac229bf9f18 /core/divelist.c
parentf1c2cd375e295730d92e23093e44777baf838f1d (diff)
downloadsubsurface-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.c364
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;
-}