Add product archive tree by date.

Sun, 22 May 2022 10:22:22 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 22 May 2022 10:22:22 +0200
changeset 234
51aea8b798f0
parent 233
baf666307ebb
child 235
57dba736d10b

Add product archive tree by date.

CMakeLists.txt file | annotate | diff | comparison | revisions
src/MainWindow.cpp file | annotate | diff | comparison | revisions
src/MainWindow.h file | annotate | diff | comparison | revisions
src/ProdOnDate.cpp file | annotate | diff | comparison | revisions
src/ProdOnDate.h file | annotate | diff | comparison | revisions
src/ProdOnTree.cpp file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sat May 21 21:44:24 2022 +0200
+++ b/CMakeLists.txt	Sun May 22 10:22:22 2022 +0200
@@ -163,6 +163,7 @@
     ${SRCDIR}/ProdInprod.cpp
     ${SRCDIR}/ProdOnName.cpp
     ${SRCDIR}/ProdOnCode.cpp
+    ${SRCDIR}/ProdOnDate.cpp
     ${SRCDIR}/ProdOnTree.cpp
     ${SRCDIR}/EditProduct.cpp
     ${SRCDIR}/Setup.cpp
@@ -204,6 +205,7 @@
     ${SRCDIR}/ProdInprod.h
     ${SRCDIR}/ProdOnName.h
     ${SRCDIR}/ProdOnCode.h
+    ${SRCDIR}/ProdOnDate.h
     ${SRCDIR}/ProdOnTree.h
     ${SRCDIR}/EditProduct.h
     ${SRCDIR}/Setup.h
--- a/src/MainWindow.cpp	Sat May 21 21:44:24 2022 +0200
+++ b/src/MainWindow.cpp	Sun May 22 10:22:22 2022 +0200
@@ -27,6 +27,7 @@
 #include "ProdInprod.h"
 #include "ProdOnName.h"
 #include "ProdOnCode.h"
+#include "ProdOnDate.h"
 #include "ProdOnTree.h"
 #include "ProfileWaters.h"
 #include "ProfileMashs.h"
@@ -576,6 +577,30 @@
 }
 
 
