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):
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 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.tweak_book.editor.syntax.html import ATTR_NAME, ATTR_END, ATTR_START, ATTR_VALUE
from calibre.utils.icu import utf16_length
from calibre.gui2.tweak_book import tprefs
from calibre.gui2.tweak_book.editor.smart import NullSmarts
get_offset = itemgetter(0)
@ -273,6 +274,7 @@ class HTMLSmarts(NullSmarts):
def __init__(self, *args, **kwargs):
NullSmarts.__init__(self, *args, **kwargs)
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):
ans = []
@ -529,3 +531,24 @@ class HTMLSmarts(NullSmarts):
for tag in reversed(tags):
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,
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.gui2.tweak_book import tprefs, TOP
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
PARAGRAPH_SEPARATOR = '\u2029'
entity_pat = re.compile(r'&(#{0,1}[a-zA-Z0-9]{1,8});')
def get_highlighter(syntax):
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
ev.setAccepted(False)
return
if self.smarts.handle_key_press(ev, self):
return
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):
c = self.textCursor()
@ -789,19 +788,6 @@ class TextEdit(PlainTextEdit):
c.insertText(safe_chr(num))
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):
c = self.textCursor()
c.clearSelection()