diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-11-19 14:11:08 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-11-20 11:42:01 -0800 |
commit | a8d413551e3b6c7c2ab9d092b67e0976550e2115 (patch) | |
tree | a305ddc5fb8ee66a6c6ca44f4ccc929991493252 /libdivecomputer.c | |
parent | d1571ead2df6276ff8db06bd54d39b873b4ab9c9 (diff) | |
download | subsurface-a8d413551e3b6c7c2ab9d092b67e0976550e2115.tar.gz |
Allow the user to cancel a dive computer download
The code pretended to support this for libdivecomputer based downloads,
but it had never been hooked up when the native Uemis downloader was
implemented. When I finally decided to close that feature gap I realized
that the original code was, shall we say, "aspirational" or "completely
bogus" and therefore never worked.
So instead of just hooking up the code for the Uemis downloader I instead
implemented this correctly for the first time for both libdivecomputer and
the native Uemis downloader.
In order not to have to mess with multithreaded Gtk development I simply
opted for a helper function that fires on a 100ms timeout and have it end
the dialog without a response. This way we can run the dialog while
waiting for the download to finish, still update the progress bar and
respond in a useful manner to the user clicking cancel.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'libdivecomputer.c')
-rw-r--r-- | libdivecomputer.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/libdivecomputer.c b/libdivecomputer.c index 076126dfb..d4ffcc174 100644 --- a/libdivecomputer.c +++ b/libdivecomputer.c @@ -423,21 +423,55 @@ static void *pthread_wrapper(void *_data) return (void *)err_string; } +/* this simply ends the dialog without a response and asks not to be fired again + * as we set this function up in every loop while uemis_download is waiting for + * the download to finish */ +static gboolean timeout_func(gpointer _data) +{ + GtkDialog *dialog = _data; + if (!import_thread_cancelled) + gtk_dialog_response(dialog, GTK_RESPONSE_NONE); + return FALSE; +} + GError *do_import(device_data_t *data) { pthread_t pthread; void *retval; + GtkDialog *dialog = data->dialog; /* I'm sure there is some better interface for waiting on a thread in a UI main loop */ import_thread_done = 0; progress_bar_text = ""; progress_bar_fraction = 0.0; pthread_create(&pthread, NULL, pthread_wrapper, data); + /* loop here until the import is done or was cancelled by the user; + * in order to get control back from gtk we register a timeout function + * that ends the dialog with no response every 100ms; we then update the + * progressbar and setup the timeout again - unless of course the user + * pressed cancel, in which case we just wait for the download thread + * to react to that and exit */ while (!import_thread_done) { - import_thread_cancelled = process_ui_events(); - update_progressbar(&data->progress, progress_bar_fraction); - update_progressbar_text(&data->progress, progress_bar_text); - usleep(100000); + if (!import_thread_cancelled) { + int result; + g_timeout_add(100, timeout_func, dialog); + update_progressbar(&data->progress, progress_bar_fraction); + update_progressbar_text(&data->progress, progress_bar_text); + result = gtk_dialog_run(dialog); + switch (result) { + case GTK_RESPONSE_CANCEL: + import_thread_cancelled = TRUE; + progress_bar_text = "Cancelled..."; + break; + default: + /* nothing */ + break; + } + } else { + update_progressbar(&data->progress, progress_bar_fraction); + update_progressbar_text(&data->progress, progress_bar_text); + usleep(100000); + } } if (pthread_join(pthread, &retval) < 0) retval = _("Odd pthread error return"); |