src/EditRecipe.cpp

changeset 126
3c013ef88a00
parent 125
2e79e0975e58
child 127
475c8b8df67f
--- a/src/EditRecipe.cpp	Sat Apr 09 21:50:19 2022 +0200
+++ b/src/EditRecipe.cpp	Mon Apr 11 16:18:40 2022 +0200
@@ -647,7 +647,17 @@
 
 bool EditRecipe::hop_sort_test(const Hops &D1, const Hops &D2)
 {
-    return (D1.h_useat <= D2.h_useat ) && (D1.h_time >= D2.h_time) && (D1.h_amount >= D2.h_amount);
+    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);
 }
 
 
@@ -659,7 +669,7 @@
     QTableWidgetItem *item;
 
     qDebug() << "refreshHops" << recipe->hops.size();
-    // std::sort(recipe->hops.begin(), recipe->hops.end(), hop_sort_test);
+    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
@@ -1592,6 +1602,21 @@
 }
 
 
+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_deleteFermentRow_clicked()
 {
     QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
@@ -1625,6 +1650,24 @@
 }
 
 
+void EditRecipe::on_deleteHopRow_clicked()
+{
+    QPushButton *pb = qobject_cast<QPushButton *>(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::ferment_amount_changed(double val)
 {
     QTableWidgetItem *item;
@@ -1662,6 +1705,34 @@
     is_changed();
 }
 
+
+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::ferment_pct_changed(double val)
 {
     QTableWidgetItem *item;
@@ -1695,7 +1766,7 @@
     item = new QTableWidgetItem(QString("%1 Kg").arg(recipe->fermentables[recipe->fermentables_row].f_amount, 4, 'f', 3, '0'));
     item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
     ui->fermentablesTable->setItem(recipe->fermentables_row, 7, item);
-    this->amountEdit->setValue(recipe->fermentables[recipe->fermentables_row].f_amount);
+    this->famountEdit->setValue(recipe->fermentables[recipe->fermentables_row].f_amount);
 
     item = new QTableWidgetItem(QString("%1%").arg(recipe->fermentables[recipe->fermentables_row].f_percentage, 2, 'f', 1, '0'));
     item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
@@ -1713,6 +1784,41 @@
     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::ferment_to100_changed(bool val)
 {
     qDebug() << "ferment_to100_changed()" << recipe->fermentables_row << val << recipe->fermentables_use100;
@@ -1728,13 +1834,13 @@
         recipe->fermentables_use100 = true;
         recipe->fermentables[recipe->fermentables_row].f_adjust_to_total_100 = true;
 	pctEdit->setReadOnly(false);
-	amountEdit->setReadOnly(true);
+	famountEdit->setReadOnly(true);
     } else if (recipe->fermentables_use100 && recipe->fermentables[recipe->fermentables_row].f_adjust_to_total_100 && ! val) {
 	/* Scenario 2. */
 	recipe->fermentables[recipe->fermentables_row].f_adjust_to_total_100 = false;
 	recipe->fermentables_use100 = false;
 	pctEdit->setReadOnly(true);
-	amountEdit->setReadOnly(false);
+	famountEdit->setReadOnly(false);
     } else if (recipe->fermentables_use100 && ! recipe->fermentables[recipe->fermentables_row].f_adjust_to_total_100 && val) {
 	/* Scenario 3. */
 	for (int i = 0; i < recipe->fermentables.size(); i++) {
@@ -1757,7 +1863,7 @@
 void EditRecipe::ferment_select_changed(int val)
 {
     QSqlQuery query;
-    bool instock = instockEdit->isChecked();
+    bool instock = finstockEdit->isChecked();
     QString w;
     QTableWidgetItem *item;
 
@@ -1808,9 +1914,9 @@
     /*
      * Update the visible fields
      */
-    nameEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_name);
-    supplierEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_supplier);
-    maxEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_max_in_batch);
+    fnameEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_name);
+    fsupplierEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_supplier);
+    fmaxEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_max_in_batch);
 
     ui->fermentablesTable->setItem(recipe->fermentables_row, 0, new QTableWidgetItem(recipe->fermentables.at(recipe->fermentables_row).f_supplier));
     ui->fermentablesTable->setItem(recipe->fermentables_row, 1, new QTableWidgetItem(recipe->fermentables.at(recipe->fermentables_row).f_name));
