aboutsummaryrefslogtreecommitdiffstats
path: root/divelist.c
diff options
context:
space:
mode:
Diffstat (limited to 'divelist.c')
-rw-r--r--divelist.c179
1 files changed, 33 insertions, 146 deletions
diff --git a/divelist.c b/divelist.c
index ab6fee14c..0fac6ea39 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1654,168 +1654,55 @@ static void collapse_all_cb(GtkWidget *menuitem, GtkTreeView *tree_view)
gtk_tree_view_collapse_all(tree_view);
}
-/* copy the node and return the index */
-static int copy_tree_node(GtkTreeIter *a, GtkTreeIter *b)
+static int get_path_index(GtkTreePath *path)
{
- struct dive store_dive;
- int totalweight, idx;
- char *cylinder_text;
- GdkPixbuf *icon;
+ GtkTreeIter iter;
+ int idx;
- gtk_tree_model_get(MODEL(dive_list), a,
- DIVE_INDEX, &idx,
- DIVE_NR, &store_dive.number,
- DIVE_DATE, &store_dive.when,
- DIVE_RATING, &store_dive.rating,
- DIVE_DEPTH, &store_dive.maxdepth,
- DIVE_DURATION, &store_dive.duration,
- DIVE_TEMPERATURE, &store_dive.watertemp.mkelvin,
- DIVE_TOTALWEIGHT, &totalweight,
- DIVE_SUIT, &store_dive.suit,
- DIVE_CYLINDER, &cylinder_text,
- DIVE_SAC, &store_dive.sac,
- DIVE_OTU, &store_dive.otu,
- DIVE_MAXCNS, &store_dive.maxcns,
- DIVE_LOCATION, &store_dive.location,
- DIVE_LOC_ICON, &icon,
- -1);
- gtk_tree_store_set(STORE(dive_list), b,
- DIVE_INDEX, idx,
- DIVE_NR, store_dive.number,
- DIVE_DATE, store_dive.when,
- DIVE_RATING, store_dive.rating,
- DIVE_DEPTH, store_dive.maxdepth,
- DIVE_DURATION, store_dive.duration,
- DIVE_TEMPERATURE, store_dive.watertemp.mkelvin,
- DIVE_TOTALWEIGHT, totalweight,
- DIVE_SUIT, store_dive.suit,
- DIVE_CYLINDER, cylinder_text,
- DIVE_SAC, store_dive.sac,
- DIVE_OTU, store_dive.otu,
- DIVE_MAXCNS, store_dive.maxcns,
- DIVE_LOCATION, store_dive.location,
- DIVE_LOC_ICON, icon,
- -1);
- free(cylinder_text);
- free(store_dive.location);
- free(store_dive.suit);
+ gtk_tree_model_get_iter(MODEL(dive_list), &iter, path);
+ gtk_tree_model_get(MODEL(dive_list), &iter, DIVE_INDEX, &idx, -1);
return idx;
}
-/* to avoid complicated special cases based on ordering or number of children,
- we always take the first and last child and pick the smaller timestamp_t (which
- works regardless of ordering and also with just one child) */
-static void update_trip_timestamp(GtkTreeIter *parent, dive_trip_t *divetrip)
-{
- GtkTreeIter first_child, last_child;
- int nr;
- timestamp_t t1, t2, tnew;
-
- if (gtk_tree_store_iter_depth(STORE(dive_list), parent) != 0 ||
- gtk_tree_model_iter_n_children(MODEL(dive_list), parent) == 0)
- return;
- nr = gtk_tree_model_iter_n_children(MODEL(dive_list), parent);
- gtk_tree_model_iter_nth_child(MODEL(dive_list), &first_child, parent, 0);
- gtk_tree_model_get(MODEL(dive_list), &first_child, DIVE_DATE, &t1, -1);
- gtk_tree_model_iter_nth_child(MODEL(dive_list), &last_child, parent, nr - 1);
- gtk_tree_model_get(MODEL(dive_list), &last_child, DIVE_DATE, &t2, -1);
- tnew = MIN(t1, t2);
- gtk_tree_store_set(STORE(dive_list), parent, DIVE_DATE, tnew, -1);
- if (divetrip)
- divetrip->when = tnew;
-}
-
-/* move dive_iter, which is a child of old_trip (could be NULL) to new_trip (could be NULL);
- * either of the trips being NULL means that this was (or will be) a dive without a trip;
- * update the dive trips (especially the starting times) accordingly
- * maintain the selected status of the dive
- * IMPORTANT - the move needs to keep the tree consistant - so no out of order moving... */
-static GtkTreeIter *move_dive_between_trips(GtkTreeIter *dive_iter, GtkTreeIter *old_trip, GtkTreeIter *new_trip,
- GtkTreeIter *sibling, gboolean before)
+/* Move a top-level dive into the trip above it */
+static void merge_dive_into_trip_above_cb(GtkWidget *menuitem, GtkTreePath *path)
{
int idx;
- timestamp_t old_when, new_when;
struct dive *dive;
- dive_trip_t *old_divetrip, *new_divetrip;
- GtkTreeIter *new_iter = malloc(sizeof(GtkTreeIter));
+ dive_trip_t *trip;
- if (before)
- gtk_tree_store_insert_before(STORE(dive_list), new_iter, new_trip, sibling);
- else
- gtk_tree_store_insert_after(STORE(dive_list), new_iter, new_trip, sibling);
- idx = copy_tree_node(dive_iter, new_iter);
- gtk_tree_model_get(MODEL(dive_list), new_iter, DIVE_INDEX, &idx, -1);
+ idx = get_path_index(path);
dive = get_dive(idx);
- gtk_tree_store_remove(STORE(dive_list), dive_iter);
- if (old_trip) {
- gtk_tree_model_get(MODEL(dive_list), old_trip, DIVE_DATE, &old_when, -1);
- old_divetrip = find_matching_trip(old_when);
- update_trip_timestamp(old_trip, old_divetrip);
- }
- if (new_trip) {
- gtk_tree_model_get(MODEL(dive_list), new_trip, DIVE_DATE, &new_when, -1);
- new_divetrip = dive->divetrip;
- update_trip_timestamp(new_trip, new_divetrip);
- }
- if (dive->selected) {
- GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
- gtk_tree_selection_select_iter(selection, new_iter);
- }
- return new_iter;
-}
-/* this gets called when we are on a top level dive and we know that the previous
- * top level node is a trip; if multiple consecutive dives are selected, they are
- * all merged into the previous trip*/
-static void merge_dive_into_trip_above_cb(GtkWidget *menuitem, GtkTreePath *path)
-{
- int idx;
- GtkTreeIter dive_iter, trip_iter, prev_iter;
- GtkTreePath *trip_path;
- struct dive *dive, *prev_dive;
-
- /* get the path and iter for the trip and the last dive of that trip */
- trip_path = gtk_tree_path_copy(path);
- (void)gtk_tree_path_prev(trip_path);
- gtk_tree_model_get_iter(MODEL(dive_list), &trip_iter, trip_path);
- gtk_tree_model_get_iter(MODEL(dive_list), &dive_iter, path);
- gtk_tree_model_iter_nth_child(MODEL(dive_list), &prev_iter, &trip_iter,
- gtk_tree_model_iter_n_children(MODEL(dive_list), &trip_iter) - 1);
- gtk_tree_model_get(MODEL(dive_list), &dive_iter, DIVE_INDEX, &idx, -1);
- dive = get_dive(idx);
- gtk_tree_model_get(MODEL(dive_list), &prev_iter, DIVE_INDEX, &idx, -1);
- prev_dive = get_dive(idx);
- /* add the dive to the trip */
+ /* Needs to be a dive, and at the top level */
+ if (!dive || dive->divetrip)
+ return;
+
+ /* Find the "trip above". */
for (;;) {
- add_dive_to_trip(dive, prev_dive->divetrip);
- /* we intentionally changed the dive_trip, so update the time
- * stamp that we fall back to when toggling autogroup */
- dive->tripflag = IN_TRIP;
- free(move_dive_between_trips(&dive_iter, NULL, &trip_iter, NULL, TRUE));
- prev_dive = dive;
- /* by merging the dive into the trip above the path now points to the next
- top level entry. If that iter exists, it's also a dive and both this dive
- and that next dive are selected, continue merging dives into the trip */
- if (!gtk_tree_model_get_iter(MODEL(dive_list), &dive_iter, path))
- break;
- gtk_tree_model_get(MODEL(dive_list), &dive_iter, DIVE_INDEX, &idx, -1);
- if (idx < 0)
- break;
- dive = get_dive(idx);
- if (!dive->selected || !prev_dive->selected)
+ if (!gtk_tree_path_prev(path))
+ return;
+ idx = get_path_index(path);
+ trip = find_trip_by_idx(idx);
+ if (trip)
break;
}
- mark_divelist_changed(TRUE);
-}
-static int get_path_index(GtkTreePath *path)
-{
- GtkTreeIter iter;
- int idx;
+ remember_tree_state();
- gtk_tree_model_get_iter(MODEL(dive_list), &iter, path);
- gtk_tree_model_get(MODEL(dive_list), &iter, DIVE_INDEX, &idx, -1);
- return idx;
+ add_dive_to_trip(dive, trip);
+ if (dive->selected) {
+ for_each_dive(idx, dive) {
+ if (!dive->selected)
+ continue;
+ add_dive_to_trip(dive, trip);
+ }
+ }
+
+ trip->expanded = 1;
+ dive_list_update_dives();
+ restore_tree_state();
+ mark_divelist_changed(TRUE);
}
static void insert_trip_before_cb(GtkWidget *menuitem, GtkTreePath *path)