Source code for lib_openmolar.common.qt4.widgets.completer_textedit
#! /usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
## ##
## Copyright 2010, Neil Wallace <rowinggolfer@googlemail.com> ##
## ##
## This program is free software: you can redistribute it and/or modify ##
## it under the terms of the GNU General Public License as published by ##
## the Free Software Foundation, either version 3 of the License, or ##
## (at your option) any later version. ##
## ##
## This program is distributed in the hope that it will be useful, ##
## but WITHOUT ANY WARRANTY; without even the implied warranty of ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##
## GNU General Public License for more details. ##
## ##
## You should have received a copy of the GNU General Public License ##
## along with this program. If not, see <http://www.gnu.org/licenses/>. ##
## ##
###############################################################################
from PyQt4 import QtGui, QtCore
from lib_openmolar.common import SETTINGS
[docs]class DictionaryCompleter(QtGui.QCompleter):
[docs] def __init__(self, parent=None):
words = []
try:
f = open(SETTINGS.DICT_LOCATION, "r")
for word in f:
words.append(word.strip())
f.close()
except IOError:
print "dictionary not in anticipated location"
QtGui.QCompleter.__init__(self, words, parent)
[docs]class CompletionTextEdit(QtGui.QTextEdit):
[docs] def __init__(self, parent=None):
super(CompletionTextEdit, self).__init__(parent)
self.setMinimumWidth(400)
self.completer = None
self.setCompleter(DictionaryCompleter())
self.setTabChangesFocus(True)
[docs] def setCompleter(self, completer):
if self.completer:
self.disconnect(self.completer,
QtCore.SIGNAL("activated(const QString&)"),
self.insertCompletion)
if not completer:
return
completer.setWidget(self)
completer.setCompletionMode(QtGui.QCompleter.PopupCompletion)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer = completer
self.connect(self.completer,
QtCore.SIGNAL("activated(const QString&)"), self.insertCompletion)
[docs] def insertCompletion(self, completion):
tc = self.textCursor()
extra = (completion.length() -
self.completer.completionPrefix().length())
tc.movePosition(QtGui.QTextCursor.Left)
tc.movePosition(QtGui.QTextCursor.EndOfWord)
tc.insertText(completion.right(extra))
self.setTextCursor(tc)
[docs] def textUnderCursor(self):
tc = self.textCursor()
tc.select(QtGui.QTextCursor.WordUnderCursor)
return tc.selectedText()
[docs] def focusInEvent(self, event):
if self.completer:
self.completer.setWidget(self);
QtGui.QTextEdit.focusInEvent(self, event)
[docs] def keyPressEvent(self, event):
if self.completer and self.completer.popup().isVisible():
if event.key() in (
QtCore.Qt.Key_Enter,
QtCore.Qt.Key_Return,
QtCore.Qt.Key_Escape,
QtCore.Qt.Key_Tab,
QtCore.Qt.Key_Backtab):
event.ignore()
return
## has ctrl-E been pressed??
isShortcut = (event.modifiers() == QtCore.Qt.ControlModifier and
event.key() == QtCore.Qt.Key_E)
if (not self.completer or not isShortcut):
QtGui.QTextEdit.keyPressEvent(self, event)
## ctrl or shift key on it's own??
ctrlOrShift = event.modifiers() in (QtCore.Qt.ControlModifier ,
QtCore.Qt.ShiftModifier)
if ctrlOrShift and event.text().isEmpty():
# ctrl or shift key on it's own
return
eow = QtCore.QString("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=") #end of word
hasModifier = ((event.modifiers() != QtCore.Qt.NoModifier) and
not ctrlOrShift)
completionPrefix = self.textUnderCursor()
if (not isShortcut and (hasModifier or event.text().isEmpty() or
completionPrefix.length() < 3 or
eow.contains(event.text().right(1)))):
self.completer.popup().hide()
return
if (completionPrefix != self.completer.completionPrefix()):
self.completer.setCompletionPrefix(completionPrefix)
popup = self.completer.popup()
popup.setCurrentIndex(
self.completer.completionModel().index(0,0))
cr = self.cursorRect()
cr.setWidth(self.completer.popup().sizeHintForColumn(0)
+ self.completer.popup().verticalScrollBar().sizeHint().width())
self.completer.complete(cr) ## popup it up!
if __name__ == "__main__":
app = QtGui.QApplication([])
te = CompletionTextEdit()
te.show()
app.exec_()