Refactor tableview out of MainWindow

This commit is contained in:
Christopher T. Johnson
2025-02-14 12:11:34 -05:00
parent 5bbe1ebeca
commit 760cd72612
2 changed files with 172 additions and 79 deletions

View File

@@ -1,10 +1,11 @@
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 typing import Any, Self, cast
from PySide6.QtCore import QDate, QEvent, QModelIndex, QObject, QPersistentModelIndex, QPoint, QRect, QSize, Signal, Qt, Slot
from PySide6.QtGui import QColor, QFont, QPainter, QTextDocument, QTextDocumentFragment
from PySide6.QtSql import QSqlTableModel
from PySide6.QtWidgets import QAbstractItemView, QHeaderView, QMainWindow, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QWidget
from PySide6.QtWidgets import QAbstractItemView, QHeaderView, QMainWindow, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QTableView, QWidget
from docketModel import docketModel
from dockettableview import documentDelegate
from ui.MainWindow import Ui_MainWindow
from workers import loadCases, updateThread
@@ -12,6 +13,7 @@ class QStyleOptionViewItemInit(QStyleOptionViewItem):
backgroundBrush: QColor
rect: QRect
widget: QWidget
font: QFont
text: str
class dateDelegate(QStyledItemDelegate):
@@ -47,69 +49,6 @@ class activeDelegate(QStyledItemDelegate):
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)
@@ -119,12 +58,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self) -> None:
super(MainWindow, self).__init__()
self.setupUi(self)
self.loadThread = loadCases()
self.loadThread.finished.connect(self.updateDone)
self.loadThread.start()
#self.loadThread = loadCases()
#self.loadThread.finished.connect(self.updateDone)
#self.loadThread.start()
model = QSqlTableModel()
model.setTable("cases")
model.sort(1, Qt.SortOrder.AscendingOrder)
model.select()
model.setHeaderData(1, Qt.Orientation.Horizontal, "Docket")
model.setHeaderData(2, Qt.Orientation.Horizontal, "Petitioners")
@@ -141,7 +81,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.casesView.setItemDelegate(activeDelegate())
self.casesView.setItemDelegateForColumn(4, dateDelegate())
self.casesView.resizeColumnToContents(1)
self.casesView.resizeColumnToContents(5)
self.casesView.resizeColumnToContents(4)
header = self.casesView.horizontalHeader()
header.setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed)
header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed)
@@ -149,7 +89,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
remaining = (
self.casesView.width()
- header.sectionSize(1)
- header.sectionSize(5)
- header.sectionSize(4)
- 5
)
self.casesView.setColumnWidth(2, int(remaining * 0.5))
@@ -159,12 +99,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.casesView.doubleClicked.connect(self.rowClicked)
self.casesView.clicked.connect(self.rowClicked)
self.docketView.clickedEvent.connect(self.clickedEvent)
self.docketView.setModel(docketModel())
self.docketView.horizontalHeader().setSectionResizeMode(
1, QHeaderView.ResizeMode.Stretch
)
self.docketView.resizeRowsToContents()
self.docketView.setItemDelegateForColumn(1, documentDelegate())
#self.docketView.setItemDelegateForColumn(1, documentDelegate())
return
@Slot(QModelIndex) # type: ignore
@@ -174,8 +115,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
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)
model = cast(docketModel, self.docketView.model())
model.newCase(index.siblingAtColumn(0).data())
self.docketView.resizeColumnToContents(0)
self.docketView.resizeRowsToContents()
return
@@ -194,11 +135,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
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()}")
@Slot()
def clickedEvent(self, pos:QPoint) -> None:
print(pos)
viewport = self.docketView.viewport()
print(viewport,viewport.children())
return
@Slot()
def updateDone(self) -> None:
self.updateThread = None

151
dockettableview.py Normal file
View File

@@ -0,0 +1,151 @@
from typing import cast
from PySide6.QtCore import QAbstractItemModel, QDir, QEvent, QFile, QModelIndex, QObject, QPersistentModelIndex, QPoint, QRect, QSize, QUrl, Signal, Qt, Slot
from PySide6.QtGui import QColor, QFont, QMouseEvent, QPainter, QPalette, QShowEvent, QTextDocument
from PySide6.QtWidgets import QApplication, QSizePolicy, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QTableView, QTextEdit, QWidget
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
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 = 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