|
1 /** |
|
2 * EditProduct.cpp is part of bmsapp. |
|
3 * |
|
4 * Tab 3, fermentables |
|
5 * |
|
6 * bmsapp is free software: you can redistribute it and/or modify |
|
7 * it under the terms of the GNU General Public License as published by |
|
8 * the Free Software Foundation, either version 3 of the License, or |
|
9 * (at your option) any later version. |
|
10 * |
|
11 * bmsapp is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 * GNU General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU General Public License |
|
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
18 */ |
|
19 |
|
20 |
|
21 |
|
22 bool EditProduct::ferment_sort_test(const Fermentables &D1, const Fermentables &D2) |
|
23 { |
|
24 if (D1.f_added > D2.f_added) |
|
25 return false; |
|
26 if (D1.f_added < D2.f_added) |
|
27 return true; |
|
28 return (D1.f_amount >= D2.f_amount) && (D1.f_color < D2.f_color); |
|
29 } |
|
30 |
|
31 |
|
32 void EditProduct::to100Fermentables(int row) |
|
33 { |
|
34 if (product->fermentables.at(row).f_adjust_to_total_100) { |
|
35 QWidget *pWidget = new QWidget(); |
|
36 QLabel *label = new QLabel; |
|
37 label->setPixmap(QPixmap(":icons/silk/tick.png")); |
|
38 QHBoxLayout *pLayout = new QHBoxLayout(pWidget); |
|
39 pLayout->addWidget(label); |
|
40 pLayout->setAlignment(Qt::AlignCenter); |
|
41 pLayout->setContentsMargins(0, 0, 0, 0); |
|
42 pWidget->setLayout(pLayout); |
|
43 ui->fermentablesTable->setCellWidget(row, 9, pWidget); |
|
44 } else { |
|
45 ui->fermentablesTable->removeCellWidget(row, 9); |
|
46 } |
|
47 } |
|
48 |
|
49 |
|
50 void EditProduct::refreshFermentables() |
|
51 { |
|
52 QString w; |
|
53 QWidget* pWidget; |
|
54 QHBoxLayout* pLayout; |
|
55 QTableWidgetItem *item; |
|
56 |
|
57 qDebug() << "refreshFermentables" << product->fermentables.size(); |
|
58 std::sort(product->fermentables.begin(), product->fermentables.end(), ferment_sort_test); |
|
59 |
|
60 const QStringList labels({tr("Supplier"), tr("Fermentable"), tr("EBC"), tr("Type"), tr("Graintype"), tr("When"), tr("Yield"), |
|
61 tr("Amount"), tr("Procent"), tr("100%"), tr("Delete"), tr("Edit") }); |
|
62 ui->fermentablesTable->setColumnCount(12); |
|
63 ui->fermentablesTable->setColumnWidth(0, 150); /* Supplier */ |
|
64 ui->fermentablesTable->setColumnWidth(1, 225); /* Fermentable */ |
|
65 ui->fermentablesTable->setColumnWidth(2, 50); /* Color */ |
|
66 ui->fermentablesTable->setColumnWidth(3, 75); /* Type */ |
|
67 ui->fermentablesTable->setColumnWidth(4, 75); /* Graintype */ |
|
68 ui->fermentablesTable->setColumnWidth(5, 82); /* Added */ |
|
69 ui->fermentablesTable->setColumnWidth(6, 60); /* Yield */ |
|
70 ui->fermentablesTable->setColumnWidth(7, 90); /* Amount */ |
|
71 ui->fermentablesTable->setColumnWidth(8, 60); /* Procent */ |
|
72 ui->fermentablesTable->setColumnWidth(9, 50); /* 100% */ |
|
73 ui->fermentablesTable->setColumnWidth(10, 80); /* Delete */ |
|
74 ui->fermentablesTable->setColumnWidth(11, 80); /* Edit */ |
|
75 ui->fermentablesTable->setHorizontalHeaderLabels(labels); |
|
76 ui->fermentablesTable->verticalHeader()->hide(); |
|
77 ui->fermentablesTable->setRowCount(product->fermentables.size()); |
|
78 |
|
79 for (int i = 0; i < product->fermentables.size(); i++) { |
|
80 |
|
81 ui->fermentablesTable->setItem(i, 0, new QTableWidgetItem(product->fermentables.at(i).f_supplier)); |
|
82 ui->fermentablesTable->setItem(i, 1, new QTableWidgetItem(product->fermentables.at(i).f_name)); |
|
83 |
|
84 w = QString("%1").arg(product->fermentables.at(i).f_color, 1, 'f', 0, '0'); |
|
85 item = new QTableWidgetItem(w); |
|
86 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
87 ui->fermentablesTable->setItem(i, 2, item); |
|
88 |
|
89 item = new QTableWidgetItem(fermentable_types[product->fermentables.at(i).f_type]); |
|
90 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
|
91 ui->fermentablesTable->setItem(i, 3, item); |
|
92 |
|
93 item = new QTableWidgetItem(fermentable_graintypes[product->fermentables.at(i).f_graintype]); |
|
94 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
|
95 ui->fermentablesTable->setItem(i, 4, item); |
|
96 |
|
97 item = new QTableWidgetItem(fermentable_added[product->fermentables.at(i).f_added]); |
|
98 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
|
99 ui->fermentablesTable->setItem(i, 5, item); |
|
100 |
|
101 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(i).f_yield, 2, 'f', 1, '0')); |
|
102 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
103 ui->fermentablesTable->setItem(i, 6, item); |
|
104 |
|
105 item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables.at(i).f_amount, 4, 'f', 3, '0')); |
|
106 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
107 ui->fermentablesTable->setItem(i, 7, item); |
|
108 |
|
109 if (product->fermentables.at(i).f_added < 4) { |
|
110 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(i).f_percentage, 2, 'f', 1, '0')); |
|
111 } else { |
|
112 item = new QTableWidgetItem(QString("")); // Blank for bottling and kegging. |
|
113 } |
|
114 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
115 ui->fermentablesTable->setItem(i, 8, item); |
|
116 |
|
117 to100Fermentables(i); |
|
118 |
|
119 /* Add the Delete row button */ |
|
120 pWidget = new QWidget(); |
|
121 QPushButton* btn_dele = new QPushButton(); |
|
122 btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */ |
|
123 btn_dele->setText(tr("Delete")); |
|
124 connect(btn_dele, SIGNAL(clicked()), this, SLOT(deleteFermentRow_clicked())); |
|
125 pLayout = new QHBoxLayout(pWidget); |
|
126 pLayout->addWidget(btn_dele); |
|
127 pLayout->setContentsMargins(5, 0, 5, 0); |
|
128 pWidget->setLayout(pLayout); |
|
129 ui->fermentablesTable->setCellWidget(i, 10, pWidget); |
|
130 |
|
131 pWidget = new QWidget(); |
|
132 QPushButton* btn_edit = new QPushButton(); |
|
133 btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */ |
|
134 btn_edit->setText(tr("Edit")); |
|
135 connect(btn_edit, SIGNAL(clicked()), this, SLOT(editFermentRow_clicked())); |
|
136 pLayout = new QHBoxLayout(pWidget); |
|
137 pLayout->addWidget(btn_edit); |
|
138 pLayout->setContentsMargins(5, 0, 5, 0); |
|
139 pWidget->setLayout(pLayout); |
|
140 ui->fermentablesTable->setCellWidget(i, 11, pWidget); |
|
141 } |
|
142 } |
|
143 |
|
144 |
|
145 void EditProduct::calcFermentables() |
|
146 { |
|
147 int i; |
|
148 double psugar = 0, pcara = 0, d, s = 0, x, color; |
|
149 double vol = 0; // Volume sugars after boil |
|
150 double addedS = 0; // Added sugars after boil |
|
151 double addedmass = 0; // Added mass after boil |
|
152 double mvol = 0; // Mash volume |
|
153 double lintner = 0; // Total product lintner |
|
154 double sugarsf = 0; // fermentable sugars mash + boil |
|
155 double sugarsm = 0; // fermentable sugars in mash |
|
156 double sugardensity = 1.611; // kg/l in solution |
|
157 double mashtime = 0; // Total mash time |
|
158 double mashtemp = 0; // Average mash temperature |
|
159 double mashinfuse = 0; // Mash infuse amount |
|
160 double colort = 0; // Colors srm * vol totals |
|
161 double colorh = 0; // Colors ebc * vol * kt |
|
162 double colorn = 0; // Colors ebc * pt * pct |
|
163 |
|
164 qDebug() << "calcFermentables()"; |
|
165 |
|
166 /* |
|
167 * Get average mashtemp and mashtime from the Mash schedule. |
|
168 * It is possible that the schedule is not (yet) present. |
|
169 */ |
|
170 if (product->mashs.size() > 0) { |
|
171 for (i = 0; i < product->mashs.size(); i++) { |
|
172 if (product->mashs.at(i).step_type == 0) // Infusion |
|
173 mashinfuse += product->mashs.at(i).step_infuse_amount; |
|
174 if (product->mashs.at(i).step_temp < 75) { // Ignore mashout |
|
175 mashtime += product->mashs.at(i).step_time; |
|
176 mashtemp += product->mashs.at(i).step_time * product->mashs.at(i).step_temp; |
|
177 } |
|
178 } |
|
179 mashtemp = mashtemp / mashtime; |
|
180 mvol = mashinfuse; |
|
181 qDebug() << " mash time" << mashtime << "temp" << mashtemp << "infuse" << mashinfuse; |
|
182 } else { |
|
183 qDebug() << " no mash schedule"; |
|
184 } |
|
185 |
|
186 const QSignalBlocker blocker1(ui->est_ogEdit); |
|
187 const QSignalBlocker blocker2(ui->est_og2Edit); |
|
188 |
|
189 if (product->fermentables.size() < 1) { |
|
190 qDebug() << " no fermentables, return."; |
|
191 product->est_og = 0.980; |
|
192 ui->est_ogEdit->setValue(0.980); |
|
193 ui->est_og2Edit->setValue(0.980); |
|
194 ui->est_og3Edit->setValue(0.980); |
|
195 ui->est_ogShow->setValue(0.980); |
|
196 product->est_color = 0; |
|
197 ui->est_colorEdit->setValue(0); |
|
198 ui->est_colorEdit->setStyleSheet(Utils::ebc_to_style(0)); |
|
199 ui->est_color2Edit->setValue(0); |
|
200 ui->est_color2Edit->setStyleSheet(Utils::ebc_to_style(0)); |
|
201 ui->est_colorShow->setValue(0); |
|
202 ui->perc_mashShow->setValue(0); |
|
203 ui->perc_sugarsShow->setValue(0); |
|
204 ui->perc_caraShow->setValue(0); |
|
205 ui->lintnerShow->setValue(0); |
|
206 product->est_fg = 0.980; |
|
207 ui->est_fgEdit->setValue(0.980); |
|
208 ui->est_fg3Edit->setValue(0.980); |
|
209 ui->est_fgShow->setValue(0.980); |
|
210 ui->est_abvEdit->setValue(0); |
|
211 ui->est_abv2Edit->setValue(0); |
|
212 ui->est_abvShow->setValue(0); |
|
213 product->est_abv = 0; |
|
214 ui->calEdit->setValue(0); |
|
215 product->mashs_kg = 0; |
|
216 return; |
|
217 } |
|
218 qDebug() << " adjust to 100" << product->fermentables_use100; |
|
219 |
|
220 product->mashs_kg = 0; |
|
221 for (i = 0; i < product->fermentables.size(); i++) { |
|
222 if (product->fermentables.at(i).f_type == 1 && product->fermentables.at(i).f_added < 4) // Sugars |
|
223 psugar += product->fermentables.at(i).f_percentage; |
|
224 if (product->fermentables.at(i).f_graintype == 2 && product->fermentables.at(i).f_added < 4) // Crystal/Cara |
|
225 pcara += product->fermentables.at(i).f_percentage; |
|
226 d = product->fermentables.at(i).f_amount * (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100); |
|
227 if (product->fermentables.at(i).f_added == 0) { // Mash |
|
228 if (mvol > 0) { // If mash volume is known |
|
229 mvol += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_moisture / 100; |
|
230 s += d; |
|
231 } |
|
232 d = ui->efficiencyEdit->value() / 100 * d; |
|
233 sugarsm += d; |
|
234 product->mashs_kg += product->fermentables.at(i).f_amount; |
|
235 } |
|
236 if (product->fermentables.at(i).f_added == 0 || product->fermentables.at(i).f_added == 1) // Mash or boil |
|
237 sugarsf += d; |
|
238 if (product->fermentables.at(i).f_added == 2 || product->fermentables.at(i).f_added == 3) { // Fermentation or lagering |
|
239 x = (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100); |
|
240 addedS += product->fermentables.at(i).f_amount * x; |
|
241 addedmass += product->fermentables.at(i).f_amount; |
|
242 vol += (x * sugardensity + (1 - x) * 1) * product->fermentables.at(i).f_amount; |
|
243 } |
|
244 if (product->fermentables.at(i).f_added == 0 && |
|
245 (product->fermentables.at(i).f_type == 0 || product->fermentables.at(i).f_type == 4) && |
|
246 product->fermentables.at(i).f_color < 50) { |
|
247 lintner += product->fermentables.at(i).f_diastatic_power * product->fermentables.at(i).f_amount; |
|
248 } |
|
249 if (product->fermentables.at(i).f_added < 4) { |
|
250 colort += product->fermentables.at(i).f_amount * Utils::ebc_to_srm(product->fermentables.at(i).f_color); |
|
251 colorh += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_color * Utils::get_kt(product->fermentables.at(i).f_color); |
|
252 colorn += (product->fermentables.at(i).f_percentage / 100) * product->fermentables.at(i).f_color; // For 8.6 Pt wort. |
|
253 } |
|
254 } |
|
255 qDebug() << " colort" << colort << "colorh" << colorh << "colorn" << colorn; |
|
256 qDebug() << " psugar" << psugar << "pcara" << pcara << "mvol" << mvol; |
|
257 qDebug() << " sugarsf" << sugarsf << "sugarsm" << sugarsm; |
|
258 |
|
259 double og = Utils::estimate_sg(sugarsf + addedS, product->batch_size); |
|
260 qDebug() << " OG" << ui->est_ogEdit->value() << og; |
|
261 product->est_og = og; |
|
262 ui->est_ogEdit->setValue(og); |
|
263 ui->est_og2Edit->setValue(og); |
|
264 ui->est_og3Edit->setValue(og); |
|
265 ui->est_ogShow->setValue(og); |
|
266 |
|
267 product->preboil_sg = Utils::estimate_sg(sugarsm, product->boil_size); |
|
268 qDebug() << " preboil SG" << product->preboil_sg; |
|
269 |
|
270 /* |
|
271 * Color of the wort |
|
272 */ |
|
273 if (product->color_method == 4) { // Naudts |
|
274 color = round(((Utils::sg_to_plato(og) / 8.6) * colorn) + (product->boil_time / 60)); |
|
275 } else if (product->color_method == 3) { // Hans Halberstadt |
|
276 double bv = 0.925; // Beer loss efficiency |
|
277 double sr = 0.95; // Mash and sparge efficiency |
|
278 color = round((4.46 * bv * sr) / product->batch_size * colorh); |
|
279 } else { |
|
280 double cw = colort / product->batch_size * 8.34436; |
|
281 color = Utils::kw_to_ebc(product->color_method, cw); |
|
282 //qDebug() << " oud EBC" << color << "new EBC" << Utils::kw_to_newebc(product->color_method, cw) << "SRM" << Utils::kw_to_srm(product->color_method, cw); |
|
283 } |
|
284 qDebug() << " color" << ui->est_colorEdit->value() << color << product->est_color; |
|
285 product->est_color = color; |
|
286 ui->est_colorEdit->setValue(color); |
|
287 ui->est_colorEdit->setStyleSheet(Utils::ebc_to_style(color)); |
|
288 ui->est_color2Edit->setValue(color); |
|
289 ui->est_color2Edit->setStyleSheet(Utils::ebc_to_style(color)); |
|
290 ui->est_colorShow->setValue(color); |
|
291 |
|
292 /* |
|
293 * We don't have a equipment profile in products, |
|
294 * so we assume a certain guessed mashtun size. |
|
295 */ |
|
296 ui->perc_mashShow->setValue(round(product->mashs_kg / (product->boil_size / 3) * 100)); |
|
297 ui->perc_sugarsShow->setValue(round(psugar)); |
|
298 ui->perc_caraShow->setValue(round(pcara)); |
|
299 if (product->mashs_kg > 0) { |
|
300 qDebug() << " lintner" << lintner << " mashkg" << product->mashs_kg << "final" << round(lintner / product->mashs_kg); |
|
301 ui->lintnerShow->setValue(round(lintner / product->mashs_kg)); |
|
302 } else { |
|
303 qDebug() << " lintner N/A"; |
|
304 ui->lintnerShow->setValue(0); |
|
305 } |
|
306 |
|
307 /* |
|
308 * Calculate the apparant attenuation. |
|
309 */ |
|
310 double svg = 0; |
|
311 if (product->yeasts.size() > 0) { |
|
312 for (i = 0; i < product->yeasts.size(); i++) { |
|
313 if (product->yeasts.at(i).y_use == 0) { // Used in primary |
|
314 if (product->yeasts.at(i).y_attenuation > svg) |
|
315 svg = product->yeasts.at(i).y_attenuation; // Take the highest if multiple yeasts. |
|
316 } |
|
317 // TODO: brett or others in secondary. |
|
318 } |
|
319 qDebug() << " SVG" << svg; |
|
320 } |
|
321 if (svg == 0) |
|
322 svg = 77.0; |
|
323 ui->est_svgEdit->setValue(svg); |
|
324 |
|
325 double fg; |
|
326 if (product->mashs_kg > 0 && mashinfuse > 0 && mashtime > 0 && mashtemp > 0) |
|
327 fg = Utils::estimate_fg(psugar, pcara, mashinfuse / product->mashs_kg, mashtime, mashtemp, svg, og); |
|
328 else |
|
329 fg = Utils::estimate_fg(psugar, pcara, 0, 0, 0, svg, og); |
|
330 qDebug() << " FG" << ui->est_fgEdit->value() << fg; |
|
331 product->est_fg = fg; |
|
332 ui->est_fgEdit->setValue(fg); |
|
333 ui->est_fg3Edit->setValue(fg); |
|
334 ui->est_fgShow->setValue(fg); |
|
335 |
|
336 double abv = Utils::abvol(og, fg); |
|
337 qDebug() << " ABV" << ui->est_abvEdit->value() << abv; |
|
338 ui->est_abvEdit->setValue(abv); |
|
339 ui->est_abv2Edit->setValue(abv); |
|
340 ui->est_abvShow->setValue(abv); |
|
341 product->est_abv = abv; |
|
342 |
|
343 /* |
|
344 * Calculate kilocalories/liter. Formula from brouwhulp. |
|
345 * Take the alcohol and sugar parts and then combine. |
|
346 */ |
|
347 double alc = 1881.22 * fg * (og - fg) / (1.775 - og); |
|
348 double sug = 3550 * fg * (0.1808 * og + 0.8192 * fg - 1.0004); |
|
349 ui->calEdit->setValue(round((alc + sug) / (12 * 0.0295735296))); |
|
350 |
|
351 // Bottle priming |
|
352 double priming_total = 0; |
|
353 for (i = 0; i < product->fermentables.size(); i++) { |
|
354 if (product->fermentables.at(i).f_added == 4) { |
|
355 priming_total += ((product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100)) * |
|
356 product->fermentables.at(i).f_amount; |
|
357 qDebug() << " priming" << product->fermentables.at(i).f_amount << "total" << priming_total; |
|
358 } |
|
359 } |
|
360 double grl = priming_total * 1000.0 * (1 / product->batch_size); |
|
361 double volco2 = grl * 0.510; |
|
362 qDebug() << " priming gr/l" << grl << "volco2" << volco2; |
|
363 |
|
364 if (volco2 > 0) { |
|
365 product->est_carb = volco2; |
|
366 ui->est_carbEdit->setValue(product->est_carb); |
|
367 ui->est_carbShow->setValue(product->est_carb); |
|
368 } |
|
369 } |
|
370 |
|
371 |
|
372 void EditProduct::calcFermentablesFromOG(double og) |
|
373 { |
|
374 qDebug() << "calcFermentablesFromOG" << og; |
|
375 |
|
376 int i; |
|
377 double totmass = 0; |
|
378 double tot = 0; |
|
379 double d, amount; |
|
380 double efficiency = product->efficiency; |
|
381 double sug = Utils::sg_to_plato(og) * product->batch_size * og / 100.0; // total amount of sugars in kg. |
|
382 |
|
383 for (i = 0; i < product->fermentables.size(); i++) { |
|
384 if (product->fermentables.at(i).f_added < 4) { |
|
385 d = product->fermentables.at(i).f_percentage / 100.0 * |
|
386 (product->fermentables.at(i).f_yield / 100.0) * |
|
387 (1 - product->fermentables.at(i).f_moisture / 100.0); |
|
388 if (product->fermentables.at(i).f_added == 0) // Mash |
|
389 d = efficiency / 100.0 * d; |
|
390 tot += d; |
|
391 } |
|
392 } |
|
393 if (tot) |
|
394 totmass = round((sug / tot) * 1000.0) / 1000.0; |
|
395 |
|
396 if (totmass) { |
|
397 for (i = 0; i < product->fermentables.size(); i++) { |
|
398 amount = round(product->fermentables.at(i).f_percentage * 10.0 * totmass) / 1000.0; |
|
399 product->fermentables[i].f_amount = amount; |
|
400 } |
|
401 } |
|
402 } |
|
403 |
|
404 |
|
405 void EditProduct::ferment_perc_mash_valueChanged(int value) |
|
406 { |
|
407 if (value < 90) |
|
408 ui->perc_mashShow->setStyleSheet(bar_green); |
|
409 else if (value < 100) |
|
410 ui->perc_mashShow->setStyleSheet(bar_orange); |
|
411 else |
|
412 ui->perc_mashShow->setStyleSheet(bar_red); |
|
413 } |
|
414 |
|
415 |
|
416 void EditProduct::ferment_perc_sugars_valueChanged(int value) |
|
417 { |
|
418 if (value < 20) |
|
419 ui->perc_sugarsShow->setStyleSheet(bar_green); |
|
420 else |
|
421 ui->perc_sugarsShow->setStyleSheet(bar_red); |
|
422 } |
|
423 |
|
424 |
|
425 void EditProduct::ferment_perc_cara_valueChanged(int value) |
|
426 { |
|
427 if (value < 25) |
|
428 ui->perc_caraShow->setStyleSheet(bar_green); |
|
429 else |
|
430 ui->perc_caraShow->setStyleSheet(bar_red); |
|
431 } |
|
432 |
|
433 |
|
434 void EditProduct::ferment_lintner_valueChanged(int value) |
|
435 { |
|
436 if (value < 30) |
|
437 ui->lintnerShow->setStyleSheet(bar_red); |
|
438 else if (value < 40) |
|
439 ui->lintnerShow->setStyleSheet(bar_orange); |
|
440 else |
|
441 ui->lintnerShow->setStyleSheet(bar_green); |
|
442 } |
|
443 |
|
444 |
|
445 void EditProduct::addFermentRow_clicked() |
|
446 { |
|
447 Fermentables newf; |
|
448 |
|
449 qDebug() << "Add fermentable row"; |
|
450 |
|
451 for (int i = 0; i < product->fermentables.size(); i++) { |
|
452 if (product->fermentables.at(i).f_amount == 0 && product->fermentables.at(i).f_color == 0) |
|
453 return; // Add only one at a time. |
|
454 } |
|
455 |
|
456 newf.f_name = "Select one"; |
|
457 newf.f_origin = ""; |
|
458 newf.f_supplier = ""; |
|
459 newf.f_amount = 0; |
|
460 newf.f_cost = 0; |
|
461 newf.f_type = 0; |
|
462 newf.f_yield = 0; |
|
463 newf.f_color = 0; |
|
464 newf.f_coarse_fine_diff = 0; |
|
465 newf.f_moisture = 0; |
|
466 newf.f_diastatic_power = 0; |
|
467 newf.f_protein = 0; |
|
468 newf.f_dissolved_protein = 0; |
|
469 newf.f_max_in_batch = 100; |
|
470 newf.f_graintype = 0; |
|
471 newf.f_added = 0; |
|
472 newf.f_recommend_mash = true; |
|
473 newf.f_add_after_boil = false; |
|
474 newf.f_adjust_to_total_100 = false; |
|
475 newf.f_percentage = 0; |
|
476 newf.f_di_ph = 0; |
|
477 newf.f_acid_to_ph_57 = 0; |
|
478 |
|
479 product->fermentables.append(newf); |
|
480 emit refreshAll(); |
|
481 } |
|
482 |
|
483 |
|
484 void EditProduct::deleteFermentRow_clicked() |
|
485 { |
|
486 if (product->locked) |
|
487 return; |
|
488 |
|
489 QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender()); |
|
490 int row = pb->objectName().toInt(); |
|
491 qDebug() << "Delete fermentable row" << row << product->fermentables.size(); |
|
492 |
|
493 if (product->fermentables.size() < 1) |
|
494 return; |
|
495 |
|
496 int rc = QMessageBox::warning(this, tr("Delete fermentable"), tr("Delete %1").arg(product->fermentables.at(row).f_name), |
|
497 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); |
|
498 if (rc == QMessageBox::No) |
|
499 return; |
|
500 |
|
501 product->fermentables.removeAt(row); |
|
502 |
|
503 /* |
|
504 * Recalculate the percentages on the rows left. |
|
505 */ |
|
506 double total = 0; |
|
507 for (int i = 0; i < product->fermentables.size(); i++) |
|
508 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging |
|
509 total += product->fermentables.at(i).f_amount; |
|
510 for (int i = 0; i < product->fermentables.size(); i++) |
|
511 if (product->fermentables.at(i).f_added < 4) |
|
512 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100; |
|
513 |
|
514 is_changed(); |
|
515 emit refreshAll(); |
|
516 } |
|
517 |
|
518 |
|
519 void EditProduct::ferment_amount_changed(double val) |
|
520 { |
|
521 QTableWidgetItem *item; |
|
522 double total = 0, perc; |
|
523 |
|
524 if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4) |
|
525 return; |
|
526 |
|
527 qDebug() << "ferment_amount_changed()" << product->fermentables_row << val; |
|
528 |
|
529 product->fermentables[product->fermentables_row].f_amount = val; |
|
530 item = new QTableWidgetItem(QString("%1 Kg").arg(val, 4, 'f', 3, '0')); |
|
531 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
532 ui->fermentablesTable->setItem(product->fermentables_row, 7, item); |
|
533 |
|
534 for (int i = 0; i < product->fermentables.size(); i++) |
|
535 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging |
|
536 total += product->fermentables.at(i).f_amount; |
|
537 /* |
|
538 * Recalculate the percentages |
|
539 */ |
|
540 for (int i = 0; i < product->fermentables.size(); i++) { |
|
541 if (product->fermentables.at(i).f_added < 4) { |
|
542 perc = product->fermentables.at(i).f_amount / total * 100; |
|
543 product->fermentables[i].f_percentage = perc; |
|
544 item = new QTableWidgetItem(QString("%1%").arg(perc, 2, 'f', 1, '0')); |
|
545 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
546 ui->fermentablesTable->setItem(i, 8, item); |
|
547 if (i == product->fermentables_row) |
|
548 this->pctEdit->setValue(perc); |
|
549 } |
|
550 } |
|
551 is_changed(); |
|
552 } |
|
553 |
|
554 |
|
555 void EditProduct::ferment_pct_changed(double val) |
|
556 { |
|
557 QTableWidgetItem *item; |
|
558 double total = 0, row100 = -1; |
|
559 |
|
560 if (! product->fermentables_use100) |
|
561 return; |
|
562 |
|
563 qDebug() << "ferment_pct_changed()" << product->fermentables_row << val; |
|
564 /* |
|
565 * Since we have arrived here, adjust_to_100 is active and |
|
566 * this is not the entry to be adjusted to 100. |
|
567 */ |
|
568 for (int i = 0; i < product->fermentables.size(); i++) { |
|
569 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging |
|
570 total += product->fermentables.at(i).f_amount; |
|
571 if (product->fermentables.at(i).f_adjust_to_total_100) |
|
572 row100 = i; |
|
573 } |
|
574 double oldperc = product->fermentables.at(product->fermentables_row).f_percentage; |
|
575 double diffp = val - oldperc; |
|
576 double diffw = (diffp / 100) * total; |
|
577 qDebug() << "row100" << row100 << "total" << total << "diff kg" << diffw << "diff %" << diffp; |
|
578 |
|
579 product->fermentables[product->fermentables_row].f_percentage += diffp; |
|
580 product->fermentables[product->fermentables_row].f_amount += diffw; |
|
581 product->fermentables[row100].f_percentage -= diffp; |
|
582 product->fermentables[row100].f_amount -= diffw; |
|
583 |
|
584 item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables[product->fermentables_row].f_amount, 4, 'f', 3, '0')); |
|
585 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
586 ui->fermentablesTable->setItem(product->fermentables_row, 7, item); |
|
587 this->famountEdit->setValue(product->fermentables[product->fermentables_row].f_amount); |
|
588 |
|
589 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables[product->fermentables_row].f_percentage, 2, 'f', 1, '0')); |
|
590 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
591 ui->fermentablesTable->setItem(product->fermentables_row, 8, item); |
|
592 |
|
593 item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables[row100].f_amount, 4, 'f', 3, '0')); |
|
594 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
595 ui->fermentablesTable->setItem(row100, 7, item); |
|
596 |
|
597 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables[row100].f_percentage, 2, 'f', 1, '0')); |
|
598 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
599 ui->fermentablesTable->setItem(row100, 8, item); |
|
600 |
|
601 is_changed(); |
|
602 } |
|
603 |
|
604 |
|
605 void EditProduct::ferment_to100_changed(bool val) |
|
606 { |
|
607 qDebug() << "ferment_to100_changed()" << product->fermentables_row << val << product->fermentables_use100; |
|
608 |
|
609 if (product->fermentables.at(product->fermentables_row).f_added >= 4) { |
|
610 const QSignalBlocker blocker1(to100Edit); |
|
611 product->fermentables[product->fermentables_row].f_adjust_to_total_100 = false; |
|
612 to100Edit->setChecked(false); |
|
613 return; |
|
614 } |
|
615 |
|
616 /* |
|
617 * Three scenario's. |
|
618 * 1. There is no fermentable selected yet, just mark it. |
|
619 * 2. There is current one is selected, deselect it. |
|
620 * 3. There is another one selected, deselect and select this one. |
|
621 */ |
|
622 if (! product->fermentables_use100 && val) { |
|
623 /* Scenario 1. */ |
|
624 product->fermentables_use100 = true; |
|
625 product->fermentables[product->fermentables_row].f_adjust_to_total_100 = true; |
|
626 pctEdit->setReadOnly(false); |
|
627 famountEdit->setReadOnly(true); |
|
628 } else if (product->fermentables_use100 && product->fermentables[product->fermentables_row].f_adjust_to_total_100 && ! val) { |
|
629 /* Scenario 2. */ |
|
630 product->fermentables[product->fermentables_row].f_adjust_to_total_100 = false; |
|
631 product->fermentables_use100 = false; |
|
632 pctEdit->setReadOnly(true); |
|
633 famountEdit->setReadOnly(false); |
|
634 } else if (product->fermentables_use100 && ! product->fermentables[product->fermentables_row].f_adjust_to_total_100 && val) { |
|
635 /* Scenario 3. */ |
|
636 for (int i = 0; i < product->fermentables.size(); i++) { |
|
637 product->fermentables[i].f_adjust_to_total_100 = false; |
|
638 } |
|
639 product->fermentables[product->fermentables_row].f_adjust_to_total_100 = true; |
|
640 } else { |
|
641 qDebug() << "bug"; |
|
642 return; |
|
643 } |
|
644 |
|
645 for (int i = 0; i < product->fermentables.size(); i++) { |
|
646 to100Fermentables(i); |
|
647 } |
|
648 is_changed(); |
|
649 } |
|
650 |
|
651 |
|
652 void EditProduct::ferment_select_changed(int val) |
|
653 { |
|
654 QSqlQuery query; |
|
655 bool instock = finstockEdit->isChecked(); |
|
656 QString w; |
|
657 QTableWidgetItem *item; |
|
658 |
|
659 if (val < 1) |
|
660 return; |
|
661 |
|
662 qDebug() << "ferment_select_changed()" << product->fermentables_row << val << instock; |
|
663 |
|
664 /* |
|
665 * Search the fermentable pointed by the index and instock flag. |
|
666 */ |
|
667 QString sql = "SELECT name,origin,supplier,cost,type,yield,color,coarse_fine_diff,moisture,diastatic_power,protein,dissolved_protein,max_in_batch," |
|
668 "graintype,recommend_mash,add_after_boil,di_ph,acid_to_ph_57 FROM inventory_fermentables "; |
|
669 if (instock) |
|
670 sql.append("WHERE inventory > 0 "); |
|
671 sql.append("ORDER BY supplier,name"); |
|
672 query.prepare(sql); |
|
673 query.exec(); |
|
674 query.first(); |
|
675 for (int i = 0; i < (val - 1); i++) { |
|
676 query.next(); |
|
677 } |
|
678 qDebug() << "found" << query.value(2).toString() << query.value(0).toString(); |
|
679 |
|
680 /* |
|
681 * Replace the fermentable record contents |
|
682 */ |
|
683 product->fermentables[product->fermentables_row].f_name = query.value(0).toString(); |
|
684 product->fermentables[product->fermentables_row].f_origin = query.value(1).toString(); |
|
685 product->fermentables[product->fermentables_row].f_supplier = query.value(2).toString(); |
|
686 product->fermentables[product->fermentables_row].f_cost = query.value(3).toDouble(); |
|
687 product->fermentables[product->fermentables_row].f_type = query.value(4).toInt(); |
|
688 product->fermentables[product->fermentables_row].f_yield = query.value(5).toDouble(); |
|
689 product->fermentables[product->fermentables_row].f_color = query.value(6).toDouble(); |
|
690 product->fermentables[product->fermentables_row].f_coarse_fine_diff = query.value(7).toDouble(); |
|
691 product->fermentables[product->fermentables_row].f_moisture = query.value(8).toDouble(); |
|
692 product->fermentables[product->fermentables_row].f_diastatic_power = query.value(9).toDouble(); |
|
693 product->fermentables[product->fermentables_row].f_protein = query.value(10).toDouble(); |
|
694 product->fermentables[product->fermentables_row].f_dissolved_protein = query.value(11).toDouble(); |
|
695 product->fermentables[product->fermentables_row].f_max_in_batch = query.value(12).toDouble(); |
|
696 product->fermentables[product->fermentables_row].f_graintype = query.value(13).toInt(); |
|
697 product->fermentables[product->fermentables_row].f_recommend_mash = query.value(14).toInt() ? true:false; |
|
698 product->fermentables[product->fermentables_row].f_add_after_boil = query.value(15).toInt() ? true:false; |
|
699 product->fermentables[product->fermentables_row].f_di_ph = query.value(16).toDouble(); |
|
700 product->fermentables[product->fermentables_row].f_acid_to_ph_57 = query.value(17).toDouble(); |
|
701 |
|
702 /* |
|
703 * Update the visible fields |
|
704 */ |
|
705 fnameEdit->setText(product->fermentables.at(product->fermentables_row).f_name); |
|
706 fsupplierEdit->setText(product->fermentables.at(product->fermentables_row).f_supplier); |
|
707 fmaxEdit->setValue(product->fermentables.at(product->fermentables_row).f_max_in_batch); |
|
708 |
|
709 ui->fermentablesTable->setItem(product->fermentables_row, 0, new QTableWidgetItem(product->fermentables.at(product->fermentables_row).f_supplier)); |
|
710 ui->fermentablesTable->setItem(product->fermentables_row, 1, new QTableWidgetItem(product->fermentables.at(product->fermentables_row).f_name)); |
|
711 |
|
712 w = QString("%1").arg(product->fermentables.at(product->fermentables_row).f_color, 1, 'f', 0, '0'); |
|
713 item = new QTableWidgetItem(w); |
|
714 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
715 ui->fermentablesTable->setItem(product->fermentables_row, 2, item); |
|
716 |
|
717 item = new QTableWidgetItem(fermentable_types[product->fermentables.at(product->fermentables_row).f_type]); |
|
718 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
|
719 ui->fermentablesTable->setItem(product->fermentables_row, 3, item); |
|
720 |
|
721 item = new QTableWidgetItem(fermentable_graintypes[product->fermentables.at(product->fermentables_row).f_graintype]); |
|
722 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
|
723 ui->fermentablesTable->setItem(product->fermentables_row, 4, item); |
|
724 |
|
725 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(product->fermentables_row).f_yield, 2, 'f', 1, '0')); |
|
726 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
727 ui->fermentablesTable->setItem(product->fermentables_row, 6, item); |
|
728 |
|
729 calcFermentables(); |
|
730 is_changed(); |
|
731 } |
|
732 |
|
733 |
|
734 void EditProduct::ferment_instock_changed(bool val) |
|
735 { |
|
736 QSqlQuery query; |
|
737 |
|
738 qDebug() << "ferment_instock_changed()" << product->fermentables_row << val; |
|
739 |
|
740 this->fselectEdit->setCurrentIndex(-1); |
|
741 this->fselectEdit->clear(); |
|
742 QString sql = "SELECT supplier,name,color,inventory FROM inventory_fermentables "; |
|
743 if (val) |
|
744 sql.append("WHERE inventory > 0 "); |
|
745 sql.append("ORDER BY supplier,name"); |
|
746 query.prepare(sql); |
|
747 query.exec(); |
|
748 query.first(); |
|
749 this->fselectEdit->addItem(""); // Start with empty value |
|
750 for (int i = 0; i < query.size(); i++) { |
|
751 this->fselectEdit->addItem(query.value(0).toString()+" - "+query.value(1).toString()+" ("+query.value(2).toString()+" EBC) "+ |
|
752 QString("%1 kg").arg(query.value(3).toDouble(), 4, 'f', 3, '0')); |
|
753 query.next(); |
|
754 } |
|
755 } |
|
756 |
|
757 |
|
758 void EditProduct::ferment_added_changed(int val) |
|
759 { |
|
760 qDebug() << "ferment_added_changed()" << product->fermentables_row << val; |
|
761 |
|
762 product->fermentables[product->fermentables_row].f_added = val; |
|
763 QTableWidgetItem *item = new QTableWidgetItem(fermentable_added[val]); |
|
764 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
|
765 ui->fermentablesTable->setItem(product->fermentables_row, 5, item); |
|
766 |
|
767 famountEdit->setReadOnly(product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4); |
|
768 pctEdit->setReadOnly(! (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4)); |
|
769 |
|
770 double total = 0; |
|
771 for (int i = 0; i < product->fermentables.size(); i++) |
|
772 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging |
|
773 total += product->fermentables.at(i).f_amount; |
|
774 for (int i = 0; i < product->fermentables.size(); i++) |
|
775 if (product->fermentables.at(i).f_added < 4) |
|
776 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100; |
|
777 |
|
778 is_changed(); |
|
779 emit refreshAll(); |
|
780 } |
|
781 |
|
782 |
|
783 void EditProduct::editFermentRow_clicked() |
|
784 { |
|
785 QSqlQuery query; |
|
786 |
|
787 if (product->locked) |
|
788 return; |
|
789 |
|
790 QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender()); |
|
791 product->fermentables_row = pb->objectName().toInt(); |
|
792 qDebug() << "Edit fermentable row" << product->fermentables_row; |
|
793 Fermentables backup = product->fermentables.at(product->fermentables_row); |
|
794 |
|
795 QDialog* dialog = new QDialog(this); |
|
796 dialog->resize(738, 287); |
|
797 QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); |
|
798 buttonBox->setObjectName(QString::fromUtf8("buttonBox")); |
|
799 buttonBox->setGeometry(QRect(30, 240, 671, 32)); |
|
800 buttonBox->setLayoutDirection(Qt::LeftToRight); |
|
801 buttonBox->setOrientation(Qt::Horizontal); |
|
802 buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); |
|
803 buttonBox->setCenterButtons(true); |
|
804 QLabel *nameLabel = new QLabel(dialog); |
|
805 nameLabel->setObjectName(QString::fromUtf8("nameLabel")); |
|
806 nameLabel->setText(tr("Current ingredient:")); |
|
807 nameLabel->setGeometry(QRect(10, 10, 141, 20)); |
|
808 nameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
809 QLabel *supplierLabel = new QLabel(dialog); |
|
810 supplierLabel->setObjectName(QString::fromUtf8("supplierLabel")); |
|
811 supplierLabel->setText(tr("Supplier:")); |
|
812 supplierLabel->setGeometry(QRect(10, 40, 141, 20)); |
|
813 supplierLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
814 QLabel *amountLabel = new QLabel(dialog); |
|
815 amountLabel->setObjectName(QString::fromUtf8("amountLabel")); |
|
816 amountLabel->setText(tr("Amount in kg:")); |
|
817 amountLabel->setGeometry(QRect(10, 100, 141, 20)); |
|
818 amountLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
819 QLabel *pctLabel = new QLabel(dialog); |
|
820 pctLabel->setObjectName(QString::fromUtf8("pctLabel")); |
|
821 pctLabel->setText(tr("Percentage in batch:")); |
|
822 pctLabel->setGeometry(QRect(10, 130, 141, 20)); |
|
823 pctLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
824 QLabel *to100Label = new QLabel(dialog); |
|
825 to100Label->setObjectName(QString::fromUtf8("to100Label")); |
|
826 to100Label->setText(tr("Auto fill to 100%:")); |
|
827 to100Label->setGeometry(QRect(10, 160, 141, 20)); |
|
828 to100Label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
829 QLabel *addedLabel = new QLabel(dialog); |
|
830 addedLabel->setObjectName(QString::fromUtf8("addedLabel")); |
|
831 addedLabel->setText(tr("Use at:")); |
|
832 addedLabel->setGeometry(QRect(10, 190, 141, 20)); |
|
833 addedLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
834 QLabel *selectLabel = new QLabel(dialog); |
|
835 selectLabel->setObjectName(QString::fromUtf8("selectLabel")); |
|
836 selectLabel->setText(tr("Select ingredient:")); |
|
837 selectLabel->setGeometry(QRect(10, 70, 141, 20)); |
|
838 selectLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
839 QLabel *instockLabel = new QLabel(dialog); |
|
840 instockLabel->setObjectName(QString::fromUtf8("instockLabel")); |
|
841 instockLabel->setText(tr("In stock:")); |
|
842 instockLabel->setGeometry(QRect(525, 70, 121, 20)); |
|
843 instockLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
844 QLabel *maxLabel = new QLabel(dialog); |
|
845 maxLabel->setObjectName(QString::fromUtf8("maxLabel")); |
|
846 maxLabel->setText(tr("Max in batch:")); |
|
847 maxLabel->setGeometry(QRect(420, 130, 121, 20)); |
|
848 maxLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
849 |
|
850 fselectEdit = new QComboBox(dialog); |
|
851 fselectEdit->setObjectName(QString::fromUtf8("fselectEdit")); |
|
852 fselectEdit->setGeometry(QRect(160, 70, 371, 23)); |
|
853 |
|
854 fnameEdit = new QLineEdit(dialog); |
|
855 fnameEdit->setObjectName(QString::fromUtf8("fnameEdit")); |
|
856 fnameEdit->setText(product->fermentables.at(product->fermentables_row).f_name); |
|
857 fnameEdit->setGeometry(QRect(160, 10, 511, 23)); |
|
858 fnameEdit->setReadOnly(true); |
|
859 fsupplierEdit = new QLineEdit(dialog); |
|
860 fsupplierEdit->setObjectName(QString::fromUtf8("fsupplierEdit")); |
|
861 fsupplierEdit->setText(product->fermentables.at(product->fermentables_row).f_supplier); |
|
862 fsupplierEdit->setGeometry(QRect(160, 40, 511, 23)); |
|
863 fsupplierEdit->setReadOnly(true); |
|
864 famountEdit = new QDoubleSpinBox(dialog); |
|
865 famountEdit->setObjectName(QString::fromUtf8("famountEdit")); |
|
866 famountEdit->setGeometry(QRect(160, 100, 121, 24)); |
|
867 famountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
868 famountEdit->setAccelerated(true); |
|
869 famountEdit->setDecimals(3); |
|
870 famountEdit->setReadOnly(product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4); |
|
871 famountEdit->setMaximum(100000.0); |
|
872 famountEdit->setSingleStep(0.0010); |
|
873 famountEdit->setValue(product->fermentables.at(product->fermentables_row).f_amount); |
|
874 |
|
875 pctEdit = new QDoubleSpinBox(dialog); |
|
876 pctEdit->setObjectName(QString::fromUtf8("pctEdit")); |
|
877 pctEdit->setGeometry(QRect(160, 130, 121, 24)); |
|
878 pctEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
879 pctEdit->setAccelerated(true); |
|
880 pctEdit->setDecimals(1); |
|
881 if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4) { |
|
882 if (product->fermentables.at(product->fermentables_row).f_adjust_to_total_100) |
|
883 pctEdit->setReadOnly(true); |
|
884 else |
|
885 pctEdit->setReadOnly(false); |
|
886 } else { |
|
887 pctEdit->setReadOnly(true); |
|
888 } |
|
889 pctEdit->setMaximum(100.0); |
|
890 pctEdit->setSingleStep(0.1); |
|
891 pctEdit->setValue(product->fermentables.at(product->fermentables_row).f_percentage); |
|
892 |
|
893 faddedEdit = new QComboBox(dialog); |
|
894 faddedEdit->setObjectName(QString::fromUtf8("faddedEdit")); |
|
895 faddedEdit->setGeometry(QRect(160, 190, 161, 23)); |
|
896 faddedEdit->addItem(tr("Mash")); |
|
897 faddedEdit->addItem(tr("Boil")); |
|
898 faddedEdit->addItem(tr("Fermentation")); |
|
899 faddedEdit->addItem(tr("Lagering")); |
|
900 faddedEdit->addItem(tr("Bottle")); |
|
901 faddedEdit->addItem(tr("Kegs")); |
|
902 faddedEdit->setCurrentIndex(product->fermentables.at(product->fermentables_row).f_added); |
|
903 |
|
904 to100Edit = new QCheckBox(dialog); |
|
905 to100Edit->setObjectName(QString::fromUtf8("to100Edit")); |
|
906 to100Edit->setGeometry(QRect(160, 160, 85, 21)); |
|
907 to100Edit->setChecked(product->fermentables.at(product->fermentables_row).f_adjust_to_total_100); |
|
908 |
|
909 finstockEdit = new QCheckBox(dialog); |
|
910 finstockEdit->setObjectName(QString::fromUtf8("instockEdit")); |
|
911 finstockEdit->setGeometry(QRect(655, 70, 85, 21)); |
|
912 finstockEdit->setChecked(true); |
|
913 |
|
914 fmaxEdit = new QDoubleSpinBox(dialog); |
|
915 fmaxEdit->setObjectName(QString::fromUtf8("fmaxEdit")); |
|
916 fmaxEdit->setGeometry(QRect(550, 130, 121, 24)); |
|
917 fmaxEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
|
918 fmaxEdit->setReadOnly(true); |
|
919 fmaxEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); |
|
920 fmaxEdit->setDecimals(1); |
|
921 fmaxEdit->setValue(product->fermentables.at(product->fermentables_row).f_max_in_batch); |
|
922 |
|
923 ferment_instock_changed(true); |
|
924 |
|
925 connect(fselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::ferment_select_changed); |
|
926 connect(famountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::ferment_amount_changed); |
|
927 connect(pctEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::ferment_pct_changed); |
|
928 connect(faddedEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::ferment_added_changed); |
|
929 connect(to100Edit, &QCheckBox::stateChanged, this, &EditProduct::ferment_to100_changed); |
|
930 connect(finstockEdit, &QCheckBox::stateChanged, this, &EditProduct::ferment_instock_changed); |
|
931 connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); |
|
932 connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); |
|
933 |
|
934 dialog->setModal(true); |
|
935 dialog->exec(); |
|
936 if (dialog->result() == QDialog::Rejected) { |
|
937 qDebug() << "reject and rollback"; |
|
938 product->fermentables[product->fermentables_row] = backup; |
|
939 /* |
|
940 * Recalculate the percentages |
|
941 */ |
|
942 double total = 0; |
|
943 for (int i = 0; i < product->fermentables.size(); i++) |
|
944 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging |
|
945 total += product->fermentables.at(i).f_amount; |
|
946 product->fermentables_use100 = false; |
|
947 for (int i = 0; i < product->fermentables.size(); i++) { |
|
948 if (product->fermentables.at(i).f_adjust_to_total_100) |
|
949 product->fermentables_use100 = true; |
|
950 if (product->fermentables.at(i).f_added < 4) { |
|
951 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100; |
|
952 } |
|
953 } |
|
954 } |
|
955 |
|
956 disconnect(fselectEdit, nullptr, nullptr, nullptr); |
|
957 disconnect(famountEdit, nullptr, nullptr, nullptr); |
|
958 disconnect(pctEdit, nullptr, nullptr, nullptr); |
|
959 disconnect(faddedEdit, nullptr, nullptr, nullptr); |
|
960 disconnect(to100Edit, nullptr, nullptr, nullptr); |
|
961 disconnect(finstockEdit, nullptr, nullptr, nullptr); |
|
962 disconnect(buttonBox, nullptr, nullptr, nullptr); |
|
963 |
|
964 emit refreshAll(); |
|
965 } |
|
966 |
|
967 |