All profile and inventory editors now log warnings if something went wrong. Also added a Clone button. Delete now asks for confirmation.

Mon, 01 Aug 2022 13:05:23 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 01 Aug 2022 13:05:23 +0200
changeset 385
09af9f46518f
parent 384
d68826df8b63
child 386
2e30c9c20d22

All profile and inventory editors now log warnings if something went wrong. Also added a Clone button. Delete now asks for confirmation.

src/EditEquipment.cpp file | annotate | diff | comparison | revisions
src/EditEquipment.h file | annotate | diff | comparison | revisions
src/EditFermentable.cpp file | annotate | diff | comparison | revisions
src/EditFermentable.h file | annotate | diff | comparison | revisions
src/EditHop.cpp file | annotate | diff | comparison | revisions
src/EditMisc.cpp file | annotate | diff | comparison | revisions
src/EditMisc.h file | annotate | diff | comparison | revisions
src/EditProfileFerment.cpp file | annotate | diff | comparison | revisions
src/EditProfileFerment.h file | annotate | diff | comparison | revisions
src/EditProfileMash.cpp file | annotate | diff | comparison | revisions
src/EditProfileMash.h file | annotate | diff | comparison | revisions
src/EditProfileWater.cpp file | annotate | diff | comparison | revisions
src/EditProfileWater.h file | annotate | diff | comparison | revisions
src/EditWater.cpp file | annotate | diff | comparison | revisions
src/EditWater.h file | annotate | diff | comparison | revisions
src/EditYeast.cpp file | annotate | diff | comparison | revisions
src/EditYeast.h file | annotate | diff | comparison | revisions
ui/EditEquipment.ui file | annotate | diff | comparison | revisions
ui/EditFermentable.ui file | annotate | diff | comparison | revisions
ui/EditMisc.ui file | annotate | diff | comparison | revisions
ui/EditProfileFerment.ui file | annotate | diff | comparison | revisions
ui/EditProfileMash.ui file | annotate | diff | comparison | revisions
ui/EditProfileWater.ui file | annotate | diff | comparison | revisions
ui/EditWater.ui file | annotate | diff | comparison | revisions
ui/EditYeast.ui file | annotate | diff | comparison | revisions
--- a/src/EditEquipment.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditEquipment.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -72,7 +72,6 @@
 	query2.bindValue(":name", query.value(1).toString());
 	query2.exec();
 	inuse = query2.size();
-	qDebug() << "in use" << inuse;
 	ui->nameEdit->setReadOnly(inuse > 0);
     } else {
 	/* Set some defaults */
@@ -132,7 +131,6 @@
 
 EditEquipment::~EditEquipment()
 {
-    qDebug() << "EditEquipment done";
     delete ui;
     emit entry_changed();
 }
@@ -221,7 +219,7 @@
         }
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditEquipment" << query.lastError();
+	    qWarning() << "EditEquipment" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -238,15 +236,73 @@
 }
 
 
