Added keyboard shortcut help.

This commit is contained in:
Storm Dragon
2026-09-15 18:39:27 -04:00
parent 33bba7282e
commit bd6cfb83eb
3 changed files with 87 additions and 2 deletions
@@ -1,6 +1,6 @@
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
pkgname=navipy-git
pkgver=r11.gd9f4ac4
pkgver=r12.g33bba72
pkgrel=1
pkgdesc='Accessible Subsonic desktop client tested with Navidrome'
arch=('any')
+67
View File
@@ -10,6 +10,9 @@ import time
from concurrent.futures import ThreadPoolExecutor
from PySide6.QtWidgets import (
QHBoxLayout,
QDialog,
QDialogButtonBox,
QHeaderView,
QLabel,
QMenu,
QListWidget,
@@ -20,6 +23,8 @@ from PySide6.QtWidgets import (
QSlider,
QSplitter,
QStatusBar,
QTableWidget,
QTableWidgetItem,
QVBoxLayout,
QWidget,
)
@@ -222,6 +227,10 @@ class MainWindow(QMainWindow):
# Help menu
helpMenu = menuBar.addMenu("&Help")
self.keyboardShortcutsAction = QAction("&Keyboard Shortcuts", self)
self.keyboardShortcutsAction.triggered.connect(self.showKeyboardShortcuts)
helpMenu.addAction(self.keyboardShortcutsAction)
self.aboutAction = QAction("&About NaviPy", self)
self.aboutAction.triggered.connect(self.showAbout)
helpMenu.addAction(self.aboutAction)
@@ -1830,6 +1839,64 @@ class MainWindow(QMainWindow):
parent=self
)
def showKeyboardShortcuts(self):
"""Show the application's keyboard shortcuts in an accessible table."""
shortcuts = (
("Ctrl+O", "Connect to server"),
("F5", "Refresh library"),
("Shift+F5", "Full library sync"),
("Ctrl+Q", "Quit"),
("Space", "Play or pause"),
("X", "Play or resume"),
("C", "Toggle pause"),
("V", "Stop playback"),
("Ctrl+Left or Z", "Previous track"),
("Ctrl+Right or B", "Next track"),
("Alt+S", "Toggle shuffle"),
("Alt+R", "Change repeat mode"),
("+", "Favorite selected item"),
("_", "Unfavorite selected item"),
("Ctrl+Up or 0", "Increase volume"),
("Ctrl+Down or 9", "Decrease volume"),
("Ctrl+F", "Search"),
("Ctrl+T", "Announce current track in a dialog"),
("Alt+C", "Announce current track"),
("Ctrl+P", "Announce playback position"),
("Alt+I", "Open actions for the current item"),
("Ctrl+Tab", "Next library tab"),
("Ctrl+Shift+Tab", "Previous library tab"),
("Enter", "Open selected collection or play selected song"),
("Backspace or Alt+Left", "Go back in the library"),
("Shift+F10 or Menu", "Open actions for selected library item"),
("Ctrl+C", "Copy selected library row"),
)
dialog = QDialog(self)
dialog.setWindowTitle("Keyboard Shortcuts")
dialog.setModal(True)
dialog.setMinimumSize(620, 500)
layout = QVBoxLayout(dialog)
table = QTableWidget(len(shortcuts), 2, dialog)
table.setHorizontalHeaderLabels(["Shortcut", "Action"])
table.setAccessibleName("Keyboard shortcuts")
table.setAccessibleDescription("A table of NaviPy keyboard shortcuts and their actions.")
table.setEditTriggers(QTableWidget.NoEditTriggers)
table.setSelectionBehavior(QTableWidget.SelectRows)
table.setSelectionMode(QTableWidget.SingleSelection)
table.verticalHeader().setVisible(False)
table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
for row, (shortcut, action) in enumerate(shortcuts):
table.setItem(row, 0, QTableWidgetItem(shortcut))
table.setItem(row, 1, QTableWidgetItem(action))
layout.addWidget(table)
buttonBox = QDialogButtonBox(QDialogButtonBox.Close, dialog)
buttonBox.rejected.connect(dialog.reject)
layout.addWidget(buttonBox)
table.setFocus()
dialog.exec()
def closeEvent(self, event):
"""Handle window close"""
# Signal background tasks to stop
+19 -1
View File
@@ -9,7 +9,7 @@ from unittest.mock import Mock
import pytest
from PySide6.QtCore import Qt
from PySide6.QtMultimedia import QMediaPlayer
from PySide6.QtWidgets import QApplication, QWidget, QTreeWidgetItem
from PySide6.QtWidgets import QApplication, QDialog, QTableWidget, QTreeWidgetItem, QWidget
from src.api.client import SubsonicClient
from src.api.models import Song, Playlist
@@ -49,6 +49,24 @@ def test_background_error_survives_until_ui_delivery(app):
assert str(errors[0]) == "synthetic failure"
def test_keyboard_shortcuts_dialog_has_accessible_shortcut_table(app, monkeypatch):
parent = QWidget()
def inspect_dialog(dialog):
table = dialog.findChild(QTableWidget)
assert dialog.windowTitle() == "Keyboard Shortcuts"
assert table.accessibleName() == "Keyboard shortcuts"
assert table.horizontalHeaderItem(0).text() == "Shortcut"
assert table.horizontalHeaderItem(1).text() == "Action"
assert table.rowCount() >= 20
assert table.item(15, 0).text() == "Ctrl+Down or 9"
assert table.item(15, 1).text() == "Decrease volume"
return QDialog.Accepted
monkeypatch.setattr(QDialog, "exec", inspect_dialog)
MainWindow.showKeyboardShortcuts(parent)
@pytest.mark.parametrize("refresh", ["forced", "full", "incremental"])
def test_refresh_bypasses_api_memory_cache(tmp_path, refresh):
raw = SubsonicClient("https://fake.example", "user", "fake")