from typing import Any, cast from PySide6.QtCore import QDate, QEvent, QModelIndex, QObject, QPersistentModelIndex, QRect, QSize, Signal, Qt, Slot from PySide6.QtGui import QColor, QPainter, QTextDocument from PySide6.QtSql import QSqlTableModel from PySide6.QtWidgets import QAbstractItemView, QHeaderView, QMainWindow, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QWidget from docketModel import docketModel from ui.MainWindow import Ui_MainWindow from workers import loadCases, updateThread class QStyleOptionViewItemInit(QStyleOptionViewItem): backgroundBrush: QColor rect: QRect widget: QWidget text: str class dateDelegate(QStyledItemDelegate): def displayText(self, value: QDate, _: Any) -> str: return value.toString("MMMM d, yyyy") def initStyleOption( self, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex, /, ) -> None: options = cast(QStyleOptionViewItemInit, option) super().initStyleOption(options, index) assert isinstance(index, QModelIndex) if index.siblingAtColumn(5).data() == 0: options.backgroundBrush = QColor(0x444444) return class activeDelegate(QStyledItemDelegate): def initStyleOption( self, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex, /, ) -> None: options = cast(QStyleOptionViewItemInit, option) super().initStyleOption(options, index) assert isinstance(index, QModelIndex) if index.siblingAtColumn(5).data() == 0: options.backgroundBrush = QColor(0x444444) return 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 eventFilter(self, object: QObject, event: QEvent) -> bool: if event.type() in [ QEvent.Type.MouseButtonPress, QEvent.Type.MouseButtonRelease, ]: return False return super().eventFilter(object, event) def event(self, ev: QEvent) -> bool: print(ev) return super(documentDelegate, self).event(ev) 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 MainWindow(QMainWindow, Ui_MainWindow): show_entries = Signal(int) loadThread = None def __init__(self) -> None: super(MainWindow, self).__init__() self.setupUi(self) self.loadThread = loadCases() self.loadThread.finished.connect(self.updateDone) self.loadThread.start() model = QSqlTableModel() model.setTable("cases") model.select() model.setHeaderData(1, Qt.Orientation.Horizontal, "Docket") model.setHeaderData(2, Qt.Orientation.Horizontal, "Petitioners") model.setHeaderData(3, Qt.Orientation.Horizontal, "Respondents") self.casesView.setModel(model) self.casesView.setSelectionMode( QAbstractItemView.SelectionMode.SingleSelection ) self.casesView.setSelectionBehavior( QAbstractItemView.SelectionBehavior.SelectRows ) self.casesView.hideColumn(0) self.casesView.setItemDelegate(activeDelegate()) self.casesView.setItemDelegateForColumn(4, dateDelegate()) self.casesView.resizeColumnToContents(1) self.casesView.resizeColumnToContents(5) header = self.casesView.horizontalHeader() header.setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed) header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) self.show() remaining = ( self.casesView.width() - header.sectionSize(1) - header.sectionSize(5) - 5 ) self.casesView.setColumnWidth(2, int(remaining * 0.5)) self.casesView.setColumnWidth(3, int(remaining * 0.5)) self.casesView.verticalHeader().hide() self.casesView.resizeRowsToContents() self.casesView.doubleClicked.connect(self.rowClicked) self.casesView.clicked.connect(self.rowClicked) self.docketView.setModel(docketModel()) self.docketView.horizontalHeader().setSectionResizeMode( 1, QHeaderView.ResizeMode.Stretch ) self.docketView.resizeRowsToContents() self.docketView.setItemDelegateForColumn(1, documentDelegate()) return @Slot(QModelIndex) # type: ignore def rowClicked(self, index: QModelIndex) -> None: if not index.isValid(): raise Exception("Bad index") docket = index.siblingAtColumn(1).data() self.docketLabel.setText(docket) self.show_entries.emit(index.siblingAtColumn(0).data()) model = docketModel(index.siblingAtColumn(0).data()) self.docketView.setModel(model) self.docketView.resizeColumnToContents(0) self.docketView.resizeRowsToContents() return updateThread = None @Slot() def on_updateButton_clicked(self) -> None: text = self.docketInput.toPlainText() print(f"on_updateButton_clicked(): {text}") if not self.updateThread: self.updateThread = updateThread() assert isinstance(self.updateThread, updateThread) self.updateThread.finished.connect(self.updateDone) self.updateThread.setDocketId(text) self.updateThread.start() return @Slot(QModelIndex) # type: ignore def on_docketView_clicked(self, index: QModelIndex) -> None: print(f"view clicked, cell: {index.column()}, {index.row()}") return @Slot() def updateDone(self) -> None: self.updateThread = None print("Done updating") model: QSqlTableModel = cast(QSqlTableModel, self.casesView.model()) query = model.query() query.exec() model.setQuery(query) return