first commit
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
#include "imagegallery.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
|
||||
// ImageThumbnail implementation
|
||||
ImageThumbnail::ImageThumbnail(const QString &filePath, QWidget *parent)
|
||||
: QLabel(parent)
|
||||
, m_filePath(filePath)
|
||||
{
|
||||
setFixedSize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
||||
setLineWidth(2);
|
||||
setScaledContents(false);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setToolTip(filePath);
|
||||
|
||||
// Enable text wrapping and text interaction
|
||||
setWordWrap(true);
|
||||
setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
|
||||
// Set a minimum size policy
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
void ImageThumbnail::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
emit thumbnailClicked(m_filePath);
|
||||
}
|
||||
QLabel::mousePressEvent(event);
|
||||
}
|
||||
|
||||
// ImageGallery implementation
|
||||
ImageGallery::ImageGallery(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_dbManager(nullptr)
|
||||
{
|
||||
// Create scroll area
|
||||
m_scrollArea = new QScrollArea(this);
|
||||
m_scrollArea->setWidgetResizable(true);
|
||||
m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
||||
// Create container widget for the grid layout
|
||||
m_containerWidget = new QWidget(m_scrollArea);
|
||||
m_gridLayout = new QGridLayout(m_containerWidget);
|
||||
m_gridLayout->setSpacing(10);
|
||||
|
||||
m_scrollArea->setWidget(m_containerWidget);
|
||||
|
||||
// Create layout for the gallery widget
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->addWidget(m_scrollArea);
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
ImageGallery::~ImageGallery()
|
||||
{
|
||||
clearGallery();
|
||||
}
|
||||
|
||||
void ImageGallery::setDatabaseManager(DatabaseManager *dbManager)
|
||||
{
|
||||
m_dbManager = dbManager;
|
||||
}
|
||||
|
||||
void ImageGallery::displayImages(const QList<DatabaseManager::ImageItem> &images)
|
||||
{
|
||||
// Clear existing thumbnails
|
||||
clearGallery();
|
||||
|
||||
const int numImages = images.size();
|
||||
int row = 0, col = 0;
|
||||
|
||||
for (int i = 0; i < numImages; ++i) {
|
||||
const auto &item = images[i];
|
||||
|
||||
// Check if file exists before creating thumbnail
|
||||
QFileInfo fileInfo(item.filePath);
|
||||
if (!fileInfo.exists() || !fileInfo.isReadable()) {
|
||||
qDebug() << "Image file does not exist or is not readable:" << item.filePath;
|
||||
continue; // Skip this image
|
||||
}
|
||||
|
||||
// Create and add thumbnail
|
||||
QPixmap thumbnail = createThumbnail(item.filePath, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
|
||||
ImageThumbnail *thumbnailLabel = new ImageThumbnail(item.filePath, this);
|
||||
thumbnailLabel->setPixmap(thumbnail);
|
||||
|
||||
// Set tooltip to show file path and partial OCR text
|
||||
QString tooltipText = item.filePath;
|
||||
if (!item.ocrText.isEmpty()) {
|
||||
// Limit OCR text length in tooltip
|
||||
QString shortOcrText = item.ocrText;
|
||||
if (shortOcrText.length() > 100) {
|
||||
shortOcrText = shortOcrText.left(97) + "...";
|
||||
}
|
||||
tooltipText += "\n\nOCR Text:\n" + shortOcrText;
|
||||
}
|
||||
thumbnailLabel->setToolTip(tooltipText);
|
||||
|
||||
// Connect the thumbnail click signal
|
||||
connect(thumbnailLabel, &ImageThumbnail::thumbnailClicked,
|
||||
this, &ImageGallery::handleThumbnailClicked);
|
||||
|
||||
// Add to grid
|
||||
m_gridLayout->addWidget(thumbnailLabel, row, col);
|
||||
m_thumbnails.append(thumbnailLabel);
|
||||
|
||||
// Update row and column
|
||||
col++;
|
||||
if (col >= COLUMNS) {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
// Display a message when no images are found
|
||||
if (m_thumbnails.isEmpty()) {
|
||||
// Create a special ImageThumbnail for the "no images" message
|
||||
ImageThumbnail *noImagesLabel = new ImageThumbnail("", this);
|
||||
noImagesLabel->setText("No images found matching your search criteria");
|
||||
noImagesLabel->setAlignment(Qt::AlignCenter);
|
||||
m_gridLayout->addWidget(noImagesLabel, 0, 0, 1, COLUMNS);
|
||||
m_thumbnails.append(noImagesLabel);
|
||||
}
|
||||
|
||||
// Add stretch to the bottom of the grid
|
||||
m_gridLayout->setRowStretch(row + 1, 1);
|
||||
}
|
||||
|
||||
void ImageGallery::clearGallery()
|
||||
{
|
||||
// Remove all thumbnails
|
||||
for (auto thumbnail : m_thumbnails) {
|
||||
m_gridLayout->removeWidget(thumbnail);
|
||||
disconnect(thumbnail, nullptr, this, nullptr);
|
||||
delete thumbnail;
|
||||
}
|
||||
|
||||
m_thumbnails.clear();
|
||||
}
|
||||
|
||||
void ImageGallery::handleSearchTextChanged(const QString &searchText)
|
||||
{
|
||||
if (m_dbManager) {
|
||||
QList<DatabaseManager::ImageItem> images = m_dbManager->searchImages(searchText);
|
||||
displayImages(images);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageGallery::handleThumbnailClicked(const QString &filePath)
|
||||
{
|
||||
// Show a wait cursor while attempting to open the file
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
// Check if file exists
|
||||
QFileInfo fileInfo(filePath);
|
||||
if (fileInfo.exists() && fileInfo.isFile()) {
|
||||
try {
|
||||
// Use QDesktopServices to open the file with the default application
|
||||
bool success = QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
|
||||
if (!success) {
|
||||
qDebug() << "Failed to open file with default application:" << filePath;
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
qDebug() << "Exception occurred while opening file:" << e.what();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "File does not exist:" << filePath;
|
||||
}
|
||||
|
||||
// Restore cursor
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
QPixmap ImageGallery::createThumbnail(const QString &filePath, int width, int height)
|
||||
{
|
||||
// Verify file exists before attempting to load
|
||||
QFileInfo fileInfo(filePath);
|
||||
if (!fileInfo.exists() || !fileInfo.isReadable()) {
|
||||
qDebug() << "Image file does not exist or is not readable:" << filePath;
|
||||
return createPlaceholderThumbnail(width, height, "File not found");
|
||||
}
|
||||
|
||||
// Try to load the image
|
||||
QPixmap pixmap(filePath);
|
||||
|
||||
// If loading failed, create a placeholder
|
||||
if (pixmap.isNull()) {
|
||||
qDebug() << "Failed to load image:" << filePath;
|
||||
return createPlaceholderThumbnail(width, height, "Failed to load");
|
||||
}
|
||||
|
||||
// Scale pixmap while maintaining aspect ratio
|
||||
return pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
QPixmap ImageGallery::createPlaceholderThumbnail(int width, int height, const QString &message)
|
||||
{
|
||||
// Create a placeholder image with text
|
||||
QPixmap placeholder(width, height);
|
||||
placeholder.fill(Qt::lightGray);
|
||||
|
||||
// Draw some text on the placeholder
|
||||
QPainter painter(&placeholder);
|
||||
painter.setPen(Qt::darkGray);
|
||||
|
||||
// Use a nice font
|
||||
QFont font = painter.font();
|
||||
font.setPointSize(12);
|
||||
font.setBold(true);
|
||||
painter.setFont(font);
|
||||
|
||||
// Draw the text centered in the pixmap
|
||||
painter.drawText(placeholder.rect(), Qt::AlignCenter, message);
|
||||
|
||||
// Add a border
|
||||
painter.setPen(QPen(Qt::darkGray, 2));
|
||||
painter.drawRect(1, 1, width-2, height-2);
|
||||
|
||||
return placeholder;
|
||||
}
|
||||
Reference in New Issue
Block a user