]> git.tdb.fi Git - ext/subsurface.git/blob - equipment.c
First (broken) try at actually tracking cylinder types
[ext/subsurface.git] / equipment.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <time.h>
6
7 #include "dive.h"
8 #include "display.h"
9 #include "divelist.h"
10
11 static GtkWidget *cylinder_description;
12
13 static gboolean match_cylinder(GtkTreeModel *model,
14                                 GtkTreePath *path,
15                                 GtkTreeIter *iter,
16                                 gpointer data)
17 {
18         const char *name;
19         const char *desc = data;
20         GValue value = {0, };
21
22         gtk_tree_model_get_value(model, iter, 0, &value);
23         name = g_value_get_string(&value);
24         if (strcmp(desc, name))
25                 return FALSE;
26         gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cylinder_description), iter);
27         return TRUE;
28 }
29
30 void show_dive_equipment(struct dive *dive)
31 {
32         const char *desc = dive->cylinder[0].type.description;
33         GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(cylinder_description));
34
35         if (!desc)
36                 return;
37         gtk_tree_model_foreach(model, match_cylinder, (gpointer)desc);
38 }
39
40 static GtkWidget *create_spinbutton(GtkWidget *vbox, const char *name)
41 {
42         GtkWidget *frame, *button;
43
44         frame = gtk_frame_new(name);
45         gtk_container_add(GTK_CONTAINER(vbox), frame);
46
47         button = gtk_spin_button_new_with_range( 1.0, 3000, 0.1);
48         gtk_container_add(GTK_CONTAINER(frame), button);
49
50         return button;
51 }
52
53 static int get_cylinder_details(const char *name, int *volume, int *pressure)
54 {
55         int result;
56         GtkWidget *dialog, *frame, *vbox;
57
58         dialog = gtk_dialog_new_with_buttons("New Cylinder Type",
59                 GTK_WINDOW(main_window),
60                 GTK_DIALOG_DESTROY_WITH_PARENT,
61                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
62                 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
63                 NULL);
64
65         frame = gtk_frame_new(name);
66         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), frame);
67         vbox = gtk_vbox_new(TRUE, 6);
68         gtk_container_add(GTK_CONTAINER(frame), vbox);
69
70         create_spinbutton(vbox, "Size:");
71         create_spinbutton(vbox, "Working pressure:");
72
73         gtk_widget_show_all(dialog);
74         result = gtk_dialog_run(GTK_DIALOG(dialog));
75         gtk_widget_destroy(dialog);
76
77         *volume = 0;
78         *pressure = 0;
79         return result == GTK_RESPONSE_ACCEPT;
80 }
81
82 static void fill_cylinder_info(cylinder_t *cyl, const char *desc, int mliter, int mbar)
83 {
84         /*
85          * The code is currently too broken to actually set anything,
86          * so just print what we would set
87          */
88         printf("Set cylinder to '%s': %.1f liter at %.1f bar working pressure\n",
89                 desc, mliter / 1000.0, mbar / 1000.);
90 #if 0
91         cyl->type.description = desc;
92         cyl->type.size.mliter = mliter;
93         cyl->type.workingpressure.mbar = mbar;
94 #endif
95 }
96
97 void flush_dive_equipment_changes(struct dive *dive)
98 {
99         GtkTreeIter iter;
100         const gchar *desc;
101         GtkComboBox *box = GTK_COMBO_BOX(cylinder_description);
102         GtkTreeModel *model = gtk_combo_box_get_model(box);
103         GtkListStore *store = GTK_LIST_STORE(model);
104         GValue value1 = {0, }, value2 = {0,}, value3 = {0, };
105         int volume, pressure;
106
107         if (!gtk_combo_box_get_active_iter(box, &iter)) {
108                 desc = gtk_combo_box_get_active_text(box);
109                 if (!get_cylinder_details(desc, &volume, &pressure))
110                         return;
111                 gtk_list_store_append(store, &iter);
112                 gtk_list_store_set(store, &iter,
113                         0, desc,
114                         1, volume,
115                         2, pressure,
116                         -1);
117         }
118
119         gtk_tree_model_get_value(model, &iter, 0, &value1);
120         desc = g_value_get_string(&value1);
121         gtk_tree_model_get_value(model, &iter, 1, &value2);
122         volume = g_value_get_int(&value2);
123         gtk_tree_model_get_value(model, &iter, 2, &value3);
124         pressure = g_value_get_int(&value3);
125         fill_cylinder_info(dive->cylinder+0, desc, volume, pressure);
126 }
127
128 /* We should take these from the dive list instead */
129 static struct tank_info {
130         const char *name;
131         int size;       /* cuft or mliter depending on psi */
132         int psi;        /* If zero, size is in mliter */
133 } tank_info[] = {
134         { "None", 0, 0 },
135         { "10.0 l", 10000 },
136         { "11.1 l", 11100 },
137         { "AL72", 72, 3000 },
138         { "AL80", 80, 3000 },
139         { "LP85", 85, 2400 },
140         { "LP95", 95, 2400 },
141         { "LP85+", 85, 2640 },
142         { "LP95+", 95, 2640 },
143         { "HP100", 100, 3442 },
144         { "HP119", 119, 3442 },
145         { NULL, }
146 };
147
148 static void fill_tank_list(GtkListStore *store)
149 {
150         GtkTreeIter iter;
151
152         struct tank_info *info = tank_info;
153
154         while (info->name) {
155                 int size = info->size;
156                 int psi = info->psi;
157                 int mbar = 0, ml = size;
158
159                 /* Is it in cuft and psi? */
160                 if (psi) {
161                         double bar = 0.0689475729 * psi;
162                         double airvolume = 28316.8466 * size;
163                         double atm = bar / 1.01325;
164
165                         ml = airvolume / atm + 0.5;
166                         mbar = bar*1000 + 0.5;
167                 }
168
169                 gtk_list_store_append(store, &iter);
170                 gtk_list_store_set(store, &iter,
171                         0, info->name,
172                         1, ml,
173                         2, mbar,
174                         -1);
175                 info++;
176         }
177 }
178
179 static void cylinder_widget(GtkWidget *box, int nr, GtkListStore *model)
180 {
181         GtkWidget *frame, *hbox, *size;
182         char buffer[80];
183
184         snprintf(buffer, sizeof(buffer), "Cylinder %d", nr);
185         frame = gtk_frame_new(buffer);
186         gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
187
188         hbox = gtk_hbox_new(TRUE, 3);
189         gtk_container_add(GTK_CONTAINER(frame), hbox);
190
191         size = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(model), 0);
192         gtk_box_pack_start(GTK_BOX(hbox), size, FALSE, FALSE, 0);
193
194         cylinder_description = size;
195 }
196
197 static GtkListStore *create_tank_size_model(void)
198 {
199         GtkListStore *model;
200
201         model = gtk_list_store_new(3,
202                 G_TYPE_STRING,          /* Tank name */
203                 G_TYPE_INT,             /* Tank size in mliter */
204                 G_TYPE_INT,             /* Tank working pressure in mbar */
205                 -1);
206
207         fill_tank_list(model);
208         return model;
209 }
210
211 GtkWidget *equipment_widget(void)
212 {
213         GtkWidget *vbox;
214         GtkListStore *model;
215
216         vbox = gtk_vbox_new(FALSE, 3);
217
218         model = create_tank_size_model();
219         cylinder_widget(vbox, 0, model);
220
221         return vbox;
222 }