Files
scotus-watch/dockettableview.py
Christopher T. Johnson 71b0a6a112 Lint
2025-02-27 13:44:45 -05:00

165 lines
4.7 KiB
Python

from typing import cast
from PySide6.QtCore import (
QDir,
QFile,
QModelIndex,
QPersistentModelIndex,
QPoint,
QPointF,
QRect,
QSize,
Qt,
QUrl,
Signal,
Slot,
)
from PySide6.QtGui import (
QMouseEvent,
QPainter,
QTextDocument,
)
from PySide6.QtNetwork import (
QNetworkAccessManager,
QNetworkReply,
QNetworkRequest,
)
from PySide6.QtWidgets import (
QAbstractItemView,
QStyle,
QStyledItemDelegate,
QStyleOptionViewItem,
QTableView,
QTextEdit,
QWidget,
)
from lib.utils import QStyleOptionViewItemInit
from pdfView import PDFViewer
class docketEntryDelegate(QStyledItemDelegate):
def __init__(
self, view: QAbstractItemView, parent: QWidget | None = None
) -> None:
super(docketEntryDelegate, self).__init__(parent)
self.view = view
return
def sizeHint(
self,
option: QStyleOptionViewItem,
index: QModelIndex | QPersistentModelIndex,
) -> QSize:
options = cast(QStyleOptionViewItemInit, option)
self.initStyleOption(options, index)
doc = QTextDocument()
doc.setHtml(options.text)
doc.setTextWidth(options.rect.width())
return QSize(int(doc.idealWidth()), int(doc.size().height()))
def paint(
self,
painter: QPainter,
option: QStyleOptionViewItem,
index: QModelIndex | QPersistentModelIndex,
) -> None:
options = cast(QStyleOptionViewItemInit, option)
self.initStyleOption(options, index)
painter.save()
doc = QTextDocument()
doc.setHtml(options.text)
doc.setTextWidth(options.rect.width())
options.text = ""
options.widget.style().drawControl(
QStyle.ControlElement.CE_ItemViewItem, options, painter
)
painter.translate(options.rect.left(), options.rect.top())
clip = QRect(0, 0, options.rect.width(), options.rect.height())
doc.drawContents(painter, clip)
painter.restore()
return
class docketTableView(QTableView):
manager: QNetworkAccessManager
clickedEvent = Signal(QPoint)
anchorSignal = Signal(QModelIndex, str)
pdf: PDFViewer
def __init__(self, parent: QWidget | None = None) -> None:
super(docketTableView, self).__init__(parent)
self.setItemDelegateForColumn(1, docketEntryDelegate(self))
self.anchorSignal.connect(self.doAnchor)
self.manager = QNetworkAccessManager()
self.manager.finished.connect(self.getDone)
return
@Slot(QNetworkReply) # type: ignore
def getDone(self, reply: QNetworkReply) -> None:
dest = QFile("." + reply.url().path())
dest.open(QFile.OpenModeFlag.WriteOnly)
dest.write(reply.readAll())
dest.close()
reply.deleteLater()
self.pdf.open(dest)
self.pdf.show()
return
@Slot(QModelIndex, str) # type: ignore
def doAnchor(self, _: QModelIndex, anchor: str) -> None:
url = QUrl(anchor)
dirs = url.path().split("/")
dirs.pop()
dirs.pop(0)
currentDir = QDir()
path = "/".join(dirs)
currentDir.mkpath(path)
print(f"Checking for .{url.path()} existance.")
if not hasattr(self, "pdf"):
self.pdf = PDFViewer(self)
if QFile("." + url.path()).exists():
self.pdf.open(QFile("." + url.path()))
self.pdf.show()
else:
print(f"Fetching {url}")
self.manager.get(QNetworkRequest(url))
return
def mousePressEvent(self, event: QMouseEvent) -> None:
#
# The mouse has been pressed somewere in our rect. We need to translate that to a click
# within the cell with the document. This will allow the document to find anchors.
#
index = self.indexAt(event.pos())
if not index.isValid():
return
if index.column() != 1:
return
doc = QTextDocument()
doc.setHtml(index.data(Qt.ItemDataRole.DisplayRole))
doc.setTextWidth(self.columnWidth(index.column()))
#
# We need to map our click position to a position within the cell.
#
pos = event.position()
new_pos = QPointF(
pos.x() - self.horizontalScrollBar().value(),
pos.y() - self.verticalScrollBar().value(),
)
rowHeight = 0
for row in range(0, index.row()):
rowHeight += self.rowHeight(row)
cell_pos = QPointF(
new_pos.x() - self.columnWidth(0), new_pos.y() - rowHeight
)
te = QTextEdit()
te.setDocument(doc)
anchor = te.anchorAt(cell_pos.toPoint())
if anchor:
self.anchorSignal.emit(index, anchor)
return