src/EditProduct.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 397
877420a13815
child 409
9c78dd948aae
permissions
-rw-r--r--

Init est_carb field for new products.

/**
 * EditProduct.cpp is part of bmsapp.
 *
 * 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/>.
 */
#include "MainWindow.h"
#include "callout.h"
#include "EditProduct.h"
#include "PrinterDialog.h"
#include "ChartCarbonate.h"
#include "ChartFermenter.h"
#include "ChartiSpindel.h"
#include "../ui/ui_EditProduct.h"
#include "Utils.h"
#include "global.h"
#include "config.h"
#include "database/db_product.h"
#include "database/db_recipe.h"


EditProduct::EditProduct(int id, QWidget *parent) : QDialog(parent), ui(new Ui::EditProduct)
{
    QSqlQuery query, wquery, yquery;

    qDebug() << "EditProduct record:" << id;
    product = new Product;
    ui->setupUi(this);
    product->fermentables_row = product->hops_row = product->miscs_row = product->yeasts_row = product->mashs_row = -1;
    product->fermentables_use100 = false;
    this->recno = id;

    WindowTitle();

    ui->typeEdit->addItem(tr("Extract"));
    ui->typeEdit->addItem(tr("Partial Mash"));
    ui->typeEdit->addItem(tr("All Grain"));

    ui->color_methodEdit->addItem("Morey");
    ui->color_methodEdit->addItem("Mosher");
    ui->color_methodEdit->addItem("Daniels");
    ui->color_methodEdit->addItem("Halberstadt");
    ui->color_methodEdit->addItem("Naudts");

    for (int i = 0; i < 3; i++)
	ui->ibu_methodEdit->addItem(g_ibu_method[i]);

    for (int i = 0; i < my_acids.size(); i++) {
	ui->mw_acidPick->addItem(my_acids.at(i).name_en);
	ui->sp_acidtypeEdit->addItem(my_acids.at(i).name_en);
    }

    query.prepare("SELECT name FROM inventory_waters ORDER BY record");
    query.exec();
    ui->w1_nameEdit->addItem("");
    ui->w2_nameEdit->addItem("");
    while (query.next()) {
	ui->w1_nameEdit->addItem(query.value(0).toString());
	ui->w2_nameEdit->addItem(query.value(0).toString());
    }

    query.prepare("SELECT name FROM profile_water ORDER BY name");
    query.exec();
    ui->wt_sourceEdit->addItem("");
    while (query.next()) {
        ui->wt_sourceEdit->addItem(query.value(0).toString());
    }

    query.prepare("SELECT name FROM profile_mash ORDER BY name");
    query.exec();
    ui->mash_pickEdit->addItem("");
    while (query.next()) {
	ui->mash_pickEdit->addItem(query.value(0).toString());
    }

    ui->beerstyleEdit->addItem(product->st_name);	// First add a dummy, the current style
    query.prepare("SELECT style_guide,style_letter,name FROM profile_styles ORDER BY style_guide,style_letter,name");
    query.exec();
    while (query.next()) {
	ui->beerstyleEdit->addItem(query.value(0).toString()+" "+query.value(1).toString()+" "+query.value(2).toString());
    }

    for (int i = 0; i < 5; i++)
	ui->brew_coolwithEdit->addItem(QCoreApplication::translate("ChillerType", g_chiller_types[i]));

    ui->brew_aerwithEdit->addItem(tr("None"));
    ui->brew_aerwithEdit->addItem(tr("Air"));
    ui->brew_aerwithEdit->addItem(tr("Oxygen"));

    ui->bottle_sugarEdit->addItem("");
    ui->keg_sugarEdit->addItem("");
    query.prepare("SELECT name FROM inventory_fermentables WHERE type = '1' OR type = '3' ORDER BY name");	// Sugars or dry extract
    query.exec();
    while (query.next()) {
	ui->bottle_sugarEdit->addItem(query.value(0).toString());
	ui->keg_sugarEdit->addItem(query.value(0).toString());
    }

    ui->spargeGroup->setId(ui->w1_spButton, 0);
    ui->spargeGroup->setId(ui->w2_spButton, 1);
    ui->spargeGroup->setId(ui->wg_spButton, 2);

    if (id >= 0) {
	if (! DB_product::load(product, this, id))
	    return;
	qInfo() << "EditProduct" << product->code << "," << product->name;

	/*
	 * Check status of logfiles.
	 */
	if (product->stage > PROD_STAGE_BREW) {
	    if (! product->log_brew) {
		query.prepare("SELECT datetime FROM log_brews WHERE code=:code");
		query.bindValue(":code", product->code);
		query.exec();
		if (query.first()) {
		    qDebug() << "should update log_brews";
		}
	    }
	    if (! product->log_fermentation) {
		query.prepare("SELECT datetime FROM log_fermenter WHERE code=:code");
		query.bindValue(":code", product->code);
		query.exec();
		if (query.first()) {
		    qDebug() << "should update log_fermenter";
		}
	    }
	    if (! product->log_ispindel) {
		query.prepare("SELECT datetime FROM log_ispindel WHERE code=:code");
                query.bindValue(":code", product->code);
                query.exec();
                if (query.first()) {
                    qDebug() << "should update log_ispindel";
                }
	    }
	}
	if (product->stage > PROD_STAGE_PACKAGE) {
	    if (! product->log_co2pressure) {
		query.prepare("SELECT datetime FROM log_co2pressure WHERE code=:code");
                query.bindValue(":code", product->code);
                query.exec();
                if (query.first()) {
                    qDebug() << "should update log_co2pressure";
                }
	    }
	}

    } else {
	/* New product, set some defaults */
	qInfo() << "EditProduct, start new product";
	product->record = -1;
	product->locked = product->log_brew = product->log_fermentation = product->log_ispindel = product->log_co2pressure = false;
	product->st_name = "";
	product->st_letter = "";
	product->st_guide = "";
	product->st_category = "";
	product->st_category_number = 0;
	product->st_type = 0;
	product->st_og_min = 1.025; product->st_og_max = 1.100;
	product->st_fg_min = 1.000; product->st_fg_max = 1.020;
	product->st_ibu_min = 5; product->st_ibu_max = 200;
	product->st_color_min = 3; product->st_color_max = 100;
	product->st_carb_min = 1.0; product->st_carb_max = 4.5;
	product->st_abv_min = 1; product->st_abv_max = 15;
	product->eq_name = product->eq_notes = product->name = product->code = "";
	product->eq_tun_specific_heat = 0.11;
	product->eq_tun_material = 0;
	product->eq_tun_volume = product->eq_tun_height = 20;
	product->eq_tun_weight = 2;
	product->eq_top_up_water = 0;
	product->eq_trub_chiller_loss = 0.5;
	product->eq_evap_rate = 1.8;
	product->eq_calc_boil_volume = true;
	product->eq_top_up_kettle = 0;
	product->eq_hop_utilization = 100;
	product->eq_lauter_volume = product->eq_lauter_height = product->eq_kettle_volume = product->eq_kettle_height = product->eq_mash_volume = 20;
	product->eq_lauter_deadspace = 0.5;
	product->eq_mash_max = 6;
	product->eq_efficiency = 75;
	product->birth = QDate::currentDate();
	product->stage = product->inventory_reduced = PROD_STAGE_PLAN;
	product->notes = "";
	product->color_method = product->ibu_method = 0;
	product->efficiency = 75;
	product->eq_batch_size = product->batch_size = 20;
	product->eq_boil_time = product->boil_time = 60;
	product->eq_boil_size = product->boil_size = product->batch_size + (round(product->batch_size * product->boil_time / 60.0) / 10.0);
	product->type = 2;
	product->est_og = product->est_og3 = product->est_fg = product->est_color = product->est_ibu = product->est_abv = product->est_carb = 0;
	product->brew_date_start = product->brew_date_end = QDateTime();
	product->brew_mash_ph = product->brew_mash_sg = product->brew_mash_efficiency = 0;
	product->brew_sparge_temperature = product->brew_sparge_volume = product->brew_sparge_est = product->brew_sparge_ph = 0;
	product->brew_preboil_volume = product->brew_preboil_sg = product->brew_preboil_ph = product->brew_preboil_efficiency = 0;
	product->brew_aboil_volume = product->brew_aboil_sg = product->brew_aboil_ph = product->brew_aboil_efficiency = 0;
	product->brew_cooling_method = product->brew_cooling_time = 0;
	product->brew_cooling_to = 20;
	product->brew_whirlpool9 = product->brew_whirlpool7 = product->brew_whirlpool6 = product->brew_whirlpool2 = 0;
	product->brew_fermenter_volume = product->brew_fermenter_extrawater = product->brew_fermenter_tcloss = 0;
	product->brew_aeration_time = product->brew_aeration_speed = product->brew_aeration_type = 0;
	product->brew_fermenter_sg = product->brew_fermenter_ibu = product->brew_fermenter_color = 0;
	product->og = product->fg = 0;
	product->primary_start_temp = product->primary_max_temp = product->primary_end_temp = product->primary_end_sg = 0;
	product->primary_end_date = product->secondary_end_date = QDate();
	product->secondary_temp = product->secondary_end_sg = product->tertiary_temp = 0;
	product->package_date = QDate();
	product->package_volume = product->package_infuse_amount = product->package_infuse_abv = product->package_abv = product->package_ph = 0;
	product->package_infuse_notes = "";
	product->bottle_amount = product->bottle_carbonation = product->bottle_priming_amount = product->bottle_carbonation_temp = 0;
	product->keg_amount = product->keg_carbonation = product->keg_priming_amount = product->keg_carbonation_temp = 0;
	product->keg_pressure = 0;
	product->bottle_priming_water = product->keg_priming_water = 0;
	product->bottle_priming_sugar = product->keg_priming_sugar = 0;
	product->taste_rate = 0;
	product->taste_date = QDate();
	product->taste_notes = product->taste_color = product->taste_transparency = product->taste_head = "";
	product->taste_aroma = product->taste_taste = product->taste_mouthfeel = product->taste_aftertaste = "";
	product->sparge_temp = 80;
        product->sparge_ph = 5.4;
        product->sparge_volume = 8;
        product->sparge_source = 0;
        product->sparge_acid_type = 0;
        product->sparge_acid_perc = 80;
        product->sparge_acid_amount = 0;
        product->mash_ph = 5.4;
        product->mash_name = "";
        product->calc_acid = true;
	product->w1_name = "";
        product->w1_amount = 0;
        product->w1_calcium = 0;
        product->w1_sulfate = 0;
        product->w1_chloride = 0;
        product->w1_sodium = 0;
        product->w1_magnesium = 0;
        product->w1_total_alkalinity = 0;
        product->w1_ph = 7;
        product->w1_cost = 0;
        product->w2_name = "";
        product->w2_amount = 0;
        product->w2_calcium = 0;
        product->w2_sulfate = 0;
        product->w2_chloride = 0;
        product->w2_sodium = 0;
        product->w2_magnesium = 0;
        product->w2_total_alkalinity = 0;
        product->w2_ph = 7;
        product->w2_cost = 0;
        product->wg_amount = 0;
        product->wg_calcium = 0;
        product->wg_sulfate = 0;
        product->wg_chloride = 0;
        product->wg_sodium = 0;
        product->wg_magnesium = 0;
        product->wg_total_alkalinity = 0;
        product->wg_ph = 7;
        product->wb_calcium = 0;
        product->wb_sulfate = 0;
        product->wb_chloride = 0;
        product->wb_sodium = 0;
        product->wb_magnesium = 0;
        product->wb_total_alkalinity = 0;
        product->wb_ph = 7;
	product->wa_acid_name = 0;
	product->wa_acid_perc = 80;
	product->wa_base_name = 0;
	product->starter_enable = false;
	product->starter_type = product->prop_type[0] = product->prop_type[1] = product->prop_type[2] = product->prop_type[3] = 0;
	product->starter_viability = 100;
	product->starter_sg = 1.037;
	product->yeast_prod_date = QDate();
	product->yeast_pitchrate = product->prop_volume[0] = product->prop_volume[1] = product->prop_volume[2] = product->prop_volume[3] = 0;
	product->divide_type = product->divide_parts = product->divide_part = 0;
	product->divide_size = 0;
	product->divide_factor = 1;
    }

    // Tab generic.
    ui->lockedEdit->setChecked(product->locked);
    ui->st_nameEdit->setText(product->st_name);
    ui->st_groupEdit->setText(product->st_letter);
    ui->st_guideEdit->setText(product->st_guide);
    ui->st_catEdit->setText(product->st_category);
    ui->st_catnrEdit->setText(QString("%1").arg(product->st_category_number));
    ui->st_typeEdit->setText(QCoreApplication::translate("BeerType", g_style_types[product->st_type]));
    ui->nameEdit->setText(product->name);
    ui->codeEdit->setText(product->code);
    ui->birthEdit->setText(product->birth.toString("dd MMM yyyy"));
    ui->notesEdit->setPlainText(product->notes);
    ui->typeEdit->setCurrentIndex(product->type);
    ui->batch_sizeEdit->setValue(product->batch_size);
    ui->boil_sizeEdit->setValue(product->boil_size);
    ui->boil_timeEdit->setValue(product->boil_time);
    ui->efficiencyEdit->setValue(product->efficiency);
    if (product->divide_type > 0)
	ui->splitatEdit->setText(QString(tr("%1, part %2 of %3").arg(QCoreApplication::translate("Splitter", g_prod_split[product->divide_type]))
								.arg(product->divide_part + 1)
								.arg(product->divide_parts + 1)));
    else
        ui->splitatEdit->setText(QCoreApplication::translate("Splitter", g_prod_split[product->divide_type]));
    ui->est_ogEdit->setValue(product->est_og);
    ui->est_ogShow->setRange(product->st_og_min, product->st_og_max);
    ui->est_ogShow->setPrecision(3);
    ui->est_ogShow->setMarkerTextIsValue(true);
    ui->est_ogShow->setValue(product->est_og);
    ui->est_fgEdit->setValue(product->est_fg);
    ui->est_fgShow->setRange(product->st_fg_min, product->st_fg_max);
    ui->est_fgShow->setPrecision(3);
    ui->est_fgShow->setMarkerTextIsValue(true);
    ui->est_fgShow->setValue(product->est_fg);
    ui->est_abvEdit->setValue(product->est_abv);
    ui->est_abvShow->setRange(product->st_abv_min, product->st_abv_max);
    ui->est_abvShow->setPrecision(1);
    ui->est_abvShow->setMarkerTextIsValue(true);
    ui->est_abvShow->setValue(product->est_abv);
    ui->est_colorEdit->setValue(product->est_color);
    ui->est_colorEdit->setStyleSheet(Utils::ebc_to_style(product->est_color));
    ui->est_colorShow->setPrecision(0);
    ui->est_colorShow->setMarkerTextIsValue(true);
    ui->est_colorShow->setRange(product->st_color_min, product->st_color_max);
    ui->est_colorShow->setValue(product->est_color);
    ui->color_methodEdit->setCurrentIndex(product->color_method);
    ui->est_ibuEdit->setValue(product->est_ibu);
    ui->est_ibuShow->setPrecision(0);
    ui->est_ibuShow->setMarkerTextIsValue(true);
    ui->est_ibuShow->setRange(product->st_ibu_min, product->st_ibu_max);
    ui->est_ibuShow->setValue(product->est_ibu);
    ui->ibu_methodEdit->setCurrentIndex(product->ibu_method);
    ui->est_bottle_co2Edit->setValue(product->bottle_carbonation);
    ui->est_bottle_co2Show->setPrecision(1);
    ui->est_bottle_co2Show->setMarkerTextIsValue(true);
    ui->est_bottle_co2Show->setRange(product->st_carb_min, product->st_carb_max);
    ui->est_bottle_co2Show->setValue(product->bottle_carbonation);
    ui->est_kegs_co2Edit->setValue(product->keg_carbonation);
    ui->est_kegs_co2Show->setPrecision(1);
    ui->est_kegs_co2Show->setMarkerTextIsValue(true);
    ui->est_kegs_co2Show->setRange(product->st_carb_min, product->st_carb_max);
    ui->est_kegs_co2Show->setValue(product->keg_carbonation);
    calcStyle();
    ui->est_buguShow->setPrecision(2);
    ui->est_buguShow->setMarkerTextIsValue(true);
    ui->est_bufguShow->setPrecision(2);
    ui->est_bufguShow->setMarkerTextIsValue(true);

    // Tab equipment.
    initEquipment();

    // Tab fermentables.
    ui->est_og2Edit->setValue(product->est_og);
    ui->est_color2Edit->setValue(product->est_color);
    ui->est_color2Edit->setStyleSheet(Utils::ebc_to_style(product->est_color));

    // Tab hops.
    ui->est_ibu2Edit->setValue(product->est_ibu);

    // Tab yeasts.
    initYeast();

    // Tab mashs.
    ui->mash_nameEdit->setText(product->mash_name);

    // Tab waters.
    qDebug() << "water 1" << product->w1_name << "default" << my_default_water;
    if (product->w1_ph > 4.0) {
	/*
	 * Water data seems present, use that and set the name between []
	 */
	ui->w1_nameEdit->setPlaceholderText(QString("["+product->w1_name+"]"));
    } else {
	bool found = false;
	if (product->w1_name != "") {
	    /*
	     * We have a name, but do we know it?
	     */
	    query.prepare("SELECT * FROM inventory_waters WHERE name=:water");
            query.bindValue(":water", product->w1_name);
	    query.exec();
	    found = query.first();
	}
	if (!found) {
	    /*
	     * Try to load default water
	     */
	    query.prepare("SELECT * FROM inventory_waters WHERE record=:record");
	    query.bindValue(":record", my_default_water);
	    query.exec();
	    found = query.first();
	}
	if (found) {
	    product->w1_calcium = query.value(3).toDouble();
	    product->w1_magnesium = query.value(8).toDouble();
	    product->w1_total_alkalinity = query.value(11).toDouble();
	    product->w1_sodium = query.value(7).toDouble();
	    product->w1_chloride = query.value(6).toDouble();
	    product->w1_sulfate = query.value(5).toDouble();
	    product->w1_ph = query.value(9).toDouble();
            ui->w1_nameEdit->setCurrentIndex(query.value(0).toInt());
	} else {
	    product->w1_calcium = 0;
	    product->w1_magnesium = 0;
	    product->w1_total_alkalinity = 0;
	    product->w1_sodium = 0;
	    product->w1_chloride = 0;
	    product->w1_sulfate = 0;
	    product->w1_ph = 0;
	}
    }
    ui->w1_volEdit->setValue(product->w1_amount);
    ui->w1_caEdit->setValue(product->w1_calcium);
    ui->w1_mgEdit->setValue(product->w1_magnesium);
    ui->w1_hco3Edit->setValue(Utils::Bicarbonate(product->w1_total_alkalinity, product->w1_ph));
    ui->w1_caco3Edit->setValue(product->w1_total_alkalinity);
    ui->w1_naEdit->setValue(product->w1_sodium);
    ui->w1_clEdit->setValue(product->w1_chloride);
    ui->w1_so4Edit->setValue(product->w1_sulfate);
    ui->w1_phEdit->setValue(product->w1_ph);

    qDebug() << "water 2" << product->w2_name;
    if (product->w2_ph  > 4.0) {
	ui->w2_nameEdit->setPlaceholderText(QString("["+product->w2_name+"]"));
    } else if (product->w2_name != "") {
	query.prepare("SELECT * FROM inventory_waters WHERE name=:water");
	query.bindValue(":water", product->w2_name);
	query.exec();
	if (query.first()) {
	    product->w2_calcium = query.value(3).toDouble();
            product->w2_magnesium = query.value(8).toDouble();
            product->w2_total_alkalinity = query.value(11).toDouble();
            product->w2_sodium = query.value(7).toDouble();
            product->w2_chloride = query.value(6).toDouble();
            product->w2_sulfate = query.value(5).toDouble();
            product->w2_ph = query.value(9).toDouble();
	    ui->w2_nameEdit->setCurrentIndex(query.value(0).toInt());
	} else {
	    product->w2_calcium = 0;
            product->w2_magnesium = 0;
            product->w2_total_alkalinity = 0;
            product->w2_sodium = 0;
            product->w2_chloride = 0;
            product->w2_sulfate = 0;
            product->w2_ph = 0;
	}
    }
    ui->w2_volEdit->setValue(product->w2_amount);
    ui->w2_caEdit->setValue(product->w2_calcium);
    ui->w2_mgEdit->setValue(product->w2_magnesium);
    ui->w2_hco3Edit->setValue(Utils::Bicarbonate(product->w2_total_alkalinity, product->w2_ph));
    ui->w2_caco3Edit->setValue(product->w2_total_alkalinity);
    ui->w2_naEdit->setValue(product->w2_sodium);
    ui->w2_clEdit->setValue(product->w2_chloride);
    ui->w2_so4Edit->setValue(product->w2_sulfate);
    ui->w2_phEdit->setValue(product->w2_ph);
    ui->mw_autoEdit->setChecked(product->calc_acid);
    ui->mw_phEdit->setReadOnly(! product->calc_acid);
    ui->mw_phEdit->setButtonSymbols(product->calc_acid ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons);
    ui->mw_acidvolEdit->setReadOnly(product->calc_acid);
    ui->mw_acidvolEdit->setButtonSymbols(product->calc_acid ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows);
    ui->sp_phEdit->setReadOnly(! product->calc_acid);
    ui->sp_phEdit->setButtonSymbols(product->calc_acid ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons);
    ui->sp_acidvolEdit->setReadOnly(product->calc_acid);
    ui->sp_acidvolEdit->setButtonSymbols(product->calc_acid ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows);
    ui->sp_volEdit->setValue(product->sparge_volume);
    ui->sp_phEdit->setValue(product->sparge_ph);
    ui->sp_acidtypeEdit->setCurrentIndex(product->sparge_acid_type);
    ui->sp_acidpercEdit->setValue(product->sparge_acid_perc);
    check_waters();

    // Tab brewday.
    updateBrewday();
    ui->brew_mashphEdit->setValue(product->brew_mash_ph);
    ui->brew_mashphShow->setValue(product->mash_ph);
    ui->brew_mashsgEdit->setValue(product->brew_mash_sg);
    ui->brew_mashsgShow->setValue(0);
    ui->brew_masheffShow->setValue(product->brew_mash_efficiency);
    ui->brew_spargetempEdit->setValue(product->sparge_temp);
    ui->brew_spargevolShow->setValue(product->sparge_volume);
    ui->brew_spargeestShow->setValue(product->brew_sparge_est);
    ui->brew_spargephEdit->setValue(product->brew_sparge_ph);
    ui->brew_spargephShow->setValue(product->sparge_ph);

    ui->brew_preboilphEdit->setValue(product->brew_preboil_ph);
    ui->brew_preboilsgEdit->setValue(product->brew_preboil_sg);
    ui->brew_preboilvolEdit->setValue(product->brew_preboil_volume);
    ui->brew_preboilvolShow->setValue(product->boil_size * 1.04);
    ui->brew_preboileffShow->setValue(product->brew_preboil_efficiency);
    ui->brew_aboilphEdit->setValue(product->brew_aboil_ph);
    ui->brew_aboilsgEdit->setValue(product->brew_aboil_sg);
    ui->brew_aboilvolEdit->setValue(product->brew_aboil_volume);
    ui->brew_aboilvolShow->setValue(product->batch_size * 1.04);
    ui->brew_aboileffShow->setValue(product->brew_aboil_efficiency);
    ui->brew_whirlpool9Edit->setValue(product->brew_whirlpool9);
    ui->brew_whirlpool7Edit->setValue(product->brew_whirlpool7);
    ui->brew_whirlpool6Edit->setValue(product->brew_whirlpool6);
    ui->brew_whirlpool2Edit->setValue(product->brew_whirlpool2);
    ui->brew_cooltoEdit->setValue(product->brew_cooling_to);
    ui->brew_coolwithEdit->setCurrentIndex(product->brew_cooling_method);
    ui->brew_cooltimeEdit->setValue(product->brew_cooling_time);

    ui->brew_trublossEdit->setValue(product->brew_fermenter_tcloss);
    ui->brew_topupwaterEdit->setValue(product->brew_fermenter_extrawater);
    ui->brew_tofermentEdit->setValue(product->brew_fermenter_volume);
    ui->brew_fermentsgShow->setValue(product->brew_fermenter_sg);
    ui->brew_fermentcolorShow->setValue(product->brew_fermenter_color);
    ui->brew_fermentcolorShow->setStyleSheet(Utils::ebc_to_style(product->brew_fermenter_color));
    ui->brew_fermentibuShow->setValue(product->brew_fermenter_ibu);

    ui->brew_aerwithEdit->setCurrentIndex(product->brew_aeration_type);
    ui->brew_aertimeEdit->setValue(product->brew_aeration_time);
    ui->brew_aerspeedEdit->setValue(product->brew_aeration_speed);

    // Tab fermentation.
    ui->prim_ogShow->setValue(product->brew_fermenter_sg);
    ui->prim_startCEdit->setValue(product->primary_start_temp);
    ui->prim_maxCEdit->setValue(product->primary_max_temp);
    ui->prim_endCEdit->setValue(product->primary_end_temp);
    ui->prim_endsgEdit->setValue(product->primary_end_sg);
    ui->prim_enddateEdit->setDate(product->primary_end_date);
    ui->prim_attShow->setValue(Utils::calc_svg(product->brew_fermenter_sg, product->primary_end_sg));
    ui->sec_tempEdit->setValue(product->secondary_temp);
    ui->sec_sgEdit->setValue(product->secondary_end_sg);
    ui->sec_enddateEdit->setDate(product->secondary_end_date);
    ui->sec_attShow->setValue(Utils::calc_svg(product->brew_fermenter_sg, product->secondary_end_sg));
    ui->tert_tempEdit->setValue(product->tertiary_temp);
    ui->tert_estsgShow->setValue(product->est_fg);
    ui->tert_sgEdit->setValue(product->fg);
    ui->tert_attShow->setValue(Utils::calc_svg(product->brew_fermenter_sg, product->fg));
    ui->tert_abvShow->setValue(Utils::abvol(product->brew_fermenter_sg, product->fg));

    // Tab packaging.
    ui->pack_dateEdit->setDate(product->package_date);
    ui->pack_carbloShow->setValue(product->st_carb_min);
    ui->pack_carbhiShow->setValue(product->st_carb_max);
    ui->pack_volumeEdit->setValue(product->package_volume);
    ui->pack_volumeEdit->setMaximum(product->brew_fermenter_volume);
    ui->pack_addvolEdit->setValue(product->package_infuse_amount);
    ui->pack_addabvEdit->setValue(product->package_infuse_abv);
    ui->pack_notesEdit->setText(product->package_infuse_notes);
    ui->pack_abvShow->setValue(product->package_abv);
    ui->pack_phEdit->setValue(product->package_ph);

    ui->bottle_volumeEdit->setValue(product->bottle_amount);
    ui->bottle_carbEdit->setValue(product->bottle_carbonation);
    ui->bottle_sug_amountShow->setValue(product->bottle_priming_amount);
    ui->bottle_sug_waterEdit->setValue(product->bottle_priming_water);
    ui->bottle_tempEdit->setValue(product->bottle_carbonation_temp);

    ui->keg_volumeEdit->setValue(product->keg_amount);
    ui->keg_carbEdit->setValue(product->keg_carbonation);
    ui->keg_sug_amountShow->setValue(product->keg_priming_amount);
    ui->keg_sug_waterEdit->setValue(product->keg_priming_water);
    ui->keg_tempEdit->setValue(product->keg_carbonation_temp);
    ui->keg_forcedEdit->setChecked(product->keg_forced_carb);

    // Tab taste.
    ui->taste_dateEdit->setDate(product->taste_date);
    ui->taste_rateEdit->setValue(product->taste_rate);
    ui->taste_notesEdit->setPlainText(product->taste_notes);
    ui->taste_colorEdit->setText(product->taste_color);
    ui->taste_transparencyEdit->setText(product->taste_transparency);
    ui->taste_headEdit->setText(product->taste_head);
    ui->taste_aromaEdit->setText(product->taste_aroma);
    ui->taste_tasteEdit->setText(product->taste_taste);
    ui->taste_mouthfeelEdit->setText(product->taste_mouthfeel);
    ui->taste_aftertasteEdit->setText(product->taste_aftertaste);

    qDebug() << "== Start connecting ==";

    // All signals from tab "Generic"
    connect(ui->lockedEdit, &QCheckBox::stateChanged, this, &EditProduct::is_changed);
    connect(ui->codeEdit, &QLineEdit::textChanged, this, &EditProduct::code_changed);
    connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditProduct::name_changed);
    connect(ui->notesEdit, SIGNAL(textChanged()), this, SLOT(notes_changed()));
    connect(ui->typeEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::brew_type_changed);
    connect(ui->batch_sizeEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::batch_size_changed);
    connect(ui->boil_timeEdit, QOverload<int>::of(&QSpinBox::valueChanged), this, &EditProduct::boil_time_changed);
    connect(ui->efficiencyEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::efficiency_changed);
    connect(ui->beerstyleEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::style_changed);
    connect(ui->est_ogEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::est_og_changed);
    connect(ui->color_methodEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::colormethod_changed);
    connect(ui->ibu_methodEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::ibumethod_changed);
    connect(ui->lockedEdit, &QCheckBox::stateChanged, this, &EditProduct::locked_changed);

    // All signals from tab "Fermentables"
    ui->fermentablesTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->est_og2Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::est_og_changed);
    connect(ui->perc_mashShow, &QProgressBar::valueChanged, this, &EditProduct::ferment_perc_mash_valueChanged);
    connect(ui->perc_sugarsShow, &QProgressBar::valueChanged, this, &EditProduct::ferment_perc_sugars_valueChanged);
    connect(ui->perc_caraShow, &QProgressBar::valueChanged, this, &EditProduct::ferment_perc_cara_valueChanged);
    connect(ui->lintnerShow, &QProgressBar::valueChanged, this, &EditProduct::ferment_lintner_valueChanged);
    connect(ui->addFermentable, SIGNAL(clicked()), this, SLOT(addFermentRow_clicked()));

    // All signals from tab "Hops"
    ui->hopsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->hop_tasteShow, &QProgressBar::valueChanged, this, &EditProduct::hop_Flavour_valueChanged);
    connect(ui->hop_aromaShow, &QProgressBar::valueChanged, this, &EditProduct::hop_Aroma_valueChanged);
    connect(ui->addHop, SIGNAL(clicked()), this, SLOT(addHopRow_clicked()));

    // All signals from tab "Miscs"
    ui->miscsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->addMisc, SIGNAL(clicked()), this, SLOT(addMiscRow_clicked()));

    // All signals from tab "Yeasts"
    connect(ui->addYeast, SIGNAL(clicked()), this, SLOT(addYeastRow_clicked()));
    connect(ui->stmethodEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::yeast_method_changed);
    connect(ui->startersgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::yeast_starter_sg_changed);
    connect(ui->productionButton1, SIGNAL(clicked()), this, SLOT(yeast_prod_date_today()));
    connect(ui->productionButton2, SIGNAL(clicked()), this, SLOT(yeast_prod_date_clear()));
    connect(ui->productionEdit, &QDateEdit::dateChanged, this, &EditProduct::yeast_prod_date_changed);

    // All signals from tab "Mash"
    ui->mashsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->addMash, SIGNAL(clicked()), this, SLOT(addMashRow_clicked()));
    connect(ui->mash_pickEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::mash_select_changed);
    connect(ui->mash_nameEdit, &QLineEdit::textChanged, this, &EditProduct::mash_name_changed);

    // All signals from tab "Water"
    connect(ui->bs_cacl2Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_cacl2_changed);
    connect(ui->bs_caso4Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_caso4_changed);
    connect(ui->bs_mgso4Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_mgso4_changed);
    connect(ui->bs_naclEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_nacl_changed);
    connect(ui->bs_mgcl2Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_mgcl2_changed);
    connect(ui->bs_nahco3Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_nahco3_changed);
    connect(ui->bs_caco3Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::wb_caco3_changed);
    connect(ui->ss_cacl2Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_cacl2_changed);
    connect(ui->ss_caso4Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_caso4_changed);
    connect(ui->ss_mgso4Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_mgso4_changed);
    connect(ui->ss_naclEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_nacl_changed);
    connect(ui->ss_mgcl2Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_mgcl2_changed);
    connect(ui->mw_autoEdit, &QCheckBox::stateChanged, this, &EditProduct::mw_calc_acid_clicked);
    connect(ui->mw_phEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::mw_ph_changed);
    connect(ui->mw_acidvolEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::mw_acid_changed);
    connect(ui->mw_acidPick, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::mw_type_changed);
    connect(ui->wt_sourceEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::wt_target_changed);
    connect(ui->w1_nameEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::w1_name_changed);
    connect(ui->w2_nameEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::w2_name_changed);
    connect(ui->w2_volEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::w2_volume_changed);
    connect(ui->sp_volEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_volume_changed);
    connect(ui->spargeGroup, SIGNAL(buttonClicked(int)), this, SLOT(sp_group_changed(int)));
    connect(ui->sp_acidtypeEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::sp_type_changed);
    connect(ui->sp_phEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_ph_changed);
    connect(ui->sp_acidvolEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_acid_changed);

    /* All signals from tab Brewday */
    calcEfficiencyBeforeBoil();
    calcEfficiencyAfterBoil();
    connect(ui->brew_startButton1, SIGNAL(clicked()), this, SLOT(brew_date_today()));
    connect(ui->brew_startButton2, SIGNAL(clicked()), this, SLOT(brew_date_clear()));
    connect(ui->brew_startDate, &QDateEdit::dateChanged, this, &EditProduct::brew_start_date_changed);
    connect(ui->brew_startTime, &QTimeEdit::timeChanged, this, &EditProduct::brew_start_time_changed);
    connect(ui->brew_endDate, &QDateEdit::dateChanged, this, &EditProduct::brew_end_date_changed);
    connect(ui->brew_endTime, &QTimeEdit::timeChanged, this, &EditProduct::brew_end_time_changed);
    connect(ui->brew_endButton1, SIGNAL(clicked()), this, SLOT(brew_end_today()));
    connect(ui->brew_ackButton, SIGNAL(clicked()), this, SLOT(brew_date_ack()));
    connect(ui->brew_mashphEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_mashph_changed);
    connect(ui->brew_mashsgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_mashsg_changed);
    connect(ui->brew_spargephEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_spargeph_changed);
    connect(ui->brew_spargetempEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::sp_temp_changed);
    connect(ui->brew_preboilphEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_preboilph_changed);
    connect(ui->brew_preboilsgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_preboilsg_changed);
    connect(ui->brew_preboilvolEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_preboilvol_changed);
    connect(ui->brew_preboilButton, SIGNAL(clicked()), this, SLOT(brew_preboil_button()));
    connect(ui->brew_aboilphEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_aboilph_changed);
    connect(ui->brew_aboilsgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_aboilsg_changed);
    connect(ui->brew_aboilvolEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_aboilvol_changed);
    connect(ui->brew_aboilButton, SIGNAL(clicked()), this, SLOT(brew_aboil_button()));
    connect(ui->brew_coolwithEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::brew_cooling_method_changed);
    connect(ui->brew_cooltoEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_cooling_to_changed);
    connect(ui->brew_cooltimeEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_cooling_time_changed);
    connect(ui->brew_whirlpool9Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_whirlpool9_changed);
    connect(ui->brew_whirlpool7Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_whirlpool7_changed);
    connect(ui->brew_whirlpool6Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_whirlpool6_changed);
    connect(ui->brew_whirlpool2Edit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_whirlpool2_changed);
    connect(ui->brew_aerwithEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::brew_aerwith_changed);
    connect(ui->brew_aerspeedEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_aerspeed_changed);
    connect(ui->brew_aertimeEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_aertime_changed);
    connect(ui->brew_trublossEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_trubloss_changed);
    connect(ui->brew_topupwaterEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::brew_topupwater_changed);
    connect(ui->brew_logButton, SIGNAL(clicked()), this, SLOT(brew_log_button()));

    /* All signals from tab Fermentation */
    connect(ui->prim_startCEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::primary_start_changed);
    connect(ui->prim_maxCEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::primary_peak_changed);
    connect(ui->prim_endCEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::primary_end_changed);
    connect(ui->prim_endsgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::primary_sg_changed);
    connect(ui->prim_endsgButton, SIGNAL(clicked()), this, SLOT(primary_sg_button()));
    connect(ui->prim_enddateEdit, &QDateEdit::dateChanged, this, &EditProduct::primary_date_changed);
    connect(ui->prim_enddateButton, SIGNAL(clicked()), this, SLOT(primary_date_button()));
    connect(ui->prim_ackButton, SIGNAL(clicked()), this, SLOT(primary_date_ack()));
    connect(ui->sec_tempEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::secondary_temp_changed);
    connect(ui->sec_sgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::secondary_sg_changed);
    connect(ui->sec_sgButton, SIGNAL(clicked()), this, SLOT(secondary_sg_button()));
    connect(ui->sec_enddateEdit, &QDateEdit::dateChanged, this, &EditProduct::secondary_date_changed);
    connect(ui->sec_enddateButton, SIGNAL(clicked()), this, SLOT(secondary_date_button()));
    connect(ui->sec_ackButton, SIGNAL(clicked()), this, SLOT(secondary_date_ack()));
    connect(ui->tert_tempEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::tertiary_temp_changed);
    connect(ui->tert_sgEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::tertiary_sg_changed);
    connect(ui->tert_sgButton, SIGNAL(clicked()), this, SLOT(tertiary_sg_button()));
    connect(ui->ferm_log1Button, SIGNAL(clicked()), this, SLOT(ferm_log1_button()));
    connect(ui->ferm_log2Button, SIGNAL(clicked()), this, SLOT(ferm_log2_button()));

    /* All signals from tab Package */
    calcPack();
    connect(ui->pack_dateEdit, &QDateEdit::dateChanged, this, &EditProduct::pack_date_changed);
    connect(ui->pack_dateButton, SIGNAL(clicked()), this, SLOT(pack_date_button()));
    connect(ui->pack_ackButton, SIGNAL(clicked()), this, SLOT(pack_date_ack()));
    connect(ui->pack_volumeEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_volume_changed);
    connect(ui->pack_phEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_ph_changed);
    connect(ui->pack_addvolEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_infusion_vol_changed);
    connect(ui->pack_addabvEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_infusion_abv_changed);
    connect(ui->pack_notesEdit, &QLineEdit::textChanged, this, &EditProduct::pack_infusion_txt_changed);
    connect(ui->pack_abvShow, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::pack_abv_changed);
    connect(ui->bottle_volumeEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_volume_changed);
    connect(ui->bottle_carbEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_co2_changed);
    connect(ui->bottle_sugarEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::bottle_sugar_changed);
    connect(ui->bottle_sug_waterEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_water_changed);
    connect(ui->bottle_tempEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::bottle_temp_changed);
    connect(ui->keg_volumeEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::kegs_volume_changed);
    connect(ui->keg_carbEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::kegs_co2_changed);
    connect(ui->keg_sugarEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::kegs_sugar_changed);
    connect(ui->keg_sug_waterEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::kegs_water_changed);
    connect(ui->keg_tempEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::kegs_temp_changed);
    connect(ui->keg_forcedEdit, &QCheckBox::stateChanged, this, &EditProduct::kegs_forced_changed);
    connect(ui->carb_logButton, SIGNAL(clicked()), this, SLOT(carb_log_button()));

    /* All signals from tab Tasting */
    connect(ui->taste_dateEdit, &QDateEdit::dateChanged, this, &EditProduct::taste_date_changed);
    connect(ui->taste_dateButton, SIGNAL(clicked()), this, SLOT(taste_date_button()));
    connect(ui->taste_ackButton, SIGNAL(clicked()), this, SLOT(taste_date_ack()));
    connect(ui->taste_rateEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditProduct::taste_rate_changed);
    connect(ui->taste_colorEdit, &QLineEdit::textChanged, this, &EditProduct::taste_color_changed);
    connect(ui->taste_transparencyEdit, &QLineEdit::textChanged, this, &EditProduct::taste_transparency_changed);
    connect(ui->taste_headEdit, &QLineEdit::textChanged, this, &EditProduct::taste_head_changed);
    connect(ui->taste_aromaEdit, &QLineEdit::textChanged, this, &EditProduct::taste_aroma_changed);
    connect(ui->taste_tasteEdit, &QLineEdit::textChanged, this, &EditProduct::taste_taste_changed);
    connect(ui->taste_mouthfeelEdit, &QLineEdit::textChanged, this, &EditProduct::taste_mouthfeel_changed);
    connect(ui->taste_aftertasteEdit, &QLineEdit::textChanged, this, &EditProduct::taste_aftertaste_changed);
    connect(ui->taste_notesEdit, SIGNAL(textChanged()), this, SLOT(taste_notes_changed()));

    setStage();

    ui->saveButton->setEnabled(false);
    ui->deleteButton->setEnabled((id >= 0 && ! product->locked) ? true:false);

    emit refreshAll();
}