@@ -1837,14 +1943,96 @@
     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::ferment_instock_changed(bool val)
 {
     QSqlQuery query;
 
     qDebug() << "ferment_instock_changed()" << recipe->fermentables_row << val;
 
-    this->selectEdit->setCurrentIndex(-1);
-    this->selectEdit->clear();
+    this->fselectEdit->setCurrentIndex(-1);
+    this->fselectEdit->clear();
     QString sql = "SELECT supplier,name,color,inventory FROM inventory_fermentables ";
     if (val)
 	sql.append("WHERE inventory > 0 ");
@@ -1852,14 +2040,39 @@
     query.prepare(sql);
     query.exec();
     query.first();
-    this->selectEdit->addItem("");	// Start with empty value
+    this->fselectEdit->addItem("");	// Start with empty value
     for (int i = 0; i < query.size(); i++) {
-        this->selectEdit->addItem(query.value(0).toString()+" - "+query.value(1).toString()+" ("+query.value(2).toString()+" EBC) "+
+        this->fselectEdit->addItem(query.value(0).toString()+" - "+query.value(1).toString()+" ("+query.value(2).toString()+" EBC) "+
 			QString("%1 kg").arg(query.value(3).toDouble(), 4, 'f', 3, '0'));
         query.next();
     }
 }
 
+
+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::ferment_added_changed(int val)
 {
     qDebug() << "ferment_added_changed()" << recipe->fermentables_row << val;
@@ -1884,6 +2097,36 @@
 }
 
 
+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_editFermentRow_clicked()
 {
     QSqlQuery query;
@@ -1948,30 +2191,30 @@
     maxLabel->setGeometry(QRect(420, 130, 121, 20));
     maxLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
 
-    selectEdit = new QComboBox(dialog);
-    selectEdit->setObjectName(QString::fromUtf8("selectEdit"));
-    selectEdit->setGeometry(QRect(160, 70, 371, 23));
+    fselectEdit = new QComboBox(dialog);
+    fselectEdit->setObjectName(QString::fromUtf8("fselectEdit"));
+    fselectEdit->setGeometry(QRect(160, 70, 371, 23));
 
-    nameEdit = new QLineEdit(dialog);
-    nameEdit->setObjectName(QString::fromUtf8("nameEdit"));
-    nameEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_name);
-    nameEdit->setGeometry(QRect(160, 10, 511, 23));
-    nameEdit->setReadOnly(true);
-    supplierEdit = new QLineEdit(dialog);
-    supplierEdit->setObjectName(QString::fromUtf8("supplierEdit"));
-    supplierEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_supplier);
-    supplierEdit->setGeometry(QRect(160, 40, 511, 23));
-    supplierEdit->setReadOnly(true);
-    amountEdit = new QDoubleSpinBox(dialog);
-    amountEdit->setObjectName(QString::fromUtf8("amountEdit"));
-    amountEdit->setGeometry(QRect(160, 100, 121, 24));
-    amountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
-    amountEdit->setAccelerated(true);
-    amountEdit->setDecimals(3);
-    amountEdit->setReadOnly(recipe->fermentables_use100);
-    amountEdit->setMaximum(100000.0);
-    amountEdit->setSingleStep(0.0010);
-    amountEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_amount);
+    fnameEdit = new QLineEdit(dialog);
+    fnameEdit->setObjectName(QString::fromUtf8("fnameEdit"));
+    fnameEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_name);
+    fnameEdit->setGeometry(QRect(160, 10, 511, 23));
+    fnameEdit->setReadOnly(true);
+    fsupplierEdit = new QLineEdit(dialog);
+    fsupplierEdit->setObjectName(QString::fromUtf8("fsupplierEdit"));
+    fsupplierEdit->setText(recipe->fermentables.at(recipe->fermentables_row).f_supplier);
+    fsupplierEdit->setGeometry(QRect(160, 40, 511, 23));
+    fsupplierEdit->setReadOnly(true);
+    famountEdit = new QDoubleSpinBox(dialog);
+    famountEdit->setObjectName(QString::fromUtf8("famountEdit"));
+    famountEdit->setGeometry(QRect(160, 100, 121, 24));
+    famountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    famountEdit->setAccelerated(true);
+    famountEdit->setDecimals(3);
+    famountEdit->setReadOnly(recipe->fermentables_use100);
+    famountEdit->setMaximum(100000.0);
+    famountEdit->setSingleStep(0.0010);
+    famountEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_amount);
 
     pctEdit = new QDoubleSpinBox(dialog);
     pctEdit->setObjectName(QString::fromUtf8("pctEdit"));
@@ -1991,44 +2234,44 @@
     pctEdit->setSingleStep(0.1);
     pctEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_percentage);
 
