mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 05:00:20 +00:00
Start sanitizing gaschange event information
Decode the gasmix data into a sane format when creating the event, and add the (currently unused) ability to specify a gas change to a particular cylinder rather than (or in addition to) the gasmix. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
b47e0658cf
commit
df4e26c875
8 changed files with 234 additions and 97 deletions
68
dive.c
68
dive.c
|
@ -26,7 +26,31 @@ static const char *default_tags[] = {
|
|||
QT_TRANSLATE_NOOP("gettextFromC", "deco")
|
||||
};
|
||||
|
||||
void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name)
|
||||
int event_is_gaschange(struct event *ev)
|
||||
{
|
||||
return ev->type == SAMPLE_EVENT_GASCHANGE ||
|
||||
ev->type == SAMPLE_EVENT_GASCHANGE2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does the gas mix data match the legacy
|
||||
* libdivecomputer event format? If so,
|
||||
* we can skip saving it, in order to maintain
|
||||
* the old save formats. We'll re-generate the
|
||||
* gas mix when loading.
|
||||
*/
|
||||
int event_gasmix_redundant(struct event *ev)
|
||||
{
|
||||
int value = ev->value;
|
||||
int o2, he;
|
||||
|
||||
o2 = (value & 0xffff) * 10;
|
||||
he = (value >> 16) * 10;
|
||||
return o2 == ev->gas.mix.o2.permille &&
|
||||
he == ev->gas.mix.he.permille;
|
||||
}
|
||||
|
||||
struct event *add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name)
|
||||
{
|
||||
struct event *ev, **p;
|
||||
unsigned int size, len = strlen(name);
|
||||
|
@ -34,7 +58,7 @@ void add_event(struct divecomputer *dc, int time, int type, int flags, int value
|
|||
size = sizeof(*ev) + len + 1;
|
||||
ev = malloc(size);
|
||||
if (!ev)
|
||||
return;
|
||||
return NULL;
|
||||
memset(ev, 0, size);
|
||||
memcpy(ev->name, name, len);
|
||||
ev->time.seconds = time;
|
||||
|
@ -42,6 +66,22 @@ void add_event(struct divecomputer *dc, int time, int type, int flags, int value
|
|||
ev->flags = flags;
|
||||
ev->value = value;
|
||||
|
||||
/*
|
||||
* Expand the events into a sane format. Currently
|
||||
* just gas switches
|
||||
*/
|
||||
switch (type) {
|
||||
case SAMPLE_EVENT_GASCHANGE2:
|
||||
/* High 16 bits are He percentage */
|
||||
ev->gas.mix.he.permille = (value >> 16) * 10;
|
||||
/* Fallthrough */
|
||||
case SAMPLE_EVENT_GASCHANGE:
|
||||
/* Low 16 bits are O2 percentage */
|
||||
ev->gas.mix.o2.permille = (value & 0xffff) * 10;
|
||||
ev->gas.index = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
p = &dc->events;
|
||||
|
||||
/* insert in the sorted list of events */
|
||||
|
@ -50,6 +90,7 @@ void add_event(struct divecomputer *dc, int time, int type, int flags, int value
|
|||
ev->next = *p;
|
||||
*p = ev;
|
||||
remember_event(name);
|
||||
return ev;
|
||||
}
|
||||
|
||||
static int same_event(struct event *a, struct event *b)
|
||||
|
@ -107,14 +148,11 @@ void update_event_name(struct dive *d, struct event *event, char *name)
|
|||
/* this returns a pointer to static variable - so use it right away after calling */
|
||||
struct gasmix *get_gasmix_from_event(struct event *ev)
|
||||
{
|
||||
static struct gasmix g;
|
||||
g.o2.permille = g.he.permille = 0;
|
||||
if (ev && (ev->type == SAMPLE_EVENT_GASCHANGE || ev->type == SAMPLE_EVENT_GASCHANGE2)) {
|
||||
g.o2.permille = 10 * ev->value & 0xffff;
|
||||
if (ev->type == SAMPLE_EVENT_GASCHANGE2)
|
||||
g.he.permille = 10 * (ev->value >> 16);
|
||||
}
|
||||
return &g;
|
||||
static struct gasmix dummy;
|
||||
if (ev && event_is_gaschange(ev))
|
||||
return &ev->gas.mix;
|
||||
|
||||
return &dummy;
|
||||
}
|
||||
|
||||
int get_pressure_units(int mb, const char **units)
|
||||
|
@ -1543,6 +1581,7 @@ static void add_initial_gaschange(struct dive *dive, struct divecomputer *dc)
|
|||
static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, int mapping[])
|
||||
{
|
||||
int i;
|
||||
struct event *ev;
|
||||
|
||||
/* Did the first gas get remapped? Add gas switch event */
|
||||
if (mapping[0] > 0)
|
||||
|
@ -1559,6 +1598,15 @@ static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, int
|
|||
if (sensor >= 0)
|
||||
s->sensor = sensor;
|
||||
}
|
||||
|
||||
/* Remap the gas change indexes */
|
||||
for (ev = dc->events; ev; ev = ev->next) {
|
||||
if (!event_is_gaschange(ev))
|
||||
continue;
|
||||
if (ev->gas.index < 0)
|
||||
continue;
|
||||
ev->gas.index = mapping[ev->gas.index];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
22
dive.h
22
dive.h
|
@ -85,11 +85,29 @@ typedef struct
|
|||
struct event {
|
||||
struct event *next;
|
||||
duration_t time;
|
||||
int type, flags, value;
|
||||
int type;
|
||||
/* This is the annoying libdivecomputer format. */
|
||||
int flags, value;
|
||||
/* .. and this is our "extended" data for some event types */
|
||||
union {
|
||||
/*
|
||||
* Currently only for gas switch events.
|
||||
*
|
||||
* NOTE! The index may be -1, which means "unknown". In that
|
||||
* case, the get_cylinder_index() function will give the best
|
||||
* match with the cylinders in the dive based on gasmix.
|
||||
*/
|
||||
struct {
|
||||
int index;
|
||||
struct gasmix mix;
|
||||
} gas;
|
||||
};
|
||||
bool deleted;
|
||||
char name[];
|
||||
};
|
||||
|
||||
extern int event_is_gaschange(struct event *ev);
|
||||
extern int event_gasmix_redundant(struct event *ev);
|
||||
|
||||
extern int get_pressure_units(int mb, const char **units);
|
||||
extern double get_depth_units(int mm, int *frac, const char **units);
|
||||
|
@ -651,7 +669,7 @@ extern void copy_samples(struct divecomputer *s, struct divecomputer *d);
|
|||
extern bool is_cylinder_used(struct dive *dive, int idx);
|
||||
extern void fill_default_cylinder(cylinder_t *cyl);
|
||||
extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx);
|
||||
extern void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
|
||||
extern struct event *add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
|
||||
extern void remove_event(struct event *event);
|
||||
extern void update_event_name(struct dive *d, struct event* event, char *name);
|
||||
extern void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration);
|
||||
|
|
21
load-git.c
21
load-git.c
|
@ -529,6 +529,13 @@ static void parse_event_keyvalue(void *_event, const char *key, const char *valu
|
|||
event->value = val;
|
||||
} else if (!strcmp(key, "name")) {
|
||||
/* We get the name from the string handling */
|
||||
} else if (!strcmp(key, "cylinder")) {
|
||||
/* NOTE! We add one here as a marker that "yes, we got a cylinder index" */
|
||||
event->gas.index = 1+get_index(value);
|
||||
} else if (!strcmp(key, "o2")) {
|
||||
event->gas.mix.o2 = get_fraction(value);
|
||||
} else if (!strcmp(key, "he")) {
|
||||
event->gas.mix.he = get_fraction(value);
|
||||
} else
|
||||
report_error("Unexpected event key/value pair (%s/%s)", key, value);
|
||||
}
|
||||
|
@ -538,7 +545,7 @@ static void parse_dc_event(char *line, struct membuffer *str, void *_dc)
|
|||
int m, s = 0;
|
||||
const char *name;
|
||||
struct divecomputer *dc = _dc;
|
||||
struct event event = { 0 };
|
||||
struct event event = { 0 }, *ev;
|
||||
|
||||
m = strtol(line, &line, 10);
|
||||
if (*line == ':')
|
||||
|
@ -557,7 +564,17 @@ static void parse_dc_event(char *line, struct membuffer *str, void *_dc)
|
|||
name = "";
|
||||
if (str->len)
|
||||
name = mb_cstring(str);
|
||||
add_event(dc, event.time.seconds, event.type, event.flags, event.value, name);
|
||||
ev = add_event(dc, event.time.seconds, event.type, event.flags, event.value, name);
|
||||
if (ev && event_is_gaschange(ev)) {
|
||||
/*
|
||||
* We subtract one here because "0" is "no index",
|
||||
* and the parsing will add one for actual cylinder
|
||||
* index data (see parse_event_keyvalue)
|
||||
*/
|
||||
ev->gas.index = event.gas.index-1;
|
||||
if (event.gas.mix.o2.permille || event.gas.mix.he.permille)
|
||||
ev->gas.mix = event.gas.mix;
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_trip_date(char *line, struct membuffer *str, void *_trip)
|
||||
|
|
136
parse-xml.c
136
parse-xml.c
|
@ -95,17 +95,17 @@ const struct units IMPERIAL_units = IMPERIAL_UNITS;
|
|||
/*
|
||||
* Dive info as it is being built up..
|
||||
*/
|
||||
#define MAX_EVENT_NAME 128
|
||||
static struct divecomputer *cur_dc;
|
||||
static struct dive *cur_dive;
|
||||
static dive_trip_t *cur_trip = NULL;
|
||||
static struct sample *cur_sample;
|
||||
static struct picture *cur_picture;
|
||||
static struct {
|
||||
int active;
|
||||
duration_t time;
|
||||
int type, flags, value;
|
||||
const char *name;
|
||||
} cur_event;
|
||||
static union {
|
||||
struct event event;
|
||||
char allocation[sizeof(struct event)+MAX_EVENT_NAME];
|
||||
} event_allocation = { .event.deleted = 1 };
|
||||
#define cur_event event_allocation.event
|
||||
static struct {
|
||||
struct {
|
||||
const char *model;
|
||||
|
@ -527,6 +527,15 @@ static void utf8_string(char *buffer, void *_res)
|
|||
*res = strdup(buffer);
|
||||
}
|
||||
|
||||
static void event_name(char *buffer, char *name)
|
||||
{
|
||||
int size = trimspace(buffer);
|
||||
if (size >= MAX_EVENT_NAME)
|
||||
size = MAX_EVENT_NAME-1;
|
||||
memcpy(name, buffer, size);
|
||||
name[size] = 0;
|
||||
}
|
||||
|
||||
/* Extract the dive computer type from the xml text buffer */
|
||||
static void get_dc_type(char *buffer, enum dive_comp_type *i)
|
||||
{
|
||||
|
@ -704,16 +713,22 @@ static void try_to_match_autogroup(const char *name, char *buf)
|
|||
|
||||
void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx)
|
||||
{
|
||||
/* The gas switch event format is insane. It will be fixed, I think */
|
||||
int o2 = get_o2(&dive->cylinder[idx].gasmix);
|
||||
int he = get_he(&dive->cylinder[idx].gasmix);
|
||||
/* The gas switch event format is insane for historical reasons */
|
||||
struct gasmix *mix = &dive->cylinder[idx].gasmix;
|
||||
int o2 = get_o2(mix);
|
||||
int he = get_he(mix);
|
||||
struct event *ev;
|
||||
int value;
|
||||
|
||||
o2 = (o2 + 5) / 10;
|
||||
he = (he + 5) / 10;
|
||||
value = o2 + (he << 16);
|
||||
|
||||
add_event(dc, seconds, he ? SAMPLE_EVENT_GASCHANGE2 : SAMPLE_EVENT_GASCHANGE, 0, value, "gaschange");
|
||||
ev = add_event(dc, seconds, he ? SAMPLE_EVENT_GASCHANGE2 : SAMPLE_EVENT_GASCHANGE, 0, value, "gaschange");
|
||||
if (ev) {
|
||||
ev->gas.index = idx;
|
||||
ev->gas.mix = *mix;
|
||||
}
|
||||
}
|
||||
|
||||
static void get_cylinderindex(char *buffer, uint8_t *i)
|
||||
|
@ -751,9 +766,9 @@ static void try_to_fill_dc_settings(const char *name, char *buf)
|
|||
static void try_to_fill_event(const char *name, char *buf)
|
||||
{
|
||||
start_match("event", name, buf);
|
||||
if (MATCH("event", utf8_string, &cur_event.name))
|
||||
if (MATCH("event", event_name, cur_event.name))
|
||||
return;
|
||||
if (MATCH("name", utf8_string, &cur_event.name))
|
||||
if (MATCH("name", event_name, cur_event.name))
|
||||
return;
|
||||
if (MATCH("time", eventtime, &cur_event.time))
|
||||
return;
|
||||
|
@ -763,6 +778,15 @@ static void try_to_fill_event(const char *name, char *buf)
|
|||
return;
|
||||
if (MATCH("value", get_index, &cur_event.value))
|
||||
return;
|
||||
if (MATCH("cylinder", get_index, &cur_event.gas.index)) {
|
||||
/* We add one to indicate that we got an actual cylinder index value */
|
||||
cur_event.gas.index++;
|
||||
return;
|
||||
}
|
||||
if (MATCH("o2", percent, &cur_event.gas.mix.o2))
|
||||
return;
|
||||
if (MATCH("he", percent, &cur_event.gas.mix.he))
|
||||
return;
|
||||
nonmatch("event", name, buf);
|
||||
}
|
||||
|
||||
|
@ -1332,36 +1356,38 @@ static void trip_end(void)
|
|||
static void event_start(void)
|
||||
{
|
||||
memset(&cur_event, 0, sizeof(cur_event));
|
||||
cur_event.active = 1;
|
||||
cur_event.deleted = 0; /* Active */
|
||||
}
|
||||
|
||||
static void event_end(void)
|
||||
{
|
||||
struct divecomputer *dc = get_dc();
|
||||
if (cur_event.name) {
|
||||
if (strcmp(cur_event.name, "surface") != 0) {
|
||||
/* 123 is a magic event that we used for a while to encode images in dives */
|
||||
if (cur_event.type == 123) {
|
||||
struct picture *pic = alloc_picture();
|
||||
pic->filename = strdup(cur_event.name);
|
||||
/* theoretically this could fail - but we didn't support multi year offsets */
|
||||
pic->offset.seconds = cur_event.time.seconds;
|
||||
dive_add_picture(cur_dive, pic);
|
||||
} else {
|
||||
/* At some point gas change events did not have any type. Thus we need to add
|
||||
* one on import, if we encounter the type one missing.
|
||||
*/
|
||||
if (cur_event.type == 0 && strcmp(cur_event.name, "gaschange") == 0)
|
||||
cur_event.type = cur_event.value >> 16 > 0 ? SAMPLE_EVENT_GASCHANGE2 : SAMPLE_EVENT_GASCHANGE;
|
||||
|
||||
add_event(dc, cur_event.time.seconds,
|
||||
cur_event.type, cur_event.flags,
|
||||
cur_event.value, cur_event.name);
|
||||
if (strcmp(cur_event.name, "surface") != 0) { /* 123 is a magic event that we used for a while to encode images in dives */
|
||||
if (cur_event.type == 123) {
|
||||
struct picture *pic = alloc_picture();
|
||||
pic->filename = strdup(cur_event.name);
|
||||
/* theoretically this could fail - but we didn't support multi year offsets */
|
||||
pic->offset.seconds = cur_event.time.seconds;
|
||||
dive_add_picture(cur_dive, pic);
|
||||
} else {
|
||||
struct event *ev;
|
||||
/* At some point gas change events did not have any type. Thus we need to add
|
||||
* one on import, if we encounter the type one missing.
|
||||
*/
|
||||
if (cur_event.type == 0 && strcmp(cur_event.name, "gaschange") == 0)
|
||||
cur_event.type = cur_event.value >> 16 > 0 ? SAMPLE_EVENT_GASCHANGE2 : SAMPLE_EVENT_GASCHANGE;
|
||||
ev = add_event(dc, cur_event.time.seconds,
|
||||
cur_event.type, cur_event.flags,
|
||||
cur_event.value, cur_event.name);
|
||||
if (ev && event_is_gaschange(ev)) {
|
||||
/* See try_to_fill_event() on why the filled-in index is one too big */
|
||||
ev->gas.index = cur_event.gas.index-1;
|
||||
if (cur_event.gas.mix.o2.permille || cur_event.gas.mix.he.permille)
|
||||
ev->gas.mix = cur_event.gas.mix;
|
||||
}
|
||||
}
|
||||
free((void *)cur_event.name);
|
||||
}
|
||||
cur_event.active = 0;
|
||||
cur_event.deleted = 1; /* No longer active */
|
||||
}
|
||||
|
||||
static void picture_start(void)
|
||||
|
@ -1472,7 +1498,7 @@ static void entry(const char *name, char *buf)
|
|||
try_to_match_autogroup(name, buf);
|
||||
return;
|
||||
}
|
||||
if (cur_event.active) {
|
||||
if (!cur_event.deleted) {
|
||||
try_to_fill_event(name, buf);
|
||||
return;
|
||||
}
|
||||
|
@ -1722,71 +1748,71 @@ extern int dm4_events(void *handle, int columns, char **data, char **column)
|
|||
switch (atoi(data[2])) {
|
||||
case 1:
|
||||
/* 1 Mandatory Safety Stop */
|
||||
cur_event.name = strdup("safety stop (mandatory)");
|
||||
strcpy(cur_event.name, "safety stop (mandatory)");
|
||||
break;
|
||||
case 3:
|
||||
/* 3 Deco */
|
||||
/* What is Subsurface's term for going to
|
||||
* deco? */
|
||||
cur_event.name = strdup("deco");
|
||||
strcpy(cur_event.name, "deco");
|
||||
break;
|
||||
case 4:
|
||||
/* 4 Ascent warning */
|
||||
cur_event.name = strdup("ascent");
|
||||
strcpy(cur_event.name, "ascent");
|
||||
break;
|
||||
case 5:
|
||||
/* 5 Ceiling broken */
|
||||
cur_event.name = strdup("violation");
|
||||
strcpy(cur_event.name, "violation");
|
||||
break;
|
||||
case 6:
|
||||
/* 6 Mandatory safety stop ceiling error */
|
||||
cur_event.name = strdup("violation");
|
||||
strcpy(cur_event.name, "violation");
|
||||
break;
|
||||
case 7:
|
||||
/* 7 Below deco floor */
|
||||
cur_event.name = strdup("below floor");
|
||||
strcpy(cur_event.name, "below floor");
|
||||
break;
|
||||
case 8:
|
||||
/* 8 Dive time alarm */
|
||||
cur_event.name = strdup("divetime");
|
||||
strcpy(cur_event.name, "divetime");
|
||||
break;
|
||||
case 9:
|
||||
/* 9 Depth alarm */
|
||||
cur_event.name = strdup("maxdepth");
|
||||
strcpy(cur_event.name, "maxdepth");
|
||||
break;
|
||||
case 10:
|
||||
/* 10 OLF 80% */
|
||||
case 11:
|
||||
/* 11 OLF 100% */
|
||||
cur_event.name = strdup("OLF");
|
||||
strcpy(cur_event.name, "OLF");
|
||||
break;
|
||||
case 12:
|
||||
/* 12 High pO₂ */
|
||||
cur_event.name = strdup("PO2");
|
||||
strcpy(cur_event.name, "PO2");
|
||||
break;
|
||||
case 13:
|
||||
/* 13 Air time */
|
||||
cur_event.name = strdup("airtime");
|
||||
strcpy(cur_event.name, "airtime");
|
||||
break;
|
||||
case 17:
|
||||
/* 17 Ascent warning */
|
||||
cur_event.name = strdup("ascent");
|
||||
strcpy(cur_event.name, "ascent");
|
||||
break;
|
||||
case 18:
|
||||
/* 18 Ceiling error */
|
||||
cur_event.name = strdup("ceiling");
|
||||
strcpy(cur_event.name, "ceiling");
|
||||
break;
|
||||
case 19:
|
||||
/* 19 Surfaced */
|
||||
cur_event.name = strdup("surface");
|
||||
strcpy(cur_event.name, "surface");
|
||||
break;
|
||||
case 20:
|
||||
/* 20 Deco */
|
||||
cur_event.name = strdup("deco");
|
||||
strcpy(cur_event.name, "deco");
|
||||
break;
|
||||
case 22:
|
||||
/* 22 Mandatory safety stop violation */
|
||||
cur_event.name = strdup("violation");
|
||||
strcpy(cur_event.name, "violation");
|
||||
break;
|
||||
case 257:
|
||||
/* 257 Dive active */
|
||||
|
@ -1796,14 +1822,14 @@ extern int dm4_events(void *handle, int columns, char **data, char **column)
|
|||
case 258:
|
||||
/* 258 Bookmark */
|
||||
if (data[3]) {
|
||||
cur_event.name = strdup("heading");
|
||||
strcpy(cur_event.name, "heading");
|
||||
cur_event.value = atoi(data[3]);
|
||||
} else {
|
||||
cur_event.name = strdup("bookmark");
|
||||
strcpy(cur_event.name, "bookmark");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cur_event.name = strdup("unknown");
|
||||
strcpy(cur_event.name, "unknown");
|
||||
cur_event.value = atoi(data[2]);
|
||||
break;
|
||||
}
|
||||
|
@ -1986,7 +2012,7 @@ extern int shearwater_changes(void *handle, int columns, char **data, char **col
|
|||
if (data[0])
|
||||
cur_event.time.seconds = atoi(data[0]);
|
||||
if (data[1]) {
|
||||
cur_event.name = strdup("gaschange");
|
||||
strcpy(cur_event.name, "gaschange");
|
||||
cur_event.value = atof(data[1]) * 100;
|
||||
}
|
||||
event_end();
|
||||
|
|
22
profile.c
22
profile.c
|
@ -289,6 +289,14 @@ struct plot_info *analyze_plot_info(struct plot_info *pi)
|
|||
return pi;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the event has an explicit cylinder index,
|
||||
* we return that. If it doesn't, we return the best
|
||||
* match based on the gasmix.
|
||||
*
|
||||
* Some dive computers give cylinder indexes, some
|
||||
* give just the gas mix.
|
||||
*/
|
||||
int get_cylinder_index(struct dive *dive, struct event *ev)
|
||||
{
|
||||
int i;
|
||||
|
@ -296,10 +304,9 @@ int get_cylinder_index(struct dive *dive, struct event *ev)
|
|||
int target_o2, target_he;
|
||||
struct gasmix *g;
|
||||
|
||||
/*
|
||||
* Crazy gas change events give us odd encoded o2/he in percent.
|
||||
* Decode into our internal permille format.
|
||||
*/
|
||||
if (ev->gas.index >= 0)
|
||||
return ev->gas.index;
|
||||
|
||||
g = get_gasmix_from_event(ev);
|
||||
target_o2 = get_o2(g);
|
||||
target_he = get_he(g);
|
||||
|
@ -318,13 +325,8 @@ int get_cylinder_index(struct dive *dive, struct event *ev)
|
|||
delta_o2 = get_o2(&cyl->gasmix) - target_o2;
|
||||
delta_he = get_he(&cyl->gasmix) - target_he;
|
||||
distance = delta_o2 * delta_o2;
|
||||
distance += delta_he * delta_he;
|
||||
|
||||
/* Check the event type to figure out if we should care about the he part.
|
||||
* SAMPLE_EVENT_GASCHANGE, aka without he
|
||||
* SAMPLE_EVENT_GASCHANGE2, aka with he
|
||||
*/
|
||||
if (ev->type == SAMPLE_EVENT_GASCHANGE2)
|
||||
distance += delta_he * delta_he;
|
||||
if (distance >= score)
|
||||
continue;
|
||||
score = distance;
|
||||
|
|
|
@ -66,10 +66,10 @@ void DiveEventItem::setupPixmap()
|
|||
setPixmap(EVENT_PIXMAP(":flag"));
|
||||
} else if (strcmp(internalEvent->name, "heading") == 0) {
|
||||
setPixmap(EVENT_PIXMAP(":flag"));
|
||||
} else if (internalEvent->type == SAMPLE_EVENT_GASCHANGE || internalEvent->type == SAMPLE_EVENT_GASCHANGE2) {
|
||||
if (internalEvent->value >> 16)
|
||||
} else if (event_is_gaschange(internalEvent)) {
|
||||
if (internalEvent->gas.mix.he.permille)
|
||||
setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeTrimix"));
|
||||
else if (internalEvent->value == 0)
|
||||
else if (gasmix_is_air(&internalEvent->gas.mix))
|
||||
setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeAir"));
|
||||
else
|
||||
setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeNitrox"));
|
||||
|
@ -86,7 +86,7 @@ void DiveEventItem::setupToolTipString()
|
|||
int value = internalEvent->value;
|
||||
int type = internalEvent->type;
|
||||
if (value) {
|
||||
if (type == SAMPLE_EVENT_GASCHANGE || type == SAMPLE_EVENT_GASCHANGE2) {
|
||||
if (event_is_gaschange(internalEvent)) {
|
||||
QModelIndexList result = dataModel->match(dataModel->index(0, DivePlotDataModel::TIME), Qt::DisplayRole, internalEvent->time.seconds);
|
||||
if (result.isEmpty()) {
|
||||
Q_ASSERT("can't find a spot in the dataModel");
|
||||
|
|
27
save-git.c
27
save-git.c
|
@ -119,6 +119,18 @@ static void save_tags(struct membuffer *b, struct tag_entry *tags)
|
|||
put_string(b, "\n");
|
||||
}
|
||||
|
||||
static void put_gasmix(struct membuffer *b, struct gasmix *mix)
|
||||
{
|
||||
int o2 = mix->o2.permille;
|
||||
int he = mix->he.permille;
|
||||
|
||||
if (o2) {
|
||||
put_format(b, " o2=%u.%u%%", FRACTION(o2, 10));
|
||||
if (he)
|
||||
put_format(b, " he=%u.%u%%", FRACTION(he, 10));
|
||||
}
|
||||
}
|
||||
|
||||
static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
||||
{
|
||||
int i, nr;
|
||||
|
@ -128,8 +140,6 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
|||
cylinder_t *cylinder = dive->cylinder + i;
|
||||
int volume = cylinder->type.size.mliter;
|
||||
const char *description = cylinder->type.description;
|
||||
int o2 = cylinder->gasmix.o2.permille;
|
||||
int he = cylinder->gasmix.he.permille;
|
||||
|
||||
put_string(b, "cylinder");
|
||||
if (volume)
|
||||
|
@ -137,11 +147,7 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
|||
put_pressure(b, cylinder->type.workingpressure, " workpressure=", "bar");
|
||||
show_utf8(b, " description=", description, "");
|
||||
strip_mb(b);
|
||||
if (o2) {
|
||||
put_format(b, " o2=%u.%u%%", FRACTION(o2, 10));
|
||||
if (he)
|
||||
put_format(b, " he=%u.%u%%", FRACTION(he, 10));
|
||||
}
|
||||
put_gasmix(b, &cylinder->gasmix);
|
||||
put_pressure(b, cylinder->start, " start=", "bar");
|
||||
put_pressure(b, cylinder->end, " end=", "bar");
|
||||
put_string(b, "\n");
|
||||
|
@ -292,6 +298,13 @@ static void save_one_event(struct membuffer *b, struct event *ev)
|
|||
show_index(b, ev->flags, "flags=", "");
|
||||
show_index(b, ev->value, "value=", "");
|
||||
show_utf8(b, " name=", ev->name, "");
|
||||
if (event_is_gaschange(ev)) {
|
||||
if (ev->gas.index >= 0) {
|
||||
show_index(b, ev->gas.index, "cylinder=", "");
|
||||
put_gasmix(b, &ev->gas.mix);
|
||||
} else if (!event_gasmix_redundant(ev))
|
||||
put_gasmix(b, &ev->gas.mix);
|
||||
}
|
||||
put_string(b, "\n");
|
||||
}
|
||||
|
||||
|
|
27
save-xml.c
27
save-xml.c
|
@ -148,6 +148,18 @@ static void save_overview(struct membuffer *b, struct dive *dive)
|
|||
show_utf8(b, dive->suit, " <suit>", "</suit>\n", 0);
|
||||
}
|
||||
|
||||
static void put_gasmix(struct membuffer *b, struct gasmix *mix)
|
||||
{
|
||||
int o2 = mix->o2.permille;
|
||||
int he = mix->he.permille;
|
||||
|
||||
if (o2) {
|
||||
put_format(b, " o2='%u.%u%%'", FRACTION(o2, 10));
|
||||
if (he)
|
||||
put_format(b, " he='%u.%u%%'", FRACTION(he, 10));
|
||||
}
|
||||
}
|
||||
|
||||
static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
||||
{
|
||||
int i, nr;
|
||||
|
@ -158,19 +170,13 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
|||
cylinder_t *cylinder = dive->cylinder + i;
|
||||
int volume = cylinder->type.size.mliter;
|
||||
const char *description = cylinder->type.description;
|
||||
int o2 = cylinder->gasmix.o2.permille;
|
||||
int he = cylinder->gasmix.he.permille;
|
||||
|
||||
put_format(b, " <cylinder");
|
||||
if (volume)
|
||||
put_milli(b, " size='", volume, " l'");
|
||||
put_pressure(b, cylinder->type.workingpressure, " workpressure='", " bar'");
|
||||
show_utf8(b, description, " description='", "'", 1);
|
||||
if (o2) {
|
||||
put_format(b, " o2='%u.%u%%'", FRACTION(o2, 10));
|
||||
if (he)
|
||||
put_format(b, " he='%u.%u%%'", FRACTION(he, 10));
|
||||
}
|
||||
put_gasmix(b, &cylinder->gasmix);
|
||||
put_pressure(b, cylinder->start, " start='", " bar'");
|
||||
put_pressure(b, cylinder->end, " end='", " bar'");
|
||||
put_format(b, " />\n");
|
||||
|
@ -261,6 +267,13 @@ static void save_one_event(struct membuffer *b, struct event *ev)
|
|||
show_index(b, ev->flags, "flags='", "'");
|
||||
show_index(b, ev->value, "value='", "'");
|
||||
show_utf8(b, ev->name, " name='", "'", 1);
|
||||
if (event_is_gaschange(ev)) {
|
||||
if (ev->gas.index >= 0) {
|
||||
show_index(b, ev->gas.index, "cylinder='", "'");
|
||||
put_gasmix(b, &ev->gas.mix);
|
||||
} else if (!event_gasmix_redundant(ev))
|
||||
put_gasmix(b, &ev->gas.mix);
|
||||
}
|
||||
put_format(b, " />\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue