mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Merge branch 'divetrip-rewrite' of git://github.com/torvalds/subsurface
Merge the dive trip rewrite by Dirk Hohndel. This just merges the dive trip changes with the timestamp handling changes. There were multiple small data conflicts, along with some newly added 'time_t' cases in the dive trip handling that needed to be converted to 'timestamp_t' along the way. * 'divetrip-rewrite' of git://github.com/torvalds/subsurface: Convert FIND_TRIP into function Partial rewrite of the dive trip code Check if trip is NULL before calling DIVE_TRIP
This commit is contained in:
commit
e8578ad9c9
5 changed files with 206 additions and 107 deletions
5
dive.c
5
dive.c
|
@ -710,6 +710,11 @@ struct dive *try_to_merge(struct dive *a, struct dive *b)
|
||||||
res = alloc_dive();
|
res = alloc_dive();
|
||||||
|
|
||||||
res->when = a->when;
|
res->when = a->when;
|
||||||
|
/* the larger tripflag is more relevant */
|
||||||
|
if(a->tripflag > b->tripflag)
|
||||||
|
res->tripflag = a->tripflag;
|
||||||
|
else
|
||||||
|
res->tripflag = b->tripflag;
|
||||||
MERGE_NONZERO(res, a, b, latitude);
|
MERGE_NONZERO(res, a, b, latitude);
|
||||||
MERGE_NONZERO(res, a, b, longitude);
|
MERGE_NONZERO(res, a, b, longitude);
|
||||||
MERGE_TXT(res, a, b, location);
|
MERGE_TXT(res, a, b, location);
|
||||||
|
|
77
dive.h
77
dive.h
|
@ -237,13 +237,21 @@ struct event {
|
||||||
#define W_IDX_SECONDARY 1
|
#define W_IDX_SECONDARY 1
|
||||||
|
|
||||||
typedef gint64 timestamp_t;
|
typedef gint64 timestamp_t;
|
||||||
typedef enum { TF_NONE, NO_TRIP, IN_TRIP, NUM_TRIPFLAGS } tripflag_t;
|
typedef enum { TF_NONE, NO_TRIP, IN_TRIP, ASSIGNED_TRIP, AUTOGEN_TRIP, NUM_TRIPFLAGS } tripflag_t;
|
||||||
extern const char *tripflag_names[NUM_TRIPFLAGS];
|
extern const char *tripflag_names[NUM_TRIPFLAGS];
|
||||||
|
|
||||||
|
typedef struct dive_trip {
|
||||||
|
tripflag_t tripflag;
|
||||||
|
timestamp_t when;
|
||||||
|
timestamp_t when_from_file;
|
||||||
|
char *location;
|
||||||
|
char *notes;
|
||||||
|
} dive_trip_t;
|
||||||
|
|
||||||
struct dive {
|
struct dive {
|
||||||
int number;
|
int number;
|
||||||
tripflag_t tripflag;
|
tripflag_t tripflag;
|
||||||
struct dive *divetrip;
|
dive_trip_t *divetrip;
|
||||||
int selected;
|
int selected;
|
||||||
timestamp_t when;
|
timestamp_t when;
|
||||||
char *location;
|
char *location;
|
||||||
|
@ -276,72 +284,15 @@ extern gboolean autogroup;
|
||||||
#define TRIP_THRESHOLD 3600*24*3
|
#define TRIP_THRESHOLD 3600*24*3
|
||||||
|
|
||||||
#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 || (_dive)->tripflag == ASSIGNED_TRIP)
|
||||||
#define DIVE_NEEDS_TRIP(_dive) ((_dive)->tripflag == TF_NONE)
|
#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) ((dive_trip_t *)(_trip)->data)
|
||||||
#define DIVE_FITS_TRIP(_dive, _dive_trip) ((_dive_trip)->when - TRIP_THRESHOLD <= (_dive)->when)
|
#define DIVE_FITS_TRIP(_dive, _dive_trip) ((_dive_trip)->when - TRIP_THRESHOLD <= (_dive)->when)
|
||||||
|
|
||||||
/* compare two dives by when they happened */
|
extern void insert_trip(dive_trip_t **trip);
|
||||||
static inline int dive_date_cmp(gconstpointer _a, gconstpointer _b) {
|
|
||||||
return ((struct dive *)_a)->when - ((struct dive *)_b)->when;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 0 if the dive happened exactly at time */
|
|
||||||
static inline int dive_when_find(gconstpointer _listentry, gconstpointer _when)
|
|
||||||
{
|
|
||||||
const struct dive *dive = _listentry;
|
|
||||||
const timestamp_t *tsp = _when;
|
|
||||||
return dive->when != *tsp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline GList *FIND_TRIP(timestamp_t *when)
|
|
||||||
{
|
|
||||||
return g_list_find_custom(dive_trip_list, when, dive_when_find);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_TRIP
|
|
||||||
static void dump_trip_list(void)
|
|
||||||
{
|
|
||||||
GList *p = NULL;
|
|
||||||
int i=0;
|
|
||||||
while ((p = NEXT_TRIP(p))) {
|
|
||||||
struct tm tm;
|
|
||||||
utc_mkdate(DIVE_TRIP(p)->when, &tm);
|
|
||||||
printf("trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u\n", ++i, DIVE_TRIP(p)->location,
|
|
||||||
tm.tm_year + 1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
|
||||||
}
|
|
||||||
printf("-----\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* insert the trip into the dive_trip_list - but ensure you don't have
|
|
||||||
* two trips for the same date; but if you have, make sure you don't
|
|
||||||
* keep the one with less information */
|
|
||||||
static void inline insert_trip(struct dive **trip)
|
|
||||||
{
|
|
||||||
struct dive *dive_trip = *trip;
|
|
||||||
GList *result = FIND_TRIP(&dive_trip->when);
|
|
||||||
if (result) {
|
|
||||||
if (! DIVE_TRIP(result)->location)
|
|
||||||
DIVE_TRIP(result)->location = dive_trip->location;
|
|
||||||
*trip = DIVE_TRIP(result);
|
|
||||||
} else {
|
|
||||||
dive_trip_list = g_list_insert_sorted(dive_trip_list, dive_trip, dive_date_cmp);
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_TRIP
|
|
||||||
dump_trip_list();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void delete_trip(GList *trip)
|
|
||||||
{
|
|
||||||
dive_trip_list = g_list_delete_link(dive_trip_list, trip);
|
|
||||||
#ifdef DEBUG_TRIP
|
|
||||||
dump_trip_list();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* We keep our internal data in well-specified units, but
|
* We keep our internal data in well-specified units, but
|
||||||
* the input and output may come in some random format. This
|
* the input and output may come in some random format. This
|
||||||
|
@ -456,7 +407,7 @@ extern void remember_event(const char *eventname);
|
||||||
extern void evn_foreach(void (*callback)(const char *, int *, void *), void *data);
|
extern void evn_foreach(void (*callback)(const char *, int *, void *), void *data);
|
||||||
|
|
||||||
extern int add_new_dive(struct dive *dive);
|
extern int add_new_dive(struct dive *dive);
|
||||||
extern gboolean edit_trip(struct dive *trip);
|
extern gboolean edit_trip(dive_trip_t *trip);
|
||||||
extern int edit_dive_info(struct dive *dive);
|
extern int edit_dive_info(struct dive *dive);
|
||||||
extern int edit_multi_dive_info(struct dive *single_dive);
|
extern int edit_multi_dive_info(struct dive *single_dive);
|
||||||
extern void dive_list_update_dives(void);
|
extern void dive_list_update_dives(void);
|
||||||
|
|
200
divelist.c
200
divelist.c
|
@ -41,7 +41,10 @@ static struct DiveList dive_list;
|
||||||
GList *dive_trip_list;
|
GList *dive_trip_list;
|
||||||
gboolean autogroup = FALSE;
|
gboolean autogroup = FALSE;
|
||||||
|
|
||||||
const char *tripflag_names[NUM_TRIPFLAGS] = { "TF_NONE", "NOTRIP", "INTRIP" };
|
/* this duplicate assignment of "INTRIP" causes the save_xml code
|
||||||
|
* to convert an ASSIGNED_TRIP (which is temporary in memory) to
|
||||||
|
* a statically assigned trip (INTRIP) in file */
|
||||||
|
const char *tripflag_names[NUM_TRIPFLAGS] = { "TF_NONE", "NOTRIP", "INTRIP", "INTRIP", "AUTOGEN_TRIP" };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The dive list has the dive data in both string format (for showing)
|
* The dive list has the dive data in both string format (for showing)
|
||||||
|
@ -942,19 +945,113 @@ void update_dive_list_col_visibility(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* helper functions for dive_trip handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
static void dump_trip_list(void)
|
||||||
|
{
|
||||||
|
GList *p = NULL;
|
||||||
|
int i=0;
|
||||||
|
timestamp_t last_time = 0;
|
||||||
|
while ((p = NEXT_TRIP(p))) {
|
||||||
|
dive_trip_t *dive_trip = DIVE_TRIP(p);
|
||||||
|
struct tm *tm = gmtime(&dive_trip->when);
|
||||||
|
if (dive_trip->when < last_time)
|
||||||
|
printf("\n\ndive_trip_list OUT OF ORDER!!!\n\n\n");
|
||||||
|
printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u\n",
|
||||||
|
dive_trip->tripflag == AUTOGEN_TRIP ? "autogen " : "",
|
||||||
|
++i, dive_trip->location,
|
||||||
|
tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
|
if (dive_trip->when_from_file && dive_trip->when != dive_trip->when_from_file) {
|
||||||
|
tm = gmtime(&dive_trip->when_from_file);
|
||||||
|
printf("originally on %04u-%02u-%02u %02u:%02u:%02u\n", tm->tm_year + 1900,
|
||||||
|
tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
|
}
|
||||||
|
last_time = dive_trip->when;
|
||||||
|
}
|
||||||
|
printf("-----\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this finds a trip that starts at precisely the time given */
|
||||||
|
static GList *find_trip(timestamp_t when)
|
||||||
|
{
|
||||||
|
GList *trip = dive_trip_list;
|
||||||
|
while (trip && DIVE_TRIP(trip)->when < when)
|
||||||
|
trip = trip->next;
|
||||||
|
if (DIVE_TRIP(trip)->when == when) {
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
struct tm *tm;
|
||||||
|
tm = gmtime(&DIVE_TRIP(trip)->when);
|
||||||
|
printf("found trip @ %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||||
|
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
|
||||||
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
|
#endif
|
||||||
|
return trip;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
printf("no matching trip\n");
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this finds the last trip that at or before the time given */
|
||||||
static GList *find_matching_trip(timestamp_t when)
|
static GList *find_matching_trip(timestamp_t when)
|
||||||
{
|
{
|
||||||
GList *trip = dive_trip_list;
|
GList *trip = dive_trip_list;
|
||||||
if (!trip || DIVE_TRIP(trip)->when > when)
|
if (!trip || DIVE_TRIP(trip)->when > when) {
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
printf("no matching trip\n");
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
while (trip->next && DIVE_TRIP(trip->next)->when <= when)
|
while (trip->next && DIVE_TRIP(trip->next)->when <= when)
|
||||||
trip = trip->next;
|
trip = trip->next;
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
{
|
||||||
|
struct tm *tm;
|
||||||
|
tm = gmtime(&DIVE_TRIP(trip)->when);
|
||||||
|
printf("found trip @ %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||||
|
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
|
||||||
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return trip;
|
return trip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dive *create_and_hookup_trip_from_dive(struct dive *dive)
|
/* insert the trip into the dive_trip_list - but ensure you don't have
|
||||||
|
* two trips for the same date; but if you have, make sure you don't
|
||||||
|
* keep the one with less information */
|
||||||
|
void insert_trip(dive_trip_t **dive_trip_p)
|
||||||
{
|
{
|
||||||
struct dive *dive_trip = alloc_dive();
|
dive_trip_t *dive_trip = *dive_trip_p;
|
||||||
|
GList *trip = dive_trip_list;
|
||||||
|
while (trip && DIVE_TRIP(trip)->when < dive_trip->when)
|
||||||
|
trip = trip->next;
|
||||||
|
if (trip && DIVE_TRIP(trip)->when == dive_trip->when) {
|
||||||
|
if (! DIVE_TRIP(trip)->location)
|
||||||
|
DIVE_TRIP(trip)->location = dive_trip->location;
|
||||||
|
*dive_trip_p = DIVE_TRIP(trip);
|
||||||
|
} else {
|
||||||
|
dive_trip_list = g_list_insert_before(dive_trip_list, trip, *dive_trip_p);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
dump_trip_list();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void delete_trip(GList *trip)
|
||||||
|
{
|
||||||
|
dive_trip_list = g_list_delete_link(dive_trip_list, trip);
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
dump_trip_list();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static dive_trip_t *create_and_hookup_trip_from_dive(struct dive *dive)
|
||||||
|
{
|
||||||
|
dive_trip_t *dive_trip = calloc(sizeof(dive_trip_t),1);
|
||||||
dive_trip->when = dive->when;
|
dive_trip->when = dive->when;
|
||||||
if (dive->location)
|
if (dive->location)
|
||||||
dive_trip->location = strdup(dive->location);
|
dive_trip->location = strdup(dive->location);
|
||||||
|
@ -971,7 +1068,7 @@ static struct dive *create_and_hookup_trip_from_dive(struct dive *dive)
|
||||||
* that starts at when and check on the way that there is no ungrouped
|
* 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
|
* dive and no break beyond the 3 day threshold between dives that
|
||||||
* haven't already been assigned to this trip */
|
* haven't already been assigned to this trip */
|
||||||
static gboolean dive_can_be_in_trip(int idx, struct dive *dive_trip)
|
static gboolean dive_can_be_in_trip(int idx, dive_trip_t *dive_trip)
|
||||||
{
|
{
|
||||||
struct dive *dive, *pdive;
|
struct dive *dive, *pdive;
|
||||||
int i = idx;
|
int i = idx;
|
||||||
|
@ -1012,9 +1109,9 @@ static void fill_dive_list(void)
|
||||||
int i;
|
int i;
|
||||||
GtkTreeIter iter, parent_iter, *parent_ptr = NULL;
|
GtkTreeIter iter, parent_iter, *parent_ptr = NULL;
|
||||||
GtkTreeStore *liststore, *treestore;
|
GtkTreeStore *liststore, *treestore;
|
||||||
struct dive *last_trip = NULL;
|
dive_trip_t *last_trip = NULL;
|
||||||
GList *trip;
|
GList *trip;
|
||||||
struct dive *dive_trip = NULL;
|
dive_trip_t *dive_trip = NULL;
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -1047,25 +1144,42 @@ static void fill_dive_list(void)
|
||||||
dive_trip = NULL;
|
dive_trip = NULL;
|
||||||
} else if (autogroup && DIVE_NEEDS_TRIP(dive)){
|
} else if (autogroup && DIVE_NEEDS_TRIP(dive)){
|
||||||
/* if we already have existing trips there are up to two trips that this
|
/* 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 */
|
* could potentially be part of.
|
||||||
if (! (dive_trip && dive_can_be_in_trip(i, dive_trip))) {
|
* Let's see if there is a matching one already */
|
||||||
/* there could be a better trip in our list already */
|
GList *matching_trip;
|
||||||
trip = find_matching_trip(dive->when);
|
matching_trip = find_matching_trip(dive->when);
|
||||||
if (! (trip && dive_can_be_in_trip(i, DIVE_TRIP(trip)))) {
|
if (matching_trip && dive_can_be_in_trip(i, DIVE_TRIP(matching_trip))) {
|
||||||
|
trip = matching_trip;
|
||||||
|
} else {
|
||||||
|
/* is there a trip we can extend ? */
|
||||||
|
if (! matching_trip && dive_trip) {
|
||||||
|
/* careful - this is before the first trip
|
||||||
|
yet we have a trip we're looking at; make
|
||||||
|
sure that is indeed the first trip */
|
||||||
|
dive_trip = DIVE_TRIP(dive_trip_list);
|
||||||
|
trip = dive_trip_list;
|
||||||
|
}
|
||||||
|
/* maybe we can extend the current trip */
|
||||||
|
if (! (dive_trip && dive_can_be_in_trip(i, dive_trip))) {
|
||||||
/* seems like neither of these trips work, so create
|
/* seems like neither of these trips work, so create
|
||||||
* a new one; all fields default to 0 and get filled
|
* a new one; all fields default to 0 and get filled
|
||||||
* in further down */
|
* in further down */
|
||||||
parent_ptr = NULL;
|
parent_ptr = NULL;
|
||||||
dive_trip = create_and_hookup_trip_from_dive(dive);
|
dive_trip = create_and_hookup_trip_from_dive(dive);
|
||||||
dive_trip->tripflag = IN_TRIP;
|
dive_trip->tripflag = AUTOGEN_TRIP;
|
||||||
trip = FIND_TRIP(&dive_trip->when);
|
trip = find_trip(dive_trip->when);
|
||||||
}
|
}
|
||||||
if (trip)
|
|
||||||
dive_trip = DIVE_TRIP(trip);
|
|
||||||
}
|
}
|
||||||
|
if (trip)
|
||||||
|
dive_trip = DIVE_TRIP(trip);
|
||||||
} else if (DIVE_IN_TRIP(dive)) {
|
} else if (DIVE_IN_TRIP(dive)) {
|
||||||
trip = find_matching_trip(dive->when);
|
trip = find_matching_trip(dive->when);
|
||||||
dive_trip = DIVE_TRIP(trip);
|
if (trip)
|
||||||
|
dive_trip = DIVE_TRIP(trip);
|
||||||
|
else
|
||||||
|
printf ("data seems inconsistent - dive claims to be in dive trip "
|
||||||
|
"yet there appears to be no matching trip\n"
|
||||||
|
"Trying to recover\n");
|
||||||
} else {
|
} else {
|
||||||
/* dive is not in a trip and we aren't autogrouping */
|
/* dive is not in a trip and we aren't autogrouping */
|
||||||
dive_trip = NULL;
|
dive_trip = NULL;
|
||||||
|
@ -1074,7 +1188,8 @@ static void fill_dive_list(void)
|
||||||
/* 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) {
|
||||||
dive->tripflag = IN_TRIP;
|
if(DIVE_NEEDS_TRIP(dive))
|
||||||
|
dive->tripflag = ASSIGNED_TRIP;
|
||||||
dive->divetrip = dive_trip;
|
dive->divetrip = dive_trip;
|
||||||
if (dive_trip->when > dive->when)
|
if (dive_trip->when > dive->when)
|
||||||
dive_trip->when = dive->when;
|
dive_trip->when = dive->when;
|
||||||
|
@ -1123,6 +1238,9 @@ static void fill_dive_list(void)
|
||||||
DIVE_SUIT, dive->suit,
|
DIVE_SUIT, dive->suit,
|
||||||
DIVE_SAC, 0,
|
DIVE_SAC, 0,
|
||||||
-1);
|
-1);
|
||||||
|
#ifdef DEBUG_TRIP
|
||||||
|
dump_trip_list();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure we display the first date of the trip in previous summary */
|
/* make sure we display the first date of the trip in previous summary */
|
||||||
|
@ -1260,12 +1378,12 @@ void edit_trip_cb(GtkWidget *menuitem, GtkTreePath *path)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
timestamp_t when;
|
timestamp_t when;
|
||||||
struct dive *dive_trip;
|
dive_trip_t *dive_trip;
|
||||||
GList *trip;
|
GList *trip;
|
||||||
|
|
||||||
gtk_tree_model_get_iter(MODEL(dive_list), &iter, path);
|
gtk_tree_model_get_iter(MODEL(dive_list), &iter, path);
|
||||||
gtk_tree_model_get(MODEL(dive_list), &iter, DIVE_DATE, &when, -1);
|
gtk_tree_model_get(MODEL(dive_list), &iter, DIVE_DATE, &when, -1);
|
||||||
trip = FIND_TRIP(&when);
|
trip = find_trip(when);
|
||||||
dive_trip = DIVE_TRIP(trip);
|
dive_trip = DIVE_TRIP(trip);
|
||||||
if (edit_trip(dive_trip))
|
if (edit_trip(dive_trip))
|
||||||
gtk_tree_store_set(STORE(dive_list), &iter, DIVE_LOCATION, dive_trip->location, -1);
|
gtk_tree_store_set(STORE(dive_list), &iter, DIVE_LOCATION, dive_trip->location, -1);
|
||||||
|
@ -1336,7 +1454,7 @@ static int copy_tree_node(GtkTreeIter *a, GtkTreeIter *b)
|
||||||
/* to avoid complicated special cases based on ordering or number of children,
|
/* to avoid complicated special cases based on ordering or number of children,
|
||||||
we always take the first and last child and pick the smaller timestamp_t (which
|
we always take the first and last child and pick the smaller timestamp_t (which
|
||||||
works regardless of ordering and also with just one child) */
|
works regardless of ordering and also with just one child) */
|
||||||
static void update_trip_timestamp(GtkTreeIter *parent, struct dive *divetrip)
|
static void update_trip_timestamp(GtkTreeIter *parent, dive_trip_t *divetrip)
|
||||||
{
|
{
|
||||||
GtkTreeIter first_child, last_child;
|
GtkTreeIter first_child, last_child;
|
||||||
int nr;
|
int nr;
|
||||||
|
@ -1366,7 +1484,8 @@ static GtkTreeIter *move_dive_between_trips(GtkTreeIter *dive_iter, GtkTreeIter
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
timestamp_t old_when, new_when;
|
timestamp_t old_when, new_when;
|
||||||
struct dive *dive, *old_divetrip, *new_divetrip;
|
struct dive *dive;
|
||||||
|
dive_trip_t *old_divetrip, *new_divetrip;
|
||||||
GtkTreeIter *new_iter = malloc(sizeof(GtkTreeIter));
|
GtkTreeIter *new_iter = malloc(sizeof(GtkTreeIter));
|
||||||
|
|
||||||
if (before)
|
if (before)
|
||||||
|
@ -1444,6 +1563,7 @@ static void turn_dive_into_trip(GtkTreePath *path)
|
||||||
char *location;
|
char *location;
|
||||||
int idx;
|
int idx;
|
||||||
struct dive *dive;
|
struct dive *dive;
|
||||||
|
dive_trip_t *dive_trip;
|
||||||
|
|
||||||
/* this is a dive on the top level, insert trip AFTER it, populate its date / location, and
|
/* this is a dive on the top level, insert trip AFTER it, populate its date / location, and
|
||||||
* then move the dive below that trip */
|
* then move the dive below that trip */
|
||||||
|
@ -1458,8 +1578,10 @@ static void turn_dive_into_trip(GtkTreePath *path)
|
||||||
treepath = gtk_tree_model_get_path(MODEL(dive_list), newiter);
|
treepath = gtk_tree_model_get_path(MODEL(dive_list), newiter);
|
||||||
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath);
|
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath);
|
||||||
dive = get_dive(idx);
|
dive = get_dive(idx);
|
||||||
/* we don't need the return value - everything is hooked up in the function */
|
/* this trip is intentionally created so it should be treated as if
|
||||||
(void)create_and_hookup_trip_from_dive(dive);
|
* it was read from a file */
|
||||||
|
dive_trip = create_and_hookup_trip_from_dive(dive);
|
||||||
|
dive_trip->when_from_file = dive_trip->when;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we know that path is pointing at a dive in a trip and are asked to split this trip into two */
|
/* we know that path is pointing at a dive in a trip and are asked to split this trip into two */
|
||||||
|
@ -1467,7 +1589,8 @@ static void insert_trip_before(GtkTreePath *path)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter, prev_iter, parent, newparent, nextsibling;
|
GtkTreeIter iter, prev_iter, parent, newparent, nextsibling;
|
||||||
GtkTreePath *treepath, *prev_path;
|
GtkTreePath *treepath, *prev_path;
|
||||||
struct dive *dive, *prev_dive, *new_divetrip;
|
struct dive *dive, *prev_dive;
|
||||||
|
dive_trip_t *new_divetrip;
|
||||||
int idx, nr, i;
|
int idx, nr, i;
|
||||||
|
|
||||||
gtk_tree_model_get_iter(MODEL(dive_list), &iter, path);
|
gtk_tree_model_get_iter(MODEL(dive_list), &iter, path);
|
||||||
|
@ -1506,6 +1629,8 @@ static void insert_trip_before(GtkTreePath *path)
|
||||||
/* we copied the dive we were called with; we are done */
|
/* we copied the dive we were called with; we are done */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* treat this divetrip as if it had been read from a file */
|
||||||
|
new_divetrip->when_from_file = new_divetrip->when;
|
||||||
treepath = gtk_tree_model_get_path(MODEL(dive_list), &newparent);
|
treepath = gtk_tree_model_get_path(MODEL(dive_list), &newparent);
|
||||||
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath);
|
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath);
|
||||||
#ifdef DEBUG_TRIP
|
#ifdef DEBUG_TRIP
|
||||||
|
@ -1564,7 +1689,7 @@ static void remove_from_trip(GtkTreePath *path)
|
||||||
/* if this was the last dive on the trip, remove the trip */
|
/* if this was the last dive on the trip, remove the trip */
|
||||||
if (! gtk_tree_model_iter_has_child(MODEL(dive_list), &parent)) {
|
if (! gtk_tree_model_iter_has_child(MODEL(dive_list), &parent)) {
|
||||||
gtk_tree_store_remove(STORE(dive_list), &parent);
|
gtk_tree_store_remove(STORE(dive_list), &parent);
|
||||||
delete_trip(FIND_TRIP(&dive->divetrip->when));
|
delete_trip(find_trip(dive->divetrip->when));
|
||||||
free(dive->divetrip);
|
free(dive->divetrip);
|
||||||
}
|
}
|
||||||
/* mark the dive as intentionally at the top level */
|
/* mark the dive as intentionally at the top level */
|
||||||
|
@ -1639,7 +1764,8 @@ static void remove_from_trip_cb(GtkWidget *menuitem, GtkTreePath *path)
|
||||||
void remove_trip(GtkTreePath *trippath, gboolean force_no_trip)
|
void remove_trip(GtkTreePath *trippath, gboolean force_no_trip)
|
||||||
{
|
{
|
||||||
GtkTreeIter newiter, parent, child, *lastiter = &parent;
|
GtkTreeIter newiter, parent, child, *lastiter = &parent;
|
||||||
struct dive *dive, *dive_trip = NULL;
|
struct dive *dive;
|
||||||
|
dive_trip_t *dive_trip = NULL;
|
||||||
int idx;
|
int idx;
|
||||||
GtkTreePath *childpath;
|
GtkTreePath *childpath;
|
||||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
|
||||||
|
@ -1672,7 +1798,7 @@ void remove_trip(GtkTreePath *trippath, gboolean force_no_trip)
|
||||||
}
|
}
|
||||||
/* finally, remove the trip */
|
/* finally, remove the trip */
|
||||||
gtk_tree_store_remove(STORE(dive_list), &parent);
|
gtk_tree_store_remove(STORE(dive_list), &parent);
|
||||||
delete_trip(FIND_TRIP(&dive_trip->when));
|
delete_trip(find_trip(dive_trip->when));
|
||||||
free(dive_trip);
|
free(dive_trip);
|
||||||
#ifdef DEBUG_TRIP
|
#ifdef DEBUG_TRIP
|
||||||
dump_trip_list();
|
dump_trip_list();
|
||||||
|
@ -2097,12 +2223,26 @@ void remove_autogen_trips()
|
||||||
while(gtk_tree_model_get_iter(TREEMODEL(dive_list), &iter, path)) {
|
while(gtk_tree_model_get_iter(TREEMODEL(dive_list), &iter, path)) {
|
||||||
gtk_tree_model_get(TREEMODEL(dive_list), &iter, DIVE_INDEX, &idx, DIVE_DATE, &when, -1);
|
gtk_tree_model_get(TREEMODEL(dive_list), &iter, DIVE_INDEX, &idx, DIVE_DATE, &when, -1);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
trip = FIND_TRIP(&when);
|
trip = find_trip(when);
|
||||||
if (DIVE_TRIP(trip)->tripflag == IN_TRIP) { /* this was autogen */
|
if (trip && DIVE_TRIP(trip)->tripflag == AUTOGEN_TRIP) { /* this was autogen */
|
||||||
remove_trip(path, FALSE);
|
remove_trip(path, FALSE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtk_tree_path_next(path);
|
gtk_tree_path_next(path);
|
||||||
}
|
}
|
||||||
|
/* now walk the remaining trips in the dive_trip_list and restore
|
||||||
|
* their original time stamp; we don't do this in the loop above
|
||||||
|
* to ensure that the list stays in chronological order */
|
||||||
|
trip = NULL;
|
||||||
|
while(NEXT_TRIP(trip)) {
|
||||||
|
trip = NEXT_TRIP(trip);
|
||||||
|
DIVE_TRIP(trip)->when = DIVE_TRIP(trip)->when_from_file;
|
||||||
|
}
|
||||||
|
/* finally walk the dives and remove the 'ASSIGNED_TRIP' designator */
|
||||||
|
for (idx = 0; idx < dive_table.nr; idx++) {
|
||||||
|
struct dive *dive = get_dive(idx);
|
||||||
|
if (dive->tripflag == ASSIGNED_TRIP)
|
||||||
|
dive->tripflag = TF_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
8
info.c
8
info.c
|
@ -445,7 +445,7 @@ static void save_dive_info_changes(struct dive *dive, struct dive *master, struc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dive_trip_widget(GtkWidget *box, struct dive *trip, struct dive_info *info)
|
static void dive_trip_widget(GtkWidget *box, dive_trip_t *trip, struct dive_info *info)
|
||||||
{
|
{
|
||||||
GtkWidget *hbox, *label;
|
GtkWidget *hbox, *label;
|
||||||
char buffer[80] = "Edit trip summary";
|
char buffer[80] = "Edit trip summary";
|
||||||
|
@ -537,7 +537,7 @@ void update_equipment_data(struct dive *dive, struct dive *master)
|
||||||
memcpy(dive->weightsystem, master->weightsystem, WS_BYTES);
|
memcpy(dive->weightsystem, master->weightsystem, WS_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean edit_trip(struct dive *trip)
|
gboolean edit_trip(dive_trip_t *trip)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog, *vbox;
|
GtkWidget *dialog, *vbox;
|
||||||
int success;
|
int success;
|
||||||
|
@ -571,10 +571,8 @@ gboolean edit_trip(struct dive *trip)
|
||||||
if (old_text)
|
if (old_text)
|
||||||
g_free(old_text);
|
g_free(old_text);
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed)
|
||||||
mark_divelist_changed(TRUE);
|
mark_divelist_changed(TRUE);
|
||||||
flush_divelist(trip);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gtk_widget_destroy(dialog);
|
gtk_widget_destroy(dialog);
|
||||||
return changed;
|
return changed;
|
||||||
|
|
23
parse-xml.c
23
parse-xml.c
|
@ -156,7 +156,8 @@ const struct units IMPERIAL_units = {
|
||||||
/*
|
/*
|
||||||
* Dive info as it is being built up..
|
* Dive info as it is being built up..
|
||||||
*/
|
*/
|
||||||
static struct dive *cur_dive, *cur_trip = NULL;
|
static struct dive *cur_dive;
|
||||||
|
static dive_trip_t *cur_trip = NULL;
|
||||||
static struct sample *cur_sample;
|
static struct sample *cur_sample;
|
||||||
static struct {
|
static struct {
|
||||||
int active;
|
int active;
|
||||||
|
@ -512,8 +513,10 @@ static void get_tripflag(char *buffer, void *_tf)
|
||||||
|
|
||||||
*tf = TF_NONE;
|
*tf = TF_NONE;
|
||||||
for (i = NO_TRIP; i < NUM_TRIPFLAGS; i++)
|
for (i = NO_TRIP; i < NUM_TRIPFLAGS; i++)
|
||||||
if(! strcmp(buffer, tripflag_names[i]))
|
if(! strcmp(buffer, tripflag_names[i])) {
|
||||||
*tf = i;
|
*tf = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void centibar(char *buffer, void *_pressure)
|
static void centibar(char *buffer, void *_pressure)
|
||||||
|
@ -1122,21 +1125,23 @@ static void try_to_fill_dive(struct dive **divep, const char *name, char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're in the top-level trip xml. Try to convert whatever value to a trip value */
|
/* We're in the top-level trip xml. Try to convert whatever value to a trip value */
|
||||||
static void try_to_fill_trip(struct dive **divep, const char *name, char *buf)
|
static void try_to_fill_trip(dive_trip_t **dive_trip_p, const char *name, char *buf)
|
||||||
{
|
{
|
||||||
int len = strlen(name);
|
int len = strlen(name);
|
||||||
|
|
||||||
start_match("trip", name, buf);
|
start_match("trip", name, buf);
|
||||||
|
|
||||||
struct dive *dive = *divep;
|
dive_trip_t *dive_trip = *dive_trip_p;
|
||||||
|
|
||||||
if (MATCH(".date", divedate, &dive->when))
|
if (MATCH(".date", divedate, &dive_trip->when))
|
||||||
return;
|
return;
|
||||||
if (MATCH(".time", divetime, &dive->when))
|
if (MATCH(".time", divetime, &dive_trip->when)) {
|
||||||
|
dive_trip->when_from_file = dive_trip->when;
|
||||||
return;
|
return;
|
||||||
if (MATCH(".location", utf8_string, &dive->location))
|
}
|
||||||
|
if (MATCH(".location", utf8_string, &dive_trip->location))
|
||||||
return;
|
return;
|
||||||
if (MATCH(".notes", utf8_string, &dive->notes))
|
if (MATCH(".notes", utf8_string, &dive_trip->notes))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nonmatch("trip", name, buf);
|
nonmatch("trip", name, buf);
|
||||||
|
@ -1182,7 +1187,7 @@ static void trip_start(void)
|
||||||
{
|
{
|
||||||
if (cur_trip)
|
if (cur_trip)
|
||||||
return;
|
return;
|
||||||
cur_trip = alloc_dive();
|
cur_trip = calloc(sizeof(dive_trip_t),1);
|
||||||
memset(&cur_tm, 0, sizeof(cur_tm));
|
memset(&cur_tm, 0, sizeof(cur_tm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue