summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h8
-rw-r--r--divelist.c103
-rw-r--r--parse-xml.c2
-rw-r--r--xslt/commonTemplates.xsl26
4 files changed, 138 insertions, 1 deletions
diff --git a/dive.h b/dive.h
index 6eb9a385a..b6738d171 100644
--- a/dive.h
+++ b/dive.h
@@ -9,6 +9,9 @@
#include <glib.h>
#include <glib/gstdio.h>
#include <libxml/tree.h>
+#ifdef XSLT
+#include <libxslt/transform.h>
+#endif
#include "sha1.h"
@@ -545,6 +548,11 @@ extern void show_yearly_stats(void);
extern void update_dive(struct dive *new_dive);
extern void save_dives(const char *filename);
extern void save_dives_logic(const char *filename, gboolean select_only);
+extern void save_dive(FILE *f, struct dive *dive);
+
+#ifdef XSLT
+extern xsltStylesheetPtr get_stylesheet(const char *name);
+#endif
extern timestamp_t utc_mktime(struct tm *tm);
extern void utc_mkdate(timestamp_t, struct tm *tm);
diff --git a/divelist.c b/divelist.c
index f8e9f1682..a426d67c3 100644
--- a/divelist.c
+++ b/divelist.c
@@ -17,6 +17,12 @@
#include <math.h>
#include <glib/gi18n.h>
#include <assert.h>
+#ifdef LIBZIP
+#include <zip.h>
+#endif
+#ifdef XSLT
+#include <libxslt/transform.h>
+#endif
#include "divelist.h"
#include "dive.h"
@@ -1965,6 +1971,94 @@ static void delete_dive_cb(GtkWidget *menuitem, GtkTreePath *path)
mark_divelist_changed(TRUE);
}
+#if defined(LIBZIP) && defined(XSLT)
+static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
+{
+ int i;
+ struct dive *dive;
+ FILE *f;
+ char filename[PATH_MAX], *tempfile, *template;
+ size_t streamsize;
+ char *membuf;
+ xmlDoc *doc;
+ xsltStylesheetPtr xslt = NULL;
+ xmlDoc *transformed;
+ struct zip_source *s[dive_table.nr];
+ struct zip *zip;
+
+ /*
+ * Creating a temporary .DLD file to be eventually uploaded to
+ * divelogs.de. I wonder if this could be done in-memory.
+ */
+
+ template = strdup("/tmp/export.DLD-XXXXXX");
+ tempfile = mktemp(template);
+ zip = zip_open(tempfile, ZIP_CREATE, NULL);
+
+ if (!zip)
+ return;
+
+ if (!amount_selected)
+ return;
+
+ /* walk the dive list in chronological order */
+ for (i = 0; i < dive_table.nr; i++) {
+
+ dive = get_dive(i);
+ if (!dive)
+ continue;
+ if (!dive->selected)
+ continue;
+
+ /*
+ * Saving the dive is done into a memory buffer
+ */
+
+ f = open_memstream(&membuf, &streamsize);
+ if (!f)
+ return;
+ save_dive(f, dive);
+ fclose(f);
+
+ /*
+ * Parse the memory buffer into XML document and
+ * transform it to divelogs.de format, finally dumping
+ * the XML into a character buffer.
+ */
+
+ doc = xmlReadMemory(membuf, strlen(membuf), "divelog", NULL, 0);
+ if (!doc)
+ continue;
+
+ xslt = get_stylesheet("divelogs-export.xslt");
+ transformed = xsltApplyStylesheet(xslt, doc, NULL);
+ xsltFreeStylesheet(xslt);
+ xmlDocDumpMemory(transformed, (xmlChar **) &membuf, (int *)&streamsize);
+ xmlFreeDoc(doc);
+ xmlFreeDoc(transformed);
+
+ /*
+ * Save the XML document into a zip file.
+ */
+
+ snprintf(filename, PATH_MAX, "%d.xml", i + 1);
+ if ((s[i]=zip_source_buffer(zip, membuf, streamsize, 0)) == NULL || zip_add(zip, filename, s[i]) == -1)
+ fprintf(stderr, "failed to include dive %d\n", i);
+
+ }
+ zip_close(zip);
+
+ /*
+ * divelogs.de upload functionality should get rid of this
+ * message and use proper dialog to inform user of the success
+ * or failure of the upload
+ */
+
+ fprintf(stderr, "Created .DLD file %s\n", tempfile);
+ free(template);
+}
+#endif
+
static void merge_dive_index(int i, struct dive *a)
{
struct dive *b = get_dive(i+1);
@@ -2034,6 +2128,9 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
char deleteplurallabel[] = N_("Delete dives");
char deletesinglelabel[] = N_("Delete dive");
char *deletelabel;
+#if defined(LIBZIP) && defined(XSLT)
+ char exportlabel[] = N_("Export dive(s)");
+#endif
GtkTreePath *path, *prevpath, *nextpath;
GtkTreeIter iter, previter, nextiter;
int idx, previdx, nextidx;
@@ -2101,6 +2198,12 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
g_signal_connect(menuitem, "activate", G_CALLBACK(delete_selected_dives_cb), path);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+#if defined(LIBZIP) && defined(XSLT)
+ menuitem = gtk_menu_item_new_with_label(exportlabel);
+ g_signal_connect(menuitem, "activate", G_CALLBACK(export_selected_dives_cb), path);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+#endif
+
menuitem = gtk_menu_item_new_with_label(editlabel);
g_signal_connect(menuitem, "activate", G_CALLBACK(edit_selected_dives_cb), NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
diff --git a/parse-xml.c b/parse-xml.c
index 76c470506..4cdc3d8ab 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -1827,7 +1827,7 @@ static xsltStylesheetPtr try_get_stylesheet(const char *path, int len, const cha
return ret;
}
-static xsltStylesheetPtr get_stylesheet(const char *name)
+xsltStylesheetPtr get_stylesheet(const char *name)
{
const char *path, *next;
diff --git a/xslt/commonTemplates.xsl b/xslt/commonTemplates.xsl
index a9aa44279..cd4ee993e 100644
--- a/xslt/commonTemplates.xsl
+++ b/xslt/commonTemplates.xsl
@@ -98,4 +98,30 @@
</xsl:choose>
</xsl:template>
+ <xsl:template name="time2sec">
+ <xsl:param name="time"/>
+
+ <xsl:value-of select="substring-before($time, ':') * 60 + substring-before(substring-after($time, ':'), ' ')"/>
+ </xsl:template>
+
+ <!-- Calculate sum of all parameters, and strip any unit following the
+ value -->
+ <xsl:template name="sum">
+ <xsl:param name="values"/>
+ <xsl:param name="sum" select="'0'"/>
+
+ <xsl:variable name="value" select="substring-before($values[1], ' ')"/>
+ <xsl:choose>
+ <xsl:when test="count($values) = 1">
+ <xsl:value-of select="format-number($value + $sum, '#.#')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="sum">
+ <xsl:with-param name="values" select="$values[position() &gt; 1]"/>
+ <xsl:with-param name="sum" select="$sum + $value"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
</xsl:stylesheet>