aboutsummaryrefslogtreecommitdiffstats
path: root/scudcloud-1.1/lib/speller.py
diff options
context:
space:
mode:
Diffstat (limited to 'scudcloud-1.1/lib/speller.py')
-rw-r--r--scudcloud-1.1/lib/speller.py90
1 files changed, 90 insertions, 0 deletions
diff --git a/scudcloud-1.1/lib/speller.py b/scudcloud-1.1/lib/speller.py
new file mode 100644
index 0000000..e60967c
--- /dev/null
+++ b/scudcloud-1.1/lib/speller.py
@@ -0,0 +1,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(str(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();