src/EditProductTab5.cpp

Tue, 03 May 2022 20:05:04 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 03 May 2022 20:05:04 +0200
changeset 190
bb6c06910f0f
parent 179
512f492358e3
child 194
ea8cce5e7eb9
permissions
-rw-r--r--

Added calcSupplies() which shows if ingredients are in stock to brew the recipe. In tab 3, changed the fermentables numbers into more readable enum constants. Disable delete and edit buttons in fermentables rows for bottle and kegs sugars. Better mash time calculation in calcFermentables. Added check supplies. Added recalculate volumes. Update inventory when a fermentable is replaced. Added tooltips in brewing salts fields in the miscs table.

/**
 * EditProduct.cpp is part of bmsapp.
 *
 * tab 5, 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 EditProduct::misc_sort_test(const Miscs &D1, const Miscs &D2)
{
    if (D1.m_use_use > D2.m_use_use)
	return false;
    if (D1.m_use_use < D2.m_use_use)
	return true;
    if (D1.m_type > D2.m_type)
	return false;
    if (D1.m_type < D2.m_type)
	return true;
    return (D1.m_amount > D2.m_amount);
}


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

    qDebug() << "refreshMiscs" << product->miscs.size();
    std::sort(product->miscs.begin(), product->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 QStringList labels({tr("Ingredient"), tr("Type"), tr("Use at"), tr("Time"), tr("Amount"), tr("Stock"), tr("Delete"), tr("Edit") });

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

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

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

	item = new QTableWidgetItem(misc_types[product->miscs.at(i).m_type]);
        item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
        ui->miscsTable->setItem(i, 1, item);

	item = new QTableWidgetItem(misc_uses[product->miscs.at(i).m_use_use]);
        item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
        ui->miscsTable->setItem(i, 2, item);

	if (product->miscs.at(i).m_use_use == 2) {	// Boil
	    item = new QTableWidgetItem(QString("%1 min.").arg(product->miscs.at(i).m_time, 1, 'f', 0, '0'));
	} else if (product->miscs.at(i).m_use_use == 3 || product->miscs.at(i).m_use_use == 4) {	// Primary or secondary
	    item = new QTableWidgetItem(QString("%1 days.").arg(product->miscs.at(i).m_time / 1440, 1, 'f', 0, '0'));
	} else {
	    item = new QTableWidgetItem(QString(""));
	}
	item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
        ui->miscsTable->setItem(i, 3, item);

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

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

	/*
	 * Add the Delete and Edit row buttons.
	 * Not for water agents, these are set on the water tab.
	 */
	if (product->miscs.at(i).m_type == 4) {
	    item = new QTableWidgetItem("");
            item->setToolTip(tr("Edit this from the water tab"));
            ui->miscsTable->setItem(i, 6, item);
            item = new QTableWidgetItem("");
            item->setToolTip(tr("Edit this from the water tab"));
            ui->miscsTable->setItem(i, 7, item);
	} else {
            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, 6, 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, 7, pWidget);
	}

	/*
	 * Update the water agents.
	 */
	if (product->miscs.at(i).m_type == 4) {
	    if (product->miscs.at(i).m_name == "CaCl2") {
		ui->bs_cacl2Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "CaSO4") {
		ui->bs_caso4Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "MgSO4") {
		ui->bs_mgso4Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "NaCl") {
		ui->bs_naclEdit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "MgCl2") {
		ui->bs_mgcl2Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "NaHCO3") {
		ui->bs_nahco3Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "CaCO3") {
		ui->bs_caco3Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "Melkzuur" || product->miscs.at(i).m_name == "Lactic") {
		product->wa_acid_name = 0;
		product->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(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "Zoutzuur" || product->miscs.at(i).m_name == "Hydrochloric") {
                product->wa_acid_name = 1;
                product->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(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "Fosforzuur" || product->miscs.at(i).m_name == "Phosphoric") {
                product->wa_acid_name = 2;
                product->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(product->miscs.at(i).m_amount * 1000.0);
	    } else if (product->miscs.at(i).m_name == "Zwavelzuur" || product->miscs.at(i).m_name == "Sulfuric") {
                product->wa_acid_name = 3;
                product->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(product->miscs.at(i).m_amount * 1000.0);
	    }
	}
    }
}


/*
 * Manipulate the memory array and update the miscs table.
 */
