# HG changeset patch # User Michiel Broek # Date 1649269607 -7200 # Node ID 224be4d9f8eb870756ac3005bfd25df3d78302f4 # Parent 1ce50e72a6b1d256620a0428ddbd72ff77721754 Fermentables are loaded in the main recipe record in a QList. The refresh table function does the sorting, on added moment (mash first), amount and finally color of the malt. Removed the old hidden table columns. Do all manipulation on the recipe record with QList arrays. The ferment_amount_changed() slot is complete. The whole recipe editor is going in the right direction. diff -r 1ce50e72a6b1 -r 224be4d9f8eb src/EditRecipe.cpp --- a/src/EditRecipe.cpp Wed Apr 06 12:10:33 2022 +0200 +++ b/src/EditRecipe.cpp Wed Apr 06 20:26:47 2022 +0200 @@ -20,6 +20,7 @@ #include "Utils.h" + EditRecipe::EditRecipe(int id, QWidget *parent) : QDialog(parent), ui(new Ui::EditRecipe) { QSqlQuery query; @@ -27,7 +28,6 @@ qDebug() << "EditRecipe record:" << id; recipe = new Recipe; ui->setupUi(this); - recipe->fermentables_records = recipe->hops_records = recipe->misc_records = recipe->yeasts_records = recipe->mashs_records = 0; recipe->fermentables_current = recipe->hops_current = recipe->misc_current = recipe->yeasts_current = recipe->mashs_current = -1; recipe->fermentables_use100 = false; this->recno = id; @@ -154,9 +154,41 @@ const auto& f_json = query.value(84).toString(); if (!f_json.trimmed().isEmpty()) { const auto& formattedJson = QString("%1").arg(f_json); - this->fermentables = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError); - if (parseError.error != QJsonParseError::NoError) + QJsonDocument fermentables = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError); + if (parseError.error != QJsonParseError::NoError) { qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ; + } else if (fermentables.isArray()) { + for (int i = 0; i < fermentables.array().size(); i++) { + QJsonObject obj = fermentables.array().at(i).toObject(); + Fermentables f; + f.f_name = obj["f_name"].toString(); + f.f_origin = obj["f_origin"].toString(); + f.f_supplier = obj["f_supplier"].toString(); + f.f_amount = obj["f_amount"].toDouble(); + f.f_cost = obj["f_cost"].toDouble(); + f.f_type = obj["f_type"].toInt(); + f.f_yield = obj["f_yield"].toDouble(); + f.f_color = obj["f_color"].toDouble(); + f.f_coarse_fine_diff = obj["f_coarse_fine_diff"].toDouble(); + f.f_moisture = obj["f_moisture"].toDouble(); + f.f_diastatic_power = obj["f_diastatic_power"].toDouble(); + f.f_protein = obj["f_protein"].toDouble(); + f.f_dissolved_protein = obj["f_dissolved_protein"].toDouble(); + f.f_max_in_batch = obj["f_max_in_batch"].toDouble(); + f.f_graintype = obj["f_graintype"].toInt(); + f.f_added = obj["f_added"].toInt(); + f.f_recommend_mash = obj["f_recommend_mash"].toInt() ? true:false; + f.f_add_after_boil = obj["f_add_after_boil"].toInt() ? true:false; + f.f_adjust_to_total_100 = obj["f_adjust_to_total_100"].toInt() ? true:false; + f.f_percentage = obj["f_percentage"].toDouble(); + f.f_di_ph = obj["f_di_ph"].toDouble(); + f.f_acid_to_ph_57 = obj["f_acid_to_ph_57"].toDouble(); + if (f.f_adjust_to_total_100) + recipe->fermentables_use100 = true; + recipe->fermentables.append(f); + } + qDebug() << "fermentables" << recipe->fermentables.size(); + } } else { qDebug() << "empty fermentables"; } @@ -195,14 +227,12 @@ if (!ma_json.trimmed().isEmpty()) { const auto& formattedJson = QString("%1").arg(ma_json); QJsonDocument mashs = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError); - if (parseError.error != QJsonParseError::NoError) + if (parseError.error != QJsonParseError::NoError) { qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ; - - if (mashs.isArray()) { + } else if (mashs.isArray()) { for (int i = 0; i < mashs.array().size(); i++) { QJsonObject obj = mashs.array().at(i).toObject(); - - qDebug() << i << obj; +// qDebug() << i << obj; Mashs m; m.step_name = obj["step_name"].toString(); m.step_type = obj["step_type"].toInt(); @@ -220,13 +250,7 @@ } else { qDebug() << "empty mashs"; } - recipe->mashs_records = recipe->mashs.size(); - -// qDebug() << query.value(88).toString(); -// if (recipe->mashs.size()) { - qDebug() << recipe->mashs.size(); -// } - //qDebug() << recipe->mashs; + qDebug() << "mashs" << recipe->mashs.size(); } else { /* Set some defaults */ @@ -298,7 +322,6 @@ recipe->wa_base_name = 0; 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()); @@ -388,7 +411,6 @@ connect(ui->perc_sugarsShow, &QProgressBar::valueChanged, this, &EditRecipe::on_perc_sugars_valueChanged); connect(ui->perc_caraShow, &QProgressBar::valueChanged, this, &EditRecipe::on_perc_cara_valueChanged); connect(ui->lintnerShow, &QProgressBar::valueChanged, this, &EditRecipe::on_lintner_valueChanged); - connect(ui->fermentablesTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Fermentable_changed(int, int))); // All signals from tab "Hops" // connect(ui->hopsTable, SIGNAL(cellChanged(int, int)), this, SLOT(cell_Changed(int, int))); @@ -420,6 +442,12 @@ } +bool EditRecipe::ferment_sort_test(const Fermentables &D1, const Fermentables &D2) +{ + return (D1.f_added <= D2.f_added) && (D1.f_amount >= D2.f_amount) && (D1.f_color < D2.f_color); +} + + void EditRecipe::refreshFermentables() { QString w; @@ -427,18 +455,19 @@ QHBoxLayout* pLayout; QTableWidgetItem *item; QLabel *label; - double d; - int j; - int total = 0; + + qDebug() << "refreshFermentables" << recipe->fermentables.size(); + std::sort(recipe->fermentables.begin(), recipe->fermentables.end(), ferment_sort_test); - 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. */ + /* + * 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("Supplier"), tr("Fermentable"), tr("EBC"), tr("Type"), tr("Graintype"), tr("When"), tr("Yield"), tr("Amount"), tr("Procent"), tr("100%"), tr("Delete"), tr("Edit") }); - ui->fermentablesTable->setColumnCount(30); + ui->fermentablesTable->setColumnCount(12); ui->fermentablesTable->setColumnWidth(0, 150); /* Supplier */ ui->fermentablesTable->setColumnWidth(1, 225); /* Fermentable */ ui->fermentablesTable->setColumnWidth(2, 50); /* Color */ @@ -451,49 +480,45 @@ ui->fermentablesTable->setColumnWidth(9, 50); /* 100% */ ui->fermentablesTable->setColumnWidth(10, 80); /* Delete */ ui->fermentablesTable->setColumnWidth(11, 80); /* Edit */ - for (int i = 12; i < 30; i++) - ui->fermentablesTable->setColumnHidden(i, true); ui->fermentablesTable->setHorizontalHeaderLabels(labels); ui->fermentablesTable->verticalHeader()->hide(); - ui->fermentablesTable->setRowCount(this->fermentables.array().size()); + ui->fermentablesTable->setRowCount(recipe->fermentables.size()); - if (this->fermentables.isArray()) { - for (int i = 0; i < this->fermentables.array().size(); i++) { - QJsonObject obj = this->fermentables.array().at(i).toObject(); + for (int i = 0; i < recipe->fermentables.size(); i++) { - ui->fermentablesTable->setItem(i, 0, new QTableWidgetItem(obj["f_supplier"].toString())); - ui->fermentablesTable->setItem(i, 1, new QTableWidgetItem(obj["f_name"].toString())); + ui->fermentablesTable->setItem(i, 0, new QTableWidgetItem(recipe->fermentables.at(i).f_supplier)); + ui->fermentablesTable->setItem(i, 1, new QTableWidgetItem(recipe->fermentables.at(i).f_name)); - w = QString("%1").arg(obj["f_color"].toDouble(), 1, 'f', 0, '0'); - item = new QTableWidgetItem(w); - item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 2, item); + w = QString("%1").arg(recipe->fermentables.at(i).f_color, 1, 'f', 0, '0'); + item = new QTableWidgetItem(w); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 2, item); - item = new QTableWidgetItem(f_types[obj["f_type"].toInt()]); - item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 3, item); + item = new QTableWidgetItem(f_types[recipe->fermentables.at(i).f_type]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 3, item); - item = new QTableWidgetItem(f_graintypes[obj["f_graintype"].toInt()]); - item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 4, item); + item = new QTableWidgetItem(f_graintypes[recipe->fermentables.at(i).f_graintype]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 4, item); - item = new QTableWidgetItem(f_added[obj["f_added"].toInt()]); - item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 5, item); + item = new QTableWidgetItem(f_added[recipe->fermentables.at(i).f_added]); + item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 5, item); - item = new QTableWidgetItem(QString("%1%").arg(obj["f_yield"].toDouble(), 2, 'f', 1, '0')); - item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 6, item); + item = new QTableWidgetItem(QString("%1%").arg(recipe->fermentables.at(i).f_yield, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 6, item); - item = new QTableWidgetItem(QString("%1 Kg").arg(obj["f_amount"].toDouble(), 4, 'f', 3, '0')); - item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 7, item); + item = new QTableWidgetItem(QString("%1 Kg").arg(recipe->fermentables.at(i).f_amount, 4, 'f', 3, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 7, item); - item = new QTableWidgetItem(QString("%1%").arg(obj["f_percentage"].toDouble(), 2, 'f', 1, '0')); - item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - ui->fermentablesTable->setItem(i, 8, item); + item = new QTableWidgetItem(QString("%1%").arg(recipe->fermentables.at(i).f_percentage, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 8, item); - if (obj["f_adjust_to_total_100"].toInt()) { + if (recipe->fermentables.at(i).f_adjust_to_total_100) { pWidget = new QWidget(); label = new QLabel; label->setPixmap(QPixmap(":icons/silk/tick.png")); @@ -503,56 +528,33 @@ pLayout->setContentsMargins(0, 0, 0, 0); pWidget->setLayout(pLayout); ui->fermentablesTable->setCellWidget(i, 9, pWidget); - } else { + } else { ui->fermentablesTable->removeCellWidget(i, 9); - } - - /* Add the Delete row button */ - pWidget = new QWidget(); - QPushButton* btn_dele = new QPushButton(); - btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */ - btn_dele->setText(tr("Delete")); - connect(btn_dele, SIGNAL(clicked()), this, SLOT(on_deleteFermentRow_clicked())); - pLayout = new QHBoxLayout(pWidget); - pLayout->addWidget(btn_dele); - pLayout->setContentsMargins(5, 0, 5, 0); - pWidget->setLayout(pLayout); - ui->fermentablesTable->setCellWidget(i, 10, pWidget); + } - pWidget = new QWidget(); - QPushButton* btn_edit = new QPushButton(); - btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */ - btn_edit->setText(tr("Edit")); - connect(btn_edit, SIGNAL(clicked()), this, SLOT(on_editFermentRow_clicked())); - pLayout = new QHBoxLayout(pWidget); - pLayout->addWidget(btn_edit); - pLayout->setContentsMargins(5, 0, 5, 0); - pWidget->setLayout(pLayout); - ui->fermentablesTable->setCellWidget(i, 11, pWidget); + /* Add the Delete row button */ + pWidget = new QWidget(); + QPushButton* btn_dele = new QPushButton(); + btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */ + btn_dele->setText(tr("Delete")); + connect(btn_dele, SIGNAL(clicked()), this, SLOT(on_deleteFermentRow_clicked())); + pLayout = new QHBoxLayout(pWidget); + pLayout->addWidget(btn_dele); + pLayout->setContentsMargins(5, 0, 5, 0); + pWidget->setLayout(pLayout); + ui->fermentablesTable->setCellWidget(i, 10, pWidget); - /* Hidden columns */ - ui->fermentablesTable->setItem(i, 12, new QTableWidgetItem(QString("%1").arg(obj["f_acid_to_ph_57"].toDouble(), 6, 'f', 5, '0'))); - ui->fermentablesTable->setItem(i, 13, new QTableWidgetItem(QString("%1").arg(obj["f_add_after_boil"].toInt(), 1, 'f', 0, '0'))); - ui->fermentablesTable->setItem(i, 14, new QTableWidgetItem(QString("%1").arg(obj["f_coarse_fine_diff"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 15, new QTableWidgetItem(QString("%1").arg(obj["f_cost"].toDouble(), 3, 'f', 2, '0'))); - ui->fermentablesTable->setItem(i, 16, new QTableWidgetItem(QString("%1").arg(obj["f_di_ph"].toDouble(), 6, 'f', 5, '0'))); - ui->fermentablesTable->setItem(i, 17, new QTableWidgetItem(QString("%1").arg(obj["f_diastatic_power"].toDouble(), 6, 'f', 5, '0'))); - ui->fermentablesTable->setItem(i, 18, new QTableWidgetItem(QString("%1").arg(obj["f_dissolved_protein"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 19, new QTableWidgetItem(QString("%1").arg(obj["f_moisture"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 20, new QTableWidgetItem(obj["f_origin"].toString())); - ui->fermentablesTable->setItem(i, 21, new QTableWidgetItem(QString("%1").arg(obj["f_protein"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 22, new QTableWidgetItem(QString("%1").arg(obj["f_recommend_mash"].toInt(), 1, 'f', 0, '0'))); - /* Again these because the visible ones have human readable strings added. */ - ui->fermentablesTable->setItem(i, 23, new QTableWidgetItem(QString("%1").arg(obj["f_amount"].toDouble(), 4, 'f', 3, '0'))); - ui->fermentablesTable->setItem(i, 24, new QTableWidgetItem(QString("%1").arg(obj["f_percentage"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 25, new QTableWidgetItem(QString("%1").arg(obj["f_yield"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 26, new QTableWidgetItem(QString("%1").arg(obj["f_max_in_batch"].toDouble(), 2, 'f', 1, '0'))); - ui->fermentablesTable->setItem(i, 27, new QTableWidgetItem(QString("%1").arg(obj["f_type"].toDouble(), 1, 'f', 0, '0'))); - ui->fermentablesTable->setItem(i, 28, new QTableWidgetItem(QString("%1").arg(obj["f_graintype"].toDouble(), 1, 'f', 0, '0'))); - ui->fermentablesTable->setItem(i, 29, new QTableWidgetItem(QString("%1").arg(obj["f_added"].toDouble(), 1, 'f', 0, '0'))); - } + pWidget = new QWidget(); + QPushButton* btn_edit = new QPushButton(); + btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */ + btn_edit->setText(tr("Edit")); + connect(btn_edit, SIGNAL(clicked()), this, SLOT(on_editFermentRow_clicked())); + pLayout = new QHBoxLayout(pWidget); + pLayout->addWidget(btn_edit); + pLayout->setContentsMargins(5, 0, 5, 0); + pWidget->setLayout(pLayout); + ui->fermentablesTable->setCellWidget(i, 11, pWidget); } - this->ignoreChanges = false; } @@ -607,7 +609,6 @@ QJsonObject obj; qDebug() << "calcFermentables()"; - use_to100 = false; /* * Get average mashtemp and mashtime from the Mash schedule. @@ -629,44 +630,42 @@ qDebug() << " no mash schedule"; } - if (this->fermentables.array().size() < 1) { + if (recipe->fermentables.size() < 1) { qDebug() << " no fermentables, return."; return; } + qDebug() << " adjust to 100" << recipe->fermentables_use100; - for (i = 0; i < this->fermentables.array().size(); i++) { - obj = this->fermentables.array().at(i).toObject(); - if (obj["f_adjust_to_total_100"].toInt()) - use_to100 = 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 + for (i = 0; i < recipe->fermentables.size(); i++) { + if (recipe->fermentables.at(i).f_type == 1 && recipe->fermentables.at(i).f_added < 4) // Sugars + psugar += recipe->fermentables.at(i).f_percentage; + if (recipe->fermentables.at(i).f_graintype == 2 && recipe->fermentables.at(i).f_added < 4) // Crystal/Cara + pcara += recipe->fermentables.at(i).f_percentage; + d = recipe->fermentables.at(i).f_amount * (recipe->fermentables.at(i).f_yield / 100) * (1 - recipe->fermentables.at(i).f_moisture / 100); + if (recipe->fermentables.at(i).f_added == 0) { // Mash if (mvol > 0) { // If mash volume is known - mvol += obj["f_amount"].toDouble() * obj["f_moisture"].toDouble() / 100; + mvol += recipe->fermentables.at(i).f_amount * recipe->fermentables.at(i).f_moisture / 100; s += d; } d = ui->efficiencyEdit->value() / 100 * d; sugarsm += d; - mashkg += obj["f_amount"].toDouble(); + mashkg += recipe->fermentables.at(i).f_amount; } - if (obj["f_added"].toInt() == 0 || obj["f_added"].toInt() == 1) // Mash or boil + if (recipe->fermentables.at(i).f_added == 0 || recipe->fermentables.at(i).f_added == 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 (recipe->fermentables.at(i).f_added == 2 || recipe->fermentables.at(i).f_added == 3) { // Fermentation or lagering + x = (recipe->fermentables.at(i).f_yield / 100) * (1 - recipe->fermentables.at(i).f_moisture / 100); + addedS += recipe->fermentables.at(i).f_amount * x; + addedmass += recipe->fermentables.at(i).f_amount; + vol += (x * sugardensity + (1 - x) * 1) * recipe->fermentables.at(i).f_amount; } - 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 (recipe->fermentables.at(i).f_added == 0 && (recipe->fermentables.at(i).f_type == 0 || recipe->fermentables.at(i).f_type == 4) && recipe->fermentables.at(i).f_color < 50) { + lintner += recipe->fermentables.at(i).f_diastatic_power * recipe->fermentables.at(i).f_amount; } - if (obj["f_added"].toInt() < 4) { - colort += obj["f_amount"].toDouble() * Utils::ebc_to_srm(obj["f_color"].toDouble()); - colorh += obj["f_amount"].toDouble() * obj["f_color"].toDouble() * Utils::get_kt(obj["f_color"].toDouble()); - colorn += (obj["f_percentage"].toDouble() / 100) * obj["f_color"].toDouble(); // For 8.6 Pt wort. + if (recipe->fermentables.at(i).f_added < 4) { + colort += recipe->fermentables.at(i).f_amount * Utils::ebc_to_srm(recipe->fermentables.at(i).f_color); + colorh += recipe->fermentables.at(i).f_amount * recipe->fermentables.at(i).f_color * Utils::get_kt(recipe->fermentables.at(i).f_color); + colorn += (recipe->fermentables.at(i).f_percentage / 100) * recipe->fermentables.at(i).f_color; // For 8.6 Pt wort. } } qDebug() << " colort" << colort << "colorh" << colorh << "colorn" << colorn; @@ -754,9 +753,6 @@ double alc = 1881.22 * fg * (og - fg) / (1.775 - og); double sug = 3550 * fg * (0.1808 * og + 0.8192 * fg - 1.0004); ui->calEdit->setValue(round((alc + sug) / (12 * 0.0295735296))); - - // If to_100 then make all amount fields t/o and percent fields r/w - } @@ -1003,84 +999,46 @@ } +/* TODO: move this code to MySQL save */ void EditRecipe::fermentable_Json() { QTableWidgetItem *item; QJsonArray array; qDebug() << "fermentable_Json()"; - ui->fermentablesTable->sortItems(23, Qt::DescendingOrder); // Sort on amount. - qDebug() << "fermentable_Json() 1"; - for (int i = 0; i < ui->fermentablesTable->rowCount(); i++) { + for (int i = 0; i < recipe->fermentables.size(); i++) { - qDebug() << "fermentable_Json() 2" << i; QJsonObject obj; - item = ui->fermentablesTable->item(i, 12); - obj.insert("f_acid_to_ph_57", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 13); - obj.insert("f_add_after_boil", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 29); - obj.insert("f_added", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 9); - obj.insert("f_adjust_to_total_100", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 23); - obj.insert("f_amount", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 14); - obj.insert("f_coarse_fine_diff", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 2); - obj.insert("f_color", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 15); - obj.insert("f_cost", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 16); - obj.insert("f_di_ph", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 17); - obj.insert("f_diastatic_power", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 18); - obj.insert("f_dissolved_protein", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 28); - obj.insert("f_graintype", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 26); - obj.insert("f_max_in_batch", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 19); - obj.insert("f_moisture", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 1); - obj.insert("f_name", item->text()); - item = ui->fermentablesTable->item(i, 20); - obj.insert("f_origin", item->text()); - item = ui->fermentablesTable->item(i, 24); - obj.insert("f_percentage", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 21); - obj.insert("f_protein", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 22); - obj.insert("f_recommend_mash", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 0); - obj.insert("f_supplier", item->text()); - item = ui->fermentablesTable->item(i, 27); - obj.insert("f_type", item->text().toDouble()); - item = ui->fermentablesTable->item(i, 25); - obj.insert("f_yield", item->text().toDouble()); + obj.insert("f_acid_to_ph_57", recipe->fermentables.at(i).f_acid_to_ph_57); + obj.insert("f_add_after_boil", recipe->fermentables.at(i).f_add_after_boil); + obj.insert("f_added", recipe->fermentables.at(i).f_added); + obj.insert("f_adjust_to_total_100", recipe->fermentables.at(i).f_adjust_to_total_100); + obj.insert("f_amount", recipe->fermentables.at(i).f_added); + obj.insert("f_coarse_fine_diff", recipe->fermentables.at(i).f_coarse_fine_diff); + obj.insert("f_color", recipe->fermentables.at(i).f_color); + obj.insert("f_cost", recipe->fermentables.at(i).f_cost); + obj.insert("f_di_ph", recipe->fermentables.at(i).f_di_ph); + obj.insert("f_diastatic_power", recipe->fermentables.at(i).f_diastatic_power); + obj.insert("f_dissolved_protein", recipe->fermentables.at(i).f_dissolved_protein); + obj.insert("f_graintype", recipe->fermentables.at(i).f_graintype); + obj.insert("f_max_in_batch", recipe->fermentables.at(i).f_max_in_batch); + obj.insert("f_moisture", recipe->fermentables.at(i).f_moisture); + obj.insert("f_name", recipe->fermentables.at(i).f_name); + obj.insert("f_origin", recipe->fermentables.at(i).f_origin); + obj.insert("f_percentage", recipe->fermentables.at(i).f_percentage); + obj.insert("f_protein", recipe->fermentables.at(i).f_protein); + obj.insert("f_recommend_mash", recipe->fermentables.at(i).f_recommend_mash); + obj.insert("f_supplier", recipe->fermentables.at(i).f_supplier); + obj.insert("f_type", recipe->fermentables.at(i).f_type); + obj.insert("f_yield", recipe->fermentables.at(i).f_yield); qDebug() << "fermentable_Json" << i << obj; array.append(obj); /* Append this object */ } qDebug() << array; /* Copy to the global array and refresh */ - this->fermentables.setArray(array); - is_changed(); - emit refreshAll(); -} - - -void EditRecipe::cell_Fermentable_changed(int nRow, int nCol) -{ - if (this->ignoreChanges) - return; - - qDebug() << "Cell at row " + QString::number(nRow) + " column " + QString::number(nCol) + " was changed."; - - // TODO: some checks and auto fixes. -// make_Json(); +// this->fermentables.setArray(array); } @@ -1090,54 +1048,56 @@ int row = pb->objectName().toInt(); qDebug() << "Delete fermentable row" << row; - QJsonObject obj = this->fermentables.array().at(row).toObject(); - qDebug() << obj; - - int rc = QMessageBox::warning(this, tr("Delete fermentable"), tr("Delete %1").arg(obj["f_name"].toString()), + int rc = QMessageBox::warning(this, tr("Delete fermentable"), tr("Delete %1").arg(recipe->fermentables.at(row).f_name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (rc == QMessageBox::No) return; ui->fermentablesTable->removeRow(row); // recalculate percentages - fermentable_Json(); +// fermentable_Json(); } void EditRecipe::ferment_amount_changed(double val) { QTableWidgetItem *item; - double total = 0; + double total = 0, perc; + + if (recipe->fermentables_use100) + return; qDebug() << "ferment_amount_changed()" << editrow << val; - this->ignoreChanges = true; + recipe->fermentables[editrow].f_amount = val; item = new QTableWidgetItem(QString("%1 Kg").arg(val, 4, 'f', 3, '0')); item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); ui->fermentablesTable->setItem(editrow, 7, item); - item = new QTableWidgetItem(QString("%1").arg(val, 4, 'f', 3, '0')); - ui->fermentablesTable->setItem(editrow, 23, item); - - for (int i = 0; i < ui->fermentablesTable->rowCount(); i++) { - item = ui->fermentablesTable->item(i, 23); - total += item->text().toDouble(); - } - qDebug() << "total weight now" << total; + for (int i = 0; i < recipe->fermentables.size(); i++) + total += recipe->fermentables.at(i).f_amount; -// for (int i = 0; i < ui->fermentablesTable->rowCount(); i++) { -// item = ui->fermentablesTable->item(i, 23); -// total += item->text().toDouble(); -// } - + /* + * Recalculate the percentages + */ + for (int i = 0; i < recipe->fermentables.size(); i++) { + perc = recipe->fermentables.at(i).f_amount / total * 100; + recipe->fermentables[i].f_percentage = perc; + item = new QTableWidgetItem(QString("%1%").arg(perc, 2, 'f', 1, '0')); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + ui->fermentablesTable->setItem(i, 8, item); + if (i == editrow) + this->pctEdit->setValue(perc); + } this->ignoreChanges = false; - -// fermentable_Json(); } void EditRecipe::ferment_pct_changed(double val) { + if (! recipe->fermentables_use100) + return; + qDebug() << "ferment_pct_changed()" << val; } @@ -1147,10 +1107,7 @@ QPushButton *pb = qobject_cast(QObject::sender()); editrow = pb->objectName().toInt(); qDebug() << "Edit fermentable row" << editrow; - work = this->fermentables.array().at(editrow).toObject(); - backup = this->fermentables.array().at(editrow).toObject(); - - qDebug() << work; + Fermentables backup = recipe->fermentables.at(editrow); QDialog* dialog = new QDialog(this); dialog->resize(738, 287); @@ -1212,12 +1169,12 @@ selectEdit->setGeometry(QRect(160, 70, 251, 23)); nameEdit = new QLineEdit(dialog); nameEdit->setObjectName(QString::fromUtf8("nameEdit")); - nameEdit->setText(work["f_name"].toString()); + nameEdit->setText(recipe->fermentables.at(editrow).f_name); nameEdit->setGeometry(QRect(160, 10, 511, 23)); nameEdit->setReadOnly(true); supplierEdit = new QLineEdit(dialog); supplierEdit->setObjectName(QString::fromUtf8("supplierEdit")); - supplierEdit->setText(work["f_supplier"].toString()); + supplierEdit->setText(recipe->fermentables.at(editrow).f_supplier); supplierEdit->setGeometry(QRect(160, 40, 511, 23)); supplierEdit->setReadOnly(true); amountEdit = new QDoubleSpinBox(dialog); @@ -1226,10 +1183,10 @@ amountEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); amountEdit->setAccelerated(true); amountEdit->setDecimals(3); - amountEdit->setReadOnly(use_to100); + amountEdit->setReadOnly(recipe->fermentables_use100); amountEdit->setMaximum(100000.0); amountEdit->setSingleStep(0.0010); - amountEdit->setValue(work["f_amount"].toDouble()); + amountEdit->setValue(recipe->fermentables.at(editrow).f_amount); connect(amountEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::ferment_amount_changed); pctEdit = new QDoubleSpinBox(dialog); @@ -1238,8 +1195,8 @@ pctEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); pctEdit->setAccelerated(true); pctEdit->setDecimals(1); - if (use_to100) { - if (work["f_adjust_to_total_100"].toInt()) + if (recipe->fermentables_use100) { + if (recipe->fermentables.at(editrow).f_adjust_to_total_100) pctEdit->setReadOnly(true); else pctEdit->setReadOnly(false); @@ -1248,7 +1205,7 @@ } pctEdit->setMaximum(100.0); pctEdit->setSingleStep(0.1); - pctEdit->setValue(work["f_percentage"].toDouble()); + pctEdit->setValue(recipe->fermentables.at(editrow).f_percentage); connect(pctEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::ferment_pct_changed); addedEdit = new QComboBox(dialog); @@ -1260,12 +1217,12 @@ addedEdit->addItem(tr("Lagering")); addedEdit->addItem(tr("Bottle")); addedEdit->addItem(tr("Kegs")); - addedEdit->setCurrentIndex(work["f_added"].toInt()); + addedEdit->setCurrentIndex(recipe->fermentables.at(editrow).f_added); to100Edit = new QCheckBox(dialog); to100Edit->setObjectName(QString::fromUtf8("to100Edit")); to100Edit->setGeometry(QRect(160, 160, 85, 21)); - to100Edit->setChecked(work["f_adjust_to_total_100"].toInt() ? true:false); + to100Edit->setChecked(recipe->fermentables.at(editrow).f_adjust_to_total_100); instockEdit = new QCheckBox(dialog); instockEdit->setObjectName(QString::fromUtf8("instockEdit")); @@ -1278,7 +1235,7 @@ maxEdit->setReadOnly(true); maxEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); maxEdit->setDecimals(1); - maxEdit->setValue(work["f_max_in_batch"].toDouble()); + maxEdit->setValue(recipe->fermentables.at(editrow).f_max_in_batch); connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); @@ -1286,6 +1243,7 @@ if (dialog->result() == QDialog::Rejected) { qDebug() << "rejected"; // restore fermentbackup + // recalculate percentages } else { qDebug() << "accepted"; // fermentrow to final @@ -1295,6 +1253,7 @@ // disconnect // return + emit refreshAll(); } diff -r 1ce50e72a6b1 -r 224be4d9f8eb src/EditRecipe.h --- a/src/EditRecipe.h Wed Apr 06 12:10:33 2022 +0200 +++ b/src/EditRecipe.h Wed Apr 06 20:26:47 2022 +0200 @@ -227,16 +227,11 @@ * that belong with the loaded recipe data and are present to * make things easier. */ - int fermentables_records; ///< Total records int fermentables_current; ///< Current record, -1 is invalid. bool fermentables_use100; ///< Use percentages instead of amount - int hops_records; int hops_current; - int misc_records; int misc_current; - int yeasts_records; int yeasts_current; - int mashs_records; int mashs_current; }; @@ -269,7 +264,6 @@ void refreshYeasts(); void refreshMashs(); void refreshAll(); - void cell_Fermentable_changed(int nRow, int nCol); void ferment_amount_changed(double val); void ferment_pct_changed(double val); void on_deleteFermentRow_clicked(); @@ -292,18 +286,17 @@ int recno, editrow; bool textIsChanged = false; bool ignoreChanges = false; - bool use_to100 = false; Recipe *recipe; /* * Variables for popup ingredients editing. */ - QJsonDocument fermentables, hops, miscs, yeasts; - QJsonObject work, backup; + QJsonDocument hops, miscs, yeasts; QComboBox *selectEdit, *addedEdit; QLineEdit *nameEdit, *supplierEdit; QDoubleSpinBox *amountEdit, *pctEdit, *maxEdit; QCheckBox *to100Edit, *instockEdit; + static bool ferment_sort_test(const Fermentables &D1, const Fermentables &D2); void WindowTitle(); void fermentable_Json(); void calcFermentables();