src/EditRecipeTab5.cpp

Fri, 29 Jul 2022 13:12:26 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 29 Jul 2022 13:12:26 +0200
changeset 373
b02aca4e926c
parent 301
fe6346211b5b
child 395
7212b980a527
permissions
-rw-r--r--

First load of changes for hops. In EditHop load the dropdown buttons from the global table. Use named query fields. Added database utilisation and bu_factor fields for hop extracts. Added edit fields for these new fields. Added post boil SG, utilisation and bu_factor parameters to the toIBU function. Added hops form parameter to the hopFlavourContribution and hopAromaContribution display bars. In the hops inventory list dispay volumes instead of weight for hop extracts. Modified the TinsethIBU function to use utilisation and bu_factor parameters. Add calculations for co2 and iso hop extracts, this is work in progress. The toIBU function makes use of the preSG and postSG values to use the correct SG to caall the TinsethIBU function. This results in a bit lower IBU values mostly affecting the late additions. Added use hop at bottling for iso hop extracts like Tetra hops using the formula from BarthHaas.

/**
 * EditRecipe.cpp is part of bmsapp.
 *
 * tab 5, yeasts.
 *
 * 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 yeaste 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::yeast_sort_test(const Yeasts &D1, const Yeasts &D2)
{
    if (D1.use > D2.use)
	return false;
    if (D1.use < D2.use)
	return true;
    return (D1.amount > D2.amount);
}


void EditRecipe::refreshYeasts()
{
    QString w;
    QWidget* pWidget;
    QHBoxLayout* pLayout;
    QTableWidgetItem *item;

    qDebug() << "refreshYeasts" << recipe->yeasts.size();
    std::sort(recipe->yeasts.begin(), recipe->yeasts.end(), yeast_sort_test);

    const QStringList labels({tr("Yeast"), tr("Laboratory"), tr("Code"), tr("Type"), tr("Use for"), tr("Min. °C"), tr("Max. °C"),
		              tr("Tol. %"), tr("Attn. %"), tr("Amount"), tr("Delete"), tr("Edit") });

    ui->yeastsTable->setColumnCount(12);
    ui->yeastsTable->setColumnWidth(0, 200);	/* Yeast	*/
    ui->yeastsTable->setColumnWidth(1, 125);	/* Laboratory	*/
    ui->yeastsTable->setColumnWidth(2,  80);	/* Code		*/
    ui->yeastsTable->setColumnWidth(3,  80);	/* Type		*/
    ui->yeastsTable->setColumnWidth(4, 100);	/* Usage	*/
    ui->yeastsTable->setColumnWidth(5,  60);	/* Min. 	*/
    ui->yeastsTable->setColumnWidth(6,  60);	/* Max.		*/
    ui->yeastsTable->setColumnWidth(7,  60);	/* Tolerance	*/
    ui->yeastsTable->setColumnWidth(8,  60);	/* Attenuation	*/
    ui->yeastsTable->setColumnWidth(9,  90);	/* Amount	*/
    ui->yeastsTable->setColumnWidth(10, 80);	/* Delete	*/
    ui->yeastsTable->setColumnWidth(11, 80);	/* Edit		*/
    ui->yeastsTable->setHorizontalHeaderLabels(labels);
    ui->yeastsTable->verticalHeader()->hide();
    ui->yeastsTable->setRowCount(recipe->yeasts.size());

    for (int i = 0; i < recipe->yeasts.size(); i++) {

	ui->yeastsTable->setItem(i, 0, new QTableWidgetItem(recipe->yeasts.at(i).name));
	ui->yeastsTable->setItem(i, 1, new QTableWidgetItem(recipe->yeasts.at(i).laboratory));
	ui->yeastsTable->setItem(i, 2, new QTableWidgetItem(recipe->yeasts.at(i).product_id));

	item = new QTableWidgetItem(QCoreApplication::translate("YeastForm", g_yeast_forms[recipe->yeasts.at(i).form]));
        item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 3, item);

        item = new QTableWidgetItem(QCoreApplication::translate("YeastUse", g_yeast_use[recipe->yeasts.at(i).use]));
        item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 4, item);

	item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(i).min_temperature, 2, 'f', 1, '0'));
	item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 5, item);

	item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(i).max_temperature, 2, 'f', 1, '0'));
        item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 6, item);

	item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(i).tolerance, 2, 'f', 1, '0'));
        item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 7, item);

	item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(i).attenuation, 2, 'f', 1, '0'));
        item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 8, item);

	if (recipe->yeasts.at(i).form == 0)
            item = new QTableWidgetItem(QString("%1 pack").arg(recipe->yeasts.at(i).amount, 1, 'f', 0, '0'));
	else if (recipe->yeasts.at(i).form == 1)
	    item = new QTableWidgetItem(QString("%1 gr").arg(recipe->yeasts.at(i).amount * 1000.0, 3, 'f', 2, '0'));
	else
	    item = new QTableWidgetItem(QString("%1 ml").arg(recipe->yeasts.at(i).amount * 1000.0, 3, 'f', 2, '0'));
        item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->yeastsTable->setItem(i, 9, item);

	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(deleteYeastRow_clicked()));
        pLayout = new QHBoxLayout(pWidget);
        pLayout->addWidget(btn_dele);
        pLayout->setContentsMargins(5, 0, 5, 0);
        pWidget->setLayout(pLayout);
        ui->yeastsTable->setCellWidget(i, 10, 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(editYeastRow_clicked()));
        pLayout = new QHBoxLayout(pWidget);
        pLayout->addWidget(btn_edit);
        pLayout->setContentsMargins(5, 0, 5, 0);
        pWidget->setLayout(pLayout);
        ui->yeastsTable->setCellWidget(i, 11, pWidget);
    }
}


