| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
1 |
#include "mainwindow.h" |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
2 |
#include "imagemodel.h" |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
3 |
#include "imageviewwidget.h" |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
4 |
#include "preferencesdialog.h" |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
5 |
#include "thumbnailcache.h" |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
6 |
#include "exifreader.h" |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
7 |
#include "fsdirmodel.h" |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
8 |
#include "pathcompletermodel.h" |
| 1dcea855 |
Poul Sander |
2026-05-26 21:48 |
9 |
#include "thumbnaildelegate.h" |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
10 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
11 |
#include <QFile> |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
12 |
#include <QTreeView> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
13 |
#include <QTreeView> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
14 |
#include <QListView> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
15 |
#include <QLabel> |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
16 |
#include <QStackedWidget> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
17 |
#include <QDir> |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
18 |
#include <QListWidget> |
| fc5f2e27 |
Poul Sander |
2026-02-22 22:06 |
19 |
#include <QStandardPaths> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
20 |
#include <QImageReader> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
21 |
#include <QHeaderView> |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
22 |
#include <QScrollBar> |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
23 |
#include <QTimer> |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
24 |
#include <QEvent> |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
25 |
#include <QKeyEvent> |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
26 |
#include <QCloseEvent> |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
27 |
#include <QItemSelectionModel> |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
28 |
#include <QDockWidget> |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
29 |
#include <QMenuBar> |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
30 |
#include <QMenu> |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
31 |
#include <QAction> |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
32 |
#include <QSettings> |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
33 |
#include <QTableWidget> |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
34 |
#include <QDialog> |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
35 |
#include <QVBoxLayout> |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
36 |
#include <QHBoxLayout> |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
37 |
#include <QDialogButtonBox> |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
38 |
#include <QPlainTextEdit> |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
39 |
#include <QMessageBox> |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
40 |
#include <QLineEdit> |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
41 |
#include <QPushButton> |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
42 |
#include <QCompleter> |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
43 |
#include <iostream> |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
44 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
45 |
#include <fcntl.h> |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
46 |
#include <sys/stat.h> |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
47 |
#include <unistd.h> |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
48 |
|
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
49 |
namespace |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
50 |
{ |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
51 |
ThumbnailCache::Size thumbnailSizeFromString(const QString &s) |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
52 |
{ |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
53 |
return (s == "large") ? ThumbnailCache::Size::Large |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
54 |
: ThumbnailCache::Size::Normal; |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
55 |
} |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
56 |
} // namespace |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
57 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
58 |
MainWindow::MainWindow(QWidget *parent) |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
59 |
: QMainWindow(parent) |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
60 |
{ |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
61 |
setupUi(); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
62 |
setupMenuBar(); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
63 |
setupConnections(); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
64 |
loadPreferences(); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
65 |
} |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
66 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
67 |
void MainWindow::setupUi() |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
68 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
69 |
// Folder model (left pane) — backed by std::filesystem so directories with |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
70 |
// non-UTF-8 filenames are listed correctly. |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
71 |
m_dirModel = new FsDirModel(this); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
72 |
m_dirModel->setRootPath(QDir::homePath()); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
73 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
74 |
// Root chooser list |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
75 |
m_rootList = new QListWidget; |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
76 |
m_rootList->setSelectionMode(QAbstractItemView::SingleSelection); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
77 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
78 |
auto addRootItem = [this](const QString &label, const QString &path) { |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
79 |
QListWidgetItem *item = new QListWidgetItem(label, m_rootList); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
80 |
item->setData(Qt::UserRole, path); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
81 |
}; |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
82 |
addRootItem("Home", QDir::homePath()); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
83 |
addRootItem("Pictures", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
84 |
addRootItem("File System", QDir::rootPath()); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
85 |
m_rootList->setCurrentRow(0); |
| fc5f2e27 |
Poul Sander |
2026-02-22 22:06 |
86 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
87 |
m_treeView = new QTreeView; |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
88 |
m_treeView->setModel(m_dirModel); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
89 |
m_treeView->setRootIndex(m_dirModel->rootIndex()); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
90 |
m_treeView->header()->hide(); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
91 |
m_treeView->setColumnHidden(1, true); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
92 |
m_treeView->setColumnHidden(2, true); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
93 |
m_treeView->setColumnHidden(3, true); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
94 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
95 |
// Thumbnail model (center pane) |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
96 |
m_imageModel = new ImageModel(this); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
97 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
98 |
m_listView = new QListView; |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
99 |
m_listView->setModel(m_imageModel); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
100 |
m_listView->setViewMode(QListView::IconMode); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
101 |
m_listView->setIconSize(QSize(128, 128)); |
| b614a581 |
Poul Sander |
2026-02-19 21:18 |
102 |
m_listView->setGridSize(QSize(148, 168)); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
103 |
m_listView->setResizeMode(QListView::Adjust); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
104 |
m_listView->setSelectionMode(QAbstractItemView::SingleSelection); |
| b614a581 |
Poul Sander |
2026-02-19 21:18 |
105 |
m_listView->setSpacing(4); |
| b614a581 |
Poul Sander |
2026-02-19 21:18 |
106 |
m_listView->setWordWrap(true); |
| b614a581 |
Poul Sander |
2026-02-19 21:18 |
107 |
m_listView->setTextElideMode(Qt::ElideRight); |
| 1dcea855 |
Poul Sander |
2026-05-26 21:48 |
108 |
m_listView->setItemDelegate(new ThumbnailDelegate(this)); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
109 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
110 |
// Preview pane (right) |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
111 |
m_previewLabel = new QLabel; |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
112 |
m_previewLabel->setAlignment(Qt::AlignCenter); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
113 |
m_previewLabel->setMinimumWidth(200); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
114 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
115 |
// Single image view |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
116 |
m_imageView = new ImageViewWidget; |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
117 |
|
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
118 |
// Path bar: editable absolute path with ajax-style folder completion and a Go button |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
119 |
m_pathEdit = new QLineEdit; |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
120 |
m_goButton = new QPushButton(tr("Go")); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
121 |
m_pathCompleterModel = new PathCompleterModel(this); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
122 |
m_pathCompleter = new QCompleter(m_pathCompleterModel, this); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
123 |
m_pathCompleter->setCaseSensitivity(Qt::CaseSensitive); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
124 |
m_pathCompleter->setCompletionMode(QCompleter::PopupCompletion); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
125 |
m_pathCompleter->setFilterMode(Qt::MatchStartsWith); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
126 |
m_pathEdit->setCompleter(m_pathCompleter); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
127 |
|
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
128 |
auto *pathRow = new QHBoxLayout; |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
129 |
pathRow->setContentsMargins(4, 4, 4, 0); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
130 |
pathRow->addWidget(m_pathEdit, 1); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
131 |
pathRow->addWidget(m_goButton); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
132 |
|
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
133 |
auto *browserPage = new QWidget; |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
134 |
auto *vbox = new QVBoxLayout(browserPage); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
135 |
vbox->setContentsMargins(0, 0, 0, 0); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
136 |
vbox->setSpacing(0); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
137 |
vbox->addLayout(pathRow); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
138 |
vbox->addWidget(m_listView, 1); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
139 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
140 |
// Stack to switch between browser and single image |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
141 |
m_stack = new QStackedWidget; |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
142 |
m_stack->addWidget(browserPage); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
143 |
m_stack->addWidget(m_imageView); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
144 |
m_browserPage = browserPage; |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
145 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
146 |
setCentralWidget(m_stack); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
147 |
|
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
148 |
updatePathField(QFile::encodeName(QDir::homePath())); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
149 |
|
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
150 |
// Dock widgets — can be dragged, floated and stacked by the user |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
151 |
m_rootDock = new QDockWidget(tr("Roots"), this); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
152 |
m_rootDock->setObjectName("RootDock"); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
153 |
m_rootDock->setWidget(m_rootList); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
154 |
addDockWidget(Qt::LeftDockWidgetArea, m_rootDock); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
155 |
|
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
156 |
m_folderDock = new QDockWidget(tr("Folders"), this); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
157 |
m_folderDock->setObjectName("FolderDock"); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
158 |
m_folderDock->setWidget(m_treeView); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
159 |
addDockWidget(Qt::LeftDockWidgetArea, m_folderDock); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
160 |
splitDockWidget(m_rootDock, m_folderDock, Qt::Vertical); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
161 |
|
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
162 |
m_previewDock = new QDockWidget(tr("Preview"), this); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
163 |
m_previewDock->setObjectName("PreviewDock"); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
164 |
m_previewDock->setWidget(m_previewLabel); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
165 |
addDockWidget(Qt::RightDockWidgetArea, m_previewDock); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
166 |
|
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
167 |
// EXIF info dock — placed below the preview dock by default |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
168 |
m_exifTable = new QTableWidget(0, 2); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
169 |
m_exifTable->setHorizontalHeaderLabels({tr("Field"), tr("Value")}); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
170 |
m_exifTable->horizontalHeader()->setStretchLastSection(true); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
171 |
m_exifTable->verticalHeader()->hide(); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
172 |
m_exifTable->setEditTriggers(QAbstractItemView::NoEditTriggers); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
173 |
m_exifTable->setSelectionMode(QAbstractItemView::NoSelection); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
174 |
m_exifTable->setShowGrid(false); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
175 |
m_exifTable->setAlternatingRowColors(true); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
176 |
m_exifTable->setMinimumWidth(200); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
177 |
|
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
178 |
m_exifDock = new QDockWidget(tr("EXIF Info"), this); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
179 |
m_exifDock->setObjectName("ExifDock"); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
180 |
m_exifDock->setWidget(m_exifTable); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
181 |
addDockWidget(Qt::RightDockWidgetArea, m_exifDock); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
182 |
splitDockWidget(m_previewDock, m_exifDock, Qt::Vertical); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
183 |
} |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
184 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
185 |
void MainWindow::setupMenuBar() |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
186 |
{ |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
187 |
m_menuBar = menuBar(); |
| 0df01dc1 |
Poul Sander |
2026-02-24 18:51 |
188 |
m_menuBar->setStyleSheet( |
| 0df01dc1 |
Poul Sander |
2026-02-24 18:51 |
189 |
"QMenuBar { padding: 1px 2px; }" |
| 0df01dc1 |
Poul Sander |
2026-02-24 18:51 |
190 |
"QMenuBar::item { padding: 2px 6px; }" |
| 0df01dc1 |
Poul Sander |
2026-02-24 18:51 |
191 |
); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
192 |
QMenu *viewMenu = m_menuBar->addMenu("&View"); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
193 |
viewMenu->addAction(m_rootDock->toggleViewAction()); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
194 |
viewMenu->addAction(m_folderDock->toggleViewAction()); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
195 |
viewMenu->addAction(m_previewDock->toggleViewAction()); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
196 |
viewMenu->addAction(m_exifDock->toggleViewAction()); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
197 |
|
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
198 |
QMenu *editMenu = m_menuBar->addMenu("&Edit"); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
199 |
QAction *preferencesAction = editMenu->addAction("&Preferences"); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
200 |
connect(preferencesAction, &QAction::triggered, this, &MainWindow::onPreferencesTriggered); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
201 |
} |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
202 |
|
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
203 |
void MainWindow::navigateToFolder(const QString &path) |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
204 |
{ |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
205 |
navigateToFolder(QFile::encodeName(path)); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
206 |
} |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
207 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
208 |
void MainWindow::navigateToFolder(const QByteArray &path) |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
209 |
{ |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
210 |
m_previousFolderPath = m_imageModel->currentDirectory(); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
211 |
m_imageModel->setDirectory(path); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
212 |
QModelIndex dirIdx = m_dirModel->indexForPath(path); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
213 |
if (dirIdx.isValid()) |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
214 |
m_treeView->setCurrentIndex(dirIdx); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
215 |
updatePathField(path); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
216 |
QTimer::singleShot(0, this, [this]() { |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
217 |
selectPreviousFolderIfExists(); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
218 |
loadVisibleThumbnails(); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
219 |
}); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
220 |
} |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
221 |
|
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
222 |
void MainWindow::updatePathField(const QByteArray &path) |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
223 |
{ |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
224 |
if (!m_pathEdit) |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
225 |
return; |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
226 |
const QString text = QFile::decodeName(path); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
227 |
if (m_pathEdit->text() != text) |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
228 |
m_pathEdit->setText(text); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
229 |
} |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
230 |
|
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
231 |
void MainWindow::onPathEntered() |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
232 |
{ |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
233 |
const QString text = m_pathEdit->text().trimmed(); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
234 |
if (text.isEmpty()) |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
235 |
return; |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
236 |
openPath(text); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
237 |
} |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
238 |
|
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
239 |
void MainWindow::openPath(const QString &path) |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
240 |
{ |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
241 |
QFileInfo info(path); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
242 |
if (!info.exists()) |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
243 |
return; |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
244 |
|
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
245 |
if (info.isDir()) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
246 |
navigateToFolder(QFile::encodeName(info.absoluteFilePath())); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
247 |
} else if (info.isFile()) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
248 |
navigateToFolder(QFile::encodeName(info.absolutePath())); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
249 |
|
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
250 |
// ImageModel::setDirectory is synchronous, so items are ready now. |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
251 |
// Find the file in the model and open it. |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
252 |
QByteArray target = QFile::encodeName(info.absoluteFilePath()); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
253 |
for (int i = 0; i < m_imageModel->rowCount(); ++i) { |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
254 |
QModelIndex idx = m_imageModel->index(i); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
255 |
if (m_imageModel->filePath(idx) == target) { |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
256 |
m_listView->setCurrentIndex(idx); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
257 |
m_listView->scrollTo(idx); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
258 |
showPreview(idx); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
259 |
if (!m_imageModel->isFolder(idx)) |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
260 |
enterSingleImageMode(idx); |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
261 |
break; |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
262 |
} |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
263 |
} |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
264 |
} |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
265 |
} |
| 48607848 |
Poul Sander |
2026-05-19 19:20 |
266 |
|
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
267 |
void MainWindow::selectPreviousFolderIfExists() |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
268 |
{ |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
269 |
if (m_previousFolderPath.isEmpty()) |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
270 |
return; |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
271 |
|
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
272 |
// Find the previous folder in the current directory's contents |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
273 |
for (int i = 0; i < m_imageModel->rowCount(); ++i) { |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
274 |
QModelIndex idx = m_imageModel->index(i); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
275 |
if (m_imageModel->isFolder(idx)) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
276 |
QByteArray folderPath = m_imageModel->filePath(idx); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
277 |
if (folderPath == m_previousFolderPath) { |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
278 |
m_listView->setCurrentIndex(idx); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
279 |
m_listView->scrollTo(idx); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
280 |
return; |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
281 |
} |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
282 |
} |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
283 |
} |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
284 |
} |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
285 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
286 |
void MainWindow::setupConnections() |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
287 |
{ |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
288 |
connect(m_pathEdit, &QLineEdit::returnPressed, |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
289 |
this, &MainWindow::onPathEntered); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
290 |
connect(m_goButton, &QPushButton::clicked, |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
291 |
this, &MainWindow::onPathEntered); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
292 |
connect(m_pathEdit, &QLineEdit::textEdited, |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
293 |
m_pathCompleterModel, &PathCompleterModel::setPrefix); |
| fd7f51cd |
Poul Sander |
2026-05-22 15:30 |
294 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
295 |
connect(m_rootList, &QListWidget::currentItemChanged, this, |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
296 |
[this](QListWidgetItem *current, QListWidgetItem *) { |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
297 |
if (current == nullptr) |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
298 |
return; |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
299 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
300 |
QString rootPath = current->data(Qt::UserRole).toString(); |
| fc5f2e27 |
Poul Sander |
2026-02-22 22:06 |
301 |
m_dirModel->setRootPath(rootPath); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
302 |
m_treeView->setRootIndex(m_dirModel->rootIndex()); |
| fc5f2e27 |
Poul Sander |
2026-02-22 22:06 |
303 |
}); |
| fc5f2e27 |
Poul Sander |
2026-02-22 22:06 |
304 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
305 |
connect(m_treeView, &QTreeView::clicked, this, |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
306 |
[this](const QModelIndex &index) |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
307 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
308 |
QByteArray path = m_dirModel->filePath(index); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
309 |
navigateToFolder(path); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
310 |
}); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
311 |
|
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
312 |
connect(m_listView, &QListView::clicked, this, |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
313 |
[this](const QModelIndex &index) { showPreview(index); }); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
314 |
|
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
315 |
connect(m_listView->selectionModel(), &QItemSelectionModel::currentChanged, |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
316 |
this, [this](const QModelIndex ¤t) { showPreview(current); }); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
317 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
318 |
connect(m_listView, &QListView::doubleClicked, this, |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
319 |
[this](const QModelIndex &index) { |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
320 |
if (m_imageModel->isFolder(index)) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
321 |
QByteArray path = m_imageModel->filePath(index); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
322 |
navigateToFolder(path); |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
323 |
} else { |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
324 |
enterSingleImageMode(index); |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
325 |
} |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
326 |
}); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
327 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
328 |
connect(m_imageView, &ImageViewWidget::closeRequested, |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
329 |
this, &MainWindow::leaveSingleImageMode); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
330 |
connect(m_imageView, &ImageViewWidget::editCaptionRequested, |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
331 |
this, &MainWindow::onEditCaption); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
332 |
connect(m_imageView, &ImageViewWidget::nextRequested, this, [this]() { |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
333 |
QModelIndex cur = m_listView->currentIndex(); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
334 |
int next = cur.isValid() ? cur.row() + 1 : 0; |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
335 |
while (next < m_imageModel->rowCount() && m_imageModel->isFolder(m_imageModel->index(next))) |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
336 |
++next; |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
337 |
if (next < m_imageModel->rowCount()) |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
338 |
{ |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
339 |
QModelIndex idx = m_imageModel->index(next); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
340 |
m_listView->setCurrentIndex(idx); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
341 |
enterSingleImageMode(idx); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
342 |
} |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
343 |
}); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
344 |
|
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
345 |
connect(m_imageView, &ImageViewWidget::previousRequested, this, [this]() { |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
346 |
QModelIndex cur = m_listView->currentIndex(); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
347 |
int prev = cur.isValid() ? cur.row() - 1 : 0; |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
348 |
while (prev >= 0 && m_imageModel->isFolder(m_imageModel->index(prev))) |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
349 |
--prev; |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
350 |
if (prev >= 0) |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
351 |
{ |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
352 |
QModelIndex idx = m_imageModel->index(prev); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
353 |
m_listView->setCurrentIndex(idx); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
354 |
enterSingleImageMode(idx); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
355 |
} |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
356 |
}); |
| 1ffc1962 |
Poul Sander |
2026-02-20 23:41 |
357 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
358 |
connect(m_listView->verticalScrollBar(), &QScrollBar::valueChanged, |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
359 |
this, [this]() |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
360 |
{ loadVisibleThumbnails(); }); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
361 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
362 |
// Also catch resize — visible range changes when the viewport is resized |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
363 |
m_listView->viewport()->installEventFilter(this); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
364 |
} |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
365 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
366 |
bool MainWindow::eventFilter(QObject *obj, QEvent *event) |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
367 |
{ |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
368 |
if (obj == m_listView->viewport() && event->type() == QEvent::Resize) |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
369 |
QTimer::singleShot(0, this, &MainWindow::loadVisibleThumbnails); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
370 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
371 |
return QMainWindow::eventFilter(obj, event); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
372 |
} |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
373 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
374 |
void MainWindow::loadVisibleThumbnails() |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
375 |
{ |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
376 |
QModelIndex topLeft = m_listView->indexAt(QPoint(0, 0)); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
377 |
QModelIndex bottomRight = m_listView->indexAt( |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
378 |
QPoint(m_listView->viewport()->width() - 1, |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
379 |
m_listView->viewport()->height() - 1)); |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
380 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
381 |
int first = topLeft.isValid() ? topLeft.row() : 0; |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
382 |
int last = bottomRight.isValid() ? bottomRight.row() |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
383 |
: m_imageModel->rowCount() - 1; |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
384 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
385 |
if (last < 0) |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
386 |
return; |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
387 |
|
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
388 |
std::cout << "loadVisibleThumbnails: " << first << " - " << last << "\n"; |
| 6fcd6c90 |
Poul Sander |
2026-02-19 21:12 |
389 |
m_imageModel->requestThumbnails(first, last); |
| 032aa1e1 |
Poul Sander |
2026-02-19 18:55 |
390 |
} |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
391 |
|
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
392 |
void MainWindow::showPreview(const QModelIndex &index) |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
393 |
{ |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
394 |
if (!index.isValid()) |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
395 |
return; |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
396 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
397 |
QByteArray path = m_imageModel->filePath(index); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
398 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
399 |
int fd = ::open(path.constData(), O_RDONLY | O_CLOEXEC); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
400 |
if (fd >= 0) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
401 |
QFile file; |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
402 |
if (file.open(fd, QIODevice::ReadOnly, QFileDevice::AutoCloseHandle)) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
403 |
QImageReader reader(&file); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
404 |
reader.setAutoTransform(true); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
405 |
QSize fullSize = reader.size(); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
406 |
if (fullSize.isValid()) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
407 |
QSize target = fullSize.scaled(m_previewLabel->size(), Qt::KeepAspectRatio); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
408 |
reader.setScaledSize(target); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
409 |
} |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
410 |
QImage image = reader.read(); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
411 |
m_previewLabel->setPixmap( |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
412 |
QPixmap::fromImage(image).scaled( |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
413 |
m_previewLabel->size(), |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
414 |
Qt::KeepAspectRatio, |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
415 |
Qt::SmoothTransformation)); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
416 |
} |
| 7889168c |
Poul Sander |
2026-02-26 18:27 |
417 |
} |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
418 |
|
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
419 |
updateExifInfo(path); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
420 |
} |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
421 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
422 |
void MainWindow::updateExifInfo(const QByteArray &path) |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
423 |
{ |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
424 |
// Check if this is a folder by attempting stat |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
425 |
struct ::stat st{}; |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
426 |
if (::stat(path.constData(), &st) != 0 || S_ISDIR(st.st_mode)) { |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
427 |
m_exifTable->setRowCount(0); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
428 |
return; |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
429 |
} |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
430 |
const ExifData data = ExifReader::read(path); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
431 |
const auto fields = data.toList(); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
432 |
m_exifTable->setRowCount(fields.size()); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
433 |
for (int i = 0; i < fields.size(); ++i) { |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
434 |
m_exifTable->setItem(i, 0, new QTableWidgetItem(fields[i].first)); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
435 |
m_exifTable->setItem(i, 1, new QTableWidgetItem(fields[i].second)); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
436 |
} |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
437 |
m_exifTable->resizeColumnToContents(0); |
| cfe4a67b |
Poul Sander |
2026-02-19 23:06 |
438 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
439 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
440 |
void MainWindow::enterSingleImageMode(const QModelIndex &index) |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
441 |
{ |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
442 |
if (!index.isValid()) |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
443 |
return; |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
444 |
|
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
445 |
// Only save state and hide chrome when transitioning from browse mode |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
446 |
if (m_stack->currentWidget() != m_imageView) { |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
447 |
m_rootDockWasVisible = m_rootDock->isVisible(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
448 |
m_folderDockWasVisible = m_folderDock->isVisible(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
449 |
m_previewDockWasVisible = m_previewDock->isVisible(); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
450 |
m_exifDockWasVisible = m_exifDock->isVisible(); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
451 |
m_rootDock->hide(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
452 |
m_folderDock->hide(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
453 |
m_previewDock->hide(); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
454 |
m_exifDock->hide(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
455 |
m_menuBar->hide(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
456 |
} |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
457 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
458 |
m_imageView->setBackgroundColor(m_backgroundColorPreference); |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
459 |
QByteArray path = m_imageModel->filePath(index); |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
460 |
m_imageView->setNeighborPaths(computeNeighborPaths(index)); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
461 |
m_imageView->setImage(path); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
462 |
m_imageView->setExifData(ExifReader::read(path)); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
463 |
updateExifInfo(path); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
464 |
m_stack->setCurrentWidget(m_imageView); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
465 |
m_imageView->setFocus(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
466 |
|
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
467 |
if (m_imageViewWasFullScreen) { |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
468 |
setFullScreenMode(true); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
469 |
m_imageViewWasFullScreen = false; |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
470 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
471 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
472 |
|
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
473 |
void MainWindow::onEditCaption() |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
474 |
{ |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
475 |
const QByteArray path = m_imageView->currentPath(); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
476 |
if (path.isEmpty()) |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
477 |
return; |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
478 |
|
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
479 |
if (::access(path.constData(), W_OK) != 0) { |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
480 |
QMessageBox::warning(this, tr("Cannot Edit Caption"), |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
481 |
tr("The file is write-protected and cannot be edited.\n\n%1") |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
482 |
.arg(QString::fromLocal8Bit(path))); |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
483 |
return; |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
484 |
} |
| 835a6bea |
Poul Sander |
2026-05-19 22:03 |
485 |
|
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
486 |
ExifData data = ExifReader::read(path); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
487 |
|
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
488 |
QDialog dlg(this); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
489 |
dlg.setWindowTitle(tr("Edit Caption")); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
490 |
auto *layout = new QVBoxLayout(&dlg); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
491 |
layout->addWidget(new QLabel(tr("Caption-Abstract:"), &dlg)); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
492 |
auto *edit = new QPlainTextEdit(&dlg); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
493 |
edit->setPlainText(data.captionAbstract); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
494 |
edit->setMinimumWidth(400); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
495 |
layout->addWidget(edit); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
496 |
auto *buttons = new QDialogButtonBox( |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
497 |
QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
498 |
layout->addWidget(buttons); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
499 |
connect(buttons, &QDialogButtonBox::accepted, &dlg, &QDialog::accept); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
500 |
connect(buttons, &QDialogButtonBox::rejected, &dlg, &QDialog::reject); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
501 |
|
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
502 |
if (dlg.exec() != QDialog::Accepted) |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
503 |
return; |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
504 |
|
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
505 |
const QString newCaption = edit->toPlainText(); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
506 |
if (ExifReader::saveCaption(path, newCaption, data)) { |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
507 |
ExifData updated = ExifReader::read(path); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
508 |
m_imageView->setExifData(updated); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
509 |
updateExifInfo(path); |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
510 |
} |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
511 |
} |
| beb4a823 |
Poul Sander |
2026-05-19 21:53 |
512 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
513 |
void MainWindow::leaveSingleImageMode() |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
514 |
{ |
| 3968465e |
Poul Sander |
2026-02-23 19:13 |
515 |
if (isFullScreen()) { |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
516 |
m_imageViewWasFullScreen = true; |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
517 |
setFullScreenMode(false); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
518 |
} |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
519 |
m_imageView->clearCache(); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
520 |
m_stack->setCurrentWidget(m_browserPage); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
521 |
m_menuBar->show(); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
522 |
if (m_rootDockWasVisible) |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
523 |
m_rootDock->show(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
524 |
if (m_folderDockWasVisible) |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
525 |
m_folderDock->show(); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
526 |
if (m_previewDockWasVisible) |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
527 |
m_previewDock->show(); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
528 |
if (m_exifDockWasVisible) |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
529 |
m_exifDock->show(); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
530 |
m_listView->setFocus(); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
531 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
532 |
|
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
533 |
QList<QByteArray> MainWindow::computeNeighborPaths(const QModelIndex &index) const |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
534 |
{ |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
535 |
QList<QByteArray> paths; |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
536 |
int row = index.row(); |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
537 |
|
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
538 |
// Collect up to CacheKeepBehind non-folder images before current |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
539 |
int count = 0; |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
540 |
for (int i = row - 1; i >= 0 && count < ImageViewWidget::CacheKeepBehind; --i) { |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
541 |
QModelIndex idx = m_imageModel->index(i); |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
542 |
if (!m_imageModel->isFolder(idx)) { |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
543 |
paths.prepend(m_imageModel->filePath(idx)); |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
544 |
++count; |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
545 |
} |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
546 |
} |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
547 |
|
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
548 |
// Collect up to CacheReadAhead non-folder images after current |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
549 |
count = 0; |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
550 |
for (int i = row + 1; i < m_imageModel->rowCount() && count < ImageViewWidget::CacheReadAhead; ++i) { |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
551 |
QModelIndex idx = m_imageModel->index(i); |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
552 |
if (!m_imageModel->isFolder(idx)) { |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
553 |
paths.append(m_imageModel->filePath(idx)); |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
554 |
++count; |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
555 |
} |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
556 |
} |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
557 |
|
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
558 |
return paths; |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
559 |
} |
| 58103277 |
Poul Sander |
2026-03-01 22:53 |
560 |
|
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
561 |
void MainWindow::setFullScreenMode(bool fullScreen) |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
562 |
{ |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
563 |
if (fullScreen == isFullScreen()) |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
564 |
return; |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
565 |
|
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
566 |
if (fullScreen) { |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
567 |
m_wasMaximized = isMaximized(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
568 |
m_menuBar->hide(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
569 |
showFullScreen(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
570 |
} else { |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
571 |
// Only restore menu bar when returning to browse mode |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
572 |
if (m_stack->currentWidget() != m_imageView) |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
573 |
m_menuBar->show(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
574 |
if (m_wasMaximized) |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
575 |
showMaximized(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
576 |
else |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
577 |
showNormal(); |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
578 |
} |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
579 |
} |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
580 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
581 |
void MainWindow::keyPressEvent(QKeyEvent *event) |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
582 |
{ |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
583 |
if (event->key() == Qt::Key_F11 && m_stack->currentWidget() == m_imageView) |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
584 |
{ |
| ccb726b8 |
Poul Sander |
2026-02-23 22:43 |
585 |
setFullScreenMode(!isFullScreen()); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
586 |
event->accept(); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
587 |
return; |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
588 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
589 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
590 |
if (event->key() == Qt::Key_Return && m_stack->currentWidget() == m_browserPage) |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
591 |
{ |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
592 |
QModelIndex current = m_listView->currentIndex(); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
593 |
if (current.isValid()) |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
594 |
{ |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
595 |
if (m_imageModel->isFolder(current)) { |
| 80a9926d |
Poul Sander |
2026-05-19 20:28 |
596 |
QByteArray path = m_imageModel->filePath(current); |
| 665ac308 |
Poul Sander |
2026-02-23 19:34 |
597 |
navigateToFolder(path); |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
598 |
} else { |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
599 |
enterSingleImageMode(current); |
| 09130ab9 |
Poul Sander |
2026-02-22 22:19 |
600 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
601 |
event->accept(); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
602 |
return; |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
603 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
604 |
} |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
605 |
|
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
606 |
QMainWindow::keyPressEvent(event); |
| 61136b77 |
Poul Sander |
2026-02-20 22:45 |
607 |
} |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
608 |
|
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
609 |
void MainWindow::closeEvent(QCloseEvent *event) |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
610 |
{ |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
611 |
if (m_stack->currentWidget() == m_imageView) |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
612 |
{ |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
613 |
leaveSingleImageMode(); |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
614 |
event->ignore(); |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
615 |
return; |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
616 |
} |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
617 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
618 |
savePreferences(); |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
619 |
QMainWindow::closeEvent(event); |
| c9e5684a |
Poul Sander |
2026-02-23 19:18 |
620 |
} |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
621 |
|
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
622 |
void MainWindow::applyDockLocking(bool lock) |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
623 |
{ |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
624 |
const QDockWidget::DockWidgetFeatures movableFeatures = |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
625 |
QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable; |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
626 |
const QDockWidget::DockWidgetFeatures baseFeatures = |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
627 |
QDockWidget::DockWidgetClosable; |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
628 |
|
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
629 |
QDockWidget::DockWidgetFeatures features = lock ? baseFeatures |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
630 |
: (baseFeatures | movableFeatures); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
631 |
m_rootDock->setFeatures(features); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
632 |
m_folderDock->setFeatures(features); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
633 |
m_previewDock->setFeatures(features); |
| 53fdab93 |
Poul Sander |
2026-05-18 18:45 |
634 |
m_exifDock->setFeatures(features); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
635 |
} |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
636 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
637 |
void MainWindow::loadPreferences() |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
638 |
{ |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
639 |
QSettings settings("SagoImageBrowser", "SagoImageBrowser"); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
640 |
m_backgroundColorPreference = settings.value("backgroundColor", "black").toString(); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
641 |
m_imageView->setBackgroundColor(m_backgroundColorPreference); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
642 |
m_lockDockingPreference = settings.value("lockDocking", false).toBool(); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
643 |
applyDockLocking(m_lockDockingPreference); |
| 459bad0f |
Poul Sander |
2026-05-17 14:11 |
644 |
m_folderCacheSizePreference = settings.value("folderCacheSize", 4).toInt(); |
| 459bad0f |
Poul Sander |
2026-05-17 14:11 |
645 |
m_imageModel->setCacheMaxSize(m_folderCacheSizePreference); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
646 |
m_thumbnailCacheSizePreference = settings.value("thumbnailCacheSize", "normal").toString(); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
647 |
m_imageModel->setThumbnailSize(thumbnailSizeFromString(m_thumbnailCacheSizePreference)); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
648 |
if (settings.contains("windowGeometry")) |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
649 |
restoreGeometry(settings.value("windowGeometry").toByteArray()); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
650 |
if (settings.contains("windowState")) |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
651 |
restoreState(settings.value("windowState").toByteArray()); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
652 |
} |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
653 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
654 |
void MainWindow::savePreferences() |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
655 |
{ |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
656 |
QSettings settings("SagoImageBrowser", "SagoImageBrowser"); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
657 |
settings.setValue("backgroundColor", m_backgroundColorPreference); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
658 |
settings.setValue("lockDocking", m_lockDockingPreference); |
| 459bad0f |
Poul Sander |
2026-05-17 14:11 |
659 |
settings.setValue("folderCacheSize", m_folderCacheSizePreference); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
660 |
settings.setValue("thumbnailCacheSize", m_thumbnailCacheSizePreference); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
661 |
settings.setValue("windowGeometry", saveGeometry()); |
| cbc7d22b |
Poul Sander |
2026-02-24 19:23 |
662 |
settings.setValue("windowState", saveState()); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
663 |
} |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
664 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
665 |
void MainWindow::onPreferencesTriggered() |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
666 |
{ |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
667 |
PreferencesDialog dialog(this); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
668 |
dialog.setBackgroundColor(m_backgroundColorPreference); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
669 |
dialog.setLockDocking(m_lockDockingPreference); |
| 459bad0f |
Poul Sander |
2026-05-17 14:11 |
670 |
dialog.setCacheSize(m_folderCacheSizePreference); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
671 |
dialog.setThumbnailCacheSize(m_thumbnailCacheSizePreference); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
672 |
|
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
673 |
bool shouldResetLayout = false; |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
674 |
connect(&dialog, &PreferencesDialog::resetLayoutRequested, this, [&shouldResetLayout]() { |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
675 |
shouldResetLayout = true; |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
676 |
}); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
677 |
|
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
678 |
if (dialog.exec() == QDialog::Accepted) |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
679 |
{ |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
680 |
m_backgroundColorPreference = dialog.getBackgroundColor(); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
681 |
m_imageView->setBackgroundColor(m_backgroundColorPreference); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
682 |
m_lockDockingPreference = dialog.getLockDocking(); |
| 4ae57f60 |
Poul Sander |
2026-02-25 21:35 |
683 |
applyDockLocking(m_lockDockingPreference); |
| 459bad0f |
Poul Sander |
2026-05-17 14:11 |
684 |
m_folderCacheSizePreference = dialog.getCacheSize(); |
| 459bad0f |
Poul Sander |
2026-05-17 14:11 |
685 |
m_imageModel->setCacheMaxSize(m_folderCacheSizePreference); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
686 |
QString newThumbSize = dialog.getThumbnailCacheSize(); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
687 |
if (newThumbSize != m_thumbnailCacheSizePreference) |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
688 |
{ |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
689 |
m_thumbnailCacheSizePreference = newThumbSize; |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
690 |
m_imageModel->setThumbnailSize(thumbnailSizeFromString(m_thumbnailCacheSizePreference)); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
691 |
loadVisibleThumbnails(); |
| ac476ca8 |
Poul Sander |
2026-05-18 16:47 |
692 |
} |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
693 |
savePreferences(); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
694 |
} |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
695 |
|
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
696 |
// Apply layout reset immediately after dialog closes if requested |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
697 |
if (shouldResetLayout) { |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
698 |
resetLayoutToDefault(); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
699 |
} |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
700 |
} |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
701 |
|
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
702 |
void MainWindow::resetLayoutToDefault() |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
703 |
{ |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
704 |
QSettings settings("SagoImageBrowser", "SagoImageBrowser"); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
705 |
settings.remove("windowGeometry"); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
706 |
settings.remove("windowState"); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
707 |
|
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
708 |
// Hide and detach docks completely |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
709 |
m_rootDock->hide(); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
710 |
m_folderDock->hide(); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
711 |
m_previewDock->hide(); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
712 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
713 |
m_rootDock->setFloating(false); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
714 |
m_folderDock->setFloating(false); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
715 |
m_previewDock->setFloating(false); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
716 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
717 |
removeDockWidget(m_rootDock); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
718 |
removeDockWidget(m_folderDock); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
719 |
removeDockWidget(m_previewDock); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
720 |
|
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
721 |
// Re-add in default positions |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
722 |
addDockWidget(Qt::LeftDockWidgetArea, m_rootDock); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
723 |
addDockWidget(Qt::LeftDockWidgetArea, m_folderDock); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
724 |
addDockWidget(Qt::RightDockWidgetArea, m_previewDock); |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
725 |
splitDockWidget(m_rootDock, m_folderDock, Qt::Vertical); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
726 |
|
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
727 |
// Show all docks |
| 3bee3e3e |
Poul Sander |
2026-03-05 17:07 |
728 |
m_rootDock->show(); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
729 |
m_folderDock->show(); |
| 7370f1c0 |
Poul Sander |
2026-03-01 15:15 |
730 |
m_previewDock->show(); |
| f61bf886 |
Poul Sander |
2026-02-23 19:27 |
731 |
} |
|
|
1970-01-01 00:00 |
732 |
|