- _MessageDialog: all buttons get setAutoDefault(False); first rejecting
button gets setDefault(True) so Enter=No on question dialogs; falls back
to last button (OK) for single-button info/warning dialogs
- Strip UTF-8 BOM from history_dialog.py (ast.parse-safe, diff-clean)
- Merge duplicate `from cim_suite.core.ui.chrome import …` lines in da07 main_window
- Two new tests: question defaults to No, single-OK defaults to OK (839 pass)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reverts the six per-row setting_history_action call sites (DA-12 sensors,
limits, station; DA-07 devices, channels, station) back to the default
"Setting history…" label so right-click context menus are concise and
accurate. The two main_window._open_setting_history call sites that use
the breadcrumb only for the dialog window title are left untouched.
Six test assertions reverted to match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Migrates all 12 dialog classes (+ 1 inline dialog) from QDialog to
ChromeDialog; top-level layouts re-parented to self.body; window titles
updated to breadcrumb form (Brand / Tool). Setting-history action titles
at every call site updated to breadcrumb form; 6 test assertions tracking
those labels updated to match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the eight import-time snapshot dicts (Color.*, SEVERITY, STALENESS, CHART)
with call-time current().severity/.staleness/.chart lookups and qcolor() conversion
across loading_overlay, group_band_delegate, serial_edit_dialog, traffic_tab,
alarm_tab, channels_tab (da07), sensors_tab, and history_dialog (da12). Delete the
legacy Color, Type, SEVERITY, STALENESS, CHART exports from tokens.py and their
re-export line in theme/__init__.py. Update two test files to use current() and
qcolor() for reference color values; add autouse _restore_theme_state fixture to
root conftest so theme state never bleeds between tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The visual spec (token tables, type styles, component rules, Qt notes),
the approved mockup HTML (visual reference only - the spec takes
precedence), and the brainstormed six-phase rollout design covering
foundation/theming, frameless chrome, the core component kit, and
per-module adoption (DA-12, DA-07, IOModbus, launcher).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The shared TableTab fit columns to contents exactly once, on the first
non-empty repaint. DA-12 sensors stream in one at a time, so that fit
often saw only row 0 and the Serial column clipped every wider serial
below it. The Station "Description of Setting" column had a parallel
bug: it was fit before mark_cell_help prepended the marker, leaving it
a marker too narrow. Both also lost a few px to Qt's tight size hint.
Replace the one-shot _sized guard with: re-fit on row-set size change
(not on value ticks, so live numbers don't jiggle), re-fit a help cell's
column after the marker is added, add headroom so the last glyph never
clips, and record user-dragged columns so auto-fit leaves them alone.
Fixes apply to every TableTab grid in DA-12 and DA-07.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Commit docs/samples/icon.png so make_icon.py can regenerate the committed
icon.ico / app_icon.png from source.
- build.ps1 split CIM_SIGN_PARAMS on '|' not ' ', so a cert subject name with
spaces (e.g. /n|CIMTechniques, Inc.) reaches signtool intact when signing is
enabled. Doc example updated to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copies READ-ME-FIRST.txt to the dist root so it sits beside the exe in the zip
and at {app} root after install. Degrades gracefully to portable-only when Inno
Setup is absent. Signing of inner exe + installer is gated on CIM_SIGN_CERT.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
READ-ME-FIRST.txt as a PyInstaller data file lands in _internal\ (sys._MEIPASS),
where users never see it; build.ps1 will copy it to the dist root instead. Also
exclude PIL — it is a build-time-only dep (make_icon.py), not shipped runtime.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A real DA-12 sends station-setting labels with parenthetical hints and
slightly different wording than our curated keys (e.g. "Subnet bits
(0=class A B C)", "Acquire sensors (0=off, 1=on)", "Station's mac
address"). Matching keyed off normalize_label (whitespace+case only), so
help text, subnet editing, and the reboot prompt silently missed on real
hardware while passing in the simulator -- whose seed labels were copied
from our keys, not from the device.
- Add core.ui.help.setting_match_key: strips the trailing parenthetical
hint before normalizing, so a verbose wire label matches its short key.
Used by station_tab (help + subnet) and reboot_settings.
- Seed the simulator with the EXACT labels a real DA-12 sends (captured
in docs/samples screenshots), closing the test gap that hid this. Adds
the 7 settings the capture revealed we weren't modeling.
- Fix repo_snapshot MAC lookup ("Station's mac address", not "MAC
Addr") -- station_mac() returned None on real hardware, so the settings
repository recorded nothing.
- Re-key STATION_SETTINGS to the real labels; fix Battery (run-time hrs,
not capacity %); promote Local port / Local IP / Gateway out of the
parked DA-06-tainted list using the verified docs/da12c_status.py
reference. Firmware-internal fields stay help-less by design.
783 tests pass; ruff clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>