feat(swr): export SWR sweep data to CSV (#2241)#3882
Conversation
Add a "Save CSV" button to the SWR sweep controls in the spectrum overlay menu. After a sweep completes, the collected samples (frequency + SWR) and the band name already persist in m_swrSweep until an explicit clear or band change, so the export is available whenever a trace is on the panadapter. The button emits swrSweepSaveCsvRequested(); MainWindow::saveSwrSweepCsv() opens a save dialog pre-filled with swr_sweep_<band>_<YYYYMMDD>_<HHMMSS>.csv (defaulting to the Documents folder) and writes a "Frequency (Hz),SWR" header followed by one row per sample. Guards cover an in-progress sweep, an empty dataset, and a failed file open, each with a status-bar message. This is part 1 of aethersdr#2241 (CSV export); the resonance/bandwidth markers and user-bounded sweep range remain as separate follow-ups.
There was a problem hiding this comment.
Thanks for this, @M7HNF-Ian — nicely scoped and the error handling is genuinely solid. The three guards (in-progress sweep / empty dataset / failed open), the C-locale QString::number(..., 'f', 3) to avoid comma decimal separators breaking the CSV, and the filename sanitisation are all the right calls. Verified against MainWindow.h: every field referenced (m_swrSweep.running, .samples, .originalBandName, SwrSweepSample::freqMhz/swr) exists with matching types, <cmath> is already in the includes, and the signal→slot wiring is correct. All five files are within the stated CSV-export scope.
A couple of small, optional notes — none blocking:
-
llroundunqualified (MainWindow_SwrSweep.cpp):<cmath>only guaranteesstd::llround; the global-namespacellroundis technically provided by<cmath.h>/<math.h>. It compiles fine on libstdc++/libc++, butstd::llroundwould be the strictly-portable form and matches the codebase's usualstd::prefixing. -
Save button is always enabled: clicking it with no sweep data falls through to the friendly status-bar message, which is fine. If you'd like slightly tighter UX you could grey out
m_swrSaveBtnuntil a trace exists, but the guard handles it gracefully as-is. -
Last-used directory (future, not for this PR): the dialog always defaults to Documents. Remembering the last export location via
AppSettingswould be a nice follow-up, consistent with how the rest of the app persists paths.
The live FLEX-6600 test detail (18 points, dip ~14.31 MHz) is appreciated. Looks good to me.
🤖 aethersdr-agent · cost: $1.3793 · model: claude-opus-4-8
ten9876
left a comment
There was a problem hiding this comment.
Approved. Verified the implementation:
- Three guards (in-progress sweep / empty dataset / failed open), each with a clear status-bar or dialog message. Not a keying path — exports the already-captured
m_swrSweepand refuses mid-sweep (Principle VI N/A). - Filename sanitization is solid —
[^A-Za-z0-9_-]→_on the band label (falls back to "band"), and the final path is user-chosen viaQFileDialoganyway, so no traversal/injection concern. - CSV correctness — C-locale
QString::number(swr, 'f', 3)(no comma-decimal break), integer Hz viallround(MHz×1e6), header + one row/sample,WriteOnly|Text|Truncate. - Signal→slot wiring correct; all referenced fields exist.
One non-blocking nit: llround → std::llround for strict portability/convention (compiles fine on all three CI platforms as-is). Nice, well-scoped first contribution — thanks @M7HNF-Ian, and the live FLEX-6600 test detail is appreciated. CI green on all 6.
Implements the CSV-export portion of #2241.
Adds a Save CSV button to the SWR sweep controls in the spectrum overlay menu. After a sweep finishes, the samples (frequency + SWR) and band name already persist in
m_swrSweep, so the export is available whenever a trace is on the panadapter.swrSweepSaveCsvRequested()signal →MainWindow::saveSwrSweepCsv().swr_sweep_<band>_<YYYYMMDD>_<HHMMSS>.csv(defaults to Documents).Frequency (Hz),SWRheader followed by one row per sample.Tested live on a FLEX-6600: ran a 20 m sweep, exported, and confirmed the file opens correctly in a spreadsheet (18 points, resonant dip ~14.31 MHz).
Scope is deliberately limited to CSV export. The resonance/bandwidth markers and user-bounded sweep range remain as separate follow-ups.