From 9967e34d0ad27ab5c4a78629dfdd7e4880ded25f Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 10 Dec 2011 15:03:08 +0100 Subject: [PATCH 1/5] re reverted changes Fixes: https://launchpad.net/bugs/768495 --- openlp/core/utils/actions.py | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 86ee69a48..525a18f37 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -188,6 +188,7 @@ class ActionList(object): actions or categories. """ instance = None + shortcut_map = {} def __init__(self): self.categories = CategoryList() @@ -226,17 +227,41 @@ class ActionList(object): self.categories[category].actions.append(action) else: self.categories[category].actions.add(action, weight) - if category is None: - # Stop here, as this action is not configurable. - return # Load the shortcut from the config. settings = QtCore.QSettings() settings.beginGroup(u'shortcuts') shortcuts = settings.value(action.objectName(), QtCore.QVariant(action.shortcuts())).toStringList() + settings.endGroup() + if not shortcuts: + action.setShortcuts([]) + return + shortcuts = map(unicode, 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 confllicts. + if len(shortcuts) == 2: + existing_actions = ActionList.shortcut_map.get(shortcuts[1], []) + # Check for conflicts with other actions considering the shortcut + # context. + if self._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._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( [QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) - settings.endGroup() def remove_action(self, action, category=None): """ @@ -244,7 +269,7 @@ class ActionList(object): automatically removed. ``action`` - The QAction object to be removed. + The ``QAction`` object to be removed. ``category`` The name (unicode string) of the category, which contains the @@ -279,6 +304,30 @@ class ActionList(object): return self.categories.add(name, weight) + def _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): """ From 3cde99d9d955c1d60c7a33793ca74f3215154c76 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 10 Dec 2011 15:03:41 +0100 Subject: [PATCH 2/5] update map when shortcuts change --- openlp/core/ui/shortcutlistform.py | 5 +++- openlp/core/utils/actions.py | 38 +++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 1eccddc95..3b3fc7c60 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -344,8 +344,11 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): if category.name is None: continue for action in category.actions: - if self.changedActions .has_key(action): + if self.changedActions.has_key(action): + old_shortcuts = map(unicode, + map(QtGui.QKeySequence.toString, action.shortcuts())) action.setShortcuts(self.changedActions[action]) + self.action_list.update_shortcut_map(action, old_shortcuts) settings.setValue( action.objectName(), QtCore.QVariant(action.shortcuts())) settings.endGroup() diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 525a18f37..d89230c81 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -244,7 +244,7 @@ class ActionList(object): existing_actions = ActionList.shortcut_map.get(shortcuts[1], []) # Check for conflicts with other actions considering the shortcut # context. - if self._shortcut_available(existing_actions, action): + if self._is_shortcut_available(existing_actions, action): actions = ActionList.shortcut_map.get(shortcuts[1], []) actions.append(action) ActionList.shortcut_map[shortcuts[1]] = actions @@ -254,7 +254,7 @@ class ActionList(object): existing_actions = ActionList.shortcut_map.get(shortcuts[0], []) # Check for conflicts with other actions considering the shortcut # context. - if self._shortcut_available(existing_actions, action): + if self._is_shortcut_available(existing_actions, action): actions = ActionList.shortcut_map.get(shortcuts[0], []) actions.append(action) ActionList.shortcut_map[shortcuts[0]] = actions @@ -304,7 +304,39 @@ class ActionList(object): return self.categories.add(name, weight) - def _shortcut_available(self, existing_actions, action): + 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: + # Should always be the case. + if old_shortcut in ActionList.shortcut_map: + # 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 shortcut 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. From 08743f147c3568e440f6af0eb0921c20222a2fcf Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 10 Dec 2011 15:10:56 +0100 Subject: [PATCH 3/5] replaced has_key --- openlp/core/ui/shortcutlistform.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 3b3fc7c60..711b46c43 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -344,7 +344,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): if category.name is None: continue 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]) @@ -455,7 +455,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): those shortcuts which are not saved yet but already assigned (as changes are applied when closing the dialog). """ - if self.changedActions.has_key(action): + if action in self.changedActions: return self.changedActions[action] return action.shortcuts() From d2cf6aa684ee11b6d23159e268c69a599c4180d5 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 14 Dec 2011 16:45:11 +0100 Subject: [PATCH 4/5] fixed a i18n bug + remove shortcut from map if removing the action --- openlp/core/utils/actions.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index d62ee99fe..5bf4d6593 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -234,10 +234,14 @@ class ActionList(object): if not shortcuts: action.setShortcuts([]) return - shortcuts = map(unicode, shortcuts) + # 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 confllicts. + # (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 @@ -279,6 +283,15 @@ class ActionList(object): # Remove empty categories. if len(self.categories[category].actions) == 0: 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): """ @@ -316,17 +329,15 @@ class ActionList(object): A list of unicode keysequences. """ for old_shortcut in old_shortcuts: - # Should always be the case. - if old_shortcut in ActionList.shortcut_map: - # 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] + # 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 shortcut to the map. + # 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) From 27843ae71889d5ef7ff416d71de727856cffc482 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 15 Dec 2011 16:27:17 +0100 Subject: [PATCH 5/5] removed space --- openlp/core/utils/actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 5bf4d6593..857e8ceed 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -238,7 +238,7 @@ class ActionList(object): # 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)) + 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.