src/EditRecipe.h

Fri, 22 Apr 2022 13:46:59 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 22 Apr 2022 13:46:59 +0200
changeset 152
58e4ce7dd217
parent 150
fd568cc1dd0e
child 154
1af9f7b7f317
permissions
-rw-r--r--

Fixed vanishing mash profiles from some recipes. All ingnoreChanges flags removed and replaced by blocking signals. Update prompts and yeast amounts depending on the yeast form. Save water profile names fixed.

#ifndef _EDITRECIPE_H
#define _EDITRECIPE_H

#include <QDialog>
#include <QStringList>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDoubleSpinBox>
#include <QCheckBox>
#include <QComboBox>
#include <QLineEdit>
#include <QDialogButtonBox>
#include <QList>
#include <QLabel>


/*
 * Fermentables, Hops, Miscs, Yeasts and Mashs are stored in the 
 * database in json arrays. These are the QList structures.
 */
struct Fermentables
{
    QString	f_name;
    QString	f_origin;
    QString	f_supplier;
    double	f_amount;
    double	f_cost;
    int		f_type;
    double	f_yield;
    double	f_color;
    double	f_coarse_fine_diff;
    double	f_moisture;
    double	f_diastatic_power;
    double	f_protein;
    double	f_dissolved_protein;
    double	f_max_in_batch;
    int		f_graintype;
    int		f_added;
    bool	f_recommend_mash;
    bool	f_add_after_boil;
    bool	f_adjust_to_total_100;
    double	f_percentage;
    double	f_di_ph;
    double	f_acid_to_ph_57;
};


struct Hops
{
    QString	h_name;
    QString	h_origin;
    double	h_amount;
    double	h_cost;
    int		h_type;
    int		h_form;
    int		h_useat;
    double	h_time;
    double	h_alpha;
    double	h_beta;
    double	h_hsi;
    double	h_humulene;
    double	h_caryophyllene;
    double	h_cohumulone;
    double	h_myrcene;
    double	h_total_oil;
};


struct Miscs
{
    QString	m_name;
    double	m_amount;
    int		m_type;
    int		m_use_use;
    double	m_time;
    bool	m_amount_is_weight;
    double	m_cost;
};


struct Yeasts
{
    QString	y_name;
    QString	y_laboratory;
    QString	y_product_id;
    double	y_amount;
    int		y_type;
    int		y_form;
    double	y_min_temperature;
    double	y_max_temperature;
    int		y_flocculation;
    double	y_attenuation;
    double	y_cells;
    double	y_tolerance;
    double	y_inventory;
    int		y_use;
    bool	y_sta1;
    bool	y_bacteria;
    bool	y_harvest_top;
    int		y_harvest_time;
    double	y_pitch_temperature;
    bool	y_pofpos;
    int		y_zymocide;
    int		y_gr_hl_lo;
    double	y_sg_lo;
    int		y_gr_hl_hi;
    double	y_sg_hi;
    double	y_cost;
};


struct Mashs
{
    QString	step_name;
    int		step_type;
    double	step_volume;		///< The water volume upto this step.
    double	step_infuse_amount;	///< Infuse/decoction volume this step.
    double	step_infuse_temp;	///< Infuse/decoction temperature.
    double	step_temp;		///< Start tmperature this step.
    double	step_time;		///< Step rest time.
    double	ramp_time;		///< Estimated ramp time to this step.
    double	end_temp;		///< End temperature this step.
    double	step_wg_ratio;		///< Current water/grain ratio.
};


/*
 * The main recipe record stored in the database.
 */
struct Recipe
{
    int		record;
    QString	uuid;
    bool	locked;
    QString	st_name;
    QString	st_letter;
    QString	st_guide;
    QString	st_category;
    int		st_category_number;
    int		st_type;
    double	st_og_min;
    double	st_og_max;
    double	st_fg_min;
    double	st_fg_max;
    double	st_ibu_min;
    double	st_ibu_max;
    double	st_color_min;
    double	st_color_max;
    double	st_carb_min;
    double	st_carb_max;
    double	st_abv_min;
    double	st_abv_max;

    QString	name;
    QString	notes;
    int		type;
    double	batch_size;
    double	boil_size;
    double	boil_time;
    double	efficiency;
    double	est_og;
    double	est_fg;
    double	est_abv;
    double	est_color;
    int		color_method;
    double	est_ibu;
    int		ibu_method;
    double	est_carb;

    double	sparge_temp;
    double	sparge_ph;
    double	sparge_volume;
    int		sparge_source;
    int		sparge_acid_type;
    double	sparge_acid_perc;
    double	sparge_acid_amount;
    double	mash_ph;
    QString	mash_name;
    bool	calc_acid;

