src/EditRecipeTab4.cpp

Thu, 18 Aug 2022 20:34:15 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 18 Aug 2022 20:34:15 +0200
changeset 401
583148eb6e01
parent 359
dfbb012c631c
child 454
2dfead81c72f
permissions
-rw-r--r--

Init est_carb field for new products.

/**
 * EditRecipe.cpp is part of bmsapp.
 *
 * tab 4, miscs.
 *
 * 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::misc_sort_test(const Miscs &D1, const Miscs &D2)
{
    if (D1.use_use > D2.use_use)
	return false;
    if (D1.use_use < D2.use_use)
	return true;
    if (D1.type > D2.type)
	return false;
    if (D1.type < D2.type)
	return true;
    return (D1.amount > D2.amount);
}


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

    qDebug() << "refreshMiscs" << recipe->miscs.size();
    std::sort(recipe->miscs.begin(), recipe->miscs.end(), misc_sort_test);

    const QSignalBlocker blocker1(ui->bs_cacl2Edit);
    const QSignalBlocker blocker2(ui->bs_caso4Edit);
    const QSignalBlocker blocker3(ui->bs_mgso4Edit);
    const QSignalBlocker blocker4(ui->bs_naclEdit);
    const QSignalBlocker blocker5(ui->bs_mgcl2Edit);
    const QSignalBlocker blocker6(ui->bs_nahco3Edit);
    const QSignalBlocker blocker7(ui->bs_caco3Edit);
    const QSignalBlocker blocker8(ui->mw_acidPick);
    const QSignalBlocker blocker9(ui->mw_acidvolEdit);
    const QSignalBlocker blocker10(ui->ss_cacl2Edit);
    const QSignalBlocker blocker11(ui->ss_caso4Edit);
    const QSignalBlocker blocker12(ui->ss_mgso4Edit);
    const QSignalBlocker blocker13(ui->ss_naclEdit);
    const QSignalBlocker blocker14(ui->ss_mgcl2Edit);
    const QSignalBlocker blocker15(ui->sp_acidtypeEdit);
    const QSignalBlocker blocker16(ui->sp_acidvolEdit);

    const QStringList labels({tr("Ingredient"), tr("Type"), tr("Use at"), tr("Time"), tr("Amount"), tr("Delete"), tr("Edit") });

    ui->miscsTable->setColumnCount(7);
    ui->miscsTable->setColumnWidth(0, 300);	/* Ingredient	*/
    ui->miscsTable->setColumnWidth(1, 100);	/* Type		*/
    ui->miscsTable->setColumnWidth(2, 100);	/* Added	*/
    ui->miscsTable->setColumnWidth(3,  75);	/* Time		*/
    ui->miscsTable->setColumnWidth(4,  90);	/* Amount	*/
    ui->miscsTable->setColumnWidth(5,  80);	/* Delete	*/
    ui->miscsTable->setColumnWidth(6,  80);	/* Edit		*/
    ui->miscsTable->setHorizontalHeaderLabels(labels);
    ui->miscsTable->verticalHeader()->hide();
    ui->miscsTable->setRowCount(recipe->miscs.size());

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

	ui->miscsTable->setItem(i, 0, new QTableWidgetItem(recipe->miscs.at(i).name));

	item = new QTableWidgetItem(QCoreApplication::translate("MiscType", g_misc_types[recipe->miscs.at(i).type]));
        item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
        ui->miscsTable->setItem(i, 1, item);

	item = new QTableWidgetItem(QCoreApplication::translate("MiscUse", g_misc_uses[recipe->miscs.at(i).use_use]));
        item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
        ui->miscsTable->setItem(i, 2, item);

	if (recipe->miscs.at(i).use_use == MISC_USES_BOIL) {
	    item = new QTableWidgetItem(QString("%1 min.").arg(recipe->miscs.at(i).time, 1, 'f', 0, '0'));
	} else if (recipe->miscs.at(i).use_use == MISC_USES_PRIMARY || recipe->miscs.at(i).use_use == MISC_USES_SECONDARY) {
	    item = new QTableWidgetItem(QString("%1 days.").arg(recipe->miscs.at(i).time / 1440, 1, 'f', 0, '0'));
	} else {
	    item = new QTableWidgetItem(QString(""));
	}
	item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->miscsTable->setItem(i, 3, item);

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

	/*
	 * Add the Delete and Edit row buttons.
	 * Not for water agents, these are set on the water tab.
	 */
	if (recipe->miscs.at(i).type == MISC_TYPES_WATER_AGENT) {
	    ui->miscsTable->removeCellWidget(i, 5);
	    ui->miscsTable->removeCellWidget(i, 6);
	    item = new QTableWidgetItem("");
            item->setToolTip(tr("Edit this from the water tab"));
            ui->miscsTable->setItem(i, 5, item);
	    item = new QTableWidgetItem("");
            item->setToolTip(tr("Edit this from the water tab"));
            ui->miscsTable->setItem(i, 6, item);
	} else {
	    if (ui->miscsTable->item(i, 5)) {
                ui->miscsTable->takeItem(i, 5);         /* to remove the old tooltip */
            }
            if (ui->miscsTable->item(i, 6)) {
                ui->miscsTable->takeItem(i, 6);
            }
            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(deleteMiscRow_clicked()));
            pLayout = new QHBoxLayout(pWidget);
            pLayout->addWidget(btn_dele);
            pLayout->setContentsMargins(5, 0, 5, 0);
            pWidget->setLayout(pLayout);
            ui->miscsTable->setCellWidget(i, 5, 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(editMiscRow_clicked()));
            pLayout = new QHBoxLayout(pWidget);
            pLayout->addWidget(btn_edit);
            pLayout->setContentsMargins(5, 0, 5, 0);
            pWidget->setLayout(pLayout);
            ui->miscsTable->setCellWidget(i, 6, pWidget);
	}

	/*
	 * Update the water agents.
	 */
	if (recipe->miscs.at(i).type == MISC_TYPES_WATER_AGENT && recipe->miscs.at(i).use_use == MISC_USES_MASH) {
	    if (recipe->miscs.at(i).name == "CaCl2") {
		ui->bs_cacl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "CaSO4") {
		ui->bs_caso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "MgSO4") {
		ui->bs_mgso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "NaCl") {
		ui->bs_naclEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "MgCl2") {
		ui->bs_mgcl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "NaHCO3") {
		ui->bs_nahco3Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "CaCO3") {
		ui->bs_caco3Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "Melkzuur" || recipe->miscs.at(i).name == "Lactic") {
		recipe->wa_acid_name = 0;
		recipe->wa_acid_perc = my_acids.at(0).AcidPrc;
		ui->mw_acidPick->setCurrentIndex(0);
		ui->mw_acidpercEdit->setValue(my_acids.at(0).AcidPrc);
		ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "Zoutzuur" || recipe->miscs.at(i).name == "Hydrochloric") {
                recipe->wa_acid_name = 1;
                recipe->wa_acid_perc = my_acids.at(1).AcidPrc;
		ui->mw_acidPick->setCurrentIndex(1);
                ui->mw_acidpercEdit->setValue(my_acids.at(1).AcidPrc);
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "Fosforzuur" || recipe->miscs.at(i).name == "Phosphoric") {
                recipe->wa_acid_name = 2;
                recipe->wa_acid_perc = my_acids.at(2).AcidPrc;
		ui->mw_acidPick->setCurrentIndex(2);
                ui->mw_acidpercEdit->setValue(my_acids.at(2).AcidPrc);
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    } else if (recipe->miscs.at(i).name == "Zwavelzuur" || recipe->miscs.at(i).name == "Sulfuric") {
                recipe->wa_acid_name = 3;
                recipe->wa_acid_perc = my_acids.at(3).AcidPrc;
		ui->mw_acidPick->setCurrentIndex(3);
                ui->mw_acidpercEdit->setValue(my_acids.at(3).AcidPrc);
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
	    }
	} else if (recipe->miscs.at(i).type == MISC_TYPES_WATER_AGENT && recipe->miscs.at(i).use_use == MISC_USES_SPARGE) {
            if (recipe->miscs.at(i).name == "CaCl2") {
                ui->ss_cacl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "CaSO4") {
                ui->ss_caso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "MgSO4") {
                ui->ss_mgso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "NaCl") {
                ui->ss_naclEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "MgCl2") {
                ui->ss_mgcl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Melkzuur" || recipe->miscs.at(i).name == "Lactic") {
                recipe->sparge_acid_type = 0;
                recipe->sparge_acid_perc = my_acids.at(0).AcidPrc;
                ui->sp_acidtypeEdit->setCurrentIndex(0);
                ui->sp_acidpercEdit->setValue(my_acids.at(0).AcidPrc);
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Zoutzuur" || recipe->miscs.at(i).name == "Hydrochloric") {
                recipe->sparge_acid_type = 1;
                recipe->sparge_acid_perc = my_acids.at(1).AcidPrc;
                ui->sp_acidtypeEdit->setCurrentIndex(1);
                ui->sp_acidpercEdit->setValue(my_acids.at(1).AcidPrc);
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Fosforzuur" || recipe->miscs.at(i).name == "Phosphoric") {
                recipe->sparge_acid_type = 2;
                recipe->sparge_acid_perc = my_acids.at(2).AcidPrc;
                ui->sp_acidtypeEdit->setCurrentIndex(2);
                ui->sp_acidpercEdit->setValue(my_acids.at(2).AcidPrc);
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Zwavelzuur" || recipe->miscs.at(i).name == "Sulfuric") {
                recipe->sparge_acid_type = 3;
                recipe->sparge_acid_perc = my_acids.at(3).AcidPrc;
                ui->sp_acidtypeEdit->setCurrentIndex(3);
                ui->sp_acidpercEdit->setValue(my_acids.at(3).AcidPrc);
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            }
	}
    }
}


