Add the option to ALT+click a decoded CQ or QRZ message which only

moves the Rx  frequency to theirs, this facilitates  calling a station
who is busy and may have  many callers on their frequency. Updated the
corresponding mouse shortcuts help text.

Allow for times with seconds when parsing fast mode and FT8 decodes.

Exclude the RR73 grid square from  and grid validation or matching, it
is not a grid square any more as  far as WSJT-X is concerned, it is an
RRR substitute.

Add a  simple state  machine for  QSO progress  such that  replies and
auto-sequencing can be better controlled.

Get compound callsign edge cases working again and allow QSOs from and
to compound callsign holders working in as many situations as possible
including  auto-sequencing and  FT8 auto-reply  mode.  This  does mean
that a  "DE W6/K1ABC DM93"  type message close to  a callers Tx  or Rx
frequency will be taken  as a reply to a CQ call  despite it not being
explicitly addressed back to the  CQ caller. Compound callsigns should
work in MSK144 contest  mode also as well as in  short code modes with
some  minor  restrictions   (short  codes  will  not   be  used  where
configuration demands that  a message be used to send  a full compound
callsign).

Auto sequencing  has been made  generic such that  it can be  used for
more than one mode if desired.

Allow the use of free text messages to sign off in auto sequenced QSOs
without the message  being overwritten by the  sequencer. Double click
actions have  been added to the  Tx5 radio and push  buttons to revert
back to the default standard 73 message.

Make DisplayText  class interface  more idiomatic  C++ and  simplify a
bit.

Fixed  some  displayed widget  arrangements  for  different modes  and
sub-modes  so that  they  are  consistent when  starting  up and  when
switching mode or sub-mode.

This is  a big change which  has been extensively tested  but no doubt
there will also be some new defects introduced.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7939 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2017-07-24 19:27:23 +00:00
parent ba0228b173
commit 87ae336443
8 changed files with 533 additions and 376 deletions

View File