/*
 * The results are not stored line in EditProduct. This is just a hint.
 */
void EditRecipe::calcYeast()
{
    double sg = recipe->est_og;
    double plato = Utils::sg_to_plato(sg);
    double volume = recipe->batch_size * 0.9;	// Volume min trub chiller loss.
    bool maybe_starter = false;
    double pitchrate = 0.75;
    double initcells = 0;

    qDebug() << "calcYeast()";
    ui->yeastProcedure->setCurrentIndex(0);

    if (recipe->yeasts.size() == 0)
	return;		// No yeast in recipe.

    for (int i = 0; i < recipe->yeasts.size(); i++) {
	if (recipe->yeasts.at(i).use == 0) {		// Primary
	    if (recipe->yeasts.at(i).form == 1) {
		/*
		 * Dry yeast, build the formule with the yeast parameters.
		 * Based on https://www.lallemandbrewing.com/en/canada/brewers-corner/brewing-tools/pitching-rate-calculator/
		 */
		ui->yeastProcedure->setCurrentIndex(2);
		ui->lo_gr_hlEdit->setValue(recipe->yeasts.at(i).gr_hl_lo);
		ui->hi_gr_hlEdit->setValue(recipe->yeasts.at(i).gr_hl_hi);
		ui->lo_sgEdit->setValue(recipe->yeasts.at(i).sg_lo);
		ui->hi_sgEdit->setValue(recipe->yeasts.at(i).sg_hi);
		double og = recipe->yeasts.at(i).sg_lo;
		double f1 = recipe->yeasts.at(i).gr_hl_lo / 100.0;
		double f2 = round(f1 / 5 * 1000000.0) / 1000000.0;
     		double multiplier = (sg <= og) ? f1 : (f1 + f2 * (sg - og) / 0.008);
		qDebug() << "  sg:" << sg << "og:" << og << "f1:" << f1 << "f2:" << f2 << "multiplier:" << multiplier;
     		double yeast_grams = round(volume * multiplier * 100.0) / 100.0; // * (100 / dataRecord.starter_viability), 2);
     		double yeast_gr_hl = round((yeast_grams / (volume * 0.01)) * 100.0) / 100.0;
		ui->need_grEdit->setValue(yeast_grams);
		ui->pitch_grEdit->setValue(yeast_gr_hl);
     		qDebug() << "  need" << yeast_grams << "grams, gr/hl:" << yeast_gr_hl;
		return;
	    } else {
		/*
		 * Liquid, slant, culture etc.
		 * pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/
		 * and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
		 */
		ui->yeastProcedure->setCurrentIndex(1);
		if (recipe->yeasts.at(i).type == 0) {		// Lager yeast
		    pitchrate = 1.5;
		    if (sg > 1.060)
			pitchrate = 2.0;
		} else if (recipe->yeasts.at(i).type == 6) {	// Real Kveik
		    pitchrate = 0.075;
		} else {
		    pitchrate = 0.75;
		    if (sg > 1.060)
			pitchrate = 1.0;
		}
		if (recipe->yeasts.at(i).form == 0)
		    initcells = (recipe->yeasts.at(i).cells / 1000000000) * recipe->yeasts.at(i).amount * 0.97;	// 97% viability assumed.
		else
		    initcells = (recipe->yeasts.at(i).cells / 1000000) * recipe->yeasts.at(i).amount * 0.97;

		double needed = round(pitchrate * volume * plato * 10.0) / 10.0;
		double starter = 0;
		if (needed > initcells) {
		    maybe_starter = true;
		    starter = round(needed / 2.0) / 100.0;	// A very rough starter size estimate.
		}

		ui->pitchrateEdit->setValue(pitchrate);
		ui->initcellsEdit->setValue(initcells);
		ui->targetcellsEdit->setValue(needed);
		ui->starterEdit->setValue(starter);

		qDebug() << "  pitchrate:" << pitchrate << "needed:" << needed << "initcells:" << initcells << "starter" << maybe_starter << "size" << starter;
	    }
	    break;
	}
    }
}


