Files
scotus-watch/dockettableview.py
2025-02-20 10:12:58 -05:00

140 lines
4.2 KiB
Python

from typing import cast
from PySide6.QtCore import (
QAbstractItemModel,
QDir,
QFile,
QModelIndex,
QObject,
QPersistentModelIndex,
QPoint,
QSize,
Qt,
QUrl,
Signal,
Slot,
)
from PySide6.QtGui import (
QMouseEvent,
QPalette,
QTextDocument,
)
from PySide6.QtNetwork import (
QNetworkAccessManager,
QNetworkReply,
QNetworkRequest,
)
from PySide6.QtWidgets import (
QAbstractItemView,
QSizePolicy,
QStyledItemDelegate,
QStyleOptionViewItem,
QTableView,
QTextEdit,
QWidget,
)
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, _: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex) -> QSize:
widget = self.view.indexWidget(index)
return widget.sizeHint()
class docketEntry(QTextEdit):
def __init__(self, parent: QWidget|None = None) -> None:
super(docketEntry, self).__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Preferred ,
QSizePolicy.Policy.Fixed)
return
def mousePressEvent(self, e: QMouseEvent) -> None:
super().mousePressEvent(e)
anchor = self.anchorAt(e.pos())
if anchor:
obj = cast(QObject, self)
while not isinstance(obj, docketTableView) and obj is not None:
obj = obj.parent()
assert obj is not None
index = obj.indexAt(obj.mapFromGlobal(self.mapToGlobal(e.pos())))
obj.anchorSignal.emit(index, anchor)
return
def sizeHint(self) -> QSize:
size = self.size()
doc = QTextDocument()
doc.setPlainText(self.document().toPlainText())
doc.setTextWidth(size.width())
docSize = doc.size()
return QSize(size.width(), int(docSize.height()))
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
def setModel(self, model: QAbstractItemModel | None) -> None:
assert model is not None
super().setModel(model)
self.model().modelReset.connect(self.modelReset)
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 modelReset(self) -> None:
model = self.model()
red = QPalette()
red.setColor(QPalette.ColorRole.Base, Qt.GlobalColor.red)
for row in range(0, model.rowCount()):
index = model.index(row, 1)
widget = docketEntry()
widget.setHtml(model.data(index, Qt.ItemDataRole.DisplayRole))
widget.setAutoFillBackground(False)
widget.setReadOnly(True)
widget.setPalette(red)
self.setIndexWidget(index, widget)
return