Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5057316
feat(browser): add canonical read-only Signal Catalog for SCL and dis…
masarray Sep 27, 2026
833e1a4
build(qml): include canonical Signal Catalog in workbench module
masarray Sep 27, 2026
df22ef6
feat(browser): unify canonical DataSet catalog selection across Open …
masarray Sep 27, 2026
a546e14
feat(browser): expose Signal Catalog action and route DataSets throug…
masarray Sep 27, 2026
eb0329b
feat(browser): navigate canonical DataSets offline and route live sel…
masarray Sep 27, 2026
fbe879a
feat(browser): inspect ordered canonical DataSet signals offline or o…
masarray Sep 27, 2026
a2ebb68
fix(qml): normalize IEC reference FC suffix with proper regex escaping
masarray Sep 27, 2026
d7f5dca
test(browser): enrich rendered offline fixture with ordered static Da…
masarray Sep 27, 2026
55286a9
test(browser): expose rendered ordered DataSet member list for QA
masarray Sep 27, 2026
26979bb
test(browser): assert canonical offline DataSet projection and explic…
masarray Sep 27, 2026
918e3d9
test(browser): add R1A canonical Signal Catalog and safety contract
masarray Sep 27, 2026
0429bbc
test(browser): expose first rendered DataSet member text
masarray Sep 27, 2026
57c1658
test(browser): require rendered offline canonical DataSet member in f…
masarray Sep 27, 2026
2e66813
ci(browser): gate R1A catalog source contract and rendered offline Da…
masarray Sep 27, 2026
6456880
test(browser): verify normalized canonical reference lookup in DataSe…
masarray Sep 27, 2026
a389e94
fix(browser): normalize DataSet FC labels for explicit Global Data MM…
masarray Sep 27, 2026
2359103
fix(qml): bind nested DataSet member text explicitly from required de…
masarray Sep 27, 2026
7d7cc5e
test(browser): allow one render frame for virtualized ordered DataSet…
masarray Sep 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(browser): unify canonical DataSet catalog selection across Open …
…SCL and Discovery
  • Loading branch information
masarray committed Sep 27, 2026
commit df22ef6a8f18db773f3af450979554bc0bdd82fc
93 changes: 93 additions & 0 deletions apps/ied_simulator/qml/IedBrowserWorkspace.qml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,79 @@ Item {
property string activeSectionTitle: "Data Model"
property var selectedModelNode: context.treeModel.selectedNode

// Read-only canonical inventory is available even without an MMS association.
// A live directory may add verified membership and owned dynamic entries.
// Both Open SCL and Discovery use this same selected-reference path.
property string selectedCatalogReference: ""
property var lastPromptedCatalogGeneration: -1
readonly property var dataSetCatalog: {
var canonical = context.loaded ? context.dataSets : []
var live = reports.connected ? reports.dataSets : []
var result = []
for (var i = 0; i < canonical.length; ++i) {
var item = canonical[i]
var matching = null
for (var j = 0; j < live.length; ++j) {
if (live[j].reference === item.reference) {
matching = live[j]
break
}
}
result.push(matching && matching.directoryAvailable === true
? matching : item)
}
for (var k = 0; k < live.length; ++k) {
var exists = false
for (var n = 0; n < result.length; ++n) {
if (result[n].reference === live[k].reference) {
exists = true
break
}
}
if (!exists)
result.push(live[k])
}
return result
}
readonly property var selectedCatalogDataSet: {
for (var i = 0; i < dataSetCatalog.length; ++i) {
if (dataSetCatalog[i].reference === selectedCatalogReference)
return dataSetCatalog[i]
}
return dataSetCatalog.length ? dataSetCatalog[0] : null
}
readonly property string effectiveCatalogReference: selectedCatalogDataSet
? selectedCatalogDataSet.reference : ""

function chooseCatalogDataSet(reference) {
var found = false
for (var i = 0; i < dataSetCatalog.length; ++i) {
if (dataSetCatalog[i].reference === reference) {
found = true
break
}
}
if (!found)
return false
root.selectedCatalogReference = reference
// Selection only: do not connect, create, rebind or enable an RCB.
if (reports.connected) {
for (var j = 0; j < reports.dataSets.length; ++j) {
if (reports.dataSets[j].reference === reference) {
reports.selectDataSet(j)
break
}
}
}
root.selectSection(1, "DataSets")
return true
}

function openSignalCatalog() {
if (context.loaded && !context.selectionRequired)
signalCatalogDialog.open()
}

signal watchedDataChanged()

function watchedRows() { return globalDataPane.snapshotRows() }
Expand Down Expand Up @@ -72,6 +145,26 @@ Item {
function onWatchSnapshotChanged() { root.watchedDataChanged() }
}

Connections {
target: context
function onContextChanged() {
// A discovery (not a reconnect or an offline SCL open) surfaces
// its catalog once per canonical generation. Other IED tabs are
// not interrupted by a dialog belonging to an inactive slot.
if (!root.visible || !context.loaded
|| context.authorityKey !== "live-discovery"
|| context.dataSetCount <= 0
|| root.lastPromptedCatalogGeneration === context.contextGeneration)
return
root.lastPromptedCatalogGeneration = context.contextGeneration
Qt.callLater(function() {
if (root.visible && context.loaded
&& context.authorityKey === "live-discovery")
root.openSignalCatalog()
})
}
}

onActiveSectionChanged: ensureActiveService()

Shortcut { sequence: "Alt+1"; enabled: root.visible; onActivated: root.selectSection(0, "Data Model") }
Expand Down
Loading