void EditProduct::brewing_salt_sub(QString salt, double val)
{
    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 < product->miscs.size(); i++) {
	    if (salt.contains(product->miscs.at(i).m_name)) {
		qDebug() << "  brewing_salt_sub delete" << salt;
		product->miscs.removeAt(i);
		refreshMiscs();
		return;
	    }
	}
	qDebug() << "  brewing_salt_sub delete error";
	return;
    }

    /*
     * First see if this salt is in the table.
     * If it is, update the amount.
     */
    for (int i = 0; i < product->miscs.size(); i++) {
	if (salt.contains(product->miscs.at(i).m_name)) {
	    product->miscs[i].m_amount = val / 1000.0;
	    if (product->miscs.at(i).m_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.m_name = query.value(1).toString();
            m.m_amount = val / 1000.0;
            m.m_type = query.value(2).toInt();
            m.m_use_use = query.value(3).toInt();
            m.m_time = query.value(4).toDouble();
            m.m_amount_is_weight = query.value(5).toInt() ? true:false;
            m.m_cost = query.value(10).toDouble();
            product->miscs.append(m);
	    refreshMiscs();
	    return;
	}
    }

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


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


void EditProduct::addMiscRow_clicked()
{
    Miscs newm;

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

    newm.m_name = "Select one";
    newm.m_amount = 0;
    newm.m_type = 0;
    newm.m_use_use = 0;
    newm.m_time = 0;
    newm.m_amount_is_weight = true;
    newm.m_cost = 0;
    product->miscs.append(newm);
    is_changed();
    emit refreshAll();
}


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

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

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

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


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

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

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

    is_changed();
}


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

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

    if (product->miscs.at(product->miscs_row).m_use_use == 2) {       // Boil
	product->miscs[product->miscs_row].m_time = val;
	item = new QTableWidgetItem(QString("%1 min.").arg(val, 1, 'f', 0, '0'));
    } else if (product->miscs.at(product->miscs_row).m_use_use == 3 || product->miscs.at(product->miscs_row).m_use_use == 4) {  // Primary or secondary
	product->miscs[product->miscs_row].m_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(product->miscs_row, 3, item);

    is_changed();
}


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

    if (val < 1)
        return;

    qDebug() << "misc_select_changed()" << product->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
     */
    product->miscs[product->miscs_row].m_name = query.value(0).toString();
    product->miscs[product->miscs_row].m_type = query.value(1).toInt();
    product->miscs[product->miscs_row].m_use_use = query.value(2).toInt();
    product->miscs[product->miscs_row].m_time = query.value(3).toDouble();
    product->miscs[product->miscs_row].m_amount_is_weight = query.value(4).toInt() ? true:false;
    product->miscs[product->miscs_row].m_cost = query.value(5).toDouble();

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

    item = new QTableWidgetItem(misc_types[product->miscs.at(product->miscs_row).m_type]);
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->miscsTable->setItem(product->miscs_row, 1, item);

    item = new QTableWidgetItem(misc_uses[product->miscs.at(product->miscs_row).m_use_use]);
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->miscsTable->setItem(product->miscs_row, 2, item);
    useatEdit->setCurrentIndex(product->miscs.at(product->miscs_row).m_use_use);

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

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

    is_changed();
    emit refreshAll();
}


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

    qDebug() << "misc_instock_changed()" << product->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()+ " (" + 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 EditProduct::misc_useat_changed(int val)
{
    QTableWidgetItem *item;

    qDebug() << "misc_useat_changed" << val;
    product->miscs[product->miscs_row].m_use_use = val;
    item = new QTableWidgetItem(misc_uses[val]);
    item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
    ui->miscsTable->setItem(product->miscs_row, 2, item);

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

    is_changed();
}


void EditProduct::editMiscRow_clicked()
{
    QSqlQuery query;

    if (product->locked)
	return;

    QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender());
    product->miscs_row = pb->objectName().toInt();
    qDebug() << "Edit misc row" << product->miscs_row;
    Miscs backup = product->miscs.at(product->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 (product->miscs.at(product->miscs_row).m_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 (product->miscs.at(product->miscs_row).m_use_use == 3 || product->miscs.at(product->miscs_row).m_use_use == 4)	// Fermentation stages
        mtimeLabel->setText(tr("Time in days:"));
    else if (product->miscs.at(product->miscs_row).m_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(product->miscs.at(product->miscs_row).m_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(product->miscs.at(product->miscs_row).m_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 (product->miscs.at(product->miscs_row).m_use_use == 3 || product->miscs.at(product->miscs_row).m_use_use == 4) {	// Fermentation stages
	mtimeEdit->setValue(product->miscs.at(product->miscs_row).m_time / 1440);
        mtimeEdit->setReadOnly(false);
    } else if (product->miscs.at(product->miscs_row).m_use_use == 2) {	// Boil
	mtimeEdit->setValue(product->miscs.at(product->miscs_row).m_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->setCurrentIndex(product->miscs.at(product->miscs_row).m_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, &EditProduct::misc_select_changed);
    connect(mamountEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::misc_amount_changed);
    connect(mtimeEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &EditProduct::misc_time_changed);
    connect(useatEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::misc_useat_changed);
    connect(minstockEdit, &QCheckBox::stateChanged, this, &EditProduct::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";
        product->miscs[product->miscs_row] = backup;
    } else {
        /* Clear time if misc is not used for boil or fermentation. */
        if (! (product->miscs.at(product->miscs_row).m_use_use == 2 ||
               product->miscs.at(product->miscs_row).m_use_use == 3 ||
               product->miscs.at(product->miscs_row).m_use_use == 4)) {
            if (product->miscs.at(product->miscs_row).m_time) {
                product->miscs[product->miscs_row].m_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 EditProduct::adjustMiscs(double factor)
{
    double amount;

    if (product->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);

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

	/*
         * Update the water agents.
         */
        if (product->miscs.at(i).m_type == 4) {
            if (product->miscs.at(i).m_name == "CaCl2") {
                ui->bs_cacl2Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "CaSO4") {
                ui->bs_caso4Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "MgSO4") {
                ui->bs_mgso4Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "NaCl") {
                ui->bs_naclEdit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "MgCl2") {
                ui->bs_mgcl2Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "NaHCO3") {
                ui->bs_nahco3Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "CaCO3") {
                ui->bs_caco3Edit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "Melkzuur" || product->miscs.at(i).m_name == "Lactic") {
                ui->mw_acidvolEdit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "Zoutzuur" || product->miscs.at(i).m_name == "Hydrochloric") {
                ui->mw_acidvolEdit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "Fosforzuur" || product->miscs.at(i).m_name == "Phosphoric") {
                ui->mw_acidvolEdit->setValue(product->miscs.at(i).m_amount * 1000.0);
            } else if (product->miscs.at(i).m_name == "Zwavelzuur" || product->miscs.at(i).m_name == "Sulfuric") {
                ui->mw_acidvolEdit->setValue(product->miscs.at(i).m_amount * 1000.0);
            }
        }
    }
}

mercurial