forked from openlp/openlp
Shortcut can be assigned twice in certain circumstances)
Description of the fix: 1) Create a dict with the shortcuts as keys and a list of actions using this shortcut as value. 2) When we add a new action/shortcut we check if the shortcut is valid. If this is the case we add it to the dict and if not we remove the shortcut. bzr-revno: 1840
This commit is contained in:
commit
36d6a9003d
@ -344,8 +344,11 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
if category.name is None:
|
if category.name is None:
|
||||||
continue
|
continue
|
||||||
for action in category.actions:
|
for action in category.actions:
|
||||||
if self.changedActions .has_key(action):
|
if action in self.changedActions:
|
||||||
|
old_shortcuts = map(unicode,
|
||||||
|
map(QtGui.QKeySequence.toString, action.shortcuts()))
|
||||||
action.setShortcuts(self.changedActions[action])
|
action.setShortcuts(self.changedActions[action])
|
||||||
|
self.action_list.update_shortcut_map(action, old_shortcuts)
|
||||||
settings.setValue(
|
settings.setValue(
|
||||||
action.objectName(), QtCore.QVariant(action.shortcuts()))
|
action.objectName(), QtCore.QVariant(action.shortcuts()))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
@ -452,7 +455,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
those shortcuts which are not saved yet but already assigned (as changes
|
those shortcuts which are not saved yet but already assigned (as changes
|
||||||
are applied when closing the dialog).
|
are applied when closing the dialog).
|
||||||
"""
|
"""
|
||||||
if self.changedActions.has_key(action):
|
if action in self.changedActions:
|
||||||
return self.changedActions[action]
|
return self.changedActions[action]
|
||||||
return action.shortcuts()
|
return action.shortcuts()
|
||||||
|
|
||||||
|
@ -188,6 +188,7 @@ class ActionList(object):
|
|||||||
actions or categories.
|
actions or categories.
|
||||||
"""
|
"""
|
||||||
instance = None
|
instance = None
|
||||||
|
shortcut_map = {}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.categories = CategoryList()
|
self.categories = CategoryList()
|
||||||
@ -224,17 +225,45 @@ class ActionList(object):
|
|||||||
self.categories[category].actions.append(action)
|
self.categories[category].actions.append(action)
|
||||||
else:
|
else:
|
||||||
self.categories[category].actions.add(action, weight)
|
self.categories[category].actions.add(action, weight)
|
||||||
if not category:
|
|
||||||
# Stop here, as this action is not configurable.
|
|
||||||
return
|
|
||||||
# Load the shortcut from the config.
|
# Load the shortcut from the config.
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
settings.beginGroup(u'shortcuts')
|
settings.beginGroup(u'shortcuts')
|
||||||
shortcuts = settings.value(action.objectName(),
|
shortcuts = settings.value(action.objectName(),
|
||||||
QtCore.QVariant(action.shortcuts())).toStringList()
|
QtCore.QVariant(action.shortcuts())).toStringList()
|
||||||
|
settings.endGroup()
|
||||||
|
if not shortcuts:
|
||||||
|
action.setShortcuts([])
|
||||||
|
return
|
||||||
|
# We have to do this to ensure that the loaded shortcut list e. g.
|
||||||
|
# STRG+O (German) is converted to CTRL+O, which is only done when we
|
||||||
|
# convert the strings in this way (QKeySequence -> QString -> unicode).
|
||||||
|
shortcuts = map(QtGui.QKeySequence, shortcuts)
|
||||||
|
shortcuts = map(unicode, map(QtGui.QKeySequence.toString, shortcuts))
|
||||||
|
# Check the alternate shortcut first, to avoid problems when the
|
||||||
|
# alternate shortcut becomes the primary shortcut after removing the
|
||||||
|
# (initial) primary shortcut due to conflicts.
|
||||||
|
if len(shortcuts) == 2:
|
||||||
|
existing_actions = ActionList.shortcut_map.get(shortcuts[1], [])
|
||||||
|
# Check for conflicts with other actions considering the shortcut
|
||||||
|
# context.
|
||||||
|
if self._is_shortcut_available(existing_actions, action):
|
||||||
|
actions = ActionList.shortcut_map.get(shortcuts[1], [])
|
||||||
|
actions.append(action)
|
||||||
|
ActionList.shortcut_map[shortcuts[1]] = actions
|
||||||
|
else:
|
||||||
|
shortcuts.remove(shortcuts[1])
|
||||||
|
# Check the primary shortcut.
|
||||||
|
existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
||||||
|
# Check for conflicts with other actions considering the shortcut
|
||||||
|
# context.
|
||||||
|
if self._is_shortcut_available(existing_actions, action):
|
||||||
|
actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
||||||
|
actions.append(action)
|
||||||
|
ActionList.shortcut_map[shortcuts[0]] = actions
|
||||||
|
else:
|
||||||
|
shortcuts.remove(shortcuts[0])
|
||||||
action.setShortcuts(
|
action.setShortcuts(
|
||||||
[QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
|
[QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
|
||||||
settings.endGroup()
|
|
||||||
|
|
||||||
def remove_action(self, action, category=None):
|
def remove_action(self, action, category=None):
|
||||||
"""
|
"""
|
||||||
@ -242,7 +271,7 @@ class ActionList(object):
|
|||||||
automatically removed.
|
automatically removed.
|
||||||
|
|
||||||
``action``
|
``action``
|
||||||
The QAction object to be removed.
|
The ``QAction`` object to be removed.
|
||||||
|
|
||||||
``category``
|
``category``
|
||||||
The name (unicode string) of the category, which contains the
|
The name (unicode string) of the category, which contains the
|
||||||
@ -254,6 +283,15 @@ class ActionList(object):
|
|||||||
# Remove empty categories.
|
# Remove empty categories.
|
||||||
if len(self.categories[category].actions) == 0:
|
if len(self.categories[category].actions) == 0:
|
||||||
self.categories.remove(category)
|
self.categories.remove(category)
|
||||||
|
shortcuts = map(unicode,
|
||||||
|
map(QtGui.QKeySequence.toString, action.shortcuts()))
|
||||||
|
for shortcut in shortcuts:
|
||||||
|
# Remove action from the list of actions which are using this
|
||||||
|
# shortcut.
|
||||||
|
ActionList.shortcut_map[shortcut].remove(action)
|
||||||
|
# Remove empty entries.
|
||||||
|
if not ActionList.shortcut_map[shortcut]:
|
||||||
|
del ActionList.shortcut_map[shortcut]
|
||||||
|
|
||||||
def add_category(self, name, weight):
|
def add_category(self, name, weight):
|
||||||
"""
|
"""
|
||||||
@ -275,6 +313,60 @@ class ActionList(object):
|
|||||||
return
|
return
|
||||||
self.categories.add(name, weight)
|
self.categories.add(name, weight)
|
||||||
|
|
||||||
|
def update_shortcut_map(self, action, old_shortcuts):
|
||||||
|
"""
|
||||||
|
Remove the action for the given ``old_shortcuts`` from the
|
||||||
|
``shortcut_map`` to ensure its up-to-dateness.
|
||||||
|
|
||||||
|
**Note**: The new action's shortcuts **must** be assigned to the given
|
||||||
|
``action`` **before** calling this method.
|
||||||
|
|
||||||
|
``action``
|
||||||
|
The action whose shortcuts are supposed to be updated in the
|
||||||
|
``shortcut_map``.
|
||||||
|
|
||||||
|
``old_shortcuts``
|
||||||
|
A list of unicode keysequences.
|
||||||
|
"""
|
||||||
|
for old_shortcut in old_shortcuts:
|
||||||
|
# Remove action from the list of actions which are using this
|
||||||
|
# shortcut.
|
||||||
|
ActionList.shortcut_map[old_shortcut].remove(action)
|
||||||
|
# Remove empty entries.
|
||||||
|
if not ActionList.shortcut_map[old_shortcut]:
|
||||||
|
del ActionList.shortcut_map[old_shortcut]
|
||||||
|
new_shortcuts = map(unicode,
|
||||||
|
map(QtGui.QKeySequence.toString, action.shortcuts()))
|
||||||
|
# Add the new shortcuts to the map.
|
||||||
|
for new_shortcut in new_shortcuts:
|
||||||
|
existing_actions = ActionList.shortcut_map.get(new_shortcut, [])
|
||||||
|
existing_actions.append(action)
|
||||||
|
ActionList.shortcut_map[new_shortcut] = existing_actions
|
||||||
|
|
||||||
|
def _is_shortcut_available(self, existing_actions, action):
|
||||||
|
"""
|
||||||
|
Checks if the given ``action`` may use its assigned shortcut(s) or not.
|
||||||
|
Returns ``True`` or ``False.
|
||||||
|
|
||||||
|
``existing_actions``
|
||||||
|
A list of actions which already use a particular shortcut.
|
||||||
|
|
||||||
|
``action``
|
||||||
|
The action which wants to use a particular shortcut.
|
||||||
|
"""
|
||||||
|
for existing_action in existing_actions:
|
||||||
|
if action is existing_action:
|
||||||
|
continue
|
||||||
|
if existing_action.parent() is action.parent():
|
||||||
|
return False
|
||||||
|
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut,
|
||||||
|
QtCore.Qt.ApplicationShortcut]:
|
||||||
|
return False
|
||||||
|
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
|
||||||
|
QtCore.Qt.ApplicationShortcut]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class CategoryOrder(object):
|
class CategoryOrder(object):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user