+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,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int val;
+ struct tm *tm;
+ time_t when;
+ char buffer[40];
+
+ gtk_tree_model_get(model, iter, DIVE_DATE, &val, -1);
+
+ /* 2038 problem */
+ when = val;
+
+ tm = gmtime(&when);
+ snprintf(buffer, sizeof(buffer),
+ "%s, %s %d, %d %02d:%02d",
+ weekday(tm->tm_wday),
+ monthname(tm->tm_mon),
+ tm->tm_mday, tm->tm_year + 1900,
+ tm->tm_hour, tm->tm_min);
+ g_object_set(renderer, "text", buffer, NULL);
+}
+
+static void depth_data_func(GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int depth, integer, frac, len;
+ char buffer[40];
+
+ gtk_tree_model_get(model, iter, DIVE_DEPTH, &depth, -1);
+
+ switch (output_units.length) {
+ case METERS:
+ /* To tenths of meters */
+ depth = (depth + 49) / 100;
+ integer = depth / 10;
+ frac = depth % 10;
+ if (integer < 20)
+ break;
+ if (frac >= 5)
+ integer++;
+ frac = -1;
+ break;
+ case FEET:
+ integer = mm_to_feet(depth) + 0.5;
+ frac = -1;
+ break;
+ default:
+ return;
+ }
+ len = snprintf(buffer, sizeof(buffer), "%d", integer);
+ if (frac >= 0)
+ len += snprintf(buffer+len, sizeof(buffer)-len, ".%d", frac);
+
+ g_object_set(renderer, "text", buffer, NULL);
+}
+
+static void duration_data_func(GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ unsigned int sec;
+ char buffer[16];
+
+ gtk_tree_model_get(model, iter, DIVE_DURATION, &sec, -1);
+ snprintf(buffer, sizeof(buffer), "%d:%02d", sec / 60, sec % 60);
+
+ g_object_set(renderer, "text", buffer, NULL);
+}
+
+static void temperature_data_func(GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int value;
+ char buffer[80];
+
+ gtk_tree_model_get(model, iter, DIVE_TEMPERATURE, &value, -1);
+
+ *buffer = 0;
+ if (value) {
+ double deg;
+ switch (output_units.temperature) {
+ case CELSIUS:
+ deg = mkelvin_to_C(value);
+ break;
+ case FAHRENHEIT:
+ deg = mkelvin_to_F(value);
+ break;
+ default:
+ return;
+ }
+ snprintf(buffer, sizeof(buffer), "%.1f", deg);
+ }
+
+ g_object_set(renderer, "text", buffer, NULL);
+}
+
+/* Get max O2/He permille levels for a dive for the dive summary */
+static void get_dive_gas(struct dive *dive, int *o2, int *he)
+{
+ int i;
+ int maxo2 = -1, maxhe = -1;
+
+ for (i = 0; i < MAX_CYLINDERS; i++) {
+ struct gasmix *mix = &dive->cylinder[i].gasmix;
+ if (mix->o2.permille > maxo2)
+ maxo2 = mix->o2.permille;
+ if (mix->he.permille > maxhe)
+ maxhe = mix->he.permille;
+ }
+ *o2 = maxo2;
+ *he = maxhe;
+}
+
+static gint nitrox_sort_func(GtkTreeModel *model,
+ GtkTreeIter *iter_a,
+ GtkTreeIter *iter_b,
+ gpointer user_data)
+{
+ int index_a, index_b;
+ struct dive *a, *b;
+ int a_o2, b_o2;
+ int a_he, b_he;
+
+ gtk_tree_model_get(model, iter_a, DIVE_INDEX, &index_a, -1);
+ gtk_tree_model_get(model, iter_b, DIVE_INDEX, &index_b, -1);
+ a = get_dive(index_a);
+ b = get_dive(index_b);
+ get_dive_gas(a, &a_o2, &a_he);
+ get_dive_gas(b, &b_o2, &b_he);
+
+ /* Sort by Helium first, O2 second */
+ if (a_he == b_he)
+ return a_o2 - b_o2;
+ return a_he - b_he;
+}
+
+static void nitrox_data_func(GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int index, o2, he;
+ char buffer[80];
+ struct dive *dive;
+
+ gtk_tree_model_get(model, iter, DIVE_INDEX, &index, -1);
+ dive = get_dive(index);
+ get_dive_gas(dive, &o2, &he);
+ o2 = (o2 + 5) / 10;
+ he = (he + 5) / 10;
+
+ if (he)
+ snprintf(buffer, sizeof(buffer), "%d/%d", o2, he);
+ else if (o2)
+ snprintf(buffer, sizeof(buffer), "%d", o2);
+ else
+ strcpy(buffer, "air");
+
+ g_object_set(renderer, "text", buffer, NULL);
+}
+
+/* Render the SAC data (integer value of "ml / min") */
+static void sac_data_func(GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int value;
+ const char *fmt;
+ char buffer[16];
+ double sac;
+
+ gtk_tree_model_get(model, iter, DIVE_SAC, &value, -1);
+
+ if (!value) {
+ g_object_set(renderer, "text", "", NULL);
+ return;
+ }
+
+ sac = value / 1000.0;
+ switch (output_units.volume) {
+ case LITER:
+ fmt = "%4.1f";
+ break;
+ case CUFT:
+ fmt = "%4.2f";
+ sac = ml_to_cuft(sac * 1000);
+ break;
+ }
+ snprintf(buffer, sizeof(buffer), fmt, sac);
+
+ g_object_set(renderer, "text", buffer, NULL);
+}
+
+/* Render the OTU data (integer value of "OTU") */
+static void otu_data_func(GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int value;
+ char buffer[16];
+
+ gtk_tree_model_get(model, iter, DIVE_OTU, &value, -1);
+
+ if (!value) {
+ g_object_set(renderer, "text", "", NULL);
+ return;
+ }
+
+ snprintf(buffer, sizeof(buffer), "%d", value);
+
+ g_object_set(renderer, "text", buffer, NULL);