+void EditEquipment::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO inventory_equipments SET name=:name, boil_size=:boil_size, "
+                "batch_size=:batch_size, tun_volume=:tun_volume, tun_weight=:tun_weight, "
+                "tun_specific_heat=:tun_specific_heat, tun_material=:tun_material, tun_height=:tun_height, "
+                "top_up_water=:top_up_water, trub_chiller_loss=:chiller_loss, evap_rate=:evap_rate, "
+                "boil_time=:boil_time, calc_boil_volume=:calcboil, top_up_kettle=:top_up_kettle, "
+                "hop_utilization=:hopfactor, notes=:notes, lauter_volume=:lauter_volume, "
+                "lauter_height=:lauter_height, lauter_deadspace=:lauter_deadspace, kettle_volume=:kettle_volume, "
+                "kettle_height=:kettle_height, mash_volume=:mash_volume, mash_max=:mash_max, "
+                "efficiency=:efficiency, uuid=:uuid");
+
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":boil_size", QString("%1").arg(ui->boil_sizeEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":batch_size", QString("%1").arg(ui->batch_sizeEdit->value(), 3, 'f', 2, '0'));
+    query.bindValue(":tun_volume", QString("%1").arg(ui->tun_volumeEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":tun_weight", QString("%1").arg(ui->tun_weightEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":tun_specific_heat", QString("%1").arg(ui->tun_specific_heatEdit->value(), 4, 'f', 3, '0'));
+    query.bindValue(":tun_material", ui->tun_materialEdit->currentIndex());
+    query.bindValue(":tun_height", QString("%1").arg(ui->tun_heightEdit->value() / 100, 4, 'f', 3, '0'));
+    query.bindValue(":top_up_water", QString("%1").arg(ui->top_up_waterEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":chiller_loss", QString("%1").arg(ui->chiller_lossEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":evap_rate", QString("%1").arg(ui->evap_rateEdit->value(), 3, 'f', 2, '0'));
+    query.bindValue(":boil_time", QString("%1").arg(ui->boil_timeEdit->value(), 1, 'f', 0, '0'));
+    query.bindValue(":calcboil", ui->calcboilEdit->isChecked() ? 1:0);
+    query.bindValue(":top_up_kettle", QString("%1").arg(ui->top_up_kettleEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":hopfactor", QString("%1").arg(ui->hopfactorEdit->value(), 1, 'f', 0, '0'));
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":lauter_volume", QString("%1").arg(ui->lauter_volumeEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":lauter_height", QString("%1").arg(ui->lauter_heightEdit->value() / 100, 4, 'f', 3, '0'));
+    query.bindValue(":lauter_deadspace", QString("%1").arg(ui->lauter_deadspaceEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":kettle_volume", QString("%1").arg(ui->kettle_volumeEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":kettle_height", QString("%1").arg(ui->kettle_heightEdit->value() / 100, 4, 'f', 3, '0'));
+    query.bindValue(":mash_volume", QString("%1").arg(ui->mash_volumeEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":mash_max", QString("%1").arg(ui->mash_maxEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":efficiency", QString("%1").arg(ui->efficiencyEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditEquipment" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditEquipment Saved";
+    }
+}
+
+
 void EditEquipment::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete equipment"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM inventory_equipments WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditEquipment" << query.lastError();
+	qWarning() << "EditEquipment" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditEquipment.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditEquipment.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditFermentable.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditFermentable.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -56,11 +56,6 @@
 	query.bindValue(":recno", id);
 	query.exec();
 	query.next();
-
-	QSqlRecord rec = query.record();
-    	for (int i = 0; i < rec.count(); i++)
-            qDebug() << i << rec.fieldName(i) << query.value(i);
-
 	ui->nameEdit->setText(query.value("name").toString());
 	ui->notesEdit->setPlainText(query.value("notes").toString());
 	ui->originEdit->setText(query.value("origin").toString());
@@ -146,7 +141,6 @@
 
 EditFermentable::~EditFermentable()
 {
-    qDebug() << "EditFermentable done";
     delete ui;
     emit entry_changed();
 }
@@ -238,7 +232,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditFermentable" << query.lastError();
+	    qWarning() << "EditFermentable" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -255,15 +249,69 @@
 }
 
 
+void EditFermentable::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO inventory_fermentables SET name=:name, type=:type, yield=:yield, color=:color, "
+                "add_after_boil=:addafter, origin=:origin, supplier=:supplier, notes=:notes, coarse_fine_diff=:coarse, "
+                "moisture=:moisture, diastatic_power=:diastatic, protein=:protein, dissolved_protein=:dissolved, "
+                "max_in_batch=:maxinbatch, recommend_mash=:mash, added=:added, always_on_stock=:always, di_ph=:diph, "
+                "acid_to_ph_57=:acidph, graintype=:graintype, inventory=:inventory, cost=:cost, production_date=:prod, "
+                "tht_date=:tht, uuid = :uuid");
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":type", ui->typeEdit->currentIndex());
+    query.bindValue(":yield", QString("%1").arg(ui->yieldEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":color", QString("%1").arg(ui->colorEdit->value(), 1, 'f', 0, '0'));
+    query.bindValue(":addafter", ui->addafterEdit->isChecked() ? 1:0);
+    query.bindValue(":origin", ui->originEdit->text());
+    query.bindValue(":supplier", ui->supplierEdit->text());
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":coarse", QString("%1").arg(ui->coarseEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":moisture", QString("%1").arg(ui->moistureEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":diastatic", Utils::kolbach_to_lintner(ui->wkEdit->value()));
+    query.bindValue(":protein", QString("%1").arg(ui->proteinEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":dissolved", QString("%1").arg(ui->dissolvedEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":maxinbatch", QString("%1").arg(ui->maxinbatchEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":mash", ui->mashEdit->isChecked() ? 1:0);
+    query.bindValue(":added", ui->addedEdit->currentIndex());
+    query.bindValue(":always", ui->alwaysEdit->isChecked() ? 1:0);
+    query.bindValue(":diph", QString("%1").arg(ui->diphEdit->value(), 3, 'f', 2, '0'));
+    query.bindValue(":acidph", QString("%1").arg(ui->acidphEdit->value(), 6, 'f', 5, '0'));
+    query.bindValue(":graintype", ui->graintypeEdit->currentIndex());
+    query.bindValue(":inventory", QString("%1").arg(0, 4, 'f', 3, '0'));
+    query.bindValue(":cost", QString("%1").arg(ui->costEdit->value(), 3, 'f', 2, '0'));
+    query.bindValue(":prod", QDate());
+    query.bindValue(":tht", QDate());
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditFermentable" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditFermentable Saved";
+    }
+}
+
+
 void EditFermentable::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete fermentable"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM inventory_fermentables WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditFermentable" << query.lastError();
+	qWarning() << "EditFermentable" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditFermentable.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditFermentable.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditHop.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditHop.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -113,7 +113,6 @@
 
 EditHop::~EditHop()
 {
-    qDebug() << "EditHop done";
     delete ui;
     emit entry_changed();
 }
@@ -201,7 +200,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditHop" << query.lastError();
+	    qWarning() << "EditHop" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -245,7 +244,6 @@
     query.bindValue(":always", ui->alwaysEdit->isChecked() ? 1:0);
     query.bindValue(":inventory", QString("%1").arg(0, 5, 'f', 4, '0'));
     query.bindValue(":cost", QString("%1").arg(ui->costEdit->value(), 3, 'f', 2, '0'));
-    /* Uses https://www.qtcentre.org/threads/17295-How-to-put-empty-value-in-QDateEdit */
     query.bindValue(":prod", QDate());
     query.bindValue(":tht", QDate());
     query.bindValue(":oil", QString("%1").arg(ui->oilEdit->value(), 2, 'f', 1, '0'));
@@ -254,7 +252,7 @@
     query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
     query.exec();
     if (query.lastError().isValid()) {
-        qDebug() << "EditHop" << query.lastError();
+        qWarning() << "EditHop" << query.lastError();
         QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -271,11 +269,16 @@
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete hop"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM inventory_hops WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditHop" << query.lastError();
+	qWarning() << "EditHop" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditMisc.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditMisc.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -105,7 +105,6 @@
 
 EditMisc::~EditMisc()
 {
-    qDebug() << "EditMisc done";
     delete ui;
     emit entry_changed();
 }
@@ -173,7 +172,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditMisc" << query.lastError();
+	    qWarning() << "EditMisc" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -190,15 +189,57 @@
 }
 
 
+void EditMisc::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO inventory_miscs SET name=:name, type=:type, use_use=:use, "
+                "time=:time, amount_is_weight=:isweight, use_for=:usefor, notes=:notes, "
+                "always_on_stock=:always, inventory=:inventory, cost=:cost, production_date=:prod, "
+                "tht_date=:tht, uuid = :uuid");
+
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":type", ui->typeEdit->currentIndex());
+    query.bindValue(":use", ui->useEdit->currentIndex());
+    query.bindValue(":time", ui->timeEdit->value());
+    query.bindValue(":isweight", ui->isweightEdit->isChecked() ? 1:0);
+    query.bindValue(":usefor", ui->useforEdit->toPlainText());
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":always", ui->alwaysEdit->isChecked() ? 1:0);
+    query.bindValue(":inventory", QString("%1").arg(0, 5, 'f', 4, '0'));
+    query.bindValue(":cost", QString("%1").arg(ui->costEdit->value(), 3, 'f', 2, '0'));
+    query.bindValue(":prod", QDate());
+    query.bindValue(":tht", QDate());
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditMisc" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditMisc Saved";
+    }
+}
+
+
 void EditMisc::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete misc"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM inventory_miscs WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditMisc" << query.lastError();
+	qWarning() << "EditMisc" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditMisc.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditMisc.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditProfileFerment.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditProfileFerment.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -187,7 +187,6 @@
 
 EditProfileFerment::~EditProfileFerment()
 {
-    qDebug() << "EditProfileFerment done";
     delete ui;
     emit entry_changed();
 }
@@ -247,7 +246,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditProfileFerment" << query.lastError();
+	    qWarning() << "EditProfileFerment" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -264,15 +263,51 @@
 }
 
 
+void EditProfileFerment::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO profile_fermentation SET name=:name, inittemp_lo=:templo, "
+                "inittemp_hi=:temphi, fridgemode=:fridgemode, totalsteps=:totalsteps, duration=:duration, "
+                "steps=:steps, uuid = :uuid");
+
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":templo", QString("%1").arg(ui->temploEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":temphi", QString("%1").arg(ui->temphiEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":fridgemode", ui->sensorEdit->currentIndex());
+    query.bindValue(":totalsteps", QString("%1").arg(totalsteps));
+    query.bindValue(":duration", QString("%1").arg(duration));
+    query.bindValue(":steps", this->steps.toJson(QJsonDocument::Compact));
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditProfileFerment" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditProfileFerment Saved";
+    }
+}
+
+
 void EditProfileFerment::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete fermentation profile"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM profile_fermentation WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditProfileFerment" << query.lastError();
+	qWarning() << "EditProfileFerment" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditProfileFerment.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditProfileFerment.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditProfileMash.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditProfileMash.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -172,7 +172,6 @@
 
 EditProfileMash::~EditProfileMash()
 {
-    qDebug() << "EditProfileMash done";
     delete ui;
     emit entry_changed();
 }
@@ -225,7 +224,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditProfileMash" << query.lastError();
+	    qWarning() << "EditProfileMash" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -242,15 +241,44 @@
 }
 
 
