This commit is contained in:
Kovid Goyal 2019-07-02 18:08:34 +05:30
parent 04d58d6877
commit 93fc64184e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -7,6 +7,7 @@ import os
import re import re
import weakref import weakref
from collections import defaultdict from collections import defaultdict
from contextlib import contextmanager
from html5_parser import parse from html5_parser import parse
from lxml import html from lxml import html
@ -159,6 +160,16 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
def readonly(self, val): def readonly(self, val):
self.setReadOnly(bool(val)) self.setReadOnly(bool(val))
@contextmanager
def editing_cursor(self, set_cursor=True):
c = self.textCursor()
c.beginEditBlock()
yield c
c.endEditBlock()
if set_cursor:
self.setTextCursor(c)
self.focus_self()
def __init__(self, parent=None): def __init__(self, parent=None):
QTextEdit.__init__(self, parent) QTextEdit.__init__(self, parent)
self.setTabChangesFocus(True) self.setTabChangesFocus(True)
@ -302,12 +313,10 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
raise NotImplementedError('TODO') raise NotImplementedError('TODO')
def do_vertical_align(self, which): def do_vertical_align(self, which):
c = self.textCursor() with self.editing_cursor() as c:
fmt = QTextCharFormat() fmt = QTextCharFormat()
fmt.setVerticalAlignment(which) fmt.setVerticalAlignment(which)
c.mergeCharFormat(fmt) c.mergeCharFormat(fmt)
self.setTextCursor(c)
self.focus_self()
def do_superscript(self): def do_superscript(self):
self.do_vertical_align(QTextCharFormat.AlignSuperScript) self.do_vertical_align(QTextCharFormat.AlignSuperScript)
@ -316,16 +325,14 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
self.do_vertical_align(QTextCharFormat.AlignSubScript) self.do_vertical_align(QTextCharFormat.AlignSubScript)
def do_list(self, fmt): def do_list(self, fmt):
c = self.textCursor() with self.editing_cursor() as c:
ls = c.currentList() ls = c.currentList()
if ls is not None: if ls is not None:
lf = ls.format() lf = ls.format()
lf.setStyle(fmt) lf.setStyle(fmt)
ls.setFormat(lf) ls.setFormat(lf)
else: else:
ls = c.createList(fmt) ls = c.createList(fmt)
self.setTextCursor(c)
self.focus_self()
def do_ordered_list(self): def do_ordered_list(self):
self.do_list(QTextListFormat.ListDecimal) self.do_list(QTextListFormat.ListDecimal)
@ -354,13 +361,9 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
self.focus_self() self.focus_self()
def do_remove_format(self): def do_remove_format(self):
c = self.textCursor() with self.editing_cursor() as c:
c.beginEditBlock() c.setBlockFormat(QTextBlockFormat())
c.setBlockFormat(QTextBlockFormat()) c.setCharFormat(QTextCharFormat())
c.setCharFormat(QTextCharFormat())
c.endEditBlock()
self.setTextCursor(c)
self.focus_self()
def do_copy(self): def do_copy(self):
self.copy() self.copy()
@ -375,12 +378,10 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
self.focus_self() self.focus_self()
def indent_block(self, mult=1): def indent_block(self, mult=1):
c = self.textCursor() with self.editing_cursor() as c:
bf = c.blockFormat() bf = c.blockFormat()
bf.setTextIndent(bf.textIndent() + 2 * self.em_size * mult) bf.setTextIndent(bf.textIndent() + 2 * self.em_size * mult)
c.setBlockFormat(bf) c.setBlockFormat(bf)
self.setTextCursor(c)
self.focus_self()
def do_indent(self): def do_indent(self):
self.indent_block() self.indent_block()
@ -389,11 +390,9 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
self.indent_block(-1) self.indent_block(-1)
def do_select_all(self): def do_select_all(self):
c = self.textCursor() with self.editing_cursor() as c:
c.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor) c.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
c.movePosition(QTextCursor.End, QTextCursor.KeepAnchor) c.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)
self.setTextCursor(c)
self.focus_self()
def level_for_block_type(self, name): def level_for_block_type(self, name):
if name == 'blockquote': if name == 'blockquote':
@ -407,39 +406,35 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
def do_format_block(self): def do_format_block(self):
name = self.sender().block_name name = self.sender().block_name
c = self.textCursor() with self.editing_cursor() as c:
c.beginEditBlock() bf = QTextBlockFormat()
bf = QTextBlockFormat() cf = QTextCharFormat()
cf = QTextCharFormat() bcf = c.blockCharFormat()
bcf = c.blockCharFormat() lvl = self.level_for_block_type(name)
lvl = self.level_for_block_type(name) hmargin = 0
hmargin = 0 wt = 75 if lvl else None
wt = 75 if lvl else None adjust = (0, 3, 2, 1, 0, -1, -1)[lvl]
adjust = (0, 3, 2, 1, 0, -1, -1)[lvl] if name == 'blockquote':
if name == 'blockquote': hmargin = self.em_size * 3
hmargin = self.em_size * 3 pos = None
pos = None if not c.hasSelection():
if not c.hasSelection(): pos = c.position()
pos = c.position() c.movePosition(QTextCursor.StartOfBlock, QTextCursor.MoveAnchor)
c.movePosition(QTextCursor.StartOfBlock, QTextCursor.MoveAnchor) c.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
c.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) bf.setLeftMargin(hmargin), bf.setRightMargin(bf.leftMargin())
bf.setLeftMargin(hmargin), bf.setRightMargin(bf.leftMargin()) bf.setTopMargin(self.vmargin_for_block_type(name)), bf.setBottomMargin(bf.topMargin())
bf.setTopMargin(self.vmargin_for_block_type(name)), bf.setBottomMargin(bf.topMargin()) bf.setHeadingLevel(lvl)
bf.setHeadingLevel(lvl) if adjust:
if adjust: bcf.setProperty(QTextCharFormat.FontSizeAdjustment, adjust)
bcf.setProperty(QTextCharFormat.FontSizeAdjustment, adjust) cf.setProperty(QTextCharFormat.FontSizeAdjustment, adjust)
cf.setProperty(QTextCharFormat.FontSizeAdjustment, adjust) if wt:
if wt: bcf.setProperty(QTextCharFormat.FontWeight, wt)
bcf.setProperty(QTextCharFormat.FontWeight, wt) cf.setProperty(QTextCharFormat.FontWeight, wt)
cf.setProperty(QTextCharFormat.FontWeight, wt) c.setBlockCharFormat(bcf)
c.setBlockCharFormat(bcf) c.mergeCharFormat(cf)
c.mergeCharFormat(cf) c.mergeBlockFormat(bf)
c.mergeBlockFormat(bf) if pos is not None:
if pos is not None: c.setPosition(pos)
c.setPosition(pos)
c.endEditBlock()
self.setTextCursor(c)
self.focus_self()
def do_color(self): def do_color(self):
col = QColorDialog.getColor(Qt.black, self, col = QColorDialog.getColor(Qt.black, self,
@ -454,18 +449,13 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
if col.isValid(): if col.isValid():
fmt = QTextCharFormat() fmt = QTextCharFormat()
fmt.setBackground(QBrush(col)) fmt.setBackground(QBrush(col))
c = self.textCursor() with self.editing_cursor() as c:
c.mergeCharFormat(fmt) c.mergeCharFormat(fmt)
self.setTextCursor(c)
def do_insert_hr(self, *args): def do_insert_hr(self, *args):
c = self.textCursor() with self.editing_cursor() as c:
c.beginEditBlock() c.movePosition(c.EndOfBlock, c.MoveAnchor)
c.movePosition(c.EndOfBlock, c.MoveAnchor) c.insertHtml('<hr>')
c.insertHtml('<hr>')
c.endEditBlock()
self.setTextCursor(c)
self.focus_self()
def do_insert_link(self, *args): def do_insert_link(self, *args):
link, name, is_image = self.ask_link() link, name, is_image = self.ask_link()