/*
 * Manipulate the memory array and update the miscs table.
 */
void EditRecipe::brewing_salt_sub(QString salt, double val, int use)
{
    QTableWidgetItem *item;

    val = round(val * 100.0) / 100.0;
    if (val == 0) {
	/*
	 * Remove this salt if it is in the table.
	 */
	for (int i = 0; i < recipe->miscs.size(); i++) {
	    if (salt.contains(recipe->miscs.at(i).name) && recipe->miscs.at(i).use_use == use) {
		qDebug() << "  brewing_salt_sub delete" << salt << use;
		recipe->miscs.removeAt(i);
		refreshMiscs();
		return;
	    }
	}
	return;
    }

    /*
     * First see if this salt is in the table.
     * If it is, update the amount.
     */
    for (int i = 0; i < recipe->miscs.size(); i++) {
	if (salt.contains(recipe->miscs.at(i).name) && recipe->miscs.at(i).use_use == use) {
	    recipe->miscs[i].amount = val / 1000.0;
	    if (recipe->miscs.at(i).amount_is_weight)
            	item = new QTableWidgetItem(QString("%1 gr").arg(val, 3, 'f', 2, '0'));
            else
	    	item = new QTableWidgetItem(QString("%1 ml").arg(val, 3, 'f', 2, '0'));
	    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
	    ui->miscsTable->setItem(i, 4, item);
	    return;
	}
    }

    /*
     * We need a new entry. Search in the database is tricky because
     * we are here with possible more names for the same salt. The
     * name can be like 'Lactic Melkzuur'. So we select only the
     * brewing salts and manually check their names.
     */
    QSqlQuery query("SELECT * FROM inventory_miscs WHERE type = 4");
    while (query.next()) {
	if (salt.contains(query.value(1).toString())) {
	    qDebug() << "  found it, append";
	    Miscs m;
	    m.name = query.value(1).toString();
            m.amount = val / 1000.0;
            m.type = query.value(2).toInt();
            m.use_use = use;
            m.time = query.value(4).toDouble();
            m.amount_is_weight = query.value(5).toInt() ? true:false;
            m.cost = query.value(10).toDouble();
            recipe->miscs.append(m);
	    refreshMiscs();
	    return;
	}
    }

    qDebug() << "brewing_salt_sub, nothing done." << salt << val << use;
}


