diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-11 14:38:58 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-11 14:38:58 -0800 |
commit | 8cca5404440960ba14ed870e77c6eb6537f4aa2e (patch) | |
tree | 3b42f4488c72c971dc8c10a5f5b74c9ecf2bb129 /divelist.c | |
parent | 4df81487fefc6eb6b2a1a1de6a48e2f2f534b18a (diff) | |
download | subsurface-8cca5404440960ba14ed870e77c6eb6537f4aa2e.tar.gz |
Add capability of custom sorts to divelist columns
.. and use this for the nitrox column, which can now be more complex
than just a single number.
The rule for the "nitrox" column is now:
- we look up the highest Oxygen and Helium mix for the dive
(Note: we look them up independently, so if you have a EAN50 deco
bottle, and a 20% Helium low-oxygen bottle for the deep portion, then
we'll consider the dive to be a "50% Oxygen, 20% Helium" dive, even
though you obviously never used that combination at the same time)
- we sort by Helium first, Oxygen second. So a dive with a 10% Helium
mix is considered to be "stronger" than a 50% Nitrox mix.
- If Helium is non-zero, we show "O2/He", otherwise we show just "O2"
(or "air"). So "21/20" means "21% oxygen, 20% Helium", while "40"
means "Ean 40".
- I got rid of the decimals. We save them, and you can see them in the
dive equipment details, but for the dive list we just use rounded
percentages.
Let's see how many bugs I introduced. I don't actually have any trimix
dives, but I edited a few for (very limited) testing.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'divelist.c')
-rw-r--r-- | divelist.c | 122 |
1 files changed, 100 insertions, 22 deletions
diff --git a/divelist.c b/divelist.c index 6674f1df4..546d54bd0 100644 --- a/divelist.c +++ b/divelist.c @@ -45,7 +45,7 @@ enum { DIVE_DURATION, /* int: in seconds */ DIVE_TEMPERATURE, /* int: in mkelvin */ DIVE_CYLINDER, - DIVE_NITROX, /* int: in permille */ + DIVE_NITROX, /* int: dummy */ DIVE_SAC, /* int: in ml/min */ DIVE_OTU, /* int: in OTUs */ DIVE_LOCATION, /* "2nd Cathedral, Lanai" */ @@ -223,19 +223,66 @@ static void temperature_data_func(GtkTreeViewColumn *col, 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 value; + int index, o2, he; char buffer[80]; + struct dive *dive; - gtk_tree_model_get(model, iter, DIVE_NITROX, &value, -1); + 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 (value) - snprintf(buffer, sizeof(buffer), "%.1f", value/10.0); + if (he) + snprintf(buffer, sizeof(buffer), "%d/%d", o2, he); + else if (o2) + snprintf(buffer, sizeof(buffer), "%d", o2); else strcpy(buffer, "air"); @@ -433,7 +480,6 @@ static void fill_one_dive(struct dive *dive, DIVE_RATING, dive->rating, DIVE_SAC, dive->sac, DIVE_OTU, dive->otu, - DIVE_NITROX, dive->cylinder[0].gasmix.o2, -1); } @@ -517,7 +563,6 @@ static void fill_dive_list(void) DIVE_DURATION, dive->duration.seconds, DIVE_LOCATION, "location", DIVE_TEMPERATURE, dive->watertemp.mkelvin, - DIVE_NITROX, dive->cylinder[0].gasmix.o2, DIVE_SAC, 0, -1); } @@ -537,12 +582,45 @@ void dive_list_update_dives(void) repaint_dive(); } -static GtkTreeViewColumn *divelist_column(struct DiveList *dl, int index, const char *title, - data_func_t data_func, unsigned int flags, int visible) +static struct divelist_column { + const char *header; + data_func_t data; + sort_func_t sort; + unsigned int flags; + int *visible; +} column[] = { + [DIVE_NR] = { "#", NULL, NULL, ALIGN_RIGHT | UNSORTABLE }, + [DIVE_DATE] = { "Date", date_data_func, NULL, ALIGN_LEFT }, + [DIVE_RATING] = { UTF8_BLACKSTAR, star_data_func, NULL, ALIGN_LEFT }, + [DIVE_DEPTH] = { "ft", depth_data_func, NULL, ALIGN_RIGHT }, + [DIVE_DURATION] = { "min", duration_data_func, NULL, ALIGN_RIGHT }, + [DIVE_TEMPERATURE] = { UTF8_DEGREE "F", temperature_data_func, NULL, ALIGN_RIGHT, &visible_cols.temperature }, + [DIVE_CYLINDER] = { "Cyl", NULL, NULL, 0, &visible_cols.cylinder }, + [DIVE_NITROX] = { "O" UTF8_SUBSCRIPT_2 "%", nitrox_data_func, nitrox_sort_func, 0, &visible_cols.nitrox }, + [DIVE_SAC] = { "SAC", sac_data_func, NULL, 0, &visible_cols.sac }, + [DIVE_OTU] = { "OTU", otu_data_func, NULL, 0, &visible_cols.otu }, + [DIVE_LOCATION] = { "Location", NULL, NULL, ALIGN_LEFT }, +}; + + +static GtkTreeViewColumn *divelist_column(struct DiveList *dl, struct divelist_column *col) { - if (!visible) + int index = col - &column[0]; + const char *title = col->header; + data_func_t data_func = col->data; + sort_func_t sort_func = col->sort; + unsigned int flags = col->flags; + int *visible = col->visible; + GtkWidget *tree_view = dl->tree_view; + GtkListStore *model = dl->model; + GtkTreeViewColumn *ret; + + if (visible && !*visible) flags |= INVISIBLE; - return tree_view_column(dl->tree_view, index, title, data_func, flags); + ret = tree_view_column(tree_view, index, title, data_func, flags); + if (sort_func) + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), index, sort_func, NULL, NULL); + return ret; } /* @@ -594,17 +672,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, 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); + dive_list.nr = divelist_column(&dive_list, column + DIVE_NR); + dive_list.date = divelist_column(&dive_list, column + DIVE_DATE); + dive_list.stars = divelist_column(&dive_list, column + DIVE_RATING); + dive_list.depth = divelist_column(&dive_list, column + DIVE_DEPTH); + dive_list.duration = divelist_column(&dive_list, column + DIVE_DURATION); + dive_list.temperature = divelist_column(&dive_list, column + DIVE_TEMPERATURE); + dive_list.cylinder = divelist_column(&dive_list, column + DIVE_CYLINDER); + dive_list.nitrox = divelist_column(&dive_list, column + DIVE_NITROX); + dive_list.sac = divelist_column(&dive_list, column + DIVE_SAC); + dive_list.otu = divelist_column(&dive_list, column + DIVE_OTU); + dive_list.location = divelist_column(&dive_list, column + DIVE_LOCATION); fill_dive_list(); |