EditProduct::~EditProduct()
{
    qDebug() << "EditProduct done start";
    delete ui;
    emit entry_changed();
    qDebug() << "EditProduct done final";
}


void EditProduct::calcSupplies()
{
    if (product->inventory_reduced > PROD_STAGE_PACKAGE) {
	ui->ok_pmptLabel->setVisible(false);
	ui->ok_pmptIcon->setVisible(false);
	return;
    }

    qDebug() << "calcSupplies() f:" << product->fermentables_ok << "h:" << product->hops_ok << "m:" << product->miscs_ok << "y:" << product->yeasts_ok << "w:" << product->waters_ok;
    if (product->fermentables_ok && product->hops_ok && product->miscs_ok && product->yeasts_ok && product->waters_ok) {
	ui->ok_pmptIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/silk/tick.png")));
    } else {
	ui->ok_pmptIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/silk/cancel.png")));
    }
}


void EditProduct::refreshAll()
{
    refreshFermentables();
    calcFermentables();		/* Must be before Hops */
    refreshHops();
    calcIBUs();
    refreshMiscs();
    calcMiscs();
    refreshYeasts();
    calcYeast();
    calcMash();
    refreshMashs();
    refreshWaters();
    calcWater();
    calcSupplies();
}


/*
 * Window header, mark any change with '**'
 */
