Compare commits

...

28 Commits

Author SHA1 Message Date
Jordan Sherer 5addf8f61f Fixed bug with space collapsing in displayTextForFreq 2018-11-05 16:51:24 -05:00
Jordan Sherer 367966f5e6 Bump to v0.8.3 2018-11-05 16:47:09 -05:00
Jordan Sherer caaaa957b6 Fixed OSX issue with menuBar menus that have sub-menues that aren't populated at construction, but when the menu is aboutToShow 2018-11-05 16:00:12 -05:00
Jordan Sherer c440d4c143 Added TDELTA macro variable 2018-11-05 11:35:37 -05:00
Jordan Sherer 740c0b4c04 Fixed call activity with empty rows 2018-11-04 14:57:44 -05:00
Jordan Sherer f5ce9f0e30 Added TU short command 2018-11-03 22:38:27 -04:00
Jordan Sherer 0a6ec136f9 Fixed macro expansion for auto-reply messages QTC and QTH 2018-11-03 22:20:49 -04:00
Jordan Sherer d5e1f2822d Fixed more issues with compressed data decoding and invalid frames 2018-11-03 22:14:42 -04:00
Jordan Sherer 3fffb45338 Bump to v0.8.2 2018-11-03 02:13:19 -04:00
Jordan Sherer 1d255b1ebf Fixed time delta labeling 2018-11-03 02:06:20 -04:00
Jordan Sherer bb97799bdf Added checkmark to column header for worked before status 2018-11-03 02:01:01 -04:00
Jordan Sherer cc6a719f6d Added default column show settings 2018-11-03 01:59:21 -04:00
Jordan Sherer ccd380356a Fixed log cache issue by reloading log after qso or erase 2018-11-03 01:47:54 -04:00
Jordan Sherer 9f8583c8e2 Fixed reply queuing when text is typed in the reply textbox 2018-11-03 01:31:24 -04:00
Jordan Sherer c9016d7378 Fixed issue with false decodes causing app crash 2018-11-03 01:14:31 -04:00
Jordan Sherer cd683f9bf7 Added back foxcom waveform to the modulator 2018-11-01 22:14:57 -04:00
Jordan Sherer 6d7b187269 Fixed table column swap for snr and offset 2018-11-01 00:50:39 -04:00
Jordan Sherer 13308a38f8 Fixed sync for non APPLE 2018-11-01 00:44:14 -04:00
Jordan Sherer 804605e9e6 Fixed text count for APPLE 2018-11-01 00:41:15 -04:00
Jordan Sherer 4e981da9c8 Fixed send button initial frame count. Fixed apple specific text counting 2018-11-01 00:37:29 -04:00
Jordan Sherer 6436e163bd Fixed QSO log not uppercase callsign 2018-11-01 00:20:20 -04:00
Jordan Sherer 379a0fa78f Fixed bug with auto-replies using selected callsign as the directed callsign 2018-11-01 00:06:09 -04:00
Jordan Sherer 1c4a2ab7d8 Fix bug with fort.19 2018-11-01 00:05:41 -04:00
Jordan Sherer 54f6bdb0af Bump to v0.8.1 2018-10-31 22:13:26 -04:00
Jordan Sherer 5a0e2a8b14 Fixed time delta average reset on activity clear 2018-10-31 22:10:04 -04:00
Jordan Sherer 1a9c611195 Fixed issue with tdrift average when reset 2018-10-31 22:09:03 -04:00
Jordan Sherer c70661461e Fixed selcall button should prevent heartbeat acks 2018-10-31 21:52:58 -04:00
Jordan Sherer 1f866e14f1 Hotfix. Fixed heartbear idle min value should be zero 2018-10-31 21:42:08 -04:00
11 changed files with 163 additions and 81 deletions
+8 -5
View File
@@ -675,6 +675,9 @@ text message.</string>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Number of minutes before unattended heartbeat transmissions are aborted.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Number of minutes before unattended heartbeat transmissions are aborted.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="specialValueText">
<string>Disabled</string>
</property>
<property name="suffix"> <property name="suffix">
<string> minutes</string> <string> minutes</string>
</property> </property>
@@ -682,7 +685,7 @@ text message.</string>
<string>after </string> <string>after </string>
</property> </property>
<property name="minimum"> <property name="minimum">
<number>1</number> <number>0</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>1440</number> <number>1440</number>
@@ -3668,12 +3671,12 @@ soundcard changes</string>
</connection> </connection>
</connections> </connections>
<buttongroups> <buttongroups>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="CAT_handshake_button_group"/> <buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/> <buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="TX_audio_source_button_group"/> <buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="TX_mode_button_group"/>
</buttongroups> </buttongroups>
</ui> </ui>
+1
View File
@@ -291,6 +291,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
if (m_ic > i1) m_amp = 0.0; if (m_ic > i1) m_amp = 0.0;
sample=qRound(m_amp*qSin(m_phi)); sample=qRound(m_amp*qSin(m_phi));
if(m_toneSpacing < 0) sample=qRound(m_amp*foxcom_.wave[m_ic]);
samples = load(postProcessSample(sample), samples); samples = load(postProcessSample(sample), samples);
++framesGenerated; ++framesGenerated;
++m_ic; ++m_ic;
+1 -1
View File
@@ -1,6 +1,6 @@
# Version number components # Version number components
set (WSJTX_VERSION_MAJOR 0) set (WSJTX_VERSION_MAJOR 0)
set (WSJTX_VERSION_MINOR 8) set (WSJTX_VERSION_MINOR 8)
set (WSJTX_VERSION_PATCH 0) set (WSJTX_VERSION_PATCH 3)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions 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 set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
+5
View File
@@ -61,6 +61,11 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
bits_ = bits(); bits_ = bits();
// don't even try to unpack -24dB frames...they are *very* likely to be false decodes...
if(snr() <= -24){
return;
}
tryUnpack(); tryUnpack();
} }
+18 -6
View File
@@ -107,17 +107,23 @@ QString JSC::decompress(Codeword const& bitvec){
QList<quint64> bytes; QList<quint64> bytes;
QList<int> separators; QList<int> separators;
auto iter = bitvec.begin();
while(iter != bitvec.end()){ int i = 0;
quint64 byte = Varicode::bitsToInt(iter, 4); int count = bitvec.count();
iter += 4; while(i < count){
auto b = bitvec.mid(i, 4);
if(b.length() != 4){
break;
}
quint64 byte = Varicode::bitsToInt(b);
bytes.append(byte); bytes.append(byte);
i += 4;
if(byte < s){ if(byte < s){
if(*iter){ if(count - i > 0 && bitvec.at(i)){
separators.append(bytes.length()-1); separators.append(bytes.length()-1);
} }
iter += 1; i += 1;
} }
} }
@@ -131,8 +137,14 @@ QString JSC::decompress(Codeword const& bitvec){
k++; k++;
} }
if(start + k >= bytes.length()){
break;
}
j = j*s + bytes[start + k] + base[k]; j = j*s + bytes[start + k] + base[k];
if(j >= (int)JSC::size){
break;
}
auto word = QString(JSC::map[j].str); auto word = QString(JSC::map[j].str);
out.append(word); out.append(word);
-26
View File
@@ -93,32 +93,6 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
n30min=minval(n30fox(1:nfox)) n30min=minval(n30fox(1:nfox))
n30max=maxval(n30fox(1:nfox)) n30max=maxval(n30fox(1:nfox))
endif endif
j=0
rewind 19
if(nfox.eq.0) then
endfile 19
rewind 19
else
do i=1,nfox
n=n30fox(i)
if(n30max-n30fox(i).le.4) then
j=j+1
c2fox(j)=c2fox(i)
g2fox(j)=g2fox(i)
nsnrfox(j)=nsnrfox(i)
nfreqfox(j)=nfreqfox(i)
n30fox(j)=n
m=n30max-n
if(len(trim(g2fox(j))).eq.4) then
call azdist(mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm, &
nHotAz,nHotABetter)
else
nDkm=9999
endif
endif
enddo
nfox=j
endif
go to 800 go to 800
endif endif
+3 -3
View File
@@ -98,9 +98,9 @@ void LogQSO::accept()
QString hisCall,hisGrid,mode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band,operator_call; QString hisCall,hisGrid,mode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band,operator_call;
QString comments,name; QString comments,name;
hisCall=ui->call->text(); hisCall=ui->call->text().toUpper();
hisGrid=ui->grid->text(); hisGrid=ui->grid->text().toUpper();
mode=ui->mode->text(); mode=ui->mode->text().toUpper();
rptSent=ui->sent->text(); rptSent=ui->sent->text();
rptRcvd=ui->rcvd->text(); rptRcvd=ui->rcvd->text();
m_dateTimeOn = ui->start_date_time->dateTime (); m_dateTimeOn = ui->start_date_time->dateTime ();
+117 -32
View File
@@ -551,6 +551,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
m_manual {&m_network_manager}, m_manual {&m_network_manager},
m_txFrameCount {0}, m_txFrameCount {0},
m_txTextDirty {false}, m_txTextDirty {false},
m_txFrameCountEstimate {0},
m_previousFreq {0} m_previousFreq {0}
{ {
ui->setupUi(this); ui->setupUi(this);
@@ -1444,6 +1445,12 @@ void MainWindow::initializeDummyData(){
return; return;
} }
auto d = DecodedText("h+vWp6mRPprH", 6);
qDebug() << d.message() << buildMessageFrames(d.message());
d = DecodedText("bYG4CKYT0cKG", 7);
qDebug() << d.message();
// qDebug() << Varicode::isValidCallsign("@GROUP1", nullptr); // qDebug() << Varicode::isValidCallsign("@GROUP1", nullptr);
// qDebug() << Varicode::packAlphaNumeric50("VE7/KN4CRD"); // qDebug() << Varicode::packAlphaNumeric50("VE7/KN4CRD");
// qDebug() << Varicode::unpackAlphaNumeric50(Varicode::packAlphaNumeric50("VE7/KN4CRD")); // qDebug() << Varicode::unpackAlphaNumeric50(Varicode::packAlphaNumeric50("VE7/KN4CRD"));
@@ -1496,6 +1503,7 @@ void MainWindow::initializeDummyData(){
displayTextForFreq("KN4CRD: @ALLCALL? \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-315), true, true, true); displayTextForFreq("KN4CRD: @ALLCALL? \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-315), true, true, true);
displayTextForFreq("J1Y: KN4CRD SNR -05 \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-300), false, true, true); displayTextForFreq("J1Y: KN4CRD SNR -05 \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-300), false, true, true);
displayTextForFreq("HELLO BRAVE NEW WORLD \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-300), false, true, true);
displayActivity(true); displayActivity(true);
@@ -2274,9 +2282,22 @@ void MainWindow::showSoundOutError(const QString& errorMsg)
} }
void MainWindow::showStatusMessage(const QString& statusMsg) void MainWindow::showStatusMessage(const QString& statusMsg)
{statusBar()->showMessage(statusMsg);} {
statusBar()->showMessage(statusMsg);
}
/**
* This function forces the menuBar to rebuild a QAction that has a submenu
* on OSX fixing a weird bug where they aren't displayed correctly.
*/
void rebuildMacQAction(QMenu *menu, QAction *existingAction){
auto dummyAction = new QAction("...");
menu->insertAction(existingAction, dummyAction);
menu->insertAction(dummyAction, existingAction);
menu->removeAction(dummyAction);
}
void MainWindow::on_menuWindow_aboutToShow(){ void MainWindow::on_menuWindow_aboutToShow(){
auto hsizes = ui->textHorizontalSplitter->sizes(); auto hsizes = ui->textHorizontalSplitter->sizes();
ui->actionShow_Band_Activity->setChecked(hsizes.at(0) > 0); ui->actionShow_Band_Activity->setChecked(hsizes.at(0) > 0);
@@ -2289,25 +2310,37 @@ void MainWindow::on_menuWindow_aboutToShow(){
ui->actionShow_Time_Drift_Controls->setChecked(ui->driftSyncFrame->isVisible()); ui->actionShow_Time_Drift_Controls->setChecked(ui->driftSyncFrame->isVisible());
ui->actionShow_Time_Drift_Controls->setEnabled(ui->actionShow_Waterfall->isChecked()); ui->actionShow_Time_Drift_Controls->setEnabled(ui->actionShow_Waterfall->isChecked());
QMenu * sortBandMenu = new QMenu(ui->menuWindow); QMenu * sortBandMenu = new QMenu(this->menuBar()); //ui->menuWindow);
buildBandActivitySortByMenu(sortBandMenu); buildBandActivitySortByMenu(sortBandMenu);
ui->actionSort_Band_Activity->setMenu(sortBandMenu); ui->actionSort_Band_Activity->setMenu(sortBandMenu);
ui->actionSort_Band_Activity->setEnabled(ui->actionShow_Band_Activity->isChecked()); ui->actionSort_Band_Activity->setEnabled(ui->actionShow_Band_Activity->isChecked());
#if __APPLE__
rebuildMacQAction(ui->menuWindow, ui->actionSort_Band_Activity);
#endif
QMenu * sortCallMenu = new QMenu(ui->menuWindow); QMenu * sortCallMenu = new QMenu(this->menuBar()); //ui->menuWindow);
buildCallActivitySortByMenu(sortCallMenu); buildCallActivitySortByMenu(sortCallMenu);
ui->actionSort_Call_Activity->setMenu(sortCallMenu); ui->actionSort_Call_Activity->setMenu(sortCallMenu);
ui->actionSort_Call_Activity->setEnabled(ui->actionShow_Call_Activity->isChecked()); ui->actionSort_Call_Activity->setEnabled(ui->actionShow_Call_Activity->isChecked());
#if __APPLE__
rebuildMacQAction(ui->menuWindow, ui->actionSort_Call_Activity);
#endif
QMenu * showBandMenu = new QMenu(ui->menuWindow); QMenu * showBandMenu = new QMenu(this->menuBar()); //ui->menuWindow);
buildShowColumnsMenu(showBandMenu, "band"); buildShowColumnsMenu(showBandMenu, "band");
ui->actionShow_Band_Activity_Columns->setMenu(showBandMenu); ui->actionShow_Band_Activity_Columns->setMenu(showBandMenu);
ui->actionShow_Band_Activity_Columns->setEnabled(ui->actionShow_Band_Activity->isChecked()); ui->actionShow_Band_Activity_Columns->setEnabled(ui->actionShow_Band_Activity->isChecked());
#if __APPLE__
rebuildMacQAction(ui->menuWindow, ui->actionShow_Band_Activity_Columns);
#endif
QMenu * showCallMenu = new QMenu(ui->menuWindow); QMenu * showCallMenu = new QMenu(this->menuBar()); //ui->menuWindow);
buildShowColumnsMenu(showCallMenu, "call"); buildShowColumnsMenu(showCallMenu, "call");
ui->actionShow_Call_Activity_Columns->setMenu(showCallMenu); ui->actionShow_Call_Activity_Columns->setMenu(showCallMenu);
ui->actionShow_Call_Activity_Columns->setEnabled(ui->actionShow_Call_Activity->isChecked()); ui->actionShow_Call_Activity_Columns->setEnabled(ui->actionShow_Call_Activity->isChecked());
#if __APPLE__
rebuildMacQAction(ui->menuWindow, ui->actionShow_Call_Activity_Columns);
#endif
} }
void MainWindow::on_actionShow_Band_Activity_triggered(bool checked){ void MainWindow::on_actionShow_Band_Activity_triggered(bool checked){
@@ -3549,14 +3582,6 @@ void MainWindow::readFromStdout() //readFromStdout
, tr ("Cannot open \"%1\" for append: %2") , tr ("Cannot open \"%1\" for append: %2")
.arg (f.fileName ()).arg (f.errorString ())); .arg (f.fileName ()).arg (f.errorString ()));
} }
if (m_config.insert_blank () && m_blankLine && !m_config.bFox()) {
QString band;
if((DriftingDateTime::currentMSecsSinceEpoch() / 1000 - m_secBandChanged) > 4*m_TRperiod/4) {
band = ' ' + m_config.bands ()->find (m_freqNominal);
}
ui->decodedTextBrowser->insertLineSpacer (band.rightJustified (40, '-'));
m_blankLine = false;
}
DecodedText decodedtext {QString::fromUtf8 (t.constData ()).remove (QRegularExpression {"\r|\n"}), "FT8" == m_mode && DecodedText decodedtext {QString::fromUtf8 (t.constData ()).remove (QRegularExpression {"\r|\n"}), "FT8" == m_mode &&
ui->cbVHFcontest->isChecked(), m_config.my_grid ()}; ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
@@ -3899,6 +3924,10 @@ bool MainWindow::hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffs
} }
void MainWindow::logCallActivity(CallDetail d, bool spot){ void MainWindow::logCallActivity(CallDetail d, bool spot){
if(d.call.trimmed().isEmpty()){
return;
}
if(m_callActivity.contains(d.call)){ if(m_callActivity.contains(d.call)){
// update (keep grid) // update (keep grid)
CallDetail old = m_callActivity[d.call]; CallDetail old = m_callActivity[d.call];
@@ -5141,6 +5170,7 @@ int MainWindow::writeMessageTextToUI(QDateTime date, QString text, int freq, boo
c.insertText(text); c.insertText(text);
} else { } else {
text = text.toHtmlEscaped(); text = text.toHtmlEscaped();
text = text.replace(" ", "&nbsp;");
if(bold){ if(bold){
text = QString("<strong>%1</strong>").arg(text); text = QString("<strong>%1</strong>").arg(text);
} }
@@ -5747,7 +5777,10 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
clearCallsignSelected(); clearCallsignSelected();
m_logBook.init();
if (m_config.clear_DX () and !m_config.bHound()) clearDX (); if (m_config.clear_DX () and !m_config.bHound()) clearDX ();
m_dateTimeQSOOn = QDateTime {}; m_dateTimeQSOOn = QDateTime {};
} }
@@ -6036,6 +6069,8 @@ void MainWindow::on_actionErase_js8call_log_adi_triggered()
if(ret==MessageBox::Yes) { if(ret==MessageBox::Yes) {
QFile f {m_config.writeable_data_dir ().absoluteFilePath ("js8call_log.adi")}; QFile f {m_config.writeable_data_dir ().absoluteFilePath ("js8call_log.adi")};
f.remove(); f.remove();
m_logBook.init();
} }
} }
@@ -6245,6 +6280,7 @@ void MainWindow::on_clearAction_triggered(QObject * sender){
if(sender == ui->tableWidgetRXAll){ if(sender == ui->tableWidgetRXAll){
m_bandActivity.clear(); m_bandActivity.clear();
clearTableWidget(ui->tableWidgetRXAll); clearTableWidget(ui->tableWidgetRXAll);
resetTimeDeltaAverage();
} }
// TODO: jsherer - abstract this into a tableWidgetCallsReset function // TODO: jsherer - abstract this into a tableWidgetCallsReset function
@@ -6252,6 +6288,7 @@ void MainWindow::on_clearAction_triggered(QObject * sender){
m_callActivity.clear(); m_callActivity.clear();
clearTableWidget((ui->tableWidgetCalls)); clearTableWidget((ui->tableWidgetCalls));
createAllcallTableRows(ui->tableWidgetCalls, ""); createAllcallTableRows(ui->tableWidgetCalls, "");
resetTimeDeltaAverage();
} }
if(sender == ui->extFreeTextMsgEdit){ if(sender == ui->extFreeTextMsgEdit){
@@ -6346,8 +6383,8 @@ void MainWindow::setShowColumn(QString tableKey, QString columnKey, bool value){
displayCallActivity(); displayCallActivity();
} }
bool MainWindow::showColumn(QString tableKey, QString columnKey){ bool MainWindow::showColumn(QString tableKey, QString columnKey, bool default_){
return m_showColumnsCache.value(tableKey + columnKey, QVariant(true)).toBool(); return m_showColumnsCache.value(tableKey + columnKey, QVariant(default_)).toBool();
} }
void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){ void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
@@ -6355,7 +6392,13 @@ void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
{"Frequency Offset", "offset"}, {"Frequency Offset", "offset"},
{"Last heard timestamp", "timestamp"}, {"Last heard timestamp", "timestamp"},
{"SNR", "snr"}, {"SNR", "snr"},
{"Time delta", "tdrift"}, {"Time Delta", "tdrift"},
};
QMap<QString, bool> defaultOverride = {
{"tdrift", false},
{"grid", false},
{"distance", false}
}; };
if(tableKey == "call"){ if(tableKey == "call"){
@@ -6376,7 +6419,13 @@ void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
auto a = menu->addAction(columnLabel); auto a = menu->addAction(columnLabel);
a->setCheckable(true); a->setCheckable(true);
a->setChecked(showColumn(tableKey, columnKey));
bool showByDefault = true;
if(defaultOverride.contains(columnKey)){
showByDefault = defaultOverride[columnKey];
}
a->setChecked(showColumn(tableKey, columnKey, showByDefault));
connect(a, &QAction::triggered, this, [this, a, tableKey, columnKey](){ connect(a, &QAction::triggered, this, [this, a, tableKey, columnKey](){
setShowColumn(tableKey, columnKey, a->isChecked()); setShowColumn(tableKey, columnKey, a->isChecked());
@@ -6546,7 +6595,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
menu->addSeparator(); menu->addSeparator();
auto snrQueryAction = menu->addAction(QString("%1 SNR? - What is my signal report?").arg(call)); auto snrQueryAction = menu->addAction(QString("%1 SNR? - What is my signal report?").arg(call).trimmed());
snrQueryAction->setDisabled(isAllCall); snrQueryAction->setDisabled(isAllCall);
connect(snrQueryAction, &QAction::triggered, this, [this](){ connect(snrQueryAction, &QAction::triggered, this, [this](){
@@ -6560,7 +6609,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
if(m_config.transmit_directed()) toggleTx(true); if(m_config.transmit_directed()) toggleTx(true);
}); });
auto qthQueryAction = menu->addAction(QString("%1 QTH? - What is your QTH message?").arg(call)); auto qthQueryAction = menu->addAction(QString("%1 QTH? - What is your QTH message?").arg(call).trimmed());
qthQueryAction->setDisabled(isAllCall); qthQueryAction->setDisabled(isAllCall);
connect(qthQueryAction, &QAction::triggered, this, [this](){ connect(qthQueryAction, &QAction::triggered, this, [this](){
@@ -6574,7 +6623,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
if(m_config.transmit_directed()) toggleTx(true); if(m_config.transmit_directed()) toggleTx(true);
}); });
auto gridQueryAction = menu->addAction(QString("%1 GRID? - What is your current grid locator?").arg(call)); auto gridQueryAction = menu->addAction(QString("%1 GRID? - What is your current grid locator?").arg(call).trimmed());
gridQueryAction->setDisabled(isAllCall); gridQueryAction->setDisabled(isAllCall);
connect(gridQueryAction, &QAction::triggered, this, [this](){ connect(gridQueryAction, &QAction::triggered, this, [this](){
@@ -6787,6 +6836,19 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
if(m_config.transmit_directed()) toggleTx(true); if(m_config.transmit_directed()) toggleTx(true);
}); });
auto tuAction = menu->addAction(QString("%1 TU - Thank You").arg(call).trimmed());
connect(tuAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
if(selectedCall.isEmpty()){
return;
}
addMessageText(QString("%1 TU").arg(selectedCall), true);
if(m_config.transmit_directed()) toggleTx(true);
});
auto qrzAction = menu->addAction(QString("%1 QRZ? - Who is calling me?").arg(call).trimmed()); auto qrzAction = menu->addAction(QString("%1 QRZ? - Who is calling me?").arg(call).trimmed());
connect(qrzAction, &QAction::triggered, this, [this](){ connect(qrzAction, &QAction::triggered, this, [this](){
@@ -6888,6 +6950,7 @@ QMap<QString, QString> MainWindow::buildMacroValues(){
auto cd = m_callActivity[selectedCall]; auto cd = m_callActivity[selectedCall];
values["<CALL>"] = selectedCall; values["<CALL>"] = selectedCall;
values["<TDELTA>"] = QString("%1 ms").arg((int)(1000*cd.tdrift));
if(cd.snr > -31){ if(cd.snr > -31){
values["<SNR>"] = Varicode::formatSNR(cd.snr); values["<SNR>"] = Varicode::formatSNR(cd.snr);
@@ -8018,7 +8081,12 @@ void MainWindow::updateTextDisplay(){
} }
} }
#if __APPLE__
#define USE_SYNC_FRAME_COUNT 1
#else
#define USE_SYNC_FRAME_COUNT 0 #define USE_SYNC_FRAME_COUNT 0
#endif
void MainWindow::refreshTextDisplay(){ void MainWindow::refreshTextDisplay(){
qDebug() << "refreshing text display..."; qDebug() << "refreshing text display...";
@@ -8029,8 +8097,8 @@ void MainWindow::refreshTextDisplay(){
QStringList textList; QStringList textList;
qDebug() << "frames:"; qDebug() << "frames:";
foreach(Frame frame, frames){ foreach(auto frame, frames){
auto dt = DecodedText(frame.frame, frame.bits); auto dt = DecodedText(frame.first, frame.second);
qDebug() << "->" << frame << dt.message() << Varicode::frameTypeString(dt.frameType()); qDebug() << "->" << frame << dt.message() << Varicode::frameTypeString(dt.frameType());
textList.append(dt.message()); textList.append(dt.message());
} }
@@ -8269,12 +8337,15 @@ void MainWindow::observeTimeDeltaForAverage(float delta){
} }
// display average // display average
ui->driftAvgLabel->setText(QString("Avg RX TDrift: %1 ms").arg(m_timeDeltaMsMMA)); ui->driftAvgLabel->setText(QString("Avg Time Delta: %1 ms").arg(m_timeDeltaMsMMA));
} }
void MainWindow::resetTimeDeltaAverage(){ void MainWindow::resetTimeDeltaAverage(){
m_timeDeltaMsMMA = 0; m_timeDeltaMsMMA = 0;
m_timeDeltaMsMMA_N = 0; m_timeDeltaMsMMA_N = 0;
// observe zero for reset
observeTimeDeltaForAverage(0);
} }
void MainWindow::processRxActivity() { void MainWindow::processRxActivity() {
@@ -8721,7 +8792,7 @@ void MainWindow::processCommandActivity() {
continue; continue;
} }
reply = QString("%1 QTH %2").arg(d.from).arg(qth); reply = QString("%1 QTH %2").arg(d.from).arg(replaceMacros(qth, buildMacroValues(), true));
} }
// QUERIED ACTIVE // QUERIED ACTIVE
@@ -8745,7 +8816,11 @@ void MainWindow::processCommandActivity() {
// QUERIED STATION MESSAGE // QUERIED STATION MESSAGE
else if (d.cmd == " QTC?" && !isAllCall) { else if (d.cmd == " QTC?" && !isAllCall) {
reply = QString("%1 QTC %2").arg(d.from).arg(m_config.my_station()); QString qtc = m_config.my_station();
if(qtc.isEmpty()) {
continue;
}
reply = QString("%1 QTC %2").arg(d.from).arg(replaceMacros(qtc, buildMacroValues(), true));
} }
#if ALLOW_STATIONS_HEARD #if ALLOW_STATIONS_HEARD
@@ -8859,7 +8934,7 @@ void MainWindow::processCommandActivity() {
} }
// PROCESS HEARTBEAT // PROCESS HEARTBEAT
else if (d.cmd == " HEARTBEAT" && ui->heartbeatButton->isChecked() && ui->autoReplyButton->isChecked()){ else if (d.cmd == " HEARTBEAT" && ui->heartbeatButton->isChecked() && ui->autoReplyButton->isChecked() && !ui->selcalButton->isChecked()){
reply = QString("%1 HEARTBEAT ACK %2").arg(d.from).arg(Varicode::formatSNR(d.snr)); reply = QString("%1 HEARTBEAT ACK %2").arg(d.from).arg(Varicode::formatSNR(d.snr));
enqueueHeartbeat(reply); enqueueHeartbeat(reply);
@@ -8956,6 +9031,7 @@ void MainWindow::processCommandActivity() {
} }
#endif #endif
// well, if there's no reply, don't do anything...
if (reply.isEmpty()) { if (reply.isEmpty()) {
continue; continue;
} }
@@ -8965,6 +9041,11 @@ void MainWindow::processCommandActivity() {
continue; continue;
} }
// do not queue for reply if there's text in the window
if(!ui->extFreeTextMsgEdit->toPlainText().isEmpty()){
continue;
}
// add @ALLCALLs to the @ALLCALL cache // add @ALLCALLs to the @ALLCALL cache
if(isAllCall){ if(isAllCall){
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 25); m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 25);
@@ -9397,7 +9478,7 @@ void MainWindow::displayBandActivity() {
ui->tableWidgetRXAll->setColumnHidden(0, !showColumn("band", "offset")); ui->tableWidgetRXAll->setColumnHidden(0, !showColumn("band", "offset"));
ui->tableWidgetRXAll->setColumnHidden(1, !showColumn("band", "timestamp")); ui->tableWidgetRXAll->setColumnHidden(1, !showColumn("band", "timestamp"));
ui->tableWidgetRXAll->setColumnHidden(2, !showColumn("band", "snr")); ui->tableWidgetRXAll->setColumnHidden(2, !showColumn("band", "snr"));
ui->tableWidgetRXAll->setColumnHidden(3, !showColumn("band", "tdrift")); ui->tableWidgetRXAll->setColumnHidden(3, !showColumn("band", "tdrift", false));
// Resize the table columns // Resize the table columns
ui->tableWidgetRXAll->resizeColumnToContents(0); ui->tableWidgetRXAll->resizeColumnToContents(0);
@@ -9509,6 +9590,10 @@ void MainWindow::displayCallActivity() {
int callsignAging = m_config.callsign_aging(); int callsignAging = m_config.callsign_aging();
foreach(QString call, keys) { foreach(QString call, keys) {
if(call.trimmed().isEmpty()){
continue;
}
CallDetail d = m_callActivity[call]; CallDetail d = m_callActivity[call];
bool isCallSelected = (call == selectedCall); bool isCallSelected = (call == selectedCall);
@@ -9585,11 +9670,11 @@ void MainWindow::displayCallActivity() {
ui->tableWidgetCalls->setColumnHidden(0, !showColumn("call", "callsign")); ui->tableWidgetCalls->setColumnHidden(0, !showColumn("call", "callsign"));
ui->tableWidgetCalls->setColumnHidden(1, !showColumn("call", "flag")); ui->tableWidgetCalls->setColumnHidden(1, !showColumn("call", "flag"));
ui->tableWidgetCalls->setColumnHidden(2, !showColumn("call", "timestamp")); ui->tableWidgetCalls->setColumnHidden(2, !showColumn("call", "timestamp"));
ui->tableWidgetCalls->setColumnHidden(3, !showColumn("call", "offset")); ui->tableWidgetCalls->setColumnHidden(3, !showColumn("call", "snr"));
ui->tableWidgetCalls->setColumnHidden(4, !showColumn("call", "snr")); ui->tableWidgetCalls->setColumnHidden(4, !showColumn("call", "offset"));
ui->tableWidgetCalls->setColumnHidden(5, !showColumn("call", "tdrift")); ui->tableWidgetCalls->setColumnHidden(5, !showColumn("call", "tdrift", false));
ui->tableWidgetCalls->setColumnHidden(6, !showColumn("call", "grid")); ui->tableWidgetCalls->setColumnHidden(6, !showColumn("call", "grid", false));
ui->tableWidgetCalls->setColumnHidden(7, !showColumn("call", "distance")); ui->tableWidgetCalls->setColumnHidden(7, !showColumn("call", "distance", false));
// Resize the table columns // Resize the table columns
ui->tableWidgetCalls->resizeColumnToContents(0); ui->tableWidgetCalls->resizeColumnToContents(0);
+1 -1
View File
@@ -271,7 +271,7 @@ private slots:
void on_qthMacroButton_clicked(); void on_qthMacroButton_clicked();
void on_qtcMacroButton_clicked(); void on_qtcMacroButton_clicked();
void setShowColumn(QString tableKey, QString columnKey, bool value); void setShowColumn(QString tableKey, QString columnKey, bool value);
bool showColumn(QString tableKey, QString columnKey); bool showColumn(QString tableKey, QString columnKey, bool default_=true);
void buildShowColumnsMenu(QMenu *menu, QString tableKey); void buildShowColumnsMenu(QMenu *menu, QString tableKey);
void setSortBy(QString key, QString value); void setSortBy(QString key, QString value);
QString getSortBy(QString key, QString defaultValue); QString getSortBy(QString key, QString defaultValue);
+4 -4
View File
@@ -1277,7 +1277,7 @@ background-color: #00ff00;
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Rx TDrift</string> <string>Time Delta</string>
</property> </property>
</column> </column>
<column> <column>
@@ -1422,7 +1422,7 @@ QTextEdit[transmitting=&quot;true&quot;] {
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string/> <string>✓</string>
</property> </property>
<property name="textAlignment"> <property name="textAlignment">
<set>AlignCenter</set> <set>AlignCenter</set>
@@ -1445,7 +1445,7 @@ QTextEdit[transmitting=&quot;true&quot;] {
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Rx TDrift</string> <string>Time Delta</string>
</property> </property>
</column> </column>
<column> <column>
@@ -2065,7 +2065,7 @@ background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #2ecc71, stop:1 #00FF
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>Avg RX TDrift: 0 ms</string> <string>Avg Time Delta: 0 ms</string>
</property> </property>
</widget> </widget>
</item> </item>
+5 -3
View File
@@ -65,7 +65,8 @@ QMap<QString, int> directed_cmds = {
//{"!", 7 }, // alert message //{"!", 7 }, // alert message
//{"$", 3 }, // query station(s) heard //{"$", 3 }, // query station(s) heard
//{"=", 9 }, // unused
{" TU", 9 }, // thank you
{" ACTIVE", 10 }, // i have been active in the past 10 minutes {" ACTIVE", 10 }, // i have been active in the past 10 minutes
{" IDLE", 11 }, // i have not been active in the past 10 minutes {" IDLE", 11 }, // i have not been active in the past 10 minutes
@@ -96,7 +97,7 @@ QMap<QString, int> directed_cmds = {
{" ", 31 }, // send freetext {" ", 31 }, // send freetext
}; };
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> 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}; QSet<int> buffered_cmds = {3, 5, /*6,*/ /*7,*/ 8, 13, 14, 15};
@@ -111,7 +112,7 @@ QMap<int, int> checksum_cmds = {
}; };
QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)"); QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)");
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:HEARTBEAT (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|(?:(?:ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|ACTIVE|IDLE)(?=[ ]|$))|[?*^&@#> ]))?"); QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:HEARTBEAT (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|(?:(?:ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|ACTIVE|IDLE|TU)(?=[ ]|$))|[?*^&@#> ]))?");
QString optional_grid_pattern = QString("(?<grid>\\s?[A-R]{2}[0-9]{2})?"); 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_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|HEARTBEAT ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?"); QString optional_num_pattern = QString("(?<num>(?<=SNR|HEARTBEAT ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
@@ -1622,6 +1623,7 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(
#define ALLOW_SEND_COMPOUND_DIRECTED 1 #define ALLOW_SEND_COMPOUND_DIRECTED 1
#define AUTO_PREPEND_DIRECTED 1 #define AUTO_PREPEND_DIRECTED 1
#define AUTO_REMOVE_MYCALL 1 #define AUTO_REMOVE_MYCALL 1
#define AUTO_PREPEND_DIRECTED_ALLOW_TEXT_CALLSIGNS 1
bool mycallCompound = Varicode::isCompoundCallsign(mycall); bool mycallCompound = Varicode::isCompoundCallsign(mycall);