summaryrefslogtreecommitdiffstats
path: root/divelist.c
diff options
context:
space:
mode:
authorGravatar Miika Turkia <miika.turkia@gmail.com>2013-03-24 10:00:25 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-03-24 06:37:56 -0700
commit12d5ab4ce31756999fc34a56c50f54dc585d8bbb (patch)
treed3d262c988ca6e5d6eb9436ae51032bb9bc47480 /divelist.c
parentca0ecc234adc8948e093f47feaf622435849f48a (diff)
downloadsubsurface-12d5ab4ce31756999fc34a56c50f54dc585d8bbb.tar.gz
Export dives to UDDF file
This patch implements exporting dives from Subsurface to UDDF format. Events and cylinder info are the most remarkable things still missing from the export. Signed-off-by: Miika Turkia <miika.turkia@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'divelist.c')
-rw-r--r--divelist.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/divelist.c b/divelist.c
index c25ee6271..198e2d643 100644
--- a/divelist.c
+++ b/divelist.c
@@ -2102,6 +2102,92 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
}
#endif
+#if defined(XSLT)
+static void export_dives_uddf(const gboolean selected)
+{
+ FILE *f;
+ char *filename = NULL;
+ size_t streamsize;
+ char *membuf;
+ xmlDoc *doc;
+ xsltStylesheetPtr xslt = NULL;
+ xmlDoc *transformed;
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new(_("Export As UDDF File"),
+ GTK_WINDOW(main_window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ }
+ gtk_widget_destroy(dialog);
+
+ if (!filename)
+ return;
+
+ /* Save XML to file and convert it into a memory buffer */
+ save_dives_logic(filename, selected);
+ f = fopen(filename, "r");
+ fseek(f, 0, SEEK_END);
+ streamsize = ftell(f);
+ rewind(f);
+
+ membuf = malloc(streamsize + 1);
+ if (!membuf || !fread(membuf, streamsize, 1, f)) {
+ fprintf(stderr, "Failed to read memory buffer\n");
+ return;
+ }
+ membuf[streamsize] = 0;
+ fclose(f);
+ g_unlink(filename);
+
+ /*
+ * Parse the memory buffer into XML document and
+ * transform it to UDDF format, finally dumping
+ * the XML into a character buffer.
+ */
+ doc = xmlReadMemory(membuf, strlen(membuf), "divelog", NULL, 0);
+ if (!doc) {
+ fprintf(stderr, "Failed to read XML memory\n");
+ return;
+ }
+ free((void *)membuf);
+
+ /* Convert to UDDF format */
+ xslt = get_stylesheet("uddf-export.xslt");
+ if (!xslt) {
+ fprintf(stderr, "Failed to open UDDF conversion stylesheet\n");
+ return;
+ }
+ transformed = xsltApplyStylesheet(xslt, doc, NULL);
+ xsltFreeStylesheet(xslt);
+ xmlFreeDoc(doc);
+
+ /* Write the transformed XML to file */
+ f = g_fopen(filename, "w");
+ xmlDocFormatDump(f, transformed, 1);
+ xmlFreeDoc(transformed);
+
+ fclose(f);
+ g_free(filename);
+}
+
+static void export_selected_dives_uddf_cb(GtkWidget *menuitem, GtkTreePath *path)
+{
+ export_dives_uddf(TRUE);
+}
+
+void export_all_dives_uddf_cb()
+{
+ export_dives_uddf(FALSE);
+}
+#endif
+
static void merge_dive_index(int i, struct dive *a)
{
struct dive *b = get_dive(i+1);
@@ -2171,6 +2257,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(XSLT)
+ char exportuddflabel[] = N_("Export dive(s) to UDDF");
+#endif
#if defined(LIBZIP) && defined(XSLT)
char exportlabel[] = N_("Export dive(s)");
#endif
@@ -2247,6 +2336,12 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
#endif
+#if defined(XSLT)
+ menuitem = gtk_menu_item_new_with_label(exportuddflabel);
+ g_signal_connect(menuitem, "activate", G_CALLBACK(export_selected_dives_uddf_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);