mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-08 00:16:16 +00:00
Add code to enter SAC rates for dive planning
This just provides the infrastructure to enter the data, nothing is
calculated, yet.
This adds a new get_thousandths() helper function so we can enter
information of the 'mili-' type as decimal values. So things like
"14.5 l/min" or "0.75 cuft/min" are parsed correctly and converted
into a ml value.
In the process of implementing that I also fixed a bug introduced in
commit ab7aecf16e
("Simplify dive planning code") which broke the
get_tenth() function.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
417391a801
commit
189cba7fd2
2 changed files with 94 additions and 8 deletions
4
dive.h
4
dive.h
|
@ -607,7 +607,9 @@ struct divedatapoint {
|
||||||
|
|
||||||
struct diveplan {
|
struct diveplan {
|
||||||
timestamp_t when;
|
timestamp_t when;
|
||||||
int surface_pressure;
|
int surface_pressure; /* mbar */
|
||||||
|
int bottomsac; /* ml/min */
|
||||||
|
int decosac; /* ml/min */
|
||||||
struct divedatapoint *dp;
|
struct divedatapoint *dp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
98
planner.c
98
planner.c
|
@ -523,21 +523,45 @@ static int get_tenths(const char *begin, const char **endp)
|
||||||
char *end;
|
char *end;
|
||||||
int value = strtol(begin, &end, 10);
|
int value = strtol(begin, &end, 10);
|
||||||
|
|
||||||
*endp = end;
|
|
||||||
if (begin == end)
|
if (begin == end)
|
||||||
return -1;
|
return -1;
|
||||||
value *= 10;
|
value *= 10;
|
||||||
|
|
||||||
/* Fraction? We only look at the first digit */
|
/* Fraction? We only look at the first digit */
|
||||||
if (*end == '.') {
|
if (*end == '.') {
|
||||||
++*end;
|
end++;
|
||||||
if (!isdigit(*end))
|
if (!isdigit(*end))
|
||||||
return -1;
|
return -1;
|
||||||
value += *end - '0';
|
value += *end - '0';
|
||||||
do {
|
do {
|
||||||
++*end;
|
end++;
|
||||||
} while (isdigit(*end));
|
} while (isdigit(*end));
|
||||||
}
|
}
|
||||||
|
*endp = end;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_thousandths(const char *begin, const char **endp)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
int value = strtol(begin, &end, 10);
|
||||||
|
|
||||||
|
if (begin == end)
|
||||||
|
return -1;
|
||||||
|
value *= 1000;
|
||||||
|
|
||||||
|
/* now deal with up to three more digits after decimal point */
|
||||||
|
if (*end == '.') {
|
||||||
|
int factor = 100;
|
||||||
|
do {
|
||||||
|
++end;
|
||||||
|
if (!isdigit(*end))
|
||||||
|
break;
|
||||||
|
value += (*end - '0') * factor;
|
||||||
|
factor /= 10;
|
||||||
|
} while (factor);
|
||||||
|
}
|
||||||
|
*endp = end;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,6 +713,42 @@ static int validate_depth(const char *text, int *mm_p)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int validate_volume(const char *text, int *sac)
|
||||||
|
{
|
||||||
|
int volume, imperial;
|
||||||
|
|
||||||
|
if (!text)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
volume = get_thousandths(text, &text);
|
||||||
|
if (volume < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (isspace(*text))
|
||||||
|
text++;
|
||||||
|
|
||||||
|
imperial = get_units()->volume == CUFT;
|
||||||
|
if (*text == 'l') {
|
||||||
|
imperial = 0;
|
||||||
|
text++;
|
||||||
|
} else if (!strncasecmp(text, "cuft", 4)) {
|
||||||
|
imperial = 1;
|
||||||
|
text += 4;
|
||||||
|
}
|
||||||
|
while (isspace(*text) || *text == '/')
|
||||||
|
text++;
|
||||||
|
if (!strncasecmp(text, "min", 3))
|
||||||
|
text += 3;
|
||||||
|
while (isspace(*text))
|
||||||
|
text++;
|
||||||
|
if (*text)
|
||||||
|
return 0;
|
||||||
|
if (imperial)
|
||||||
|
volume = cuft_to_l(volume) + 0.5; /* correct for mcuft -> ml */
|
||||||
|
*sac = volume;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static GtkWidget *add_entry_to_box(GtkWidget *box, const char *label)
|
static GtkWidget *add_entry_to_box(GtkWidget *box, const char *label)
|
||||||
{
|
{
|
||||||
GtkWidget *entry, *frame;
|
GtkWidget *entry, *frame;
|
||||||
|
@ -844,6 +904,16 @@ static gboolean surfpres_focus_out_cb(GtkWidget *entry, GdkEvent * event, gpoint
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean sac_focus_out_cb(GtkWidget *entry, GdkEvent * event, gpointer data)
|
||||||
|
{
|
||||||
|
const char *sactext;
|
||||||
|
|
||||||
|
sactext = gtk_entry_get_text(GTK_ENTRY(entry));
|
||||||
|
if (validate_volume(sactext, data))
|
||||||
|
show_planned_dive();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static GtkWidget *add_gas_combobox_to_box(GtkWidget *box, const char *label, int idx)
|
static GtkWidget *add_gas_combobox_to_box(GtkWidget *box, const char *label, int idx)
|
||||||
{
|
{
|
||||||
GtkWidget *frame, *combo;
|
GtkWidget *frame, *combo;
|
||||||
|
@ -917,19 +987,20 @@ static void add_waypoint_cb(GtkButton *button, gpointer _data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_entry_with_callback(GtkWidget *box, int length, char *label, char *initialtext,
|
static void add_entry_with_callback(GtkWidget *box, int length, char *label, char *initialtext,
|
||||||
gboolean (*callback)(GtkWidget *, GdkEvent *, gpointer ))
|
gboolean (*callback)(GtkWidget *, GdkEvent *, gpointer ), gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget *entry = add_entry_to_box(box, label);
|
GtkWidget *entry = add_entry_to_box(box, label);
|
||||||
gtk_entry_set_max_length(GTK_ENTRY(entry), length);
|
gtk_entry_set_max_length(GTK_ENTRY(entry), length);
|
||||||
gtk_entry_set_text(GTK_ENTRY(entry), initialtext);
|
gtk_entry_set_text(GTK_ENTRY(entry), initialtext);
|
||||||
gtk_widget_add_events(entry, GDK_FOCUS_CHANGE_MASK);
|
gtk_widget_add_events(entry, GDK_FOCUS_CHANGE_MASK);
|
||||||
g_signal_connect(entry, "focus-out-event", G_CALLBACK(callback), NULL);
|
g_signal_connect(entry, "focus-out-event", G_CALLBACK(callback), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set up the dialog where the user can input their dive plan */
|
/* set up the dialog where the user can input their dive plan */
|
||||||
void input_plan()
|
void input_plan()
|
||||||
{
|
{
|
||||||
GtkWidget *planner, *content, *vbox, *hbox, *outervbox, *add_row, *label;
|
GtkWidget *planner, *content, *vbox, *hbox, *outervbox, *add_row, *label;
|
||||||
|
char *bottom_sac, *deco_sac;
|
||||||
|
|
||||||
if (diveplan.dp)
|
if (diveplan.dp)
|
||||||
free_dps(diveplan.dp);
|
free_dps(diveplan.dp);
|
||||||
|
@ -959,8 +1030,21 @@ void input_plan()
|
||||||
gtk_box_pack_start(GTK_BOX(outervbox), vbox, TRUE, TRUE, 0);
|
gtk_box_pack_start(GTK_BOX(outervbox), vbox, TRUE, TRUE, 0);
|
||||||
hbox = gtk_hbox_new(FALSE, 0);
|
hbox = gtk_hbox_new(FALSE, 0);
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
|
||||||
add_entry_with_callback(hbox, 12, _("Dive starts when?"), "+60:00", starttime_focus_out_cb);
|
add_entry_with_callback(hbox, 12, _("Dive starts when?"), "+60:00", starttime_focus_out_cb, NULL);
|
||||||
add_entry_with_callback(hbox, 12, _("Surface Pressure (mbar)"), SURFACE_PRESSURE_STRING, surfpres_focus_out_cb);
|
add_entry_with_callback(hbox, 12, _("Surface Pressure (mbar)"), SURFACE_PRESSURE_STRING, surfpres_focus_out_cb, NULL);
|
||||||
|
if (get_units()->volume == CUFT) {
|
||||||
|
bottom_sac = "0.7 cuft/min";
|
||||||
|
deco_sac = "0.6 cuft/min";
|
||||||
|
diveplan.bottomsac = 1000 * cuft_to_l(0.7);
|
||||||
|
diveplan.decosac = 1000 * cuft_to_l(0.6);
|
||||||
|
} else {
|
||||||
|
bottom_sac = "20 l/min";
|
||||||
|
deco_sac = "17 l/min";
|
||||||
|
diveplan.bottomsac = 20000;
|
||||||
|
diveplan.decosac = 17000;
|
||||||
|
}
|
||||||
|
add_entry_with_callback(hbox, 12, _("SAC during dive"), bottom_sac, sac_focus_out_cb, &diveplan.bottomsac);
|
||||||
|
add_entry_with_callback(hbox, 12, _("SAC during decostop"), deco_sac, sac_focus_out_cb, &diveplan.decosac);
|
||||||
|
|
||||||
diveplan.when = current_time_notz() + 3600;
|
diveplan.when = current_time_notz() + 3600;
|
||||||
diveplan.surface_pressure = SURFACE_PRESSURE;
|
diveplan.surface_pressure = SURFACE_PRESSURE;
|
||||||
|
|
Loading…
Add table
Reference in a new issue