/*
 * Edit brewing salt and recalculate.
 */
void EditRecipe::set_brewing_salt(QString salt, double val, int use)
{
    val = round(val * 100.0) / 100.0;
    qDebug() << "set_brewing_salt" << salt << val << use;
    brewing_salt_sub(salt, val, use);
    calcWater();
    is_changed();
}


void EditRecipe::addMiscRow_clicked()
{
    Miscs newm;

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

    newm.name = "Select one";
    newm.amount = 0;
    newm.type = 0;
    newm.use_use = 0;
    newm.time = 0;
    newm.amount_is_weight = true;
    newm.cost = 0;
    recipe->miscs.append(newm);
    is_changed();
    refreshMiscs();
}


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

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

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

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


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

    qDebug() << "misc_amount_changed()" << recipe->miscs_row << val;

    recipe->miscs[recipe->miscs_row].amount = val / 1000.0;
    if (recipe->miscs.at(recipe->miscs_row).amount_is_weight) {
        item = new QTableWidgetItem(QString("%1 gr").arg(recipe->miscs.at(recipe->miscs_row).amount * 1000.0, 3, 'f', 2, '0'));
    } else {
        item = new QTableWidgetItem(QString("%1 ml").arg(recipe->miscs.at(recipe->miscs_row).amount * 1000.0, 3, 'f', 2, '0'));
    }
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 4, item);

    is_changed();
}


