summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2012-12-21 21:00:06 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-12-22 20:14:34 -0800
commit50aa6d1afa38a3d71d9d699fbf9635aed34a6c14 (patch)
tree5263825db515693a307f6d5ff2e79014ef9cc14d
parent8d2abc05f60cb9a5ec79db9a215fe8aa97e0c311 (diff)
downloadsubsurface-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.h2
-rw-r--r--gtk-gui.c159
-rw-r--r--main.c15
3 files changed, 124 insertions, 52 deletions
diff --git a/dive.h b/dive.h
index b7fae2a85..32b7e0027 100644
--- a/dive.h
+++ b/dive.h
@@ -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
diff --git a/gtk-gui.c b/gtk-gui.c
index bb1142e41..4da70f56f 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -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;
}
}
diff --git a/main.c b/main.c
index 465cded78..c5a41590d 100644
--- a/main.c
+++ b/main.c
@@ -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];