Commit cdd5dbc
Closes #3413 (phase 1 — see scope section below for what remains)
## Summary
Adds **Help → Check for Updates…** — an on-demand update check that fires only when the operator explicitly requests it. This is the minimum viable slice of #3413 that gets the core network/comparison machinery in place without committing to a persistent-notification UX that hasn't been agreed upon yet.
## What this PR does
### New class: `UpdateChecker` (`src/core/UpdateChecker.h/.cpp`)
- `GET https://api.github.com/repos/aethersdr/AetherSDR/releases/latest` with proper GitHub API headers including `User-Agent` and a 15 s transfer timeout (matches `WhatsNewDialog` precedent).
- Parses `tag_name` from the JSON response, strips the leading `v`.
- Compares against the running version using the existing `VersionNumber` class (CalVer `YY.M.patch[.hotfix]`).
- Emits `updateAvailable(latestVersion)`, `upToDate(currentVersion)`, or `checkFailed()`.
- `kReleasesPageUrl` is a public `static constexpr` in the header so the releases-page URL lives in exactly one place and is easy to update in the future.
### Changed: `MainWindow`
- `UpdateChecker` instantiated in the constructor **before** `buildMenuBar()` is called — mirrors the existing `m_bandPlanMgr` pattern, eliminating any implicit ordering dependency on `buildUI()`.
- **Help menu** gains **"Check for Updates…"** (positioned just before the final separator / About item).
- **Update available** → `QMessageBox` titled _"AetherSDR Update Available"_ showing the available and current versions, with a **"View Latest Release"** button that opens the releases page in the system browser via `QDesktopServices`, and a **Close** button.
- **Up to date** → `QMessageBox::information` _"AetherSDR is up to date (vX.Y.Z)"_.
- **Check failed** (network error, 403, malformed JSON, unparseable tag) → `QMessageBox::warning` _"Could not reach GitHub. Check your connection and try again."_ — appropriate for an operator-initiated action where silent failure is indistinguishable from a hung click.
- Both buttons have `autoDefault(false)` per widget guidelines.
- Layout spacer injected into the `QMessageBox` grid to guarantee the full window title renders without truncation (`setMinimumWidth` is silently ignored by `QMessageBox` internally).
- Stack-allocated `QMessageBox` + synchronous `exec()` — no heap leaks, no `WA_DeleteOnClose` needed.
## What this PR deliberately does NOT do
This is **phase 1**. The following are explicitly out of scope:
| Feature | Status |
|---|---|
| Automatic check on startup | Phase 2 |
| Background periodic check | Phase 2 |
| Persistent update badge/notification | Phase 2 — needs design agreement |
| Check throttle / cooldown | Phase 2 |
| AppSettings key for update preferences | Phase 2 |
The check fires **only on explicit operator request**. Principle XIII.
## Phase 2 needs a design discussion before implementation
Phase 2 will introduce an automatic check and a **persistent notification** visible without opening a menu. Before that is implemented, the team should agree on where that notification lives. The options currently on the table are:
1. **Title bar indicator** — a small button alongside PC Audio / PanLock. Always visible, but adds weight to an already-busy bar.
2. **Status bar badge** — an amber label/icon in the bottom strip. Low-profile but easy to miss.
3. **Blocking popup on launch** — guaranteed visibility, but disruptive during a QSO or in automated modes.
4. **Non-blocking toast / platform notification** — friendliest UX, but requires a custom widget or OS notification API.
Resolving those questions in #3413 first is exactly why this PR ships phase 1 as a standalone change.
## Compliance
- Follows `docs/style/dialog-patterns.md` (stack-alloc, `exec()`, no `WA_DeleteOnClose`, `autoDefault` disabled).
- No `QSettings` — `AppSettings` used project-wide; nothing to persist in phase 1.
- `kReleasesPageUrl` follows the `kPascalCase` constant naming convention from AGENTS.md.
- Tested on **Debian 13 Trixie**.
Squashed-from: #3468
Co-authored-by: W5JWP <281197059+w5jwp@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Pat Jensen <patjensen@gmail.com>1 parent 84e9285 commit cdd5dbc
6 files changed
Lines changed: 130 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
549 | 549 | | |
550 | 550 | | |
551 | 551 | | |
| 552 | + | |
552 | 553 | | |
553 | 554 | | |
554 | 555 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
188 | 188 | | |
189 | 189 | | |
190 | 190 | | |
| 191 | + | |
| 192 | + | |
191 | 193 | | |
192 | 194 | | |
193 | 195 | | |
| |||
1655 | 1657 | | |
1656 | 1658 | | |
1657 | 1659 | | |
| 1660 | + | |
| 1661 | + | |
| 1662 | + | |
| 1663 | + | |
| 1664 | + | |
| 1665 | + | |
| 1666 | + | |
| 1667 | + | |
| 1668 | + | |
| 1669 | + | |
| 1670 | + | |
| 1671 | + | |
| 1672 | + | |
| 1673 | + | |
| 1674 | + | |
| 1675 | + | |
| 1676 | + | |
| 1677 | + | |
| 1678 | + | |
| 1679 | + | |
| 1680 | + | |
| 1681 | + | |
| 1682 | + | |
| 1683 | + | |
| 1684 | + | |
| 1685 | + | |
| 1686 | + | |
| 1687 | + | |
| 1688 | + | |
| 1689 | + | |
1658 | 1690 | | |
1659 | 1691 | | |
1660 | 1692 | | |
| |||
9986 | 10018 | | |
9987 | 10019 | | |
9988 | 10020 | | |
| 10021 | + | |
| 10022 | + | |
| 10023 | + | |
9989 | 10024 | | |
9990 | 10025 | | |
9991 | 10026 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| 91 | + | |
91 | 92 | | |
92 | 93 | | |
93 | 94 | | |
| |||
920 | 921 | | |
921 | 922 | | |
922 | 923 | | |
| 924 | + | |
923 | 925 | | |
924 | 926 | | |
925 | 927 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
299 | 300 | | |
300 | 301 | | |
301 | 302 | | |
302 | | - | |
| 303 | + | |
303 | 304 | | |
304 | 305 | | |
305 | 306 | | |
| |||
0 commit comments