X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=divelist.c;h=36c40b8b249342e2288d25dd69950b95bb084386;hb=f9bb3f79106baba7cda330e0c04f54a01745581f;hp=ca984b4eb169ed90b520ce0541ae3670c3765daf;hpb=a487f6c9314f0fe5e4173b670d9653067285da21;p=ext%2Fsubsurface.git diff --git a/divelist.c b/divelist.c index ca984b4..36c40b8 100644 --- a/divelist.c +++ b/divelist.c @@ -25,7 +25,7 @@ struct DiveList { GtkWidget *tree_view; GtkWidget *container_widget; GtkListStore *model; - GtkTreeViewColumn *nr, *date, *depth, *duration, *location; + GtkTreeViewColumn *nr, *date, *stars, *depth, *duration, *location; GtkTreeViewColumn *temperature, *cylinder, *nitrox, *sac, *otu; int changed; }; @@ -40,6 +40,7 @@ enum { DIVE_INDEX = 0, DIVE_NR, /* int: dive->nr */ DIVE_DATE, /* time_t: dive->when */ + DIVE_RATING, /* int: 0-5 stars */ DIVE_DEPTH, /* int: dive->maxdepth in mm */ DIVE_DURATION, /* int: in seconds */ DIVE_TEMPERATURE, /* int: in mkelvin */ @@ -89,6 +90,31 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model) } } +const char *star_strings[] = { + ZERO_STARS, + ONE_STARS, + TWO_STARS, + THREE_STARS, + FOUR_STARS, + FIVE_STARS +}; + +static void star_data_func(GtkTreeViewColumn *col, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + int nr_stars; + char buffer[40]; + + gtk_tree_model_get(model, iter, DIVE_RATING, &nr_stars, -1); + if (nr_stars < 0 || nr_stars > 5) + nr_stars = 0; + snprintf(buffer, sizeof(buffer), "%s", star_strings[nr_stars]); + g_object_set(renderer, "text", buffer, NULL); +} + static void date_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, @@ -134,8 +160,9 @@ static void depth_data_func(GtkTreeViewColumn *col, frac = depth % 10; if (integer < 20) break; + if (frac >= 5) + integer++; frac = -1; - /* Rounding? */ break; case FEET: integer = mm_to_feet(depth) + 0.5; @@ -223,7 +250,6 @@ static void sac_data_func(GtkTreeViewColumn *col, gpointer data) { int value; - const double liters_per_cuft = 28.317; const char *fmt; char buffer[16]; double sac; @@ -242,7 +268,7 @@ static void sac_data_func(GtkTreeViewColumn *col, break; case CUFT: fmt = "%4.2f"; - sac /= liters_per_cuft; + sac = ml_to_cuft(sac * 1000); break; } snprintf(buffer, sizeof(buffer), fmt, sac); @@ -300,6 +326,7 @@ static double calculate_airuse(struct dive *dive) int i; for (i = 0; i < MAX_CYLINDERS; i++) { + pressure_t start, end; cylinder_t *cyl = dive->cylinder + i; int size = cyl->type.size.mliter; double kilo_atm; @@ -307,7 +334,9 @@ static double calculate_airuse(struct dive *dive) if (!size) continue; - kilo_atm = (cyl->start.mbar - cyl->end.mbar) / 1013250.0; + start = cyl->start.mbar ? cyl->start : cyl->sample_start; + end = cyl->end.mbar ? cyl->end : cyl->sample_end; + kilo_atm = (to_ATM(start) - to_ATM(end)) / 1000.0; /* Liters of air at 1 atm == milliliters at 1k atm*/ airuse += kilo_atm * size; @@ -318,6 +347,7 @@ static double calculate_airuse(struct dive *dive) static int calculate_sac(struct dive *dive) { double airuse, pressure, sac; + int duration, i; airuse = calculate_airuse(dive); if (!airuse) @@ -325,14 +355,38 @@ static int calculate_sac(struct dive *dive) if (!dive->duration.seconds) return 0; + /* find and eliminate long surface intervals */ + duration = dive->duration.seconds; + for (i = 0; i < dive->samples; i++) { + if (dive->sample[i].depth.mm < 100) { /* less than 10cm */ + int end = i + 1; + while (end < dive->samples && dive->sample[end].depth.mm < 100) + end++; + /* we only want the actual surface time during a dive */ + if (end < dive->samples) { + end--; + duration -= dive->sample[end].time.seconds - + dive->sample[i].time.seconds; + i = end + 1; + } + } + } /* Mean pressure in atm: 1 atm per 10m */ pressure = 1 + (dive->meandepth.mm / 10000.0); - sac = airuse / pressure * 60 / dive->duration.seconds; + sac = airuse / pressure * 60 / duration; /* milliliters per minute.. */ return sac * 1000; } +void update_cylinder_related_info(struct dive *dive) +{ + if (dive != NULL) { + dive->sac = calculate_sac(dive); + dive->otu = calculate_otu(dive); + } +} + static void get_string(char **str, const char *s) { int len; @@ -341,8 +395,8 @@ static void get_string(char **str, const char *s) if (!s) s = ""; len = strlen(s); - if (len > 40) - len = 40; + if (len > 60) + len = 60; n = malloc(len+1); memcpy(n, s, len); n[len] = 0; @@ -376,6 +430,7 @@ static void fill_one_dive(struct dive *dive, DIVE_NR, dive->number, DIVE_LOCATION, location, DIVE_CYLINDER, cylinder, + DIVE_RATING, dive->rating, DIVE_SAC, dive->sac, DIVE_OTU, dive->otu, -1); @@ -420,27 +475,10 @@ void update_dive_list_units(void) const char *unit; GtkTreeModel *model = GTK_TREE_MODEL(dive_list.model); - switch (output_units.length) { - case METERS: - unit = "m"; - break; - case FEET: - unit = "ft"; - break; - } + (void) get_depth_units(0, NULL, &unit); gtk_tree_view_column_set_title(dive_list.depth, unit); - switch (output_units.temperature) { - case CELSIUS: - unit = UTF8_DEGREE "C"; - break; - case FAHRENHEIT: - unit = UTF8_DEGREE "F"; - break; - case KELVIN: - unit = "Kelvin"; - break; - } + (void) get_temp_units(0, &unit); gtk_tree_view_column_set_title(dive_list.temperature, unit); gtk_tree_model_foreach(model, set_one_dive, NULL); @@ -464,11 +502,11 @@ static void fill_dive_list(void) store = GTK_LIST_STORE(dive_list.model); - for (i = 0; i < dive_table.nr; i++) { + i = dive_table.nr; + while (--i >= 0) { struct dive *dive = dive_table.dives[i]; - dive->otu = calculate_otu(dive); - dive->sac = calculate_sac(dive); + update_cylinder_related_info(dive); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, DIVE_INDEX, i, @@ -499,9 +537,11 @@ void dive_list_update_dives(void) } static GtkTreeViewColumn *divelist_column(struct DiveList *dl, int index, const char *title, - data_func_t data_func, PangoAlignment align, gboolean visible) + data_func_t data_func, unsigned int flags, int visible) { - return tree_view_column(dl->tree_view, index, title, data_func, align, visible); + if (!visible) + flags |= INVISIBLE; + return tree_view_column(dl->tree_view, index, title, data_func, flags); } /* @@ -513,6 +553,20 @@ static void realize_cb(GtkWidget *tree_view, gpointer userdata) gtk_widget_grab_focus(tree_view); } +static void row_activated_cb(GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + GtkTreeModel *model) +{ + int index; + GtkTreeIter iter; + + if (!gtk_tree_model_get_iter(model, &iter, path)) + return; + gtk_tree_model_get(model, &iter, DIVE_INDEX, &index, -1); + edit_dive_info(get_dive(index)); +} + GtkWidget *dive_list_create(void) { GtkTreeSelection *selection; @@ -521,6 +575,7 @@ GtkWidget *dive_list_create(void) G_TYPE_INT, /* index */ G_TYPE_INT, /* nr */ G_TYPE_INT, /* Date */ + G_TYPE_INT, /* Star rating */ G_TYPE_INT, /* Depth */ G_TYPE_INT, /* Duration */ G_TYPE_INT, /* Temperature */ @@ -538,17 +593,17 @@ GtkWidget *dive_list_create(void) gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE); gtk_widget_set_size_request(dive_list.tree_view, 200, 200); - dive_list.nr = divelist_column(&dive_list, DIVE_NR, "#", NULL, PANGO_ALIGN_RIGHT, TRUE); - gtk_tree_view_column_set_sort_column_id(dive_list.nr, -1); - dive_list.date = divelist_column(&dive_list, DIVE_DATE, "Date", date_data_func, PANGO_ALIGN_LEFT, TRUE); - dive_list.depth = divelist_column(&dive_list, DIVE_DEPTH, "ft", depth_data_func, PANGO_ALIGN_RIGHT, TRUE); - dive_list.duration = divelist_column(&dive_list, DIVE_DURATION, "min", duration_data_func, PANGO_ALIGN_RIGHT, TRUE); - dive_list.temperature = divelist_column(&dive_list, DIVE_TEMPERATURE, UTF8_DEGREE "F", temperature_data_func, PANGO_ALIGN_RIGHT, visible_cols.temperature); - dive_list.cylinder = divelist_column(&dive_list, DIVE_CYLINDER, "Cyl", NULL, PANGO_ALIGN_CENTER, visible_cols.cylinder); - dive_list.nitrox = divelist_column(&dive_list, DIVE_NITROX, "O" UTF8_SUBSCRIPT_2 "%", nitrox_data_func, PANGO_ALIGN_CENTER, visible_cols.nitrox); - dive_list.sac = divelist_column(&dive_list, DIVE_SAC, "SAC", sac_data_func, PANGO_ALIGN_CENTER, visible_cols.sac); - dive_list.otu = divelist_column(&dive_list, DIVE_OTU, "OTU", otu_data_func, PANGO_ALIGN_CENTER, visible_cols.otu); - dive_list.location = divelist_column(&dive_list, DIVE_LOCATION, "Location", NULL, PANGO_ALIGN_LEFT, TRUE); + dive_list.nr = divelist_column(&dive_list, DIVE_NR, "#", NULL, ALIGN_RIGHT | UNSORTABLE, TRUE); + dive_list.date = divelist_column(&dive_list, DIVE_DATE, "Date", date_data_func, ALIGN_LEFT, TRUE); + dive_list.stars = divelist_column(&dive_list, DIVE_RATING, UTF8_BLACKSTAR, star_data_func, ALIGN_LEFT, TRUE); + dive_list.depth = divelist_column(&dive_list, DIVE_DEPTH, "ft", depth_data_func, ALIGN_RIGHT, TRUE); + dive_list.duration = divelist_column(&dive_list, DIVE_DURATION, "min", duration_data_func, ALIGN_RIGHT, TRUE); + dive_list.temperature = divelist_column(&dive_list, DIVE_TEMPERATURE, UTF8_DEGREE "F", temperature_data_func, ALIGN_RIGHT, visible_cols.temperature); + dive_list.cylinder = divelist_column(&dive_list, DIVE_CYLINDER, "Cyl", NULL, 0, visible_cols.cylinder); + dive_list.nitrox = divelist_column(&dive_list, DIVE_NITROX, "O" UTF8_SUBSCRIPT_2 "%", nitrox_data_func, 0, visible_cols.nitrox); + dive_list.sac = divelist_column(&dive_list, DIVE_SAC, "SAC", sac_data_func, 0, visible_cols.sac); + dive_list.otu = divelist_column(&dive_list, DIVE_OTU, "OTU", otu_data_func, 0, visible_cols.otu); + dive_list.location = divelist_column(&dive_list, DIVE_LOCATION, "Location", NULL, ALIGN_LEFT, TRUE); fill_dive_list(); @@ -558,6 +613,7 @@ GtkWidget *dive_list_create(void) NULL); g_signal_connect_after(dive_list.tree_view, "realize", G_CALLBACK(realize_cb), NULL); + g_signal_connect(dive_list.tree_view, "row-activated", G_CALLBACK(row_activated_cb), dive_list.model); g_signal_connect(selection, "changed", G_CALLBACK(selection_cb), dive_list.model); dive_list.container_widget = gtk_scrolled_window_new(NULL, NULL);