+void EditProfileMash::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO profile_mash SET name=:name, notes=:notes, steps=:steps, uuid=:uuid");
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":steps", this->steps.toJson(QJsonDocument::Compact));
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditProfileMash" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditProfileMash Saved";
+    }
+}
+
+
 void EditProfileMash::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete mash profile"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM profile_mash WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditProfileMash" << query.lastError();
+	qWarning() << "EditProfileMash" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditProfileMash.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditProfileMash.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditProfileWater.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditProfileWater.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -79,7 +79,6 @@
 
 EditProfileWater::~EditProfileWater()
 {
-    qDebug() << "EditProfileWater done";
     delete ui;
     emit entry_changed();
 }
@@ -142,7 +141,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditProfileWater" << query.lastError();
+	    qWarning() << "EditProfileWater" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -159,15 +158,54 @@
 }
 
 
+void EditProfileWater::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO profile_water SET name=:name, calcium=:ca, "
+                "bicarbonate=:hco, sulfate=:so4, chloride=:cl, sodium=:na, magnesium=:mg, ph=:ph, notes=:notes, "
+                "total_alkalinity=:alkalinity, uuid = :uuid");
+
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":ca", round(calcium * 1000) / 1000);
+    query.bindValue(":hco", round(bicarbonate * 1000) / 1000);
+    query.bindValue(":so4", round(sulfate * 1000) / 1000);
+    query.bindValue(":cl", round(chloride * 1000) / 1000);
+    query.bindValue(":na", round(sodium * 1000) / 1000);
+    query.bindValue(":mg", round(magnesium * 1000) / 1000);
+    query.bindValue(":ph", round(ph * 1000) / 1000);
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":alkalinity", round(total_alkalinity * 1000) / 1000);
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditProfileWater" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditProfileWater Saved";
+    }
+}
+
+
 void EditProfileWater::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete water profile"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM profile_water WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditProfileWater" << query.lastError();
