diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-12-21 21:00:06 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-12-22 20:14:34 -0800 |
commit | 50aa6d1afa38a3d71d9d699fbf9635aed34a6c14 (patch) | |
tree | 5263825db515693a307f6d5ff2e79014ef9cc14d | |
parent | 8d2abc05f60cb9a5ec79db9a215fe8aa97e0c311 (diff) | |
download | subsurface-50aa6d1afa38a3d71d9d699fbf9635aed34a6c14.tar.gz |
Imrpove the nickname handling
We now store the model information together with the deviceid and nickname
in order to be able to check if we have a record for any dive computer
with the same model (as that now triggers our nickname dialog).
This changes the format of the config entries for nicknames - the best
solution might be to just delete those and start again.
What is still missing is the code to store the nicknames in the XML file.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | dive.h | 2 | ||||
-rw-r--r-- | gtk-gui.c | 159 | ||||
-rw-r--r-- | main.c | 15 |
3 files changed, 124 insertions, 52 deletions
@@ -529,7 +529,7 @@ 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 *nickname, gboolean change_conf); +extern void remember_dc(uint32_t deviceid, const char *model, const char *nickname, gboolean change_conf); #define DIVE_ERROR_PARSE 1 @@ -41,6 +41,7 @@ struct preferences prefs = { struct dcnicknamelist { const char *nickname; + const char *model; uint32_t deviceid; struct dcnicknamelist *next; }; @@ -1204,7 +1205,7 @@ void init_ui(int *argcp, char ***argvp) conf_value = subsurface_get_conf("dc_nicknames", PREF_STRING); nicknamestring = strdup(""); if (conf_value) { - char *next_token, *nickname; + char *next_token, *nickname, *model; uint32_t deviceid; int len; next_token = strdup(conf_value); @@ -1212,16 +1213,35 @@ void init_ui(int *argcp, char ***argvp) while ((next_token = g_utf8_strchr(next_token, len, '{')) != NULL) { /* replace the '{' so we keep looking in case any test fails */ *next_token = '('; - /* the next 8 chars are the deviceid, after that we have the utf8 nickname */ + /* the next 8 chars are the deviceid, after that we have the model + * and the utf8 nickname (if set) */ if (sscanf(next_token, "(%8x,", &deviceid) > 0) { - char *namestart, *nameend; + char *namestart, *nameend, *tupleend; namestart = g_utf8_strchr(next_token, len, ','); - nameend = g_utf8_strchr(next_token, len, '}'); - if (!namestart || !nameend) - continue; + /* we know that namestart isn't NULL based on the sscanf succeeding */ + len = strlen(namestart + 1); + nameend = g_utf8_strchr(namestart + 1, len, ','); + tupleend = g_utf8_strchr(namestart + 1, len, '}'); + if (!nameend && !tupleend) + /* the config entry is messed up - bail */ + break; + if (!nameend || tupleend < nameend) + nameend = tupleend; *nameend = '\0'; - nickname = strdup(namestart + 1); - remember_dc(deviceid, nickname, FALSE); + model = strdup(namestart + 1); + if (tupleend == nameend) { + /* no nickname */ + nickname = strdup(""); + } else { + namestart = nameend + 1; + len = strlen(namestart); + nameend = g_utf8_strchr(namestart, len, '}'); + if (!nameend) + break; + *nameend = '\0'; + nickname = strdup(namestart); + } + remember_dc(deviceid, model, nickname, FALSE); next_token = nameend + 1; }; } @@ -2027,13 +2047,30 @@ const char *get_dc_nickname(uint32_t deviceid) { struct dcnicknamelist *known = nicknamelist; while (known) { - if (known->deviceid == deviceid) - return known->nickname; + if (known->deviceid == deviceid) { + if (known->nickname && *known->nickname) + return known->nickname; + else + return known->model; + } known = known->next; } return NULL; } +/* do we have a DIFFERENT divecomputer of the same model? */ +static gboolean dc_model_exists(struct divecomputer *dc) +{ + struct dcnicknamelist *known = nicknamelist; + while (known) { + if (known->model && dc->model && !strcmp(known->model, dc->model) && + known->deviceid != dc->deviceid) + return TRUE; + known = known->next; + } + return FALSE; +} + /* no curly braces or commas, please */ static char *cleanedup_nickname(const char *nickname, int len) { @@ -2061,66 +2098,96 @@ static char *cleanedup_nickname(const char *nickname, int len) return clean; } -void remember_dc(uint32_t deviceid, const char *nickname, gboolean change_conf) +void remember_dc(uint32_t deviceid, const char *model, const char *nickname, gboolean change_conf) { if (!get_dc_nickname(deviceid)) { char buffer[160]; struct dcnicknamelist *nn_entry = malloc(sizeof(struct dcnicknamelist)); nn_entry->deviceid = deviceid; + nn_entry->model = model; /* make sure there are no curly braces or commas in the string and that * it will fit in the buffer */ - nn_entry->nickname = cleanedup_nickname(nickname, sizeof(buffer) - 12); + nn_entry->nickname = cleanedup_nickname(nickname, sizeof(buffer) - 13 - strlen(model)); nn_entry->next = nicknamelist; nicknamelist = nn_entry; - snprintf(buffer, sizeof(buffer), "{%08x,%s}", deviceid, nn_entry->nickname); + if (*nickname != '\0') + snprintf(buffer, sizeof(buffer), "{%08x,%s,%s}", deviceid, model, nn_entry->nickname); + else + snprintf(buffer, sizeof(buffer), "{%08x,%s}", deviceid, model); nicknamestring = realloc(nicknamestring, strlen(nicknamestring) + strlen(buffer) + 1); strcat(nicknamestring, buffer); if (change_conf) subsurface_set_conf("dc_nicknames", PREF_STRING, nicknamestring); } +#if defined(NICKNAME_DEBUG) + struct dcnicknamelist *nn_entry = nicknamelist; + fprintf(debugfile, "nicknames:\n"); + while (nn_entry) { + fprintf(debugfile, "id %8x model %s nickname %s\n", nn_entry->deviceid, nn_entry->model, + nn_entry->nickname && *nn_entry->nickname ? nn_entry->nickname : "(none)"); + nn_entry = nn_entry->next; + } + fprintf(debugfile, "----------\n"); +#endif } void set_dc_nickname(struct dive *dive) { GtkWidget *dialog, *vbox, *entry, *frame, *label; char nickname[160] = ""; + char dialogtext[1024]; const char *name = nickname; + struct divecomputer *dc = &dive->dc; if (!dive) return; - - /* we should only do this if we already have a different dive computer - * with the same model -- TBI */ - if (get_dc_nickname(dive->dc.deviceid) == NULL) { - dialog = gtk_dialog_new_with_buttons( - _("Dive Computer Nickname"), - GTK_WINDOW(main_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NULL); - vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - label = gtk_label_new(_("Subsurface can use a nickname for your dive computer.\n" - "The default is the model and device ID as shown below.\n" - "If you don't want to name this dive computer click " - "'Cancel' and Subsurface will simply display its model " - "as nickname.")); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 3); - frame = gtk_frame_new(_("Nickname")); - gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 3); - entry = gtk_entry_new(); - gtk_container_add(GTK_CONTAINER(frame), entry); - gtk_entry_set_max_length(GTK_ENTRY(entry), 68); - snprintf(nickname, sizeof(nickname), "%s (%08x)", dive->dc.model, dive->dc.deviceid); - gtk_entry_set_text(GTK_ENTRY(entry), nickname); - gtk_widget_show_all(dialog); - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - if (strcmp(dive->dc.model, gtk_entry_get_text(GTK_ENTRY(entry)))) - name = cleanedup_nickname(gtk_entry_get_text(GTK_ENTRY(entry)), - sizeof(nickname)); + while (dc) { +#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 (!dc_model_exists(dc)) { + /* just remember the dive computer without setting a nickname */ + if (dc->model) + remember_dc(dc->deviceid, dc->model, "", TRUE); + } else { + dialog = gtk_dialog_new_with_buttons( + _("Dive Computer Nickname"), + GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + snprintf(dialogtext, sizeof(dialogtext), + _("You already have a dive computer of model %s\n" + "Subsurface can maintain a nickname for this device to " + "distinguish it from the existing one. " + "The default is the model and device ID as shown below.\n" + "If you don't want to name this dive computer click " + "'Cancel' and Subsurface will simply display its model " + "as its name (which may mean that you cannot tell the two " + "dive computers apart in the logs."), + dc->model ? dc->model : "(unset)"); + label = gtk_label_new(dialogtext); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 3); + frame = gtk_frame_new(_("Nickname")); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 3); + entry = gtk_entry_new(); + gtk_container_add(GTK_CONTAINER(frame), entry); + gtk_entry_set_max_length(GTK_ENTRY(entry), 68); + snprintf(nickname, sizeof(nickname), "%s (%08x)", dc->model, dc->deviceid); + gtk_entry_set_text(GTK_ENTRY(entry), nickname); + gtk_widget_show_all(dialog); + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + if (strcmp(dc->model, gtk_entry_get_text(GTK_ENTRY(entry)))) + name = cleanedup_nickname(gtk_entry_get_text(GTK_ENTRY(entry)), sizeof(nickname)); + } + gtk_widget_destroy(dialog); + remember_dc(dc->deviceid, dc->model, name, TRUE); + } } - gtk_widget_destroy(dialog); - remember_dc(dive->dc.deviceid, name, TRUE); + dc = dc->next; } } @@ -129,6 +129,10 @@ void report_dives(gboolean is_imported, gboolean prefer_imported) * first one */ if (preexisting < dive_table.nr && dive_table.dives[preexisting]->downloaded) set_dc_nickname(dive_table.dives[preexisting]); + else + /* they aren't downloaded, so record / check all new ones */ + for (i = preexisting; i < dive_table.nr; i++) + set_dc_nickname(dive_table.dives[i]); /* This does the right thing for -1: NULL */ last = get_dive(preexisting-1); @@ -251,11 +255,6 @@ int main(int argc, char **argv) textdomain("subsurface"); output_units = SI_units; - subsurface_command_line_init(&argc, &argv); - parse_xml_init(); - - init_ui(&argc, &argv); - #if DEBUGFILE > 1 debugfile = stderr; #elif defined(DEBUGFILE) @@ -265,6 +264,12 @@ int main(int argc, char **argv) (debugfile = g_fopen(debugfilename, "w")) == NULL) printf("oh boy, can't create debugfile"); #endif + + subsurface_command_line_init(&argc, &argv); + parse_xml_init(); + + init_ui(&argc, &argv); + for (i = 1; i < argc; i++) { const char *a = argv[i]; |