Files
ORC-Gallery-Linux/src/imagegallery.cpp
T
2025-11-15 21:14:36 -05:00

229 lines
7.2 KiB
C++

#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;
}