Make the shortcut config widget a little more robust by not relying on QKeyEvent::text()

This commit is contained in:
Kovid Goyal 2014-08-25 16:48:34 +05:30
parent c0708c760d
commit a0f4117d30

View File

@ -16,7 +16,6 @@ from PyQt5.Qt import (QObject, QKeySequence, QAbstractItemModel, QModelIndex,
QGridLayout, QLabel, QRadioButton, QPushButton, QToolButton, QIcon) QGridLayout, QLabel, QRadioButton, QPushButton, QToolButton, QIcon)
from calibre.utils.config import JSONConfig from calibre.utils.config import JSONConfig
from calibre.utils.cleantext import clean_ascii_chars
from calibre.constants import DEBUG from calibre.constants import DEBUG
from calibre import prints from calibre import prints
from calibre.utils.icu import sort_key, lower from calibre.utils.icu import sort_key, lower
@ -29,6 +28,21 @@ ROOT = QModelIndex()
class NameConflict(ValueError): class NameConflict(ValueError):
pass pass
def keysequence_from_event(ev): # {{{
k, mods = ev.key(), int(ev.modifiers())
if k in (
0, Qt.Key_unknown, Qt.Key_Shift, Qt.Key_Control, Qt.Key_Alt,
Qt.Key_Meta, Qt.Key_AltGr, Qt.Key_CapsLock, Qt.Key_NumLock,
Qt.Key_ScrollLock):
return
letter = QKeySequence(k).toString(QKeySequence.PortableText)
if mods & Qt.SHIFT and letter.lower() == letter.upper():
# Something like Shift+* or Shift+> we have to remove the shift,
# since it is included in keycode.
mods = mods & ~Qt.SHIFT
return QKeySequence(k | mods)
# }}}
def finalize(shortcuts, custom_keys_map={}): # {{{ def finalize(shortcuts, custom_keys_map={}): # {{{
''' '''
Resolve conflicts and assign keys to every action in shorcuts, which must Resolve conflicts and assign keys to every action in shorcuts, which must
@ -437,22 +451,15 @@ class Editor(QFrame): # {{{
button.setText(_('None')) button.setText(_('None'))
def key_press_event(self, ev, which=0): def key_press_event(self, ev, which=0):
code = ev.key() if self.capture == 0:
if self.capture == 0 or code in (0, Qt.Key_unknown,
Qt.Key_Shift, Qt.Key_Control, Qt.Key_Alt, Qt.Key_Meta,
Qt.Key_AltGr, Qt.Key_CapsLock, Qt.Key_NumLock, Qt.Key_ScrollLock):
return QWidget.keyPressEvent(self, ev) return QWidget.keyPressEvent(self, ev)
sequence = keysequence_from_event(ev)
if sequence is None:
return QWidget.keyPressEvent(self, ev)
ev.accept()
button = getattr(self, 'button%d'%which) button = getattr(self, 'button%d'%which)
button.setStyleSheet('QPushButton { font-weight: normal}') button.setStyleSheet('QPushButton { font-weight: normal}')
mods = int(ev.modifiers()) & ~Qt.KeypadModifier
# for some reason qt sometimes produces ascii control codes in text,
# for example ctrl+shift+u will give text == '\x15' on linux
txt = clean_ascii_chars(ev.text())
if txt and txt.lower() == txt.upper():
# We have a symbol like ! or > etc. In this case the value of code
# already includes Shift, so remove it
mods &= ~Qt.ShiftModifier
sequence = QKeySequence(code|mods)
button.setText(sequence.toString(QKeySequence.NativeText)) button.setText(sequence.toString(QKeySequence.NativeText))
self.capture = 0 self.capture = 0
dup_desc = self.dup_check(sequence) dup_desc = self.dup_check(sequence)