Compare commits

...

23 Commits

Author SHA1 Message Date
Jordan Sherer 4168e1937c Fixed beacon scheduling with a beacon now context menu item 2018-10-11 01:11:48 -04:00
Jordan Sherer f4b640df75 Fixed incremental directed decode for compound calls 2018-10-11 01:01:38 -04:00
Jordan Sherer cf1cece11c Added log button back in. Moved halt button up to balance. Added pressed state 2018-10-11 00:21:34 -04:00
Jordan Sherer 59893f6dfa Fixed label for relay dialog message notifications 2018-10-11 00:16:07 -04:00
Jordan Sherer ead5c225b5 Fixed separator for restore previous message action 2018-10-11 00:15:52 -04:00
Jordan Sherer 4744952a1a Fixed issue with button and text display in the gui event loop 2018-10-10 17:43:11 -04:00
Jordan Sherer a30bff5589 Bump to 0.7.3 2018-10-10 16:01:54 -04:00
Jordan Sherer e7e2f8357f Fixed idle timer alert 2018-10-10 15:36:53 -04:00
Jordan Sherer 4ffa82f695 Fixed default idle timer 2018-10-10 15:29:48 -04:00
Jordan Sherer 3e38067561 Fixed incremental directed message receipt for ALLCALL and GROUPCALL 2018-10-10 13:35:52 -04:00
Jordan Sherer 52177a0513 Fixed parsing of commands to not split up command words 2018-10-10 10:10:30 -04:00
Jordan Sherer f79ca47a93 Fixed incremental print for directed messages.
Fixed compound calls in the heard list
2018-10-10 09:04:56 -04:00
Jordan Sherer f0e30dc7b0 Fixed compound calls / beacon / cq differentiation 2018-10-09 20:09:53 -04:00
Jordan Sherer d20fe46447 Fixed tx first dependence on checkbox and potential delay caused by event processing 2018-10-09 17:44:36 -04:00
Jordan Sherer aa2c41f124 Initial tx cycle cleanup 2018-10-09 17:33:30 -04:00
Jordan Sherer ad563c0aed LDPC codeword update 2018-10-09 15:36:50 -04:00
Jordan Sherer 60b58fb50f Fixed display of beacons and beacon acks when not beaconining 2018-10-09 15:26:13 -04:00
Jordan Sherer ca79a450ca Fixed beacon queue reset on beacon toggle 2018-10-09 15:03:30 -04:00
Jordan Sherer 3c8c80a5d7 Fixed side-effect of double space fix, where F characters were not being encoded correctly 2018-10-09 14:12:00 -04:00
Jordan Sherer fc43c7fbb4 Fixed issue with directed commands splitting up words that appear in the command. E.g., 'NO' 'T' 2018-10-09 09:31:33 -04:00
Jordan Sherer 353d75ac49 Fixed double space compression issue by word replacement for a space character 2018-10-08 15:36:09 -04:00
Jordan Sherer 2d392dd676 Fixed trimming of trailing whitespace for configuration messages and grids 2018-10-08 15:04:10 -04:00
Jordan Sherer 18fac2e4ba Fixed BEACON ACK replies to CQs 2018-10-08 15:00:54 -04:00
12 changed files with 365 additions and 1101 deletions
+7 -7
View File
@@ -922,7 +922,7 @@ QString Configuration::my_grid() const
if (m_->use_dynamic_info_ && m_->dynamic_grid_.size () >= 4) {
grid = m_->dynamic_grid_;
}
return grid;
return grid.trimmed();
}
QString Configuration::my_station() const
@@ -931,22 +931,22 @@ QString Configuration::my_station() const
if(m_->use_dynamic_info_ && !m_->dynamic_qtc_.isEmpty()){
station = m_->dynamic_qtc_;
}
return station;
return station.trimmed();
}
QString Configuration::my_qth() const
{
return m_->my_qth_;
return m_->my_qth_.trimmed();
}
QString Configuration::cq_message() const
{
return m_->cq_;
return m_->cq_.trimmed();
}
QString Configuration::reply_message() const
{
return m_->reply_;
return m_->reply_.trimmed();
}
int Configuration::callsign_aging() const
@@ -1650,7 +1650,7 @@ void Configuration::impl::read_settings ()
quick_call_ = settings_->value ("QuickCall", false).toBool ();
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
beacon_ = settings_->value ("TxBeacon", 30).toInt ();
watchdog_ = settings_->value ("TxWatchdog", 0).toInt ();
watchdog_ = settings_->value ("TxIdleWatchdog", 60).toInt ();
if(watchdog_){
watchdog_ = qMax(5, watchdog_);
}
@@ -1783,7 +1783,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("QuickCall", quick_call_);
settings_->setValue ("73TxDisable", disable_TX_on_73_);
settings_->setValue ("TxBeacon", beacon_);
settings_->setValue ("TxWatchdog", watchdog_);
settings_->setValue ("TxIdleWatchdog", watchdog_);
settings_->setValue ("Tx2QSO", TX_messages_);
settings_->setValue ("CATForceDTR", rig_params_.force_dtr);
settings_->setValue ("DTR", rig_params_.dtr_high);
+9 -6
View File
@@ -457,7 +457,7 @@
<string/>
</property>
<property name="minimum">
<number>10</number>
<number>5</number>
</property>
<property name="maximum">
<number>1440</number>
@@ -466,7 +466,7 @@
<number>1</number>
</property>
<property name="value">
<number>30</number>
<number>15</number>
</property>
</widget>
</item>
@@ -498,6 +498,9 @@
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1440</number>
</property>
@@ -505,7 +508,7 @@
<number>1</number>
</property>
<property name="value">
<number>0</number>
<number>60</number>
</property>
</widget>
</item>
@@ -2562,7 +2565,7 @@ QListView::item:hover {
<item row="1" column="0">
<widget class="QLabel" name="sound_am_path_label">
<property name="text">
<string>Reply Message Received:</string>
<string>Reply Dialog Message Received:</string>
</property>
<property name="buddy">
<cstring>azel_path_select_push_button</cstring>
@@ -3616,11 +3619,11 @@ soundcard changes</string>
</connections>
<buttongroups>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="PTT_method_button_group"/>
</buttongroups>
</ui>
+1 -1
View File
@@ -1,6 +1,6 @@
# Version number components
set (WSJTX_VERSION_MAJOR 0)
set (WSJTX_VERSION_MINOR 7)
set (WSJTX_VERSION_PATCH 2)
set (WSJTX_VERSION_PATCH 3)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
+18 -9
View File
@@ -23,6 +23,7 @@
#include <cmath>
#include <QDebug>
Codeword JSC::codeword(quint32 index, bool separate, quint32 bytesize, quint32 s, quint32 c){
QList<Codeword> out;
@@ -52,9 +53,19 @@ QList<CodewordPair> JSC::compress(QString text){
const quint32 s = 7;
const quint32 c = pow(2, 4) - s;
foreach(QString w, text.split(" ", QString::SkipEmptyParts)){
QString space(" ");
foreach(QString w, text.split(" ", QString::KeepEmptyParts)){
bool ok = false;
bool isSpaceCharacter = false;
// if this is an empty part, it should be a space.
if(w.isEmpty()){
w = space;
isSpaceCharacter = true;
}
while(!w.isEmpty()){
// this does both prefix and full match lookup
auto index = lookup(w, &ok);
@@ -63,10 +74,11 @@ QList<CodewordPair> JSC::compress(QString text){
}
auto t = JSC::map[index];
w = QString(w.mid(t.size));
w = QString(w).mid(t.size);
bool isLast = w.isEmpty();
out.append({ codeword(index, isLast, b, s, c), (quint32)t.size + (isLast ? 1 : 0) /* for the space that follows */});
bool shouldAppendSpace = isLast && !isSpaceCharacter;
out.append({ codeword(index, shouldAppendSpace, b, s, c), (quint32)t.size + (shouldAppendSpace ? 1 : 0) /* for the space that follows */});
}
}
@@ -118,7 +130,9 @@ QString JSC::decompress(Codeword const& bitvec){
j = j*s + bytes[start + k] + base[k];
out.append(QString(JSC::map[j].str));
auto word = QString(JSC::map[j].str);
out.append(word);
if(!separators.isEmpty() && separators.first() == start + k){
out.append(" ");
separators.removeFirst();
@@ -167,11 +181,6 @@ quint32 JSC::lookup(char const* b, bool *ok){
// now that we have the first index in the list, let's just iterate through the list, comparing words along the way
for(quint32 i = index; i < index + count; i++){
// if we're no longer a prefix match, end.
if(b[0] != JSC::list[i].str[0]){
break;
}
quint32 len = JSC::list[i].size;
if(strncmp(b, JSC::list[i].str, len) == 0){
if(ok) *ok = true;
+2 -2
View File
@@ -39,8 +39,8 @@ public:
static const Tuple map[262144];
static const Tuple list[262144];
static const quint32 prefixSize = 68;
static const Tuple prefix[68];
static const quint32 prefixSize = 69;
static const Tuple prefix[69];
};
#endif // JSC_H
+8 -7
View File
@@ -29,7 +29,7 @@ const Tuple JSC::list[262144] = {
{"_", 1, 48},
{"^", 1, 64},
{"]", 1, 59},
{"\\", 1, 67},
{" ", 1, 67},
{"[", 1, 58},
{"ZZZZ", 4, 91474},
{"ZZZ", 3, 70901},
@@ -180080,8 +180080,8 @@ const Tuple JSC::list[262144] = {
{"FTAD", 4, 112460},
{"FTAC", 4, 68872},
{"FTAB", 4, 72752},
{"FT8CALL", 7, 69},
{"FT8", 3, 68},
{"\\", 1, 69},
{"FT8", 3, 68},
{"FSYW", 4, 155790},
{"FSYT", 4, 186523},
{"FSYS", 4, 69541},
@@ -262164,10 +262164,10 @@ const Tuple JSC::list[262144] = {
{"$", 1, 51},
{"#", 1, 53},
{"\"", 1, 26},
{"!", 1, 28},
{"!", 1, 28},
};
const Tuple JSC::prefix[68] = {
const Tuple JSC::prefix[69] = {
{"!", 1, 262143},
{"\"", 1, 262142},
{"#", 1, 262141},
@@ -262204,7 +262204,8 @@ const Tuple JSC::prefix[68] = {
{"B", 13306, 233869},
{"C", 17608, 216261},
{"D", 13749, 202512},
{"E", 12403, 190109},
{"E", 12403, 190109},
{"\\", 1, 180059},
{"F", 11252, 178857},
{"G", 10672, 168185},
{"H", 9060, 159125},
@@ -262227,7 +262228,7 @@ const Tuple JSC::prefix[68] = {
{"Y", 4348, 2264},
{"Z", 2254, 10},
{"[", 1, 9},
{"\\", 1, 8},
{" ", 1, 8},
{"]", 1, 7},
{"^", 1, 6},
{"_", 1, 5},
+3 -3
View File
@@ -88,9 +88,9 @@ const Tuple JSC::map[262144] = {
{"^", 1, 64},
{"`", 1, 65},
{"~", 1, 66},
{"\\", 1, 67},
{"FT8", 3, 68},
{"FT8CALL", 7, 69},
{" ", 1, 67},
{"FT8", 3, 68},
{"\\", 1, 69},
{"JS8", 3, 70},
{"JS8CALL", 7, 71},
{"JSQSO", 5, 72},
+1 -1
View File
@@ -65,7 +65,7 @@ write(*,*) "niter= ",max_iterations," s= ",s
allocate ( codeword(N), decoded(K), message(K) )
allocate ( rxdata(N), llr(N) )
msg="K1JT K9AN EN50"
msg="0123456789012"
! msg="G4WJS K9AN EN50"
call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent,.false.,grid) !Unpack to get msgsent
+160 -934
View File
File diff suppressed because it is too large Load Diff
+2 -9
View File
@@ -120,8 +120,6 @@ public slots:
void diskDat();
void freezeDecode(int n);
void guiUpdate();
void doubleClickOnCall (Qt::KeyboardModifiers);
void doubleClickOnCall2(Qt::KeyboardModifiers);
void readFromStdout();
void p1ReadFromStdout();
void setXIT(int n, Frequency base = 0u);
@@ -213,7 +211,6 @@ private slots:
void on_EraseButton_clicked();
void band_activity_cleared ();
void rx_frequency_activity_cleared ();
void on_txFirstCheckBox_stateChanged(int arg1);
void set_dateTimeQSO(int m_ntx);
void set_ntx(int n);
void on_txrb1_toggled(bool status);
@@ -417,7 +414,6 @@ private:
private:
void astroUpdate ();
void writeAllTxt(QString message);
void auto_sequence (DecodedText const& message, unsigned start_tolerance, unsigned stop_tolerance);
void hideMenus(bool b);
NetworkAccessManager m_network_manager;
@@ -721,6 +717,7 @@ private:
QString text;
QDateTime utcTimestamp;
int snr;
bool shouldDisplay;
};
struct MessageBuffer {
@@ -860,8 +857,6 @@ private:
void writeSettings();
void createStatusBar();
void updateStatusBar();
void genStdMsgs(QString rpt, bool unconditional = false);
void genCQMsg();
void clearDX ();
void lookup();
void ba2msg(QByteArray ba, char* message);
@@ -874,19 +869,17 @@ private:
void rigFailure (QString const& reason);
void pskSetLocal ();
void aprsSetLocal ();
void pskPost(DecodedText const& decodedtext);
void pskLogReport(QString mode, int offset, int snr, QString callsign, QString grid);
void aprsLogReport(int offset, int snr, QString callsign, QString grid);
Radio::Frequency dialFrequency();
void displayDialFrequency ();
void transmitDisplay (bool);
void processMessage(DecodedText const&, Qt::KeyboardModifiers = 0);
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence, quint8 modifiers);
void locationChange(QString const& location);
void replayDecodes ();
void postDecode (bool is_new, QString const& message);
void displayTransmit();
void updateButtonDisplay();
void updateTextDisplay();
void updateFrameCountEstimate(int count);
void updateTextStatsDisplay(QString text, int count);
void updateTxButtonDisplay();
+153 -121
View File
@@ -948,7 +948,7 @@ background-color: #00ff00;
</size>
</property>
<property name="visible">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Insert a new entry into the log&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@@ -969,6 +969,9 @@ min-height:30px;
/*max-width:60px;*/
max-height:30px;
}
QPushButton:pressed {
background-color: darkgray;
}
QPushButton[state=&quot;error&quot;] {
background-color: red;
}
@@ -1113,6 +1116,51 @@ background-color: #6699ff;
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QPushButton" name="stopTxButton">
<property name="minimumSize">
<size>
<width>75</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop transmitting&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
font-family: helvetica;
font-weight: bold;
background-color: lightgray;
color: black;
border-style: solid;
border-radius:2px;
border-width:0px;
border-color: gray;
font-size:90%;
min-width:75px;
min-height:30px;
/*max-width:60px;*/
max-height:30px;
}
QPushButton:pressed {
background-color: darkgray;
}
QPushButton[state=&quot;error&quot;] {
background-color: red;
}
QPushButton[state=&quot;warning&quot;] {
background-color: orange;
}
QPushButton[state=&quot;ok&quot;] {
background-color: #00ff00;
}</string>
</property>
<property name="text">
<string>HALT</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -1420,7 +1468,39 @@ QTextEdit[transmitting=&quot;true&quot;] {
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="10">
<item row="1" column="2">
<widget class="QPushButton" name="replyMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reply to a CQ&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Reply</string>
</property>
</widget>
</item>
<item row="1" column="13">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="11">
<widget class="QPushButton" name="queryButton">
<property name="minimumSize">
<size>
@@ -1437,7 +1517,58 @@ QTextEdit[transmitting=&quot;true&quot;] {
</widget>
</item>
<item row="1" column="12">
<spacer name="horizontalSpacer_5">
<widget class="QPushButton" name="deselectButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Deselect the current callsign for directed messaging&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Deselect</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="qthMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send your station location message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>QTH</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="cqMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send a CQ message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>CQ</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="7">
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -1452,7 +1583,23 @@ QTextEdit[transmitting=&quot;true&quot;] {
</property>
</spacer>
</item>
<item row="1" column="13">
<item row="1" column="5">
<widget class="QPushButton" name="qtcMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send your station message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>QTC</string>
</property>
</widget>
</item>
<item row="1" column="14">
<widget class="QPushButton" name="startTxButton">
<property name="enabled">
<bool>false</bool>
@@ -1484,39 +1631,7 @@ color:#555;
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="qthMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send your station location message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>QTH</string>
</property>
</widget>
</item>
<item row="1" column="14">
<widget class="QPushButton" name="stopTxButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop transmitting&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Halt</string>
</property>
</widget>
</item>
<item row="1" column="8">
<item row="1" column="6">
<widget class="QPushButton" name="macrosMacroButton">
<property name="minimumSize">
<size>
@@ -1532,89 +1647,6 @@ color:#555;
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="replyMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reply to a CQ&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Reply</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="cqMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send a CQ message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>CQ</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="11">
<widget class="QPushButton" name="deselectButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Deselect the current callsign for directed messaging&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Deselect</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="qtcMacroButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send your station message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>QTC</string>
</property>
</widget>
</item>
<item row="1" column="6">
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QFrame" name="frame_5">
@@ -4588,7 +4620,7 @@ list. The list can be maintained in Settings (F2).</string>
<x>0</x>
<y>0</y>
<width>872</width>
<height>21</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
+1 -1
View File
@@ -96,7 +96,7 @@ QMap<int, int> checksum_cmds = {
};
QString callsign_pattern = QString("(?<callsign>[A-Z0-9/]+)");
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:AGN[?]|ACK|73|YES|NO|SNR|QSL[?]?|RR|HEARING|HW CPY[?]|FB|QTH|QTC|GRID|APRS[:]|BEACON (ACK|REQ)|QRZ[?]|[?@&$%#^> ]))?");
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:BEACON (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|(?:ACK|73|YES|NO|SNR|QSL|RR|HEARING|FB|QTH|QTC|GRID)(?= |$)|[?@&$%#^> ]))?");
QString optional_grid_pattern = QString("(?<grid>\\s?[A-R]{2}[0-9]{2})?");
QString optional_extended_grid_pattern = QString("^(?<grid>\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?");
QString optional_num_pattern = QString("(?<num>(?<=SNR|HEARING|BEACON ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");