void EditRecipe::misc_time_changed(int val)
{
    QTableWidgetItem *item;

    qDebug() << "misc_time_changed()" << recipe->miscs_row << val;

    if (recipe->miscs.at(recipe->miscs_row).use_use == MISC_USES_BOIL) {
	recipe->miscs[recipe->miscs_row].time = val;
	item = new QTableWidgetItem(QString("%1 min.").arg(val, 1, 'f', 0, '0'));
    } else if (recipe->miscs.at(recipe->miscs_row).use_use == MISC_USES_PRIMARY ||
	       recipe->miscs.at(recipe->miscs_row).use_use == MISC_USES_SECONDARY) {
	recipe->miscs[recipe->miscs_row].time = val * 1440;
	item = new QTableWidgetItem(QString("%1 days.").arg(val, 1, 'f', 0, '0'));
    } else {
	item = new QTableWidgetItem(QString(""));
    }
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 3, item);

    is_changed();
}


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

    if (val < 1)
        return;

    qDebug() << "misc_select_changed()" << recipe->miscs_row << val << instock;

    /*
     * Search the misc ingredient pointed by the index and instock flag.
     */
    QString sql = "SELECT name,type,use_use,time,amount_is_weight,cost FROM inventory_miscs WHERE ";
    if (instock)
        sql.append("inventory > 0 AND ");
    sql.append("type != 4 ORDER BY name");
    qDebug() << sql;
    query.prepare(sql);
    query.exec();
    query.first();
    for (int i = 0; i < (val - 1); i++) {
        query.next();
    }
    qDebug() << "found" << query.value(0).toString();

    /*
     * Replace the misc record contents
     */
    recipe->miscs[recipe->miscs_row].name = query.value(0).toString();
    recipe->miscs[recipe->miscs_row].type = query.value(1).toInt();
    recipe->miscs[recipe->miscs_row].use_use = query.value(2).toInt();
    recipe->miscs[recipe->miscs_row].time = query.value(3).toDouble();
    recipe->miscs[recipe->miscs_row].amount_is_weight = query.value(4).toInt() ? true:false;
    recipe->miscs[recipe->miscs_row].cost = query.value(5).toDouble();

    /*
     * Update the visible fields
     */
    mnameEdit->setText(recipe->miscs.at(recipe->miscs_row).name);
    ui->miscsTable->setItem(recipe->miscs_row, 0, new QTableWidgetItem(recipe->miscs.at(recipe->miscs_row).name));

    item = new QTableWidgetItem(QCoreApplication::translate("MiscType", g_misc_types[recipe->miscs.at(recipe->miscs_row).type]));
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 1, item);

    item = new QTableWidgetItem(QCoreApplication::translate("MiscUse", g_misc_uses[recipe->miscs.at(recipe->miscs_row).use_use]));
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 2, item);
    useatEdit->setCurrentIndex(recipe->miscs.at(recipe->miscs_row).use_use);

    if (recipe->miscs.at(recipe->miscs_row).use_use == 3 || recipe->miscs.at(recipe->miscs_row).use_use == 4) {     // Fermentation stages
        mtimeEdit->setValue(recipe->miscs.at(recipe->miscs_row).time / 1440);
        mtimeEdit->setReadOnly(false);
	mtimeLabel->setText(tr("Time in days:"));
	item = new QTableWidgetItem(QString("%1 days.").arg(recipe->miscs.at(recipe->miscs_row).time / 1440, 1, 'f', 0, '0'));
    } else if (recipe->miscs.at(recipe->miscs_row).use_use == 2) {    // Boil
        mtimeEdit->setValue(recipe->miscs.at(recipe->miscs_row).time);
        mtimeEdit->setReadOnly(false);
	mtimeLabel->setText(tr("Time in minutes:"));
	item = new QTableWidgetItem(QString("%1 min.").arg(recipe->miscs.at(recipe->miscs_row).time, 1, 'f', 0, '0'));
    } else {
        mtimeEdit->setReadOnly(true);
	mtimeLabel->setText("");
	item = new QTableWidgetItem(QString(""));
    }
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 3, item);

    if (recipe->miscs.at(recipe->miscs_row).amount_is_weight) {
	mamountLabel->setText(tr("Amount in gr:"));
	item = new QTableWidgetItem(QString("%1 gr").arg(recipe->miscs.at(recipe->miscs_row).amount * 1000.0, 3, 'f', 2, '0'));
    } else {
	mamountLabel->setText(tr("Amount in ml:"));
	item = new QTableWidgetItem(QString("%1 ml").arg(recipe->miscs.at(recipe->miscs_row).amount * 1000.0, 3, 'f', 2, '0'));
    }
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 4, item);

    qDebug() << "before" << recipe->miscs_row;
    is_changed();
    refreshMiscs();
    /*
     * The order of the list is changed, lookup the item we just added.
     */
    for (int i = 0; i < recipe->miscs.size(); i++) {
        if ((recipe->miscs.at(i).name == query.value(0).toString()) &&
            (recipe->miscs.at(i).type == query.value(1).toInt()) &&
            (recipe->miscs.at(i).use_use == query.value(2).toInt())) {
            recipe->miscs_row = i;
            break;
        }
    }
    qDebug() << "after" << recipe->miscs_row;
}


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

    qDebug() << "misc_instock_changed()" << recipe->miscs_row << val;

    this->mselectEdit->setCurrentIndex(-1);
    this->mselectEdit->clear();
    QString sql = "SELECT name,type,amount_is_weight,inventory FROM inventory_miscs WHERE ";
    if (val)
        sql.append("inventory > 0 AND ");
    sql.append("type != 4 ORDER BY name");
    query.prepare(sql);
    query.exec();
    query.first();
    this->mselectEdit->addItem("");      // Start with empty value
    for (int i = 0; i < query.size(); i++) {
        this->mselectEdit->addItem(query.value(0).toString()+ " (" + QCoreApplication::translate("MiscType", g_misc_types[query.value(1).toInt()]) + ") " +
                        QString("%1 %2").arg(query.value(3).toDouble() * 1000.0, 3, 'f', 2, '0').arg(query.value(2).toInt()?"gr":"ml"));
        query.next();
    }
}