+void MainWindow::fromProdOnDate()
+{
+    qDebug() << Q_FUNC_INFO;
+    ui->mainStack->setCurrentIndex(-1);
+    ui->mainStack->removeWidget(ProdOnDateWindow);
+    delete ProdOnDateWindow;
+    setWindowTitle( QString("BMSapp - %1").arg(VERSIONSTRING) );
+    ui->menuBar->setVisible(true);
+    statusBar()->clearMessage();
+}
+
+
+void MainWindow::on_actionOn_Date_triggered()
+{
+    qDebug() << Q_FUNC_INFO;
+    ProdOnDateWindow = new ProdOnDate(this);
+    int index = ui->mainStack->count();
+    ui->mainStack->addWidget(ProdOnDateWindow);
+    ui->mainStack->setCurrentIndex(index);
+    setWindowTitle(QString("BMSapp - %1 - Products archive on date").arg(VERSIONSTRING));
+    ui->menuBar->setVisible(false);
+}
+
+
 void MainWindow::fromProdOnTree()
 {
     qDebug() << Q_FUNC_INFO;
--- a/src/MainWindow.h	Sat May 21 21:44:24 2022 +0200
+++ b/src/MainWindow.h	Sun May 22 10:22:22 2022 +0200
@@ -12,6 +12,7 @@
 #include "ProdInprod.h"
 #include "ProdOnName.h"
 #include "ProdOnCode.h"
+#include "ProdOnDate.h"
 #include "ProdOnTree.h"
 #include "ProfileWaters.h"
 #include "ProfileMashs.h"
@@ -113,6 +114,7 @@
     ProdInprod *ProdInprodWindow;
     ProdOnName *ProdOnNameWindow;
     ProdOnCode *ProdOnCodeWindow;
+    ProdOnDate *ProdOnDateWindow;
     ProdOnTree *ProdOnTreeWindow;
     ProfileWaters *ProfileWatersWindow;
     ProfileMashs *ProfileMashsWindow;
@@ -125,6 +127,7 @@
     void on_actionProd_inprod_triggered();
     void on_actionOn_Name_triggered();
     void on_actionOn_Code_triggered();
+    void on_actionOn_Date_triggered();
     void on_actionOn_Tree_triggered();
     void on_actionRecipes_triggered();
     void on_actionSuppliers_triggered();
@@ -155,6 +158,7 @@
     void fromProdInprod();
     void fromProdOnName();
     void fromProdOnCode();
+    void fromProdOnDate();
     void fromProdOnTree();
     void fromProfileWaters();
     void fromProfileMashs();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ProdOnDate.cpp	Sun May 22 10:22:22 2022 +0200
@@ -0,0 +1,399 @@
+/**
+ * ProdOnDate.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 "ProdOnDate.h"
+#include "MainWindow.h"
+#include "EditProduct.h"
+#include "config.h"
+#include "Utils.h"
+
+
+ProdOnDate::ProdOnDate(QWidget *parent) : QDialog(parent)
+{
+    qDebug() << "ProdOnDate start";
+
+    gridLayout = new QGridLayout(this);
+    gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+    treeWidget = new QTreeWidget(this);
+    treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
+    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+    sizePolicy.setHorizontalStretch(0);
+    sizePolicy.setVerticalStretch(0);
+    sizePolicy.setHeightForWidth(treeWidget->sizePolicy().hasHeightForWidth());
+    treeWidget->setSizePolicy(sizePolicy);
+    gridLayout->addWidget(treeWidget, 0, 0, 1, 1);
+
+    recipeBox = new QGroupBox(this);
+    recipeBox->setObjectName(QString::fromUtf8("recipeBox"));
+    QSizePolicy sizePolicy3(QSizePolicy::Preferred, QSizePolicy::Expanding);
+    sizePolicy3.setHorizontalStretch(0);
+    sizePolicy3.setVerticalStretch(0);
+    sizePolicy3.setHeightForWidth(recipeBox->sizePolicy().hasHeightForWidth());
+    recipeBox->setSizePolicy(sizePolicy3);
+    recipeBox->setMinimumSize(QSize(500, 0));
+
+    volumeLabel = new QLabel(recipeBox);
+    volumeLabel->setObjectName(QString::fromUtf8("volumeLabel"));
+    volumeLabel->setGeometry(QRect(100, 30, 141, 20));
+    volumeLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    volumeLabel->setText(tr("Brew volume:"));
+    efficiencyLabel = new QLabel(recipeBox);
+    efficiencyLabel->setObjectName(QString::fromUtf8("efficiencyLabel"));
+    efficiencyLabel->setGeometry(QRect(100, 120, 141, 20));
+    efficiencyLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    efficiencyLabel->setText(tr("Brewhouse efficiency:"));
+    boilvolumeLabel = new QLabel(recipeBox);
+    boilvolumeLabel->setObjectName(QString::fromUtf8("boilvolumeLabel"));
+    boilvolumeLabel->setGeometry(QRect(100, 60, 141, 20));
+    boilvolumeLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    boilvolumeLabel->setText(tr("Boil volume:"));
+    boiltimeLabel = new QLabel(recipeBox);
+    boiltimeLabel->setObjectName(QString::fromUtf8("boiltimeLabel"));
+    boiltimeLabel->setGeometry(QRect(100, 90, 141, 20));
+    boiltimeLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    boiltimeLabel->setText(tr("Boil time:"));
+    ogLabel = new QLabel(recipeBox);
+    ogLabel->setObjectName(QString::fromUtf8("ogLabel"));
+    ogLabel->setGeometry(QRect(100, 150, 141, 20));
+    ogLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    ogLabel->setText(tr("Original gravity:"));
+    fgLabel = new QLabel(recipeBox);
+    fgLabel->setObjectName(QString::fromUtf8("fgLabel"));
+    fgLabel->setGeometry(QRect(100, 180, 141, 20));
+    fgLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    fgLabel->setText(tr("Final gravity:"));
+    abvLabel = new QLabel(recipeBox);
+    abvLabel->setObjectName(QString::fromUtf8("abvLabel"));
+    abvLabel->setGeometry(QRect(100, 210, 141, 20));
+    abvLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    abvLabel->setText(tr("Alcohol by Volume:"));
+    co2Label = new QLabel(recipeBox);
+    co2Label->setObjectName(QString::fromUtf8("co2Label"));
+    co2Label->setGeometry(QRect(100, 240, 141, 20));
+    co2Label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    co2Label->setText(tr("CO2 Volume:"));
+    colorLabel = new QLabel(recipeBox);
+    colorLabel->setObjectName(QString::fromUtf8("colorLabel"));
+    colorLabel->setGeometry(QRect(100, 270, 141, 20));
+    colorLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    colorLabel->setText(tr("Color EBC:"));
+    colormethodLabel = new QLabel(recipeBox);
+    colormethodLabel->setObjectName(QString::fromUtf8("colormethodLabel"));
+    colormethodLabel->setGeometry(QRect(100, 300, 141, 20));
+    colormethodLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    colormethodLabel->setText(tr("Color method:"));
+    ibuLabel = new QLabel(recipeBox);
+    ibuLabel->setObjectName(QString::fromUtf8("ibuLabel"));
+    ibuLabel->setGeometry(QRect(100, 330, 141, 20));
+    ibuLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    ibuLabel->setText(tr("Bitterness IBU:"));
+    ibumethodLabel = new QLabel(recipeBox);
+    ibumethodLabel->setObjectName(QString::fromUtf8("ibumethodLabel"));
+    ibumethodLabel->setGeometry(QRect(100, 360, 141, 20));
+    ibumethodLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    ibumethodLabel->setText(tr("Bitterness method:"));
+    remarksLabel = new QLabel(recipeBox);
+    remarksLabel->setObjectName(QString::fromUtf8("remarksLabel"));
+    remarksLabel->setGeometry(QRect(30, 390, 101, 20));
+    remarksLabel->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter);
+    remarksLabel->setText(tr("Remarks:"));
+
+    volumeEdit = new QDoubleSpinBox(recipeBox);
+    volumeEdit->setObjectName(QString::fromUtf8("volumeEdit"));
+    volumeEdit->setGeometry(QRect(260, 30, 111, 24));
+    volumeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    volumeEdit->setReadOnly(true);
+    volumeEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    volumeEdit->setDecimals(1);
+    volumeEdit->setMaximum(100000.000000000000000);
+    volumeEdit->setSuffix(tr(" L"));
+    boilvolumeEdit = new QDoubleSpinBox(recipeBox);
+    boilvolumeEdit->setObjectName(QString::fromUtf8("boilvolumeEdit"));
+    boilvolumeEdit->setGeometry(QRect(260, 60, 111, 24));
+    boilvolumeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    boilvolumeEdit->setReadOnly(true);
+    boilvolumeEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    boilvolumeEdit->setDecimals(1);
+    boilvolumeEdit->setMaximum(100000.000000000000000);
+    boilvolumeEdit->setSuffix(tr(" L"));
+    efficiencyEdit = new QDoubleSpinBox(recipeBox);
+    efficiencyEdit->setObjectName(QString::fromUtf8("efficiencyEdit"));
+    efficiencyEdit->setGeometry(QRect(260, 120, 111, 24));
+    efficiencyEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    efficiencyEdit->setReadOnly(true);
+    efficiencyEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    efficiencyEdit->setDecimals(1);
+    efficiencyEdit->setMaximum(100.000000000000000);
+    efficiencyEdit->setSuffix(tr(" %"));
+    ogEdit = new QDoubleSpinBox(recipeBox);
+    ogEdit->setObjectName(QString::fromUtf8("ogEdit"));
+    ogEdit->setGeometry(QRect(260, 150, 111, 24));
+    ogEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    ogEdit->setReadOnly(true);
+    ogEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    ogEdit->setDecimals(3);
+    ogEdit->setMaximum(1.200000000000000);
+    fgEdit = new QDoubleSpinBox(recipeBox);
+    fgEdit->setObjectName(QString::fromUtf8("fgEdit"));
+    fgEdit->setGeometry(QRect(260, 180, 111, 24));
+    fgEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    fgEdit->setReadOnly(true);
+    fgEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    fgEdit->setDecimals(3);
+    fgEdit->setMaximum(1.200000000000000);
+    abvEdit = new QDoubleSpinBox(recipeBox);
+    abvEdit->setObjectName(QString::fromUtf8("abvEdit"));
+    abvEdit->setGeometry(QRect(260, 210, 111, 24));
+    abvEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    abvEdit->setReadOnly(true);
+    abvEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    abvEdit->setDecimals(1);
+    abvEdit->setMaximum(100.000000000000000);
+    abvEdit->setSuffix(tr(" %"));
+    co2Edit = new QDoubleSpinBox(recipeBox);
+    co2Edit->setObjectName(QString::fromUtf8("co2Edit"));
+    co2Edit->setGeometry(QRect(260, 240, 111, 24));
+    co2Edit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    co2Edit->setReadOnly(true);
+    co2Edit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    co2Edit->setDecimals(2);
+    co2Edit->setMaximum(100.000000000000000);
+    boiltimeEdit = new QSpinBox(recipeBox);
+    boiltimeEdit->setObjectName(QString::fromUtf8("boiltimeEdit"));
+    boiltimeEdit->setGeometry(QRect(260, 90, 111, 24));
+    boiltimeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    boiltimeEdit->setReadOnly(true);
+    boiltimeEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    boiltimeEdit->setMaximum(1440);
+    boiltimeEdit->setSuffix(tr(" min"));
+    colorEdit = new QSpinBox(recipeBox);
+    colorEdit->setObjectName(QString::fromUtf8("colorEdit"));
+    colorEdit->setGeometry(QRect(260, 270, 111, 24));
+    colorEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    colorEdit->setReadOnly(true);
+    colorEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    colorEdit->setMaximum(1440);
+    ibuEdit = new QSpinBox(recipeBox);
+    ibuEdit->setObjectName(QString::fromUtf8("ibuEdit"));
+    ibuEdit->setGeometry(QRect(260, 330, 111, 24));
+    ibuEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+    ibuEdit->setReadOnly(true);
+    ibuEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+    ibuEdit->setMaximum(1440);
+    remarksEdit = new QPlainTextEdit(recipeBox);
+    remarksEdit->setObjectName(QString::fromUtf8("remarksEdit"));
+    remarksEdit->setGeometry(QRect(30, 410, 441, 111));
+    remarksEdit->setReadOnly(true);
+    colormethodEdit = new QLineEdit(recipeBox);
+    colormethodEdit->setObjectName(QString::fromUtf8("colormethodEdit"));
+    colormethodEdit->setGeometry(QRect(260, 300, 113, 23));
+    colormethodEdit->setReadOnly(true);
+    ibumethodEdit = new QLineEdit(recipeBox);
+    ibumethodEdit->setObjectName(QString::fromUtf8("ibumethodEdit"));
+    ibumethodEdit->setGeometry(QRect(260, 360, 113, 23));
+    ibumethodEdit->setReadOnly(true);
+
+    gridLayout->addWidget(recipeBox, 0, 1, 2, 1);
+
+    groupBox = new QGroupBox(this);
+    groupBox->setObjectName(QString::fromUtf8("groupBox"));
+    groupBox->setEnabled(true);
+    groupBox->setFlat(false);
+    horizontalLayout = new QHBoxLayout(groupBox);
+    horizontalLayout->setSpacing(6);
+    horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
+    horizontalLayout->setContentsMargins(0, 0, 0, 0);
+
+    quitButton = new QPushButton(groupBox);
+    quitButton->setObjectName(QString::fromUtf8("quitButton"));
+    quitButton->setMinimumSize(QSize(80, 24));
+    quitButton->setText(tr("Quit"));
+    QIcon icon;
+    icon.addFile(QString::fromUtf8(":icons/silk/door_out.png"), QSize(), QIcon::Normal, QIcon::Off);
+    quitButton->setIcon(icon);
+    horizontalLayout->addWidget(quitButton, 0, Qt::AlignLeft);
+
+    openButton = new QPushButton(groupBox);
+    openButton->setObjectName(QString::fromUtf8("openButton"));
+    openButton->setMinimumSize(QSize(80, 24));
+    openButton->setText(tr("Open"));
+    QIcon icon1;
+    icon1.addFile(QString::fromUtf8(":icons/silk/cup_go.png"), QSize(), QIcon::Normal, QIcon::Off);
+    openButton->setIcon(icon1);
+    horizontalLayout->addWidget(openButton, 0, Qt::AlignRight);
+
+    gridLayout->addWidget(groupBox, 1, 0, 1, 1);
+
+    record = -2;
+    connect(quitButton, SIGNAL(clicked()), parent, SLOT(fromProdOnDate()));
+    connect(openButton, SIGNAL(clicked()), this, SLOT(on_openButton_clicked()));
+    connect(this, SIGNAL(setStatus(QString)), parent, SLOT(statusMsg(QString)));
+
+    treeWidget->setColumnCount(4);
+    treeWidget->setHeaderLabels({ tr("Year"), tr("Date"), tr("Code"), tr("Product") });
+    treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+    treeWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+    connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(on_item_clicked(QTreeWidgetItem*, int)));
+    connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(on_item_doubleclicked(QTreeWidgetItem*, int)));
+
+    emit refreshTable();
+}
+
+
+void ProdOnDate::refreshTable()
+{
+    QTreeWidgetItem *year, *name;
+
+    qDebug() << "ProdOnDate reload";
+
+    treeWidget->clear();
+    bool first = true;
+
+    QSqlQuery query0;
+    query0.prepare("SELECT DISTINCT YEAR(brew_date_start) AS YEAR FROM products WHERE stage='11' ORDER BY YEAR(brew_date_start) DESC");
+    query0.exec();
+    while (query0.next()) {
+	year = new QTreeWidgetItem( QStringList( { query0.value(0).toString() } ));
+	treeWidget->addTopLevelItem( year );
+	year->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
+
+	QSqlQuery query1;
+	query1.prepare("SELECT name,record,code,brew_date_start FROM products WHERE stage='11' AND YEAR(brew_date_start)=:theyear ORDER BY code,name");
+        query1.bindValue(":theyear", query0.value(0).toString());
+        query1.exec();
+	while (query1.next()) {
+	    name = new QTreeWidgetItem(QStringList({ "", query1.value("brew_date_start").toDate().toString("dd MMM yyyy"),
+				    query1.value("code").toString(), query1.value("name").toString(), query1.value("record").toString() }));
+	    year->addChild( name );
+	}
+	if (first)
+	    treeWidget->expandItem(year);
+	first = false;
+    }
+
+    QSqlQuery query("SELECT record FROM products WHERE stage='11'");
+    emit setStatus(QString(tr("Total items: %1")).arg(query.size()));
+
+    showRecipe();
+}
+
+
+void ProdOnDate::showRecipe()
+{
+    QString w;
+
+    qDebug() << "showRecipe" << record;
+
+    const QStringList c_method({"Morey", "Mosher", "Daniels", "Halberstadt", "Naudts" });
+    const QStringList i_method({"Tinseth", "Rager", "Daniels" });
+
+    /*
+     * If no recipe is "pre" selected, return.
+     */
+    if (record < 1) {
+    	recipeBox->setEnabled(false);
+	return;
+    }
+
+    /*
+     * Fill in basic details of the selected recipe.
+     */
+    QSqlQuery query;
+    query.prepare("SELECT batch_size,boil_size,boil_time,efficiency,est_og,est_fg,est_abv,est_color,color_method,est_ibu,ibu_method,est_carb,notes,name,code "
+		  "FROM products WHERE record=:record");
+    query.bindValue(":record", record);
+    query.exec();
+    if (query.size() == 1) {
+	query.first();
+	volumeEdit->setValue(query.value(0).toDouble());
+	boilvolumeEdit->setValue(query.value(1).toDouble());
+	boiltimeEdit->setValue(query.value(2).toInt());
+	efficiencyEdit->setValue(query.value(3).toDouble());
+	ogEdit->setValue(query.value(4).toDouble());
+	fgEdit->setValue(query.value(5).toDouble());
+	abvEdit->setValue(query.value(6).toInt());
+	colorEdit->setValue(query.value(7).toInt());
+	colorEdit->setStyleSheet(Utils::ebc_to_style(query.value(7).toInt()));
+	colormethodEdit->setText(c_method[query.value(8).toInt()]);
+	ibuEdit->setValue(query.value(9).toInt());
+	ibumethodEdit->setText(i_method[query.value(10).toInt()]);
+	co2Edit->setValue(query.value(11).toDouble());
+	remarksEdit->setPlainText(query.value(12).toString());
+	recipeBox->setTitle(query.value(14).toString() + " - " + query.value(13).toString());
+	recipeBox->setEnabled(true);
+    } else {
+	qDebug() << "Error getting product record" << record;
+    }
+}
+
+
+ProdOnDate::~ProdOnDate() {}
+
+
+void ProdOnDate::edit(int recno)
+{
+    EditProduct dialog(recno, this);
+    /* Signal from editor if a refresh is needed */
+    connect(&dialog, SIGNAL(entry_changed()), this, SLOT(refreshTable()));
+    dialog.setModal(true);
+    dialog.exec();
+}
+
+
+void ProdOnDate::on_openButton_clicked()
+{
+    if (record > 0)
+    	edit(record);
+}
+
+
+void ProdOnDate::on_item_clicked(QTreeWidgetItem *item, int col)
+{
+    record = -2; // Invalid
+
+    if (col == 0) {
+        if (item->isExpanded()) {
+	    treeWidget->collapseItem(item);
+	} else {
+	    treeWidget->expandItem(item);
+	}
+    } else if (col > 0) {
+    	/*
+    	 * if a product line is selected then:
+	 *   item column 1 contains the product date,
+	 *   item column 2 contains the product code,
+    	 *   item column 3 contains the product name,
+    	 *   item column 4 contains the product record number.
+    	 */
+    	if (item->text(4).toInt() > 0) {
+	    if (record != item->text(4).toInt()) {
+	    	record = item->text(4).toInt();
+	    	showRecipe();
+	    }
+    	}
+    }
+}
+
+
+void ProdOnDate::on_item_doubleclicked(QTreeWidgetItem *item, int col)
+{
+    if ((col > 0) && (item->text(4).toInt() > 0)) {
+	edit(item->text(4).toInt());
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ProdOnDate.h	Sun May 22 10:22:22 2022 +0200
@@ -0,0 +1,62 @@
+#ifndef _PRODONDATE_H
+#define _PRODONDATE_H
+
+#include <QDialog>
+#include <QtWidgets/QGridLayout>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QListView>
+#include <QtWidgets/QTreeWidget>
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QPlainTextEdit>
+#include <QtWidgets/QDoubleSpinBox>
+#include <QtWidgets/QSpinBox>
+
+namespace Ui {
+class ProdOnDate;
+}
+
+class ProdOnDate : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit ProdOnDate(QWidget *parent = nullptr);
+    ~ProdOnDate();
+
+signals:
+    void setStatus(QString);
+
+private slots:
+    void on_openButton_clicked();
+    void on_item_clicked(QTreeWidgetItem *, int);
+    void on_item_doubleclicked(QTreeWidgetItem *, int);
+    void refreshTable(void);
+
+private:
+    QGridLayout *gridLayout;
+    QTreeWidget *treeWidget;
+    QGroupBox *groupBox, *recipeBox;
+    QHBoxLayout *horizontalLayout;
+    QPushButton *quitButton, *openButton;
+    QLabel *volumeLabel, *efficiencyLabel, *boilvolumeLabel;
+    QLabel *boiltimeLabel, *ogLabel, *fgLabel;
+    QLabel *abvLabel, *co2Label, *colorLabel;
+    QLabel *colormethodLabel, *ibuLabel, *ibumethodLabel;
+    QLabel *remarksLabel;
+    QDoubleSpinBox *volumeEdit, *boilvolumeEdit;
+    QDoubleSpinBox *efficiencyEdit, *ogEdit, *fgEdit;
+    QDoubleSpinBox *abvEdit, *co2Edit;
+    QSpinBox *boiltimeEdit, *colorEdit, *ibuEdit;
+    QPlainTextEdit *remarksEdit;
+    QLineEdit *colormethodEdit, *ibumethodEdit;
+    int	record;
+
+    void edit(int recno);
+    void showRecipe();
+};
+
+#endif
--- a/src/ProdOnTree.cpp	Sat May 21 21:44:24 2022 +0200
+++ b/src/ProdOnTree.cpp	Sun May 22 10:22:22 2022 +0200
@@ -242,8 +242,8 @@
     connect(openButton, SIGNAL(clicked()), this, SLOT(on_openButton_clicked()));
     connect(this, SIGNAL(setStatus(QString)), parent, SLOT(statusMsg(QString)));
 
-    treeWidget->setColumnCount(4);
-    treeWidget->setHeaderLabels({ tr("Guide"), tr("Group"), tr("Style"), tr("Product") });
+    treeWidget->setColumnCount(5);
+    treeWidget->setHeaderLabels({ tr("Guide"), tr("Group"), tr("Style"), tr("Code"), tr("Product") });
     treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
     treeWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
 
@@ -298,7 +298,7 @@
             	query3.exec();
 		while (query3.next()) {
 		    name = new QTreeWidgetItem(QStringList({ "", "", "",
-					    query3.value(2).toString() + " - " + query3.value(0).toString(), query3.value(1).toString() }));
+					    query3.value(2).toString(), query3.value(0).toString(), query3.value(1).toString() }));
 		    st_name->addChild( name );
 		}
 	    }
