Commit Graph

3 Commits

Author SHA1 Message Date
fdf86a2e17 Export: ODS meta block + header-row freeze/filter; flat CSV with aligned column names.
ODS sheets now carry a per-connection meta block (Connection / Transform
/ Left / Right) above the data; the header row anchors the freeze, the
auto-filter range, and the zebra striping. CSV stays a single flat
15-column table whose names match the ODS headers exactly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 18:21:50 +02:00
aa59d1a041 ODS writer: drop duplicate XML declaration; harden sheet-name sanitiser.
LibreOffice rejected the generated `.ods` with `Format error at 2,39
in content.xml`. Root cause: `pugi::format_no_declaration` suppresses
only the *implicit* declaration auto-added at save time — the explicit
`node_declaration` I had appended to the document still got serialised,
on top of a manual `<?xml…?>` string prepend in the output. Two
declarations back-to-back, invalid XML.

Fix: let pugixml emit the explicit declaration node, drop the manual
prepend.

Also harden the sheet-name sanitiser in the export action: ODS / Excel
also forbid `< > &` in raw cell or table names, so the default
connection name `bp/J20 <-> payload1/P0` made content.xml entity-
escape `<` to `&lt;`, which a few viewers handle but Excel rejects.
Clip to 31 chars too (Excel's hard limit) so multi-name connections
don't blow up the open.

Verified by `soffice --headless --convert-to csv` round-tripping the
output without errors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 12:22:51 +02:00
67de4dcaf3 Refactor: extract export commands; co-locate sigtype popup logic.
Two focused, behaviour-preserving moves:

1. `OpenSignalTypeDialog` + `ApplySignalTypeChoice` moved from
   `shell.cpp` to `screen_sigtype_modal.cpp` so the popup owns all of
   its logic instead of having its open/apply functions live in the
   shell file.

2. The `export` command extracted from `commands.cpp` to a new
   `commands_export.cpp` under a `Tui::RegisterExportCommands()`
   member. `RegisterCommands()` calls it at the end. File-local
   helpers (`csv_quote`, `pin_side`) move alongside in an anonymous
   namespace.

Establishes the pattern for future per-group splits: declare a
`Register<X>Commands()` member, define it in its own file, call it
from the orchestrator. Other groups stay in `commands.cpp` for now —
nothing else has grown large enough to warrant the split.

Sizes: shell.cpp 497 → 448, commands.cpp 846 → 675 (+ 191 for the
new commands_export.cpp). DESIGN.md updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 12:18:58 +02:00