mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
6ddf0e1d22
commit
b49b081bb9
2 changed files with 73 additions and 0 deletions
1
dive.h
1
dive.h
|
@ -271,6 +271,7 @@ extern gboolean autogroup;
|
||||||
|
|
||||||
#define UNGROUPED_DIVE(_dive) ((_dive)->tripflag == NO_TRIP)
|
#define UNGROUPED_DIVE(_dive) ((_dive)->tripflag == NO_TRIP)
|
||||||
#define DIVE_IN_TRIP(_dive) ((_dive)->tripflag == IN_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 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 PREV_TRIP(_entry) ((_entry) ? g_list_previous(_entry) : g_list_last(dive_trip_list))
|
||||||
#define DIVE_TRIP(_trip) ((struct dive *)(_trip)->data)
|
#define DIVE_TRIP(_trip) ((struct dive *)(_trip)->data)
|
||||||
|
|
72
divelist.c
72
divelist.c
|
@ -65,6 +65,9 @@ enum {
|
||||||
DIVELIST_COLUMNS
|
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
|
#ifdef DEBUG_MODEL
|
||||||
static gboolean dump_model_entry(GtkTreeModel *model, GtkTreePath *path,
|
static gboolean dump_model_entry(GtkTreeModel *model, GtkTreePath *path,
|
||||||
GtkTreeIter *iter, gpointer data)
|
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
|
/* make sure that if we expand a summary row that is selected, the children show
|
||||||
up as selected, too */
|
up as selected, too */
|
||||||
void row_expanded_cb(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data)
|
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;
|
struct dive *last_trip = NULL;
|
||||||
GList *trip;
|
GList *trip;
|
||||||
struct dive *dive_trip = NULL;
|
struct dive *dive_trip = NULL;
|
||||||
|
gboolean need_scan = FALSE;
|
||||||
|
|
||||||
/* if we have pre-existing trips, start on the last one */
|
/* if we have pre-existing trips, start on the last one */
|
||||||
trip = g_list_last(dive_trip_list);
|
trip = g_list_last(dive_trip_list);
|
||||||
|
@ -981,6 +1007,15 @@ static void fill_dive_list(void)
|
||||||
dive_trip = NULL;
|
dive_trip = NULL;
|
||||||
parent_ptr = 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
|
/* update dive as part of dive_trip and
|
||||||
* (if necessary) update dive_trip time and location */
|
* (if necessary) update dive_trip time and location */
|
||||||
if (dive_trip) {
|
if (dive_trip) {
|
||||||
|
@ -1041,6 +1076,43 @@ static void fill_dive_list(void)
|
||||||
DIVE_DATE, dive_trip->when,
|
DIVE_DATE, dive_trip->when,
|
||||||
DIVE_LOCATION, dive_trip->location,
|
DIVE_LOCATION, dive_trip->location,
|
||||||
-1);
|
-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();
|
update_dive_list_units();
|
||||||
if (gtk_tree_model_get_iter_first(MODEL(dive_list), &iter)) {
|
if (gtk_tree_model_get_iter_first(MODEL(dive_list), &iter)) {
|
||||||
GtkTreeSelection *selection;
|
GtkTreeSelection *selection;
|
||||||
|
|
Loading…
Add table
Reference in a new issue