aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--divelist.c118
1 files changed, 62 insertions, 56 deletions
diff --git a/divelist.c b/divelist.c
index 77538b78f..c30e9f28a 100644
--- a/divelist.c
+++ b/divelist.c
@@ -963,6 +963,49 @@ static struct dive *create_and_hookup_trip_from_dive(struct dive *dive)
return dive_trip;
}
+/* check that a dive should be in a trip starting at 'when'
+ * first the regular check (dive is before the trip start, but within the
+ * threshold)
+ * then for dives that are after the trip start we walk back to the dive
+ * that starts at when and check on the way that there is no ungrouped
+ * dive and no break beyond the 3 day threshold between dives that
+ * haven't already been assigned to this trip */
+static gboolean dive_can_be_in_trip(int idx, struct dive *dive_trip)
+{
+ struct dive *dive, *pdive;
+ int i = idx;
+ time_t when = dive_trip->when;
+
+ dive = get_dive(idx);
+ /* if the dive is before the trip start but within the threshold
+ * then just accept it, otherwise reject it */
+ if (dive->when < when) {
+ if (DIVE_FITS_TRIP(dive, dive_trip))
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ while (--i >= 0) {
+ pdive = get_dive(i);
+ /* an ungrouped dive cannot be in the middle of a trip
+ * also, if there are two consecutive dives that are too far apart
+ * that aren't both already labeled as 'in trip' (which shows that
+ * this was manually done so we shouldn't override that) */
+ if ( UNGROUPED_DIVE(pdive) ||
+ (! (DIVE_IN_TRIP(pdive) && DIVE_IN_TRIP(dive)) &&
+ dive->when - pdive->when > TRIP_THRESHOLD)) {
+ return FALSE;
+ }
+ if (pdive->when == when)
+ /* done - we have reached the first dive in the trip */
+ return TRUE;
+ dive = pdive;
+ }
+ /* we should never get here */
+ return TRUE;
+}
+
static void fill_dive_list(void)
{
int i;
@@ -971,7 +1014,6 @@ static void fill_dive_list(void)
struct dive *last_trip = NULL;
GList *trip;
struct dive *dive_trip = NULL;
- gboolean need_scan = FALSE;
/* if we have pre-existing trips, start on the last one */
trip = g_list_last(dive_trip_list);
@@ -1002,31 +1044,32 @@ static void fill_dive_list(void)
/* first dives that go to the top level */
parent_ptr = NULL;
dive_trip = NULL;
- } else if (autogroup && !DIVE_IN_TRIP(dive)) {
- if ( ! dive_trip || ! DIVE_FITS_TRIP(dive, dive_trip)) {
- /* allocate new trip - all fields default to 0
- and get filled in further down */
- dive_trip = create_and_hookup_trip_from_dive(dive);
- dive_trip->tripflag = IN_TRIP; /* this marks an autogen trip */
- trip = FIND_TRIP(dive_trip->when);
+ } else if (autogroup && DIVE_NEEDS_TRIP(dive)){
+ /* if we already have existing trips there are up to two trips that this
+ * could potentially be part of. Let's try the one we are on, first */
+ if (! (dive_trip && dive_can_be_in_trip(i, dive_trip))) {
+ /* there could be a better trip in our list already */
+ trip = find_matching_trip(dive->when);
+ if (! (trip && dive_can_be_in_trip(i, DIVE_TRIP(trip)))) {
+ /* seems like neither of these trips work, so create
+ * a new one; all fields default to 0 and get filled
+ * in further down */
+ parent_ptr = NULL;
+ dive_trip = create_and_hookup_trip_from_dive(dive);
+ dive_trip->tripflag = IN_TRIP;
+ trip = FIND_TRIP(dive_trip->when);
+ }
+ if (trip)
+ dive_trip = DIVE_TRIP(trip);
}
} else if (DIVE_IN_TRIP(dive)) {
- trip = find_matching_trip(dive->when);
- dive_trip = DIVE_TRIP(trip);
+ trip = find_matching_trip(dive->when);
+ dive_trip = DIVE_TRIP(trip);
} else {
/* dive is not in a trip and we aren't autogrouping */
dive_trip = NULL;
parent_ptr = NULL;
}
- /* if we have an new dive and the dive_trip date is earlier than the
- * dive then this is an existing trip and a new dive; as we are walking the
- * dive_list oldest first it's very hard right now to know if this dive
- * should be in that trip; so postpone this decision until the 'forward'
- * scan at the end of this function */
- if (DIVE_NEEDS_TRIP(dive) && dive_trip && dive_trip->when < dive->when) {
- dive_trip = NULL;
- need_scan = TRUE;
- }
/* update dive as part of dive_trip and
* (if necessary) update dive_trip time and location */
if (dive_trip) {
@@ -1087,43 +1130,6 @@ static void fill_dive_list(void)
DIVE_DATE, dive_trip->when,
DIVE_LOCATION, dive_trip->location,
-1);
- /* now walk the dive list one more time to make sure any new
- * dives that fit into an existing dive_trip have been added
- * to the matching trips */
- if (autogroup && need_scan) {
- struct dive *dive;
- time_t last_trip_dive_when;
- GtkTreePath *path;
-
- trip = dive_trip_list;
- last_trip_dive_when = DIVE_TRIP(trip)->when;
- for (i = 0; i < dive_table.nr; i++) {
- dive = get_dive(i);
- if (UNGROUPED_DIVE(dive)) {
- /* this ends any trip */
- trip = NULL;
- last_trip_dive_when = 0;
- } else if (DIVE_IN_TRIP(dive)) {
- trip = find_matching_trip(dive->when);
- if (dive->when > last_trip_dive_when)
- last_trip_dive_when = dive->when;
- } else { /* DIVE_NEEDS_TRIP */
- if (dive->when - last_trip_dive_when < TRIP_THRESHOLD) {
- /* dive should be in this trip */
- dive->tripflag = IN_TRIP;
- dive->divetrip = DIVE_TRIP(trip);
- /* now move the tree node into place */
- path = get_path_from(dive);
- merge_dive_into_trip_above_cb(NULL, path);
-
- } else {
- /* we did need a new trip for this dive */
- path = get_path_from(dive);
- turn_dive_into_trip(path);
- }
- }
- }
- }
update_dive_list_units();
if (gtk_tree_model_get_iter_first(MODEL(dive_list), &iter)) {
GtkTreeSelection *selection;