]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Save and parse notes and locations
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Sep 2011 02:56:04 +0000 (19:56 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Sep 2011 02:56:04 +0000 (19:56 -0700)
It's pretty rough, but it seems to work.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
dive.h
info.c
parse-xml.c
save-xml.c

diff --git a/dive.h b/dive.h
index 15a357f8998ec32bc29ff02351d65c7712507403..c1b95e3f6bd2293a5556a957f64d61dd441fc057 100644 (file)
--- a/dive.h
+++ b/dive.h
@@ -104,6 +104,8 @@ struct sample {
 struct dive {
        const char *name;
        time_t when;
+       char *location;
+       char *notes;
        depth_t maxdepth, meandepth;
        duration_t duration, surfacetime;
        depth_t visibility;
@@ -133,6 +135,7 @@ static inline struct dive *get_dive(unsigned int nr)
 extern void parse_xml_init(void);
 extern void parse_xml_file(const char *filename);
 
-void save_dives(const char *filename);
+extern void flush_dive_info_changes(void);
+extern void save_dives(const char *filename);
 
 #endif /* DIVE_H */
diff --git a/info.c b/info.c
index 547b5d1190f19b4559eb491daef0312e77b9b33c..3adbe15d191446d0495285c13f16b6666f3b2afe 100644 (file)
--- a/info.c
+++ b/info.c
@@ -6,7 +6,9 @@
 #include "display.h"
 
 static GtkWidget *divedate, *divetime, *depth, *duration;
-static GtkWidget *location, *notes;
+static GtkTextBuffer *location, *notes;
+static int location_changed = 1, notes_changed = 1;
+static struct dive *buffered_dive;
 
 static const char *weekday(int wday)
 {
@@ -16,10 +18,42 @@ static const char *weekday(int wday)
        return wday_array[wday];
 }
 
+static char *get_text(GtkTextBuffer *buffer)
+{
+       GtkTextIter start;
+       GtkTextIter end;
+
+       gtk_text_buffer_get_start_iter(buffer, &start);
+       gtk_text_buffer_get_end_iter(buffer, &end);
+       return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+}
+
+void flush_dive_info_changes(void)
+{
+       struct dive *dive = buffered_dive;
+
+       if (!dive)
+               return;
+
+       if (location_changed) {
+               g_free(dive->location);
+               dive->location = get_text(location);
+       }
+
+       if (notes_changed) {
+               g_free(dive->notes);
+               dive->notes = get_text(notes);
+       }
+}
+
 void update_dive_info(struct dive *dive)
 {
        struct tm *tm;
        char buffer[80];
+       char *text;
+
+       flush_dive_info_changes();
+       buffered_dive = dive;
 
        if (!dive) {
                gtk_label_set_text(GTK_LABEL(divedate), "no dive");
@@ -50,6 +84,11 @@ void update_dive_info(struct dive *dive)
                "%d min",
                dive->duration.seconds / 60);
        gtk_label_set_text(GTK_LABEL(duration), buffer);
+
+       text = dive->location ? : "";
+       gtk_text_buffer_set_text(location, text, -1);
+       text = dive->notes ? : "";
+       gtk_text_buffer_set_text(notes, text, -1);
 }
 
 static GtkWidget *info_label(GtkWidget *box, const char *str)
@@ -80,14 +119,20 @@ GtkWidget *dive_info_frame(void)
        return frame;
 }
 
-static GtkWidget *text_entry(GtkWidget *box, const char *label)
+static GtkTextBuffer *text_entry(GtkWidget *box, const char *label, gboolean expand)
 {
-       GtkWidget *entry;
+       GtkWidget *view;
+       GtkTextBuffer *buffer;
+
        GtkWidget *frame = gtk_frame_new(label);
-       gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
-       entry = gtk_entry_new();
-       gtk_container_add(GTK_CONTAINER(frame), entry);
-       return entry;
+
+       gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0);
+
+       view = gtk_text_view_new ();
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+       gtk_container_add(GTK_CONTAINER(frame), view);
+       return buffer;
 }
 
 GtkWidget *extended_dive_info_frame(void)
@@ -101,9 +146,8 @@ GtkWidget *extended_dive_info_frame(void)
        vbox = gtk_vbox_new(FALSE, 5);
        gtk_container_add(GTK_CONTAINER(frame), vbox);
 
-       location = text_entry(vbox, "Location");
-       notes = text_entry(vbox, "Notes");
-       location = gtk_entry_new();
+       location = text_entry(vbox, "Location", FALSE);
+       notes = text_entry(vbox, "Notes", TRUE);
 
        /* Add extended info here: name, description, yadda yadda */
        update_dive_info(current_dive);
index 6c93ad1a534e1f6fc7e5bf4dae944eeb7032fd75..86ef31ade91369ba0a1f3750acf03e49097dbaee 100644 (file)
@@ -349,6 +349,11 @@ static void gasmix_nitrogen(char *buffer, void *_gasmix)
        /* Ignore n2 percentages. There's no value in them. */
 }
 
+static void utf8_string(char *buffer, void *_res)
+{
+       *(char **)_res = buffer;
+}
+
 #define MATCH(pattern, fn, dest) \
        match(pattern, strlen(pattern), name, len, fn, buf, dest)
 
@@ -423,6 +428,10 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
                return;
        if (MATCH(".cylinderendpressure", pressure, &dive->end_pressure))
                return;
+       if (MATCH(".location", utf8_string, &dive->location))
+               return;
+       if (MATCH(".notes", utf8_string, &dive->notes))
+               return;
 
        if (MATCH(".o2", gasmix, &dive->gasmix[gasmix_index].o2))
                return;
index efff300886b54fe6a03031bff53b3d160802146f..cd7bad2bad547e652529a301ab8dba9dee3f55cd 100644 (file)
@@ -40,6 +40,63 @@ static void show_pressure(FILE *f, pressure_t pressure, const char *pre, const c
                fprintf(f, "%s%u.%03u bar%s", pre, FRACTION(pressure.mbar, 1000), post);
 }
 
+/*
+ * We're outputting utf8 in xml.
+ * We need to quote the characters <, >, &.
+ *
+ * Nothing else (and if we ever do this using attributes, we'd need to
+ * quote the quotes we use too).
+ */
+static void quote(FILE *f, const char *text)
+{
+       const char *p = text;
+
+       for (;;) {
+               const char *escape;
+
+               switch (*p++) {
+               default:
+                       continue;
+               case 0:
+                       escape = NULL;
+                       break;
+               case '<':
+                       escape = "&lt;";
+                       break;
+               case '>':
+                       escape = "&gt;";
+                       break;
+               case '&':
+                       escape = "&amp;";
+                       break;
+               }
+               fwrite(text, (p - text - 1), 1, f);
+               if (!escape)
+                       break;
+               fputs(escape, f);
+               text = p;
+       }
+}
+
+static void show_utf8(FILE *f, const char *text, const char *pre, const char *post)
+{
+       int len;
+
+       if (!text)
+               return;
+       while (isspace(*text))
+               text++;
+       len = strlen(text);
+       if (!len)
+               return;
+       while (len && isspace(text[len-1]))
+               len--;
+       /* FIXME! Quoting! */
+       fputs(pre, f);
+       quote(f, text);
+       fputs(post, f);
+}
+
 static void save_overview(FILE *f, struct dive *dive)
 {
        show_depth(f, dive->maxdepth, "  <maxdepth>", "</maxdepth>\n");
@@ -50,6 +107,8 @@ static void save_overview(FILE *f, struct dive *dive)
        show_duration(f, dive->surfacetime, "  <surfacetime>", "</surfacetime>\n");
        show_pressure(f, dive->beginning_pressure, "  <cylinderstartpressure>", "</cylinderstartpressure>\n");
        show_pressure(f, dive->end_pressure, "  <cylinderendpressure>", "</cylinderendpressure>\n");
+       show_utf8(f, dive->location, "  <location>","</location>\n");
+       show_utf8(f, dive->notes, "  <notes>","</notes>\n");
 }
 
 static void save_gasmix(FILE *f, struct dive *dive)
@@ -106,6 +165,10 @@ void save_dives(const char *filename)
 
        if (!f)
                return;
+
+       /* Flush any edits of current dives back to the dives! */
+       flush_dive_info_changes();
+
        fprintf(f, "<dives>\n<program name='diveclog' version='%d'></program>\n", VERSION);
        for (i = 0; i < dive_table.nr; i++)
                save_dive(f, get_dive(i));