summaryrefslogtreecommitdiff
path: root/ui/namespace_panel.py
diff options
context:
space:
mode:
Diffstat (limited to 'ui/namespace_panel.py')
-rw-r--r--ui/namespace_panel.py48
1 files changed, 35 insertions, 13 deletions
diff --git a/ui/namespace_panel.py b/ui/namespace_panel.py
index 7d8c42d..44750c6 100644
--- a/ui/namespace_panel.py
+++ b/ui/namespace_panel.py
@@ -28,10 +28,11 @@ from core.signal_processor import SignalProcessor
_VARS_POLL_MS = 400
_C_KIND = 0
-_C_NAME = 1
-_C_DIR = 2
-_C_VALUE = 3
-_C_SOURCE = 4
+_C_ID = 1
+_C_NAME = 2
+_C_DIR = 3
+_C_VALUE = 4
+_C_SOURCE = 5
def _fmt_value(v) -> str:
@@ -42,6 +43,16 @@ def _fmt_value(v) -> str:
return str(v)
+def _fmt_ref(dev_id: str, ch_id: str) -> str:
+ """Absolute reference for a source — device_id/channel_id for a Signal
+ (device_id is stable across machines even when the COM/tty port isn't,
+ see ProfileManager.apply()'s port re-detection), or the bare channel_id
+ for another Channel (derived channels have no device to qualify with)."""
+ if dev_id == "derived":
+ return ch_id
+ return f"{dev_id}/{ch_id}"
+
+
class NamespacePanel(QWidget):
def __init__(self, registry: DeviceRegistry, processor: SignalProcessor):
super().__init__()
@@ -73,13 +84,14 @@ class NamespacePanel(QWidget):
self._table = QTableWidget()
self._table.setObjectName("channelTable")
- self._table.setColumnCount(5)
+ self._table.setColumnCount(6)
self._table.setHorizontalHeaderLabels(
- ["Kind", "Name", "Dir", "Value", "Source"]
+ ["Kind", "ID", "Name", "Dir", "Value", "Source"]
)
hdr = self._table.horizontalHeader()
hdr.setSectionResizeMode(_C_SOURCE, QHeaderView.ResizeMode.Stretch)
hdr.setSectionResizeMode(_C_KIND, QHeaderView.ResizeMode.ResizeToContents)
+ hdr.setSectionResizeMode(_C_ID, QHeaderView.ResizeMode.ResizeToContents)
hdr.setSectionResizeMode(_C_NAME, QHeaderView.ResizeMode.ResizeToContents)
hdr.setSectionResizeMode(_C_DIR, QHeaderView.ResizeMode.ResizeToContents)
hdr.setSectionResizeMode(_C_VALUE, QHeaderView.ResizeMode.ResizeToContents)
@@ -122,23 +134,33 @@ class NamespacePanel(QWidget):
ch = dev.get_channel(ch_id) if dev else None
name = ch.name if ch else ch_id
is_wr = bool(ch and ch.writable)
- self._set_row(row, "Signal", name, "WRITE" if is_wr else "READ",
- None, f"{dev_id}/{ch_id}")
+ self._set_row(row, "Signal", ch_id, name, "WRITE" if is_wr else "READ",
+ None, _fmt_ref(dev_id, ch_id))
elif kind == "channel":
_, channel_id = key
dc = next((d for d in self.processor.get_derived()
if d.channel_id == channel_id), None)
name = dc.name if dc else channel_id
- src = dc.kind if dc else ""
- self._set_row(row, "Channel", name, "READ", None, src)
+ if dc and dc.sources:
+ # Absolute reference(s) this Channel is chained from — same
+ # format as another row's ID column, so a chain (Channel 1 ->
+ # Channel 2 -> Channel 3) can be traced by eye: Channel 3's
+ # Source literally matches Channel 2's ID.
+ src = ", ".join(_fmt_ref(d, c) for d, c in dc.sources)
+ else:
+ src = dc.kind if dc else ""
+ self._set_row(row, "Channel", channel_id, name, "READ", None, src)
else: # var
_, name = key
val = self.processor.get_var(name, None)
- self._set_row(row, "var", name, "R/W", val, "shared (vars)")
+ self._set_row(row, "var", name, name, "R/W", val, "shared (vars)")
- def _set_row(self, row: int, kind: str, name: str, direction: str,
- value, source: str):
+ def _set_row(self, row: int, kind: str, id_ref: str, name: str,
+ direction: str, value, source: str):
self._table.setItem(row, _C_KIND, QTableWidgetItem(kind))
+ id_item = QTableWidgetItem(id_ref)
+ id_item.setForeground(QColor("#94a3b8"))
+ self._table.setItem(row, _C_ID, id_item)
self._table.setItem(row, _C_NAME, QTableWidgetItem(name))
dir_item = QTableWidgetItem(direction)
dir_item.setForeground(_dir_color(direction))