Skip to content

feat(gui): Waveforms dialog under File menu for WFP status and management#2779

Merged
ten9876 merged 1 commit into
aethersdr:mainfrom
NF0T:pr/waveforms-dialog
May 17, 2026
Merged

feat(gui): Waveforms dialog under File menu for WFP status and management#2779
ten9876 merged 1 commit into
aethersdr:mainfrom
NF0T:pr/waveforms-dialog

Conversation

@NF0T

@NF0T NF0T commented May 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Surfaces the data already collected by FlexWaveformModel (merged in #2759) in a non-modal, geometry-persistent dialog at File → Waveforms, mirroring SmartSDR's layout and location.

  • WFP status bar at the top: power indicator (●), ready indicator (●), and IP address — all live-updating via FlexWaveformModel::wfpStatusChanged
  • Waveform list: one row per installed waveform or Docker container, with name, version, and type badge — live-updating via FlexWaveformModel::waveformsChanged
  • Restart button per row — fire-and-forget, no confirmation; sends waveform restart <name>
  • Remove (container) / Uninstall (legacy .wfp) button per row — QMessageBox::question confirmation before sending waveform remove_container <name> or waveform uninstall <name>
  • Install omitted intentionally — Docker containers are managed at the radio/firmware level, not from the client

Implementation

WaveformsDialog inherits PersistentDialog (geometry-persist + frameless-chrome handling) and takes a FlexWaveformModel* in its constructor. No refresh logic in MainWindow — the dialog wires FlexWaveformModel signals directly. showOrRaisePersistent handles lazy-construct, raise-if-open, and frameless toggle registration automatically.

Test plan

  • File → Waveforms opens dialog; re-triggering raises it rather than opening a second
  • WFP status shows correct power/ready state and IP address
  • freedv-flex (or other container) appears in the list with version and [Container] badge
  • Restart sends waveform restart freedv-flex — visible in radio log
  • Remove → cancel → no command sent; Remove → confirm → sends waveform remove_container freedv-flex
  • Disconnect from radio → list empties, status clears (driven by FlexWaveformModel::clear())
  • Frameless mode toggle applies correctly

🤖 Generated with Claude Code

…nagement

Surfaces the data already collected by FlexWaveformModel (PR aethersdr#2759) in a
non-modal, geometry-persistent dialog accessible via File → Waveforms.

The dialog shows the WFP power/ready/IP status bar at the top and a
scrollable list of installed waveforms and Docker containers. Each row has a
Restart button (fire-and-forget, no confirmation) and a Remove/Uninstall
button (asks for confirmation before sending the command). Mirrors the
SmartSDR File → Waveforms panel in location and function; Install is
intentionally omitted as Docker containers are managed at the radio level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NF0T NF0T requested review from jensenpat and ten9876 as code owners May 16, 2026 23:58

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, focused PR — thanks @NF0T! The dialog correctly uses PersistentDialog + showOrRaisePersistent, all model accessors and signals match FlexWaveformModel's API, and commandReady is already wired in RadioModel so the Restart/Remove/Uninstall buttons land on the radio. The disconnect path is handled because FlexWaveformModel::clear() emits both waveformsChanged and wfpStatusChanged.

A couple of small, optional polish suggestions — not blocking:

  1. Disable action buttons when WFP isn't ready. Right now Restart / Remove / Uninstall are always enabled, even when WFP is off or the radio is disconnected. The radio will just ignore the command, but greying them out (e.g. restartBtn->setEnabled(m_model->wfpPowered() && m_model->wfpReady()); inside refreshWaveformList(), and re-running it from refreshStatus() or hooking wfpStatusChanged to a single enabled-state update) would give clearer feedback that nothing's going to happen.

  2. Full rebuild on every waveformsChanged. refreshWaveformList() deleteLaters every row and rebuilds it whenever the model changes. That's fine for the common case (rare waveform mutations), but if a WFP eventually emits high-frequency status updates that get coalesced into waveformsChanged, you may want to diff-update instead. Not a problem today.

Nothing else to flag — looks good to me.

@ten9876 ten9876 merged commit 22017e4 into aethersdr:main May 17, 2026
5 checks passed
@ten9876

ten9876 commented May 17, 2026

Copy link
Copy Markdown
Collaborator

Claude here — landed at 01:44 UTC. Nine PRs today, Ryan. 🎉

Closing the loop from #2759 (protocol layer captures FlexLib v4.2.18 waveform status) to this PR (user can see and manage them) within hours is the right kind of arc — you built the data layer first, validated it ships clean, then built the UI consumer on top with no MainWindow refresh plumbing because the model emits the right targeted signals (`wfpStatusChanged`, `waveformsChanged`) and the dialog wires directly. Clean separation, easy to maintain.

The pattern choices were all the right ones:

  • `PersistentDialog` inheritance — geometry-persist + frameless-chrome propagation for free
  • `showOrRaisePersistent` — lazy-construct, raise-on-reopen, registry-based auto-toggle
  • Asymmetric confirmation — Restart fire-and-forget, Remove/Uninstall gated on `QMessageBox::question`
  • `setMenuRole(QAction::NoRole)` — pre-empting macOS application-menu remapping that would otherwise dump this under the wrong category

The "no install" decision was right — Docker container images live on the radio's internal registry; the client doesn't push them. Matches what SmartSDR does and avoids inventing a surface that conflicts with the radio-side container management.

Today's tally: #2745, #2747, #2752, #2754, #2759, #2771, #2773, #2776, #2779. Nine PRs, nine distinct concerns. Consistently excellent.

73, Jeremy KK7GWY & Claude (AI dev partner)

@NF0T NF0T deleted the pr/waveforms-dialog branch May 17, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants