Move special handling of keypresses into the syntax dependent smarts modules

This commit is contained in:
Kovid Goyal 2014-11-21 14:02:56 +05:30
parent 7aa1f5e54f
commit 4d7da61387
3 changed files with 31 additions and 19 deletions

View File

@ -28,3 +28,6 @@ class NullSmarts(object):
def get_inner_HTML(self, editor): def get_inner_HTML(self, editor):
return None return None
def handle_key_press(self, ev, editor):
return False

View File

@ -10,12 +10,13 @@ import sys, re
from operator import itemgetter from operator import itemgetter
from cssutils import parseStyle from cssutils import parseStyle
from PyQt5.Qt import QTextEdit from PyQt5.Qt import QTextEdit, Qt
from calibre import prepare_string_for_xml from calibre import prepare_string_for_xml, xml_entity_to_unicode
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END, ATTR_START, ATTR_VALUE from calibre.gui2.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END, ATTR_START, ATTR_VALUE
from calibre.utils.icu import utf16_length from calibre.utils.icu import utf16_length
from calibre.gui2.tweak_book import tprefs
from calibre.gui2.tweak_book.editor.smart import NullSmarts from calibre.gui2.tweak_book.editor.smart import NullSmarts
get_offset = itemgetter(0) get_offset = itemgetter(0)
@ -273,6 +274,7 @@ class HTMLSmarts(NullSmarts):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
NullSmarts.__init__(self, *args, **kwargs) NullSmarts.__init__(self, *args, **kwargs)
self.last_matched_tag = None self.last_matched_tag = None
self.entity_pat = re.compile(r'&(#{0,1}[a-zA-Z0-9]{1,8});$')
def get_extra_selections(self, editor): def get_extra_selections(self, editor):
ans = [] ans = []
@ -529,3 +531,24 @@ class HTMLSmarts(NullSmarts):
for tag in reversed(tags): for tag in reversed(tags):
set_style_property(tag, 'text-align', value, editor) set_style_property(tag, 'text-align', value, editor)
def handle_key_press(self, ev, editor):
text = ev.text()
key = ev.key()
if tprefs['replace_entities_as_typed'] and (key == Qt.Key_Semicolon or ';' in text):
self.replace_possible_entity(editor)
return True
return False
def replace_possible_entity(self, editor):
c = editor.textCursor()
c.insertText(';')
c.setPosition(c.position() - min(c.positionInBlock(), 10), c.KeepAnchor)
text = editor.selected_text_from_cursor(c)
m = self.entity_pat.search(text)
if m is not None:
ent = m.group()
repl = xml_entity_to_unicode(m)
if repl != ent:
c.setPosition(c.position() + m.start(), c.KeepAnchor)
c.insertText(repl)
editor.setTextCursor(c)

View File

@ -16,7 +16,7 @@ from PyQt5.Qt import (
QTextEdit, QTextFormat, QWidget, QSize, QPainter, Qt, QRect, pyqtSlot, QTextEdit, QTextFormat, QWidget, QSize, QPainter, Qt, QRect, pyqtSlot,
QApplication, QMimeData, QColor, QColorDialog, QTimer, pyqtSignal, QT_VERSION) QApplication, QMimeData, QColor, QColorDialog, QTimer, pyqtSignal, QT_VERSION)
from calibre import prepare_string_for_xml, xml_entity_to_unicode from calibre import prepare_string_for_xml
from calibre.constants import isosx from calibre.constants import isosx
from calibre.gui2.tweak_book import tprefs, TOP from calibre.gui2.tweak_book import tprefs, TOP
from calibre.gui2.tweak_book.editor import ( from calibre.gui2.tweak_book.editor import (
@ -33,7 +33,6 @@ from calibre.utils.icu import safe_chr, string_length, capitalize, upper, lower,
from calibre.utils.titlecase import titlecase from calibre.utils.titlecase import titlecase
PARAGRAPH_SEPARATOR = '\u2029' PARAGRAPH_SEPARATOR = '\u2029'
entity_pat = re.compile(r'&(#{0,1}[a-zA-Z0-9]{1,8});')
def get_highlighter(syntax): def get_highlighter(syntax):
ans = {'html':HTMLHighlighter, 'css':CSSHighlighter, 'xml':XMLHighlighter}.get(syntax, SyntaxHighlighter) ans = {'html':HTMLHighlighter, 'css':CSSHighlighter, 'xml':XMLHighlighter}.get(syntax, SyntaxHighlighter)
@ -762,9 +761,9 @@ class TextEdit(PlainTextEdit):
# https://bugreports.qt-project.org/browse/QTBUG-36281 # https://bugreports.qt-project.org/browse/QTBUG-36281
ev.setAccepted(False) ev.setAccepted(False)
return return
if self.smarts.handle_key_press(ev, self):
return
QPlainTextEdit.keyPressEvent(self, ev) QPlainTextEdit.keyPressEvent(self, ev)
if (ev.key() == Qt.Key_Semicolon or ';' in unicode(ev.text())) and tprefs['replace_entities_as_typed'] and self.syntax == 'html':
self.replace_possible_entity()
def replace_possible_unicode_sequence(self): def replace_possible_unicode_sequence(self):
c = self.textCursor() c = self.textCursor()
@ -789,19 +788,6 @@ class TextEdit(PlainTextEdit):
c.insertText(safe_chr(num)) c.insertText(safe_chr(num))
return True return True
def replace_possible_entity(self):
c = self.textCursor()
c.setPosition(c.position() - min(c.positionInBlock(), 10), c.KeepAnchor)
text = unicode(c.selectedText()).rstrip('\0')
m = entity_pat.search(text)
if m is None:
return
ent = m.group()
repl = xml_entity_to_unicode(m)
if repl != ent:
c.setPosition(c.position() + m.start(), c.KeepAnchor)
c.insertText(repl)
def select_all(self): def select_all(self):
c = self.textCursor() c = self.textCursor()
c.clearSelection() c.clearSelection()