Better handling of compound callsigns

Option  to control  standard message  generation for  type 2  compound
callsign holders.

Process decoded  messages based  on either base  or full  callsign for
both DE and DX callsigns.

Change CW id when callsign changed in settings.

Merged from wsjtx-1.4 branch.



git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5000 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2015-03-04 12:22:33 +00:00
parent d3ca5fdc8e
commit 50901a5354
7 changed files with 178 additions and 52 deletions

View File

@ -181,6 +181,8 @@ namespace
{
qRegisterMetaType<Configuration::DataMode> ("Configuration::DataMode");
qRegisterMetaTypeStreamOperators<Configuration::DataMode> ("Configuration::DataMode");
qRegisterMetaType<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen");
qRegisterMetaTypeStreamOperators<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen");
}
} static_initializer;
@ -475,6 +477,8 @@ private:
float jt9w_min_dt_;
float jt9w_max_dt_;
Type2MsgGen type_2_msg_gen_;
QStringListModel macros_;
RearrangableMacrosModel next_macros_;
QAction * macro_delete_action_;
@ -587,6 +591,7 @@ bool Configuration::restart_audio_output () const {return m_->restart_sound_outp
unsigned Configuration::jt9w_bw_mult () const {return m_->jt9w_bw_mult_;}
float Configuration::jt9w_min_dt () const {return m_->jt9w_min_dt_;}
float Configuration::jt9w_max_dt () const {return m_->jt9w_max_dt_;}
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
QString Configuration::my_callsign () const {return m_->my_callsign_;}
QString Configuration::my_grid () const {return m_->my_grid_;}
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
@ -1025,6 +1030,7 @@ void Configuration::impl::initialise_models ()
ui_->jt9w_bandwidth_mult_combo_box->setCurrentText (QString::number (jt9w_bw_mult_));
ui_->jt9w_min_dt_double_spin_box->setValue (jt9w_min_dt_);
ui_->jt9w_max_dt_double_spin_box->setValue (jt9w_max_dt_);
ui_->type_2_msg_gen_combo_box->setCurrentIndex (type_2_msg_gen_);
ui_->rig_combo_box->setCurrentText (rig_params_.rig_name_);
ui_->TX_mode_button_group->button (data_mode_)->setChecked (true);
ui_->split_mode_button_group->button (rig_params_.split_mode_)->setChecked (true);
@ -1167,6 +1173,8 @@ void Configuration::impl::read_settings ()
jt9w_min_dt_ = settings_->value ("DTmin", -2.5).toFloat ();
jt9w_max_dt_ = settings_->value ("DTmax", 5.).toFloat ();
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
@ -1252,6 +1260,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("ToneMult", jt9w_bw_mult_);
settings_->setValue ("DTmin", jt9w_min_dt_);
settings_->setValue ("DTmax", jt9w_max_dt_);
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
settings_->setValue ("PSKReporter", spot_to_psk_reporter_);
@ -1605,6 +1614,7 @@ void Configuration::impl::accept ()
jt9w_bw_mult_ = ui_->jt9w_bandwidth_mult_combo_box->currentText ().toUInt ();
jt9w_min_dt_ = static_cast<float> (ui_->jt9w_min_dt_double_spin_box->value ());
jt9w_max_dt_ = static_cast<float> (ui_->jt9w_max_dt_double_spin_box->value ());
type_2_msg_gen_ = static_cast<Type2MsgGen> (ui_->type_2_msg_gen_combo_box->currentIndex ());
log_as_RTTY_ = ui_->log_as_RTTY_check_box->isChecked ();
report_in_comments_ = ui_->report_in_comments_check_box->isChecked ();
prompt_to_log_ = ui_->prompt_to_log_check_box->isChecked ();
@ -2420,8 +2430,11 @@ bool operator != (RigParams const& lhs, RigParams const& rhs)
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (Configuration, DataMode);
ENUM_QDEBUG_OPS_IMPL (Configuration, Type2MsgGen);
#endif
ENUM_QDATASTREAM_OPS_IMPL (Configuration, DataMode);
ENUM_QDATASTREAM_OPS_IMPL (Configuration, Type2MsgGen);
ENUM_CONVERSION_OPS_IMPL (Configuration, DataMode);
ENUM_CONVERSION_OPS_IMPL (Configuration, Type2MsgGen);

View File

@ -54,7 +54,7 @@ class Configuration final
: public QObject
{
Q_OBJECT;
Q_ENUMS (DataMode);
Q_ENUMS (DataMode Type2MsgGen);
public:
using MODE = Transceiver::MODE;
@ -62,6 +62,7 @@ public:
using Frequency = Radio::Frequency;
enum DataMode {data_mode_none, data_mode_USB, data_mode_data};
enum Type2MsgGen {type_2_msg_1_full, type_2_msg_3_full, type_2_msg_5_only};
explicit Configuration (QSettings * settings, QWidget * parent = nullptr);
~Configuration ();
@ -113,6 +114,7 @@ public:
unsigned jt9w_bw_mult () const;
float jt9w_min_dt () const;
float jt9w_max_dt () const;
Type2MsgGen type_2_msg_gen () const;
QColor color_CQ () const;
QColor color_MyCall () const;
QColor color_TxMsg () const;
@ -186,13 +188,17 @@ private:
};
Q_DECLARE_METATYPE (Configuration::DataMode);
Q_DECLARE_METATYPE (Configuration::Type2MsgGen);
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (Configuration, DataMode);
ENUM_QDEBUG_OPS_DECL (Configuration, Type2MsgGen);
#endif
ENUM_QDATASTREAM_OPS_DECL (Configuration, DataMode);
ENUM_QDATASTREAM_OPS_DECL (Configuration, Type2MsgGen);
ENUM_CONVERSION_OPS_DECL (Configuration, DataMode);
ENUM_CONVERSION_OPS_DECL (Configuration, Type2MsgGen);
#endif

View File

@ -53,8 +53,18 @@
<property name="title">
<string>Station Details</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<layout class="QGridLayout" name="gridLayout_13">
<item row="0" column="3">
<widget class="QLabel" name="grid_label">
<property name="text">
<string>M&amp;y Grid:</string>
</property>
<property name="buddy">
<cstring>grid_line_edit</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="callsign_label">
<property name="text">
<string>My C&amp;all:</string>
@ -64,14 +74,21 @@
</property>
</widget>
</item>
<item>
<item row="0" column="4">
<widget class="QLineEdit" name="grid_line_edit">
<property name="toolTip">
<string>Maidenhead locator (only the first four characters are required).</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="callsign_line_edit">
<property name="toolTip">
<string>Station callsign.</string>
</property>
</widget>
</item>
<item>
<item row="0" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -84,20 +101,44 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="grid_label">
<property name="text">
<string>M&amp;y Grid:</string>
<item row="1" column="4">
<widget class="QComboBox" name="type_2_msg_gen_combo_box">
<property name="enabled">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>grid_line_edit</cstring>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Type 2 compound callsigns are those with prefixes or suffixes not included in the allowed shortlist (See Help-&amp;gt;Add-on prefixes and suffixes).&lt;/p&gt;&lt;p&gt;This option determines which generated messages should contain your full type 2 compound call sign rather than your base callsign. It only applies if you have a type 2 compound callsign.&lt;/p&gt;&lt;p&gt;This option controls the way the messages that are used to answer CQ calls are generated. Generated messages 6 (CQ) and 5 (73) will always contain your full callsign. The JT65 and JT9 protocols allow for some standard messages with your full call at the expense of another piece of information such as the DX call or your locator.&lt;/p&gt;&lt;p&gt;Choosing message 1 omits the DX callsign which may be an issue when replying to CQ calls. Choosing message 3 also omits the DX callsign and many versions of this and other software will not extract the report. Choosing neither means that your full callsign only goes in your message 5 (73) so your QSO partner my log the wrong callsign.&lt;/p&gt;&lt;p&gt;None of these options are perfect, message 3 is best but be aware your QSO partner may not log the report you send them.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>Full call in Tx1</string>
</property>
</item>
<item>
<property name="text">
<string>Full call in Tx3</string>
</property>
</item>
<item>
<property name="text">
<string>Full call in Tx5 only</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLineEdit" name="grid_line_edit">
<property name="toolTip">
<string>Maidenhead locator (only the first four characters are required).</string>
<item row="1" column="0" colspan="4">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Message generation for type 2 compound callsign holders:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>type_2_msg_gen_combo_box</cstring>
</property>
</widget>
</item>
@ -1953,6 +1994,7 @@ soundcard changes</string>
<tabstop>configuration_tabs</tabstop>
<tabstop>callsign_line_edit</tabstop>
<tabstop>grid_line_edit</tabstop>
<tabstop>type_2_msg_gen_combo_box</tabstop>
<tabstop>insert_blank_check_box</tabstop>
<tabstop>miles_check_box</tabstop>
<tabstop>TX_messages_check_box</tabstop>
@ -1961,6 +2003,7 @@ soundcard changes</string>
<tabstop>decoded_text_font_push_button</tabstop>
<tabstop>monitor_off_check_box</tabstop>
<tabstop>monitor_last_used_check_box</tabstop>
<tabstop>tx_QSY_check_box</tabstop>
<tabstop>quick_call_check_box</tabstop>
<tabstop>tx_QSY_check_box</tabstop>
<tabstop>disable_TX_on_73_check_box</tabstop>
@ -2088,12 +2131,12 @@ soundcard changes</string>
</connection>
</connections>
<buttongroups>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="CAT_handshake_button_group"/>
</buttongroups>
</ui>

View File

@ -50,7 +50,7 @@ int DecodedText::snr()
*/
// find and extract any report. Returns true if this is a standard message
bool DecodedText::report(const QString myCall, /*mod*/QString& report)
bool DecodedText::report(QString const& myBaseCall, QString const& dxBaseCall, /*mod*/QString& report)
{
QString msg=_string.mid(column_qsoText);
int i1=msg.indexOf("\r");
@ -59,10 +59,16 @@ bool DecodedText::report(const QString myCall, /*mod*/QString& report)
bool b = stdmsg_(msg.mid(0,22).toLatin1().constData(),22); // stdmsg is a fortran routine that packs the text, unpacks it and compares the result
QStringList w=msg.split(" ",QString::SkipEmptyParts);
if(b and w[0]==myCall)
if(b && (w[0] == myBaseCall
|| w[0].endsWith ("/" + myBaseCall)
|| w[0].startsWith (myBaseCall + "/")
|| (w.size () > 1 && !dxBaseCall.isEmpty ()
&& (w[1] == dxBaseCall
|| w[1].endsWith ("/" + dxBaseCall)
|| w[1].startsWith (dxBaseCall + "/")))))
{
QString tt="";
if(w.length()>=3) tt=w[2];
if(w.size() > 2) tt=w[2];
bool ok;
i1=tt.toInt(&ok);
if (ok and i1>=-50 and i1<50)

View File

@ -67,7 +67,7 @@ public:
int snr();
// find and extract any report. Returns true if this is a standard message
bool report(const QString myCall, /*mod*/QString& report);
bool report(QString const& myBaseCall, QString const& dxBaseCall, /*mod*/QString& report);
// get the first text word, usually the call
QString call();

View File

@ -119,7 +119,11 @@ void DisplayText::displayDecodedText(DecodedText decodedText, QString myCall,
CQcall = true;
bg=color_CQ.name();
}
if (myCall != "" and decodedText.indexOf(" " + myCall + " ") > 0)
if (myCall != "" and (
decodedText.indexOf (" " + myCall + " ") >= 0
or decodedText.indexOf (" " + myCall + "/") >= 0
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

View File

@ -658,8 +658,18 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
ui->readFreq->setStyleSheet("");
ui->readFreq->setEnabled(false);
auto callsign = m_config.my_callsign ();
if (QDialog::Accepted == m_config.exec ())
{
if (m_config.my_callsign () != callsign)
{
morse_(const_cast<char *> (m_config.my_callsign ().toLatin1().constData())
, const_cast<int *> (icw)
, &m_ncw
, m_config.my_callsign ().length());
}
on_dxGridEntry_textChanged (m_hisGrid); // recalculate distances in case of units change
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
@ -786,6 +796,12 @@ void MainWindow::keyPressEvent( QKeyEvent *e ) //keyPressEvent
case Qt::Key_F4:
ui->dxCallEntry->setText("");
ui->dxGridEntry->setText("");
m_hisCall="";
m_hisGrid="";
m_rptSent="";
m_rptRcvd="";
m_qsoStart="";
m_qsoStop="";
genStdMsgs("");
if (1 == ui->tabWidget->currentIndex())
{
@ -1366,9 +1382,11 @@ void MainWindow::readFromStdout() //readFromStdout
DecodedText decodedtext;
decodedtext = t.replace("\n",""); //t.replace("\n","").mid(0,t.length()-4);
auto my_base_call = baseCall (m_config.my_callsign ());
// the left band display
ui->decodedTextBrowser->displayDecodedText (decodedtext
, m_config.my_callsign ()
, my_base_call
, m_config.DXCC ()
, m_logBook
, m_config.color_CQ()
@ -1380,7 +1398,7 @@ void MainWindow::readFromStdout() //readFromStdout
{
// the right QSO window
ui->decodedTextBrowser2->displayDecodedText(decodedtext
, m_config.my_callsign ()
, my_base_call
, false
, m_logBook
, m_config.color_CQ()
@ -1395,7 +1413,9 @@ void MainWindow::readFromStdout() //readFromStdout
}
// find and extract any report for myCall
bool stdMsg = decodedtext.report(m_config.my_callsign (),/*mod*/m_rptRcvd);
bool stdMsg = decodedtext.report(my_base_call
, baseCall (ui->dxCallEntry-> text ().toUpper ().trimmed ())
, /*mod*/m_rptRcvd);
// extract details and send to PSKreporter
int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged;
@ -1900,6 +1920,16 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
QStringList t4=t3.split(" ",QString::SkipEmptyParts);
if(t4.length() <5) return; //Skip the rest if no decoded text
QString hiscall;
QString hisgrid;
decodedtext.deCallAndGrid(/*out*/hiscall,hisgrid);
// basic valid call sign check i.e. contains at least one digit and
// one letter next to each other
if (!hiscall.contains (QRegularExpression {R"(\d[[:upper:]]|[[:upper:]]\d)"}))
{
return;
}
// only allow automatic mode changes when not transmitting
if (!m_transmitting)
{
@ -1938,11 +1968,13 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
}
}
auto my_base_call = baseCall (m_config.my_callsign ());
int i9=m_QSOText.indexOf(decodedtext.string());
if (i9<0 and !decodedtext.isTX())
{
ui->decodedTextBrowser2->displayDecodedText(decodedtext
, m_config.my_callsign ()
, my_base_call
, false
, m_logBook
, m_config.color_CQ()
@ -1965,12 +1997,13 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
return;
}
QString hiscall;
QString hisgrid;
decodedtext.deCallAndGrid(/*out*/hiscall,hisgrid);
if (hiscall != ui->dxCallEntry->text())
ui->dxGridEntry->setText("");
ui->dxCallEntry->setText(hiscall);
auto base_call = baseCall (hiscall);
if (base_call != baseCall (ui->dxCallEntry-> text ().toUpper ().trimmed ()) || base_call != hiscall)
{
// his base call different or his call more qualified
// i.e. compound version of same base call
ui->dxCallEntry->setText(hiscall);
}
if (gridOK(hisgrid))
ui->dxGridEntry->setText(hisgrid);
if (ui->dxGridEntry->text()=="")
@ -1987,7 +2020,10 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
genStdMsgs(rpt);
// determine the appropriate response to the received msg
if(decodedtext.indexOf(m_config.my_callsign ())>=0)
auto dtext = " " + decodedtext.string () + " ";
if(dtext.contains (" " + my_base_call + " ")
|| dtext.contains ("/" + my_base_call + " ")
|| dtext.contains (" " + my_base_call + "/"))
{
if (t4.length()>=7 // enough fields for a normal msg
and !gridOK(t4.at(7))) // but no grid on end of msg
@ -2057,6 +2093,15 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
{
QString t;
if(m_config.my_callsign () !="" and m_config.my_grid () !="")
{
t="CQ " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx6);
}
else
{
ui->tx6->setText("");
}
QString hisCall=ui->dxCallEntry->text().toUpper().trimmed();
ui->dxCallEntry->setText(hisCall);
if(hisCall=="") {
@ -2067,11 +2112,6 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
ui->tx3->setText("");
ui->tx4->setText("");
ui->tx5->setCurrentText("");
ui->tx6->setText("");
if(m_config.my_callsign () !="" and m_config.my_grid () !="") {
t="CQ " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx6);
}
ui->genMsg->setText("");
return;
}
@ -2080,7 +2120,6 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
QString t0=hisBase + " " + myBase + " ";
t=t0 + m_config.my_grid ().mid(0,4);
// if(myBase!=m_config.my_callsign ()) t="DE " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4); //###
msgtype(t, ui->tx1);
if(rpt == "") {
t=t+" OOO";
@ -2096,12 +2135,9 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
t=t0 + "RRR";
msgtype(t, ui->tx4);
t=t0 + "73";
// if(myBase!=m_config.my_callsign ()) t="DE " + m_config.my_callsign () + " 73"; //###
msgtype(t, ui->tx5->lineEdit ());
}
t="CQ " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx6);
if(m_config.my_callsign ()!=myBase) {
if(shortList(m_config.my_callsign ())) {
t=hisCall + " " + m_config.my_callsign ();
@ -2109,22 +2145,40 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
t="CQ " + m_config.my_callsign ();
msgtype(t, ui->tx6);
} else {
t="DE " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx2);
switch (m_config.type_2_msg_gen ())
{
case Configuration::type_2_msg_1_full:
t="DE " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx1);
t=t0 + "R" + rpt;
msgtype(t, ui->tx3);
break;
case Configuration::type_2_msg_3_full:
t = t0 + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx1);
t="DE " + m_config.my_callsign () + " R" + rpt;
msgtype(t, ui->tx3);
break;
case Configuration::type_2_msg_5_only:
t = t0 + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx1);
t=t0 + "R" + rpt;
msgtype(t, ui->tx3);
break;
}
t="DE " + m_config.my_callsign () + " 73";
msgtype(t, ui->tx5->lineEdit ());
t="CQ " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx6);
}
} else {
if(hisCall!=hisBase) {
if(shortList(hisCall)) {
t=hisCall + " " + m_config.my_callsign ();
t=hisBase + " " + m_config.my_callsign () + " " + m_config.my_grid ().mid (0,4);
msgtype(t, ui->tx1);
} else {
t=hisCall + " 73";
msgtype(t, ui->tx5->lineEdit());
}
t=hisCall + " 73";
msgtype(t, ui->tx5->lineEdit());
}
}
m_ntx=1;