    QString	w1_name;			///< Water source 1
    double	w1_amount;
    double	w1_calcium;
    double	w1_sulfate;
    double	w1_chloride;
    double	w1_sodium;
    double	w1_magnesium;
    double	w1_total_alkalinity;
    double	w1_ph;
    double	w1_cost;
    QString     w2_name;			///< Water source 2
    double      w2_amount;
    double      w2_calcium;
    double      w2_sulfate;
    double      w2_chloride;
    double      w2_sodium;
    double      w2_magnesium;
    double      w2_total_alkalinity;
    double      w2_ph;
    double      w2_cost;
    double      wg_amount;			///< Mixed water
    double      wg_calcium;
    double      wg_sulfate;
    double      wg_chloride;
    double      wg_sodium;
    double      wg_magnesium;
    double      wg_total_alkalinity;
    double      wg_ph;
    double      wb_calcium;			///< Treated water
    double      wb_sulfate;
    double      wb_chloride;
    double      wb_sodium;
    double      wb_magnesium;
    double      wb_total_alkalinity;
    double      wb_ph;
    int		wa_acid_name;
    double	wa_acid_perc;
    int		wa_base_name;

    QList<Fermentables>	fermentables;
    QList<Hops>		hops;
    QList<Miscs>	miscs;
    QList<Yeasts>	yeasts;
    QList<Mashs>	mashs;

    /*
     * These are not in the MySL database, but are global variables
     * that belong with the loaded recipe data and are present to
     * make things easier.
     */
    int		fermentables_row;	///< Current row, -1 is invalid.
    bool	fermentables_use100;	///< Use percentages instead of amount
    int		hops_row;
    int		miscs_row;
    int		yeasts_row;
    int		mashs_row;
    double	mashs_kg;		///< Kg fermentables in the mash.
    int		mashs_time;		///< Total mash time.
    double	preboil_sg;
};


namespace Ui {
class EditRecipe;
}

class EditRecipe : public QDialog
{
    Q_OBJECT

signals:
    void entry_changed();

public:
    explicit EditRecipe(int id, QWidget *parent = 0);
    ~EditRecipe();

private slots:
    void on_saveButton_clicked();
    void on_quitButton_clicked();
    void on_deleteButton_clicked();
    void is_changed();
    void name_changed(QString);
    void notes_changed();
    void style_changed(int val);
    void colormethod_changed(int val);
    void ibumethod_changed(int val);
    void est_og_changed(double val);
    void efficiency_changed(double val);
    void boil_time_changed(int val);
    void batch_size_changed(double val);
    void brew_type_changed(int val);
    void refreshFermentables();
    void refreshHops();
    void refreshMiscs();
    void refreshYeasts();
    void refreshMashs();
    void refreshWaters();
    void refreshAll();
    void ferment_amount_changed(double val);
    void ferment_pct_changed(double val);
    void ferment_to100_changed(bool val);
    void ferment_select_changed(int val);
    void ferment_instock_changed(bool val);
    void ferment_added_changed(int val);
    void hop_amount_changed(double val);
    void hop_time_changed(int val);
    void hop_select_changed(int val);
    void hop_instock_changed(bool val);
    void hop_useat_changed(int val);
    void misc_amount_changed(double val);
    void misc_time_changed(int val);
    void misc_select_changed(int val);
    void misc_instock_changed(bool val);
    void misc_useat_changed(int val);
    void yeast_amount_changed(double val);
    void yeast_select_changed(int val);
    void yeast_instock_changed(bool val);
    void yeast_useat_changed(int val);
    void addFermentRow_clicked();
    void deleteFermentRow_clicked();
    void editFermentRow_clicked();
    void addHopRow_clicked();
    void deleteHopRow_clicked();
    void editHopRow_clicked();
    void addMiscRow_clicked();
    void deleteMiscRow_clicked();
    void editMiscRow_clicked();
    void addYeastRow_clicked();
    void deleteYeastRow_clicked();
    void editYeastRow_clicked();
    void addMashRow_clicked();
    void deleteMashRow_clicked();
    void editMashRow_clicked();
    void upMashRow_clicked();
    void downMashRow_clicked();

    void w1_name_changed(int val);
    void w2_name_changed(int val);
    void w2_volume_changed(double val);
    void wb_cacl2_changed(double val);
    void wb_caso4_changed(double val);
    void wb_mgso4_changed(double val);
    void wb_nacl_changed(double val);
    void wb_mgcl2_changed(double val);
    void wb_nahco3_changed(double val);
    void wb_caco3_changed(double val);
    void mw_calc_acid_clicked();
    void wt_target_changed(int val);
    void mw_ph_changed(double val);
    void mw_acid_changed(double val);
    void mw_type_changed(int val);
    void step_name_changed(QString val);
    void step_type_changed(int val);
    void step_temp_changed(double val);
    void end_temp_changed(double val);
    void step_time_changed(double val);
    void ramp_time_changed(double val);
    void infuse_changed(double val);
    void mash_select_changed(int val);

