from typing import Any, cast from PySide6.QtCore import ( QAbstractItemModel, QDir, QEvent, QFile, QModelIndex, QObject, QPersistentModelIndex, QPoint, QRect, QSize, Qt, QUrl, Signal, Slot, ) from PySide6.QtGui import ( QColor, QFont, QMouseEvent, QPainter, QPalette, QShowEvent, QTextDocument, ) from PySide6.QtNetwork import ( QNetworkAccessManager, QNetworkReply, QNetworkRequest, ) from PySide6.QtWidgets import ( QApplication, QSizePolicy, QStyle, QStyledItemDelegate, QStyleOptionViewItem, QTableView, QTextEdit, QWidget, ) from pdfView import PDFViewer class QStyleOptionViewItemInit(QStyleOptionViewItem): backgroundBrush: QColor rect: QRect widget: QWidget font: QFont text: str class documentDelegate(QStyledItemDelegate): def initStyleOption( self, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex, /, ) -> None: options = cast(QStyleOptionViewItemInit, option) super().initStyleOption(options, index) assert index.isValid() and isinstance(index, QModelIndex) if index.siblingAtColumn(6).data() == 0: options.backgroundBrush = QColor(0x444444) return def paint( self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex, ) -> None: options = cast(QStyleOptionViewItemInit, option) self.initStyleOption(options, index) painter.save() doc = QTextDocument() doc.setTextWidth(options.rect.width()) doc.setHtml(options.text) 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 def sizeHint( self, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex, ) -> QSize: options = cast(QStyleOptionViewItemInit, option) self.initStyleOption(options, index) doc = QTextDocument() doc.setTextWidth(options.rect.width()) doc.setHtml(options.text) doc.setTextWidth(options.rect.width()) return QSize(int(doc.idealWidth()), int(doc.size().height())) class docketEntry(QTextEdit): def mousePressEvent(self, e: QMouseEvent) -> None: super().mousePressEvent(e) anchor = self.anchorAt(e.pos()) print(f"self.size(): {self.size()}") if anchor: print(f"Anchors away: {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() print(f"size: {size}, docSize: {docSize}") return QSize(size.width(), int(docSize.height())) class docketTableView(QTableView): manager = QNetworkAccessManager() clickedEvent = Signal(QPoint) anchorSignal = Signal(QModelIndex, str) def __init__(self, parent: QWidget | None = None) -> None: super(docketTableView, self).__init__(parent) self.anchorSignal.connect(self.doAnchor) 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) print("Setting Model") 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 = PDFViewer(self) self.pdf.load_pdf(dest) self.pdf.show() return @Slot(QModelIndex, str) # type: ignore def doAnchor(self, index: QModelIndex, anchor: str) -> None: url = QUrl(anchor) print(f"{index.row()}, {index.column()} -> {url.path()}") dirs = url.path().split("/") dirs.pop() dirs.pop(0) currentDir = QDir() path = "/".join(dirs) currentDir.mkpath(path) if QDir("." + url.path()).exists(): file = QFile("." + url.path()) self.pdf = PDFViewer(self) self.pdf.load_pdf(file) self.pdf.show() else: 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