diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-09-25 07:28:47 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-09-26 10:58:15 -0700 |
commit | 43f122f9ff6eb933fcf831ac0b242f770204d2d5 (patch) | |
tree | 79e85a4ed5b33480bdcf458169941fc148f05ce5 /gtk-gui.c | |
parent | 5305fb152b5cb31e81ac3f1ca2f2782d20b8bb83 (diff) | |
download | subsurface-43f122f9ff6eb933fcf831ac0b242f770204d2d5.tar.gz |
First implementation of native Uemis downloader
This includes one major hack that uses a private data structure from
libdivecomputer to allow us to show the Uemis Zurich as one computer the
user can import from.
Once the user has chosen the Uemis we don't use libdivecomputer but our
own downloader. Just like in the libdicecomputer case this runs in its own
thread and updates the import dialog with progress information.
The code also keeps track of the last dive that has been downloaded from a
Uemis computer so we only import new dives on subsequent downloads. And
since the Uemis Zurich gives us its device id, we make this a "per
divecomputer" property for people who dive with multiple Uemis Zurich
computers.
This uses the debugfile infrastructure to allow easily collecting
debugging output - especially on Windows where by default console output
is lost.
Known limitations: when the Uemis runs out of space (it uses its
filesystem for communication with the host computer) we have no graceful
way to reset things. This is why the code doesn't try to download ALL
dives on the computer but instead download them in increments of ten
dives. This clearly needs to be addressed once I understand how to reset
the device.
The Cancel button of the import dialog isn't correctly hooked up, yet.
I still need to figure out how to gracefully shut down a download without
potentially hanging the device.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'gtk-gui.c')
-rw-r--r-- | gtk-gui.c | 77 |
1 files changed, 74 insertions, 3 deletions
@@ -14,6 +14,7 @@ #include "divelist.h" #include "display.h" #include "display-gtk.h" +#include "uemis.h" #include "libdivecomputer.h" @@ -38,6 +39,7 @@ visible_cols_t visible_cols = {TRUE, FALSE}; 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 int is_default_dive_computer(const char *vendor, const char *product) { @@ -74,6 +76,12 @@ static void set_default_dive_computer_device(const char *name) subsurface_set_conf("dive_computer_device", PREF_STRING, name); } +static void set_uemis_last_dive(char *data) +{ + uemis_max_dive_data = data; + subsurface_set_conf("uemis_max_dive_data", PREF_STRING, data); +} + void repaint_dive(void) { update_dive(current_dive); @@ -980,6 +988,7 @@ void init_ui(int *argcp, char ***argvp) GtkIconTheme *icon_theme=NULL; GtkSettings *settings; GtkUIManager *ui_manager; + const char *conf_value; gtk_init(argcp, argvp); settings = gtk_settings_get_default(); @@ -1014,7 +1023,11 @@ void init_ui(int *argcp, char ***argvp) default_dive_computer_vendor = subsurface_get_conf("dive_computer_vendor", PREF_STRING); default_dive_computer_product = subsurface_get_conf("dive_computer_product", PREF_STRING); default_dive_computer_device = subsurface_get_conf("dive_computer_device", PREF_STRING); - + conf_value = subsurface_get_conf("uemis_max_dive_data", PREF_STRING); + if (!conf_value) + uemis_max_dive_data = strdup(""); + else + uemis_max_dive_data = strdup(conf_value); error_info_bar = NULL; win = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_set_application_name ("subsurface"); @@ -1205,12 +1218,20 @@ int process_ui_events(void) return ret; } +struct mydescriptor { + const char *vendor; + const char *product; + dc_family_t type; + unsigned int model; +}; + static int fill_computer_list(GtkListStore *store) { int index = -1, i; GtkTreeIter iter; dc_iterator_t *iterator = NULL; dc_descriptor_t *descriptor = NULL; + struct mydescriptor *mydescriptor; i = 0; dc_descriptor_iterator(&iterator); @@ -1227,6 +1248,21 @@ static int fill_computer_list(GtkListStore *store) i++; } dc_iterator_free(iterator); + /* and add the Uemis Zurich which we are handling internally + THIS IS A HACK as we use the internal of libdivecomputer + data structures... eventually the UEMIS code needs to move + into libdivecomputer, I guess */ + mydescriptor = malloc(sizeof(mydescriptor)); + mydescriptor->vendor = "Uemis"; + mydescriptor->product = "Zurich"; + mydescriptor->type = DC_FAMILY_NULL; + mydescriptor->model = 0; + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, mydescriptor, -1); + if (is_default_dive_computer("Uemis", "Zurich")) + index = i; + return index; } @@ -1372,12 +1408,48 @@ void import_files(GtkWidget *w, gpointer data) gtk_widget_destroy(fs_dialog); } +static GError *setup_uemis_import(device_data_t *data) +{ + GError *error = NULL; + + for (;;) { + char *buf; + error = uemis_download(data->devname, &uemis_max_dive_data, &buf, &data->progress); + if (buf && strlen(buf) > 1) { +#ifdef DEBUGFILE + fprintf(debugfile, "xml buffer \"%s\"\n\n", buf); +#endif + parse_xml_buffer("Uemis Download", buf, strlen(buf), &error); + set_uemis_last_dive(uemis_max_dive_data); +#if UEMIS_DEBUG + fprintf(debugfile, "%s\n", uemis_max_dive_data); +#endif + /* this function is set up to download all the remaining dives + * yet this can fail in odd ways if we run out of ANS files on + * the dive computer (basically, its file system is only 6MB and + * no more than 2MB can be used for communication responses). + * So in order to avoid this issue we break out here as well, + * but once we understand how to reset the Uemis Zurich from + * software the following break statement should be removed */ + break; + } else { + break; + } + } + return error; +} + static GtkWidget *import_dive_computer(device_data_t *data, GtkDialog *dialog) { GError *error; GtkWidget *vbox, *info, *container, *label, *button; - error = do_import(data); + /* HACK to simply include the Uemis Zurich in the list */ + if (! strcmp(data->vendor, "Uemis") && ! strcmp(data->product, "Zurich")) { + error = setup_uemis_import(data); + } else { + error = do_import(data); + } if (!error) return NULL; @@ -1459,7 +1531,6 @@ repeat: info = import_dive_computer(&devicedata, GTK_DIALOG(dialog)); if (info) goto repeat; - report_dives(TRUE); break; default: |