Context
Part of #2679 (umbrella PersistentDialog migrations). Reference implementation: PR #2742 (migrated ProfileImportExportDialog).
Important context the umbrella issue didn't capture: `TxBandDialog` is not currently a standalone class — it's a 119-line inline-constructed `QDialog` inside `MainWindow.cpp` starting at line 6548. This sub-issue requires an extra extract-to-class step before the PersistentDialog migration can apply.
This is why the umbrella ordered this one second — slightly more work than `PropDashboardDialog` (#2767), still simpler than `RadioSetupDialog`.
What to do — two-phase change
Phase A — Extract the inline construction
- Create `src/gui/TxBandDialog.{cpp,h}` — a real class.
- Copy the 119-line inline construction at `MainWindow.cpp:6548` (after `m_txBandDialog = dlg;`) into the new `TxBandDialog` constructor.
- Constructor signature should accept whatever data the inline construction needed (probably `RadioModel*` plus the current TX-profile string, based on the existing setup).
- Wire signals between MainWindow and the new TxBandDialog class as needed.
- `MainWindow.h` — change `QPointer m_txBandDialog;` at line 496 to `QPointer m_txBandDialog;`.
- `MainWindow.cpp` — replace the inline construction block with a `showOrRaisePersistent(m_txBandDialog, ...)` call.
Phase B — Inherit from PersistentDialog
Apply the same recipe as PR #2742:
- New `TxBandDialog` class inherits `: public PersistentDialog`.
- Constructor `: PersistentDialog("TX Band Settings", "TxBandDialogGeometry", parent)`.
- Build content into `bodyWidget()` instead of a hand-rolled body widget.
- Drop the manual `FramelessWindowTitleBar` + `FramelessResizer` setup — base class provides them.
- `closeEvent` forwards to `PersistentDialog::closeEvent` if overridden at all.
- `MainWindow.cpp` — remove the `setDialogFramelessMode(m_txBandDialog, on)` branch at line 11632-11633 from `setFramelessWindow()` — base class propagates via `m_persistentDialogs` registry.
AppSettings geometry key
Use `TxBandDialogGeometry` (PascalCase).
Acceptance criteria
Risk
- Extract step is the load-bearing change. Test thoroughly that TX Band Settings opens, edits propagate to the radio, and closes save state.
- 119 lines of UI code needs careful translation — preserve the FlexLib bandset semantics (`transmit bandset {BandId} ...` commands, `interlock bandset {BandId} ...` commands).
Pickup
AetherClaude-eligible but more substantial than #2767 — extra extract step. Ship as one PR (extract + migrate together) since the extract isn't useful in isolation.
73, Jeremy KK7GWY & Claude (AI dev partner)
Context
Part of #2679 (umbrella PersistentDialog migrations). Reference implementation: PR #2742 (migrated ProfileImportExportDialog).
Important context the umbrella issue didn't capture: `TxBandDialog` is not currently a standalone class — it's a 119-line inline-constructed `QDialog` inside `MainWindow.cpp` starting at line 6548. This sub-issue requires an extra extract-to-class step before the PersistentDialog migration can apply.
This is why the umbrella ordered this one second — slightly more work than `PropDashboardDialog` (#2767), still simpler than `RadioSetupDialog`.
What to do — two-phase change
Phase A — Extract the inline construction
Phase B — Inherit from PersistentDialog
Apply the same recipe as PR #2742:
AppSettings geometry key
Use `TxBandDialogGeometry` (PascalCase).
Acceptance criteria
Risk
Pickup
AetherClaude-eligible but more substantial than #2767 — extra extract step. Ship as one PR (extract + migrate together) since the extract isn't useful in isolation.
73, Jeremy KK7GWY & Claude (AI dev partner)