summaryrefslogtreecommitdiffstats
path: root/gtk-gui.c
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2012-09-25 07:28:47 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-09-26 10:58:15 -0700
commit43f122f9ff6eb933fcf831ac0b242f770204d2d5 (patch)
tree79e85a4ed5b33480bdcf458169941fc148f05ce5 /gtk-gui.c
parent5305fb152b5cb31e81ac3f1ca2f2782d20b8bb83 (diff)
downloadsubsurface-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.c77
1 files changed, 74 insertions, 3 deletions
diff --git a/gtk-gui.c b/gtk-gui.c
index cb46da43b..11f9a8013 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -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: