Fri, 20 May 2022 22:06:06 +0200
Version 0.2.1. Updated translations.
/** * 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 <http://www.gnu.org/licenses/>. */ 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); 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, 84); /* Type */ ui->hopsTable->setColumnWidth(3, 84); /* 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, 90); /* 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(hop_types[recipe->hops.at(i).h_type]); item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); ui->hopsTable->setItem(i, 2, item); item = new QTableWidgetItem(hop_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(hop_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, recipe->boil_time); 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(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(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); } } void EditRecipe::hop_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::hop_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, recipe->boil_time); 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 << "method" << recipe->ibu_method; recipe->est_ibu = ibus; ui->est_ibuEdit->setValue(recipe->est_ibu); ui->est_ibu2Edit->setValue(recipe->est_ibu); ui->est_ibuShow->setValue(recipe->est_ibu); ui->hop_tasteShow->setValue(hop_flavour); ui->hop_aromaShow->setValue(hop_aroma); } void EditRecipe::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. } newh.h_name = "Select one"; newh.h_origin = ""; newh.h_amount = 0; newh.h_cost = 0; newh.h_type = 0; newh.h_form = 0; newh.h_useat = 2; newh.h_time = 0; newh.h_alpha = 0; newh.h_beta = 0; newh.h_hsi = 0; newh.h_humulene = 0; newh.h_caryophyllene = 0; newh.h_cohumulone = 0; newh.h_myrcene = 0; newh.h_total_oil = 0; recipe->hops.append(newh); emit refreshAll(); } void EditRecipe::deleteHopRow_clicked() { if (recipe->locked || recipe->hops.size() < 1) return; QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender()); int row = pb->objectName().toInt(); qDebug() << "Delete hop row" << row << recipe->hops.size(); 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; recipe->hops.removeAt(row); is_changed(); emit refreshAll(); } void EditRecipe::hop_amount_changed(double val) { QTableWidgetItem *item; qDebug() << "hop_amount_changed()" << recipe->hops_row << val; 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, recipe->boil_time); 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); calcIBUs(); is_changed(); } void EditRecipe::hop_time_changed(int val) { QTableWidgetItem *item; qDebug() << "hop_time_changed()" << recipe->hops_row << 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')); recipe->hops[recipe->hops_row].h_time = val; } else if (recipe->hops.at(recipe->hops_row).h_useat == 5) { // Dry-hop item = new QTableWidgetItem(QString("%1 days.").arg(val, 1, 'f', 0, '0')); recipe->hops[recipe->hops_row].h_time = val * 1440; } else { item = new QTableWidgetItem(QString("")); recipe->hops[recipe->hops_row].h_time = val; } 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, recipe->boil_time); 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); 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 */ 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, recipe->boil_time); 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(hop_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(hop_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); 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; recipe->hops[recipe->hops_row].h_useat = val; QTableWidgetItem *item = new QTableWidgetItem(hop_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); } is_changed(); emit refreshAll(); } void EditRecipe::editHopRow_clicked() { QSqlQuery query; if (recipe->locked) return; QPushButton *pb = qobject_cast<QPushButton *>(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, recipe->boil_time); ibuEdit->setValue(ibu); hop_instock_changed(true); connect(hselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::hop_select_changed); connect(hamountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::hop_amount_changed); connect(htimeEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &EditRecipe::hop_time_changed); connect(useatEdit, QOverload<int>::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(); } void EditRecipe::adjustHops(double factor) { double amount; if (recipe->hops.size() == 0) return; for (int i = 0; i < recipe->hops.size(); i++) { amount = recipe->hops.at(i).h_amount * factor; recipe->hops[i].h_amount = amount; } }