aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tomaz Canabrava <tcanabrava@kde.org>2013-06-06 11:57:12 -0300
committerGravatar Tomaz Canabrava <tcanabrava@kde.org>2013-06-06 11:57:12 -0300
commit2d05f4227e5538f3e8976a8244b54a5247ec833c (patch)
treea73d0803705afbf7a823d63bcb79511ab0c1dbcd
parentf55ae1570738ec4e890ec35504e2c1e5c81364cc (diff)
downloadsubsurface-2d05f4227e5538f3e8976a8244b54a5247ec833c.tar.gz
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 <tcanabrava@kde.org>
-rw-r--r--qt-ui/subsurfacewebservices.cpp103
-rw-r--r--webservice.c60
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 <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
+#include <QSettings>
#include <qdesktopservices.h>
+#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 <libintl.h>
#include <glib/gi18n.h>
#include <libsoup/soup.h>
-
+#include <libxml/tree.h>
+#include <libxml/parser.h>
#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 <download> or <error> tag under the <root> 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;