Some tweaking in the highlichter class, and added the spelling suggestion context menu.
This commit is contained in:
+61
-3
@@ -16,9 +16,9 @@ import enchant
|
|||||||
|
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QTextEdit
|
from PyQt5.QtWidgets import QTextEdit, QAction, QMenu
|
||||||
from PyQt5.QtCore import Qt, QTimer
|
from PyQt5.QtCore import Qt, QTimer, QEvent, pyqtSignal
|
||||||
from PyQt5.QtGui import QTextCursor, QTextOption
|
from PyQt5.QtGui import QTextCursor, QTextOption, QMouseEvent
|
||||||
|
|
||||||
from nw.gui.dochighlight import GuiDocHighlighter
|
from nw.gui.dochighlight import GuiDocHighlighter
|
||||||
from nw.gui.wordcounter import WordCounter
|
from nw.gui.wordcounter import WordCounter
|
||||||
@@ -148,6 +148,56 @@ class GuiDocEditor(QTextEdit):
|
|||||||
QTextEdit.keyPressEvent(self, keyEvent)
|
QTextEdit.keyPressEvent(self, keyEvent)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def mousePressEvent(self, theEvent):
|
||||||
|
"""Capture right click events and rewrite them to left button event. This moves the cursor
|
||||||
|
to the location of the pointer. Needed to select the word under the right click.
|
||||||
|
Adapted from: https://nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check
|
||||||
|
"""
|
||||||
|
if theEvent.button() == Qt.RightButton:
|
||||||
|
theEvent = QMouseEvent(
|
||||||
|
QEvent.MouseButtonPress, theEvent.pos(), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier
|
||||||
|
)
|
||||||
|
QTextEdit.mousePressEvent(self, theEvent)
|
||||||
|
return
|
||||||
|
|
||||||
|
def contextMenuEvent(self, theEvent):
|
||||||
|
"""Intercept the context menu and insert spelling suggestions, if any.
|
||||||
|
Uses the custom QAction class SpellAction from the same example code.
|
||||||
|
Adapted from: https://nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check
|
||||||
|
"""
|
||||||
|
mnuSpell = self.createStandardContextMenu()
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
theCursor.select(QTextCursor.WordUnderCursor)
|
||||||
|
self.setTextCursor(theCursor)
|
||||||
|
|
||||||
|
if self.textCursor().hasSelection():
|
||||||
|
theText = self.textCursor().selectedText()
|
||||||
|
if not self.theDict.check(theText):
|
||||||
|
mnuSuggest = QMenu("Spelling Suggestions")
|
||||||
|
for aWord in self.theDict.suggest(theText):
|
||||||
|
action = SpellAction(aWord, mnuSuggest)
|
||||||
|
action.correct.connect(self._correctWord)
|
||||||
|
mnuSuggest.addAction(action)
|
||||||
|
if len(mnuSuggest.actions()) > 0:
|
||||||
|
theActions = mnuSpell.actions()
|
||||||
|
mnuSpell.insertSeparator(theActions[0])
|
||||||
|
mnuSpell.insertMenu(theActions[0], mnuSuggest)
|
||||||
|
|
||||||
|
mnuSpell.exec_(theEvent.globalPos())
|
||||||
|
return
|
||||||
|
|
||||||
|
##
|
||||||
|
# Internal Functions
|
||||||
|
##
|
||||||
|
|
||||||
|
def _correctWord(self, word):
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
theCursor.beginEditBlock()
|
||||||
|
theCursor.removeSelectedText()
|
||||||
|
theCursor.insertText(word)
|
||||||
|
theCursor.endEditBlock()
|
||||||
|
return
|
||||||
|
|
||||||
def _docChange(self, thePos, charsRemoved, charsAdded):
|
def _docChange(self, thePos, charsRemoved, charsAdded):
|
||||||
self.lastEdit = time()
|
self.lastEdit = time()
|
||||||
if not self.wcTimer.isActive():
|
if not self.wcTimer.isActive():
|
||||||
@@ -270,3 +320,11 @@ class GuiDocEditor(QTextEdit):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# END Class GuiDocEditor
|
# END Class GuiDocEditor
|
||||||
|
|
||||||
|
class SpellAction(QAction):
|
||||||
|
correct = pyqtSignal(str)
|
||||||
|
def __init__(self, *args):
|
||||||
|
QAction.__init__(self, *args)
|
||||||
|
self.triggered.connect(lambda x: self.correct.emit(self.text()))
|
||||||
|
|
||||||
|
# END Class SpellAction
|
||||||
|
|||||||
+12
-17
@@ -13,7 +13,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import nw
|
import nw
|
||||||
|
|
||||||
from PyQt5.QtCore import QRegularExpression, Qt
|
from PyQt5.QtCore import QRegularExpression
|
||||||
from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter
|
from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -29,17 +29,17 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
self.theDict = theDict
|
self.theDict = theDict
|
||||||
self.hRules = []
|
self.hRules = []
|
||||||
|
|
||||||
self.colHead = ( 0,155,200,255)
|
self.colHead = QColor( 0,155,200)
|
||||||
self.colHeadH = ( 0,105,135,255)
|
self.colHeadH = QColor( 0,105,135)
|
||||||
self.colEmph = (200,120, 0,255)
|
self.colEmph = QColor(200,120, 0)
|
||||||
self.colDialN = (200, 46, 0,255)
|
self.colDialN = QColor(200, 46, 0)
|
||||||
self.colDialD = (184,200, 0,255)
|
self.colDialD = QColor(184,200, 0)
|
||||||
self.colDialS = (136,200, 0,255)
|
self.colDialS = QColor(136,200, 0)
|
||||||
self.colComm = (150,150,150,255)
|
self.colComm = QColor(150,150,150)
|
||||||
self.colKey = (200, 46, 0,255)
|
self.colKey = QColor(200, 46, 0)
|
||||||
self.colVal = (184,200, 0,255)
|
self.colVal = QColor(184,200, 0)
|
||||||
|
|
||||||
self.colSpell = QColor(200,46,0)
|
self.colSpell = QColor(200, 46, 0)
|
||||||
|
|
||||||
self.hStyles = {
|
self.hStyles = {
|
||||||
"header1" : self._makeFormat(self.colHead, "bold",1.8),
|
"header1" : self._makeFormat(self.colHead, "bold",1.8),
|
||||||
@@ -155,12 +155,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
theFormat = QTextCharFormat()
|
theFormat = QTextCharFormat()
|
||||||
|
|
||||||
if fmtCol is not None:
|
if fmtCol is not None:
|
||||||
theCol = QColor()
|
theFormat.setForeground(fmtCol)
|
||||||
if isinstance(fmtCol,str):
|
|
||||||
theCol.setNamedColor(fmtCol)
|
|
||||||
else:
|
|
||||||
theCol.setRgb(*fmtCol)
|
|
||||||
theFormat.setForeground(theCol)
|
|
||||||
|
|
||||||
if fmtStyle is not None:
|
if fmtStyle is not None:
|
||||||
if "bold" in fmtStyle:
|
if "bold" in fmtStyle:
|
||||||
|
|||||||
Reference in New Issue
Block a user