summaryrefslogtreecommitdiffstats
path: root/planner.c
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2013-02-13 15:03:25 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-02-13 23:02:00 -0800
commit0cde0eff103ec8742656c4cb167a0e6245293697 (patch)
tree14c2a60007c6c0c4abfe2ffc23c68eb5e4f0900c /planner.c
parent81603510b20f69247a80ac9e1b60f325b709a039 (diff)
downloadsubsurface-0cde0eff103ec8742656c4cb167a0e6245293697.tar.gz
Rewriting the error handling in planner.c
Printf is not a way to issue warnings and errors. This is a very late addition but seems necessary for a viable release of the planner. This also adds one artificial limit and two warnings: a) no dives deeper than 400m b) warning of potentially very long calculation times for dives longer than 3h (180min) before the ascent and dives deeper than 150m It also creates quite a number of new strings that need to be translated (and marks a few existing ones for translation as well). Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'planner.c')
-rw-r--r--planner.c75
1 files changed, 63 insertions, 12 deletions
diff --git a/planner.c b/planner.c
index 6ae83333c..017031a19 100644
--- a/planner.c
+++ b/planner.c
@@ -18,6 +18,7 @@ int decostoplevels[] = { 0, 3000, 6000, 9000, 12000, 15000, 18000, 21000, 24000,
90000};
double plangflow, plangfhigh;
char *disclaimer;
+GtkWidget *planner, *planner_error_bar, *error_label;
#if DEBUG_PLAN
void dump_plan(struct diveplan *diveplan)
@@ -44,6 +45,43 @@ void dump_plan(struct diveplan *diveplan)
}
#endif
+static void on_error_bar_response(GtkWidget *widget, gint response, gpointer data)
+{
+ if (response == GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy(widget);
+ planner_error_bar = NULL;
+ error_label = NULL;
+ }
+}
+
+static void show_error(const char *fmt, ...)
+{
+ va_list args;
+ GError *error;
+ GtkWidget *box, *container;
+ gboolean bar_is_visible = TRUE;
+
+ va_start(args, fmt);
+ error = g_error_new_valist(g_quark_from_string("subsurface"), DIVE_ERROR_PLAN, fmt, args);
+ va_end(args);
+ if (!planner_error_bar) {
+ planner_error_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+ g_signal_connect(planner_error_bar, "response", G_CALLBACK(on_error_bar_response), NULL);
+ gtk_info_bar_set_message_type(GTK_INFO_BAR(planner_error_bar), GTK_MESSAGE_ERROR);
+ bar_is_visible = FALSE;
+ }
+ container = gtk_info_bar_get_content_area(GTK_INFO_BAR(planner_error_bar));
+ if (error_label)
+ gtk_container_remove(GTK_CONTAINER(container), error_label);
+ error_label = gtk_label_new(error->message);
+ gtk_container_add(GTK_CONTAINER(container), error_label);
+ box = gtk_dialog_get_content_area(GTK_DIALOG(planner));
+ if (!bar_is_visible)
+ gtk_box_pack_start(GTK_BOX(box), planner_error_bar, FALSE, FALSE, 0);
+ gtk_widget_show_all(box);
+}
+
void get_gas_from_events(struct divecomputer *dc, int time, int *o2, int *he)
{
struct event *event = dc->events;
@@ -113,7 +151,7 @@ double tissue_at_end(struct dive *dive, char **cached_datap)
t1 = sample->time.seconds;
get_gas_from_events(&dive->dc, t0, &o2, &he);
if ((gasidx = get_gasidx(dive, o2, he)) == -1) {
- printf("can't find gas %d/%d\n", (o2 + 5) / 10, (he + 5) / 10);
+ show_error(_("Can't find gas %d/%d"), (o2 + 5) / 10, (he + 5) / 10);
gasidx = 0;
}
if (i > 0)
@@ -168,14 +206,14 @@ int add_gas(struct dive *dive, int o2, int he)
return i;
}
if (i == MAX_CYLINDERS) {
- printf("too many cylinders\n");
+ show_error(_("Too many gas mixes"));
return -1;
}
mix->o2.permille = o2;
mix->he.permille = he;
/* since air is stored as 0/0 we need to set a name or an air cylinder
* would be seen as unset (by cylinder_nodata()) */
- cyl->type.description = strdup("Cylinder for planning");
+ cyl->type.description = strdup(_("Cylinder for planning"));
return i;
}
@@ -322,6 +360,8 @@ void add_duration_to_nth_dp(struct diveplan *diveplan, int idx, int duration, gb
duration += pdp->time;
}
dp->time = duration;
+ if (duration > 180 * 60)
+ show_error(_("Warning, extremely long dives can cause long calculation time"));
}
/* this function is ONLY called from the dialog callback - so it
@@ -865,6 +905,9 @@ static int validate_depth(const char *text, int *mm_p)
depth *= 100;
}
*mm_p = depth;
+ /* we don't support extreme depths */
+ if (depth > 400000)
+ return 0;
return 1;
}
@@ -943,7 +986,7 @@ static GtkWidget *add_entry_to_box(GtkWidget *box, const char *label)
return entry;
}
-#define MAX_WAYPOINTS 8
+#define MAX_WAYPOINTS 12
GtkWidget *entry_depth[MAX_WAYPOINTS], *entry_duration[MAX_WAYPOINTS], *entry_gas[MAX_WAYPOINTS], *entry_po2[MAX_WAYPOINTS];
int nr_waypoints = 0;
static GtkListStore *gas_model = NULL;
@@ -1008,7 +1051,7 @@ static void gas_changed_cb(GtkWidget *combo, gpointer data)
if (!validate_gas(gastext, &o2, &he)) {
/* this should never happen as only validated texts should be
* in the dropdown */
- printf("invalid gas for row %d\n",idx);
+ show_error(_("Invalid gas for row %d"),idx);
}
add_gas_to_nth_dp(&diveplan, idx, o2, he);
show_planned_dive();
@@ -1017,16 +1060,22 @@ static void gas_changed_cb(GtkWidget *combo, gpointer data)
static gboolean depth_focus_out_cb(GtkWidget *entry, GdkEvent *event, gpointer data)
{
const char *depthtext;
- int depth;
+ int depth = -1;
int idx = data - NULL;
depthtext = gtk_entry_get_text(GTK_ENTRY(entry));
+
if (validate_depth(depthtext, &depth)) {
+ if (depth > 150000)
+ show_error(_("Warning - planning very deep dives can take excessive amounts of time"));
add_depth_to_nth_dp(&diveplan, idx, depth);
show_planned_dive();
} else {
- /* we need to instead change the color of the input field or something */
- printf("invalid depth for row %d\n", idx);
+ /* it might be better to instead change the color of the input field or something */
+ if (depth == -1)
+ show_error(_("Invalid depth - could not parse \"%s\""), depthtext);
+ else
+ show_error(_("Invalid depth - values deeper than 400m not supported"));
}
return FALSE;
}
@@ -1089,8 +1138,8 @@ static gboolean starttime_focus_out_cb(GtkWidget *entry, GdkEvent * event, gpoin
diveplan.when = cur + starttime;
show_planned_dive();
} else {
- /* we need to instead change the color of the input field or something */
- printf("invalid starttime\n");
+ /* it might be better to instead change the color of the input field or something */
+ show_error(_("Invalid starttime"));
}
return FALSE;
}
@@ -1190,7 +1239,7 @@ static void add_waypoint_cb(GtkButton *button, gpointer _data)
dialog = gtk_widget_get_parent(ovbox);
gtk_widget_show_all(dialog);
} else {
- // some error
+ show_error(_("Too many waypoints"));
}
}
@@ -1207,7 +1256,7 @@ static void add_entry_with_callback(GtkWidget *box, int length, char *label, cha
/* set up the dialog where the user can input their dive plan */
void input_plan()
{
- GtkWidget *planner, *content, *vbox, *hbox, *outervbox, *add_row, *label;
+ GtkWidget *content, *vbox, *hbox, *outervbox, *add_row, *label;
char *bottom_sac, *deco_sac, gflowstring[4], gfhighstring[4];
char *explanationtext = _("<small>Add segments below.\nEach line describes part of the planned dive.\n"
"An entry with depth, time and gas describes a segment that ends "
@@ -1301,5 +1350,7 @@ void input_plan()
}
}
gtk_widget_destroy(planner);
+ planner_error_bar = NULL;
+ error_label = NULL;
set_gf(prefs.gflow, prefs.gfhigh);
}