src/EditProductTab6.cpp

changeset 195
9887278c4fbe
parent 179
512f492358e3
child 196
f7954f2d4451
equal deleted inserted replaced
194:ea8cce5e7eb9 195:9887278c4fbe
87 87
88 item = new QTableWidgetItem(QString("%1%").arg(product->yeasts.at(i).y_attenuation, 2, 'f', 1, '0')); 88 item = new QTableWidgetItem(QString("%1%").arg(product->yeasts.at(i).y_attenuation, 2, 'f', 1, '0'));
89 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 89 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
90 ui->yeastsTable->setItem(i, 8, item); 90 ui->yeastsTable->setItem(i, 8, item);
91 91
92 if (product->yeasts.at(i).y_form == 0) 92 if (product->yeasts.at(i).y_form == YEAST_FORMS_LIQUID)
93 item = new QTableWidgetItem(QString("%1 pack").arg(product->yeasts.at(i).y_amount, 1, 'f', 0, '0')); 93 item = new QTableWidgetItem(QString("%1 pack").arg(product->yeasts.at(i).y_amount, 1, 'f', 0, '0'));
94 else if (product->yeasts.at(i).y_form == 1) 94 else if (product->yeasts.at(i).y_form == YEAST_FORMS_DRY || product->yeasts.at(i).y_form == YEAST_FORMS_DRIED)
95 item = new QTableWidgetItem(QString("%1 gr").arg(product->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0')); 95 item = new QTableWidgetItem(QString("%1 gr").arg(product->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0'));
96 else 96 else
97 item = new QTableWidgetItem(QString("%1 ml").arg(product->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0')); 97 item = new QTableWidgetItem(QString("%1 ml").arg(product->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0'));
98 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 98 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
99 ui->yeastsTable->setItem(i, 9, item); 99 ui->yeastsTable->setItem(i, 9, item);
100 100
101 if (product->yeasts.at(i).y_form == 0) 101 if (product->yeasts.at(i).y_form == YEAST_FORMS_LIQUID)
102 item = new QTableWidgetItem(QString("%1 pack").arg(product->yeasts.at(i).y_inventory, 1, 'f', 0, '0')); 102 item = new QTableWidgetItem(QString("%1 pack").arg(product->yeasts.at(i).y_inventory, 1, 'f', 0, '0'));
103 else if (product->yeasts.at(i).y_form == 1) 103 else if (product->yeasts.at(i).y_form == YEAST_FORMS_DRY || product->yeasts.at(i).y_form == YEAST_FORMS_DRIED)
104 item = new QTableWidgetItem(QString("%1 gr").arg(product->yeasts.at(i).y_inventory * 1000.0, 3, 'f', 2, '0')); 104 item = new QTableWidgetItem(QString("%1 gr").arg(product->yeasts.at(i).y_inventory * 1000.0, 3, 'f', 2, '0'));
105 else 105 else
106 item = new QTableWidgetItem(QString("%1 ml").arg(product->yeasts.at(i).y_inventory * 1000.0, 3, 'f', 2, '0')); 106 item = new QTableWidgetItem(QString("%1 ml").arg(product->yeasts.at(i).y_inventory * 1000.0, 3, 'f', 2, '0'));
107 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 107 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
108 if (product->yeasts.at(i).y_inventory < product->yeasts.at(i).y_amount)
109 item->setForeground(QBrush(QColor(Qt::red)));
108 ui->yeastsTable->setItem(i, 10, item); 110 ui->yeastsTable->setItem(i, 10, item);
109 111
110 pWidget = new QWidget(); 112 pWidget = new QWidget();
111 QPushButton* btn_dele = new QPushButton(); 113 QPushButton* btn_dele = new QPushButton();
112 btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */ 114 btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */
130 ui->yeastsTable->setCellWidget(i, 12, pWidget); 132 ui->yeastsTable->setCellWidget(i, 12, pWidget);
131 } 133 }
132 } 134 }
133 135
134 136
137 void EditProduct::initYeast()
138 {
139 ui->est_og4Edit->setValue(product->est_og);
140 ui->est_fg3Edit->setValue(product->est_fg);
141 ui->est_abv2Edit->setValue(product->est_abv);
142 ui->productionEdit->setText(product->yeast_prod_date.toString("dd MMM yyyy"));
143 ui->conditionShow->setValue(product->starter_viability);
144 ui->startersgEdit->setValue(product->starter_sg);
145 ui->pitchrateEdit->setValue(product->yeast_pitchrate);
146
147 ui->yeastsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
148
149 for (int i = 0; i < starters.size(); i++) {
150 ui->stmethodEdit->addItem(starters[i]);
151 }
152 ui->stmethodEdit->setCurrentIndex(product->starter_type);
153 }
154
155
135 /* 156 /*
136 * The results are not stored line in EditProduct. This is just a hint. 157 * Calculate the needed yeast for this batch.
137 */ 158 */
138 void EditProduct::calcYeast() 159 void EditProduct::calcYeast()
139 { 160 {
140 double sg = product->est_og; 161 double sg = product->brew_fermenter_sg;
141 double plato = Utils::sg_to_plato(sg); 162 double use_cells;
142 double volume = product->batch_size * 0.9; // Volume min trub chiller loss. 163 double needed = 0;
164 double initcells = 0;
143 bool maybe_starter = false; 165 bool maybe_starter = false;
144 double pitchrate = 0.75;
145 double initcells = 0;
146 166
147 qDebug() << "calcYeast()"; 167 qDebug() << "calcYeast()";
148 ui->yeastProcedure->setCurrentIndex(0); 168 ui->yeastProcedure->setCurrentIndex(0);
149 169
170 if (sg <= 1.0001 && product->fg > 1.000)
171 sg = product->fg;
172 else if (sg <= 1.0001)
173 sg = product->est_og;
174 double plato = Utils::sg_to_plato(sg);
175
176 double volume = product->brew_fermenter_volume;
177 if (volume > 0) {
178 if (product->brew_fermenter_extrawater > 0)
179 volume += product->brew_fermenter_extrawater;
180 } else {
181 volume = product->batch_size - product->eq_trub_chiller_loss;
182 }
183
184 // Also in calcFermentables()
185 //$('#yeast_cells').val(initcells);
186
150 if (product->yeasts.size() == 0) 187 if (product->yeasts.size() == 0)
151 return; // No yeast in product. 188 return; // No yeast in product.
152 189
153 for (int i = 0; i < product->yeasts.size(); i++) { 190 for (int i = 0; i < product->yeasts.size(); i++) {
154 if (product->yeasts.at(i).y_use == 0) { // Primary 191 if (product->yeasts.at(i).y_use == YEAST_USE_PRIMARY) { // Primary
155 if (product->yeasts.at(i).y_form == 1) { 192 if (product->yeasts.at(i).y_form == YEAST_FORMS_DRY) {
156 /* 193 /*
157 * Dry yeast, build the formule with the yeast parameters. 194 * Dry yeast, build the formule with the yeast parameters.
158 * Based on https://www.lallemandbrewing.com/en/canada/brewers-corner/brewing-tools/pitching-rate-calculator/ 195 * Based on https://www.lallemandbrewing.com/en/canada/brewers-corner/brewing-tools/pitching-rate-calculator/
159 */ 196 */
160 ui->yeastProcedure->setCurrentIndex(2); 197 ui->yeastProcedure->setCurrentIndex(2);
178 * Liquid, slant, culture etc. 215 * Liquid, slant, culture etc.
179 * pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/ 216 * pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/
180 * and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/ 217 * and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
181 */ 218 */
182 ui->yeastProcedure->setCurrentIndex(1); 219 ui->yeastProcedure->setCurrentIndex(1);
183 if (product->yeasts.at(i).y_type == 0) { // Lager yeast 220 if (product->yeast_pitchrate == 0) {
184 pitchrate = 1.5; 221 /*
185 if (sg > 1.060) 222 * No pitchrate yet, do a educated guess ..
186 pitchrate = 2.0; 223 */
187 } else if (product->yeasts.at(i).y_type == 6) { // Real Kveik 224 if (product->yeasts.at(i).y_type == YEAST_TYPES_LAGER) {
188 pitchrate = 0.075; 225 product->yeast_pitchrate = 1.5;
189 } else { 226 if (sg > 1.060)
190 pitchrate = 0.75; 227 product->yeast_pitchrate = 2.0;
191 if (sg > 1.060) 228 } else if (product->yeasts.at(i).y_type == YEAST_TYPES_KVEIK) { // Real Kveik
192 pitchrate = 1.0; 229 product->yeast_pitchrate = 0.075;
230 } else {
231 product->yeast_pitchrate = 0.75;
232 if (sg > 1.060)
233 product->yeast_pitchrate = 1.0;
234 }
235 is_changed();
236 ui->pitchrateEdit->setValue(product->yeast_pitchrate);
193 } 237 }
194 if (product->yeasts.at(i).y_form == 0) 238
239 initcells = (product->yeasts.at(i).y_cells / 1000000) * product->yeasts.at(i).y_amount * 0.97; // cells / ml.
240 if (product->yeasts.at(i).y_form == YEAST_FORMS_LIQUID)
195 initcells = (product->yeasts.at(i).y_cells / 1000000000) * product->yeasts.at(i).y_amount * 0.97; // 97% viability assumed. 241 initcells = (product->yeasts.at(i).y_cells / 1000000000) * product->yeasts.at(i).y_amount * 0.97; // 97% viability assumed.
196 else 242
197 initcells = (product->yeasts.at(i).y_cells / 1000000) * product->yeasts.at(i).y_amount * 0.97; 243 needed = round(product->yeast_pitchrate * volume * plato * 10.0) / 10.0;
198
199 double needed = round(pitchrate * volume * plato * 10.0) / 10.0;
200 double starter = 0;
201 if (needed > initcells) { 244 if (needed > initcells) {
202 maybe_starter = true; 245 maybe_starter = true;
203 starter = round(needed / 2.0) / 100.0; // A very rough starter size estimate.
204 } 246 }
205 247
206 ui->pitchrateEdit->setValue(pitchrate); 248 qDebug() << " pitchrate:" << product->yeast_pitchrate << "needed:" << needed << "initcells:" << initcells << "starter" << maybe_starter;
207 ui->initcellsEdit->setValue(initcells);
208 ui->targetcellsEdit->setValue(needed);
209 ui->starterEdit->setValue(starter);
210
211 qDebug() << " pitchrate:" << pitchrate << "needed:" << needed << "initcells:" << initcells << "starter" << maybe_starter << "size" << starter;
212 } 249 }
213 break; 250 break;
214 } 251 }
215 } 252 }
253
254 if (maybe_starter != product->starter_enable) {
255 product->starter_enable = maybe_starter;
256 qDebug() << " Set starter enable" << maybe_starter;
257 is_changed();
258 }
259
260 if (product->starter_enable) {
261 qDebug() << " Starter calculate..";
262
263 const QStringList labels({tr("Method"), tr("Volume"), tr("Inj. factor"), tr("New cells"), tr("Total cells"), tr("Grow factor"), "" });
264 ui->starterTable->show();
265 ui->starterTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
266 ui->starterTable->clear();
267 ui->starterTable->setColumnCount(7);
268 ui->starterTable->setRowCount(0);
269 ui->starterTable->setColumnWidth(0, 130); /* Method */
270 ui->starterTable->setColumnWidth(1, 90); /* Volume */
271 ui->starterTable->setColumnWidth(2, 90); /* Inj. factor */
272 ui->starterTable->setColumnWidth(3, 90); /* New cells */
273 ui->starterTable->setColumnWidth(4, 90); /* Total cells */
274 ui->starterTable->setColumnWidth(5, 90); /* Grow factor */
275 ui->starterTable->setColumnWidth(6, 30); /* Edit button */
276 ui->starterTable->setHorizontalHeaderLabels(labels);
277 calcSteps(product->starter_type, initcells, needed);
278 } else {
279 ui->starterTable->hide();
280 }
281 }
282
283
284 /*
285 * http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
286 *
287 * stype: 0=stirred, 1=shaken, 2=simple
288 * totcells: initial cells
289 * egrams: gram extract
290 */
291 double EditProduct::getGrowthRate(int stype, double totcells, double egrams)
292 {
293 /* Cells per grams extract (B/g) */
294 double cpe = totcells / egrams;
295
296 if (cpe > 3.5)
297 return 0; // no growth
298 if (stype == STARTERS_SIMPLE)
299 return 0.4; // simple starter
300 if (stype == STARTERS_SHAKEN)
301 return 0.62; // shaken starter
302 if (cpe <= 1.4) // stirred starter
303 return 1.4;
304 return 2.33 - (.67 * cpe);
305 };
306
307
308 StepResult EditProduct::calcStep(double svol, int stype, double start)
309 {
310 StepResult res;
311 double gperpoint = 2.72715; //number of grams of extract per point of starter gravity per liter
312 double irate = round(start / svol * 10000.0) / 10.0;
313 double egrams = (product->starter_sg - 1) * svol * gperpoint;
314 double grate = getGrowthRate(stype, start, egrams);
315 double ncells = round(egrams * grate * 10.0) / 10.0;
316 double totcells = ncells + start;
317
318 res.svol = svol;
319 res.irate = irate;
320 res.ncells = ncells;
321 res.totcells = totcells;
322 res.growf = round((ncells / start) * 100.0) / 100.0;
323 qDebug() << " calcStep(" << svol << "," << stype << "," << start << ") irate" << irate
324 << "ncells" << res.ncells << "totcells" << res.totcells << "growf" << res.growf;
325 return res;
326 }
327
328
329 /*
330 * Calculate all starter steps.
331 * stype: final starter type: 0 = stirred, 1 = shaked, 2 = simple.
332 * start: initial cells in billions
333 * needed: needed cells in billions
334 *
335 * result: all values updated.
336 */
337 void EditProduct::calcSteps(int stype, double start, double needed)
338 {
339 int i, step, svol;
340 int lasti = 0;
341 /* Erlenmeyer sizes */
342 const int uvols[] { 20, 40, 60, 80, 100, 150, 200, 250, 375, 500, 625, 750, 875, 1000, 1250, 1500, 2000, 2500, 3000, 4000, 5000 };
343 int mvols = sizeof(uvols);
344 StepResult result;
345 QTableWidgetItem *item;
346 QWidget* pWidget;
347 QHBoxLayout* pLayout;
348 double tcells = start;
349 QIcon iconT;
350
351 iconT.addFile(QString::fromUtf8(":/icons/silk/pencil.png"), QSize(), QIcon::Normal, QIcon::Off);
352
353 if ((product->prop1_volume + product->prop2_volume + product->prop3_volume + product->prop4_volume) == 0) {
354 /*
355 * Auto calculate the starter.
356 */
357 qDebug() << " calcSteps() auto";
358
359 if (start > needed)
360 return;
361
362 for (step = 1; step < 5; step++) {
363 qDebug() << " step" << step;
364
365 for (i = lasti; i <= mvols; i++) {
366 lasti = i;
367 svol = uvols[lasti];
368 result = calcStep(svol, stype, tcells);
369 if (result.irate < 25) {
370 // inocculation rate too low, backup one step and break out.
371 lasti = i - 1;
372 svol = uvols[lasti];
373 result = calcStep(svol, stype, tcells);
374 break;
375 }
376 if (result.totcells > needed || i == mvols) { // hit the target or loops done
377 break;
378 }
379 }
380 ui->starterTable->setRowCount(step);
381 item = new QTableWidgetItem(starters[stype]);
382 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
383 ui->starterTable->setItem(step -1, 0, item);
384
385 item = new QTableWidgetItem(QString("%1").arg(result.svol / 1000.0, 4, 'f', 3, '0')); // To liters
386 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
387 ui->starterTable->setItem(step -1, 1, item);
388
389 item = new QTableWidgetItem(QString("%1").arg(result.irate, 2, 'f', 1, '0'));
390 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
391 ui->starterTable->setItem(step -1, 2, item);
392
393 item = new QTableWidgetItem(QString("%1").arg(result.ncells, 2, 'f', 1, '0'));
394 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
395 ui->starterTable->setItem(step -1, 3, item);
396
397 item = new QTableWidgetItem(QString("%1").arg(result.totcells, 2, 'f', 1, '0'));
398 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
399 ui->starterTable->setItem(step -1, 4, item);
400
401 item = new QTableWidgetItem(QString("%1").arg(result.growf, 3, 'f', 2, '0'));
402 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
403 ui->starterTable->setItem(step -1, 5, item);
404
405 pWidget = new QWidget();
406 QToolButton* btn_edit = new QToolButton();
407 btn_edit->setObjectName(QString("%1").arg(step - 1)); /* Send row with the button */
408 btn_edit->setIcon(iconT);
409 connect(btn_edit, SIGNAL(clicked()), this, SLOT(yeast_starter_edit_clicked()));
410 pLayout = new QHBoxLayout(pWidget);
411 pLayout->addWidget(btn_edit);
412 pLayout->setContentsMargins(5, 0, 5, 0);
413 pWidget->setLayout(pLayout);
414 ui->starterTable->setCellWidget(step -1, 6, pWidget);
415
416 if (step == 1) {
417 product->prop1_type = product->starter_type;
418 product->prop1_volume = result.svol / 1000.0;
419 } else if (step == 2) {
420 product->prop2_type = product->starter_type;
421 product->prop2_volume = result.svol / 1000.0;
422 } else if (step == 3) {
423 product->prop3_type = product->starter_type;
424 product->prop3_volume = result.svol / 1000.0;
425 } else if (step == 4) {
426 product->prop4_type = product->starter_type;
427 product->prop4_volume = result.svol / 1000.0;
428 }
429
430 tcells = result.totcells;
431 if (result.totcells > needed) // Hit the target
432 return;
433 }
434
435 } else {
436 /*
437 * Recalculate the starter.
438 */
439 qDebug() << " calcSteps() recalculate";
440
441 if (product->prop1_volume > 0) {
442 result = calcStep(product->prop1_volume * 1000, product->prop1_type, tcells);
443 ui->starterTable->setRowCount(1);
444 item = new QTableWidgetItem(starters[product->prop1_type]);
445 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
446 ui->starterTable->setItem(0, 0, item);
447
448 item = new QTableWidgetItem(QString("%1").arg(result.svol / 1000.0, 4, 'f', 3, '0')); // To liters
449 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
450 ui->starterTable->setItem(0, 1, item);
451
452 item = new QTableWidgetItem(QString("%1").arg(result.irate, 2, 'f', 1, '0'));
453 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
454 ui->starterTable->setItem(0, 2, item);
455
456 item = new QTableWidgetItem(QString("%1").arg(result.ncells, 2, 'f', 1, '0'));
457 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
458 ui->starterTable->setItem(0, 3, item);
459
460 item = new QTableWidgetItem(QString("%1").arg(result.totcells, 2, 'f', 1, '0'));
461 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
462 ui->starterTable->setItem(0, 4, item);
463
464 item = new QTableWidgetItem(QString("%1").arg(result.growf, 3, 'f', 2, '0'));
465 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
466 ui->starterTable->setItem(0, 5, item);
467
468 pWidget = new QWidget();
469 QToolButton* btn_edit = new QToolButton();
470 btn_edit->setObjectName(QString("0")); /* Send row with the button */
471 btn_edit->setIcon(iconT);
472 connect(btn_edit, SIGNAL(clicked()), this, SLOT(yeast_starter_edit_clicked()));
473 pLayout = new QHBoxLayout(pWidget);
474 pLayout->addWidget(btn_edit);
475 pLayout->setContentsMargins(5, 0, 5, 0);
476 pWidget->setLayout(pLayout);
477 ui->starterTable->setCellWidget(0, 6, pWidget);
478
479 tcells = result.totcells;
480 if (result.totcells > needed) { // Hit the target
481 product->prop2_volume = product->prop3_volume = product->prop4_volume = 0;
482 product->prop2_type = product->prop3_type = product->prop4_type = 0;
483 return;
484 } else if (product->prop2_volume == 0) { // Extra step needed, start with the same size.
485 product->prop2_volume = product->prop1_volume;
486 product->prop2_type = product->prop1_type;
487 }
488 }
489 if (product->prop2_volume > 0) {
490 result = calcStep(product->prop2_volume * 1000, product->prop2_type, tcells);
491 ui->starterTable->setRowCount(2);
492 item = new QTableWidgetItem(starters[product->prop2_type]);
493 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
494 ui->starterTable->setItem(1, 0, item);
495
496 item = new QTableWidgetItem(QString("%1").arg(result.svol / 1000.0, 4, 'f', 3, '0')); // To liters
497 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
498 ui->starterTable->setItem(1, 1, item);
499
500 item = new QTableWidgetItem(QString("%1").arg(result.irate, 2, 'f', 1, '0'));
501 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
502 ui->starterTable->setItem(1, 2, item);
503
504 item = new QTableWidgetItem(QString("%1").arg(result.ncells, 2, 'f', 1, '0'));
505 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
506 ui->starterTable->setItem(1, 3, item);
507
508 item = new QTableWidgetItem(QString("%1").arg(result.totcells, 2, 'f', 1, '0'));
509 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
510 ui->starterTable->setItem(1, 4, item);
511
512 item = new QTableWidgetItem(QString("%1").arg(result.growf, 3, 'f', 2, '0'));
513 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
514 ui->starterTable->setItem(1, 5, item);
515
516 pWidget = new QWidget();
517 QToolButton* btn_edit = new QToolButton();
518 btn_edit->setObjectName(QString("1")); /* Send row with the button */
519 btn_edit->setIcon(iconT);
520 connect(btn_edit, SIGNAL(clicked()), this, SLOT(yeast_starter_edit_clicked()));
521 pLayout = new QHBoxLayout(pWidget);
522 pLayout->addWidget(btn_edit);
523 pLayout->setContentsMargins(5, 0, 5, 0);
524 pWidget->setLayout(pLayout);
525 ui->starterTable->setCellWidget(1, 6, pWidget);
526
527 tcells = result.totcells;
528 if (result.totcells > needed) { // Hit the target
529 product->prop3_volume = product->prop4_volume = 0;
530 product->prop3_type = product->prop4_type = 0;
531 return;
532 } else if (product->prop3_volume == 0) { // Extra step needed, start with the same size.
533 product->prop3_volume = product->prop2_volume;
534 product->prop3_type = product->prop2_type;
535 }
536 }
537 if (product->prop3_volume > 0) {
538 result = calcStep(product->prop3_volume * 1000, product->prop3_type, tcells);
539 ui->starterTable->setRowCount(3);
540 item = new QTableWidgetItem(starters[product->prop3_type]);
541 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
542 ui->starterTable->setItem(2, 0, item);
543
544 item = new QTableWidgetItem(QString("%1").arg(result.svol / 1000.0, 4, 'f', 3, '0')); // To liters
545 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
546 ui->starterTable->setItem(2, 1, item);
547
548 item = new QTableWidgetItem(QString("%1").arg(result.irate, 2, 'f', 1, '0'));
549 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
550 ui->starterTable->setItem(2, 2, item);
551
552 item = new QTableWidgetItem(QString("%1").arg(result.ncells, 2, 'f', 1, '0'));
553 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
554 ui->starterTable->setItem(2, 3, item);
555
556 item = new QTableWidgetItem(QString("%1").arg(result.totcells, 2, 'f', 1, '0'));
557 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
558 ui->starterTable->setItem(2, 4, item);
559
560 item = new QTableWidgetItem(QString("%1").arg(result.growf, 3, 'f', 2, '0'));
561 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
562 ui->starterTable->setItem(2, 5, item);
563
564 pWidget = new QWidget();
565 QToolButton* btn_edit = new QToolButton();
566 btn_edit->setObjectName(QString("2")); /* Send row with the button */
567 btn_edit->setIcon(iconT);
568 connect(btn_edit, SIGNAL(clicked()), this, SLOT(yeast_starter_edit_clicked()));
569 pLayout = new QHBoxLayout(pWidget);
570 pLayout->addWidget(btn_edit);
571 pLayout->setContentsMargins(5, 0, 5, 0);
572 pWidget->setLayout(pLayout);
573 ui->starterTable->setCellWidget(2, 6, pWidget);
574
575 tcells = result.totcells;
576 if (result.totcells > needed) { // Hit the target
577 product->prop4_volume = 0;
578 product->prop4_type = 0;
579 return;
580 } else if (product->prop4_volume == 0) { // Extra step needed, start with the same size.
581 product->prop4_volume = product->prop3_volume;
582 product->prop4_type = product->prop3_type;
583 }
584 }
585 if (product->prop4_volume > 0) {
586 result = calcStep(product->prop4_volume * 1000, product->prop4_type, tcells);
587 ui->starterTable->setRowCount(4);
588 item = new QTableWidgetItem(starters[product->prop4_type]);
589 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
590 ui->starterTable->setItem(3, 0, item);
591
592 item = new QTableWidgetItem(QString("%1").arg(result.svol / 1000.0, 4, 'f', 3, '0')); // To liters
593 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
594 ui->starterTable->setItem(3, 1, item);
595
596 item = new QTableWidgetItem(QString("%1").arg(result.irate, 2, 'f', 1, '0'));
597 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
598 ui->starterTable->setItem(3, 2, item);
599
600 item = new QTableWidgetItem(QString("%1").arg(result.ncells, 2, 'f', 1, '0'));
601 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
602 ui->starterTable->setItem(3, 3, item);
603
604 item = new QTableWidgetItem(QString("%1").arg(result.totcells, 2, 'f', 1, '0'));
605 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
606 ui->starterTable->setItem(3, 4, item);
607
608 item = new QTableWidgetItem(QString("%1").arg(result.growf, 3, 'f', 2, '0'));
609 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
610 ui->starterTable->setItem(3, 5, item);
611
612 pWidget = new QWidget();
613 QToolButton* btn_edit = new QToolButton();
614 btn_edit->setObjectName(QString("3")); /* Send row with the button */
615 btn_edit->setIcon(iconT);
616 connect(btn_edit, SIGNAL(clicked()), this, SLOT(yeast_starter_edit_clicked()));
617 pLayout = new QHBoxLayout(pWidget);
618 pLayout->addWidget(btn_edit);
619 pLayout->setContentsMargins(5, 0, 5, 0);
620 pWidget->setLayout(pLayout);
621 ui->starterTable->setCellWidget(3, 6, pWidget);
622 }
623 }
624 }
625
626
627 void EditProduct::yeast_prod_date_clicked()
628 {
629 }
630
631
632 void EditProduct::yeast_method_changed(int val)
633 {
634 qDebug() << "yeast_method_changed" << val;
635 product->starter_type = val;
636 calcYeast();
637 is_changed();
638 }
639
640
641 void EditProduct::yeast_starter_sg_changed(double val)
642 {
643 qDebug() << "yeast_starter_sg_changed" << val;
644 product->starter_sg = val;
645 calcYeast();
646 is_changed();
647 }
648
649
650 void EditProduct::yeast_pitchrate_button_clicked()
651 {
652 }
653
654
655 void EditProduct::yeast_starter_edit_clicked()
656 {
657 QToolButton *pb = qobject_cast<QToolButton *>(QObject::sender());
658 int row = pb->objectName().toInt();
659 qDebug() << "yeast_starter_edit_clicked" << row;
216 } 660 }
217 661
218 662
219 void EditProduct::addYeastRow_clicked() 663 void EditProduct::addYeastRow_clicked()
220 { 664 {
592 1036
593 if (product->yeasts.size() == 0) 1037 if (product->yeasts.size() == 0)
594 return; 1038 return;
595 1039
596 for (int i = 0; i < product->yeasts.size(); i++) { 1040 for (int i = 0; i < product->yeasts.size(); i++) {
597 if (product->yeasts.at(i).y_form == 1) { // Only adjust dry yeast 1041 if (product->yeasts.at(i).y_form == YEAST_FORMS_DRY) { // Only adjust dry yeast
598 amount = product->yeasts.at(i).y_amount * factor; 1042 amount = product->yeasts.at(i).y_amount * factor;
599 product->yeasts[i].y_amount = amount; 1043 product->yeasts[i].y_amount = amount;
600 } 1044 }
601 } 1045 }
602 } 1046 }

mercurial