@ -3,6 +3,11 @@
#include <QStringList>
#include <QRegularExpression>
extern "C" {
bool stdmsg_(const char* msg, int len);
}
QString DecodedText::CQersCall()
{
// extract the CQer's call TODO: does this work with all call formats?
@ -37,12 +42,12 @@ QString DecodedText::CQersCall()
bool DecodedText::isJT65()
{
return _string.indexOf("#") == column_mode;
return _string.indexOf("#") == column_mode + padding_;
}
bool DecodedText::isJT9()
{
return _string.indexOf("@") == column_mode;
return _string.indexOf("@") == column_mode + padding_;
}
bool DecodedText::isTX()
@ -53,7 +58,7 @@ bool DecodedText::isTX()
int DecodedText::frequencyOffset()
{
return _string.mid(column_freq,4).toInt();
return _string.mid(column_freq + padding_,4).toInt();
}
int DecodedText::snr()
@ -64,7 +69,7 @@ int DecodedText::snr()
float DecodedText::dt()
{
return _string.mid(column_dt,5).toFloat();
return _string.mid(column_dt + padding_,5).toFloat();
}
/*
@ -79,7 +84,7 @@ float DecodedText::dt()
// find and extract any report. Returns true if this is a standard message
bool DecodedText::report(QString const& myBaseCall, QString const& dxBaseCall, /*mod*/QString& report)
{
QString msg=_string.mid(column_qsoText).trimmed();
QString msg=_string.mid(column_qsoText + padding_).trimmed();
if(msg.length() < 1) return false;
msg = msg.left (22).remove (QRegularExpression {"[<>]"});
int i1=msg.indexOf('\r');
@ -124,7 +129,7 @@ bool DecodedText::report(QString const& myBaseCall, QString const& dxBaseCall, /
QString DecodedText::call()
{
auto call = _string;
call = call.replace (QRegularExpression {" CQ ([A-Z]{2,2}|[0-9]{3,3}) "}, " CQ_\\1 ").mid (column_qsoText);
call = call.replace (QRegularExpression {" CQ ([A-Z]{2,2}|[0-9]{3,3}) "}, " CQ_\\1 ").mid (column_qsoText + padding_);
int i = call.indexOf(" ");
return call.mid(0,i);
}
@ -134,7 +139,7 @@ void DecodedText::deCallAndGrid(/*out*/QString& call, QString& grid)
{
auto msg = _string;
if(msg.mid(4,1)!=" ") msg=msg.mid(0,4)+msg.mid(6,-1); //Remove seconds from UTC
msg = msg.replace (QRegularExpression {" CQ ([A-Z]{2,2}|[0-9]{3,3}) "}, " CQ_\\1 ").mid (column_qsoText);
msg = msg.replace (QRegularExpression {" CQ ([A-Z]{2,2}|[0-9]{3,3}) "}, " CQ_\\1 ").mid (column_qsoText + padding_);
int i1 = msg.indexOf (" ");
call = msg.mid (i1 + 1);
int i2 = call.indexOf (" ");

View File

@ -15,79 +15,78 @@
/*
0123456789012345678901234567890123456789
^ ^ ^ ^ ^ ^
2343 -11 0.8 1259 # YV6BFE F6GUU R-08
2343 -19 0.3 718 # VE6WQ SQ2NIJ -14
2343 -7 0.3 815 # KK4DSD W7VP -16
2343 -13 0.1 3627 @ CT1FBK IK5YZT R+02
^ ^ ^ ^ ^ ^
2343 -11 0.8 1259 # YV6BFE F6GUU R-08
2343 -19 0.3 718 # VE6WQ SQ2NIJ -14
2343 -7 0.3 815 # KK4DSD W7VP -16
2343 -13 0.1 3627 @ CT1FBK IK5YZT R+02
0605 Tx 1259 # CQ VK3ACF QF22
0605 Tx 1259 # CQ VK3ACF QF22
*/
class DecodedText
{
public:
// These define the columns in the decoded text where fields are to be found.
// We rely on these columns being the same in the fortran code (lib/decoder.f90) that formats the decoded text
enum Columns { column_time = 0,
column_snr = 5,
column_dt = 9,
column_freq = 14,
column_mode = 19,
column_qsoText = 22 };
void operator=(const QString &rhs)
{
_string = rhs;
padding_ = _string.indexOf (" ") > 4 ? 2 : 0; // allow for seconds
};
void operator=(const QByteArray &rhs)
{
_string = rhs;
padding_ = _string.indexOf (" ") > 4 ? 2 : 0; // allow for seconds
};
void operator=(const QString &rhs)
{
_string = rhs;
};
void operator=(const QByteArray &rhs)
{
_string = rhs;
};
void operator+=(const QString &rhs)
{
_string += rhs;
};
void operator+=(const QString &rhs)
{
_string += rhs;
};
QString string() { return _string; };
QString string() { return _string; };
int indexOf(QString s) { return _string.indexOf(s); };
int indexOf(QString s, int i) { return _string.indexOf(s,i); };
QString mid(int f, int t) { return _string.mid(f,t); };
QString left(int i) { return _string.left(i); };
int indexOf(QString s) { return _string.indexOf(s); };
int indexOf(QString s, int i) { return _string.indexOf(s,i); };
QString mid(int f, int t) { return _string.mid(f,t); };
QString left(int i) { return _string.left(i); };
void clear() { _string.clear(); };
void clear() { _string.clear(); };
QString CQersCall();
QString CQersCall();
bool isJT65();
bool isJT9();
bool isTX();
int frequencyOffset(); // hertz offset from the tuned dial or rx frequency, aka audio frequency
int snr();
float dt();
bool isJT65();
bool isJT9();
bool isTX();
int frequencyOffset(); // hertz offset from the tuned dial or rx frequency, aka audio frequency
int snr();
float dt();
// find and extract any report. Returns true if this is a standard message
// find and extract any report. Returns true if this is a standard message
bool report(QString const& myBaseCall, QString const& dxBaseCall, /*mod*/QString& report);
// get the first text word, usually the call
QString call();
// get the first message text word, usually the call
QString call();
// get the second word, most likely the de call and the third word, most likely grid
void deCallAndGrid(/*out*/QString& call, QString& grid);
// get the second word, most likely the de call and the third word, most likely grid
void deCallAndGrid(/*out*/QString& call, QString& grid);
int timeInSeconds();
int timeInSeconds();
// returns a string of the SNR field with a leading + or - followed by two digits
QString report();
// returns a string of the SNR field with a leading + or - followed by two digits
QString report();
private:
QString _string;
// These define the columns in the decoded text where fields are to be found.
// We rely on these columns being the same in the fortran code (lib/decoder.f90) that formats the decoded text
enum Columns {column_time = 0,
column_snr = 5,
column_dt = 9,
column_freq = 14,
column_mode = 19,
column_qsoText = 22 };
QString _string;
int padding_;
};
extern "C" { bool stdmsg_(const char* msg, int len); }
#endif // DECODEDTEXT_H

View File

@ -40,8 +40,8 @@ void DisplayText::setContentFont(QFont const& font)
void DisplayText::mouseDoubleClickEvent(QMouseEvent *e)
{
bool ctrl = (e->modifiers() & Qt::ControlModifier);
bool shift = (e->modifiers() & Qt::ShiftModifier);
emit(selectCallsign(shift,ctrl));
bool alt = (e->modifiers() & Qt::AltModifier);
emit(selectCallsign(alt,ctrl));
QTextEdit::mouseDoubleClickEvent(e);
}
@ -72,24 +72,24 @@ void DisplayText::appendText(QString const& text, QString const& bg)
}
void DisplayText::_appendDXCCWorkedB4(DecodedText& t1, QString& bg,
QString DisplayText::_appendDXCCWorkedB4(QString message, QString const& callsign, QString * bg,
LogBook logBook, QColor color_CQ,
QColor color_DXCC,
QColor color_NewCall)
{
QString call = t1.CQersCall ();
QString call = callsign;
QString countryName;
bool callWorkedBefore;
bool countryWorkedBefore;
if(call.length()==2) {
int i0=t1.indexOf("CQ "+call);
call=t1.mid(i0+6,-1);
int i0=message.indexOf("CQ "+call);
call=message.mid(i0+6,-1);
i0=call.indexOf(" ");
call=call.mid(0,i0);
}
if(call.length()<3) return;
if(!call.contains(QRegExp("[0-9]")) or !call.contains(QRegExp("[A-Z]"))) return;
if(call.length()<3) return message;
if(!call.contains(QRegExp("[0-9]")) or !call.contains(QRegExp("[A-Z]"))) return message;
logBook.match(/*in*/call,/*out*/countryName,callWorkedBefore,countryWorkedBefore);
int charsAvail = 48;
@ -97,31 +97,31 @@ void DisplayText::_appendDXCCWorkedB4(DecodedText& t1, QString& bg,
// the decoder (seems) to always generate 41 chars. For a normal CQ call, the last five are spaces
// TODO this magic 37 characters is also referenced in MainWindow::doubleClickOnCall()
int nmin=37;
int i=t1.indexOf(" CQ ");
int k=t1.string().mid(i+4,3).toInt();
int i=message.indexOf(" CQ ");
int k=message.mid(i+4,3).toInt();
if(k>0 and k<999) nmin += 4;
int s3 = t1.indexOf(" ",nmin);
int s3 = message.indexOf(" ",nmin);
if (s3 < nmin) s3 = nmin; // always want at least the characters to position 35
s3 += 1; // convert the index into a character count
t1 = t1.left(s3); // reduce trailing white space
message = message.left(s3); // reduce trailing white space
charsAvail -= s3;
if (charsAvail > 4)
{
if (!countryWorkedBefore) // therefore not worked call either
{
t1 += "!";
bg=color_DXCC.name();
message += "!";
*bg = color_DXCC.name();
}
else
if (!callWorkedBefore) // but have worked the country
{
t1 += "~";
bg=color_NewCall.name();
message += "~";
*bg = color_NewCall.name();
}
else
{
t1 += " "; // have worked this call before
bg=color_CQ.name();
message += " "; // have worked this call before
*bg = color_CQ.name();
}
charsAvail -= 1;
@ -144,8 +144,9 @@ void DisplayText::_appendDXCCWorkedB4(DecodedText& t1, QString& bg,
countryName.replace ("Asiatic", "AS");
countryName.replace ("European", "EU");
countryName.replace ("African", "AF");
t1 += countryName;
message += countryName;
}
return message;
}
void DisplayText::displayDecodedText(DecodedText decodedText, QString myCall,
@ -170,11 +171,13 @@ void DisplayText::displayDecodedText(DecodedText decodedText, QString myCall,
or decodedText.indexOf (" " + myCall + ">") >= 0)) {
bg=color_MyCall.name();
}
// if enabled add the DXCC entity and B4 status to the end of the preformated text line t1
// if enabled add the DXCC entity and B4 status to the end of the
// preformated text line t1
auto message = decodedText.string ();
if (displayDXCCEntity && CQcall)
_appendDXCCWorkedB4(/*mod*/decodedText,bg,logBook,color_CQ,
color_DXCC,color_NewCall);
appendText(decodedText.string(),bg);
_appendDXCCWorkedB4 (message, decodedText.CQersCall (), &bg, logBook, color_CQ,
color_DXCC, color_NewCall);
appendText (message, bg);
}

View File

@ -23,7 +23,7 @@ public:
void displayQSY(QString text);
signals:
void selectCallsign(bool shift, bool ctrl);
void selectCallsign(bool alt, bool ctrl);
public slots:
void appendText(QString const& text, QString const& bg = "white");
@ -32,7 +32,7 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *e);
private:
void _appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString &bg, LogBook logBook,
QString _appendDXCCWorkedB4(QString message, QString const& callsign, QString * bg, LogBook logBook,
QColor color_CQ, QColor color_DXCC, QColor color_NewCall);
QTextCharFormat m_charFormat;

File diff suppressed because it is too large Load Diff

View File

@ -160,12 +160,14 @@ private slots:
void on_txrb3_toggled(bool status);
void on_txrb4_toggled(bool status);
void on_txrb5_toggled(bool status);
void on_txrb5_doubleClicked ();
void on_txrb6_toggled(bool status);
void on_txb1_clicked();
void on_txb2_clicked();
void on_txb3_clicked();
void on_txb4_clicked();
void on_txb5_clicked();
void on_txb5_doubleClicked ();
void on_txb6_clicked();
void on_lookupButton_clicked();
void on_addButton_clicked();
@ -299,7 +301,7 @@ private:
private:
void astroUpdate ();
void writeAllTxt(QString message);
void FT8_AutoSeq(QString message);
void auto_sequence (QString const& message, unsigned tolerance);
void hideMenus(bool b);
NetworkAccessManager m_network_manager;
@ -446,6 +448,17 @@ private:
bool m_bQRAsyncWarned;
bool m_bDoubleClicked;
bool m_bCallingCQ;
bool m_bAutoReply;
enum
{
CALLING,
REPLYING,
REPORT,
ROGER_REPORT,
ROGERS,
SIGNOFF
}
m_QSOProgress;
int m_ihsym;
int m_nzap;
@ -557,7 +570,7 @@ private:
void writeSettings();
void createStatusBar();
void updateStatusBar();
void genStdMsgs(QString rpt);
void genStdMsgs(QString rpt, bool unconditional = false);
void genCQMsg();
void clearDX ();
void lookup();
@ -573,7 +586,7 @@ private:
void pskPost(DecodedText decodedtext);
void displayDialFrequency ();
void transmitDisplay (bool);
void processMessage(QString const& messages, qint32 position, bool ctrl);
void processMessage(QString const& messages, qint32 position, bool ctrl = false, bool alt = false);
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
void replayDecodes ();
void postDecode (bool is_new, QString const& message);

View File

@ -1292,9 +1292,9 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
</item>
<item row="5" column="1" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QRadioButton" name="txrb5">
<widget class="DoubleClickableRadioButton" name="txrb5">
<property name="toolTip">
<string>Send this message in next Tx interval</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send this message in next Tx interval&lt;/p&gt;&lt;p&gt;Double-click to reset to the standard 73 message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
@ -1308,7 +1308,7 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="txb5">
<widget class="DoubleClickablePushButton" name="txb5">
<property name="maximumSize">
<size>
<width>30</width>
@ -1316,7 +1316,7 @@ list. The list can be maintained in Settings (F2).</string>
</size>
</property>
<property name="toolTip">
<string>Switch to this Tx message NOW</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Switch to this Tx message NOW&lt;/p&gt;&lt;p&gt;Double-click to reset to the standard 73 message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Tx &amp;5</string>
@ -3018,6 +3018,16 @@ QPushButton[state=&quot;ok&quot;] {
<extends>QSpinBox</extends>
<header>RestrictedSpinBox.hpp</header>
</customwidget>
<customwidget>
<class>DoubleClickableRadioButton</class>
<extends>QRadioButton</extends>
<header>DoubleClickableRadioButton.hpp</header>
</customwidget>
<customwidget>
<class>DoubleClickablePushButton</class>
<extends>QPushButton</extends>
<header>DoubleClickablePushButton.hpp</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>logQSOButton</tabstop>

View File

@ -18,7 +18,10 @@
locator to Dx Grid; change Rx and Tx frequencies to<br/>
decoded signal's frequency; generate standard messages.<br/>
If first callsign is your own, Tx frequency is not<br/>
changed unless Ctrl is held down when double-clicking.
changed unless Ctrl is held down when double-clicking.<br/>
<br/>
Hold down Alt to only move the Rx frequency when<br/>
when double-clicking to reply to a CQ or QRZ caller.
</td>
</tr>
<tr>