Skip to content

Conversation

@sjwoodr
Copy link

@sjwoodr sjwoodr commented Nov 8, 2025

This change is to allow WSJT-X format broadcast packets to trigger a callbook lookup even when the grid square is not specified. This is useful for non FT8 content. For example, realtime contest logs being sent from WriteLog to Qlog via the WSJT-X protocol. It is safe to call finalizeCallsignEdit() even without the grid square because the CallbookManager will cache lookups and prevent redundant lookups when WSJT-X sends multiple status type messages.

This change is to allow WSJT-X format broadcast packets to trigger a
callbook lookup even when the grid square is not specified. This is
useful for non FT8 content. For example, realtime contest logs being
sent from WriteLog to Qlog via the WSJT-X protocol.  It is safe to
call finalizeCallsignEdit() even without the grid square because the
CallbookManager will cache lookups and prevent redundant lookups
when WSJT-X sends multiple status type messages.
@foldynl
Copy link
Owner

foldynl commented Nov 8, 2025

Unfortunately, this change breaks the essence of why it was there. And that is the fact that if you have a QSO from WSJT and it doesn't have a Grid, you can't tell whether the received Callbook entry corresponds to the current position of the DX Station. That's why the condition "to have a grid" was there.

@sjwoodr
Copy link
Author

sjwoodr commented Nov 8, 2025

Unfortunately, this change breaks the essence of why it was there. And that is the fact that if you have a QSO from WSJT and it doesn't have a Grid, you can't tell whether the received Callbook entry corresponds to the current position of the DX Station. That's why the condition "to have a grid" was there.

OK, that makes sense. Right now I have a work-around, and that is sending grid AA00 if it is not filled in. That's in the middle of the ocean and unlikely to be valid. This will trigger a callbook lookup in Qlog ... but it results in the AA00 being logged (the callbook lookup won't override it).

What would you say about allowing the callbook to override the grid if it was something like AA00 or even something invalid like 0000 ?

@sjwoodr
Copy link
Author

sjwoodr commented Nov 8, 2025

Oops.. i meant AB00 as a placeholder. But it would be cool to allow callbook lookups to override the grid square if it came in via WSJT-X protocol as an invalid grid like 0000.

@sjwoodr
Copy link
Author

sjwoodr commented Nov 8, 2025

@foldynl How about a change like this instead?

