Store multiple QKeySequences in KeySequence
This commit is contained in:
parent
79a337767a
commit
d077f38ac4
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import collections
|
import collections
|
||||||
|
import itertools
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
@ -261,15 +262,23 @@ class KeyInfo:
|
|||||||
|
|
||||||
class KeySequence:
|
class KeySequence:
|
||||||
|
|
||||||
def __init__(self, *args):
|
_MAX_LEN = 4
|
||||||
self._sequence = QKeySequence(*args)
|
|
||||||
for key in self._sequence:
|
def __init__(self, strings=None):
|
||||||
assert key != Qt.Key_unknown
|
self._sequences = []
|
||||||
# FIXME handle more than 4 keys
|
if strings is None:
|
||||||
|
strings = []
|
||||||
|
|
||||||
|
for sub in utils.chunk(strings, 4):
|
||||||
|
# Catch old API usage FIXME
|
||||||
|
assert all(isinstance(s, str) for s in sub)
|
||||||
|
sequence = QKeySequence(', '.join(sub))
|
||||||
|
self._sequences.append(sequence)
|
||||||
|
self._validate()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
parts = []
|
parts = []
|
||||||
for info in self._sequence:
|
for info in self:
|
||||||
parts.append(str(info))
|
parts.append(str(info))
|
||||||
return ''.join(parts)
|
return ''.join(parts)
|
||||||
|
|
||||||
@ -278,7 +287,7 @@ class KeySequence:
|
|||||||
modifier_mask = int(Qt.ShiftModifier | Qt.ControlModifier |
|
modifier_mask = int(Qt.ShiftModifier | Qt.ControlModifier |
|
||||||
Qt.AltModifier | Qt.MetaModifier |
|
Qt.AltModifier | Qt.MetaModifier |
|
||||||
Qt.KeypadModifier | Qt.GroupSwitchModifier)
|
Qt.KeypadModifier | Qt.GroupSwitchModifier)
|
||||||
for key in self._sequence:
|
for key in itertools.chain.from_iterable(self._sequences):
|
||||||
yield KeyInfo(
|
yield KeyInfo(
|
||||||
key=int(key) & ~modifier_mask,
|
key=int(key) & ~modifier_mask,
|
||||||
modifiers=Qt.KeyboardModifiers(int(key) & modifier_mask))
|
modifiers=Qt.KeyboardModifiers(int(key) & modifier_mask))
|
||||||
@ -287,26 +296,38 @@ class KeySequence:
|
|||||||
return utils.get_repr(self, keys=str(self))
|
return utils.get_repr(self, keys=str(self))
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return self._sequence < other._sequence
|
return self._sequences < other._sequences
|
||||||
|
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
return self._sequence > other._sequence
|
return self._sequences > other._sequences
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self._sequence == other._sequence
|
return self._sequences == other._sequences
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return self._sequence != other._sequence
|
return self._sequences != other._sequences
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self._sequence)
|
# FIXME is this correct?
|
||||||
|
return hash(tuple(self._sequences))
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._sequence)
|
return sum(len(seq) for seq in self._sequences)
|
||||||
|
|
||||||
|
def _validate(self):
|
||||||
|
for info in self:
|
||||||
|
assert info.key != Qt.Key_unknown
|
||||||
|
|
||||||
def matches(self, other):
|
def matches(self, other):
|
||||||
|
# FIXME test this
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
return self._sequence.matches(other._sequence)
|
assert self._sequences
|
||||||
|
assert other._sequences
|
||||||
|
for seq1, seq2 in zip(self._sequences, other._sequences):
|
||||||
|
match = seq1.matches(seq2)
|
||||||
|
if match != QKeySequence.ExactMatch:
|
||||||
|
return match
|
||||||
|
return QKeySequence.ExactMatch
|
||||||
|
|
||||||
def append_event(self, ev):
|
def append_event(self, ev):
|
||||||
"""Create a new KeySequence object with the given QKeyEvent added.
|
"""Create a new KeySequence object with the given QKeyEvent added.
|
||||||
@ -325,17 +346,28 @@ class KeySequence:
|
|||||||
|
|
||||||
FIXME: create test cases!
|
FIXME: create test cases!
|
||||||
"""
|
"""
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
new = self.__class__()
|
||||||
|
new._sequences = self._sequences[:]
|
||||||
|
|
||||||
modifiers = ev.modifiers()
|
modifiers = ev.modifiers()
|
||||||
if (modifiers == Qt.ShiftModifier and
|
if (modifiers == Qt.ShiftModifier and
|
||||||
unicodedata.category(ev.text()) != 'Lu'):
|
unicodedata.category(ev.text()) != 'Lu'):
|
||||||
modifiers = Qt.KeyboardModifiers()
|
modifiers = Qt.KeyboardModifiers()
|
||||||
return self.__class__(*self._sequence, modifiers | ev.key())
|
|
||||||
|
if new._sequences and len(new._sequences[-1]) < self._MAX_LEN:
|
||||||
|
new._sequences[-1] = QKeySequence(*new._sequences[-1],
|
||||||
|
ev.key() | int(modifiers))
|
||||||
|
else:
|
||||||
|
new._sequences.append(QKeySequence(ev.key() | int(modifiers)))
|
||||||
|
|
||||||
|
new._validate()
|
||||||
|
return new
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse(cls, keystr):
|
def parse(cls, keystr):
|
||||||
"""Parse a keystring like <Ctrl-x> or xyz and return a KeySequence."""
|
"""Parse a keystring like <Ctrl-x> or xyz and return a KeySequence."""
|
||||||
# FIXME have multiple sequences in self!
|
parts = list(_parse_keystring(keystr))
|
||||||
s = ', '.join(_parse_keystring(keystr))
|
new = cls(parts)
|
||||||
new = cls(s)
|
|
||||||
assert len(new) > 0
|
assert len(new) > 0
|
||||||
return new
|
return new
|
||||||
|
@ -659,3 +659,13 @@ def yaml_dump(data, f=None):
|
|||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return yaml_data.decode('utf-8')
|
return yaml_data.decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def chunk(elems, n):
|
||||||
|
"""Yield successive n-sized chunks from elems.
|
||||||
|
|
||||||
|
If elems % n != 0, the last chunk will be smaller.
|
||||||
|
"""
|
||||||
|
# FIXME test this
|
||||||
|
for i in range(0, len(elems), n):
|
||||||
|
yield elems[i:i + n]
|
||||||
|
Loading…
Reference in New Issue
Block a user