git repos / SagoImageBrowser

commit 237d2c81

Poul Sander · 2026-06-06 14:53
237d2c816459e2a34d843e5160a1ef523a8f2ca7 patch · browse files
parent edaf35e267126cebf2631d084097a394ad8b643b

Add right click menu to copy paths

Changed files

M src/mainwindow.cpp before
M src/mainwindow.h before
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a82e3fd..e631c72 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp
@@ -34,6 +34,11 @@
#include <QLineEdit>
#include <QPushButton>
#include <QCompleter>
+#include <QClipboard>
+#include <QDialogButtonBox>
+#include <QFileInfo>
+#include <QGuiApplication>
+#include <QVBoxLayout>
#include <iostream>
#include <fcntl.h>
@@ -48,6 +53,19 @@ ThumbnailCache::Size thumbnailSizeFromString(const QString &s)
return (s == "large") ? ThumbnailCache::Size::Large
: ThumbnailCache::Size::Normal;
}
+
+QString displayPath(const QByteArray &path)
+{
+ return QString::fromLocal8Bit(path.constData(), path.size());
+}
+
+QString filenameFromPath(const QByteArray &path)
+{
+ const std::filesystem::path fsPath(path.toStdString());
+ const std::string nativeName = fsPath.filename().native();
+ return QString::fromLocal8Bit(nativeName.data(),
+ static_cast<qsizetype>(nativeName.size()));
+}
} // namespace
MainWindow::MainWindow(QWidget *parent)
@@ -101,6 +119,7 @@ void MainWindow::setupUi()
m_listView->setWordWrap(true);
m_listView->setTextElideMode(Qt::ElideRight);
m_listView->setItemDelegate(new ThumbnailDelegate(this));
+ m_listView->setContextMenuPolicy(Qt::CustomContextMenu);
// Preview pane (right)
m_previewLabel = new QLabel;
@@ -380,6 +399,9 @@ void MainWindow::setupConnections()
}
});
+ connect(m_listView, &QListView::customContextMenuRequested,
+ this, &MainWindow::showImageContextMenu);
+
connect(m_imageView, &ImageViewWidget::closeRequested,
this, &MainWindow::leaveSingleImageMode);
connect(m_imageView, &ImageViewWidget::editCaptionRequested,
@@ -550,14 +572,22 @@ void MainWindow::enterSingleImageMode(const QModelIndex &index)
void MainWindow::onEditCaption()
{
- const QByteArray path = m_imageView->currentPath();
+ QByteArray path;
+ if (m_stack->currentWidget() == m_imageView) {
+ path = m_imageView->currentPath();
+ } else {
+ const QModelIndex index = m_listView->currentIndex();
+ if (index.isValid() && !m_imageModel->isFolder(index))
+ path = m_imageModel->filePath(index);
+ }
+
if (path.isEmpty())
return;
if (::access(path.constData(), W_OK) != 0) {
QMessageBox::warning(this, tr("Cannot Edit Caption"),
tr("The file is write-protected and cannot be edited.\n\n%1")
- .arg(QString::fromLocal8Bit(path)));
+ .arg(displayPath(path)));
return;
}
@@ -583,11 +613,39 @@ void MainWindow::onEditCaption()
const QString newCaption = edit->toPlainText();
if (ExifReader::saveCaption(path, newCaption, data)) {
ExifData updated = ExifReader::read(path);
- m_imageView->setExifData(updated);
+ if (m_imageView->currentPath() == path)
+ m_imageView->setExifData(updated);
updateExifInfo(path);
}
}
+void MainWindow::showImageContextMenu(const QPoint &pos)
+{
+ const QModelIndex index = m_listView->indexAt(pos);
+ if (!index.isValid() || m_imageModel->isFolder(index))
+ return;
+
+ m_listView->setCurrentIndex(index);
+ showPreview(index);
+
+ const QByteArray path = m_imageModel->filePath(index);
+
+ QMenu menu(this);
+ QAction *copyFilenameAction = menu.addAction(tr("Copy filename"));
+ QAction *copyFullPathAction = menu.addAction(tr("Copy full path"));
+ menu.addSeparator();
+ QAction *editDescriptionAction = menu.addAction(tr("Edit description"));
+
+ QAction *chosen = menu.exec(m_listView->viewport()->mapToGlobal(pos));
+ if (chosen == copyFilenameAction) {
+ QGuiApplication::clipboard()->setText(filenameFromPath(path));
+ } else if (chosen == copyFullPathAction) {
+ QGuiApplication::clipboard()->setText(displayPath(path));
+ } else if (chosen == editDescriptionAction) {
+ onEditCaption();
+ }
+}
+
void MainWindow::leaveSingleImageMode()
{
if (isFullScreen()) {
diff --git a/src/mainwindow.h b/src/mainwindow.h index d597ddb..1e3e8b4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h
@@ -15,6 +15,7 @@ class QTableWidget;
class QLineEdit;
class QPushButton;
class QCompleter;
+class QPoint;
class ImageModel;
class ImageViewWidget;
class PathCompleterModel;
@@ -46,6 +47,7 @@ private:
void enterSingleImageMode(const QModelIndex &index);
void leaveSingleImageMode();
void onEditCaption();
+ void showImageContextMenu(const QPoint &pos);
void onPathEntered();
void updatePathField(const QByteArray &path);
QList<QByteArray> computeNeighborPaths(const QModelIndex &index) const;
@@ -93,4 +95,4 @@ private:
bool m_lockDockingPreference = false;
void applyDockLocking(bool lock);
-};
\ No newline at end of file
+};