diff --git a/ui/NewContactWidget.cpp b/ui/NewContactWidget.cpp
index 9d5418c0..1926cb3c 100644
--- a/ui/NewContactWidget.cpp
+++ b/ui/NewContactWidget.cpp
@@ -2939,7 +2939,17 @@ void NewContactWidget::prepareWSJTXQSO(const QString &receivedCallsign,

     callsign = receivedCallsign;
     ui->callsignEdit->setText(receivedCallsign);
-    uiDynamic->gridEdit->setText(grid);
+
+    // WSJT-X packets with "XXXX" as a grid:
+    // We should trigger callbook lookup but not persist XXXX in the UI
+    bool shouldTriggerCallbookLookup = (grid == "XXXX");
+    QString gridToUse = shouldTriggerCallbookLookup ? QString() : grid;
+
+    if ( !gridToUse.isEmpty() )
+    {
+        uiDynamic->gridEdit->setText(gridToUse);
+    }
+
     checkDupe();
     setDxccInfo(receivedCallsign);
     queryPota();
@@ -2951,9 +2961,10 @@ void NewContactWidget::prepareWSJTXQSO(const QString &receivedCallsign,
     // 1) prev Callsign empty grid
     // 2) new Callsign empty grid
     // 3) new Calllsign, new gris
-    if ( !grid.isEmpty() )
+    // If grid is "XXXX", treat it as a trigger to perform callbook lookup
+    if ( !gridToUse.isEmpty() || shouldTriggerCallbookLookup )
     {
-        useFieldsFromPrevQSO(callsign, grid);
+        useFieldsFromPrevQSO(callsign, gridToUse);
         finalizeCallsignEdit();
     }
 }

@foldynl
Copy link
Owner

foldynl commented Nov 9, 2025

Can we go back to the beginning? Through which messages does writelog send that data? Because you’re modifying the handling of the “WSJTX Status message”, but that message itself doesn’t log anything. The QSO is written only when the “WSJTX Log message” is received.

You’re right that the “WSJTX Status message” with the Grid triggers a Callbook query, but that’s only a preparation phase for the “WSJTX Log message.”

Could you please send me the complete message flow you expect to occur? Will you also include the XXXX grid in the “WSJTX Log message”?

@sjwoodr
Copy link
Author

sjwoodr commented Nov 10, 2025

Hi @foldynl - Here's a summary of the packets that my script sends:

Packet Type Sends "XXXX" Grid? Notes
Heartbeat (0) ❌ No No grid field present
Status (1) ✅ Yes Triggers callbook lookup?
QSO Logged (5) ✅ Yes Becomes part of QSO record
ADIF (12) ✅ Yes Embedded in ADIF text

The actual script that is doing the realtime conversion of WriteLog xml packets and forwarding them on to Qlog can be found here: https://github.com/sjwoodr/QLog/blob/n9oh/scripts/wl2qlog.py

edit: this script works as-is and QSOs do show up in QLog after being entered in WriteLog. However, that fake "XXXX" grid gets logged. If I send no grid at all, we still log the QSO in QLog, but none of the callbook lookups happen, and the name, qth, etc is left unfilled out in the log entry.

@foldynl
Copy link
Owner

foldynl commented Nov 11, 2025

To be honest, I don't like this solution much when grid contains something invalid. But I have another idea. There is already a workaround for JTDX due to time zone. An acceptable solution would be to follow the approach used for JTDX.

That is, don't try to pretend your script is WSJTX (I mean the packet application ID), but choose some unique identifier. If we slightly change how information is passed in QLog we can do something like:
if (ID == "WRITELOG") then query callsign.

@sjwoodr
Copy link
Author

sjwoodr commented Nov 12, 2025

@foldynl - OK let's look at what your suggestion would look like:

Key Changes:

  1. ui/WsjtxWidget.h & ui/WsjtxWidget.cpp: Updated the callsignSelected signal to include the application ID field
    • Signal now: void callsignSelected(QString callsign, QString grid, QString id)
  2. ui/NewContactWidget.h & ui/NewContactWidget.cpp: Updated prepareWSJTXQSO to accept and use the ID parameter
    • Method signature: void prepareWSJTXQSO(const QString &receivedCallsign, const QString &grid, const QString &id)
    • Added WRITELOG-specific logic: If id.contains("WRITELOG"), always trigger callbook lookup
    • Grid handling: Only sets grid in UI if not empty

How it works:

  • When a packet comes from an application with ID containing "WRITELOG", QLog will always trigger the callbook lookup (via useFieldsFromPrevQSO and finalizeCallsignEdit)
  • The grid field is handled normally - if it's provided and not empty, it's displayed in the UI
  • This follows the same pattern used for JTDX timezone handling (lines 299 and 342 in core/WsjtxUDPReceiver.cpp:299 and core/WsjtxUDPReceiver.cpp:342)
diff --git a/ui/NewContactWidget.cpp b/ui/NewContactWidget.cpp
index 9d5418c0..7f39acf9 100644
--- a/ui/NewContactWidget.cpp
+++ b/ui/NewContactWidget.cpp
@@ -2915,11 +2915,12 @@ void NewContactWidget::fillCallsignGrid(const QString &callsign, const QString &
 }

 void NewContactWidget::prepareWSJTXQSO(const QString &receivedCallsign,
-                                       const QString &grid)
+                                       const QString &grid,
+                                       const QString &id)
 {
     FCT_IDENTIFICATION;

-    qCDebug(function_parameters) << receivedCallsign << grid;
+    qCDebug(function_parameters) << receivedCallsign << grid << id;

     if ( isManualEnterMode )
     {
@@ -2939,7 +2940,12 @@ void NewContactWidget::prepareWSJTXQSO(const QString &receivedCallsign,

     callsign = receivedCallsign;
     ui->callsignEdit->setText(receivedCallsign);
-    uiDynamic->gridEdit->setText(grid);
+
+    if ( !grid.isEmpty() )
+    {
+        uiDynamic->gridEdit->setText(grid);
+    }
+
     checkDupe();
     setDxccInfo(receivedCallsign);
     queryPota();
@@ -2951,7 +2957,9 @@ void NewContactWidget::prepareWSJTXQSO(const QString &receivedCallsign,
     // 1) prev Callsign empty grid
     // 2) new Callsign empty grid
     // 3) new Calllsign, new gris
-    if ( !grid.isEmpty() )
+    // WRITELOG workaround: Similar to JTDX, check application ID
+    // If ID contains "WRITELOG", always trigger callbook lookup
+    if ( !grid.isEmpty() || id.contains("WRITELOG") )
     {
         useFieldsFromPrevQSO(callsign, grid);
         finalizeCallsignEdit();
diff --git a/ui/NewContactWidget.h b/ui/NewContactWidget.h
index e79b4a5a..1ec99c1f 100644
--- a/ui/NewContactWidget.h
+++ b/ui/NewContactWidget.h
@@ -236,7 +236,7 @@ public slots:
     void readGlobalSettings();
     void tuneDx(const DxSpot &spot);
     void fillCallsignGrid(const QString &callsign, const QString& grid);
-    void prepareWSJTXQSO(const QString &receivedCallsign, const QString &grid);
+    void prepareWSJTXQSO(const QString &receivedCallsign, const QString &grid, const QString &id);
     void resetContact();
     void saveContact();

diff --git a/ui/WsjtxWidget.cpp b/ui/WsjtxWidget.cpp
index 024ecd59..9c99c18c 100644
--- a/ui/WsjtxWidget.cpp
+++ b/ui/WsjtxWidget.cpp
@@ -193,7 +193,7 @@ void WsjtxWidget::statusReceived(WsjtxStatus newStatus)
     if ( this->status.dx_call != newStatus.dx_call
          || this->status.dx_grid != newStatus.dx_grid )
     {
-        emit callsignSelected(newStatus.dx_call, newStatus.dx_grid);
+        emit callsignSelected(newStatus.dx_call, newStatus.dx_grid, newStatus.id);
     }

     if ( this->status.mode != newStatus.mode )
diff --git a/ui/WsjtxWidget.h b/ui/WsjtxWidget.h
index 514781b1..1dd35469 100644
--- a/ui/WsjtxWidget.h
+++ b/ui/WsjtxWidget.h
@@ -35,7 +35,7 @@ private slots:
     void actionFilter();

 signals:
-    void callsignSelected(QString callsign, QString grid);
+    void callsignSelected(QString callsign, QString grid, QString id);
     void reply(WsjtxDecode);
     void CQSpot(WsjtxEntry);
     void filteredCQSpot(WsjtxEntry);

I can submit a new PR with this change if you agree with the approach and I understood your suggestion correctly. :)

Thanks!

@foldynl
Copy link
Owner

foldynl commented Nov 12, 2025

I haven’t tested it, but probably something like you described. I’m not sure if it will be exactly like this; I might still make some changes, but the principle will stay the same. Just note that this is a functional change, so it will be in version 0.47 at the earliest. And to be honest, 0.47 will come sometime in January.

@sjwoodr
Copy link
Author

sjwoodr commented Nov 12, 2025

@foldynl OK, i've submitted a new PR with these changes: #833 --- i'll close this PR out.

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