diff options
-rw-r--r-- | dive.h | 5 | ||||
-rw-r--r-- | gtk-gui.c | 99 | ||||
-rw-r--r-- | parse-xml.c | 51 | ||||
-rw-r--r-- | profile.c | 2 | ||||
-rw-r--r-- | save-xml.c | 17 |
5 files changed, 137 insertions, 37 deletions
@@ -528,8 +528,9 @@ extern void dive_list_update_dives(void); extern void flush_divelist(struct dive *dive); extern void set_dc_nickname(struct dive *dive); -extern const char *get_dc_nickname(uint32_t deviceid); -extern void remember_dc(uint32_t deviceid, const char *model, const char *nickname, gboolean change_conf); +extern const char *get_dc_nickname(const char *model, uint32_t deviceid); +extern void remember_dc(const char *model, uint32_t deviceid, const char *nickname, gboolean change_conf); +extern void add_dc_to_string(char **dc_xml, struct divecomputer *dc); #define DIVE_ERROR_PARSE 1 @@ -1245,7 +1245,7 @@ void init_ui(int *argcp, char ***argvp) *nameend = '\0'; nickname = strdup(namestart); } - remember_dc(deviceid, model, nickname, FALSE); + remember_dc(model, deviceid, nickname, FALSE); next_token = nameend + 1; }; } @@ -2047,40 +2047,41 @@ void set_filename(const char *filename, gboolean force) existing_filename = NULL; } -const char *get_dc_nickname(uint32_t deviceid) +/* just find the entry for this divecomputer */ +static struct dcnicknamelist *get_dc_nicknameentry(const char *model, int deviceid) { struct dcnicknamelist *known = nicknamelist; + if (!model) + model = ""; while (known) { - if (known->deviceid == deviceid) { - if (known->nickname && *known->nickname) - return known->nickname; - else - return known->model; - } + if (!strcmp(known->model, model) && known->deviceid == deviceid) + return known; known = known->next; } return NULL; } -/* do we have a DIFFERENT divecomputer of the same model? */ -static struct dcnicknamelist *get_different_dc_nicknameentry(const char *model, int deviceid) +const char *get_dc_nickname(const char *model, uint32_t deviceid) { - struct dcnicknamelist *known = nicknamelist; - while (known) { - if (known->model && model && !strcmp(known->model, model) && - known->deviceid != deviceid) - return known; - known = known->next; + struct dcnicknamelist *known = get_dc_nicknameentry(model, deviceid); + if (known) { + if (known->nickname && *known->nickname) + return known->nickname; + else + return known->model; } return NULL; } -/* just fine the entry for this divecomputer */ -static struct dcnicknamelist *get_dc_nicknameentry(int deviceid) +/* do we have a DIFFERENT divecomputer of the same model? */ +static struct dcnicknamelist *get_different_dc_nicknameentry(const char *model, int deviceid) { struct dcnicknamelist *known = nicknamelist; + if (!model) + model = ""; while (known) { - if (known->deviceid == deviceid) + if (known->model && !strcmp(known->model, model) && + known->deviceid != deviceid) return known; known = known->next; } @@ -2114,16 +2115,18 @@ static char *cleanedup_nickname(const char *nickname, int len) return clean; } -void replace_nickname_nicknamestring(int deviceid, const char *nickname) +void replace_nickname_nicknamestring(const char *model, int deviceid, const char *nickname) { char buf[11]; char *entry, *comma1, *comma2, *brace, *new_nn; int len; + if (!nickname) + nickname = ""; snprintf(buf, sizeof(buf), "{%08x,", deviceid); entry = strstr(nicknamestring, buf); if (!entry) - /* this cannot happen as we know have an entry for this deviceid */ + /* this cannot happen as we know we have an entry for this deviceid */ goto bail; len = strlen(entry); comma1 = g_utf8_strchr(entry, len, ','); @@ -2145,9 +2148,9 @@ void replace_nickname_nicknamestring(int deviceid, const char *nickname) } new_nn = malloc(len); if (strlen(nickname)) - snprintf(new_nn, len, "%s,%s}%s", entry, nickname, brace + 1); + snprintf(new_nn, len, "%s,%s}%s", nicknamestring, nickname, brace + 1); else - snprintf(new_nn, len, "%s}%s", entry, brace + 1); + snprintf(new_nn, len, "%s}%s", nicknamestring, brace + 1); free(nicknamestring); nicknamestring = new_nn; return; @@ -2158,9 +2161,11 @@ bail: } -void remember_dc(uint32_t deviceid, const char *model, const char *nickname, gboolean change_conf) +void remember_dc(const char *model, uint32_t deviceid, const char *nickname, gboolean change_conf) { - if (!get_dc_nickname(deviceid)) { + if (!nickname) + nickname = ""; + if (!get_dc_nickname(model, deviceid)) { char buffer[160]; struct dcnicknamelist *nn_entry = malloc(sizeof(struct dcnicknamelist)); nn_entry->deviceid = deviceid; @@ -2180,11 +2185,11 @@ void remember_dc(uint32_t deviceid, const char *model, const char *nickname, gbo subsurface_set_conf("dc_nicknames", PREF_STRING, nicknamestring); } else { /* modify existing entry */ - struct dcnicknamelist *nn_entry = get_dc_nicknameentry(deviceid); + struct dcnicknamelist *nn_entry = get_dc_nicknameentry(model, deviceid); if (!nn_entry->model || !*nn_entry->model) nn_entry->model = model; nn_entry->nickname = nickname; - replace_nickname_nicknamestring(deviceid, nickname); + replace_nickname_nicknamestring(model, deviceid, nickname); } #if defined(NICKNAME_DEBUG) struct dcnicknamelist *nn_entry = nicknamelist; @@ -2212,12 +2217,12 @@ void set_dc_nickname(struct dive *dive) #if NICKNAME_DEBUG & 16 fprintf(debugfile, "set_dc_nickname for model %s deviceid %8x\n", dc->model ? : "", dc->deviceid); #endif - if (get_dc_nickname(dc->deviceid) == NULL) { + if (get_dc_nickname(dc->model, dc->deviceid) == NULL) { struct dcnicknamelist *nn_entry = get_different_dc_nicknameentry(dc->model, dc->deviceid); if (!nn_entry) { /* just remember the dive computer without setting a nickname */ if (dc->model) - remember_dc(dc->deviceid, dc->model, "", TRUE); + remember_dc(dc->model, dc->deviceid, "", TRUE); } else { dialog = gtk_dialog_new_with_buttons( _("Dive Computer Nickname"), @@ -2255,9 +2260,43 @@ void set_dc_nickname(struct dive *dive) name = cleanedup_nickname(gtk_entry_get_text(GTK_ENTRY(entry)), sizeof(nickname)); } gtk_widget_destroy(dialog); - remember_dc(dc->deviceid, dc->model, name, TRUE); + remember_dc(dc->model, dc->deviceid, name, TRUE); } } dc = dc->next; } } + +void add_dc_to_string(char **dc_xml, struct divecomputer *dc) +{ + char *pattern, *tmp; + const char *nickname; + int len; + + if (!dc || !dc->model || !*dc->model) + /* we have no dc or no model information... nothing to do here */ + return; + len = sizeof(" model='' deviceid=''") + strlen(dc->model) + 8; + pattern = malloc(len); + snprintf(pattern, len, " model='%s' deviceid='%08x'", dc->model, dc->deviceid); + if (*dc_xml && strstr(*dc_xml, pattern)) { + /* already have that one */ + free(pattern); + return; + } + nickname = get_dc_nickname(dc->model, dc->deviceid); + if (!nickname || !*nickname || !strcmp(dc->model, nickname)) { + /* we still want to store this entry as it explicitly tells us + * "no nickname needed, use model" */ + len += strlen(*dc_xml) + sizeof("<divecomputerid/>\n"); + tmp = malloc(len); + snprintf(tmp, len, "%s<divecomputerid%s/>\n", *dc_xml, pattern); + } else { + len += strlen(*dc_xml) + strlen(nickname) + sizeof("<divecomputerid nickname=''/>\n"); + tmp = malloc(len); + snprintf(tmp, len, "%s<divecomputerid%s nickname='%s'/>\n", *dc_xml, pattern, nickname); + } + free(pattern); + free(*dc_xml); + *dc_xml = tmp; +} diff --git a/parse-xml.c b/parse-xml.c index 57c4dd1cd..f82338b8a 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -145,6 +145,14 @@ static struct { int type, flags, value; const char *name; } cur_event; +static struct { +struct { + const char *model; + uint32_t deviceid; + const char *nickname; +} dc; +} cur_settings; +static gboolean in_settings = FALSE; static struct tm cur_tm; static int cur_cylinder_index, cur_ws_index; static int lastndl, laststoptime, laststopdepth, lastcns, lastpo2; @@ -592,6 +600,21 @@ static void eventtime(char *buffer, void *_duration) duration->seconds += cur_sample->time.seconds; } +static void try_to_fill_dc_settings(const char *name, char *buf) +{ + int len = strlen(name); + + start_match("divecomputerid", name, buf); + if (MATCH(".model", utf8_string, &cur_settings.dc.model)) + return; + if (MATCH(".deviceid", hex_value, &cur_settings.dc.deviceid)) + return; + if (MATCH(".nickname", utf8_string, &cur_settings.dc.nickname)) + return; + + nonmatch("divecomputerid", name, buf); +} + static void try_to_fill_event(const char *name, char *buf) { int len = strlen(name); @@ -988,6 +1011,29 @@ static void reset_dc_info(struct divecomputer *dc) lastcns = lastpo2 = lastndl = laststoptime = laststopdepth = 0; } +static void reset_dc_settings(void) +{ + free((void *)cur_settings.dc.model); + free((void *)cur_settings.dc.nickname); + cur_settings.dc.model = NULL; + cur_settings.dc.nickname = NULL; + cur_settings.dc.deviceid = 0; +} + +static void dc_settings_start(void) +{ + in_settings = TRUE; + reset_dc_settings(); +} + +static void dc_settings_end(void) +{ + in_settings = FALSE; + if (cur_settings.dc.model) + remember_dc(cur_settings.dc.model, cur_settings.dc.deviceid, cur_settings.dc.nickname, TRUE); + reset_dc_settings(); +} + static void dive_start(void) { if (cur_dive) @@ -1137,6 +1183,10 @@ static void entry(const char *name, int size, const char *raw) return; memcpy(buf, raw, size); buf[size] = 0; + if (in_settings) { + try_to_fill_dc_settings(name, buf); + return; + } if (cur_event.active) { try_to_fill_event(name, buf); return; @@ -1271,6 +1321,7 @@ static struct nesting { const char *name; void (*start)(void), (*end)(void); } nesting[] = { + { "divecomputerid", dc_settings_start, dc_settings_end }, { "dive", dive_start, dive_end }, { "Dive", dive_start, dive_end }, { "trip", trip_start, trip_end }, @@ -1879,7 +1879,7 @@ void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale) cairo_stroke(gc->cr); /* Put the dive computer name in the lower left corner */ - nickname = get_dc_nickname(dc->deviceid); + nickname = get_dc_nickname(dc->model, dc->deviceid); if (!nickname || *nickname == '\0') nickname = dc->model; if (nickname) { diff --git a/save-xml.c b/save-xml.c index fb9eb413a..88ae4e1e9 100644 --- a/save-xml.c +++ b/save-xml.c @@ -443,13 +443,14 @@ static void save_dive(FILE *f, struct dive *dive) fprintf(f, "</dive>\n"); } -#define VERSION 1 +#define VERSION 2 void save_dives(const char *filename) { int i; struct dive *dive; dive_trip_t *trip = NULL; + char *dc_xml = strdup(""); FILE *f = g_fopen(filename, "w"); @@ -459,8 +460,16 @@ void save_dives(const char *filename) /* Flush any edits of current dives back to the dives! */ update_dive(current_dive); - fprintf(f, "<dives>\n<program name='subsurface' version='%d'></program>\n", VERSION); - + fprintf(f, "<divelog program='subsurface' version='%d'>\n<settings>\n", VERSION); + for_each_dive(i, dive) { + struct divecomputer *dc = &dive->dc; + while (dc) { + add_dc_to_string(&dc_xml, dc); + dc = dc->next; + } + } + fprintf(f, dc_xml); + fprintf(f, "</settings>\n<dives>\n"); /* save the dives */ for_each_dive(i, dive) { dive_trip_t *thistrip = dive->divetrip; @@ -477,6 +486,6 @@ void save_dives(const char *filename) } if (trip) fprintf(f, "</trip>\n"); - fprintf(f, "</dives>\n"); + fprintf(f, "</dives>\n</divelog>\n"); fclose(f); } |