Skip to content

feat(cpn): add detailed progress to read and write radio#7450

Merged
pfeerick merged 6 commits into
mainfrom
elecpower/add-detailed-status
Jun 30, 2026
Merged

feat(cpn): add detailed progress to read and write radio#7450
pfeerick merged 6 commits into
mainfrom
elecpower/add-detailed-status

Conversation

@elecpower

@elecpower elecpower commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Summary of changes:

  • since the move to yaml the radio read and write has not provided any indication of progress
  • the feature provides progress bar and message log

Summary by CodeRabbit

  • Bug Fixes

    • Image preview now clears correctly when no bitmap/model image is selected.
    • Improved and more consistent error messaging for SD card operations, image cache handling, and archive read/write failures.
  • Refactor

    • Enhanced progress reporting with smoother real-time updates during model/settings and firmware read/write to/from radio and SD card.
    • Simplified write flows and dialog behavior for models/settings, with clearer success/failure outcomes and more consistent status text.

@elecpower elecpower added enhancement ✨ New feature or request companion Related to the companion software labels Jun 10, 2026
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eb239b34-3fef-47c7-9104-6024b631328e

📥 Commits

Reviewing files that changed from the base of the PR and between 09f0517 and 0d16491.

📒 Files selected for processing (13)
  • companion/src/flash/radiointerface.cpp
  • companion/src/mainwindow.cpp
  • companion/src/mainwindow.h
  • companion/src/mdichild.cpp
  • companion/src/mdichild.h
  • companion/src/modeledit/setup.cpp
  • companion/src/progress/progresswidget.cpp
  • companion/src/progress/progresswidget.h
  • companion/src/storage/etx.cpp
  • companion/src/storage/labeled.cpp
  • companion/src/storage/sdcard.cpp
  • companion/src/storage/storage.cpp
  • companion/src/storage/storage.h
💤 Files with no reviewable changes (1)
  • companion/src/mainwindow.h
🚧 Files skipped from review as they are similar to previous changes (12)
  • companion/src/mdichild.h
  • companion/src/modeledit/setup.cpp
  • companion/src/storage/storage.cpp
  • companion/src/storage/sdcard.cpp
  • companion/src/flash/radiointerface.cpp
  • companion/src/storage/storage.h
  • companion/src/storage/etx.cpp
  • companion/src/mainwindow.cpp
  • companion/src/progress/progresswidget.h
  • companion/src/storage/labeled.cpp
  • companion/src/progress/progresswidget.cpp
  • companion/src/mdichild.cpp

📝 Walkthrough

Walkthrough

This PR wires progress reporting into storage formats, updates radio and SD-card read/write flows to use progress dialogs/widgets, and refactors related UI paths to the new progress-aware write and import methods.

Changes

Progress and Storage Integration

Layer / File(s) Summary
Storage progress infrastructure
companion/src/storage/storage.h, companion/src/storage/storage.cpp, companion/src/progress/progresswidget.h, companion/src/progress/progresswidget.cpp
StorageFormat gains _progress plus status/fatal/progress helpers, Storage attaches progress before load/write, and ProgressWidget adds logging-level filtering and event flushing during UI updates.
Storage file formats
companion/src/storage/etx.cpp, companion/src/storage/sdcard.cpp
EtxFormat and SdcardFormat switch to fatal/status messaging, tighten read/write validation, and update image/file copy paths to report success and failure through the progress-aware API.
Labeled storage pipeline
companion/src/storage/labeled.cpp
LabelsStorageFormat adds stepped progress during model and label load/write, and simplifies checklist and radio-settings failures to immediate returns with fatal messaging.
MdiChild progress write flow
companion/src/mdichild.h, companion/src/mdichild.cpp
saveFile() adds a toRadio path that uses saveFileProgress(), writeSettings becomes writeModelsSettings, and radio destination handling branches between direct writes and progress-dialog writes.
MainWindow radio read/write flows
companion/src/mainwindow.h, companion/src/mainwindow.cpp
MainWindow uses explicit ProgressWidget lifecycle handling for radio reads, inlines the SD-path read/write flow, and calls the new MdiChild write method directly.
Flash interface and model preview
companion/src/flash/radiointerface.cpp, companion/src/modeledit/setup.cpp
readSettingsSDCard() guards progress-widget usage and switches between progress fatal messages and modal errors, while loadImagePreview() clears the preview when no bitmap is selected.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

