SpecTreeModel
The tree of specs, sections and work units of the spec workspace.
| Inherits | QAbstractItemModel |
| Group | libtrove |
In the namespace octomy::trove::workspace. Declared in src/libs/libtrove/trove/workspace/SpecTreeModel.hpp.
Detailed description
The left pane of the spec workspace (trove-spec-workspace §SW-3): one row for each spec of the scope, its sections below it, and the work units below each section. The free-standing work units of the scope, the side quests of §DM-10, are one more group at the end, so nothing in the project's corpus is out of sight.
The "No project" group
A spec made before its project existed has an empty project, and the filter of the scope hides it on every board (trove-unified-ui §TUI-D-11, owner ruling Q9). When the tree shows one project, the last group, No project, lists every such spec as an ordinary spec row, with its sections. UnscopedRole marks those rows, so the workspace can offer "Move to this project". With "All projects", every spec shows at the top, and the group goes.
The Recurring group
Before the side quests, the group Recurring lists each spec whose switch is on and each spec that has runs (trove-recurring §TRC-D-10). Its rows are links: a row's key is the key of its spec, and it has no children, so the spec's own row stays the one place of its sections. A row with the switch off is dormant (DormantRole). Its status cell shows the trend of the first probe (TrendTextRole) and the trust badge (TrustedRole). SpecTreeSource::recurringSpecs() reads the group, and refresh() follows it as the runs write their samples.
Lazy, by Qt's own mechanism
The model is a QAbstractItemModel with canFetchMore() and fetchMore(), and a plain QTreeView shows it (trove-parts §TPK-1 rows 16 and 17). A reload reads the specs only. A spec lists its sections when the view expands it. A section loads one window of windowRows() work units when it expands, and the next window when the view scrolls to its end (QTreeView::verticalScrollbarValueChanged() in Qt). So a section of a million units loads one window when it opens. Each window is a keyset seek in the store, not an OFFSET scan.
Scope
The scope is a project UUID (§SW-2.2). It filters the specs by Spec::project and the side quests by WorkUnit::project. The units of a section show whatever their own project column says, because a spec owns its sections and their units. The "All projects" toggle, setAllProjects(), drops the filter, because visibility is not scoped (§SW-2).
Rollups
The status column of a spec, a section and the side quests shows a StatusRollup. The model reads it from the source on first use and keeps it until a unit below it changes (updateWorkUnit()) or the tree reloads.
See also SpecTreeSource, SpecAggregateModel, SpecWorkspace.