void EditRecipe::addYeastRow_clicked()
{
    Yeasts newy;

    qDebug() << "Add yeast row";

    for (int i = 0; i < recipe->yeasts.size(); i++) {
        if (recipe->yeasts.at(i).amount == 0)
            return;     // Add only one at a time.
    }

    newy.name = "Select one";
    newy.laboratory = "";
    newy.product_id = "";
    newy.amount = 0;
    newy.type = 0;
    newy.form = 0;
    newy.min_temperature = 0;
    newy.max_temperature = 0;
    newy.flocculation = 0;
    newy.attenuation = 0;
    newy.cells = 0;
    newy.tolerance = 0;
    newy.inventory = 0;
    newy.use = 0;
    newy.sta1 = false;
    newy.bacteria = false;
    newy.harvest_top = false;
    newy.harvest_time = 0;
    newy.pitch_temperature = 0;
    newy.pofpos = false;
    newy.zymocide = 0;
    newy.gr_hl_lo = 0;
    newy.sg_lo = 0;
    newy.gr_hl_hi = 0;
    newy.sg_hi = 0;
    newy.cost = 0;

    recipe->yeasts.append(newy);
    emit refreshAll();
}


void EditRecipe::deleteYeastRow_clicked()
{
    if (recipe->locked || recipe->yeasts.size() < 1)
	return;

    QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
    int row = pb->objectName().toInt();
    qDebug() << "Delete yeast row" << row << recipe->yeasts.size();

    int rc = QMessageBox::warning(this, tr("Delete yeast"), tr("Delete %1").arg(recipe->yeasts.at(row).name),
                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
    if (rc == QMessageBox::No)
        return;

    recipe->yeasts.removeAt(row);
    is_changed();
    emit refreshAll();
}


void EditRecipe::yeast_amount_changed(double val)
{
    QTableWidgetItem *item;

    qDebug() << "yeast_amount_changed()" << recipe->yeasts_row << val;

    if (recipe->yeasts.at(recipe->yeasts_row).form == 0) {
	recipe->yeasts[recipe->yeasts_row].amount = val;
        item = new QTableWidgetItem(QString("%1 pack").arg(val, 1, 'f', 0, '0'));
    } else if (recipe->yeasts.at(recipe->yeasts_row).form == 1) {
	recipe->yeasts[recipe->yeasts_row].amount = val / 1000.0;
        item = new QTableWidgetItem(QString("%1 gr").arg(val, 3, 'f', 2, '0'));
    } else {
        recipe->yeasts[recipe->yeasts_row].amount = val / 1000.0;
        item = new QTableWidgetItem(QString("%1 ml").arg(val, 3, 'f', 2, '0'));
    }
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 9, item);

    calcYeast();
    is_changed();
}


