diff -r 3c013ef88a00 -r 475c8b8df67f src/EditRecipeTab3.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/EditRecipeTab3.cpp Mon Apr 11 17:22:43 2022 +0200 @@ -0,0 +1,612 @@ +/** + * EditRecipe.cpp is part of bmsapp. + * + * Tab 3, hops + * + * bmsapp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * bmsapp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + + +bool EditRecipe::hop_sort_test(const Hops &D1, const Hops &D2) +{ + if (D1.h_useat > D2.h_useat) + return false; + if (D1.h_useat < D2.h_useat) + return true; + /* Same useat moments, test time. */ + if (D1.h_time < D2.h_time) + return false; + if (D1.h_time > D2.h_time) + return true; + /* Finally consider the amounts */ + return (D1.h_amount > D2.h_amount); +} + + +void EditRecipe::refreshHops() +{ + QString w; + QWidget* pWidget; + QHBoxLayout* pLayout; + QTableWidgetItem *item; + + qDebug() << "refreshHops" << recipe->hops.size(); + std::sort(recipe->hops.begin(), recipe->hops.end(), hop_sort_test); + + /* + * During filling the table turn off the cellChanged signal because every cell that is filled + * triggers the cellChanged signal. The QTableWidget has no better signal to use. + */ + this->ignoreChanges = true; + + const QStringList labels({tr("Origin"), tr("Hop"), tr("Type"), tr("Form"), tr("Alpha"), tr("Use at"), tr("Time"), + tr("IBU"), tr("Amount"), tr("Delete"), tr("Edit") }); + + ui->hopsTable->setColumnCount(11); + ui->hopsTable->setColumnWidth(0, 150); /* Origin */ + ui->hopsTable->setColumnWidth(1, 225); /* Hop */ + ui->hopsTable->setColumnWidth(2, 75); /* Type */ + ui->hopsTable->setColumnWidth(3, 75); /* Form */ + ui->hopsTable->setColumnWidth(4, 75); /* Alpha% */ + ui->hopsTable->setColumnWidth(5, 75); /* Added */ + ui->hopsTable->setColumnWidth(6, 75); /* Time */ + ui->hopsTable->setColumnWidth(7, 60); /* IBU */ + ui->hopsTable->setColumnWidth(8, 75); /* Amount */ + ui->hopsTable->setColumnWidth(9, 80); /* Delete */ + ui->hopsTable->setColumnWidth(10, 80); /* Edit */ + ui->hopsTable->setHorizontalHeaderLabels(labels); + ui->hopsTable->verticalHeader()->hide(); + ui->hopsTable->setRowCount(recipe->hops.size()); + + for (int i = 0; i < recipe->hops.size(); i++) { + + ui->hopsTable->setItem(i, 0, new QTableWidgetItem(recipe->hops.at(i).h_origin)); + ui->hopsTable->setItem(i, 1, new QTableWidgetItem(recipe->hops.at(i).h_name)); + + item = new QTableWidgetItem(h_types[recipe->hops.at(i).h_type]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 2, item); + + item = new QTableWidgetItem(h_forms[recipe->hops.at(i).h_form]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 3, item); + + item = new QTableWidgetItem(QString("%1%").arg(recipe->hops.at(i).h_alpha, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 4, item); + + item = new QTableWidgetItem(h_useat[recipe->hops.at(i).h_useat]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 5, item); + + if (recipe->hops.at(i).h_useat == 2 || recipe->hops.at(i).h_useat == 4) { // Boil or whirlpool + item = new QTableWidgetItem(QString("%1 min.").arg(recipe->hops.at(i).h_time, 1, 'f', 0, '0')); + } else if (recipe->hops.at(i).h_useat == 5) { // Dry-hop + item = new QTableWidgetItem(QString("%1 days.").arg(recipe->hops.at(i).h_time / 1440, 1, 'f', 0, '0')); + } else { + item = new QTableWidgetItem(QString("")); + } + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 6, item); + + double ibu = Utils::toIBU(recipe->hops.at(i).h_useat, recipe->hops.at(i).h_form, recipe->preboil_sg, recipe->batch_size, recipe->hops.at(i).h_amount, + recipe->hops.at(i).h_time, recipe->hops.at(i).h_alpha, recipe->ibu_method, 0, recipe->hops.at(i).h_time, 0); + item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 7, item); + + if (recipe->hops.at(i).h_amount < 1.0) { + item = new QTableWidgetItem(QString("%1 gr").arg(recipe->hops.at(i).h_amount * 1000.0, 2, 'f', 1, '0')); + } else { + item = new QTableWidgetItem(QString("%1 kg").arg(recipe->hops.at(i).h_amount, 4, 'f', 3, '0')); + } + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(i, 8, item); + + /* Add the Delete row button */ + pWidget = new QWidget(); + QPushButton* btn_dele = new QPushButton(); + btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */ + btn_dele->setText(tr("Delete")); + connect(btn_dele, SIGNAL(clicked()), this, SLOT(on_deleteHopRow_clicked())); + pLayout = new QHBoxLayout(pWidget); + pLayout->addWidget(btn_dele); + pLayout->setContentsMargins(5, 0, 5, 0); + pWidget->setLayout(pLayout); + ui->hopsTable->setCellWidget(i, 9, pWidget); + + pWidget = new QWidget(); + QPushButton* btn_edit = new QPushButton(); + btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */ + btn_edit->setText(tr("Edit")); + connect(btn_edit, SIGNAL(clicked()), this, SLOT(on_editHopRow_clicked())); + pLayout = new QHBoxLayout(pWidget); + pLayout->addWidget(btn_edit); + pLayout->setContentsMargins(5, 0, 5, 0); + pWidget->setLayout(pLayout); + ui->hopsTable->setCellWidget(i, 10, pWidget); + } + this->ignoreChanges = false; +} + + +void EditRecipe::on_Flavour_valueChanged(int value) +{ + if (value < 20) { + ui->hop_tasteShow->setStyleSheet(bar_20); + ui->hop_tasteShow->setFormat(tr("Very low")); + } else if (value < 40) { + ui->hop_tasteShow->setStyleSheet(bar_40); + ui->hop_tasteShow->setFormat(tr("Low")); + } else if (value < 60) { + ui->hop_tasteShow->setStyleSheet(bar_60); + ui->hop_tasteShow->setFormat(tr("Moderate")); + } else if (value < 80) { + ui->hop_tasteShow->setStyleSheet(bar_80); + ui->hop_tasteShow->setFormat(tr("High")); + } else { + ui->hop_tasteShow->setStyleSheet(bar_100); + ui->hop_tasteShow->setFormat(tr("Very high")); + } +} + + +void EditRecipe::on_Aroma_valueChanged(int value) +{ + if (value < 20) { + ui->hop_aromaShow->setStyleSheet(bar_20); + ui->hop_aromaShow->setFormat(tr("Very low")); + } else if (value < 40) { + ui->hop_aromaShow->setStyleSheet(bar_40); + ui->hop_aromaShow->setFormat(tr("Low")); + } else if (value < 60) { + ui->hop_aromaShow->setStyleSheet(bar_60); + ui->hop_aromaShow->setFormat(tr("Moderate")); + } else if (value < 80) { + ui->hop_aromaShow->setStyleSheet(bar_80); + ui->hop_aromaShow->setFormat(tr("High")); + } else { + ui->hop_aromaShow->setStyleSheet(bar_100); + ui->hop_aromaShow->setFormat(tr("Very high")); + } +} + + +void EditRecipe::calcIBUs() +{ + double hop_flavour = 0, hop_aroma = 0, ibus = 0; + + for (int i = 0; i < recipe->hops.size(); i++) { + + ibus += Utils::toIBU(recipe->hops.at(i).h_useat, recipe->hops.at(i).h_form, recipe->preboil_sg, recipe->batch_size, recipe->hops.at(i).h_amount, + recipe->hops.at(i).h_time, recipe->hops.at(i).h_alpha, recipe->ibu_method, 0, recipe->hops.at(i).h_time, 0); + hop_flavour += Utils::hopFlavourContribution(recipe->hops.at(i).h_time, recipe->batch_size, recipe->hops.at(i).h_useat, recipe->hops.at(i).h_amount); + hop_aroma += Utils::hopAromaContribution(recipe->hops.at(i).h_time, recipe->batch_size, recipe->hops.at(i).h_useat, recipe->hops.at(i).h_amount); + } + + hop_flavour = round(hop_flavour * 1000.0 / 5.0) / 10; + hop_aroma = round(hop_aroma * 1000.0 / 6.0) / 10; + if (hop_flavour > 100) + hop_flavour = 100; + if (hop_aroma > 100) + hop_aroma = 100; + qDebug() << "ibu" << recipe->est_ibu << ibus << "flavour" << hop_flavour << "aroma" << hop_aroma; + + recipe->est_ibu = ibus; + ui->est_ibuEdit->setValue(recipe->est_ibu); + ui->est_ibu2Edit->setValue(recipe->est_ibu); + ui->hop_tasteShow->setValue(hop_flavour); + ui->hop_aromaShow->setValue(hop_aroma); +} + + +void EditRecipe::on_addHopRow_clicked() +{ + Hops newh; + + qDebug() << "Add hop row"; + + for (int i = 0; i < recipe->hops.size(); i++) { + if (recipe->hops.at(i).h_amount == 0 && recipe->hops.at(i).h_alpha == 0) + return; // Add only one at a time. + } + + emit refreshAll(); +} + + +void EditRecipe::on_deleteHopRow_clicked() +{ + QPushButton *pb = qobject_cast(QObject::sender()); + int row = pb->objectName().toInt(); + qDebug() << "Delete hop row" << row << recipe->hops.size(); + + if (recipe->hops.size() < 1) + return; + + int rc = QMessageBox::warning(this, tr("Delete hop"), tr("Delete %1").arg(recipe->hops.at(row).h_name), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if (rc == QMessageBox::No) + return; + + +} + + +void EditRecipe::hop_amount_changed(double val) +{ + QTableWidgetItem *item; + + qDebug() << "hop_amount_changed()" << recipe->hops_row << val; + this->ignoreChanges = true; + + recipe->hops[recipe->hops_row].h_amount = val / 1000.0; + item = new QTableWidgetItem(QString("%1 gr").arg(val, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 8, item); + + double ibu = Utils::toIBU(recipe->hops.at(recipe->hops_row).h_useat, recipe->hops.at(recipe->hops_row).h_form, recipe->preboil_sg, + recipe->batch_size, recipe->hops.at(recipe->hops_row).h_amount, recipe->hops.at(recipe->hops_row).h_time, + recipe->hops.at(recipe->hops_row).h_alpha, recipe->ibu_method, 0, recipe->hops.at(recipe->hops_row).h_time, 0); + + ibuEdit->setValue(ibu); + item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 7, item); + + this->ignoreChanges = false; + calcIBUs(); + is_changed(); +} + + +void EditRecipe::hop_time_changed(int val) +{ + QTableWidgetItem *item; + + qDebug() << "hop_time_changed()" << recipe->hops_row << val; + + this->ignoreChanges = true; + recipe->hops[recipe->hops_row].h_time = val; + + if (recipe->hops.at(recipe->hops_row).h_useat == 2 || recipe->hops.at(recipe->hops_row).h_useat == 4) { // Boil or whirlpool + item = new QTableWidgetItem(QString("%1 min.").arg(val, 1, 'f', 0, '0')); + } else if (recipe->hops.at(recipe->hops_row).h_useat == 5) { // Dry-hop + item = new QTableWidgetItem(QString("%1 days.").arg(val / 1440, 1, 'f', 0, '0')); + } else { + item = new QTableWidgetItem(QString("")); + } + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 6, item); + + double ibu = Utils::toIBU(recipe->hops.at(recipe->hops_row).h_useat, recipe->hops.at(recipe->hops_row).h_form, recipe->preboil_sg, + recipe->batch_size, recipe->hops.at(recipe->hops_row).h_amount, recipe->hops.at(recipe->hops_row).h_time, + recipe->hops.at(recipe->hops_row).h_alpha, recipe->ibu_method, 0, recipe->hops.at(recipe->hops_row).h_time, 0); + + ibuEdit->setValue(ibu); + item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 7, item); + + this->ignoreChanges = false; + calcIBUs(); + is_changed(); +} + + +void EditRecipe::hop_select_changed(int val) +{ + QSqlQuery query; + bool instock = hinstockEdit->isChecked(); + QString w; + QTableWidgetItem *item; + + if (val < 1) + return; + + qDebug() << "hop_select_changed()" << recipe->fermentables_row << val << instock; + + /* + * Search the hop pointed by the index and instock flag. + */ + QString sql = "SELECT name,origin,alpha,beta,humulene,caryophyllene,cohumulone,myrcene,hsi,total_oil,type,form,cost FROM inventory_hops "; + if (instock) + sql.append("WHERE inventory > 0 "); + sql.append("ORDER BY origin,name"); + query.prepare(sql); + query.exec(); + query.first(); + for (int i = 0; i < (val - 1); i++) { + query.next(); + } + qDebug() << "found" << query.value(1).toString() << query.value(0).toString(); + + /* + * Replace the hop record contents + */ + this->ignoreChanges = true; + recipe->hops[recipe->hops_row].h_name = query.value(0).toString(); + recipe->hops[recipe->hops_row].h_origin = query.value(1).toString(); + recipe->hops[recipe->hops_row].h_alpha = query.value(2).toDouble(); + recipe->hops[recipe->hops_row].h_beta = query.value(3).toDouble(); + recipe->hops[recipe->hops_row].h_humulene = query.value(4).toDouble(); + recipe->hops[recipe->hops_row].h_caryophyllene = query.value(5).toDouble(); + recipe->hops[recipe->hops_row].h_cohumulone = query.value(6).toDouble(); + recipe->hops[recipe->hops_row].h_myrcene = query.value(7).toDouble(); + recipe->hops[recipe->hops_row].h_hsi = query.value(8).toDouble(); + recipe->hops[recipe->hops_row].h_total_oil = query.value(9).toDouble(); + recipe->hops[recipe->hops_row].h_type = query.value(10).toInt(); + recipe->hops[recipe->hops_row].h_form = query.value(11).toInt(); + recipe->hops[recipe->hops_row].h_cost = query.value(12).toDouble(); + + /* + * Update the visible fields + */ + hnameEdit->setText(recipe->hops.at(recipe->hops_row).h_name); + horiginEdit->setText(recipe->hops.at(recipe->hops_row).h_origin); + + double ibu = Utils::toIBU(recipe->hops.at(recipe->hops_row).h_useat, recipe->hops.at(recipe->hops_row).h_form, recipe->preboil_sg, + recipe->batch_size, recipe->hops.at(recipe->hops_row).h_amount, recipe->hops.at(recipe->hops_row).h_time, + recipe->hops.at(recipe->hops_row).h_alpha, recipe->ibu_method, 0, recipe->hops.at(recipe->hops_row).h_time, 0); + ibuEdit->setValue(ibu); + + ui->hopsTable->setItem(recipe->hops_row, 0, new QTableWidgetItem(recipe->hops.at(recipe->hops_row).h_origin)); + ui->hopsTable->setItem(recipe->hops_row, 1, new QTableWidgetItem(recipe->hops.at(recipe->hops_row).h_name)); + + item = new QTableWidgetItem(h_types[recipe->hops.at(recipe->hops_row).h_type]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 2, item); + + item = new QTableWidgetItem(h_forms[recipe->hops.at(recipe->hops_row).h_form]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 3, item); + + item = new QTableWidgetItem(QString("%1%").arg(recipe->hops.at(recipe->hops_row).h_alpha, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 4, item); + + item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 7, item); + + this->ignoreChanges = false; + calcIBUs(); + is_changed(); +} + + +void EditRecipe::hop_instock_changed(bool val) +{ + QSqlQuery query; + + qDebug() << "hop_instock_changed()" << recipe->hops_row << val; + + this->hselectEdit->setCurrentIndex(-1); + this->hselectEdit->clear(); + QString sql = "SELECT origin,name,alpha,inventory FROM inventory_hops "; + if (val) + sql.append("WHERE inventory > 0 "); + sql.append("ORDER BY origin,name"); + query.prepare(sql); + query.exec(); + query.first(); + this->hselectEdit->addItem(""); // Start with empty value + for (int i = 0; i < query.size(); i++) { + this->hselectEdit->addItem(query.value(0).toString()+" - "+query.value(1).toString()+" ("+query.value(2).toString()+"%) "+ + QString("%1 gr").arg(query.value(3).toDouble() * 1000.0, 2, 'f', 1, '0')); + query.next(); + } +} + + +void EditRecipe::hop_useat_changed(int val) +{ + qDebug() << "hop_useat_changed()" << recipe->hops_row << val; + + this->ignoreChanges = true; + recipe->hops[recipe->hops_row].h_useat = val; + QTableWidgetItem *item = new QTableWidgetItem(h_useat[val]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->hopsTable->setItem(recipe->hops_row, 5, item); + + if (val == 2 || val == 4) { // Boil or whirlpool + htimeLabel->setText(tr("Time in minutes:")); + htimeEdit->setValue(recipe->hops.at(recipe->hops_row).h_time); + htimeEdit->setReadOnly(false); + } else if (val == 5) { // Dry-hop + htimeLabel->setText(tr("Time in days:")); + htimeEdit->setValue(recipe->hops.at(recipe->hops_row).h_time / 1440); + htimeEdit->setReadOnly(false); + } else { + htimeLabel->setText(""); + htimeEdit->setValue(0); + htimeEdit->setReadOnly(true); + } + + this->ignoreChanges = false; + is_changed(); + emit refreshAll(); +} + + +void EditRecipe::on_editHopRow_clicked() +{ + QSqlQuery query; + + QPushButton *pb = qobject_cast(QObject::sender()); + recipe->hops_row = pb->objectName().toInt(); + qDebug() << "Edit hop row" << recipe->hops_row; + Hops backup = recipe->hops.at(recipe->hops_row); + + QDialog* dialog = new QDialog(this); + dialog->resize(738, 260); + QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog); + buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setGeometry(QRect(30, 210, 671, 32)); + buttonBox->setLayoutDirection(Qt::LeftToRight); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + buttonBox->setCenterButtons(true); + QLabel *nameLabel = new QLabel(dialog); + nameLabel->setObjectName(QString::fromUtf8("nameLabel")); + nameLabel->setText(tr("Current hop:")); + nameLabel->setGeometry(QRect(10, 10, 141, 20)); + nameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + QLabel *originLabel = new QLabel(dialog); + originLabel->setObjectName(QString::fromUtf8("originLabel")); + originLabel->setText(tr("Origin:")); + originLabel->setGeometry(QRect(10, 40, 141, 20)); + originLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + QLabel *amountLabel = new QLabel(dialog); + amountLabel->setObjectName(QString::fromUtf8("amountLabel")); + amountLabel->setText(tr("Amount in gr:")); + amountLabel->setGeometry(QRect(10, 100, 141, 20)); + amountLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + htimeLabel = new QLabel(dialog); + htimeLabel->setObjectName(QString::fromUtf8("htimeLabel")); + if (recipe->hops.at(recipe->hops_row).h_useat == 5) // Dry-hop + htimeLabel->setText(tr("Time in days:")); + else if (recipe->hops.at(recipe->hops_row).h_useat == 2 || recipe->hops.at(recipe->hops_row).h_useat == 4) // Boil or whirlpool + htimeLabel->setText(tr("Time in minutes:")); + else + htimeLabel->setText(""); + + htimeLabel->setGeometry(QRect(10, 130, 141, 20)); + htimeLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + QLabel *useatLabel = new QLabel(dialog); + useatLabel->setObjectName(QString::fromUtf8("useatLabel")); + useatLabel->setText(tr("Use at:")); + useatLabel->setGeometry(QRect(10, 160, 141, 20)); + useatLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + QLabel *selectLabel = new QLabel(dialog); + selectLabel->setObjectName(QString::fromUtf8("selectLabel")); + selectLabel->setText(tr("Select hop:")); + selectLabel->setGeometry(QRect(10, 70, 141, 20)); + selectLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + QLabel *instockLabel = new QLabel(dialog); + instockLabel->setObjectName(QString::fromUtf8("instockLabel")); + instockLabel->setText(tr("In stock:")); + instockLabel->setGeometry(QRect(525, 70, 121, 20)); + instockLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + QLabel *ibuLabel = new QLabel(dialog); + ibuLabel->setObjectName(QString::fromUtf8("maxLabel")); + ibuLabel->setText(tr("Bitterness IBU:")); + ibuLabel->setGeometry(QRect(420, 130, 121, 20)); + ibuLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + + hselectEdit = new QComboBox(dialog); + hselectEdit->setObjectName(QString::fromUtf8("selectEdit")); + hselectEdit->setGeometry(QRect(160, 70, 371, 23)); + + hnameEdit = new QLineEdit(dialog); + hnameEdit->setObjectName(QString::fromUtf8("hnameEdit")); + hnameEdit->setText(recipe->hops.at(recipe->hops_row).h_name); + hnameEdit->setGeometry(QRect(160, 10, 511, 23)); + hnameEdit->setReadOnly(true); + horiginEdit = new QLineEdit(dialog); + horiginEdit->setObjectName(QString::fromUtf8("horiginEdit")); + horiginEdit->setText(recipe->hops.at(recipe->hops_row).h_origin); + horiginEdit->setGeometry(QRect(160, 40, 511, 23)); + horiginEdit->setReadOnly(true); + hamountEdit = new QDoubleSpinBox(dialog); + hamountEdit->setObjectName(QString::fromUtf8("hamountEdit")); + hamountEdit->setGeometry(QRect(160, 100, 121, 24)); + hamountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + hamountEdit->setAccelerated(true); + hamountEdit->setDecimals(1); + hamountEdit->setMaximum(1000000.0); + hamountEdit->setSingleStep(0.5); + hamountEdit->setValue(recipe->hops.at(recipe->hops_row).h_amount * 1000.0); + htimeEdit = new QSpinBox(dialog); + htimeEdit->setObjectName(QString::fromUtf8("htimeEdit")); + htimeEdit->setGeometry(QRect(160, 130, 121, 24)); + htimeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + htimeEdit->setAccelerated(true); + htimeEdit->setMaximum(10000.0); + if (recipe->hops.at(recipe->hops_row).h_useat == 2 || recipe->hops.at(recipe->hops_row).h_useat == 4) { // Boil or whirlpool + htimeEdit->setValue(recipe->hops.at(recipe->hops_row).h_time); + htimeEdit->setReadOnly(false); + } else if (recipe->hops.at(recipe->hops_row).h_useat == 5){ // Dry-hop + htimeEdit->setValue(recipe->hops.at(recipe->hops_row).h_time / 1440); + htimeEdit->setReadOnly(false); + } else { + htimeEdit->setReadOnly(true); + } + useatEdit = new QComboBox(dialog); + useatEdit->setObjectName(QString::fromUtf8("useatEdit")); + useatEdit->setGeometry(QRect(160, 160, 161, 23)); + useatEdit->addItem(tr("Mash")); + useatEdit->addItem(tr("First wort")); + useatEdit->addItem(tr("Boil")); + useatEdit->addItem(tr("Aroma")); + useatEdit->addItem(tr("Whirlpool")); + useatEdit->addItem(tr("Dry hop")); + useatEdit->setCurrentIndex(recipe->hops.at(recipe->hops_row).h_useat); + + hinstockEdit = new QCheckBox(dialog); + hinstockEdit->setObjectName(QString::fromUtf8("hinstockEdit")); + hinstockEdit->setGeometry(QRect(655, 70, 85, 21)); + hinstockEdit->setChecked(true); + + ibuEdit = new QDoubleSpinBox(dialog); + ibuEdit->setObjectName(QString::fromUtf8("ibuEdit")); + ibuEdit->setGeometry(QRect(550, 130, 121, 24)); + ibuEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + ibuEdit->setReadOnly(true); + ibuEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); + ibuEdit->setDecimals(1); + double ibu = Utils::toIBU(recipe->hops.at(recipe->hops_row).h_useat, recipe->hops.at(recipe->hops_row).h_form, recipe->preboil_sg, + recipe->batch_size, recipe->hops.at(recipe->hops_row).h_amount, recipe->hops.at(recipe->hops_row).h_time, + recipe->hops.at(recipe->hops_row).h_alpha, recipe->ibu_method, 0, recipe->hops.at(recipe->hops_row).h_time, 0); + ibuEdit->setValue(ibu); + + hop_instock_changed(true); + + connect(hselectEdit, QOverload::of(&QComboBox::currentIndexChanged), this, &EditRecipe::hop_select_changed); + connect(hamountEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::hop_amount_changed); + connect(htimeEdit, QOverload::of(&QSpinBox::valueChanged), this, &EditRecipe::hop_time_changed); + connect(useatEdit, QOverload::of(&QComboBox::currentIndexChanged), this, &EditRecipe::hop_useat_changed); + connect(hinstockEdit, &QCheckBox::stateChanged, this, &EditRecipe::hop_instock_changed); + connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); + + dialog->setModal(true); + dialog->exec(); + if (dialog->result() == QDialog::Rejected) { + qDebug() << "reject and rollback"; + recipe->hops[recipe->hops_row] = backup; + } else { + /* Clear time if hop is not used for boil, whirlpool or dry-hop. */ + if (! (recipe->hops.at(recipe->hops_row).h_useat == 2 || + recipe->hops.at(recipe->hops_row).h_useat == 4 || + recipe->hops.at(recipe->hops_row).h_useat == 5)) { + if (recipe->hops.at(recipe->hops_row).h_time) { + recipe->hops[recipe->hops_row].h_time = 0; + is_changed(); + } + } + } + + disconnect(hselectEdit, nullptr, nullptr, nullptr); + disconnect(hamountEdit, nullptr, nullptr, nullptr); + disconnect(htimeEdit, nullptr, nullptr, nullptr); + disconnect(useatEdit, nullptr, nullptr, nullptr); + disconnect(hinstockEdit, nullptr, nullptr, nullptr); + disconnect(buttonBox, nullptr, nullptr, nullptr); + + emit refreshAll(); +} + +