mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Create keyboard settings file; keyboard settings for recent files
This commit is contained in:
parent
6c1da756aa
commit
5475f5d843
9 changed files with 140 additions and 11 deletions
|
|
@ -5,6 +5,8 @@ Added
|
|||
-----
|
||||
|
||||
* Show list of recent files on welcome screen
|
||||
* Keyboard shortcuts can now be configured via a settings file.
|
||||
Go to "Settings -> Open Settings Folder" and edit KeyboardSettings.ini
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
|
|
|||
|
|
@ -265,4 +265,9 @@ actions = [
|
|||
'checkable': True,
|
||||
'callback': 'on_action_always_on_top',
|
||||
},
|
||||
{
|
||||
'id': 'open_settings_dir',
|
||||
'text': 'Open Settings Folder',
|
||||
'callback': 'on_action_open_settings_dir',
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -98,6 +98,12 @@ menu_structure = [
|
|||
'arrange_vertical',
|
||||
],
|
||||
},
|
||||
{
|
||||
'menu': '&Settings',
|
||||
'items': [
|
||||
'open_settings_dir',
|
||||
],
|
||||
},
|
||||
{
|
||||
'menu': '&Help',
|
||||
'items': [
|
||||
|
|
|
|||
|
|
@ -112,16 +112,26 @@ class ActionsMixin:
|
|||
|
||||
files = self.settings.get_recent_files(existing_only=True)
|
||||
items = []
|
||||
i = -1
|
||||
for i, filename in enumerate(files):
|
||||
qaction = QtGui.QAction(os.path.basename(filename), self)
|
||||
action_id = f'recent_files_{i}'
|
||||
key = 0 if i == 9 else i + 1
|
||||
if key < 10:
|
||||
qaction.setShortcuts([f'Ctrl+{key}'])
|
||||
shortcuts = KeyboardSettings().get_shortcuts(
|
||||
'Actions', action_id, [f'Ctrl+{key}'])
|
||||
qaction.setShortcuts(shortcuts)
|
||||
qaction.triggered.connect(partial(self.open_from_file, filename))
|
||||
self.addAction(qaction)
|
||||
self._recent_files_submenu.addAction(qaction)
|
||||
self.bee_actions[f'recent_files_{i}'] = qaction
|
||||
items.append(f'recent_files_{i}')
|
||||
self.bee_actions[action_id] = qaction
|
||||
items.append(action_id)
|
||||
|
||||
# Set shorcuts in settings file for remaining slots:
|
||||
for j in range(i + 1, 10):
|
||||
key = 0 if j == 9 else j + 1
|
||||
KeyboardSettings().get_shortcuts(
|
||||
'Actions', f'recent_files_{j}', [f'Ctrl+{key}'])
|
||||
|
||||
def _clear_recent_files(self):
|
||||
for action in self._recent_files_submenu.actions():
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ class BeeSettings(QtCore.QSettings):
|
|||
|
||||
class KeyboardSettings(QtCore.QSettings):
|
||||
|
||||
save_unknown_shortcuts = True
|
||||
|
||||
def __init__(self):
|
||||
settings_format = QtCore.QSettings.Format.IniFormat
|
||||
filename = os.path.join(
|
||||
|
|
@ -159,7 +161,12 @@ class KeyboardSettings(QtCore.QSettings):
|
|||
values = list(filter(lambda x: x, values.split(', ')))
|
||||
logger.debug(f'Found custom shortcuts for {group}/{key}: {values}')
|
||||
return values
|
||||
return default or []
|
||||
|
||||
values = default or []
|
||||
if self.save_unknown_shortcuts:
|
||||
self.set_shortcuts(group, key, values)
|
||||
|
||||
return values
|
||||
|
||||
|
||||
def logfile_name():
|
||||
|
|
|
|||
|
|
@ -489,6 +489,11 @@ class BeeGraphicsView(MainControlsMixin,
|
|||
return
|
||||
logger.info('No image data or text in clipboard')
|
||||
|
||||
def on_action_open_settings_dir(self):
|
||||
dirname = os.path.dirname(self.settings.fileName())
|
||||
QtGui.QDesktopServices.openUrl(
|
||||
QtCore.QUrl.fromLocalFile(dirname))
|
||||
|
||||
def on_selection_changed(self):
|
||||
logger.debug('Currently selected items: %s',
|
||||
len(self.scene.selectedItems(user_only=True)))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os.path
|
||||
from unittest.mock import patch, MagicMock
|
||||
from unittest.mock import patch, MagicMock, call
|
||||
|
||||
from PyQt6 import QtWidgets
|
||||
|
||||
|
|
@ -26,8 +26,10 @@ class FooWidget(QtWidgets.QWidget, ActionsMixin):
|
|||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
@patch('beeref.actions.mixin.KeyboardSettings.get_shortcuts')
|
||||
def test_create_actions(
|
||||
actions_mock, menu_mock, toggle_mock, trigger_mock, qapp):
|
||||
kb_mock, actions_mock, menu_mock, toggle_mock, trigger_mock, qapp):
|
||||
kb_mock.side_effect = lambda group, key, default: default
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
|
|
@ -47,6 +49,7 @@ def test_create_actions(
|
|||
assert qaction.shortcut() == 'Ctrl+F'
|
||||
assert qaction.isEnabled() is True
|
||||
assert widget.bee_actions['foo'] == qaction
|
||||
kb_mock.assert_called_once_with('Actions', 'foo', ['Ctrl+F'])
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
|
|
@ -267,7 +270,10 @@ def test_build_menu_and_actions_disables_actiongroups(
|
|||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_create_recent_files(actions_mock, menu_mock, triggered_mock, qapp):
|
||||
@patch('beeref.actions.mixin.KeyboardSettings.get_shortcuts')
|
||||
def test_create_recent_files_more_files_than_shortcuts(
|
||||
kb_mock, actions_mock, menu_mock, triggered_mock, qapp):
|
||||
kb_mock.side_effect = lambda group, key, default: default
|
||||
widget = FooWidget()
|
||||
widget.settings.get_recent_files.return_value = [
|
||||
os.path.abspath(f'{i}.bee') for i in range(15)]
|
||||
|
|
@ -295,6 +301,69 @@ def test_create_recent_files(actions_mock, menu_mock, triggered_mock, qapp):
|
|||
assert qaction15.isEnabled() is True
|
||||
assert widget.bee_actions['recent_files_14'] == qaction15
|
||||
|
||||
assert kb_mock.call_count == 10
|
||||
kb_mock.assert_has_calls(
|
||||
[call('Actions', 'recent_files_0', ['Ctrl+1']),
|
||||
call('Actions', 'recent_files_9', ['Ctrl+0'])],
|
||||
any_order=True)
|
||||
|
||||
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
@patch('beeref.actions.mixin.KeyboardSettings.get_shortcuts')
|
||||
def test_create_recent_files_fewer_files_than_shortcuts(
|
||||
kb_mock, actions_mock, menu_mock, triggered_mock, qapp):
|
||||
kb_mock.side_effect = lambda group, key, default: default
|
||||
widget = FooWidget()
|
||||
widget.settings.get_recent_files.return_value = [
|
||||
os.path.abspath(f'{i}.bee') for i in range(5)]
|
||||
menu_mock.__iter__.return_value = [{
|
||||
'menu': 'Open &Recent',
|
||||
'items': '_build_recent_files',
|
||||
}]
|
||||
|
||||
widget.build_menu_and_actions()
|
||||
triggered_mock.connect.assert_called()
|
||||
assert len(widget.actions()) == 5
|
||||
qaction1 = widget.actions()[0]
|
||||
assert qaction1.text() == '0.bee'
|
||||
assert qaction1.shortcut() == 'Ctrl+1'
|
||||
assert qaction1.isEnabled() is True
|
||||
assert widget.bee_actions['recent_files_0'] == qaction1
|
||||
qaction5 = widget.actions()[4]
|
||||
assert qaction5.text() == '4.bee'
|
||||
assert qaction5.shortcut() == 'Ctrl+5'
|
||||
assert qaction5.isEnabled() is True
|
||||
assert widget.bee_actions['recent_files_4'] == qaction5
|
||||
|
||||
assert kb_mock.call_count == 10
|
||||
kb_mock.assert_has_calls(
|
||||
[call('Actions', 'recent_files_0', ['Ctrl+1']),
|
||||
call('Actions', 'recent_files_9', ['Ctrl+0'])],
|
||||
any_order=True)
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
@patch('beeref.actions.mixin.KeyboardSettings.get_shortcuts')
|
||||
def test_create_recent_files_when_no_files(
|
||||
kb_mock, actions_mock, menu_mock, qapp):
|
||||
kb_mock.side_effect = lambda group, key, default: default
|
||||
widget = FooWidget()
|
||||
widget.settings.get_recent_files.return_value = []
|
||||
menu_mock.__iter__.return_value = [{
|
||||
'menu': 'Open &Recent',
|
||||
'items': '_build_recent_files',
|
||||
}]
|
||||
widget.build_menu_and_actions()
|
||||
assert len(widget.actions()) == 0
|
||||
assert kb_mock.call_count == 10
|
||||
kb_mock.assert_has_calls(
|
||||
[call('Actions', 'recent_files_0', ['Ctrl+1']),
|
||||
call('Actions', 'recent_files_9', ['Ctrl+0'])],
|
||||
any_order=True)
|
||||
|
||||
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ def pytest_configure(config):
|
|||
import logging.config
|
||||
logging.config.dictConfig = MagicMock
|
||||
|
||||
# Disable creation of KeyboardSettings.ini to speed tests up
|
||||
from beeref.config import KeyboardSettings
|
||||
KeyboardSettings.save_unknown_shortcuts = False
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def commandline_args():
|
||||
|
|
|
|||
|
|
@ -83,15 +83,36 @@ def test_keyboardsettings_set_shortcuts_multiple(kbsettings):
|
|||
assert kbsettings.get_shortcuts('Actions', 'foo') == ['Ctrl+F', 'Alt+O']
|
||||
|
||||
|
||||
def test_keyboardsettings_get_shortcuts_existing(kbsettings):
|
||||
kbsettings.set_shortcuts('Actions', 'bar', ['Ctrl+R'])
|
||||
with patch.object(kbsettings, 'set_shortcuts') as set_mock:
|
||||
with patch.object(kbsettings, 'save_unknown_shortcuts', True):
|
||||
shortcuts = kbsettings.get_shortcuts('Actions', 'bar', ['Ctrl+B'])
|
||||
assert shortcuts == ['Ctrl+R']
|
||||
set_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_keyboardsettings_get_shortcuts_default(kbsettings):
|
||||
assert kbsettings.get_shortcuts('Actions', 'bar', ['Ctrl+B']) == ['Ctrl+B']
|
||||
with patch.object(kbsettings, 'set_shortcuts') as set_mock:
|
||||
with patch.object(kbsettings, 'save_unknown_shortcuts', True):
|
||||
shortcuts = kbsettings.get_shortcuts('Actions', 'bar', ['Ctrl+B'])
|
||||
assert shortcuts == ['Ctrl+B']
|
||||
set_mock.assert_called_once_with('Actions', 'bar', ['Ctrl+B'])
|
||||
|
||||
|
||||
def test_keyboardsettings_get_shortcuts_defaults_dont_overwrite_empty(
|
||||
def test_keyboardsettings_get_shortcuts_default_doesnt_override_empty(
|
||||
kbsettings):
|
||||
kbsettings.set_shortcuts('Actions', 'bar', [])
|
||||
assert kbsettings.get_shortcuts('Actions', 'bar', ['Ctrl+B']) == []
|
||||
with patch.object(kbsettings, 'set_shortcuts') as set_mock:
|
||||
with patch.object(kbsettings, 'save_unknown_shortcuts', True):
|
||||
shortcuts = kbsettings.get_shortcuts('Actions', 'bar', ['Ctrl+B'])
|
||||
assert shortcuts == []
|
||||
set_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_keyboardsettings_get_shortcuts_not_set_no_defaults(kbsettings):
|
||||
assert kbsettings.get_shortcuts('Actions', 'baz') == []
|
||||
with patch('beeref.config.KeyboardSettings.set_shortcuts') as set_mock:
|
||||
with patch.object(kbsettings, 'save_unknown_shortcuts', True):
|
||||
shortcuts = kbsettings.get_shortcuts('Actions', 'baz')
|
||||
assert shortcuts == []
|
||||
set_mock.assert_called_once_with('Actions', 'baz', [])
|
||||
|
|
|
|||
Loading…
Reference in a new issue