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