    /* Modified progress bars */
    void ferment_perc_mash_valueChanged(int value);
    void ferment_perc_sugars_valueChanged(int value);
    void ferment_perc_cara_valueChanged(int value);
    void ferment_lintner_valueChanged(int value);
    void hop_Flavour_valueChanged(int value);
    void hop_Aroma_valueChanged(int value);

private:
    Ui::EditRecipe *ui;
    QStringList s_types = { tr("Lager"), tr("Ale"), tr("Mead"), tr("Wheat"), tr("Mixed"), tr("Cider") };
    QStringList f_types = { tr("Grain"), tr("Sugar"), tr("Extract"), tr("Dry extract"), tr("Adjunct") };
    QStringList f_graintypes = { tr("Base"), tr("Roast"), tr("Crystal"), tr("Kilned"), tr("Sour Malt"), tr("Special"), tr("No malt")};
    QStringList f_added = { tr("Mash"), tr("Boil"), tr("Fermentation"), tr("Lagering"), tr("Bottle"), tr("Kegs") };
    QStringList h_types = { tr("Bittering"), tr("Aroma"), tr("Both") };
    QStringList h_forms = { tr("Pellet"), tr("Plug"), tr("Leaf"), tr("Leaf wet"), tr("Cryo") };
    QStringList h_useat = { tr("Mash"), tr("First wort"), tr("Boil"), tr("Aroma"), tr("Whirlpool"), tr("Dry hop") };
    QStringList m_types = { tr("Spice"), tr("Herb"), tr("Flavor"), tr("Fining"), tr("Water agent"), tr("Yeast nutrient"), tr("Other") };
    QStringList m_uses = { tr("Starter"), tr("Mash"), tr("Boil"), tr("Primary"), tr("Secondary"), tr("Bottling") };
    //QStringList y_types = { tr("Lager"), tr("Ale"), tr("Wheat"), tr("Wine"), tr("Champagne"), tr("Brett"), tr("Kveik"), tr("Hybrid") };
    QStringList y_forms = { tr("Liquid"), tr("Dry"), tr("Slant"), tr("Culture"), tr("Frozen"), tr("Bottle"), tr("Dried") };
    QStringList y_use = { tr("Primary"), tr("Secondary"), tr("Tertiary"), tr("Bottle") };
    QStringList starters = { tr("Stirred"), tr("Shaken"), tr("Simple") };
    QStringList step_types = { tr("Infusion"), tr("Temperature"), tr("Decoction") };
    QString bar_red = "QProgressBar::chunk {background: #FF0000;}";
    QString bar_orange = "QProgressBar::chunk {background: #EB7331;}";
    QString bar_green = "QProgressBar::chunk {background: #008C00;}";
    QString bar_20 = "QProgressBar::chunk {background: #004D00;}";
    QString bar_40 = "QProgressBar::chunk {background: #008C00;}";
    QString bar_60 = "QProgressBar::chunk {background: #00BF00;}";
    QString bar_80 = "QProgressBar::chunk {background: #00FF00;}";
    QString bar_100 = "QProgressBar::chunk {background: #80FF80;}";
    int recno;
    bool textIsChanged = false;
    Recipe *recipe;
    /*
     * Variables for popup ingredients editing.
     */
    QComboBox *fselectEdit, *faddedEdit, *hselectEdit,*haddedEdit, *useatEdit, *mselectEdit, *yselectEdit;
    QLineEdit *fnameEdit, *fsupplierEdit, *hnameEdit, *horiginEdit, *mnameEdit, *ynameEdit, *ylaboratoryEdit, *yproduct_idEdit, *stepnameEdit;
    QDoubleSpinBox *famountEdit, *pctEdit, *fmaxEdit, *hamountEdit, *ibuEdit, *mamountEdit, *yamountEdit;
    QDoubleSpinBox *steptempEdit, *endtempEdit, *steptimeEdit, *ramptimeEdit, *stepivolEdit, *stepitmpEdit;
    QSpinBox *htimeEdit, *mtimeEdit;
    QCheckBox *to100Edit, *finstockEdit, *hinstockEdit, *minstockEdit, *yinstockEdit;
    QLabel *htimeLabel, *mtimeLabel, *mamountLabel, *yamountLabel, *ivolLabel, *itmpLabel;

    void to100Fermentables(int row);
    static bool ferment_sort_test(const Fermentables &D1, const Fermentables &D2);
    static bool hop_sort_test(const Hops &D1, const Hops &D2);
    static bool misc_sort_test(const Miscs &D1, const Miscs &D2);
    static bool yeast_sort_test(const Yeasts &D1, const Yeasts &D2);
    void WindowTitle();
    void brewing_salt_sub(QString salt, double val);
    void set_brewing_salt(QString salt, double val);
    void calcFermentables();
    void calcFermentablesFromOG(double og);
    void calcIBUs();
    void adjustHops(double factor);
    void adjustMiscs(double factor);
    double ZAlkalinity(double pHZ);
    double ZRA(double pHZ);
    double BufferCapacity(Fermentables F);
    double AcidRequired(double ZpH, Fermentables F);
    double ProtonDeficit(double pHZ);
    double MashpH();
    void calcWater();
    double GetBUGU();
    double GetOptSO4Clratio();
    void calcYeast();
    void adjustYeasts(double factor);
    double infusionVol(double step_infused, double step_mashkg, double infuse_temp, double step_temp, double last_temp);
    double decoctionVol(double step_volume, double step_temp, double prev_temp);
    void calcMash();
    void adjustWaters(double factor);
};

#endif

mercurial