# HG changeset patch # User Michiel Broek # Date 1674229448 -3600 # Node ID c5f6f3f1b7142878ca4b1707377a3ffefa991ee2 # Parent 68ef2cc3e8d2b65e0727efaafa355efda11dbfd8 Added more buttons to the images tab. Load images from the database and display thumbnails added. Added support for jpeg files. Rename pictures in the database to .png. Added temporary images_list, images_count and images_current variables to the product record. diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 src/EditProduct.cpp --- a/src/EditProduct.cpp Wed Jan 18 17:08:25 2023 +0100 +++ b/src/EditProduct.cpp Fri Jan 20 16:44:08 2023 +0100 @@ -151,6 +151,8 @@ } } } + product->images_count = -1; /* Not yet loaded */ + product->images_dirty = false; } else { /* New product, set some defaults */ @@ -280,6 +282,8 @@ product->divide_type = product->divide_parts = product->divide_part = 0; product->divide_size = 0; product->divide_factor = 1; + product->images_count = -1; + product->images_dirty = false; } // Tab generic. @@ -755,6 +759,11 @@ /* All signals from tab Images */ connect(ui->addImage, SIGNAL(clicked()), this, SLOT(addImage_clicked())); + connect(ui->delImage, SIGNAL(clicked()), this, SLOT(delImage_clicked())); + connect(ui->nextImage, SIGNAL(clicked()), this, SLOT(nextImage_clicked())); + connect(ui->prevImage, SIGNAL(clicked()), this, SLOT(prevImage_clicked())); + connect(ui->downloadImage, SIGNAL(clicked()), this, SLOT(downloadImage_clicked())); + connect(ui->printImage, SIGNAL(clicked()), this, SLOT(printImage_clicked())); setStage(); diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 src/EditProduct.h --- a/src/EditProduct.h Wed Jan 18 17:08:25 2023 +0100 +++ b/src/EditProduct.h Fri Jan 20 16:44:08 2023 +0100 @@ -259,6 +259,12 @@ void taste_notes_changed(); void addImage_clicked(); + void delImage_clicked(); + void nextImage_clicked(); + void prevImage_clicked(); + void downloadImage_clicked(); + void printImage_clicked(); + void selectImage_clicked(int val); /* Modified progress bars */ void ferment_perc_mash_valueChanged(int value); @@ -378,7 +384,8 @@ bool block_yeast(int stage, int use); void check_waters(); void images_Init(); - bool images_loadFile(const QString &fileName); + void images_Thumbnails(); + void images_Main(int id); }; #endif diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 src/EditProductTab13.cpp --- a/src/EditProductTab13.cpp Wed Jan 18 17:08:25 2023 +0100 +++ b/src/EditProductTab13.cpp Fri Jan 20 16:44:08 2023 +0100 @@ -19,17 +19,107 @@ void EditProduct::images_Init() { - qDebug() << "images_Init()"; + qDebug() << "images_Init()"; // Start spinner - // Clean old picture areas - // Load images data for this product uuid - // Show thumbnails on the left. + + /* + * Clean old picture areas. + */ + + /* + * Load images data for this product uuid. + */ + if (product->images_count < 0) { + QSqlQuery query; + + qDebug() << " loading data"; + query.prepare("SELECT * FROM products_pics WHERE uuid=:uuid"); + query.bindValue(":uuid", product->uuid); + query.exec(); + + if (query.lastError().isValid()) { + qWarning() << "images_init()" << 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())); + } + product->images_count = 0; + + while (query.next()) { + Images i; + qDebug() << product->images_count << query.value("pic_data").toByteArray().size(); + i.pic_type = query.value("pic_type").toInt(); + i.pic_data = query.value("pic_data").toByteArray(); + i.pic_comment = query.value("pic_comment").toString(); + i.filename = query.value("filename").toString(); + i.timestamp = query.value("timestamp").toDateTime(); + product->images_list.append(i); + product->images_count++; + } + qDebug() << " loaded" << product->images_count << product->images_list.size(); + if (product->images_count < 1) + product->images_current = -1; + else + product->images_current = 0; + } + + images_Thumbnails(); + if (product->images_current >= 0) { + ui->filmStrip->setCurrentRow(product->images_current); + } + images_Main(product->images_current); + // If any, show picture 1 // Stop spinner } +/* + * Show thumbnails on the left. + */ +void EditProduct::images_Thumbnails() +{ + QList items = ui->filmStrip->selectedItems(); + foreach(QListWidgetItem * item, items) { + delete ui->filmStrip->takeItem(ui->filmStrip->row(item)); + } + + for (int i = 0; i < product->images_list.size(); i++) { + QListWidgetItem* newItem = new QListWidgetItem(); + QString text = QCoreApplication::translate("PicType", g_prod_pic_types[product->images_list.at(i).pic_type]); + if (product->images_list.at(i).filename != "") + text.append("\n" + product->images_list.at(i).filename); + if (product->images_list.at(i).pic_comment != "") + text.append("\n" + product->images_list.at(i).pic_comment); + // product->images_list.at(i).timestamp + newItem->setText(text); + newItem->setBackground(QColor(0x45,0x53,0x64)); + + QPixmap outPixmap = QPixmap(); + outPixmap.loadFromData(product->images_list.at(i).pic_data); + qDebug() << " " << outPixmap.width() << "x" << outPixmap.height() << "size" << outPixmap.size() << product->images_list.at(i).filename; + if (outPixmap.width() > 320 || outPixmap.height() > 240) + newItem->setIcon(QIcon(outPixmap.scaled(320, 240, Qt::KeepAspectRatio, Qt::SmoothTransformation))); + else + newItem->setIcon(QIcon(outPixmap)); + + ui->filmStrip->addItem(newItem); + } +} + + +void EditProduct::images_Main(int id) +{ + qDebug() << " Main(" << id << ")"; + + ui->prevImage->setEnabled((product->images_count > 0 && product->images_current > 0) ? true:false); + ui->nextImage->setEnabled((product->images_count > 0 && (product->images_current + 1) < product->images_count) ? true:false); + ui->downloadImage->setEnabled((product->images_count > 0) ? true:false); + ui->printImage->setEnabled((product->images_count > 0) ? true:false); + ui->delImage->setEnabled((product->images_count > 0) ? true:false); +} + + void EditProduct::addImage_clicked() { QString fileName; @@ -42,7 +132,7 @@ /* Only a few image formats are valid */ QStringList mimeTypeFilters ({ "image/bmp", "image/gif", "image/jpeg", "image/png", "image/svg+xml" }); dialog1.setMimeTypeFilters(mimeTypeFilters); - dialog1.setNameFilter("Images (*.bmp *.BMP *.gif *.GIF *.jpg *.JPG *.png *.PNG *.svg *.SVG)"); + dialog1.setNameFilter("Images (*.bmp *.BMP *.gif *.GIF *.jpg *.JPG *.jpeg *.JPEG *.png *.PNG *.svg *.SVG)"); dialog1.setAcceptMode(QFileDialog::AcceptOpen); // dialog1.setOption(QFileDialog::DontUseNativeDialog); if (dialog1.exec() != QDialog::Accepted) @@ -66,7 +156,7 @@ QBuffer buffer(&imageByteArray); buffer.open(QIODevice::WriteOnly); - newImage.save(&buffer, "PNG"); + newImage.save(&buffer, "PNG"); /* Convert to lossless .png format. */ /* * Now that we have selected a valid image, create a new dialog so @@ -132,10 +222,10 @@ query.prepare("INSERT INTO products_pics SET uuid=:uuid, pic_type=:pic_type, pic_data=:pic_data, " "pic_comment=:pic_comment, filename=:filename, timestamp=:timestamp"); query.bindValue(":uuid", product->uuid); - query.bindValue(":pic_type", g_prod_pic_types[typeEdit->currentIndex()]); + query.bindValue(":pic_type", typeEdit->currentIndex()); query.bindValue(":pic_data", imageByteArray); query.bindValue(":pic_comment", commentEdit->text()); - query.bindValue(":filename", fi.fileName()); + query.bindValue(":filename", fi.completeBaseName() + ".png"); /* The image is converted to .png */ query.bindValue(":timestamp", fi.lastModified()); query.exec(); @@ -151,3 +241,54 @@ } +void EditProduct::delImage_clicked() +{ + qDebug() << "delImage_clicked()" << product->images_current << ui->filmStrip->currentRow(); +} + + +void EditProduct::nextImage_clicked() +{ + qDebug() << "nextImage_clicked()" << product->images_current << ui->filmStrip->currentRow(); + + if (product->images_count >= 0) { + if ((product->images_current + 1) < product->images_count) { + product->images_current++; + ui->filmStrip->setCurrentRow(product->images_current); + images_Main(product->images_current); + } + } +} + + +void EditProduct::prevImage_clicked() +{ + qDebug() << "prevImage_clicked()" << product->images_current << ui->filmStrip->currentRow(); + + if (product->images_count >= 0) { + if (product->images_current > 0) { + product->images_current--; + ui->filmStrip->setCurrentRow(product->images_current); + images_Main(product->images_current); + } + } +} + + +void EditProduct::downloadImage_clicked() +{ + qDebug() << "downloadImage_clicked()" << product->images_current << ui->filmStrip->currentRow(); +} + + +void EditProduct::printImage_clicked() +{ + qDebug() << "printImage_clicked()" << product->images_current << ui->filmStrip->currentRow(); +} + + +void EditProduct::selectImage_clicked(int val) +{ + qDebug() << "selectImage_clicked()" << val << product->images_current << ui->filmStrip->currentRow(); +} + diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 src/global.h --- a/src/global.h Wed Jan 18 17:08:25 2023 +0100 +++ b/src/global.h Fri Jan 20 16:44:08 2023 +0100 @@ -237,6 +237,16 @@ }; +struct Images +{ + int pic_type; + QByteArray pic_data; + QString pic_comment; + QString filename; + QDateTime timestamp; +}; + + struct Equipment { QString name; @@ -687,6 +697,10 @@ double ws_sodium; double ws_magnesium; double ws_total_alkalinity; + QList images_list; ///< List of loaded images. + int images_count; ///< -1 if not yet loaded. + int images_current; ///< -1 or image in focus. + bool images_dirty; }; diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 translations/bmsapp_en.ts --- a/translations/bmsapp_en.ts Wed Jan 18 17:08:25 2023 +0100 +++ b/translations/bmsapp_en.ts Fri Jan 20 16:44:08 2023 +0100 @@ -2336,12 +2336,14 @@ + Save + @@ -2857,7 +2859,7 @@ - + Add @@ -4098,12 +4100,23 @@ - + + Previous + + + + + Next + + + + Export - + + Print @@ -4138,48 +4151,48 @@ - + %1, part %2 of %3 - + BMSapp - Add new product - + BMSapp - Edit %1 - %2 - - + + Edit Product - + Name empty or too short. - + No beerstyle selected. - + Delete product - + Product changed - + The product has been modified. Save changes? @@ -4304,7 +4317,7 @@ - + Delete %1 @@ -5225,30 +5238,49 @@ - + Open File - + Cannot load %1: %2 - + Image here - + Image type: - + Image comment: + + + The comment for this image. + + + + + + Database error + + + + + + MySQL error: %1 +%2 +%3 + + EditProfileFerment diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 translations/bmsapp_nl.ts --- a/translations/bmsapp_nl.ts Wed Jan 18 17:08:25 2023 +0100 +++ b/translations/bmsapp_nl.ts Fri Jan 20 16:44:08 2023 +0100 @@ -2636,12 +2636,14 @@ + Save Bewaar + @@ -3056,7 +3058,7 @@ - + Add Nieuw @@ -4538,12 +4540,23 @@ Plaatjes - + + Previous + + + + + Next + + + + Export Exporteer - + + Print Print @@ -4563,7 +4576,7 @@ Mout - + BMSapp - Edit %1 - %2 BMSapp - Wijzig %1 - %2 @@ -4611,15 +4624,17 @@ Zuurstof + + Database error - Database fout + Database fout MySQL error: record %1 not found MySQL fout: record %1 niet gevonden - + %1, part %2 of %3 %1, deel %2 van %3 @@ -4628,7 +4643,7 @@ Koken %1 minuten - + BMSapp - Add new product BMSapp - Nieuw product @@ -4637,41 +4652,43 @@ BMSapp - Wijzig product %1 - - + + Edit Product Wijzig Product - + Name empty or too short. De naam is leeg of te kort. - + No beerstyle selected. Geen bierstijl gekozen. + + MySQL error: %1 %2 %3 - MySQL fout: %1 + MySQL fout: %1 %2 %3 - + Delete product Verwijder product - + Product changed Product gewijzigd - + The product has been modified. Save changes? Het product is gewijzigd. Wijzigingen opslaan? @@ -4808,7 +4825,7 @@ - + Delete %1 Verwijder %1 @@ -5825,29 +5842,34 @@ Bevestig dat het proeven gedaan is en opmerkingen ingevuld zijn. - + Open File - Open bestand - - - + Open bestand + + + Cannot load %1: %2 - Kan niet laden %1: %2 - - - + Kan niet laden %1: %2 + + + Image here - - - - + Plaatje hier + + + Image type: - - - - + Soort plaatje: + + + Image comment: - + Bijschrift: + + + + The comment for this image. + Het bijschrift of commentaar bij dit plaatje. diff -r 68ef2cc3e8d2 -r c5f6f3f1b714 ui/EditProduct.ui --- a/ui/EditProduct.ui Wed Jan 18 17:08:25 2023 +0100 +++ b/ui/EditProduct.ui Fri Jan 20 16:44:08 2023 +0100 @@ -12119,20 +12119,10 @@ Images - - - - 10 - 10 - 181 - 451 - - - - 60 + 950 470 80 23 @@ -12146,6 +12136,137 @@ :/icons/silk/image_add.png:/icons/silk/image_add.png + + + + 10 + 10 + 346 + 491 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + true + + + Qt::IgnoreAction + + + + 330 + 330 + + + + Qt::ElideRight + + + QListView::Static + + + QListView::Fixed + + + QListView::Batched + + + 5 + + + QListView::IconMode + + + + + + 1060 + 470 + 80 + 23 + + + + Delete + + + + :/icons/silk/image_delete.png:/icons/silk/image_delete.png + + + + + + 390 + 470 + 80 + 23 + + + + Previous + + + + :/icons/silk/resultset_previous.png:/icons/silk/resultset_previous.png + + + + + + 500 + 470 + 80 + 23 + + + + Next + + + + :/icons/silk/resultset_next.png:/icons/silk/resultset_next.png + + + + + + 670 + 470 + 80 + 23 + + + + Save + + + + :/icons/silk/disk.png:/icons/silk/disk.png + + + + + + 780 + 470 + 80 + 23 + + + + Print + + + + :/icons/silk/printer.png:/icons/silk/printer.png + +