void EditProduct::WindowTitle()
{
    QString txt;

    if (this->recno < 0) {
	txt = QString(tr("BMSapp - Add new product"));
    } else {
	txt = QString(tr("BMSapp - Edit product %1").arg(this->recno));
    }

    if (this->textIsChanged) {
	txt.append((QString(" **")));
    }
    setWindowTitle(txt);
}


void EditProduct::on_saveButton_clicked()
{
    /*
     * If there are errors in the form, show a message and do "return;"
     */
    if (ui->nameEdit->text().length() < 2) {
	QMessageBox::warning(this, tr("Edit Product"), tr("Name empty or too short."));
	return;
    }
    if (ui->st_nameEdit->text().length() < 2) {
        QMessageBox::warning(this, tr("Edit Product"), tr("No beerstyle selected."));
        return;
    }

    if (this->textIsChanged) {
	product->record = this->recno;
	if (DB_product::save(product, this)) {
	    /*
	     * If this was a new record, update the global recno.
	     */
	    this->recno = product->record;
	}
	inventory_reduce();
    }

    ui->saveButton->setEnabled(false);
    this->textIsChanged = false;
    WindowTitle();
}


#include "EditProductTab1.cpp"
#include "EditProductTab2.cpp"
#include "EditProductTab3.cpp"
#include "EditProductTab4.cpp"
#include "EditProductTab5.cpp"
#include "EditProductTab6.cpp"
#include "EditProductTab7.cpp"
#include "EditProductTab8.cpp"
#include "EditProductTab9.cpp"
#include "EditProductTab10.cpp"
#include "EditProductTab11.cpp"
#include "EditProductTab12.cpp"
#include "EditProductExport.cpp"


void EditProduct::on_deleteButton_clicked()
{
    int rc = QMessageBox::warning(this, tr("Delete product"), tr("Delete %1").arg(product->name),
                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
    if (rc == QMessageBox::No)
        return;

    DB_product::dele(this, this->recno);

    this->close();
    this->setResult(1);
}


void EditProduct::is_changed()
{
    ui->saveButton->setEnabled(true);
    ui->deleteButton->setEnabled(((this->recno >= 0) ? true:false) && ! product->locked);
    this->textIsChanged = true;
    WindowTitle();
}


void EditProduct::on_quitButton_clicked()
{
    if (this->textIsChanged) {
	int rc = QMessageBox::warning(this, tr("Product changed"), tr("The product has been modified. Save changes?"),
                                QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save);
        switch (rc) {
            case QMessageBox::Save:
                        on_saveButton_clicked();
                        break;  /* Saved and then Quit */
            case QMessageBox::Discard:
                        break;  /* Quit without Save */
            case QMessageBox::Cancel:
                        return; /* Return to the editor page */
        }
    }

    this->close();
    this->setResult(1);
}

mercurial