From: Linus Torvalds Date: Sat, 24 Mar 2012 04:07:53 +0000 (-0700) Subject: Merge branch 'weight' of git://subsurface.hohndel.org/subsurface X-Git-Url: http://git.tdb.fi/?p=ext%2Fsubsurface.git;a=commitdiff_plain;h=81fddfa67e779c8d378eee4c57fd9f201e15f96f Merge branch 'weight' of git://subsurface.hohndel.org/subsurface Pull weight management from Dirk Hohndel: "This is the fifth or sixth version of this code, I'm begining to lose track. I still struggle with the balance between code duplication and unnecessary indirectness and complexity. Maybe I'm just not finding the right level of abstraction. Maybe I'm just trying too hard. The code here is reasonably well tested. Works for me :-) It can import DivingLog xml files with weight systems and correctly parses those. It obviously can read and write weight systems in its own file format. It adds a KG/lbs unit default (and correctly stores that). The thing I still worry about is the code in equipment.c. You'll see that I tried to abstract things in a way that weight systems and cylinders share quite a bit of code - but there's more very similar code that isn't shared as my attempts to do so turned into ugly and hard to read code. It always felt like trying to write C++ in C..." * 'weight' of git://subsurface.hohndel.org/subsurface: Add weight system tracking Fix up some trivial conflicts due to various renaming of globals and simplification in function interfaces. --- 81fddfa67e779c8d378eee4c57fd9f201e15f96f diff --cc equipment.c index e4f880f,579c455..abfb0e7 --- a/equipment.c +++ b/equipment.c @@@ -82,8 -101,22 +99,21 @@@ static void convert_volume_pressure(in } *v = volume; *p = pressure; - return decimals; } + static int convert_weight(int grams, double *m) + { + int decimals = 1; /* not sure - do people do less than whole lbs/kg ? */ + double weight; + + if (output_units.weight == LBS) + weight = grams_to_lbs(grams); + else + weight = grams / 1000.0; + *m = weight; + return decimals; + } + static void set_cylinder_type_spinbuttons(struct cylinder_widget *cylinder, int ml, int mbar) { double volume, pressure; @@@ -303,8 -442,15 +439,15 @@@ int cylinder_none(void *_data !cyl->end.mbar; } - static void set_one_cylinder(cylinder_t *cyl, GtkListStore *model, GtkTreeIter *iter) + int weightsystem_none(void *_data) + { + weightsystem_t *ws = _data; + return !ws->weight.grams && !ws->description; + } + -static void set_one_cylinder(int index, void *_data, GtkListStore *model, GtkTreeIter *iter) ++static void set_one_cylinder(void *_data, GtkListStore *model, GtkTreeIter *iter) { + cylinder_t *cyl = _data; unsigned int start, end; start = cyl->start.mbar ? : cyl->sample_start.mbar; @@@ -320,33 -466,59 +463,59 @@@ -1); } - void show_dive_equipment(struct dive *dive) -static void set_one_weightsystem(int index, void *_data, GtkListStore *model, GtkTreeIter *iter) ++static void set_one_weightsystem(void *_data, GtkListStore *model, GtkTreeIter *iter) + { + weightsystem_t *ws = _data; + + gtk_list_store_set(model, iter, + WS_DESC, ws->description ? : "unspecified", + WS_WEIGHT, ws->weight.grams, + -1); + } + + static void *cyl_ptr(struct dive *dive, int idx) + { + if (idx < 0 || idx >= MAX_CYLINDERS) + return NULL; + return &dive->cylinder[idx]; + } + + static void *ws_ptr(struct dive *dive, int idx) { - int i, max; + if (idx < 0 || idx >= MAX_WEIGHTSYSTEMS) + return NULL; + return &dive->weightsystem[idx]; + } + + static void show_equipment(struct dive *dive, int max, + struct equipment_list *equipment_list, + void*(*ptr_function)(struct dive*, int), + int(*none_function)(void *), - void(*set_one_function)(int, void*, GtkListStore*, GtkTreeIter *)) ++ void(*set_one_function)(void*, GtkListStore*, GtkTreeIter *)) + { + int i, used; + void *data; GtkTreeIter iter; - GtkListStore *model; + GtkListStore *model = equipment_list->model; - model = cylinder_list.model; gtk_list_store_clear(model); - max = MAX_CYLINDERS; + used = max; do { - cylinder_t *cyl = &dive->cylinder[max-1]; - - if (!cylinder_none(cyl)) + data = ptr_function(dive, used-1); + if (!none_function(data)) break; - } while (--max); + } while (--used); - cylinder_list.max_index = max; + equipment_list->max_index = used; - gtk_widget_set_sensitive(cylinder_list.edit, 0); - gtk_widget_set_sensitive(cylinder_list.del, 0); - gtk_widget_set_sensitive(cylinder_list.add, max < MAX_CYLINDERS); - - for (i = 0; i < max; i++) { - cylinder_t *cyl = dive->cylinder+i; + gtk_widget_set_sensitive(equipment_list->edit, 0); + gtk_widget_set_sensitive(equipment_list->del, 0); + gtk_widget_set_sensitive(equipment_list->add, used < max); + for (i = 0; i < used; i++) { + data = ptr_function(dive, i); gtk_list_store_append(model, &iter); - set_one_cylinder(cyl, model, &iter); - set_one_function(i, data, model, &iter); ++ set_one_function(data, model, &iter); } } @@@ -802,6 -1135,86 +1132,86 @@@ static void del_cb(GtkButton *button, G gtk_widget_set_sensitive(cylinder_list.add, 1); } + static void ws_edit_cb(GtkButton *button, GtkTreeView *tree_view) + { + int index; + GtkTreeIter iter; + GtkListStore *model = weightsystem_list.model; + GtkTreeSelection *selection; + weightsystem_t ws; + + selection = gtk_tree_view_get_selection(tree_view); + + /* Nothing selected? This shouldn't happen, since the button should be inactive */ + if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) + return; + + index = get_model_index(model, &iter); + if (!edit_weightsystem_dialog(index, &ws)) + return; + - set_one_weightsystem(index, &ws, model, &iter); ++ set_one_weightsystem(&ws, model, &iter); + repaint_dive(); + } + + static void ws_add_cb(GtkButton *button, GtkTreeView *tree_view) + { + int index = weightsystem_list.max_index; + GtkTreeIter iter; + GtkListStore *model = weightsystem_list.model; + GtkTreeSelection *selection; + weightsystem_t ws; + + if (!edit_weightsystem_dialog(index, &ws)) + return; + + gtk_list_store_append(model, &iter); - set_one_weightsystem(index, &ws, model, &iter); ++ set_one_weightsystem(&ws, model, &iter); + + selection = gtk_tree_view_get_selection(tree_view); + gtk_tree_selection_select_iter(selection, &iter); + + weightsystem_list.max_index++; + gtk_widget_set_sensitive(weightsystem_list.add, weightsystem_list.max_index < MAX_WEIGHTSYSTEMS); + } + + static void ws_del_cb(GtkButton *button, GtkTreeView *tree_view) + { + int index, nr; + GtkTreeIter iter; + GtkListStore *model = weightsystem_list.model; + GtkTreeSelection *selection; + struct dive *dive; + weightsystem_t *ws; + + selection = gtk_tree_view_get_selection(tree_view); + + /* Nothing selected? This shouldn't happen, since the button should be inactive */ + if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) + return; + + index = get_model_index(model, &iter); + + dive = current_dive; + if (!dive) + return; + ws = dive->weightsystem + index; + nr = weightsystem_list.max_index - index - 1; + + gtk_list_store_remove(model, &iter); + + weightsystem_list.max_index--; + memmove(ws, ws+1, nr*sizeof(*ws)); + memset(ws+nr, 0, sizeof(*ws)); + + mark_divelist_changed(TRUE); + flush_divelist(dive); + + gtk_widget_set_sensitive(weightsystem_list.edit, 0); + gtk_widget_set_sensitive(weightsystem_list.del, 0); + gtk_widget_set_sensitive(weightsystem_list.add, 1); + } + static GtkListStore *create_tank_size_model(void) { GtkListStore *model; diff --cc parse-xml.c index 2877e3a,34afdb9..e920a11 --- a/parse-xml.c +++ b/parse-xml.c @@@ -103,9 -104,9 +104,9 @@@ static struct duration_t time; int type, flags, value; const char *name; -} event; -static struct tm tm; -static int cylinder_index, ws_index; +} cur_event; +static struct tm cur_tm; - static int cur_cylinder_index; ++static int cur_cylinder_index, cur_ws_index; static enum import_source { UNKNOWN, @@@ -1026,22 -1048,27 +1048,27 @@@ static void try_to_fill_dive(struct div return; if (MATCH(".rating", get_index, &dive->rating)) return; - if (MATCH(".cylinder.size", cylindersize, &dive->cylinder[cylinder_index].type.size)) + if (MATCH(".cylinder.size", cylindersize, &dive->cylinder[cur_cylinder_index].type.size)) return; - if (MATCH(".cylinder.workpressure", pressure, &dive->cylinder[cylinder_index].type.workingpressure)) + if (MATCH(".cylinder.workpressure", pressure, &dive->cylinder[cur_cylinder_index].type.workingpressure)) return; - if (MATCH(".cylinder.description", utf8_string, &dive->cylinder[cylinder_index].type.description)) + if (MATCH(".cylinder.description", utf8_string, &dive->cylinder[cur_cylinder_index].type.description)) return; - if (MATCH(".cylinder.start", pressure, &dive->cylinder[cylinder_index].start)) + if (MATCH(".cylinder.start", pressure, &dive->cylinder[cur_cylinder_index].start)) return; - if (MATCH(".cylinder.end", pressure, &dive->cylinder[cylinder_index].end)) + if (MATCH(".cylinder.end", pressure, &dive->cylinder[cur_cylinder_index].end)) return; - - if (MATCH(".weightsystem.description", utf8_string, &dive->weightsystem[ws_index].description)) ++ if (MATCH(".weightsystem.description", utf8_string, &dive->weightsystem[cur_ws_index].description)) + return; - if (MATCH(".weightsystem.weight", weight, &dive->weightsystem[ws_index].weight)) ++ if (MATCH(".weightsystem.weight", weight, &dive->weightsystem[cur_ws_index].weight)) + return; - if (MATCH("weight", weight, &dive->weightsystem[ws_index].weight)) ++ if (MATCH("weight", weight, &dive->weightsystem[cur_ws_index].weight)) + return; - if (MATCH(".o2", gasmix, &dive->cylinder[cylinder_index].gasmix.o2)) + if (MATCH(".o2", gasmix, &dive->cylinder[cur_cylinder_index].gasmix.o2)) return; - if (MATCH(".n2", gasmix_nitrogen, &dive->cylinder[cylinder_index].gasmix)) + if (MATCH(".n2", gasmix_nitrogen, &dive->cylinder[cur_cylinder_index].gasmix)) return; - if (MATCH(".he", gasmix, &dive->cylinder[cylinder_index].gasmix.he)) + if (MATCH(".he", gasmix, &dive->cylinder[cur_cylinder_index].gasmix.he)) return; nonmatch("dive", name, buf); @@@ -1063,11 -1206,13 +1090,12 @@@ static void dive_start(void static void dive_end(void) { - if (!dive) + if (!cur_dive) return; - sanitize_cylinder_info(dive); - record_dive(dive); - dive = NULL; - cylinder_index = 0; - ws_index = 0; + record_dive(cur_dive); + cur_dive = NULL; + cur_cylinder_index = 0; ++ cur_ws_index = 0; } static void event_start(void) @@@ -1091,12 -1234,21 +1119,21 @@@ static void cylinder_start(void static void cylinder_end(void) { - cylinder_index++; + cur_cylinder_index++; } + static void ws_start(void) + { + } + + static void ws_end(void) + { - ws_index++; ++ cur_ws_index++; + } + static void sample_start(void) { - sample = prepare_sample(&dive); + cur_sample = prepare_sample(&cur_dive); } static void sample_end(void)