@@ -335,7 +335,7 @@
      * Fill in basic details of the selected recipe.
      */
     QSqlQuery query;
-    query.prepare("SELECT batch_size,boil_size,boil_time,efficiency,est_og,est_fg,est_abv,est_color,color_method,est_ibu,ibu_method,est_carb,notes,name "
+    query.prepare("SELECT batch_size,boil_size,boil_time,efficiency,est_og,est_fg,est_abv,est_color,color_method,est_ibu,ibu_method,est_carb,notes,name,code "
 		  "FROM products WHERE record=:record");
     query.bindValue(":record", record);
     query.exec();
@@ -355,7 +355,7 @@
 	ibumethodEdit->setText(i_method[query.value(10).toInt()]);
 	co2Edit->setValue(query.value(11).toDouble());
 	remarksEdit->setPlainText(query.value(12).toString());
-	recipeBox->setTitle(query.value(13).toString());
+	recipeBox->setTitle(query.value(14).toString() + " - " + query.value(13).toString());
 	recipeBox->setEnabled(true);
     } else {
 	qDebug() << "Error getting product record" << record;
@@ -405,15 +405,16 @@
 	} else {
 	    item->setExpanded(true);
 	}
-    } else if (col == 3) {
+    } else if ((col == 3) || (col == 4)) {
     	/*
     	 * if a recipe name is selected then:
-    	 *   item column 3 contains the recipe name,
-    	 *   item column 4 contains the recipe record number.
+    	 *   item column 3 contains the product code,
+	 *   item column 4 contains the product name,
+    	 *   item column 5 contains the product record number.
     	 */
-    	if (item->text(4).toInt() > 0) {
-	    if (record != item->text(4).toInt()) {
-	    	record = item->text(4).toInt();
+    	if (item->text(5).toInt() > 0) {
+	    if (record != item->text(5).toInt()) {
+	    	record = item->text(5).toInt();
 	    	showRecipe();
 	    }
     	}
@@ -423,8 +424,8 @@
 
 void ProdOnTree::on_item_doubleclicked(QTreeWidgetItem *item, int col)
 {
-    if ((col == 3) && (item->text(4).toInt() > 0)) {
-	edit(item->text(4).toInt());
+    if (((col == 3) || (col == 4)) && (item->text(5).toInt() > 0)) {
+	edit(item->text(5).toInt());
     }
 }
 

mercurial