mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-09-29 08:51:14 +13:00
Tweaking completer
This commit is contained in:
parent
e41446c3e1
commit
a3d4bc1b1d
4 changed files with 89 additions and 108 deletions
|
@ -51,13 +51,16 @@ class basicHighlighter(QSyntaxHighlighter):
|
||||||
When subclassing basicHighlighter, you must call highlightBlockAfter
|
When subclassing basicHighlighter, you must call highlightBlockAfter
|
||||||
after your custom highlighting.
|
after your custom highlighting.
|
||||||
"""
|
"""
|
||||||
#print("Highlighting")
|
|
||||||
|
# References
|
||||||
for txt in re.finditer(r"::(\w):(\d+?)::", text):
|
for txt in re.finditer(r"::(\w):(\d+?)::", text):
|
||||||
fmt = self.format(txt.start())
|
fmt = self.format(txt.start())
|
||||||
|
fmt.setFontFixedPitch(True)
|
||||||
|
fmt.setFontWeight(QFont.DemiBold)
|
||||||
if txt.group(1) == "T":
|
if txt.group(1) == "T":
|
||||||
fmt.setBackground(QBrush(QColor(Qt.blue).lighter(190)))
|
fmt.setBackground(QBrush(QColor(Qt.blue).lighter(190)))
|
||||||
elif txt.group(1) == "C":
|
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(),
|
self.setFormat(txt.start(),
|
||||||
txt.end() - txt.start(),
|
txt.end() - txt.start(),
|
||||||
fmt)
|
fmt)
|
||||||
|
|
|
@ -15,8 +15,10 @@ class completer(QWidget, Ui_completer):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.setWindowFlags(Qt.Popup)
|
self.setWindowFlags(Qt.Popup)
|
||||||
self.text.textEdited.connect(self.updateListFromData)
|
self.text.textChanged.connect(self.updateListFromData)
|
||||||
self.text.returnPressed.connect(self.submit)
|
self.text.returnPressed.connect(self.submit)
|
||||||
|
self.listDelegate = listCompleterDelegate(self)
|
||||||
|
self.list.setItemDelegate(self.listDelegate)
|
||||||
self.list.itemActivated.connect(self.submit)
|
self.list.itemActivated.connect(self.submit)
|
||||||
|
|
||||||
self.outlineModel = mainWindow().mdlOutline
|
self.outlineModel = mainWindow().mdlOutline
|
||||||
|
@ -27,7 +29,8 @@ class completer(QWidget, Ui_completer):
|
||||||
self.populate()
|
self.populate()
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
def popup(self):
|
def popup(self, completion=""):
|
||||||
|
self.text.setText(completion)
|
||||||
self.text.setFocus(Qt.PopupFocusReason)
|
self.text.setFocus(Qt.PopupFocusReason)
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
|
@ -44,7 +47,7 @@ class completer(QWidget, Ui_completer):
|
||||||
|
|
||||||
def addChildren(item):
|
def addChildren(item):
|
||||||
for c in item.children():
|
for c in item.children():
|
||||||
d.append((c.title(), c.ID()))
|
d.append((c.title(), c.ID(), c.path()))
|
||||||
addChildren(c)
|
addChildren(c)
|
||||||
|
|
||||||
r = self.outlineModel.rootItem
|
r = self.outlineModel.rootItem
|
||||||
|
@ -58,7 +61,9 @@ class completer(QWidget, Ui_completer):
|
||||||
for r in range(self.persoModel.rowCount()):
|
for r in range(self.persoModel.rowCount()):
|
||||||
name = self.persoModel.item(r, Perso.name.value).text()
|
name = self.persoModel.item(r, Perso.name.value).text()
|
||||||
ID = self.persoModel.item(r, Perso.ID.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
|
self.data[(self.tr("Characters"), "C")] = d
|
||||||
|
|
||||||
|
@ -67,10 +72,13 @@ class completer(QWidget, Ui_completer):
|
||||||
def updateListFromData(self):
|
def updateListFromData(self):
|
||||||
self.list.clear()
|
self.list.clear()
|
||||||
for cat in self.data:
|
for cat in self.data:
|
||||||
|
filtered = [i for i in self.data[cat] if self.text.text().lower() in i[0].lower()]
|
||||||
|
if filtered:
|
||||||
self.addCategory(cat[0])
|
self.addCategory(cat[0])
|
||||||
for item in [i for i in self.data[cat] if self.text.text().lower() in i[0].lower()]:
|
for item in filtered:
|
||||||
i = QListWidgetItem(item[0])
|
i = QListWidgetItem(item[0])
|
||||||
i.setData(Qt.UserRole, "::{}:{}::".format(cat[1], item[1]))
|
i.setData(Qt.UserRole, "::{}:{}::".format(cat[1], item[1]))
|
||||||
|
i.setData(Qt.UserRole+1, item[2])
|
||||||
self.list.addItem(i)
|
self.list.addItem(i)
|
||||||
|
|
||||||
self.list.setCurrentRow(1)
|
self.list.setCurrentRow(1)
|
||||||
|
@ -86,3 +94,30 @@ class completer(QWidget, Ui_completer):
|
||||||
self.list.keyPressEvent(event)
|
self.list.keyPressEvent(event)
|
||||||
else:
|
else:
|
||||||
QWidget.keyPressEvent(self, event)
|
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()
|
|
@ -37,9 +37,11 @@ class textEditCompleter(textEditView):
|
||||||
tc.insertText(txt)
|
tc.insertText(txt)
|
||||||
self.setTextCursor(tc)
|
self.setTextCursor(tc)
|
||||||
|
|
||||||
def textUnderCursor(self):
|
def textUnderCursor(self, select=False):
|
||||||
tc = self.textCursor()
|
tc = self.textCursor()
|
||||||
tc.select(QTextCursor.WordUnderCursor)
|
tc.select(QTextCursor.WordUnderCursor)
|
||||||
|
if select:
|
||||||
|
self.setTextCursor(tc)
|
||||||
return tc.selectedText()
|
return tc.selectedText()
|
||||||
|
|
||||||
def refUnderCursor(self, cursor):
|
def refUnderCursor(self, cursor):
|
||||||
|
@ -63,6 +65,16 @@ class textEditCompleter(textEditView):
|
||||||
return True
|
return True
|
||||||
return textEditView.event(self, event)
|
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):
|
def keyPressEvent(self, event):
|
||||||
if self.completer.isVisible():
|
if self.completer.isVisible():
|
||||||
if event.key() in (
|
if event.key() in (
|
||||||
|
@ -77,97 +89,21 @@ class textEditCompleter(textEditView):
|
||||||
isShortcut = (event.modifiers() == Qt.ControlModifier and\
|
isShortcut = (event.modifiers() == Qt.ControlModifier and\
|
||||||
event.key() == Qt.Key_Space)
|
event.key() == Qt.Key_Space)
|
||||||
|
|
||||||
print(isShortcut)
|
|
||||||
|
|
||||||
if not self.completer or not isShortcut:
|
if not self.completer or not isShortcut:
|
||||||
self.completer.setVisible(False)
|
self.completer.setVisible(False)
|
||||||
textEditView.keyPressEvent(self, event)
|
textEditView.keyPressEvent(self, event)
|
||||||
return
|
return
|
||||||
|
|
||||||
completionPrefix = self.textUnderCursor()
|
self.popupCompleter()
|
||||||
|
|
||||||
|
def popupCompleter(self):
|
||||||
|
if self.completer:
|
||||||
cr = self.cursorRect()
|
cr = self.cursorRect()
|
||||||
cr.moveTopLeft(self.mapToGlobal(cr.bottomLeft()))
|
cr.moveTopLeft(self.mapToGlobal(cr.bottomLeft()))
|
||||||
cr.setWidth(self.completer.sizeHint().width())
|
cr.setWidth(self.completer.sizeHint().width())
|
||||||
self.completer.setGeometry(cr)
|
self.completer.setGeometry(cr)
|
||||||
self.completer.popup()
|
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!
|
|
||||||
|
|
||||||
|
|
|
@ -392,18 +392,25 @@ class textEditView(QTextEdit):
|
||||||
return
|
return
|
||||||
|
|
||||||
popup_menu = self.createStandardContextMenu()
|
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.
|
# Select the word under the cursor.
|
||||||
cursor = self.textCursor()
|
cursor = self.textCursor()
|
||||||
|
#cursor = self.cursorForPosition(pos)
|
||||||
cursor.select(QTextCursor.WordUnderCursor)
|
cursor.select(QTextCursor.WordUnderCursor)
|
||||||
self.setTextCursor(cursor)
|
self.setTextCursor(cursor)
|
||||||
|
|
||||||
# Check if the selected word is misspelled and offer spelling
|
# Check if the selected word is misspelled and offer spelling
|
||||||
# suggestions if it is.
|
# suggestions if it is.
|
||||||
if self.textCursor().hasSelection():
|
if cursor.hasSelection():
|
||||||
text = str(self.textCursor().selectedText())
|
text = str(cursor.selectedText())
|
||||||
if not self._dict.check(text):
|
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):
|
for word in self._dict.suggest(text):
|
||||||
action = self.SpellAction(word, spell_menu)
|
action = self.SpellAction(word, spell_menu)
|
||||||
action.correct.connect(self.correctWord)
|
action.correct.connect(self.correctWord)
|
||||||
|
@ -414,7 +421,7 @@ class textEditView(QTextEdit):
|
||||||
popup_menu.insertSeparator(popup_menu.actions()[0])
|
popup_menu.insertSeparator(popup_menu.actions()[0])
|
||||||
popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)
|
popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)
|
||||||
|
|
||||||
popup_menu.exec_(event.globalPos())
|
return popup_menu
|
||||||
|
|
||||||
def correctWord(self, word):
|
def correctWord(self, word):
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Reference in a new issue