Added keyboard shortcut help.
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user