Coverage for modules/org/openteacher/interfaces/qt/enterers/words/words : 48%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
|
#! /usr/bin/env python3 # -*- coding: utf-8 -*-
# Copyright 2011-2013, Marten de Vries # Copyright 2011, Cas Widdershoven # Copyright 2011, Milan Boers # # This file is part of OpenTeacher. # # OpenTeacher 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. # # OpenTeacher 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 OpenTeacher. If not, see <http://www.gnu.org/licenses/>.
global SpellingHighlighter, WordsTableView, WordsTableModel, EnterWidget
super().__init__(*args, **kwargs)
self._checkWord = checkWord self._splitWords = splitWords
if text.endswith(u"…"): #might not be the best tokenization, but better than #what enchant can do in this situation... if u" " in text: text = text.rsplit(u" ", 1)[0] else: text = u""
for word, pos in self._splitWords(text): if not self._checkWord(word): self.setFormat(pos, len(word), self._format)
"""A default delegate, with the difference that it installs an event filter for some non-default keys. The equals key and return key are, from the perspective of Qt, equal to the tab key. It also allows callers to access the current editor via the currentEditor property, and paints html when displaying.
Next to that, it offers spell checking. Set the 'checkQuestion' and 'checkAnswer' properties to a function that checks one word before using this class because of that.
""" event = QtGui.QKeyEvent( event.type(), QtCore.Qt.Key_Tab, event.modifiers(), event.text(), event.isAutoRepeat(), event.count() )
self.initStyleOption(option, index)
#set up document with syntax highlighting document = QtGui.QTextDocument()
check = lambda item: True split = lambda words: [] with contextlib.suppress(AttributeError): if index.column() == 0: check = self.checkQuestion split = self.splitQuestion elif index.column() == 1: check = self.checkAnswer split = self.splitAnswer SpellingHighlighter(check, split, document)
#get elided text text = option.widget.fontMetrics().elidedText(option.text, option.textElideMode, option.rect.width() - document.documentMargin()) #set elided text document.setHtml(text)
#calculate place to start rendering yPos = option.rect.center().y() - option.widget.fontMetrics().height() / 2 - document.documentMargin() startPoint = QtCore.QPoint(option.rect.x(), yPos)
#move to place to start rendering, render, and move back. painter.translate(startPoint) document.drawContents(painter) painter.translate(-startPoint)
parent, option, index )
else: checker = self._createChecker(lang) self.itemDelegate().checkQuestion = checker.check self.itemDelegate().splitQuestion = checker.split self._wholeModelChanged()
else: checker = self._createChecker(lang) self.itemDelegate().checkAnswer = checker.check self.itemDelegate().splitAnswer = checker.split self._wholeModelChanged()
self.model().dataChanged.emit( self.model().index(0, 0), self.model().index(self.model().rowCount() -1, self.model().columnCount() -1) )
#AttributeError: first time. self.model().questionLanguageChanged.disconnect(self._questionLanguageChanged) self.model().answerLanguageChanged.disconnect(self._answerLanguageChanged)
#setting the model is 'resetting' too.
#If the model is empty, let the user start editing #(model has always one starting row.)
"""Reimplentation of moveCursor that makes sure that tab only moves between the questions and answers column (so not the comment column). This way, inserting words is way faster.
""" if cursorAction not in (QtWidgets.QAbstractItemView.MoveNext, QtWidgets.QAbstractItemView.MovePrevious): return super().moveCursor(cursorAction, modifiers) if self.model().columnCount() == 0 or self.model().rowCount() == 0: return QtCore.QModelIndex()
row = self.currentIndex().row() column = self.currentIndex().column() if cursorAction == QtWidgets.QAbstractItemView.MoveNext: column += 1 if column > 1: column = 0 row += 1 if row > self.model().rowCount() -1: row = 0 elif cursorAction == QtWidgets.QAbstractItemView.MovePrevious: column -= 1 if column < 0: column = 1 row -= 1 if row < 0: row = self.model().rowCount() -1
return self.model().index(row, column)
items = self.lesson.list.get("items", []) if column == self.QUESTIONS: sortedItems = sorted(items, key=lambda word: word.get("questions", [])) elif column == self.ANSWERS: sortedItems = sorted(items, key=lambda word: word.get("answers", [])) elif column == self.COMMENT: sortedItems = sorted(items, key=lambda word: word.get("comment", u"")) elif column == self.COMMENT_AFTER_ANSWERING: sortedItems = sorted(items, key=lambda word: word.get("commentAfterAnswering", u""))
if order == QtCore.Qt.DescendingOrder: sortedItems.reverse()
self.layoutAboutToBeChanged.emit() self.indexes = [self.lesson.list["items"].index(item) for item in sortedItems] self.layoutChanged.emit()
self.lesson.list["title"] = title self.lesson.changed = True
self.lesson.list["questionLanguage"] = questionLanguage self.questionLanguageChanged.emit() self.lesson.changed = True
self.lesson.list["answerLanguage"] = answerLanguage self.answerLanguageChanged.emit() self.lesson.changed = True
role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole)): else: word = self.lesson.list["items"][listIndex]
if index.column() == self.QUESTIONS: return self._compose(word.get("questions", [])) elif index.column() == self.ANSWERS: return self._compose(word.get("answers", [])) elif index.column() == self.COMMENT: return word.get("comment", u"") elif index.column() == self.COMMENT_AFTER_ANSWERING: return word.get("commentAfterAnswering", u"")
QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable )
if not (index.isValid() and role == QtCore.Qt.EditRole): return False #add 'items' key to the list if not there already, since setData needs it. if "items" not in self.lesson.list: self.lesson.list["items"] = [] while True: #repeat because this does two things: #- add a row if needed #- enter the data in that row (and then break the loop) try: listIndex = self.indexes[index.row()] except IndexError: #insert row if not value: return False
word = {"created": datetime.datetime.now()} try: word["id"] = self.lesson.list["items"][-1]["id"] +1 except IndexError: word["id"] = 0 self.beginInsertRows( QtCore.QModelIndex(), self.rowCount(), self.rowCount() ) self.lesson.list["items"].append(word) self.indexes.append(self.lesson.list["items"].index(word)) self.endInsertRows() else: #set data word = self.lesson.list["items"][listIndex]
if index.column() == self.QUESTIONS: word["questions"] = self._parse(value) elif index.column() == self.ANSWERS: word["answers"] = self._parse(value) elif index.column() == self.COMMENT: word["comment"] = value.strip() if not len(word["comment"]): del word["comment"] elif index.column() == self.COMMENT_AFTER_ANSWERING: word["commentAfterAnswering"] = value.strip() if not len(word["commentAfterAnswering"]): del word["commentAfterAnswering"] break self.lesson.changed = True return True
listIndex = self.indexes[row] self.beginRemoveRows(parent, row, row) del self.indexes[row] #update self.indexes for i in range(len(self.indexes)): if self.indexes[i] > listIndex: self.indexes[i] -= 1 del self.lesson.list["items"][listIndex] self.lesson.changed = True self.endRemoveRows()
#Initialize all widgets
#Install the table model
def lesson(self): return self._wordsTableModel.lesson
while True: try: i = self._wordsTableView.selectedIndexes()[0] except IndexError: break try: self._wordsTableModel.removeRow(i.row()) except IndexError: #trying to remove the empty add row isn't going to work break
i = self._wordsTableView.currentIndex() if not i.isValid(): return
data = self._wordsTableModel.data(i) + letter self._wordsTableModel.setData(i, data) self._wordsTableView.edit(i) self._wordsTableView.itemDelegate().currentEditor.deselect()
self.removeSelectedRows )
self._wordsTableModel.updateTitle ) self._wordsTableModel.updateQuestionLanguage ) self._wordsTableModel.updateAnswerLanguage )
"default": 450, } self._mm.mods(type="translator"), self._mm.mods(type="spellChecker"), self._mm.mods(type="charsKeyboard"), ) self._mm.mods(type="ui"), self._mm.mods(type="wordsStringComposer"), self._mm.mods(type="wordsStringParser"), )
def _charsKeyboard(self): "active", type="charsKeyboard" ).createWidget() except IndexError: return
def _compose(self): "active", type="wordsStringComposer" ).compose
def _parse(self): "active", type="wordsStringParser" ).parse
def _createChecker(self): except IndexError: class Fallback: def __init__(self, *args, **kwargs): pass def check(self, item): #'everything is a well spelled word' return True def split(self, words): #'no words in there' return [] return Fallback
self._createChecker, self._charsKeyboard, self._compose, self._parse )
global QtCore, QtGui, QtWidgets except ImportError: return
else:
#Translations global _ global ngettext
else: self._mm.resourcePath("translations") )
|