From 4b6d343850eef35f6ab7fc625bfa7e1eaffae366 Mon Sep 17 00:00:00 2001 From: Jordan Sherer Date: Sat, 28 Mar 2020 15:10:41 -0400 Subject: [PATCH] Configurable custom HB and STATUS messages --- Configuration.cpp | 42 ++++++ Configuration.hpp | 6 +- Configuration.ui | 104 ++++++++++----- Versions.cmake | 4 +- mainwindow.cpp | 102 ++++++++------- mainwindow.h | 3 +- mainwindow.ui | 319 ++++++++++++++++++++++++---------------------- varicode.cpp | 7 +- 8 files changed, 354 insertions(+), 233 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 69b33ea..86710dd 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -578,6 +578,7 @@ private: unsigned transceiver_command_number_; QString dynamic_grid_; QString dynamic_info_; + QString dynamic_status_; // configuration fields that we publish bool auto_switch_bands_; @@ -591,7 +592,9 @@ private: QStringList secondary_highlight_words_; QString eot_; QString my_info_; + QString my_status_; QString cq_; + QString hb_; QString reply_; int callsign_aging_; int activity_aging_; @@ -1070,6 +1073,21 @@ QString Configuration::my_info() const return info.trimmed(); } +QString Configuration::my_status() const +{ + auto status = m_->my_status_; + if(m_->use_dynamic_info_ && !m_->dynamic_status_.isEmpty()){ + status = m_->dynamic_status_; + } + + return status.trimmed(); +} + +QString Configuration::hb_message() const +{ + return m_->hb_.trimmed(); +} + QString Configuration::cq_message() const { return m_->cq_.trimmed().replace("CQCQCQ", "CQ CQ CQ"); // deprecate legacy @@ -1100,6 +1118,12 @@ void Configuration::set_dynamic_station_info(QString const& info) m_->dynamic_info_ = info.trimmed (); } +void Configuration::set_dynamic_station_status(QString const& status) +{ + m_->dynamic_status_ = status.trimmed (); +} + + namespace { #if defined (Q_OS_MAC) @@ -1261,14 +1285,18 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory, ui_->info_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); ui_->reply_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); ui_->cq_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); + ui_->hb_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); + ui_->status_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); ui_->groups_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); setUppercase(ui_->callsign_line_edit); setUppercase(ui_->grid_line_edit); setUppercase(ui_->add_macro_line_edit); setUppercase(ui_->info_message_line_edit); + setUppercase(ui_->status_message_line_edit); setUppercase(ui_->reply_message_line_edit); setUppercase(ui_->cq_message_line_edit); + setUppercase(ui_->hb_message_line_edit); setUppercase(ui_->groups_line_edit); setUppercase(ui_->auto_whitelist_line_edit); @@ -1476,7 +1504,9 @@ void Configuration::impl::initialize_models () ui_->secondaryHighlightLineEdit->setText(secondary_highlight_words_.join(", ")); ui_->eot_line_edit->setText(eot_.trimmed().left(2)); ui_->info_message_line_edit->setText (my_info_.toUpper()); + ui_->status_message_line_edit->setText (my_status_.toUpper()); ui_->cq_message_line_edit->setText(cq_.toUpper().replace("CQCQCQ", "CQ CQ CQ")); + ui_->hb_message_line_edit->setText(hb_.toUpper()); ui_->reply_message_line_edit->setText (reply_.toUpper()); ui_->use_dynamic_grid->setChecked(use_dynamic_info_); @@ -1753,6 +1783,8 @@ void Configuration::impl::read_settings () activity_aging_ = settings_->value ("ActivityAging", 2).toInt (); eot_ = settings_->value("EOTCharacter", QString{"\u2662"}).toString().trimmed().left(2); my_info_ = settings_->value("MyInfo", QString {}).toString(); + my_status_ = settings_->value("MyStatus", QString {"IDLE VERSION "}).toString(); + hb_ = settings_->value("HBMessage", QString {"HB "}).toString(); cq_ = settings_->value("CQMessage", QString {"CQ CQ CQ "}).toString(); reply_ = settings_->value("Reply", QString {"HW CPY?"}).toString(); next_color_cq_ = color_cq_ = settings_->value("colorCQ","#66ff66").toString(); @@ -2070,7 +2102,9 @@ void Configuration::impl::write_settings () settings_->setValue ("SecondaryHighlightWords", secondary_highlight_words_); settings_->setValue ("EOTCharacter", eot_); settings_->setValue ("MyInfo", my_info_); + settings_->setValue ("MyStatus", my_status_); settings_->setValue ("CQMessage", cq_); + settings_->setValue ("HBMessage", hb_); settings_->setValue ("Reply", reply_); settings_->setValue ("CallsignAging", callsign_aging_); settings_->setValue ("ActivityAging", activity_aging_); @@ -2435,6 +2469,12 @@ bool Configuration::impl::validate () } } + auto hb = ui_->hb_message_line_edit->text().toUpper().trimmed(); + if(!hb.isEmpty() && !(hb.startsWith("HB") || hb.contains(callsign))){ + MessageBox::critical_message (this, QString("The HB message format is invalid. It must either start with \"HB\" or contain your callsign.")); + return false; + } + auto cq = ui_->cq_message_line_edit->text().toUpper().trimmed(); if(!cq.isEmpty() && !(cq.startsWith("CQ") || cq.contains(callsign))){ MessageBox::critical_message (this, QString("The CQ message format is invalid. It must either start with \"CQ\" or contain your callsign.")); @@ -2749,9 +2789,11 @@ void Configuration::impl::accept () primary_highlight_words_ = splitWords(ui_->primaryHighlightLineEdit->text().toUpper().trimmed()); secondary_highlight_words_ = splitWords(ui_->secondaryHighlightLineEdit->text().toUpper().trimmed()); cq_ = ui_->cq_message_line_edit->text().toUpper(); + hb_ = ui_->hb_message_line_edit->text().toUpper(); reply_ = ui_->reply_message_line_edit->text().toUpper(); eot_ = ui_->eot_line_edit->text().trimmed().left(2); my_info_ = ui_->info_message_line_edit->text().toUpper(); + my_status_ = ui_->status_message_line_edit->text().toUpper(); callsign_aging_ = ui_->callsign_aging_spin_box->value(); activity_aging_ = ui_->activity_aging_spin_box->value(); spot_to_reporting_networks_ = ui_->psk_reporter_check_box->isChecked (); diff --git a/Configuration.hpp b/Configuration.hpp index 2c5f450..324cb21 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -116,6 +116,8 @@ public: int callsign_aging() const; QString eot() const; QString my_info () const; + QString my_status () const; + QString hb_message () const; QString cq_message () const; QString reply_message () const; QFont table_font() const; @@ -255,9 +257,11 @@ public: // Set the dynamic grid which is only used if configuration setting is enabled. void set_dynamic_location (QString const&); - // Set the dynamic station qth message which is only used if configuration setting is enabled. + // Set the dynamic station info message which is only used if configuration setting is enabled. void set_dynamic_station_info(QString const& info); + // Set the dynamic station status message which is only used if configuration setting is enabled. + void set_dynamic_station_status(QString const& status); // This method queries if a CAT and PTT connection is operational. bool is_transceiver_online () const; diff --git a/Configuration.ui b/Configuration.ui index b38b970..fab19e2 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -190,14 +190,14 @@ Station Messages - - + + - HW CPY? + IDLE <MYIDLE> VERSION <MYVERSION> - + Reply Message: @@ -205,27 +205,34 @@ - + - CQ Message: - - - - - - - CQCQCQ <MYGRID4> + HB Message: - - - <html><head/><body><p>Station location message that is transmitted in response to &quot;@&quot; directed queries.</p></body></html> + + + HW CPY? - + + + + HB <MYGRID4> + + + + + + + CQ CQ CQ <MYGRID4> + + + + <html><head/><body><p>Station location message</p></body></html> @@ -235,6 +242,27 @@ + + + + Station Status (Weather, Idle Time, Version, etc): + + + + + + + <html><head/><body><p>Station location message that is transmitted in response to &quot;@&quot; directed queries.</p></body></html> + + + + + + + CQ Message: + + + @@ -281,7 +309,7 @@ 0 0 - 615 + 724 537 @@ -1534,7 +1562,7 @@ a few, particularly some Kenwood rigs, require it). 0 0 - 494 + 718 490 @@ -1938,8 +1966,8 @@ this setting allows you to select which audio input will be used 0 0 - 266 - 345 + 760 + 510 @@ -2325,7 +2353,7 @@ both here. 0 0 - 508 + 746 567 @@ -2522,7 +2550,7 @@ comments field. <html><head/><body><p>Check to allow changes to grid, qtc, etc from external programs</p></body></html> - Accept Dynamic Station Information + Accept Dynamic Station Information (Grid, Info, Status, etc) @@ -2850,8 +2878,8 @@ for assessing propagation and system performance. 0 0 - 487 - 341 + 760 + 510 @@ -3187,8 +3215,8 @@ QListView::item:hover { 0 0 - 163 - 99 + 760 + 510 @@ -3330,8 +3358,8 @@ QListView::item:hover { 0 0 - 274 - 690 + 724 + 418 @@ -4401,9 +4429,11 @@ soundcard changes grid_line_edit groups_line_edit avoid_allcall_check_box + hb_message_line_edit cq_message_line_edit reply_message_line_edit info_message_line_edit + status_message_line_edit scrollArea_2 miles_check_box monitor_off_check_box @@ -4521,6 +4551,22 @@ soundcard changes sbBandwidth cbx4ToneSpacing sbNtrials + write_logs_check_box + scrollArea_11 + heartbeat_anywhere_check_box + heartbeat_qso_pause_check_box + hb_blacklist_line_edit + autoreply_on_check_box + cqMessagesButton + relay_disabled_check_box + auto_whitelist_line_edit + auto_blacklist_line_edit + tx_watchdog_spin_box + autoreply_confirmation_check_box + notification_sound_output_combo_box + scrollArea_12 + notifications_check_box + notifications_table_widget diff --git a/Versions.cmake b/Versions.cmake index e02c664..520fde7 100644 --- a/Versions.cmake +++ b/Versions.cmake @@ -1,6 +1,6 @@ # Version number components set (WSJTX_VERSION_MAJOR 2) -set (WSJTX_VERSION_MINOR 1) -set (WSJTX_VERSION_PATCH 2) +set (WSJTX_VERSION_MINOR 2) +set (WSJTX_VERSION_PATCH 0) 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 diff --git a/mainwindow.cpp b/mainwindow.cpp index af45f50..25a2f3e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -8127,10 +8127,15 @@ void MainWindow::sendHeartbeat(){ QString mygrid = m_config.my_grid().left(4); QStringList parts; - parts.append(QString("%1:").arg(mycall)); - parts.append("HB"); - parts.append(mygrid); + + auto hb = m_config.hb_message(); + if(hb.isEmpty()){ + parts.append("HB"); + parts.append(mygrid); + } else { + parts.append(hb); + } QString message = parts.join(" ").trimmed(); @@ -8286,6 +8291,17 @@ void MainWindow::on_infoMacroButton_clicked(){ if(m_config.transmit_directed()) toggleTx(true); } +void MainWindow::on_statusMacroButton_clicked(){ + QString status = m_config.my_status(); + if(status.isEmpty()){ + return; + } + + addMessageText(QString("STATUS %1").arg(replaceMacros(status, buildMacroValues(), true))); + + if(m_config.transmit_directed()) toggleTx(true); +} + void MainWindow::setShowColumn(QString tableKey, QString columnKey, bool value){ m_showColumnsCache[tableKey + columnKey] = QVariant(value); displayBandActivity(); @@ -8843,14 +8859,22 @@ void MainWindow::buildEditMenu(QMenu *menu, QTextEdit *edit){ } QMap MainWindow::buildMacroValues(){ + auto lastActive = DriftingDateTime::currentDateTimeUtc().addSecs(-m_idleMinutes*60); + QString myIdle = since(lastActive).toUpper().replace("NOW", "0M"); + QString myVersion = version().replace("-devel", "").replace("-rc", ""); + QMap values = { {"", m_config.my_callsign()}, {"", m_config.my_grid().left(4)}, {"", m_config.my_grid().left(12)}, {"", m_config.my_info()}, + {"", m_config.hb_message()}, {"", m_config.cq_message()}, {"", m_config.reply_message()}, - {"", generateStatus()}, + {"", m_config.my_status()}, + + {"", myVersion}, + {"", myIdle}, }; auto selectedCall = callsignSelected(); @@ -8867,7 +8891,9 @@ QMap MainWindow::buildMacroValues(){ // these macros can have recursive macros values[""] = replaceMacros(values[""], values, false); + values[""] = replaceMacros(values[""], values, false); values[""] = replaceMacros(values[""], values, false); + values[""] = replaceMacros(values[""], values, false); values[""] = replaceMacros(values[""], values, false); return values; @@ -9875,7 +9901,11 @@ void MainWindow::updateModeButtonText(){ } if(autoreply){ - modeText += QString("+AUTO"); + if(m_config.autoreply_confirmation()){ + modeText += QString("+AUTO+CONF"); + } else { + modeText += QString("+AUTO"); + } } if(heartbeat){ @@ -9894,12 +9924,14 @@ void MainWindow::updateButtonDisplay(){ auto selectedCallsign = callsignSelected(true); bool emptyCallsign = selectedCallsign.isEmpty(); bool emptyInfo = m_config.my_info().isEmpty(); + bool emptyStatus = m_config.my_status().isEmpty(); ui->hbMacroButton->setDisabled(isTransmitting); ui->cqMacroButton->setDisabled(isTransmitting); ui->replyMacroButton->setDisabled(isTransmitting || emptyCallsign); ui->snrMacroButton->setDisabled(isTransmitting || emptyCallsign); ui->infoMacroButton->setDisabled(isTransmitting || emptyInfo); + ui->statusMacroButton->setDisabled(isTransmitting || emptyStatus); ui->macrosMacroButton->setDisabled(isTransmitting); ui->queryButton->setDisabled(isTransmitting || emptyCallsign); ui->deselectButton->setDisabled(isTransmitting || emptyCallsign); @@ -10711,44 +10743,6 @@ void MainWindow::processBufferedActivity() { } } -QString MainWindow::generateStatus() { - auto lastActive = DriftingDateTime::currentDateTimeUtc().addSecs(-m_idleMinutes*60); - QString lastActiveString = since(lastActive).toUpper().replace("NOW", "0M"); - - QStringList status; - status.append(generateStatusFlags()); - - if(!lastActiveString.isEmpty()){ - status.append(lastActiveString.trimmed()); - } - - status.append("V" + version().replace("-devel", "").replace("-rc", "")); - - return status.join(" ").trimmed(); -} - -QStringList MainWindow::generateStatusFlags() { - QStringList flags; - - if(ui->hbMacroButton->isChecked() && m_hbInterval > 0){ - flags.append("HB"); - } - - if(ui->actionModeAutoreply->isChecked()){ - flags.append("AUTO"); - } - - if(ui->actionModeAutoreply->isChecked() && !m_config.relay_off()){ - flags.append("RELAY"); - } - - if(m_config.spot_to_reporting_networks()){ - flags.append("SPOT"); - } - - return flags; -} - void MainWindow::processCommandActivity() { #if 0 if (!m_txFrameQueue.isEmpty()) { @@ -10999,7 +10993,12 @@ void MainWindow::processCommandActivity() { // QUERIED ACTIVE else if (d.cmd == " STATUS?" && !isAllCall) { - reply = QString("%1 STATUS %2").arg(d.from).arg(generateStatus()); + QString status = m_config.my_status(); + if (status.isEmpty()) { + continue; + } + + reply = QString("%1 STATUS %2").arg(d.from).arg(replaceMacros(status, buildMacroValues(), true)); } // QUERIED GRID @@ -12583,6 +12582,21 @@ void MainWindow::networkMessage(Message const &message) return; } + if(type == "STATION.GET_STATUS"){ + sendNetworkMessage("STATION.STATUS", m_config.my_status(), { + {"_ID", id}, + }); + return; + } + + if(type == "STATION.SET_STATUS"){ + m_config.set_dynamic_station_status(message.value()); + sendNetworkMessage("STATION.STATUS", m_config.my_status(), { + {"_ID", id}, + }); + return; + } + // RX.GET_CALL_ACTIVITY // RX.GET_CALL_SELECTED // RX.GET_BAND_ACTIVITY diff --git a/mainwindow.h b/mainwindow.h index 5d09a20..dd02320 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -322,6 +322,7 @@ private slots: void on_replyMacroButton_clicked(); void on_snrMacroButton_clicked(); void on_infoMacroButton_clicked(); + void on_statusMacroButton_clicked(); void setShowColumn(QString tableKey, QString columnKey, bool value); bool showColumn(QString tableKey, QString columnKey, bool default_=true); void buildShowColumnsMenu(QMenu *menu, QString tableKey); @@ -992,8 +993,6 @@ private: void processIdleActivity(); void processCompoundActivity(); void processBufferedActivity(); - QString generateStatus(); - QStringList generateStatusFlags(); void processCommandActivity(); QString inboxPath(); void refreshInboxCounts(); diff --git a/mainwindow.ui b/mainwindow.ui index 1065c9f..7254325 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -1437,6 +1437,54 @@ QTextEdit[transmitting="true"] { 0 + + + + + 0 + 30 + + + + <html><head/><body><p>Send a directed message to another station</p></body></html> + + + Directed + + + + + + + + 0 + 30 + + + + <html><head/><body><p>Send an signal report</p></body></html> + + + SNR + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 10 + + + + @@ -1465,11 +1513,8 @@ QTextEdit[transmitting="true"] { - - - - false - + + 0 @@ -1477,26 +1522,26 @@ QTextEdit[transmitting="true"] { - <html><head/><body><p>Start transmitting</p></body></html> - - - false - - - QPushButton:checked { -background-color: #22FF22; -color:#222; -} -QPushButton[transmitting="true"]{ -background:#FF2222; -color:#222; -} + <html><head/><body><p>Send a saved message</p></body></html> - Send + Saved - - true + + + + + + + 0 + 30 + + + + <html><head/><body><p>Send your station information</p></body></html> + + + INFO @@ -1531,120 +1576,11 @@ color:#222; - - - - - 0 - 30 - - - - <html><head/><body><p>Send your station information</p></body></html> - - - INFO - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 20 - 10 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 20 - 10 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 20 - 10 - - - - - - - - - 0 - 30 - - - - <html><head/><body><p>Send an signal report</p></body></html> - - - SNR - - - - - - - - 0 - 30 - - - - <html><head/><body><p>Reply to a CQ</p></body></html> - - - REPLY - - - - - - - 75 - 30 - + + + false - - <html><head/><body><p>Stop transmitting</p></body></html> - - - Halt - - - - - 0 @@ -1652,30 +1588,30 @@ color:#222; - <html><head/><body><p>Send a saved message</p></body></html> + <html><head/><body><p>Start transmitting</p></body></html> + + + false + + + QPushButton:checked { +background-color: #22FF22; +color:#222; +} +QPushButton[transmitting="true"]{ +background:#FF2222; +color:#222; +} - Saved + Send + + + true - - - - - 0 - 30 - - - - <html><head/><body><p>Send a directed message to another station</p></body></html> - - - Directed - - - - + @@ -1697,6 +1633,83 @@ color:#222; + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 10 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 10 + + + + + + + + + 0 + 30 + + + + <html><head/><body><p>Reply to a CQ</p></body></html> + + + REPLY + + + + + + + + 75 + 30 + + + + <html><head/><body><p>Stop transmitting</p></body></html> + + + Halt + + + + + + + + 0 + 30 + + + + STATUS + + + diff --git a/varicode.cpp b/varicode.cpp index db6e0a8..546336f 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -262,7 +262,10 @@ QMap basecalls = { { "@RADAR", nbasecall + 42 }, // RADAR GROUP { "@SKYWARN", nbasecall + 43 }, // SKYWARN GROUP { "@CQ", nbasecall + 44 }, // CQ GROUP - { "@QSO", nbasecall + 45 }, // QSO GROUP + { "@HB", nbasecall + 45 }, // HB GROUP + { "@QSO", nbasecall + 46 }, // QSO GROUP + { "@QSOPARTY", nbasecall + 47 }, // QSO PARTY GROUP + { "@CONTEST", nbasecall + 48 }, // CONTEST GROUP }; QMap cqs = { @@ -342,7 +345,7 @@ int dbmTomwatts(int dbm){ QString Varicode::extendedChars(){ static QString c; if(c.size() == 0){ - for(int i = 0; i < JSC::prefixSize; i++){ + for(quint32 i = 0; i < JSC::prefixSize; i++){ if(JSC::prefix[i].size != 1){ continue; } c.append(QLatin1String(JSC::prefix[i].str, 1)); }