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