summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--display-gtk.h3
-rw-r--r--dive.c61
-rw-r--r--dive.h7
-rw-r--r--divelist.c4
-rw-r--r--gtk-gui.c27
-rw-r--r--libdivecomputer.c3
-rw-r--r--libdivecomputer.h1
-rw-r--r--main.c11
-rw-r--r--uemis-downloader.c8
9 files changed, 90 insertions, 35 deletions
diff --git a/display-gtk.h b/display-gtk.h
index d709696a6..4f156c7f7 100644
--- a/display-gtk.h
+++ b/display-gtk.h
@@ -113,6 +113,7 @@ typedef gint (*sort_func_t)(GtkTreeModel *model,
extern GtkTreeViewColumn *tree_view_column(GtkWidget *tree_view, int index, const char *title,
data_func_t data_func, unsigned int flags);
-GError *uemis_download(const char *path, char **divenr, char **xml_buffer, progressbar_t *progress);
+GError *uemis_download(const char *path, char **divenr, char **xml_buffer,
+ progressbar_t *progress, gboolean force_download);
#endif
diff --git a/dive.c b/dive.c
index 295d14ae5..15038bd9e 100644
--- a/dive.c
+++ b/dive.c
@@ -590,6 +590,9 @@ struct dive *fixup_dive(struct dive *dive)
#define MERGE_TXT(res, a, b, n) res->n = merge_text(a->n, b->n)
#define MERGE_NONZERO(res, a, b, n) res->n = a->n ? a->n : b->n
+#define MERGE_MAX_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : MAX(a->n, b->n)
+#define MERGE_MIN_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n)
+
static struct dive *add_sample(struct sample *sample, int time, struct dive *dive)
{
struct sample *p = prepare_sample(&dive);
@@ -684,6 +687,20 @@ add_sample_b:
}
}
+static struct dive *copy_samples(struct dive *res, struct dive *src)
+{
+ int samples = src->samples;
+ struct sample *s = src->sample;
+ while (samples) {
+ if (!res)
+ return NULL;
+ res = add_sample(s, s->time.seconds, res);
+ s++;
+ samples--;
+ }
+ return fixup_dive(res);
+}
+
static char *merge_text(const char *a, const char *b)
{
char *res;
@@ -1027,9 +1044,9 @@ static int find_sample_offset(struct dive *a, struct dive *b)
* merges almost exact duplicates - something that happens easily
* with overlapping dive downloads.
*/
-struct dive *try_to_merge(struct dive *a, struct dive *b)
+struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer_downloaded)
{
- int offset;
+ int offset = 0;
/*
* This assumes that the clocks on the dive computers are
@@ -1037,19 +1054,26 @@ struct dive *try_to_merge(struct dive *a, struct dive *b)
*/
if ((a->when >= b->when + 60) || (a->when <= b->when - 60))
return NULL;
-
- /* Dive 'a' is 'offset' seconds before dive 'b' */
- offset = find_sample_offset(a, b);
- if (offset > 120 || offset < -120)
+ if (prefer_downloaded && a->when != b->when)
return NULL;
-
- return merge_dives(a, b, offset);
+ if (!prefer_downloaded) {
+ /* Dive 'a' is 'offset' seconds before dive 'b' */
+ offset = find_sample_offset(a, b);
+ if (offset > 120 || offset < -120)
+ return NULL;
+ }
+ return merge_dives(a, b, offset, prefer_downloaded);
}
-struct dive *merge_dives(struct dive *a, struct dive *b, int offset)
+struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded)
{
struct dive *res = alloc_dive();
+ struct dive *dl = NULL;
+ if (a->downloaded)
+ dl = a;
+ else if (b->downloaded)
+ dl = b;
res->when = a->when;
res->selected = a->selected || b->selected;
merge_trip(res, a, b);
@@ -1062,16 +1086,21 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset)
MERGE_MAX(res, a, b, rating);
MERGE_TXT(res, a, b, suit);
MERGE_MAX(res, a, b, number);
- MERGE_MAX(res, a, b, maxdepth.mm);
+ MERGE_MAX_PREFDL(res, dl, a, b, maxdepth.mm);
res->meandepth.mm = 0;
MERGE_NONZERO(res, a, b, salinity);
MERGE_NONZERO(res, a, b, visibility);
MERGE_NONZERO(res, a, b, surface_pressure.mbar);
- MERGE_MAX(res, a, b, duration.seconds);
- MERGE_MAX(res, a, b, surfacetime.seconds);
- MERGE_MAX(res, a, b, airtemp.mkelvin);
- MERGE_MIN(res, a, b, watertemp.mkelvin);
+ MERGE_MAX_PREFDL(res, dl, a, b, duration.seconds);
+ MERGE_MAX_PREFDL(res, dl, a, b, surfacetime.seconds);
+ MERGE_MAX_PREFDL(res, dl, a, b, airtemp.mkelvin);
+ MERGE_MIN_PREFDL(res, dl, a, b, watertemp.mkelvin);
merge_equipment(res, a, b);
- merge_events(res, a, b, offset);
- return merge_samples(res, a, b, offset);
+ if (dl) {
+ res->events = dl->events;
+ return copy_samples(res, dl);
+ } else {
+ merge_events(res, a, b, offset);
+ return merge_samples(res, a, b, offset);
+ }
}
diff --git a/dive.h b/dive.h
index 481d8a17a..d4da7af07 100644
--- a/dive.h
+++ b/dive.h
@@ -261,6 +261,7 @@ struct dive {
tripflag_t tripflag;
dive_trip_t *divetrip;
int selected;
+ gboolean downloaded;
int start, end;
timestamp_t when;
char *location;
@@ -414,10 +415,10 @@ extern void delete_dive(struct dive *dive);
extern struct sample *prepare_sample(struct dive **divep);
extern void finish_sample(struct dive *dive);
-extern void report_dives(gboolean imported);
+extern void report_dives(gboolean imported, gboolean prefer_imported);
extern struct dive *fixup_dive(struct dive *dive);
-extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset);
-extern struct dive *try_to_merge(struct dive *a, struct dive *b);
+extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded);
+extern struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer_downloaded);
extern void renumber_dives(int nr);
diff --git a/divelist.c b/divelist.c
index fd55dcd60..10c1ce4b3 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1417,7 +1417,7 @@ void add_dive_cb(GtkWidget *menuitem, gpointer data)
dive = alloc_dive();
if (add_new_dive(dive)) {
record_dive(dive);
- report_dives(TRUE);
+ report_dives(TRUE, FALSE);
return;
}
free(dive);
@@ -2088,7 +2088,7 @@ 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);
+ res = merge_dives(a, b, b->when - a->when, FALSE);
if (!res)
return;
diff --git a/gtk-gui.c b/gtk-gui.c
index a34f278b6..025cd1e45 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -43,6 +43,8 @@ static const char *default_dive_computer_vendor;
static const char *default_dive_computer_product;
static const char *default_dive_computer_device;
static char *uemis_max_dive_data;
+static gboolean force_download;
+static gboolean prefer_downloaded;
static int is_default_dive_computer(const char *vendor, const char *product)
{
@@ -350,7 +352,7 @@ static void file_open(GtkWidget *w, gpointer data)
}
g_free(filename);
g_slist_free(fn_glist);
- report_dives(FALSE);
+ report_dives(FALSE, FALSE);
}
gtk_widget_destroy(dialog);
}
@@ -510,6 +512,8 @@ OPTIONCALLBACK(autogroup_toggle, autogroup)
OPTIONCALLBACK(po2_toggle, partial_pressure_graphs.po2)
OPTIONCALLBACK(pn2_toggle, partial_pressure_graphs.pn2)
OPTIONCALLBACK(phe_toggle, partial_pressure_graphs.phe)
+OPTIONCALLBACK(force_toggle, force_download)
+OPTIONCALLBACK(prefer_dl_toggle, prefer_downloaded)
static void event_toggle(GtkWidget *w, gpointer _data)
{
@@ -1605,7 +1609,7 @@ void import_files(GtkWidget *w, gpointer data)
filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(fs_dialog));
if (filenames) {
g_slist_foreach(filenames, do_import_file, NULL);
- report_dives(TRUE);
+ report_dives(TRUE, FALSE);
g_slist_free(filenames);
}
}
@@ -1619,7 +1623,7 @@ static GError *setup_uemis_import(device_data_t *data)
GError *error = NULL;
char *buf = NULL;
- error = uemis_download(data->devname, &uemis_max_dive_data, &buf, &data->progress);
+ error = uemis_download(data->devname, &uemis_max_dive_data, &buf, &data->progress, data->force_download);
if (buf && strlen(buf) > 1) {
#ifdef DEBUGFILE
fprintf(debugfile, "xml buffer \"%s\"\n\n", buf);
@@ -1696,6 +1700,18 @@ void download_dialog(GtkWidget *w, gpointer data)
devicedata.progress.bar = gtk_progress_bar_new();
gtk_container_add(GTK_CONTAINER(hbox), devicedata.progress.bar);
+ force_download = FALSE;
+ button = gtk_check_button_new_with_label(_("Force download of all dives"));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 6);
+ g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(force_toggle), NULL);
+
+ prefer_downloaded = FALSE;
+ button = gtk_check_button_new_with_label(_("Always prefer downloaded dive"));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 6);
+ g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(prefer_dl_toggle), NULL);
+
button = gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
if (!gtk_combo_box_get_active_iter(computer, &iter))
gtk_widget_set_sensitive(button, FALSE);
@@ -1747,15 +1763,16 @@ repeat:
while (*(--ne) == ' ' || *ne == '\t')
*ne = '\0';
devicedata.devname = ns;
+ devicedata.force_download = force_download;
info = import_dive_computer(&devicedata, GTK_DIALOG(dialog));
free((void *)devname);
if (info)
goto repeat;
- report_dives(TRUE);
+ report_dives(TRUE, prefer_downloaded);
break;
default:
/* it's possible that some dives were downloaded */
- report_dives(TRUE);
+ report_dives(TRUE, prefer_downloaded);
break;
}
gtk_widget_destroy(dialog);
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 6a9b07f80..f0c3c7549 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -311,9 +311,10 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dc_parser_destroy(parser);
/* If we already saw this dive, abort. */
- if (find_dive(dive, devdata))
+ if (!devdata->force_download && find_dive(dive, devdata))
return 0;
+ dive->downloaded = TRUE;
record_dive(dive);
return 1;
}
diff --git a/libdivecomputer.h b/libdivecomputer.h
index 6430c8448..7497abf11 100644
--- a/libdivecomputer.h
+++ b/libdivecomputer.h
@@ -17,6 +17,7 @@ typedef struct device_data_t {
dc_context_t *context;
progressbar_t progress;
int preexisting;
+ gboolean force_download;
} device_data_t;
extern GError *do_import(device_data_t *data);
diff --git a/main.c b/main.c
index 88a28c8c2..1c4d33736 100644
--- a/main.c
+++ b/main.c
@@ -111,7 +111,7 @@ static gboolean imported = FALSE;
* This doesn't really report anything at all. We just sort the
* dives, the GUI does the reporting
*/
-void report_dives(gboolean is_imported)
+void report_dives(gboolean is_imported, gboolean prefer_imported)
{
int i;
int preexisting = dive_table.preexisting;
@@ -131,7 +131,7 @@ void report_dives(gboolean is_imported)
if (prev->when + prev->duration.seconds < dive->when)
continue;
- merged = try_to_merge(prev, dive);
+ merged = try_to_merge(prev, dive, prefer_imported);
if (!merged)
continue;
@@ -145,6 +145,9 @@ void report_dives(gboolean is_imported)
delete_single_dive(i+1);
delete_single_dive(i+1);
}
+ /* make sure no dives are still marked as downloaded */
+ for (i = 1; i < dive_table.nr; i++)
+ dive_table.dives[i]->downloaded = FALSE;
if (is_imported) {
/* Was the previous dive table state numbered? */
@@ -173,7 +176,7 @@ static void parse_argument(const char *arg)
if (strcmp(arg,"--import") == 0) {
/* mark the dives so far as the base,
* everything after is imported */
- report_dives(FALSE);
+ report_dives(FALSE, FALSE);
imported = TRUE;
return;
}
@@ -276,7 +279,7 @@ int main(int argc, char **argv)
set_filename(filename, FALSE);
free((void *)filename);
}
- report_dives(imported);
+ report_dives(imported, FALSE);
if (dive_table.nr == 0)
show_dive_info(NULL);
run_ui();
diff --git a/uemis-downloader.c b/uemis-downloader.c
index 6f85eca59..922aa90ae 100644
--- a/uemis-downloader.c
+++ b/uemis-downloader.c
@@ -44,6 +44,7 @@ struct argument_block {
char **max_dive_data;
char **xml_buffer;
progressbar_t *progress;
+ gboolean force_download;
};
static int import_thread_done = 0, import_thread_cancelled;
@@ -796,7 +797,7 @@ static char *do_uemis_download(struct argument_block *args)
* certainly want to start downloading from the first dive on
* the Uemis; otherwise check which was the last dive
* downloaded */
- if (dive_table.nr > 0)
+ if (!args->force_download && dive_table.nr > 0)
newmax = get_divenr(*max_dive_data, deviceid);
else
newmax = strdup("0");
@@ -874,11 +875,12 @@ static void *pthread_wrapper(void *_data)
return (void *)err_string;
}
-GError *uemis_download(const char *mountpath, char **max_dive_data, char **xml_buffer, progressbar_t *progress)
+GError *uemis_download(const char *mountpath, char **max_dive_data, char **xml_buffer, progressbar_t *progress,
+ gboolean force_download)
{
pthread_t pthread;
void *retval;
- struct argument_block args = {mountpath, max_dive_data, xml_buffer, progress};
+ struct argument_block args = {mountpath, max_dive_data, xml_buffer, progress, force_download};
/* I'm sure there is some better interface for waiting on a thread in a UI main loop */
import_thread_done = 0;