From fe4d2f4a85461514f9cec78efa08161c179e437d Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" Date: Sat, 4 May 2019 22:10:41 +0200 Subject: [PATCH] Some tweaking in the highlichter class, and added the spelling suggestion context menu. --- nw/gui/doceditor.py | 64 ++++++++++++++++++++++++++++++++++++++++-- nw/gui/dochighlight.py | 29 ++++++++----------- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index e17a3090..568f8168 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -16,9 +16,9 @@ import enchant from time import time -from PyQt5.QtWidgets import QTextEdit -from PyQt5.QtCore import Qt, QTimer -from PyQt5.QtGui import QTextCursor, QTextOption +from PyQt5.QtWidgets import QTextEdit, QAction, QMenu +from PyQt5.QtCore import Qt, QTimer, QEvent, pyqtSignal +from PyQt5.QtGui import QTextCursor, QTextOption, QMouseEvent from nw.gui.dochighlight import GuiDocHighlighter from nw.gui.wordcounter import WordCounter @@ -148,6 +148,56 @@ class GuiDocEditor(QTextEdit): QTextEdit.keyPressEvent(self, keyEvent) 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): self.lastEdit = time() if not self.wcTimer.isActive(): @@ -270,3 +320,11 @@ class GuiDocEditor(QTextEdit): return # 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 diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py index e6319d51..eb9ddd43 100644 --- a/nw/gui/dochighlight.py +++ b/nw/gui/dochighlight.py @@ -13,7 +13,7 @@ import logging import nw -from PyQt5.QtCore import QRegularExpression, Qt +from PyQt5.QtCore import QRegularExpression from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter logger = logging.getLogger(__name__) @@ -29,17 +29,17 @@ class GuiDocHighlighter(QSyntaxHighlighter): self.theDict = theDict self.hRules = [] - self.colHead = ( 0,155,200,255) - self.colHeadH = ( 0,105,135,255) - self.colEmph = (200,120, 0,255) - self.colDialN = (200, 46, 0,255) - self.colDialD = (184,200, 0,255) - self.colDialS = (136,200, 0,255) - self.colComm = (150,150,150,255) - self.colKey = (200, 46, 0,255) - self.colVal = (184,200, 0,255) + self.colHead = QColor( 0,155,200) + self.colHeadH = QColor( 0,105,135) + self.colEmph = QColor(200,120, 0) + self.colDialN = QColor(200, 46, 0) + self.colDialD = QColor(184,200, 0) + self.colDialS = QColor(136,200, 0) + self.colComm = QColor(150,150,150) + self.colKey = QColor(200, 46, 0) + self.colVal = QColor(184,200, 0) - self.colSpell = QColor(200,46,0) + self.colSpell = QColor(200, 46, 0) self.hStyles = { "header1" : self._makeFormat(self.colHead, "bold",1.8), @@ -155,12 +155,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): theFormat = QTextCharFormat() if fmtCol is not None: - theCol = QColor() - if isinstance(fmtCol,str): - theCol.setNamedColor(fmtCol) - else: - theCol.setRgb(*fmtCol) - theFormat.setForeground(theCol) + theFormat.setForeground(fmtCol) if fmtStyle is not None: if "bold" in fmtStyle: