diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-09-07 10:12:31 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-09-07 10:12:31 -0700 |
commit | b49b081bb9c3938e5df201350a3a7d397c2c6216 (patch) | |
tree | 0fb28dc9756f18ce13011e5754882c789f444cf9 | |
parent | 6ddf0e1d227bdf707469a2d7313ea850d35a6cda (diff) | |
download | subsurface-b49b081bb9c3938e5df201350a3a7d397c2c6216.tar.gz |
Handle new dives correctly if trips exist
There is an interesting issue when adding new dives into a dive list with
existing trips. Since fill_dive_list walks the list backwards and trips
are determined by the timestamp of the first dive in a trip, it is
non-trivial to know when a dive is added if it should be part of an
existing trip or not. Let's say when we see the dive we can also see a
trip entry that starts four days earlier. Without looking forward in the
list of dives we cannot tell if this is a multi-day trip that this dive
would fit into, or if there is a break of more than tree days (our current
trip threshold).
Instead this commit adds a second scan of the dives in chronological order
that does the right thing for new dives.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | dive.h | 1 | ||||
-rw-r--r-- | divelist.c | 72 |
2 files changed, 73 insertions, 0 deletions
@@ -271,6 +271,7 @@ extern gboolean autogroup; #define UNGROUPED_DIVE(_dive) ((_dive)->tripflag == NO_TRIP) #define DIVE_IN_TRIP(_dive) ((_dive)->tripflag == IN_TRIP) +#define DIVE_NEEDS_TRIP(_dive) ((_dive)->tripflag == TF_NONE) #define NEXT_TRIP(_entry) ((_entry) ? g_list_next(_entry) : (dive_trip_list)) #define PREV_TRIP(_entry) ((_entry) ? g_list_previous(_entry) : g_list_last(dive_trip_list)) #define DIVE_TRIP(_trip) ((struct dive *)(_trip)->data) diff --git a/divelist.c b/divelist.c index 5fb01daa4..00d18fce0 100644 --- a/divelist.c +++ b/divelist.c @@ -65,6 +65,9 @@ enum { DIVELIST_COLUMNS }; +static void turn_dive_into_trip(GtkTreePath *path); +static void merge_dive_into_trip_above_cb(GtkWidget *menuitem, GtkTreePath *path); + #ifdef DEBUG_MODEL static gboolean dump_model_entry(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) @@ -136,6 +139,28 @@ static void first_leaf(GtkTreeModel *model, GtkTreeIter *iter, int *diveidx) } } +static GtkTreePath *path_match; + +static gboolean match_dive(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) +{ + int idx; + struct dive *dive = data; + + gtk_tree_model_get(model, iter, DIVE_INDEX, &idx, -1); + if (idx >= 0) + if (get_dive(idx)->when == dive->when) { + path_match = gtk_tree_path_copy(path); + return TRUE; + } + return FALSE; +} + +static GtkTreePath *get_path_from(struct dive *dive) +{ + gtk_tree_model_foreach(TREEMODEL(dive_list), match_dive, dive); + return path_match; +} + /* make sure that if we expand a summary row that is selected, the children show up as selected, too */ void row_expanded_cb(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data) @@ -935,6 +960,7 @@ 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); @@ -981,6 +1007,15 @@ static void fill_dive_list(void) 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) { @@ -1041,6 +1076,43 @@ 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; |