Add persist_shortcut option for keyboard shortcuts that may be library specific.

This commit is contained in:
Jim Miller 2020-10-16 15:02:12 -05:00
parent aba21a2b1b
commit fdc7b36105
2 changed files with 39 additions and 18 deletions

View File

@ -154,7 +154,7 @@ class InterfaceAction(QObject):
bn = self.interface_action_base_plugin.name bn = self.interface_action_base_plugin.name
return 'Interface Action: %s (%s)'%(bn, self.name) return 'Interface Action: %s (%s)'%(bn, self.name)
def create_action(self, spec=None, attr='qaction', shortcut_name=None): def create_action(self, spec=None, attr='qaction', shortcut_name=None, persist_shortcut=False):
if spec is None: if spec is None:
spec = self.action_spec spec = self.action_spec
text, icon, tooltip, shortcut = spec text, icon, tooltip, shortcut = spec
@ -191,7 +191,8 @@ class InterfaceAction(QObject):
self.gui.keyboard.register_shortcut(self.unique_name + ' - ' + attr, self.gui.keyboard.register_shortcut(self.unique_name + ' - ' + attr,
shortcut_name, default_keys=keys, shortcut_name, default_keys=keys,
action=shortcut_action, description=desc, action=shortcut_action, description=desc,
group=self.action_spec[0]) group=self.action_spec[0],
persist_shortcut=persist_shortcut)
except NameConflict as e: except NameConflict as e:
try: try:
prints(unicode_type(e)) prints(unicode_type(e))
@ -216,7 +217,7 @@ class InterfaceAction(QObject):
return action return action
def create_menu_action(self, menu, unique_name, text, icon=None, shortcut=None, def create_menu_action(self, menu, unique_name, text, icon=None, shortcut=None,
description=None, triggered=None, shortcut_name=None): description=None, triggered=None, shortcut_name=None, persist_shortcut=False):
''' '''
Convenience method to easily add actions to a QMenu. Convenience method to easily add actions to a QMenu.
Returns the created QAction. This action has one extra attribute Returns the created QAction. This action has one extra attribute
@ -242,6 +243,10 @@ class InterfaceAction(QObject):
:param shortcut_name: The text displayed to the user when customizing :param shortcut_name: The text displayed to the user when customizing
the keyboard shortcuts for this action. By default it is set to the the keyboard shortcuts for this action. By default it is set to the
value of ``text``. value of ``text``.
:param persist_shortcut: Shortcuts for actions that don't
always appear, or are library dependent, may disappear
when other keyboard shortcuts are edited unless
```persist_shortcut``` is set True.
''' '''
if shortcut_name is None: if shortcut_name is None:
@ -265,7 +270,8 @@ class InterfaceAction(QObject):
if shortcut is not False: if shortcut is not False:
self.gui.keyboard.register_shortcut(unique_name, self.gui.keyboard.register_shortcut(unique_name,
shortcut_name, default_keys=keys, shortcut_name, default_keys=keys,
action=ac, description=description, group=self.action_spec[0]) action=ac, description=description, group=self.action_spec[0],
persist_shortcut=persist_shortcut)
# In Qt 5 keyboard shortcuts dont work unless the # In Qt 5 keyboard shortcuts dont work unless the
# action is explicitly added to the main window and on OSX and # action is explicitly added to the main window and on OSX and
# Unity since the menu might be exported, the shortcuts wont work # Unity since the menu might be exported, the shortcuts wont work

View File

@ -105,7 +105,7 @@ class Manager(QObject): # {{{
self.groups = {} self.groups = {}
def register_shortcut(self, unique_name, name, default_keys=(), def register_shortcut(self, unique_name, name, default_keys=(),
description=None, action=None, group=None): description=None, action=None, group=None, persist_shortcut=False):
''' '''
Register a shortcut with calibre. calibre will manage the shortcut, Register a shortcut with calibre. calibre will manage the shortcut,
automatically resolving conflicts and allowing the user to customize automatically resolving conflicts and allowing the user to customize
@ -124,13 +124,18 @@ class Manager(QObject): # {{{
:param group: A string describing what "group" this shortcut belongs :param group: A string describing what "group" this shortcut belongs
to. This is used to organize the list of shortcuts when the user is to. This is used to organize the list of shortcuts when the user is
customizing them. customizing them.
:persist_shortcut: Shortcuts for actions that don't always
appear, or are library dependent, may disappear when other
keyboard shortcuts are edited unless ```persist_shortcut``` is
set True.
''' '''
if unique_name in self.shortcuts: if unique_name in self.shortcuts:
name = self.shortcuts[unique_name]['name'] name = self.shortcuts[unique_name]['name']
raise NameConflict('Shortcut for %r already registered by %s'%( raise NameConflict('Shortcut for %r already registered by %s'%(
unique_name, name)) unique_name, name))
shortcut = {'name':name, 'desc':description, 'action': action, shortcut = {'name':name, 'desc':description, 'action': action,
'default_keys':tuple(default_keys)} 'default_keys':tuple(default_keys),
'persist_shortcut':persist_shortcut}
self.shortcuts[unique_name] = shortcut self.shortcuts[unique_name] = shortcut
group = group if group else _('Miscellaneous') group = group if group else _('Miscellaneous')
self.groups[group] = self.groups.get(group, []) + [unique_name] self.groups[group] = self.groups.get(group, []) + [unique_name]
@ -277,24 +282,34 @@ class ConfigModel(SearchQueryParser, QAbstractItemModel):
self.index(num-1, 0, group)) self.index(num-1, 0, group))
def commit(self): def commit(self):
# start with a copy and remove set_to_defaults instead of kmap = {}
# building from empty because shortcuts tied to actions not # persist flags not in map for back compat
# visible in the current library will be erased otherwise. # not *just* persist flag for forward compat
# Reading List, View Manager and FanFicFare plugins are options_map = {}
# examples where menu actions change by library. options_map.update(self.keyboard.config.get('options_map',{}))
kmap = dict(self.keyboard.config['map']) # keep mapped keys that are marked persistent.
for un, keys in iteritems(self.keyboard.config['map']):
if options_map.get(un,{}).get('persist_shortcut',False):
kmap[un] = keys
for node in self.all_shortcuts: for node in self.all_shortcuts:
sc = node.data sc = node.data
un = sc['unique_name']
if sc['set_to_default']: if sc['set_to_default']:
if sc['unique_name'] in kmap: if un in kmap:
del kmap[sc['unique_name']] del kmap[un]
if un in options_map:
del options_map[un]
else: else:
if sc['persist_shortcut']:
options_map[un] = options_map.get(un,{})
options_map[un]['persist_shortcut'] = sc['persist_shortcut']
keys = [unicode_type(k.toString(k.PortableText)) for k in sc['keys']] keys = [unicode_type(k.toString(k.PortableText)) for k in sc['keys']]
kmap[sc['unique_name']] = keys kmap[un] = keys
# note that something further on appears to depends on # note that JSONConfig further on appears to depends on
# self.keyboard.config['map'] being a different object now to # self.keyboard.config['map'] and ['persist_map'] being
# signal to save it. # different objects now to signal to save to disk.
self.keyboard.config['map'] = kmap self.keyboard.config['map'] = kmap
self.keyboard.config['options_map'] = options_map
def universal_set(self): def universal_set(self):
ans = set() ans = set()