Compare commits
16 Commits
v1.0.0-rc3
...
v1.0.0-ga
| Author | SHA1 | Date | |
|---|---|---|---|
| 9423640e52 | |||
| 952cc0b844 | |||
| 0bd7a74103 | |||
| 82a0cdd0cf | |||
| 7f187f4cf8 | |||
| f2ba541f09 | |||
| e9d2d59842 | |||
| bda9a5202e | |||
| 40e1bfab0e | |||
| b031a2cdbe | |||
| a2c6451b47 | |||
| 3f6c87b200 | |||
| fa4c39495d | |||
| 5f3b74338c | |||
| d1ccbc599b | |||
| 6e036b7d58 |
+7
-1
@@ -628,6 +628,7 @@ private:
|
||||
qint32 RxBandwidth_;
|
||||
double degrade_;
|
||||
double txDelay_;
|
||||
bool check_for_updates_;
|
||||
bool id_after_73_;
|
||||
bool tx_qsy_allowed_;
|
||||
bool spot_to_reporting_networks_;
|
||||
@@ -750,6 +751,7 @@ qint32 Configuration::aggressive() const {return m_->aggressive_;}
|
||||
double Configuration::degrade() const {return m_->degrade_;}
|
||||
double Configuration::txDelay() const {return m_->txDelay_;}
|
||||
qint32 Configuration::RxBandwidth() const {return m_->RxBandwidth_;}
|
||||
bool Configuration::check_for_updates() const { return m_->check_for_updates_; }
|
||||
bool Configuration::id_after_73 () const {return m_->id_after_73_;}
|
||||
bool Configuration::tx_qsy_allowed () const {return m_->tx_qsy_allowed_;}
|
||||
bool Configuration::spot_to_reporting_networks () const
|
||||
@@ -772,7 +774,7 @@ bool Configuration::heartbeat_qso_pause() const { return m_->heartbeat_qso_pause
|
||||
bool Configuration::relay_off() const { return m_->relay_disabled_; }
|
||||
bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
|
||||
bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
|
||||
bool Configuration::log_as_DATA () const {return m_->log_as_DATA_;}
|
||||
bool Configuration::log_as_DATA () const { return false; }
|
||||
bool Configuration::report_in_comments () const {return m_->report_in_comments_;}
|
||||
bool Configuration::prompt_to_log () const {return m_->prompt_to_log_;}
|
||||
bool Configuration::insert_blank () const {return m_->insert_blank_;}
|
||||
@@ -1400,6 +1402,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->sound_cq_path_display_label->setText(sound_cq_path_);
|
||||
ui_->sound_dm_path_display_label->setText(sound_dm_path_);
|
||||
ui_->sound_am_path_display_label->setText(sound_am_path_);
|
||||
ui_->checkForUpdates_checkBox->setChecked (check_for_updates_);
|
||||
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
|
||||
ui_->tx_qsy_check_box->setChecked (tx_qsy_allowed_);
|
||||
ui_->psk_reporter_check_box->setChecked (spot_to_reporting_networks_);
|
||||
@@ -1677,6 +1680,7 @@ void Configuration::impl::read_settings ()
|
||||
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
|
||||
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
|
||||
spot_to_reporting_networks_ = settings_->value ("PSKReporter", true).toBool ();
|
||||
check_for_updates_ = settings_->value("CheckForUpdates", true).toBool();
|
||||
id_after_73_ = settings_->value ("After73", false).toBool ();
|
||||
tx_qsy_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
|
||||
use_dynamic_info_ = settings_->value ("AutoGrid", false).toBool ();
|
||||
@@ -1849,6 +1853,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
|
||||
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
|
||||
settings_->setValue ("PSKReporter", spot_to_reporting_networks_);
|
||||
settings_->setValue ("CheckForUpdates", check_for_updates_);
|
||||
settings_->setValue ("After73", id_after_73_);
|
||||
settings_->setValue ("TxQSYAllowed", tx_qsy_allowed_);
|
||||
settings_->setValue ("Macros", macros_.stringList ());
|
||||
@@ -2381,6 +2386,7 @@ void Configuration::impl::accept ()
|
||||
aggressive_ = ui_->sbAggressive->value ();
|
||||
degrade_ = ui_->sbDegrade->value ();
|
||||
RxBandwidth_ = ui_->sbBandwidth->value ();
|
||||
check_for_updates_ = ui_->checkForUpdates_checkBox->isChecked();
|
||||
id_after_73_ = ui_->CW_id_after_73_check_box->isChecked ();
|
||||
tx_qsy_allowed_ = ui_->tx_qsy_check_box->isChecked ();
|
||||
transmit_directed_ = ui_->transmit_directed_check_box->isChecked();
|
||||
|
||||
@@ -118,6 +118,7 @@ public:
|
||||
qint32 RxBandwidth() const;
|
||||
double degrade() const;
|
||||
double txDelay() const;
|
||||
bool check_for_updates() const;
|
||||
bool id_after_73 () const;
|
||||
bool tx_qsy_allowed () const;
|
||||
bool spot_to_reporting_networks () const;
|
||||
|
||||
+38
-25
@@ -23,7 +23,7 @@
|
||||
<string>Select tab to change configuration parameters.</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="general_tab">
|
||||
<attribute name="title">
|
||||
@@ -63,7 +63,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>738</width>
|
||||
<height>453</height>
|
||||
<height>448</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
@@ -278,8 +278,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>615</width>
|
||||
<height>646</height>
|
||||
<width>726</width>
|
||||
<height>631</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_26">
|
||||
@@ -394,6 +394,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkForUpdates_checkBox">
|
||||
<property name="text">
|
||||
<string>Check for software updates at startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
@@ -918,8 +925,8 @@ text message.</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>718</width>
|
||||
<height>435</height>
|
||||
<width>285</width>
|
||||
<height>397</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_27">
|
||||
@@ -1339,8 +1346,8 @@ a few, particularly some Kenwood rigs, require it).</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>237</width>
|
||||
<height>467</height>
|
||||
<width>257</width>
|
||||
<height>427</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_28">
|
||||
@@ -1767,8 +1774,8 @@ radio interface behave as expected.</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>760</width>
|
||||
<height>502</height>
|
||||
<width>267</width>
|
||||
<height>302</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29">
|
||||
@@ -2080,8 +2087,8 @@ both here.</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>746</width>
|
||||
<height>525</height>
|
||||
<width>572</width>
|
||||
<height>498</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_30">
|
||||
@@ -2108,7 +2115,7 @@ both here.</string>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Op Call:</string>
|
||||
<string>Operator Callsign (if different than Station Callsign):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -2153,6 +2160,9 @@ both here.</string>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="log_as_RTTY_check_box">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Some logging programs will not accept JT-65 or JT9 as a recognized mode.</string>
|
||||
</property>
|
||||
@@ -2182,6 +2192,9 @@ comments field.</string>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -2339,7 +2352,7 @@ This is used for reverse ping analysis which is very useful
|
||||
for assessing propagation and system performance.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable spotting to reporting networks (JS8 Network, PSKReporter, APRS-IS, etc)</string>
|
||||
<string>Enable spotting to reporting networks (JS8NET, PSKReporter, APRS-IS, etc)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
@@ -2537,8 +2550,8 @@ for assessing propagation and system performance.</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>760</width>
|
||||
<height>502</height>
|
||||
<width>498</width>
|
||||
<height>321</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_31">
|
||||
@@ -3115,8 +3128,8 @@ QListView::item:hover {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>738</width>
|
||||
<height>378</height>
|
||||
<width>280</width>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_15">
|
||||
@@ -3370,8 +3383,8 @@ QListView::item:hover {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>233</width>
|
||||
<height>253</height>
|
||||
<width>236</width>
|
||||
<height>258</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
@@ -3574,8 +3587,8 @@ QListView::item:hover {
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>277</width>
|
||||
<height>93</height>
|
||||
<width>288</width>
|
||||
<height>96</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
@@ -4184,11 +4197,11 @@ soundcard changes</string>
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="TX_mode_button_group"/>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="TX_audio_source_button_group"/>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="TX_mode_button_group"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@ void SpotClient::setLocalStation(QString callsign, QString grid, QString info, Q
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// send local information to network on change, or once every 5 minutes
|
||||
if(changed || m_seq % 5 == 0){
|
||||
// send local information to network on change, or once every 15 minutes
|
||||
if(changed || m_seq % 15 == 0){
|
||||
enqueueLocalSpot(callsign, grid, info, version);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
set (WSJTX_VERSION_MAJOR 1)
|
||||
set (WSJTX_VERSION_MINOR 0)
|
||||
set (WSJTX_VERSION_PATCH 0)
|
||||
set (WSJTX_RC 3) # 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
|
||||
|
||||
@@ -23,7 +23,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
"development group. <br/>JS8Call is "
|
||||
"licensed under and in accordance with the terms "
|
||||
"of the <a href=\"https://www.gnu.org/licenses/gpl-3.0.txt\">GPLv3 license</a>.<br/>"
|
||||
"The source code modifications are public and can be found in <a href=\"https://bitbucket.org/widefido/wsjtx/\">this repository</a>.<br/><br/>"
|
||||
"The source code modifications are public and can be found in <a href=\"https://bitbucket.org/widefido/js8call/\">this repository</a>.<br/><br/>"
|
||||
|
||||
"JS8Call is heavily inspired by WSJT-X, Fldigi, "
|
||||
"and FSQCall <br/>and would not exist without the hard work and "
|
||||
|
||||
+173
-72
@@ -12,6 +12,9 @@
|
||||
#include <QRegExp>
|
||||
#include <QRegularExpression>
|
||||
#include <QDesktopServices>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrl>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
@@ -1116,7 +1119,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
//splashTimer.setSingleShot (true);
|
||||
//splashTimer.start (20 * 1000);
|
||||
|
||||
// TODO: jsherer - need to remove this eventually...
|
||||
QTimer::singleShot (0, this, SLOT (checkStartupWarnings ()));
|
||||
|
||||
if(!ui->cbMenus->isChecked()) {
|
||||
@@ -1639,27 +1641,91 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
|
||||
}
|
||||
|
||||
QDate eol(2019, 4, 1);
|
||||
|
||||
void MainWindow::checkExpiryWarningMessage()
|
||||
{
|
||||
if(QDateTime::currentDateTimeUtc().date() > eol){
|
||||
MessageBox::critical_message (this, QString("This pre-release development build of JS8Call has reached its end-of-life. Please check for an upgrade to the latest version."));
|
||||
QPair<QPair<int, int>, int> splitVersion(QString v){
|
||||
int hyphenPos = v.lastIndexOf("-");
|
||||
if(hyphenPos >= 0){
|
||||
v = v.left(hyphenPos);
|
||||
}
|
||||
|
||||
QVector<int> intSegs;
|
||||
foreach(QString seg, v.split(".")){
|
||||
bool ok = false;
|
||||
int i = seg.toInt(&ok);
|
||||
if(!ok){
|
||||
break;
|
||||
}
|
||||
intSegs.append(i);
|
||||
}
|
||||
|
||||
int len = intSegs.count();
|
||||
QPair<QPair<int, int>, int> tuple;
|
||||
if(len > 0){
|
||||
tuple.first.first = intSegs.at(0);
|
||||
}
|
||||
if(len > 1){
|
||||
tuple.first.second = intSegs.at(1);
|
||||
}
|
||||
if(len > 2){
|
||||
tuple.second = intSegs.at(2);
|
||||
}
|
||||
return tuple;
|
||||
}
|
||||
|
||||
void MainWindow::checkVersion(bool alertOnUpToDate){
|
||||
auto m = new QNetworkAccessManager(this);
|
||||
connect(m, &QNetworkAccessManager::finished, this, [this, alertOnUpToDate](QNetworkReply * reply){
|
||||
if(reply->error()){
|
||||
qDebug() << "Checking for Updates Error:" << reply->errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QString content = reply->readAll().trimmed();
|
||||
|
||||
auto currentVersion = splitVersion(version());
|
||||
auto networkVersion = splitVersion(content);
|
||||
|
||||
qDebug() << "Checking Version" << currentVersion << "with" << networkVersion;
|
||||
|
||||
if(currentVersion < networkVersion){
|
||||
|
||||
SelfDestructMessageBox * m = new SelfDestructMessageBox(60,
|
||||
"New Updates Available",
|
||||
QString("A new version (%1) of JS8Call is now available. Please see js8call.com for more details.").arg(content),
|
||||
QMessageBox::Information,
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::Ok,
|
||||
false,
|
||||
this);
|
||||
|
||||
m->show();
|
||||
|
||||
} else if(alertOnUpToDate){
|
||||
|
||||
SelfDestructMessageBox * m = new SelfDestructMessageBox(60,
|
||||
"No Updates Available",
|
||||
QString("Your version (%1) of JS8Call is up-to-date.").arg(version()),
|
||||
QMessageBox::Information,
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::Ok,
|
||||
false,
|
||||
this);
|
||||
|
||||
m->show();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
qDebug() << "Checking for Updates...";
|
||||
QUrl url("http://files.js8call.com/version.txt");
|
||||
QNetworkRequest r(url);
|
||||
m->get(r);
|
||||
}
|
||||
|
||||
void MainWindow::checkStartupWarnings ()
|
||||
{
|
||||
MessageBox::critical_message (this,
|
||||
QString("This version of %1 is a pre-release development\n"
|
||||
"build and will expire after %2 (UTC), upon which you\n"
|
||||
"will need to upgrade to the latest version. \n\n"
|
||||
"Use of development versions of JS8Call are at your own risk \n"
|
||||
"and carry a responsiblity to report any problems to:\n"
|
||||
"Jordan Sherer (KN4CRD) kn4crd@gmail.com\n\n").arg(QApplication::applicationName()).arg(eol.toString()));
|
||||
|
||||
checkExpiryWarningMessage();
|
||||
|
||||
if(m_config.check_for_updates()){
|
||||
checkVersion(false);
|
||||
}
|
||||
ensureCallsignSet(false);
|
||||
}
|
||||
|
||||
@@ -2603,6 +2669,10 @@ void MainWindow::on_menuControl_aboutToShow(){
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::on_actionCheck_for_Updates_triggered(){
|
||||
checkVersion(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Spotting_toggled(bool checked){
|
||||
ui->spotButton->setChecked(checked);
|
||||
}
|
||||
@@ -3438,7 +3508,7 @@ void MainWindow::on_actionCopyright_Notice_triggered()
|
||||
"IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR; "
|
||||
"Philip Karn, KA9Q; and other members of the WSJT Development Group.\n\n"
|
||||
"Further, the source code of JS8Call contains material Copyright (C) "
|
||||
"2018 by Jordan Sherer, KN4CRD.\"");
|
||||
"2018-2019 by Jordan Sherer, KN4CRD.\"");
|
||||
MessageBox::warning_message(this, message);
|
||||
}
|
||||
|
||||
@@ -6030,8 +6100,6 @@ bool MainWindow::ensureCreateMessageReady(const QString &text){
|
||||
}
|
||||
|
||||
QString MainWindow::createMessage(QString const& text){
|
||||
checkExpiryWarningMessage();
|
||||
|
||||
return createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false), true);
|
||||
}
|
||||
|
||||
@@ -6439,18 +6507,16 @@ void MainWindow::on_genStdMsgsPushButton_clicked()
|
||||
|
||||
void MainWindow::on_logQSOButton_clicked() //Log QSO button
|
||||
{
|
||||
/*
|
||||
if (!m_hisCall.size ()) {
|
||||
MessageBox::warning_message (this, tr ("Warning: DX Call field is empty."));
|
||||
QString call = callsignSelected();
|
||||
if(m_callSelectedTime.contains(call)){
|
||||
m_dateTimeQSOOn = m_callSelectedTime[call];
|
||||
}
|
||||
*/
|
||||
// m_dateTimeQSOOn should really already be set but we'll ensure it gets set to something just in case
|
||||
if (!m_dateTimeQSOOn.isValid ()) {
|
||||
m_dateTimeQSOOn = DriftingDateTime::currentDateTimeUtc();
|
||||
}
|
||||
auto dateTimeQSOOff = DriftingDateTime::currentDateTimeUtc();
|
||||
if (dateTimeQSOOff < m_dateTimeQSOOn) dateTimeQSOOff = m_dateTimeQSOOn;
|
||||
QString call=callsignSelected();
|
||||
|
||||
if(call.startsWith("@")){
|
||||
call = "";
|
||||
}
|
||||
@@ -7062,8 +7128,17 @@ void MainWindow::buildFrequencyMenu(QMenu *menu){
|
||||
}
|
||||
|
||||
void MainWindow::buildHeartbeatMenu(QMenu *menu){
|
||||
auto autoAckHB = menu->addAction(ui->autoReplyButton->isChecked() ? "Send Heartbeat Acknowledgments (ACK)" : "Send Heartbeat Acknowledgments (ACK) (AUTO disabled)");
|
||||
autoAckHB->setEnabled(ui->autoReplyButton->isChecked());
|
||||
auto selectedCallsign = callsignSelected();
|
||||
bool enabled = ui->autoReplyButton->isChecked() && selectedCallsign.isEmpty();
|
||||
auto text = "Send Heartbeat Acknowledgments (ACK)";
|
||||
if(!ui->autoReplyButton->isChecked()){
|
||||
text = "Send Heartbeat Acknowledgments (ACK) (Disabled: AUTO is off)";
|
||||
}
|
||||
if(!selectedCallsign.isEmpty()){
|
||||
text = "Send Heartbeat Acknowledgments (ACK) (Disabled: Currently in QSO)";
|
||||
}
|
||||
auto autoAckHB = menu->addAction(text);
|
||||
autoAckHB->setEnabled(enabled);
|
||||
autoAckHB->setCheckable(true);
|
||||
autoAckHB->setChecked(m_hbAutoAck);
|
||||
connect(autoAckHB, &QAction::triggered, this, [this, autoAckHB](){
|
||||
@@ -7078,7 +7153,7 @@ void MainWindow::buildHeartbeatMenu(QMenu *menu){
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
buildRepeatMenu(menu, ui->hbMacroButton, &m_hbInterval);
|
||||
buildRepeatMenu(menu, ui->hbMacroButton, false, &m_hbInterval);
|
||||
|
||||
menu->addSeparator();
|
||||
auto now = menu->addAction("Send Heartbeat Now");
|
||||
@@ -7092,14 +7167,14 @@ void MainWindow::buildCQMenu(QMenu *menu){
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
buildRepeatMenu(menu, ui->cqMacroButton, &m_cqInterval);
|
||||
buildRepeatMenu(menu, ui->cqMacroButton, true, &m_cqInterval);
|
||||
|
||||
menu->addSeparator();
|
||||
auto now = menu->addAction("Send CQ Now");
|
||||
connect(now, &QAction::triggered, this, [this](){ sendCQ(true); });
|
||||
}
|
||||
|
||||
void MainWindow::buildRepeatMenu(QMenu *menu, QPushButton * button, int * interval){
|
||||
void MainWindow::buildRepeatMenu(QMenu *menu, QPushButton * button, bool isLowInterval, int * interval){
|
||||
QList<QPair<QString, int>> items = {
|
||||
{"On demand / do not repeat", 0},
|
||||
{"Repeat every 1 minute", 1},
|
||||
@@ -7111,6 +7186,14 @@ void MainWindow::buildRepeatMenu(QMenu *menu, QPushButton * button, int * interv
|
||||
{"Repeat every N minutes (Custom Interval)", -1}, // this needs to be last because of isSet bool
|
||||
};
|
||||
|
||||
if(isLowInterval){
|
||||
items.removeAt(5); // remove the thirty minute interval
|
||||
items.removeAt(5); // remove the sixty minute interval
|
||||
} else {
|
||||
items.removeAt(1); // remove the one minute interval
|
||||
items.removeAt(1); // remove the five minute interval
|
||||
}
|
||||
|
||||
auto customFormat = QString("Repeat every %1 minutes (Custom Interval)");
|
||||
|
||||
QActionGroup * group = new QActionGroup(menu);
|
||||
@@ -8071,45 +8154,10 @@ void MainWindow::on_tableWidgetRXAll_cellDoubleClicked(int row, int col){
|
||||
void MainWindow::on_tableWidgetRXAll_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/){
|
||||
on_extFreeTextMsgEdit_currentTextChanged(ui->extFreeTextMsgEdit->toPlainText());
|
||||
|
||||
auto placeholderText = QString("Type your outgoing messages here.");
|
||||
auto selectedCall = callsignSelected();
|
||||
if(selectedCall.isEmpty()){
|
||||
// try to restore hb
|
||||
if(m_hbPaused){
|
||||
ui->hbMacroButton->setChecked(true);
|
||||
m_hbPaused = false;
|
||||
}
|
||||
} else {
|
||||
placeholderText = QString("Type your outgoing directed message to %1 here.").arg(selectedCall);
|
||||
|
||||
// when we select a callsign, use it as the qso start time
|
||||
m_dateTimeQSOOn = DriftingDateTime::currentDateTimeUtc();
|
||||
|
||||
// TODO: jsherer - move this to a generic "callsign changed" signal
|
||||
if(m_config.heartbeat_qso_pause()){
|
||||
// don't hb if we select a callsign... (but we should keep track so if we deselect, we restore our hb)
|
||||
if(ui->hbMacroButton->isChecked()){
|
||||
ui->hbMacroButton->setChecked(false);
|
||||
m_hbPaused = true;
|
||||
}
|
||||
|
||||
// don't cq if we select a callsign... (and it will not be restored otherwise)
|
||||
if(ui->cqMacroButton->isChecked()){
|
||||
ui->cqMacroButton->setChecked(false);
|
||||
}
|
||||
}
|
||||
if(selectedCall != m_prevSelectedCallsign){
|
||||
callsignSelectedChanged(m_prevSelectedCallsign, selectedCall);
|
||||
}
|
||||
ui->extFreeTextMsgEdit->setPlaceholderText(placeholderText);
|
||||
|
||||
#if SHOW_CALL_DETAIL_BROWSER
|
||||
auto html = generateCallDetail(selectedCall);
|
||||
ui->callDetailTextBrowser->setHtml(html);
|
||||
ui->callDetailTextBrowser->setVisible(!selectedCall.isEmpty() && (!hearing.isEmpty() || !heardby.isEmpty()));
|
||||
#endif
|
||||
|
||||
// immediately update the display);
|
||||
updateButtonDisplay();
|
||||
updateTextDisplay();
|
||||
}
|
||||
|
||||
QString MainWindow::generateCallDetail(QString selectedCall){
|
||||
@@ -9187,7 +9235,8 @@ void MainWindow::updateButtonDisplay(){
|
||||
}
|
||||
|
||||
void MainWindow::updateRepeatButtonDisplay(){
|
||||
auto hbBase = m_hbAutoAck && ui->autoReplyButton->isChecked() ? "HB + ACK" : "HB";
|
||||
auto selectedCallsign = callsignSelected();
|
||||
auto hbBase = m_hbAutoAck && ui->autoReplyButton->isChecked() && selectedCallsign.isEmpty() ? "HB + ACK" : "HB";
|
||||
if(ui->hbMacroButton->isChecked() && m_hbInterval > 0 && m_nextHeartbeat.isValid()){
|
||||
auto secs = DriftingDateTime::currentDateTimeUtc().secsTo(m_nextHeartbeat);
|
||||
if(secs > 0){
|
||||
@@ -9404,7 +9453,56 @@ QString MainWindow::callsignSelected(bool useInputText){
|
||||
return QString();
|
||||
}
|
||||
|
||||
void MainWindow::callsignSelectedChanged(QString /*old*/, QString selectedCall){
|
||||
auto placeholderText = QString("Type your outgoing messages here.");
|
||||
if(selectedCall.isEmpty()){
|
||||
// try to restore hb
|
||||
if(m_hbPaused){
|
||||
ui->hbMacroButton->setChecked(true);
|
||||
m_hbPaused = false;
|
||||
}
|
||||
} else {
|
||||
placeholderText = QString("Type your outgoing directed message to %1 here.").arg(selectedCall);
|
||||
|
||||
// when we select a callsign, use it as the qso start time
|
||||
if(!m_callSelectedTime.contains(selectedCall)){
|
||||
m_callSelectedTime[selectedCall] = DriftingDateTime::currentDateTimeUtc();
|
||||
}
|
||||
|
||||
if(m_config.heartbeat_qso_pause()){
|
||||
// TODO: jsherer - HB issue
|
||||
// don't hb if we select a callsign... (but we should keep track so if we deselect, we restore our hb)
|
||||
if(ui->hbMacroButton->isChecked()){
|
||||
ui->hbMacroButton->setChecked(false);
|
||||
m_hbPaused = true;
|
||||
}
|
||||
|
||||
// don't cq if we select a callsign... (and it will not be restored otherwise)
|
||||
if(ui->cqMacroButton->isChecked()){
|
||||
ui->cqMacroButton->setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
ui->extFreeTextMsgEdit->setPlaceholderText(placeholderText);
|
||||
|
||||
#if SHOW_CALL_DETAIL_BROWSER
|
||||
auto html = generateCallDetail(selectedCall);
|
||||
ui->callDetailTextBrowser->setHtml(html);
|
||||
ui->callDetailTextBrowser->setVisible(!selectedCall.isEmpty() && (!hearing.isEmpty() || !heardby.isEmpty()));
|
||||
#endif
|
||||
|
||||
// immediately update the display);
|
||||
updateButtonDisplay();
|
||||
updateTextDisplay();
|
||||
|
||||
m_prevSelectedCallsign = selectedCall;
|
||||
}
|
||||
|
||||
void MainWindow::clearCallsignSelected(){
|
||||
// remove the date cache
|
||||
m_callSelectedTime.remove(m_prevSelectedCallsign);
|
||||
|
||||
// remove the callsign selection
|
||||
ui->tableWidgetCalls->clearSelection();
|
||||
ui->tableWidgetRXAll->clearSelection();
|
||||
}
|
||||
@@ -9913,6 +10011,7 @@ void MainWindow::processCommandActivity() {
|
||||
while (!m_rxCommandQueue.isEmpty()) {
|
||||
auto d = m_rxCommandQueue.dequeue();
|
||||
|
||||
auto selectedCallsign = callsignSelected();
|
||||
bool isAllCall = isAllCallIncluded(d.to);
|
||||
bool isGroupCall = isGroupCallIncluded(d.to);
|
||||
|
||||
@@ -10099,7 +10198,7 @@ void MainWindow::processCommandActivity() {
|
||||
|
||||
// if this is an allcall, check to make sure we haven't replied to their allcall recently (in the past ten minutes)
|
||||
// that way we never get spammed by allcalls at too high of a frequency
|
||||
if (isAllCall && m_txAllcallCommandCache.contains(d.from) && m_txAllcallCommandCache[d.from]->secsTo(now) / 60 < 10) {
|
||||
if (isAllCall && m_txAllcallCommandCache.contains(d.from) && m_txAllcallCommandCache[d.from]->secsTo(now) / 60 < 15) {
|
||||
qDebug() << "skipping command for allcall timeout" << d.from;
|
||||
continue;
|
||||
}
|
||||
@@ -10338,8 +10437,8 @@ void MainWindow::processCommandActivity() {
|
||||
}
|
||||
|
||||
// PROCESS ACTIVE HEARTBEAT
|
||||
// if we have auto reply enabled and we are heartbeating and selcall is not enabled
|
||||
else if (d.cmd == " HB" && ui->autoReplyButton->isChecked() && m_hbAutoAck){
|
||||
// if we have auto reply enabled and auto ack enabled and no callsign is selected
|
||||
else if (d.cmd == " HB" && ui->autoReplyButton->isChecked() && m_hbAutoAck && selectedCallsign.isEmpty()){
|
||||
|
||||
// check to see if we have a message for a station who is heartbeating
|
||||
QString extra;
|
||||
@@ -10575,6 +10674,7 @@ void MainWindow::processCommandActivity() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: jsherer - HB issue here
|
||||
// do not queue a reply if it's a HB and HB is not active
|
||||
if((!ui->hbMacroButton->isChecked() || m_hbInterval <= 0) && d.cmd.contains("HB")){
|
||||
continue;
|
||||
@@ -11354,6 +11454,7 @@ void MainWindow::displayCallActivity() {
|
||||
|
||||
auto iconItem = new QTableWidgetItem(hasMessage ? "\u2691" : hasACK ? "\u2605" : hasCQ ? "\u260E" : "");
|
||||
iconItem->setData(Qt::UserRole, QVariant(d.call));
|
||||
iconItem->setToolTip(hasMessage ? "Message Available" : hasACK ? "Hearing Your Station" : hasCQ ? "Calling CQ" : "");
|
||||
iconItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui->tableWidgetCalls->setItem(row, col++, iconItem);
|
||||
if(hasMessage || hasACK || hasCQ){
|
||||
|
||||
+6
-2
@@ -177,6 +177,7 @@ private slots:
|
||||
void on_tx5_currentTextChanged (QString const&);
|
||||
void on_tx6_editingFinished();
|
||||
void on_menuControl_aboutToShow();
|
||||
void on_actionCheck_for_Updates_triggered();
|
||||
void on_actionEnable_Spotting_toggled(bool checked);
|
||||
void on_actionEnable_Auto_Reply_toggled(bool checked);
|
||||
void on_menuWindow_aboutToShow();
|
||||
@@ -283,7 +284,7 @@ private slots:
|
||||
void buildFrequencyMenu(QMenu *menu);
|
||||
void buildHeartbeatMenu(QMenu *menu);
|
||||
void buildCQMenu(QMenu *menu);
|
||||
void buildRepeatMenu(QMenu *menu, QPushButton * button, int * interval);
|
||||
void buildRepeatMenu(QMenu *menu, QPushButton * button, bool isLowInterval, int * interval);
|
||||
void sendHeartbeat();
|
||||
void sendHeartbeatAck(QString to, int snr, QString extra);
|
||||
void on_hbMacroButton_toggled(bool checked);
|
||||
@@ -413,7 +414,7 @@ private slots:
|
||||
void on_cbCQTx_toggled(bool b);
|
||||
void splash_done ();
|
||||
void on_measure_check_box_stateChanged (int);
|
||||
void checkExpiryWarningMessage ();
|
||||
void checkVersion(bool alertOnUpToDate);
|
||||
void checkStartupWarnings ();
|
||||
void clearCallsignSelected();
|
||||
void refreshTextDisplay();
|
||||
@@ -762,6 +763,7 @@ private:
|
||||
QList<ActivityDetail> msgs;
|
||||
};
|
||||
|
||||
QString m_prevSelectedCallsign;
|
||||
int m_bandActivityWidth;
|
||||
int m_callActivityWidth;
|
||||
int m_textActivityWidth;
|
||||
@@ -837,6 +839,7 @@ private:
|
||||
|
||||
JSCChecker * m_checker;
|
||||
|
||||
QMap<QString, QDateTime> m_callSelectedTime; // call -> timestamp when callsign was last selected
|
||||
QSet<QString> m_callSeenHeartbeat; // call
|
||||
int m_previousFreq;
|
||||
bool m_shouldRestoreFreq;
|
||||
@@ -947,6 +950,7 @@ private:
|
||||
bool isAllCallIncluded(QString const &text);
|
||||
bool isGroupCallIncluded(const QString &text);
|
||||
QString callsignSelected(bool useInputText=false);
|
||||
void callsignSelectedChanged(QString old, QString current);
|
||||
bool isRecentOffset(int offset);
|
||||
void markOffsetRecent(int offset);
|
||||
bool isDirectedOffset(int offset, bool *pIsAllCall);
|
||||
|
||||
+7
-1
@@ -4613,7 +4613,7 @@ list. The list can be maintained in Settings (F2).</string>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>994</width>
|
||||
<height>22</height>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@@ -4688,6 +4688,7 @@ list. The list can be maintained in Settings (F2).</string>
|
||||
<addaction name="actionShort_list_of_add_on_prefixes_and_suffixes"/>
|
||||
<addaction name="actionCopyright_Notice"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCheck_for_Updates"/>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuMode">
|
||||
@@ -5677,6 +5678,11 @@ list. The list can be maintained in Settings (F2).</string>
|
||||
<string>Show Message Inbox...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheck_for_Updates">
|
||||
<property name="text">
|
||||
<string>Check for Updates</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
||||
Reference in New Issue
Block a user