Change the method the document is rehighlighted. This is significantly faster

This commit is contained in:
Veronica K. B. Olsen
2019-11-19 21:49:11 +01:00
parent 2758c587af
commit eb68f3efc0
4 changed files with 33 additions and 5 deletions
+2
View File
@@ -264,6 +264,7 @@ class GuiConfigEditGeneral(QWidget):
guiDark = self.guiDarkIcons.isChecked()
spellTool = self.spellToolList.currentData()
spellLanguage = self.spellLangList.currentData()
bigDocLimit = self.spellBigDoc.value()
autoSaveDoc = self.autoSaveDoc.value()
autoSaveProj = self.autoSaveProj.value()
backupPath = self.projBackupPath.text()
@@ -278,6 +279,7 @@ class GuiConfigEditGeneral(QWidget):
self.mainConf.guiDark = guiDark
self.mainConf.spellTool = spellTool
self.mainConf.spellLanguage = spellLanguage
self.mainConf.bigDocLimit = bigDocLimit
self.mainConf.autoSaveDoc = autoSaveDoc
self.mainConf.autoSaveProj = autoSaveProj
self.mainConf.backupPath = backupPath
+17 -4
View File
@@ -304,9 +304,11 @@ class GuiDocEditor(QTextEdit):
# Updating root frame triggers a QTextDocument->contentsChange
# signal, which we do not want as it re-runs the syntax
# highlighter and spell checker, so we block it briefly.
# We then emit a signal that does not trigger re-highlighting.
self.qDocument.blockSignals(True)
self.qDocument.rootFrame().setFrameFormat(docFormat)
self.qDocument.blockSignals(False)
self.qDocument.contentsChange.emit(0,0,0)
return
@@ -372,18 +374,26 @@ class GuiDocEditor(QTextEdit):
self.theParent.mainMenu.setSpellCheck(theMode)
self.theProject.setSpellCheck(theMode)
self.hLight.setSpellCheck(theMode)
self.hLight.rehighlight()
self.reHighlightDocument()
logger.verbose("Spell check is set to %s" % str(theMode))
return True
def updateSpellCheck(self):
def reHighlightDocument(self):
"""Rerun the highlighter to update spell checking status of the
currently loaded text.
currently loaded text. The fastest way to do this, at least as
of Qt 5.13, is to clear the text and put it back.
"""
if self.spellCheck:
self.hLight.rehighlight()
theText = self.getText()
self.clear()
bfTime = time()
self.setPlainText(theText)
afTime = time()
logger.debug("Document re-highlighted in %.3f milliseconds" % (1000*(afTime-bfTime)))
return True
##
@@ -615,6 +625,9 @@ class GuiDocEditor(QTextEdit):
return
def _docChange(self, thePos, charsRemoved, charsAdded):
"""Triggered by QTextDocument->contentsChanged. This also
triggers the syntax highlighter.
"""
self.lastEdit = time()
if not self.docChanged:
self.setDocumentChanged(True)
+1 -1
View File
@@ -618,7 +618,7 @@ class GuiMainMenu(QMenuBar):
self.aReRunSpell = QAction("Re-Run Spell Check", self)
self.aReRunSpell.setStatusTip("Run the spell checker on current document")
self.aReRunSpell.setShortcut("F7")
self.aReRunSpell.triggered.connect(self.theParent.docEditor.updateSpellCheck)
self.aReRunSpell.triggered.connect(self.theParent.docEditor.reHighlightDocument)
self.toolsMenu.addAction(self.aReRunSpell)
# Tools > Separator
+13
View File
@@ -201,6 +201,11 @@ class GuiDocHighlighter(QSyntaxHighlighter):
##
def highlightBlock(self, theText):
"""Highlight a single block. Prefer to check first character for
all formats that are defined by their initial characters. This
is significantly faster than running the regex checks we use for
text paragraphs.
"""
if self.theHandle is None or not theText:
return
@@ -224,6 +229,10 @@ class GuiDocHighlighter(QSyntaxHighlighter):
kwFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
self.setFormat(xPos, xLen, kwFmt)
# We never want to run the spell checker on keyword/values,
# so we force a return here
return
elif theText.startswith("# "): # Header 1
self.setFormat(0, 1, self.hStyles["header1"])
self.setFormat(1, len(theText), self.hStyles["header1h"])
@@ -277,6 +286,10 @@ class GuiDocHighlighter(QSyntaxHighlighter):
##
def _makeFormat(self, fmtCol=None, fmtStyle=None, fmtSize=None):
"""Generate a valid character format to be applied to the text
that is to be highlighted.
"""
theFormat = QTextCharFormat()
if fmtCol is not None: