From c6688534cd7176eb4e8fe19d3a7271d5a39cb3be Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 24 May 2020 16:33:14 +0100 Subject: [PATCH 1/2] Performance improvements to decode highlighting The Highlight Callsign (13) UDP message now operates in a slightly different way. The "Highlight last" field, when true valued, causes all instances of the specified callsign to be highlighted in the decoding period. This allows external applications to highlight DX callsigns even when multiple stations are calling them. Before this was unlikely to work since the external application would have to respond to Decode (2) UDP messages exceedingly quickly to guarantee successful highlighting before another decode with the same DX call was printed. There should be no changes required to external applications acting as servers to the WSJT-X UDP Message Protocol, although using the version of the Highlight Callsign (13) with "Highlight last" should not be required for adhoc callsign highlighting. It should be reserved for commonly recurring targets and limited to no more than 100 active highlighting requests at any one time, otherwise there may be performance impacts on WSJT-X. --- Network/NetworkMessage.hpp | 16 ++++-- widgets/displaytext.cpp | 114 ++++++++++++++++++++++++------------- widgets/displaytext.h | 2 +- 3 files changed, 87 insertions(+), 45 deletions(-) diff --git a/Network/NetworkMessage.hpp b/Network/NetworkMessage.hpp index d01a3475e..8055e2a49 100644 --- a/Network/NetworkMessage.hpp +++ b/Network/NetworkMessage.hpp @@ -447,16 +447,20 @@ * The server may send this message at any time. The message * specifies the background and foreground color that will be * used to highlight the specified callsign in the decoded - * messages printed in the Band Activity panel. The WSJT-X + * messages printed in the Band Activity panel. The WSJT-X * clients maintain a list of such instructions and apply them to * all decoded messages in the band activity window. To clear - * highlighting send an invalid QColor value for either or both - * of the background and foreground fields. + * and cancel highlighting send an invalid QColor value for + * either or both of the background and foreground fields. When + * using this mode the total number of callsign highlighting + * requests should be limited otherwise the performance of WSJT-X + * decoding may be impacted. A rough rule of thumb might be too + * limit the number of active highlighting requests to no more + * than 100. * * The "Highlight last" field allows the sender to request that - * the last instance only instead of all instances of the - * specified call be highlighted or have it's highlighting - * cleared. + * all instances of "Callsign" in the last period only, instead + * of all instances in all periods, be highlighted. * * * SwitchConfiguration In 14 quint32 diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index db00e2587..b3ccf8eb2 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -497,60 +497,92 @@ namespace { void update_selection (QTextCursor& cursor, QColor const& bg, QColor const& fg) { - if (!cursor.isNull ()) + QTextCharFormat format {cursor.charFormat ()}; + if (bg.isValid ()) { - QTextCharFormat format {cursor.charFormat ()}; - if (bg.isValid ()) - { - format.setBackground (bg); - } - else - { - format.clearBackground (); - } - if (fg.isValid ()) - { - format.setForeground (fg); - } - else - { - format.clearForeground (); - } - cursor.mergeCharFormat (format); + format.setBackground (bg); } + else + { + format.clearBackground (); + } + if (fg.isValid ()) + { + format.setForeground (fg); + } + else + { + format.clearForeground (); + } + cursor.mergeCharFormat (format); } void reset_selection (QTextCursor& cursor) { - if (!cursor.isNull ()) + // restore previous text format, we rely on the text + // char format at he start of the selection being the + // old one which should be the case + auto c2 = cursor; + c2.setPosition (c2.selectionStart ()); + cursor.setCharFormat (c2.charFormat ()); + } +} + +namespace +{ + QString get_timestamp (QTextCursor& cursor) + { + QString timestamp; + if (cursor.movePosition (QTextCursor::PreviousCharacter) + && cursor.movePosition (QTextCursor::StartOfLine) + && cursor.movePosition (QTextCursor::EndOfWord, QTextCursor::KeepAnchor) + && cursor.hasSelection ()) { - // restore previous text format, we rely on the text - // char format at he start of the selection being the - // old one which should be the case - auto c2 = cursor; - c2.setPosition (c2.selectionStart ()); - cursor.setCharFormat (c2.charFormat ()); + timestamp = cursor.selectedText (); + cursor.movePosition (QTextCursor::StartOfLine); } + return timestamp; } } void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg, - QColor const& fg, bool last_only) + QColor const& fg, bool last_period_only) { + // qDebug () << "DisplayText::highlight_callsign: callsign:" << callsign << "last period:" << last_period_only; + if (!callsign.size ()) + { + return; + } + QRegularExpression target {QString {"?"}, QRegularExpression::DontCaptureOption}; QTextCharFormat old_format {currentCharFormat ()}; QTextCursor cursor {document ()}; - if (last_only) + if (last_period_only) { + // highlight each instance of the given callsign (word) in the + // current period cursor.movePosition (QTextCursor::End); - cursor = document ()->find (callsign, cursor - , QTextDocument::FindBackward | QTextDocument::FindWholeWords); - if (bg.isValid () || fg.isValid ()) + QTextCursor period_start {cursor}; + QTextCursor prior {cursor}; + auto period_timestamp = get_timestamp (period_start); + while (period_timestamp.size () && period_timestamp == get_timestamp (prior)) { - update_selection (cursor, bg, fg); + period_start = prior; } - else + while (!cursor.isNull () && cursor > period_start) { - reset_selection (cursor); + cursor = document ()->find (target, cursor + , QTextDocument::FindBackward | QTextDocument::FindWholeWords); + if (!cursor.isNull () && cursor.hasSelection ()) + { + if (bg.isValid () || fg.isValid ()) + { + update_selection (cursor, bg, fg); + } + else + { + reset_selection (cursor); + } + } } } else @@ -569,8 +601,11 @@ void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg, } while (!cursor.isNull ()) { - cursor = document ()->find (callsign, cursor, QTextDocument::FindWholeWords); - update_selection (cursor, bg, fg); + cursor = document ()->find (target, cursor, QTextDocument::FindWholeWords); + if (!cursor.isNull () && cursor.hasSelection ()) + { + update_selection (cursor, bg, fg); + } } } else if (pos != highlighted_calls_.end ()) @@ -579,8 +614,11 @@ void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg, QTextCursor cursor {document ()}; while (!cursor.isNull ()) { - cursor = document ()->find (callsign, cursor, QTextDocument::FindWholeWords); - reset_selection (cursor); + cursor = document ()->find (target, cursor, QTextDocument::FindWholeWords); + if (!cursor.isNull () && cursor.hasSelection ()) + { + reset_selection (cursor); + } } } } diff --git a/widgets/displaytext.h b/widgets/displaytext.h index 5aa8c7103..fb8bb6134 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -43,7 +43,7 @@ public: Q_SLOT void appendText (QString const& text, QColor bg = QColor {}, QColor fg = QColor {} , QString const& call1 = QString {}, QString const& call2 = QString {}); Q_SLOT void erase (); - Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only); + Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_period_only); private: void mouseDoubleClickEvent (QMouseEvent *) override; From bef3cc877d8adaf3abcf034076e51e4d95837cdb Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 24 May 2020 16:50:12 +0100 Subject: [PATCH 2/2] Release note updates --- NEWS | 60 +++++++++++++++++++++++++++++++++++++++++++++++ Release_Notes.txt | 1 + 2 files changed, 61 insertions(+) diff --git a/NEWS b/NEWS index 4fb665223..fee190bdc 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,66 @@ Copyright 2001 - 2019 by Joe Taylor, K1JT. + Release: WSJT-X 2.2.0-rc2 + May 25, 2020 + ------------------------- + +WSJT-X 2.2.0-rc2 is a release candidate for WSJT-X 2.2.0. The +following bugs present in the -rc1 version have been fixed: + + - Missing blank line between some decode sequences. + - Improper functioning of "Start new period decodes at top". + - Font selection caused crash on some macOS systems. + - Mouse action in band selector box not right in some macOS systems. + - Incorrect recall of Tx power setting in WSPR mode. + - Many fixes to hamlib library and executables (rigctld, etc.). + - Some regional settings did not allow WSJT-X to start. + - Main window "looked like old Windows" in macOS. + - Crash when "Ref Spec" is selected and no refspec.dat available. + - Improper decoding of some FT4 messages with hashed "MyCall". + - Crash after warning message about double-clicking in ISCAT mode. + +In addition, we have made the following improvements: + + - Updated some figures and text in User Guide. + - Corrected some formatting issues in the pdf version of User Guide. + - Added some new sample files. + - Improved shape and position of "green goal post" in Wide Graph. + - Significantly reduced the rate of false decodes in FT4 and FT8. + - Allow FT4 to use NA VHF Contest message formats. + - Hold Tx frequency no longer cleared when switching between modes. + - Added capability for translations of the user interface into + languages other than English. First working example (special + thanks to Xavi Perez, EA3W!), is Catalan. Spanish will be next. + - Performance improvements to decode highlighting via UDP messages. + +And finally: + +Increasing FT8 usage on the popular bands 40, 30, and 20m means that +the default 3 kHz sub-bands are often wall-to-wall with signals. +Overcrowding encourages some to turn on their amplifiers, which only +makes things worse. We are trying to coordinate the suggested +frequencies in WSJT-X with updated band plans being considered by +IARU, ARRL, and other amateur radio societies. + +On a trial basis, and in response to numerous suggestions from around +the world, we have added a second set of suggested dial frequencies +for FT8 on three HF bands and also on 6 meters. The new suggested dial +frequencies are 7.071, 10.133, 14.071, and 50.310 MHz. These +frequencies will appear in your drop-down band-selector list after you +go to the "Settings | Frequencies" tab, right-click on the frequency +table, and select "Reset". Alternatively, you can add the new FT8 +frequencies manually. + +When the conventional FT8 sub-band on 6, 20, 30, or 40 m seems too +full, please try moving your dial frequency down 3 kHz! Be aware that +as currently implemented, WSJT-X will set your dial to the lowest +frequency for the selected mode and band, when you switch bands. + +See the next section for a list of other program improvements since +WSJT-X 2.1.2. + + Release: WSJT-X 2.2.0-rc1 May 10, 2020 ------------------------- diff --git a/Release_Notes.txt b/Release_Notes.txt index f0d4a6872..8a1d8fdeb 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -43,6 +43,7 @@ In addition, we have made the following improvements: - Added capability for translations of the user interface into languages other than English. First working example (special thanks to Xavi Perez, EA3W!), is Catalan. Spanish will be next. + - Performance improvements to decode highlighting via UDP messages. And finally: