From 2d05f4227e5538f3e8976a8244b54a5247ec833c Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 6 Jun 2013 11:57:12 -0300 Subject: [PATCH] Hoocked up the Apply button. Hoocked up the apply button - Didn't tested ( as I frankly don't know what the expected result should be. ). but the app is not crashing, yey. Signed-off-by: Tomaz Canabrava --- qt-ui/subsurfacewebservices.cpp | 103 +++++++++++++++++++++++++++++++- webservice.c | 60 ++++++++++++++++++- 2 files changed, 158 insertions(+), 5 deletions(-) diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp index c6314bf03..2f82d6d26 100644 --- a/qt-ui/subsurfacewebservices.cpp +++ b/qt-ui/subsurfacewebservices.cpp @@ -7,8 +7,15 @@ #include #include #include +#include #include +#include "../dive.h" +#include "../divelist.h" + +struct dive_table gps_location_table; +static gboolean merge_locations_into_dives(void); + SubsurfaceWebServices* SubsurfaceWebServices::instance() { static SubsurfaceWebServices *self = new SubsurfaceWebServices(); @@ -21,15 +28,39 @@ SubsurfaceWebServices::SubsurfaceWebServices(QWidget* parent, Qt::WindowFlags f) connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui->download, SIGNAL(clicked(bool)), this, SLOT(startDownload())); ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); + QSettings s; + ui->userID->setText(s.value("webservice_uid").toString()); +} + + +static void clear_table(struct dive_table *table) +{ + int i; + for (i = 0; i < table->nr; i++) + free(table->dives[i]); + table->nr = 0; } void SubsurfaceWebServices::buttonClicked(QAbstractButton* button) { ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); switch(ui->buttonBox->buttonRole(button)){ - case QDialogButtonBox::ApplyRole: - qDebug() << "Apply Clicked"; - break; + case QDialogButtonBox::ApplyRole:{ + clear_table(&gps_location_table); + QByteArray url = tr("Webservice").toLocal8Bit(); + parse_xml_buffer(url.data(), downloadedData.data(), downloadedData.length(), &gps_location_table, NULL); + + /* now merge the data in the gps_location table into the dive_table */ + if (merge_locations_into_dives()) { + mark_divelist_changed(TRUE); + } + + /* store last entered uid in config */ + QSettings s; + s.setValue("webservice_uid", ui->userID->text()); + s.sync(); + } + break; case QDialogButtonBox::RejectRole: manager->deleteLater(); reply->deleteLater(); @@ -53,6 +84,7 @@ void SubsurfaceWebServices::startDownload() request.setUrl(url); request.setRawHeader("Accept", "text/xml"); reply = manager->get(request); + ui->status->setText(tr("Wait a bit untill we have something...")); ui->progressBar->setRange(0,0); // this makes the progressbar do an 'infinite spin' ui->download->setEnabled(false); ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); @@ -140,3 +172,68 @@ unsigned int SubsurfaceWebServices::download_dialog_parse_response(const QByteAr xmlFreeDoc(doc); return status; } + +static gboolean is_automatic_fix(struct dive *gpsfix) +{ + if (gpsfix && gpsfix->location && + (!strcmp(gpsfix->location, "automatic fix") || + !strcmp(gpsfix->location, "Auto-created dive"))) + return TRUE; + return FALSE; +} + +#define SAME_GROUP 6 * 3600 // six hours + +static gboolean merge_locations_into_dives(void) +{ + int i, nr = 0, changed = 0; + struct dive *gpsfix, *last_named_fix = NULL, *dive; + + sort_table(&gps_location_table); + + for_each_gps_location(i, gpsfix) { + if (is_automatic_fix(gpsfix)) { + dive = find_dive_including(gpsfix->when); + if (dive && !dive_has_gps_location(dive)) { +#if DEBUG_WEBSERVICE + struct tm tm; + utc_mkdate(gpsfix->when, &tm); + printf("found dive named %s @ %04d-%02d-%02d %02d:%02d:%02d\n", + gpsfix->location, + tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +#endif + changed++; + copy_gps_location(gpsfix, dive); + } + } else { + if (last_named_fix && dive_within_time_range(last_named_fix, gpsfix->when, SAME_GROUP)) { + nr++; + } else { + nr = 1; + last_named_fix = gpsfix; + } + dive = find_dive_n_near(gpsfix->when, nr, SAME_GROUP); + if (dive) { + if (!dive_has_gps_location(dive)) { + copy_gps_location(gpsfix, dive); + changed++; + } + if (!dive->location) { + dive->location = strdup(gpsfix->location); + changed++; + } + } else { + struct tm tm; + utc_mkdate(gpsfix->when, &tm); +#if DEBUG_WEBSERVICE + printf("didn't find dive matching gps fix named %s @ %04d-%02d-%02d %02d:%02d:%02d\n", + gpsfix->location, + tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +#endif + } + } + } + return changed > 0; +} diff --git a/webservice.c b/webservice.c index 2ac19c85a..f4f8baeb4 100644 --- a/webservice.c +++ b/webservice.c @@ -1,16 +1,36 @@ #include #include #include - +#include +#include #include "dive.h" #include "divelist.h" #include "display-gtk.h" #include "file.h" -#include "webservice.h" struct dive_table gps_location_table; static gboolean merge_locations_into_dives(void); +enum { + DD_STATUS_OK, + DD_STATUS_ERROR_CONNECT, + DD_STATUS_ERROR_ID, + DD_STATUS_ERROR_PARSE, +}; + +static const gchar *download_dialog_status_text(const gint status) +{ + switch (status) { + case DD_STATUS_ERROR_CONNECT: + return _("Connection Error: "); + case DD_STATUS_ERROR_ID: + return _("Invalid user identifier!"); + case DD_STATUS_ERROR_PARSE: + return _("Cannot parse response!"); + } + return _("Download Success!"); +} + /* provides a state of the download dialog contents and the downloaded xml */ struct download_dialog_state { GtkWidget *uid; @@ -53,6 +73,42 @@ gboolean webservice_request_user_xml(const gchar *user_id, return ret; } +/* requires that there is a or tag under the tag */ +static void download_dialog_traverse_xml(xmlNodePtr node, guint *download_status) +{ + xmlNodePtr cur_node; + for (cur_node = node; cur_node; cur_node = cur_node->next) { + if ((!strcmp((const char *)cur_node->name, (const char *)"download")) && + (!strcmp((const char *)xmlNodeGetContent(cur_node), (const char *)"ok"))) { + *download_status = DD_STATUS_OK; + return; + } else if (!strcmp((const char *)cur_node->name, (const char *)"error")) { + *download_status = DD_STATUS_ERROR_ID; + return; + } + } +} + +static guint download_dialog_parse_response(gchar *xmldata, guint len) +{ + xmlNodePtr root; + xmlDocPtr doc = xmlParseMemory(xmldata, len); + guint status = DD_STATUS_ERROR_PARSE; + + if (!doc) + return DD_STATUS_ERROR_PARSE; + root = xmlDocGetRootElement(doc); + if (!root) { + status = DD_STATUS_ERROR_PARSE; + goto end; + } + if (root->children) + download_dialog_traverse_xml(root->children, &status); + end: + xmlFreeDoc(doc); + return status; +} + static void download_dialog_connect_cb(GtkWidget *w, gpointer data) { struct download_dialog_state *state = (struct download_dialog_state *)data;