Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 22e4b0891e | |||
| 8c564b6637 | |||
| 97763ed82d | |||
| a7849c5b72 | |||
| 04394273dd | |||
| 1052dd3f9f | |||
| 78ed799a8b | |||
| c0d08f87b6 | |||
| f92b3db5ea | |||
| cebed44ccd | |||
| d47d88681b | |||
| 1be0ee4f4f | |||
| 43d8986e0a | |||
| fd69dce0ae | |||
| b2fb3f31ac | |||
| db704858e2 | |||
| 1d11f0f8ba | |||
| b6bc50a8e1 | |||
| 5addf8f61f | |||
| 367966f5e6 | |||
| caaaa957b6 | |||
| c440d4c143 | |||
| 740c0b4c04 | |||
| f5ce9f0e30 | |||
| 0a6ec136f9 | |||
| d5e1f2822d | |||
| 3fffb45338 | |||
| 1d255b1ebf | |||
| bb97799bdf | |||
| cc6a719f6d | |||
| ccd380356a | |||
| 9f8583c8e2 | |||
| c9016d7378 | |||
| cd683f9bf7 | |||
| 6d7b187269 | |||
| 13308a38f8 | |||
| 804605e9e6 | |||
| 4e981da9c8 | |||
| 6436e163bd | |||
| 379a0fa78f | |||
| 1c4a2ab7d8 | |||
| 54f6bdb0af | |||
| 5a0e2a8b14 | |||
| 1a9c611195 | |||
| c70661461e | |||
| 1f866e14f1 |
+51
-4
@@ -463,6 +463,9 @@ private:
|
||||
void delete_selected_macros (QModelIndexList);
|
||||
Q_SLOT void on_save_path_select_push_button_clicked (bool);
|
||||
Q_SLOT void on_azel_path_select_push_button_clicked (bool);
|
||||
Q_SLOT void on_sound_cq_path_select_push_button_clicked();
|
||||
Q_SLOT void on_sound_cq_path_test_push_button_clicked();
|
||||
Q_SLOT void on_sound_cq_path_reset_push_button_clicked();
|
||||
Q_SLOT void on_sound_dm_path_select_push_button_clicked();
|
||||
Q_SLOT void on_sound_dm_path_test_push_button_clicked();
|
||||
Q_SLOT void on_sound_dm_path_reset_push_button_clicked();
|
||||
@@ -517,6 +520,7 @@ private:
|
||||
QDir default_azel_directory_;
|
||||
QDir azel_directory_;
|
||||
|
||||
QString sound_cq_path_; // cq message sound file
|
||||
QString sound_dm_path_; // directed message sound file
|
||||
QString sound_am_path_; // alert message sound file
|
||||
|
||||
@@ -810,6 +814,7 @@ QStringListModel * Configuration::macros () {return &m_->macros_;}
|
||||
QStringListModel const * Configuration::macros () const {return &m_->macros_;}
|
||||
QDir Configuration::save_directory () const {return m_->save_directory_;}
|
||||
QDir Configuration::azel_directory () const {return m_->azel_directory_;}
|
||||
QString Configuration::sound_cq_path() const {return m_->sound_cq_path_;}
|
||||
QString Configuration::sound_dm_path() const {return m_->sound_dm_path_;}
|
||||
QString Configuration::sound_am_path() const {return m_->sound_am_path_;}
|
||||
QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
|
||||
@@ -1042,6 +1047,7 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
, default_audio_output_device_selected_ {false}
|
||||
{
|
||||
ui_->setupUi (this);
|
||||
|
||||
// ui_->groupBox_6->setVisible(false); //### Temporary ??? ###
|
||||
|
||||
{
|
||||
@@ -1331,6 +1337,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->PTT_method_button_group->button (rig_params_.ptt_type)->setChecked (true);
|
||||
ui_->save_path_display_label->setText (save_directory_.absolutePath ());
|
||||
ui_->azel_path_display_label->setText (azel_directory_.absolutePath ());
|
||||
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_->CW_id_after_73_check_box->setChecked (id_after_73_);
|
||||
@@ -1430,7 +1437,7 @@ void Configuration::impl::done (int r)
|
||||
{
|
||||
// do this here since window is still on screen at this point
|
||||
SettingsGroup g {settings_, "Configuration"};
|
||||
settings_->setValue ("window/geometry", saveGeometry ());
|
||||
settings_->setValue ("WindowGeometry", saveGeometry ());
|
||||
|
||||
QDialog::done (r);
|
||||
}
|
||||
@@ -1438,7 +1445,9 @@ void Configuration::impl::done (int r)
|
||||
void Configuration::impl::read_settings ()
|
||||
{
|
||||
SettingsGroup g {settings_, "Configuration"};
|
||||
restoreGeometry (settings_->value ("window/geometry").toByteArray ());
|
||||
setMinimumSize(800, 400);
|
||||
restoreGeometry (settings_->value ("WindowGeometry").toByteArray ());
|
||||
setMinimumSize(800, 400);
|
||||
|
||||
auto_switch_bands_ = settings_->value("AutoSwitchBands", false).toBool();
|
||||
my_callsign_ = settings_->value ("MyCall", QString {}).toString ();
|
||||
@@ -1533,6 +1542,7 @@ void Configuration::impl::read_settings ()
|
||||
RxBandwidth_ = settings_->value ("RxBandwidth", 2500).toInt ();
|
||||
save_directory_ = settings_->value ("SaveDir", default_save_directory_.absolutePath ()).toString ();
|
||||
azel_directory_ = settings_->value ("AzElDir", default_azel_directory_.absolutePath ()).toString ();
|
||||
sound_cq_path_ = settings_->value ("SoundCQPath", "").toString ();
|
||||
sound_dm_path_ = settings_->value ("SoundDMPath", "").toString ();
|
||||
sound_am_path_ = settings_->value ("SoundAMPath", "").toString ();
|
||||
|
||||
@@ -1736,6 +1746,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("PTTport", rig_params_.ptt_port);
|
||||
settings_->setValue ("SaveDir", save_directory_.absolutePath ());
|
||||
settings_->setValue ("AzElDir", azel_directory_.absolutePath ());
|
||||
settings_->setValue ("SoundCQPath", sound_cq_path_);
|
||||
settings_->setValue ("SoundDMPath", sound_dm_path_);
|
||||
settings_->setValue ("SoundAMPath", sound_am_path_);
|
||||
|
||||
@@ -1880,7 +1891,8 @@ void Configuration::impl::set_rig_invariants ()
|
||||
// makes no sense with rig as "None"
|
||||
ui_->monitor_last_used_check_box->setEnabled (false);
|
||||
|
||||
ui_->CAT_control_group_box->setEnabled (false);
|
||||
ui_->catTab->setEnabled(false);
|
||||
//ui_->CAT_control_group_box->setEnabled (false);
|
||||
ui_->test_CAT_push_button->setEnabled (false);
|
||||
ui_->test_PTT_push_button->setEnabled (TransceiverFactory::PTT_method_DTR == ptt_method
|
||||
|| TransceiverFactory::PTT_method_RTS == ptt_method);
|
||||
@@ -1889,7 +1901,8 @@ void Configuration::impl::set_rig_invariants ()
|
||||
else
|
||||
{
|
||||
ui_->monitor_last_used_check_box->setEnabled (true);
|
||||
ui_->CAT_control_group_box->setEnabled (true);
|
||||
ui_->catTab->setEnabled(true);
|
||||
//ui_->CAT_control_group_box->setEnabled (true);
|
||||
ui_->test_CAT_push_button->setEnabled (true);
|
||||
ui_->test_PTT_push_button->setEnabled (false);
|
||||
ui_->TX_audio_source_group_box->setEnabled (transceiver_factory_.has_CAT_PTT_mic_data (rig) && TransceiverFactory::PTT_method_CAT == ptt_method);
|
||||
@@ -1940,7 +1953,9 @@ void Configuration::impl::set_rig_invariants ()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ui_->CAT_serial_port_parameters_group_box->setEnabled (is_serial_CAT);
|
||||
|
||||
ui_->force_DTR_combo_box->setEnabled (is_serial_CAT
|
||||
&& (cat_port != ptt_port
|
||||
|| !ui_->PTT_DTR_radio_button->isEnabled ()
|
||||
@@ -2277,6 +2292,7 @@ void Configuration::impl::accept ()
|
||||
data_mode_ = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
|
||||
save_directory_ = ui_->save_path_display_label->text ();
|
||||
azel_directory_ = ui_->azel_path_display_label->text ();
|
||||
sound_cq_path_ = ui_->sound_cq_path_display_label->text();
|
||||
sound_dm_path_ = ui_->sound_dm_path_display_label->text();
|
||||
sound_am_path_ = ui_->sound_am_path_display_label->text();
|
||||
enable_VHF_features_ = ui_->enable_VHF_features_check_box->isChecked ();
|
||||
@@ -2945,6 +2961,37 @@ void Configuration::impl::on_azel_path_select_push_button_clicked (bool /* check
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_cq_path_select_push_button_clicked(){
|
||||
QStringList filters;
|
||||
filters << "Audio files (*.wav)"
|
||||
<< "Any files (*)";
|
||||
|
||||
QFileDialog fd {this, tr ("Sound File"), ui_->sound_cq_path_display_label->text ()};
|
||||
fd.setNameFilters(filters);
|
||||
|
||||
if (fd.exec ()) {
|
||||
if (fd.selectedFiles ().size ()) {
|
||||
if(rig_params_.ptt_type == TransceiverFactory::PTT_method_VOX){
|
||||
QMessageBox::warning(this, "Notifications Sounds Warning", "You have enabled notification sounds while using VOX. To avoid transmitting these notification sounds, please make sure your rig is using a different sound card than your system.");
|
||||
}
|
||||
ui_->sound_cq_path_display_label->setText(fd.selectedFiles().at(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_cq_path_test_push_button_clicked(){
|
||||
auto path = ui_->sound_cq_path_display_label->text();
|
||||
if(path.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
QSound::play(path);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_cq_path_reset_push_button_clicked(){
|
||||
ui_->sound_cq_path_display_label->clear();
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_dm_path_select_push_button_clicked(){
|
||||
QStringList filters;
|
||||
filters << "Audio files (*.wav)"
|
||||
|
||||
@@ -180,6 +180,7 @@ public:
|
||||
QStringListModel const * macros () const;
|
||||
QDir save_directory () const;
|
||||
QDir azel_directory () const;
|
||||
QString sound_cq_path() const;
|
||||
QString sound_dm_path() const;
|
||||
QString sound_am_path() const;
|
||||
QString rig_name () const;
|
||||
|
||||
+1091
-760
File diff suppressed because it is too large
Load Diff
@@ -50,6 +50,13 @@ require this so normally you can choose not to install libusb-1.0-dev
|
||||
but if you have a SoftRock USB or similar SDR that uses a custom USB
|
||||
interface then it is required.
|
||||
|
||||
On Debian based systems, install requirements like:
|
||||
|
||||
sudo apt install git cmake clang gfortran \
|
||||
libfftw3-dev git libgfortran3 libusb-1.0-dev autoconf libtool \
|
||||
texinfo qt5-default qtmultimedia5-dev libqt5multimedia5-plugins libqt5serialport5-dev \
|
||||
libudev-dev pkg-config
|
||||
|
||||
The Hamlib library is required. Currently WSJT-X needs to be built
|
||||
using a forked version of the Hamlib git master. This fork contains
|
||||
patches not yet accepted by the Hamlib development team which are
|
||||
|
||||
@@ -291,6 +291,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
if (m_ic > i1) m_amp = 0.0;
|
||||
|
||||
sample=qRound(m_amp*qSin(m_phi));
|
||||
if(m_toneSpacing < 0) sample=qRound(m_amp*foxcom_.wave[m_ic]);
|
||||
samples = load(postProcessSample(sample), samples);
|
||||
++framesGenerated;
|
||||
++m_ic;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Version number components
|
||||
set (WSJTX_VERSION_MAJOR 0)
|
||||
set (WSJTX_VERSION_MINOR 8)
|
||||
set (WSJTX_VERSION_MINOR 9)
|
||||
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
|
||||
|
||||
@@ -61,6 +61,11 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
|
||||
bits_ = bits();
|
||||
|
||||
// don't even try to unpack -24dB frames...they are *very* likely to be false decodes...
|
||||
if(snr() <= -24){
|
||||
return;
|
||||
}
|
||||
|
||||
tryUnpack();
|
||||
}
|
||||
|
||||
|
||||
@@ -107,17 +107,23 @@ QString JSC::decompress(Codeword const& bitvec){
|
||||
|
||||
QList<quint64> bytes;
|
||||
QList<int> separators;
|
||||
auto iter = bitvec.begin();
|
||||
while(iter != bitvec.end()){
|
||||
quint64 byte = Varicode::bitsToInt(iter, 4);
|
||||
iter += 4;
|
||||
|
||||
int i = 0;
|
||||
int count = bitvec.count();
|
||||
while(i < count){
|
||||
auto b = bitvec.mid(i, 4);
|
||||
if(b.length() != 4){
|
||||
break;
|
||||
}
|
||||
quint64 byte = Varicode::bitsToInt(b);
|
||||
bytes.append(byte);
|
||||
i += 4;
|
||||
|
||||
if(byte < s){
|
||||
if(*iter){
|
||||
if(count - i > 0 && bitvec.at(i)){
|
||||
separators.append(bytes.length()-1);
|
||||
}
|
||||
iter += 1;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +137,14 @@ QString JSC::decompress(Codeword const& bitvec){
|
||||
k++;
|
||||
}
|
||||
|
||||
if(start + k >= bytes.length()){
|
||||
break;
|
||||
}
|
||||
j = j*s + bytes[start + k] + base[k];
|
||||
|
||||
if(j >= (int)JSC::size){
|
||||
break;
|
||||
}
|
||||
auto word = QString(JSC::map[j].str);
|
||||
|
||||
out.append(word);
|
||||
|
||||
@@ -93,32 +93,6 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
n30min=minval(n30fox(1:nfox))
|
||||
n30max=maxval(n30fox(1:nfox))
|
||||
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
|
||||
endif
|
||||
|
||||
|
||||
+3
-3
@@ -98,9 +98,9 @@ void LogQSO::accept()
|
||||
QString hisCall,hisGrid,mode,rptSent,rptRcvd,dateOn,dateOff,timeOn,timeOff,band,operator_call;
|
||||
QString comments,name;
|
||||
|
||||
hisCall=ui->call->text();
|
||||
hisGrid=ui->grid->text();
|
||||
mode=ui->mode->text();
|
||||
hisCall=ui->call->text().toUpper();
|
||||
hisGrid=ui->grid->text().toUpper();
|
||||
mode=ui->mode->text().toUpper();
|
||||
rptSent=ui->sent->text();
|
||||
rptRcvd=ui->rcvd->text();
|
||||
m_dateTimeOn = ui->start_date_time->dateTime ();
|
||||
|
||||
+323
-55
@@ -551,6 +551,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_manual {&m_network_manager},
|
||||
m_txFrameCount {0},
|
||||
m_txTextDirty {false},
|
||||
m_txFrameCountEstimate {0},
|
||||
m_previousFreq {0}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@@ -1101,10 +1102,9 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
ui->menuTools->setEnabled(false);
|
||||
ui->menuView->setEnabled(false);
|
||||
foreach(auto action, ui->menuBar->actions()){
|
||||
if(action->text() == "View") ui->menuBar->removeAction(action);
|
||||
if(action->text() == "Mode") ui->menuBar->removeAction(action);
|
||||
//if(action->text() == "Decode") ui->menuBar->removeAction(action);
|
||||
if(action->text() == "Tools") ui->menuBar->removeAction(action);
|
||||
if(action->text() == "Old View") ui->menuBar->removeAction(action);
|
||||
if(action->text() == "Old Mode") ui->menuBar->removeAction(action);
|
||||
if(action->text() == "Old Tools") ui->menuBar->removeAction(action);
|
||||
}
|
||||
ui->dxCallEntry->clear();
|
||||
ui->dxGridEntry->clear();
|
||||
@@ -1294,6 +1294,22 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
auto clearAction4 = new QAction(QIcon::fromTheme("edit-clear"), QString("Clear"), ui->tableWidgetCalls);
|
||||
connect(clearAction4, &QAction::triggered, this, [this](){ this->on_clearAction_triggered(ui->tableWidgetCalls); });
|
||||
|
||||
auto addStation = new QAction(QString("Add New Station.."), ui->tableWidgetCalls);
|
||||
connect(addStation, &QAction::triggered, this, [this](){
|
||||
bool ok = false;
|
||||
QString callsign = QInputDialog::getText(this, tr("Add New Station..."),
|
||||
tr("Station Callsign:"), QLineEdit::Normal,
|
||||
"", &ok).toUpper().trimmed();
|
||||
if(!ok || callsign.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
CallDetail cd = {};
|
||||
cd.call = callsign;
|
||||
m_callActivity[callsign] = cd;
|
||||
displayActivity(true);
|
||||
});
|
||||
|
||||
auto removeStation = new QAction(QString("Remove Station"), ui->tableWidgetCalls);
|
||||
connect(removeStation, &QAction::triggered, this, [this](){
|
||||
QString selectedCall = callsignSelected();
|
||||
@@ -1305,7 +1321,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
|
||||
|
||||
ui->tableWidgetCalls->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->tableWidgetCalls, &QTableWidget::customContextMenuRequested, this, [this, logAction, clearAction4, clearActionAll, removeStation](QPoint const &point){
|
||||
connect(ui->tableWidgetCalls, &QTableWidget::customContextMenuRequested, this, [this, logAction, clearAction4, clearActionAll, addStation, removeStation](QPoint const &point){
|
||||
QMenu * menu = new QMenu(ui->tableWidgetCalls);
|
||||
|
||||
ui->tableWidgetRXAll->selectionModel()->clearSelection();
|
||||
@@ -1351,6 +1367,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
menu->addAction(addStation);
|
||||
removeStation->setDisabled(missingCallsign || isAllCall);
|
||||
menu->addAction(removeStation);
|
||||
|
||||
@@ -1389,6 +1406,35 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
ui->heartbeatButton->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
ui->heartbeatButton->addAction(heartbeatNow);
|
||||
|
||||
|
||||
int width = 75;
|
||||
/*
|
||||
QList<QPushButton*> btns;
|
||||
foreach(auto child, ui->buttonGrid->children()){
|
||||
if(!child->isWidgetType()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!child->objectName().contains("Button")){
|
||||
continue;
|
||||
}
|
||||
|
||||
auto b = qobject_cast<QPushButton*>(child);
|
||||
width = qMax(width, b->geometry().width());
|
||||
btns.append(b);
|
||||
}
|
||||
*/
|
||||
auto buttonLayout = ui->buttonGrid->layout();
|
||||
auto gridButtonLayout = qobject_cast<QGridLayout*>(buttonLayout);
|
||||
gridButtonLayout->setColumnMinimumWidth(0, width);
|
||||
gridButtonLayout->setColumnMinimumWidth(1, width);
|
||||
gridButtonLayout->setColumnMinimumWidth(2, width);
|
||||
gridButtonLayout->setColumnMinimumWidth(3, width);
|
||||
gridButtonLayout->setColumnStretch(0, 1);
|
||||
gridButtonLayout->setColumnStretch(1, 1);
|
||||
gridButtonLayout->setColumnStretch(2, 1);
|
||||
gridButtonLayout->setColumnStretch(3, 1);
|
||||
|
||||
pskSetLocal();
|
||||
aprsSetLocal();
|
||||
|
||||
@@ -1414,7 +1460,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
|
||||
}
|
||||
|
||||
QDate eol(2018, 11, 15);
|
||||
QDate eol(2018, 11, 30);
|
||||
|
||||
void MainWindow::checkExpiryWarningMessage()
|
||||
{
|
||||
@@ -1444,6 +1490,12 @@ void MainWindow::initializeDummyData(){
|
||||
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::packAlphaNumeric50("VE7/KN4CRD");
|
||||
// qDebug() << Varicode::unpackAlphaNumeric50(Varicode::packAlphaNumeric50("VE7/KN4CRD"));
|
||||
@@ -1496,6 +1548,7 @@ void MainWindow::initializeDummyData(){
|
||||
|
||||
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("HELLO BRAVE NEW WORLD \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-300), false, true, true);
|
||||
|
||||
displayActivity(true);
|
||||
|
||||
@@ -1682,6 +1735,7 @@ void MainWindow::writeSettings()
|
||||
m_settings->setValue("ShowTimeDrift", ui->driftSyncFrame->isVisible());
|
||||
m_settings->setValue("TimeDrift", ui->driftSpinBox->value());
|
||||
m_settings->setValue("SelCal", ui->selcalButton->isChecked());
|
||||
m_settings->setValue("ShowTooltips", ui->actionShow_Tooltips->isChecked());
|
||||
|
||||
m_settings->endGroup();
|
||||
|
||||
@@ -1754,8 +1808,9 @@ void MainWindow::readSettings()
|
||||
ui->cbAutoSeq->setVisible(false);
|
||||
ui->cbFirst->setVisible(false);
|
||||
m_settings->beginGroup("MainWindow");
|
||||
setMinimumSize(800, 400);
|
||||
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
|
||||
setMinimumSize(800, 545);
|
||||
setMinimumSize(800, 400);
|
||||
|
||||
m_geometryNoControls = m_settings->value ("geometryNoControls",saveGeometry()).toByteArray();
|
||||
restoreState (m_settings->value ("state", saveState ()).toByteArray ());
|
||||
@@ -1792,6 +1847,7 @@ void MainWindow::readSettings()
|
||||
ui->driftSyncFrame->setVisible(m_settings->value("ShowTimeDrift", false).toBool());
|
||||
ui->driftSpinBox->setValue(m_settings->value("TimeDrift", 0).toInt());
|
||||
ui->selcalButton->setChecked(m_settings->value("SelCal", false).toBool());
|
||||
ui->actionShow_Tooltips->setChecked(m_settings->value("ShowTooltips", true).toBool());
|
||||
|
||||
m_settings->endGroup();
|
||||
|
||||
@@ -2274,40 +2330,96 @@ void MainWindow::showSoundOutError(const QString& errorMsg)
|
||||
}
|
||||
|
||||
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);
|
||||
menu->insertAction(existingAction, dummyAction);
|
||||
menu->insertAction(dummyAction, existingAction);
|
||||
menu->removeAction(dummyAction);
|
||||
}
|
||||
|
||||
void MainWindow::on_menuControl_aboutToShow(){
|
||||
ui->actionEnable_Spotting->setChecked(ui->spotButton->isChecked());
|
||||
ui->actionEnable_Auto_Reply->setChecked(ui->autoReplyButton->isChecked());
|
||||
ui->actionEnable_Heartbeat->setChecked(ui->heartbeatButton->isChecked());
|
||||
ui->actionEnable_Selcall->setChecked(ui->selcalButton->isChecked());
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Spotting_toggled(bool checked){
|
||||
ui->spotButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Auto_Reply_toggled(bool checked){
|
||||
ui->autoReplyButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Heartbeat_toggled(bool checked){
|
||||
ui->heartbeatButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Selcall_toggled(bool checked){
|
||||
ui->selcalButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_menuWindow_aboutToShow(){
|
||||
auto hsizes = ui->textHorizontalSplitter->sizes();
|
||||
ui->actionShow_Band_Activity->setChecked(hsizes.at(0) > 0);
|
||||
ui->actionShow_Call_Activity->setChecked(hsizes.at(2) > 0);
|
||||
|
||||
auto vsizes = ui->mainSplitter->sizes();
|
||||
ui->actionShow_Frequency_Clock->setChecked(vsizes.first() > 0);
|
||||
ui->actionShow_Waterfall->setChecked(vsizes.last() > 0);
|
||||
ui->actionShow_Waterfall_Controls->setChecked(m_wideGraph->controlsVisible());
|
||||
ui->actionShow_Waterfall_Controls->setEnabled(ui->actionShow_Waterfall->isChecked());
|
||||
ui->actionShow_Time_Drift_Controls->setChecked(ui->driftSyncFrame->isVisible());
|
||||
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);
|
||||
ui->actionSort_Band_Activity->setMenu(sortBandMenu);
|
||||
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);
|
||||
ui->actionSort_Call_Activity->setMenu(sortCallMenu);
|
||||
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");
|
||||
ui->actionShow_Band_Activity_Columns->setMenu(showBandMenu);
|
||||
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");
|
||||
ui->actionShow_Call_Activity_Columns->setMenu(showCallMenu);
|
||||
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_Frequency_Clock_triggered(bool checked){
|
||||
auto vsizes = ui->mainSplitter->sizes();
|
||||
vsizes[0] = checked ? ui->logHorizontalWidget->minimumHeight() : 0;
|
||||
ui->logHorizontalWidget->setVisible(checked);
|
||||
ui->mainSplitter->setSizes(vsizes);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionShow_Band_Activity_triggered(bool checked){
|
||||
@@ -2402,6 +2514,8 @@ void MainWindow::openSettings(int tab){
|
||||
m_msAudioOutputBuffered);
|
||||
}
|
||||
|
||||
ui->bandComboBox->view ()->setMinimumWidth (ui->bandComboBox->view ()->sizeHintForColumn (FrequencyList_v2::frequency_mhz_column));
|
||||
|
||||
displayDialFrequency ();
|
||||
displayActivity(true);
|
||||
|
||||
@@ -2533,6 +2647,34 @@ void MainWindow::on_autoButton_clicked (bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_autoReplyButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->autoReplyButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_monitorButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->monitorButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_monitorTxButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->monitorTxButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_selcalButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->selcalButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_tuneButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->tuneButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_spotButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->spotButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_heartbeatButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->heartbeatButton);
|
||||
}
|
||||
|
||||
void MainWindow::auto_tx_mode (bool state)
|
||||
{
|
||||
ui->autoButton->setChecked (state);
|
||||
@@ -2669,6 +2811,13 @@ bool MainWindow::eventFilter (QObject * object, QEvent * event)
|
||||
remove_child_from_event_filter (static_cast<QChildEvent *> (event)->child ());
|
||||
break;
|
||||
|
||||
case QEvent::ToolTip:
|
||||
if(!ui->actionShow_Tooltips->isChecked()){
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
return QObject::eventFilter(object, event);
|
||||
@@ -3549,14 +3698,6 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
, tr ("Cannot open \"%1\" for append: %2")
|
||||
.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 &&
|
||||
ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
|
||||
@@ -3649,6 +3790,9 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
// it is not processed elsewhere, so we need to just log it here.
|
||||
logCallActivity(cd, true);
|
||||
|
||||
// play cq notification
|
||||
playSoundNotification(m_config.sound_cq_path());
|
||||
|
||||
} else {
|
||||
// convert HEARTBEAT to a directed command and process...
|
||||
cmd.from = cd.call;
|
||||
@@ -3872,6 +4016,15 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
// See MainWindow::postDecode for displaying the latest decodes
|
||||
}
|
||||
|
||||
void MainWindow::playSoundNotification(const QString &path){
|
||||
if(path.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Trying to play sound file" << path;
|
||||
|
||||
QSound::play(path);
|
||||
}
|
||||
|
||||
bool MainWindow::hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffset){
|
||||
if(m_messageBuffer.contains(offset)){
|
||||
@@ -3899,6 +4052,10 @@ bool MainWindow::hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffs
|
||||
}
|
||||
|
||||
void MainWindow::logCallActivity(CallDetail d, bool spot){
|
||||
if(d.call.trimmed().isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_callActivity.contains(d.call)){
|
||||
// update (keep grid)
|
||||
CallDetail old = m_callActivity[d.call];
|
||||
@@ -4353,6 +4510,7 @@ void MainWindow::guiUpdate()
|
||||
tx_status_label.setText(t.trimmed());
|
||||
}
|
||||
}
|
||||
|
||||
} else if(m_monitoring) {
|
||||
if (m_tx_watchdog) {
|
||||
tx_status_label.setStyleSheet ("QLabel{background-color: #ff0000}");
|
||||
@@ -4376,9 +4534,10 @@ void MainWindow::guiUpdate()
|
||||
|
||||
auto drift = DriftingDateTime::drift();
|
||||
QDateTime t = DriftingDateTime::currentDateTimeUtc();
|
||||
QString utc = t.date().toString("yyyy MMM dd") + "\n " +
|
||||
t.time().toString() + (!drift ? " " : QString(" (%1%2ms)").arg(drift > 0 ? "+" : "").arg(drift));
|
||||
ui->labUTC->setText(utc);
|
||||
QStringList parts;
|
||||
parts << (t.time().toString() + (!drift ? " " : QString(" (%1%2ms)").arg(drift > 0 ? "+" : "").arg(drift)));
|
||||
parts << t.date().toString("yyyy MMM dd");
|
||||
ui->labUTC->setText(parts.join("\n"));
|
||||
|
||||
auto delta = t.secsTo(m_nextHeartbeat);
|
||||
QString ping;
|
||||
@@ -5141,6 +5300,7 @@ int MainWindow::writeMessageTextToUI(QDateTime date, QString text, int freq, boo
|
||||
c.insertText(text);
|
||||
} else {
|
||||
text = text.toHtmlEscaped();
|
||||
text = text.replace(" ", " ");
|
||||
if(bold){
|
||||
text = QString("<strong>%1</strong>").arg(text);
|
||||
}
|
||||
@@ -5311,7 +5471,7 @@ void MainWindow::createMessage(QString const& text){
|
||||
}
|
||||
|
||||
resetMessageTransmitQueue();
|
||||
createMessageTransmitQueue(text);
|
||||
createMessageTransmitQueue(replaceMacros(text, buildMacroValues(), false));
|
||||
}
|
||||
|
||||
void MainWindow::createMessageTransmitQueue(QString const& text){
|
||||
@@ -5620,7 +5780,7 @@ void MainWindow::prepareHeartbeat(){
|
||||
|
||||
|
||||
|
||||
QString MainWindow::calculateDistance(QString const& value, int *pDistance)
|
||||
QString MainWindow::calculateDistance(QString const& value, int *pDistance, int *pAzimuth)
|
||||
{
|
||||
QString grid = value.trimmed();
|
||||
if(grid.isEmpty() || grid.length() < 4){
|
||||
@@ -5634,20 +5794,21 @@ QString MainWindow::calculateDistance(QString const& value, int *pDistance)
|
||||
const_cast <char *> ((grid + " ").left (6).toLatin1().constData()),&utch,
|
||||
&nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,6,6);
|
||||
|
||||
if(pAzimuth) *pAzimuth = nAz;
|
||||
|
||||
if(m_config.miles()){
|
||||
if(pDistance) *pDistance = nDmiles;
|
||||
return QString("%1 mi").arg(nDmiles);
|
||||
return QString("%1 mi / %2°").arg(nDmiles).arg(nAz);
|
||||
}
|
||||
|
||||
if(pDistance) *pDistance = nDkm;
|
||||
return QString("%1 km").arg(nDkm);
|
||||
return QString("%1 km / %2°").arg(nDkm).arg(nAz);
|
||||
}
|
||||
|
||||
// this function is called by auto_tx_mode, which is called by autoButton.clicked
|
||||
void MainWindow::on_startTxButton_toggled(bool checked)
|
||||
{
|
||||
if(checked){
|
||||
checkExpiryWarningMessage();
|
||||
createMessage(ui->extFreeTextMsgEdit->toPlainText());
|
||||
startTx();
|
||||
} else {
|
||||
@@ -5747,7 +5908,10 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
|
||||
|
||||
clearCallsignSelected();
|
||||
|
||||
m_logBook.init();
|
||||
|
||||
if (m_config.clear_DX () and !m_config.bHound()) clearDX ();
|
||||
|
||||
m_dateTimeQSOOn = QDateTime {};
|
||||
}
|
||||
|
||||
@@ -6036,6 +6200,8 @@ void MainWindow::on_actionErase_js8call_log_adi_triggered()
|
||||
if(ret==MessageBox::Yes) {
|
||||
QFile f {m_config.writeable_data_dir ().absoluteFilePath ("js8call_log.adi")};
|
||||
f.remove();
|
||||
|
||||
m_logBook.init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6245,6 +6411,7 @@ void MainWindow::on_clearAction_triggered(QObject * sender){
|
||||
if(sender == ui->tableWidgetRXAll){
|
||||
m_bandActivity.clear();
|
||||
clearTableWidget(ui->tableWidgetRXAll);
|
||||
resetTimeDeltaAverage();
|
||||
}
|
||||
|
||||
// TODO: jsherer - abstract this into a tableWidgetCallsReset function
|
||||
@@ -6252,6 +6419,7 @@ void MainWindow::on_clearAction_triggered(QObject * sender){
|
||||
m_callActivity.clear();
|
||||
clearTableWidget((ui->tableWidgetCalls));
|
||||
createAllcallTableRows(ui->tableWidgetCalls, "");
|
||||
resetTimeDeltaAverage();
|
||||
}
|
||||
|
||||
if(sender == ui->extFreeTextMsgEdit){
|
||||
@@ -6346,8 +6514,8 @@ void MainWindow::setShowColumn(QString tableKey, QString columnKey, bool value){
|
||||
displayCallActivity();
|
||||
}
|
||||
|
||||
bool MainWindow::showColumn(QString tableKey, QString columnKey){
|
||||
return m_showColumnsCache.value(tableKey + columnKey, QVariant(true)).toBool();
|
||||
bool MainWindow::showColumn(QString tableKey, QString columnKey, bool default_){
|
||||
return m_showColumnsCache.value(tableKey + columnKey, QVariant(default_)).toBool();
|
||||
}
|
||||
|
||||
void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
|
||||
@@ -6355,7 +6523,13 @@ void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
|
||||
{"Frequency Offset", "offset"},
|
||||
{"Last heard timestamp", "timestamp"},
|
||||
{"SNR", "snr"},
|
||||
{"Time delta", "tdrift"},
|
||||
{"Time Delta", "tdrift"},
|
||||
};
|
||||
|
||||
QMap<QString, bool> defaultOverride = {
|
||||
{"tdrift", false},
|
||||
{"grid", false},
|
||||
{"distance", false}
|
||||
};
|
||||
|
||||
if(tableKey == "call"){
|
||||
@@ -6376,7 +6550,13 @@ void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
|
||||
|
||||
auto a = menu->addAction(columnLabel);
|
||||
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](){
|
||||
setShowColumn(tableKey, columnKey, a->isChecked());
|
||||
@@ -6546,7 +6726,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
|
||||
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);
|
||||
connect(snrQueryAction, &QAction::triggered, this, [this](){
|
||||
|
||||
@@ -6560,7 +6740,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
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);
|
||||
connect(qthQueryAction, &QAction::triggered, this, [this](){
|
||||
|
||||
@@ -6574,7 +6754,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
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);
|
||||
connect(gridQueryAction, &QAction::triggered, this, [this](){
|
||||
|
||||
@@ -6787,6 +6967,19 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
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());
|
||||
connect(qrzAction, &QAction::triggered, this, [this](){
|
||||
|
||||
@@ -6888,6 +7081,7 @@ QMap<QString, QString> MainWindow::buildMacroValues(){
|
||||
auto cd = m_callActivity[selectedCall];
|
||||
|
||||
values["<CALL>"] = selectedCall;
|
||||
values["<TDELTA>"] = QString("%1 ms").arg((int)(1000*cd.tdrift));
|
||||
|
||||
if(cd.snr > -31){
|
||||
values["<SNR>"] = Varicode::formatSNR(cd.snr);
|
||||
@@ -7182,7 +7376,51 @@ void MainWindow::stopTuneATU()
|
||||
m_bTxTime=false;
|
||||
}
|
||||
|
||||
void MainWindow::resetPushButtonToggleText(QPushButton *btn){
|
||||
bool checked = btn->isChecked();
|
||||
auto style = btn->styleSheet();
|
||||
if(checked){
|
||||
style = style.replace("font-weight:normal;", "font-weight:bold;");
|
||||
} else {
|
||||
style = style.replace("font-weight:bold;", "font-weight:normal;");
|
||||
}
|
||||
btn->setStyleSheet(style);
|
||||
|
||||
#if PUSH_BUTTON_CHECKMARK
|
||||
auto on = "✓ ";
|
||||
auto text = btn->text();
|
||||
if(checked){
|
||||
btn->setText(on + text.replace(on, ""));
|
||||
} else {
|
||||
btn->setText(text.replace(on, ""));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PUSH_BUTTON_MIN_WIDTH
|
||||
int width = 0;
|
||||
QList<QPushButton*> btns;
|
||||
foreach(auto child, ui->buttonGrid->children()){
|
||||
if(!child->isWidgetType()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!child->objectName().contains("Button")){
|
||||
continue;
|
||||
}
|
||||
|
||||
auto b = qobject_cast<QPushButton*>(child);
|
||||
width = qMax(width, b->geometry().width());
|
||||
btns.append(b);
|
||||
}
|
||||
|
||||
foreach(auto child, btns){
|
||||
child->setMinimumWidth(width);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::on_monitorTxButton_clicked(){
|
||||
ui->monitorTxButton->setChecked(false);
|
||||
on_stopTxButton_clicked();
|
||||
}
|
||||
|
||||
@@ -7716,6 +7954,8 @@ void MainWindow::aprsSetLocal ()
|
||||
|
||||
void MainWindow::transmitDisplay (bool transmitting)
|
||||
{
|
||||
ui->monitorTxButton->setChecked(transmitting);
|
||||
|
||||
if (transmitting == m_transmitting) {
|
||||
if (transmitting) {
|
||||
ui->signal_meter_widget->setValue(0,0);
|
||||
@@ -7759,8 +7999,10 @@ void MainWindow::transmitDisplay (bool transmitting)
|
||||
}
|
||||
|
||||
// TODO: jsherer - encapsulate this in a function?
|
||||
/*
|
||||
ui->monitorButton->setVisible(!transmitting);
|
||||
ui->monitorTxButton->setVisible(transmitting);
|
||||
*/
|
||||
}
|
||||
|
||||
void MainWindow::on_sbFtol_valueChanged(int value)
|
||||
@@ -8018,7 +8260,12 @@ void MainWindow::updateTextDisplay(){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if __APPLE__
|
||||
#define USE_SYNC_FRAME_COUNT 1
|
||||
#else
|
||||
#define USE_SYNC_FRAME_COUNT 0
|
||||
#endif
|
||||
|
||||
void MainWindow::refreshTextDisplay(){
|
||||
qDebug() << "refreshing text display...";
|
||||
@@ -8029,8 +8276,8 @@ void MainWindow::refreshTextDisplay(){
|
||||
|
||||
QStringList textList;
|
||||
qDebug() << "frames:";
|
||||
foreach(Frame frame, frames){
|
||||
auto dt = DecodedText(frame.frame, frame.bits);
|
||||
foreach(auto frame, frames){
|
||||
auto dt = DecodedText(frame.first, frame.second);
|
||||
qDebug() << "->" << frame << dt.message() << Varicode::frameTypeString(dt.frameType());
|
||||
textList.append(dt.message());
|
||||
}
|
||||
@@ -8269,12 +8516,15 @@ void MainWindow::observeTimeDeltaForAverage(float delta){
|
||||
}
|
||||
|
||||
// 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(){
|
||||
m_timeDeltaMsMMA = 0;
|
||||
m_timeDeltaMsMMA_N = 0;
|
||||
|
||||
// observe zero for reset
|
||||
observeTimeDeltaForAverage(0);
|
||||
}
|
||||
|
||||
void MainWindow::processRxActivity() {
|
||||
@@ -8686,10 +8936,7 @@ void MainWindow::processCommandActivity() {
|
||||
});
|
||||
|
||||
if(!isAllCall){
|
||||
auto wav = m_config.sound_dm_path();
|
||||
if(!wav.isEmpty()){
|
||||
QSound::play(wav);
|
||||
}
|
||||
playSoundNotification(m_config.sound_dm_path());
|
||||
}
|
||||
|
||||
writeDirectedCommandToFile(d);
|
||||
@@ -8721,7 +8968,7 @@ void MainWindow::processCommandActivity() {
|
||||
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
|
||||
@@ -8745,7 +8992,11 @@ void MainWindow::processCommandActivity() {
|
||||
|
||||
// QUERIED STATION MESSAGE
|
||||
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
|
||||
@@ -8859,7 +9110,7 @@ void MainWindow::processCommandActivity() {
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
enqueueHeartbeat(reply);
|
||||
@@ -8956,6 +9207,7 @@ void MainWindow::processCommandActivity() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// well, if there's no reply, don't do anything...
|
||||
if (reply.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -8965,6 +9217,11 @@ void MainWindow::processCommandActivity() {
|
||||
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
|
||||
if(isAllCall){
|
||||
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 25);
|
||||
@@ -9052,10 +9309,7 @@ void MainWindow::processAlertReplyForCommand(CommandDetail d, QString from, QStr
|
||||
}
|
||||
});
|
||||
|
||||
auto wav = m_config.sound_am_path();
|
||||
if(!wav.isEmpty()){
|
||||
QSound::play(wav);
|
||||
}
|
||||
playSoundNotification(m_config.sound_am_path());
|
||||
|
||||
msgBox->setModal(false);
|
||||
msgBox->show();
|
||||
@@ -9397,7 +9651,7 @@ void MainWindow::displayBandActivity() {
|
||||
ui->tableWidgetRXAll->setColumnHidden(0, !showColumn("band", "offset"));
|
||||
ui->tableWidgetRXAll->setColumnHidden(1, !showColumn("band", "timestamp"));
|
||||
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
|
||||
ui->tableWidgetRXAll->resizeColumnToContents(0);
|
||||
@@ -9509,6 +9763,10 @@ void MainWindow::displayCallActivity() {
|
||||
|
||||
int callsignAging = m_config.callsign_aging();
|
||||
foreach(QString call, keys) {
|
||||
if(call.trimmed().isEmpty()){
|
||||
continue;
|
||||
}
|
||||
|
||||
CallDetail d = m_callActivity[call];
|
||||
|
||||
bool isCallSelected = (call == selectedCall);
|
||||
@@ -9541,6 +9799,7 @@ void MainWindow::displayCallActivity() {
|
||||
auto flagItem = new QTableWidgetItem(flag);
|
||||
flagItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui->tableWidgetCalls->setItem(row, col++, flagItem);
|
||||
if(d.utcTimestamp.isValid()){
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(QString("(%1)").arg(since(d.utcTimestamp))));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(QString("%1").arg(Varicode::formatSNR(d.snr))));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(QString("%1").arg(d.freq)));
|
||||
@@ -9554,6 +9813,15 @@ void MainWindow::displayCallActivity() {
|
||||
distanceItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
ui->tableWidgetCalls->setItem(ui->tableWidgetCalls->rowCount() - 1, col++, distanceItem);
|
||||
|
||||
} else {
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(""));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(""));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(""));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(""));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(""));
|
||||
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(""));
|
||||
}
|
||||
|
||||
if (isCallSelected) {
|
||||
for(int i = 0; i < ui->tableWidgetCalls->columnCount(); i++){
|
||||
ui->tableWidgetCalls->item(row, i)->setSelected(true);
|
||||
@@ -9585,11 +9853,11 @@ void MainWindow::displayCallActivity() {
|
||||
ui->tableWidgetCalls->setColumnHidden(0, !showColumn("call", "callsign"));
|
||||
ui->tableWidgetCalls->setColumnHidden(1, !showColumn("call", "flag"));
|
||||
ui->tableWidgetCalls->setColumnHidden(2, !showColumn("call", "timestamp"));
|
||||
ui->tableWidgetCalls->setColumnHidden(3, !showColumn("call", "offset"));
|
||||
ui->tableWidgetCalls->setColumnHidden(4, !showColumn("call", "snr"));
|
||||
ui->tableWidgetCalls->setColumnHidden(5, !showColumn("call", "tdrift"));
|
||||
ui->tableWidgetCalls->setColumnHidden(6, !showColumn("call", "grid"));
|
||||
ui->tableWidgetCalls->setColumnHidden(7, !showColumn("call", "distance"));
|
||||
ui->tableWidgetCalls->setColumnHidden(3, !showColumn("call", "snr"));
|
||||
ui->tableWidgetCalls->setColumnHidden(4, !showColumn("call", "offset"));
|
||||
ui->tableWidgetCalls->setColumnHidden(5, !showColumn("call", "tdrift", false));
|
||||
ui->tableWidgetCalls->setColumnHidden(6, !showColumn("call", "grid", false));
|
||||
ui->tableWidgetCalls->setColumnHidden(7, !showColumn("call", "distance", false));
|
||||
|
||||
// Resize the table columns
|
||||
ui->tableWidgetCalls->resizeColumnToContents(0);
|
||||
|
||||
+18
-2
@@ -130,6 +130,7 @@ public slots:
|
||||
void msgAvgDecode2();
|
||||
void fastPick(int x0, int x1, int y);
|
||||
|
||||
void playSoundNotification(const QString &path);
|
||||
bool hasExistingMessageBuffer(int offset, bool drift, int *pPrevOffset);
|
||||
void logCallActivity(CallDetail d, bool spot=true);
|
||||
QString lookupCallInCompoundCache(QString const &call);
|
||||
@@ -170,7 +171,13 @@ private slots:
|
||||
void on_tx4_editingFinished();
|
||||
void on_tx5_currentTextChanged (QString const&);
|
||||
void on_tx6_editingFinished();
|
||||
void on_menuControl_aboutToShow();
|
||||
void on_actionEnable_Spotting_toggled(bool checked);
|
||||
void on_actionEnable_Auto_Reply_toggled(bool checked);
|
||||
void on_actionEnable_Heartbeat_toggled(bool checked);
|
||||
void on_actionEnable_Selcall_toggled(bool checked);
|
||||
void on_menuWindow_aboutToShow();
|
||||
void on_actionShow_Frequency_Clock_triggered(bool checked);
|
||||
void on_actionShow_Band_Activity_triggered(bool checked);
|
||||
void on_actionShow_Call_Activity_triggered(bool checked);
|
||||
void on_actionShow_Waterfall_triggered(bool checked);
|
||||
@@ -185,6 +192,7 @@ private slots:
|
||||
void on_actionAbout_triggered();
|
||||
void on_autoButton_clicked (bool);
|
||||
void on_labDialFreq_clicked();
|
||||
void resetPushButtonToggleText(QPushButton *btn);
|
||||
void on_monitorTxButton_clicked();
|
||||
void on_stopTxButton_clicked();
|
||||
void on_stopButton_clicked();
|
||||
@@ -271,7 +279,7 @@ private slots:
|
||||
void on_qthMacroButton_clicked();
|
||||
void on_qtcMacroButton_clicked();
|
||||
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 setSortBy(QString key, QString value);
|
||||
QString getSortBy(QString key, QString defaultValue);
|
||||
@@ -307,7 +315,7 @@ private slots:
|
||||
void unpauseHeartbeat();
|
||||
void checkHeartbeat();
|
||||
void prepareHeartbeat();
|
||||
QString calculateDistance(QString const& grid, int *pDistance=nullptr);
|
||||
QString calculateDistance(QString const& grid, int *pDistance=nullptr, int *pAzimuth=nullptr);
|
||||
void on_driftSpinBox_valueChanged(int n);
|
||||
void on_driftSyncButton_clicked();
|
||||
void on_driftSyncEndButton_clicked();
|
||||
@@ -342,6 +350,14 @@ private slots:
|
||||
void stop_tuning ();
|
||||
void stopTuneATU();
|
||||
void auto_tx_mode(bool);
|
||||
void on_autoReplyButton_toggled(bool checked);
|
||||
void on_monitorButton_toggled(bool checked);
|
||||
void on_monitorTxButton_toggled(bool checked);
|
||||
void on_selcalButton_toggled(bool checked);
|
||||
void on_tuneButton_toggled(bool checked);
|
||||
void on_spotButton_toggled(bool checked);
|
||||
void on_heartbeatButton_toggled(bool checked);
|
||||
|
||||
void on_actionMessage_averaging_triggered();
|
||||
void on_actionFox_Log_triggered();
|
||||
void on_actionInclude_averaging_toggled (bool);
|
||||
|
||||
+608
-618
File diff suppressed because it is too large
Load Diff
+5
-3
@@ -65,7 +65,8 @@ QMap<QString, int> directed_cmds = {
|
||||
|
||||
//{"!", 7 }, // alert message
|
||||
//{"$", 3 }, // query station(s) heard
|
||||
//{"=", 9 }, // unused
|
||||
|
||||
{" TU", 9 }, // thank you
|
||||
|
||||
{" ACTIVE", 10 }, // i have 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
|
||||
};
|
||||
|
||||
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};
|
||||
|
||||
@@ -111,7 +112,7 @@ QMap<int, int> checksum_cmds = {
|
||||
};
|
||||
|
||||
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_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]))?");
|
||||
@@ -1622,6 +1623,7 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(
|
||||
#define ALLOW_SEND_COMPOUND_DIRECTED 1
|
||||
#define AUTO_PREPEND_DIRECTED 1
|
||||
#define AUTO_REMOVE_MYCALL 1
|
||||
#define AUTO_PREPEND_DIRECTED_ALLOW_TEXT_CALLSIGNS 1
|
||||
|
||||
bool mycallCompound = Varicode::isCompoundCallsign(mycall);
|
||||
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1083</width>
|
||||
<height>337</height>
|
||||
<height>154</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -43,7 +43,7 @@
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>100</height>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
|
||||
Reference in New Issue
Block a user