mainwindow.cpp: move ensureMessageDock() member function to its own file
MessagePanel.cpp: fix column width/sort ordering bugs in populateMessages()
UI_Constructor.cpp: build custom title bar once in ensureMessageDock()
after messageDock_ exists, instead of inside the toggled handler,
ensures dock is restored visible on startup
ensureMessageDock.cpp: new member function file that handles the Message Inbox
and turns it into a Qt::Window instead of a Qt::Tool when
it is in floating mode
CMakeLists.txt: add ensureMessageDock.cpp to compile object code for the member function
Fix stale Message Inbox after delivery to another station:
markMsgDelivered() and markGroupMsgDeliveredForCallsign() updated
the inbox database but never emitted messageAdded, so an already-open
message panel wouldn't refresh until closed/reopened
Both now emit messageAdded on success, reusing the existing
messageAdded -> MessagePanel::refresh connection that already handles
new incoming messages to refresh the message panel for a MSG delivery
overwrite each other in RX pane (textEditRX)
Context:
When multiple stations reply to a group-addressed query (i.e.
"@GROUP QUERY MSGS") within the same second, their replies share an
identical rendered timestamp string in textEditRX. The avoid
duplicate line logic in processCommandActivity() searched backward
for that timestamp string alone and erased whatever block it found,
with no check that the found block actually belonged to the same
sender. With enough replies landing in one processing tick, each new
reply erased the previous different station's line, leaving only
the last reply visible in textEditRX (the incoming MSG pane)
Thanks to John W2KI for reporting this bug and testing the fix
and place it in a separate member function file in JS8_Mainwindow
- Add UI hooks for Auto Reply confirmation back into the function
- Remove redundant member function declarations from mainwindow.cpp that
left over after moving the function to separate files, leaving only the
function call sites
- Move source file comments to the mainwindow header
* RX.GET_FREE_OFFSETS API addition
- Reads optional `SPEED`, `LOW`, `HIGH` params (defaults: current mode, 500 Hz, 2500 Hz)
- For each active offset in `m_bandActivity` (within 30 seconds), computes the blocked zone as `occ ± (requestedBW/2 + signalBW/2)` — accounting for both the occupying signal's actual bandwidth and your intended TX bandwidth
- Sorts and merges overlapping blocked zones, then returns the gaps as `FREE` segments
- Omits gaps narrower than your TX bandwidth (they can't fit anyway)
- Example response: {"params":{"FREE":[{"HIGH":860,"LOW":500,"WIDTH":360},{"HIGH":2500,"LOW":1120,"WIDTH":1380}],"BANDWIDTH":160,"HIGH":2500,"LOW":500,"SPEED":2,"_ID":...},"type":"RX.FREE_OFFSETS","value":""}
- Rename FILTER.GET_FILTER -> RX.GET_FILTER
- Rename FILTER.SET_FILTER -> RX.SET_FILTER
- Rename FILTER.SET_ENABLED -> RX.SET_FILTER_ENABLED
- Response type FILTER.FILTER -> RX.FILTER
- Add @note API 2.6+ to each @brief block
- Remove standalone FILTER command group (now part of RX)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Move RX.FILTER commands to RX section for Doxygen grouping
Move RX.GET_FILTER, RX.SET_FILTER and RX.SET_FILTER_ENABLED handlers
from after the MODE section into the RX section, just before the
End RX Commands marker. Update summary comment block.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: BrunoKlu <brunoklu@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Rename all MODE.* config commands to STATION.* (including SET_GROUPS
and SET_AVOID_ALLCALL)
- Add @note API 2.6+ to each new @brief block (12 commands total)
- Translate French comments to English
* Move STATION commands to STATION section for Doxygen grouping
Co-authored-by: BrunoKlu <brunoklu@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Wyatt Miler <wmiler1@gmail.com>
This uses the two respective modes' approx transmisson speed in
words per minute instead of using frame time/bandwidth.
Improve the documentation for these two modes to better explain
that HB networking is disabled when using them
This eliminates use of terms like "Turbo" which is a mechanical
gas turbine compressor, changes the faster modes to designation
of frame time/bandwidth
* TCP API: 8 STATION commands + headless autoreply confirmation
- networkMessage.cpp: MODE.GET_CONFIG, SET_AUTO_REPLY, SET_JS8HB,
SET_HBACK, SET_MULTI_DECODER, SET_HB_INTERVAL, SET_HB_TIMER, SEND_HB
- mainwindow.cpp/h: confirmThenEnqueueMessage() sends TCP push
instead of SelfDestructMessageBox (headless/xvfb compatible)
- Configuration.cpp/h: autoreply_confirmation accessor
- Rename 10 new config commands from MODE.* to STATION.* (MODE is
reserved for JS8 protocol only, STATION is for configuration)
- Add @note API 2.6+ to each new @brief block
- Translate French comments to English
Add the `BITS` parameter (from `ActivityDetail::bits`) to the
`RX.ACTIVITY` network message, alongside the existing FREQ, DIAL,
OFFSET, SNR, SPEED, TDRIFT, and UTC parameters.
This allows TCP clients to detect frame boundaries — specifically
`JS8CallFirst` (bit 0) and `JS8CallLast` (bit 1) — enabling instant
message finalization without waiting for a timeout-based deadline.
Currently, `RX.DIRECTED` messages already benefit from the `isLast`
check (in `processCommandActivity.cpp`) which appends the EOT character
before sending the network message. However, `RX.ACTIVITY` sends the
network message *before* the `isLast` check, so TCP clients have no way
to know when a message is complete. Adding BITS solves this asymmetry.
Use case: headless JS8Call stations (e.g., Raspberry Pi) using the TCP
API for RX can now display decoded messages with 0s delay instead of
waiting TRPeriod + margin.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds an indication for the number of available messages to the response to the MSGS? query, HB response, and message response in addition to the ID of the next available message.
Changing NEXT MSG ID logic to send first available ID instead of next in list when sending messages
Allow message inbox to dock into the main UI
Enable column sorting in the message table
Rework mark-as-read signals to trigger on row deselection
Add SemiSortableHeader subclass of QHeaderView
Both value and TEXT fields now contain the message body without
the FROM prefix, making the API consistent and useful for clients.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
FROM prefix
The previous fix incorrectly used d.text which is empty for simple
directed messages. This fix properly constructs valueWithoutFrom
from the message components (d.to, d.cmd, d.extra, d.text).
The value field in RX.DIRECTED messages was using the formatted 'text'
variable which includes the FROM callsign prefix. When TCP clients
reconstruct messages as "FROM: value", this resulted in duplicate
callsigns (e.g., "W9TEK: W9TEK: KC1QKM SNR -05").
Changed the value parameter from 'text' to 'd.text' (the raw message
body without FROM prefix) to match the TEXT parameter behavior.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move OmniRig to deprecated group, scheduled for deprecation due
to being no longer supported by Windows 11 and Qt6.9.3
Schedule OmniRig to removed from the code in July 2026
Noted in the doxy file description
rename remaining files that didn't match their class definitions
relocate the explicit UI_Constructor member function to JS8_MainWindow
relocate the processBufferedActivity member function to JS8_MainWindow
format affected files with LLVM clang-format
Set default APRS inbound relay to off
Fix layout of General->Networking & Autoreply tab in Settings
TEXT param contained the full formatted message including FROM prefix,
causing duplication when clients reconstruct the message. Changed to
use d.text (message body) instead.
Co-authored-by: Manuel Ochoa <mochoa@protonmail.com>