void EditRecipe::yeast_select_changed(int val)
{
    QSqlQuery query;
    bool instock = yinstockEdit->isChecked();
    QString w;
    QTableWidgetItem *item;

    if (val < 1)
        return;

    qDebug() << "yeast_select_changed()" << recipe->yeasts_row << val << instock;

    /*
     * Search the yeast pointed by the index and instock flag.
     */
    QString sql = "SELECT name,laboratory,product_id,type,form,min_temperature,max_temperature,flocculation,attenuation,"
	          "cells,tolerance,sta1,bacteria,harvest_top,harvest_time,pitch_temperature,pofpos,zymocide,"
		  "gr_hl_lo,sg_lo,gr_hl_hi,sg_hi,cost FROM inventory_yeasts ";
    if (instock)
        sql.append("WHERE inventory > 0 ");
    sql.append("ORDER BY laboratory,product_id,name");
    query.prepare(sql);
    query.exec();
    query.first();
    for (int i = 0; i < (val - 1); i++) {
        query.next();
    }
    qDebug() << "found" << query.value(0).toString() << query.value(2).toString();

    /*
     * Replace the yeast record contents
     */
    recipe->yeasts[recipe->yeasts_row].name = query.value(0).toString();
    recipe->yeasts[recipe->yeasts_row].laboratory = query.value(1).toString();
    recipe->yeasts[recipe->yeasts_row].product_id = query.value(2).toString();
    recipe->yeasts[recipe->yeasts_row].type = query.value(3).toInt();
    recipe->yeasts[recipe->yeasts_row].form = query.value(4).toInt();
    recipe->yeasts[recipe->yeasts_row].min_temperature = query.value(5).toDouble();
    recipe->yeasts[recipe->yeasts_row].max_temperature = query.value(6).toDouble();
    recipe->yeasts[recipe->yeasts_row].flocculation = query.value(7).toInt();
    recipe->yeasts[recipe->yeasts_row].attenuation = query.value(8).toDouble();
    recipe->yeasts[recipe->yeasts_row].cells = query.value(9).toDouble();
    recipe->yeasts[recipe->yeasts_row].tolerance = query.value(10).toDouble();
    recipe->yeasts[recipe->yeasts_row].sta1 = query.value(11).toInt() ? true:false;
    recipe->yeasts[recipe->yeasts_row].bacteria = query.value(12).toInt() ? true:false;
    recipe->yeasts[recipe->yeasts_row].harvest_top = query.value(13).toInt() ? true:false;
    recipe->yeasts[recipe->yeasts_row].harvest_time = query.value(14).toInt();
    recipe->yeasts[recipe->yeasts_row].pitch_temperature = query.value(15).toDouble();
    recipe->yeasts[recipe->yeasts_row].pofpos = query.value(16).toInt() ? true:false;
    recipe->yeasts[recipe->yeasts_row].zymocide = query.value(17).toInt();
    recipe->yeasts[recipe->yeasts_row].gr_hl_lo = query.value(18).toInt();
    recipe->yeasts[recipe->yeasts_row].sg_lo = query.value(19).toDouble();
    recipe->yeasts[recipe->yeasts_row].gr_hl_hi = query.value(20).toInt();
    recipe->yeasts[recipe->yeasts_row].sg_hi = query.value(21).toDouble();
    recipe->yeasts[recipe->yeasts_row].cost = query.value(22).toDouble();

    /*
     * Update the visible fields
     */
    ynameEdit->setText(recipe->yeasts.at(recipe->yeasts_row).name);
    ylaboratoryEdit->setText(recipe->yeasts.at(recipe->yeasts_row).laboratory);
    yproduct_idEdit->setText(recipe->yeasts.at(recipe->yeasts_row).product_id);
    if (recipe->yeasts.at(recipe->yeasts_row).form == 0) {
	yamountEdit->setDecimals(0);
	yamountEdit->setSingleStep(1.0);
	yamountLabel->setText(tr("Total packs:"));
    } else if (recipe->yeasts.at(recipe->yeasts_row).form == 1) {
	yamountEdit->setDecimals(1);
    	yamountEdit->setSingleStep(0.5);
	yamountLabel->setText(tr("Amount in gr:"));
    } else {
	yamountEdit->setDecimals(1);
	yamountEdit->setSingleStep(0.5);
	yamountLabel->setText(tr("Amount in ml:"));
    }

    ui->yeastsTable->setItem(recipe->yeasts_row, 0, new QTableWidgetItem(recipe->yeasts.at(recipe->yeasts_row).name));
    ui->yeastsTable->setItem(recipe->yeasts_row, 1, new QTableWidgetItem(recipe->yeasts.at(recipe->yeasts_row).laboratory));
    ui->yeastsTable->setItem(recipe->yeasts_row, 2, new QTableWidgetItem(recipe->yeasts.at(recipe->yeasts_row).product_id));

    item = new QTableWidgetItem(QCoreApplication::translate("YeastForm", g_yeast_forms[recipe->yeasts.at(recipe->yeasts_row).form]));
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 3, item);

    item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(recipe->yeasts_row).min_temperature, 2, 'f', 1, '0'));
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 5, item);

    item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(recipe->yeasts_row).max_temperature, 2, 'f', 1, '0'));
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 6, item);

    item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(recipe->yeasts_row).tolerance, 2, 'f', 1, '0'));
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 7, item);

    item = new QTableWidgetItem(QString("%1").arg(recipe->yeasts.at(recipe->yeasts_row).attenuation, 2, 'f', 1, '0'));
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 8, item);

    calcYeast();
    is_changed();
}


