Compare commits

...

30 Commits

Author SHA1 Message Date
Jordan Sherer 8529ef0982 Fixed allcall and groupcall counts to respect aging 2018-10-18 10:51:53 -04:00
Jordan Sherer 8bba574963 Fixed issue where whitespace broke ACKd messages 2018-10-17 14:36:15 -04:00
Jordan Sherer 80d798d7e3 Fixed APRS passcode warning 2018-10-17 14:31:23 -04:00
Jordan Sherer 23a554220b Fixed APRS passcode warning 2018-10-17 14:30:32 -04:00
Jordan Sherer 7e903349ae Added QTC, QTH, and Saved messages to the 'immediately transmit' setting 2018-10-17 14:23:17 -04:00
Jordan Sherer 55810e63a6 Transmit entry should be JS8 not FT8 2018-10-17 14:17:53 -04:00
Jordan Sherer 9162d851d4 Made some adjustments to the tx cycling...should help those having trouble with their audio interface not working fast enough. 2018-10-17 11:19:27 -04:00
Jordan Sherer 2022908509 Bump to 0.7.5 2018-10-17 09:11:05 -04:00
Jordan Sherer 2e2551519d Added ACTIVE/IDLE query. Fixed CQ start transmission. 2018-10-17 09:08:37 -04:00
Jordan Sherer 18052773f1 Added clarification labels to the configuration 2018-10-17 08:58:54 -04:00
Jordan Sherer 51010e7310 Allow out of period starts toggles 2018-10-16 20:15:04 -04:00
Jordan Sherer a3eaf1cf74 Fixed BEACON ACK printing overwrite 2018-10-16 17:47:38 -04:00
Jordan Sherer c731fa51ce Fixed menu shortkeys 2018-10-16 17:23:12 -04:00
Jordan Sherer a5f59019d3 Remove unused count message frames function 2018-10-16 17:09:19 -04:00
Jordan Sherer 4a87edc4c7 Fixed compound callsigns and directed messages (SNR reports) 2018-10-16 16:11:28 -04:00
Jordan Sherer 2da25c3171 Move around the force update to be more reliable 2018-10-16 09:49:53 -04:00
Jordan Sherer 87a6e10bd6 Added async frame counting 2018-10-15 22:06:31 -04:00
Jordan Sherer cf9c74b99e Fixed issue with multiple beacon acks not displaying in rx window 2018-10-15 12:43:49 -04:00
Jordan Sherer dae50d3a99 Added constants for NEAR thresholds 2018-10-15 12:10:13 -04:00
Jordan Sherer 83268fbdaf Added groupcall and allcall callsign counts 2018-10-15 12:01:28 -04:00
Jordan Sherer 3b2242e258 Fixed display of APRS frames where a space after the colon causes concern 2018-10-15 11:53:54 -04:00
Jordan Sherer c42c3b7ad1 Added lookup cache to the lookup function 2018-10-15 03:03:26 -04:00
Jordan Sherer 9496d5ed81 Deslect callsign on click cq button 2018-10-15 02:41:35 -04:00
Jordan Sherer 83174bc6fa Fixed stations heard ordering (by time) 2018-10-15 02:37:21 -04:00
Jordan Sherer d74850b8e1 Fixed reversed qtc qth macro buttons 2018-10-15 02:30:46 -04:00
Jordan Sherer 2f1dca3c49 Updated comments 2018-10-15 02:29:40 -04:00
Jordan Sherer 4a38778808 Removed single shot timer from gui loop 2018-10-15 02:10:48 -04:00
Jordan Sherer 960b9b14d1 Rip out fox/hound junk 2018-10-15 01:04:57 -04:00
Jordan Sherer 9e93745587 Instrumentation and pull ui update async 2018-10-15 00:59:38 -04:00
Jordan Sherer 8aa28108ea Fixed font dialog for OSX 2018-10-11 10:49:48 -04:00
9 changed files with 265 additions and 227 deletions
+15 -6
View File
@@ -2338,14 +2338,23 @@ void Configuration::impl::reject ()
void Configuration::impl::on_font_push_button_clicked ()
{
next_font_ = QFontDialog::getFont (0, next_font_, this);
next_font_ = QFontDialog::getFont (0, next_font_, this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->font_push_button->setText(QString("Application Font (%1 %2)").arg(next_font_.family()).arg(next_font_.pointSize()));
}
void Configuration::impl::on_tableFontButton_clicked ()
{
next_table_font_ = QFontDialog::getFont (0, next_table_font_, this);
next_table_font_ = QFontDialog::getFont (0, next_table_font_, this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->tableFontButton->setText(QString("Table Font (%1 %2)").arg(next_table_font_.family()).arg(next_table_font_.pointSize()));
}
@@ -2453,7 +2462,7 @@ void Configuration::impl::on_rxFontButton_clicked ()
next_rx_text_font_ = QFontDialog::getFont (0, next_rx_text_font_ , this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, 0
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->rxFontButton->setText(QString("Font (%1 %2)").arg(next_rx_text_font_.family()).arg(next_rx_text_font_.pointSize()));
@@ -2495,7 +2504,7 @@ void Configuration::impl::on_txFontButton_clicked ()
next_tx_text_font_ = QFontDialog::getFont (0, next_tx_text_font_ , this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, 0
, QFontDialog::DontUseNativeDialog
#endif
);
@@ -2507,7 +2516,7 @@ void Configuration::impl::on_composeFontButton_clicked ()
next_compose_text_font_ = QFontDialog::getFont (0, next_compose_text_font_ , this
, tr ("Font Chooser")
#if QT_VERSION >= 0x050201
, 0
, QFontDialog::DontUseNativeDialog
#endif
);
ui_->composeFontButton->setText(QString("Font (%1 %2)").arg(next_compose_text_font_.family()).arg(next_compose_text_font_.pointSize()));
+26 -27
View File
@@ -195,7 +195,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Station location message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>QTH Message:</string>
<string>Station Location (QTH) Message:</string>
</property>
</widget>
</item>
@@ -212,7 +212,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Station Description Message&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>QTC Message:</string>
<string>Station Detail (QTC) Message:</string>
</property>
</widget>
</item>
@@ -269,6 +269,19 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="monitor_off_check_box">
<property name="toolTip">
<string>Don't start decoding until the monitor button is clicked.</string>
</property>
<property name="text">
<string>Mon&amp;itor (RX) off at startup</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoreply_off_check_box">
<property name="text">
@@ -283,19 +296,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="monitor_off_check_box">
<property name="toolTip">
<string>Don't start decoding until the monitor button is clicked.</string>
</property>
<property name="text">
<string>Mon&amp;itor (RX) off at startup</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="monitor_last_used_check_box">
<property name="visible">
@@ -309,13 +309,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="transmit_directed_check_box">
<property name="text">
<string>Immediately transmit directed responses from the menu</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="tx_qsy_check_box">
<property name="enabled">
@@ -349,6 +342,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="transmit_directed_check_box">
<property name="text">
<string>Immediately transmit CQ, Reply, QTC, QTH, Saved, and Directed messages from the menu</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_155">
<item>
@@ -3482,7 +3482,6 @@ soundcard changes</string>
<tabstop>use_dynamic_grid</tabstop>
<tabstop>region_combo_box</tabstop>
<tabstop>type_2_msg_gen_combo_box</tabstop>
<tabstop>monitor_off_check_box</tabstop>
<tabstop>monitor_last_used_check_box</tabstop>
<tabstop>quick_call_check_box</tabstop>
<tabstop>tx_watchdog_spin_box</tabstop>
@@ -3618,12 +3617,12 @@ soundcard changes</string>
</connection>
</connections>
<buttongroups>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="TX_audio_source_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 3)
set (WSJTX_VERSION_PATCH 5)
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
+2
View File
@@ -197,6 +197,8 @@ bool DecodedText::tryUnpackDirected(){
message_ = QString(parts.join(""));
}
message_ = message_.replace("APRS: ", "APRS:");
directed_ = parts;
frameType_ = type;
return true;
+16 -1
View File
@@ -24,6 +24,9 @@
#include <cmath>
#include <QDebug>
#include <QCache>
QMap<QString, quint32> LOOKUP_CACHE;
Codeword JSC::codeword(quint32 index, bool separate, quint32 bytesize, quint32 s, quint32 c){
QList<Codeword> out;
@@ -145,7 +148,19 @@ QString JSC::decompress(Codeword const& bitvec){
}
quint32 JSC::lookup(QString w, bool * ok){
return lookup(w.toLatin1().data(), ok);
if(LOOKUP_CACHE.contains(w)){
if(ok) *ok = true;
return LOOKUP_CACHE[w];
}
bool found = false;
quint32 result = lookup(w.toLatin1().data(), &found);
if(found){
LOOKUP_CACHE[w] = result;
}
if(ok) *ok = found;
return result;
}
quint32 JSC::lookup(char const* b, bool *ok){
+157 -153
View File
@@ -151,6 +151,9 @@ extern "C" {
void plotsave_(float swide[], int* m_w , int* m_h1, int* irow);
}
const int NEAR_THRESHOLD_RX = 10;
const int NEAR_THRESHOLD_GROUPCALL = 125;
int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID
struct dec_data dec_data; // for sharing with Fortran
@@ -420,7 +423,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
m_btxok {false},
m_diskData {false},
m_loopall {false},
m_txFirst {false},
m_auto {false},
m_restart {false},
m_startAnother {false},
@@ -842,6 +844,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
, &QTextEdit::textChanged
, [this] () {on_extFreeTextMsgEdit_currentTextChanged (ui->extFreeTextMsgEdit->toPlainText ());});
m_guiTimer.setSingleShot(true);
connect(&m_guiTimer, &QTimer::timeout, this, &MainWindow::guiUpdate);
m_guiTimer.start(100); //### Don't change the 100 ms! ###
@@ -1672,7 +1675,6 @@ void MainWindow::writeSettings()
m_settings->setValue ("geometryNoControls", m_geometryNoControls);
m_settings->setValue ("state", saveState ());
m_settings->setValue("MRUdir", m_path);
m_settings->setValue("TxFirst",m_txFirst);
m_settings->setValue("DXcall",ui->dxCallEntry->text());
m_settings->setValue("DXgrid",ui->dxGridEntry->text());
m_settings->setValue ("AstroDisplayed", m_astroWidget && m_astroWidget->isVisible());
@@ -1768,7 +1770,6 @@ void MainWindow::readSettings()
ui->dxCallEntry->setText (m_settings->value ("DXcall", QString {}).toString ());
ui->dxGridEntry->setText (m_settings->value ("DXgrid", QString {}).toString ());
m_path = m_settings->value("MRUdir", m_config.save_directory ().absolutePath ()).toString ();
m_txFirst = m_settings->value("TxFirst",false).toBool();
auto displayAstro = m_settings->value ("AstroDisplayed", false).toBool ();
auto displayMsgAvg = m_settings->value ("MsgAvgDisplayed", false).toBool ();
if (m_settings->contains ("FreeText")) ui->freeTextMsg->setCurrentText (
@@ -4087,11 +4088,22 @@ void MainWindow::decodeBusy(bool b) //decodeBusy()
//------------------------------------------------------------- //guiUpdate()
void MainWindow::guiUpdate()
{
static quint64 lastLoop;
static char message[29];
static char msgsent[29];
double txDuration;
QString rt;
quint64 thisLoop = QDateTime::currentMSecsSinceEpoch();
if(lastLoop == 0){
lastLoop = thisLoop;
}
quint64 delta = thisLoop - lastLoop;
if(delta > (100 + 10)){
qDebug() << "guiupdate overrun" << (delta-100);
}
lastLoop = thisLoop;
if(m_TRperiod==0) m_TRperiod=60;
txDuration=0.0;
if(m_modeTx=="FT8") txDuration=1.0 + NUM_FT8_SYMBOLS*1920/12000.0; // FT8
@@ -4104,15 +4116,10 @@ void MainWindow::guiUpdate()
if((icw[0]>0) and (!m_bFast9)) tx2 += icw[0]*2560.0/48000.0; //Full length including CW ID
if(tx2>m_TRperiod) tx2=m_TRperiod;
if(!m_txFirst and !m_mode.startsWith ("WSPR")) {
tx1 += m_TRperiod;
tx2 += m_TRperiod;
}
qint64 ms = DriftingDateTime::currentMSecsSinceEpoch() % 86400000;
int nsec=ms/1000;
double tsec=0.001*ms;
double t2p=fmod(tsec,2*m_TRperiod);
double t2p=fmod(tsec, m_TRperiod);
m_s6=fmod(tsec,6.0);
m_nseq = nsec % m_TRperiod;
m_tRemaining=m_TRperiod - fmod(tsec,double(m_TRperiod));
@@ -4125,11 +4132,6 @@ void MainWindow::guiUpdate()
if(m_transmitting or m_auto or m_tune) {
m_dateTimeLastTX = DriftingDateTime::currentDateTime ();
// Check for "txboth" (testing purposes only)
QFile f(m_appDir + "/txboth");
if(f.exists() and
fmod(tsec,m_TRperiod)<(1.0 + 85.0*m_nsps/12000.0)) m_bTxTime=true;
// Don't transmit another mode in the 30 m WSPR sub-band
Frequency onAirFreq = m_freqNominal + ui->TxFreqSpinBox->value();
@@ -4154,29 +4156,7 @@ void MainWindow::guiUpdate()
}
}
if(m_mode=="FT8" and m_config.bFox()) {
// Don't allow Fox mode in any of the default FT8 sub-bands.
qint32 ft8Freq[]={1840,3573,7074,10136,14074,18100,21074,24915,28074,50313,70100};
for(int i=0; i<11; i++) {
int kHzdiff=m_freqNominal/1000 - ft8Freq[i];
if(qAbs(kHzdiff) < 4) {
m_bTxTime=false;
if (m_auto) auto_tx_mode (false);
auto const& message = tr ("Please choose another dial frequency."
" WSJT-X will not operate in Fox mode"
" in the standard FT8 sub-bands.");
#if QT_VERSION >= 0x050400
QTimer::singleShot (0, [=] { // don't block guiUpdate
MessageBox::warning_message (this, tr ("Fox Mode warning"), message);
});
#else
MessageBox::warning_message (this, tr ("Fox Mode warning"), message);
#endif
break;
}
}
}
// watchdog!
if (m_config.watchdog() && !m_mode.startsWith ("WSPR")
&& m_idleMinutes >= m_config.watchdog ()) {
tx_watchdog (true); // disable transmit
@@ -4199,7 +4179,8 @@ void MainWindow::guiUpdate()
// TODO: stop
if(msgLength==0 and !m_tune) on_stopTxButton_clicked();
if(g_iptt==0 and ((m_bTxTime and fTR<0.75 and msgLength>0) or m_tune)) {
float lateThreshold=(12.6/3.0)/15.0; //0.75;
if(g_iptt==0 and ((m_bTxTime and fTR<lateThreshold and msgLength>0) or m_tune)) {
//### Allow late starts
icw[0]=m_ncw;
g_iptt = 1;
@@ -4351,22 +4332,6 @@ void MainWindow::guiUpdate()
}
m_restart=false;
//----------------------------------------------------------------------
} else {
if (!m_auto && m_sentFirst73)
{
m_sentFirst73 = false;
if (1 == ui->tabWidget->currentIndex())
{
ui->genMsg->setText(ui->tx6->text());
m_ntx=7;
m_QSOProgress = CALLING;
m_gen_message_is_cq = true;
ui->rbGenMsg->setChecked(true);
} else {
//JHT 11/29/2015 m_ntx=6;
// ui->txrb6->setChecked(true);
}
}
}
if (g_iptt == 1 && m_iptt0 == 0)
@@ -4382,22 +4347,6 @@ void MainWindow::guiUpdate()
write_transmit_entry ("ALL.TXT");
}
if (m_config.TX_messages () && !m_tune && !m_config.bFox()) {
ui->decodedTextBrowser2->displayTransmittedText(current_message, m_modeTx,
ui->TxFreqSpinBox->value(),m_config.color_rx_background(),m_bFastMode);
}
switch (m_ntx)
{
case 1: m_QSOProgress = REPLYING; break;
case 2: m_QSOProgress = REPORT; break;
case 3: m_QSOProgress = ROGER_REPORT; break;
case 4: m_QSOProgress = ROGERS; break;
case 5: m_QSOProgress = SIGNOFF; break;
case 6: m_QSOProgress = CALLING; break;
default: break; // determined elsewhere
}
// TODO: jsherer - perhaps an on_transmitting signal?
m_lastTxTime = DriftingDateTime::currentDateTimeUtc();
@@ -4427,39 +4376,13 @@ void MainWindow::guiUpdate()
} else {
m_bVHFwarned=false;
}
// if(m_config.bFox()) {
// if(m_config.my_callsign()=="K1JT" or m_config.my_callsign()=="K9AN" or
// m_config.my_callsign()=="G4WJS" or m_config.my_callsign().contains("KH7Z")) {
// ui->sbNslots->setMaximum(5);
// m_Nslots=ui->sbNslots->value();
// ui->sbNslots->setEnabled(true);
// } else {
// ui->sbNslots->setMaximum(1);
// m_Nslots=1;
// ui->sbNslots->setEnabled(false);
// }
// }
if(m_config.bHound()) {
m_bWarnedHound=false;
qint32 tHound=DriftingDateTime::currentMSecsSinceEpoch()/1000 - m_tAutoOn;
//To keep calling Fox, Hound must reactivate Enable Tx at least once every 2 minutes
if(tHound >= 120 and m_ntx==1) auto_tx_mode(false);
}
if(m_auto and m_mode=="Echo" and m_bEchoTxOK) {
progressBar.setMaximum(6);
progressBar.setValue(int(m_s6));
}
if(m_mode!="Echo") {
if(m_monitoring or m_transmitting) {
if(m_monitoring or m_transmitting) {
progressBar.setMaximum(m_TRperiod);
int isec=int(fmod(tsec,m_TRperiod));
progressBar.setValue(isec);
} else {
} else {
progressBar.setValue(0);
}
}
astroUpdate ();
@@ -4533,28 +4456,31 @@ void MainWindow::guiUpdate()
tryBandHop();
}
// once per period/3
// at the end of the period
bool forceDirty = false;
if(m_sec0 % (m_TRperiod/3) == 0){
// force rx dirty three times per period
if(m_sec0 % (m_TRperiod-2) == 0 ||
m_sec0 % (m_TRperiod) == 0 ||
m_sec0 % (m_TRperiod+2) == 0 ){
// force rx dirty at the end of the period
forceDirty = true;
}
// once per second...
// update the dial frequency once per second..
displayDialFrequency();
// process all received activity...
processActivity(forceDirty);
// once per second...but not when we're transmitting
if(!m_transmitting){
// process all received activity...
processActivity(forceDirty);
// process outgoing tx queue...
processTxQueue();
// process outgoing tx queue...
processTxQueue();
// once processed, lets update the display...
displayActivity(forceDirty);
updateButtonDisplay();
updateTextDisplay();
// once processed, lets update the display...
displayActivity(forceDirty);
updateButtonDisplay();
updateTextDisplay();
}
}
// once per 100ms
@@ -4562,6 +4488,16 @@ void MainWindow::guiUpdate()
m_iptt0=g_iptt;
m_btxok0=m_btxok;
// compute the processing time and adjust loop to hit the next 100ms
auto endLoop = QDateTime::currentMSecsSinceEpoch();
auto processingTime = endLoop - thisLoop;
auto nextLoopMs = 0;
if(processingTime < 100){
nextLoopMs = 100 - processingTime;
}
m_guiTimer.start(nextLoopMs);
} //End of guiUpdate
@@ -4581,14 +4517,6 @@ void MainWindow::startTx()
ui->rbNextFreeTextMsg->setChecked(true);
if (m_transmitting) m_restart=true;
// detect if we're currently in a possible transmit cycle...and if so, wait until the next one if we're more than 2 seconds in...
QDateTime now {DriftingDateTime::currentDateTimeUtc()};
int s=now.addSecs(-2).time().second();
int n=s % (2*m_TRperiod);
if((n <= m_TRperiod && m_txFirst) || (n > m_TRperiod && !m_txFirst)){
m_txFirst = !m_txFirst;
}
// hack the auto button to kick off the transmit
if(!ui->autoButton->isChecked()){
ui->autoButton->setEnabled(true);
@@ -4617,11 +4545,6 @@ void MainWindow::startTx2()
}
}
void MainWindow::continueTx()
{
m_txFirst = !m_txFirst;
}
void MainWindow::stopTx()
{
Q_EMIT endTransmitMessage ();
@@ -4637,9 +4560,7 @@ void MainWindow::stopTx()
}
bool shouldContinue = !m_tx_watchdog && prepareNextMessageFrame();
if(shouldContinue){
continueTx();
} else {
if(!shouldContinue){
// TODO: jsherer - split this up...
ui->extFreeTextMsgEdit->setReadOnly(false);
update_dynamic_property(ui->extFreeTextMsgEdit, "transmitting", false);
@@ -5132,14 +5053,32 @@ void MainWindow::clearActivity(){
void MainWindow::createAllcallTableRow(QTableWidget *table, bool selected){
table->insertRow(table->rowCount());
int count = 0;
auto now = DriftingDateTime::currentDateTimeUtc();
int callsignAging = m_config.callsign_aging();
if(ui->selcalButton->isChecked()){
auto item = new QTableWidgetItem("GROUPCALL");
int freq = currentFreqOffset();
foreach(auto cd, m_callActivity.values()){
if (callsignAging && cd.utcTimestamp.secsTo(now) / 60 >= callsignAging) {
continue;
}
if(abs(freq - cd.freq) <= NEAR_THRESHOLD_GROUPCALL){
count++;
}
}
auto item = new QTableWidgetItem(count == 0 ? QString("GROUPCALL") : QString("GROUPCALL (%1)").arg(count));
item->setData(Qt::UserRole, QVariant("GROUPCALL"));
table->setItem(table->rowCount() - 1, 0, item);
table->setSpan(table->rowCount() - 1, 0, 1, table->columnCount());
} else {
auto item = new QTableWidgetItem("ALLCALL");
foreach(auto cd, m_callActivity.values()){
if (callsignAging && cd.utcTimestamp.secsTo(now) / 60 >= callsignAging) {
continue;
}
count++;
}
auto item = new QTableWidgetItem(count == 0 ? QString("ALLCALL") : QString("ALLCALL (%1)").arg(count));
item->setData(Qt::UserRole, QVariant("ALLCALL"));
table->setItem(table->rowCount() - 1, 0, item);
table->setSpan(table->rowCount() - 1, 0, 1, table->columnCount());
@@ -5381,6 +5320,11 @@ void MainWindow::createMessage(QString const& text){
return;
}
if(text.contains("APRS:") && !m_aprsClient->isPasscodeValid()){
MessageBox::warning_message(this, tr ("Please ensure a valid APRS passcode is set in the settings when sending an APRS packet."));
return;
}
resetMessageTransmitQueue();
createMessageTransmitQueue(text);
}
@@ -5454,7 +5398,8 @@ void MainWindow::on_extFreeTextMsgEdit_currentTextChanged (QString const& text)
ui->extFreeTextMsgEdit->setTextCursor(c);
}
m_txTextDirty = true;
m_txTextDirty = x != m_txTextDirtyLastText;
m_txTextDirtyLastText = x;
// immediately update the display
updateButtonDisplay();
@@ -5465,10 +5410,6 @@ int MainWindow::currentFreqOffset(){
return ui->RxFreqSpinBox->value();
}
int MainWindow::countMessageFrames(QString const& text){
return buildMessageFrames(text).length();
}
QStringList MainWindow::buildMessageFrames(const QString &text){
// prepare selected callsign for directed message
QString selectedCall = callsignSelected();
@@ -5594,7 +5535,7 @@ void MainWindow::scheduleBeacon(bool first){
// round to 15 second increment
int secondsSinceEpoch = (timestamp.toMSecsSinceEpoch()/1000);
int delta = roundUp(secondsSinceEpoch, 15) + 1 + (first ? /*m_txFirst ? 15 : 30*/ 0 : qMax(1, m_config.beacon()) * 60) - secondsSinceEpoch;
int delta = roundUp(secondsSinceEpoch, 15) + 1 + (first ? 0 : qMax(1, m_config.beacon()) * 60) - secondsSinceEpoch;
timestamp = timestamp.addSecs(delta);
// 25% of the time, switch intervals
@@ -6365,7 +6306,11 @@ void MainWindow::on_cqMacroButton_clicked(){
message = QString("CQCQCQ %1").arg(mygrid).trimmed();
}
clearCallsignSelected();
addMessageText(message);
if(m_config.transmit_directed()) toggleTx(true);
}
void MainWindow::on_replyMacroButton_clicked(){
@@ -6373,7 +6318,10 @@ void MainWindow::on_replyMacroButton_clicked(){
if(call.isEmpty()){
return;
}
addMessageText(QString("%1 %2").arg(call).arg(m_config.reply_message()));
if(m_config.transmit_directed()) toggleTx(true);
}
void MainWindow::on_qthMacroButton_clicked(){
@@ -6381,7 +6329,10 @@ void MainWindow::on_qthMacroButton_clicked(){
if(qth.isEmpty()){
return;
}
addMessageText(QString("QTH %1").arg(qth));
if(m_config.transmit_directed()) toggleTx(true);
}
void MainWindow::on_qtcMacroButton_clicked(){
@@ -6389,7 +6340,10 @@ void MainWindow::on_qtcMacroButton_clicked(){
if(qtc.isEmpty()){
return;
}
addMessageText(QString("QTC %1").arg(qtc));
if(m_config.transmit_directed()) toggleTx(true);
}
void MainWindow::setShowColumn(QString tableKey, QString columnKey, bool value){
@@ -6595,7 +6549,21 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
if(m_config.transmit_directed()) toggleTx(true);
});
auto heardQueryAction = menu->addAction(QString("%1$ - What are the stations are you hearing? (Top 4 ranked by strongest SNR)").arg(call).trimmed());
auto stationIdleQueryAction = menu->addAction(QString("%1* - Is your station active or idle?").arg(call).trimmed());
stationIdleQueryAction->setDisabled(isAllCall);
connect(stationIdleQueryAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
if(selectedCall.isEmpty()){
return;
}
addMessageText(QString("%1*").arg(selectedCall), true);
if(m_config.transmit_directed()) toggleTx(true);
});
auto heardQueryAction = menu->addAction(QString("%1$ - What are the stations are you hearing? (Top 4 ranked by most recently heard)").arg(call).trimmed());
heardQueryAction->setDisabled(isAllCall);
connect(heardQueryAction, &QAction::triggered, this, [this](){
@@ -6889,7 +6857,11 @@ void MainWindow::buildEditMenu(QMenu *menu, QTextEdit *edit){
void MainWindow::buildSavedMessagesMenu(QMenu *menu){
foreach(QString macro, m_config.macros()->stringList()){
QAction *action = menu->addAction(macro);
connect(action, &QAction::triggered, this, [this, macro](){ addMessageText(macro); });
connect(action, &QAction::triggered, this, [this, macro](){
addMessageText(macro);
if(m_config.transmit_directed()) toggleTx(true);
});
}
menu->addSeparator();
@@ -7957,8 +7929,8 @@ void MainWindow::updateButtonDisplay(){
ui->cqMacroButton->setDisabled(isTransmitting);
ui->replyMacroButton->setDisabled(isTransmitting || emptyCallsign);
ui->qthMacroButton->setDisabled(isTransmitting || m_config.my_station().isEmpty());
ui->qtcMacroButton->setDisabled(isTransmitting || m_config.my_qth().isEmpty());
ui->qtcMacroButton->setDisabled(isTransmitting || m_config.my_station().isEmpty());
ui->qthMacroButton->setDisabled(isTransmitting || m_config.my_qth().isEmpty());
ui->macrosMacroButton->setDisabled(isTransmitting);
ui->queryButton->setDisabled(isTransmitting || emptyCallsign);
ui->deselectButton->setDisabled(isTransmitting || emptyCallsign);
@@ -7983,9 +7955,10 @@ void MainWindow::updateTextDisplay(){
}
}
#define USE_SYNC_FRAME_COUNT 1
#define USE_SYNC_FRAME_COUNT 0
void MainWindow::refreshTextDisplay(){
qDebug() << "refreshing text display...";
auto text = ui->extFreeTextMsgEdit->toPlainText();
#if USE_SYNC_FRAME_COUNT
@@ -8014,7 +7987,6 @@ void MainWindow::refreshTextDisplay(){
#else
// prepare selected callsign for directed message
QString selectedCall = callsignSelected();
m_txTextDirtyLastSelectedCall = selectedCall;
// prepare compound
bool compound = Radio::is_compound_callsign(m_config.my_callsign());
@@ -8030,7 +8002,7 @@ void MainWindow::refreshTextDisplay(){
);
connect(t, &BuildMessageFramesThread::finished, t, &QObject::deleteLater);
connect(t, &BuildMessageFramesThread::resultReady, this, [this](const QStringList frames){
connect(t, &BuildMessageFramesThread::resultReady, this, [this, text](const QStringList frames){
QStringList textList;
qDebug() << "frames:";
@@ -8040,10 +8012,18 @@ void MainWindow::refreshTextDisplay(){
textList.append(dt.message());
}
updateFrameCountEstimate(frames.length());
updateTextStatsDisplay(textList.join(""), frames.length());
auto transmitText = textList.join("");
auto count = frames.length();
// ugh...i hate these globals
m_txTextDirtyLastSelectedCall = callsignSelected(true);
m_txTextDirtyLastText = text;
m_txFrameCountEstimate = count;
m_txTextDirty = false;
updateTextStatsDisplay(transmitText, count);
updateTxButtonDisplay();
});
t->start();
#endif
@@ -8125,7 +8105,7 @@ void MainWindow::clearCallsignSelected(){
}
bool MainWindow::isRecentOffset(int offset){
if(abs(offset - currentFreqOffset()) <= 10){
if(abs(offset - currentFreqOffset()) <= NEAR_THRESHOLD_RX){
return true;
}
return (
@@ -8210,18 +8190,20 @@ void MainWindow::processRxActivity() {
return;
}
int freqOffset = currentFreqOffset();
while (!m_rxActivityQueue.isEmpty()) {
ActivityDetail d = m_rxActivityQueue.dequeue();
// use the actual frequency and check its delta from our current frequency
// meaning, if our current offset is 1502 and the d.freq is 1492, the delta is <= 10;
bool shouldDisplay = abs(d.freq - currentFreqOffset()) <= 10;
bool shouldDisplay = abs(d.freq - freqOffset) <= NEAR_THRESHOLD_RX;
int prevOffset = d.freq;
if(hasExistingMessageBuffer(d.freq, false, &prevOffset) && (
(m_messageBuffer[prevOffset].cmd.to == m_config.my_callsign()) ||
(isAllCallIncluded(m_messageBuffer[prevOffset].cmd.to) && !ui->selcalButton->isChecked()) ||
(isGroupCallIncluded(m_messageBuffer[prevOffset].cmd.to) && abs(prevOffset - currentFreqOffset()) <= 125)
(isGroupCallIncluded(m_messageBuffer[prevOffset].cmd.to) && abs(prevOffset - freqOffset) <= NEAR_THRESHOLD_GROUPCALL)
)
){
d.isBuffered = true;
@@ -8446,10 +8428,12 @@ void MainWindow::processBufferedActivity() {
int checksumSize = Varicode::isCommandChecksumed(buffer.cmd.cmd);
if(checksumSize == 32) {
message = Varicode::lstrip(message);
checksum = message.right(6);
message = message.left(message.length() - 7);
valid = Varicode::checksum32Valid(checksum, message);
} else if(checksumSize == 16) {
message = Varicode::lstrip(message);
checksum = message.right(3);
message = message.left(message.length() - 4);
valid = Varicode::checksum16Valid(checksum, message);
@@ -8496,11 +8480,13 @@ void MainWindow::processCommandActivity() {
auto now = DriftingDateTime::currentDateTimeUtc();
int freqOffset = currentFreqOffset();
while (!m_rxCommandQueue.isEmpty()) {
auto d = m_rxCommandQueue.dequeue();
bool isAllCall = isAllCallIncluded(d.to);
bool isNear = abs(d.freq - currentFreqOffset()) <= 125; // 100Hz + a 25Hz buffer
bool isNear = abs(d.freq - freqOffset) <= NEAR_THRESHOLD_GROUPCALL; // 100Hz + a 25Hz buffer
bool isGroupCall = isGroupCallIncluded(d.to) && isNear;
qDebug() << "try processing command" << d.from << d.to << d.cmd << d.freq << d.grid << d.extra;
@@ -8575,7 +8561,11 @@ void MainWindow::processCommandActivity() {
c.movePosition(QTextCursor::End);
ui->textEditRX->setTextCursor(c);
if(/*isRecentOffset(d.freq) &&*/ ui->textEditRX->find(d.utcTimestamp.time().toString(), QTextDocument::FindBackward)){
// BEACON ACKs are the most likely source of items to be overwritten (multiple responses at once)...
// so don't overwrite those (i.e., print each on a new line)
bool shouldOverwrite = (!d.cmd.contains("BEACON ACK")); /* && isRecentOffset(d.freq);*/
if(shouldOverwrite && ui->textEditRX->find(d.utcTimestamp.time().toString(), QTextDocument::FindBackward)){
// ... maybe we could delete the last line that had this message on this frequency...
c = ui->textEditRX->textCursor();
c.movePosition(QTextCursor::StartOfBlock);
@@ -8642,6 +8632,15 @@ void MainWindow::processCommandActivity() {
reply = QString("%1 QTH %2").arg(d.from).arg(qth);
}
// QUERIED ACTIVE
else if (d.cmd == "*" && !isAllCall) {
if(m_idleMinutes < 10){
reply = QString("%1 ACTIVE").arg(d.from);
} else {
reply = QString("%1 IDLE").arg(d.from);
}
}
// QUERIED GRID
else if (d.cmd == "^" && !isAllCall) {
QString grid = m_config.my_grid();
@@ -8667,7 +8666,7 @@ void MainWindow::processCommandActivity() {
const & b) {
auto left = m_callActivity[a];
auto right = m_callActivity[b];
return right.snr < left.snr;
return right.utcTimestamp < left.utcTimestamp;
});
QStringList lines;
@@ -8684,12 +8683,12 @@ void MainWindow::processCommandActivity() {
continue;
}
lines.append(QString("<%1 SNR %2>").arg(d.call).arg(Varicode::formatSNR(d.snr)));
lines.append(QString("%1 SNR %2 (%3)").arg(d.call).arg(Varicode::formatSNR(d.snr)).arg(since(d.utcTimestamp)));
i++;
}
lines.prepend(QString("<%1 HEARING>").arg(m_config.my_callsign()));
lines.prepend(QString("%1 HEARING").arg(d.from));
reply = lines.join('\n');
}
@@ -9560,8 +9559,13 @@ void MainWindow::networkMessage(Message const &message)
// RX.GET_TEXT
if(type == "RX.GET_CALL_ACTIVITY"){
auto now = DriftingDateTime::currentDateTimeUtc();
int callsignAging = m_config.callsign_aging();
QMap<QString, QVariant> calls;
foreach(auto cd, m_callActivity.values()){
if (callsignAging && cd.utcTimestamp.secsTo(now) / 60 >= callsignAging) {
continue;
}
QMap<QString, QVariant> detail;
detail["SNR"] = QVariant(cd.snr);
detail["GRID"] = QVariant(cd.grid);
@@ -10219,7 +10223,7 @@ void MainWindow::write_transmit_entry (QString const& file_name)
auto dt = DecodedText(m_currentMessage);
out << time.toString("yyyy-MM-dd hh:mm:ss")
<< " Transmitting " << qSetRealNumberPrecision (12) << (m_freqNominal / 1.e6)
<< " MHz " << m_modeTx
<< " MHz " << QString(m_modeTx).replace("FT8", "JS8")
<< ": " << dt.message() << endl;
f.close();
}
-3
View File
@@ -254,7 +254,6 @@ private slots:
void startTx();
void startTx2();
void startP1();
void continueTx();
void stopTx();
void stopTx2();
void on_pbCallCQ_clicked();
@@ -296,7 +295,6 @@ private slots:
void on_nextFreeTextMsg_currentTextChanged (QString const&);
void on_extFreeTextMsgEdit_currentTextChanged (QString const&);
int currentFreqOffset();
int countMessageFrames(QString const& text);
QStringList buildMessageFrames(QString const& text);
bool prepareNextMessageFrame();
bool isFreqOffsetFree(int f, int bw);
@@ -535,7 +533,6 @@ private:
bool m_diskData;
bool m_loopall;
bool m_decoderBusy;
bool m_txFirst;
bool m_auto;
bool m_restart;
bool m_startAnother;
+18 -8
View File
@@ -4625,7 +4625,7 @@ list. The list can be maintained in Settings (F2).</string>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
<string>&amp;File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionOpen_next_in_directory"/>
@@ -4670,7 +4670,7 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
<widget class="QMenu" name="menuSave">
<property name="title">
<string>Save</string>
<string>&amp;Save</string>
</property>
<addaction name="actionNone"/>
<addaction name="actionSave_decoded"/>
@@ -4682,18 +4682,16 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
<string>&amp;Help</string>
</property>
<addaction name="actionRelease_Notes"/>
<addaction name="actionOnline_User_Guide"/>
<addaction name="actionLocal_User_Guide"/>
<addaction name="actionFT8_DXpedition_Mode_User_Guide"/>
<addaction name="download_samples_action"/>
<addaction name="separator"/>
<addaction name="actionKeyboard_shortcuts"/>
<addaction name="actionSpecial_mouse_commands"/>
<addaction name="actionShort_list_of_add_on_prefixes_and_suffixes"/>
<addaction name="separator"/>
<addaction name="actionCopyright_Notice"/>
<addaction name="separator"/>
<addaction name="actionAbout"/>
@@ -4724,7 +4722,7 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
<widget class="QMenu" name="menuConfig">
<property name="title">
<string>Configurations</string>
<string>&amp;Configurations</string>
</property>
</widget>
<widget class="QMenu" name="menuTools">
@@ -4742,7 +4740,7 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
<widget class="QMenu" name="menuWindow">
<property name="title">
<string>Window</string>
<string>&amp;Window</string>
</property>
<addaction name="actionShow_Band_Activity"/>
<addaction name="actionShow_Band_Activity_Columns"/>
@@ -4760,7 +4758,7 @@ list. The list can be maintained in Settings (F2).</string>
</widget>
<widget class="QMenu" name="menu_Log">
<property name="title">
<string>Log</string>
<string>&amp;Log</string>
</property>
<addaction name="actionAdd_Log_Entry"/>
<addaction name="separator"/>
@@ -4905,6 +4903,9 @@ list. The list can be maintained in Settings (F2).</string>
</property>
</action>
<action name="actionKeyboard_shortcuts">
<property name="visible">
<bool>false</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
@@ -4916,6 +4917,9 @@ list. The list can be maintained in Settings (F2).</string>
</property>
</action>
<action name="actionSpecial_mouse_commands">
<property name="visible">
<bool>false</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
@@ -5238,6 +5242,9 @@ list. The list can be maintained in Settings (F2).</string>
</property>
</action>
<action name="download_samples_action">
<property name="visible">
<bool>false</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
@@ -5265,6 +5272,9 @@ list. The list can be maintained in Settings (F2).</string>
</property>
</action>
<action name="actionRelease_Notes">
<property name="visible">
<bool>false</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
+30 -28
View File
@@ -46,14 +46,14 @@ QMap<QString, int> directed_cmds = {
{"$", 3 }, // query station(s) heard
{"^", 4 }, // query grid
{">", 5 }, // relay message
//{"|", 6 }, // retransmit message
{"*", 6 }, // query idle message
//{"!", 7 }, // alert message
{"#", 8 }, // all or nothing message
// {"=", 9 }, // unused
// {"/", 10 }, // unused
{" ACTIVE", 10 }, // i have been active in the past 10 minutes
{" IDLE", 11 }, // i have not been active in the past 10 minutes
{" BEACON", -1 }, // this is my beacon (unused except for faux processing of beacons as directed commands)
{" BEACON ACK", 12 }, // i received your beacon at this snr
@@ -81,7 +81,7 @@ QMap<QString, int> directed_cmds = {
{" ", 31 }, // send freetext
};
QSet<int> allowed_cmds = {-1, 0, 1, 2, 3, 4, 5, /*6,*/ /*7,*/ 8, /*...*/ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
QSet<int> allowed_cmds = {-1, 0, 1, 2, 3, 4, 5, 6, /*7,*/ 8, /*9,*/ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
QSet<int> buffered_cmds = {3, 5, /*6,*/ /*7,*/ 8, 13, 14, 15};
@@ -96,10 +96,10 @@ QMap<int, int> checksum_cmds = {
};
QString callsign_pattern = QString("(?<callsign>[A-Z0-9/]+)");
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_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|ACTIVE|IDLE)(?=[ ]|$))|[?@&$%#^>* ]))?");
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]))?");
QString optional_num_pattern = QString("(?<num>(?<=SNR|BEACON ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
QRegularExpression directed_re("^" +
callsign_pattern +
@@ -108,13 +108,13 @@ QRegularExpression directed_re("^" +
QRegularExpression beacon_re(R"(^\s*(?<type>CQCQCQ|CQ QRPP?|CQ DX|CQ TEST|CQ( CQ){0,2}|BEACON)(?:\s(?<grid>[A-R]{2}[0-9]{2}))?\b)");
QRegularExpression compound_re("^\\s*[<]" +
QRegularExpression compound_re("^\\s*[`]" +
callsign_pattern +
"(?<extra>" +
optional_grid_pattern +
optional_grid_pattern + // there's a reason this is first (see: buildMessageFrames)
optional_cmd_pattern +
optional_num_pattern +
")[>]");
")");
QMap<QString, QString> hufftable = {
// char code weight
@@ -333,7 +333,7 @@ QStringList Varicode::parseCallsigns(QString const &input){
if(!match.hasMatch()){
continue;
}
QString callsign = match.captured("callsign");
QString callsign = match.captured("callsign").trimmed();
QRegularExpression m(grid_pattern);
if(m.match(callsign).hasMatch()){
continue;
@@ -1021,6 +1021,7 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){
qDebug() << "trying to pack compound message" << text;
auto parsedText = compound_re.match(text);
if(!parsedText.hasMatch()){
qDebug() << "no match for compound message";
if(n) *n = 0;
return frame;
}
@@ -1061,6 +1062,8 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){
quint8 type = FrameCompound;
quint16 extra = nmaxgrid;
qDebug() << "try pack cmd" << cmd << directed_cmds.contains(cmd) << Varicode::isCommandAllowed(cmd);
if (!cmd.isEmpty() && directed_cmds.contains(cmd) && Varicode::isCommandAllowed(cmd)){
bool packedNum = false;
qint8 inum = Varicode::packNum(num, nullptr);
@@ -1206,7 +1209,7 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi
QString from = callsign;
QString to = match.captured("callsign");
QString cmd = match.captured("cmd");
QString num = match.captured("num").trimmed();
QString num = match.captured("num");
// ensure we have a directed command
if(cmd.isEmpty()){
@@ -1240,8 +1243,11 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi
}
// packing general number...
quint8 inum = Varicode::packNum(num, nullptr);
if(pNum) *pNum = num;
bool numOK = false;
quint8 inum = Varicode::packNum(num.trimmed(), &numOK);
if(numOK){
if(pNum) *pNum = num;
}
quint32 packed_from = Varicode::packCallsign(from);
quint32 packed_to = Varicode::packCallsign(to);
@@ -1251,12 +1257,15 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi
return frame;
}
QString cmdOut;
quint8 packed_cmd = 0;
if(directed_cmds.contains(cmd)){
packed_cmd = directed_cmds[cmd];
cmdOut = cmd;
packed_cmd = directed_cmds[cmdOut];
}
if(directed_cmds.contains(cmd.trimmed())){
packed_cmd = directed_cmds[cmd.trimmed()];
cmdOut = cmd.trimmed();
packed_cmd = directed_cmds[cmdOut];
}
quint8 packed_flag = FrameDirected;
quint8 packed_extra = inum;
@@ -1269,7 +1278,7 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi
Varicode::intToBits(packed_cmd % 32, 5)
);
if(pCmd) *pCmd = cmd;
if(pCmd) *pCmd = cmdOut;
if(n) *n = match.captured(0).length();
return Varicode::pack72bits(Varicode::bitsToInt(bits), packed_extra % 64);
}
@@ -1501,8 +1510,8 @@ QStringList Varicode::buildMessageFrames(
#if AUTO_PREPEND_DIRECTED
// see if we need to prepend the directed call to the line...
// if we have a selected call and the text doesn't start with that call...
// and if this isn't a raw message (starting with "<")... then...
if(!selectedCall.isEmpty() && !line.startsWith(selectedCall) && !line.startsWith("<")){
// and if this isn't a raw message (starting with "`")... then...
if(!selectedCall.isEmpty() && !line.startsWith(selectedCall) && !line.startsWith("`")){
auto calls = Varicode::parseCallsigns(line);
bool lineStartsWithBaseCall = (
@@ -1512,7 +1521,7 @@ QStringList Varicode::buildMessageFrames(
Varicode::startsWithCQ(line)
);
bool lineStartsWithStandardCall = !calls.isEmpty() && line.startsWith(calls.first());
bool lineStartsWithStandardCall = !calls.isEmpty() && line.startsWith(calls.first()) && calls.first().length() > 2;
if(lineStartsWithBaseCall || lineStartsWithStandardCall){
// pass
@@ -1622,14 +1631,14 @@ QStringList Varicode::buildMessageFrames(
bool shouldUseStandardFrame = true;
if(compound || dirToCompound){
// Cases 1, 2, 3 all send a standard compound frame first...
QString deCompoundMessage = QString("<%1 %2>").arg(mycall).arg(mygrid);
QString deCompoundMessage = QString("`%1 %2").arg(mycall).arg(mygrid);
QString deCompoundFrame = Varicode::packCompoundMessage(deCompoundMessage, nullptr);
if(!deCompoundFrame.isEmpty()){
frames.append(deCompoundFrame);
}
// Followed, by a standard OR compound directed message...
QString dirCompoundMessage = QString("<%1%2%3>").arg(dirTo).arg(dirCmd).arg(dirNum);
QString dirCompoundMessage = QString("`%1%2%3").arg(dirTo).arg(dirCmd).arg(dirNum); //.replace(" ", " ");
QString dirCompoundFrame = Varicode::packCompoundMessage(dirCompoundMessage, nullptr);
if(!dirCompoundFrame.isEmpty()){
frames.append(dirCompoundFrame);
@@ -1664,13 +1673,6 @@ QStringList Varicode::buildMessageFrames(
}
qDebug() << "after:" << line;
}
#if 0
// APRS:
if(dirCmd.trimmed() == "APRS:" && !m_aprsClient->isPasscodeValid()){
MessageBox::warning_message(this, tr ("Please enter a valid APRS passcode in the settings to send an APRS packet."));
}
#endif
}
if(useDat){