UX-UI

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding detailed progress for radio read/write.
Description check ✅ Passed The description follows the template's summary section and clearly explains the change; the optional Fixes line is omitted.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch elecpower/add-detailed-status

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
companion/src/mdichild.cpp (1)

625-625: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Typo in error message string.

Line 625 has "Models and Setting" but should be "Models and Settings" to match the rest of the codebase.

📝 Proposed fix
-                          TR("Failed to write Models and Setting to") % " "
+                          TR("Failed to write Models and Settings to") % " "
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@companion/src/mdichild.cpp` at line 625, Typo in the error message inside
MdiChild::onItemActivated — change the user-visible string "Models and Setting"
to "Models and Settings" so it matches the rest of the codebase; locate the
string literal in the MdiChild::onItemActivated method and update it
accordingly.
🧹 Nitpick comments (1)
companion/src/progress/progresswidget.cpp (1)

72-72: ⚖️ Poor tradeoff

Consider the implications of frequent processEvents() calls.

QCoreApplication::processEvents() is called after nearly every UI update to reduce latency. While this can improve responsiveness, it introduces re-entrancy risk where events triggered during processEvents() could call back into these same methods or modify state unexpectedly.

Ensure that:

  1. No critical state mutations can be triggered by re-entrant calls
  2. Consider whether Qt's built-in event coalescing and deferred updates would suffice
  3. Document this pattern if it's a deliberate design choice for progress feedback

Also applies to: 80-80, 87-87, 93-93, 104-104, 189-189, 252-252

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@companion/src/progress/progresswidget.cpp` at line 72, Multiple methods in
ProgressWidget call QCoreApplication::processEvents() frequently, which risks
re-entrancy and unexpected state mutation; add a lightweight re-entrancy guard
(e.g., a private bool like m_inProcessEvents) around every place you call
QCoreApplication::processEvents() in ProgressWidget so the call is skipped when
already running, or replace immediate processing with a safer alternative
(QCoreApplication::processEvents(QEventLoop::AllEvents, timeout) or posting
deferred updates via QMetaObject::invokeMethod(..., Qt::QueuedConnection)),
ensure any critical state mutations in methods such as the ProgressWidget
update/paint/slot functions are protected (no mutations while m_inProcessEvents
is true), and add a brief comment documenting why processEvents is used and the
guard to prevent re-entrancy.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@companion/src/progress/progresswidget.cpp`:
- Line 56: The constructor of ProgressWidget calls
QCoreApplication::processEvents(), which risks re-entrancy during construction;
remove that direct call from ProgressWidget::ProgressWidget and instead defer
processing by scheduling a zero-delay callback (e.g., via QTimer::singleShot(0,
...) or by triggering the work from showEvent/initialize method) so events are
processed only after the object is fully constructed and shown.
- Around line 153-158: The current allowed predicate special-cases QtInfoMsg and
prevents it when m_logLevel is Warning/Critical/Fatal; if you want a standard
severity threshold, replace the expression with a simple comparison like "const
bool allowed = (type >= m_logLevel);" (ensuring QtMsgType ordering is used
correctly) and add a short comment near m_logLevel/allowed explaining the
threshold policy for QtInfoMsg; if you instead want to preserve the
special-case, add an explicit comment documenting why QtInfoMsg is filtered when
m_logLevel is QtWarningMsg/QtCriticalMsg/QtFatalMsg.

In `@companion/src/storage/sdcard.cpp`:
- Around line 106-112: The current write validation only checks for zero-length
writes via writesz and misses partial or error cases; update the logic around
qint64 writesz = file.write(data.data(), data.size()) to treat any writesz < 0
(error) or writesz != qint64(data.size()) (partial write) as failures: close the
file if needed, log/fatal the path with a descriptive message including expected
vs written byte counts, and return false instead of treating partial writes as
success (refer to the writesz variable, file.write call, and data.size()).

---

Outside diff comments:
In `@companion/src/mdichild.cpp`:
- Line 625: Typo in the error message inside MdiChild::onItemActivated — change
the user-visible string "Models and Setting" to "Models and Settings" so it
matches the rest of the codebase; locate the string literal in the
MdiChild::onItemActivated method and update it accordingly.

---

Nitpick comments:
In `@companion/src/progress/progresswidget.cpp`:
- Line 72: Multiple methods in ProgressWidget call
QCoreApplication::processEvents() frequently, which risks re-entrancy and
unexpected state mutation; add a lightweight re-entrancy guard (e.g., a private
bool like m_inProcessEvents) around every place you call
QCoreApplication::processEvents() in ProgressWidget so the call is skipped when
already running, or replace immediate processing with a safer alternative
(QCoreApplication::processEvents(QEventLoop::AllEvents, timeout) or posting
deferred updates via QMetaObject::invokeMethod(..., Qt::QueuedConnection)),
ensure any critical state mutations in methods such as the ProgressWidget
update/paint/slot functions are protected (no mutations while m_inProcessEvents
is true), and add a brief comment documenting why processEvents is used and the
guard to prevent re-entrancy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0910acfc-0a31-4339-bddc-19bdb07bfe86

📥 Commits

Reviewing files that changed from the base of the PR and between 65f135c and 08417bf.

📒 Files selected for processing (13)
  • companion/src/flash/radiointerface.cpp
  • companion/src/mainwindow.cpp
  • companion/src/mainwindow.h
  • companion/src/mdichild.cpp
  • companion/src/mdichild.h
  • companion/src/modeledit/setup.cpp
  • companion/src/progress/progresswidget.cpp
  • companion/src/progress/progresswidget.h
  • companion/src/storage/etx.cpp
  • companion/src/storage/labeled.cpp
  • companion/src/storage/sdcard.cpp
  • companion/src/storage/storage.cpp
  • companion/src/storage/storage.h
💤 Files with no reviewable changes (1)
  • companion/src/mainwindow.h

Comment thread companion/src/progress/progresswidget.cpp Outdated
Comment thread companion/src/progress/progresswidget.cpp
Comment thread companion/src/storage/sdcard.cpp
@pfeerick pfeerick added this to the 3.0 milestone Jun 16, 2026
@pfeerick pfeerick force-pushed the elecpower/add-detailed-status branch from 09f0517 to 0d16491 Compare June 29, 2026 00:44
@pfeerick

Copy link
Copy Markdown
Member

LGTM, and is a nice QoL improvement... thanks Neil! :)

A future tweak might be to have some way to have it auto-close... particularly for read, as it does add an extra click if it is successful (i.e. nothing to see here, move along)... not sure what the best option is though... a auto-close on success option in the settings, or a checkbox on the dialog (as I can see you trying to frantically unclick it if you do want to see the log even though all is good).

Also, for what it is worth, I see two lines when deleting the models (PA01, if that makes any difference)... one with full path, one with relative path.

@pfeerick pfeerick merged commit d345826 into main Jun 30, 2026
13 checks passed
@pfeerick pfeerick deleted the elecpower/add-detailed-status branch June 30, 2026 01:42
@elecpower

Copy link
Copy Markdown
Collaborator Author

Agree some more tweaks would be nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

companion Related to the companion software enhancement ✨ New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants