Save and parse notes and locations

It's pretty rough, but it seems to work.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2011-09-01 19:56:04 -07:00
parent 0189de695c
commit 22fcef2ec7
4 changed files with 130 additions and 11 deletions

5
dive.h
View file

@ -104,6 +104,8 @@ struct sample {
struct dive { struct dive {
const char *name; const char *name;
time_t when; time_t when;
char *location;
char *notes;
depth_t maxdepth, meandepth; depth_t maxdepth, meandepth;
duration_t duration, surfacetime; duration_t duration, surfacetime;
depth_t visibility; 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_init(void);
extern void parse_xml_file(const char *filename); 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 */ #endif /* DIVE_H */

64
info.c
View file

@ -6,7 +6,9 @@
#include "display.h" #include "display.h"
static GtkWidget *divedate, *divetime, *depth, *duration; 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) static const char *weekday(int wday)
{ {
@ -16,10 +18,42 @@ static const char *weekday(int wday)
return wday_array[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) void update_dive_info(struct dive *dive)
{ {
struct tm *tm; struct tm *tm;
char buffer[80]; char buffer[80];
char *text;
flush_dive_info_changes();
buffered_dive = dive;
if (!dive) { if (!dive) {
gtk_label_set_text(GTK_LABEL(divedate), "no dive"); gtk_label_set_text(GTK_LABEL(divedate), "no dive");
@ -50,6 +84,11 @@ void update_dive_info(struct dive *dive)
"%d min", "%d min",
dive->duration.seconds / 60); dive->duration.seconds / 60);
gtk_label_set_text(GTK_LABEL(duration), buffer); 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) static GtkWidget *info_label(GtkWidget *box, const char *str)
@ -80,14 +119,20 @@ GtkWidget *dive_info_frame(void)
return frame; 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); GtkWidget *frame = gtk_frame_new(label);
gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0);
gtk_container_add(GTK_CONTAINER(frame), entry);
return entry; 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) GtkWidget *extended_dive_info_frame(void)
@ -101,9 +146,8 @@ GtkWidget *extended_dive_info_frame(void)
vbox = gtk_vbox_new(FALSE, 5); vbox = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(frame), vbox); gtk_container_add(GTK_CONTAINER(frame), vbox);
location = text_entry(vbox, "Location"); location = text_entry(vbox, "Location", FALSE);
notes = text_entry(vbox, "Notes"); notes = text_entry(vbox, "Notes", TRUE);
location = gtk_entry_new();
/* Add extended info here: name, description, yadda yadda */ /* Add extended info here: name, description, yadda yadda */
update_dive_info(current_dive); update_dive_info(current_dive);

View file

@ -349,6 +349,11 @@ static void gasmix_nitrogen(char *buffer, void *_gasmix)
/* Ignore n2 percentages. There's no value in them. */ /* 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) \ #define MATCH(pattern, fn, dest) \
match(pattern, strlen(pattern), name, len, fn, buf, 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; return;
if (MATCH(".cylinderendpressure", pressure, &dive->end_pressure)) if (MATCH(".cylinderendpressure", pressure, &dive->end_pressure))
return; 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)) if (MATCH(".o2", gasmix, &dive->gasmix[gasmix_index].o2))
return; return;

View 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); 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) static void save_overview(FILE *f, struct dive *dive)
{ {
show_depth(f, dive->maxdepth, " <maxdepth>", "</maxdepth>\n"); 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_duration(f, dive->surfacetime, " <surfacetime>", "</surfacetime>\n");
show_pressure(f, dive->beginning_pressure, " <cylinderstartpressure>", "</cylinderstartpressure>\n"); show_pressure(f, dive->beginning_pressure, " <cylinderstartpressure>", "</cylinderstartpressure>\n");
show_pressure(f, dive->end_pressure, " <cylinderendpressure>", "</cylinderendpressure>\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) static void save_gasmix(FILE *f, struct dive *dive)
@ -106,6 +165,10 @@ void save_dives(const char *filename)
if (!f) if (!f)
return; 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); fprintf(f, "<dives>\n<program name='diveclog' version='%d'></program>\n", VERSION);
for (i = 0; i < dive_table.nr; i++) for (i = 0; i < dive_table.nr; i++)
save_dive(f, get_dive(i)); save_dive(f, get_dive(i));