void EditRecipe::yeast_instock_changed(bool val)
{
    QSqlQuery query;

    qDebug() << "yeast_instock_changed()" << recipe->yeasts_row << val;

    this->yselectEdit->setCurrentIndex(-1);
    this->yselectEdit->clear();
    QString sql = "SELECT name,laboratory,product_id,inventory FROM inventory_yeasts ";
    if (val)
        sql.append("WHERE inventory > 0 ");
    sql.append("ORDER BY laboratory,product_id,name");
    query.prepare(sql);
    query.exec();
    query.first();
    this->yselectEdit->addItem("");      // Start with empty value
    for (int i = 0; i < query.size(); i++) {
        this->yselectEdit->addItem(query.value(1).toString()+" - "+query.value(2).toString()+" "+query.value(0).toString() + 
                        QString(" (%1 gr)").arg(query.value(3).toDouble() * 1000.0, 2, 'f', 1, '0'));
        query.next();
    }
}


void EditRecipe::yeast_useat_changed(int val)
{
    qDebug() << "yeast_useat_changed()" << recipe->yeasts_row << val;

    recipe->yeasts[recipe->yeasts_row].use = val;
    QTableWidgetItem *item = new QTableWidgetItem(QCoreApplication::translate("YeastUse", g_yeast_use[val]));
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->yeastsTable->setItem(recipe->yeasts_row, 5, item);
    is_changed();
    emit refreshAll();
}


