diff --git a/src/ui/editors/basicHighlighter.py b/src/ui/editors/basicHighlighter.py index c08225b4..eb5f313b 100644 --- a/src/ui/editors/basicHighlighter.py +++ b/src/ui/editors/basicHighlighter.py @@ -51,13 +51,16 @@ class basicHighlighter(QSyntaxHighlighter): When subclassing basicHighlighter, you must call highlightBlockAfter after your custom highlighting. """ - #print("Highlighting") + + # References for txt in re.finditer(r"::(\w):(\d+?)::", text): fmt = self.format(txt.start()) + fmt.setFontFixedPitch(True) + fmt.setFontWeight(QFont.DemiBold) if txt.group(1) == "T": fmt.setBackground(QBrush(QColor(Qt.blue).lighter(190))) elif txt.group(1) == "C": - fmt.setBackground(QBrush(QColor(Qt.yellow).lighter(190))) + fmt.setBackground(QBrush(QColor(Qt.yellow).lighter(170))) self.setFormat(txt.start(), txt.end() - txt.start(), fmt) diff --git a/src/ui/editors/completer.py b/src/ui/editors/completer.py index 1af45f43..2f0ced90 100644 --- a/src/ui/editors/completer.py +++ b/src/ui/editors/completer.py @@ -15,8 +15,10 @@ class completer(QWidget, Ui_completer): QWidget.__init__(self, parent) self.setupUi(self) self.setWindowFlags(Qt.Popup) - self.text.textEdited.connect(self.updateListFromData) + self.text.textChanged.connect(self.updateListFromData) self.text.returnPressed.connect(self.submit) + self.listDelegate = listCompleterDelegate(self) + self.list.setItemDelegate(self.listDelegate) self.list.itemActivated.connect(self.submit) self.outlineModel = mainWindow().mdlOutline @@ -27,7 +29,8 @@ class completer(QWidget, Ui_completer): self.populate() self.hide() - def popup(self): + def popup(self, completion=""): + self.text.setText(completion) self.text.setFocus(Qt.PopupFocusReason) self.show() @@ -44,7 +47,7 @@ class completer(QWidget, Ui_completer): def addChildren(item): for c in item.children(): - d.append((c.title(), c.ID())) + d.append((c.title(), c.ID(), c.path())) addChildren(c) r = self.outlineModel.rootItem @@ -58,7 +61,9 @@ class completer(QWidget, Ui_completer): for r in range(self.persoModel.rowCount()): name = self.persoModel.item(r, Perso.name.value).text() ID = self.persoModel.item(r, Perso.ID.value).text() - d.append((name, ID)) + imp = self.persoModel.item(r, Perso.importance.value).text() + imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)] + d.append((name, ID, imp)) self.data[(self.tr("Characters"), "C")] = d @@ -67,11 +72,14 @@ class completer(QWidget, Ui_completer): def updateListFromData(self): self.list.clear() for cat in self.data: - self.addCategory(cat[0]) - for item in [i for i in self.data[cat] if self.text.text().lower() in i[0].lower()]: - i = QListWidgetItem(item[0]) - i.setData(Qt.UserRole, "::{}:{}::".format(cat[1], item[1])) - self.list.addItem(i) + filtered = [i for i in self.data[cat] if self.text.text().lower() in i[0].lower()] + if filtered: + self.addCategory(cat[0]) + for item in filtered: + i = QListWidgetItem(item[0]) + i.setData(Qt.UserRole, "::{}:{}::".format(cat[1], item[1])) + i.setData(Qt.UserRole+1, item[2]) + self.list.addItem(i) self.list.setCurrentRow(1) self.text.setFocus(Qt.PopupFocusReason) @@ -85,4 +93,31 @@ class completer(QWidget, Ui_completer): if event.key() in [Qt.Key_Up, Qt.Key_Down]: self.list.keyPressEvent(event) else: - QWidget.keyPressEvent(self, event) \ No newline at end of file + QWidget.keyPressEvent(self, event) + + +class listCompleterDelegate(QStyledItemDelegate): + def __init__(self, parent=None): + QStyledItemDelegate.__init__(self, parent) + + def paint(self, painter, option, index): + extra = index.data(Qt.UserRole+1) + if not extra: + return QStyledItemDelegate.paint(self, painter, option, index) + + else: + if option.state & QStyle.State_Selected: + painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) + + title = index.data() + extra = " - {}".format(extra) + painter.drawText(option.rect, Qt.AlignLeft, title) + + fm = QFontMetrics(option.font) + w = fm.width(title) + r = QRect(option.rect) + r.setLeft(r.left() + w) + painter.save() + painter.setPen(Qt.gray) + painter.drawText(r, Qt.AlignLeft, extra) + painter.restore() \ No newline at end of file diff --git a/src/ui/views/textEditCompleter.py b/src/ui/views/textEditCompleter.py index d86ac4b9..bcc9e551 100644 --- a/src/ui/views/textEditCompleter.py +++ b/src/ui/views/textEditCompleter.py @@ -37,9 +37,11 @@ class textEditCompleter(textEditView): tc.insertText(txt) self.setTextCursor(tc) - def textUnderCursor(self): + def textUnderCursor(self, select=False): tc = self.textCursor() tc.select(QTextCursor.WordUnderCursor) + if select: + self.setTextCursor(tc) return tc.selectedText() def refUnderCursor(self, cursor): @@ -63,6 +65,16 @@ class textEditCompleter(textEditView): return True return textEditView.event(self, event) + def createStandardContextMenu(self): + menu = textEditView.createStandardContextMenu(self) + + a = QAction(self.tr("Insert reference"), menu) + a.triggered.connect(self.popupCompleter) + menu.insertSeparator(menu.actions()[0]) + menu.insertAction(menu.actions()[0], a) + + return menu + def keyPressEvent(self, event): if self.completer.isVisible(): if event.key() in ( @@ -77,97 +89,21 @@ class textEditCompleter(textEditView): isShortcut = (event.modifiers() == Qt.ControlModifier and\ event.key() == Qt.Key_Space) - print(isShortcut) - if not self.completer or not isShortcut: self.completer.setVisible(False) textEditView.keyPressEvent(self, event) return - - completionPrefix = self.textUnderCursor() - cr = self.cursorRect() - cr.moveTopLeft(self.mapToGlobal(cr.bottomLeft())) - cr.setWidth(self.completer.sizeHint().width()) - self.completer.setGeometry(cr) - self.completer.popup() + self.popupCompleter() + + def popupCompleter(self): + if self.completer: + cr = self.cursorRect() + cr.moveTopLeft(self.mapToGlobal(cr.bottomLeft())) + cr.setWidth(self.completer.sizeHint().width()) + self.completer.setGeometry(cr) + self.completer.popup(self.textUnderCursor(select=True)) + - def keyPressEvent_(self, event): - if self.completer and self.completer.popup() and self.completer.popup().isVisible(): - if event.key() in ( - Qt.Key_Enter, - Qt.Key_Return, - Qt.Key_Escape, - Qt.Key_Tab, - Qt.Key_Backtab): - event.ignore() - return - ## has ctrl-Space been pressed?? - isShortcut = (event.modifiers() == Qt.ControlModifier and\ - event.key() == Qt.Key_Space) - ## modifier to complete suggestion inline ctrl-e - inline = (event.modifiers() == Qt.ControlModifier and \ - event.key() == Qt.Key_E) - ## if inline completion has been chosen - if inline: - # set completion mode as inline - self.completer.setCompletionMode(QCompleter.InlineCompletion) - completionPrefix = self.textUnderCursor() - if (completionPrefix != self.completer.completionPrefix()): - self.completer.setCompletionPrefix(completionPrefix) - self.completer.complete() -# self.completer.setCurrentRow(0) -# self.completer.activated.emit(self.completer.currentCompletion()) - # set the current suggestion in the text box - self.completer.activated.emit(self.completer.currentCompletion()) - # reset the completion mode - self.completer.setCompletionMode(QCompleter.PopupCompletion) - return - if (not self.completer or not isShortcut): - pass - QTextEdit.keyPressEvent(self, event) - # debug - print("After controlspace") - print("isShortcut is: {}".format(isShortcut)) - # debug over - ## ctrl or shift key on it's own?? - #ctrlOrShift = event.modifiers() in (Qt.ControlModifier ,\ - #Qt.ShiftModifier) - #if ctrlOrShift and event.text()== '': -## ctrl or shift key on it's own - #return - # debug - print("After on its own") - print("isShortcut is: {}".format(isShortcut)) - # debug over -# eow = QString("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=") #end of word -# eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=" #end of word - eow = "~!@#$%^&*+{}|:\"<>?,./;'[]\\-=" #end of word - - #hasModifier = ((event.modifiers() != Qt.NoModifier) and\ - #not ctrlOrShift) - - completionPrefix = self.textUnderCursor() -# print('event . text = {}'.format(event.text().right(1))) -# if (not isShortcut and (hasModifier or event.text()=='' or\ -# len(completionPrefix) < 3 or \ -# eow.contains(event.text().right(1)))): - if not isShortcut : - if self.completer.popup(): - self.completer.popup().hide() - return - print("complPref: {}".format(completionPrefix)) - print("completer.complPref: {}".format(self.completer.completionPrefix())) - print("mode: {}".format(self.completer.completionMode())) - # if (completionPrefix != self.completer.completionPrefix()): - print("Poping up") - 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! \ No newline at end of file diff --git a/src/ui/views/textEditView.py b/src/ui/views/textEditView.py index 7dfd32a5..e9f0e41a 100644 --- a/src/ui/views/textEditView.py +++ b/src/ui/views/textEditView.py @@ -390,20 +390,27 @@ class textEditView(QTextEdit): if not self.spellcheck: QTextEdit.contextMenuEvent(self, event) return - + popup_menu = self.createStandardContextMenu() - + popup_menu.exec_(event.globalPos()) + + def createStandardContextMenu(self): + popup_menu = QTextEdit.createStandardContextMenu(self) + + if not self.spellcheck: + return popup_menu + # Select the word under the cursor. cursor = self.textCursor() + #cursor = self.cursorForPosition(pos) cursor.select(QTextCursor.WordUnderCursor) self.setTextCursor(cursor) - # Check if the selected word is misspelled and offer spelling # suggestions if it is. - if self.textCursor().hasSelection(): - text = str(self.textCursor().selectedText()) + if cursor.hasSelection(): + text = str(cursor.selectedText()) if not self._dict.check(text): - spell_menu = QMenu(self.tr('Spelling Suggestions')) + spell_menu = QMenu(self.tr('Spelling Suggestions'), self) for word in self._dict.suggest(text): action = self.SpellAction(word, spell_menu) action.correct.connect(self.correctWord) @@ -413,9 +420,9 @@ class textEditView(QTextEdit): if len(spell_menu.actions()) != 0: popup_menu.insertSeparator(popup_menu.actions()[0]) popup_menu.insertMenu(popup_menu.actions()[0], spell_menu) - - popup_menu.exec_(event.globalPos()) - + + return popup_menu + def correctWord(self, word): ''' Replaces the selected text with word.