From 3322d372f99b9ca678387930c0baab38cf09754c Mon Sep 17 00:00:00 2001 From: ZFordDev Date: Fri, 28 Aug 2026 04:38:50 +1000 Subject: [PATCH 1/2] fix: make Qt model defaults and class state explicit --- src/ui/pyqt/task_list.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ui/pyqt/task_list.py b/src/ui/pyqt/task_list.py index 903111a..f4a52cf 100644 --- a/src/ui/pyqt/task_list.py +++ b/src/ui/pyqt/task_list.py @@ -1,5 +1,7 @@ """Model-backed task table with search, filtering, and sorting.""" +from typing import ClassVar + from PyQt6.QtCore import ( QAbstractTableModel, QModelIndex, @@ -22,6 +24,8 @@ from logic import local_time from ui.pyqt.settings_dialog import FILTERS, SORT_FIELDS, UiPreferences +INVALID_MODEL_INDEX = QModelIndex() + class TaskTableModel(QAbstractTableModel): HEADERS = ("Date", "Time", "Task", "Status", "Created") @@ -34,10 +38,10 @@ def __init__( self.date_format = date_format self.time_format = time_format - def rowCount(self, parent=QModelIndex()): + def rowCount(self, parent=INVALID_MODEL_INDEX): return 0 if parent.isValid() else len(self.tasks) - def columnCount(self, parent=QModelIndex()): + def columnCount(self, parent=INVALID_MODEL_INDEX): return 0 if parent.isValid() else len(self.HEADERS) def data(self, index, role=Qt.ItemDataRole.DisplayRole): @@ -109,7 +113,13 @@ class TaskListWidget(QWidget): delete_requested = pyqtSignal(object) complete_requested = pyqtSignal(object) - SORT_COLUMNS = {"date": 0, "time": 1, "text": 2, "status": 3, "created": 4} + SORT_COLUMNS: ClassVar[dict[str, int]] = { + "date": 0, + "time": 1, + "text": 2, + "status": 3, + "created": 4, + } def __init__(self, scheduler, preferences: UiPreferences, parent=None): super().__init__(parent) From a83f2bc99230caff0bec5d875ac9640f714287f8 Mon Sep 17 00:00:00 2001 From: ZFordDev Date: Fri, 28 Aug 2026 04:38:50 +1000 Subject: [PATCH 2/2] test: cover Qt model root index behavior --- tests/test_pyqt_task_workspace.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/test_pyqt_task_workspace.py b/tests/test_pyqt_task_workspace.py index b89a6b2..98bc060 100644 --- a/tests/test_pyqt_task_workspace.py +++ b/tests/test_pyqt_task_workspace.py @@ -12,7 +12,7 @@ from ui.pyqt.add_dialog import AddTaskDialog, EditTaskDialog from ui.pyqt.calendar_view import CalendarWorkspace from ui.pyqt.settings_dialog import SettingsDialog, UiPreferences -from ui.pyqt.task_list import TaskListWidget +from ui.pyqt.task_list import TaskListWidget, TaskTableModel from ui.pyqt.window import SchedPlusWindow from updater.config import BuildInfo from updater.preferences import UpdatePreferences @@ -94,6 +94,18 @@ def test_task_workspace_filters_and_searches(app): assert "1 of 3" in widget.count_label.text() +def test_task_table_model_respects_root_and_child_indexes(app): + model = TaskTableModel([Task(date="2026-08-28", time="09:00", text="Plan")]) + + assert model.rowCount() == 1 + assert model.columnCount() == 5 + + child_index = model.index(0, 0) + assert child_index.isValid() + assert model.rowCount(child_index) == 0 + assert model.columnCount(child_index) == 0 + + def test_edit_dialog_is_prepopulated(app): task = Task(date="2026-08-12", time="09:05", text="Plan release")