Improved automatic message handling

More consistent and accurate processing of compund callsigns including
recognizing the  user's call  in both base  and fully  qualified form,
extracting reports  from special type  one and type two  compound call
messages.  Ensure that  "CQ DX"  message prefixes  are recognized  and
processd correctly.

The  cycle of  double  clicking through  a QSO  has  been enhanced  to
recognoize the  standard messages correctly  and use the  correct next
message. The automatic  transmission button "Enable Tx"  now does what
it says and does not double as a stop transmit button. This allows the
current transmission  to complete  even if the  automatic transmission
feature is  disabled. In line with  this the "stop sending  after a 73
message is sent"  feature turns off the  automatic transmission enable
at the start of the sending of  a 73 message and also the next message
is now set up as the CQ  message automatically in this scenario.  A 73
message is now  either a standard message containing the  word "73" or
any free text  message containing "73" (not necessarily  as a distinct
word").

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5055 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2015-03-14 19:13:18 +00:00
parent ad9d5b99a2
commit bd0ae24aba
6 changed files with 294 additions and 228 deletions

179
Radio.cpp
View File

@ -1,72 +1,107 @@
#include "Radio.hpp" #include "Radio.hpp"
#include <cmath> #include <cmath>
#include <QMetaType> #include <QMetaType>
#include <QString> #include <QString>
#include <QChar> #include <QChar>
#include <QDebug> #include <QDebug>
#include <QRegExpValidator> #include <QRegExpValidator>
#include <QDataStream> #include <QDataStream>
#include <QRegularExpression>
namespace Radio
{ namespace Radio
namespace {
{ namespace
struct init {
{ struct init
init () {
{ init ()
qRegisterMetaType<Frequency> ("Frequency"); {
qRegisterMetaType<Frequency> ("Frequency");
qRegisterMetaType<Frequencies> ("Frequencies");
qRegisterMetaTypeStreamOperators<Frequencies> ("Frequencies"); qRegisterMetaType<Frequencies> ("Frequencies");
qRegisterMetaTypeStreamOperators<Frequencies> ("Frequencies");
qRegisterMetaType<FrequencyDelta> ("FrequencyDelta");
} qRegisterMetaType<FrequencyDelta> ("FrequencyDelta");
} static_initaializer; }
} static_initaializer;
double constexpr MHz_factor {1.e6};
int constexpr frequency_precsion {6}; double constexpr MHz_factor {1.e6};
} int constexpr frequency_precsion {6};
// very loose validation - callsign must contain a letter next to
Frequency frequency (QVariant const& v, int scale) // a number
{ QRegularExpression valid_callsign_regexp {R"(\d[[:alpha:]]|[[:alpha:]]\d)"};
return std::llround (v.toDouble () * std::pow (10., scale)); }
}
FrequencyDelta frequency_delta (QVariant const& v, int scale) Frequency frequency (QVariant const& v, int scale)
{ {
return std::llround (v.toDouble () * std::pow (10., scale)); return std::llround (v.toDouble () * std::pow (10., scale));
} }
FrequencyDelta frequency_delta (QVariant const& v, int scale)
QString frequency_MHz_string (Frequency f, QLocale const& locale) {
{ return std::llround (v.toDouble () * std::pow (10., scale));
return locale.toString (f / MHz_factor, 'f', frequency_precsion); }
}
QString frequency_MHz_string (FrequencyDelta d, QLocale const& locale) QString frequency_MHz_string (Frequency f, QLocale const& locale)
{ {
return locale.toString (d / MHz_factor, 'f', frequency_precsion); return locale.toString (f / MHz_factor, 'f', frequency_precsion);
} }
QString pretty_frequency_MHz_string (Frequency f, QLocale const& locale) QString frequency_MHz_string (FrequencyDelta d, QLocale const& locale)
{ {
auto f_string = locale.toString (f / MHz_factor, 'f', frequency_precsion); return locale.toString (d / MHz_factor, 'f', frequency_precsion);
return f_string.insert (f_string.size () - 3, QChar::Nbsp); }
}
QString pretty_frequency_MHz_string (Frequency f, QLocale const& locale)
QString pretty_frequency_MHz_string (double f, int scale, QLocale const& locale) {
{ auto f_string = locale.toString (f / MHz_factor, 'f', frequency_precsion);
auto f_string = locale.toString (f / std::pow (10., scale - 6), 'f', frequency_precsion); return f_string.insert (f_string.size () - 3, QChar::Nbsp);
return f_string.insert (f_string.size () - 3, QChar::Nbsp); }
}
QString pretty_frequency_MHz_string (double f, int scale, QLocale const& locale)
QString pretty_frequency_MHz_string (FrequencyDelta d, QLocale const& locale) {
{ auto f_string = locale.toString (f / std::pow (10., scale - 6), 'f', frequency_precsion);
auto d_string = locale.toString (d / MHz_factor, 'f', frequency_precsion); return f_string.insert (f_string.size () - 3, QChar::Nbsp);
return d_string.insert (d_string.size () - 3, QChar::Nbsp); }
}
} QString pretty_frequency_MHz_string (FrequencyDelta d, QLocale const& locale)
{
auto d_string = locale.toString (d / MHz_factor, 'f', frequency_precsion);
return d_string.insert (d_string.size () - 3, QChar::Nbsp);
}
bool is_callsign (QString const& callsign)
{
return callsign.contains (valid_callsign_regexp);
}
bool is_compound_callsign (QString const& callsign)
{
return callsign.contains ('/');
}
// split on first '/' and return the larger portion or the whole if
// there is no '/'
QString base_callsign (QString callsign)
{
auto slash_pos = callsign.indexOf ('/');
if (slash_pos >= 0)
{
auto right_size = callsign.size () - slash_pos - 1;
if (right_size>= slash_pos)
{
callsign = callsign.mid (slash_pos + 1);
}
else
{
callsign = callsign.left (slash_pos);
}
}
return callsign;
}
}

101
Radio.hpp
View File

@ -1,47 +1,54 @@
#ifndef RADIO_HPP_ #ifndef RADIO_HPP_
#define RADIO_HPP_ #define RADIO_HPP_
#include <QObject> #include <QObject>
#include <QLocale> #include <QLocale>
#include <QList> #include <QList>
class QVariant; class QVariant;
class QString; class QString;
// //
// Declarations common to radio software. // Declarations common to radio software.
// //
namespace Radio namespace Radio
{ {
// //
// Frequency types // Frequency types
// //
using Frequency = quint64; using Frequency = quint64;
using Frequencies = QList<Frequency>; using Frequencies = QList<Frequency>;
using FrequencyDelta = qint64; using FrequencyDelta = qint64;
// //
// Frequency type conversion. // Frequency type conversion.
// //
// QVariant argument is convertible to double and is assumed to // QVariant argument is convertible to double and is assumed to
// be scaled by (10 ** -scale). // be scaled by (10 ** -scale).
// //
Frequency frequency (QVariant const&, int scale); Frequency frequency (QVariant const&, int scale);
FrequencyDelta frequency_delta (QVariant const&, int scale); FrequencyDelta frequency_delta (QVariant const&, int scale);
// //
// Frequency type formatting // Frequency type formatting
// //
QString frequency_MHz_string (Frequency, QLocale const& = QLocale ()); QString frequency_MHz_string (Frequency, QLocale const& = QLocale ());
QString frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ()); QString frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
QString pretty_frequency_MHz_string (Frequency, QLocale const& = QLocale ()); QString pretty_frequency_MHz_string (Frequency, QLocale const& = QLocale ());
QString pretty_frequency_MHz_string (double, int scale, QLocale const& = QLocale ()); QString pretty_frequency_MHz_string (double, int scale, QLocale const& = QLocale ());
QString pretty_frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ()); QString pretty_frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
}
//
Q_DECLARE_METATYPE (Radio::Frequency); // Callsigns
Q_DECLARE_METATYPE (Radio::Frequencies); //
Q_DECLARE_METATYPE (Radio::FrequencyDelta); bool is_callsign (QString const&);
bool is_compound_callsign (QString const&);
#endif QString base_callsign (QString);
}
Q_DECLARE_METATYPE (Radio::Frequency);
Q_DECLARE_METATYPE (Radio::Frequencies);
Q_DECLARE_METATYPE (Radio::FrequencyDelta);
#endif

