Proper handling of directed messages for compound calls using an alias scheme

This commit is contained in:
Jordan Sherer 2018-07-24 15:19:02 -04:00
parent 706a9b1ebd
commit 0bf2afa5f8
3 changed files with 145 additions and 38 deletions

View File

@ -90,7 +90,7 @@ bool DecodedText::tryUnpackCompound(){
} }
compound_ = QString("%1/%2").arg(parts.at(0), parts.at(1)); compound_ = QString("%1/%2").arg(parts.at(0), parts.at(1));
message_ = QString("%1:").arg(compound_); message_ = QString("%1: ").arg(compound_);
return true; return true;
} }
@ -110,10 +110,10 @@ bool DecodedText::tryUnpackDirected(){
if(parts.length() == 3){ if(parts.length() == 3){
// replace it with the correct unpacked (directed) // replace it with the correct unpacked (directed)
message_ = QString("%1: %2%3").arg(parts.at(0), parts.at(1), parts.at(2)); message_ = QString("%1: %2%3 ").arg(parts.at(0), parts.at(1), parts.at(2));
} else if(parts.length() == 4){ } else if(parts.length() == 4){
// replace it with the correct unpacked (directed numeric) // replace it with the correct unpacked (directed numeric)
message_ = QString("%1: %2%3 %4").arg(parts.at(0), parts.at(1), parts.at(2), parts.at(3)); message_ = QString("%1: %2%3 %4 ").arg(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
} else { } else {
// replace it with the correct unpacked (freetext) // replace it with the correct unpacked (freetext)
message_ = QString(parts.join("")); message_ = QString(parts.join(""));

View File

@ -164,7 +164,7 @@ namespace
{ {
Radio::Frequency constexpr default_frequency {14074000}; Radio::Frequency constexpr default_frequency {14074000};
QRegExp message_alphabet {"[- A-Za-z0-9+./?:!^]*"}; QRegExp message_alphabet {"[- A-Za-z0-9+./?:!^]*"};
QRegExp message_input_alphabet {"[- A-Za-z0-9+./?\\n:!^@&|]*"}; // @&| are used for commands but are never transmitted QRegExp message_input_alphabet {"[- A-Za-z0-9+./?\\n:!^@&|$]*"}; // @&|$ are used for commands but are never transmitted
// grid exact match excluding RR73 // grid exact match excluding RR73
QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"};
@ -1027,7 +1027,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->dxCallEntry->clear(); ui->dxCallEntry->clear();
ui->dxGridEntry->clear(); ui->dxGridEntry->clear();
auto f = findFreeFreqOffset(500, 2000, 50); auto f = findFreeFreqOffset(500, 2000, 50);
setFreq4(f, f); setFreqForRestore(f, false);
ui->cbVHFcontest->setChecked(false); // this needs to always be false ui->cbVHFcontest->setChecked(false); // this needs to always be false
ui->spotButton->setChecked(m_config.spot_to_psk_reporter()); ui->spotButton->setChecked(m_config.spot_to_psk_reporter());
@ -1043,21 +1043,18 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
connect(clearAction1, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->textEditRX); }); connect(clearAction1, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->textEditRX); });
ui->textEditRX->setContextMenuPolicy(Qt::ActionsContextMenu); ui->textEditRX->setContextMenuPolicy(Qt::ActionsContextMenu);
ui->textEditRX->addAction(clearAction1); ui->textEditRX->addAction(clearAction1);
ui->textEditRX->addAction(clearActionSep);
ui->textEditRX->addAction(clearActionAll); ui->textEditRX->addAction(clearActionAll);
auto clearAction2 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->extFreeTextMsgEdit); auto clearAction2 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->extFreeTextMsgEdit);
connect(clearAction2, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->extFreeTextMsgEdit); }); connect(clearAction2, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->extFreeTextMsgEdit); });
ui->extFreeTextMsgEdit->setContextMenuPolicy(Qt::ActionsContextMenu); ui->extFreeTextMsgEdit->setContextMenuPolicy(Qt::ActionsContextMenu);
ui->extFreeTextMsgEdit->addAction(clearAction2); ui->extFreeTextMsgEdit->addAction(clearAction2);
ui->extFreeTextMsgEdit->addAction(clearActionSep);
ui->extFreeTextMsgEdit->addAction(clearActionAll); ui->extFreeTextMsgEdit->addAction(clearActionAll);
auto clearAction3 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->tableWidgetRXAll); auto clearAction3 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->tableWidgetRXAll);
connect(clearAction3, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->tableWidgetRXAll); }); connect(clearAction3, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->tableWidgetRXAll); });
ui->tableWidgetRXAll->setContextMenuPolicy(Qt::ActionsContextMenu); ui->tableWidgetRXAll->setContextMenuPolicy(Qt::ActionsContextMenu);
ui->tableWidgetRXAll->addAction(clearAction3); ui->tableWidgetRXAll->addAction(clearAction3);
ui->tableWidgetRXAll->addAction(clearActionSep);
ui->tableWidgetRXAll->addAction(clearActionAll); ui->tableWidgetRXAll->addAction(clearActionAll);
auto clearAction4 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->tableWidgetCalls); auto clearAction4 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->tableWidgetCalls);
@ -1073,7 +1070,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
menu->addSeparator(); menu->addSeparator();
menu->addAction(clearAction4); menu->addAction(clearAction4);
menu->addSeparator();
menu->addAction(clearActionAll); menu->addAction(clearActionAll);
menu->popup(ui->tableWidgetCalls->mapToGlobal(point)); menu->popup(ui->tableWidgetCalls->mapToGlobal(point));
@ -3231,6 +3227,7 @@ void MainWindow::readFromStdout() //readFromStdout
ActivityDetail d; ActivityDetail d;
d.isLowConfidence = decodedtext.isLowConfidence(); d.isLowConfidence = decodedtext.isLowConfidence();
d.isFree = !decodedtext.isStandardMessage(); d.isFree = !decodedtext.isStandardMessage();
d.isCompound = decodedtext.isCompoundMessage();
d.bits = decodedtext.bits(); d.bits = decodedtext.bits();
d.firstCall = decodedtext.CQersCall(); d.firstCall = decodedtext.CQersCall();
if(d.firstCall.isEmpty()){ if(d.firstCall.isEmpty()){
@ -3245,7 +3242,7 @@ void MainWindow::readFromStdout() //readFromStdout
} }
d.freq = offset; d.freq = offset;
d.text = decodedtext.messageWords().first().trimmed(); d.text = decodedtext.messageWords().isEmpty() ? "" : decodedtext.messageWords().first().trimmed();
d.utcTimestamp = QDateTime::currentDateTimeUtc(); d.utcTimestamp = QDateTime::currentDateTimeUtc();
d.snr = decodedtext.snr(); d.snr = decodedtext.snr();
m_bandActivity[offset].append(d); m_bandActivity[offset].append(d);
@ -3333,6 +3330,24 @@ void MainWindow::readFromStdout() //readFromStdout
cd.utcTimestamp = d.utcTimestamp; cd.utcTimestamp = d.utcTimestamp;
m_callActivity[Radio::base_callsign(cd.call)] = cd; m_callActivity[Radio::base_callsign(cd.call)] = cd;
bool shouldCaptureThirdPartyCallsigns = false;
// check to see if this is a station we've heard 3rd party
if(shouldCaptureThirdPartyCallsigns && Radio::base_callsign(d.to) != Radio::base_callsign(m_config.my_callsign())){
QString relayCall = QString("%1|%2").arg(Radio::base_callsign(d.from)).arg(Radio::base_callsign(d.to));
int snr = -100;
if(parts.length() == 4){
snr = QString(parts.at(3)).toInt();
}
CallDetail td;
td.through = d.from;
td.call = d.to;
td.grid = "";
td.snr = snr;
td.freq = d.freq;
td.utcTimestamp = d.utcTimestamp;
m_callActivity[relayCall] = td;
}
int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged; int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged;
bool okToPost=(nsec>(4*m_TRperiod)/5); bool okToPost=(nsec>(4*m_TRperiod)/5);
if (okToPost){ if (okToPost){
@ -3412,10 +3427,10 @@ void MainWindow::readFromStdout() //readFromStdout
// TODO: jsherer - parse decode... // TODO: jsherer - parse decode...
RXDetail d; RXDetail d;
d.isFree = !decodedtext.isStandardMessage(); d.isFree = !decodedtext.isStandardMessage();
d.isCompound = decodedtext.isCompoundMessage();
d.bits = decodedtext.bits(); d.bits = decodedtext.bits();
d.freq = audioFreq; d.freq = audioFreq;
d.text = decodedtext.message(); d.text = decodedtext.message();
qDebug() << d.text;
d.utcTimestamp = QDateTime::currentDateTimeUtc(); d.utcTimestamp = QDateTime::currentDateTimeUtc();
m_rxFrameQueue.append(d); m_rxFrameQueue.append(d);
} }
@ -5369,7 +5384,9 @@ void MainWindow::clearActivity(){
// this is now duplicated in three places :( // this is now duplicated in three places :(
ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount()); ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount());
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, new QTableWidgetItem("ALLCALL")); auto item = new QTableWidgetItem("ALLCALL");
item->setData(Qt::UserRole, QVariant("ALLCALL"));
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, item);
ui->tableWidgetCalls->setSpan(ui->tableWidgetCalls->rowCount() - 1, 0, 1, ui->tableWidgetCalls->columnCount()); ui->tableWidgetCalls->setSpan(ui->tableWidgetCalls->rowCount() - 1, 0, 1, ui->tableWidgetCalls->columnCount());
clearTableWidget(ui->tableWidgetRXAll); clearTableWidget(ui->tableWidgetRXAll);
@ -5380,9 +5397,17 @@ void MainWindow::clearActivity(){
ui->extFreeTextMsgEdit->clear(); ui->extFreeTextMsgEdit->clear();
} }
int MainWindow::logRxTxMessageText(QDateTime date, bool isFree, QString text, int freq, bool tx, int block){ int MainWindow::logRxTxMessageText(QDateTime date, QString text, int freq, bool tx, int block){
auto c = ui->textEditRX->textCursor(); auto c = ui->textEditRX->textCursor();
// fixup compound callsigns cache / aliases...
foreach(auto call, m_compoundCallCache.keys()){
//QRegExp re(QString("").arg(call));
//text = text.replace(call, m_compoundCallCache[call]);
QRegularExpression re(QString(R"((?<![\/])%1(?![\/]))").arg(QRegularExpression::escape(call)));
text = text.replace(re, m_compoundCallCache[call]);
}
bool found = false; bool found = false;
if(block != -1){ if(block != -1){
QTextBlock b = c.document()->findBlockByNumber(block); QTextBlock b = c.document()->findBlockByNumber(block);
@ -5470,7 +5495,7 @@ void MainWindow::createMessageTransmitQueue(QString const& text){
m_txFrameCount = frames.length(); m_txFrameCount = frames.length();
int freq = currentFreq(); int freq = currentFreq();
logRxTxMessageText(QDateTime::currentDateTimeUtc(), false, lines.join(""), freq, true); logRxTxMessageText(QDateTime::currentDateTimeUtc(), lines.join(""), freq, true);
} }
void MainWindow::resetMessageTransmitQueue(){ void MainWindow::resetMessageTransmitQueue(){
@ -5557,6 +5582,7 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
QStringList lines; QStringList lines;
// prepare compound // prepare compound
bool compoundSent = false;
bool compound = Radio::is_compound_callsign(m_config.my_callsign()); bool compound = Radio::is_compound_callsign(m_config.my_callsign());
QString mycall = m_config.my_callsign(); QString mycall = m_config.my_callsign();
QString basecall = Radio::base_callsign(m_config.my_callsign()); QString basecall = Radio::base_callsign(m_config.my_callsign());
@ -5625,11 +5651,12 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
} }
if(useDir){ if(useDir){
if(compound){ if(compound && !compoundSent){
QString compoundFrame = Varicode::packCompoundMessage(basecall, fix, prefix, 0); QString compoundFrame = Varicode::packCompoundMessage(basecall, fix, prefix, 0);
if(!compoundFrame.isEmpty()){ if(!compoundFrame.isEmpty()){
frames.append(compoundFrame); frames.append(compoundFrame);
lines.append(QString("%1: ").arg(mycall)); lines.append(QString("%1: ").arg(mycall));
compoundSent = true;
} }
} }
@ -5637,10 +5664,10 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
// TODO: jsherer - would be nice to clean this up and have an object that can just decode the actual transmitted frames instead. // TODO: jsherer - would be nice to clean this up and have an object that can just decode the actual transmitted frames instead.
if(!line.startsWith(basecall) && !compound){ if(!line.startsWith(basecall) && !compound){
lines.append(QString("%1: ").arg(basecall)); lines.append(QString("%1: ").arg(lookupCallInCompoundCache(basecall)));
} }
lines.append(line.left(n)); lines.append(line.left(n) + " ");
line = line.mid(n); line = line.mid(n);
} }
@ -5924,7 +5951,11 @@ QString MainWindow::calculateDistance(QString const& grid)
// this function is called by auto_tx_mode, which is called by autoButton.clicked // this function is called by auto_tx_mode, which is called by autoButton.clicked
void MainWindow::on_startTxButton_toggled(bool checked) void MainWindow::on_startTxButton_toggled(bool checked)
{ {
if(checked){ toggleTx(checked);
}
void MainWindow::toggleTx(bool start){
if(start){
createMessage(ui->extFreeTextMsgEdit->toPlainText()); createMessage(ui->extFreeTextMsgEdit->toPlainText());
startTx(); startTx();
} else { } else {
@ -6963,8 +6994,10 @@ void MainWindow::on_clearAction_triggered(QObject * sender){
m_callActivity.clear(); m_callActivity.clear();
clearTableWidget((ui->tableWidgetCalls)); clearTableWidget((ui->tableWidgetCalls));
auto item = new QTableWidgetItem("ALLCALL");
item->setData(Qt::UserRole, QVariant("ALLCALL"));
ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount()); ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount());
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, new QTableWidgetItem("ALLCALL")); ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, item);
ui->tableWidgetCalls->setSpan(ui->tableWidgetCalls->rowCount() - 1, 0, 1, ui->tableWidgetCalls->columnCount()); ui->tableWidgetCalls->setSpan(ui->tableWidgetCalls->rowCount() - 1, 0, 1, ui->tableWidgetCalls->columnCount());
} }
@ -7018,7 +7051,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
bool isAllCall = call == "ALLCALL"; bool isAllCall = call == "ALLCALL";
auto sendReplyAction = menu->addAction("Reply to Callsign"); auto sendReplyAction = menu->addAction("CALL - Send a message to selected callsign");
connect(sendReplyAction, &QAction::triggered, this, [this](){ connect(sendReplyAction, &QAction::triggered, this, [this](){
@ -7031,7 +7064,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
}); });
auto sendSNRAction = menu->addAction("Send Signal Report"); auto sendSNRAction = menu->addAction("SNR - Send a signal report to the selected callsign");
sendSNRAction->setEnabled(m_callActivity.contains(call)); sendSNRAction->setEnabled(m_callActivity.contains(call));
connect(sendSNRAction, &QAction::triggered, this, [this](){ connect(sendSNRAction, &QAction::triggered, this, [this](){
@ -7046,6 +7079,9 @@ void MainWindow::buildQueryMenu(QMenu * menu){
auto d = m_callActivity[selectedCall]; auto d = m_callActivity[selectedCall];
addMessageText(QString("%1 SNR %2").arg(selectedCall).arg(Varicode::formatSNR(d.snr)), true); addMessageText(QString("%1 SNR %2").arg(selectedCall).arg(Varicode::formatSNR(d.snr)), true);
// perhaps a better name here?
toggleTx(true);
}); });
menu->addSeparator(); menu->addSeparator();
@ -7060,6 +7096,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1?").arg(selectedCall), true); addMessageText(QString("%1?").arg(selectedCall), true);
toggleTx(true);
}); });
auto qthAction = menu->addAction("@ - What is your QTH message?"); auto qthAction = menu->addAction("@ - What is your QTH message?");
@ -7072,6 +7109,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1@").arg(selectedCall), true); addMessageText(QString("%1@").arg(selectedCall), true);
toggleTx(true);
}); });
auto stationAction = menu->addAction("&& - What is your station message?"); auto stationAction = menu->addAction("&& - What is your station message?");
@ -7084,9 +7122,22 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1&").arg(selectedCall), true); addMessageText(QString("%1&").arg(selectedCall), true);
toggleTx(true);
});
auto heardAction = menu->addAction("$ - What stations are you hearing?");
heardAction->setDisabled(isAllCall);
connect(heardAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
if(selectedCall.isEmpty()){
return;
}
addMessageText(QString("%1$").arg(selectedCall), true);
toggleTx(true);
}); });
//menu->addAction("$ - What stations are you hearing?")->setEnabled(false);
//menu->addAction("| - Please relay the following message")->setEnabled(false); //menu->addAction("| - Please relay the following message")->setEnabled(false);
menu->addSeparator(); menu->addSeparator();
@ -7100,6 +7151,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1 AGN?").arg(selectedCall), true); addMessageText(QString("%1 AGN?").arg(selectedCall), true);
toggleTx(true);
}); });
auto rrAction = menu->addAction("RR - I acknowledge your last transmission"); auto rrAction = menu->addAction("RR - I acknowledge your last transmission");
@ -7111,6 +7163,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1 RR").arg(selectedCall), true); addMessageText(QString("%1 RR").arg(selectedCall), true);
toggleTx(true);
}); });
@ -7123,6 +7176,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1 YES").arg(selectedCall), true); addMessageText(QString("%1 YES").arg(selectedCall), true);
toggleTx(true);
}); });
auto noAction = menu->addAction("NO - I do not confirm your last inquiry"); auto noAction = menu->addAction("NO - I do not confirm your last inquiry");
@ -7134,6 +7188,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1 NO").arg(selectedCall), true); addMessageText(QString("%1 NO").arg(selectedCall), true);
toggleTx(true);
}); });
auto sevenThreeAction = menu->addAction("73 - I send my best regards / end of contact"); auto sevenThreeAction = menu->addAction("73 - I send my best regards / end of contact");
@ -7145,6 +7200,7 @@ void MainWindow::buildQueryMenu(QMenu * menu){
} }
addMessageText(QString("%1 73").arg(selectedCall), true); addMessageText(QString("%1 73").arg(selectedCall), true);
toggleTx(true);
}); });
} }
@ -7192,7 +7248,7 @@ void MainWindow::on_tableWidgetRXAll_cellClicked(int row, int col){
auto item = ui->tableWidgetRXAll->item(row, 0); auto item = ui->tableWidgetRXAll->item(row, 0);
int offset = item->text().toInt(); int offset = item->text().toInt();
setFreq4(offset, offset); setFreqForRestore(offset, false);
ui->tableWidgetCalls->selectionModel()->select( ui->tableWidgetCalls->selectionModel()->select(
ui->tableWidgetCalls->selectionModel()->selection(), ui->tableWidgetCalls->selectionModel()->selection(),
@ -7215,13 +7271,17 @@ void MainWindow::on_tableWidgetRXAll_cellDoubleClicked(int row, int col){
if(activityAging && d.utcTimestamp.secsTo(now)/60 >= activityAging){ if(activityAging && d.utcTimestamp.secsTo(now)/60 >= activityAging){
continue; continue;
} }
// TODO: jsherer - still ok to skip these here?
if(d.isCompound){
continue;
}
if(activityText.isEmpty()){ if(activityText.isEmpty()){
firstActivity = d.utcTimestamp; firstActivity = d.utcTimestamp;
} }
activityText.append(d.text); activityText.append(d.text);
} }
if(!activityText.isEmpty()){ if(!activityText.isEmpty()){
int block = logRxTxMessageText(firstActivity, true, activityText, offset, false); int block = logRxTxMessageText(firstActivity, activityText, offset, false);
m_rxFrameBlockNumbers[offset] = block; m_rxFrameBlockNumbers[offset] = block;
m_rxRecentCache.insert(offset/10*10, new QDateTime(QDateTime::currentDateTimeUtc()), 25); m_rxRecentCache.insert(offset/10*10, new QDateTime(QDateTime::currentDateTimeUtc()), 25);
} }
@ -7242,14 +7302,20 @@ void MainWindow::on_tableWidgetRXAll_selectionChanged(const QItemSelection &sele
} }
void MainWindow::on_tableWidgetCalls_cellClicked(int row, int col){ void MainWindow::on_tableWidgetCalls_cellClicked(int row, int col){
/*
auto item = ui->tableWidgetCalls->item(row, 0); auto item = ui->tableWidgetCalls->item(row, 0);
auto call = Radio::base_callsign(item->text()); auto call = Radio::base_callsign(item->data(Qt::UserRole).toString());
//auto call = Radio::base_callsign(item->text());
*/
auto call = callsignSelected();
if(!m_callActivity.contains(call)){ if(!m_callActivity.contains(call)){
return; return;
} }
auto d = m_callActivity[call]; auto d = m_callActivity[call];
setFreqForRestore(d.freq, true); setFreqForRestore(d.freq, false);
ui->tableWidgetRXAll->selectionModel()->select( ui->tableWidgetRXAll->selectionModel()->select(
ui->tableWidgetRXAll->selectionModel()->selection(), ui->tableWidgetRXAll->selectionModel()->selection(),
@ -7259,8 +7325,13 @@ void MainWindow::on_tableWidgetCalls_cellClicked(int row, int col){
void MainWindow::on_tableWidgetCalls_cellDoubleClicked(int row, int col){ void MainWindow::on_tableWidgetCalls_cellDoubleClicked(int row, int col){
on_tableWidgetCalls_cellClicked(row, col); on_tableWidgetCalls_cellClicked(row, col);
/*
auto item = ui->tableWidgetCalls->item(row, 0); auto item = ui->tableWidgetCalls->item(row, 0);
auto call = Radio::base_callsign(item->text()); auto call = Radio::base_callsign(item->data(Qt::UserRole).toString());
//auto call = Radio::base_callsign(item->text());
*/
auto call = callsignSelected();
addMessageText(call); addMessageText(call);
} }
@ -8188,7 +8259,10 @@ void MainWindow::updateButtonDisplay(){
QString MainWindow::callsignSelected(){ QString MainWindow::callsignSelected(){
if(!ui->tableWidgetCalls->selectedItems().isEmpty()){ if(!ui->tableWidgetCalls->selectedItems().isEmpty()){
auto selectedCalls = ui->tableWidgetCalls->selectedItems(); auto selectedCalls = ui->tableWidgetCalls->selectedItems();
return Radio::base_callsign(selectedCalls.first()->text()); if(!selectedCalls.isEmpty()){
auto call = selectedCalls.first()->data(Qt::UserRole).toString();
return Radio::base_callsign(call);
}
} }
if(!ui->tableWidgetRXAll->selectedItems().isEmpty()){ if(!ui->tableWidgetRXAll->selectedItems().isEmpty()){
@ -8311,6 +8385,7 @@ void MainWindow::displayActivity(bool force){
ui->tableWidgetRXAll->insertRow(ui->tableWidgetRXAll->rowCount()); ui->tableWidgetRXAll->insertRow(ui->tableWidgetRXAll->rowCount());
auto offsetItem = new QTableWidgetItem(QString("%1").arg(offset)); auto offsetItem = new QTableWidgetItem(QString("%1").arg(offset));
offsetItem->setData(Qt::UserRole, QVariant(offset));
ui->tableWidgetRXAll->setItem(ui->tableWidgetRXAll->rowCount() - 1, 0, offsetItem); ui->tableWidgetRXAll->setItem(ui->tableWidgetRXAll->rowCount() - 1, 0, offsetItem);
auto ageItem = new QTableWidgetItem(QString("(%1)").arg(age)); auto ageItem = new QTableWidgetItem(QString("(%1)").arg(age));
@ -8367,7 +8442,9 @@ void MainWindow::displayActivity(bool force){
clearTableWidget(ui->tableWidgetCalls); clearTableWidget(ui->tableWidgetCalls);
ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount()); ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount());
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, new QTableWidgetItem("ALLCALL")); auto item = new QTableWidgetItem("ALLCALL");
item->setData(Qt::UserRole, QVariant("ALLCALL"));
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, item);
ui->tableWidgetCalls->setSpan(ui->tableWidgetCalls->rowCount() - 1, 0, 1, ui->tableWidgetCalls->columnCount()); ui->tableWidgetCalls->setSpan(ui->tableWidgetCalls->rowCount() - 1, 0, 1, ui->tableWidgetCalls->columnCount());
if(selectedCall == "ALLCALL"){ if(selectedCall == "ALLCALL"){
ui->tableWidgetCalls->selectRow(ui->tableWidgetCalls->rowCount() - 1); ui->tableWidgetCalls->selectRow(ui->tableWidgetCalls->rowCount() - 1);
@ -8384,7 +8461,11 @@ void MainWindow::displayActivity(bool force){
} }
ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount()); ui->tableWidgetCalls->insertRow(ui->tableWidgetCalls->rowCount());
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, new QTableWidgetItem(d.call));
QString displayCall = d.through.isEmpty() ? d.call : QString("%1 | %2").arg(d.through).arg(d.call);
auto displayItem = new QTableWidgetItem(displayCall);
displayItem->setData(Qt::UserRole, QVariant((d.call)));
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 0, displayItem);
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 1, new QTableWidgetItem(QString("(%1)").arg(since(d.utcTimestamp)))); ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 1, new QTableWidgetItem(QString("(%1)").arg(since(d.utcTimestamp))));
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 2, new QTableWidgetItem(QString("%1").arg(Varicode::formatSNR(d.snr)))); ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 2, new QTableWidgetItem(QString("%1").arg(Varicode::formatSNR(d.snr))));
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 3, new QTableWidgetItem(QString("%1").arg(d.grid))); ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, 3, new QTableWidgetItem(QString("%1").arg(d.grid)));
@ -8406,8 +8487,12 @@ void MainWindow::displayActivity(bool force){
// Recently Directed Activity // Recently Directed Activity
while(!m_rxFrameQueue.isEmpty()){ while(!m_rxFrameQueue.isEmpty()){
RXDetail d = m_rxFrameQueue.first(); RXDetail d = m_rxFrameQueue.dequeue();
m_rxFrameQueue.removeFirst();
// TODO: jsherer - is it safe to just ignore printing these?
if(d.isCompound){
continue;
}
bool isLast = d.bits == Varicode::FT8CallLast; bool isLast = d.bits == Varicode::FT8CallLast;
@ -8417,7 +8502,7 @@ void MainWindow::displayActivity(bool force){
int freq = d.freq/10*10; int freq = d.freq/10*10;
int block = m_rxFrameBlockNumbers.contains(freq) ? m_rxFrameBlockNumbers[freq] : -1; int block = m_rxFrameBlockNumbers.contains(freq) ? m_rxFrameBlockNumbers[freq] : -1;
block = logRxTxMessageText(d.utcTimestamp, d.isFree, d.text, d.freq, false, block); block = logRxTxMessageText(d.utcTimestamp, d.text, d.freq, false, block);
m_rxFrameBlockNumbers[freq] = block; m_rxFrameBlockNumbers[freq] = block;
if(isLast){ if(isLast){
@ -8447,7 +8532,7 @@ void MainWindow::displayActivity(bool force){
continue; continue;
} }
// we're only processing allcall and our callsign at this point // we're only responding to allcall and our callsign at this point, but we'll log callsigns we've heard
if(!isAllCall && d.to != m_config.my_callsign().trimmed() && d.to != Radio::base_callsign(m_config.my_callsign()).trimmed()){ if(!isAllCall && d.to != m_config.my_callsign().trimmed() && d.to != Radio::base_callsign(m_config.my_callsign()).trimmed()){
continue; continue;
} }
@ -8460,11 +8545,11 @@ void MainWindow::displayActivity(bool force){
// construct reply // construct reply
QString reply; QString reply;
// SNR // QUERIED SNR
if(d.cmd == "?"){ if(d.cmd == "?"){
reply = QString("%1 SNR %2").arg(Radio::base_callsign(d.from)).arg(Varicode::formatSNR(d.snr)); reply = QString("%1 SNR %2").arg(Radio::base_callsign(d.from)).arg(Varicode::formatSNR(d.snr));
} }
// QTH // QUERIED QTH
else if(d.cmd == "@" && !isAllCall){ else if(d.cmd == "@" && !isAllCall){
QString qth = m_config.my_qth(); QString qth = m_config.my_qth();
if(qth.isEmpty()){ if(qth.isEmpty()){
@ -8477,9 +8562,27 @@ void MainWindow::displayActivity(bool force){
reply = QString("%1 %2").arg(Radio::base_callsign(d.from)).arg(qth); reply = QString("%1 %2").arg(Radio::base_callsign(d.from)).arg(qth);
} }
// STATION MESSAGE // QUERIED STATION MESSAGE
else if(d.cmd == "&" && !isAllCall){ else if(d.cmd == "&" && !isAllCall){
reply = QString("%1 %2").arg(Radio::base_callsign(d.from)).arg(m_config.my_station()); reply = QString("%1 %2").arg(Radio::base_callsign(d.from)).arg(m_config.my_station());
}
// QUERIED STATIONS HEARD
else if(d.cmd == "$" && !isAllCall){
auto calls = m_callActivity.keys();
qSort(calls.begin(), calls.end(), [this](QString const &a, QString const &b){
auto left = m_callActivity[a];
auto right = m_callActivity[b];
return right.snr < left.snr;
});
QStringList lines;
foreach(auto call, calls){
auto d = m_callActivity[call];
lines.append(QString("%1 SNR %2").arg(Radio::base_callsign(call)).arg(Varicode::formatSNR(d.snr)));
}
reply = lines.join('\n');
} else { } else {
continue; continue;
} }

View File

@ -123,7 +123,7 @@ public slots:
QString lookupCallInCompoundCache(QString const &call); QString lookupCallInCompoundCache(QString const &call);
void clearActivity(); void clearActivity();
int logRxTxMessageText(QDateTime date, bool isFree, QString text, int freq, bool tx, int block=-1); int logRxTxMessageText(QDateTime date, QString text, int freq, bool tx, int block=-1);
void addMessageText(QString text, bool clear=false); void addMessageText(QString text, bool clear=false);
void resetMessage(); void resetMessage();
void resetMessageUI(); void resetMessageUI();
@ -199,6 +199,7 @@ private slots:
void on_txb5_doubleClicked (); void on_txb5_doubleClicked ();
void on_txb6_clicked(); void on_txb6_clicked();
void on_startTxButton_toggled(bool checked); void on_startTxButton_toggled(bool checked);
void toggleTx(bool start);
void splitAndSendNextMessage(); void splitAndSendNextMessage();
void on_rbNextFreeTextMsg_toggled (bool status); void on_rbNextFreeTextMsg_toggled (bool status);
void on_lookupButton_clicked(); void on_lookupButton_clicked();
@ -639,6 +640,7 @@ private:
struct CallDetail struct CallDetail
{ {
QString call; QString call;
QString through;
QString grid; QString grid;
int freq; int freq;
QDateTime utcTimestamp; QDateTime utcTimestamp;
@ -659,6 +661,7 @@ private:
{ {
bool isFree; bool isFree;
bool isLowConfidence; bool isLowConfidence;
bool isCompound;
int bits; int bits;
QString firstCall; QString firstCall;
QString secondCall; QString secondCall;
@ -672,6 +675,7 @@ private:
{ {
bool isFree; bool isFree;
bool isLowConfidence; bool isLowConfidence;
bool isCompound;
int bits; int bits;
int freq; int freq;
QString text; QString text;