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