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