Sat, 02 Apr 2022 23:01:13 +0200
Added change beerstyle, the fermentables table, and first part of calcFermentables to the recipe editor.
src/EditRecipe.cpp | file | annotate | diff | comparison | revisions | |
src/EditRecipe.h | file | annotate | diff | comparison | revisions | |
src/RangedSlider.cpp | file | annotate | diff | comparison | revisions | |
ui/EditRecipe.ui | file | annotate | diff | comparison | revisions |
--- a/src/EditRecipe.cpp Fri Apr 01 17:25:42 2022 +0200 +++ b/src/EditRecipe.cpp Sat Apr 02 23:01:13 2022 +0200 @@ -44,6 +44,15 @@ ui->ibu_methodEdit->addItem("Rager"); ui->ibu_methodEdit->addItem("Daniels"); + ui->beerstyleEdit->addItem(""); // First add a dummy + query.prepare("SELECT style_guide,style_letter,name FROM profile_styles ORDER BY style_guide,style_letter,name"); + query.exec(); + query.first(); + for (int i = 0; i < query.size(); i++) { + ui->beerstyleEdit->addItem(query.value(0).toString()+" "+query.value(1).toString()+" "+query.value(2).toString()); + query.next(); + } + if (id >= 0) { query.prepare("SELECT * FROM recipes WHERE record = :recno"); query.bindValue(":recno", id); @@ -56,7 +65,7 @@ ui->st_guideEdit->setText(query.value(5).toString()); ui->st_catEdit->setText(query.value(6).toString()); ui->st_catnrEdit->setText(query.value(7).toString()); - ui->st_typeEdit->setText(query.value(8).toString()); + ui->st_typeEdit->setText(s_types[query.value(8).toInt()]); ui->nameEdit->setText(query.value(21).toString()); ui->notesEdit->setPlainText(query.value(22).toString()); @@ -67,18 +76,22 @@ ui->efficiencyEdit->setValue(query.value(27).toDouble()); ui->est_ogEdit->setValue(query.value(28).toDouble()); + ui->est_og2Edit->setValue(query.value(28).toDouble()); + ui->est_og3Edit->setValue(query.value(28).toDouble()); ui->est_ogShow->setRange(query.value(9).toDouble(), query.value(10).toDouble()); ui->est_ogShow->setPrecision(3); ui->est_ogShow->setMarkerTextIsValue(true); ui->est_ogShow->setValue(query.value(28).toDouble()); ui->est_fgEdit->setValue(query.value(29).toDouble()); + ui->est_fg3Edit->setValue(query.value(29).toDouble()); ui->est_fgShow->setRange(query.value(11).toDouble(), query.value(12).toDouble()); ui->est_fgShow->setPrecision(3); ui->est_fgShow->setMarkerTextIsValue(true); ui->est_fgShow->setValue(query.value(29).toDouble()); ui->est_abvEdit->setValue(query.value(30).toDouble()); + ui->est_abv2Edit->setValue(query.value(30).toDouble()); ui->est_abvShow->setRange(query.value(19).toDouble(), query.value(20).toDouble()); ui->est_abvShow->setPrecision(1); ui->est_abvShow->setMarkerTextIsValue(true); @@ -87,6 +100,8 @@ QColor color = Utils::ebc_to_color(query.value(31).toInt()); ui->est_colorEdit->setValue(query.value(31).toDouble()); ui->est_colorEdit->setStyleSheet(Utils::ebc_to_style(query.value(31).toInt())); + ui->est_color2Edit->setValue(query.value(31).toDouble()); + ui->est_color2Edit->setStyleSheet(Utils::ebc_to_style(query.value(31).toInt())); ui->est_colorShow->setPrecision(0); ui->est_colorShow->setMarkerTextIsValue(true); ui->est_colorShow->setRange(query.value(15).toDouble(), query.value(16).toDouble()); @@ -95,6 +110,7 @@ ui->color_methodEdit->setCurrentIndex(query.value(32).toInt()); ui->est_ibuEdit->setValue(query.value(33).toDouble()); + ui->est_ibu2Edit->setValue(query.value(33).toDouble()); ui->est_ibuShow->setPrecision(0); ui->est_ibuShow->setMarkerTextIsValue(true); ui->est_ibuShow->setRange(query.value(13).toDouble(), query.value(14).toDouble()); @@ -156,30 +172,104 @@ // 81 wa_acid_name // 82 wa_acid_perc // 83 wa_base_name - // 84 json_fermentables + + /* + * Progress bars. + * perc_maltShow pmalts = mashkg / (dataRecord.boil_size / 3) * 100; + * perc_sugarsShow if (row.f_type == 1 && row.f_added < 4) // Sugar + * psugar += row.f_percentage; + * perc_caraShow if (row.f_graintype == 2 && row.f_added < 4) // Crystal + * pcara += row.f_percentage; + * lintner if (row.f_added == 0 && (row.f_type == 0 || row.f_type == 4) && row.f_color < 50) + * lintner += row.f_diastatic_power * row.f_amount; + * lintner = parseFloat(lintner / mashkg) + * + * perc_malts range(0, 120) + * stop: 90, color: '#008C00' + * stop: 100, color: '#EB7331' + * stop: 120, color: '#FF0000' + * + * perc_sugars range(0, 50) + * stop: 20, color: '#008C00' + * stop: 50, color: '#FF0000' + * perc_cara range(0, 50) + * stop: 25, color: '#008C00' + * stop: 50, color: '#FF0000' + * lintner range(0, 200) + * stop: 30, color: '#FF0000' red + * stop: 40, color: '#EB7331' orange + * stop: 200, color: '#008C00' green + */ + +// ui->lintnerShow->setValue(52); + if (ui->lintnerShow->value() < 30) + ui->lintnerShow->setStyleSheet(bar_red); + else if (ui->lintnerShow->value() < 40) + ui->lintnerShow->setStyleSheet(bar_orange); + else + ui->lintnerShow->setStyleSheet(bar_green); + + QJsonParseError parseError; + const auto& json = query.value(84).toString(); + if (!json.trimmed().isEmpty()) { + const auto& formattedJson = QString("%1").arg(json); + this->fermentables = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError); + if (parseError.error != QJsonParseError::NoError) + qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ; + } else { + qDebug() << "empty fermentables"; + } + // 85 json_hops // 86 json_miscs // 87 json_yeasts // 88 json_mashs } else { /* Set some defaults */ + + const auto& formattedJson = QString("[]"); + this->fermentables = QJsonDocument::fromJson(formattedJson.toUtf8()); + this->hops = QJsonDocument::fromJson(formattedJson.toUtf8()); + this->miscs = QJsonDocument::fromJson(formattedJson.toUtf8()); + this->yeasts = QJsonDocument::fromJson(formattedJson.toUtf8()); + this->mashs = QJsonDocument::fromJson(formattedJson.toUtf8()); } + // All signals from tab "Generic" connect(ui->lockedEdit, &QCheckBox::stateChanged, this, &EditRecipe::is_changed); - connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditRecipe::is_changed); connect(ui->notesEdit, SIGNAL(textChanged()), this, SLOT(is_changed())); connect(ui->typeEdit, &QComboBox::currentTextChanged, this, &EditRecipe::is_changed); connect(ui->batch_sizeEdit, &QDoubleSpinBox::textChanged, this, &EditRecipe::is_changed); connect(ui->boil_timeEdit, &QSpinBox::textChanged, this, &EditRecipe::is_changed); connect(ui->efficiencyEdit, &QDoubleSpinBox::textChanged, this, &EditRecipe::is_changed); - + connect(ui->beerstyleEdit, &QComboBox::currentTextChanged, this, &EditRecipe::style_changed); + connect(ui->est_ogEdit, &QDoubleSpinBox::textChanged, this, &EditRecipe::is_changed); connect(ui->color_methodEdit, &QComboBox::currentTextChanged, this, &EditRecipe::is_changed); + connect(ui->ibu_methodEdit, &QComboBox::currentTextChanged, this, &EditRecipe::is_changed); - connect(ui->ibu_methodEdit, &QComboBox::currentTextChanged, this, &EditRecipe::is_changed); + // All signals from tab "Fermentables" + connect(ui->est_og2Edit, &QDoubleSpinBox::textChanged, this, &EditRecipe::is_changed); +// connect(ui->fermentablesTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Changed(int, int))); + + // All signals from tab "Hops" +// connect(ui->hopsTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Changed(int, int))); + + // All signals from tab "Miscs" +// connect(ui->hopsTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Changed(int, int))); + + // All signals from tab "Yeasts" +// connect(ui->hopsTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Changed(int, int))); + + // All signals from tab "Mash" +// connect(ui->hopsTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Changed(int, int))); + + // All signals from tab "Water" ui->saveButton->setEnabled(false); ui->deleteButton->setEnabled((id >= 0) ? true:false); + + emit refreshAll(); } @@ -192,6 +282,230 @@ } +void EditRecipe::refreshFermentables() +{ + QString w; + QWidget* pWidget; + QHBoxLayout* pLayout; + QTableWidgetItem *item; + QLabel *label; + double d; + int j; + int total = 0; + + qDebug() << "refreshFermentables" << this->fermentables << this->fermentables.isArray() << this->fermentables.array().size(); + /* During filling the table turn off the cellChanged signal because every cell that is filled + * triggers the cellChanged signal. The QTableWidget has no better signal to use. */ + this->ignoreChanges = true; + + const QStringList labels({tr("Fermentable"), tr("EBC"), tr("Type"), tr("Graintype"), tr("When"), tr("Yield"), tr("Amount"), tr("Procent"), tr("100%"), tr("Button")}); + ui->fermentablesTable->setColumnCount(10); + ui->fermentablesTable->setColumnWidth(0, 350); /* Fermentable */ + ui->fermentablesTable->setColumnWidth(1, 50); /* Color */ + ui->fermentablesTable->setColumnWidth(2, 75); /* Type */ + ui->fermentablesTable->setColumnWidth(3, 75); /* Graintype */ + ui->fermentablesTable->setColumnWidth(4, 75); /* Added */ + ui->fermentablesTable->setColumnWidth(5, 75); /* Yield */ + ui->fermentablesTable->setColumnWidth(6, 75); /* Amount */ + ui->fermentablesTable->setColumnWidth(7, 60); /* Procent */ + ui->fermentablesTable->setColumnWidth(8, 50); /* 100% */ + ui->fermentablesTable->setColumnWidth(9, 80); /* Button */ + ui->fermentablesTable->setHorizontalHeaderLabels(labels); + ui->fermentablesTable->verticalHeader()->hide(); + ui->fermentablesTable->setRowCount(this->fermentables.array().size()); + + if (this->fermentables.isArray()) { + for (int i = 0; i < this->fermentables.array().size(); i++) { + QJsonObject obj = this->fermentables.array().at(i).toObject(); + + w = obj["f_supplier"].toString()+" / "+obj["f_name"].toString(); + ui->fermentablesTable->setItem(i, 0, new QTableWidgetItem(w)); + + if (obj["f_color"].isString()) + d = QString(obj["f_color"].toString()).toDouble(); + else + d = obj["f_color"].toDouble(); + w = QString("%1").arg(d, 1, 'f', 0, '0'); + item = new QTableWidgetItem(w); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 1, item); + + if (obj["f_type"].isString()) + j = QString(obj["f_type"].toString()).toInt(); + else + j = obj["f_type"].toInt(); + item = new QTableWidgetItem(f_types[j]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 2, item); + + if (obj["f_graintype"].isString()) + j = QString(obj["f_graintype"].toString()).toInt(); + else + j = obj["f_graintype"].toInt(); + item = new QTableWidgetItem(f_graintypes[j]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 3, item); + + if (obj["f_added"].isString()) + j = QString(obj["f_added"].toString()).toInt(); + else + j = obj["f_added"].toInt(); + item = new QTableWidgetItem(f_added[j]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 4, item); + + if (obj["f_yield"].isString()) + d = QString(obj["f_yield"].toString()).toDouble(); + else + d = obj["f_yield"].toDouble(); + w = QString("%1%").arg(d, 2, 'f', 1, '0'); + item = new QTableWidgetItem(w); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 5, item); + + if (obj["f_amount"].isString()) + d = QString(obj["f_amount"].toString()).toDouble(); + else + d = obj["f_amount"].toDouble(); + w = QString("%1 Kg").arg(d, 4, 'f', 3, '0'); + item = new QTableWidgetItem(w); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 6, item); + + if (obj["f_percentage"].isString()) + d = QString(obj["f_percentage"].toString()).toDouble(); + else + d = obj["f_percentage"].toDouble(); + w = QString("%1%").arg(d, 2, 'f', 1, '0'); + item = new QTableWidgetItem(w); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 7, item); + + if (obj["f_adjust_to_total_100"].toString().toInt()) { + pWidget = new QWidget(); + label = new QLabel; + label->setPixmap(QPixmap(":icons/silk/tick.png")); + pLayout = new QHBoxLayout(pWidget); + pLayout->addWidget(label); + pLayout->setAlignment(Qt::AlignCenter); + pLayout->setContentsMargins(0, 0, 0, 0); + pWidget->setLayout(pLayout); + ui->fermentablesTable->setCellWidget(i, 8, pWidget); + } else { + ui->fermentablesTable->removeCellWidget(i, 8); + } + + /* Add the Delete row button */ + pWidget = new QWidget(); + QPushButton* btn_edit = new QPushButton(); + btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */ + btn_edit->setText(tr("Delete")); + connect(btn_edit, SIGNAL(clicked()), this, SLOT(on_deleteFermentRow_clicked())); + pLayout = new QHBoxLayout(pWidget); + pLayout->addWidget(btn_edit); + pLayout->setContentsMargins(5, 0, 5, 0); + pWidget->setLayout(pLayout); + ui->fermentablesTable->setCellWidget(i, 9, pWidget); + } + } + + this->ignoreChanges = false; +} + + +void EditRecipe::refreshHops() +{ +} + + +void EditRecipe::refreshMiscs() +{ +} + + +void EditRecipe::refreshYeasts() +{ +} + + +void EditRecipe::refreshMashs() +{ +} + + +void EditRecipe::refreshAll() +{ + refreshFermentables(); + + calcFermentables(); +} + + +void EditRecipe::calcFermentables() +{ + int i; + bool my_100 = false; + double psugar = 0, pcara = 0, d, s = 0, x; + double vol = 0; // Volume sugars after boil + double addedS = 0; // Added sugars after boil + double addedmass = 0; // Added mass after boil + double mvol = 0; // Mash volume + double lintner = 0; // Total recipe lintner + double mashkg = 0; + double sugarsf = 0; // fermentable sugars mash + boil + double sugarsm = 0; // fermentable sugars in mash + double sugardensity = 1.611; // kg/l in solution + QJsonObject obj; + + qDebug() << "calcFermentables()"; + + // Get mashtemp and mashtime from the Mash schedule. + + if (this->fermentables.array().size() < 1) { + qDebug() << " no fermentables, return."; + return; + } + + for (i = 0; i < this->fermentables.array().size(); i++) { + obj = this->fermentables.array().at(i).toObject(); + if (obj["f_adjust_to_total_100"].toInt()) { + my_100 = true; + } + if (obj["f_type"].toInt() == 1 && obj["f_added"].toInt() < 4) // Sugars + psugar += obj["f_percentage"].toDouble(); + if (obj["f_graintype"].toInt() == 2 && obj["f_added"].toInt() < 4) // Crystal/Cara + pcara += obj["f_percentage"].toDouble(); + d = obj["f_amount"].toDouble() * (obj["f_yield"].toDouble() / 100) * (1 - obj["f_moisture"].toDouble() / 100); + if (obj["f_added"].toInt() == 0) { // Mash + if (mvol > 0) { // If mash volume is known + mvol += obj["f_amount"].toDouble() * obj["f_moisture"].toDouble() / 100; + s += d; + } + d = ui->efficiencyEdit->value() / 100 * d; + sugarsm += d; + mashkg += obj["f_amount"].toDouble(); + } + if (obj["f_added"].toInt() == 0 || obj["f_added"].toInt() == 1) // Mash or boil + sugarsf += d; + if (obj["f_added"].toInt() == 2 || obj["f_added"].toInt() == 3) { // Fermentation or lagering + x = (obj["f_yield"].toDouble() / 100) * (1 - obj["f_moisture"].toDouble() / 100); + addedS += obj["f_amount"].toDouble() * x; + addedmass += obj["f_amount"].toDouble(); + vol += (x * sugardensity + (1 - x) * 1) * obj["f_amount"].toDouble(); + } + if (obj["f_added"].toInt() == 0 && (obj["f_type"].toInt() == 0 || obj["f_type"].toInt() == 4) && obj["f_color"].toDouble() < 50) { + lintner += obj["f_diastatic_power"].toDouble() * obj["f_amount"].toDouble(); + } + if (obj["f_added"].toInt() < 4) { + // colors + } + } + + qDebug() << " lintner" << lintner << " mashkg" << mashkg << "final" << round(lintner / mashkg); + ui->lintnerShow->setValue(round(lintner / mashkg)); +} + + /* * Window header, mark any change with '**' */ @@ -288,12 +602,57 @@ } +/* + * New beerstyle is selected. + */ +void EditRecipe::style_changed() +{ + QSqlQuery query; + + if (ui->beerstyleEdit->currentIndex() < 1) + return; + + query.prepare("SELECT * FROM profile_styles ORDER BY style_guide,style_letter,name"); + query.exec(); + query.first(); + // Skip to the record index. + for (int i = 0; i < (ui->beerstyleEdit->currentIndex() - 1); i++) { + query.next(); + } + // Set relevant fields and update ranges. + ui->st_nameEdit->setText(query.value(1).toString()); + ui->st_catEdit->setText(query.value(2).toString()); + ui->st_catnrEdit->setText(query.value(3).toString()); + ui->st_groupEdit->setText(query.value(4).toString()); + ui->st_guideEdit->setText(query.value(5).toString()); + ui->st_typeEdit->setText(s_types[query.value(6).toInt()]); + ui->est_ogShow->setRange(query.value(7).toDouble(), query.value(8).toDouble()); + ui->est_fgShow->setRange(query.value(9).toDouble(), query.value(10).toDouble()); + ui->est_ibuShow->setRange(query.value(11).toDouble(), query.value(12).toDouble()); + ui->est_colorShow->setRange(query.value(13).toDouble(), query.value(14).toDouble()); + ui->est_carbShow->setRange(query.value(15).toDouble(), query.value(16).toDouble()); + ui->est_abvShow->setRange(query.value(17).toDouble(), query.value(18).toDouble()); + + is_changed(); +} + + void EditRecipe::time_changed() { is_changed(); } +void EditRecipe::on_deleteFermentRow_clicked() +{ + QPushButton *pb = qobject_cast<QPushButton *>(QObject::sender()); + int row = pb->objectName().toInt(); + qDebug() << "Delete row" << row; + ui->fermentablesTable->removeRow(row); +// make_Json(); +} + + void EditRecipe::on_quitButton_clicked() { if (this->textIsChanged) {
--- a/src/EditRecipe.h Fri Apr 01 17:25:42 2022 +0200 +++ b/src/EditRecipe.h Sat Apr 02 23:01:13 2022 +0200 @@ -2,7 +2,8 @@ #define _EDITRECIPE_H #include <QDialog> - +#include <QStringList> +#include <QJsonDocument> namespace Ui { class EditRecipe; @@ -24,14 +25,32 @@ void on_quitButton_clicked(); void on_deleteButton_clicked(); void is_changed(); + void style_changed(); void time_changed(); + void refreshFermentables(); + void refreshHops(); + void refreshMiscs(); + void refreshYeasts(); + void refreshMashs(); + void refreshAll(); + void on_deleteFermentRow_clicked(); 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") }; + QString bar_red = "QProgressBar::chunk {background: #FF0000;}"; + QString bar_orange = "QProgressBar::chunk {background: #EB7331;}"; + QString bar_green = "QProgressBar::chunk {background: #008C00;}"; int recno, lasttime = 0; bool textIsChanged = false; + bool ignoreChanges = false; + QJsonDocument fermentables, hops, miscs, yeasts, mashs; void WindowTitle(); + void calcFermentables(); }; #endif
--- a/src/RangedSlider.cpp Fri Apr 01 17:25:42 2022 +0200 +++ b/src/RangedSlider.cpp Sat Apr 02 23:01:13 2022 +0200 @@ -105,7 +105,6 @@ if (_markerTextIsValue) { _markerText = QString("%1").arg(value, 0, 'f', _prec); - qDebug() << _markerText; } update();
--- a/ui/EditRecipe.ui Fri Apr 01 17:25:42 2022 +0200 +++ b/ui/EditRecipe.ui Sat Apr 02 23:01:13 2022 +0200 @@ -84,7 +84,7 @@ <rect> <x>0</x> <y>0</y> - <width>1131</width> + <width>1128</width> <height>501</height> </rect> </property> @@ -95,7 +95,7 @@ <enum>QTabWidget::Rounded</enum> </property> <property name="currentIndex"> - <number>0</number> + <number>1</number> </property> <property name="elideMode"> <enum>Qt::ElideNone</enum> @@ -629,7 +629,7 @@ <rect> <x>510</x> <y>350</y> - <width>201</width> + <width>141</width> <height>23</height> </rect> </property> @@ -649,7 +649,7 @@ <rect> <x>510</x> <y>200</y> - <width>201</width> + <width>226</width> <height>23</height> </rect> </property> @@ -807,7 +807,7 @@ <rect> <x>510</x> <y>380</y> - <width>201</width> + <width>141</width> <height>23</height> </rect> </property> @@ -1013,6 +1013,22 @@ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> + <widget class="QLabel" name="beerstyleLabel"> + <property name="geometry"> + <rect> + <x>370</x> + <y>200</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Select style:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> </widget> <widget class="QWidget" name="fermentables"> <attribute name="icon"> @@ -1022,6 +1038,265 @@ <attribute name="title"> <string>Fermentables</string> </attribute> + <widget class="QLabel" name="est_color2Label"> + <property name="geometry"> + <rect> + <x>0</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Color EBC:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_color2Edit"> + <property name="geometry"> + <rect> + <x>140</x> + <y>10</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="minimum"> + <double>0.000000000000000</double> + </property> + <property name="maximum"> + <double>400.000000000000000</double> + </property> + <property name="singleStep"> + <double>1.000000000000000</double> + </property> + </widget> + <widget class="QLabel" name="est_og2Label"> + <property name="geometry"> + <rect> + <x>0</x> + <y>40</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Estimated OG:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_og2Edit"> + <property name="geometry"> + <rect> + <x>140</x> + <y>40</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="decimals"> + <number>3</number> + </property> + <property name="minimum"> + <double>0.980000000000000</double> + </property> + <property name="maximum"> + <double>2.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.001000000000000</double> + </property> + </widget> + <widget class="QLabel" name="perc_mashLabel"> + <property name="geometry"> + <rect> + <x>440</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Mash tun %:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QLabel" name="perc_sugarLabel"> + <property name="geometry"> + <rect> + <x>440</x> + <y>40</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Sugars %:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QLabel" name="perc_caraLabel"> + <property name="geometry"> + <rect> + <x>440</x> + <y>70</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Cara/crystal %:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QLabel" name="lintnerLabel"> + <property name="geometry"> + <rect> + <x>440</x> + <y>100</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Lintner:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QTableWidget" name="fermentablesTable"> + <property name="geometry"> + <rect> + <x>10</x> + <y>130</y> + <width>1101</width> + <height>331</height> + </rect> + </property> + </widget> + <widget class="QProgressBar" name="lintnerShow"> + <property name="geometry"> + <rect> + <x>580</x> + <y>100</y> + <width>381</width> + <height>20</height> + </rect> + </property> + <property name="maximum"> + <number>200</number> + </property> + <property name="value"> + <number>24</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="format"> + <string>%v lintner</string> + </property> + </widget> + <widget class="QProgressBar" name="perc_mashShow"> + <property name="geometry"> + <rect> + <x>580</x> + <y>10</y> + <width>381</width> + <height>20</height> + </rect> + </property> + <property name="maximum"> + <number>120</number> + </property> + <property name="value"> + <number>24</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="format"> + <string>%v%</string> + </property> + </widget> + <widget class="QProgressBar" name="perc_sugarsShow"> + <property name="geometry"> + <rect> + <x>580</x> + <y>40</y> + <width>381</width> + <height>20</height> + </rect> + </property> + <property name="maximum"> + <number>50</number> + </property> + <property name="value"> + <number>24</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="format"> + <string>%v%</string> + </property> + </widget> + <widget class="QProgressBar" name="perc_caraShow"> + <property name="geometry"> + <rect> + <x>580</x> + <y>70</y> + <width>381</width> + <height>20</height> + </rect> + </property> + <property name="maximum"> + <number>50</number> + </property> + <property name="value"> + <number>24</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="format"> + <string>%v%</string> + </property> + </widget> </widget> <widget class="QWidget" name="hops"> <attribute name="icon"> @@ -1031,6 +1306,142 @@ <attribute name="title"> <string>Hops</string> </attribute> + <widget class="QLabel" name="est_ibu2Label"> + <property name="geometry"> + <rect> + <x>0</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Bitterness IBU:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_ibu2Edit"> + <property name="geometry"> + <rect> + <x>140</x> + <y>10</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="minimum"> + <double>0.000000000000000</double> + </property> + <property name="maximum"> + <double>400.000000000000000</double> + </property> + <property name="singleStep"> + <double>1.000000000000000</double> + </property> + </widget> + <widget class="QLabel" name="hop_tasteLabel"> + <property name="geometry"> + <rect> + <x>220</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Hop taste:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QLabel" name="hop_aromaLabel"> + <property name="geometry"> + <rect> + <x>670</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Hop aroma:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QProgressBar" name="hop_tasteShow"> + <property name="geometry"> + <rect> + <x>360</x> + <y>10</y> + <width>301</width> + <height>20</height> + </rect> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>24</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="format"> + <string>%v%</string> + </property> + </widget> + <widget class="QProgressBar" name="hop_aromaShow"> + <property name="geometry"> + <rect> + <x>810</x> + <y>10</y> + <width>301</width> + <height>20</height> + </rect> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>24</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="format"> + <string>%v%</string> + </property> + </widget> + <widget class="QTableWidget" name="hopsTable"> + <property name="geometry"> + <rect> + <x>10</x> + <y>50</y> + <width>1101</width> + <height>411</height> + </rect> + </property> + </widget> </widget> <widget class="QWidget" name="miscs"> <attribute name="icon"> @@ -1040,6 +1451,16 @@ <attribute name="title"> <string>Miscs</string> </attribute> + <widget class="QTableWidget" name="miscsTable"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>1101</width> + <height>451</height> + </rect> + </property> + </widget> </widget> <widget class="QWidget" name="yeasts"> <attribute name="icon"> @@ -1049,6 +1470,216 @@ <attribute name="title"> <string>Yeasts</string> </attribute> + <widget class="QLabel" name="est_og3Label"> + <property name="geometry"> + <rect> + <x>50</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Estimated OG:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_og3Edit"> + <property name="geometry"> + <rect> + <x>190</x> + <y>10</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="decimals"> + <number>3</number> + </property> + <property name="minimum"> + <double>0.980000000000000</double> + </property> + <property name="maximum"> + <double>2.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.001000000000000</double> + </property> + </widget> + <widget class="QLabel" name="est_fg3Label"> + <property name="geometry"> + <rect> + <x>50</x> + <y>40</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Estimated FG:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_fg3Edit"> + <property name="geometry"> + <rect> + <x>190</x> + <y>40</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="decimals"> + <number>3</number> + </property> + <property name="minimum"> + <double>0.980000000000000</double> + </property> + <property name="maximum"> + <double>2.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.001000000000000</double> + </property> + </widget> + <widget class="QLabel" name="est_abv2Label"> + <property name="geometry"> + <rect> + <x>570</x> + <y>10</y> + <width>131</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Alcohol Volume:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_abv2Edit"> + <property name="geometry"> + <rect> + <x>710</x> + <y>10</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="decimals"> + <number>1</number> + </property> + <property name="minimum"> + <double>0.000000000000000</double> + </property> + <property name="maximum"> + <double>80.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.100000000000000</double> + </property> + </widget> + <widget class="QLabel" name="est_svgLabel"> + <property name="geometry"> + <rect> + <x>550</x> + <y>40</y> + <width>151</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Appearant Attenuation:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + <widget class="QDoubleSpinBox" name="est_svgEdit"> + <property name="geometry"> + <rect> + <x>710</x> + <y>40</y> + <width>71</width> + <height>24</height> + </rect> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="decimals"> + <number>1</number> + </property> + <property name="minimum"> + <double>0.000000000000000</double> + </property> + <property name="maximum"> + <double>80.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.100000000000000</double> + </property> + </widget> + <widget class="QTableWidget" name="yeastsTable"> + <property name="geometry"> + <rect> + <x>10</x> + <y>90</y> + <width>1101</width> + <height>371</height> + </rect> + </property> + </widget> </widget> <widget class="QWidget" name="mash"> <attribute name="icon"> @@ -1058,6 +1689,16 @@ <attribute name="title"> <string>Mash</string> </attribute> + <widget class="QTableWidget" name="mashsTable"> + <property name="geometry"> + <rect> + <x>10</x> + <y>70</y> + <width>1101</width> + <height>391</height> + </rect> + </property> + </widget> </widget> <widget class="QWidget" name="water"> <attribute name="icon">