diff options
author | Lubomir I. Ivanov <neolit123@gmail.com> | 2012-09-23 16:28:23 +0300 |
---|---|---|
committer | Lubomir I. Ivanov <neolit123@gmail.com> | 2012-09-24 03:41:18 +0300 |
commit | 9036f3f80e32dc72280e6b9f6ff4560171210331 (patch) | |
tree | 45b22f88efa0352312c0f9c49918d927425e6a9b /divelist.c | |
parent | 4d9abf6e8ee465728d1ff1308e18265557dbca42 (diff) | |
download | subsurface-9036f3f80e32dc72280e6b9f6ff4560171210331.tar.gz |
Update the trip's "when" flag after deleting a dive from it
Both gtk_tree_selection_selected_foreach() and
gtk_tree_selection_get_selected_rows() are problematic.
gtk_tree_selection_get_selected_rows is not compatible with older GTK,
while gtk_tree_selection_selected_foreach() should not be used to
modify the tree. A workaround to is allocate memory and store what
is returned from the gtk_tree_selection_selected_foreach() callback
function as a GtkTreeIter array. Once done iterate trought the array
and pass the values to delete_single_dive().
A bit excesive, but it is not certain how safe is modifying the tree
while in the "_foreach" loop, even if it only shows a warning.
On the other hand the GTK source shows gtk_tree_selection_get_selected_rows()
to be a rather complicated and slow method.
Inside delete_single_dive(), once a dive is no longer part of "dive_table"
and if the dive was part of a trip, remove the dive from the tree
(gtk_tree_store_remove()) and call update_trip_timestamp().
The struct type "tree_selected_st" and tree_selected_foreach() are
reusable.
Reported-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Diffstat (limited to 'divelist.c')
-rw-r--r-- | divelist.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/divelist.c b/divelist.c index b9fe927d6..ce9796d82 100644 --- a/divelist.c +++ b/divelist.c @@ -1847,6 +1847,7 @@ static void delete_single_dive(GtkTreeIter *iter) { int i, idx; struct dive *dive, *pdive, *ndive; + GtkTreeIter parent; gtk_tree_model_get(MODEL(dive_list), iter, DIVE_INDEX, &idx, -1); dive = get_dive(idx); @@ -1865,8 +1866,10 @@ static void delete_single_dive(GtkTreeIter *iter) GList *trip = find_matching_trip(dive->when); delete_trip(trip); free(dive->divetrip); + dive->divetrip = NULL; } } + /* simply remove the dive and recreate the divelist * (we can't just manipulate the tree_view as the indices for dives change) */ for (i = idx; i < dive_table.nr - 1; i++) @@ -1874,22 +1877,48 @@ static void delete_single_dive(GtkTreeIter *iter) dive_table.nr--; if (dive->selected) amount_selected--; + + /* once the dive is deleted, update the 'when' flag of the trip it was part of + * to the 'when' flag of the earliest dive left in the same trip */ + if (dive->divetrip) { + gtk_tree_model_iter_parent(MODEL(dive_list), &parent, iter); + gtk_tree_store_remove(STORE(dive_list), iter); + update_trip_timestamp(&parent, dive->divetrip); + } + free(dive); } -/* much simpler to use compared to gtk_tree_selection_get_selected_rows() */ -static void delete_selected_foreach(GtkTreeModel *model, GtkTreePath *path, - GtkTreeIter *iter, gpointer userdata) +/* workaround for not using gtk_tree_selection_get_selected_rows() or modifying the tree + * directly from the gtk_tree_selection_selected_foreach() callback function */ +struct tree_selected_st { + GtkTreeIter *list; + int total; +}; + +static void tree_selected_foreach(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer userdata) { - delete_single_dive(iter); + struct tree_selected_st *st = (struct tree_selected_st *)userdata; + + st->total++; + st->list = (GtkTreeIter *)realloc(st->list, sizeof(GtkTreeIter) * st->total); + memcpy(&st->list[st->total - 1], iter, sizeof(GtkTreeIter)); } /* called when multiple dives are selected and one of these is right-clicked for delete */ static void delete_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path) { + int i; GtkTreeView *tree_view = GTK_TREE_VIEW(dive_list.tree_view); GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); - gtk_tree_selection_selected_foreach(selection, delete_selected_foreach, NULL); + struct tree_selected_st st = {NULL, 0}; + + gtk_tree_selection_selected_foreach(selection, tree_selected_foreach, &st); + + for (i = 0; i < st.total; i++) + delete_single_dive(&st.list[i]); + free(st.list); dive_list_update_dives(); mark_divelist_changed(TRUE); |