1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
import os
from resources import Resources
from PyQt4 import QtGui
from PyQt4.QtCore import QObject
from PyQt4.QtCore import QLocale, QFile, QTextBoundaryFinder
# Checking if python-hunspell is present
try:
import hunspell
except ImportError:
class hunspell:
HunSpell = None
# Simplified version of QupZilla Speller (https://github.com/QupZilla/qupzilla/blob/v1.8/src/lib/plugins/qtwebkit/spellcheck/speller.cpp)
class Speller(QObject):
hunspell = None
initialized = False
startPos = 0
def __init__(self):
super(Speller, self).__init__()
if self.initialized or hunspell.HunSpell is None:
return
dictionaryPath = self.getDictionaryPath()
language = self.parseLanguage(dictionaryPath)
if not dictionaryPath or language is None:
return
self.hunspell = hunspell.HunSpell(dictionaryPath + ".dic", dictionaryPath + ".aff")
self.initialized = True
def isMisspelled(self, s):
return not self.hunspell.spell(s)
def suggest(self, s):
return self.hunspell.suggest(s)
def parseLanguage(self, path):
if '/' in path:
pos = path.rfind('/')
return path[-int(pos + 1):]
return path
def dictionaryExists(self, path):
return QFile(path + ".dic").exists() and QFile(path + ".aff").exists();
def getDictionaryPath(self):
dicPath = Resources.SPELL_DICT_PATH + QLocale.system().name()
if self.dictionaryExists(dicPath):
return dicPath
return ''
def replaceWord(self, element, word):
action = self.sender()
new = action.data()
text = str(element.evaluateJavaScript("this.value"))
cursorPos = int(element.evaluateJavaScript("this.selectionStart"))
text = text[:self.startPos] + new + text[self.startPos+len(word):]
text = text.replace('\\', "\\\\")
text = text.replace('\n', "\\n")
text = text.replace('\'', "\\'")
element.evaluateJavaScript("this.value='{}'".format(text))
element.evaluateJavaScript("this.selectionStart=this.selectionEnd={}".format(cursorPos))
def getWord(self, element):
text = str(element.evaluateJavaScript("this.value"))
pos = int(int(element.evaluateJavaScript("this.selectionStart")) + int(1))
finder = QTextBoundaryFinder(QTextBoundaryFinder.Word, text)
finder.setPosition(pos)
self.startPos = finder.toPreviousBoundary()
return text[self.startPos:finder.toNextBoundary()].strip()
def populateContextMenu(self, menu, element):
word = self.getWord(element)
if self.isMisspelled(word):
suggests = self.suggest(word)
count = Resources.SPELL_LIMIT
if len(suggests) < count:
count = len(suggests)
boldFont = menu.font()
boldFont.setBold(True)
for i in range(0, count):
action = QtGui.QAction(suggests[i], self)
action.triggered.connect(lambda:self.replaceWord(element, word))
action.setData(suggests[i])
action.setFont(boldFont)
menu.addAction(action)
if count == 0:
menu.addAction(menu.tr("No suggestions")).setEnabled(False)
menu.addSeparator();
|