summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.c9
-rw-r--r--dive.h3
-rw-r--r--divelist.c69
-rw-r--r--main.c8
4 files changed, 77 insertions, 12 deletions
diff --git a/dive.c b/dive.c
index 16939de62..f7c5d99c6 100644
--- a/dive.c
+++ b/dive.c
@@ -811,15 +811,13 @@ static void merge_equipment(struct dive *res, struct dive *a, struct dive *b)
* The 'next' dive is not involved in the dive merging, but is the dive
* that will be the next dive after the merged dive.
*/
-static void pick_and_delete_trip(struct dive *res, struct dive *pick, struct dive *remove)
+static void pick_trip(struct dive *res, struct dive *pick)
{
tripflag_t tripflag = pick->tripflag;
dive_trip_t *trip = pick->divetrip;
res->tripflag = tripflag;
add_dive_to_trip(res, trip);
- remove_dive_from_trip(pick);
- remove_dive_from_trip(remove);
}
/*
@@ -860,10 +858,9 @@ static void merge_trip(struct dive *res, struct dive *a, struct dive *b)
goto pick_b;
pick_a:
- pick_and_delete_trip(res, a, b);
- return;
+ b = a;
pick_b:
- pick_and_delete_trip(res, b, a);
+ pick_trip(res, b);
}
/*
diff --git a/dive.h b/dive.h
index 97668477c..481d8a17a 100644
--- a/dive.h
+++ b/dive.h
@@ -321,6 +321,9 @@ extern gboolean autogroup;
extern void add_dive_to_trip(struct dive *, dive_trip_t *);
extern void remove_dive_from_trip(struct dive *);
+extern void delete_single_dive(int idx);
+extern void add_single_dive(int idx, struct dive *dive);
+
extern void insert_trip(dive_trip_t **trip);
/*
diff --git a/divelist.c b/divelist.c
index 6aa26c2bd..8dab5b4cb 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1919,7 +1919,7 @@ void merge_trips_cb(GtkWidget *menuitem, GtkTreePath *trippath)
/* this implements the mechanics of removing the dive from the table,
* but doesn't deal with updating dive trips, etc */
-static void delete_single_dive(int idx)
+void delete_single_dive(int idx)
{
int i;
struct dive *dive = get_dive(idx);
@@ -1934,6 +1934,17 @@ static void delete_single_dive(int idx)
free(dive);
}
+void add_single_dive(int idx, struct dive *dive)
+{
+ int i;
+ dive_table.nr++;
+ for (i = idx; i < dive_table.nr ; i++) {
+ struct dive *tmp = dive_table.dives[i];
+ dive_table.dives[i] = dive;
+ dive = tmp;
+ }
+}
+
/* remember expanded state */
static void remember_tree_state()
{
@@ -2070,6 +2081,58 @@ static void delete_dive_cb(GtkWidget *menuitem, GtkTreePath *path)
mark_divelist_changed(TRUE);
}
+static void merge_dive_index(int i, struct dive *a)
+{
+ struct dive *b = get_dive(i+1);
+ struct dive *res;
+
+ res = merge_dives(a, b, b->when - a->when);
+ if (!res)
+ return;
+
+ add_single_dive(i, res);
+ delete_single_dive(i+1);
+ delete_single_dive(i+1);
+
+ dive_list_update_dives();
+ restore_tree_state();
+ mark_divelist_changed(TRUE);
+}
+
+static void merge_dives_cb(GtkWidget *menuitem, void *unused)
+{
+ int i;
+ struct dive *dive;
+
+ for_each_dive(i, dive) {
+ if (dive->selected) {
+ merge_dive_index(i, dive);
+ return;
+ }
+ }
+}
+
+/* Called if there are exactly two selected dives and the dive at idx is one of them */
+static void add_dive_merge_label(int idx, GtkMenuShell *menu)
+{
+ struct dive *d;
+ GtkWidget *menuitem;
+
+ /* The other selected dive must be next to it.. */
+ if (!((d = get_dive(idx-1)) && d->selected) &&
+ !((d = get_dive(idx+1)) && d->selected))
+ return;
+
+ /* .. and they had better be in the same dive trip */
+ if (d->divetrip != get_dive(idx)->divetrip)
+ return;
+
+ /* If so, we can add a "merge dive" menu entry */
+ menuitem = gtk_menu_item_new_with_label(_("Merge dives"));
+ g_signal_connect(menuitem, "activate", G_CALLBACK(merge_dives_cb), NULL);
+ gtk_menu_shell_append(menu, menuitem);
+}
+
static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int button, GdkEventButton *event)
{
GtkWidget *menu, *menuitem, *image;
@@ -2142,6 +2205,10 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
menuitem = gtk_menu_item_new_with_label(editlabel);
g_signal_connect(menuitem, "activate", G_CALLBACK(edit_selected_dives_cb), NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
+ /* Two contiguous selected dives? */
+ if (amount_selected == 2)
+ add_dive_merge_label(idx, GTK_MENU_SHELL(menu));
} else {
deletelabel = _(deletesinglelabel);
menuitem = gtk_menu_item_new_with_label(deletelabel);
diff --git a/main.c b/main.c
index ca3722383..88a28c8c2 100644
--- a/main.c
+++ b/main.c
@@ -138,14 +138,12 @@ void report_dives(gboolean is_imported)
/* careful - we might free the dive that last points to. Oops... */
if (last == prev || last == dive)
last = merged;
- free(prev);
- free(dive);
- *pp = merged;
- dive_table.nr--;
- memmove(pp+1, pp+2, sizeof(*pp)*(dive_table.nr - i));
/* Redo the new 'i'th dive */
i--;
+ add_single_dive(i, merged);
+ delete_single_dive(i+1);
+ delete_single_dive(i+1);
}
if (is_imported) {