summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2012-09-11 13:37:06 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-09-11 13:37:06 -0700
commit41d3a11ee3d793e7a20a85baf66c18b3dca431a4 (patch)
tree3ed1fd27093cd1aaf63a044d1908c37e9cbd2e4b
parent0fceb1c9070eb2b1c65f26e665d49ee54cc4e17e (diff)
downloadsubsurface-41d3a11ee3d793e7a20a85baf66c18b3dca431a4.tar.gz
Fix a long standing bug when editing dives
Calling edit from the context menu creates a combined editing widget that contains both dive info and equipment. When editing cylinders or weightsystems from that widget and confirming those edits with OK those changes were already committed to the current_dive - regardless on which dive the user clicked. Worse, even when the user clicked Cancel in the edit widget, any changes to the equipment stayed in effect. This had especially confusing consequences when editing multiple dives. As a workaround this commit adds a global edit_dive variable. This fake dive is edited by the secondary editing widgets and if the user accepts changes with OK then they are copied over to the current dive (or all selected dives in multi dive editing mode). Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.h4
-rw-r--r--equipment.c37
-rw-r--r--info.c28
3 files changed, 47 insertions, 22 deletions
diff --git a/dive.h b/dive.h
index e45d962ff..1fb0870aa 100644
--- a/dive.h
+++ b/dive.h
@@ -262,6 +262,10 @@ struct dive {
struct sample sample[];
};
+/* this is a global spot for a temporary dive structure that we use to
+ * be able to edit a dive without unintended side effects */
+extern struct dive edit_dive;
+
extern GList *dive_trip_list;
extern gboolean autogroup;
/* random threashold: three days without diving -> new trip
diff --git a/equipment.c b/equipment.c
index d676fc05d..89e95ef59 100644
--- a/equipment.c
+++ b/equipment.c
@@ -46,6 +46,7 @@ struct equipment_list {
static struct equipment_list cylinder_list[2], weightsystem_list[2];
+struct dive edit_dive;
struct cylinder_widget {
int index, changed;
@@ -1047,7 +1048,7 @@ static void ws_widget(GtkWidget *vbox, struct ws_widget *ws_widget, GtkListStore
ws_widget->weight = GTK_SPIN_BUTTON(widget);
}
-static int edit_cylinder_dialog(int index, cylinder_t *cyl)
+static int edit_cylinder_dialog(int index, cylinder_t *cyl, int w_idx)
{
int success;
GtkWidget *dialog, *vbox;
@@ -1057,7 +1058,10 @@ static int edit_cylinder_dialog(int index, cylinder_t *cyl)
cylinder.index = index;
cylinder.changed = 0;
- dive = current_dive;
+ if (w_idx == W_IDX_PRIMARY)
+ dive = current_dive;
+ else
+ dive = &edit_dive;
if (!dive)
return 0;
*cyl = dive->cylinder[index];
@@ -1079,9 +1083,11 @@ static int edit_cylinder_dialog(int index, cylinder_t *cyl)
if (success) {
record_cylinder_changes(cyl, &cylinder);
dive->cylinder[index] = *cyl;
- mark_divelist_changed(TRUE);
- update_cylinder_related_info(dive);
- flush_divelist(dive);
+ if (w_idx == W_IDX_PRIMARY) {
+ mark_divelist_changed(TRUE);
+ update_cylinder_related_info(dive);
+ flush_divelist(dive);
+ }
}
gtk_widget_destroy(dialog);
@@ -1089,7 +1095,7 @@ static int edit_cylinder_dialog(int index, cylinder_t *cyl)
return success;
}
-static int edit_weightsystem_dialog(int index, weightsystem_t *ws)
+static int edit_weightsystem_dialog(int index, weightsystem_t *ws, int w_idx)
{
int success;
GtkWidget *dialog, *vbox;
@@ -1099,7 +1105,10 @@ static int edit_weightsystem_dialog(int index, weightsystem_t *ws)
weightsystem_widget.index = index;
weightsystem_widget.changed = 0;
- dive = current_dive;
+ if (w_idx == W_IDX_PRIMARY)
+ dive = current_dive;
+ else
+ dive = &edit_dive;
if (!dive)
return 0;
*ws = dive->weightsystem[index];
@@ -1121,8 +1130,10 @@ static int edit_weightsystem_dialog(int index, weightsystem_t *ws)
if (success) {
record_weightsystem_changes(ws, &weightsystem_widget);
dive->weightsystem[index] = *ws;
- mark_divelist_changed(TRUE);
- flush_divelist(dive);
+ if (w_idx == W_IDX_PRIMARY) {
+ mark_divelist_changed(TRUE);
+ flush_divelist(dive);
+ }
}
gtk_widget_destroy(dialog);
@@ -1158,7 +1169,7 @@ static void edit_cb(GtkButton *button, int w_idx)
return;
index = get_model_index(model, &iter);
- if (!edit_cylinder_dialog(index, &cyl))
+ if (!edit_cylinder_dialog(index, &cyl, w_idx))
return;
set_one_cylinder(&cyl, model, &iter);
@@ -1174,7 +1185,7 @@ static void add_cb(GtkButton *button, int w_idx)
GtkTreeSelection *selection;
cylinder_t cyl;
- if (!edit_cylinder_dialog(index, &cyl))
+ if (!edit_cylinder_dialog(index, &cyl, w_idx))
return;
gtk_list_store_append(model, &iter);
@@ -1241,7 +1252,7 @@ static void ws_edit_cb(GtkButton *button, int w_idx)
return;
index = get_model_index(model, &iter);
- if (!edit_weightsystem_dialog(index, &ws))
+ if (!edit_weightsystem_dialog(index, &ws, w_idx))
return;
set_one_weightsystem(&ws, model, &iter);
@@ -1257,7 +1268,7 @@ static void ws_add_cb(GtkButton *button, int w_idx)
GtkTreeSelection *selection;
weightsystem_t ws;
- if (!edit_weightsystem_dialog(index, &ws))
+ if (!edit_weightsystem_dialog(index, &ws, w_idx))
return;
gtk_list_store_append(model, &iter);
diff --git a/info.c b/info.c
index 3efb40cf8..e9cd3c812 100644
--- a/info.c
+++ b/info.c
@@ -481,7 +481,7 @@ static weightsystem_t remember_ws[MAX_WEIGHTSYSTEMS];
#define CYL_BYTES sizeof(cylinder_t) * MAX_CYLINDERS
#define WS_BYTES sizeof(weightsystem_t) * MAX_WEIGHTSYSTEMS
-void save_equipment_data(struct dive *dive)
+static void save_equipment_data(struct dive *dive)
{
if (dive) {
memcpy(remember_cyl, dive->cylinder, CYL_BYTES);
@@ -583,13 +583,19 @@ int edit_multi_dive_info(struct dive *single_dive)
}
}
}
-
- dive_info_widget(vbox, master, &info, multi);
- show_dive_equipment(master, W_IDX_SECONDARY);
- save_equipment_data(master);
+ /* edit a temporary copy of the master dive;
+ * edit_dive is a global dive structure that is modified by the
+ * cylinder / weightsystem dialogs if we open W_IDX_SECONDARY
+ * edit widgets as we do here */
+ memcpy(&edit_dive, master, sizeof(struct dive));
+
+ dive_info_widget(vbox, &edit_dive, &info, multi);
+ show_dive_equipment(&edit_dive, W_IDX_SECONDARY);
+ save_equipment_data(&edit_dive);
gtk_widget_show_all(dialog);
success = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT;
if (success) {
+ mark_divelist_changed(TRUE);
/* Update the non-current selected dives first */
if (!single_dive) {
int i;
@@ -599,19 +605,23 @@ int edit_multi_dive_info(struct dive *single_dive)
if (dive == master || !dive->selected)
continue;
/* copy all "info" fields */
- save_dive_info_changes(dive, master, &info);
+ save_dive_info_changes(dive, &edit_dive, &info);
/* copy the cylinders / weightsystems */
- update_equipment_data(dive, master);
+ update_equipment_data(dive, &edit_dive);
/* this is extremely inefficient... it loops through all
dives to find the right one - but we KNOW the index already */
+ update_cylinder_related_info(dive);
flush_divelist(dive);
}
}
/* Update the master dive last! */
- save_dive_info_changes(master, master, &info);
- update_equipment_data(master, master);
+ save_dive_info_changes(master, &edit_dive, &info);
+ update_equipment_data(master, &edit_dive);
+ update_cylinder_related_info(master);
flush_divelist(master);
+ process_selected_dives();
+ update_dive(master);
}
gtk_widget_destroy(dialog);