View File

@ -2,15 +2,29 @@
#include <QDebug> #include <QDebug>
#include "decodedtext.h" #include "decodedtext.h"
QString DecodedText::CQersCall() QString DecodedText::CQersCall()
{ {
// extract the CQer's call TODO: does this work with all call formats? What about 'CQ DX'? // extract the CQer's call TODO: does this work with all call formats?
int s1 = 4 + _string.indexOf(" CQ "); int s1;
int s2 = _string.indexOf(" ",s1); int position;
QString call = _string.mid(s1,s2-s1); if ((position = _string.indexOf (" CQ DX ")) >= 0)
return call; {
s1 = 7 + position;
}
else if ((position = _string.indexOf (" CQ ")) >= 0)
{
s1 = 4 + position;
}
else if ((position = _string.indexOf (" DE ")) >= 0)
{
s1 = 4 + position;
}
else if ((position = _string.indexOf (" QRZ ")) >= 0)
{
s1 = 5 + position;
}
auto s2 = _string.indexOf (" ", s1);
return _string.mid (s1, s2 - s1);
} }
@ -95,21 +109,22 @@ bool DecodedText::report(QString const& myBaseCall, QString const& dxBaseCall, /
// get the first text word, usually the call // get the first text word, usually the call
QString DecodedText::call() QString DecodedText::call()
{ {
QString call = _string.mid(column_qsoText); auto call = _string;
int i = call.indexOf(" "); call = call.replace (" CQ DX ", " CQ_DX ").mid (column_qsoText);
call = call.mid(0,i); int i = call.indexOf(" ");
return call; return call.mid(0,i);
} }
// get the second word, most likely the de call and the third word, most likely grid // get the second word, most likely the de call and the third word, most likely grid
void DecodedText::deCallAndGrid(/*out*/QString& call, QString& grid) void DecodedText::deCallAndGrid(/*out*/QString& call, QString& grid)
{ {
QString msg=_string.mid(column_qsoText); auto msg = _string;
int i1 = msg.indexOf(" "); msg = msg.replace (" CQ DX ", " CQ_DX ").mid (column_qsoText);
call = msg.mid(i1+1); int i1 = msg.indexOf(" ");
int i2 = call.indexOf(" "); call = msg.mid(i1+1);
grid = call.mid(i2+1,4); int i2 = call.indexOf(" ");
call = call.mid(0,i2); grid = call.mid(i2+1,4);
call = call.mid(0,i2);
} }
int DecodedText::timeInSeconds() int DecodedText::timeInSeconds()

View File

@ -44,10 +44,7 @@ void DisplayText::_appendDXCCWorkedB4(DecodedText& t1, QString& bg,
QColor color_DXCC, QColor color_DXCC,
QColor color_NewCall) QColor color_NewCall)
{ {
// extract the CQer's call TODO: does this work with all call formats? What about 'CQ DX'? QString call = t1.CQersCall ();
int s1 = 4 + t1.indexOf(" CQ ");
int s2 = t1.indexOf(" ",s1);
QString call = t1.mid(s1,s2-s1);
QString countryName; QString countryName;
bool callWorkedBefore; bool callWorkedBefore;
@ -114,7 +111,7 @@ void DisplayText::displayDecodedText(DecodedText decodedText, QString myCall,
{ {
QString bg="white"; QString bg="white";
bool CQcall = false; bool CQcall = false;
if (decodedText.indexOf(" CQ ") > 0) if (decodedText.string ().contains (" CQ ") > 0 || decodedText.string ().contains (" CQ DX "))
{ {
CQcall = true; CQcall = true;
bg=color_CQ.name(); bg=color_CQ.name();

View File

@ -26,6 +26,7 @@
#include "sleep.h" #include "sleep.h"
#include "getfile.h" #include "getfile.h"
#include "logqso.h" #include "logqso.h"
#include "Radio.hpp"
#include "Bands.hpp" #include "Bands.hpp"
#include "TransceiverFactory.hpp" #include "TransceiverFactory.hpp"
#include "FrequencyList.hpp" #include "FrequencyList.hpp"
@ -334,6 +335,8 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
m_repeatMsg=0; m_repeatMsg=0;
m_secBandChanged=0; m_secBandChanged=0;
m_lockTxFreq=false; m_lockTxFreq=false;
m_baseCall = Radio::base_callsign (m_config.my_callsign ());
ui->readFreq->setEnabled(false); ui->readFreq->setEnabled(false);
m_QSOText.clear(); m_QSOText.clear();
decodeBusy(false); decodeBusy(false);
@ -665,6 +668,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
{ {
if (m_config.my_callsign () != callsign) if (m_config.my_callsign () != callsign)
{ {
m_baseCall = Radio::base_callsign (m_config.my_callsign ());
morse_(const_cast<char *> (m_config.my_callsign ().toLatin1().constData()) morse_(const_cast<char *> (m_config.my_callsign ().toLatin1().constData())
, const_cast<int *> (icw) , const_cast<int *> (icw)
, &m_ncw , &m_ncw
@ -765,12 +769,6 @@ void MainWindow::on_actionAbout_triggered() //Display "About"
void MainWindow::on_autoButton_clicked (bool checked) void MainWindow::on_autoButton_clicked (bool checked)
{ {
m_auto = checked; m_auto = checked;
if (!m_auto)
{
m_btxok = false;
monitor (true);
m_repeatMsg = 0;
}
} }
void MainWindow::auto_tx_mode (bool state) void MainWindow::auto_tx_mode (bool state)
@ -1383,11 +1381,9 @@ void MainWindow::readFromStdout() //readFromStdout
DecodedText decodedtext; DecodedText decodedtext;
decodedtext = t.replace("\n",""); //t.replace("\n","").mid(0,t.length()-4); 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 // the left band display
ui->decodedTextBrowser->displayDecodedText (decodedtext ui->decodedTextBrowser->displayDecodedText (decodedtext
, my_base_call , m_baseCall
, m_config.DXCC () , m_config.DXCC ()
, m_logBook , m_logBook
, m_config.color_CQ() , m_config.color_CQ()
@ -1399,7 +1395,7 @@ void MainWindow::readFromStdout() //readFromStdout
{ {
// the right QSO window // the right QSO window
ui->decodedTextBrowser2->displayDecodedText(decodedtext ui->decodedTextBrowser2->displayDecodedText(decodedtext
, my_base_call , m_baseCall
, false , false
, m_logBook , m_logBook
, m_config.color_CQ() , m_config.color_CQ()
@ -1414,8 +1410,8 @@ void MainWindow::readFromStdout() //readFromStdout
} }
// find and extract any report for myCall // find and extract any report for myCall
bool stdMsg = decodedtext.report(my_base_call bool stdMsg = decodedtext.report(m_baseCall
, baseCall (ui->dxCallEntry-> text ().toUpper ().trimmed ()) , Radio::base_callsign (ui->dxCallEntry-> text ().toUpper ().trimmed ())
, /*mod*/m_rptRcvd); , /*mod*/m_rptRcvd);
// extract details and send to PSKreporter // extract details and send to PSKreporter
@ -1524,7 +1520,7 @@ void MainWindow::guiUpdate()
double t2p=fmod(tsec,2*m_TRperiod); double t2p=fmod(tsec,2*m_TRperiod);
bool bTxTime = ((t2p >= tx1) and (t2p < tx2)) or m_tune; bool bTxTime = ((t2p >= tx1) and (t2p < tx2)) or m_tune;
if(m_auto or m_tune) { if(m_transmitting || m_auto || m_tune) {
QFile f(m_config.temp_dir ().absoluteFilePath ("txboth")); QFile f(m_config.temp_dir ().absoluteFilePath ("txboth"));
if(f.exists() and fmod(tsec,m_TRperiod) < (1.0 + 85.0*m_nsps/12000.0)) { if(f.exists() and fmod(tsec,m_TRperiod) < (1.0 + 85.0*m_nsps/12000.0)) {
@ -1563,6 +1559,7 @@ void MainWindow::guiUpdate()
Q_EMIT m_config.transceiver_ptt (true); Q_EMIT m_config.transceiver_ptt (true);
ptt1Timer->start(200); //Sequencer delay ptt1Timer->start(200); //Sequencer delay
} }
if(!bTxTime) { if(!bTxTime) {
m_btxok=false; m_btxok=false;
} }
@ -1623,15 +1620,27 @@ void MainWindow::guiUpdate()
} }
} }
QStringList w=t.split(" ",QString::SkipEmptyParts); auto t2 = QDateTime::currentDateTimeUtc ().toString ("hhmm");
t=""; icw[0] = 0;
if(w.length()==3) t=w[2]; auto msg_parts = t.split (" ", QString::SkipEmptyParts);
icw[0]=0; m_sent73 = (itype < 6 && msg_parts.contains ("73"))
m_sent73=(t=="73" or itype==6); || (itype == 6 && t.contains ("73"));
if(m_sent73) { if (m_sent73)
if(m_config.id_after_73 ()) icw[0]=m_ncw; {
if(m_config.prompt_to_log () && !m_tune) logQSOTimer->start(200); m_qsoStop=t2;
} if(m_config.id_after_73 ())
{
icw[0] = m_ncw;
}
if (m_config.prompt_to_log () && !m_tune)
{
logQSOTimer->start (0);
}
if (m_config.disable_TX_on_73 ())
{
auto_tx_mode (false);
}
}
if(m_config.id_interval () >0) { if(m_config.id_interval () >0) {
int nmin=(m_sec0-m_secID)/60; int nmin=(m_sec0-m_secID)/60;
@ -1641,27 +1650,51 @@ void MainWindow::guiUpdate()
} }
} }
QString t2=QDateTime::currentDateTimeUtc().toString("hhmm"); if (itype < 6 && msg_parts.length() >= 3
if(itype<6 and w.length()>=3 and w[1]==m_config.my_callsign ()) { && (msg_parts[1] == m_config.my_callsign () || msg_parts[1] == m_baseCall))
int i1; {
bool ok; int i1;
i1=t.toInt(&ok); bool ok;
if(ok and i1>=-50 and i1<50) { i1 = msg_parts[2].toInt(&ok);
m_rptSent=t; if(ok and i1>=-50 and i1<50)
m_qsoStart=t2; {
} else { m_rptSent = msg_parts[2];
if(t.mid(0,1)=="R") { m_qsoStart = t2;
i1=t.mid(1).toInt(&ok);
if(ok and i1>=-50 and i1<50) {
m_rptSent=t.mid(1);
m_qsoStart=t2;
} }
} else
{
if (msg_parts[2].mid (0, 1) == "R")
{
i1 = msg_parts[2].mid (1).toInt (&ok);
if (ok and i1 >= -50 and i1 < 50)
{
m_rptSent = msg_parts[2].mid (1);
m_qsoStart = t2;
}
}
}
qDebug () << "Report sent:" << m_rptSent;
} }
}
if(itype==6 or (w.length()==3 and w[2]=="73")) m_qsoStop=t2;
m_restart=false; m_restart=false;
} }
else
{
if (!m_auto && m_sent73)
{
m_sent73 = false;
if (1 == ui->tabWidget->currentIndex())
{
ui->genMsg->setText(ui->tx6->text());
m_ntx=7;
ui->rbGenMsg->setChecked(true);
}
else
{
m_ntx=6;
ui->txrb6->setChecked(true);
}
}
}
if (g_iptt == 1 && iptt0 == 0) if (g_iptt == 1 && iptt0 == 0)
{ {
@ -1798,11 +1831,6 @@ void MainWindow::stopTx2()
//Lower PTT //Lower PTT
Q_EMIT m_config.transceiver_ptt (false); Q_EMIT m_config.transceiver_ptt (false);
if (m_config.disable_TX_on_73 () && m_sent73)
{
on_stopTxButton_clicked();
}
if (m_config.watchdog () && m_repeatMsg>=m_watchdogLimit-1) if (m_config.watchdog () && m_repeatMsg>=m_watchdogLimit-1)
{ {
on_stopTxButton_clicked(); on_stopTxButton_clicked();
@ -1904,29 +1932,25 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
if (decodedtext.indexOf(" CQ ") > 0) if (decodedtext.indexOf(" CQ ") > 0)
{ {
// TODO this magic 36 characters is also referenced in DisplayText::_appendDXCCWorkedB4() // TODO this magic 36 characters is also referenced in DisplayText::_appendDXCCWorkedB4()
int s3 = decodedtext.indexOf(" ",35); auto eom_pos = decodedtext.string ().indexOf (' ', 35);
if (s3 < 35) if (eom_pos < 35) eom_pos = decodedtext.string ().size () - 1; // we always want at least the characters
s3 = 35; // we always want at least the characters to position 35 // to position 35
s3 += 1; // convert the index into a character count decodedtext = decodedtext.string ().left (eom_pos + 1); // remove DXCC entity and worked B4 status. TODO need a better way to do this
decodedtext = decodedtext.left(s3); // remove DXCC entity and worked B4 status. TODO need a better way to do this
} }
// if(decodedtext.indexOf("Tx")==6) return; //Ignore Tx line // if(decodedtext.indexOf("Tx")==6) return; //Ignore Tx line
int i4=t.mid(i1).length(); // int i4=t.mid(i1).length();
if(i4>55) i4=55; // if(i4>55) i4=55;
QString t3=t.mid(i1,i4); // QString t3=t.mid(i1,i4);
int i5=t3.indexOf(" CQ DX "); auto t3 = decodedtext.string ();
if(i5>0) t3=t3.mid(0,i5+3) + "_" + t3.mid(i5+4); //Make it "CQ_DX" (one word) auto t4 = t3.replace (" CQ DX ", " CQ_DX ").split (" ", QString::SkipEmptyParts);
QStringList t4=t3.split(" ",QString::SkipEmptyParts); if(t4.size () <5) return; //Skip the rest if no decoded text
if(t4.length() <5) return; //Skip the rest if no decoded text
QString hiscall; QString hiscall;
QString hisgrid; QString hisgrid;
decodedtext.deCallAndGrid(/*out*/hiscall,hisgrid); decodedtext.deCallAndGrid(/*out*/hiscall,hisgrid);
// basic valid call sign check i.e. contains at least one digit and if (!Radio::is_callsign (hiscall))
// one letter next to each other
if (!hiscall.contains (QRegularExpression {R"(\d[[:upper:]]|[[:upper:]]\d)"}))
{ {
return; return;
} }
@ -1957,7 +1981,7 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
QString firstcall = decodedtext.call(); QString firstcall = decodedtext.call();
// Don't change Tx freq if a station is calling me, unless m_lockTxFreq // Don't change Tx freq if a station is calling me, unless m_lockTxFreq
// is true or CTRL is held down // is true or CTRL is held down
if ((firstcall!=m_config.my_callsign ()) or m_lockTxFreq or ctrl) if ((firstcall!=m_config.my_callsign () && firstcall != m_baseCall) || m_lockTxFreq or ctrl)
{ {
if (ui->TxFreqSpinBox->isEnabled ()) if (ui->TxFreqSpinBox->isEnabled ())
{ {
@ -1969,13 +1993,11 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
} }
} }
auto my_base_call = baseCall (m_config.my_callsign ());
int i9=m_QSOText.indexOf(decodedtext.string()); int i9=m_QSOText.indexOf(decodedtext.string());
if (i9<0 and !decodedtext.isTX()) if (i9<0 and !decodedtext.isTX())
{ {
ui->decodedTextBrowser2->displayDecodedText(decodedtext ui->decodedTextBrowser2->displayDecodedText(decodedtext
, my_base_call , m_baseCall
, false , false
, m_logBook , m_logBook
, m_config.color_CQ() , m_config.color_CQ()
@ -1998,8 +2020,8 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
return; return;
} }
auto base_call = baseCall (hiscall); auto base_call = Radio::base_callsign (hiscall);
if (base_call != baseCall (ui->dxCallEntry-> text ().toUpper ().trimmed ()) || base_call != hiscall) if (base_call != Radio::base_callsign (ui->dxCallEntry-> text ().toUpper ().trimmed ()) || base_call != hiscall)
{ {
// his base call different or his call more qualified // his base call different or his call more qualified
// i.e. compound version of same base call // i.e. compound version of same base call
@ -2022,14 +2044,15 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
// determine the appropriate response to the received msg // determine the appropriate response to the received msg
auto dtext = " " + decodedtext.string () + " "; auto dtext = " " + decodedtext.string () + " ";
if(dtext.contains (" " + my_base_call + " ") if(dtext.contains (" " + m_baseCall + " ")
|| dtext.contains ("/" + my_base_call + " ") || dtext.contains ("/" + m_baseCall + " ")
|| dtext.contains (" " + my_base_call + "/")) || dtext.contains (" " + m_baseCall + "/")
|| firstcall == "DE")
{ {
if (t4.length()>=7 // enough fields for a normal msg if (t4.size () > 7 // enough fields for a normal msg
and !gridOK(t4.at(7))) // but no grid on end of msg and !gridOK (t4.at (7))) // but no grid on end of msg
{ {
QString r=t4.at(7); QString r=t4.at (7);
if(r.mid(0,3)=="RRR") { if(r.mid(0,3)=="RRR") {
m_ntx=5; m_ntx=5;
ui->txrb5->setChecked(true); ui->txrb5->setChecked(true);
@ -2116,10 +2139,9 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
ui->genMsg->setText(""); ui->genMsg->setText("");
return; return;
} }
QString hisBase=baseCall(hisCall); QString hisBase = Radio::base_callsign (hisCall);
QString myBase=baseCall(m_config.my_callsign ());
QString t0=hisBase + " " + myBase + " "; QString t0=hisBase + " " + m_baseCall + " ";
t=t0 + m_config.my_grid ().mid(0,4); t=t0 + m_config.my_grid ().mid(0,4);
msgtype(t, ui->tx1); msgtype(t, ui->tx1);
if(rpt == "") { if(rpt == "") {
@ -2139,9 +2161,9 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
msgtype(t, ui->tx5->lineEdit ()); msgtype(t, ui->tx5->lineEdit ());
} }
if(m_config.my_callsign ()!=myBase) { if(m_config.my_callsign () != m_baseCall) {
if(shortList(m_config.my_callsign ())) { if(shortList(m_config.my_callsign ())) {
t=hisCall + " " + m_config.my_callsign (); t=hisBase + " " + m_config.my_callsign ();
msgtype(t, ui->tx1); msgtype(t, ui->tx1);
t="CQ " + m_config.my_callsign (); t="CQ " + m_config.my_callsign ();
msgtype(t, ui->tx6); msgtype(t, ui->tx6);
@ -2187,15 +2209,6 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs()
m_rpt=rpt; m_rpt=rpt;
} }
QString MainWindow::baseCall(QString t)
{
int n1=t.indexOf("/");
if(n1<0) return t;
int n2=t.length()-n1-1;
if(n2>=n1) return t.mid(n1+1);
return t.mid(0,n1);
}
void MainWindow::lookup() //lookup() void MainWindow::lookup() //lookup()
{ {
QString hisCall=ui->dxCallEntry->text().toUpper().trimmed(); QString hisCall=ui->dxCallEntry->text().toUpper().trimmed();
@ -2780,8 +2793,8 @@ void MainWindow::on_rbGenMsg_toggled(bool checked)
{ {
m_freeText=!checked; m_freeText=!checked;
if(!m_freeText) { if(!m_freeText) {
if(m_ntx != 7 && m_transmitting) m_restart=true;
m_ntx=7; m_ntx=7;
if(m_transmitting) m_restart=true;
} }
} }

View File

@ -386,7 +386,6 @@ private:
void qsy(Frequency f); void qsy(Frequency f);
bool gridOK(QString g); bool gridOK(QString g);
bool shortList(QString callsign); bool shortList(QString callsign);
QString baseCall(QString t);
void transmit (double snr = 99.); void transmit (double snr = 99.);
void rigFailure (QString const& reason, QString const& detail); void rigFailure (QString const& reason, QString const& detail);
void pskSetLocal (); void pskSetLocal ();