Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8529ef0982 | |||
| 8bba574963 | |||
| 80d798d7e3 | |||
| 23a554220b | |||
| 7e903349ae | |||
| 55810e63a6 | |||
| 9162d851d4 | |||
| 2022908509 | |||
| 2e2551519d | |||
| 18052773f1 | |||
| 51010e7310 | |||
| a3eaf1cf74 | |||
| c731fa51ce | |||
| a5f59019d3 | |||
| 4a87edc4c7 | |||
| 2da25c3171 | |||
| 87a6e10bd6 | |||
| cf9c74b99e | |||
| dae50d3a99 | |||
| 83268fbdaf | |||
| 3b2242e258 | |||
| c42c3b7ad1 | |||
| 9496d5ed81 | |||
| 83174bc6fa | |||
| d74850b8e1 | |||
| 2f1dca3c49 | |||
| 4a38778808 | |||
| 960b9b14d1 | |||
| 9e93745587 | |||
| 8aa28108ea |
+15
-6
@@ -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
@@ -195,7 +195,7 @@
|
||||
<string><html><head/><body><p>Station location message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>QTH Message:</string>
|
||||
<string>Station Location (QTH) Message:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -212,7 +212,7 @@
|
||||
<string><html><head/><body><p>Station Description Message</p></body></html></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&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&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
@@ -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
|
||||
|
||||
@@ -197,6 +197,8 @@ bool DecodedText::tryUnpackDirected(){
|
||||
message_ = QString(parts.join(""));
|
||||
}
|
||||
|
||||
message_ = message_.replace("APRS: ", "APRS:");
|
||||
|
||||
directed_ = parts;
|
||||
frameType_ = type;
|
||||
return true;
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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>&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>&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>&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>&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>&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>&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
@@ -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){
|
||||
|
||||
Reference in New Issue
Block a user