Make KeySequence.matchs() work correctly

This commit is contained in:
Florian Bruhin 2018-03-04 17:46:26 +01:00
parent 866c758660
commit 8da878c77c
2 changed files with 58 additions and 7 deletions

View File

@ -361,15 +361,38 @@ class KeySequence:
raise KeyParseError(keystr, "Got unknown key!")
def matches(self, other):
"""Check whether the given KeySequence matches with this one."""
"""Check whether the given KeySequence matches with this one.
We store multiple QKeySequences with <= 4 keys each, so we need to match
those pair-wise, and account for an unequal amount of sequences as well.
"""
# pylint: disable=protected-access
assert self._sequences
assert other._sequences
for seq1, seq2 in zip(self._sequences, other._sequences):
match = seq1.matches(seq2)
if len(self._sequences) > len(other._sequences):
# If we entered more sequences than there are in the config, there's
# no way there can be a match.
return QKeySequence.NoMatch
for entered, configured in zip(self._sequences, other._sequences):
# If we get NoMatch/PartialMatch in a sequence, we can abort there.
match = entered.matches(configured)
if match != QKeySequence.ExactMatch:
return match
return QKeySequence.ExactMatch
# We checked all common sequences and they had an ExactMatch.
#
# If there's still more sequences configured than entered, that's a
# PartialMatch, as more keypresses can still follow and new sequences
# will appear which we didn't check above.
#
# If there's the same amount of sequences configured and entered, that's
# an EqualMatch.
if len(self._sequences) == len(other._sequences):
return QKeySequence.ExactMatch
elif len(self._sequences) < len(other._sequences):
return QKeySequence.PartialMatch
else:
assert False, (self, other)
def append_event(self, ev):
"""Create a new KeySequence object with the given QKeyEvent added.

View File

@ -21,7 +21,7 @@ import operator
import pytest
from PyQt5.QtCore import Qt, QEvent, pyqtSignal
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtGui import QKeyEvent, QKeySequence
from PyQt5.QtWidgets import QWidget
from tests.unit.keyinput import key_data
@ -291,6 +291,34 @@ class TestKeySequence:
assert s1[3:5] == s2
assert seq[3:5] == expected
@pytest.mark.parametrize('entered, configured, expected', [
# config: abcd
('abc', 'abcd', QKeySequence.PartialMatch),
('abcd', 'abcd', QKeySequence.ExactMatch),
('ax', 'abcd', QKeySequence.NoMatch),
('abcdef', 'abcd', QKeySequence.NoMatch),
# config: abcd ef
('abc', 'abcdef', QKeySequence.PartialMatch),
('abcde', 'abcdef', QKeySequence.PartialMatch),
('abcd', 'abcdef', QKeySequence.PartialMatch),
('abcdx', 'abcdef', QKeySequence.NoMatch),
('ax', 'abcdef', QKeySequence.NoMatch),
('abcdefg', 'abcdef', QKeySequence.NoMatch),
('abcdef', 'abcdef', QKeySequence.ExactMatch),
# other examples
('ab', 'a', QKeySequence.NoMatch),
# empty strings
('', '', QKeySequence.ExactMatch),
('', 'a', QKeySequence.PartialMatch),
('a', '', QKeySequence.NoMatch),
])
def test_matches(self, entered, configured, expected):
entered = keyutils.KeySequence.parse(entered)
configured = keyutils.KeySequence.parse(configured)
assert entered.matches(configured) == expected
@pytest.mark.parametrize('keystr, expected', [
('<Control-x>', keyutils.KeySequence(Qt.ControlModifier | Qt.Key_X)),