+	qWarning() << "EditProfileWater" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditProfileWater.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditProfileWater.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditWater.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditWater.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -88,7 +88,6 @@
 
 EditWater::~EditWater()
 {
-    qDebug() << "EditWater done";
     delete ui;
     emit entry_changed();
 }
@@ -155,7 +154,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditWater" << query.lastError();
+	    qWarning() << "EditWater" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -172,15 +171,58 @@
 }
 
 
+void EditWater::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO inventory_waters SET name=:name, unlimited_stock=:unlimited, calcium=:ca, "
+                "bicarbonate=:hco, sulfate=:so4, chloride=:cl, sodium=:na, magnesium=:mg, ph=:ph, notes=:notes, "
+                "total_alkalinity=:alkalinity, inventory=:inventory, cost=:cost, nitrate=:no, uuid = :uuid");
+
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":unlimited", ui->unlimitedEdit->isChecked() ? 1:0);
+    query.bindValue(":ca", round(calcium * 1000) / 1000);
+    query.bindValue(":hco", round(bicarbonate * 1000) / 1000);
+    query.bindValue(":so4", round(sulfate * 1000) / 1000);
+    query.bindValue(":cl", round(chloride * 1000) / 1000);
+    query.bindValue(":na", round(sodium * 1000) / 1000);
+    query.bindValue(":mg", round(magnesium * 1000) / 1000);
+    query.bindValue(":ph", round(ph * 1000) / 1000);
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":alkalinity", round(total_alkalinity * 1000) / 1000);
+    query.bindValue(":inventory", QString("%1").arg(0, 2, 'f', 1, '0'));
+    query.bindValue(":cost", QString("%1").arg(ui->costEdit->value(), 6, 'f', 5, '0'));
+    query.bindValue(":no", round(nitrate * 1000) / 1000);
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditWater" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditWater Saved";
+    }
+}
+
+
 void EditWater::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete water"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM inventory_waters WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditWater" << query.lastError();
