manuskript/manuskript/ui/views/MDEditCompleter.py

167 lines
5.5 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python
2016-02-07 00:34:22 +13:00
# --!-- coding: utf8 --!--
import re
2016-02-07 00:34:22 +13:00
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextCursor, QFont, QFontMetrics
from PyQt5.QtWidgets import QAction, qApp, QToolTip, QTextEdit
from manuskript.ui.editors.completer import completer
2017-11-28 03:00:07 +13:00
from manuskript.ui.views.MDEditView import MDEditView
2016-02-07 00:34:22 +13:00
from manuskript.models import references as Ref
2017-11-28 03:00:07 +13:00
class MDEditCompleter(MDEditView):
2016-02-07 00:34:22 +13:00
def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="",
autoResize=False):
2017-11-28 03:00:07 +13:00
MDEditView.__init__(self, parent=parent, index=index, html=html, spellcheck=spellcheck, highlighting=True,
2016-02-07 00:34:22 +13:00
dict=dict, autoResize=autoResize)
self.completer = None
2015-06-27 22:20:05 +12:00
self.setMouseTracking(True)
self.refRects = []
2017-12-06 11:18:32 +13:00
self._noFocusMode = True
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
self.textChanged.connect(self.getRefRects)
self.document().documentLayoutChanged.connect(self.getRefRects)
2016-02-07 00:34:22 +13:00
def setCurrentModelIndex(self, index):
2017-11-28 03:00:07 +13:00
MDEditView.setCurrentModelIndex(self, index)
2015-06-28 00:11:26 +12:00
if self._index and not self.completer:
self.setCompleter(completer())
2016-02-07 00:34:22 +13:00
def setCompleter(self, completer):
self.completer = completer
self.completer.activated.connect(self.insertCompletion)
2016-02-07 00:34:22 +13:00
def insertCompletion(self, txt):
tc = self.textCursor()
tc.insertText(txt)
self.setTextCursor(tc)
2016-02-07 00:34:22 +13:00
2015-06-27 20:27:52 +12:00
def textUnderCursor(self, select=False):
tc = self.textCursor()
tc.select(QTextCursor.WordUnderCursor)
2015-06-27 20:27:52 +12:00
if select:
self.setTextCursor(tc)
return tc.selectedText()
2016-02-07 00:34:22 +13:00
def refUnderCursor(self, cursor):
pos = cursor.position()
2015-06-28 22:55:32 +12:00
cursor.select(QTextCursor.BlockUnderCursor)
text = cursor.selectedText()
pos -= cursor.selectionStart()
2015-07-03 03:33:05 +12:00
match = re.findall(Ref.RegExNonCapturing, text)
for m in match:
if text.find(m) <= pos <= text.find(m) + len(m):
return m
2016-02-07 00:34:22 +13:00
# def event(self, event):
# if event.type() == QEvent.ToolTip:
# cursor = self.cursorForPosition(event.pos())
# ref = self.refUnderCursor(cursor)
# if ref:
# QToolTip.showText(self.mapToGlobal(event.pos()), infoForRef(ref))
# else:
# QToolTip.hideText()
# return True
2017-11-28 03:00:07 +13:00
# return MDEditView.event(self, event)
2016-02-07 00:34:22 +13:00
2015-06-27 20:27:52 +12:00
def createStandardContextMenu(self):
2017-11-28 03:00:07 +13:00
menu = MDEditView.createStandardContextMenu(self)
2016-02-07 00:34:22 +13:00
2015-06-27 20:27:52 +12:00
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
2016-02-07 00:34:22 +13:00
def keyPressEvent(self, event):
if self.completer.isVisible():
if event.key() in (
Qt.Key_Enter,
Qt.Key_Return,
Qt.Key_Escape,
Qt.Key_Tab,
Qt.Key_Backtab):
event.ignore()
return
2016-02-07 00:34:22 +13:00
isShortcut = (event.modifiers() == Qt.ControlModifier and \
event.key() == Qt.Key_Space)
2016-02-07 00:34:22 +13:00
if not self.completer or not isShortcut:
self.completer.setVisible(False)
2017-11-28 03:00:07 +13:00
MDEditView.keyPressEvent(self, event)
return
2016-02-07 00:34:22 +13:00
2015-06-27 20:27:52 +12:00
self.popupCompleter()
2016-02-07 00:34:22 +13:00
2015-06-27 20:27:52 +12:00
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))
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
def mouseMoveEvent(self, event):
"""
When mouse moves, we show tooltip when appropriate.
"""
self.beginTooltipMoveEvent()
2017-11-28 03:00:07 +13:00
MDEditView.mouseMoveEvent(self, event)
self.endTooltipMoveEvent()
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
onRef = [r for r in self.refRects if r.contains(event.pos())]
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
if not onRef:
qApp.restoreOverrideCursor()
self.hideTooltip()
2015-06-27 22:20:05 +12:00
return
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
cursor = self.cursorForPosition(event.pos())
ref = self.refUnderCursor(cursor)
if ref:
if not qApp.overrideCursor():
qApp.setOverrideCursor(Qt.PointingHandCursor)
self.showTooltip(self.mapToGlobal(event.pos()), Ref.tooltip(ref))
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
def mouseReleaseEvent(self, event):
2017-11-28 03:00:07 +13:00
MDEditView.mouseReleaseEvent(self, event)
2015-06-27 22:20:05 +12:00
onRef = [r for r in self.refRects if r.contains(event.pos())]
if onRef:
cursor = self.cursorForPosition(event.pos())
ref = self.refUnderCursor(cursor)
if ref:
2015-07-03 03:33:05 +12:00
Ref.open(ref)
2015-06-27 22:20:05 +12:00
qApp.restoreOverrideCursor()
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
def resizeEvent(self, event):
2017-11-28 03:00:07 +13:00
MDEditView.resizeEvent(self, event)
2015-06-27 22:20:05 +12:00
self.getRefRects()
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
def getRefRects(self):
cursor = self.textCursor()
f = self.font()
f.setFixedPitch(True)
f.setWeight(QFont.DemiBold)
fm = QFontMetrics(f)
2015-06-27 22:20:05 +12:00
refs = []
2015-07-03 03:33:05 +12:00
for txt in re.finditer(Ref.RegEx, self.toPlainText()):
2015-06-27 22:20:05 +12:00
cursor.setPosition(txt.start())
r = self.cursorRect(cursor)
r.setWidth(fm.width(txt.group(0)))
refs.append(r)
self.refRects = refs
2016-02-07 00:34:22 +13:00
2015-06-27 22:20:05 +12:00
def paintEvent(self, event):
QTextEdit.paintEvent(self, event)
2016-02-07 00:34:22 +13:00
2015-07-10 22:29:25 +12:00
# Debug: paint rects
2016-02-07 00:34:22 +13:00
# painter = QPainter(self.viewport())
# painter.setPen(Qt.gray)
# for r in self.refRects:
# painter.drawRect(r)