summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h4
-rw-r--r--gtk-gui.c137
-rw-r--r--main.c10
-rw-r--r--parse-xml.c2
-rw-r--r--profile.c5
-rw-r--r--save-xml.c2
6 files changed, 158 insertions, 2 deletions
diff --git a/dive.h b/dive.h
index 7927512b7..d504790ae 100644
--- a/dive.h
+++ b/dive.h
@@ -266,6 +266,7 @@ struct event {
struct divecomputer {
timestamp_t when;
const char *model;
+ const char *nickname;
uint32_t deviceid, diveid;
int samples, alloc_samples;
struct sample *sample;
@@ -524,6 +525,9 @@ extern int edit_multi_dive_info(struct dive *single_dive);
extern void dive_list_update_dives(void);
extern void flush_divelist(struct dive *dive);
+extern void set_dc_nickname(struct dive *dive);
+extern void remember_dc(uint32_t deviceid, const char *nickname, gboolean change_conf);
+
#define DIVE_ERROR_PARSE 1
const char *weekday(int wday);
diff --git a/gtk-gui.c b/gtk-gui.c
index 59e62948c..18a022c9d 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -39,6 +39,14 @@ struct preferences prefs = {
FALSE
};
+struct dcnicknamelist {
+ const char *nickname;
+ uint32_t deviceid;
+ struct dcnicknamelist *next;
+};
+static struct dcnicknamelist *nicknamelist;
+char *nicknamestring;
+
static GtkWidget *dive_profile;
static const char *default_dive_computer_vendor;
static const char *default_dive_computer_product;
@@ -1178,6 +1186,33 @@ void init_ui(int *argcp, char ***argvp)
default_dive_computer_vendor = subsurface_get_conf("dive_computer_vendor", PREF_STRING);
default_dive_computer_product = subsurface_get_conf("dive_computer_product", PREF_STRING);
default_dive_computer_device = subsurface_get_conf("dive_computer_device", PREF_STRING);
+ conf_value = subsurface_get_conf("dc_nicknames", PREF_STRING);
+ nicknamestring = strdup("");
+ if (conf_value) {
+ char *next_token, *nickname;
+ uint32_t deviceid;
+ int len;
+ next_token = strdup(conf_value);
+ len = strlen(next_token);
+ 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 */
+ if (sscanf(next_token, "(%8x,", &deviceid) > 0) {
+ char *namestart, *nameend;
+ namestart = g_utf8_strchr(next_token, len, ',');
+ nameend = g_utf8_strchr(next_token, len, '}');
+ if (!namestart || !nameend)
+ continue;
+ *nameend = '\0';
+ nickname = strdup(namestart + 1);
+ remember_dc(deviceid, nickname, FALSE);
+ next_token = nameend + 1;
+ };
+ }
+ free((void *)conf_value);
+ free(next_token);
+ }
error_info_bar = NULL;
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_set_application_name ("subsurface");
@@ -1966,3 +2001,105 @@ void set_filename(const char *filename, gboolean force)
else
existing_filename = NULL;
}
+
+static const char *get_dc_nickname(uint32_t deviceid)
+{
+ struct dcnicknamelist *known = nicknamelist;
+ while (known) {
+ if (known->deviceid == deviceid)
+ return known->nickname;
+ known = known->next;
+ }
+ return NULL;
+}
+
+/* no curly braces or commas, please */
+static char *cleanedup_nickname(const char *nickname, int len)
+{
+ char *clean;
+ if (nickname) {
+ char *brace;
+
+ if (!g_utf8_validate(nickname, -1, NULL))
+ return strdup("");
+ brace = clean = strdup(nickname);
+ while (*brace) {
+ if (*brace == '{')
+ *brace = '(';
+ else if (*brace == '}')
+ *brace = ')';
+ else if (*brace == ',')
+ *brace = '.';
+ brace = g_utf8_next_char(brace);
+ if (*brace && g_utf8_next_char(brace) - clean >= len)
+ *brace = '\0';
+ }
+ } else {
+ clean = strdup("");
+ }
+ return clean;
+}
+
+void remember_dc(uint32_t deviceid, const char *nickname, gboolean change_conf)
+{
+ if (!get_dc_nickname(deviceid)) {
+ char buffer[80];
+ struct dcnicknamelist *nn_entry = malloc(sizeof(struct dcnicknamelist));
+ nn_entry->deviceid = deviceid;
+ /* 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->next = nicknamelist;
+ nicknamelist = nn_entry;
+ snprintf(buffer, 80, "{%08x,%s}", deviceid, nn_entry->nickname);
+ nicknamestring = realloc(nicknamestring, strlen(nicknamestring) + strlen(buffer) + 1);
+ strcat(nicknamestring, buffer);
+ if (change_conf)
+ subsurface_set_conf("dc_nicknames", PREF_STRING, nicknamestring);
+ }
+}
+
+void set_dc_nickname(struct dive *dive)
+{
+ GtkWidget *dialog, *vbox, *entry, *frame, *label;
+ char nickname[68];
+ const char *name;
+
+ if (!dive)
+ return;
+
+ if ((name = get_dc_nickname(dive->dc.deviceid)) != NULL) {
+ dive->dc.nickname = strdup(name);
+ } 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));
+ 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, 69, "%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))))
+ dive->dc.nickname = cleanedup_nickname(gtk_entry_get_text(GTK_ENTRY(entry)),
+ sizeof(nickname));
+ }
+ gtk_widget_destroy(dialog);
+ remember_dc(dive->dc.deviceid, dive->dc.nickname, TRUE);
+ }
+}
diff --git a/main.c b/main.c
index b8d5079cc..44373faf6 100644
--- a/main.c
+++ b/main.c
@@ -124,6 +124,16 @@ void report_dives(gboolean is_imported, gboolean prefer_imported)
int preexisting = dive_table.preexisting;
struct dive *last;
+ /* set the nickname for the divecomputer for newly downloaded dives */
+ for (i = dive_table.preexisting; i < dive_table.nr; i++)
+ if (dive_table.dives[i]->downloaded) {
+ set_dc_nickname(dive_table.dives[i]);
+ } else {
+ struct divecomputer *dc = &dive_table.dives[i]->dc;
+ if (dc->nickname && *dc->nickname)
+ remember_dc(dc->deviceid, dc->nickname, TRUE);
+ }
+
/* This does the right thing for -1: NULL */
last = get_dive(preexisting-1);
diff --git a/parse-xml.c b/parse-xml.c
index 376860e6b..dd35379fb 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -625,6 +625,8 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf)
return;
if (MATCH(".model", utf8_string, &dc->model))
return;
+ if (MATCH(".nickname", utf8_string, &dc->nickname))
+ return;
if (MATCH(".deviceid", hex_value, &dc->deviceid))
return;
if (MATCH(".diveid", hex_value, &dc->diveid))
diff --git a/profile.c b/profile.c
index c8571b8d5..984c5e2c9 100644
--- a/profile.c
+++ b/profile.c
@@ -1857,9 +1857,10 @@ 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 */
- if (dc->model) {
+ if (dc->nickname || dc->model) {
static const text_render_options_t computer = {10, TIME_TEXT, LEFT, MIDDLE};
- plot_text(gc, &computer, 0, 1, "%s", dc->model);
+ plot_text(gc, &computer, 0, 1, "%s",
+ dc->nickname && *dc->nickname ? dc->nickname : dc->model);
}
if (PP_GRAPHS_ENABLED) {
diff --git a/save-xml.c b/save-xml.c
index fb9eb413a..0ec6f27d0 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -400,6 +400,8 @@ static void save_dc(FILE *f, struct dive *dive, struct divecomputer *dc)
fprintf(f, " <divecomputer");
if (dc->model)
show_utf8(f, dc->model, " model='", "'", 1);
+ if (dc->nickname && *dc->nickname)
+ show_utf8(f, dc->nickname, " nickname='", "'", 1);
if (dc->deviceid)
fprintf(f, " deviceid='%08x'", dc->deviceid);
if (dc->diveid)