void EditRecipe::misc_useat_changed(int val)
{
    QTableWidgetItem *item;

    qDebug() << "misc_useat_changed" << val;
    recipe->miscs[recipe->miscs_row].use_use = val;
    item = new QTableWidgetItem(QCoreApplication::translate("MiscUse", g_misc_uses[val]));
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 2, item);

    if (val == MISC_USES_PRIMARY || val == MISC_USES_SECONDARY) {
	recipe->miscs[recipe->miscs_row].time = mtimeEdit->value() * 1440;
        mtimeEdit->setReadOnly(false);
        mtimeLabel->setText(tr("Time in days:"));
        item = new QTableWidgetItem(QString("%1 days.").arg(recipe->miscs.at(recipe->miscs_row).time / 1440, 1, 'f', 0, '0'));
    } else if (val == MISC_USES_BOIL) {
	recipe->miscs[recipe->miscs_row].time = mtimeEdit->value();
        mtimeEdit->setReadOnly(false);
        mtimeLabel->setText(tr("Time in minutes:"));
        item = new QTableWidgetItem(QString("%1 min.").arg(recipe->miscs.at(recipe->miscs_row).time, 1, 'f', 0, '0'));
    } else {
	recipe->miscs[recipe->miscs_row].time = 0;
	mtimeEdit->setValue(0);
        mtimeEdit->setReadOnly(true);
        mtimeLabel->setText("");
        item = new QTableWidgetItem(QString(""));
    }
    item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
    ui->miscsTable->setItem(recipe->miscs_row, 3, item);

    is_changed();
}


