Sat, 09 Jul 2022 23:05:25 +0200
Increased some labels sizes.
/** * Printer.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 "PrinterDialog.h" #include "Utils.h" #include "EditRecipe.h" #include "EditProduct.h" #include "config.h" #include "global.h" #include <QPrintPreviewDialog> #include <QDebug> #include <QtSql> PrinterDialog::PrinterDialog(int job, int rec, QWidget* parent) : QDialog(parent) { qDebug() << "PrinterDialog start job" << job << "rec" << rec; p_job = job; p_rec = rec; QPrinter printer(QPrinter::ScreenResolution); QPrintPreviewDialog preview(&printer, this); connect(&preview, &QPrintPreviewDialog::paintRequested, this, &PrinterDialog::printDocument); preview.exec(); } PrinterDialog::~PrinterDialog() {} void PrinterDialog::printDocument(QPrinter *printer) { qDebug() << "PrinterDialog printDocument()"; QRect rectangle; QRect boundingRect; QPainter painter; QString w; QSqlQuery query; const QColor c_header(255, 150, 100, 255); const QColor c_line1( 210, 245, 255, 255); const QColor c_line2( 255, 255, 210, 255); const QColor f_line( 250, 195, 65, 255); const QColor h_line( 100, 250, 65, 255); const QColor y_line( 175, 175, 255, 255); const QColor mw_line( 240, 140, 130, 255); const QColor mf_line( 95, 180, 25, 255); const QColor ms_line( 240, 250, 65, 255); const QColor mo_line( 210, 245, 255, 255); const QColor line( 175, 175, 255, 255); // also y_line const QColor w_line( 120, 255, 250, 255); const QStringList y_unit({tr("pkg"), tr("gr"), tr("ml"), tr("ml"), tr("ml"), tr("ml"), tr("gr")}); const QStringList color_method({ "Morey", "Mosher", "Daniels", "Halberstadt", "Naudts" }); painter.begin(printer); qreal y = 0; if (p_job == PR_SUPPLIES) { qInfo() << "Print supplies"; /* * Print supplies in stock */ double tot_fermentables = 0, tot_hops = 0, tot_yeasts = 0, tot_miscs = 0; printHeader(&painter); y = 120; /* Fermentables supplies header */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(100, y+4, 100, 20, Qt::AlignLeft, tr("Supplier")); painter.drawText(200, y+4, 260, 20, Qt::AlignLeft, tr("Fermentable")); painter.drawText(460, y+4, 115, 20, Qt::AlignRight, tr("Stock")); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, tr("Price/Kg")); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, tr("Value")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); query.exec("SELECT type,name,supplier,inventory,cost FROM inventory_fermentables WHERE inventory > 0 ORDER BY type,supplier,name"); query.first(); for (int i = 0 ; i < query.size() ; i++ ) { if ((y + 20) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2); painter.drawText( 20, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("FermentableType", g_fermentable_types[query.value(0).toInt()])); painter.drawText(100, y+4, 100, 20, Qt::AlignLeft, query.value(2).toString()); painter.drawText(200, y+4, 260, 20, Qt::AlignLeft, query.value(1).toString()); w = QString("%1 kg").arg(query.value(3).toDouble(), 10, 'f', 3); painter.drawText(460, y+4, 115, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(4).toDouble(), 8, 'f', 2); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(3).toDouble() * query.value(4).toDouble(), 8, 'f', 2); tot_fermentables += (query.value(3).toDouble() * query.value(4).toDouble()); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); query.next(); y += 20; } painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 100, 20, Qt::AlignLeft, tr("Total")); w = QString("%1 €").arg(tot_fermentables, 8, 'f', 2); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); y += 20; /* Hops supplies */ query.exec("SELECT name,form,origin,inventory,cost FROM inventory_hops WHERE inventory > 0 ORDER BY origin,name"); query.first(); if ((y + 80 + (query.size() * 20)) > painter.device()->height()) { /* Rows + header + footer + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Country")); painter.drawText(140, y+4, 240, 20, Qt::AlignLeft, tr("Hop name")); painter.drawText(380, y+4, 80, 20, Qt::AlignLeft, tr("Form")); painter.drawText(460, y+4, 115, 20, Qt::AlignRight, tr("Stock")); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, tr("Price/Kg")); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, tr("Value")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < query.size(); i++) { if ((y + 20) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, query.value(2).toString()); painter.drawText(140, y+4, 240, 20, Qt::AlignLeft, query.value(0).toString()); painter.drawText(380, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("HopForm", g_hop_forms[query.value(1).toInt()])); if (query.value(3).toDouble() < 0.6) w = QString("%1 gr").arg(query.value(3).toDouble() * 1000.0, 10, 'f', 1); else w = QString("%1 kg").arg(query.value(3).toDouble(), 10, 'f', 3); painter.drawText(460, y+4, 115, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(4).toDouble(), 8, 'f', 2); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(3).toDouble() * query.value(4).toDouble(), 8, 'f', 2); tot_hops += (query.value(3).toDouble() * query.value(4).toDouble()); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); query.next(); y += 20; } painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 100, 20, Qt::AlignLeft, tr("Total")); w = QString("%1 €").arg(tot_hops, 8, 'f', 2); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); y += 20; /* Yeasts supplies */ query.exec("SELECT name,laboratory,product_id,form,inventory,cost FROM inventory_yeasts WHERE inventory > 0 ORDER BY laboratory,product_id"); query.first(); if ((y + 80 + (query.size() * 20)) > painter.device()->height()) { /* Rows + header + footer + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Laboratory")); painter.drawText(140, y+4, 120, 20, Qt::AlignLeft, tr("Product")); painter.drawText(260, y+4, 235, 20, Qt::AlignLeft, tr("Yeast")); painter.drawText(495, y+4, 80, 20, Qt::AlignRight, tr("Stock")); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, tr("Price/Kg")); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, tr("Value")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < query.size(); i++) { if ((y + 20) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, query.value(1).toString()); painter.drawText(140, y+4, 120, 20, Qt::AlignLeft, query.value(2).toString()); painter.drawText(260, y+4, 235, 20, Qt::AlignLeft, query.value(0).toString()); if (query.value(3).toInt() == 0) w = QString("%1 %2").arg(query.value(4).toDouble(), 10, 'f', 1).arg(y_unit[query.value(3).toInt()]); else w = QString("%1 %2").arg(query.value(4).toDouble() * 1000.0, 10, 'f', 1).arg(y_unit[query.value(3).toInt()]); painter.drawText(495, y+4, 80, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(5).toDouble(), 8, 'f', 2); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(4).toDouble() * query.value(5).toDouble(), 8, 'f', 2); tot_yeasts += (query.value(4).toDouble() * query.value(5).toDouble()); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); query.next(); y += 20; } painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 100, 20, Qt::AlignLeft, tr("Total")); w = QString("%1 €").arg(tot_yeasts, 8, 'f', 2); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); y += 20; /* Miscs supplies */ query.exec("SELECT name,type,amount_is_weight,inventory,cost FROM inventory_miscs WHERE inventory > 0 ORDER BY type,name"); query.first(); if ((y + 80 + (query.size() * 20)) > painter.device()->height()) { /* Rows + header + footer + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Type")); painter.drawText(140, y+4, 320, 20, Qt::AlignLeft, tr("Ingredient")); painter.drawText(460, y+4, 115, 20, Qt::AlignRight, tr("Stock")); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, tr("Price/Kg")); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, tr("Value")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < query.size(); i++) { if ((y + 20) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, QCoreApplication::translate("MiscType", g_misc_types[query.value(1).toInt()])); painter.drawText(140, y+4, 320, 20, Qt::AlignLeft, query.value(0).toString()); if (query.value(2).toInt()) w = QString("%1 gr").arg(query.value(3).toDouble() * 1000.0, 10, 'f', 1); else w = QString("%1 ml").arg(query.value(3).toDouble() * 1000.0, 10, 'f', 1); painter.drawText(460, y+4, 115, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(4).toDouble(), 8, 'f', 2); painter.drawText(575, y+4, 80, 20, Qt::AlignRight, w); w = QString("%1 €").arg(query.value(3).toDouble() * query.value(4).toDouble(), 8, 'f', 2); tot_miscs += (query.value(3).toDouble() * query.value(4).toDouble()); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); query.next(); y += 20; } painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 100, 20, Qt::AlignLeft, tr("Total")); w = QString("%1 €").arg(tot_miscs, 8, 'f', 2); painter.drawText(655, y+4, 80, 20, Qt::AlignRight, w); y += 20; } else if (p_job == PR_YEASTBANK) { qInfo() << "Print yeastbank"; /* * Print yeast in the private yeast bank. */ printHeader(&painter); y = 120; painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 180, 20, Qt::AlignLeft, tr("Yeast")); painter.drawText(200, y+4, 230, 20, Qt::AlignLeft, tr("Description")); painter.drawText(430, y+4, 80, 20, Qt::AlignCenter, tr("Type")); painter.drawText(510, y+4, 80, 20, Qt::AlignCenter, tr("Form")); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, tr("Stock")); painter.drawText(665, y+4, 70, 20, Qt::AlignLeft, tr("Date")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); query.prepare("SELECT name,type,form,inventory,production_date,short_desc " "FROM inventory_yeasts WHERE inventory > 0 AND laboratory = :my_lab ORDER BY product_id"); query.bindValue(":my_lab", my_yeastlab); query.exec(); query.first(); for (int i = 0; i < query.size(); i++) { painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2); painter.drawText( 20, y+4, 180, 20, Qt::AlignLeft, query.value(0).toString()); painter.drawText(200, y+4, 230, 20, Qt::AlignLeft, query.value(5).toString()); painter.drawText(430, y+4, 80, 20, Qt::AlignCenter, QCoreApplication::translate("YeastType", g_yeast_types[query.value(1).toInt()])); painter.drawText(510, y+4, 80, 20, Qt::AlignCenter, QCoreApplication::translate("YeastForm", g_yeast_forms[query.value(2).toInt()])); if (query.value(2).toInt() == 0) w = QString("%1 %2").arg(query.value(3).toDouble(), 10, 'f', 1).arg(y_unit[query.value(2).toInt()]); else w = QString("%1 %2").arg(query.value(3).toDouble() * 1000.0, 10, 'f', 1).arg(y_unit[query.value(2).toInt()]); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, w); painter.drawText(665, y+4, 70, 20, Qt::AlignLeft, query.value(4).toString()); query.next(); y += 20; } } else if (p_job == PR_RECIPE) { qInfo() << "Print recipe" << recipe->record; printHeader(&painter); y = 120; /* Generic header */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 715, 20, Qt::AlignCenter, tr("Recipe overview")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Brew type")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QCoreApplication::translate("Recipe_type", g_recipe_types[recipe->type])); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Efficiency")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 %").arg(recipe->efficiency, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Boil time")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 minutes.").arg(recipe->boil_time, 1, 'f', 0)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Batch size")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L.").arg(recipe->batch_size, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Start SG")); painter.drawText(170, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(recipe->est_og, 1, 'f', 3)); painter.drawText(260, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(recipe->st_og_min, 1, 'f', 3).arg(recipe->st_og_max, 1, 'f', 3)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("End SG")); painter.drawText(555, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(recipe->est_fg, 1, 'f', 3)); painter.drawText(645, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(recipe->st_fg_min, 1, 'f', 3).arg(recipe->st_fg_max, 1, 'f', 3)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Estimated Alcohol")); painter.drawText(170, y+4, 90, 20, Qt::AlignLeft, QString("%1%").arg(recipe->est_abv, 1, 'f', 1)); painter.drawText(260, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(recipe->st_abv_min, 1, 'f', 1).arg(recipe->st_abv_max, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Estimated CO2 vol")); painter.drawText(555, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(recipe->est_carb, 1, 'f', 1)); painter.drawText(645, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(recipe->st_carb_min, 1, 'f', 1).arg(recipe->st_carb_max, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 150, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Color (") + color_method[recipe->color_method] + ")"); painter.fillRect(170, y, 180, 20, Utils::ebc_to_color(recipe->est_color)); if (recipe->est_color > 30) painter.setPen(Qt::white); painter.drawText(170, y+4, 90, 20, Qt::AlignLeft, QString("%1 EBC").arg(recipe->est_color, 1, 'f', 0)); painter.drawText(260, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(recipe->st_color_min, 1, 'f', 0).arg(recipe->st_color_max, 1, 'f', 0)); painter.setPen(Qt::black); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("IBU (") + g_ibu_method[recipe->ibu_method] + ")"); painter.drawText(555, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(recipe->est_ibu, 1, 'f', 1)); painter.drawText(645, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(recipe->st_ibu_min, 1, 'f', 0).arg(recipe->st_ibu_max, 1, 'f', 0)); y += 40; /* Fermentables */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, tr("Fermentable")); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, tr("Percent")); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, tr("Yield")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_fermentables = 0; QString soort, amount, use; for (int i = 0; i < recipe->fermentables.size(); i++) { double cost = recipe->fermentables.at(i).amount * recipe->fermentables.at(i).cost; cost_fermentables += cost; if (recipe->fermentables.at(i).type == 0) soort = QCoreApplication::translate("FermentableGraintype", g_fermentable_graintypes[recipe->fermentables.at(i).graintype]); else soort = QCoreApplication::translate("FermentableType", g_fermentable_types[recipe->fermentables.at(i).type]); if (recipe->fermentables.at(i).amount > 100) amount = QString("%1 kg").arg(recipe->fermentables.at(i).amount, 1, 'f', 1); else if (recipe->fermentables.at(i).amount > 10) amount = QString("%1 kg").arg(recipe->fermentables.at(i).amount, 1, 'f', 2); else amount = QString("%1 gr").arg(recipe->fermentables.at(i).amount * 1000, 1, 'f', 0); painter.fillRect( 20, y, 715, 20, f_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, recipe->fermentables.at(i).name + QString(", %1 EBC (").arg(recipe->fermentables.at(i).color, 1, 'f', 0) + recipe->fermentables.at(i).supplier + ")"); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(recipe->fermentables.at(i).percentage, 1, 'f', 1)); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(recipe->fermentables.at(i).yield, 1, 'f', 1)); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, soort); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("FermentableAdded", g_fermentable_added[recipe->fermentables.at(i).added])); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, amount); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_fermentables, 1, 'f', 3)); y += 40; /* Hops */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, tr("Hop")); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, tr("Alpha")); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, tr("IBU")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_hops = 0; for (int i = 0; i < recipe->hops.size(); i++) { double cost = recipe->hops.at(i).amount * recipe->hops.at(i).cost; cost_hops += cost; double ibu = Utils::toIBU(recipe->hops.at(i).useat, recipe->hops.at(i).form, recipe->preboil_sg, recipe->batch_size, recipe->hops.at(i).amount, recipe->hops.at(i).time, recipe->hops.at(i).alpha, recipe->ibu_method, 0, recipe->hops.at(i).time, 0, recipe->boil_time, 0, 0, 0); if (recipe->hops.at(i).useat == 2 || recipe->hops.at(i).useat == 4) // Boil or Whirlpool use = QCoreApplication::translate("HopUse", g_hop_useat[recipe->hops.at(i).useat]) + QString(" %1 min").arg(recipe->hops.at(i).time); else if (recipe->hops.at(i).useat == 5) // Dryhop use = QCoreApplication::translate("HopUse", g_hop_useat[recipe->hops.at(i).useat]) + QString(" %1 days").arg(recipe->hops.at(i).time / 1440); else use = QCoreApplication::translate("HopUse", g_hop_useat[recipe->hops.at(i).useat]); if (recipe->hops.at(i).amount > 1) amount = QString("%1 kg").arg(recipe->hops.at(i).amount, 1, 'f', 3); else amount = QString("%1 gr").arg(recipe->hops.at(i).amount * 1000, 1, 'f', 1); painter.fillRect( 20, y, 715, 20, h_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, recipe->hops.at(i).name + " (" + recipe->hops.at(i).origin + ")"); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(recipe->hops.at(i).alpha, 1, 'f', 1)); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(ibu, 1, 'f', 1)); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("HopForm", g_hop_forms[recipe->hops.at(i).form])); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, use); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, amount); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_hops, 1, 'f', 3)); y += 40; /* Yeasts */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 335, 20, Qt::AlignLeft, tr("Yeast")); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, tr("Attn")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_yeasts = 0; for (int i = 0; i < recipe->yeasts.size(); i++) { double cost = recipe->yeasts.at(i).amount * recipe->yeasts.at(i).cost; cost_yeasts += cost; if (recipe->yeasts.at(i).form == 0) amount = QString("%1 pack").arg(recipe->yeasts.at(i).amount, 1, 'f', 0); else if (recipe->yeasts.at(i).form == 1 || recipe->yeasts.at(i).form == 6) amount = QString("%1 gr").arg(recipe->yeasts.at(i).amount * 1000.0, 1, 'f', 1); else amount = QString("%1 ml").arg(recipe->yeasts.at(i).amount * 1000.0, 1, 'f', 1); painter.fillRect( 20, y, 715, 20, y_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, recipe->yeasts.at(i).laboratory + " " + recipe->yeasts.at(i).product_id + " (" + recipe->yeasts.at(i).name + ")"); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(recipe->yeasts.at(i).attenuation, 1, 'f', 1)); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("YeastForm", g_yeast_forms[recipe->yeasts.at(i).form])); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("YeastUse", g_yeast_use[recipe->yeasts.at(i).use])); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, amount); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_yeasts, 1, 'f', 3)); if ((y + 80 + (recipe->miscs.size() * 20)) > painter.device()->height()) { /* Rows + header + footer + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Miscs */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 410, 20, Qt::AlignLeft, tr("Misc ingredient")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_miscs = 0; for (int i = 0; i < recipe->miscs.size(); i++) { double cost = recipe->miscs.at(i).amount * recipe->miscs.at(i).cost; cost_miscs += cost; if (recipe->miscs.at(i).use_use == 2) use = QCoreApplication::translate("MiscUse", g_misc_uses[recipe->miscs.at(i).use_use]) + QString(" %1 min").arg(recipe->miscs.at(i).time); else use = QCoreApplication::translate("MiscUse", g_misc_uses[recipe->miscs.at(i).use_use]); if (recipe->miscs.at(i).type == 4) // Water agent painter.fillRect( 20, y, 715, 20, mw_line); else if (recipe->miscs.at(i).type == 3) // Fining painter.fillRect( 20, y, 715, 20, mf_line); else if (recipe->miscs.at(i).type < 3 || recipe->miscs.at(i).type == 5) // Spice, Herb, Flavour, Yeast nutrient painter.fillRect( 20, y, 715, 20, ms_line); else painter.fillRect( 20, y, 715, 20, mo_line); painter.drawText( 20, y+4, 410, 20, Qt::AlignLeft, recipe->miscs.at(i).name); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("MiscType", g_misc_types[recipe->miscs.at(i).type])); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, use); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, QString("%1 %2").arg(recipe->miscs.at(i).amount * 1000.0, 1, 'f', 1).arg(recipe->miscs.at(i).amount_is_weight ? "gr":"ml")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_miscs, 1, 'f', 3)); if ((y + 60 + (recipe->mashs.size() * 20)) > painter.device()->height()) { /* Rows + header + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Mash */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 160, 20, Qt::AlignLeft, tr("Mash step")); painter.drawText(180, y+4, 80, 20, Qt::AlignLeft, tr("Step type")); painter.drawText(260, y+4, 60, 20, Qt::AlignRight, tr("Start °C")); painter.drawText(325, y+4, 60, 20, Qt::AlignRight, tr("End °C")); painter.drawText(390, y+4, 60, 20, Qt::AlignRight, tr("Time")); painter.drawText(455, y+4, 60, 20, Qt::AlignRight, tr("Ramp")); painter.drawText(520, y+4, 60, 20, Qt::AlignRight, tr("L/kg")); painter.drawText(585, y+4, 70, 20, Qt::AlignRight, tr("Inf/dec L.")); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, tr("Inf/dec °C")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < recipe->mashs.size(); i++) { painter.fillRect( 20, y, 715, 20, line); painter.drawText( 20, y+4, 160, 20, Qt::AlignLeft, recipe->mashs.at(i).step_name); painter.drawText(180, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("StepType", g_step_types[recipe->mashs.at(i).step_type])); painter.drawText(260, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).step_temp, 1, 'f', 1)); painter.drawText(325, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).end_temp, 1, 'f', 1)); painter.drawText(390, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).step_time, 1, 'f', 0)); painter.drawText(455, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).ramp_time, 1, 'f', 0)); painter.drawText(520, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).step_wg_ratio, 1, 'f', 2)); if (recipe->mashs.at(i).step_type != 1) { painter.drawText(585, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).step_infuse_amount, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->mashs.at(i).step_infuse_temp, 1, 'f', 1)); } y += 20; } if ((y + 80 + ((recipe->w2_amount > 0) ? 40:0)) > painter.device()->height()) { /* waters + header + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Water */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Water source")); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, tr("Volume")); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, tr("Ca")); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, tr("Mg")); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, tr("CaCO3")); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, tr("Na")); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, tr("Cl")); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, tr("SO4")); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, tr("pH")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, recipe->w1_name); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, QString("%1 L").arg(recipe->w1_amount, 1, 'f', 1)); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w1_ph, 1, 'f', 2)); y += 20; if (recipe->w2_amount > 0) { /* * If there is dillution water, show it and the mixed result too. */ painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, recipe->w2_name); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, QString("%1 L").arg(recipe->w2_amount, 1, 'f', 1)); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->w2_ph, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Mixed water")); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, QString("%1 L").arg(recipe->wg_amount, 1, 'f', 1)); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wg_ph, 1, 'f', 2)); y += 20; } painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Treated water")); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(recipe->wb_ph, 1, 'f', 2)); y += 20; /* * Print recipe notes if present. */ if (recipe->notes.length()) { QStringList lines = recipe->notes.split("\n"); if (lines.size() && recipe->notes != "") { if ((y + 80 + (lines.size() * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Notes header */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 715, 20, Qt::AlignCenter, tr("Recipe notes")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < lines.size(); i++) { painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 715, 20, Qt::AlignLeft, lines[i]); y += 20; } } } } else if (p_job == PR_PRODUCT) { qInfo() << "print product" << product->record; printHeader(&painter); y = 120; /* Generic header */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 715, 20, Qt::AlignCenter, tr("Product overview")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Brew type")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QCoreApplication::translate("RecipeType", g_recipe_types[product->type])); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Efficiency")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 %").arg(product->efficiency, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Boil time")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 minutes.").arg(product->boil_time, 1, 'f', 0)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Batch size")); if (product->divide_type) { painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L. of %2 L.").arg(product->batch_size, 1, 'f', 1) .arg(product->batch_size / product->divide_factor, 1, 'f', 1)); } else { painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L.").arg(product->batch_size, 1, 'f', 1)); } y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Start SG")); painter.drawText(170, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(product->est_og, 1, 'f', 3)); painter.drawText(260, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(product->st_og_min, 1, 'f', 3).arg(product->st_og_max, 1, 'f', 3)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("End SG")); painter.drawText(555, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(product->est_fg, 1, 'f', 3)); painter.drawText(645, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(product->st_fg_min, 1, 'f', 3).arg(product->st_fg_max, 1, 'f', 3)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Estimated Alcohol")); painter.drawText(170, y+4, 90, 20, Qt::AlignLeft, QString("%1%").arg(product->est_abv, 1, 'f', 1)); painter.drawText(260, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(product->st_abv_min, 1, 'f', 1).arg(product->st_abv_max, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Estimated CO2 vol")); painter.drawText(555, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(product->est_carb, 1, 'f', 1)); painter.drawText(645, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(product->st_carb_min, 1, 'f', 1).arg(product->st_carb_max, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 150, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Color (") + color_method[product->color_method] + ")"); painter.fillRect(170, y, 180, 20, Utils::ebc_to_color(product->est_color)); if (product->est_color > 30) painter.setPen(Qt::white); painter.drawText(170, y+4, 90, 20, Qt::AlignLeft, QString("%1 EBC").arg(product->est_color, 1, 'f', 0)); painter.drawText(260, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(product->st_color_min, 1, 'f', 0).arg(product->st_color_max, 1, 'f', 0)); painter.setPen(Qt::black); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("IBU (") + g_ibu_method[product->ibu_method] + ")"); painter.drawText(555, y+4, 90, 20, Qt::AlignLeft, QString("%1").arg(product->est_ibu, 1, 'f', 1)); painter.drawText(645, y+4, 90, 20, Qt::AlignLeft, QString("(%1 - %2)").arg(product->st_ibu_min, 1, 'f', 0).arg(product->st_ibu_max, 1, 'f', 0)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Beer style")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, product->st_name); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Stage")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QCoreApplication::translate("ProdStages", g_prod_stages[product->stage])); if (product->divide_parts) { y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Split batch")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QCoreApplication::translate("Splitter", g_prod_split[product->divide_type])); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Batch number")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 of %2").arg(product->divide_part + 1).arg(product->divide_parts + 1)); } y += 40; /* Fermentables */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, tr("Fermentable")); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, tr("Percent")); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, tr("Yield")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_fermentables = 0; QString soort, amount, use; for (int i = 0; i < product->fermentables.size(); i++) { double cost = product->fermentables.at(i).amount * product->fermentables.at(i).cost; cost_fermentables += cost; if (product->fermentables.at(i).type == 0) soort = QCoreApplication::translate("FermentableGraintype", g_fermentable_graintypes[product->fermentables.at(i).graintype]); else soort = QCoreApplication::translate("FermentableType", g_fermentable_types[product->fermentables.at(i).type]); if (product->fermentables.at(i).amount > 100) amount = QString("%1 kg").arg(product->fermentables.at(i).amount, 1, 'f', 1); else if (product->fermentables.at(i).amount > 10) amount = QString("%1 kg").arg(product->fermentables.at(i).amount, 1, 'f', 2); else amount = QString("%1 gr").arg(product->fermentables.at(i).amount * 1000, 1, 'f', 0); painter.fillRect( 20, y, 715, 20, f_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, product->fermentables.at(i).name + QString(", %1 EBC (").arg(product->fermentables.at(i).color, 1, 'f', 0) + product->fermentables.at(i).supplier + ")"); if (product->fermentables.at(i).added < FERMENTABLE_ADDED_BOTTLE) painter.drawText(285, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(product->fermentables.at(i).percentage, 1, 'f', 1)); else painter.drawText(285, y+4, 70, 20, Qt::AlignRight, ""); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(product->fermentables.at(i).yield, 1, 'f', 1)); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, soort); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("FermentableAdded", g_fermentable_added[product->fermentables.at(i).added])); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, amount); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_fermentables, 1, 'f', 3)); y += 40; /* Hops */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, tr("Hop")); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, tr("Alpha")); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, tr("IBU")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_hops = 0; for (int i = 0; i < product->hops.size(); i++) { double cost = product->hops.at(i).amount * product->hops.at(i).cost; cost_hops += cost; double ibu = Utils::toIBU(product->hops.at(i).useat, product->hops.at(i).form, product->preboil_sg, product->batch_size, product->hops.at(i).amount, product->hops.at(i).time, product->hops.at(i).alpha, product->ibu_method, product->brew_whirlpool9, product->brew_whirlpool7, product->brew_whirlpool6, product->boil_time, product->brew_cooling_method, 0, 0); if (product->hops.at(i).useat == 2 || product->hops.at(i).useat == 4) // Boil or Whirlpool use = QCoreApplication::translate("HopUse", g_hop_useat[product->hops.at(i).useat]) + QString(" %1 min").arg(product->hops.at(i).time); else if (product->hops.at(i).useat == 5) // Dryhop use = QCoreApplication::translate("HopUse", g_hop_useat[product->hops.at(i).useat]) + QString(" %1 days").arg(product->hops.at(i).time / 1440); else use = QCoreApplication::translate("HopUse", g_hop_useat[product->hops.at(i).useat]); if (product->hops.at(i).amount > 1) amount = QString("%1 kg").arg(product->hops.at(i).amount, 1, 'f', 3); else amount = QString("%1 gr").arg(product->hops.at(i).amount * 1000, 1, 'f', 1); painter.fillRect( 20, y, 715, 20, h_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, product->hops.at(i).name + " (" + product->hops.at(i).origin + ")"); painter.drawText(285, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(product->hops.at(i).alpha, 1, 'f', 1)); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(ibu, 1, 'f', 1)); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("HopForm", g_hop_forms[product->hops.at(i).form])); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, use); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, amount); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_hops, 1, 'f', 3)); y += 40; /* Yeasts */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 335, 20, Qt::AlignLeft, tr("Yeast")); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, tr("Attn")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_yeasts = 0; for (int i = 0; i < product->yeasts.size(); i++) { double cost = product->yeasts.at(i).amount * product->yeasts.at(i).cost; cost_yeasts += cost; if (product->yeasts.at(i).form == 0) amount = QString("%1 pack").arg(product->yeasts.at(i).amount, 1, 'f', 0); else if (product->yeasts.at(i).form == 1 || product->yeasts.at(i).form == 6) amount = QString("%1 gr").arg(product->yeasts.at(i).amount * 1000.0, 1, 'f', 1); else amount = QString("%1 ml").arg(product->yeasts.at(i).amount * 1000.0, 1, 'f', 1); painter.fillRect( 20, y, 715, 20, y_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, product->yeasts.at(i).laboratory + " " + product->yeasts.at(i).product_id + " (" + product->yeasts.at(i).name + ")"); painter.drawText(360, y+4, 70, 20, Qt::AlignRight, QString("%1%").arg(product->yeasts.at(i).attenuation, 1, 'f', 1)); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("YeastForm", g_yeast_forms[product->yeasts.at(i).form])); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("YeastUse", g_yeast_use[product->yeasts.at(i).use])); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, amount); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } if (product->starter_enable && product->prop_volume[0]) { int st = 0; double sv = 0; for (int i = 0; i < 4; i++) { if (product->prop_volume[i] > 0.0) { st++; if (product->prop_volume[i] > sv) sv = product->prop_volume[i]; } } painter.fillRect( 20, y, 715, 20, y_line); painter.drawText( 20, y+4, 260, 20, Qt::AlignLeft, QString(tr("%1 step yeaststarter")).arg(st)); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, QString(tr("Before"))); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, QString("%1 L").arg(sv, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_yeasts, 1, 'f', 3)); if ((y + 80 + (product->miscs.size() * 20)) > painter.device()->height()) { /* Rows + header + footer + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Miscs */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 410, 20, Qt::AlignLeft, tr("Misc ingredient")); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, tr("Type")); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, tr("Use at")); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, tr("Amount")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, tr("Cost")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); double cost_miscs = 0; for (int i = 0; i < product->miscs.size(); i++) { double cost = product->miscs.at(i).amount * product->miscs.at(i).cost; cost_miscs += cost; if (product->miscs.at(i).use_use == 2) use = QCoreApplication::translate("MiscUse", g_misc_uses[product->miscs.at(i).use_use]) + QString(" %1 min").arg(product->miscs.at(i).time); else use = QCoreApplication::translate("MiscUse", g_misc_uses[product->miscs.at(i).use_use]); if (product->miscs.at(i).type == 4) // Water agent painter.fillRect( 20, y, 715, 20, mw_line); else if (product->miscs.at(i).type == 3) // Fining painter.fillRect( 20, y, 715, 20, mf_line); else if (product->miscs.at(i).type < 3 || product->miscs.at(i).type == 5) // Spice, Herb, Flavour, Yeast nutrient painter.fillRect( 20, y, 715, 20, ms_line); else painter.fillRect( 20, y, 715, 20, mo_line); painter.drawText( 20, y+4, 410, 20, Qt::AlignLeft, product->miscs.at(i).name); painter.drawText(435, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("MiscType", g_misc_types[product->miscs.at(i).type])); painter.drawText(520, y+4, 80, 20, Qt::AlignLeft, use); painter.drawText(605, y+4, 60, 20, Qt::AlignRight, QString("%1 %2").arg(product->miscs.at(i).amount * 1000.0, 1, 'f', 1).arg(product->miscs.at(i).amount_is_weight ? "gr":"ml")); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost, 1, 'f', 3)); y += 20; } painter.fillRect(670, y, 60, 20, c_line1); painter.drawText(670, y+4, 60, 20, Qt::AlignRight, QString("%1 €").arg(cost_miscs, 1, 'f', 3)); if ((y + 60 + (product->mashs.size() * 20)) > painter.device()->height()) { /* Rows + header + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Mash */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 160, 20, Qt::AlignLeft, tr("Mash step")); painter.drawText(180, y+4, 80, 20, Qt::AlignLeft, tr("Step type")); painter.drawText(260, y+4, 60, 20, Qt::AlignRight, tr("Start °C")); painter.drawText(325, y+4, 60, 20, Qt::AlignRight, tr("End °C")); painter.drawText(390, y+4, 60, 20, Qt::AlignRight, tr("Time")); painter.drawText(455, y+4, 60, 20, Qt::AlignRight, tr("Ramp")); painter.drawText(520, y+4, 60, 20, Qt::AlignRight, tr("L/kg")); painter.drawText(585, y+4, 70, 20, Qt::AlignRight, tr("Inf/dec L.")); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, tr("Inf/dec °C")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < product->mashs.size(); i++) { painter.fillRect( 20, y, 715, 20, line); painter.drawText( 20, y+4, 160, 20, Qt::AlignLeft, product->mashs.at(i).step_name); painter.drawText(180, y+4, 80, 20, Qt::AlignLeft, QCoreApplication::translate("StepType", g_step_types[product->mashs.at(i).step_type])); painter.drawText(260, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).step_temp, 1, 'f', 1)); painter.drawText(325, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).end_temp, 1, 'f', 1)); painter.drawText(390, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).step_time, 1, 'f', 0)); painter.drawText(455, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).ramp_time, 1, 'f', 0)); painter.drawText(520, y+4, 60, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).step_wg_ratio, 1, 'f', 2)); if (product->mashs.at(i).step_type != 1) { painter.drawText(585, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).step_infuse_amount, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->mashs.at(i).step_infuse_temp, 1, 'f', 1)); } y += 20; } if ((y + 80 + ((product->w2_amount > 0) ? 40:0)) > painter.device()->height()) { /* waters + header + blank */ printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Water */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Water source")); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, tr("Volume")); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, tr("Ca")); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, tr("Mg")); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, tr("CaCO3")); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, tr("Na")); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, tr("Cl")); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, tr("SO4")); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, tr("pH")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, product->w1_name); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, QString("%1 L").arg(product->w1_amount, 1, 'f', 1)); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w1_ph, 1, 'f', 2)); y += 20; if (product->w2_amount > 0) { /* * If there is dillution water, show it and the mixed result too. */ painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, product->w2_name); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, QString("%1 L").arg(product->w2_amount, 1, 'f', 1)); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->w2_ph, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Mixed water")); painter.drawText(170, y+4, 70, 20, Qt::AlignRight, QString("%1 L").arg(product->wg_amount, 1, 'f', 1)); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wg_ph, 1, 'f', 2)); y += 20; } painter.fillRect( 20, y, 715, 20, w_line); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Treated water")); painter.drawText(240, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_calcium, 1, 'f', 1)); painter.drawText(310, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_magnesium, 1, 'f', 1)); painter.drawText(380, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_total_alkalinity, 1, 'f', 1)); painter.drawText(450, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_sodium, 1, 'f', 1)); painter.drawText(520, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_chloride, 1, 'f', 1)); painter.drawText(590, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_sulfate, 1, 'f', 1)); painter.drawText(660, y+4, 70, 20, Qt::AlignRight, QString("%1").arg(product->wb_ph, 1, 'f', 2)); y += 20; /* * Print product notes if present. */ if (product->notes.length()) { QStringList lines = product->notes.split("\n"); if (lines.size() && product->notes != "") { if ((y + 80 + (lines.size() * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } /* Notes header */ painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+4, 715, 20, Qt::AlignCenter, tr("Recipe notes")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); for (int i = 0; i < lines.size(); i++) { painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 715, 20, Qt::AlignLeft, lines[i]); y += 20; } } } if (product->stage > PROD_STAGE_BREW) { if ((y + 100) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+2, 715, 20, Qt::AlignCenter, tr("Product brewday")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 300, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Brewday start")); painter.drawText(140, y+4, 180, 20, Qt::AlignLeft, product->brew_date_start.toString("dd MMM yyyy hh:mm")); painter.fillRect(435, y, 300, 20, c_line1); painter.drawText(435, y+4, 120, 20, Qt::AlignLeft, tr("Brewday end")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, product->brew_date_end.toString("dd MMM yyyy hh:mm")); /* Mash history */ if ((y + 60 + (product->mashs.size() * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, line); painter.drawText( 40, y+4, 250, 20, Qt::AlignLeft, tr("Mash step")); painter.drawText(290, y+4, 120, 20, Qt::AlignLeft, tr("Step type")); painter.drawText(400, y+4, 110, 20, Qt::AlignLeft, tr("Temperature")); painter.drawText(510, y+4, 75, 20, Qt::AlignLeft, tr("Minutes")); painter.drawText(585, y+4, 75, 20, Qt::AlignLeft, tr("SG")); painter.drawText(660, y+4, 75, 20, Qt::AlignLeft, tr("pH")); painter.setFont(QFont("Helvetica", 9, QFont::Normal)); y += 20; for (int i = 0; i < product->mashs.size(); i++) { painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 20, 20, Qt::AlignCenter, QString("%1").arg(i + 1)); painter.drawText( 40, y+4, 250, 20, Qt::AlignLeft, product->mashs.at(i).step_name); painter.drawText(290, y+4, 120, 20, Qt::AlignLeft, QCoreApplication::translate("StepType", g_step_types[product->mashs.at(i).step_type])); painter.drawText(400, y+4, 110, 20, Qt::AlignLeft, QString("%1 - %2°C"). arg(product->mashs.at(i).step_temp, 1, 'f', 1).arg(product->mashs.at(i).end_temp, 1, 'f', 1)); painter.drawText(510, y+4, 75, 20, Qt::AlignLeft, QString("%1").arg(product->mashs.at(i).step_time, 1, 'f', 0)); painter.drawText(585, y+4, 75, 20, Qt::AlignLeft, QString("%1").arg(product->mashs.at(i).step_sg, 1, 'f', 3)); painter.drawText(660, y+4, 75, 20, Qt::AlignLeft, QString("%1").arg(product->mashs.at(i).step_ph, 1, 'f', 1)); y += 20; } /* Brew history */ if ((y + 470) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 715, 20, line); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Brew item")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, tr("Expected")); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, tr("Reached")); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, tr("Difference")); painter.setFont(QFont("Helvetica", 9, QFont::Normal)); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Mash pH")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->mash_ph, 1, 'f', 2)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->brew_mash_ph, 1, 'f', 2)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->mash_ph, product->brew_mash_ph, 2, " pH")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Mash density")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, strDensity(product->est_mash_sg)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, strDensity(product->brew_mash_sg)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->est_mash_sg, product->brew_mash_sg, 3, " SG")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Mash efficiency")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, "100%"); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1%").arg(product->brew_mash_efficiency, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(100.0, product->brew_mash_efficiency, 1, "%")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Sparge pH")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->sparge_ph, 1, 'f', 2)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->brew_sparge_ph, 1, 'f', 2)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->sparge_ph, product->brew_sparge_ph, 2, " pH")); y += 25; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Pre boil pH")); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->brew_preboil_ph, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Pre boil density")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, strDensity(product->preboil_sg)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, strDensity(product->brew_preboil_sg)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->preboil_sg, product->brew_preboil_sg, 3, " SG")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Pre boil volume")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->boil_size * 1.04, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->brew_preboil_volume, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->boil_size * 1.04, product->brew_preboil_volume, 1, " L")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Pre boil efficiency")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1%").arg(product->efficiency, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1%").arg(product->brew_preboil_efficiency, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->efficiency, product->brew_preboil_efficiency, 1, "%")); y += 25; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("After boil pH")); //painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->brew_preboil_ph, 1, 'f', 2)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 pH").arg(product->brew_aboil_ph, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("After boil density")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, strDensity(product->est_og)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, strDensity(product->brew_aboil_sg)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->est_og, product->brew_aboil_sg, 3, " SG")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("After boil volume")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->batch_size * 1.04, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->brew_aboil_volume, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->batch_size * 1.04, product->brew_aboil_volume, 1, " L")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("After boil efficiency")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1%").arg(product->efficiency, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1%").arg(product->brew_aboil_efficiency, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->efficiency, product->brew_aboil_efficiency, 1, "%")); y += 25; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Chiller and trub loss")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->eq_trub_chiller_loss, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->brew_fermenter_tcloss, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->eq_trub_chiller_loss, product->brew_fermenter_tcloss, 1, " L")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Top up water")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->eq_top_up_water, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->brew_fermenter_extrawater, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->eq_top_up_water, product->brew_fermenter_extrawater, 1, " L")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Fermenter volume")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->batch_size - product->eq_trub_chiller_loss, 1, 'f', 1)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 L").arg(product->brew_fermenter_volume, 1, 'f', 1)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->batch_size - product->eq_trub_chiller_loss, product->brew_fermenter_volume, 1, " L")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Fermenter density")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, strDensity(product->est_og)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, strDensity(product->brew_fermenter_sg)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->est_og, product->brew_fermenter_sg, 3, " SG")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Fermenter color")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 EBC").arg(product->est_color, 1, 'f', 0)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 EBC").arg(product->brew_fermenter_color, 1, 'f', 0)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->est_color, product->brew_fermenter_color, 0, " EBC")); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Fermenter IBU")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 IBU").arg(product->est_ibu, 1, 'f', 0)); painter.drawText(450, y+4, 200, 20, Qt::AlignLeft, QString("%1 IBU").arg(product->brew_fermenter_ibu, 1, 'f', 0)); painter.drawText(650, y+4, 85, 20, Qt::AlignLeft, strDiff(product->est_ibu, product->brew_fermenter_ibu, 0, " IBU")); y += 25; painter.fillRect( 20, y, 430, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Cooling method")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QCoreApplication::translate("ChillerType", g_chiller_types[product->brew_cooling_method])); y += 20; painter.fillRect( 20, y, 430, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Cooling temperature")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1°C").arg(product->brew_cooling_to, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 430, 20, c_line1); painter.drawText( 20, y+4, 230, 20, Qt::AlignLeft, tr("Cooling time")); painter.drawText(250, y+4, 200, 20, Qt::AlignLeft, QString("%1 min").arg(product->brew_cooling_time, 1, 'f', 0)); } if (product->stage > PROD_STAGE_TERTIARY) { if ((y + 200) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+2, 715, 20, Qt::AlignCenter, tr("Product fermentation")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Primary start temp")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->primary_start_temp, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Primary peak temp")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->primary_max_temp, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Primary end temp")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->primary_end_temp, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Primary density")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 SG").arg(product->primary_end_sg, 1, 'f', 3)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Primary end date")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, product->primary_end_date.toString("dd MMM yyyy")); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Secondary end temp")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->secondary_temp, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Secondary density")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 SG").arg(product->secondary_end_sg, 1, 'f', 3)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Secondary end date")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, product->secondary_end_date.toString("dd MMM yyyy")); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Tertiary temperature")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->tertiary_temp, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Final density")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 SG").arg(product->fg, 1, 'f', 3)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Tertiary end date")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, product->package_date.toString("dd MMM yyyy")); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Apperant attenuation")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1%").arg(Utils::calc_svg(product->brew_fermenter_sg, product->fg), 1, 'f', 1)); } if (product->stage > PROD_STAGE_PACKAGE) { if ((y + ((product->package_infuse_amount > 0) ? 305:265)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+2, 715, 20, Qt::AlignCenter, tr("Package product")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Package date")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, product->package_date.toString("dd MMM yyyy")); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Package volume")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->package_volume, 1, 'f', 1)); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Alcohol volume")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1%").arg(product->package_abv, 1, 'f', 2)); y += 20; if (product->package_infuse_amount > 0) { painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Infuse volume")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->package_infuse_amount, 1, 'f', 3)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Infuse alcohol")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1%").arg(product->package_infuse_abv, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 715, 20, Qt::AlignLeft, product->package_infuse_notes); y += 20; } y += 5; painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.fillRect( 20, y, 330, 20, line); painter.drawText( 20, y+2, 330, 20, Qt::AlignCenter, tr("Bottles")); painter.fillRect(405, y, 330, 20, line); painter.drawText(405, y+2, 330, 20, Qt::AlignCenter, tr("Kegs")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Bottles volume")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->bottle_amount, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Kegs volume")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->keg_amount, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Bottles CO2 volumes")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->bottle_carbonation, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Kegs CO2 volumes")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->keg_carbonation, 1, 'f', 1)); y += 20; QString bsugar = "", ksugar = ""; double bamount = 0, kamount = 0; for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_BOTTLE) { bsugar = product->fermentables.at(i).name; bamount = product->fermentables.at(i).amount; } if (product->fermentables.at(i).added == FERMENTABLE_ADDED_KEGS) { ksugar = product->fermentables.at(i).name; kamount = product->fermentables.at(i).amount; } } painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Sugar")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, bsugar); painter.fillRect(405, y, 330, 20, c_line1); if (product->keg_forced_carb) { painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Forced carbonation")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, tr("Yes")); } else { painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Sugar")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, ksugar); } y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Sugar amount")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 Kg").arg(bamount, 1, 'f', 3)); if (! product->keg_forced_carb) { painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Sugar amount")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 Kg").arg(kamount, 1, 'f', 3)); } y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Water amount")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->bottle_priming_water, 1, 'f', 3)); if (! product->keg_forced_carb) { painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Water amount")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 L").arg(product->keg_priming_water, 1, 'f', 3)); } y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Alcohol volume")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1%").arg(product->bottle_abv, 1, 'f', 2)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Alcohol volume")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1%").arg(product->keg_abv, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Pressure")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1 bar").arg(product->bottle_bar, 1, 'f', 2)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Pressure")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1 bar").arg(product->keg_bar, 1, 'f', 2)); y += 20; painter.fillRect( 20, y, 330, 20, c_line1); painter.drawText( 20, y+4, 150, 20, Qt::AlignLeft, tr("Carbonation temp")); painter.drawText(170, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->bottle_carbonation_temp, 1, 'f', 1)); painter.fillRect(405, y, 330, 20, c_line1); painter.drawText(405, y+4, 150, 20, Qt::AlignLeft, tr("Carbonation temp")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1°C").arg(product->keg_carbonation_temp, 1, 'f', 1)); } if (product->stage > PROD_STAGE_TASTE) { QStringList lines = product->taste_notes.split("\n"); if (lines.size() && (product->taste_notes != "")) { if ((y + 220 + (lines.size() * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } } else { if ((y + 220) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 40; } } painter.setFont(QFont("Helvetica", 9, QFont::Bold)); painter.setPen(Qt::black); painter.fillRect( 20, y, 715, 20, c_header); painter.drawText( 20, y+2, 715, 20, Qt::AlignCenter, tr("Tasting notes")); y += 20; painter.setFont(QFont("Helvetica", 9, QFont::Normal)); painter.fillRect( 20, y, 300, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Tasting date")); painter.drawText(120, y+4, 180, 20, Qt::AlignLeft, product->taste_date.toString("dd MMM yyyy")); painter.fillRect(435, y, 300, 20, c_line1); painter.drawText(435, y+4, 120, 20, Qt::AlignLeft, tr("Taste score")); painter.drawText(555, y+4, 180, 20, Qt::AlignLeft, QString("%1").arg(product->taste_rate, 1, 'f', 1)); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Color")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_color); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Transparency")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_transparency); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Head")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_head); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Aroma")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_aroma); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Taste")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_taste); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Mouthfeel")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_mouthfeel); y += 20; painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 120, 20, Qt::AlignLeft, tr("Aftertaste")); painter.drawText(120, y+4, 595, 20, Qt::AlignLeft, product->taste_aftertaste); y += 25; for (int i = 0; i < lines.size(); i++) { painter.fillRect( 20, y, 715, 20, c_line1); painter.drawText( 20, y+4, 715, 20, Qt::AlignLeft, lines[i]); y += 20; } } } else if (p_job == PR_CHECKLIST) { double factor = 1.0 / product->divide_factor; double mashwater = 0; int numsalts = 0; qInfo() << "Print checklist" << product->record << "factor" << factor << product->divide_factor; printHeader(&painter); y = 120; /* First item, a yeast starter if needed, days before brewday. */ if (product->starter_enable && product->prop_volume[0]) { checkHeader(&painter, &y, tr("Make a yeast starter")); int days = 0; int last = 0; QString s = ""; for (int i = 0; i < 4; i++) { if (product->prop_volume[i]) { last = i; if (product->prop_type[i] == STARTERS_STIRRED) days += 2; else if (product->prop_type[i] == STARTERS_SHAKEN) days += 4; else days += 6; // Simple starter } } checkLine(&painter, &y, QString(tr("Start about %1 days before brewday with the starter.")).arg(days)); for (int i = 0; i < 4; i++) { if (product->prop_volume[i]) { checkLine(&painter, &y, QString(tr("Starter step %1 of %2 liter with SG %3")).arg(i+1).arg(product->prop_volume[i], 1, 'f', 3). arg(product->starter_sg, 1, 'f', 3)); QString w = tr(" until there is enough yeast"); if (product->prop_type[i] == STARTERS_STIRRED) checkLine(&painter, &y, QString(tr("about 24 hours on a stirplate"))+w); else if (product->prop_type[i] == STARTERS_SHAKEN) checkLine(&painter, &y, QString(tr("shake often for a few days"))+w); else checkLine(&painter, &y, QString(tr("let it rest for almost a week"))+w); if (i < last) { checkLine(&painter, &y, QString(tr("place starter in the fridge for 24 hours"))); checkLine(&painter, &y, QString(tr("remove starter from the fridge and decant"))); } else { checkLine(&painter, &y, QString(tr("place starter in the fridge until brewday"))); checkLine(&painter, &y, QString(tr("remove starter from the fridge and decant"))); } } } y += 20; } checkHeader(&painter, &y, tr("Mash water and treatment")); checkLine(&painter, &y, QString("%1 liter water %2").arg(product->w1_amount * factor, 1, 'f', 1).arg(product->w1_name)); mashwater += product->w1_amount * factor; if (product->w2_name != "" && product->w2_amount > 0) { checkLine(&painter, &y, QString("%1 liter water %2").arg(product->w2_amount * factor, 1, 'f', 1).arg(product->w2_name)); mashwater += product->w2_amount * factor; } for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).type == MISC_TYPES_WATER_AGENT) { QString unit = (product->miscs.at(i).amount_is_weight) ? "gr":"ml"; checkLine(&painter, &y, QString("%1 %2 %3").arg(product->miscs.at(i).amount * 1000 * factor, 1, 'f', 2).arg(unit).arg(product->miscs.at(i).name)); numsalts++; } } y += 20; checkHeader(&painter, &y, tr("Weight and mill the malts")); for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_MASH) { checkLine(&painter, &y, QString("%1 kg `%2` (%3)").arg(product->fermentables.at(i).amount * factor, 1, 'f', 3). arg(product->fermentables.at(i).name).arg(product->fermentables.at(i).supplier)); } } checkLine(&painter, &y, QString(tr("Mill the malts"))); y += 20; checkHeader(&painter, &y, tr("Mash")); int loop = 0; double l, mvol = 0, msugars = 0; for (int i = 0; i < product->mashs.size(); i++) { if (product->mashs.at(i).step_type == 0) mvol += product->mashs.at(i).step_infuse_amount * factor; // We need this later if (loop == 0) { if (product->mashs.at(i).step_type == 0) l = product->mashs.at(i).step_infuse_amount * factor; else l = mashwater; checkLine(&painter, &y, QString(tr("Heat %1 liter water to %2°C (%3 cm below kettle top)")) .arg(mashwater, 1, 'f', 1).arg(product->mashs.at(i).step_infuse_temp, 1, 'f', 1) .arg(Utils::kettle_cm(l, product->eq_tun_volume, product->eq_tun_height), 1, 'f', 1)); if (numsalts > 0) checkLine(&painter, &y, QString(tr("Add brouwzouten"))); checkLine(&painter, &y, QString(tr("Add malts and dough-in"))); for (int j = 0; j < product->hops.size(); j++) { if (product->hops.at(j).useat == HOP_USEAT_MASH) { checkLine(&painter, &y, QString(tr("Add %1 gram `%2` hop")).arg(product->hops.at(j).amount * 1000 * factor, 1, 'f', 1) .arg(product->hops.at(j).name)); } } for (int j = 0; j < product->miscs.size(); j++) { if ((product->miscs.at(j).use_use == MISC_USES_MASH) && (product->miscs.at(j).type != MISC_TYPES_WATER_AGENT)) { QString unit = (product->miscs.at(j).amount_is_weight) ? "gr":"ml"; checkLine(&painter, &y, QString(tr("Add %1 %2 `%3`")).arg(product->miscs.at(j).amount * 1000 * factor, 1, 'f', 2) .arg(unit).arg(product->miscs.at(j).name)); } } } else { // loop > 0 if (product->mashs.at(i).step_type == 0) { // Infusion checkLine(&painter, &y, QString(tr("Add %1 liter water of %2°C")).arg(product->mashs.at(i).step_infuse_amount * factor, 1, 'f', 1) .arg(product->mashs.at(i).step_infuse_temp, 1, 'f', 1)); } else if (product->mashs.at(i).step_type == 1) { // Direct heat checkLine(&painter, &y, QString(tr("Heat upto %1°C")).arg(product->mashs.at(i).step_temp, 1, 'f', 1)); } else { // Decoction checkLine(&painter, &y, QString(tr("Take, heat, boil and return %1 part of the mash")) .arg(product->mashs.at(i).step_infuse_amount * factor, 1, 'f', 1)); } } if (product->mashs.at(i).step_temp != product->mashs.at(i).end_temp) { checkInput(&painter, &y, QString(tr("%1 minutes from %2°C to %3°C")).arg(product->mashs.at(i).step_time) .arg(product->mashs.at(i).step_temp, 1, 'f', 1).arg(product->mashs.at(i).end_temp, 1, 'f', 1), QString(tr("Brix"))); } else { checkInput(&painter, &y, QString(tr("%1 minutes at %2°C")).arg(product->mashs.at(i).step_time) .arg(product->mashs.at(i).step_temp, 1, 'f', 1), QString(tr("Brix"))); } if (loop == 0) checkInput(&painter, &y, QString(tr("Measure and adjust pH (target %1 pH)")).arg(product->mash_ph, 1, 'f', 2), QString(tr("pH"))); loop++; } double est_masg_sg = 0, sugardensity = 1.611, grainabsorbtion = 0; for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_MASH) { double d = product->fermentables.at(i).amount * factor * (product->fermentables.at(i).yield / 100) * (1 - product->fermentables.at(i).moisture / 100); mvol += product->fermentables.at(i).amount * factor * (product->fermentables.at(i).moisture / 100); grainabsorbtion += my_grain_absorbtion * product->fermentables.at(i).amount * factor; msugars += d; } } double v = msugars / sugardensity + mvol; double plato = 1000.0 * msugars / (v * 10.0); // deg. Plato double mash_sg = Utils::plato_to_sg(plato); checkInput(&painter, &y, QString(tr("Target SG end mash: ")) + strDensity(mash_sg), QString(tr("SG"))); if ((y + 140) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } checkHeader(&painter, &y, tr("Lauter and Sparge")); checkLine(&painter, &y, QString(tr("Heat %1 liter sparge water to %2°C")).arg(product->sparge_volume * factor, 1, 'f', 1) .arg(product->sparge_temp, 1, 'f', 1)); checkInput(&painter, &y, QString(tr("Bring to %1 pH with %2 ml. `%3`")).arg(product->sparge_ph, 1, 'f', 2) .arg(product->sparge_acid_amount * 1000 * factor, 1, 'f', 2).arg(my_acids.at(product->sparge_acid_type).name_en), QString(tr("pH"))); checkLine(&painter, &y, QString(tr("Sparge with close to %1 liter water")) .arg(((product->boil_size * factor) - mashwater + grainabsorbtion + product->eq_lauter_deadspace) * 1.03, 1, 'f', 1)); checkInput(&painter, &y, QString(tr("Target volume in boil kettle: %1 liter (%2 cm below kettle top)")) .arg(product->boil_size * factor * 1.04, 1, 'f', 1) .arg(Utils::kettle_cm(product->boil_size * factor * 1.04, product->eq_kettle_volume, product->eq_kettle_height), 1, 'f', 1), QString(tr("cm"))); checkInput(&painter, &y, QString(tr("Target SG in boil kettle: ")) + strDensity(product->preboil_sg), QString(tr("SG"))); checkInput(&painter, &y, "", QString(tr("pH"))); for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_FWH) { checkLine(&painter, &y, QString(tr("Add %1 gr `%2` hop after sparge")).arg(product->hops.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->hops.at(i).name)); } } if (checkSplit(&painter, &y, 1)) factor = 1; /* Boil, how much space do we need */ int lines = 0; if (product->boil_time == 0) { lines = 3; } else { lines = 5; if (product->brew_cooling_method == CHILLER_TYPE_EMERSION) lines++; for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_BOIL) lines++; } for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_BOIL || product->hops.at(i).useat == HOP_USEAT_AROMA) lines++; } for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_BOIL) lines++; } } qDebug() << "check" << lines << y + (lines * 20) << painter.device()->height(); if ((y + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } checkHeader(&painter, &y, tr("Boil")); if (product->boil_time > 0) { checkLine(&painter, &y, QString(tr("Total boiltime: %1 minutes")).arg(product->boil_time, 1, 'f', 0)); for (int i = product->boil_time; i >= 0; i--) { if (i == 10) { for (int j = 0; j < product->fermentables.size(); j++) { if (product->fermentables.at(j).added == FERMENTABLE_ADDED_BOIL) checkLine(&painter, &y, QString(tr("%1 kg `%2` at 10 minutes before end of boil")) .arg(product->fermentables.at(j).amount * factor, 1, 'f', 3) .arg(product->fermentables.at(j).name)); } if (product->brew_cooling_method == CHILLER_TYPE_EMERSION) checkLine(&painter, &y, QString(tr("Place emersion chiller at 10 minutes before end of boil"))); } for (int j = 0; j < product->hops.size(); j++) { if ((product->hops.at(j).useat == HOP_USEAT_BOIL || product->hops.at(j).useat == HOP_USEAT_AROMA) && product->hops.at(j).time == i) { if (i == 0) checkLine(&painter, &y, QString(tr("%1 gr `%2` at flameout")).arg(product->hops.at(j).amount * 1000 * factor, 1, 'f', 2) .arg(product->hops.at(j).name)); else checkLine(&painter, &y, QString(tr("%1 gr `%2` at %3 minutes before end of boil")) .arg(product->hops.at(j).amount * 1000 * factor, 1, 'f', 2).arg(product->hops.at(j).name).arg(i)); } } for (int j = 0; j < product->miscs.size(); j++) { if (product->miscs.at(j).use_use == MISC_USES_BOIL && product->miscs.at(j).time == i) { QString unit = (product->miscs.at(j).amount_is_weight) ? "gr":"ml"; if (i == 0) checkLine(&painter, &y, QString(tr("%1 %2 `%3` at flameout")) .arg(product->miscs.at(j).amount * 1000 * factor, 1, 'f', 2).arg(unit).arg(product->miscs.at(j).name)); else checkLine(&painter, &y, QString(tr("%1 %2 `%3` at %4 minutes before end of boil")) .arg(product->miscs.at(j).amount * 1000 * factor, 1, 'f', 2).arg(unit).arg(product->miscs.at(j).name).arg(i)); } } } checkInput(&painter, &y, QString(tr("Target volume at end of boil: %1 liter (%2 cm below kettle top)")) .arg(product->batch_size * 1.04 * factor, 1, 'f', 1) .arg(Utils::kettle_cm(product->batch_size * 1.04 * factor, product->eq_kettle_volume, product->eq_kettle_height)), QString(tr("cm"))); checkInput(&painter, &y, QString(tr("Target SG at end of boil: ")) + strDensity(product->est_og3), QString(tr("SG"))); checkInput(&painter, &y, "", QString(tr("pH"))); if (checkSplit(&painter, &y, 2)) factor = 1; } else { checkLine(&painter, &y, QString(tr("This is a `no-boil` recipe"))); } /* Whirlpools and chilling */ lines = 5; if (product->brew_whirlpool9) lines++; if (product->brew_whirlpool7) lines++; if (product->brew_whirlpool6) lines++; if (product->brew_whirlpool2) lines++; for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_WHIRLPOOL) lines++; } if ((y + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } if ((product->brew_whirlpool9 + product->brew_whirlpool7 + product->brew_whirlpool6 + product->brew_whirlpool2) > 0) { checkHeader(&painter, &y, tr("Whirlpool(s) and cooling")); if (product->brew_whirlpool9 > 0) checkLine(&painter, &y, QString(tr("Wirlpool for %1 minutes. Keep temp above 85°C")).arg(product->brew_whirlpool9, 1, 'f', 0)); if (product->brew_whirlpool7 > 0) checkLine(&painter, &y, QString(tr("Wirlpool for %1 minutes. Keep temp between 72 and 79°C")).arg(product->brew_whirlpool7, 1, 'f', 0)); if (product->brew_whirlpool6 > 0) checkLine(&painter, &y, QString(tr("Wirlpool for %1 minutes. Keep temp between 60 and 66°C")).arg(product->brew_whirlpool6, 1, 'f', 0)); for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_WHIRLPOOL) checkLine(&painter, &y, QString(tr("%1 gr `%2` for %3 minutes in the whirlpool")) .arg(product->hops.at(i).amount * 1000 * factor, 1, 'f', 1).arg(product->hops.at(i).name) .arg(product->hops.at(i).time)); } checkLine(&painter, &y, QString(tr("Cool to %1°C")).arg(product->brew_cooling_to, 1, 'f', 1)); if (product->brew_whirlpool2 > 0) checkLine(&painter, &y, QString(tr("Wirlpool for %1 minutes.")).arg(product->brew_whirlpool2, 1, 'f', 0)); } else { checkHeader(&painter, &y, tr("Cooling")); checkLine(&painter, &y, QString(tr("Cool to %1°C")).arg(product->brew_cooling_to, 1, 'f', 1)); } checkLine(&painter, &y, QString(tr("Desinfect fermenter and pump and hoses if needed"))); checkInput(&painter, &y, QString(tr("Transfer wort to fermenter")), QString(tr("Liter"))); if (checkSplit(&painter, &y, 3)) factor = 1; double climate = product->brew_cooling_to; lines = 3; for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { lines++; if (product->yeasts.at(i).type == YEAST_TYPES_KVEIK && (product->yeasts.at(i).pitch_temperature > 0)) lines++; } } if (product->brew_aeration_type > 0) lines++; if (product->brew_fermenter_extrawater > 0) lines++; if ((y + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } double dry = 0; checkHeader(&painter, &y, tr("Yeast pitching and fermentation")); for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { switch (product->yeasts.at(i).form) { case YEAST_FORMS_LIQUID: checkLine(&painter, &y, QString(tr("%1 pack %2, `%3` yeast")).arg(product->yeasts.at(i).amount) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); break; case YEAST_FORMS_DRY: dry += product->yeasts.at(i).amount * 1000 * factor; case YEAST_FORMS_DRIED: checkLine(&painter, &y, QString(tr("%1 gram %2, `%3` yeast")) .arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); break; default: checkLine(&painter, &y, QString(tr("%1 ml %2, `%3` yeast")) .arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 0) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); break; } if (product->yeasts.at(i).type == YEAST_TYPES_KVEIK && (product->yeasts.at(i).pitch_temperature > 0)) { checkLine(&painter, &y, QString(tr("Pitch yeast at %1°C")).arg(product->yeasts.at(i).pitch_temperature, 1, 'f', 1)); climate = product->yeasts.at(i).pitch_temperature; } } } if (dry > 0) { checkLine(&painter, &y, QString(tr("Pitch yeast dry into the wort"))); } else { if (product->starter_enable && product->prop_volume[0]) checkLine(&painter, &y, QString(tr("Add decanted yeast starter"))); else checkLine(&painter, &y, QString(tr("Add the yeast"))); } if (product->brew_fermenter_extrawater) checkLine(&painter, &y, QString(tr("Add %1 liter water in the fermenter")).arg(product->brew_fermenter_extrawater * factor, 1, 'f', 1)); if (product->brew_aeration_type > 0) checkLine(&painter, &y, QString(tr("Aerate %1 minutes with %2")).arg(product->brew_aeration_time) .arg((product->brew_aeration_type == 1) ? "air":"oxygen")); checkLine(&painter, &y, QString(tr("Set fermentation start temperature to %1°C")).arg(climate, 1, 'f', 1)); checkLine(&painter, &y, QString(tr("Start fermentation"))); /* During primary fermentation */ lines = 0; for (int i = 0; i < product->fermentables.size(); i++) if (product->fermentables.at(i).added == FERMENTABLE_ADDED_FERMENTATION) lines++; for (int i = 0; i < product->miscs.size(); i++) if (product->miscs.at(i).use_use == MISC_USES_PRIMARY) lines++; if (lines) { if ((y + 20 + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } checkHeader(&painter, &y, tr("Primary fermentation")); for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_FERMENTATION) checkLine(&painter, &y, QString(tr("Add %1 kg `%2` on day 3 or 4")).arg(product->fermentables.at(i).amount * factor, 1, 'f', 3) .arg(product->fermentables.at(i).name)); } for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_PRIMARY) { QString unit = (product->miscs.at(i).amount_is_weight) ? "gr":"ml"; checkLine(&painter, &y, QString(tr("Add %1 %2 `%3` on day 3 or 4")).arg(product->miscs.at(i).amount * 1000 * factor, 1, 'f', 3) .arg(unit).arg(product->miscs.at(i).name)); } } } if (checkSplit(&painter, &y, 4)) factor = 1; /* During secondary fermentation, yeast */ lines = 0; for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_SECONDARY) lines++; if (product->yeasts.at(i).harvest_time > 0) lines++; } if (lines) { if ((y + 20 + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } checkHeader(&painter, &y, tr("Secondary fermentation")); for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_SECONDARY) { if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) { checkLine(&painter, &y, QString(tr("Add %1 pack %2, `%3` yeast (with starter if needed)")) .arg(product->yeasts.at(i).amount).arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } else if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { checkLine(&painter, &y, QString(tr("Add %1 gram %2, `%3`")).arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } else { checkLine(&painter, &y, QString(tr("Add %1 gram %2, `%3` yeast (with starter if needed)")) .arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } } if (product->yeasts.at(i).harvest_time > 0) { checkLine(&painter, &y, QString(tr("After %1 hours harvest yeast from the %2")).arg(product->yeasts.at(i).harvest_time) .arg((product->yeasts.at(i).harvest_top > 0) ? "top":"bottom")); } } } if (checkSplit(&painter, &y, 5)) factor = 1; /* During tertiary fermentation */ lines = 0; for (int i = 0; i < product->fermentables.size(); i++) if (product->fermentables.at(i).added == FERMENTABLE_ADDED_LAGERING) lines++; for (int i = 0; i < product->hops.size(); i++) if (product->hops.at(i).useat == HOP_USEAT_DRY_HOP) lines++; for (int i = 0; i < product->miscs.size(); i++) if (product->miscs.at(i).use_use == MISC_USES_SECONDARY) lines++; for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_TERTIARY) lines++; } if (lines) { if ((y + 20 + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } checkHeader(&painter, &y, tr("Tertiary fermentation")); for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_LAGERING) checkLine(&painter, &y, QString(tr("Add %1 kg `%2`")).arg(product->fermentables.at(i).amount * factor, 1, 'f', 3) .arg(product->fermentables.at(i).name)); } for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_DRY_HOP) { checkLine(&painter, &y, QString(tr("Add %1 gram `%2` for %3 days")).arg(product->hops.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->hops.at(i).name).arg(product->hops.at(i).time / 1440)); } } for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_TERTIARY) { if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) { checkLine(&painter, &y, QString(tr("Add %1 pack %2, `%3` yeast (with starter if needed)")) .arg(product->yeasts.at(i).amount).arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } else if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { checkLine(&painter, &y, QString(tr("Add %1 gram %2, `%3`")).arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } else { checkLine(&painter, &y, QString(tr("Add %1 ml %2, `%3` yeast (with starter if needed)")) .arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } } } for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_SECONDARY) { QString unit = (product->miscs.at(i).amount_is_weight) ? "gr":"ml"; checkLine(&painter, &y, QString(tr("Add %1 %2 `%3` for %4 days")).arg(product->miscs.at(i).amount * 1000.0 * factor, 1, 'f', 2) .arg(unit).arg(product->miscs.at(i).name).arg(product->miscs.at(i).time / 1440)); } } } if (checkSplit(&painter, &y, 6)) factor = 1; /* During packaging */ lines = 0; for (int i = 0; i < product->fermentables.size(); i++) if (product->fermentables.at(i).added >= FERMENTABLE_ADDED_BOTTLE) lines++; for (int i = 0; i < product->miscs.size(); i++) if (product->miscs.at(i).use_use == MISC_USES_BOTTLING) lines++; for (int i = 0; i < product->yeasts.size(); i++) if (product->yeasts.at(i).use == YEAST_USE_BOTTLE) lines++; if (lines) { if ((y + 20 + (lines * 20)) > painter.device()->height()) { printer->newPage(); printHeader(&painter); y = 120; } else { y += 20; } checkHeader(&painter, &y, tr("Packaging")); for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_BOTTLE) checkLine(&painter, &y, QString(tr("Bottling add %1 kg `%2` with %3 liter water")) .arg(product->fermentables.at(i).amount * factor, 1, 'f', 3) .arg(product->fermentables.at(i).name).arg(product->bottle_priming_water * factor, 1, 'f', 3)); if (product->fermentables.at(i).added == FERMENTABLE_ADDED_KEGS) checkLine(&painter, &y, QString(tr("Kegging add %1 kg `%2` with %3 liter water")) .arg(product->fermentables.at(i).amount * factor, 1, 'f', 3) .arg(product->fermentables.at(i).name).arg(product->keg_priming_water * factor, 1, 'f', 3)); } for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_BOTTLE) { if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) { checkLine(&painter, &y, QString(tr("Add %1, `%2` as bottle yeast")) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } else if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { checkLine(&painter, &y, QString(tr("Add %1 gram %2, `%3` as bottle yeast")) .arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } else { checkLine(&painter, &y, QString(tr("Add %1 ml %2, `%3` as bottle yeast")) .arg(product->yeasts.at(i).amount * 1000 * factor, 1, 'f', 1) .arg(product->yeasts.at(i).product_id).arg(product->yeasts.at(i).name)); } } } for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_BOTTLING) { QString unit = (product->miscs.at(i).amount_is_weight) ? "gr":"ml"; checkLine(&painter, &y, QString(tr("Add %1 %2 `%3` during bottling")).arg(product->miscs.at(i).amount * 1000 * factor, 1, 'f', 2) .arg(unit).arg(product->miscs.at(i).name)); } } } } painter.end(); } void PrinterDialog::checkHeader(QPainter *painter, qreal *y, QString text) { painter->setFont(QFont("Arial", 10, QFont::Bold)); painter->setPen(Qt::black); painter->drawText(50, *y, 700, 20, Qt::AlignLeft, text); painter->setFont(QFont("Arial", 10, QFont::Normal)); *y += 20; } /* * Draw a checkbox and text. */ void PrinterDialog::checkLine(QPainter *painter, qreal *y, QString text) { painter->drawRect(24, *y, 16, 16); painter->drawText(50, *y,630, 20, Qt::AlignLeft, text); *y += 20; } void PrinterDialog::checkInput(QPainter *painter, qreal *y, QString text, QString prompt) { if (text != "") { painter->drawRect(24, *y, 16, 16); painter->drawText(50, *y,480, 20, Qt::AlignLeft, text); } painter->drawText(515, *y, 150, 20, Qt::AlignRight, QString(tr("Measured:")) + QString(" _________")); painter->drawText(675, *y, 60, 20, Qt::AlignLeft, prompt); *y += 20; } bool PrinterDialog::checkSplit(QPainter *painter, qreal *y, int moment) { if (product->divide_type && product->divide_type == moment) { *y += 20; painter->setFont(QFont("Helvetica", 14, QFont::Bold)); painter->drawText(20, *y, 715, 20, Qt::AlignCenter, QString(tr("%1 split the batch here!")).arg(QCoreApplication::translate("Splitter", g_prod_split[product->divide_type]))); painter->setFont(QFont("Arial", 10, QFont::Normal)); *y += 26; return true; } return false; } QString PrinterDialog::strDiff(double v1, double v2, int decimals, QString suffix) { return QString("%1%2%3").arg((v2 > v1) ? "+":"").arg(v2 - v1, 1, 'f', decimals).arg(suffix); } QString PrinterDialog::strDensity(double density) { return QString("%1 SG %2°Brix %3°P").arg(density, 1, 'f', 3).arg(Utils::sg_to_brix(density), 1, 'f', 1).arg(Utils::sg_to_plato(density), 1, 'f', 1); } void PrinterDialog::printHeader(QPainter *painter) { QPixmap outPixmap = QPixmap(); outPixmap.loadFromData(my_logoByteArray); int w = outPixmap.width(); int h = outPixmap.height(); /* Make sure to keep the logo aspect ratio */ if (w == h) { painter->drawPixmap(20, 0, 100, 100, outPixmap); } else if (w > h) { painter->drawPixmap(20, 0, 100, (h * 100) / w, outPixmap); } else { painter->drawPixmap(20, 0, (w * 100) / h, 100, outPixmap); } /* The fat header line */ painter->setFont(QFont("Helvetica",18, QFont::Bold)); if (p_job == PR_SUPPLIES) { painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Inventory") + " " + my_brewery_name); } else if (p_job == PR_YEASTBANK) { painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Yeastbank") + " " + my_brewery_name); } else if (p_job == PR_RECIPE) { painter->drawText(140, 0, 500, 40, Qt::AlignLeft, recipe->name); } else if (p_job == PR_PRODUCT || p_job == PR_CHECKLIST) { painter->drawText(140, 0, 500, 40, Qt::AlignLeft, product->code + " " + product->name); } else { painter->drawText(140, 0, 500, 40, Qt::AlignLeft, "?? " + my_brewery_name); } /* The first normal header line */ painter->setFont(QFont("Helvetica",10, QFont::Normal)); painter->drawText(140,35, 80, 20, Qt::AlignLeft, tr("Date and time")); painter->drawText(220,35, 400, 20, Qt::AlignLeft, ": " + QDateTime::currentDateTime().toString("dd-MMM-yyyy hh:mm")); if (p_job == PR_RECIPE) { painter->drawText(140,55, 80, 20, Qt::AlignLeft, tr("Beer style")); painter->drawText(220,55, 400, 20, Qt::AlignLeft, ": " + recipe->st_name); } if (p_job == PR_PRODUCT || p_job == PR_CHECKLIST) { painter->drawText(140,55, 80, 20, Qt::AlignLeft, tr("Beer style")); painter->drawText(220,55, 400, 20, Qt::AlignLeft, ": " + product->st_name); } /* The report itself may print more lines from y = 55. */ }