-    addedEdit = new QComboBox(dialog);
-    addedEdit->setObjectName(QString::fromUtf8("addedEdit"));
-    addedEdit->setGeometry(QRect(160, 190, 161, 23));
-    addedEdit->addItem(tr("Mash"));
-    addedEdit->addItem(tr("Boil"));
-    addedEdit->addItem(tr("Fermentation"));
-    addedEdit->addItem(tr("Lagering"));
-    addedEdit->addItem(tr("Bottle"));
-    addedEdit->addItem(tr("Kegs"));
-    addedEdit->setCurrentIndex(recipe->fermentables.at(recipe->fermentables_row).f_added);
+    faddedEdit = new QComboBox(dialog);
+    faddedEdit->setObjectName(QString::fromUtf8("faddedEdit"));
+    faddedEdit->setGeometry(QRect(160, 190, 161, 23));
+    faddedEdit->addItem(tr("Mash"));
+    faddedEdit->addItem(tr("Boil"));
+    faddedEdit->addItem(tr("Fermentation"));
+    faddedEdit->addItem(tr("Lagering"));
+    faddedEdit->addItem(tr("Bottle"));
+    faddedEdit->addItem(tr("Kegs"));
+    faddedEdit->setCurrentIndex(recipe->fermentables.at(recipe->fermentables_row).f_added);
 
     to100Edit = new QCheckBox(dialog);
     to100Edit->setObjectName(QString::fromUtf8("to100Edit"));
     to100Edit->setGeometry(QRect(160, 160, 85, 21));
     to100Edit->setChecked(recipe->fermentables.at(recipe->fermentables_row).f_adjust_to_total_100);
 
-    instockEdit = new QCheckBox(dialog);
-    instockEdit->setObjectName(QString::fromUtf8("instockEdit"));
-    instockEdit->setGeometry(QRect(655, 70, 85, 21));
-    instockEdit->setChecked(true);
+    finstockEdit = new QCheckBox(dialog);
+    finstockEdit->setObjectName(QString::fromUtf8("instockEdit"));
+    finstockEdit->setGeometry(QRect(655, 70, 85, 21));
+    finstockEdit->setChecked(true);
 
-    maxEdit = new QDoubleSpinBox(dialog);
-    maxEdit->setObjectName(QString::fromUtf8("maxEdit"));
-    maxEdit->setGeometry(QRect(550, 130, 121, 24));
-    maxEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
-    maxEdit->setReadOnly(true);
-    maxEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
-    maxEdit->setDecimals(1);
-    maxEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_max_in_batch);
+    fmaxEdit = new QDoubleSpinBox(dialog);
+    fmaxEdit->setObjectName(QString::fromUtf8("fmaxEdit"));
+    fmaxEdit->setGeometry(QRect(550, 130, 121, 24));
+    fmaxEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    fmaxEdit->setReadOnly(true);
+    fmaxEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    fmaxEdit->setDecimals(1);
+    fmaxEdit->setValue(recipe->fermentables.at(recipe->fermentables_row).f_max_in_batch);
 
     ferment_instock_changed(true);
 
-    connect(selectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::ferment_select_changed);
-    connect(amountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::ferment_amount_changed);
+    connect(fselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::ferment_select_changed);
+    connect(famountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::ferment_amount_changed);
     connect(pctEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::ferment_pct_changed);
-    connect(addedEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::ferment_added_changed);
+    connect(faddedEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::ferment_added_changed);
     connect(to100Edit, &QCheckBox::stateChanged, this, &EditRecipe::ferment_to100_changed);
-    connect(instockEdit, &QCheckBox::stateChanged, this, &EditRecipe::ferment_instock_changed);
+    connect(finstockEdit, &QCheckBox::stateChanged, this, &EditRecipe::ferment_instock_changed);
     connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
     connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
 
@@ -2054,12 +2297,181 @@
 	}
     }
 
-    disconnect(selectEdit, nullptr, nullptr, nullptr);
-    disconnect(amountEdit, nullptr, nullptr, nullptr);
+    disconnect(fselectEdit, nullptr, nullptr, nullptr);
+    disconnect(famountEdit, nullptr, nullptr, nullptr);
     disconnect(pctEdit, nullptr, nullptr, nullptr);
-    disconnect(addedEdit, nullptr, nullptr, nullptr);
+    disconnect(faddedEdit, nullptr, nullptr, nullptr);
     disconnect(to100Edit, nullptr, nullptr, nullptr);
-    disconnect(instockEdit, nullptr, nullptr, nullptr);
+    disconnect(finstockEdit, nullptr, nullptr, nullptr);
+    disconnect(buttonBox, nullptr, nullptr, nullptr);
+
+    emit refreshAll();
+}
+
+
+void EditRecipe::on_editHopRow_clicked()
+{
+    QSqlQuery query;
+
+    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);
+    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();

mercurial