version 2

This commit is contained in:
master
2025-11-15 21:49:04 -05:00
parent 8c55eeffd4
commit f2cf0d7d89
28 changed files with 1315 additions and 1007 deletions
+15 -7
View File
@@ -1,14 +1,16 @@
# Screenshot OCR Gallery # Screenshot OCR Gallery
A Qt6-based image gallery application that allows you to search through OCR data from your screenshots with live preview. A Qt6-based image gallery application that allows you to search through OCR data from your screenshots with live preview and dynamic resizing.
## Features ## Features
- Fast visual navigation through your screenshot collection - Fast visual navigation through your screenshot collection
- Live search through OCR text as you type - Ultra-responsive live search through OCR text as you type with optimized performance
- 4×4 image gallery grid with 256px wide previews - Dynamic grid layout that automatically reflows (1x, 2x, 3x, 4x, etc.) based on window width
- No horizontal scrollbars - content always fits the window width
- Filename overlay at the bottom of each image for easy identification
- Opens images in your default image viewer on click - Opens images in your default image viewer on click
- Responsive design that adjusts to window size - Minimal 2px spacing between images for a compact view
- Proper error handling for missing files and database issues - Proper error handling for missing files and database issues
## Requirements ## Requirements
@@ -88,9 +90,15 @@ After building, run the application:
1. When the application starts, it will display all screenshots found in the database 1. When the application starts, it will display all screenshots found in the database
2. Type in the search bar to filter images by OCR text content 2. Type in the search bar to filter images by OCR text content
3. Results update as you type 3. Results update instantly as you type with optimized search performance
4. Click on any image to open it in your default image viewer 4. When you clear the search bar, all images are immediately shown
5. Hover over an image to see the file path and a preview of its OCR text 5. Resize the application window to see the grid automatically reflow:
- Wider windows show more columns (4x, 5x, etc.)
- Narrower windows reduce to fewer columns (3x, 2x)
- Very narrow windows show a single centered column (1x)
- No horizontal scrolling - content always fits the available width
6. Each image displays its filename at the bottom for easy identification
7. Click on any image to open it in your default image viewer
## Troubleshooting ## Troubleshooting
@@ -288,6 +288,7 @@
/usr/include/pthread.h /usr/include/pthread.h
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QProcess /usr/include/qt6/QtCore/QProcess
@@ -1174,6 +1175,7 @@ CMakeFiles/screenshot-gallery.dir/screenshot-gallery_autogen/mocs_compilation.cp
/usr/include/pthread.h /usr/include/pthread.h
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QProcess /usr/include/qt6/QtCore/QProcess
@@ -1756,6 +1758,7 @@ CMakeFiles/screenshot-gallery.dir/src/databasemanager.cpp.o
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QFileInfo /usr/include/qt6/QtCore/QFileInfo
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QString /usr/include/qt6/QtCore/QString
@@ -2248,6 +2251,7 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QFileInfo /usr/include/qt6/QtCore/QFileInfo
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QProcess /usr/include/qt6/QtCore/QProcess
@@ -2256,6 +2260,7 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o
/usr/include/qt6/QtCore/QSizeF /usr/include/qt6/QtCore/QSizeF
/usr/include/qt6/QtCore/QString /usr/include/qt6/QtCore/QString
/usr/include/qt6/QtCore/QThread /usr/include/qt6/QtCore/QThread
/usr/include/qt6/QtCore/QTimer
/usr/include/qt6/QtCore/QUrl /usr/include/qt6/QtCore/QUrl
/usr/include/qt6/QtCore/q17memory.h /usr/include/qt6/QtCore/q17memory.h
/usr/include/qt6/QtCore/q20functional.h /usr/include/qt6/QtCore/q20functional.h
@@ -2386,6 +2391,7 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o
/usr/include/qt6/QtCore/qtextstream.h /usr/include/qt6/QtCore/qtextstream.h
/usr/include/qt6/QtCore/qtformat_impl.h /usr/include/qt6/QtCore/qtformat_impl.h
/usr/include/qt6/QtCore/qthread.h /usr/include/qt6/QtCore/qthread.h
/usr/include/qt6/QtCore/qtimer.h
/usr/include/qt6/QtCore/qtimezone.h /usr/include/qt6/QtCore/qtimezone.h
/usr/include/qt6/QtCore/qtmetamacros.h /usr/include/qt6/QtCore/qtmetamacros.h
/usr/include/qt6/QtCore/qtnoop.h /usr/include/qt6/QtCore/qtnoop.h
@@ -2462,7 +2468,9 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o
/usr/include/qt6/QtSql/qtsqlexports.h /usr/include/qt6/QtSql/qtsqlexports.h
/usr/include/qt6/QtSql/qtsqlglobal.h /usr/include/qt6/QtSql/qtsqlglobal.h
/usr/include/qt6/QtWidgets/QApplication /usr/include/qt6/QtWidgets/QApplication
/usr/include/qt6/QtWidgets/QFrame
/usr/include/qt6/QtWidgets/QGridLayout /usr/include/qt6/QtWidgets/QGridLayout
/usr/include/qt6/QtWidgets/QHBoxLayout
/usr/include/qt6/QtWidgets/QLabel /usr/include/qt6/QtWidgets/QLabel
/usr/include/qt6/QtWidgets/QPushButton /usr/include/qt6/QtWidgets/QPushButton
/usr/include/qt6/QtWidgets/QScrollArea /usr/include/qt6/QtWidgets/QScrollArea
@@ -2798,6 +2806,7 @@ CMakeFiles/screenshot-gallery.dir/src/main.cpp.o
/usr/include/pthread.h /usr/include/pthread.h
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QProcess /usr/include/qt6/QtCore/QProcess
@@ -3380,6 +3389,7 @@ CMakeFiles/screenshot-gallery.dir/src/mainwindow.cpp.o
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QFileInfo /usr/include/qt6/QtCore/QFileInfo
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QProcess /usr/include/qt6/QtCore/QProcess
@@ -287,6 +287,7 @@ screenshot-gallery_autogen/timestamp: /home/master/screenshot-gallery/CMakeLists
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -1172,6 +1173,7 @@ CMakeFiles/screenshot-gallery.dir/screenshot-gallery_autogen/mocs_compilation.cp
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -1753,6 +1755,7 @@ CMakeFiles/screenshot-gallery.dir/src/databasemanager.cpp.o: /home/master/screen
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QFileInfo \ /usr/include/qt6/QtCore/QFileInfo \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QString \ /usr/include/qt6/QtCore/QString \
@@ -2244,6 +2247,7 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o: /home/master/screensho
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QFileInfo \ /usr/include/qt6/QtCore/QFileInfo \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -2252,6 +2256,7 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o: /home/master/screensho
/usr/include/qt6/QtCore/QSizeF \ /usr/include/qt6/QtCore/QSizeF \
/usr/include/qt6/QtCore/QString \ /usr/include/qt6/QtCore/QString \
/usr/include/qt6/QtCore/QThread \ /usr/include/qt6/QtCore/QThread \
/usr/include/qt6/QtCore/QTimer \
/usr/include/qt6/QtCore/QUrl \ /usr/include/qt6/QtCore/QUrl \
/usr/include/qt6/QtCore/q17memory.h \ /usr/include/qt6/QtCore/q17memory.h \
/usr/include/qt6/QtCore/q20functional.h \ /usr/include/qt6/QtCore/q20functional.h \
@@ -2382,6 +2387,7 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o: /home/master/screensho
/usr/include/qt6/QtCore/qtextstream.h \ /usr/include/qt6/QtCore/qtextstream.h \
/usr/include/qt6/QtCore/qtformat_impl.h \ /usr/include/qt6/QtCore/qtformat_impl.h \
/usr/include/qt6/QtCore/qthread.h \ /usr/include/qt6/QtCore/qthread.h \
/usr/include/qt6/QtCore/qtimer.h \
/usr/include/qt6/QtCore/qtimezone.h \ /usr/include/qt6/QtCore/qtimezone.h \
/usr/include/qt6/QtCore/qtmetamacros.h \ /usr/include/qt6/QtCore/qtmetamacros.h \
/usr/include/qt6/QtCore/qtnoop.h \ /usr/include/qt6/QtCore/qtnoop.h \
@@ -2458,7 +2464,9 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o: /home/master/screensho
/usr/include/qt6/QtSql/qtsqlexports.h \ /usr/include/qt6/QtSql/qtsqlexports.h \
/usr/include/qt6/QtSql/qtsqlglobal.h \ /usr/include/qt6/QtSql/qtsqlglobal.h \
/usr/include/qt6/QtWidgets/QApplication \ /usr/include/qt6/QtWidgets/QApplication \
/usr/include/qt6/QtWidgets/QFrame \
/usr/include/qt6/QtWidgets/QGridLayout \ /usr/include/qt6/QtWidgets/QGridLayout \
/usr/include/qt6/QtWidgets/QHBoxLayout \
/usr/include/qt6/QtWidgets/QLabel \ /usr/include/qt6/QtWidgets/QLabel \
/usr/include/qt6/QtWidgets/QPushButton \ /usr/include/qt6/QtWidgets/QPushButton \
/usr/include/qt6/QtWidgets/QScrollArea \ /usr/include/qt6/QtWidgets/QScrollArea \
@@ -2793,6 +2801,7 @@ CMakeFiles/screenshot-gallery.dir/src/main.cpp.o: /home/master/screenshot-galler
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -3374,6 +3383,7 @@ CMakeFiles/screenshot-gallery.dir/src/mainwindow.cpp.o: /home/master/screenshot-
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QFileInfo \ /usr/include/qt6/QtCore/QFileInfo \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -4282,6 +4292,8 @@ CMakeFiles/screenshot-gallery.dir/src/mainwindow.cpp.o:
/usr/lib/cmake/Qt6/QtPublicAppleHelpers.cmake: /usr/lib/cmake/Qt6/QtPublicAppleHelpers.cmake:
/usr/lib/cmake/Qt6/Qt6Targets.cmake:
/usr/lib/cmake/Qt6Widgets/Qt6WidgetsDependencies.cmake: /usr/lib/cmake/Qt6Widgets/Qt6WidgetsDependencies.cmake:
/usr/include/c++/15.2.1/variant: /usr/include/c++/15.2.1/variant:
@@ -4522,6 +4534,8 @@ CMakeFiles/screenshot-gallery.dir/screenshot-gallery_autogen/mocs_compilation.cp
/usr/include/c++/15.2.1/bits/std_function.h: /usr/include/c++/15.2.1/bits/std_function.h:
/usr/include/qt6/QtCore/QMap:
/usr/include/c++/15.2.1/typeinfo: /usr/include/c++/15.2.1/typeinfo:
/usr/include/c++/15.2.1/bits/specfun.h: /usr/include/c++/15.2.1/bits/specfun.h:
@@ -5094,6 +5108,8 @@ screenshot-gallery_autogen/UVLADIE3JM/moc_imagegallery.cpp:
/usr/include/c++/15.2.1/algorithm: /usr/include/c++/15.2.1/algorithm:
/usr/include/qt6/QtWidgets/QFrame:
/usr/include/c++/15.2.1/backward/auto_ptr.h: /usr/include/c++/15.2.1/backward/auto_ptr.h:
/usr/include/c++/15.2.1/bits/basic_ios.h: /usr/include/c++/15.2.1/bits/basic_ios.h:
@@ -5278,6 +5294,8 @@ CMakeFiles/4.1.2/CMakeCXXCompiler.cmake:
/usr/include/qt6/QtCore/q20utility.h: /usr/include/qt6/QtCore/q20utility.h:
/usr/include/qt6/QtWidgets/QHBoxLayout:
/usr/include/qt6/QtCore/qabstracteventdispatcher.h: /usr/include/qt6/QtCore/qabstracteventdispatcher.h:
/usr/lib/cmake/Qt6Gui/Qt6QEglFSKmsGbmIntegrationPluginConfig.cmake: /usr/lib/cmake/Qt6Gui/Qt6QEglFSKmsGbmIntegrationPluginConfig.cmake:
@@ -5330,8 +5348,6 @@ CMakeFiles/4.1.2/CMakeCXXCompiler.cmake:
/usr/include/qt6/QtCore/qbytearrayview.h: /usr/include/qt6/QtCore/qbytearrayview.h:
/usr/lib/cmake/Qt6/Qt6Targets.cmake:
/usr/include/c++/15.2.1/bits/uses_allocator_args.h: /usr/include/c++/15.2.1/bits/uses_allocator_args.h:
/usr/include/qt6/QtCore/qchar.h: /usr/include/qt6/QtCore/qchar.h:
@@ -339,8 +339,8 @@ CMakeFiles/screenshot-gallery.dir/screenshot-gallery_autogen/mocs_compilation.cp
/usr/include/c++/15.2.1/bits/unique_lock.h \ /usr/include/c++/15.2.1/bits/unique_lock.h \
/usr/include/c++/15.2.1/condition_variable \ /usr/include/c++/15.2.1/condition_variable \
/usr/include/c++/15.2.1/bits/atomic_futex.h \ /usr/include/c++/15.2.1/bits/atomic_futex.h \
/usr/include/c++/15.2.1/bits/std_thread.h \ /usr/include/c++/15.2.1/bits/std_thread.h /usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/qtmochelpers.h \ /usr/include/qt6/QtCore/qmap.h /usr/include/qt6/QtCore/qtmochelpers.h \
/usr/include/qt6/QtCore/qtmocconstants.h \ /usr/include/qt6/QtCore/qtmocconstants.h \
/usr/include/qt6/QtCore/q20algorithm.h \ /usr/include/qt6/QtCore/q20algorithm.h \
/usr/include/qt6/QtCore/q23type_traits.h \ /usr/include/qt6/QtCore/q23type_traits.h \
@@ -338,10 +338,11 @@ CMakeFiles/screenshot-gallery.dir/src/databasemanager.cpp.o: \
/usr/include/c++/15.2.1/bits/unique_lock.h \ /usr/include/c++/15.2.1/bits/unique_lock.h \
/usr/include/c++/15.2.1/condition_variable \ /usr/include/c++/15.2.1/condition_variable \
/usr/include/c++/15.2.1/bits/atomic_futex.h \ /usr/include/c++/15.2.1/bits/atomic_futex.h \
/usr/include/c++/15.2.1/bits/std_thread.h \ /usr/include/c++/15.2.1/bits/std_thread.h /usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QVariant /usr/include/qt6/QtCore/qvariant.h \ /usr/include/qt6/QtCore/qmap.h /usr/include/qt6/QtCore/QVariant \
/usr/include/qt6/QtCore/QFileInfo /usr/include/qt6/QtCore/qfileinfo.h \ /usr/include/qt6/QtCore/qvariant.h /usr/include/qt6/QtCore/QFileInfo \
/usr/include/qt6/QtCore/qfile.h /usr/include/qt6/QtCore/qfiledevice.h \ /usr/include/qt6/QtCore/qfileinfo.h /usr/include/qt6/QtCore/qfile.h \
/usr/include/qt6/QtCore/qfiledevice.h \
/usr/include/qt6/QtCore/qiodevice.h /usr/include/qt6/QtCore/qspan.h \ /usr/include/qt6/QtCore/qiodevice.h /usr/include/qt6/QtCore/qspan.h \
/usr/include/c++/15.2.1/cassert /usr/include/qt6/QtCore/q20iterator.h \ /usr/include/c++/15.2.1/cassert /usr/include/qt6/QtCore/q20iterator.h \
/usr/include/c++/15.2.1/filesystem /usr/include/c++/15.2.1/bits/fs_fwd.h \ /usr/include/c++/15.2.1/filesystem /usr/include/c++/15.2.1/bits/fs_fwd.h \
@@ -402,11 +402,11 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o: \
/usr/include/c++/15.2.1/bits/unique_lock.h \ /usr/include/c++/15.2.1/bits/unique_lock.h \
/usr/include/c++/15.2.1/condition_variable \ /usr/include/c++/15.2.1/condition_variable \
/usr/include/c++/15.2.1/bits/atomic_futex.h \ /usr/include/c++/15.2.1/bits/atomic_futex.h \
/usr/include/c++/15.2.1/bits/std_thread.h \ /usr/include/c++/15.2.1/bits/std_thread.h /usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtGui/QMouseEvent /usr/include/qt6/QtCore/QFileInfo \ /usr/include/qt6/QtCore/qmap.h /usr/include/qt6/QtGui/QMouseEvent \
/usr/include/qt6/QtCore/qfileinfo.h /usr/include/qt6/QtCore/qfile.h \ /usr/include/qt6/QtCore/QFileInfo /usr/include/qt6/QtCore/qfileinfo.h \
/usr/include/qt6/QtCore/qfiledevice.h /usr/include/c++/15.2.1/filesystem \ /usr/include/qt6/QtCore/qfile.h /usr/include/qt6/QtCore/qfiledevice.h \
/usr/include/c++/15.2.1/bits/fs_fwd.h \ /usr/include/c++/15.2.1/filesystem /usr/include/c++/15.2.1/bits/fs_fwd.h \
/usr/include/c++/15.2.1/bits/fs_path.h /usr/include/c++/15.2.1/locale \ /usr/include/c++/15.2.1/bits/fs_path.h /usr/include/c++/15.2.1/locale \
/usr/include/c++/15.2.1/bits/locale_facets.h \ /usr/include/c++/15.2.1/bits/locale_facets.h \
/usr/include/c++/15.2.1/cwctype /usr/include/wctype.h \ /usr/include/c++/15.2.1/cwctype /usr/include/wctype.h \
@@ -438,4 +438,8 @@ CMakeFiles/screenshot-gallery.dir/src/imagegallery.cpp.o: \
/usr/include/qt6/QtCore/qurl.h /usr/include/qt6/QtGui/QPainter \ /usr/include/qt6/QtCore/qurl.h /usr/include/qt6/QtGui/QPainter \
/usr/include/qt6/QtGui/qpainter.h /usr/include/qt6/QtGui/qtextoption.h \ /usr/include/qt6/QtGui/qpainter.h /usr/include/qt6/QtGui/qtextoption.h \
/usr/include/qt6/QtGui/qpen.h /usr/include/qt6/QtWidgets/QApplication \ /usr/include/qt6/QtGui/qpen.h /usr/include/qt6/QtWidgets/QApplication \
/usr/include/qt6/QtWidgets/qapplication.h /usr/include/qt6/QtWidgets/qapplication.h \
/usr/include/qt6/QtWidgets/QFrame /usr/include/qt6/QtWidgets/qframe.h \
/usr/include/qt6/QtWidgets/QHBoxLayout \
/usr/include/qt6/QtWidgets/qboxlayout.h /usr/include/qt6/QtCore/QTimer \
/usr/include/qt6/QtCore/qtimer.h
@@ -395,7 +395,8 @@ CMakeFiles/screenshot-gallery.dir/src/main.cpp.o: \
/usr/include/c++/15.2.1/bits/unique_lock.h \ /usr/include/c++/15.2.1/bits/unique_lock.h \
/usr/include/c++/15.2.1/condition_variable \ /usr/include/c++/15.2.1/condition_variable \
/usr/include/c++/15.2.1/bits/atomic_futex.h \ /usr/include/c++/15.2.1/bits/atomic_futex.h \
/usr/include/c++/15.2.1/bits/std_thread.h \ /usr/include/c++/15.2.1/bits/std_thread.h /usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/qmap.h \
/home/master/screenshot-gallery/src/imagegallery.h \ /home/master/screenshot-gallery/src/imagegallery.h \
/usr/include/qt6/QtWidgets/QWidget /usr/include/qt6/QtWidgets/qwidget.h \ /usr/include/qt6/QtWidgets/QWidget /usr/include/qt6/QtWidgets/qwidget.h \
/usr/include/qt6/QtWidgets/QGridLayout \ /usr/include/qt6/QtWidgets/QGridLayout \
@@ -386,7 +386,8 @@ CMakeFiles/screenshot-gallery.dir/src/mainwindow.cpp.o: \
/usr/include/c++/15.2.1/bits/unique_lock.h \ /usr/include/c++/15.2.1/bits/unique_lock.h \
/usr/include/c++/15.2.1/condition_variable \ /usr/include/c++/15.2.1/condition_variable \
/usr/include/c++/15.2.1/bits/atomic_futex.h \ /usr/include/c++/15.2.1/bits/atomic_futex.h \
/usr/include/c++/15.2.1/bits/std_thread.h \ /usr/include/c++/15.2.1/bits/std_thread.h /usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/qmap.h \
/home/master/screenshot-gallery/src/imagegallery.h \ /home/master/screenshot-gallery/src/imagegallery.h \
/usr/include/qt6/QtWidgets/QWidget /usr/include/qt6/QtWidgets/qwidget.h \ /usr/include/qt6/QtWidgets/QWidget /usr/include/qt6/QtWidgets/qwidget.h \
/usr/include/qt6/QtWidgets/QGridLayout \ /usr/include/qt6/QtWidgets/QGridLayout \
File diff suppressed because it is too large Load Diff
@@ -288,6 +288,7 @@
/usr/include/pthread.h /usr/include/pthread.h
/usr/include/qt6/QtCore/QDebug /usr/include/qt6/QtCore/QDebug
/usr/include/qt6/QtCore/QList /usr/include/qt6/QtCore/QList
/usr/include/qt6/QtCore/QMap
/usr/include/qt6/QtCore/QObject /usr/include/qt6/QtCore/QObject
/usr/include/qt6/QtCore/QPair /usr/include/qt6/QtCore/QPair
/usr/include/qt6/QtCore/QProcess /usr/include/qt6/QtCore/QProcess
@@ -287,6 +287,7 @@ screenshot-gallery_autogen/timestamp: /home/master/screenshot-gallery/CMakeLists
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -1279,6 +1280,8 @@ screenshot-gallery_autogen/timestamp: /home/master/screenshot-gallery/CMakeLists
/usr/lib/cmake/Qt6/QtPublicAppleHelpers.cmake: /usr/lib/cmake/Qt6/QtPublicAppleHelpers.cmake:
/usr/lib/cmake/Qt6/Qt6Targets.cmake:
/usr/lib/cmake/Qt6Widgets/Qt6WidgetsDependencies.cmake: /usr/lib/cmake/Qt6Widgets/Qt6WidgetsDependencies.cmake:
/usr/include/c++/15.2.1/variant: /usr/include/c++/15.2.1/variant:
@@ -1495,6 +1498,8 @@ screenshot-gallery_autogen/timestamp: /home/master/screenshot-gallery/CMakeLists
/usr/include/c++/15.2.1/bits/std_function.h: /usr/include/c++/15.2.1/bits/std_function.h:
/usr/include/qt6/QtCore/QMap:
/usr/include/c++/15.2.1/typeinfo: /usr/include/c++/15.2.1/typeinfo:
/usr/include/c++/15.2.1/bits/specfun.h: /usr/include/c++/15.2.1/bits/specfun.h:
@@ -2243,8 +2248,6 @@ CMakeFiles/4.1.2/CMakeCXXCompiler.cmake:
/usr/include/qt6/QtCore/qbytearrayview.h: /usr/include/qt6/QtCore/qbytearrayview.h:
/usr/lib/cmake/Qt6/Qt6Targets.cmake:
/usr/include/c++/15.2.1/bits/uses_allocator_args.h: /usr/include/c++/15.2.1/bits/uses_allocator_args.h:
/usr/include/qt6/QtCore/qchar.h: /usr/include/qt6/QtCore/qchar.h:
Binary file not shown.
@@ -273,6 +273,7 @@
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QString \ /usr/include/qt6/QtCore/QString \
@@ -132,7 +132,9 @@ template <> constexpr inline auto ImageGallery::qt_create_metaobjectdata<qt_meta
"", "",
"searchText", "searchText",
"handleThumbnailClicked", "handleThumbnailClicked",
"filePath" "filePath",
"handleContainerResized",
"updateGridLayout"
}; };
QtMocHelpers::UintData qt_methods { QtMocHelpers::UintData qt_methods {
@@ -144,6 +146,10 @@ template <> constexpr inline auto ImageGallery::qt_create_metaobjectdata<qt_meta
QtMocHelpers::SlotData<void(const QString &)>(4, 2, QMC::AccessPublic, QMetaType::Void, {{ QtMocHelpers::SlotData<void(const QString &)>(4, 2, QMC::AccessPublic, QMetaType::Void, {{
{ QMetaType::QString, 5 }, { QMetaType::QString, 5 },
}}), }}),
// Slot 'handleContainerResized'
QtMocHelpers::SlotData<void()>(6, 2, QMC::AccessPublic, QMetaType::Void),
// Slot 'updateGridLayout'
QtMocHelpers::SlotData<void()>(7, 2, QMC::AccessPublic, QMetaType::Void),
}; };
QtMocHelpers::UintData qt_properties { QtMocHelpers::UintData qt_properties {
}; };
@@ -169,6 +175,8 @@ void ImageGallery::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id
switch (_id) { switch (_id) {
case 0: _t->handleSearchTextChanged((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break; case 0: _t->handleSearchTextChanged((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break;
case 1: _t->handleThumbnailClicked((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break; case 1: _t->handleThumbnailClicked((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break;
case 2: _t->handleContainerResized(); break;
case 3: _t->updateGridLayout(); break;
default: ; default: ;
} }
} }
@@ -193,14 +201,14 @@ int ImageGallery::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2) if (_id < 4)
qt_static_metacall(this, _c, _id, _a); qt_static_metacall(this, _c, _id, _a);
_id -= 2; _id -= 4;
} }
if (_c == QMetaObject::RegisterMethodArgumentMetaType) { if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2) if (_id < 4)
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType();
_id -= 2; _id -= 4;
} }
return _id; return _id;
} }
@@ -275,6 +275,7 @@
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
@@ -276,6 +276,7 @@
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
+1
View File
@@ -284,6 +284,7 @@ screenshot-gallery_autogen/timestamp: \
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt6/QtCore/QDebug \ /usr/include/qt6/QtCore/QDebug \
/usr/include/qt6/QtCore/QList \ /usr/include/qt6/QtCore/QList \
/usr/include/qt6/QtCore/QMap \
/usr/include/qt6/QtCore/QObject \ /usr/include/qt6/QtCore/QObject \
/usr/include/qt6/QtCore/QPair \ /usr/include/qt6/QtCore/QPair \
/usr/include/qt6/QtCore/QProcess \ /usr/include/qt6/QtCore/QProcess \
+57 -7
View File
@@ -9,6 +9,11 @@ DatabaseManager::DatabaseManager(QObject *parent)
: QObject(parent) : QObject(parent)
, m_initialized(false) , m_initialized(false)
{ {
// Initialize search cache
m_searchCache.clear();
// Create index on ocr_text if it doesn't exist
// This will be executed once the database is initialized
} }
DatabaseManager::~DatabaseManager() DatabaseManager::~DatabaseManager()
@@ -78,6 +83,10 @@ bool DatabaseManager::initialize(const QString &dbPath)
return false; return false;
} }
// Create an index on the ocr_text column if it doesn't exist
// This will speed up text searches dramatically
query.exec("CREATE INDEX IF NOT EXISTS idx_ocr_text ON ocr_results(ocr_text)");
m_initialized = true; m_initialized = true;
qDebug() << "Database initialized successfully."; qDebug() << "Database initialized successfully.";
return true; return true;
@@ -99,6 +108,9 @@ QList<DatabaseManager::ImageItem> DatabaseManager::getAllImages()
return images; return images;
} }
// Start transaction to speed up query
m_db.transaction();
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT full_path, ocr_text FROM ocr_results"); query.prepare("SELECT full_path, ocr_text FROM ocr_results");
@@ -108,6 +120,9 @@ QList<DatabaseManager::ImageItem> DatabaseManager::getAllImages()
} }
// Check if files exist as we add them // Check if files exist as we add them
// Reserve space for results to avoid reallocations
images.reserve(query.size() > 0 ? query.size() : 100);
while (query.next()) { while (query.next()) {
ImageItem item; ImageItem item;
item.filePath = query.value(0).toString(); item.filePath = query.value(0).toString();
@@ -119,6 +134,7 @@ QList<DatabaseManager::ImageItem> DatabaseManager::getAllImages()
} }
} }
m_db.commit();
return images; return images;
} }
@@ -140,24 +156,43 @@ QList<DatabaseManager::ImageItem> DatabaseManager::searchImages(const QString &s
// If search text is empty, return all images // If search text is empty, return all images
if (searchText.isEmpty()) { if (searchText.isEmpty()) {
// Clear the search cache when empty search is performed
m_searchCache.clear();
return getAllImages(); return getAllImages();
} }
// Check if we have a cached result for this search query
if (m_searchCache.contains(searchText)) {
return m_searchCache[searchText];
}
// Start transaction to speed up queries
m_db.transaction();
QSqlQuery query; QSqlQuery query;
// Use LIKE query with wildcards for flexible searching
query.prepare("SELECT full_path, ocr_text FROM ocr_results WHERE ocr_text LIKE :search");
// Ensure search text is properly sanitized // Optimize the query based on length of search text
QString sanitizedSearch = searchText; if (searchText.length() <= 3) {
sanitizedSearch.replace('\'', "''"); // Escape single quotes // For short search terms, use a more targeted approach
query.prepare("SELECT full_path, ocr_text FROM ocr_results WHERE ocr_text LIKE :search");
query.bindValue(":search", "%" + sanitizedSearch + "%"); query.bindValue(":search", "%" + searchText + "%");
} else {
// For longer search terms, use LIKE with a more specific pattern at start
// which can utilize indexes better if they exist
query.prepare("SELECT full_path, ocr_text FROM ocr_results WHERE ocr_text LIKE :search OR ocr_text LIKE :wordstart");
query.bindValue(":search", "%" + searchText + "%");
query.bindValue(":wordstart", "% " + searchText + "%");
}
if (!query.exec()) { if (!query.exec()) {
qDebug() << "Failed to search images:" << query.lastError().text(); qDebug() << "Failed to search images:" << query.lastError().text();
m_db.rollback();
return images; return images;
} }
// Reserve space for results to avoid reallocations
images.reserve(query.size() > 0 ? query.size() : 100);
while (query.next()) { while (query.next()) {
ImageItem item; ImageItem item;
item.filePath = query.value(0).toString(); item.filePath = query.value(0).toString();
@@ -169,5 +204,20 @@ QList<DatabaseManager::ImageItem> DatabaseManager::searchImages(const QString &s
} }
} }
m_db.commit();
// Cache the result for future queries
if (images.size() > 0) {
m_searchCache.insert(searchText, images);
// Limit cache size to avoid memory issues
if (m_searchCache.size() > MAX_CACHE_SIZE) {
// Remove the first key (oldest entry)
if (!m_searchCache.isEmpty()) {
m_searchCache.remove(m_searchCache.firstKey());
}
}
}
return images; return images;
} }
+7
View File
@@ -10,6 +10,7 @@
#include <QList> #include <QList>
#include <QPair> #include <QPair>
#include <QThread> #include <QThread>
#include <QMap>
/** /**
* @brief The DatabaseManager class handles all database operations * @brief The DatabaseManager class handles all database operations
@@ -63,6 +64,12 @@ public slots:
private: private:
QSqlDatabase m_db; QSqlDatabase m_db;
bool m_initialized; bool m_initialized;
// Cache for search results to improve response time
QMap<QString, QList<ImageItem>> m_searchCache;
// Maximum number of cached search queries
static const int MAX_CACHE_SIZE = 50;
}; };
#endif // DATABASEMANAGER_H #endif // DATABASEMANAGER_H
+182 -16
View File
@@ -6,6 +6,9 @@
#include <QUrl> #include <QUrl>
#include <QPainter> #include <QPainter>
#include <QApplication> #include <QApplication>
#include <QFrame>
#include <QHBoxLayout>
#include <QTimer>
// ImageThumbnail implementation // ImageThumbnail implementation
ImageThumbnail::ImageThumbnail(const QString &filePath, QWidget *parent) ImageThumbnail::ImageThumbnail(const QString &filePath, QWidget *parent)
@@ -18,7 +21,7 @@ ImageThumbnail::ImageThumbnail(const QString &filePath, QWidget *parent)
setLineWidth(2); setLineWidth(2);
setScaledContents(false); setScaledContents(false);
setCursor(Qt::PointingHandCursor); setCursor(Qt::PointingHandCursor);
setToolTip(filePath); // We're removing tooltips as requested
// Enable text wrapping and text interaction // Enable text wrapping and text interaction
setWordWrap(true); setWordWrap(true);
@@ -44,13 +47,22 @@ ImageGallery::ImageGallery(QWidget *parent)
// Create scroll area // Create scroll area
m_scrollArea = new QScrollArea(this); m_scrollArea = new QScrollArea(this);
m_scrollArea->setWidgetResizable(true); m_scrollArea->setWidgetResizable(true);
m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Prevent horizontal scrollbar
m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
// Create container widget for the grid layout // Create container widget for the grid layout
m_containerWidget = new QWidget(m_scrollArea); m_containerWidget = new QWidget(m_scrollArea);
// Make container expand to fill the available width
m_containerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
// Create grid layout with minimal spacing
m_gridLayout = new QGridLayout(m_containerWidget); m_gridLayout = new QGridLayout(m_containerWidget);
m_gridLayout->setSpacing(10); m_gridLayout->setSpacing(THUMBNAIL_SPACING);
m_gridLayout->setContentsMargins(THUMBNAIL_SPACING, THUMBNAIL_SPACING, THUMBNAIL_SPACING, THUMBNAIL_SPACING);
// Initialize column count based on container width
m_columnsCount = 4; // Default value, will be updated in updateGridLayout
m_scrollArea->setWidget(m_containerWidget); m_scrollArea->setWidget(m_containerWidget);
@@ -58,6 +70,19 @@ ImageGallery::ImageGallery(QWidget *parent)
QVBoxLayout *mainLayout = new QVBoxLayout(this); QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(m_scrollArea); mainLayout->addWidget(m_scrollArea);
setLayout(mainLayout); setLayout(mainLayout);
// No need to connect to container widget - we'll use resizeEvent instead
// Initial layout update
QTimer::singleShot(0, this, &ImageGallery::updateGridLayout);
// Install event filter on viewport to catch resize events
m_scrollArea->viewport()->installEventFilter(this);
// We'll still keep a periodic check as backup
QTimer *resizeTimer = new QTimer(this);
connect(resizeTimer, &QTimer::timeout, this, &ImageGallery::handleContainerResized);
resizeTimer->start(300); // Check every 300ms
} }
ImageGallery::~ImageGallery() ImageGallery::~ImageGallery()
@@ -75,6 +100,9 @@ void ImageGallery::displayImages(const QList<DatabaseManager::ImageItem> &images
// Clear existing thumbnails // Clear existing thumbnails
clearGallery(); clearGallery();
// Update grid layout to ensure correct column count before adding images
updateGridLayout();
const int numImages = images.size(); const int numImages = images.size();
int row = 0, col = 0; int row = 0, col = 0;
@@ -93,17 +121,29 @@ void ImageGallery::displayImages(const QList<DatabaseManager::ImageItem> &images
ImageThumbnail *thumbnailLabel = new ImageThumbnail(item.filePath, this); ImageThumbnail *thumbnailLabel = new ImageThumbnail(item.filePath, this);
thumbnailLabel->setPixmap(thumbnail); thumbnailLabel->setPixmap(thumbnail);
// Set tooltip to show file path and partial OCR text // Add filename overlay at the bottom of the thumbnail
QString tooltipText = item.filePath; QFileInfo fileNameInfo(item.filePath);
if (!item.ocrText.isEmpty()) { QString fileName = fileNameInfo.fileName();
// Limit OCR text length in tooltip
QString shortOcrText = item.ocrText; // Create overlay container with dark background
if (shortOcrText.length() > 100) { QFrame* overlay = new QFrame(thumbnailLabel);
shortOcrText = shortOcrText.left(97) + "..."; overlay->setStyleSheet("background-color: rgba(0, 0, 0, 0.7);");
} overlay->setFixedHeight(20);
tooltipText += "\n\nOCR Text:\n" + shortOcrText; overlay->setFixedWidth(THUMBNAIL_WIDTH);
}
thumbnailLabel->setToolTip(tooltipText); // Create label for the filename
QLabel* fileNameLabel = new QLabel(fileName, overlay);
fileNameLabel->setStyleSheet("color: white; background: transparent;");
fileNameLabel->setAlignment(Qt::AlignCenter);
fileNameLabel->setFixedWidth(THUMBNAIL_WIDTH - 10);
// Layout for the overlay
QHBoxLayout* overlayLayout = new QHBoxLayout(overlay);
overlayLayout->setContentsMargins(5, 0, 5, 0);
overlayLayout->addWidget(fileNameLabel);
// Position the overlay at the bottom of the thumbnail
overlay->move(0, THUMBNAIL_HEIGHT - overlay->height());
// Connect the thumbnail click signal // Connect the thumbnail click signal
connect(thumbnailLabel, &ImageThumbnail::thumbnailClicked, connect(thumbnailLabel, &ImageThumbnail::thumbnailClicked,
@@ -115,7 +155,7 @@ void ImageGallery::displayImages(const QList<DatabaseManager::ImageItem> &images
// Update row and column // Update row and column
col++; col++;
if (col >= COLUMNS) { if (col >= m_columnsCount) {
col = 0; col = 0;
row++; row++;
} }
@@ -127,7 +167,7 @@ void ImageGallery::displayImages(const QList<DatabaseManager::ImageItem> &images
ImageThumbnail *noImagesLabel = new ImageThumbnail("", this); ImageThumbnail *noImagesLabel = new ImageThumbnail("", this);
noImagesLabel->setText("No images found matching your search criteria"); noImagesLabel->setText("No images found matching your search criteria");
noImagesLabel->setAlignment(Qt::AlignCenter); noImagesLabel->setAlignment(Qt::AlignCenter);
m_gridLayout->addWidget(noImagesLabel, 0, 0, 1, COLUMNS); m_gridLayout->addWidget(noImagesLabel, 0, 0, 1, m_columnsCount);
m_thumbnails.append(noImagesLabel); m_thumbnails.append(noImagesLabel);
} }
@@ -202,6 +242,132 @@ QPixmap ImageGallery::createThumbnail(const QString &filePath, int width, int he
return pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); return pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
} }
void ImageGallery::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
// Trigger grid layout update when gallery is resized
QTimer::singleShot(0, this, &ImageGallery::updateGridLayout);
// Ensure the container widget fills the viewport width
if (m_scrollArea && m_containerWidget) {
int viewportWidth = m_scrollArea->viewport()->width();
m_containerWidget->setMinimumWidth(viewportWidth);
// Immediately update layout to avoid visual glitches during resize
m_gridLayout->activate();
m_containerWidget->updateGeometry();
}
}
// Event filter to catch viewport resize events
bool ImageGallery::eventFilter(QObject *watched, QEvent *event)
{
// Check if this is a resize event on the viewport
if (watched == m_scrollArea->viewport() && event->type() == QEvent::Resize) {
// Update the grid layout
updateGridLayout();
return false; // Allow event to propagate
}
// Pass unhandled events to parent
return QWidget::eventFilter(watched, event);
}
void ImageGallery::handleContainerResized()
{
// This will be called periodically to check if container size changed
static int lastWidth = -1;
int currentWidth = m_containerWidget->width();
if (currentWidth > 0 && currentWidth != lastWidth) {
lastWidth = currentWidth;
updateGridLayout();
}
}
void ImageGallery::updateGridLayout()
{
// Get the viewport width to determine available space
int viewportWidth = m_scrollArea->viewport()->width();
if (viewportWidth <= 0) {
return; // Can't determine width yet
}
// Force container width to match the viewport
m_containerWidget->setMinimumWidth(viewportWidth);
// Account for left and right margins in the grid layout
int availableWidth = viewportWidth - (m_gridLayout->contentsMargins().left() + m_gridLayout->contentsMargins().right());
// Calculate how many thumbnails can fit, accounting for spacing between them
int effectiveThumbnailWidth = THUMBNAIL_WIDTH + THUMBNAIL_SPACING;
// Calculate column count, allowing even very narrow views to show at least 1 column
int newColumnCount = std::max(1, availableWidth / (THUMBNAIL_WIDTH + 2 * THUMBNAIL_SPACING));
// Only update if column count changes
if (newColumnCount != m_columnsCount) {
m_columnsCount = newColumnCount;
// If we have thumbnails, rearrange them in the grid
if (!m_thumbnails.isEmpty()) {
// We need to readjust all the thumbnails to the new grid layout
// First remove all widgets from the grid
for (auto thumbnail : m_thumbnails) {
m_gridLayout->removeWidget(thumbnail);
}
// Then add them back in the new arrangement
int row = 0, col = 0;
for (auto thumbnail : m_thumbnails) {
m_gridLayout->addWidget(thumbnail, row, col);
col++;
if (col >= m_columnsCount) {
col = 0;
row++;
}
}
// Force layout update
m_gridLayout->invalidate();
m_containerWidget->adjustSize();
m_containerWidget->updateGeometry();
// Handle single column mode specially
if (m_columnsCount == 1) {
// Center the thumbnails in the viewport
int centeringMargin = (viewportWidth - THUMBNAIL_WIDTH) / 2;
centeringMargin = std::max(THUMBNAIL_SPACING, centeringMargin);
m_gridLayout->setContentsMargins(centeringMargin, THUMBNAIL_SPACING, centeringMargin, THUMBNAIL_SPACING);
// Let all thumbnails expand to fill available width in single column mode
for (auto thumbnail : m_thumbnails) {
thumbnail->setMaximumWidth(THUMBNAIL_WIDTH);
thumbnail->setAlignment(Qt::AlignCenter);
}
} else {
// For multi-column, use minimal margins
m_gridLayout->setContentsMargins(THUMBNAIL_SPACING, THUMBNAIL_SPACING, THUMBNAIL_SPACING, THUMBNAIL_SPACING);
// Reset thumbnail constraints
for (auto thumbnail : m_thumbnails) {
thumbnail->setMaximumWidth(QWIDGETSIZE_MAX);
}
// For multi-column, let the container fill the viewport
m_containerWidget->setMinimumWidth(viewportWidth);
}
// Update the layout again after a short delay to handle edge cases
QTimer::singleShot(10, this, [this](){
m_gridLayout->update();
m_containerWidget->update();
});
}
}
}
QPixmap ImageGallery::createPlaceholderThumbnail(int width, int height, const QString &message) QPixmap ImageGallery::createPlaceholderThumbnail(int width, int height, const QString &message)
{ {
// Create a placeholder image with text // Create a placeholder image with text
+8 -1
View File
@@ -14,9 +14,9 @@
#include "databasemanager.h" #include "databasemanager.h"
// Global constants // Global constants
static const int COLUMNS = 4;
static const int THUMBNAIL_WIDTH = 256; static const int THUMBNAIL_WIDTH = 256;
static const int THUMBNAIL_HEIGHT = 256; static const int THUMBNAIL_HEIGHT = 256;
static const int THUMBNAIL_SPACING = 2; // Reduced spacing between thumbnails
class ImageThumbnail : public QLabel class ImageThumbnail : public QLabel
{ {
@@ -52,6 +52,12 @@ public:
public slots: public slots:
void handleSearchTextChanged(const QString &searchText); void handleSearchTextChanged(const QString &searchText);
void handleThumbnailClicked(const QString &filePath); void handleThumbnailClicked(const QString &filePath);
void handleContainerResized(); // New slot to handle resize events
void updateGridLayout(); // Adjusts grid based on current window size
protected:
void resizeEvent(QResizeEvent *event) override;
bool eventFilter(QObject *watched, QEvent *event) override;
private: private:
QGridLayout *m_gridLayout; QGridLayout *m_gridLayout;
@@ -59,6 +65,7 @@ private:
QWidget *m_containerWidget; QWidget *m_containerWidget;
DatabaseManager *m_dbManager; DatabaseManager *m_dbManager;
QList<ImageThumbnail*> m_thumbnails; QList<ImageThumbnail*> m_thumbnails;
int m_columnsCount; // Dynamic column count based on window size
QPixmap createThumbnail(const QString &filePath, int width, int height); QPixmap createThumbnail(const QString &filePath, int width, int height);
QPixmap createPlaceholderThumbnail(int width, int height, const QString &message); QPixmap createPlaceholderThumbnail(int width, int height, const QString &message);
+25 -7
View File
@@ -19,6 +19,9 @@ MainWindow::MainWindow(QWidget *parent)
setWindowTitle(tr("Screenshot OCR Gallery")); setWindowTitle(tr("Screenshot OCR Gallery"));
resize(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT); resize(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT);
// Remove fixed minimum size to allow for single column layout at any width
// setMinimumSize(640, 480);
// Center window on screen // Center window on screen
QScreen *screen = QGuiApplication::primaryScreen(); QScreen *screen = QGuiApplication::primaryScreen();
if (screen) { if (screen) {
@@ -61,6 +64,8 @@ void MainWindow::createLayout()
// Create main layout // Create main layout
m_mainLayout = new QVBoxLayout(m_centralWidget); m_mainLayout = new QVBoxLayout(m_centralWidget);
m_mainLayout->setSpacing(5); // Reduce spacing between elements
m_mainLayout->setContentsMargins(5, 5, 5, 5); // Reduce margins
// Create title label // Create title label
m_titleLabel = new QLabel(tr("Screenshot OCR Gallery"), this); m_titleLabel = new QLabel(tr("Screenshot OCR Gallery"), this);
@@ -77,6 +82,7 @@ void MainWindow::createLayout()
// Create gallery widget // Create gallery widget
m_imageGallery = new ImageGallery(this); m_imageGallery = new ImageGallery(this);
m_imageGallery->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// Add widgets to layout // Add widgets to layout
m_mainLayout->addWidget(m_titleLabel); m_mainLayout->addWidget(m_titleLabel);
@@ -140,15 +146,16 @@ void MainWindow::handleSearchTextChanged()
return; return;
} }
// Restart the timer each time the user types
m_searchDelayTimer->start();
// If search bar is cleared, immediately show all images // If search bar is cleared, immediately show all images
if (m_searchBar->text().isEmpty() && !m_lastSearchText.isEmpty()) { if (m_searchBar->text().isEmpty()) {
m_lastSearchText.clear(); m_lastSearchText.clear();
m_searchDelayTimer->stop(); m_searchDelayTimer->stop();
performSearch(); displayAllImages(); // Show all images immediately
return; // Skip the timer since we've already updated
} }
// For non-empty searches, restart the timer each time the user types
m_searchDelayTimer->start();
} }
void MainWindow::performSearch() void MainWindow::performSearch()
@@ -203,6 +210,17 @@ void MainWindow::resizeEvent(QResizeEvent *event)
{ {
QMainWindow::resizeEvent(event); QMainWindow::resizeEvent(event);
// The ImageGallery widget will automatically adjust to the new size // Notify the image gallery of the resize event
// because of the layout system, but you can add custom resize handling here if needed if (m_imageGallery) {
// The gallery will handle its own layout updates through its resize event
// Just make sure it's visible and has the correct size policy
m_imageGallery->setVisible(true);
}
// Update status bar to show current window dimensions
// This helps with debugging layout issues
if (statusBar() && statusBar()->isVisible()) {
QString sizeInfo = QString("Window size: %1×%2").arg(width()).arg(height());
statusBar()->showMessage(sizeInfo, 1000);
}
} }
+1 -1
View File
@@ -46,7 +46,7 @@ private:
bool m_hasValidDatabase; bool m_hasValidDatabase;
// Constants // Constants
static constexpr int SEARCH_DELAY_MS = 300; // Delay for search typing static constexpr int SEARCH_DELAY_MS = 50; // Reduced delay for more responsive typing
static constexpr int DEFAULT_WINDOW_WIDTH = 1200; static constexpr int DEFAULT_WINDOW_WIDTH = 1200;
static constexpr int DEFAULT_WINDOW_HEIGHT = 800; static constexpr int DEFAULT_WINDOW_HEIGHT = 800;
static const QString DEFAULT_DB_PATH; static const QString DEFAULT_DB_PATH;