extras: pylint fixes
[git-cola.git] / cola / widgets / spellcheck.py
blobf44e0b8487d20c72aadb892bc6aa58a484d26dd0
1 from __future__ import absolute_import, division, print_function, unicode_literals
2 import re
4 from qtpy.QtCore import Qt
5 from qtpy.QtCore import QEvent
6 from qtpy.QtCore import Signal
7 from qtpy.QtGui import QMouseEvent
8 from qtpy.QtGui import QSyntaxHighlighter
9 from qtpy.QtGui import QTextCharFormat
10 from qtpy.QtGui import QTextCursor
11 from qtpy.QtWidgets import QAction
13 from .. import qtutils
14 from .. import spellcheck
15 from ..i18n import N_
16 from .text import HintedTextEdit
19 # pylint: disable=too-many-ancestors
20 class SpellCheckTextEdit(HintedTextEdit):
21 def __init__(self, context, hint, parent=None):
22 HintedTextEdit.__init__(self, context, hint, parent)
24 # Default dictionary based on the current locale.
25 self.spellcheck = spellcheck.NorvigSpellCheck()
26 self.highlighter = Highlighter(self.document(), self.spellcheck)
28 def set_dictionary(self, dictionary):
29 self.spellcheck.set_dictionary(dictionary)
31 def mousePressEvent(self, event):
32 if event.button() == Qt.RightButton:
33 # Rewrite the mouse event to a left button event so the cursor is
34 # moved to the location of the pointer.
35 event = QMouseEvent(
36 QEvent.MouseButtonPress,
37 event.pos(),
38 Qt.LeftButton,
39 Qt.LeftButton,
40 Qt.NoModifier,
42 HintedTextEdit.mousePressEvent(self, event)
44 def context_menu(self):
45 popup_menu = HintedTextEdit.createStandardContextMenu(self)
47 # Select the word under the cursor.
48 cursor = self.textCursor()
49 cursor.select(QTextCursor.WordUnderCursor)
50 self.setTextCursor(cursor)
52 # Check if the selected word is misspelled and offer spelling
53 # suggestions if it is.
54 spell_menu = None
55 if self.textCursor().hasSelection():
56 text = self.textCursor().selectedText()
57 if not self.spellcheck.check(text):
58 title = N_('Spelling Suggestions')
59 spell_menu = qtutils.create_menu(title, self)
60 for word in self.spellcheck.suggest(text):
61 action = SpellAction(word, spell_menu)
62 action.result.connect(self.correct)
63 spell_menu.addAction(action)
64 # Only add the spelling suggests to the menu if there are
65 # suggestions.
66 if spell_menu.actions():
67 popup_menu.addSeparator()
68 popup_menu.addMenu(spell_menu)
70 return popup_menu, spell_menu
72 def contextMenuEvent(self, event):
73 popup_menu, _ = self.context_menu()
74 popup_menu.exec_(self.mapToGlobal(event.pos()))
76 def correct(self, word):
77 """Replaces the selected text with word."""
78 cursor = self.textCursor()
79 cursor.beginEditBlock()
81 cursor.removeSelectedText()
82 cursor.insertText(word)
84 cursor.endEditBlock()
87 class Highlighter(QSyntaxHighlighter):
89 WORDS = r"(?iu)[\w']+"
91 def __init__(self, doc, spellcheck_widget):
92 QSyntaxHighlighter.__init__(self, doc)
93 self.spellcheck = spellcheck_widget
94 self.enabled = False
96 def enable(self, enabled):
97 self.enabled = enabled
98 self.rehighlight()
100 def highlightBlock(self, text):
101 if not self.enabled:
102 return
103 fmt = QTextCharFormat()
104 fmt.setUnderlineColor(Qt.red)
105 fmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
107 for word_object in re.finditer(self.WORDS, text):
108 if not self.spellcheck.check(word_object.group()):
109 self.setFormat(
110 word_object.start(), word_object.end() - word_object.start(), fmt
114 class SpellAction(QAction):
115 """QAction that returns the text in a signal."""
117 result = Signal(object)
119 def __init__(self, *args):
120 QAction.__init__(self, *args)
121 # pylint: disable=no-member
122 self.triggered.connect(self.correct)
124 def correct(self):
125 self.result.emit(self.text())