Store the tag names instead of an opaque number

And as we need the names for that, simplify the way we show the tags in the
Dive Info tab (and mark them for translation while we are at it).

In the process I renamed the constants to DTAG_ from DTYPE_ (and made
their nature as being just bits more obvious).

Also mark the box on the Info tab "Dive Tags", not "Dive Type".

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2013-04-09 13:06:30 -07:00
parent ed3f67bc33
commit 9e4f9fad19
6 changed files with 100 additions and 68 deletions

27
dive.h
View file

@ -28,18 +28,21 @@
#define SEAWATER_SALINITY 10300 #define SEAWATER_SALINITY 10300
#define FRESHWATER_SALINITY 10000 #define FRESHWATER_SALINITY 10000
/* Dive types definition */ /* Dive tag definitions */
#define DTYPE_INVALID 1 #define DTAG_INVALID (1 << 0)
#define DTYPE_BOAT 2 #define DTAG_BOAT (1 << 1)
#define DTYPE_SHORE 4 #define DTAG_SHORE (1 << 2)
#define DTYPE_DRIFT 8 #define DTAG_DRIFT (1 << 3)
#define DTYPE_DEEP 16 #define DTAG_DEEP (1 << 4)
#define DTYPE_CAVERN 32 #define DTAG_CAVERN (1 << 5)
#define DTYPE_ICE 64 #define DTAG_ICE (1 << 6)
#define DTYPE_WRECK 128 #define DTAG_WRECK (1 << 7)
#define DTYPE_CAVE 256 #define DTAG_CAVE (1 << 8)
#define DTYPE_ALTITUDE 512 #define DTAG_ALTITUDE (1 << 9)
#define DTYPE_POOL 1024 #define DTAG_POOL (1 << 10)
#define DTAG_NR 11
/* defined in statistics.c */
extern char *dtag_names[DTAG_NR];
/* /*
* Some silly typedefs to make our units very explicit. * Some silly typedefs to make our units very explicit.

View file

@ -716,7 +716,7 @@ static void fill_dive_list(void)
while (--i >= 0) { while (--i >= 0) {
struct dive *dive = get_dive(i); struct dive *dive = get_dive(i);
dive_trip_t *trip; dive_trip_t *trip;
if ((dive->dive_tags & DTYPE_INVALID) && !prefs.display_invalid_dives) if ((dive->dive_tags & DTAG_INVALID) && !prefs.display_invalid_dives)
continue; continue;
trip = dive->divetrip; trip = dive->divetrip;
@ -1082,14 +1082,14 @@ static void invalid_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
/* now swap the invalid tag if just 1 dive was selected /* now swap the invalid tag if just 1 dive was selected
* otherwise set all to invalid */ * otherwise set all to invalid */
if(amount_selected == 1) { if(amount_selected == 1) {
if (dive->dive_tags & DTYPE_INVALID) if (dive->dive_tags & DTAG_INVALID)
dive->dive_tags &= ~DTYPE_INVALID; dive->dive_tags &= ~DTAG_INVALID;
else else
dive->dive_tags |= DTYPE_INVALID; dive->dive_tags |= DTAG_INVALID;
changed = 1; changed = 1;
} else { } else {
if (! dive->dive_tags & DTYPE_INVALID) { if (! dive->dive_tags & DTAG_INVALID) {
dive->dive_tags |= DTYPE_INVALID; dive->dive_tags |= DTAG_INVALID;
changed = 1; changed = 1;
} }
} }
@ -1682,7 +1682,7 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
if (amount_selected == 1) { if (amount_selected == 1) {
if (dive->dive_tags & DTYPE_INVALID) if (dive->dive_tags & DTAG_INVALID)
menuitem = gtk_menu_item_new_with_label(_("Mark valid")); menuitem = gtk_menu_item_new_with_label(_("Mark valid"));
else else
menuitem = gtk_menu_item_new_with_label(_("Mark invalid")); menuitem = gtk_menu_item_new_with_label(_("Mark invalid"));

36
info.c
View file

@ -893,55 +893,55 @@ static void dive_info_widget(GtkWidget *obox, struct dive *dive, struct dive_inf
gtk_box_pack_start(GTK_BOX(framebox), sbox, TRUE, FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), sbox, TRUE, FALSE, 3);
/* 1st line */ /* 1st line */
button = gtk_check_button_new_with_label(_("Boat Dive")); button = gtk_check_button_new_with_label(_("Boat Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_BOAT); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_BOAT);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_BOAT)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_BOAT));
button = gtk_check_button_new_with_label(_("Shore Dive")); button = gtk_check_button_new_with_label(_("Shore Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_SHORE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_SHORE);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_SHORE)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_SHORE));
button = gtk_check_button_new_with_label(_("Pool Dive")); button = gtk_check_button_new_with_label(_("Pool Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_POOL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_POOL);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_POOL)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_POOL));
sbox = gtk_hbox_new(FALSE, 6); sbox = gtk_hbox_new(FALSE, 6);
gtk_box_pack_start(GTK_BOX(framebox), sbox, TRUE, FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), sbox, TRUE, FALSE, 3);
/* 2nd line */ /* 2nd line */
button = gtk_check_button_new_with_label(_("Drift Dive")); button = gtk_check_button_new_with_label(_("Drift Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_DRIFT); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_DRIFT);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_DRIFT)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_DRIFT));
button = gtk_check_button_new_with_label(_("Deep Dive")); button = gtk_check_button_new_with_label(_("Deep Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_DEEP); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_DEEP);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_DEEP)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_DEEP));
button = gtk_check_button_new_with_label(_("Cavern Dive")); button = gtk_check_button_new_with_label(_("Cavern Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_CAVERN); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_CAVERN);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_CAVERN)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_CAVERN));
sbox = gtk_hbox_new(FALSE, 6); sbox = gtk_hbox_new(FALSE, 6);
gtk_box_pack_start(GTK_BOX(framebox), sbox, TRUE, FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), sbox, TRUE, FALSE, 3);
/* 3rd line */ /* 3rd line */
button = gtk_check_button_new_with_label(_("Ice Dive")); button = gtk_check_button_new_with_label(_("Ice Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_ICE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_ICE);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_ICE)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_ICE));
button = gtk_check_button_new_with_label(_("Wreck Dive")); button = gtk_check_button_new_with_label(_("Wreck Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_WRECK); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_WRECK);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_WRECK)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_WRECK));
button = gtk_check_button_new_with_label(_("Cave Dive")); button = gtk_check_button_new_with_label(_("Cave Dive"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTYPE_CAVE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), dive->dive_tags & DTAG_CAVE);
gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(sbox), button, FALSE, FALSE, 6);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTYPE_CAVE)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(divetag_toggle_cb), GINT_TO_POINTER (DTAG_CAVE));
/* only show notes if editing a single dive */ /* only show notes if editing a single dive */
if (multi) { if (multi) {

View file

@ -200,6 +200,29 @@ static void divedatetime(char *buffer, void *_when)
} }
} }
static void divetags(char *buffer, void *_tags)
{
int *tags = _tags;
int i;
*tags = 0;
for (i = 0; i < DTAG_NR; i++) {
if (strstr(buffer, dtag_names[i])) {
/* stupidly we have 'cave' and 'cavern' */
if (1 << i == DTAG_CAVE) {
char *cave = strstr(buffer, "cave");
while (cave && !strncmp(cave, "cavern", strlen("cavern"))) {
cave++;
cave = strstr(cave, "cave");
}
if (!cave)
continue;
}
*tags |= (1 << i);
}
}
}
enum number_type { enum number_type {
NEITHER, NEITHER,
FLOAT FLOAT
@ -1033,7 +1056,7 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
if (MATCH(".number", get_index, &dive->number)) if (MATCH(".number", get_index, &dive->number))
return; return;
if (MATCH(".tags", get_index, &dive->dive_tags)) if (MATCH(".tags", divetags, &dive->dive_tags))
return; return;
if (MATCH(".tripflag", get_tripflag, &dive->tripflag)) if (MATCH(".tripflag", get_tripflag, &dive->tripflag))
return; return;

View file

@ -391,6 +391,22 @@ static void save_events(FILE *f, struct event *ev)
} }
} }
static void save_tags(FILE *f, int tags)
{
int i, more = 0;
fprintf(f, " tags='");
for (i = 0; i < DTAG_NR; i++) {
if (tags & (1 << i)) {
if (more)
fprintf(f, ", ");
fprintf(f, "%s", dtag_names[i]);
more = 1;
}
}
fprintf(f, "'");
}
static void show_date(FILE *f, timestamp_t when) static void show_date(FILE *f, timestamp_t when)
{ {
struct tm tm; struct tm tm;
@ -452,7 +468,8 @@ void save_dive(FILE *f, struct dive *dive)
if (dive->visibility) if (dive->visibility)
fprintf(f, " visibility='%d'", dive->visibility); fprintf(f, " visibility='%d'", dive->visibility);
if (dive->dive_tags) if (dive->dive_tags)
fprintf(f, " tags='%d'", dive->dive_tags); save_tags(f, dive->dive_tags);
show_date(f, dive->when); show_date(f, dive->when);
fprintf(f, " duration='%u:%02u min'>\n", fprintf(f, " duration='%u:%02u min'>\n",
FRACTION(dive->dc.duration.seconds, 60)); FRACTION(dive->dc.duration.seconds, 60));

View file

@ -15,6 +15,13 @@
#include "display-gtk.h" #include "display-gtk.h"
#include "divelist.h" #include "divelist.h"
/* mark for translation but don't translate here as these terms are used
* in save-xml.c */
char *dtag_names[DTAG_NR] = {
N_("invalid"), N_("boat"), N_("shore"), N_("drift"), N_("deep"), N_("cavern"),
N_("ice"), N_("wreck"), N_("cave"), N_("altitude"), N_("pool")
};
typedef struct { typedef struct {
GtkWidget *date, GtkWidget *date,
*dive_time, *dive_time,
@ -633,35 +640,17 @@ static void show_single_dive_stats(struct dive *dive)
set_label(single_w.gas_used, ""); set_label(single_w.gas_used, "");
} }
/* Dive type */ /* Dive type */
*buf = '\0';
if (dive->dive_tags) { if (dive->dive_tags) {
buf[0]=0; int i, more = 0;
if(dive->dive_tags & DTYPE_INVALID)
strcat(buf, " Invalid,"); for (i = 0; i < DTAG_NR; i++)
if(dive->dive_tags & DTYPE_BOAT) if(dive->dive_tags & (1 << i)) {
strcat(buf, " Boat,"); if (more)
if(dive->dive_tags & DTYPE_SHORE) strcat(buf, ", ");
strcat(buf, " Shore,"); strcat(buf, _(dtag_names[i]));
if(dive->dive_tags & DTYPE_DRIFT) more = 1;
strcat(buf, " Drift,"); }
if(dive->dive_tags & DTYPE_DEEP)
strcat(buf, " Deep,");
if(dive->dive_tags & DTYPE_CAVERN)
strcat(buf, " Cavern,");
if(dive->dive_tags & DTYPE_ICE)
strcat(buf, " Ice,");
if(dive->dive_tags & DTYPE_WRECK)
strcat(buf, " Wreck,");
if(dive->dive_tags & DTYPE_CAVE)
strcat(buf, " Cave,");
if(dive->dive_tags & DTYPE_ALTITUDE)
strcat(buf, " Altitude,");
if(dive->dive_tags & DTYPE_POOL)
strcat(buf, " Pool,");
if(strlen(buf) > 1)
buf[strlen(buf)-1] = 0;
}
else {
buf[0] = 0;
} }
set_label(single_w.dive_type, buf); set_label(single_w.dive_type, buf);
} }
@ -902,7 +891,7 @@ GtkWidget *single_stats_widget(void)
hbox = gtk_hbox_new(FALSE, 3); hbox = gtk_hbox_new(FALSE, 3);
gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3);
single_w.dive_type = new_info_label_in_frame(hbox, _("Dive Type")); single_w.dive_type = new_info_label_in_frame(hbox, _("Dive Tags"));
return vbox; return vbox;
} }