diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2013-03-17 18:07:59 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-03-17 20:04:25 -0700 |
commit | 8a5792d473bb30a6f5cbfd2168c4427c16436031 (patch) | |
tree | 58ec7fcb24aec27de5c7b4d2511478ed6550c1b1 | |
parent | bfa37c3cac22949323bb6a5dfb23557638d20757 (diff) | |
download | subsurface-8a5792d473bb30a6f5cbfd2168c4427c16436031.tar.gz |
Manually add gas changes to a dive
Create a little widget that lists all the gases / tanks we know about and
allow the user to pick one of them.
Turns out that add_event only added events at the end of the list - but we
treat that list as chronologically sorted. So I fixed that little
mis-feature as well.
This does raise the question whether we need the inverse operation
(removing a gas change). And if there are other things that we should be
able to manually edit, now that we have the infrastructure for this neat
little context menu...
See #60 -- this doesn't address all of the issues mentioned there, but at
least deals with the 'headline' of the feature request...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | display-gtk.h | 2 | ||||
-rw-r--r-- | dive.c | 6 | ||||
-rw-r--r-- | dive.h | 12 | ||||
-rw-r--r-- | equipment.c | 63 | ||||
-rw-r--r-- | gtk-gui.c | 11 | ||||
-rw-r--r-- | planner.c | 2 |
6 files changed, 91 insertions, 5 deletions
diff --git a/display-gtk.h b/display-gtk.h index fb7eaf254..498fceda5 100644 --- a/display-gtk.h +++ b/display-gtk.h @@ -61,7 +61,7 @@ extern GtkWidget *extended_dive_info_widget(void); extern GtkWidget *equipment_widget(int w_idx); extern GtkWidget *single_stats_widget(void); extern GtkWidget *total_stats_widget(void); - +extern int select_cylinder(struct dive *dive, int when); extern GtkWidget *dive_list_create(void); extern void dive_list_destroy(void); extern void info_widget_destroy(void); @@ -21,11 +21,13 @@ void add_event(struct divecomputer *dc, int time, int type, int flags, int value ev->type = type; ev->flags = flags; ev->value = value; - ev->next = NULL; p = &dc->events; - while (*p) + + /* insert in the sorted list of events */ + while (*p && (*p)->time.seconds < time) p = &(*p)->next; + ev->next = *p; *p = ev; remember_event(name); } @@ -471,6 +471,7 @@ extern struct dive_table dive_table; extern int selected_dive; #define current_dive (get_dive(selected_dive)) +#define current_dc (get_dive_dc(current_dive, dc_number)) static inline struct dive *get_gps_location(int nr, struct dive_table *table) { @@ -486,6 +487,16 @@ static inline struct dive *get_dive(int nr) return dive_table.dives[nr]; } +static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr) +{ + struct divecomputer *dc = NULL; + if (nr >= 0) + dc = &dive->dc; + while (nr-- > 0) + dc = dc->next; + return dc; +} + /* * Iterate over each dive, with the first parameter being the index * iterator variable, and the second one being the dive one. @@ -670,6 +681,7 @@ void add_duration_to_nth_dp(struct diveplan *diveplan, int idx, int duration, gb void add_depth_to_nth_dp(struct diveplan *diveplan, int idx, int depth); void add_gas_to_nth_dp(struct diveplan *diveplan, int idx, int o2, int he); void free_dps(struct divedatapoint *dp); +void get_gas_string(int o2, int he, char *buf, int len); #ifdef DEBUGFILE extern char *debugfilename; diff --git a/equipment.c b/equipment.c index e7f11251f..2d90f7a52 100644 --- a/equipment.c +++ b/equipment.c @@ -605,6 +605,69 @@ void show_dive_equipment(struct dive *dive, int w_idx) &ws_ptr, &weightsystem_none, &set_one_weightsystem); } +int select_cylinder(struct dive *dive, int when) +{ + GtkWidget *dialog, *vbox, *label; + GtkWidget *buttons[MAX_CYLINDERS] = { NULL, }; + GSList *group = NULL; + int i, success, nr, selected = -1; + char buffer[256]; + + nr = MAX_CYLINDERS - 1; + while (nr >= 0 && cylinder_nodata(cyl_ptr(dive, nr))) + nr--; + + if (nr == -1) { + dialog = gtk_dialog_new_with_buttons(_("Cannot add gas change"), + GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + label = gtk_label_new(_("No cylinders listed for this dive.")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + gtk_widget_show_all(dialog); + success = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT; + goto bail; + } + snprintf(buffer, sizeof(buffer), _("Add gaschange event at %d:%02u"), FRACTION(when, 60)); + dialog = gtk_dialog_new_with_buttons(buffer, + GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + NULL); + + vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + label = gtk_label_new(_("Available gases")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + for (i = 0; i <= nr; i++) { + char gas_buf[80]; + cylinder_t *cyl = cyl_ptr(dive, i); + get_gas_string(cyl->gasmix.o2.permille, cyl->gasmix.he.permille, gas_buf, sizeof(gas_buf)); + snprintf(buffer, sizeof(buffer), "%s: %s", + dive->cylinder[i].type.description ?: _("unknown"), gas_buf); + buttons[i] = gtk_radio_button_new_with_label(group, buffer); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(buttons[i])); + gtk_box_pack_start(GTK_BOX(vbox), buttons[i], FALSE, FALSE, 0); + } + gtk_widget_show_all(dialog); + success = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT; + if (success) { + for (i = 0; i <= nr; i++) + if (buttons[i] && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[i]))) + selected = i; + } + for (i = 0; i <= nr; i++) + if (buttons[i]) + gtk_widget_destroy(buttons[i]); +bail: + gtk_widget_destroy(dialog); + + return selected; + +} + static GtkWidget *create_spinbutton(GtkWidget *vbox, const char *name, double min, double max, double incr) { GtkWidget *frame, *hbox, *button; @@ -1962,7 +1962,16 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer static void add_gas_change_cb(GtkWidget *menuitem, gpointer data) { double *x = data; - printf("x = %d:%02u\n", FRACTION(x_to_time(*x), 60)); + int when = x_to_time(*x); + int cylnr = select_cylinder(current_dive, when); + if (cylnr >= 0) { + cylinder_t *cyl = ¤t_dive->cylinder[cylnr]; + int value = cyl->gasmix.o2.permille / 10 | ((cyl->gasmix.he.permille / 10) << 16); + add_event(current_dc, when, 25, 0, value, "gaschange"); + mark_divelist_changed(TRUE); + report_dives(FALSE, FALSE); + dive_list_update_dives(); + } } static void popup_profile_menu(GtkWidget *widget, GdkEventButton *event) @@ -121,7 +121,7 @@ static int get_gasidx(struct dive *dive, int o2, int he) return -1; } -static void get_gas_string(int o2, int he, char *text, int len) +void get_gas_string(int o2, int he, char *text, int len) { if (is_air(o2, he)) snprintf(text, len, _("air")); |