+	qWarning() << "EditWater" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditWater.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditWater.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/src/EditYeast.cpp	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditYeast.cpp	Mon Aug 01 13:05:23 2022 +0200
@@ -155,7 +155,6 @@
 
 EditYeast::~EditYeast()
 {
-    qDebug() << "EditYeast done";
     delete ui;
     emit entry_changed();
 }
@@ -310,7 +309,7 @@
 	}
 	query.exec();
 	if (query.lastError().isValid()) {
-	    qDebug() << "EditYeast" << query.lastError();
+	    qWarning() << "EditYeast" << query.lastError();
 	    QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
@@ -327,15 +326,77 @@
 }
 
 
+void EditYeast::on_cloneButton_clicked()
+{
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO inventory_yeasts SET name=:name, type=:type, form=:form, "
+                "laboratory=:laboratory, product_id=:productid, min_temperature=:templo, max_temperature=:temphi, "
+                "flocculation=:floc, attenuation=:att, tolerance=:tolerance, notes=:notes, best_for=:bestfor, "
+                "max_reuse=:reuse, inventory=:inventory, cost=:cost, production_date=:prod, tht_date=:tht, "
+                "cells=:cells, sta1=:sta1, bacteria=:bacteria, harvest_top=:harvesttop, harvest_time=:harvesttime, "
+                "pitch_temperature=:pitchtemp, pofpos=:pof, short_desc=:yeastbank, gr_hl_lo=:grhllo, sg_lo=:sglo, "
+                "gr_hl_hi=:grhlhi, sg_hi=:sghi, uuid = :uuid");
+
+    query.bindValue(":name", ui->nameEdit->text() + " [copy]");
+    query.bindValue(":type", ui->typeEdit->currentIndex());
+    query.bindValue(":form", ui->formEdit->currentIndex());
+    query.bindValue(":laboratory", ui->laboratoryEdit->text());
+    query.bindValue(":productid", ui->productidEdit->text());
+    query.bindValue(":templo", QString("%1").arg(ui->temploEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":temphi", QString("%1").arg(ui->temphiEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":floc", ui->flocEdit->currentIndex());
+    query.bindValue(":att", QString("%1").arg(ui->attEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":tolerance", QString("%1").arg(ui->toleranceEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":notes", ui->notesEdit->toPlainText());
+    query.bindValue(":bestfor", ui->bestforEdit->toPlainText());
+    query.bindValue(":reuse", ui->reuseEdit->value());
+    query.bindValue(":inventory", QString("%1").arg(0, 5, 'f', 4, '0'));
+    query.bindValue(":cost", QString("%1").arg(ui->costEdit->value(), 3, 'f', 2, '0'));
+    query.bindValue(":prod", QDate());
+    query.bindValue(":tht", QDate());
+    query.bindValue(":cells", QString("%1").arg(ui->cellsEdit->value() * 1000000000, 1, 'f', 0, '0'));
+    query.bindValue(":sta1", ui->sta1Edit->isChecked() ? 1:0);
+    query.bindValue(":bacteria", ui->bacteriaEdit->isChecked() ? 1:0);
+    query.bindValue(":harvesttop", ui->harvesttopEdit->isChecked() ? 1:0);
+    query.bindValue(":harvesttime", ui->harvesttimeEdit->value());
+    query.bindValue(":pitchtemp", QString("%1").arg(ui->pitchtempEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":pof", ui->pofEdit->isChecked() ? 1:0);
+    query.bindValue(":yeastbank", ui->yeastbankEdit->text());
+    query.bindValue(":grhllo", QString("%1").arg(ui->grhlloEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":sglo", ui->sgloEdit->value());
+    query.bindValue(":grhlhi", QString("%1").arg(ui->grhlhiEdit->value(), 2, 'f', 1, '0'));
+    query.bindValue(":sghi", ui->sghiEdit->value());
+    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
+
+    query.exec();
+    if (query.lastError().isValid()) {
+	qWarning() << "EditYeast" << query.lastError();
+	QMessageBox::warning(this, tr("Database error"),
+                        tr("MySQL error: %1\n%2\n%3")
+                        .arg(query.lastError().nativeErrorCode())
+                        .arg(query.lastError().driverText())
+                        .arg(query.lastError().databaseText()));
+    } else {
+	qDebug() << "EditYeast Saved";
+    }
+}
+
+
 void EditYeast::on_deleteButton_clicked()
 {
     QSqlQuery query;
 
+    int rc = QMessageBox::warning(this, tr("Delete yeast"), tr("Delete %1").arg(ui->nameEdit->text()),
+                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+    if (rc == QMessageBox::No)
+        return;
+
     query.prepare("DELETE FROM inventory_yeasts WHERE record = :recno");
     query.bindValue(":recno", this->recno);
     query.exec();
     if (query.lastError().isValid()) {
-	qDebug() << "EditYeast" << query.lastError();
+	qWarning() << "EditYeast" << query.lastError();
 	QMessageBox::warning(this, tr("Database error"),
                         tr("MySQL error: %1\n%2\n%3")
                         .arg(query.lastError().nativeErrorCode())
--- a/src/EditYeast.h	Sun Jul 31 20:23:27 2022 +0200
+++ b/src/EditYeast.h	Mon Aug 01 13:05:23 2022 +0200
@@ -21,6 +21,7 @@
 
 private slots:
     void on_saveButton_clicked();
+    void on_cloneButton_clicked();
     void on_quitButton_clicked();
     void on_deleteButton_clicked();
     void is_changed();
--- a/ui/EditEquipment.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditEquipment.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -126,7 +126,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>550</y>
         <width>80</width>
         <height>23</height>
@@ -1207,6 +1207,23 @@
        </property>
       </widget>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>550</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditFermentable.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditFermentable.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -976,7 +976,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -1139,6 +1139,23 @@
         <normaloff>:/icons/silk/delete.png</normaloff>:/icons/silk/delete.png</iconset>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditMisc.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditMisc.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -343,7 +343,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -661,6 +661,23 @@
         <normaloff>:/icons/silk/date.png</normaloff>:/icons/silk/date.png</iconset>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditProfileFerment.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditProfileFerment.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -97,7 +97,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -169,9 +169,9 @@
      <widget class="QPushButton" name="addButton">
       <property name="geometry">
        <rect>
-        <x>820</x>
+        <x>799</x>
         <y>100</y>
-        <width>80</width>
+        <width>101</width>
         <height>23</height>
        </rect>
       </property>
@@ -303,6 +303,23 @@
        </rect>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditProfileMash.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditProfileMash.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -126,7 +126,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -195,9 +195,9 @@
      <widget class="QPushButton" name="addButton">
       <property name="geometry">
        <rect>
-        <x>820</x>
+        <x>789</x>
         <y>130</y>
-        <width>80</width>
+        <width>111</width>
         <height>23</height>
        </rect>
       </property>
@@ -209,6 +209,23 @@
         <normaloff>:/icons/silk/add.png</normaloff>:/icons/silk/add.png</iconset>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditProfileWater.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditProfileWater.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -126,7 +126,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -708,6 +708,23 @@
        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditWater.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditWater.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -220,7 +220,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -872,6 +872,23 @@
        <enum>QAbstractSpinBox::DefaultStepType</enum>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>
--- a/ui/EditYeast.ui	Sun Jul 31 20:23:27 2022 +0200
+++ b/ui/EditYeast.ui	Mon Aug 01 13:05:23 2022 +0200
@@ -340,7 +340,7 @@
       </property>
       <property name="geometry">
        <rect>
-        <x>463</x>
+        <x>596</x>
         <y>510</y>
         <width>80</width>
         <height>23</height>
@@ -1219,6 +1219,23 @@
         <normaloff>:/icons/silk/date.png</normaloff>:/icons/silk/date.png</iconset>
       </property>
      </widget>
+     <widget class="QPushButton" name="cloneButton">
+      <property name="geometry">
+       <rect>
+        <x>343</x>
+        <y>510</y>
+        <width>80</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Clone</string>
+      </property>
+      <property name="icon">
+       <iconset resource="../../../../../../home/mbroek/MyProjects/bmsapp/resources/icons.qrc">
+        <normaloff>:/icons/silk/disk_multiple.png</normaloff>:/icons/silk/disk_multiple.png</iconset>
+      </property>
+     </widget>
     </widget>
    </item>
   </layout>

mercurial