src/EditProductTab4.cpp

changeset 175
f1ed3a2a94e9
child 178
1091fd9feffe
equal deleted inserted replaced
174:ceb8aa4ebd25 175:f1ed3a2a94e9
1 /**
2 * EditProduct.cpp is part of bmsapp.
3 *
4 * Tab 4, hops
5 *
6 * bmsapp is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * bmsapp is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21
22 bool EditProduct::hop_sort_test(const Hops &D1, const Hops &D2)
23 {
24 if (D1.h_useat > D2.h_useat)
25 return false;
26 if (D1.h_useat < D2.h_useat)
27 return true;
28 /* Same useat moments, test time. */
29 if (D1.h_time < D2.h_time)
30 return false;
31 if (D1.h_time > D2.h_time)
32 return true;
33 /* Finally consider the amounts */
34 return (D1.h_amount > D2.h_amount);
35 }
36
37
38 void EditProduct::refreshHops()
39 {
40 QString w;
41 QWidget* pWidget;
42 QHBoxLayout* pLayout;
43 QTableWidgetItem *item;
44
45 qDebug() << "refreshHops" << product->hops.size();
46 std::sort(product->hops.begin(), product->hops.end(), hop_sort_test);
47
48 const QStringList labels({tr("Origin"), tr("Hop"), tr("Type"), tr("Form"), tr("Alpha"), tr("Use at"), tr("Time"),
49 tr("IBU"), tr("Amount"), tr("Delete"), tr("Edit") });
50
51 ui->hopsTable->setColumnCount(11);
52 ui->hopsTable->setColumnWidth(0, 150); /* Origin */
53 ui->hopsTable->setColumnWidth(1, 225); /* Hop */
54 ui->hopsTable->setColumnWidth(2, 84); /* Type */
55 ui->hopsTable->setColumnWidth(3, 84); /* Form */
56 ui->hopsTable->setColumnWidth(4, 75); /* Alpha% */
57 ui->hopsTable->setColumnWidth(5, 75); /* Added */
58 ui->hopsTable->setColumnWidth(6, 75); /* Time */
59 ui->hopsTable->setColumnWidth(7, 60); /* IBU */
60 ui->hopsTable->setColumnWidth(8, 90); /* Amount */
61 ui->hopsTable->setColumnWidth(9, 80); /* Delete */
62 ui->hopsTable->setColumnWidth(10, 80); /* Edit */
63 ui->hopsTable->setHorizontalHeaderLabels(labels);
64 ui->hopsTable->verticalHeader()->hide();
65 ui->hopsTable->setRowCount(product->hops.size());
66
67 for (int i = 0; i < product->hops.size(); i++) {
68
69 ui->hopsTable->setItem(i, 0, new QTableWidgetItem(product->hops.at(i).h_origin));
70 ui->hopsTable->setItem(i, 1, new QTableWidgetItem(product->hops.at(i).h_name));
71
72 item = new QTableWidgetItem(hop_types[product->hops.at(i).h_type]);
73 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
74 ui->hopsTable->setItem(i, 2, item);
75
76 item = new QTableWidgetItem(hop_forms[product->hops.at(i).h_form]);
77 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
78 ui->hopsTable->setItem(i, 3, item);
79
80 item = new QTableWidgetItem(QString("%1%").arg(product->hops.at(i).h_alpha, 2, 'f', 1, '0'));
81 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
82 ui->hopsTable->setItem(i, 4, item);
83
84 item = new QTableWidgetItem(hop_useat[product->hops.at(i).h_useat]);
85 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
86 ui->hopsTable->setItem(i, 5, item);
87
88 if (product->hops.at(i).h_useat == 2 || product->hops.at(i).h_useat == 4) { // Boil or whirlpool
89 item = new QTableWidgetItem(QString("%1 min.").arg(product->hops.at(i).h_time, 1, 'f', 0, '0'));
90 } else if (product->hops.at(i).h_useat == 5) { // Dry-hop
91 item = new QTableWidgetItem(QString("%1 days.").arg(product->hops.at(i).h_time / 1440, 1, 'f', 0, '0'));
92 } else {
93 item = new QTableWidgetItem(QString(""));
94 }
95 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
96 ui->hopsTable->setItem(i, 6, item);
97
98 double ibu = Utils::toIBU(product->hops.at(i).h_useat, product->hops.at(i).h_form, product->preboil_sg, product->batch_size, product->hops.at(i).h_amount,
99 product->hops.at(i).h_time, product->hops.at(i).h_alpha, product->ibu_method, 0, product->hops.at(i).h_time, 0);
100 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0'));
101 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
102 ui->hopsTable->setItem(i, 7, item);
103
104 if (product->hops.at(i).h_amount < 1.0) {
105 item = new QTableWidgetItem(QString("%1 gr").arg(product->hops.at(i).h_amount * 1000.0, 2, 'f', 1, '0'));
106 } else {
107 item = new QTableWidgetItem(QString("%1 kg").arg(product->hops.at(i).h_amount, 4, 'f', 3, '0'));
108 }
109 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
110 ui->hopsTable->setItem(i, 8, item);
111
112 /* Add the Delete row button */
113 pWidget = new QWidget();
114 QPushButton* btn_dele = new QPushButton();
115 btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */
116 btn_dele->setText(tr("Delete"));
117 connect(btn_dele, SIGNAL(clicked()), this, SLOT(deleteHopRow_clicked()));
118 pLayout = new QHBoxLayout(pWidget);
119 pLayout->addWidget(btn_dele);
120 pLayout->setContentsMargins(5, 0, 5, 0);
121 pWidget->setLayout(pLayout);
122 ui->hopsTable->setCellWidget(i, 9, pWidget);
123
124 pWidget = new QWidget();
125 QPushButton* btn_edit = new QPushButton();
126 btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */
127 btn_edit->setText(tr("Edit"));
128 connect(btn_edit, SIGNAL(clicked()), this, SLOT(editHopRow_clicked()));
129 pLayout = new QHBoxLayout(pWidget);
130 pLayout->addWidget(btn_edit);
131 pLayout->setContentsMargins(5, 0, 5, 0);
132 pWidget->setLayout(pLayout);
133 ui->hopsTable->setCellWidget(i, 10, pWidget);
134 }
135 }
136
137
138 void EditProduct::hop_Flavour_valueChanged(int value)
139 {
140 if (value < 20) {
141 ui->hop_tasteShow->setStyleSheet(bar_20);
142 ui->hop_tasteShow->setFormat(tr("Very low"));
143 } else if (value < 40) {
144 ui->hop_tasteShow->setStyleSheet(bar_40);
145 ui->hop_tasteShow->setFormat(tr("Low"));
146 } else if (value < 60) {
147 ui->hop_tasteShow->setStyleSheet(bar_60);
148 ui->hop_tasteShow->setFormat(tr("Moderate"));
149 } else if (value < 80) {
150 ui->hop_tasteShow->setStyleSheet(bar_80);
151 ui->hop_tasteShow->setFormat(tr("High"));
152 } else {
153 ui->hop_tasteShow->setStyleSheet(bar_100);
154 ui->hop_tasteShow->setFormat(tr("Very high"));
155 }
156 }
157
158
159 void EditProduct::hop_Aroma_valueChanged(int value)
160 {
161 if (value < 20) {
162 ui->hop_aromaShow->setStyleSheet(bar_20);
163 ui->hop_aromaShow->setFormat(tr("Very low"));
164 } else if (value < 40) {
165 ui->hop_aromaShow->setStyleSheet(bar_40);
166 ui->hop_aromaShow->setFormat(tr("Low"));
167 } else if (value < 60) {
168 ui->hop_aromaShow->setStyleSheet(bar_60);
169 ui->hop_aromaShow->setFormat(tr("Moderate"));
170 } else if (value < 80) {
171 ui->hop_aromaShow->setStyleSheet(bar_80);
172 ui->hop_aromaShow->setFormat(tr("High"));
173 } else {
174 ui->hop_aromaShow->setStyleSheet(bar_100);
175 ui->hop_aromaShow->setFormat(tr("Very high"));
176 }
177 }
178
179
180 void EditProduct::calcIBUs()
181 {
182 double hop_flavour = 0, hop_aroma = 0, ibus = 0;
183
184 for (int i = 0; i < product->hops.size(); i++) {
185
186 ibus += Utils::toIBU(product->hops.at(i).h_useat, product->hops.at(i).h_form, product->preboil_sg, product->batch_size, product->hops.at(i).h_amount,
187 product->hops.at(i).h_time, product->hops.at(i).h_alpha, product->ibu_method, 0, product->hops.at(i).h_time, 0);
188 hop_flavour += Utils::hopFlavourContribution(product->hops.at(i).h_time, product->batch_size, product->hops.at(i).h_useat, product->hops.at(i).h_amount);
189 hop_aroma += Utils::hopAromaContribution(product->hops.at(i).h_time, product->batch_size, product->hops.at(i).h_useat, product->hops.at(i).h_amount);
190 }
191
192 hop_flavour = round(hop_flavour * 1000.0 / 5.0) / 10;
193 hop_aroma = round(hop_aroma * 1000.0 / 6.0) / 10;
194 if (hop_flavour > 100)
195 hop_flavour = 100;
196 if (hop_aroma > 100)
197 hop_aroma = 100;
198 qDebug() << "ibu" << product->est_ibu << ibus << "flavour" << hop_flavour << "aroma" << hop_aroma << "method" << product->ibu_method;
199
200 product->est_ibu = ibus;
201 ui->est_ibuEdit->setValue(product->est_ibu);
202 ui->est_ibu2Edit->setValue(product->est_ibu);
203 ui->est_ibuShow->setValue(product->est_ibu);
204 ui->hop_tasteShow->setValue(hop_flavour);
205 ui->hop_aromaShow->setValue(hop_aroma);
206 }
207
208
209 void EditProduct::addHopRow_clicked()
210 {
211 Hops newh;
212
213 qDebug() << "Add hop row";
214
215 for (int i = 0; i < product->hops.size(); i++) {
216 if (product->hops.at(i).h_amount == 0 && product->hops.at(i).h_alpha == 0)
217 return; // Add only one at a time.
218 }
219
220 newh.h_name = "Select one";
221 newh.h_origin = "";
222 newh.h_amount = 0;
223 newh.h_cost = 0;
224 newh.h_type = 0;
225 newh.h_form = 0;
226 newh.h_useat = 2;
227 newh.h_time = 0;
228 newh.h_alpha = 0;
229 newh.h_beta = 0;
230 newh.h_hsi = 0;
231 newh.h_humulene = 0;
232 newh.h_caryophyllene = 0;
233 newh.h_cohumulone = 0;
234 newh.h_myrcene = 0;
235 newh.h_total_oil = 0;
236
237 product->hops.append(newh);
238 emit refreshAll();
239 }
240
241
242 void EditProduct::deleteHopRow_clicked()
243 {
244 if (product->locked || product->hops.size() < 1)
245 return;
246
247 QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
248 int row = pb->objectName().toInt();
249 qDebug() << "Delete hop row" << row << product->hops.size();
250
251 int rc = QMessageBox::warning(this, tr("Delete hop"), tr("Delete %1").arg(product->hops.at(row).h_name),
252 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
253 if (rc == QMessageBox::No)
254 return;
255
256 product->hops.removeAt(row);
257 is_changed();
258 emit refreshAll();
259 }
260
261
262 void EditProduct::hop_amount_changed(double val)
263 {
264 QTableWidgetItem *item;
265
266 qDebug() << "hop_amount_changed()" << product->hops_row << val;
267
268 product->hops[product->hops_row].h_amount = val / 1000.0;
269 item = new QTableWidgetItem(QString("%1 gr").arg(val, 2, 'f', 1, '0'));
270 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
271 ui->hopsTable->setItem(product->hops_row, 8, item);
272
273 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg,
274 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time,
275 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0);
276
277 ibuEdit->setValue(ibu);
278 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0'));
279 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
280 ui->hopsTable->setItem(product->hops_row, 7, item);
281
282 calcIBUs();
283 is_changed();
284 }
285
286
287 void EditProduct::hop_time_changed(int val)
288 {
289 QTableWidgetItem *item;
290
291 qDebug() << "hop_time_changed()" << product->hops_row << val;
292
293 if (product->hops.at(product->hops_row).h_useat == 2 || product->hops.at(product->hops_row).h_useat == 4) { // Boil or whirlpool
294 item = new QTableWidgetItem(QString("%1 min.").arg(val, 1, 'f', 0, '0'));
295 product->hops[product->hops_row].h_time = val;
296 } else if (product->hops.at(product->hops_row).h_useat == 5) { // Dry-hop
297 item = new QTableWidgetItem(QString("%1 days.").arg(val, 1, 'f', 0, '0'));
298 product->hops[product->hops_row].h_time = val * 1440;
299 } else {
300 item = new QTableWidgetItem(QString(""));
301 product->hops[product->hops_row].h_time = val;
302 }
303 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
304 ui->hopsTable->setItem(product->hops_row, 6, item);
305
306 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg,
307 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time,
308 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0);
309
310 ibuEdit->setValue(ibu);
311 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0'));
312 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
313 ui->hopsTable->setItem(product->hops_row, 7, item);
314
315 calcIBUs();
316 is_changed();
317 }
318
319
320 void EditProduct::hop_select_changed(int val)
321 {
322 QSqlQuery query;
323 bool instock = hinstockEdit->isChecked();
324 QString w;
325 QTableWidgetItem *item;
326
327 if (val < 1)
328 return;
329
330 qDebug() << "hop_select_changed()" << product->fermentables_row << val << instock;
331
332 /*
333 * Search the hop pointed by the index and instock flag.
334 */
335 QString sql = "SELECT name,origin,alpha,beta,humulene,caryophyllene,cohumulone,myrcene,hsi,total_oil,type,form,cost FROM inventory_hops ";
336 if (instock)
337 sql.append("WHERE inventory > 0 ");
338 sql.append("ORDER BY origin,name");
339 query.prepare(sql);
340 query.exec();
341 query.first();
342 for (int i = 0; i < (val - 1); i++) {
343 query.next();
344 }
345 qDebug() << "found" << query.value(1).toString() << query.value(0).toString();
346
347 /*
348 * Replace the hop record contents
349 */
350 product->hops[product->hops_row].h_name = query.value(0).toString();
351 product->hops[product->hops_row].h_origin = query.value(1).toString();
352 product->hops[product->hops_row].h_alpha = query.value(2).toDouble();
353 product->hops[product->hops_row].h_beta = query.value(3).toDouble();
354 product->hops[product->hops_row].h_humulene = query.value(4).toDouble();
355 product->hops[product->hops_row].h_caryophyllene = query.value(5).toDouble();
356 product->hops[product->hops_row].h_cohumulone = query.value(6).toDouble();
357 product->hops[product->hops_row].h_myrcene = query.value(7).toDouble();
358 product->hops[product->hops_row].h_hsi = query.value(8).toDouble();
359 product->hops[product->hops_row].h_total_oil = query.value(9).toDouble();
360 product->hops[product->hops_row].h_type = query.value(10).toInt();
361 product->hops[product->hops_row].h_form = query.value(11).toInt();
362 product->hops[product->hops_row].h_cost = query.value(12).toDouble();
363
364 /*
365 * Update the visible fields
366 */
367 hnameEdit->setText(product->hops.at(product->hops_row).h_name);
368 horiginEdit->setText(product->hops.at(product->hops_row).h_origin);
369
370 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg,
371 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time,
372 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0);
373 ibuEdit->setValue(ibu);
374
375 ui->hopsTable->setItem(product->hops_row, 0, new QTableWidgetItem(product->hops.at(product->hops_row).h_origin));
376 ui->hopsTable->setItem(product->hops_row, 1, new QTableWidgetItem(product->hops.at(product->hops_row).h_name));
377
378 item = new QTableWidgetItem(hop_types[product->hops.at(product->hops_row).h_type]);
379 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
380 ui->hopsTable->setItem(product->hops_row, 2, item);
381
382 item = new QTableWidgetItem(hop_forms[product->hops.at(product->hops_row).h_form]);
383 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
384 ui->hopsTable->setItem(product->hops_row, 3, item);
385
386 item = new QTableWidgetItem(QString("%1%").arg(product->hops.at(product->hops_row).h_alpha, 2, 'f', 1, '0'));
387 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
388 ui->hopsTable->setItem(product->hops_row, 4, item);
389
390 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0'));
391 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
392 ui->hopsTable->setItem(product->hops_row, 7, item);
393
394 calcIBUs();
395 is_changed();
396 }
397
398
399 void EditProduct::hop_instock_changed(bool val)
400 {
401 QSqlQuery query;
402
403 qDebug() << "hop_instock_changed()" << product->hops_row << val;
404
405 this->hselectEdit->setCurrentIndex(-1);
406 this->hselectEdit->clear();
407 QString sql = "SELECT origin,name,alpha,inventory FROM inventory_hops ";
408 if (val)
409 sql.append("WHERE inventory > 0 ");
410 sql.append("ORDER BY origin,name");
411 query.prepare(sql);
412 query.exec();
413 query.first();
414 this->hselectEdit->addItem(""); // Start with empty value
415 for (int i = 0; i < query.size(); i++) {
416 this->hselectEdit->addItem(query.value(0).toString()+" - "+query.value(1).toString()+" ("+query.value(2).toString()+"%) "+
417 QString("%1 gr").arg(query.value(3).toDouble() * 1000.0, 2, 'f', 1, '0'));
418 query.next();
419 }
420 }
421
422
423 void EditProduct::hop_useat_changed(int val)
424 {
425 qDebug() << "hop_useat_changed()" << product->hops_row << val;
426
427 product->hops[product->hops_row].h_useat = val;
428 QTableWidgetItem *item = new QTableWidgetItem(hop_useat[val]);
429 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
430 ui->hopsTable->setItem(product->hops_row, 5, item);
431
432 if (val == 2 || val == 4) { // Boil or whirlpool
433 htimeLabel->setText(tr("Time in minutes:"));
434 htimeEdit->setValue(product->hops.at(product->hops_row).h_time);
435 htimeEdit->setReadOnly(false);
436 } else if (val == 5) { // Dry-hop
437 htimeLabel->setText(tr("Time in days:"));
438 htimeEdit->setValue(product->hops.at(product->hops_row).h_time / 1440);
439 htimeEdit->setReadOnly(false);
440 } else {
441 htimeLabel->setText("");
442 htimeEdit->setValue(0);
443 htimeEdit->setReadOnly(true);
444 }
445
446 is_changed();
447 emit refreshAll();
448 }
449
450
451 void EditProduct::editHopRow_clicked()
452 {
453 QSqlQuery query;
454
455 if (product->locked)
456 return;
457
458 QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
459 product->hops_row = pb->objectName().toInt();
460 qDebug() << "Edit hop row" << product->hops_row;
461 Hops backup = product->hops.at(product->hops_row);
462
463 QDialog* dialog = new QDialog(this);
464 dialog->resize(738, 260);
465 QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
466 buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
467 buttonBox->setGeometry(QRect(30, 210, 671, 32));
468 buttonBox->setLayoutDirection(Qt::LeftToRight);
469 buttonBox->setOrientation(Qt::Horizontal);
470 buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
471 buttonBox->setCenterButtons(true);
472 QLabel *nameLabel = new QLabel(dialog);
473 nameLabel->setObjectName(QString::fromUtf8("nameLabel"));
474 nameLabel->setText(tr("Current hop:"));
475 nameLabel->setGeometry(QRect(10, 10, 141, 20));
476 nameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
477 QLabel *originLabel = new QLabel(dialog);
478 originLabel->setObjectName(QString::fromUtf8("originLabel"));
479 originLabel->setText(tr("Origin:"));
480 originLabel->setGeometry(QRect(10, 40, 141, 20));
481 originLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
482 QLabel *amountLabel = new QLabel(dialog);
483 amountLabel->setObjectName(QString::fromUtf8("amountLabel"));
484 amountLabel->setText(tr("Amount in gr:"));
485 amountLabel->setGeometry(QRect(10, 100, 141, 20));
486 amountLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
487 htimeLabel = new QLabel(dialog);
488 htimeLabel->setObjectName(QString::fromUtf8("htimeLabel"));
489 if (product->hops.at(product->hops_row).h_useat == 5) // Dry-hop
490 htimeLabel->setText(tr("Time in days:"));
491 else if (product->hops.at(product->hops_row).h_useat == 2 || product->hops.at(product->hops_row).h_useat == 4) // Boil or whirlpool
492 htimeLabel->setText(tr("Time in minutes:"));
493 else
494 htimeLabel->setText("");
495
496 htimeLabel->setGeometry(QRect(10, 130, 141, 20));
497 htimeLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
498 QLabel *useatLabel = new QLabel(dialog);
499 useatLabel->setObjectName(QString::fromUtf8("useatLabel"));
500 useatLabel->setText(tr("Use at:"));
501 useatLabel->setGeometry(QRect(10, 160, 141, 20));
502 useatLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
503 QLabel *selectLabel = new QLabel(dialog);
504 selectLabel->setObjectName(QString::fromUtf8("selectLabel"));
505 selectLabel->setText(tr("Select hop:"));
506 selectLabel->setGeometry(QRect(10, 70, 141, 20));
507 selectLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
508 QLabel *instockLabel = new QLabel(dialog);
509 instockLabel->setObjectName(QString::fromUtf8("instockLabel"));
510 instockLabel->setText(tr("In stock:"));
511 instockLabel->setGeometry(QRect(525, 70, 121, 20));
512 instockLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
513 QLabel *ibuLabel = new QLabel(dialog);
514 ibuLabel->setObjectName(QString::fromUtf8("maxLabel"));
515 ibuLabel->setText(tr("Bitterness IBU:"));
516 ibuLabel->setGeometry(QRect(420, 130, 121, 20));
517 ibuLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
518
519 hselectEdit = new QComboBox(dialog);
520 hselectEdit->setObjectName(QString::fromUtf8("selectEdit"));
521 hselectEdit->setGeometry(QRect(160, 70, 371, 23));
522
523 hnameEdit = new QLineEdit(dialog);
524 hnameEdit->setObjectName(QString::fromUtf8("hnameEdit"));
525 hnameEdit->setText(product->hops.at(product->hops_row).h_name);
526 hnameEdit->setGeometry(QRect(160, 10, 511, 23));
527 hnameEdit->setReadOnly(true);
528 horiginEdit = new QLineEdit(dialog);
529 horiginEdit->setObjectName(QString::fromUtf8("horiginEdit"));
530 horiginEdit->setText(product->hops.at(product->hops_row).h_origin);
531 horiginEdit->setGeometry(QRect(160, 40, 511, 23));
532 horiginEdit->setReadOnly(true);
533 hamountEdit = new QDoubleSpinBox(dialog);
534 hamountEdit->setObjectName(QString::fromUtf8("hamountEdit"));
535 hamountEdit->setGeometry(QRect(160, 100, 121, 24));
536 hamountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
537 hamountEdit->setAccelerated(true);
538 hamountEdit->setDecimals(1);
539 hamountEdit->setMaximum(1000000.0);
540 hamountEdit->setSingleStep(0.5);
541 hamountEdit->setValue(product->hops.at(product->hops_row).h_amount * 1000.0);
542 htimeEdit = new QSpinBox(dialog);
543 htimeEdit->setObjectName(QString::fromUtf8("htimeEdit"));
544 htimeEdit->setGeometry(QRect(160, 130, 121, 24));
545 htimeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
546 htimeEdit->setAccelerated(true);
547 htimeEdit->setMaximum(10000.0);
548 if (product->hops.at(product->hops_row).h_useat == 2 || product->hops.at(product->hops_row).h_useat == 4) { // Boil or whirlpool
549 htimeEdit->setValue(product->hops.at(product->hops_row).h_time);
550 htimeEdit->setReadOnly(false);
551 } else if (product->hops.at(product->hops_row).h_useat == 5){ // Dry-hop
552 htimeEdit->setValue(product->hops.at(product->hops_row).h_time / 1440);
553 htimeEdit->setReadOnly(false);
554 } else {
555 htimeEdit->setReadOnly(true);
556 }
557 useatEdit = new QComboBox(dialog);
558 useatEdit->setObjectName(QString::fromUtf8("useatEdit"));
559 useatEdit->setGeometry(QRect(160, 160, 161, 23));
560 useatEdit->addItem(tr("Mash"));
561 useatEdit->addItem(tr("First wort"));
562 useatEdit->addItem(tr("Boil"));
563 useatEdit->addItem(tr("Aroma"));
564 useatEdit->addItem(tr("Whirlpool"));
565 useatEdit->addItem(tr("Dry hop"));
566 useatEdit->setCurrentIndex(product->hops.at(product->hops_row).h_useat);
567
568 hinstockEdit = new QCheckBox(dialog);
569 hinstockEdit->setObjectName(QString::fromUtf8("hinstockEdit"));
570 hinstockEdit->setGeometry(QRect(655, 70, 85, 21));
571 hinstockEdit->setChecked(true);
572
573 ibuEdit = new QDoubleSpinBox(dialog);
574 ibuEdit->setObjectName(QString::fromUtf8("ibuEdit"));
575 ibuEdit->setGeometry(QRect(550, 130, 121, 24));
576 ibuEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
577 ibuEdit->setReadOnly(true);
578 ibuEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
579 ibuEdit->setDecimals(1);
580 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg,
581 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time,
582 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0);
583 ibuEdit->setValue(ibu);
584
585 hop_instock_changed(true);
586
587 connect(hselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::hop_select_changed);
588 connect(hamountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::hop_amount_changed);
589 connect(htimeEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &EditProduct::hop_time_changed);
590 connect(useatEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::hop_useat_changed);
591 connect(hinstockEdit, &QCheckBox::stateChanged, this, &EditProduct::hop_instock_changed);
592 connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
593 connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
594
595 dialog->setModal(true);
596 dialog->exec();
597 if (dialog->result() == QDialog::Rejected) {
598 qDebug() << "reject and rollback";
599 product->hops[product->hops_row] = backup;
600 } else {
601 /* Clear time if hop is not used for boil, whirlpool or dry-hop. */
602 if (! (product->hops.at(product->hops_row).h_useat == 2 ||
603 product->hops.at(product->hops_row).h_useat == 4 ||
604 product->hops.at(product->hops_row).h_useat == 5)) {
605 if (product->hops.at(product->hops_row).h_time) {
606 product->hops[product->hops_row].h_time = 0;
607 is_changed();
608 }
609 }
610 }
611
612 disconnect(hselectEdit, nullptr, nullptr, nullptr);
613 disconnect(hamountEdit, nullptr, nullptr, nullptr);
614 disconnect(htimeEdit, nullptr, nullptr, nullptr);
615 disconnect(useatEdit, nullptr, nullptr, nullptr);
616 disconnect(hinstockEdit, nullptr, nullptr, nullptr);
617 disconnect(buttonBox, nullptr, nullptr, nullptr);
618
619 emit refreshAll();
620 }
621
622
623 void EditProduct::adjustHops(double factor)
624 {
625 double amount;
626
627 if (product->hops.size() == 0)
628 return;
629
630 for (int i = 0; i < product->hops.size(); i++) {
631 amount = product->hops.at(i).h_amount * factor;
632 product->hops[i].h_amount = amount;
633 }
634 }
635
636

mercurial