mirror of
https://github.com/chidiwilliams/buzz.git
synced 2026-03-14 14:45:46 +01:00
Add keyboard shortcuts (#409)
This commit is contained in:
parent
474f4c5050
commit
b4a095ef3a
14 changed files with 318 additions and 44 deletions
8
buzz/assets.py
Normal file
8
buzz/assets.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def get_asset_path(path: str):
|
||||
if getattr(sys, 'frozen', False):
|
||||
return os.path.join(os.path.dirname(sys.executable), path)
|
||||
return os.path.join(os.path.dirname(__file__), '..', path)
|
||||
121
buzz/gui.py
121
buzz/gui.py
|
|
@ -1,5 +1,4 @@
|
|||
import enum
|
||||
import gettext
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
|
@ -14,7 +13,7 @@ import sounddevice
|
|||
from PyQt6 import QtGui
|
||||
from PyQt6.QtCore import (QObject, Qt, QThread,
|
||||
QTimer, QUrl, pyqtSignal, QModelIndex, QSize, QPoint,
|
||||
QUrlQuery, QMetaObject, QEvent, QLocale)
|
||||
QUrlQuery, QMetaObject, QEvent)
|
||||
from PyQt6.QtGui import (QAction, QCloseEvent, QDesktopServices, QIcon,
|
||||
QKeySequence, QPixmap, QTextCursor, QValidator, QKeyEvent, QPainter, QColor)
|
||||
from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
|
||||
|
|
@ -28,32 +27,19 @@ from whisper import tokenizer
|
|||
|
||||
from buzz.cache import TasksCache
|
||||
from .__version__ import VERSION
|
||||
from .assets import get_asset_path
|
||||
from .locale import _
|
||||
from .model_loader import ModelLoader, WhisperModelSize, ModelType, TranscriptionModel
|
||||
from .recording import RecordingAmplitudeListener
|
||||
from .settings import Settings, APP_NAME
|
||||
from .settings.settings import Settings, APP_NAME
|
||||
from .settings.shortcut import Shortcut
|
||||
from .settings.shortcut_settings import ShortcutSettings
|
||||
from .transcriber import (SUPPORTED_OUTPUT_FORMATS, FileTranscriptionOptions, OutputFormat,
|
||||
Task,
|
||||
get_default_output_file_path, segments_to_text, write_output, TranscriptionOptions,
|
||||
FileTranscriberQueueWorker, FileTranscriptionTask, RecordingTranscriber, LOADED_WHISPER_DLL,
|
||||
DEFAULT_WHISPER_TEMPERATURE)
|
||||
|
||||
|
||||
def get_asset_path(path: str):
|
||||
if getattr(sys, 'frozen', False):
|
||||
return os.path.join(os.path.dirname(sys.executable), path)
|
||||
return os.path.join(os.path.dirname(__file__), '..', path)
|
||||
|
||||
|
||||
if 'LANG' not in os.environ:
|
||||
language = str(QLocale().uiLanguages()[0]).replace("-", "_")
|
||||
os.environ['LANG'] = language
|
||||
|
||||
locale_dir = get_asset_path('locale')
|
||||
gettext.bindtextdomain('buzz', locale_dir)
|
||||
|
||||
translate = gettext.translation(APP_NAME, locale_dir, fallback=True)
|
||||
|
||||
_ = translate.gettext
|
||||
from .widgets.preferences_dialog import PreferencesDialog
|
||||
|
||||
|
||||
def get_platform_styles(all_platform_styles: Dict[str, str]):
|
||||
|
|
@ -762,8 +748,6 @@ class AboutDialog(QDialog):
|
|||
parent: Optional[QWidget] = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
self.setFixedSize(200, 250)
|
||||
|
||||
self.setWindowIcon(QIcon(BUZZ_ICON_PATH))
|
||||
self.setWindowTitle(f'{_("About")} {APP_NAME}')
|
||||
|
||||
|
|
@ -835,6 +819,8 @@ class TranscriptionTasksTableWidget(QTableWidget):
|
|||
FILE_NAME_COLUMN_INDEX = 1
|
||||
STATUS_COLUMN_INDEX = 2
|
||||
|
||||
return_clicked = pyqtSignal()
|
||||
|
||||
def __init__(self, parent: Optional[QWidget] = None):
|
||||
super().__init__(parent)
|
||||
|
||||
|
|
@ -906,6 +892,11 @@ class TranscriptionTasksTableWidget(QTableWidget):
|
|||
sibling_index = index.siblingAtColumn(TranscriptionTasksTableWidget.TASK_ID_COLUMN_INDEX).data()
|
||||
return int(sibling_index) if sibling_index is not None else None
|
||||
|
||||
def keyPressEvent(self, event: QtGui.QKeyEvent) -> None:
|
||||
if event.key() == Qt.Key.Key_Return:
|
||||
self.return_clicked.emit()
|
||||
super().keyPressEvent(event)
|
||||
|
||||
|
||||
class MainWindowToolbar(QToolBar):
|
||||
new_transcription_action_triggered: pyqtSignal
|
||||
|
|
@ -914,15 +905,14 @@ class MainWindowToolbar(QToolBar):
|
|||
ICON_LIGHT_THEME_BACKGROUND = '#555'
|
||||
ICON_DARK_THEME_BACKGROUND = '#AAA'
|
||||
|
||||
def __init__(self, parent: Optional[QWidget]):
|
||||
def __init__(self, shortcuts: Dict[str, str], parent: Optional[QWidget]):
|
||||
super().__init__(parent)
|
||||
|
||||
record_action = QAction(self.load_icon(RECORD_ICON_PATH), _('Record'), self)
|
||||
record_action.triggered.connect(self.on_record_action_triggered)
|
||||
self.record_action = QAction(self.load_icon(RECORD_ICON_PATH), _('Record'), self)
|
||||
self.record_action.triggered.connect(self.on_record_action_triggered)
|
||||
|
||||
new_transcription_action = QAction(
|
||||
self.load_icon(ADD_ICON_PATH), _('New Transcription'), self)
|
||||
self.new_transcription_action_triggered = new_transcription_action.triggered
|
||||
self.new_transcription_action = QAction(self.load_icon(ADD_ICON_PATH), _('New Transcription'), self)
|
||||
self.new_transcription_action_triggered = self.new_transcription_action.triggered
|
||||
|
||||
self.open_transcript_action = QAction(self.load_icon(EXPAND_ICON_PATH),
|
||||
_('Open Transcript'), self)
|
||||
|
|
@ -937,9 +927,11 @@ class MainWindowToolbar(QToolBar):
|
|||
self.clear_history_action_triggered = self.clear_history_action.triggered
|
||||
self.clear_history_action.setDisabled(True)
|
||||
|
||||
self.addAction(record_action)
|
||||
self.set_shortcuts(shortcuts)
|
||||
|
||||
self.addAction(self.record_action)
|
||||
self.addSeparator()
|
||||
self.addAction(new_transcription_action)
|
||||
self.addAction(self.new_transcription_action)
|
||||
self.addAction(self.open_transcript_action)
|
||||
self.addAction(self.stop_transcription_action)
|
||||
self.addAction(self.clear_history_action)
|
||||
|
|
@ -957,6 +949,14 @@ class MainWindowToolbar(QToolBar):
|
|||
self.widgetForAction(self.actions()[0]).setStyleSheet(
|
||||
'QToolButton { margin-left: 9px; margin-right: 1px; }')
|
||||
|
||||
def set_shortcuts(self, shortcuts: Dict[str, str]):
|
||||
self.record_action.setShortcut(QKeySequence.fromString(shortcuts[Shortcut.OPEN_RECORD_WINDOW.name]))
|
||||
self.new_transcription_action.setShortcut(QKeySequence.fromString(shortcuts[Shortcut.OPEN_IMPORT_WINDOW.name]))
|
||||
self.open_transcript_action.setShortcut(
|
||||
QKeySequence.fromString(shortcuts[Shortcut.OPEN_TRANSCRIPT_EDITOR.name]))
|
||||
self.stop_transcription_action.setShortcut(QKeySequence.fromString(shortcuts[Shortcut.STOP_TRANSCRIPTION.name]))
|
||||
self.clear_history_action.setShortcut(QKeySequence.fromString(shortcuts[Shortcut.CLEAR_HISTORY.name]))
|
||||
|
||||
def load_icon(self, file_path: str):
|
||||
is_dark_theme = self.palette().window().color().black() > 127
|
||||
return self.load_icon_with_color(file_path,
|
||||
|
|
@ -1003,24 +1003,31 @@ class MainWindow(QMainWindow):
|
|||
|
||||
self.tasks_cache = tasks_cache
|
||||
|
||||
self.settings = Settings()
|
||||
|
||||
self.shortcut_settings = ShortcutSettings(settings=self.settings)
|
||||
self.shortcuts = self.shortcut_settings.load()
|
||||
|
||||
self.tasks = {}
|
||||
self.tasks_changed.connect(self.on_tasks_changed)
|
||||
|
||||
self.toolbar = MainWindowToolbar(self)
|
||||
self.toolbar = MainWindowToolbar(shortcuts=self.shortcuts, parent=self)
|
||||
self.toolbar.new_transcription_action_triggered.connect(self.on_new_transcription_action_triggered)
|
||||
self.toolbar.open_transcript_action_triggered.connect(self.on_open_transcript_action_triggered)
|
||||
self.toolbar.open_transcript_action_triggered.connect(self.open_transcript_viewer)
|
||||
self.toolbar.clear_history_action_triggered.connect(self.on_clear_history_action_triggered)
|
||||
self.toolbar.stop_transcription_action_triggered.connect(self.on_stop_transcription_action_triggered)
|
||||
self.addToolBar(self.toolbar)
|
||||
self.setUnifiedTitleAndToolBarOnMac(True)
|
||||
|
||||
menu_bar = MenuBar(self)
|
||||
menu_bar.import_action_triggered.connect(
|
||||
self.menu_bar = MenuBar(shortcuts=self.shortcuts, parent=self)
|
||||
self.menu_bar.import_action_triggered.connect(
|
||||
self.on_new_transcription_action_triggered)
|
||||
self.setMenuBar(menu_bar)
|
||||
self.menu_bar.shortcuts_changed.connect(self.on_shortcuts_changed)
|
||||
self.setMenuBar(self.menu_bar)
|
||||
|
||||
self.table_widget = TranscriptionTasksTableWidget(self)
|
||||
self.table_widget.doubleClicked.connect(self.on_table_double_clicked)
|
||||
self.table_widget.return_clicked.connect(self.open_transcript_viewer)
|
||||
self.table_widget.itemSelectionChanged.connect(
|
||||
self.on_table_selection_changed)
|
||||
|
||||
|
|
@ -1119,7 +1126,7 @@ class MainWindow(QMainWindow):
|
|||
def on_openai_access_token_changed(self, access_token: str):
|
||||
self.openai_access_token = access_token
|
||||
|
||||
def on_open_transcript_action_triggered(self):
|
||||
def open_transcript_viewer(self):
|
||||
selected_rows = self.table_widget.selectionModel().selectedRows()
|
||||
for selected_row in selected_rows:
|
||||
task_id = TranscriptionTasksTableWidget.find_task_id(selected_row)
|
||||
|
|
@ -1182,11 +1189,18 @@ class MainWindow(QMainWindow):
|
|||
self.toolbar.set_clear_history_action_enabled(self.should_enable_clear_history_action())
|
||||
self.save_tasks_to_cache()
|
||||
|
||||
def on_shortcuts_changed(self, shortcuts: dict):
|
||||
self.shortcuts = shortcuts
|
||||
self.menu_bar.set_shortcuts(shortcuts=self.shortcuts)
|
||||
self.toolbar.set_shortcuts(shortcuts=self.shortcuts)
|
||||
self.shortcut_settings.save(shortcuts=self.shortcuts)
|
||||
|
||||
def closeEvent(self, event: QtGui.QCloseEvent) -> None:
|
||||
self.transcriber_worker.stop()
|
||||
self.transcriber_thread.quit()
|
||||
self.transcriber_thread.wait()
|
||||
self.save_tasks_to_cache()
|
||||
self.shortcut_settings.save(shortcuts=self.shortcuts)
|
||||
super().closeEvent(event)
|
||||
|
||||
|
||||
|
|
@ -1444,23 +1458,31 @@ class TranscriptionOptionsGroupBox(QGroupBox):
|
|||
|
||||
class MenuBar(QMenuBar):
|
||||
import_action_triggered = pyqtSignal()
|
||||
shortcuts_changed = pyqtSignal(dict)
|
||||
|
||||
def __init__(self, parent: QWidget):
|
||||
def __init__(self, shortcuts: Dict[str, str], parent: QWidget):
|
||||
super().__init__(parent)
|
||||
|
||||
import_action = QAction(_("Import Media File..."), self)
|
||||
import_action.triggered.connect(
|
||||
self.on_import_action_triggered)
|
||||
import_action.setShortcut(QKeySequence.fromString('Ctrl+O'))
|
||||
self.shortcuts = shortcuts
|
||||
|
||||
about_action = QAction(f'{_("About")} {APP_NAME}', self)
|
||||
self.import_action = QAction(_("Import Media File..."), self)
|
||||
self.import_action.triggered.connect(
|
||||
self.on_import_action_triggered)
|
||||
|
||||
about_action = QAction(f'{_("About...")} {APP_NAME}', self)
|
||||
about_action.triggered.connect(self.on_about_action_triggered)
|
||||
|
||||
self.preferences_action = QAction(_("Preferences..."), self)
|
||||
self.preferences_action.triggered.connect(self.on_preferences_action_triggered)
|
||||
|
||||
self.set_shortcuts(shortcuts)
|
||||
|
||||
file_menu = self.addMenu(_("File"))
|
||||
file_menu.addAction(import_action)
|
||||
file_menu.addAction(self.import_action)
|
||||
|
||||
help_menu = self.addMenu(_("Help"))
|
||||
help_menu.addAction(about_action)
|
||||
help_menu.addAction(self.preferences_action)
|
||||
|
||||
def on_import_action_triggered(self):
|
||||
self.import_action_triggered.emit()
|
||||
|
|
@ -1469,6 +1491,17 @@ class MenuBar(QMenuBar):
|
|||
about_dialog = AboutDialog(parent=self)
|
||||
about_dialog.open()
|
||||
|
||||
def on_preferences_action_triggered(self):
|
||||
preferences_dialog = PreferencesDialog(shortcuts=self.shortcuts, parent=self)
|
||||
preferences_dialog.shortcuts_changed.connect(self.shortcuts_changed)
|
||||
preferences_dialog.open()
|
||||
|
||||
def set_shortcuts(self, shortcuts: Dict[str, str]):
|
||||
self.shortcuts = shortcuts
|
||||
|
||||
self.import_action.setShortcut(QKeySequence.fromString(shortcuts[Shortcut.OPEN_IMPORT_WINDOW.name]))
|
||||
self.preferences_action.setShortcut(QKeySequence.fromString(shortcuts[Shortcut.OPEN_PREFERENCES_WINDOW.name]))
|
||||
|
||||
|
||||
class Application(QApplication):
|
||||
window: MainWindow
|
||||
|
|
|
|||
18
buzz/locale.py
Normal file
18
buzz/locale.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import gettext
|
||||
import os
|
||||
|
||||
from PyQt6.QtCore import QLocale
|
||||
|
||||
from buzz.assets import get_asset_path
|
||||
from buzz.settings.settings import APP_NAME
|
||||
|
||||
if 'LANG' not in os.environ:
|
||||
language = str(QLocale().uiLanguages()[0]).replace("-", "_")
|
||||
os.environ['LANG'] = language
|
||||
|
||||
locale_dir = get_asset_path('locale')
|
||||
gettext.bindtextdomain('buzz', locale_dir)
|
||||
|
||||
translate = gettext.translation(APP_NAME, locale_dir, fallback=True)
|
||||
|
||||
_ = translate.gettext
|
||||
0
buzz/settings/__init__.py
Normal file
0
buzz/settings/__init__.py
Normal file
|
|
@ -24,6 +24,8 @@ class Settings:
|
|||
FILE_TRANSCRIBER_WORD_LEVEL_TIMINGS = 'file-transcriber/word-level-timings'
|
||||
FILE_TRANSCRIBER_EXPORT_FORMATS = 'file-transcriber/export-formats'
|
||||
|
||||
SHORTCUTS = 'shortcuts'
|
||||
|
||||
def set_value(self, key: Key, value: typing.Any) -> None:
|
||||
self.settings.setValue(key.value, value)
|
||||
|
||||
26
buzz/settings/shortcut.py
Normal file
26
buzz/settings/shortcut.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import enum
|
||||
import typing
|
||||
|
||||
|
||||
class Shortcut(str, enum.Enum):
|
||||
sequence: str
|
||||
description: str
|
||||
|
||||
def __new__(cls, sequence: str, description: str):
|
||||
obj = str.__new__(cls, sequence)
|
||||
obj._value_ = sequence
|
||||
obj.sequence = sequence
|
||||
obj.description = description
|
||||
return obj
|
||||
|
||||
OPEN_RECORD_WINDOW = ('Ctrl+R', "Open Record Window")
|
||||
OPEN_IMPORT_WINDOW = ('Ctrl+O', "Import File")
|
||||
OPEN_PREFERENCES_WINDOW = ('Ctrl+,', 'Open Preferences Window')
|
||||
|
||||
OPEN_TRANSCRIPT_EDITOR = ('Ctrl+E', "Open Transcript Viewer")
|
||||
CLEAR_HISTORY = ('Ctrl+S', "Clear History")
|
||||
STOP_TRANSCRIPTION = ('Ctrl+X', "Cancel Transcription")
|
||||
|
||||
@staticmethod
|
||||
def get_default_shortcuts() -> typing.Dict[str, str]:
|
||||
return {shortcut.name: shortcut.sequence for shortcut in Shortcut}
|
||||
19
buzz/settings/shortcut_settings.py
Normal file
19
buzz/settings/shortcut_settings.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import typing
|
||||
|
||||
from buzz.settings.settings import Settings
|
||||
from buzz.settings.shortcut import Shortcut
|
||||
|
||||
|
||||
class ShortcutSettings:
|
||||
def __init__(self, settings: Settings):
|
||||
self.settings = settings
|
||||
|
||||
def load(self) -> typing.Dict[str, str]:
|
||||
shortcuts = Shortcut.get_default_shortcuts()
|
||||
custom_shortcuts: typing.Dict[str, str] = self.settings.value(Settings.Key.SHORTCUTS, {})
|
||||
for shortcut_name in custom_shortcuts:
|
||||
shortcuts[shortcut_name] = custom_shortcuts[shortcut_name]
|
||||
return shortcuts
|
||||
|
||||
def save(self, shortcuts: typing.Dict[str, str]) -> None:
|
||||
self.settings.set_value(Settings.Key.SHORTCUTS, shortcuts)
|
||||
0
buzz/widgets/__init__.py
Normal file
0
buzz/widgets/__init__.py
Normal file
35
buzz/widgets/preferences_dialog.py
Normal file
35
buzz/widgets/preferences_dialog.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from PyQt6.QtCore import pyqtSignal
|
||||
from PyQt6.QtWidgets import QDialog, QWidget, QVBoxLayout, QTabWidget, QDialogButtonBox
|
||||
|
||||
from buzz.locale import _
|
||||
from buzz.widgets.shortcuts_editor_widget import ShortcutsEditorWidget
|
||||
|
||||
|
||||
class PreferencesDialog(QDialog):
|
||||
shortcuts_changed = pyqtSignal(dict)
|
||||
|
||||
def __init__(self, shortcuts: Dict[str, str], parent: Optional[QWidget] = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
self.setWindowTitle('Preferences')
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
tab_widget = QTabWidget(self)
|
||||
|
||||
shortcuts_table_widget = ShortcutsEditorWidget(shortcuts, self)
|
||||
shortcuts_table_widget.shortcuts_changed.connect(self.shortcuts_changed)
|
||||
tab_widget.addTab(shortcuts_table_widget, _('Shortcuts'))
|
||||
|
||||
button_box = QDialogButtonBox(QDialogButtonBox.StandardButton(
|
||||
QDialogButtonBox.StandardButton.Ok), self)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
|
||||
layout.addWidget(tab_widget)
|
||||
layout.addWidget(button_box)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.setFixedSize(self.sizeHint())
|
||||
71
buzz/widgets/shortcuts_editor_widget.py
Normal file
71
buzz/widgets/shortcuts_editor_widget.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import platform
|
||||
from typing import Optional, Dict
|
||||
|
||||
from PyQt6 import QtGui
|
||||
from PyQt6.QtCore import Qt, pyqtSignal
|
||||
from PyQt6.QtGui import QKeySequence
|
||||
from PyQt6.QtWidgets import QKeySequenceEdit, QWidget, QFormLayout, QPushButton
|
||||
|
||||
from buzz.settings.shortcut import Shortcut
|
||||
|
||||
|
||||
class ShortcutsEditorWidget(QWidget):
|
||||
shortcuts_changed = pyqtSignal(dict)
|
||||
|
||||
def __init__(self, shortcuts: Dict[str, str], parent: Optional[QWidget] = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.shortcuts = shortcuts
|
||||
|
||||
self.layout = QFormLayout(self)
|
||||
for shortcut in Shortcut:
|
||||
sequence_edit = SequenceEdit(shortcuts.get(shortcut.name, ''), self)
|
||||
sequence_edit.keySequenceChanged.connect(self.get_key_sequence_changed(shortcut.name))
|
||||
self.layout.addRow(shortcut.description, sequence_edit)
|
||||
|
||||
reset_to_defaults_button = QPushButton('Reset to Defaults', self)
|
||||
reset_to_defaults_button.setDefault(False)
|
||||
reset_to_defaults_button.setAutoDefault(False)
|
||||
reset_to_defaults_button.clicked.connect(self.reset_to_defaults)
|
||||
|
||||
self.layout.addWidget(reset_to_defaults_button)
|
||||
|
||||
def get_key_sequence_changed(self, shortcut_name: str):
|
||||
def key_sequence_changed(sequence: QKeySequence):
|
||||
self.shortcuts[shortcut_name] = sequence.toString()
|
||||
self.shortcuts_changed.emit(self.shortcuts)
|
||||
|
||||
return key_sequence_changed
|
||||
|
||||
def reset_to_defaults(self):
|
||||
self.shortcuts = Shortcut.get_default_shortcuts()
|
||||
|
||||
for i, shortcut in enumerate(Shortcut):
|
||||
sequence_edit = self.layout.itemAt(i, QFormLayout.ItemRole.FieldRole).widget()
|
||||
assert isinstance(sequence_edit, SequenceEdit)
|
||||
sequence_edit.setKeySequence(QKeySequence(self.shortcuts[shortcut.name]))
|
||||
|
||||
self.shortcuts_changed.emit(self.shortcuts)
|
||||
|
||||
|
||||
class SequenceEdit(QKeySequenceEdit):
|
||||
def __init__(self, sequence: str, parent: Optional[QWidget] = None):
|
||||
super().__init__(sequence, parent)
|
||||
self.setClearButtonEnabled(True)
|
||||
if platform.system() == 'Darwin':
|
||||
self.setStyleSheet('QLineEdit:focus { border: 2px solid #4d90fe; }')
|
||||
|
||||
def keyPressEvent(self, event: QtGui.QKeyEvent) -> None:
|
||||
key = event.key()
|
||||
# The shortcut editor always focuses on the sequence edit widgets, so we need to
|
||||
# manually capture Esc key presses to close the dialog. The downside being that
|
||||
# the user can't set a shortcut that contains the Esc key.
|
||||
if key == Qt.Key.Key_Escape:
|
||||
self.parent().keyPressEvent(event)
|
||||
return
|
||||
|
||||
# Ignore pressing *only* modifier keys
|
||||
if key == Qt.Key.Key_Control or key == Qt.Key.Key_Shift or key == Qt.Key.Key_Alt or key == Qt.Key.Key_Meta:
|
||||
return
|
||||
|
||||
super().keyPressEvent(event)
|
||||
|
|
@ -235,7 +235,7 @@ class TestMainWindow:
|
|||
window.close()
|
||||
|
||||
@pytest.mark.parametrize('tasks_cache', [mock_tasks], indirect=True)
|
||||
def test_should_open_transcription_viewer(self, qtbot, tasks_cache):
|
||||
def test_should_open_transcription_viewer_when_menu_action_is_clicked(self, qtbot, tasks_cache):
|
||||
window = MainWindow(tasks_cache=tasks_cache)
|
||||
qtbot.add_widget(window)
|
||||
|
||||
|
|
@ -250,6 +250,21 @@ class TestMainWindow:
|
|||
|
||||
window.close()
|
||||
|
||||
@pytest.mark.parametrize('tasks_cache', [mock_tasks], indirect=True)
|
||||
def test_should_open_transcription_viewer_when_return_clicked(self, qtbot, tasks_cache):
|
||||
window = MainWindow(tasks_cache=tasks_cache)
|
||||
qtbot.add_widget(window)
|
||||
|
||||
table_widget: QTableWidget = window.findChild(QTableWidget)
|
||||
table_widget.selectRow(0)
|
||||
table_widget.keyPressEvent(
|
||||
QKeyEvent(QKeyEvent.Type.KeyPress, Qt.Key.Key_Return, Qt.KeyboardModifier.NoModifier, '\r'))
|
||||
|
||||
transcription_viewer = window.findChild(TranscriptionViewerWidget)
|
||||
assert transcription_viewer is not None
|
||||
|
||||
window.close()
|
||||
|
||||
@pytest.mark.parametrize('tasks_cache', [mock_tasks], indirect=True)
|
||||
def test_should_have_open_transcript_action_disabled_with_no_rows_selected(self, qtbot, tasks_cache):
|
||||
window = MainWindow(tasks_cache=tasks_cache)
|
||||
|
|
|
|||
0
tests/widgets/__init__.py
Normal file
0
tests/widgets/__init__.py
Normal file
16
tests/widgets/preferences_dialog_test.py
Normal file
16
tests/widgets/preferences_dialog_test.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from PyQt6.QtWidgets import QPushButton, QTabWidget
|
||||
from pytestqt.qtbot import QtBot
|
||||
|
||||
from buzz.widgets.preferences_dialog import PreferencesDialog
|
||||
|
||||
|
||||
class TestPreferencesDialog:
|
||||
def test_create(self, qtbot: QtBot):
|
||||
dialog = PreferencesDialog(shortcuts={})
|
||||
qtbot.add_widget(dialog)
|
||||
|
||||
assert dialog.windowTitle() == 'Preferences'
|
||||
|
||||
tab_widget = dialog.findChild(QTabWidget)
|
||||
assert isinstance(tab_widget, QTabWidget)
|
||||
assert tab_widget.tabText(0) == 'Shortcuts'
|
||||
31
tests/widgets/shortcuts_editor_widget_test.py
Normal file
31
tests/widgets/shortcuts_editor_widget_test.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from PyQt6.QtWidgets import QPushButton, QLabel
|
||||
|
||||
from buzz.settings.shortcut import Shortcut
|
||||
from buzz.widgets.shortcuts_editor_widget import ShortcutsEditorWidget, SequenceEdit
|
||||
|
||||
|
||||
class TestShortcutsEditorWidget:
|
||||
def test_should_reset_to_defaults(self, qtbot):
|
||||
widget = ShortcutsEditorWidget(shortcuts=Shortcut.get_default_shortcuts())
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
reset_button = widget.findChild(QPushButton)
|
||||
assert isinstance(reset_button, QPushButton)
|
||||
reset_button.click()
|
||||
|
||||
labels = widget.findChildren(QLabel)
|
||||
sequence_edits = widget.findChildren(SequenceEdit)
|
||||
|
||||
expected = (
|
||||
('Open Record Window', 'Ctrl+R'),
|
||||
('Import File', 'Ctrl+O'),
|
||||
('Open Preferences Window', 'Ctrl+,'),
|
||||
('Open Transcript Viewer', 'Ctrl+E'),
|
||||
('Clear History', 'Ctrl+S'),
|
||||
('Cancel Transcription', 'Ctrl+X'))
|
||||
|
||||
for i, (label, sequence_edit) in enumerate(zip(labels, sequence_edits)):
|
||||
assert isinstance(label, QLabel)
|
||||
assert isinstance(sequence_edit, SequenceEdit)
|
||||
assert label.text() == expected[i][0]
|
||||
assert sequence_edit.keySequence().toString() == expected[i][1]
|
||||
Loading…
Add table
Add a link
Reference in a new issue