void EditRecipe::editMiscRow_clicked()
{
    QSqlQuery query;

    if (recipe->locked)
	return;

    QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
    recipe->miscs_row = pb->objectName().toInt();
    qDebug() << "Edit misc row" << recipe->miscs_row;
    Miscs backup = recipe->miscs.at(recipe->miscs_row);

    QDialog* dialog = new QDialog(this);
    dialog->resize(738, 230);
    QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
    buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
    buttonBox->setGeometry(QRect(30, 180, 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 ingredient:"));
    nameLabel->setGeometry(QRect(10, 10, 141, 20));
    nameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

    mamountLabel = new QLabel(dialog);
    mamountLabel->setObjectName(QString::fromUtf8("mamountLabel"));
    if (recipe->miscs.at(recipe->miscs_row).amount_is_weight)
    	mamountLabel->setText(tr("Amount in gr:"));
    else
	mamountLabel->setText(tr("Amount in ml:"));
    mamountLabel->setGeometry(QRect(10, 70, 141, 20));
    mamountLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

    mtimeLabel = new QLabel(dialog);
    mtimeLabel->setObjectName(QString::fromUtf8("mtimeLabel"));
    if (recipe->miscs.at(recipe->miscs_row).use_use == 3 || recipe->miscs.at(recipe->miscs_row).use_use == 4)	// Fermentation stages
        mtimeLabel->setText(tr("Time in days:"));
    else if (recipe->miscs.at(recipe->miscs_row).use_use == 2)  // Boil
        mtimeLabel->setText(tr("Time in minutes:"));
    else
        mtimeLabel->setText("");
    mtimeLabel->setGeometry(QRect(10, 100, 141, 20));
    mtimeLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

    QLabel *selectLabel = new QLabel(dialog);
    selectLabel->setObjectName(QString::fromUtf8("selectLabel"));
    selectLabel->setText(tr("Select ingredient:"));
    selectLabel->setGeometry(QRect(10, 40, 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, 40, 121, 20));
    instockLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

    mselectEdit = new QComboBox(dialog);
    mselectEdit->setObjectName(QString::fromUtf8("selectEdit"));
    mselectEdit->setGeometry(QRect(160, 40, 371, 23));

    mnameEdit = new QLineEdit(dialog);
    mnameEdit->setObjectName(QString::fromUtf8("mnameEdit"));
    mnameEdit->setText(recipe->miscs.at(recipe->miscs_row).name);
    mnameEdit->setGeometry(QRect(160, 10, 511, 23));
    mnameEdit->setReadOnly(true);

    mamountEdit = new QDoubleSpinBox(dialog);
    mamountEdit->setObjectName(QString::fromUtf8("mamountEdit"));
    mamountEdit->setGeometry(QRect(160, 70, 121, 24));
    mamountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    mamountEdit->setAccelerated(true);
    mamountEdit->setDecimals(2);
    mamountEdit->setMaximum(1000000.0);
    mamountEdit->setSingleStep(0.1);
    mamountEdit->setValue(recipe->miscs.at(recipe->miscs_row).amount * 1000.0);

    mtimeEdit = new QSpinBox(dialog);
    mtimeEdit->setObjectName(QString::fromUtf8("mtimeEdit"));
    mtimeEdit->setGeometry(QRect(160, 100, 121, 24));
    mtimeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
    mtimeEdit->setAccelerated(true);
    mtimeEdit->setMaximum(10000.0);
    if (recipe->miscs.at(recipe->miscs_row).use_use == 3 || recipe->miscs.at(recipe->miscs_row).use_use == 4) {	// Fermentation stages
	mtimeEdit->setValue(recipe->miscs.at(recipe->miscs_row).time / 1440);
        mtimeEdit->setReadOnly(false);
    } else if (recipe->miscs.at(recipe->miscs_row).use_use == 2) {	// Boil
	mtimeEdit->setValue(recipe->miscs.at(recipe->miscs_row).time);
        mtimeEdit->setReadOnly(false);
    } else {
	mtimeEdit->setReadOnly(true);
    }

    useatEdit = new QComboBox(dialog);
    useatEdit->setObjectName(QString::fromUtf8("useatEdit"));
    useatEdit->setGeometry(QRect(160, 130, 161, 23));
    useatEdit->addItem(tr("Starter"));
    useatEdit->addItem(tr("Mash"));
    useatEdit->addItem(tr("Boil"));
    useatEdit->addItem(tr("Primary"));
    useatEdit->addItem(tr("Secondary"));
    useatEdit->addItem(tr("Bottling"));
    useatEdit->addItem(tr("Sparge"));
    useatEdit->setCurrentIndex(recipe->miscs.at(recipe->miscs_row).use_use);

    minstockEdit = new QCheckBox(dialog);
    minstockEdit->setObjectName(QString::fromUtf8("minstockEdit"));
    minstockEdit->setGeometry(QRect(655, 40, 85, 21));
    minstockEdit->setChecked(true);

    misc_instock_changed(true);

    connect(mselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::misc_select_changed);
    connect(mamountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::misc_amount_changed);
    connect(mtimeEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &EditRecipe::misc_time_changed);
    connect(useatEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::misc_useat_changed);
    connect(minstockEdit, &QCheckBox::stateChanged, this, &EditRecipe::misc_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->miscs[recipe->miscs_row] = backup;
    } else {
        /* Clear time if misc is not used for boil or fermentation. */
        if (! (recipe->miscs.at(recipe->miscs_row).use_use == 2 ||
               recipe->miscs.at(recipe->miscs_row).use_use == 3 ||
               recipe->miscs.at(recipe->miscs_row).use_use == 4)) {
            if (recipe->miscs.at(recipe->miscs_row).time) {
                recipe->miscs[recipe->miscs_row].time = 0;
                is_changed();
            }
        }
    }

    disconnect(mselectEdit, nullptr, nullptr, nullptr);
    disconnect(mamountEdit, nullptr, nullptr, nullptr);
    disconnect(mtimeEdit, nullptr, nullptr, nullptr);
    disconnect(useatEdit, nullptr, nullptr, nullptr);
    disconnect(minstockEdit, nullptr, nullptr, nullptr);
    disconnect(buttonBox, nullptr, nullptr, nullptr);

    emit refreshAll();
}


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

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

    const QSignalBlocker blocker1(ui->bs_cacl2Edit);
    const QSignalBlocker blocker2(ui->bs_caso4Edit);
    const QSignalBlocker blocker3(ui->bs_mgso4Edit);
    const QSignalBlocker blocker4(ui->bs_naclEdit);
    const QSignalBlocker blocker5(ui->bs_mgcl2Edit);
    const QSignalBlocker blocker6(ui->bs_nahco3Edit);
    const QSignalBlocker blocker7(ui->bs_caco3Edit);
    const QSignalBlocker blocker9(ui->mw_acidvolEdit);
    const QSignalBlocker blocker10(ui->ss_cacl2Edit);
    const QSignalBlocker blocker11(ui->ss_caso4Edit);
    const QSignalBlocker blocker12(ui->ss_mgso4Edit);
    const QSignalBlocker blocker13(ui->ss_naclEdit);
    const QSignalBlocker blocker14(ui->ss_mgcl2Edit);

    for (int i = 0; i < recipe->miscs.size(); i++) {
	amount = recipe->miscs.at(i).amount * factor;
	recipe->miscs[i].amount = amount;

	/*
         * Update the water agents.
         */
        if (recipe->miscs.at(i).type == MISC_TYPES_WATER_AGENT && recipe->miscs.at(i).use_use == MISC_USES_MASH) {
            if (recipe->miscs.at(i).name == "CaCl2") {
                ui->bs_cacl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "CaSO4") {
                ui->bs_caso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "MgSO4") {
                ui->bs_mgso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "NaCl") {
                ui->bs_naclEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "MgCl2") {
                ui->bs_mgcl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "NaHCO3") {
                ui->bs_nahco3Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "CaCO3") {
                ui->bs_caco3Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Melkzuur" || recipe->miscs.at(i).name == "Lactic") {
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Zoutzuur" || recipe->miscs.at(i).name == "Hydrochloric") {
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Fosforzuur" || recipe->miscs.at(i).name == "Phosphoric") {
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Zwavelzuur" || recipe->miscs.at(i).name == "Sulfuric") {
                ui->mw_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            }
	} else if (recipe->miscs.at(i).type == MISC_TYPES_WATER_AGENT && recipe->miscs.at(i).use_use == MISC_USES_SPARGE) {
            if (recipe->miscs.at(i).name == "CaCl2") {
                ui->ss_cacl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "CaSO4") {
                ui->ss_caso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "MgSO4") {
                ui->ss_mgso4Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "NaCl") {
                ui->ss_naclEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "MgCl2") {
                ui->ss_mgcl2Edit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Melkzuur" || recipe->miscs.at(i).name == "Lactic") {
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Zoutzuur" || recipe->miscs.at(i).name == "Hydrochloric") {
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Fosforzuur" || recipe->miscs.at(i).name == "Phosphoric") {
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            } else if (recipe->miscs.at(i).name == "Zwavelzuur" || recipe->miscs.at(i).name == "Sulfuric") {
                ui->sp_acidvolEdit->setValue(recipe->miscs.at(i).amount * 1000.0);
            }
        }
    }
}

mercurial