void EditRecipe::editYeastRow_clicked()
{
    QSqlQuery query;

    if (recipe->locked)
	return;

    QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
    recipe->yeasts_row = pb->objectName().toInt();
    qDebug() << "Edit yeast row" << recipe->yeasts_row;
    Yeasts backup = recipe->yeasts.at(recipe->yeasts_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("Yeast name:"));
    nameLabel->setGeometry(QRect(10, 10, 141, 20));
    nameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    QLabel *laboratoryLabel = new QLabel(dialog);
    laboratoryLabel->setObjectName(QString::fromUtf8("laboratoryLabel"));
    laboratoryLabel->setText(tr("Laboratory:"));
    laboratoryLabel->setGeometry(QRect(10, 40, 141, 20));
    laboratoryLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    QLabel *product_idLabel = new QLabel(dialog);
    product_idLabel->setObjectName(QString::fromUtf8("product_idLabel"));
    product_idLabel->setText(tr("Laboratory:"));
    product_idLabel->setGeometry(QRect(10, 70, 141, 20));
    product_idLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    QLabel *selectLabel = new QLabel(dialog);
    selectLabel->setObjectName(QString::fromUtf8("selectLabel"));
    selectLabel->setText(tr("Select yeast:"));
    selectLabel->setGeometry(QRect(10,100, 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,100, 121, 20));
    instockLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    yamountLabel = new QLabel(dialog);
    yamountLabel->setObjectName(QString::fromUtf8("amountLabel"));
    if (recipe->yeasts.at(recipe->yeasts_row).form == 0)
	yamountLabel->setText(tr("Total packs:"));
    else if (recipe->yeasts.at(recipe->yeasts_row).form == 1)
	yamountLabel->setText(tr("Amount in gr:"));
    else
	yamountLabel->setText(tr("Amount in ml:"));
    yamountLabel->setGeometry(QRect(10, 130, 141, 20));
    yamountLabel->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);

    ynameEdit = new QLineEdit(dialog);
    ynameEdit->setObjectName(QString::fromUtf8("ynameEdit"));
    ynameEdit->setText(recipe->yeasts.at(recipe->yeasts_row).name);
    ynameEdit->setGeometry(QRect(160, 10, 511, 23));
    ynameEdit->setReadOnly(true);
    ylaboratoryEdit = new QLineEdit(dialog);
    ylaboratoryEdit->setObjectName(QString::fromUtf8("ylaboratoryEdit"));
    ylaboratoryEdit->setText(recipe->yeasts.at(recipe->yeasts_row).laboratory);
    ylaboratoryEdit->setGeometry(QRect(160, 40, 511, 23));
    ylaboratoryEdit->setReadOnly(true);
    yproduct_idEdit = new QLineEdit(dialog);
    yproduct_idEdit->setObjectName(QString::fromUtf8("yproduct_idEdit"));
    yproduct_idEdit->setText(recipe->yeasts.at(recipe->yeasts_row).product_id);
    yproduct_idEdit->setGeometry(QRect(160, 70, 511, 23));
    yproduct_idEdit->setReadOnly(true);
    yselectEdit = new QComboBox(dialog);
    yselectEdit->setObjectName(QString::fromUtf8("selectEdit"));
    yselectEdit->setGeometry(QRect(160,100, 371, 23));
    yinstockEdit = new QCheckBox(dialog);
    yinstockEdit->setObjectName(QString::fromUtf8("yinstockEdit"));
    yinstockEdit->setGeometry(QRect(655,100, 85, 21));
    yinstockEdit->setChecked(true);
    yamountEdit = new QDoubleSpinBox(dialog);
    yamountEdit->setObjectName(QString::fromUtf8("yamountEdit"));
    yamountEdit->setGeometry(QRect(160, 130, 121, 24));
    yamountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    yamountEdit->setAccelerated(true);
    if (recipe->yeasts.at(recipe->yeasts_row).form == 0) {
	yamountEdit->setDecimals(0);
        yamountEdit->setSingleStep(1.0);
	yamountEdit->setValue(recipe->yeasts.at(recipe->yeasts_row).amount);
    } else if (recipe->yeasts.at(recipe->yeasts_row).form == 1) {
    	yamountEdit->setDecimals(1);
    	yamountEdit->setSingleStep(0.5);
	yamountEdit->setValue(recipe->yeasts.at(recipe->yeasts_row).amount * 1000.0);
    } else {
	yamountEdit->setDecimals(1);
        yamountEdit->setSingleStep(0.5);
	yamountEdit->setValue(recipe->yeasts.at(recipe->yeasts_row).amount * 1000.0);
    }
    yamountEdit->setMaximum(1000000000.0);
    useatEdit = new QComboBox(dialog);
    useatEdit->setObjectName(QString::fromUtf8("useatEdit"));
    useatEdit->setGeometry(QRect(160, 160, 161, 23));
    useatEdit->addItem(tr("Primary"));
    useatEdit->addItem(tr("Secondary"));
    useatEdit->addItem(tr("Tertiary"));
    useatEdit->addItem(tr("Bottle"));
    useatEdit->setCurrentIndex(recipe->yeasts.at(recipe->yeasts_row).use);

    yeast_instock_changed(true);

    connect(yselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::yeast_select_changed);
    connect(yamountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::yeast_amount_changed);
    connect(useatEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::yeast_useat_changed);
    connect(yinstockEdit, &QCheckBox::stateChanged, this, &EditRecipe::yeast_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->yeasts[recipe->yeasts_row] = backup;
    } else {

    }

    disconnect(yselectEdit, nullptr, nullptr, nullptr);
    disconnect(yamountEdit, nullptr, nullptr, nullptr);
    disconnect(useatEdit, nullptr, nullptr, nullptr);
    disconnect(yinstockEdit, nullptr, nullptr, nullptr);
    disconnect(buttonBox, nullptr, nullptr, nullptr);

    emit refreshAll();
}


void EditRecipe::adjustYeasts(double factor)
{
    double amount;

    if (recipe->yeasts.size() == 0)
	return;

    for (int i = 0; i < recipe->yeasts.size(); i++) {
	if (recipe->yeasts.at(i).form == 1) { // Only adjust dry yeast
	    amount = recipe->yeasts.at(i).amount * factor;
	    recipe->yeasts[i].amount = amount;
	}
    }
}

mercurial