diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6a442c4..4b9d7d4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -119,6 +120,8 @@ void MainWindow::setupUi() // Path bar: editable absolute path with ajax-style folder completion and a Go button m_pathEdit = new QLineEdit; m_goButton = new QPushButton(tr("Go")); + m_prevFolderButton = new QPushButton(tr("Prev")); + m_nextFolderButton = new QPushButton(tr("Next")); m_pathCompleterModel = new PathCompleterModel(this); m_pathCompleter = new QCompleter(m_pathCompleterModel, this); m_pathCompleter->setCaseSensitivity(Qt::CaseSensitive); @@ -130,6 +133,8 @@ void MainWindow::setupUi() pathRow->setContentsMargins(4, 4, 4, 0); pathRow->addWidget(m_pathEdit, 1); pathRow->addWidget(m_goButton); + pathRow->addWidget(m_prevFolderButton); + pathRow->addWidget(m_nextFolderButton); auto *browserPage = new QWidget; auto *vbox = new QVBoxLayout(browserPage); @@ -206,6 +211,58 @@ void MainWindow::navigateToFolder(const QString &path) navigateToFolder(QFile::encodeName(path)); } +QByteArray MainWindow::siblingFolder(int delta) const +{ + QByteArray currentDir = m_imageModel->currentDirectory(); + if (currentDir.isEmpty()) + return {}; + + namespace fs = std::filesystem; + fs::path current(currentDir.toStdString()); + fs::path parent = current.parent_path(); + if (parent.empty() || parent == current) + return {}; + + QByteArray parentPath = QByteArray::fromStdString(parent.native()); + QModelIndex parentIdx = m_dirModel->indexForPath(parentPath); + if (!parentIdx.isValid()) + return {}; + + int count = m_dirModel->rowCount(parentIdx); + int currentRow = -1; + for (int i = 0; i < count; ++i) { + QModelIndex idx = m_dirModel->index(i, 0, parentIdx); + if (m_dirModel->filePath(idx) == currentDir) { + currentRow = i; + break; + } + } + + if (currentRow < 0) + return {}; + + int targetRow = currentRow + delta; + if (targetRow < 0 || targetRow >= count) + return {}; + + QModelIndex targetIdx = m_dirModel->index(targetRow, 0, parentIdx); + return m_dirModel->filePath(targetIdx); +} + +void MainWindow::navigateToPrevFolder() +{ + QByteArray path = siblingFolder(-1); + if (!path.isEmpty()) + navigateToFolder(path); +} + +void MainWindow::navigateToNextFolder() +{ + QByteArray path = siblingFolder(+1); + if (!path.isEmpty()) + navigateToFolder(path); +} + void MainWindow::navigateToFolder(const QByteArray &path) { m_previousFolderPath = m_imageModel->currentDirectory(); @@ -290,6 +347,10 @@ void MainWindow::setupConnections() this, &MainWindow::onPathEntered); connect(m_goButton, &QPushButton::clicked, this, &MainWindow::onPathEntered); + connect(m_prevFolderButton, &QPushButton::clicked, + this, &MainWindow::navigateToPrevFolder); + connect(m_nextFolderButton, &QPushButton::clicked, + this, &MainWindow::navigateToNextFolder); connect(m_pathEdit, &QLineEdit::textEdited, m_pathCompleterModel, &PathCompleterModel::setPrefix); @@ -615,6 +676,22 @@ void MainWindow::keyPressEvent(QKeyEvent *event) } } + if (sc.matches(event, ShortcutManager::PrevFolder) + && m_stack->currentWidget() == m_browserPage) + { + navigateToPrevFolder(); + event->accept(); + return; + } + + if (sc.matches(event, ShortcutManager::NextFolder) + && m_stack->currentWidget() == m_browserPage) + { + navigateToNextFolder(); + event->accept(); + return; + } + QMainWindow::keyPressEvent(event); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 8edecb4..d597ddb 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -49,6 +49,9 @@ private: void onPathEntered(); void updatePathField(const QByteArray &path); QList computeNeighborPaths(const QModelIndex &index) const; + QByteArray siblingFolder(int delta) const; + void navigateToPrevFolder(); + void navigateToNextFolder(); void keyPressEvent(QKeyEvent *event) override; bool eventFilter(QObject *obj, QEvent *event) override; @@ -63,6 +66,8 @@ private: QLabel *m_previewLabel; QLineEdit *m_pathEdit = nullptr; QPushButton *m_goButton = nullptr; + QPushButton *m_prevFolderButton = nullptr; + QPushButton *m_nextFolderButton = nullptr; PathCompleterModel *m_pathCompleterModel = nullptr; QCompleter *m_pathCompleter = nullptr; diff --git a/src/shortcutmanager.cpp b/src/shortcutmanager.cpp index 6f98427..7f41d0b 100644 --- a/src/shortcutmanager.cpp +++ b/src/shortcutmanager.cpp @@ -31,6 +31,8 @@ static const ActionInfo kDefaults[ShortcutManager::ActionCount] = { {"EditCaption", "Edit caption", QKeySequence(Qt::Key_E), ShortcutManager::CatImageViewer}, {"ToggleFullscreen","Toggle fullscreen", QKeySequence(Qt::Key_F11), ShortcutManager::CatImageViewer}, {"ActivateEntry", "Open folder / image", QKeySequence(Qt::Key_Return), ShortcutManager::CatBrowser}, + {"PrevFolder", "Previous folder", QKeySequence(Qt::CTRL | Qt::Key_Left), ShortcutManager::CatBrowser}, + {"NextFolder", "Next folder", QKeySequence(Qt::CTRL | Qt::Key_Right), ShortcutManager::CatBrowser}, }; } // namespace diff --git a/src/shortcutmanager.h b/src/shortcutmanager.h index 2a741e8..61105a9 100644 --- a/src/shortcutmanager.h +++ b/src/shortcutmanager.h @@ -28,6 +28,8 @@ public: EditCaption, ToggleFullscreen, ActivateEntry, + PrevFolder, + NextFolder, ActionCount };