mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-22 04:11:16 -05:00
Merge branch 'hotfix-2.0.0-rc3'
This commit is contained in:
commit
388fb94698
@ -257,10 +257,14 @@ set (wsjt_qt_CXXSRCS
|
||||
MultiSettings.cpp
|
||||
MaidenheadLocatorValidator.cpp
|
||||
CallsignValidator.cpp
|
||||
ExchangeValidator.cpp
|
||||
SplashScreen.cpp
|
||||
EqualizationToolsDialog.cpp
|
||||
DoubleClickablePushButton.cpp
|
||||
DoubleClickableRadioButton.cpp
|
||||
LotWUsers.cpp
|
||||
DecodeHighlightingModel.cpp
|
||||
DecodeHighlightingListView.cpp
|
||||
)
|
||||
|
||||
set (wsjt_qtmm_CXXSRCS
|
||||
@ -308,6 +312,7 @@ set (wsjtx_CXXSRCS
|
||||
main.cpp
|
||||
wsprnet.cpp
|
||||
WSPRBandHopping.cpp
|
||||
ExportCabrillo.cpp
|
||||
)
|
||||
|
||||
set (wsjt_CXXSRCS
|
||||
@ -647,6 +652,7 @@ set (wsjtx_UISRCS
|
||||
widegraph.ui
|
||||
logqso.ui
|
||||
Configuration.ui
|
||||
ExportCabrillo.ui
|
||||
)
|
||||
|
||||
set (UDP_library_CXXSRCS
|
||||
@ -1427,7 +1433,6 @@ install (FILES
|
||||
|
||||
install (FILES
|
||||
contrib/Ephemeris/JPLEPH
|
||||
contrib/lotw-user-activity.csv
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
|
||||
#COMPONENT runtime
|
||||
)
|
||||
|
@ -157,7 +157,6 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QFont>
|
||||
#include <QFontDialog>
|
||||
#include <QColorDialog>
|
||||
#include <QSerialPortInfo>
|
||||
#include <QScopedPointer>
|
||||
#include <QDebug>
|
||||
@ -180,6 +179,9 @@
|
||||
#include "MessageBox.hpp"
|
||||
#include "MaidenheadLocatorValidator.hpp"
|
||||
#include "CallsignValidator.hpp"
|
||||
#include "LotWUsers.hpp"
|
||||
#include "ExchangeValidator.hpp"
|
||||
#include "DecodeHighlightingModel.hpp"
|
||||
|
||||
#include "ui_Configuration.h"
|
||||
#include "moc_Configuration.cpp"
|
||||
@ -354,8 +356,11 @@ public:
|
||||
using FrequencyDelta = Radio::FrequencyDelta;
|
||||
using port_type = Configuration::port_type;
|
||||
|
||||
explicit impl (Configuration * self, QDir const& temp_directory,
|
||||
QSettings * settings, QWidget * parent);
|
||||
explicit impl (Configuration * self
|
||||
, QNetworkAccessManager * network_manager
|
||||
, QDir const& temp_directory
|
||||
, QSettings * settings
|
||||
, QWidget * parent);
|
||||
~impl ();
|
||||
|
||||
bool have_rig ();
|
||||
@ -440,22 +445,19 @@ private:
|
||||
Q_SLOT void on_calibration_slope_ppm_spin_box_valueChanged (double);
|
||||
Q_SLOT void handle_transceiver_update (TransceiverState const&, unsigned sequence_number);
|
||||
Q_SLOT void handle_transceiver_failure (QString const& reason);
|
||||
Q_SLOT void on_pbCQmsg_clicked();
|
||||
Q_SLOT void on_pbMyCall_clicked();
|
||||
Q_SLOT void on_pbTxMsg_clicked();
|
||||
Q_SLOT void on_pbNewDXCC_clicked();
|
||||
Q_SLOT void on_pbNewDXCCband_clicked();
|
||||
Q_SLOT void on_pbNewCall_clicked();
|
||||
Q_SLOT void on_pbNewCallBand_clicked();
|
||||
Q_SLOT void on_pbNewGrid_clicked();
|
||||
Q_SLOT void on_pbNewGridBand_clicked();
|
||||
Q_SLOT void on_pbLoTW_clicked();
|
||||
Q_SLOT void on_pbResetDefaults_clicked();
|
||||
Q_SLOT void on_reset_highlighting_to_defaults_push_button_clicked (bool);
|
||||
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
|
||||
Q_SLOT void on_cbFox_clicked (bool);
|
||||
Q_SLOT void on_cbHound_clicked (bool);
|
||||
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
||||
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
|
||||
Q_SLOT void on_rbNone_toggled(bool);
|
||||
Q_SLOT void on_rbFieldDay_toggled();
|
||||
Q_SLOT void on_rbRTTYroundup_toggled();
|
||||
Q_SLOT void on_FieldDay_Exchange_textChanged();
|
||||
Q_SLOT void on_RTTY_Exchange_textChanged();
|
||||
Q_SLOT void on_prompt_to_log_check_box_clicked(bool);
|
||||
Q_SLOT void on_cbAutoLog_clicked(bool);
|
||||
|
||||
// typenames used as arguments must match registered type names :(
|
||||
Q_SIGNAL void start_transceiver (unsigned seqeunce_number) const;
|
||||
@ -471,6 +473,7 @@ private:
|
||||
|
||||
QScopedPointer<Ui::configuration_dialog> ui_;
|
||||
|
||||
QNetworkAccessManager * network_manager_;
|
||||
QSettings * settings_;
|
||||
|
||||
QDir doc_dir_;
|
||||
@ -488,6 +491,8 @@ private:
|
||||
QFont decoded_text_font_;
|
||||
QFont next_decoded_text_font_;
|
||||
|
||||
LotWUsers lotw_users_;
|
||||
|
||||
bool restart_sound_input_device_;
|
||||
bool restart_sound_output_device_;
|
||||
|
||||
@ -516,10 +521,14 @@ private:
|
||||
QAction * reset_frequencies_action_;
|
||||
FrequencyDialog * frequency_dialog_;
|
||||
|
||||
QAction * station_delete_action_;
|
||||
QAction * station_insert_action_;
|
||||
QAction station_delete_action_;
|
||||
QAction station_insert_action_;
|
||||
StationDialog * station_dialog_;
|
||||
|
||||
DecodeHighlightingModel decode_highlighing_model_;
|
||||
DecodeHighlightingModel next_decode_highlighing_model_;
|
||||
int LotW_days_since_upload_;
|
||||
|
||||
TransceiverFactory::ParameterPack rig_params_;
|
||||
TransceiverFactory::ParameterPack saved_rig_params_;
|
||||
TransceiverFactory::Capabilities::PortType last_port_type_;
|
||||
@ -539,26 +548,6 @@ private:
|
||||
QString my_grid_;
|
||||
QString FD_exchange_;
|
||||
QString RTTY_exchange_;
|
||||
QColor color_CQ_;
|
||||
QColor next_color_CQ_;
|
||||
QColor color_MyCall_;
|
||||
QColor next_color_MyCall_;
|
||||
QColor color_TxMsg_;
|
||||
QColor next_color_TxMsg_;
|
||||
QColor color_DXCC_;
|
||||
QColor next_color_DXCC_;
|
||||
QColor color_DXCCband_;
|
||||
QColor next_color_DXCCband_;
|
||||
QColor color_NewCall_;
|
||||
QColor next_color_NewCall_;
|
||||
QColor color_NewCallBand_;
|
||||
QColor next_color_NewCallBand_;
|
||||
QColor color_NewGrid_;
|
||||
QColor next_color_NewGrid_;
|
||||
QColor color_NewGridBand_;
|
||||
QColor next_color_NewGridBand_;
|
||||
QColor color_LoTW_;
|
||||
QColor next_color_LoTW_;
|
||||
|
||||
qint32 id_interval_;
|
||||
qint32 ntrials_;
|
||||
@ -574,6 +563,7 @@ private:
|
||||
bool log_as_RTTY_;
|
||||
bool report_in_comments_;
|
||||
bool prompt_to_log_;
|
||||
bool autoLog_;
|
||||
bool insert_blank_;
|
||||
bool DXCC_;
|
||||
bool ppfx_;
|
||||
@ -602,13 +592,9 @@ private:
|
||||
QString opCall_;
|
||||
QString udp_server_name_;
|
||||
port_type udp_server_port_;
|
||||
// QString n1mm_server_name () const;
|
||||
QString n1mm_server_name_;
|
||||
port_type n1mm_server_port_;
|
||||
bool broadcast_to_n1mm_;
|
||||
// port_type n1mm_server_port () const;
|
||||
// bool valid_n1mm_info () const;
|
||||
// bool broadcast_to_n1mm() const;
|
||||
bool accept_udp_requests_;
|
||||
bool udpWindowToFront_;
|
||||
bool udpWindowRestore_;
|
||||
@ -630,9 +616,9 @@ private:
|
||||
|
||||
|
||||
// delegate to implementation class
|
||||
Configuration::Configuration (QDir const& temp_directory,
|
||||
Configuration::Configuration (QNetworkAccessManager * network_manager, QDir const& temp_directory,
|
||||
QSettings * settings, QWidget * parent)
|
||||
: m_ {this, temp_directory, settings, parent}
|
||||
: m_ {this, network_manager, temp_directory, settings, parent}
|
||||
{
|
||||
}
|
||||
|
||||
@ -657,16 +643,6 @@ bool Configuration::restart_audio_input () const {return m_->restart_sound_input
|
||||
bool Configuration::restart_audio_output () const {return m_->restart_sound_output_device_;}
|
||||
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
|
||||
QString Configuration::my_callsign () const {return m_->my_callsign_;}
|
||||
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
|
||||
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
|
||||
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
|
||||
QColor Configuration::color_DXCC () const {return m_->color_DXCC_;}
|
||||
QColor Configuration::color_DXCCband() const {return m_->color_DXCCband_;}
|
||||
QColor Configuration::color_NewCall () const {return m_->color_NewCall_;}
|
||||
QColor Configuration::color_NewCallBand () const {return m_->color_NewCallBand_;}
|
||||
QColor Configuration::color_NewGrid () const {return m_->color_NewGrid_;}
|
||||
QColor Configuration::color_NewGridBand () const {return m_->color_NewGridBand_;}
|
||||
QColor Configuration::color_LoTW() const {return m_->color_LoTW_;}
|
||||
QFont Configuration::text_font () const {return m_->font_;}
|
||||
QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;}
|
||||
qint32 Configuration::id_interval () const {return m_->id_interval_;}
|
||||
@ -687,6 +663,7 @@ bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->
|
||||
bool Configuration::log_as_RTTY () const {return m_->log_as_RTTY_;}
|
||||
bool Configuration::report_in_comments () const {return m_->report_in_comments_;}
|
||||
bool Configuration::prompt_to_log () const {return m_->prompt_to_log_;}
|
||||
bool Configuration::autoLog() const {return m_->autoLog_;}
|
||||
bool Configuration::insert_blank () const {return m_->insert_blank_;}
|
||||
bool Configuration::DXCC () const {return m_->DXCC_;}
|
||||
bool Configuration::ppfx() const {return m_->ppfx_;}
|
||||
@ -735,6 +712,8 @@ QDir Configuration::azel_directory () const {return m_->azel_directory_;}
|
||||
QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
|
||||
bool Configuration::pwrBandTxMemory () const {return m_->pwrBandTxMemory_;}
|
||||
bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;}
|
||||
LotWUsers const& Configuration::lotw_users () const {return m_->lotw_users_;}
|
||||
DecodeHighlightingModel const& Configuration::decode_highlighting () const {return m_->decode_highlighing_model_;}
|
||||
|
||||
void Configuration::set_calibration (CalibrationParams params)
|
||||
{
|
||||
@ -906,17 +885,19 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
QSettings * settings, QWidget * parent)
|
||||
Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network_manager
|
||||
, QDir const& temp_directory, QSettings * settings, QWidget * parent)
|
||||
: QDialog {parent}
|
||||
, self_ {self}
|
||||
, transceiver_thread_ {nullptr}
|
||||
, ui_ {new Ui::configuration_dialog}
|
||||
, network_manager_ {network_manager}
|
||||
, settings_ {settings}
|
||||
, doc_dir_ {doc_path ()}
|
||||
, data_dir_ {data_path ()}
|
||||
, temp_dir_ {temp_directory}
|
||||
, writeable_data_dir_ {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}
|
||||
, lotw_users_ {network_manager_}
|
||||
, restart_sound_input_device_ {false}
|
||||
, restart_sound_output_device_ {false}
|
||||
, frequencies_ {&bands_}
|
||||
@ -926,7 +907,10 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
, current_offset_ {0}
|
||||
, current_tx_offset_ {0}
|
||||
, frequency_dialog_ {new FrequencyDialog {®ions_, &modes_, this}}
|
||||
, station_delete_action_ {tr ("&Delete"), nullptr}
|
||||
, station_insert_action_ {tr ("&Insert ..."), nullptr}
|
||||
, station_dialog_ {new StationDialog {&next_stations_, &bands_, this}}
|
||||
, LotW_days_since_upload_ {0}
|
||||
, last_port_type_ {TransceiverFactory::Capabilities::none}
|
||||
, rig_is_dummy_ {false}
|
||||
, rig_active_ {false}
|
||||
@ -997,12 +981,21 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
// this must be done after the default paths above are set
|
||||
read_settings ();
|
||||
|
||||
// conditionally load LotW users data
|
||||
ui_->LotW_CSV_fetch_push_button->setEnabled (false);
|
||||
connect (&lotw_users_, &LotWUsers::load_finished, [this] () {
|
||||
ui_->LotW_CSV_fetch_push_button->setEnabled (true);
|
||||
});
|
||||
lotw_users_.set_local_file_path (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv"));
|
||||
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text ());
|
||||
|
||||
//
|
||||
// validation
|
||||
//
|
||||
ui_->callsign_line_edit->setValidator (new CallsignValidator {this});
|
||||
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this});
|
||||
ui_->add_macro_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
ui_->FieldDay_Exchange->setValidator(new ExchangeValidator{this});
|
||||
ui_->RTTY_Exchange->setValidator(new ExchangeValidator{this});
|
||||
|
||||
ui_->udp_server_port_spin_box->setMinimum (1);
|
||||
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
@ -1115,29 +1108,30 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
ui_->frequencies_table_view->insertAction (nullptr, reset_frequencies_action_);
|
||||
connect (reset_frequencies_action_, &QAction::triggered, this, &Configuration::impl::reset_frequencies);
|
||||
|
||||
|
||||
//
|
||||
// setup stations table model & view
|
||||
//
|
||||
stations_.sort (StationList::band_column);
|
||||
|
||||
ui_->stations_table_view->setModel (&next_stations_);
|
||||
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
|
||||
|
||||
// delegates
|
||||
// stations delegates
|
||||
auto stations_item_delegate = new QStyledItemDelegate {this};
|
||||
stations_item_delegate->setItemEditorFactory (item_editor_factory ());
|
||||
ui_->stations_table_view->setItemDelegate (stations_item_delegate);
|
||||
ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this});
|
||||
|
||||
// actions
|
||||
station_delete_action_ = new QAction {tr ("&Delete"), ui_->stations_table_view};
|
||||
ui_->stations_table_view->insertAction (nullptr, station_delete_action_);
|
||||
connect (station_delete_action_, &QAction::triggered, this, &Configuration::impl::delete_stations);
|
||||
// stations actions
|
||||
ui_->stations_table_view->addAction (&station_delete_action_);
|
||||
connect (&station_delete_action_, &QAction::triggered, this, &Configuration::impl::delete_stations);
|
||||
|
||||
station_insert_action_ = new QAction {tr ("&Insert ..."), ui_->stations_table_view};
|
||||
ui_->stations_table_view->insertAction (nullptr, station_insert_action_);
|
||||
connect (station_insert_action_, &QAction::triggered, this, &Configuration::impl::insert_station);
|
||||
ui_->stations_table_view->addAction (&station_insert_action_);
|
||||
connect (&station_insert_action_, &QAction::triggered, this, &Configuration::impl::insert_station);
|
||||
|
||||
//
|
||||
// colours and highlighting setup
|
||||
//
|
||||
ui_->highlighting_list_view->setModel (&next_decode_highlighing_model_);
|
||||
|
||||
//
|
||||
// load combo boxes with audio setup choices
|
||||
@ -1181,16 +1175,6 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->callsign_line_edit->setText (my_callsign_);
|
||||
ui_->grid_line_edit->setText (my_grid_);
|
||||
ui_->use_dynamic_grid->setChecked(use_dynamic_grid_);
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name()));
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name()));
|
||||
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name()));
|
||||
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name()));
|
||||
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(color_DXCCband_.name()));
|
||||
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name()));
|
||||
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(color_NewCallBand_.name()));
|
||||
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(color_NewGrid_.name()));
|
||||
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(color_NewGridBand_.name()));
|
||||
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(color_LoTW_.name()));
|
||||
ui_->CW_id_interval_spin_box->setValue (id_interval_);
|
||||
ui_->sbNtrials->setValue (ntrials_);
|
||||
ui_->sbTxDelay->setValue (txDelay_);
|
||||
@ -1208,6 +1192,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->log_as_RTTY_check_box->setChecked (log_as_RTTY_);
|
||||
ui_->report_in_comments_check_box->setChecked (report_in_comments_);
|
||||
ui_->prompt_to_log_check_box->setChecked (prompt_to_log_);
|
||||
ui_->cbAutoLog->setChecked(autoLog_);
|
||||
ui_->insert_blank_check_box->setChecked (insert_blank_);
|
||||
ui_->DXCC_check_box->setChecked (DXCC_);
|
||||
ui_->ppfx_check_box->setChecked (ppfx_);
|
||||
@ -1291,6 +1276,9 @@ void Configuration::impl::initialize_models ()
|
||||
next_frequencies_.frequency_list (frequencies_.frequency_list ());
|
||||
next_stations_.station_list (stations_.station_list ());
|
||||
|
||||
next_decode_highlighing_model_.items (decode_highlighing_model_.items ());
|
||||
ui_->LotW_days_since_upload_spin_box->setValue (LotW_days_since_upload_);
|
||||
|
||||
set_rig_invariants ();
|
||||
}
|
||||
|
||||
@ -1314,16 +1302,6 @@ void Configuration::impl::read_settings ()
|
||||
RTTY_exchange_ = settings_->value ("RTTYExchange",QString {}).toString ();
|
||||
ui_->FieldDay_Exchange->setText(FD_exchange_);
|
||||
ui_->RTTY_Exchange->setText(RTTY_exchange_);
|
||||
next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString();
|
||||
next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString();
|
||||
next_color_TxMsg_ = color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString();
|
||||
next_color_DXCC_ = color_DXCC_ = settings_->value("colorDXCC","#ff00ff").toString();
|
||||
next_color_DXCCband_ = color_DXCCband_ = settings_->value("colorDXCCband","#ffaaff").toString();
|
||||
next_color_NewCall_ = color_NewCall_ = settings_->value("colorNewCall","#66b2ff").toString();
|
||||
next_color_NewCallBand_ = color_NewCallBand_ = settings_->value("colorNewCallBand","#99ffff").toString();
|
||||
next_color_NewGrid_ = color_NewGrid_ = settings_->value("colorNewGrid","#ffaa00").toString();
|
||||
next_color_NewGridBand_ = color_NewGridBand_ = settings_->value("colorNewGridBand","#ffcc99").toString();
|
||||
next_color_LoTW_ = color_LoTW_ = settings_->value("colorLoTW","#990000").toString();
|
||||
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_font_ != font_)
|
||||
{
|
||||
@ -1338,6 +1316,8 @@ void Configuration::impl::read_settings ()
|
||||
&& next_decoded_text_font_ != decoded_text_font_)
|
||||
{
|
||||
decoded_text_font_ = next_decoded_text_font_;
|
||||
next_decode_highlighing_model_.set_font (decoded_text_font_);
|
||||
ui_->highlighting_list_view->reset ();
|
||||
Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
|
||||
}
|
||||
else
|
||||
@ -1441,6 +1421,10 @@ void Configuration::impl::read_settings ()
|
||||
|
||||
stations_.station_list (settings_->value ("stations").value<StationList::Stations> ());
|
||||
|
||||
decode_highlighing_model_.items (settings_->value ("DecodeHighlighting", QVariant::fromValue (DecodeHighlightingModel::default_items ())).value<DecodeHighlightingModel::HighlightItems> ());
|
||||
LotW_days_since_upload_ = settings_->value ("LotWDaysSinceLastUpload", 365).toInt ();
|
||||
lotw_users_.set_age_constraint (LotW_days_since_upload_);
|
||||
|
||||
log_as_RTTY_ = settings_->value ("toRTTY", false).toBool ();
|
||||
report_in_comments_ = settings_->value("dBtoComments", false).toBool ();
|
||||
rig_params_.rig_name = settings_->value ("Rig", TransceiverFactory::basic_transceiver_name_).toString ();
|
||||
@ -1461,6 +1445,7 @@ void Configuration::impl::read_settings ()
|
||||
rig_params_.ptt_port = settings_->value ("PTTport").toString ();
|
||||
data_mode_ = settings_->value ("DataMode", QVariant::fromValue (data_mode_none)).value<Configuration::DataMode> ();
|
||||
prompt_to_log_ = settings_->value ("PromptToLog", false).toBool ();
|
||||
autoLog_ = settings_->value ("AutoLog", false).toBool ();
|
||||
insert_blank_ = settings_->value ("InsertBlank", false).toBool ();
|
||||
DXCC_ = settings_->value ("DXCCEntity", false).toBool ();
|
||||
ppfx_ = settings_->value ("PrincipalPrefix", false).toBool ();
|
||||
@ -1510,16 +1495,6 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("MyGrid", my_grid_);
|
||||
settings_->setValue ("FieldDayExchange", FD_exchange_);
|
||||
settings_->setValue ("RTTYExchange", RTTY_exchange_);
|
||||
settings_->setValue("colorCQ",color_CQ_);
|
||||
settings_->setValue("colorMyCall",color_MyCall_);
|
||||
settings_->setValue("colorTxMsg",color_TxMsg_);
|
||||
settings_->setValue("colorDXCC",color_DXCC_);
|
||||
settings_->setValue("colorDXCCband",color_DXCCband_);
|
||||
settings_->setValue("colorNewCall",color_NewCall_);
|
||||
settings_->setValue("colorNewCallBand",color_NewCallBand_);
|
||||
settings_->setValue("colorNewGrid",color_NewGrid_);
|
||||
settings_->setValue("colorNewGridBand",color_NewGridBand_);
|
||||
settings_->setValue("colorLoTW",color_LoTW_);
|
||||
settings_->setValue ("Font", font_.toString ());
|
||||
settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ());
|
||||
settings_->setValue ("IDint", id_interval_);
|
||||
@ -1561,6 +1536,8 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("Macros", macros_.stringList ());
|
||||
settings_->setValue ("FrequenciesForRegionModes", QVariant::fromValue (frequencies_.frequency_list ()));
|
||||
settings_->setValue ("stations", QVariant::fromValue (stations_.station_list ()));
|
||||
settings_->setValue ("DecodeHighlighting", QVariant::fromValue (decode_highlighing_model_.items ()));
|
||||
settings_->setValue ("LotWDaysSinceLastUpload", LotW_days_since_upload_);
|
||||
settings_->setValue ("toRTTY", log_as_RTTY_);
|
||||
settings_->setValue ("dBtoComments", report_in_comments_);
|
||||
settings_->setValue ("Rig", rig_params_.rig_name);
|
||||
@ -1573,6 +1550,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("CATHandshake", QVariant::fromValue (rig_params_.handshake));
|
||||
settings_->setValue ("DataMode", QVariant::fromValue (data_mode_));
|
||||
settings_->setValue ("PromptToLog", prompt_to_log_);
|
||||
settings_->setValue ("AutoLog", autoLog_);
|
||||
settings_->setValue ("InsertBlank", insert_blank_);
|
||||
settings_->setValue ("DXCCEntity", DXCC_);
|
||||
settings_->setValue ("PrincipalPrefix", ppfx_);
|
||||
@ -1883,20 +1861,11 @@ void Configuration::impl::accept ()
|
||||
if (next_decoded_text_font_ != decoded_text_font_)
|
||||
{
|
||||
decoded_text_font_ = next_decoded_text_font_;
|
||||
next_decode_highlighing_model_.set_font (decoded_text_font_);
|
||||
ui_->highlighting_list_view->reset ();
|
||||
Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
|
||||
}
|
||||
|
||||
color_CQ_ = next_color_CQ_;
|
||||
color_MyCall_ = next_color_MyCall_;
|
||||
color_TxMsg_ = next_color_TxMsg_;
|
||||
color_DXCC_ = next_color_DXCC_;
|
||||
color_DXCCband_ = next_color_DXCCband_;
|
||||
color_NewCall_ = next_color_NewCall_;
|
||||
color_NewCallBand_ = next_color_NewCallBand_;
|
||||
color_NewGrid_ = next_color_NewGrid_;
|
||||
color_NewGridBand_ = next_color_NewGridBand_;
|
||||
color_LoTW_ = next_color_LoTW_;
|
||||
|
||||
rig_params_ = temp_rig_params; // now we can go live with the rig
|
||||
// related configuration parameters
|
||||
rig_is_dummy_ = TransceiverFactory::basic_transceiver_name_ == rig_params_.rig_name;
|
||||
@ -1994,6 +1963,7 @@ void Configuration::impl::accept ()
|
||||
log_as_RTTY_ = ui_->log_as_RTTY_check_box->isChecked ();
|
||||
report_in_comments_ = ui_->report_in_comments_check_box->isChecked ();
|
||||
prompt_to_log_ = ui_->prompt_to_log_check_box->isChecked ();
|
||||
autoLog_ = ui_->cbAutoLog->isChecked();
|
||||
insert_blank_ = ui_->insert_blank_check_box->isChecked ();
|
||||
DXCC_ = ui_->DXCC_check_box->isChecked ();
|
||||
ppfx_ = ui_->ppfx_check_box->isChecked ();
|
||||
@ -2042,10 +2012,8 @@ void Configuration::impl::accept ()
|
||||
}
|
||||
|
||||
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
|
||||
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text ();
|
||||
n1mm_server_name_ = new_n1mm_server;
|
||||
auto new_n1mm_port = ui_->n1mm_server_port_spin_box->value ();
|
||||
n1mm_server_port_ = new_n1mm_port;
|
||||
n1mm_server_name_ = ui_->n1mm_server_name_line_edit->text ();
|
||||
n1mm_server_port_ = ui_->n1mm_server_port_spin_box->value ();
|
||||
broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked ();
|
||||
|
||||
udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
|
||||
@ -2066,10 +2034,18 @@ void Configuration::impl::accept ()
|
||||
|
||||
if (stations_.station_list () != next_stations_.station_list ())
|
||||
{
|
||||
stations_.station_list(next_stations_.station_list ());
|
||||
stations_.station_list (next_stations_.station_list ());
|
||||
stations_.sort (StationList::band_column);
|
||||
}
|
||||
|
||||
if (decode_highlighing_model_.items () != next_decode_highlighing_model_.items ())
|
||||
{
|
||||
decode_highlighing_model_.items (next_decode_highlighing_model_.items ());
|
||||
Q_EMIT self_->decode_highlighting_changed (decode_highlighing_model_);
|
||||
}
|
||||
LotW_days_since_upload_ = ui_->LotW_days_since_upload_spin_box->value ();
|
||||
lotw_users_.set_age_constraint (LotW_days_since_upload_);
|
||||
|
||||
if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
|
||||
{
|
||||
// turning on so clear it so only the next location update gets used
|
||||
@ -2108,136 +2084,27 @@ void Configuration::impl::on_font_push_button_clicked ()
|
||||
next_font_ = QFontDialog::getFont (0, next_font_, this);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbCQmsg_clicked()
|
||||
void Configuration::impl::on_reset_highlighting_to_defaults_push_button_clicked (bool /*checked*/)
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_CQ_, this, "CQ Messages Color");
|
||||
if (new_color.isValid ())
|
||||
if (MessageBox::Yes == MessageBox::query_message (this
|
||||
, tr ("Reset Decode Highlighting")
|
||||
, tr ("Reset all decode highlighting and priorities to default values")))
|
||||
{
|
||||
next_color_CQ_ = new_color;
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
|
||||
next_decode_highlighing_model_.items (DecodeHighlightingModel::default_items ());
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbMyCall_clicked()
|
||||
void Configuration::impl::on_LotW_CSV_fetch_push_button_clicked (bool /*checked*/)
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_MyCall_, this, "My Call Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_MyCall_ = new_color;
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(next_color_MyCall_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbTxMsg_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_TxMsg_, this, "Tx Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_TxMsg_ = new_color;
|
||||
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_TxMsg_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewDXCC_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_DXCC_, this, "New DXCC Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_DXCC_ = new_color;
|
||||
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(next_color_DXCC_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewDXCCband_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_DXCCband_, this, "New DXCCband Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_DXCCband_ = new_color;
|
||||
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(next_color_DXCCband_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewCall_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_NewCall_, this, "New Call Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_NewCall_ = new_color;
|
||||
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(next_color_NewCall_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewCallBand_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_NewCallBand_, this, "New CallBand Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_NewCallBand_ = new_color;
|
||||
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(next_color_NewCallBand_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewGrid_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_NewGrid_, this, "New Grid Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_NewGrid_ = new_color;
|
||||
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(next_color_NewGrid_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewGridBand_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_NewGridBand_, this, "New GridBand Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_NewGridBand_ = new_color;
|
||||
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(next_color_NewGridBand_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbLoTW_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_LoTW_, this, "Not in LoTW Color");
|
||||
if (new_color.isValid ()) {
|
||||
next_color_LoTW_ = new_color;
|
||||
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(next_color_LoTW_.name()));
|
||||
}
|
||||
}
|
||||
void Configuration::impl::on_pbResetDefaults_clicked()
|
||||
{
|
||||
next_color_CQ_ = color_CQ_ = "#66ff66";
|
||||
next_color_MyCall_ = color_MyCall_ = "#ff6666";
|
||||
next_color_TxMsg_ = color_TxMsg_ = "#ffff00";
|
||||
next_color_DXCC_ = color_DXCC_ = "#ff00ff";
|
||||
next_color_DXCCband_ = color_DXCCband_ = "#ffaaff";
|
||||
next_color_NewCall_ = color_NewCall_ = "#66b2ff";
|
||||
next_color_NewCallBand_ = color_NewCallBand_ = "#99ffff";
|
||||
next_color_NewGrid_ = color_NewGrid_ = "#ffaa00";
|
||||
next_color_NewGridBand_ = color_NewGridBand_ = "#ffcc99";
|
||||
next_color_LoTW_ = color_LoTW_ = "#5500ff";
|
||||
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(next_color_MyCall_.name()));
|
||||
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_TxMsg_.name()));
|
||||
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(next_color_DXCC_.name()));
|
||||
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(next_color_DXCCband_.name()));
|
||||
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(next_color_NewCall_.name()));
|
||||
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(next_color_NewCallBand_.name()));
|
||||
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(next_color_NewGrid_.name()));
|
||||
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(next_color_NewGridBand_.name()));
|
||||
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(next_color_LoTW_.name()));
|
||||
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), true);
|
||||
ui_->LotW_CSV_fetch_push_button->setEnabled (false);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_decoded_text_font_push_button_clicked ()
|
||||
{
|
||||
next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this
|
||||
, tr ("WSJT-X Decoded Text Font Chooser")
|
||||
#if QT_VERSION >= 0x050201
|
||||
, QFontDialog::MonospacedFonts
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
@ -2347,6 +2214,20 @@ void Configuration::impl::on_add_macro_line_edit_editingFinished ()
|
||||
ui_->add_macro_line_edit->setText (ui_->add_macro_line_edit->text ().toUpper ());
|
||||
}
|
||||
|
||||
void Configuration::impl::on_FieldDay_Exchange_textChanged()
|
||||
{
|
||||
bool b=ui_->FieldDay_Exchange->hasAcceptableInput() or !ui_->rbFieldDay->isChecked();
|
||||
if(b) ui_->FieldDay_Exchange->setStyleSheet("color: black");
|
||||
if(!b) ui_->FieldDay_Exchange->setStyleSheet("color: red");
|
||||
}
|
||||
|
||||
void Configuration::impl::on_RTTY_Exchange_textChanged()
|
||||
{
|
||||
bool b=ui_->RTTY_Exchange->hasAcceptableInput() or !ui_->rbRTTYroundup->isChecked();
|
||||
if(b) ui_->RTTY_Exchange->setStyleSheet("color: black");
|
||||
if(!b) ui_->RTTY_Exchange->setStyleSheet("color: red");
|
||||
}
|
||||
|
||||
void Configuration::impl::on_delete_macro_push_button_clicked (bool /* checked */)
|
||||
{
|
||||
auto selection_model = ui_->macros_list_view->selectionModel ();
|
||||
@ -2577,6 +2458,16 @@ void Configuration::impl::on_calibration_slope_ppm_spin_box_valueChanged (double
|
||||
rig_active_ = false; // force reset
|
||||
}
|
||||
|
||||
void Configuration::impl::on_prompt_to_log_check_box_clicked(bool checked)
|
||||
{
|
||||
if(checked) ui_->cbAutoLog->setChecked(false);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbAutoLog_clicked(bool checked)
|
||||
{
|
||||
if(checked) ui_->prompt_to_log_check_box->setChecked(false);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbFox_clicked (bool checked)
|
||||
{
|
||||
if(checked) {
|
||||
@ -2598,11 +2489,10 @@ void Configuration::impl::on_cbHound_clicked (bool checked)
|
||||
void Configuration::impl::chk77()
|
||||
{
|
||||
bool b77OK = !ui_->cbFox->isChecked() and !ui_->cbHound->isChecked();
|
||||
ui_->groupBox_8->setEnabled(b77OK);
|
||||
ui_->groupBox_9->setEnabled(b77OK);
|
||||
if(!b77OK) {
|
||||
ui_->cbGenerate77->setChecked(false);
|
||||
ui_->cbDecode77->setChecked(false);
|
||||
ui_->cbGenerate77->setChecked(true);
|
||||
ui_->cbDecode77->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2611,6 +2501,16 @@ void Configuration::impl::on_rbNone_toggled(bool b)
|
||||
if(!b) ui_->cbGenerate77->setChecked(true);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_rbFieldDay_toggled()
|
||||
{
|
||||
on_FieldDay_Exchange_textChanged();
|
||||
}
|
||||
|
||||
void Configuration::impl::on_rbRTTYroundup_toggled()
|
||||
{
|
||||
on_RTTY_Exchange_textChanged();
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbx2ToneSpacing_clicked(bool b)
|
||||
{
|
||||
if(b) ui_->cbx4ToneSpacing->setChecked(false);
|
||||
@ -3021,11 +2921,6 @@ auto Configuration::impl::remove_calibration (Frequency f) const -> Frequency
|
||||
/ (1. + calibration_.slope_ppm / 1.e6));
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_IMPL (Configuration, DataMode);
|
||||
ENUM_QDEBUG_OPS_IMPL (Configuration, Type2MsgGen);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (Configuration, DataMode);
|
||||
ENUM_QDATASTREAM_OPS_IMPL (Configuration, Type2MsgGen);
|
||||
|
||||
|
@ -16,11 +16,14 @@ class QWidget;
|
||||
class QAudioDeviceInfo;
|
||||
class QString;
|
||||
class QDir;
|
||||
class QNetworkAccessManager;
|
||||
class Bands;
|
||||
class FrequencyList_v2;
|
||||
class StationList;
|
||||
class QStringListModel;
|
||||
class QHostAddress;
|
||||
class LotWUsers;
|
||||
class DecodeHighlightingModel;
|
||||
|
||||
//
|
||||
// Class Configuration
|
||||
@ -56,7 +59,6 @@ class Configuration final
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS (DataMode Type2MsgGen)
|
||||
|
||||
public:
|
||||
using MODE = Transceiver::MODE;
|
||||
@ -69,7 +71,7 @@ public:
|
||||
enum Type2MsgGen {type_2_msg_1_full, type_2_msg_3_full, type_2_msg_5_only};
|
||||
Q_ENUM (Type2MsgGen)
|
||||
|
||||
explicit Configuration (QDir const& temp_directory, QSettings * settings,
|
||||
explicit Configuration (QNetworkAccessManager *, QDir const& temp_directory, QSettings * settings,
|
||||
QWidget * parent = nullptr);
|
||||
~Configuration ();
|
||||
|
||||
@ -115,6 +117,7 @@ public:
|
||||
bool log_as_RTTY () const;
|
||||
bool report_in_comments () const;
|
||||
bool prompt_to_log () const;
|
||||
bool autoLog() const;
|
||||
bool insert_blank () const;
|
||||
bool DXCC () const;
|
||||
bool ppfx() const;
|
||||
@ -169,18 +172,10 @@ public:
|
||||
QDir azel_directory () const;
|
||||
QString rig_name () const;
|
||||
Type2MsgGen type_2_msg_gen () const;
|
||||
QColor color_CQ () const;
|
||||
QColor color_MyCall () const;
|
||||
QColor color_TxMsg () const;
|
||||
QColor color_DXCC () const;
|
||||
QColor color_DXCCband () const;
|
||||
QColor color_NewCall () const;
|
||||
QColor color_NewCallBand () const;
|
||||
QColor color_NewGrid () const;
|
||||
QColor color_NewGridBand () const;
|
||||
QColor color_LoTW() const;
|
||||
bool pwrBandTxMemory () const;
|
||||
bool pwrBandTuneMemory () const;
|
||||
LotWUsers const& lotw_users () const;
|
||||
DecodeHighlightingModel const& decode_highlighting () const;
|
||||
|
||||
struct CalibrationParams
|
||||
{
|
||||
@ -239,8 +234,6 @@ public:
|
||||
Q_SLOT void transceiver_tx_frequency (Frequency = 0u);
|
||||
|
||||
// Set transceiver mode.
|
||||
//
|
||||
// Rationalise means ensure TX uses same mode as RX.
|
||||
Q_SLOT void transceiver_mode (MODE);
|
||||
|
||||
// Set/unset PTT.
|
||||
@ -265,15 +258,17 @@ public:
|
||||
// These signals indicate a font has been selected and accepted for
|
||||
// the application text and decoded text respectively.
|
||||
//
|
||||
Q_SIGNAL void text_font_changed (QFont);
|
||||
Q_SIGNAL void decoded_text_font_changed (QFont);
|
||||
Q_SIGNAL void text_font_changed (QFont) const;
|
||||
Q_SIGNAL void decoded_text_font_changed (QFont) const;
|
||||
|
||||
//
|
||||
// This signal is emitted when the UDP server changes
|
||||
//
|
||||
Q_SIGNAL void udp_server_changed (QString const& udp_server);
|
||||
Q_SIGNAL void udp_server_port_changed (port_type server_port);
|
||||
Q_SIGNAL void udp_server_changed (QString const& udp_server) const;
|
||||
Q_SIGNAL void udp_server_port_changed (port_type server_port) const;
|
||||
|
||||
// signal updates to decode highlighting
|
||||
Q_SIGNAL void decode_highlighting_changed (DecodeHighlightingModel const&) const;
|
||||
|
||||
//
|
||||
// These signals are emitted and reflect transceiver state changes
|
||||
@ -295,16 +290,6 @@ private:
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
#if QT_VERSION < 0x050500
|
||||
Q_DECLARE_METATYPE (Configuration::DataMode);
|
||||
Q_DECLARE_METATYPE (Configuration::Type2MsgGen);
|
||||
#endif
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_DECL (Configuration, DataMode);
|
||||
ENUM_QDEBUG_OPS_DECL (Configuration, Type2MsgGen);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_DECL (Configuration, DataMode);
|
||||
ENUM_QDATASTREAM_OPS_DECL (Configuration, Type2MsgGen);
|
||||
|
||||
|
613
Configuration.ui
613
Configuration.ui
@ -74,7 +74,7 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="grid_line_edit">
|
||||
<property name="toolTip">
|
||||
<string>Maidenhead locator (only the first four characters are required).</string>
|
||||
<string><html><head/><body><p>Maidenhead locator, preferably 6 characters.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -103,7 +103,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="region_combo_box"/>
|
||||
<widget class="QComboBox" name="region_combo_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select your IARU region.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -1700,26 +1704,12 @@ QListView::item:hover {
|
||||
<property name="text">
|
||||
<string>Op Call:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="opCallEntry">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The callsign of the operator, if different from the station callsign.</p></body></html></string>
|
||||
<property name="buddy">
|
||||
<cstring>opCallEntry</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="log_as_RTTY_check_box">
|
||||
<property name="toolTip">
|
||||
<string>Some logging programs will not accept JT-65 or JT9 as a recognized mode.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Con&vert mode to RTTY</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="report_in_comments_check_box">
|
||||
<property name="toolTip">
|
||||
<string>Some logging programs will not accept the type of reports
|
||||
@ -1732,7 +1722,7 @@ comments field.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="clear_DX_check_box">
|
||||
<property name="toolTip">
|
||||
<string>Check this option to force the clearing of the DX Call
|
||||
@ -1743,6 +1733,33 @@ and DX Grid fields when a 73 or free text message is sent.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="log_as_RTTY_check_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Some logging programs will not accept WSJT-X mode names.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Con&vert mode to RTTY</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="opCallEntry">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The callsign of the operator, if different from the station callsign.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="cbAutoLog">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Check to have QSOs logged automatically, when complete.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Log automatically</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1895,6 +1912,9 @@ for assessing propagation and system performance.</string>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>N1MM Server name or IP address:</p></body></html></string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>n1mm_server_name_line_edit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
@ -1909,6 +1929,9 @@ for assessing propagation and system performance.</string>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>N1MM Server port number:</p></body></html></string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>n1mm_server_port_spin_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
@ -2152,8 +2175,158 @@ Right click for insert and delete options.</string>
|
||||
<attribute name="title">
|
||||
<string>Colors</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5" rowstretch="1,0,0" columnstretch="1,0,0">
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_12">
|
||||
<property name="title">
|
||||
<string>Decode Highlightling</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="DecodeHighlightingListView" name="highlighting_list_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::ActionsContextMenu</enum>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable or disable using the check boxes and right-click an item to change the foreground color, background color, or reset the item to default values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="resizeMode">
|
||||
<enum>QListView::Adjust</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="reset_highlighting_to_defaults_push_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Push to reset all highlight items above to default values and priorities.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset Highlighting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_11">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Controls for Logbook of the World user lookup.</p></body></html></string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Logbook of the World User Validation</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_18">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Age of last upload less than:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>LotW_days_since_upload_spin_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="LotW_days_since_upload_spin_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> days</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>365</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Users CSV file URL:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>LotW_CSV_URL_line_edit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_20">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="LotW_CSV_URL_line_edit">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>URL of the ARRL LotW user's last upload dates and times data file which is used to highlight decodes from stations that are known to upload their log file to LotW.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>https://lotw.arrl.org/lotw-user-activity.csv</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="LotW_CSV_fetch_push_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Push this button to fetch the latest LotW user's upload date and time data file.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fetch Now</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -2166,317 +2339,6 @@ Right click for insert and delete options.</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="labLoTW">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{color: #990000}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pbMyCall">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>My Call in message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QPushButton" name="pbNewDXCCband">
|
||||
<property name="text">
|
||||
<string>New DXCC on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="labDXCCband">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #ffaaff}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pbCQmsg">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CQ in message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labTx">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: yellow}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pbTxMsg">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Transmitted message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="labMyCall">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #ff6666}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labCQ">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #66ff66}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labDXCC">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #ff00ff}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QPushButton" name="pbResetDefaults">
|
||||
<property name="text">
|
||||
<string>Reset Defaults</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="pbNewDXCC">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>New DXCC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="labNewGrid">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #ff8000}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="labNewGridBand">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #ffcc99}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="labNewCall">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #00ffff}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QPushButton" name="pbNewGrid">
|
||||
<property name="text">
|
||||
<string>New grid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QPushButton" name="pbNewGridBand">
|
||||
<property name="text">
|
||||
<string>New Grid on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="labNewCallBand">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel{background-color: #99ffff}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QPushButton" name="pbNewCall">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>New Call</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QPushButton" name="pbNewCallBand">
|
||||
<property name="text">
|
||||
<string>New Call on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QPushButton" name="pbLoTW">
|
||||
<property name="text">
|
||||
<string>LoTW</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="advanced_tab">
|
||||
@ -2560,6 +2422,9 @@ Right click for insert and delete options.</string>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbGenerate77">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>By default, early candidate releases of WSJT-X 2.0 generate 75-bit messages if the message content allows it.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Always generate 77-bit messages</string>
|
||||
</property>
|
||||
@ -2567,6 +2432,9 @@ Right click for insert and delete options.</string>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbDecode77">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Check this box to ignore FT8 transmissions using the older 75-bit protocol.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Decode only 77-bit messages</string>
|
||||
</property>
|
||||
@ -2759,6 +2627,9 @@ Right click for insert and delete options.</string>
|
||||
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,2,1,0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbNone">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>For normal operating</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
@ -2775,6 +2646,9 @@ Right click for insert and delete options.</string>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>EU VHF Contest</string>
|
||||
</property>
|
||||
@ -2784,6 +2658,9 @@ Right click for insert and delete options.</string>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbRTTYroundup">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ARRL RTTY Roundup</string>
|
||||
</property>
|
||||
@ -2805,7 +2682,7 @@ Right click for insert and delete options.</string>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_17">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<widget class="QLabel" name="labRTTY">
|
||||
<property name="text">
|
||||
<string>Exch:</string>
|
||||
</property>
|
||||
@ -2822,6 +2699,9 @@ Right click for insert and delete options.</string>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>NJ</string>
|
||||
</property>
|
||||
@ -2838,6 +2718,9 @@ Right click for insert and delete options.</string>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_17" stretch="2,1,1">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbFieldDay">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ARRL Field Day</string>
|
||||
</property>
|
||||
@ -2859,7 +2742,7 @@ Right click for insert and delete options.</string>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_16">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<widget class="QLabel" name="labFD">
|
||||
<property name="text">
|
||||
<string>Exch:</string>
|
||||
</property>
|
||||
@ -2876,6 +2759,9 @@ Right click for insert and delete options.</string>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>6A SNJ</string>
|
||||
</property>
|
||||
@ -2896,6 +2782,9 @@ Right click for insert and delete options.</string>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>NA VHF Contest</string>
|
||||
</property>
|
||||
@ -2937,9 +2826,7 @@ Right click for insert and delete options.</string>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="configuration_dialog_button_box">
|
||||
<property name="toolTip">
|
||||
<string>Discard or apply configuration changes including
|
||||
resetting the radio interface and applying any
|
||||
soundcard changes</string>
|
||||
<string><html><head/><body><p>Discard (Cancel) or apply (OK) configuration changes including</p><p>resetting the radio interface and applying any soundcard changes</p></body></html></string>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -2951,36 +2838,49 @@ soundcard changes</string>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DecodeHighlightingListView</class>
|
||||
<extends>QListView</extends>
|
||||
<header>DecodehigHlightingListView.hpp</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>configuration_tabs</tabstop>
|
||||
<tabstop>callsign_line_edit</tabstop>
|
||||
<tabstop>grid_line_edit</tabstop>
|
||||
<tabstop>use_dynamic_grid</tabstop>
|
||||
<tabstop>region_combo_box</tabstop>
|
||||
<tabstop>type_2_msg_gen_combo_box</tabstop>
|
||||
<tabstop>insert_blank_check_box</tabstop>
|
||||
<tabstop>miles_check_box</tabstop>
|
||||
<tabstop>TX_messages_check_box</tabstop>
|
||||
<tabstop>DXCC_check_box</tabstop>
|
||||
<tabstop>ppfx_check_box</tabstop>
|
||||
<tabstop>font_push_button</tabstop>
|
||||
<tabstop>decoded_text_font_push_button</tabstop>
|
||||
<tabstop>monitor_off_check_box</tabstop>
|
||||
<tabstop>monitor_last_used_check_box</tabstop>
|
||||
<tabstop>quick_call_check_box</tabstop>
|
||||
<tabstop>tx_watchdog_spin_box</tabstop>
|
||||
<tabstop>disable_TX_on_73_check_box</tabstop>
|
||||
<tabstop>CW_id_after_73_check_box</tabstop>
|
||||
<tabstop>enable_VHF_features_check_box</tabstop>
|
||||
<tabstop>tx_QSY_check_box</tabstop>
|
||||
<tabstop>single_decode_check_box</tabstop>
|
||||
<tabstop>decode_at_52s_check_box</tabstop>
|
||||
<tabstop>tx_watchdog_spin_box</tabstop>
|
||||
<tabstop>CW_id_interval_spin_box</tabstop>
|
||||
<tabstop>rig_combo_box</tabstop>
|
||||
<tabstop>CAT_poll_interval_spin_box</tabstop>
|
||||
<tabstop>CAT_port_combo_box</tabstop>
|
||||
<tabstop>CAT_serial_baud_combo_box</tabstop>
|
||||
<tabstop>CAT_default_bit_radio_button</tabstop>
|
||||
<tabstop>CAT_7_bit_radio_button</tabstop>
|
||||
<tabstop>CAT_8_bit_radio_button</tabstop>
|
||||
<tabstop>CAT_default_stop_bit_radio_button</tabstop>
|
||||
<tabstop>CAT_one_stop_bit_radio_button</tabstop>
|
||||
<tabstop>CAT_two_stop_bit_radio_button</tabstop>
|
||||
<tabstop>CAT_handshake_default_radio_button</tabstop>
|
||||
<tabstop>CAT_handshake_none_radio_button</tabstop>
|
||||
<tabstop>CAT_handshake_xon_radio_button</tabstop>
|
||||
<tabstop>CAT_handshake_hardware_radio_button</tabstop>
|
||||
@ -3014,29 +2914,48 @@ soundcard changes</string>
|
||||
<tabstop>delete_macro_push_button</tabstop>
|
||||
<tabstop>macros_list_view</tabstop>
|
||||
<tabstop>prompt_to_log_check_box</tabstop>
|
||||
<tabstop>cbAutoLog</tabstop>
|
||||
<tabstop>log_as_RTTY_check_box</tabstop>
|
||||
<tabstop>report_in_comments_check_box</tabstop>
|
||||
<tabstop>clear_DX_check_box</tabstop>
|
||||
<tabstop>opCallEntry</tabstop>
|
||||
<tabstop>psk_reporter_check_box</tabstop>
|
||||
<tabstop>udp_server_line_edit</tabstop>
|
||||
<tabstop>udp_server_port_spin_box</tabstop>
|
||||
<tabstop>accept_udp_requests_check_box</tabstop>
|
||||
<tabstop>udpWindowToFront</tabstop>
|
||||
<tabstop>udpWindowRestore</tabstop>
|
||||
<tabstop>enable_n1mm_broadcast_check_box</tabstop>
|
||||
<tabstop>n1mm_server_name_line_edit</tabstop>
|
||||
<tabstop>n1mm_server_port_spin_box</tabstop>
|
||||
<tabstop>calibration_slope_ppm_spin_box</tabstop>
|
||||
<tabstop>calibration_intercept_spin_box</tabstop>
|
||||
<tabstop>frequencies_table_view</tabstop>
|
||||
<tabstop>stations_table_view</tabstop>
|
||||
<tabstop>pbCQmsg</tabstop>
|
||||
<tabstop>pbMyCall</tabstop>
|
||||
<tabstop>pbTxMsg</tabstop>
|
||||
<tabstop>pbNewDXCC</tabstop>
|
||||
<tabstop>highlighting_list_view</tabstop>
|
||||
<tabstop>reset_highlighting_to_defaults_push_button</tabstop>
|
||||
<tabstop>LotW_CSV_URL_line_edit</tabstop>
|
||||
<tabstop>LotW_CSV_fetch_push_button</tabstop>
|
||||
<tabstop>LotW_days_since_upload_spin_box</tabstop>
|
||||
<tabstop>sbNtrials</tabstop>
|
||||
<tabstop>sbAggressive</tabstop>
|
||||
<tabstop>cbTwoPass</tabstop>
|
||||
<tabstop>sbDegrade</tabstop>
|
||||
<tabstop>sbBandwidth</tabstop>
|
||||
<tabstop>sbTxDelay</tabstop>
|
||||
<tabstop>cbx2ToneSpacing</tabstop>
|
||||
<tabstop>cbx4ToneSpacing</tabstop>
|
||||
<tabstop>cbFox</tabstop>
|
||||
<tabstop>cbHound</tabstop>
|
||||
<tabstop>cbGenerate77</tabstop>
|
||||
<tabstop>cbDecode77</tabstop>
|
||||
<tabstop>rbNone</tabstop>
|
||||
<tabstop>rbNA_VHF_Contest</tabstop>
|
||||
<tabstop>rbEU_VHF_Contest</tabstop>
|
||||
<tabstop>rbFieldDay</tabstop>
|
||||
<tabstop>FieldDay_Exchange</tabstop>
|
||||
<tabstop>rbRTTYroundup</tabstop>
|
||||
<tabstop>RTTY_Exchange</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
@ -3106,12 +3025,12 @@ soundcard changes</string>
|
||||
</connection>
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="TX_mode_button_group"/>
|
||||
<buttongroup name="TX_audio_source_button_group"/>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="CAT_stop_bits_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"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
77
DecodeHighlightingListView.cpp
Normal file
77
DecodeHighlightingListView.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
#include "DecodeHighlightingListView.hpp"
|
||||
|
||||
#include <QAction>
|
||||
#include <QColorDialog>
|
||||
|
||||
#include "DecodeHighlightingModel.hpp"
|
||||
#include "MessageBox.hpp"
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
class DecodeHighlightingListView::impl final
|
||||
{
|
||||
public:
|
||||
impl ()
|
||||
: fg_colour_action_ {tr ("&Foreground color ..."), nullptr}
|
||||
, bg_colour_action_ {tr ("&Background color ..."), nullptr}
|
||||
, defaults_action_ {tr ("&Reset this item to defaults"), nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
DecodeHighlightingListView * self_;
|
||||
QAction fg_colour_action_;
|
||||
QAction bg_colour_action_;
|
||||
QAction defaults_action_;
|
||||
};
|
||||
|
||||
DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent)
|
||||
: QListView {parent}
|
||||
{
|
||||
addAction (&m_->fg_colour_action_);
|
||||
addAction (&m_->bg_colour_action_);
|
||||
addAction (&m_->defaults_action_);
|
||||
connect (&m_->fg_colour_action_, &QAction::triggered, [this] (bool /*checked*/) {
|
||||
auto const& index = currentIndex ();
|
||||
auto colour = QColorDialog::getColor (model ()->data (index, Qt::ForegroundRole).value<QBrush> ().color ()
|
||||
, this
|
||||
, tr ("Choose %1 Foreground Color")
|
||||
.arg (model ()->data (index).toString ()));
|
||||
if (colour.isValid ())
|
||||
{
|
||||
model ()->setData (index, colour, Qt::ForegroundRole);
|
||||
}
|
||||
});
|
||||
connect (&m_->bg_colour_action_, &QAction::triggered, [this] (bool /*checked*/) {
|
||||
auto const& index = currentIndex ();
|
||||
auto colour = QColorDialog::getColor (model ()->data (index, Qt::BackgroundRole).value<QBrush> ().color ()
|
||||
, this
|
||||
, tr ("Choose %1 Background Color")
|
||||
.arg (model ()->data (index).toString ()));
|
||||
if (colour.isValid ())
|
||||
{
|
||||
model ()->setData (index, colour, Qt::BackgroundRole);
|
||||
}
|
||||
});
|
||||
connect (&m_->defaults_action_, &QAction::triggered, [this] (bool /*checked*/) {
|
||||
auto const& index = currentIndex ();
|
||||
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::EnabledDefaultRole).toBool () ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
|
||||
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::ForegroundDefaultRole), Qt::ForegroundRole);
|
||||
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::BackgroundDefaultRole), Qt::BackgroundRole);
|
||||
});
|
||||
}
|
||||
|
||||
DecodeHighlightingListView::~DecodeHighlightingListView ()
|
||||
{
|
||||
}
|
||||
|
||||
QSize DecodeHighlightingListView::sizeHint () const
|
||||
{
|
||||
auto item_height = sizeHintForRow (0);
|
||||
if (item_height >= 0)
|
||||
{
|
||||
// set the height hint to exactly the space required for all the
|
||||
// items
|
||||
return {width (), (model ()->rowCount () * (item_height + 2 * spacing ())) + 2 * frameWidth ()};
|
||||
}
|
||||
return QListView::sizeHint ();
|
||||
}
|
32
DecodeHighlightingListView.hpp
Normal file
32
DecodeHighlightingListView.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef DECODE_HIGHLIGHTING_LIST_VIEW_HPP_
|
||||
#define DECODE_HIGHLIGHTING_LIST_VIEW_HPP_
|
||||
|
||||
#include <QListView>
|
||||
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
class QWidget;
|
||||
|
||||
// Class Decode Highlighting List View
|
||||
//
|
||||
// Sub-class of a QListView that adds a context menu to adjust the
|
||||
// foreground and background colour roles of the the underlying model
|
||||
// item that lies at the context menu right-click position. It also
|
||||
// constrains the vertical size hint to limit the height to exactly
|
||||
// that of the sum of the items.
|
||||
//
|
||||
class DecodeHighlightingListView final
|
||||
: public QListView
|
||||
{
|
||||
public:
|
||||
explicit DecodeHighlightingListView (QWidget * parent = nullptr);
|
||||
~DecodeHighlightingListView ();
|
||||
|
||||
private:
|
||||
QSize sizeHint () const override;
|
||||
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
#endif
|
319
DecodeHighlightingModel.cpp
Normal file
319
DecodeHighlightingModel.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
#include "DecodeHighlightingModel.hpp"
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QList>
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include <QMap>
|
||||
#include <QVector>
|
||||
#include <QDataStream>
|
||||
#include <QMetaType>
|
||||
#include <QDebug>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_DecodeHighlightingModel.cpp"
|
||||
|
||||
class DecodeHighlightingModel::impl final
|
||||
{
|
||||
public:
|
||||
explicit impl ()
|
||||
: data_ {defaults_}
|
||||
{
|
||||
}
|
||||
|
||||
HighlightItems static const defaults_;
|
||||
HighlightItems data_;
|
||||
QFont font_;
|
||||
};
|
||||
|
||||
QList<DecodeHighlightingModel::HighlightInfo> const DecodeHighlightingModel::impl::defaults_ = {
|
||||
{Highlight::CQ, true, {}, {{0x66, 0xff, 0x66}}}
|
||||
, {Highlight::MyCall, true, {}, {{0xff, 0x66, 0x66}}}
|
||||
, {Highlight::Tx, true, {}, {{Qt::yellow}}}
|
||||
, {Highlight::DXCC, true, {}, {{0xff, 0x00, 0xff}}}
|
||||
, {Highlight::DXCCBand, true, {}, {{0xff, 0xaa, 0xff}}}
|
||||
, {Highlight::Grid, false, {}, {{0xff, 0x80, 0x00}}}
|
||||
, {Highlight::GridBand, false, {}, {{0xff, 0xcc, 0x99}}}
|
||||
, {Highlight::Call, false, {}, {{0x00, 0xff, 0xff}}}
|
||||
, {Highlight::CallBand, false, {}, {{0x99, 0xff, 0xff}}}
|
||||
, {Highlight::LotW, false, {{0x99, 0x00, 0x00}}, {}}
|
||||
};
|
||||
|
||||
bool operator == (DecodeHighlightingModel::HighlightInfo const& lhs, DecodeHighlightingModel::HighlightInfo const& rhs)
|
||||
{
|
||||
return lhs.type_ == rhs.type_
|
||||
&& lhs.enabled_ == rhs.enabled_
|
||||
&& lhs.foreground_ == rhs.foreground_
|
||||
&& lhs.background_ == rhs.background_;
|
||||
}
|
||||
|
||||
QDataStream& operator << (QDataStream& os, DecodeHighlightingModel::HighlightInfo const& item)
|
||||
{
|
||||
return os << item.type_
|
||||
<< item.enabled_
|
||||
<< item.foreground_
|
||||
<< item.background_;
|
||||
}
|
||||
|
||||
QDataStream& operator >> (QDataStream& is, DecodeHighlightingModel::HighlightInfo& item)
|
||||
{
|
||||
return is >> item.type_
|
||||
>> item.enabled_
|
||||
>> item.foreground_
|
||||
>> item.background_;
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
QDebug operator << (QDebug debug, DecodeHighlightingModel::HighlightInfo const& item)
|
||||
{
|
||||
QDebugStateSaver save {debug};
|
||||
debug.nospace () << "HighlightInfo("
|
||||
<< item.type_ << ", "
|
||||
<< item.enabled_ << ", "
|
||||
<< item.foreground_ << ", "
|
||||
<< item.background_ << ')';
|
||||
return debug;
|
||||
}
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (DecodeHighlightingModel, Highlight);
|
||||
ENUM_CONVERSION_OPS_IMPL (DecodeHighlightingModel, Highlight);
|
||||
|
||||
DecodeHighlightingModel::DecodeHighlightingModel (QObject * parent)
|
||||
: QAbstractListModel {parent}
|
||||
{
|
||||
}
|
||||
|
||||
DecodeHighlightingModel::~DecodeHighlightingModel ()
|
||||
{
|
||||
}
|
||||
|
||||
QString DecodeHighlightingModel::highlight_name (Highlight h)
|
||||
{
|
||||
switch (h)
|
||||
{
|
||||
case Highlight::CQ: return "CQ in message";
|
||||
case Highlight::MyCall: return "My Call in message";
|
||||
case Highlight::Tx: return "Transmitted message";
|
||||
case Highlight::DXCC: return "New DXCC";
|
||||
case Highlight::DXCCBand: return "New DXCC on Band";
|
||||
case Highlight::Grid: return "New Grid";
|
||||
case Highlight::GridBand: return "New Grid on Band";
|
||||
case Highlight::Call: return "New Call";
|
||||
case Highlight::CallBand: return "New Call on Band";
|
||||
case Highlight::LotW: return "LotW User";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
auto DecodeHighlightingModel::default_items () -> HighlightItems const&
|
||||
{
|
||||
return impl::defaults_;
|
||||
}
|
||||
|
||||
auto DecodeHighlightingModel::items () const -> HighlightItems const&
|
||||
{
|
||||
return m_->data_;
|
||||
}
|
||||
|
||||
void DecodeHighlightingModel::items (HighlightItems const& items)
|
||||
{
|
||||
m_->data_ = items;
|
||||
QVector<int> roles;
|
||||
roles << Qt::CheckStateRole << Qt::ForegroundRole << Qt::BackgroundRole;
|
||||
Q_EMIT dataChanged (index (0, 0), index (rowCount () - 1, 0), roles);
|
||||
}
|
||||
|
||||
void DecodeHighlightingModel::set_font (QFont const& font)
|
||||
{
|
||||
m_->font_ = font;
|
||||
}
|
||||
|
||||
int DecodeHighlightingModel::rowCount (const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid () ? 0 : m_->data_.size ();
|
||||
}
|
||||
|
||||
QVariant DecodeHighlightingModel::data (const QModelIndex& index, int role) const
|
||||
{
|
||||
QVariant result;
|
||||
if (index.isValid () && index.row () < rowCount ())
|
||||
{
|
||||
auto const& item = m_->data_[index.row ()];
|
||||
switch (role)
|
||||
{
|
||||
case Qt::CheckStateRole:
|
||||
result = item.enabled_ ? Qt::Checked : Qt::Unchecked;
|
||||
break;
|
||||
case Qt::DisplayRole:
|
||||
result = highlight_name (item.type_);
|
||||
break;
|
||||
case Qt::ForegroundRole:
|
||||
if (Qt::NoBrush != item.foreground_.style ())
|
||||
{
|
||||
result = item.foreground_;
|
||||
}
|
||||
break;
|
||||
case Qt::BackgroundRole:
|
||||
if (Qt::NoBrush != item.background_.style ())
|
||||
{
|
||||
result = item.background_;
|
||||
}
|
||||
break;
|
||||
case Qt::FontRole:
|
||||
result = m_->font_;
|
||||
break;
|
||||
case TypeRole:
|
||||
result = static_cast<int> (item.type_);
|
||||
break;
|
||||
case EnabledDefaultRole:
|
||||
for (auto const& default_item : impl::defaults_)
|
||||
{
|
||||
if (default_item.type_ == item.type_)
|
||||
{
|
||||
result = default_item.enabled_ ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ForegroundDefaultRole:
|
||||
for (auto const& default_item : impl::defaults_)
|
||||
{
|
||||
if (default_item.type_ == item.type_)
|
||||
{
|
||||
result = default_item.foreground_;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BackgroundDefaultRole:
|
||||
for (auto const& default_item : impl::defaults_)
|
||||
{
|
||||
if (default_item.type_ == item.type_)
|
||||
{
|
||||
result = default_item.background_;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Override QAbstractItemModel::itemData() as it is used by the
|
||||
// default mime encode routine used in drag'n'drop operations and we
|
||||
// want to transport the type role, this is because the display role
|
||||
// is derived from the type role.
|
||||
QMap<int, QVariant> DecodeHighlightingModel::itemData (QModelIndex const& index) const
|
||||
{
|
||||
auto roles = QAbstractListModel::itemData (index);
|
||||
QVariant variantData = data (index, TypeRole);
|
||||
if (variantData.isValid ())
|
||||
{
|
||||
roles.insert (TypeRole, variantData);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant DecodeHighlightingModel::headerData (int /*section*/, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant header;
|
||||
if (Qt::DisplayRole == role && Qt::Horizontal == orientation)
|
||||
{
|
||||
header = tr ("Highlight Type");
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
Qt::ItemFlags DecodeHighlightingModel::flags (QModelIndex const& index) const
|
||||
{
|
||||
auto flags = QAbstractListModel::flags (index) | Qt::ItemIsDragEnabled;
|
||||
if (index.isValid ())
|
||||
{
|
||||
flags |= Qt::ItemIsUserCheckable;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= Qt::ItemIsDropEnabled;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool DecodeHighlightingModel::setData (QModelIndex const& index, QVariant const& value, int role)
|
||||
{
|
||||
bool ok {false};
|
||||
if (index.isValid () && index.row () < rowCount ())
|
||||
{
|
||||
auto& item = m_->data_[index.row ()];
|
||||
QVector<int> roles;
|
||||
roles << role;
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::FontRole:
|
||||
ok = true;
|
||||
break;
|
||||
case Qt::CheckStateRole:
|
||||
if (item.enabled_ != (Qt::Checked == value))
|
||||
{
|
||||
item.enabled_ = Qt::Checked == value;
|
||||
Q_EMIT dataChanged (index, index, roles);
|
||||
}
|
||||
ok = true;
|
||||
break;
|
||||
case Qt::ForegroundRole:
|
||||
if (item.foreground_ != value.value<QBrush> ())
|
||||
{
|
||||
item.foreground_ = value.value<QBrush> ();
|
||||
Q_EMIT dataChanged (index, index, roles);
|
||||
}
|
||||
ok = true;
|
||||
break;
|
||||
case Qt::BackgroundRole:
|
||||
if (item.background_ != value.value<QBrush> ())
|
||||
{
|
||||
item.background_ = value.value<QBrush> ();
|
||||
Q_EMIT dataChanged (index, index, roles);
|
||||
}
|
||||
ok = true;
|
||||
break;
|
||||
case TypeRole:
|
||||
if (item.type_ != static_cast<Highlight> (value.toInt ()))
|
||||
{
|
||||
item.type_ = static_cast<Highlight> (value.toInt ());
|
||||
roles << Qt::DisplayRole;
|
||||
Q_EMIT dataChanged (index, index, roles);
|
||||
}
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
Qt::DropActions DecodeHighlightingModel::supportedDropActions () const
|
||||
{
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
bool DecodeHighlightingModel::insertRows (int row, int count, QModelIndex const& parent)
|
||||
{
|
||||
beginInsertRows (parent, row, row + count - 1);
|
||||
for (int index = 0; index < count; ++index)
|
||||
{
|
||||
m_->data_.insert (row, HighlightInfo {Highlight::CQ, false, {}, {}});
|
||||
}
|
||||
endInsertRows ();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeHighlightingModel::removeRows (int row, int count, QModelIndex const& parent)
|
||||
{
|
||||
beginRemoveRows (parent, row, row + count - 1);
|
||||
for (int index = 0; index < count; ++index)
|
||||
{
|
||||
m_->data_.removeAt (row);
|
||||
}
|
||||
endRemoveRows ();
|
||||
return true;
|
||||
}
|
77
DecodeHighlightingModel.hpp
Normal file
77
DecodeHighlightingModel.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef DECODE_HIGHLIGHTING_MODEL_HPP_
|
||||
#define DECODE_HIGHLIGHTING_MODEL_HPP_
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QBrush>
|
||||
#include <QList>
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
class QObject;
|
||||
class QFont;
|
||||
class QDataStream;
|
||||
class QDebug;
|
||||
|
||||
class DecodeHighlightingModel final
|
||||
: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class Highlight : char {CQ, MyCall, Tx, DXCC, DXCCBand, Grid, GridBand, Call, CallBand, LotW};
|
||||
Q_ENUM (Highlight)
|
||||
static QString highlight_name (Highlight h);
|
||||
|
||||
struct HighlightInfo final
|
||||
{
|
||||
Highlight type_;
|
||||
bool enabled_;
|
||||
QBrush foreground_;
|
||||
QBrush background_;
|
||||
};
|
||||
using HighlightItems = QList<HighlightInfo>;
|
||||
|
||||
explicit DecodeHighlightingModel (QObject * parent = 0);
|
||||
~DecodeHighlightingModel();
|
||||
|
||||
// access to raw items nd default items
|
||||
static HighlightItems const& default_items ();
|
||||
HighlightItems const& items () const;
|
||||
void items (HighlightItems const&);
|
||||
|
||||
void set_font (QFont const&);
|
||||
|
||||
enum DefaultRoles {TypeRole = Qt::UserRole, EnabledDefaultRole, ForegroundDefaultRole, BackgroundDefaultRole};
|
||||
|
||||
private:
|
||||
// implement the QAbstractListModel interface
|
||||
int rowCount (QModelIndex const& parent = QModelIndex()) const override;
|
||||
QVariant data (QModelIndex const&, int role) const override;
|
||||
QVariant headerData (int section, Qt::Orientation, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags (QModelIndex const&) const override;
|
||||
bool setData (QModelIndex const& index, QVariant const& value, int role) override;
|
||||
Qt::DropActions supportedDropActions () const override;
|
||||
bool insertRows (int row, int count, QModelIndex const& parent = QModelIndex {}) override;
|
||||
bool removeRows (int row, int count, QModelIndex const& parent = QModelIndex {}) override;
|
||||
QMap<int, QVariant> itemData (QModelIndex const&) const override;
|
||||
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
bool operator == (DecodeHighlightingModel::HighlightInfo const&, DecodeHighlightingModel::HighlightInfo const&);
|
||||
|
||||
QDataStream& operator << (QDataStream&, DecodeHighlightingModel::HighlightInfo const&);
|
||||
QDataStream& operator >> (QDataStream&, DecodeHighlightingModel::HighlightInfo&);
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
QDebug operator << (QDebug, DecodeHighlightingModel::HighlightInfo const&);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_DECL (DecodeHighlightingModel, Highlight);
|
||||
ENUM_CONVERSION_OPS_DECL (DecodeHighlightingModel, Highlight);
|
||||
|
||||
Q_DECLARE_METATYPE (DecodeHighlightingModel::HighlightInfo);
|
||||
Q_DECLARE_METATYPE (DecodeHighlightingModel::HighlightItems);
|
||||
|
||||
#endif
|
65
ExchangeValidator.cpp
Normal file
65
ExchangeValidator.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include <QDebug>
|
||||
#include "ExchangeValidator.hpp"
|
||||
|
||||
ExchangeValidator::ExchangeValidator (QObject * parent)
|
||||
: QValidator {parent}
|
||||
{
|
||||
}
|
||||
|
||||
auto ExchangeValidator::validate (QString& input, int& length) const -> State
|
||||
{
|
||||
bool ok=false;
|
||||
QStringList w=input.split(" ");
|
||||
int nwords=w.size();
|
||||
length=input.size();
|
||||
input = input.toUpper ();
|
||||
|
||||
if(nwords==1 and length<=3) {
|
||||
//ARRL RTTY Roundup
|
||||
// ntype=4;
|
||||
// ok=exch_valid_(&ntype, const_cast<char *>(input.toLatin1().constData()),length);
|
||||
QStringList states;
|
||||
states << "AL" << "AK" << "AZ" << "AR" << "CA" << "CO"
|
||||
<< "CT" << "DE" << "FL" << "GA" << "HI" << "ID"
|
||||
<< "IL" << "IN" << "IA" << "KS" << "KY" << "LA"
|
||||
<< "ME" << "MD" << "MA" << "MI" << "MN" << "MS"
|
||||
<< "MO" << "MT" << "NE" << "NV" << "NH" << "NJ"
|
||||
<< "NM" << "NY" << "NC" << "ND" << "OH" << "OK"
|
||||
<< "OR" << "PA" << "RI" << "SC" << "SD" << "TN"
|
||||
<< "TX" << "UT" << "VT" << "VA" << "WA" << "WV"
|
||||
<< "WI" << "WY" << "NB" << "NS" << "QC" << "ON"
|
||||
<< "MB" << "SK" << "AB" << "BC" << "NWT" << "NF"
|
||||
<< "LB" << "NU" << "YT" << "PEI" << "DC" << "DX";
|
||||
if(states.contains(input)) ok=true;
|
||||
|
||||
}
|
||||
if(nwords==2 and w.at(1).size()<=3) {
|
||||
//ARRL Field Day
|
||||
int n=w.at(0).size();
|
||||
if(n>3) goto done;
|
||||
int ntx=w.at(0).left(n-1).toInt();
|
||||
if(ntx<1 or ntx>32) goto done;
|
||||
QString c1=w.at(0).right(1);
|
||||
if(c1<"A" or c1>"F") goto done;
|
||||
QStringList sections;
|
||||
sections << "AB" << "AK" << "AL" << "AR" << "AZ" << "BC"
|
||||
<< "CO" << "CT" << "DE" << "EB" << "EMA" << "ENY"
|
||||
<< "EPA" << "EWA" << "GA" << "GTA" << "IA" << "ID"
|
||||
<< "IL" << "IN" << "KS" << "KY" << "LA" << "LAX"
|
||||
<< "MAR" << "MB" << "MDC" << "ME" << "MI" << "MN"
|
||||
<< "MO" << "MS" << "MT" << "NC" << "ND" << "NE"
|
||||
<< "NFL" << "NH" << "NL" << "NLI" << "NM" << "NNJ"
|
||||
<< "NNY" << "NT" << "NTX" << "NV" << "OH" << "OK"
|
||||
<< "ONE" << "ONN" << "ONS" << "OR" << "ORG" << "PAC"
|
||||
<< "PR" << "QC" << "RI" << "SB" << "SC" << "SCV"
|
||||
<< "SD" << "SDG" << "SF" << "SFL" << "SJV" << "SK"
|
||||
<< "SNJ" << "STX" << "SV" << "TN" << "UT" << "VA"
|
||||
<< "VI" << "VT" << "WCF" << "WI" << "WMA" << "WNY"
|
||||
<< "WPA" << "WTX" << "WV" << "WWA" << "WY" << "DX";
|
||||
if(sections.contains(w.at(1))) ok=true;
|
||||
}
|
||||
|
||||
done:
|
||||
if(ok) return Acceptable;
|
||||
return Intermediate;
|
||||
}
|
19
ExchangeValidator.hpp
Normal file
19
ExchangeValidator.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef EXCHANGE_VALIDATOR_HPP__
|
||||
#define EXCHANGE_VALIDATOR_HPP__
|
||||
|
||||
#include <QValidator>
|
||||
|
||||
// ExchangeValidator - QValidator for Field Day and RTTY Roundup exchanges
|
||||
|
||||
class ExchangeValidator final
|
||||
: public QValidator
|
||||
{
|
||||
public:
|
||||
ExchangeValidator (QObject * parent = nullptr);
|
||||
|
||||
// QValidator implementation
|
||||
State validate (QString& input, int& length) const override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
126
ExportCabrillo.cpp
Normal file
126
ExportCabrillo.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "ExportCabrillo.h"
|
||||
#include "SettingsGroup.hpp"
|
||||
#include "MessageBox.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "ui_ExportCabrillo.h"
|
||||
#include "moc_ExportCabrillo.cpp"
|
||||
|
||||
ExportCabrillo::ExportCabrillo(QSettings *settings, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
settings_ {settings},
|
||||
ui(new Ui::ExportCabrillo)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
read_settings();
|
||||
setWindowTitle(QApplication::applicationName() + " - Export Cabrillo");
|
||||
}
|
||||
|
||||
ExportCabrillo::~ExportCabrillo()
|
||||
{
|
||||
if(isVisible()) write_settings();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ExportCabrillo::closeEvent (QCloseEvent * e)
|
||||
{
|
||||
write_settings();
|
||||
QWidget::closeEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void ExportCabrillo::read_settings ()
|
||||
{
|
||||
SettingsGroup group {settings_, "ExportCabrillo"};
|
||||
restoreGeometry (settings_->value("window/geometry").toByteArray());
|
||||
ui->lineEdit_1->setText(settings_->value("Location").toString());
|
||||
ui->lineEdit_2->setText(settings_->value("Contest").toString());
|
||||
ui->lineEdit_3->setText(settings_->value("Callsign").toString());
|
||||
ui->lineEdit_4->setText(settings_->value("Category-Operator").toString());
|
||||
ui->lineEdit_5->setText(settings_->value("Category-Transmitter").toString());
|
||||
ui->lineEdit_6->setText(settings_->value("Category-Power").toString());
|
||||
ui->lineEdit_7->setText(settings_->value("Category-Assisted").toString());
|
||||
ui->lineEdit_8->setText(settings_->value("Category-Band").toString());
|
||||
ui->lineEdit_9->setText(settings_->value("Claimed-Score").toString());
|
||||
ui->lineEdit_10->setText(settings_->value("Operators").toString());
|
||||
ui->lineEdit_11->setText(settings_->value("Club").toString());
|
||||
ui->lineEdit_12->setText(settings_->value("Name").toString());
|
||||
ui->lineEdit_13->setText(settings_->value("Address1").toString());
|
||||
ui->lineEdit_14->setText(settings_->value("Address2").toString());
|
||||
}
|
||||
|
||||
void ExportCabrillo::write_settings ()
|
||||
{
|
||||
SettingsGroup group {settings_, "ExportCabrillo"};
|
||||
settings_->setValue ("window/geometry", saveGeometry ());
|
||||
settings_->setValue("Location",ui->lineEdit_1->text());
|
||||
settings_->setValue("Contest",ui->lineEdit_2->text());
|
||||
settings_->setValue("Callsign",ui->lineEdit_3->text());
|
||||
settings_->setValue("Category-Operator",ui->lineEdit_4->text());
|
||||
settings_->setValue("Category-Transmitter",ui->lineEdit_5->text());
|
||||
settings_->setValue("Category-Power",ui->lineEdit_6->text());
|
||||
settings_->setValue("Category-Assisted",ui->lineEdit_7->text());
|
||||
settings_->setValue("Category-Band",ui->lineEdit_8->text());
|
||||
settings_->setValue("Claimed-Score",ui->lineEdit_9->text());
|
||||
settings_->setValue("Operators",ui->lineEdit_10->text());
|
||||
settings_->setValue("Club",ui->lineEdit_11->text());
|
||||
settings_->setValue("Name",ui->lineEdit_12->text());
|
||||
settings_->setValue("Address1",ui->lineEdit_13->text());
|
||||
settings_->setValue("Address2",ui->lineEdit_14->text());
|
||||
}
|
||||
|
||||
void ExportCabrillo::setFile(QString t)
|
||||
{
|
||||
m_CabLog=t;
|
||||
}
|
||||
|
||||
|
||||
void ExportCabrillo::on_pbSaveAs_clicked()
|
||||
{
|
||||
QString fname;
|
||||
QFileDialog saveAs(this);
|
||||
saveAs.setFileMode(QFileDialog::AnyFile);
|
||||
fname=saveAs.getSaveFileName(this, "Save File", "","Cabrillo Log (*.log)");
|
||||
QFile f {fname};
|
||||
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream out(&f);
|
||||
out << "START-OF-LOG:3.0" << endl
|
||||
<< "LOCATION: " << ui->lineEdit_1->text() << endl
|
||||
<< "CONTEST: " << ui->lineEdit_2->text() << endl
|
||||
<< "CALLSIGN: " << ui->lineEdit_3->text() << endl
|
||||
<< "CATEGORY-OPERATOR: " << ui->lineEdit_4->text() << endl
|
||||
<< "CATEGORY-TRANSMITTER: " << ui->lineEdit_5->text() << endl
|
||||
<< "CATEGORY-POWER: " << ui->lineEdit_6->text() << endl
|
||||
<< "CATEGORY-ASSISTED: " << ui->lineEdit_7->text() << endl
|
||||
<< "CATEGORY-BAND: " << ui->lineEdit_8->text() << endl
|
||||
<< "CLAIMED-SCORE: " << ui->lineEdit_9->text() << endl
|
||||
<< "OPERATORS: " << ui->lineEdit_10->text() << endl
|
||||
<< "CLUB: " << ui->lineEdit_11->text() << endl
|
||||
<< "NAME: " << ui->lineEdit_12->text() << endl
|
||||
<< "ADDRESS: " << ui->lineEdit_13->text() << endl
|
||||
<< "ADDRESS: " << ui->lineEdit_14->text() << endl;
|
||||
|
||||
QFile f2(m_CabLog);
|
||||
if(f2.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream s(&f2);
|
||||
QString t=s.readAll();
|
||||
out << t << "END-OF-LOG:" << endl;
|
||||
f2.close();
|
||||
}
|
||||
f.close();
|
||||
} else {
|
||||
auto const& message = tr ("Cannot open \"%1\" for writing: %2")
|
||||
.arg (f.fileName ()).arg (f.errorString ());
|
||||
MessageBox::warning_message (this, tr ("Export Cabrillo File Error"), message);
|
||||
}
|
||||
write_settings();
|
||||
}
|
||||
|
||||
void ExportCabrillo::accept()
|
||||
{
|
||||
write_settings();
|
||||
QDialog::accept();
|
||||
}
|
37
ExportCabrillo.h
Normal file
37
ExportCabrillo.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef EXPORTCABRILLO_H
|
||||
#define EXPORTCABRILLO_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QSettings>
|
||||
|
||||
namespace Ui {
|
||||
class ExportCabrillo;
|
||||
}
|
||||
|
||||
class ExportCabrillo : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExportCabrillo(QSettings *settings, QWidget *parent = 0);
|
||||
void setFile(QString t);
|
||||
~ExportCabrillo();
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
|
||||
protected:
|
||||
void closeEvent (QCloseEvent *) override;
|
||||
|
||||
private slots:
|
||||
void on_pbSaveAs_clicked();
|
||||
|
||||
private:
|
||||
QSettings * settings_;
|
||||
QString m_CabLog;
|
||||
void read_settings();
|
||||
void write_settings();
|
||||
Ui::ExportCabrillo *ui;
|
||||
};
|
||||
|
||||
#endif // EXPORTCABRILLO_H
|
304
ExportCabrillo.ui
Normal file
304
ExportCabrillo.ui
Normal file
@ -0,0 +1,304 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExportCabrillo</class>
|
||||
<widget class="QDialog" name="ExportCabrillo">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>330</width>
|
||||
<height>407</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_1">
|
||||
<property name="text">
|
||||
<string>SNJ</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Contest:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_2">
|
||||
<property name="text">
|
||||
<string>ARRL-RTTY</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Callsign:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_3">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Category-Operator: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_4">
|
||||
<property name="text">
|
||||
<string>SINGLE-OP</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Category-Transmitter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_5">
|
||||
<property name="text">
|
||||
<string>ONE</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Category-Power:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_6">
|
||||
<property name="text">
|
||||
<string>LOW</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Category-Assisted:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_7">
|
||||
<property name="text">
|
||||
<string>NON-ASSISTED</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Category-Band:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_8">
|
||||
<property name="text">
|
||||
<string>ALL</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Claimed-Score:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_9">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Operators:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_10">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Club:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_11">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_12">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_13">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_14">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pbSaveAs">
|
||||
<property name="text">
|
||||
<string>Save As</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ExportCabrillo</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ExportCabrillo</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -261,12 +261,7 @@ HamlibTransceiver::HamlibTransceiver (int model_number, TransceiverFactory::Para
|
||||
//
|
||||
// user defined Hamlib settings
|
||||
//
|
||||
auto settings_file_name = QStandardPaths::locate (
|
||||
#if QT_VERSION >= 0x050500
|
||||
QStandardPaths::AppConfigLocation
|
||||
#else
|
||||
QStandardPaths::ConfigLocation
|
||||
#endif
|
||||
auto settings_file_name = QStandardPaths::locate (QStandardPaths::AppConfigLocation
|
||||
, "hamlib_settings.json");
|
||||
if (!settings_file_name.isEmpty ())
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ protected:
|
||||
void stepBy (int steps) override;
|
||||
|
||||
private:
|
||||
std::vector<int> values_;
|
||||
values_type values_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -92,9 +92,5 @@ QVariant IARURegions::headerData (int section, Qt::Orientation orientation, int
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_IMPL (IARURegions, Region);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (IARURegions, Region);
|
||||
ENUM_CONVERSION_OPS_IMPL (IARURegions, Region);
|
||||
|
@ -29,8 +29,6 @@ class IARURegions final
|
||||
: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS (Region)
|
||||
|
||||
public:
|
||||
//
|
||||
// This enumeration contains the supported regions, to complement
|
||||
@ -62,19 +60,6 @@ public:
|
||||
QVariant headerData (int section, Qt::Orientation, int = Qt::DisplayRole) const override;
|
||||
};
|
||||
|
||||
// Qt boilerplate to make the IARURegions::region enumeration a type
|
||||
// that can be streamed and queued as a signal argument as well as
|
||||
// showing the human readable string when output to debug streams.
|
||||
#if QT_VERSION < 0x050500
|
||||
// Qt 5.5 introduces the Q_ENUM macro which automatically registers
|
||||
// the meta-type
|
||||
Q_DECLARE_METATYPE (IARURegions::Region);
|
||||
#endif
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_DECL (IARURegions, Region);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_DECL (IARURegions, Region);
|
||||
ENUM_CONVERSION_OPS_DECL (IARURegions, Region);
|
||||
|
||||
|
280
LotWUsers.cpp
Normal file
280
LotWUsers.cpp
Normal file
@ -0,0 +1,280 @@
|
||||
#include "LotWUsers.hpp"
|
||||
|
||||
#include <future>
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QDate>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QPointer>
|
||||
#include <QSaveFile>
|
||||
#include <QUrl>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QDebug>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_LotWUsers.cpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Dictionary mapping call sign to date of last upload to LotW
|
||||
using dictionary = QHash<QString, QDate>;
|
||||
}
|
||||
|
||||
class LotWUsers::impl final
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
impl (LotWUsers * self, QNetworkAccessManager * network_manager)
|
||||
: self_ {self}
|
||||
, network_manager_ {network_manager}
|
||||
, url_valid_ {false}
|
||||
, redirect_count_ {0}
|
||||
, age_constraint_ {365}
|
||||
{
|
||||
}
|
||||
|
||||
void load (QString const& url, bool forced_fetch)
|
||||
{
|
||||
auto csv_file_name = csv_file_.fileName ();
|
||||
abort (); // abort any active download
|
||||
if (!QFileInfo::exists (csv_file_name) || forced_fetch)
|
||||
{
|
||||
current_url_.setUrl (url);
|
||||
redirect_count_ = 0;
|
||||
download (current_url_);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load the database asynchronously
|
||||
future_load_ = std::async (std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
void download (QUrl url)
|
||||
{
|
||||
if (QNetworkAccessManager::Accessible != network_manager_->networkAccessible ())
|
||||
{
|
||||
// try and recover network access for QNAM
|
||||
network_manager_->setNetworkAccessible (QNetworkAccessManager::Accessible);
|
||||
}
|
||||
|
||||
if (url.isValid () && !QSslSocket::supportsSsl ())
|
||||
{
|
||||
url.setScheme ("http");
|
||||
}
|
||||
QNetworkRequest request {url};
|
||||
request.setRawHeader ("User-Agent", "WSJT LotW User Downloader");
|
||||
request.setOriginatingObject (this);
|
||||
|
||||
// this blocks for a second or two the first time it is used on
|
||||
// Windows - annoying
|
||||
if (!url_valid_)
|
||||
{
|
||||
reply_ = network_manager_->head (request);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_ = network_manager_->get (request);
|
||||
}
|
||||
|
||||
connect (reply_.data (), &QNetworkReply::finished, this, &LotWUsers::impl::reply_finished);
|
||||
connect (reply_.data (), &QNetworkReply::readyRead, this, &LotWUsers::impl::store);
|
||||
}
|
||||
|
||||
void reply_finished ()
|
||||
{
|
||||
if (!reply_)
|
||||
{
|
||||
Q_EMIT self_->load_finished ();
|
||||
return; // we probably deleted it in an earlier call
|
||||
}
|
||||
QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()};
|
||||
if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ())
|
||||
{
|
||||
if (++redirect_count_ < 10) // maintain sanity
|
||||
{
|
||||
// follow redirect
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("Network Error - Too many redirects:\n\'%1\'")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
}
|
||||
else if (reply_->error () != QNetworkReply::NoError)
|
||||
{
|
||||
csv_file_.cancelWriting ();
|
||||
csv_file_.commit ();
|
||||
url_valid_ = false; // reset
|
||||
// report errors that are not due to abort
|
||||
if (QNetworkReply::OperationCanceledError != reply_->error ())
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("Network Error:\n%1")
|
||||
.arg (reply_->errorString ()));
|
||||
}
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (url_valid_ && !csv_file_.commit ())
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot commit changes to:\n\"%1\"")
|
||||
.arg (csv_file_.fileName ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!url_valid_)
|
||||
{
|
||||
// now get the body content
|
||||
url_valid_ = true;
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
url_valid_ = false; // reset
|
||||
// load the database asynchronously
|
||||
future_load_ = std::async (std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_.fileName ());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reply_ && reply_->isFinished ())
|
||||
{
|
||||
reply_->deleteLater ();
|
||||
}
|
||||
}
|
||||
|
||||
void store ()
|
||||
{
|
||||
if (url_valid_)
|
||||
{
|
||||
if (!csv_file_.isOpen ())
|
||||
{
|
||||
// create temporary file in the final location
|
||||
if (!csv_file_.open (QSaveFile::WriteOnly))
|
||||
{
|
||||
abort ();
|
||||
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot open file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (csv_file_.fileName ())
|
||||
.arg (csv_file_.error ())
|
||||
.arg (csv_file_.errorString ()));
|
||||
}
|
||||
}
|
||||
if (csv_file_.write (reply_->read (reply_->bytesAvailable ())) < 0)
|
||||
{
|
||||
abort ();
|
||||
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot write to file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (csv_file_.fileName ())
|
||||
.arg (csv_file_.error ())
|
||||
.arg (csv_file_.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void abort ()
|
||||
{
|
||||
if (reply_ && reply_->isRunning ())
|
||||
{
|
||||
reply_->abort ();
|
||||
}
|
||||
}
|
||||
|
||||
// Load the database from the given file name
|
||||
//
|
||||
// Expects the file to be in CSV format with no header with one
|
||||
// record per line. Record fields are call sign followed by upload
|
||||
// date in yyyy-MM-dd format followed by upload time (ignored)
|
||||
dictionary load_dictionary (QString const& lotw_csv_file)
|
||||
{
|
||||
dictionary result;
|
||||
QFile f {lotw_csv_file};
|
||||
if (f.open (QFile::ReadOnly | QFile::Text))
|
||||
{
|
||||
QTextStream s {&f};
|
||||
for (auto l = s.readLine (); !l.isNull (); l = s.readLine ())
|
||||
{
|
||||
auto pos = l.indexOf (',');
|
||||
result[l.left (pos)] = QDate::fromString (l.mid (pos + 1, l.indexOf (',', pos + 1) - pos - 1), "yyyy-MM-dd");
|
||||
}
|
||||
// qDebug () << "LotW User Data Loaded";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error {QObject::tr ("Failed to open LotW users CSV file: '%1'").arg (f.fileName ()).toStdString ()};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LotWUsers * self_;
|
||||
QNetworkAccessManager * network_manager_;
|
||||
QSaveFile csv_file_;
|
||||
bool url_valid_;
|
||||
QUrl current_url_; // may be a redirect
|
||||
int redirect_count_;
|
||||
QPointer<QNetworkReply> reply_;
|
||||
std::future<dictionary> future_load_;
|
||||
dictionary last_uploaded_;
|
||||
qint64 age_constraint_; // days
|
||||
};
|
||||
|
||||
#include "LotWUsers.moc"
|
||||
|
||||
LotWUsers::LotWUsers (QNetworkAccessManager * network_manager, QObject * parent)
|
||||
: QObject {parent}
|
||||
, m_ {this, network_manager}
|
||||
{
|
||||
}
|
||||
|
||||
LotWUsers::~LotWUsers ()
|
||||
{
|
||||
}
|
||||
|
||||
void LotWUsers::set_local_file_path (QString const& path)
|
||||
{
|
||||
m_->csv_file_.setFileName (path);
|
||||
}
|
||||
|
||||
void LotWUsers::load (QString const& url, bool force_download)
|
||||
{
|
||||
m_->load (url, force_download);
|
||||
}
|
||||
|
||||
void LotWUsers::set_age_constraint (qint64 uploaded_since_days)
|
||||
{
|
||||
m_->age_constraint_ = uploaded_since_days;
|
||||
}
|
||||
|
||||
bool LotWUsers::user (QString const& call) const
|
||||
{
|
||||
if (m_->future_load_.valid ())
|
||||
{
|
||||
try
|
||||
{
|
||||
// wait for the load to finish if necessary
|
||||
const_cast<dictionary&> (m_->last_uploaded_) = const_cast<std::future<dictionary>&> (m_->future_load_).get ();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
Q_EMIT LotW_users_error (e.what ());
|
||||
}
|
||||
Q_EMIT load_finished ();
|
||||
}
|
||||
auto p = m_->last_uploaded_.constFind (call);
|
||||
if (p != m_->last_uploaded_.end ())
|
||||
{
|
||||
return p.value ().daysTo (QDate::currentDate ()) <= m_->age_constraint_;
|
||||
}
|
||||
return false;
|
||||
}
|
41
LotWUsers.hpp
Normal file
41
LotWUsers.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef LOTW_USERS_HPP_
|
||||
#define LOTW_USERS_HPP_
|
||||
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <QObject>
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
class QString;
|
||||
class QDate;
|
||||
class QNetworkAccessManager;
|
||||
|
||||
//
|
||||
// LotWUsers - Lookup Logbook of the World users
|
||||
//
|
||||
class LotWUsers final
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LotWUsers (QNetworkAccessManager *, QObject * parent = 0);
|
||||
~LotWUsers ();
|
||||
|
||||
void set_local_file_path (QString const&);
|
||||
|
||||
Q_SLOT void load (QString const& url, bool force_download = false);
|
||||
Q_SLOT void set_age_constraint (qint64 uploaded_since_days);
|
||||
|
||||
// returns true if the specified call sign 'call' has uploaded their
|
||||
// log to LotW in the last 'age_constraint_days' days
|
||||
bool user (QString const& call) const;
|
||||
|
||||
Q_SIGNAL void LotW_users_error (QString const& reason) const;
|
||||
Q_SIGNAL void load_finished () const;
|
||||
|
||||
private:
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
#endif
|
@ -334,7 +334,7 @@ MessageClient::MessageClient (QString const& id, QString const& version, QString
|
||||
connect (&*m_, static_cast<void (impl::*) (impl::SocketError)> (&impl::error)
|
||||
, [this] (impl::SocketError e)
|
||||
{
|
||||
#if defined (Q_OS_WIN) && QT_VERSION >= 0x050500
|
||||
#if defined (Q_OS_WIN)
|
||||
if (e != impl::NetworkError // take this out when Qt 5.5
|
||||
// stops doing this
|
||||
// spuriously
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "TransceiverFactory.hpp"
|
||||
#include "WFPalette.hpp"
|
||||
#include "IARURegions.hpp"
|
||||
|
||||
#include "DecodeHighlightingModel.hpp"
|
||||
#include "FrequencyLineEdit.hpp"
|
||||
|
||||
QItemEditorFactory * item_editor_factory ()
|
||||
@ -47,10 +47,6 @@ void register_types ()
|
||||
qRegisterMetaType<AudioDevice::Channel> ("AudioDevice::Channel");
|
||||
|
||||
// Configuration
|
||||
#if QT_VERSION < 0x050500
|
||||
qRegisterMetaType<Configuration::DataMode> ("Configuration::DataMode");
|
||||
qRegisterMetaType<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen");
|
||||
#endif
|
||||
qRegisterMetaTypeStreamOperators<Configuration::DataMode> ("Configuration::DataMode");
|
||||
qRegisterMetaTypeStreamOperators<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen");
|
||||
|
||||
@ -62,17 +58,8 @@ void register_types ()
|
||||
|
||||
// Transceiver
|
||||
qRegisterMetaType<Transceiver::TransceiverState> ("Transceiver::TransceiverState");
|
||||
qRegisterMetaType<Transceiver::MODE> ("Transceiver::MODE");
|
||||
|
||||
// Transceiver factory
|
||||
#if QT_VERSION < 0x050500
|
||||
qRegisterMetaType<TransceiverFactory::DataBits> ("TransceiverFactory::DataBits");
|
||||
qRegisterMetaType<TransceiverFactory::StopBits> ("TransceiverFactory::StopBits");
|
||||
qRegisterMetaType<TransceiverFactory::Handshake> ("TransceiverFactory::Handshake");
|
||||
qRegisterMetaType<TransceiverFactory::PTTMethod> ("TransceiverFactory::PTTMethod");
|
||||
qRegisterMetaType<TransceiverFactory::TXAudioSource> ("TransceiverFactory::TXAudioSource");
|
||||
qRegisterMetaType<TransceiverFactory::SplitMode> ("TransceiverFactory::SplitMode");
|
||||
#endif
|
||||
qRegisterMetaTypeStreamOperators<TransceiverFactory::DataBits> ("TransceiverFactory::DataBits");
|
||||
qRegisterMetaTypeStreamOperators<TransceiverFactory::StopBits> ("TransceiverFactory::StopBits");
|
||||
qRegisterMetaTypeStreamOperators<TransceiverFactory::Handshake> ("TransceiverFactory::Handshake");
|
||||
@ -84,8 +71,9 @@ void register_types ()
|
||||
qRegisterMetaTypeStreamOperators<WFPalette::Colours> ("Colours");
|
||||
|
||||
// IARURegions
|
||||
#if QT_VERSION < 0x050500
|
||||
qRegisterMetaType<IARURegions::Region> ("IARURegions::Region");
|
||||
#endif
|
||||
qRegisterMetaTypeStreamOperators<IARURegions::Region> ("IARURegions::Region");
|
||||
|
||||
// DecodeHighlightingModel
|
||||
qRegisterMetaTypeStreamOperators<DecodeHighlightingModel::HighlightInfo> ("HighlightInfo");
|
||||
qRegisterMetaTypeStreamOperators<DecodeHighlightingModel::HighlightItems> ("HighlightItems");
|
||||
}
|
||||
|
@ -98,9 +98,5 @@ QVariant Modes::headerData (int section, Qt::Orientation orientation, int role)
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_IMPL (Modes, Mode);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (Modes, Mode);
|
||||
ENUM_CONVERSION_OPS_IMPL (Modes, Mode);
|
||||
|
14
Modes.hpp
14
Modes.hpp
@ -29,7 +29,6 @@ class Modes final
|
||||
: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS (Mode)
|
||||
|
||||
public:
|
||||
//
|
||||
@ -69,19 +68,6 @@ public:
|
||||
QVariant headerData (int section, Qt::Orientation, int = Qt::DisplayRole) const override;
|
||||
};
|
||||
|
||||
// Qt boilerplate to make the Modes::Mode enumeration a type that can
|
||||
// be streamed and queued as a signal argument as well as showing the
|
||||
// human readable string when output to debug streams.
|
||||
#if QT_VERSION < 0x050500
|
||||
// Qt 5.5 introduces the Q_ENUM macro which automatically registers
|
||||
// the meta-type
|
||||
Q_DECLARE_METATYPE (Modes::Mode);
|
||||
#endif
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_DECL (Modes, Mode);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_DECL (Modes, Mode);
|
||||
ENUM_CONVERSION_OPS_DECL (Modes, Mode);
|
||||
|
||||
|
@ -1,2 +1,471 @@
|
||||
The content of this file has been moved to the NEWS file, please add
|
||||
release note updates to that file.
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Copyright 2001 - 2018 by Joe Taylor, K1JT.
|
||||
|
||||
Release: WSJT-X 2.0-rc3
|
||||
October 15, 2018
|
||||
-----------------------
|
||||
|
||||
Changes from WSJT-X Version 2.0.0-rc1 include the following:
|
||||
|
||||
- Improved SNR calculation for FT8
|
||||
- Test grid4 (not grid6) for matches in ADIF log
|
||||
- Auto-generate 77-bit messages for callsigns with /R or /P
|
||||
- Fix auto-sequencing for "CQ ABC ...", "CQ ABCD ...", etc.
|
||||
- Fix the "CQ RU RU ..." bug
|
||||
- Implement AP decoding for contest messages and for Hound
|
||||
- Check Field Day and RTTY Roundup exchanges for validity
|
||||
- Implement "Select next caller" and use of "TU; ..." messages
|
||||
- Option to "auto log" in contests
|
||||
- Real-time display of contest log
|
||||
- Contest exchanges sent to ADIF log and N1MM+
|
||||
- Function to export Cabrillo log
|
||||
- Convert DXpedition mode to always use 77-bit messages
|
||||
- Fix bug associated with opening "houndcallers.txt"
|
||||
- Remove end-of-line numbers from MSK144 decodes
|
||||
- Finish MSK144 encoding/decoding for Sh msgs and nonstandard calls
|
||||
- Halt Tx before resetting power after Tune
|
||||
- Auto update of LoTW info, and faster program startup
|
||||
|
||||
|
||||
Release: WSJT-X 2.0-rc2
|
||||
September 25, 2018
|
||||
-----------------------
|
||||
Changes from WSJT-X Version 2.0.0-rc1 include the following:
|
||||
|
||||
- Corrected a flaw that encoded a message's first callsign as
|
||||
hexadecimal telemetry data if the call consisted only of letters
|
||||
A-F and digits 0-9.
|
||||
|
||||
- Corrected program logic that failed to identify certain callsigns
|
||||
as "nonstandard".
|
||||
|
||||
- Fixed a bug that color-highlighted bare CQ messages (no grid
|
||||
locator) as "New DXCC".
|
||||
|
||||
- Fixed a bug that failed to log Report Sent if MyCall is a
|
||||
nonstandard call.
|
||||
|
||||
- Fixed a bug that generated incorrect MSK144 tones for certain
|
||||
messages and caused a "memory" effect on stations receiving the
|
||||
incorrect tones.
|
||||
|
||||
- Fixed several bugs that could cause certain Tx messages to crash
|
||||
the program.
|
||||
|
||||
- Suppressed the display of certain illogical false decodes.
|
||||
|
||||
|
||||
Release: WSJT-X 2.0-rc1
|
||||
September 17, 2018
|
||||
-----------------------
|
||||
|
||||
This is the first candidate release on WSJT-X 2.0, intended for
|
||||
beta-level testing. For details see:
|
||||
|
||||
http://physics.princeton.edu/pulsar/k1jt/New_Features_WSJT-X_2.0.txt
|
||||
http://physics.princeton.edu/pulsar/k1jt/Quick_Start_WSJT-X_2.0.pdf
|
||||
http://physics.princeton.edu/pulsar/k1jt/77bit.txt
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.1
|
||||
May 31, 2018
|
||||
-----------------------------
|
||||
|
||||
This release is a critical bug fix release that removes an unintended
|
||||
restriction of FT8 DXpedition mode.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0
|
||||
May 28, 2018
|
||||
-----------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.9.0-rc4 include the following:
|
||||
- Display in the right text window of MSK144 messages addressed to
|
||||
"MyCall" has been restored.
|
||||
|
||||
- Fox is not allowed to transmit in any of the default FT8 sub-bands.
|
||||
|
||||
- Fox can now work Hounds using compound callsigns.
|
||||
|
||||
- Fox can now transmit free-text messages (and any standard FT8 message)
|
||||
by using Tab 1 or Tab 2.
|
||||
|
||||
- Added a checkbox to enable more frequent programmed CQs by Fox.
|
||||
Default is OFF.
|
||||
|
||||
- Alt+N keyboard shortcut has been restored.
|
||||
|
||||
- MacOS program crash on unexpected decode request has been fixed.
|
||||
|
||||
- Several minor bug fixes and added convenience features.
|
||||
|
||||
- Hamlib, support for TRXManger added.
|
||||
|
||||
- Hamlib, improved support for flrig.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc4
|
||||
April 30, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.9.0-rc3 include the following:
|
||||
|
||||
- Corrected a number of flaws in Fox and Hound behavior, FT8
|
||||
DXpedition Mode
|
||||
|
||||
- Decoded CQ calls where a prefix has been used as a suffix should
|
||||
have the DXCC entity name assigned correctly in almost all cases
|
||||
|
||||
- Improved AFC capability for the wider JT65 sub-modes to help with
|
||||
drifting signals
|
||||
|
||||
- Better support for macOS using hi-DPI Retina displays
|
||||
|
||||
- New UDP message that allows external applications to highlight
|
||||
decoded callsigns
|
||||
|
||||
- Main-screen geometry and state of the "splitter" setting between its
|
||||
two text windows is now properly restored after program restart.
|
||||
|
||||
- New simulator jt49sim[.exe] replaces jt4sim and jt9sim
|
||||
|
||||
- Correct S/N measurements for the JT9 slow/wide submodes
|
||||
|
||||
- Other minor bug fixes
|
||||
|
||||
- Updated copy of cty.dat
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc3
|
||||
March 18, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.9.0-rc2 include the following:
|
||||
|
||||
- Corrected a number of flaws in Fox behavior, FT8 DXpedition Mode
|
||||
|
||||
- Allow Hounds to use compound callsigns
|
||||
|
||||
- Write debugging information to FoxQSO.txt.
|
||||
|
||||
- Fix the "Blue Decode Button" bug
|
||||
|
||||
- Allow partial processing of incoming UDP Reply messages so that
|
||||
non-CQ/QRZ decodes can be processed. The processing is the same as
|
||||
double-clicking the same decoded message within WSJT-X except that
|
||||
"Enable Tx" will not be enabled.
|
||||
|
||||
- Send DX grid locator to wsjt_status.txt, for use by applications like
|
||||
PstRotatorAZ
|
||||
|
||||
- Correct the display of DXCC status of KG4 calls
|
||||
|
||||
- Updated copy of cty.dat
|
||||
|
||||
- Updates to documentation
|
||||
|
||||
- Other minor bug fixes
|
||||
|
||||
- This release contains updated Hamlib functionality including changes
|
||||
to the Yaesu FT-817 back end that allows the uBITx kit transceiver
|
||||
to be CAT controlled by WSJT-X.
|
||||
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc2
|
||||
February 26, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.8.0 include the following:
|
||||
|
||||
- New FT8 DXpedition Mode to facilitate high QSO rates in pileup
|
||||
situations
|
||||
|
||||
- Decoding improvements for JT65 mode, including a priori (AP)
|
||||
decoding when VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Optional Auto-Sequencing in JT4, JT9, and JT65 when
|
||||
VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Better suppression of low-confidence false decodes generated by AP
|
||||
decoding in FT8 mode
|
||||
|
||||
- Improved decoding performance for WSPR mode, especially effective at
|
||||
LF and MF
|
||||
|
||||
- Minor adjustments to auto-sequencing behavior
|
||||
|
||||
- More flexible Doppler control features for EME
|
||||
|
||||
- Improved waterfall sensitivity for very weak signals
|
||||
|
||||
- Automatic real-time forwarding of logged information to N1MM Logger+
|
||||
|
||||
- Expanded and improved UDP messages sent to companion programs
|
||||
|
||||
- Bug fixes and other minor tweaks to user interface
|
||||
|
||||
A primary purpose of this beta release is to allow field testing of
|
||||
FT8 DXpedition Mode. Instructions for this mode are posted here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf
|
||||
|
||||
Contacts in FT8 DXpedition Mode must use WSJT-X v1.9.0 at both ends of
|
||||
the QSO. Please report any anomalous behavior to email list
|
||||
wsjt-devel@lists.sourceforge.net. You must be a subscriber in order
|
||||
to post there.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0
|
||||
October 27, 2017
|
||||
-----------------------------
|
||||
|
||||
This is the full General Availability release of WSJT-X Version 1.8.0.
|
||||
|
||||
Changes from WSJT-X Version 1.8.0-rc3 are very minor:
|
||||
|
||||
- Right-click on the Wide Graph now pops up a Context Menu. Select
|
||||
the item *Set Rx & Tx Offset* to complete a one-handed setting of
|
||||
both red and green frequency markers.
|
||||
|
||||
- Several clarifications and additions to Tool Tips and the User Guide.
|
||||
|
||||
|
||||
We recommend that all users should upgrade to WSJT-X Version 1.8.0.
|
||||
|
||||
If you upgrade from v1.8.0-rc1 it may be necessary to do a one-time
|
||||
reset of the default list of suggested operating frequencies. Go to
|
||||
*File->Settings->Frequencies*, right click on the table and select
|
||||
*Reset*.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0-rc3
|
||||
October 16, 2017
|
||||
---------------------------------
|
||||
|
||||
Most (but not all) changes since Version 1.8.0-rc2 involve user
|
||||
control of the increasingly popular FT8 mode. The "RC3" release also
|
||||
includes minor bug fixes and updates to the WSJT-X User Guide.
|
||||
|
||||
The following list includes all of the more important changes:
|
||||
|
||||
- New optimization of GUI for simplex and split behavior in FT8 mode.
|
||||
|
||||
1. Checkbox "Lock Tx Freq" on main window is relabeled "Hold Tx Freq".
|
||||
|
||||
2. Double-clicking on decoded messages that do not contain your own
|
||||
call moves both Rx and Tx frequencies. If the first callsign is
|
||||
your own call, only Rx freq moves.
|
||||
|
||||
3. Double-clicking on decoded messages moves the Rx frequency. If
|
||||
"Hold Tx Freq" is checked, Tx frequency is moved only if CTRL was
|
||||
held down.
|
||||
|
||||
4. Clicking on the waterfall moves Rx and Tx frequencies as
|
||||
before: Rx only on a simple click, Tx only on SHIFT-click, and
|
||||
both on CTRL-click. This happens even if "Hold Tx Freq" is
|
||||
checked.
|
||||
|
||||
- Add a semi-automated "FreqCal" procedure: see *Solve for calibration
|
||||
parameters* on the Tools menu.
|
||||
|
||||
- Improv auto-sequencing behavior: stop and on-frequency
|
||||
transmission if a called station comes back to someone else.
|
||||
|
||||
- Improve S/N estimation in some situations involving QRM.
|
||||
|
||||
- Fix an initialization issue with user-modified application fonts.
|
||||
|
||||
- Fix an issue with Tx5 message generation with Type 2 compound calls.
|
||||
|
||||
- Enhance and improve the ADIF parser of logbook records. Update
|
||||
the band limits as per ADIF 3.0.6 specification.
|
||||
|
||||
- Increase the FT8 DT range to +/- 2.5 s.
|
||||
|
||||
- Do not allow window manager events to close the astronomical data
|
||||
window.
|
||||
|
||||
- Add an "Erase" item to the context (right-click) menu for decoded
|
||||
text.
|
||||
|
||||
- Extend UDP messages with an "off air" boolean field indicating that
|
||||
the decode was derived from a .WAV file playback rather than an on air
|
||||
reception.
|
||||
|
||||
- Extend reference applications to use the new off air decode message
|
||||
field.
|
||||
|
||||
- Improve performance of FT8 decoder, especially for overlapping
|
||||
signals.
|
||||
|
||||
- Allow specialized use of "x2 Tone Spacing" in FT8 and slow JT9
|
||||
modes.
|
||||
|
||||
- Move "NA VHF Contest Mode" checkbox to main screen. Query the
|
||||
operator if d > 10000 km.
|
||||
|
||||
- Adjust UI to improve portability with font size changes and between
|
||||
platforms.
|
||||
|
||||
- Extend UDP Reply message to support keyboard modifiers. This allows
|
||||
UDP servers to emulate keyboard modified double-clicks on decoded
|
||||
messages, e.g. ALT+double-click for replying to a CQ or QRZ call
|
||||
without changing ones Tx frequency offset.
|
||||
|
||||
- Update the cty.dat file (21st Sept 2017).
|
||||
|
||||
- Ensure that Fast Graph is properly initialized.
|
||||
|
||||
- Better handling of worked before and country name display. Appended
|
||||
text is added at a fixed column unless the message overlaps in which
|
||||
case the appended information floats to the right.
|
||||
|
||||
- Restore printing of MSK144 decode quality information.
|
||||
|
||||
- Display Echo Graph automatically when Echo mode is started.
|
||||
|
||||
- Fix a bug that prevented double-click on a JT65 EME-style "OOO"
|
||||
message from populating the Tx message boxes.
|
||||
|
||||
- Fixed behavior with double-click on 'CQ <AA-ZZ> <call> <grid>.'
|
||||
|
||||
- Update the "blank line" divider with band ID at 4*TRperiod/5.
|
||||
|
||||
- Fix cty.dat lookups that were not honouring exact match flags
|
||||
|
||||
- Add some further Copyright protections.
|
||||
|
||||
- Fix a bug involving "firstcall contains mycall" but not equal to mycall.
|
||||
|
||||
- Fix an issue with editing IARU regions in the working frequencies table.
|
||||
|
||||
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0-rc2
|
||||
September 2, 2017
|
||||
---------------------------------
|
||||
|
||||
Implementation of FT8 and its auto-sequencing feature is now more
|
||||
capable and more polished. The decoder is faster and better: it now
|
||||
includes signal subtraction, multi-pass decoding, and the use of
|
||||
accumulated "a priori" information as a QSO progresses. Sensitivity
|
||||
extends downward as far as -24 dB in some circumstances. Overlapping
|
||||
signals 2 and 3 deep are frequently decoded at essentially the same
|
||||
frequency. On a crowded band we sometimes see more than 30 decodes in
|
||||
a single 15-second interval, over a 2 kHz window. The North American
|
||||
VHF Contesting Mode has been extended to include both FT8 and MSK144
|
||||
modes.
|
||||
|
||||
The "RC2" release also includes many minor bug fixes and an
|
||||
extensively updated WSJT-X User Guide.
|
||||
|
||||
Depending on what code revision you upgrade from, it may be necessary
|
||||
to do a one-time reset of the default list of suggested operating
|
||||
frequencies. Go to *File->Settings->Frequencies*, right click on
|
||||
the table and select *Reset*.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0
|
||||
-----------------------------
|
||||
|
||||
NEW FEATURES IN WSJT-X Version 1.8.0
|
||||
------------------------------------
|
||||
|
||||
1. New mode called FT8: sensitivity down to -20 dB on the AWGN
|
||||
channel; QSOs 4 times faster than JT65 or JT9; auto-sequencing
|
||||
includes an option to respond automatically to first decoded
|
||||
reply to your CQ.
|
||||
|
||||
2. New mode for accurate Frequency Calibration of your radio.
|
||||
|
||||
3. Improved performance of decoders for JT65, QRA64, and MSK144.
|
||||
MSK144 includes facilities for amplitide and phase equalization
|
||||
and an "SWL" mode for short-format messages.
|
||||
|
||||
4. Options to minimize screen space used by Main and Wide Graph
|
||||
windows.
|
||||
|
||||
5. Enhanced management scheme for table of operating frequencies, and
|
||||
a new set of default frequencies specific to the three IARU
|
||||
Regions.
|
||||
|
||||
6. Improved CAT control for many rigs, including those controlled
|
||||
through Commander or OmniRig.
|
||||
|
||||
7. New keyboard shortcuts to set "Tx even/1st" ON or OFF.
|
||||
|
||||
8. A number of (mostly minor) bug fixes and tweaks to the user
|
||||
interface. For example: new behavior for the audio level slider;
|
||||
correctly logged QSO start times in certain situations; correct
|
||||
control of FT-891/991 and some other radios via rigctld.
|
||||
|
||||
At the time of the v1.8.0-rc1 release the following tasks are yet to
|
||||
be completed:
|
||||
|
||||
1. Updates to WSJT-X User Guide.
|
||||
2. Sample files for FT8.
|
||||
3. Enhanced decoding using AP ("a priori") information.
|
||||
4. Signal subtraction and multi-pass decoding.
|
||||
5. Option to Auto-respond to the weakest responder to your CQ.
|
||||
|
||||
|
||||
Installation packages for Windows, Linux, OS X, and Raspbian can be
|
||||
downloaded from the WSJT web site:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
Please send bug reports to either wsjtgroup@yahoogroups.com or
|
||||
wsjt-devel@lists.sourceforge.net. Such reports should include a full
|
||||
prescription of steps to reproduce the undesired behavior. You must
|
||||
be a subscriber to post to either of these lists.
|
||||
|
||||
|
||||
Brief Description of the FT8 Protocol
|
||||
-------------------------------------
|
||||
|
||||
WSJT-X Version 1.8.0 includes a new mode called FT8, developed by K9AN
|
||||
and K1JT. The mode name "FT8" stands for "Franke and Taylor, 8-FSK
|
||||
modulation". FT8 uses 15-second T/R sequences and provides 50% or
|
||||
better decoding probability down to -20 dB on an AWGN channel. An
|
||||
auto-sequencing facility includes an option to respond automatically
|
||||
to the first decoded reply to your CQ. FT8 QSOs are 4 times faster
|
||||
than those made with JT65 or JT9. FT8 is an excellent mode for HF
|
||||
DXing and for situations like multi-hop E_s on 6 meters, where deep
|
||||
QSB may make fast and reliable completion of QSOs desirable.
|
||||
|
||||
Some important characteristics of FT8:
|
||||
|
||||
- T/R sequence length: 15 s
|
||||
- Message length: 75 bits + 12-bit CRC
|
||||
- FEC code: LDPC(174,87)
|
||||
- Modulation: 8-FSK, tone spacing 6.25 Hz
|
||||
- Constant-envelope waveform
|
||||
- Occupied bandwidth: 50 Hz
|
||||
- Synchronization: 7x7 Costas arrays at start, middle, and end
|
||||
- Transmission duration: 79*1920/12000 = 12.64 s
|
||||
- Decoding threshold: -20 dB; several dB lower with AP decoding
|
||||
- Multi-decoder finds and decodes all FT8 signals in passband
|
||||
- Optional auto-sequencing and auto-reply to a CQ response
|
||||
- Operational behavior similar to JT9, JT65
|
||||
|
||||
We plan to implement signal subtraction, two-pass decoding, and use of
|
||||
a priori (AP) information in the decoder. These features are not yet
|
||||
activated in v1.8.0.
|
||||
|
||||
We haven't yet finalized what the three extra bits in the message
|
||||
payload will be used for. Suggestions are welcome!
|
||||
|
||||
-- Joe, K1JT, for the WSJT Development Team
|
||||
|
||||
|
@ -34,12 +34,15 @@ void RemoteFile::local_file_path (QString const& name)
|
||||
QFile file {local_file_.absoluteFilePath ()};
|
||||
if (!file.rename (new_file.absoluteFilePath ()))
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot rename file:\n\"%1\"\nto: \"%2\"\nError(%3): %4")
|
||||
.arg (file.fileName ())
|
||||
.arg (new_file.absoluteFilePath ())
|
||||
.arg (file.error ())
|
||||
.arg (file.errorString ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot rename file:\n\"%1\"\nto: \"%2\"\nError(%3): %4")
|
||||
.arg (file.fileName ())
|
||||
.arg (new_file.absoluteFilePath ())
|
||||
.arg (file.error ())
|
||||
.arg (file.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
std::swap (local_file_, new_file);
|
||||
@ -49,15 +52,18 @@ void RemoteFile::local_file_path (QString const& name)
|
||||
bool RemoteFile::local () const
|
||||
{
|
||||
auto is_local = (reply_ && !reply_->isFinished ()) || local_file_.exists ();
|
||||
if (is_local)
|
||||
if (listener_)
|
||||
{
|
||||
auto size = local_file_.size ();
|
||||
listener_->download_progress (size, size);
|
||||
listener_->download_finished (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_progress (-1, 0);
|
||||
if (is_local)
|
||||
{
|
||||
auto size = local_file_.size ();
|
||||
listener_->download_progress (size, size);
|
||||
listener_->download_finished (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_progress (-1, 0);
|
||||
}
|
||||
}
|
||||
return is_local;
|
||||
}
|
||||
@ -92,13 +98,19 @@ bool RemoteFile::sync (QUrl const& url, bool local, bool force)
|
||||
auto path = local_file_.absoluteDir ();
|
||||
if (path.remove (local_file_.fileName ()))
|
||||
{
|
||||
listener_->download_progress (-1, 0);
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_progress (-1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot delete file:\n\"%1\"")
|
||||
.arg (local_file_.absoluteFilePath ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot delete file:\n\"%1\"")
|
||||
.arg (local_file_.absoluteFilePath ()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
path.rmpath (".");
|
||||
@ -137,10 +149,13 @@ void RemoteFile::download (QUrl url)
|
||||
connect (reply_.data (), &QNetworkReply::readyRead, this, &RemoteFile::store);
|
||||
connect (reply_.data (), &QNetworkReply::downloadProgress
|
||||
, [this] (qint64 bytes_received, qint64 total_bytes) {
|
||||
// report progress of wanted file
|
||||
if (is_valid_)
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_progress (bytes_received, total_bytes);
|
||||
// report progress of wanted file
|
||||
if (is_valid_)
|
||||
{
|
||||
listener_->download_progress (bytes_received, total_bytes);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -160,7 +175,7 @@ void RemoteFile::reply_finished ()
|
||||
QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()};
|
||||
if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ())
|
||||
{
|
||||
if (listener_->redirect_request (redirect_url))
|
||||
if (!listener_ || listener_->redirect_request (redirect_url))
|
||||
{
|
||||
if (++redirect_count_ < 10) // maintain sanity
|
||||
{
|
||||
@ -169,19 +184,25 @@ void RemoteFile::reply_finished ()
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
listener_->error (tr ("Network Error")
|
||||
, tr ("Too many redirects: %1")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
listener_->error (tr ("Network Error")
|
||||
, tr ("Too many redirects: %1")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
}
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
listener_->error (tr ("Network Error")
|
||||
, tr ("Redirect not followed: %1")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
listener_->error (tr ("Network Error")
|
||||
, tr ("Redirect not followed: %1")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
}
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
}
|
||||
@ -189,10 +210,13 @@ void RemoteFile::reply_finished ()
|
||||
{
|
||||
file_.cancelWriting ();
|
||||
file_.commit ();
|
||||
listener_->download_finished (false);
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
}
|
||||
is_valid_ = false; // reset
|
||||
// report errors that are not due to abort
|
||||
if (QNetworkReply::OperationCanceledError != reply_->error ())
|
||||
if (listener_ && QNetworkReply::OperationCanceledError != reply_->error ())
|
||||
{
|
||||
listener_->error (tr ("Network Error"), reply_->errorString ());
|
||||
}
|
||||
@ -202,11 +226,17 @@ void RemoteFile::reply_finished ()
|
||||
auto path = QFileInfo {file_.fileName ()}.absoluteDir ();
|
||||
if (is_valid_ && !file_.commit ())
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot commit changes to:\n\"%1\"")
|
||||
.arg (file_.fileName ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot commit changes to:\n\"%1\"")
|
||||
.arg (file_.fileName ()));
|
||||
}
|
||||
path.rmpath ("."); // tidy empty directories
|
||||
listener_->download_finished (false);
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
}
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
else
|
||||
@ -219,7 +249,10 @@ void RemoteFile::reply_finished ()
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_finished (true);
|
||||
if (listener_)
|
||||
{
|
||||
listener_->download_finished (true);
|
||||
}
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
}
|
||||
@ -243,29 +276,38 @@ void RemoteFile::store ()
|
||||
if (!file_.open (QSaveFile::WriteOnly))
|
||||
{
|
||||
abort ();
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot open file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (path.path ())
|
||||
.arg (file_.error ())
|
||||
.arg (file_.errorString ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot open file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (path.path ())
|
||||
.arg (file_.error ())
|
||||
.arg (file_.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
abort ();
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot make path:\n\"%1\"")
|
||||
.arg (path.path ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot make path:\n\"%1\"")
|
||||
.arg (path.path ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (file_.write (reply_->read (reply_->bytesAvailable ())) < 0)
|
||||
{
|
||||
abort ();
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot write to file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (file_.fileName ())
|
||||
.arg (file_.error ())
|
||||
.arg (file_.errorString ()));
|
||||
if (listener_)
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot write to file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (file_.fileName ())
|
||||
.arg (file_.error ())
|
||||
.arg (file_.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,18 +6,9 @@
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QMessageLogContext>
|
||||
#include <QDateTime>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
QMutex lock;
|
||||
}
|
||||
|
||||
class TraceFile::impl
|
||||
{
|
||||
public:
|
||||
@ -81,35 +72,8 @@ TraceFile::impl::~impl ()
|
||||
// write Qt messages to the diagnostic log file
|
||||
void TraceFile::impl::message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
|
||||
{
|
||||
char const * severity;
|
||||
switch (type)
|
||||
{
|
||||
case QtDebugMsg:
|
||||
severity = "Debug";
|
||||
break;
|
||||
|
||||
case QtWarningMsg:
|
||||
severity = "Warning";
|
||||
break;
|
||||
|
||||
case QtFatalMsg:
|
||||
severity = "Fatal";
|
||||
break;
|
||||
|
||||
default:
|
||||
severity = "Critical";
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
// guard against multiple threads with overlapping messages
|
||||
QMutexLocker guard (&lock);
|
||||
Q_ASSERT_X (current_stream_, "TraceFile:message_handler", "no stream to write to");
|
||||
*current_stream_
|
||||
<< QDateTime::currentDateTimeUtc ().toString ("yyyy-MM-ddTHH:mm:ss.zzzZ")
|
||||
<< '(' << context.file << ':' << context.line /* << ", " << context.function */ << ')'
|
||||
<< severity << ": " << msg.trimmed () << endl;
|
||||
}
|
||||
Q_ASSERT_X (current_stream_, "TraceFile:message_handler", "no stream to write to");
|
||||
*current_stream_ << qFormatLogMessage (type, context, msg) << endl;
|
||||
|
||||
if (QtFatalMsg == type)
|
||||
{
|
||||
|
@ -3,9 +3,6 @@
|
||||
#include "moc_Transceiver.cpp"
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
|
||||
ENUM_QDEBUG_OPS_IMPL (Transceiver, MODE);
|
||||
|
||||
QDebug operator << (QDebug d, Transceiver::TransceiverState const& s)
|
||||
{
|
||||
d.nospace ()
|
||||
@ -16,7 +13,6 @@ QDebug operator << (QDebug d, Transceiver::TransceiverState const& s)
|
||||
<< ')';
|
||||
return d.space ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (Transceiver, MODE);
|
||||
|
@ -52,7 +52,6 @@ class Transceiver
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS (MODE)
|
||||
|
||||
public:
|
||||
using Frequency = Radio::Frequency;
|
||||
@ -154,13 +153,8 @@ public:
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE (Transceiver::TransceiverState);
|
||||
#if QT_VERSION < 0x050500
|
||||
Q_DECLARE_METATYPE (Transceiver::MODE);
|
||||
#endif
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_DECL (Transceiver, MODE);
|
||||
|
||||
QDebug operator << (QDebug, Transceiver::TransceiverState const&);
|
||||
#endif
|
||||
|
||||
|
@ -197,15 +197,6 @@ std::unique_ptr<Transceiver> TransceiverFactory::create (ParameterPack const& pa
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, DataBits);
|
||||
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, StopBits);
|
||||
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, Handshake);
|
||||
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, PTTMethod);
|
||||
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, TXAudioSource);
|
||||
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, SplitMode);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, DataBits);
|
||||
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, StopBits);
|
||||
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, Handshake);
|
||||
|
@ -21,7 +21,6 @@ class TransceiverFactory
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS (DataBits StopBits Handshake PTTMethod TXAudioSource SplitMode)
|
||||
|
||||
public:
|
||||
//
|
||||
@ -161,28 +160,6 @@ bool operator != (TransceiverFactory::ParameterPack const& lhs, TransceiverFacto
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//
|
||||
// boilerplate routines to make enum types useable and debuggable in
|
||||
// Qt
|
||||
//
|
||||
#if QT_VERSION < 0x050500
|
||||
Q_DECLARE_METATYPE (TransceiverFactory::DataBits);
|
||||
Q_DECLARE_METATYPE (TransceiverFactory::StopBits);
|
||||
Q_DECLARE_METATYPE (TransceiverFactory::Handshake);
|
||||
Q_DECLARE_METATYPE (TransceiverFactory::PTTMethod);
|
||||
Q_DECLARE_METATYPE (TransceiverFactory::TXAudioSource);
|
||||
Q_DECLARE_METATYPE (TransceiverFactory::SplitMode);
|
||||
#endif
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, DataBits);
|
||||
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, StopBits);
|
||||
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, Handshake);
|
||||
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, PTTMethod);
|
||||
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, TXAudioSource);
|
||||
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, SplitMode);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, DataBits);
|
||||
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, StopBits);
|
||||
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, Handshake);
|
||||
|
@ -2,5 +2,5 @@
|
||||
set (WSJTX_VERSION_MAJOR 2)
|
||||
set (WSJTX_VERSION_MINOR 0)
|
||||
set (WSJTX_VERSION_PATCH 0)
|
||||
set (WSJTX_RC 2) # release candidate number, comment out or zero for development versions
|
||||
set (WSJTX_RC 3) # release candidate number, comment out or zero for development versions
|
||||
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
|
||||
|
@ -1,23 +1,28 @@
|
||||
#include "colorhighlighting.h"
|
||||
#include "ui_colorhighlighting.h"
|
||||
#include "SettingsGroup.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
ColorHighlighting::ColorHighlighting(QSettings *settings, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
settings_ {settings},
|
||||
ui(new Ui::ColorHighlighting)
|
||||
#include "SettingsGroup.hpp"
|
||||
#include "DecodeHighlightingModel.hpp"
|
||||
|
||||
#include "ui_colorhighlighting.h"
|
||||
#include "moc_colorhighlighting.cpp"
|
||||
|
||||
ColorHighlighting::ColorHighlighting (QSettings * settings, DecodeHighlightingModel const& highlight_model, QWidget * parent)
|
||||
: QDialog {parent}
|
||||
, ui {new Ui::ColorHighlighting}
|
||||
, settings_ {settings}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle (QApplication::applicationName () + " - Colors");
|
||||
read_settings ();
|
||||
set_items (highlight_model);
|
||||
}
|
||||
|
||||
ColorHighlighting::~ColorHighlighting()
|
||||
{
|
||||
if (isVisible ()) write_settings ();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ColorHighlighting::read_settings ()
|
||||
@ -32,21 +37,68 @@ void ColorHighlighting::write_settings ()
|
||||
settings_->setValue ("window/geometry", saveGeometry ());
|
||||
}
|
||||
|
||||
|
||||
void ColorHighlighting::colorHighlightlingSetup(QColor color_CQ,QColor color_MyCall,
|
||||
QColor color_DXCC,QColor color_DXCCband,QColor color_NewCall,
|
||||
QColor color_NewCallBand,QColor color_NewGrid,QColor color_NewGridBand,
|
||||
QColor color_TxMsg,QColor color_LoTW)
|
||||
void ColorHighlighting::set_items (DecodeHighlightingModel const& highlighting_model)
|
||||
{
|
||||
setWindowTitle(QApplication::applicationName() + " - Colors");
|
||||
ui->label->setStyleSheet(QString("background: %1").arg(color_CQ.name()));
|
||||
ui->label_3->setStyleSheet(QString("background: %1").arg(color_MyCall.name()));
|
||||
ui->label_5->setStyleSheet(QString("background: %1").arg(color_TxMsg.name()));
|
||||
ui->label_7->setStyleSheet(QString("background: %1").arg(color_DXCC.name()));
|
||||
ui->label_9->setStyleSheet(QString("background: %1").arg(color_DXCCband.name()));
|
||||
ui->label_11->setStyleSheet(QString("background: %1").arg(color_NewCall.name()));
|
||||
ui->label_13->setStyleSheet(QString("background: %1").arg(color_NewCallBand.name()));
|
||||
ui->label_15->setStyleSheet(QString("background: %1").arg(color_NewGrid.name()));
|
||||
ui->label_17->setStyleSheet(QString("background: %1").arg(color_NewGridBand.name()));
|
||||
ui->label_19->setStyleSheet(QString("color: %1").arg(color_LoTW.name()));
|
||||
int index {0};
|
||||
for (auto const& item : highlighting_model.items ())
|
||||
{
|
||||
QLabel * example;
|
||||
QLabel * label;
|
||||
switch (index++)
|
||||
{
|
||||
case 0:
|
||||
example = ui->example1_label;
|
||||
label = ui->p1_label;
|
||||
break;
|
||||
case 1:
|
||||
example = ui->example2_label;
|
||||
label = ui->p2_label;
|
||||
break;
|
||||
case 2:
|
||||
example = ui->example3_label;
|
||||
label = ui->p3_label;
|
||||
break;
|
||||
case 3:
|
||||
example = ui->example4_label;
|
||||
label = ui->p4_label;
|
||||
break;
|
||||
case 4:
|
||||
example = ui->example5_label;
|
||||
label = ui->p5_label;
|
||||
break;
|
||||
case 5:
|
||||
example = ui->example6_label;
|
||||
label = ui->p6_label;
|
||||
break;
|
||||
case 6:
|
||||
example = ui->example7_label;
|
||||
label = ui->p7_label;
|
||||
break;
|
||||
case 7:
|
||||
example = ui->example8_label;
|
||||
label = ui->p8_label;
|
||||
break;
|
||||
case 8:
|
||||
example = ui->example9_label;
|
||||
label = ui->p9_label;
|
||||
break;
|
||||
case 9:
|
||||
example = ui->example10_label;
|
||||
label = ui->p10_label;
|
||||
break;
|
||||
}
|
||||
auto palette = example->parentWidget ()->palette ();
|
||||
if (Qt::NoBrush != item.background_.style ())
|
||||
{
|
||||
palette.setColor (QPalette::Window, item.background_.color ());
|
||||
}
|
||||
if (Qt::NoBrush != item.foreground_.style ())
|
||||
{
|
||||
palette.setColor (QPalette::WindowText, item.foreground_.color ());
|
||||
}
|
||||
example->setPalette (palette);
|
||||
example->setEnabled (item.enabled_);
|
||||
label->setText (DecodeHighlightingModel::highlight_name (item.type_));
|
||||
label->setEnabled (item.enabled_);
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,33 @@
|
||||
#ifndef COLORHIGHLIGHTING_H
|
||||
#define COLORHIGHLIGHTING_H
|
||||
#ifndef COLORHIGHLIGHTING_H_
|
||||
#define COLORHIGHLIGHTING_H_
|
||||
|
||||
#include <QDialog>
|
||||
#include <QSettings>
|
||||
#include <QScopedPointer>
|
||||
|
||||
class QSettings;
|
||||
class DecodeHighlightingModel;
|
||||
|
||||
namespace Ui {
|
||||
class ColorHighlighting;
|
||||
class ColorHighlighting;
|
||||
}
|
||||
|
||||
class ColorHighlighting : public QDialog
|
||||
class ColorHighlighting final
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit ColorHighlighting(QSettings *, QWidget *parent = 0);
|
||||
~ColorHighlighting();
|
||||
void colorHighlightlingSetup(QColor color_CQ, QColor color_MyCall,
|
||||
QColor color_DXCC, QColor color_DXCCband, QColor color_NewCall,
|
||||
QColor color_NewCallBand, QColor color_NewGrid, QColor color_NewGridBand,
|
||||
QColor color_TxMsg, QColor color_LoTW);
|
||||
public:
|
||||
explicit ColorHighlighting(QSettings *, DecodeHighlightingModel const&, QWidget * parent = nullptr);
|
||||
~ColorHighlighting ();
|
||||
|
||||
private:
|
||||
QSettings * settings_;
|
||||
Q_SLOT void set_items (DecodeHighlightingModel const&);
|
||||
|
||||
private:
|
||||
void read_settings ();
|
||||
void write_settings ();
|
||||
Ui::ColorHighlighting *ui;
|
||||
|
||||
QScopedPointer<Ui::ColorHighlighting> ui;
|
||||
QSettings * settings_;
|
||||
};
|
||||
|
||||
#endif // COLORHIGHLIGHTING_H
|
||||
#endif
|
||||
|
@ -10,183 +10,206 @@
|
||||
<height>253</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Transmitted message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>New Call on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>New Call</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>New Grid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>New Grid on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>CQ in message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>My Call in message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>New DXCC on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>New DXCC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
<string>Not in LoTW</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="example1_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="p1_label">
|
||||
<property name="text">
|
||||
<string>CQ in message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="example2_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="p2_label">
|
||||
<property name="text">
|
||||
<string>My Call in message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="example3_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="p3_label">
|
||||
<property name="text">
|
||||
<string>Transmitted message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="example4_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="p4_label">
|
||||
<property name="text">
|
||||
<string>New DXCC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="example5_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="p5_label">
|
||||
<property name="text">
|
||||
<string>New DXCC on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="example6_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="p6_label">
|
||||
<property name="text">
|
||||
<string>New Grid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="example7_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="p7_label">
|
||||
<property name="text">
|
||||
<string>New Grid on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="example8_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="p8_label">
|
||||
<property name="text">
|
||||
<string>New Call</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="example9_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="p9_label">
|
||||
<property name="text">
|
||||
<string>New Call on Band</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="example10_label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1ABC</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="p10_label">
|
||||
<property name="text">
|
||||
<string>Uploads to LotW</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,7 +64,7 @@ QStringList DecodedText::messageWords () const
|
||||
|
||||
QString DecodedText::CQersCall() const
|
||||
{
|
||||
QRegularExpression callsign_re {R"(^(CQ|DE|QRZ)(\s?DX|\s([A-Z]{2}|\d{3}))?\s(?<callsign>[A-Z0-9/]{2,})(\s[A-R]{2}[0-9]{2})?)"};
|
||||
QRegularExpression callsign_re {R"(^(CQ|DE|QRZ)(\s?DX|\s([A-Z]{2,4}|\d{3}))?\s(?<callsign>[A-Z0-9/]{2,})(\s[A-R]{2}[0-9]{2})?)"};
|
||||
return callsign_re.match (message_).captured ("callsign");
|
||||
}
|
||||
|
||||
|
@ -12,11 +12,11 @@ JT65 111010000000111000010000000000001
|
||||
JT65/VHF 111110010000111110101100010000000
|
||||
QRA64 111110010110111110000000001000000
|
||||
ISCAT 100111000000000110000000000000000
|
||||
MSK144 101111110100000000010001000010000
|
||||
MSK144 101111110100000000010001000000000
|
||||
WSPR 000000000000000001010000000000000
|
||||
Echo 000000000000000000000010000000000
|
||||
FCal 001101000000000000000000000001000
|
||||
FT8 111010000100111000010000100100001
|
||||
FT8 111010000100111000010000100110001
|
||||
FT8/VHF 111010000100111000010000100110001
|
||||
FT8/Fox 111010000100111000010000000000100
|
||||
FT8/Hound 111010000100111000010000000000110
|
||||
@ -55,7 +55,7 @@ Mapping of column numbers to widgets
|
||||
25. AP JT65
|
||||
26. AP DX Call
|
||||
27. cbFirst
|
||||
28. cbVHFcontest
|
||||
28. labNextCall
|
||||
29. measure_check_box
|
||||
30. labDXped
|
||||
31. cbRxAll
|
||||
|
128
displaytext.cpp
128
displaytext.cpp
@ -1,5 +1,4 @@
|
||||
#include "displaytext.h"
|
||||
#include "mainwindow.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QDateTime>
|
||||
#include <QTextCharFormat>
|
||||
@ -8,12 +7,16 @@
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "LotWUsers.hpp"
|
||||
#include "DecodeHighlightingModel.hpp"
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
#include "moc_displaytext.cpp"
|
||||
|
||||
DisplayText::DisplayText(QWidget *parent)
|
||||
: QTextEdit(parent)
|
||||
, m_config {nullptr}
|
||||
, erase_action_ {new QAction {tr ("&Erase"), this}}
|
||||
{
|
||||
setReadOnly (true);
|
||||
@ -73,13 +76,53 @@ void DisplayText::insertLineSpacer(QString const& line)
|
||||
appendText (line, "#d3d3d3");
|
||||
}
|
||||
|
||||
void DisplayText::appendText(QString const& text, QColor bg,
|
||||
QString const& call1, QString const& call2)
|
||||
namespace
|
||||
{
|
||||
void set_colours (Configuration const * config, QColor * bg, QColor * fg, DecodeHighlightingModel::Highlight type)
|
||||
{
|
||||
if (config)
|
||||
{
|
||||
for (auto const& item : config->decode_highlighting ().items ())
|
||||
{
|
||||
if (type == item.type_ && item.enabled_)
|
||||
{
|
||||
if (item.background_.style () != Qt::NoBrush)
|
||||
{
|
||||
*bg = item.background_.color ();
|
||||
}
|
||||
if (item.foreground_.style () != Qt::NoBrush)
|
||||
{
|
||||
*fg = item.foreground_.color ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayText::appendText(QString const& text, QColor bg, QColor fg
|
||||
, QString const& call1, QString const& call2)
|
||||
{
|
||||
auto cursor = textCursor ();
|
||||
cursor.movePosition (QTextCursor::End);
|
||||
auto block_format = cursor.blockFormat ();
|
||||
block_format.setBackground (bg);
|
||||
if (bg.isValid ())
|
||||
{
|
||||
block_format.setBackground (bg);
|
||||
}
|
||||
else
|
||||
{
|
||||
block_format.clearBackground ();
|
||||
}
|
||||
if (fg.isValid ())
|
||||
{
|
||||
block_format.setForeground (fg);
|
||||
}
|
||||
else
|
||||
{
|
||||
block_format.clearForeground ();
|
||||
}
|
||||
if (0 == cursor.position ())
|
||||
{
|
||||
cursor.setBlockFormat (block_format);
|
||||
@ -90,10 +133,13 @@ void DisplayText::appendText(QString const& text, QColor bg,
|
||||
else
|
||||
{
|
||||
cursor.insertBlock (block_format);
|
||||
auto char_format = cursor.charFormat ();
|
||||
char_format.clearBackground ();
|
||||
char_format.clearForeground ();
|
||||
cursor.setCharFormat (char_format);
|
||||
}
|
||||
|
||||
QTextCharFormat format = cursor.charFormat();
|
||||
format.clearBackground();
|
||||
int text_index {0};
|
||||
if (call1.size ())
|
||||
{
|
||||
@ -126,7 +172,7 @@ void DisplayText::appendText(QString const& text, QColor bg,
|
||||
if (pos != highlighted_calls_.end ())
|
||||
{
|
||||
format.setBackground (bg);
|
||||
format.clearForeground ();
|
||||
format.setForeground (fg);
|
||||
cursor.insertText(text.mid (text_index, call_index - text_index), format);
|
||||
if (pos.value ().second.isValid ())
|
||||
{
|
||||
@ -141,11 +187,14 @@ void DisplayText::appendText(QString const& text, QColor bg,
|
||||
}
|
||||
}
|
||||
}
|
||||
format.setBackground (bg);
|
||||
format.clearForeground ();
|
||||
if(call2.size()>0 and !m_LoTW.contains(call2)) {
|
||||
format.setForeground(m_color_LoTW); //Mark LoTW non-users
|
||||
}
|
||||
if (call2.size () && m_config && m_config->lotw_users ().user (call2))
|
||||
{
|
||||
QColor bg;
|
||||
QColor fg;
|
||||
set_colours (m_config, &bg, &fg, DecodeHighlightingModel::Highlight::LotW);
|
||||
if (bg.isValid ()) format.setBackground (bg);
|
||||
if (fg.isValid ()) format.setForeground (fg);
|
||||
}
|
||||
cursor.insertText(text.mid (text_index), format);
|
||||
|
||||
// position so viewport scrolled to left
|
||||
@ -156,7 +205,7 @@ void DisplayText::appendText(QString const& text, QColor bg,
|
||||
}
|
||||
|
||||
QString DisplayText::appendWorkedB4(QString message, QString const& callsign, QString grid,
|
||||
QColor * bg, LogBook const& logBook, QString currentBand)
|
||||
QColor * bg, QColor * fg, LogBook const& logBook, QString currentBand)
|
||||
{
|
||||
// allow for seconds
|
||||
int padding {message.indexOf (" ") > 4 ? 2 : 0};
|
||||
@ -191,29 +240,29 @@ QString DisplayText::appendWorkedB4(QString message, QString const& callsign, QS
|
||||
|
||||
if (!countryWorkedBefore) {
|
||||
// therefore not worked call either
|
||||
// appendage += "!";
|
||||
*bg = m_color_DXCC;
|
||||
// appendage += "!";
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::CQ);
|
||||
} else {
|
||||
if(!countryB4onBand) {
|
||||
*bg = m_color_DXCCband;
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::DXCCBand);
|
||||
} else {
|
||||
if(!gridB4) {
|
||||
*bg = m_color_NewGrid;
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::Grid);
|
||||
} else {
|
||||
if(!gridB4onBand) {
|
||||
*bg = m_color_NewGridBand;
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::GridBand);
|
||||
} else {
|
||||
if (!callWorkedBefore) {
|
||||
// but have worked the country
|
||||
// appendage += "~";
|
||||
*bg = m_color_NewCall;
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::Call);
|
||||
} else {
|
||||
if(!callB4onBand) {
|
||||
// appendage += "~";
|
||||
*bg = m_color_NewCallBand;
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::CallBand);
|
||||
} else {
|
||||
// appendage += " "; // have worked this call before
|
||||
*bg = m_color_CQ;
|
||||
set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::CQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -266,14 +315,15 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|
||||
QString currentBand, bool ppfx, bool bCQonly)
|
||||
{
|
||||
m_bPrincipalPrefix=ppfx;
|
||||
QColor bg {Qt::transparent};
|
||||
QColor bg;
|
||||
QColor fg;
|
||||
bool CQcall = false;
|
||||
if (decodedText.string ().contains (" CQ ")
|
||||
|| decodedText.string ().contains (" CQDX ")
|
||||
|| decodedText.string ().contains (" QRZ "))
|
||||
{
|
||||
CQcall = true;
|
||||
bg = m_color_CQ;
|
||||
set_colours (m_config, &bg, &fg, DecodeHighlightingModel::Highlight::CQ);
|
||||
}
|
||||
if(bCQonly and !CQcall) return;
|
||||
if (myCall != "" and (decodedText.indexOf (" " + myCall + " ") >= 0
|
||||
@ -284,7 +334,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|
||||
or decodedText.indexOf ("<" + myCall + " ") >= 0
|
||||
or decodedText.indexOf ("<" + myCall + ">") >= 0
|
||||
or decodedText.indexOf (" " + myCall + ">") >= 0)) {
|
||||
bg = m_color_MyCall;
|
||||
set_colours (m_config, &bg, &fg, DecodeHighlightingModel::Highlight::MyCall);
|
||||
}
|
||||
auto message = decodedText.string();
|
||||
QString dxCall;
|
||||
@ -296,8 +346,8 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|
||||
if (displayDXCCEntity && CQcall)
|
||||
// if enabled add the DXCC entity and B4 status to the end of the
|
||||
// preformated text line t1
|
||||
message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, logBook, currentBand);
|
||||
appendText (message.trimmed (), bg, decodedText.call (), dxCall);
|
||||
message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, &fg, logBook, currentBand);
|
||||
appendText (message.trimmed (), bg, fg, decodedText.call (), dxCall);
|
||||
}
|
||||
|
||||
|
||||
@ -321,7 +371,10 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
|
||||
" Tx " + t2 + t1 + text;
|
||||
}
|
||||
appendText (t, m_color_TxMsg);
|
||||
QColor bg;
|
||||
QColor fg;
|
||||
set_colours (m_config, &bg, &fg, DecodeHighlightingModel::Highlight::Tx);
|
||||
appendText (t, bg, fg);
|
||||
}
|
||||
|
||||
void DisplayText::displayQSY(QString text)
|
||||
@ -330,9 +383,9 @@ void DisplayText::displayQSY(QString text)
|
||||
appendText (t, "hotpink");
|
||||
}
|
||||
|
||||
void DisplayText::displayFoxToBeCalled(QString t, QColor bg)
|
||||
void DisplayText::displayFoxToBeCalled(QString t, QColor bg, QColor fg)
|
||||
{
|
||||
appendText(t,bg);
|
||||
appendText (t, bg, fg);
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -428,20 +481,3 @@ void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg,
|
||||
}
|
||||
setCurrentCharFormat (old_format);
|
||||
}
|
||||
|
||||
void DisplayText::setDecodedTextColors(QColor color_CQ, QColor color_MyCall,
|
||||
QColor color_DXCC, QColor color_DXCCband,QColor color_NewCall,QColor color_NewCallBand,
|
||||
QColor color_NewGrid, QColor color_NewGridBand,QColor color_TxMsg,QColor color_LoTW)
|
||||
{
|
||||
// Save the color highlighting scheme selected by the user.
|
||||
m_color_CQ=color_CQ;
|
||||
m_color_DXCC=color_DXCC;
|
||||
m_color_DXCCband=color_DXCCband;
|
||||
m_color_MyCall=color_MyCall;
|
||||
m_color_NewCall=color_NewCall;
|
||||
m_color_NewCallBand=color_NewCallBand;
|
||||
m_color_NewGrid=color_NewGrid;
|
||||
m_color_NewGridBand=color_NewGridBand;
|
||||
m_color_TxMsg=color_TxMsg;
|
||||
m_color_LoTW=color_LoTW;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "decodedtext.h"
|
||||
|
||||
class QAction;
|
||||
class Configuration;
|
||||
|
||||
class DisplayText
|
||||
: public QTextEdit
|
||||
@ -19,7 +20,7 @@ class DisplayText
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DisplayText(QWidget *parent = 0);
|
||||
|
||||
void set_configuration (Configuration const * configuration) {m_config = configuration;}
|
||||
void setContentFont (QFont const&);
|
||||
void insertLineSpacer(QString const&);
|
||||
void displayDecodedText(DecodedText const& decodedText, QString const& myCall,
|
||||
@ -27,16 +28,12 @@ public:
|
||||
QString currentBand="", bool ppfx=false, bool bCQonly=false);
|
||||
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode);
|
||||
void displayQSY(QString text);
|
||||
void displayFoxToBeCalled(QString t, QColor bg);
|
||||
void setDecodedTextColors(QColor color_CQ, QColor color_MyCall, QColor color_DXCC,
|
||||
QColor color_DXCCband, QColor color_NewCall, QColor color_NewCallBand,
|
||||
QColor color_NewGrid, QColor color_NewGridBand, QColor color_TxMsg,
|
||||
QColor color_LoTW);
|
||||
void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {});
|
||||
|
||||
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
|
||||
Q_SIGNAL void erased ();
|
||||
|
||||
Q_SLOT void appendText (QString const& text, QColor bg = Qt::white
|
||||
Q_SLOT void appendText (QString const& text, QColor bg = QColor {}, QColor fg = QColor {}
|
||||
, QString const& call1 = QString {}, QString const& call2 = QString {});
|
||||
Q_SLOT void erase ();
|
||||
Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only);
|
||||
@ -45,22 +42,14 @@ protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
Configuration const * m_config;
|
||||
bool m_bPrincipalPrefix;
|
||||
QString appendWorkedB4(QString message, QString const& callsign, QString grid, QColor * bg,
|
||||
LogBook const& logBook, QString currentBand);
|
||||
QString appendWorkedB4(QString message, QString const& callsign
|
||||
, QString grid, QColor * bg, QColor * fg
|
||||
, LogBook const& logBook, QString currentBand);
|
||||
QFont char_font_;
|
||||
QAction * erase_action_;
|
||||
QHash<QString, QPair<QColor, QColor>> highlighted_calls_;
|
||||
QColor m_color_CQ;
|
||||
QColor m_color_MyCall;
|
||||
QColor m_color_DXCC;
|
||||
QColor m_color_DXCCband;
|
||||
QColor m_color_NewCall;
|
||||
QColor m_color_NewCallBand;
|
||||
QColor m_color_NewGrid;
|
||||
QColor m_color_NewGridBand;
|
||||
QColor m_color_LoTW;
|
||||
QColor m_color_TxMsg;
|
||||
};
|
||||
|
||||
extern QHash<QString,int> m_LoTW;
|
||||
|
@ -37,12 +37,14 @@ information:
|
||||
|
||||
7. All features of FT8 DXpedition mode, as in WSJT-X v1.9.1
|
||||
|
||||
Enhancements to the FT8 decoder ensure that in most situations
|
||||
decoding sensitivity is slightly better than for the old protocol.
|
||||
Symbol rates and occupied bandwidths are the same as before, and
|
||||
false-decode rates are significantly lower. The decoding threshold
|
||||
for MSK144 is a fraction of a dB higher than before, owing to the
|
||||
slightly larger message payload and higher code rate.
|
||||
Conveying more information in the same bandwidth, using the same
|
||||
modulation scheme, necessarily means a higher code rate and less
|
||||
energy per information bit. Nevertheless, the decoding threshold S/N
|
||||
for the new FT8 is slightly lower than for the old version, because of
|
||||
improvements in the decoding algorithm. Decoding threshold for MSK144
|
||||
is a fraction of a dB higher than before. Symbol rates and occupied
|
||||
bandwidths for both modes are the same as before, and false-decode
|
||||
rates are significantly lower.
|
||||
|
||||
OTHER PROGRAM ENHANCEMENTS: WSJT-X 2.0 has several other new features
|
||||
and capabilities. The WSPR decoder has significantly better
|
||||
|
@ -1,6 +1,6 @@
|
||||
gfortran -c ../packjt.f90
|
||||
gfortran -c packjt77.f90
|
||||
gfortran -o encode77 -fbounds-check -Wall -Wno-conversion -Wno-real-q-constant \
|
||||
gfortran -o encode77 -fbounds-check -Wall -Wno-conversion \
|
||||
encode77.f90 ../deg2grid.f90 ../grid2deg.f90 ../fix_contest_msg.f90 \
|
||||
../to_contest_msg.f90 ../fmtmsg.f90 ../azdist.f90 ../geodist.f90 \
|
||||
packjt.o packjt77.o
|
||||
|
@ -17,10 +17,7 @@ subroutine hash10(n10,c13)
|
||||
do i=1,nzhash
|
||||
if(ihash10(i).eq.n10) then
|
||||
c13=callsign(i)
|
||||
if(c13(1:1).ne.'<') then
|
||||
n=len(trim(c13))
|
||||
c13='<'//trim(c13)//'>'//' '
|
||||
endif
|
||||
c13='<'//trim(c13)//'>'//' '
|
||||
go to 900
|
||||
endif
|
||||
enddo
|
||||
@ -36,10 +33,7 @@ subroutine hash12(n12,c13)
|
||||
do i=1,nzhash
|
||||
if(ihash12(i).eq.n12) then
|
||||
c13=callsign(i)
|
||||
if(c13(1:1).ne.'<') then
|
||||
n=len(trim(c13))
|
||||
c13='<'//trim(c13)//'>'//' '
|
||||
endif
|
||||
c13='<'//trim(c13)//'>'//' '
|
||||
go to 900
|
||||
endif
|
||||
enddo
|
||||
@ -56,10 +50,7 @@ subroutine hash22(n22,c13)
|
||||
do i=1,nzhash
|
||||
if(ihash22(i).eq.n22) then
|
||||
c13=callsign(i)
|
||||
if(c13(1:1).ne.'<') then
|
||||
n=len(trim(c13))
|
||||
c13='<'//trim(c13)//'>'//' '
|
||||
endif
|
||||
c13='<'//trim(c13)//'>'//' '
|
||||
go to 900
|
||||
endif
|
||||
enddo
|
||||
@ -71,17 +62,13 @@ end subroutine hash22
|
||||
integer function ihashcall(c0,m)
|
||||
|
||||
integer*8 n8
|
||||
character*13 c0,c1
|
||||
character*13 c0
|
||||
character*38 c
|
||||
data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/'/
|
||||
|
||||
c1=c0
|
||||
if(c1(1:1).eq.'<') c1=c1(2:)
|
||||
i=index(c1,'>')
|
||||
if(i.gt.0) c1(i:)=' '
|
||||
n8=0
|
||||
do i=1,11
|
||||
j=index(c,c1(i:i)) - 1
|
||||
j=index(c,c0(i:i)) - 1
|
||||
n8=38*n8 + j
|
||||
enddo
|
||||
ihashcall=ishft(47055833459_8*n8,m-64)
|
||||
@ -91,7 +78,7 @@ end function ihashcall
|
||||
|
||||
subroutine save_hash_call(c13,n10,n12,n22)
|
||||
|
||||
character*13 c13
|
||||
character*13 c13,cw
|
||||
logical first
|
||||
data first/.true./
|
||||
save first
|
||||
@ -104,12 +91,16 @@ subroutine save_hash_call(c13,n10,n12,n22)
|
||||
nzhash=0
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
if(c13(1:1).eq.' ' .or. c13(1:5).eq.'<...>') return
|
||||
|
||||
cw=c13
|
||||
if(cw(1:1).eq.' ' .or. cw(1:5).eq.'<...>') return
|
||||
if(cw(1:1).eq.'<') cw=cw(2:)
|
||||
i=index(cw,'>')
|
||||
if(i.gt.0) cw(i:)=' '
|
||||
|
||||
n10=ihashcall(c13,10)
|
||||
n12=ihashcall(c13,12)
|
||||
n22=ihashcall(c13,22)
|
||||
n10=ihashcall(cw,10)
|
||||
n12=ihashcall(cw,12)
|
||||
n22=ihashcall(cw,22)
|
||||
do i=1,nzhash
|
||||
if(ihash22(i).eq.n22) go to 900 !This one is already in the table
|
||||
enddo
|
||||
@ -124,7 +115,7 @@ subroutine save_hash_call(c13,n10,n12,n22)
|
||||
ihash10(1)=n10
|
||||
ihash12(1)=n12
|
||||
ihash22(1)=n22
|
||||
callsign(1)=c13
|
||||
callsign(1)=cw
|
||||
if(nzhash.lt.MAXHASH) nzhash=nzhash+1
|
||||
|
||||
900 return
|
||||
@ -236,7 +227,7 @@ subroutine unpack77(c77,msg,unpk77_success)
|
||||
"NM ","NY ","NC ","ND ","OH ","OK ","OR ","PA ","RI ","SC ", &
|
||||
"SD ","TN ","TX ","UT ","VT ","VA ","WA ","WV ","WI ","WY ", &
|
||||
"NB ","NS ","QC ","ON ","MB ","SK ","AB ","BC ","NWT","NF ", &
|
||||
"LB ","NU ","VT ","PEI","DC "/
|
||||
"LB ","NU ","YT ","PEI","DC "/
|
||||
|
||||
unpk77_success=.true.
|
||||
|
||||
@ -448,9 +439,11 @@ subroutine unpack77(c77,msg,unpk77_success)
|
||||
if(iflip.eq.0) then
|
||||
call_1=call_3
|
||||
call_2=adjustl(c11)//' '
|
||||
call add_call_to_recent_calls(call_2)
|
||||
else
|
||||
call_1=adjustl(c11)//' '
|
||||
call_2=call_3
|
||||
call add_call_to_recent_calls(call_1)
|
||||
endif
|
||||
if(icq.eq.0) then
|
||||
if(nrpt.eq.0) msg=trim(call_1)//' '//trim(call_2)
|
||||
@ -662,7 +655,7 @@ subroutine unpack28(n28_0,c13,success)
|
||||
c13=adjustl(c13)
|
||||
|
||||
900 i0=index(c13,' ')
|
||||
if(i0.lt.len(trim(c13))) then
|
||||
if(i0.ne.0 .and. i0.lt.len(trim(c13))) then
|
||||
c13='QU1RK'
|
||||
success=.false.
|
||||
endif
|
||||
@ -990,7 +983,7 @@ subroutine pack77_3(nwords,w,i3,n3,c77)
|
||||
"NM ","NY ","NC ","ND ","OH ","OK ","OR ","PA ","RI ","SC ", &
|
||||
"SD ","TN ","TX ","UT ","VT ","VA ","WA ","WV ","WI ","WY ", &
|
||||
"NB ","NS ","QC ","ON ","MB ","SK ","AB ","BC ","NWT","NF ", &
|
||||
"LB ","NU ","VT ","PEI","DC "/
|
||||
"LB ","NU ","YT ","PEI","DC "/
|
||||
|
||||
if(nwords.eq.4 .or. nwords.eq.5 .or. nwords.eq.6) then
|
||||
i1=1
|
||||
@ -1218,6 +1211,9 @@ subroutine add_call_to_recent_calls(callsign)
|
||||
recent_calls(1)=callsign
|
||||
endif
|
||||
|
||||
! Make sure that callsign is hashed
|
||||
call save_hash_call(callsign,n10,n12,n22)
|
||||
|
||||
return
|
||||
end subroutine add_call_to_recent_calls
|
||||
|
||||
|
@ -1,54 +0,0 @@
|
||||
program t1
|
||||
|
||||
real x(13)
|
||||
real(KIND=16) :: dlong,dlong0
|
||||
character wd*13,w*13,error*5
|
||||
character c*44 !NB: 44^13 = 2^(70.973)
|
||||
data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?@$'/
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.1) then
|
||||
print*,'Usage: t1 "FreeText13"'
|
||||
print*,' t1 <iters>'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,w)
|
||||
iters=1
|
||||
read(w,*,err=10) iters
|
||||
10 continue
|
||||
|
||||
do iter=1,iters
|
||||
if(iters.gt.1) then
|
||||
! Create a random free-text word
|
||||
call random_number(x)
|
||||
do i=1,13
|
||||
j=44*x(i) + 1
|
||||
w(i:i)=c(j:j)
|
||||
enddo
|
||||
endif
|
||||
! Encode a 13-character free-text message into a 71-bit integer.
|
||||
dlong=0.d0
|
||||
do i=1,13
|
||||
n=index(c,w(i:i))-1
|
||||
dlong=44.d0*dlong + n
|
||||
enddo
|
||||
dlong0=dlong
|
||||
|
||||
! Decode a a 71-bit integer into a 13-character free-text message.
|
||||
do i=13,1,-1
|
||||
j=mod(dlong,44.d0)+1.d0
|
||||
wd(i:i)=c(j:j)
|
||||
dlong=dlong/44.d0
|
||||
enddo
|
||||
|
||||
|
||||
error=' '
|
||||
if(wd.ne.w) then
|
||||
error='ERROR'
|
||||
write(*,1010) w,dlong0,wd,error
|
||||
1010 format('"',a13,'"',f25.1,2x,'"',a13'"',2x,a5)
|
||||
endif
|
||||
if(mod(iter,1000).eq.0) print*,iter
|
||||
enddo
|
||||
|
||||
999 end program t1
|
@ -1,25 +0,0 @@
|
||||
program t3
|
||||
character*3 csec
|
||||
character*70 line
|
||||
logical eof
|
||||
|
||||
eof=.false.
|
||||
j=1
|
||||
do i=1,83
|
||||
read(*,1001,end=1) csec
|
||||
1001 format(a3)
|
||||
go to 2
|
||||
1 eof=.true.
|
||||
2 line(j:j+5)='"'//csec//'",'
|
||||
j=j+6
|
||||
if(j.gt.60 .or. i.eq.83 .or.eof) then
|
||||
line(j:j+2)=' &'
|
||||
line(j+3:)=' '
|
||||
write(*,1010) line
|
||||
1010 format(a70)
|
||||
j=1
|
||||
endif
|
||||
if(eof) go to 999
|
||||
enddo
|
||||
|
||||
999 end program t3
|
@ -26,7 +26,7 @@ module crc
|
||||
integer (c_int), value :: length
|
||||
end function crc13
|
||||
|
||||
function crc13_check (data, length) bind (C, name="crc14_check")
|
||||
function crc13_check (data, length) bind (C, name="crc13_check")
|
||||
use, intrinsic :: iso_c_binding, only: c_bool, c_ptr, c_int
|
||||
implicit none
|
||||
logical (c_bool) :: crc13_check
|
||||
|
@ -67,20 +67,6 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
else
|
||||
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown',iostat=ios)
|
||||
endif
|
||||
if(params%nmode.eq.8) then
|
||||
inquire(file=trim(temp_dir)//'/houndcallers.txt',exist=ex)
|
||||
if(.not.ex) then
|
||||
c2fox=' '
|
||||
g2fox=' '
|
||||
nsnrfox=-99
|
||||
nfreqfox=-99
|
||||
n30z=0
|
||||
nwrap=0
|
||||
nfox=0
|
||||
endif
|
||||
open(19,file=trim(temp_dir)//'/houndcallers.txt',status='unknown')
|
||||
endif
|
||||
|
||||
if(ios.ne.0) then
|
||||
nfail=nfail+1
|
||||
if(nfail.le.3) then
|
||||
@ -91,6 +77,22 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
|
||||
if(params%nmode.eq.8) then
|
||||
! We're in FT8 mode
|
||||
|
||||
if(ncontest.eq.5) then
|
||||
! Fox mode: initialize and open houndcallers.txt
|
||||
inquire(file=trim(temp_dir)//'/houndcallers.txt',exist=ex)
|
||||
if(.not.ex) then
|
||||
c2fox=' '
|
||||
g2fox=' '
|
||||
nsnrfox=-99
|
||||
nfreqfox=-99
|
||||
n30z=0
|
||||
nwrap=0
|
||||
nfox=0
|
||||
endif
|
||||
open(19,file=trim(temp_dir)//'/houndcallers.txt',status='unknown')
|
||||
endif
|
||||
|
||||
call timer('decft8 ',0)
|
||||
newdat=params%newdat
|
||||
ncontest=iand(params%nexp_decode,7)
|
||||
@ -106,33 +108,37 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
n30max=maxval(n30fox(1:nfox))
|
||||
endif
|
||||
j=0
|
||||
rewind 19
|
||||
if(nfox.eq.0) then
|
||||
endfile 19
|
||||
|
||||
if(ncontest.eq.5) then
|
||||
! Fox mode: save decoded Hound calls for possible selection by FoxOp
|
||||
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
|
||||
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
|
||||
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
|
||||
1004 format(a12,1x,a4,i5,i6,i7,i3)
|
||||
endif
|
||||
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
|
||||
1004 format(a12,1x,a4,i5,i6,i7,i3)
|
||||
endif
|
||||
enddo
|
||||
nfox=j
|
||||
flush(19)
|
||||
enddo
|
||||
nfox=j
|
||||
flush(19)
|
||||
endif
|
||||
endif
|
||||
go to 800
|
||||
endif
|
||||
|
8
lib/emedop.dat
Normal file
8
lib/emedop.dat
Normal file
@ -0,0 +1,8 @@
|
||||
Lat_A 40.35417
|
||||
WLong_A 75.62500
|
||||
Lat_B 45.1875
|
||||
WLong_B -1.541667
|
||||
TxFreqMHz 143.05
|
||||
StartTime 20180907 08:00:00
|
||||
StopTime 20180907 09:00:00
|
||||
StepSec 60.0
|
67
lib/emedop.f90
Normal file
67
lib/emedop.f90
Normal file
@ -0,0 +1,67 @@
|
||||
program emedop
|
||||
|
||||
real*8 txfreq8
|
||||
real*8 rxfreq8
|
||||
real*4 LST
|
||||
real*4 lat_a
|
||||
real*4 lat_b
|
||||
character*80 infile
|
||||
character*256 jpleph_file_name
|
||||
common/jplcom/jpleph_file_name
|
||||
data jpleph_file_name/'JPLEPH'/
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.1) then
|
||||
print*,'Usage: emedop <infile>'
|
||||
go to 999
|
||||
endif
|
||||
|
||||
call getarg(1,infile)
|
||||
open(10,file=infile,status='old',err=900)
|
||||
read(10,1001) lat_a
|
||||
1001 format(10x,f12.0)
|
||||
read(10,1001) wlon_a
|
||||
read(10,1001) lat_b
|
||||
read(10,1001) wlon_b
|
||||
read(10,1001) txfreq8
|
||||
read(10,1002) nyear,month,nday,ih,im,is
|
||||
1002 format(10x,i4,2i2,1x,i2,1x,i2,1x,i2)
|
||||
sec_start=3600.0*ih + 60.0*im + is
|
||||
read(10,1002) nyear,month,nday,ih,im,is
|
||||
sec_stop=3600.0*ih + 60.0*im + is
|
||||
read(10,1001) sec_step
|
||||
|
||||
write(*,1005)
|
||||
1005 format(' Date UTC Tx Freq Rx Freq Doppler'/ &
|
||||
'------------------------------------------------------')
|
||||
|
||||
sec=sec_start
|
||||
ncalc=(sec_stop - sec_start)/sec_step
|
||||
|
||||
do icalc=1,ncalc
|
||||
uth=sec/3600.0
|
||||
call MoonDopJPL(nyear,month,nday,uth,-wlon_a,lat_a,RAMoon,DecMoon, &
|
||||
LST,HA,AzMoon,ElMoon,vr_a,techo)
|
||||
|
||||
call MoonDopJPL(nyear,month,nday,uth,-wlon_b,lat_b,RAMoon,DecMoon, &
|
||||
LST,HA,AzMoon,ElMoon,vr_b,techo)
|
||||
|
||||
dop_a=-txfreq8*vr_a/2.99792458e5 !One-way Doppler from a
|
||||
dop_b=-txfreq8*vr_b/2.99792458e5 !One-way Doppler to b
|
||||
doppler=1.e6*(dop_a + dop_b)
|
||||
rxfreq8=txfreq8 + dop_a + dop_b
|
||||
|
||||
ih=sec/3600.0
|
||||
im=(sec-ih*3600.0)/60.0
|
||||
is=nint(mod(sec,60.0))
|
||||
write(*,1010) nyear,month,nday,ih,im,is,txFreq8,rxFreq8,doppler
|
||||
1010 format(i4,2i2.2,2x,i2.2,':',i2.2,':',i2.2,2f13.7,f8.1)
|
||||
|
||||
sec=sec + sec_step
|
||||
enddo
|
||||
go to 999
|
||||
900 print*,'Cannot open file ',trim(infile)
|
||||
999 end program emedop
|
||||
|
||||
|
||||
|
@ -14,25 +14,20 @@ subroutine foxgen()
|
||||
! common/foxcom/. The generated wave(NWAVE) is passed back in the same
|
||||
! common block.
|
||||
|
||||
use crc
|
||||
parameter (NN=79,ND=58,KK=87,NSPS=4*1920)
|
||||
parameter (NN=79,ND=58,NSPS=4*1920)
|
||||
parameter (NWAVE=NN*NSPS,NFFT=614400,NH=NFFT/2)
|
||||
character*40 cmsg
|
||||
character*37 msg,msgsent
|
||||
character*87 cbits
|
||||
character*88 cb88
|
||||
integer itone(NN)
|
||||
integer icos7(0:6)
|
||||
integer*1 msgbits(KK),codeword(3*ND),msgbits2
|
||||
integer itone(79)
|
||||
integer*1 msgbits(77),msgbits2
|
||||
integer*1, target:: i1Msg8BitBytes(11)
|
||||
integer*1, target:: mycall
|
||||
real x(NFFT)
|
||||
real*8 dt,twopi,f0,fstep,dfreq,phi,dphi
|
||||
complex cx(0:NH)
|
||||
common/foxcom/wave(NWAVE),nslots,nfreq,i3bit(5),cmsg(5),mycall(12)
|
||||
common/foxcom2/itone2(NN),msgbits2(KK)
|
||||
common/foxcom2/itone2(NN),msgbits2(77)
|
||||
equivalence (x,cx),(y,cy)
|
||||
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
|
||||
|
||||
fstep=60.d0
|
||||
dfreq=6.25d0
|
||||
@ -43,51 +38,11 @@ subroutine foxgen()
|
||||
wave=0.
|
||||
|
||||
do n=1,nslots
|
||||
i3b=i3bit(n)
|
||||
if(i3b.eq.0) then
|
||||
msg=cmsg(n)(1:22) !Standard FT8 message
|
||||
else
|
||||
i1=index(cmsg(n),' ') !Special Fox message
|
||||
i2=index(cmsg(n),';')
|
||||
i3=index(cmsg(n),'<')
|
||||
i4=index(cmsg(n),'>')
|
||||
msg=cmsg(n)(1:i1)//cmsg(n)(i2+1:i3-2)//' '
|
||||
read(cmsg(n)(i4+2:i4+4),*) irpt
|
||||
endif
|
||||
call genft8(msg,0,1,1,msgsent,msgbits,itone)
|
||||
! print*,'Foxgen:',n,cmsg(n),msgsent
|
||||
msg=cmsg(n)(1:37)
|
||||
call genft8_174_91(msg,i3,n3,msgsent,msgbits,itone)
|
||||
! print*,'Foxgen:',n,msg,msgsent,i3,n3
|
||||
! write(*,'(77i1)') msgbits
|
||||
|
||||
if(i3b.eq.1) then
|
||||
icrc10=crc10(c_loc(mycall),12)
|
||||
nrpt=irpt+30
|
||||
write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,0
|
||||
1001 format(56b1.1,b10.10,b6.6,b3.3,b12.12)
|
||||
read(cbits,1002) msgbits
|
||||
1002 format(87i1)
|
||||
|
||||
cb88=cbits//'0'
|
||||
read(cb88,1003) i1Msg8BitBytes(1:11)
|
||||
1003 format(11b8)
|
||||
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
|
||||
|
||||
write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,icrc12
|
||||
read(cbits,1002) msgbits
|
||||
|
||||
call encode174(msgbits,codeword) !Encode the test message
|
||||
|
||||
! Message structure: S7 D29 S7 D29 S7
|
||||
itone(1:7)=icos7
|
||||
itone(36+1:36+7)=icos7
|
||||
itone(NN-6:NN)=icos7
|
||||
k=7
|
||||
do j=1,ND
|
||||
i=3*j -2
|
||||
k=k+1
|
||||
if(j.eq.30) k=k+7
|
||||
itone(k)=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
|
||||
enddo
|
||||
endif
|
||||
|
||||
! Make copies of itone() and msgbits() for ft8sim
|
||||
itone2=itone
|
||||
msgbits2=msgbits
|
||||
|
@ -1,6 +1,6 @@
|
||||
subroutine foxgen_wrap(msg40,msgbits,itone)
|
||||
|
||||
parameter (NN=79,ND=58,KK=87,NSPS=4*1920)
|
||||
parameter (NN=79,ND=58,KK=77,NSPS=4*1920)
|
||||
parameter (NWAVE=NN*NSPS)
|
||||
|
||||
character*40 msg40,cmsg
|
||||
|
@ -1,20 +1,43 @@
|
||||
subroutine ft8apset_174_91(mycall12,hiscall12,hisgrid6,ncontest,apsym)
|
||||
parameter(NAPM=4,KK=91)
|
||||
character*37 msg,msgsent
|
||||
character*12 mycall12,hiscall12
|
||||
character*6 hisgrid6
|
||||
character*4 hisgrid
|
||||
integer apsym(77)
|
||||
subroutine ft8apset_174_91(mycall12,hiscall12,apsym)
|
||||
use packjt77
|
||||
character*77 c77
|
||||
character*37 msg
|
||||
character*12 mycall12,hiscall12,hiscall
|
||||
integer apsym(58)
|
||||
integer*1 msgbits(77)
|
||||
integer itone(KK)
|
||||
|
||||
if(index(hiscall12," ").eq.0) hiscall12="K9ABC"
|
||||
msg=trim(mycall12)//' '//trim(hiscall12)//' RRR'
|
||||
i3=1
|
||||
n3=0
|
||||
!write(*,*) 'apset msg ',msg
|
||||
call genft8_174_91(msg,i3,n3,msgsent,msgbits,itone)
|
||||
apsym=2*msgbits-1
|
||||
!write(*,'(29i1,1x,29i1,1x,19i1)') (apsym(1:77)+1)/2
|
||||
logical nohiscall
|
||||
|
||||
if(len(trim(mycall12)).eq.0) then
|
||||
apsym=0
|
||||
apsym(1)=99
|
||||
apsym(30)=99
|
||||
return
|
||||
endif
|
||||
|
||||
nohiscall=.false.
|
||||
hiscall=hiscall12
|
||||
if(len(trim(hiscall)).eq.0) then
|
||||
hiscall="K9ABC"
|
||||
nohiscall=.true.
|
||||
endif
|
||||
|
||||
! Encode a dummy standard message: i3=1, 28 1 28 1 1 15
|
||||
!
|
||||
msg=trim(mycall12)//' '//trim(hiscall)//' RRR'
|
||||
call pack77(msg,i3,n3,c77)
|
||||
if(i3.ne.1) then
|
||||
apsym=0
|
||||
apsym(1)=99
|
||||
apsym(30)=99
|
||||
return
|
||||
endif
|
||||
|
||||
read(c77,'(58i1)',err=1) apsym(1:58)
|
||||
if(nohiscall) apsym(30)=99
|
||||
return
|
||||
|
||||
1 apsym=0
|
||||
apsym(1)=99
|
||||
apsym(30)=99
|
||||
return
|
||||
end subroutine ft8apset_174_91
|
||||
|
@ -1,5 +1,5 @@
|
||||
subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
napwid,lsubtract,nagain,iaptype,mycall12,hiscall12, &
|
||||
napwid,lsubtract,nagain,ncontest,iaptype,mycall12,hiscall12, &
|
||||
sync0,f1,xdt,xbase,apsym,nharderrors,dmin,nbadcrc,ipass,iera,msg37,xsnr)
|
||||
|
||||
use crc
|
||||
@ -16,19 +16,20 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
real a(5)
|
||||
real s8(0:7,NN)
|
||||
real s2(0:511),s2l(0:511)
|
||||
real bmeta(3*ND),bmetb(3*ND),bmetc(3*ND)
|
||||
real bmetal(3*ND),bmetbl(3*ND),bmetcl(3*ND)
|
||||
real llra(3*ND),llrb(3*ND),llrc(3*ND),llrd(3*ND) !Soft symbols
|
||||
real llral(3*ND),llrbl(3*ND),llrcl(3*ND) !Soft symbols
|
||||
real bmeta(174),bmetb(174),bmetc(174)
|
||||
real bmetal(174),bmetbl(174),bmetcl(174)
|
||||
real llra(174),llrb(174),llrc(174),llrd(174) !Soft symbols
|
||||
real llral(174),llrbl(174),llrcl(174) !Soft symbols
|
||||
real dd0(15*12000)
|
||||
integer*1 message77(77),apmask(3*ND),cw(3*ND)
|
||||
integer*1 msgbits(77)
|
||||
integer apsym(77)
|
||||
integer mcq(29),mrrr(19),m73(19),mrr73(19)
|
||||
integer*1 message77(77),apmask(174),cw(174)
|
||||
integer apsym(58)
|
||||
integer mcq(29),mcqru(29),mcqfd(29),mcqtest(29),mcqhund(29)
|
||||
integer mrrr(19),m73(19),mrr73(19)
|
||||
integer itone(NN)
|
||||
integer icos7(0:6),ip(1)
|
||||
integer nappasses(0:5) !Number of decoding passes to use for each QSO state
|
||||
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
|
||||
integer ncontest,ncontest0
|
||||
integer*1, target:: i1hiscall(12)
|
||||
logical one(0:511,0:8)
|
||||
integer graymap(0:7)
|
||||
@ -38,16 +39,25 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
complex cs(0:7,NN)
|
||||
logical first,newdat,lsubtract,lapon,lapcqonly,nagain,unpk77_success
|
||||
data icos7/3,1,4,0,6,5,2/ ! Flipped w.r.t. original FT8 sync array
|
||||
data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/
|
||||
data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/
|
||||
data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/
|
||||
data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/
|
||||
data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/
|
||||
data mcqru/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0/
|
||||
data mcqfd/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0/
|
||||
data mcqtest/0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0/
|
||||
data mcqhund/0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,1,1,0,0/
|
||||
data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/
|
||||
data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/
|
||||
data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/
|
||||
data first/.true./
|
||||
data graymap/0,1,3,2,5,6,4,7/
|
||||
save nappasses,naptypes,one,hiscall12_0
|
||||
save nappasses,naptypes,ncontest0,one,hiscall12_0
|
||||
|
||||
if(first) then
|
||||
|
||||
if(first.or.(ncontest.ne.ncontest0)) then
|
||||
mcq=2*mcq-1
|
||||
mcqfd=2*mcqfd-1
|
||||
mcqru=2*mcqru-1
|
||||
mcqtest=2*mcqtest-1
|
||||
mcqhund=2*mcqhund-1
|
||||
mrrr=2*mrrr-1
|
||||
m73=2*m73-1
|
||||
mrr73=2*mrr73-1
|
||||
@ -67,12 +77,12 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
! 5 MyCall DxCall 73 (77 ap bits)
|
||||
! 6 MyCall DxCall RR73 (77 ap bits)
|
||||
|
||||
naptypes(0,1:4)=(/1,2,0,0/)
|
||||
naptypes(1,1:4)=(/2,3,0,0/)
|
||||
naptypes(2,1:4)=(/2,3,0,0/)
|
||||
naptypes(3,1:4)=(/3,4,5,6/)
|
||||
naptypes(4,1:4)=(/3,4,5,6/)
|
||||
naptypes(5,1:4)=(/3,1,2,0/)
|
||||
naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ)
|
||||
naptypes(1,1:4)=(/2,3,0,0/) ! Tx1
|
||||
naptypes(2,1:4)=(/2,3,0,0/) ! Tx2
|
||||
naptypes(3,1:4)=(/3,4,5,6/) ! Tx3
|
||||
naptypes(4,1:4)=(/3,4,5,6/) ! Tx4
|
||||
naptypes(5,1:4)=(/3,1,2,0/) ! Tx5
|
||||
|
||||
one=.false.
|
||||
do i=0,511
|
||||
@ -81,6 +91,7 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
enddo
|
||||
enddo
|
||||
first=.false.
|
||||
ncontest0=ncontest
|
||||
endif
|
||||
|
||||
if(hiscall12.ne.hiscall12_0) then
|
||||
@ -124,7 +135,7 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
ctwk(i)=cmplx(cos(phi),sin(phi))
|
||||
phi=mod(phi+dphi,twopi)
|
||||
enddo
|
||||
call sync8d(cd0,i0,ctwk,1,2,sync)
|
||||
call sync8d(cd0,i0,ctwk,1,2,sync)
|
||||
if( sync .gt. smax ) then
|
||||
smax=sync
|
||||
delfbest=delf
|
||||
@ -211,12 +222,12 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
call normalizebmet(bmeta,3*ND)
|
||||
! call normalizebmet(bmetal,3*ND)
|
||||
call normalizebmet(bmetb,3*ND)
|
||||
! call normalizebmet(bmetbl,3*ND)
|
||||
call normalizebmet(bmetc,3*ND)
|
||||
! call normalizebmet(bmetcl,3*ND)
|
||||
call normalizebmet(bmeta,174)
|
||||
! call normalizebmet(bmetal,174)
|
||||
call normalizebmet(bmetb,174)
|
||||
! call normalizebmet(bmetbl,174)
|
||||
call normalizebmet(bmetc,174)
|
||||
! call normalizebmet(bmetcl,174)
|
||||
|
||||
scalefac=2.83
|
||||
llra=scalefac*bmeta
|
||||
@ -226,7 +237,7 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
llrc=scalefac*bmetc
|
||||
! llrcl=scalefac*bmetcl
|
||||
|
||||
apmag=maxval(abs(llrb))*1.01
|
||||
apmag=maxval(abs(llra))*1.01
|
||||
|
||||
! pass #
|
||||
!------------------------------
|
||||
@ -238,7 +249,7 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
! 6 ap pass 3
|
||||
! 7 ap pass 4
|
||||
|
||||
if(lapon) then
|
||||
if(lapon.or.ncontest.eq.6) then !Hounds always use AP
|
||||
if(.not.lapcqonly) then
|
||||
npasses=3+nappasses(nQSOProgress)
|
||||
else
|
||||
@ -264,29 +275,117 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
else
|
||||
iaptype=1
|
||||
endif
|
||||
if(iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
|
||||
if(iaptype.eq.1 .or. iaptype.eq.2 ) then ! AP,???,???
|
||||
|
||||
! ncontest=0 : NONE
|
||||
! 1 : NA_VHF
|
||||
! 2 : EU_VHF
|
||||
! 3 : FIELD DAY
|
||||
! 4 : RTTY
|
||||
! 5 : FOX
|
||||
! 6 : HOUND
|
||||
!
|
||||
! Conditions that cause us to bail out of AP decoding
|
||||
if(ncontest.le.4 .and. iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
|
||||
if(ncontest.eq.5) cycle ! No AP for Foxes
|
||||
if(ncontest.eq.6.and.f1.gt.950.0) cycle ! Hounds use AP only for signals below 950 Hz
|
||||
if(iaptype.ge.2 .and. apsym(1).gt.1) cycle ! No, or nonstandard, mycall
|
||||
if(iaptype.ge.3 .and. apsym(30).gt.1) cycle ! No, or nonstandard, dxcall
|
||||
apsym=2*apsym-1 ! Change from [0,1] to antipodal
|
||||
|
||||
if(iaptype.eq.1) then ! CQ or CQ RU or CQ TEST or CQ FD
|
||||
apmask=0
|
||||
apmask(1:29)=1
|
||||
if(ncontest.eq.0) llrd(1:29)=apmag*mcq(1:29)
|
||||
if(ncontest.eq.1) llrd(1:29)=apmag*mcqtest(1:29)
|
||||
if(ncontest.eq.2) llrd(1:29)=apmag*mcqtest(1:29)
|
||||
if(ncontest.eq.3) llrd(1:29)=apmag*mcqfd(1:29)
|
||||
if(ncontest.eq.4) llrd(1:29)=apmag*mcqru(1:29)
|
||||
if(ncontest.eq.6) llrd(1:29)=apmag*mcqhund(1:29)
|
||||
apmask(75:77)=1
|
||||
llrd(75:77)=apmag*apsym(75:77)
|
||||
if(iaptype.eq.1) llrd(1:29)=apmag*mcq(1:29)
|
||||
if(iaptype.eq.2) llrd(1:29)=apmag*apsym(1:29)
|
||||
llrd(75:76)=apmag*(-1)
|
||||
llrd(77)=apmag*(+1)
|
||||
endif
|
||||
if(iaptype.eq.3) then ! mycall, dxcall, ???
|
||||
|
||||
if(iaptype.eq.2) then ! MyCall,???,???
|
||||
apmask=0
|
||||
apmask(1:56)=1
|
||||
apmask(75:77)=1
|
||||
llrd(1:56)=apmag*apsym(1:56)
|
||||
llrd(75:77)=apmag*apsym(75:77)
|
||||
if(ncontest.eq.0.or.ncontest.eq.1) then
|
||||
apmask(1:29)=1
|
||||
llrd(1:29)=apmag*apsym(1:29)
|
||||
apmask(75:77)=1
|
||||
llrd(75:76)=apmag*(-1)
|
||||
llrd(77)=apmag*(+1)
|
||||
else if(ncontest.eq.2) then
|
||||
apmask(1:28)=1
|
||||
llrd(1:28)=apmag*apsym(1:28)
|
||||
apmask(72:74)=1
|
||||
llrd(72)=apmag*(-1)
|
||||
llrd(73)=apmag*(+1)
|
||||
llrd(74)=apmag*(-1)
|
||||
apmask(75:77)=1
|
||||
llrd(75:77)=apmag*(-1)
|
||||
else if(ncontest.eq.3) then
|
||||
apmask(1:28)=1
|
||||
llrd(1:28)=apmag*apsym(1:28)
|
||||
apmask(75:77)=1
|
||||
llrd(75:77)=apmag*(-1)
|
||||
else if(ncontest.eq.4) then
|
||||
apmask(2:29)=1
|
||||
llrd(2:29)=apmag*apsym(1:28)
|
||||
apmask(75:77)=1
|
||||
llrd(75)=apmag*(-1)
|
||||
llrd(76:77)=apmag*(+1)
|
||||
else if(ncontest.eq.6) then ! ??? RR73; MyCall <???> ???
|
||||
apmask(29:56)=1
|
||||
llrd(29:56)=apmag*apsym(1:28)
|
||||
apmask(72:77)=1
|
||||
llrd(72:73)=apmag*(-1)
|
||||
llrd(74)=apmag*(+1)
|
||||
llrd(75:77)=apmag*(-1)
|
||||
endif
|
||||
endif
|
||||
|
||||
if(iaptype.eq.3) then ! MyCall,DxCall,???
|
||||
apmask=0
|
||||
if(ncontest.eq.0.or.ncontest.eq.1.or.ncontest.eq.2.or.ncontest.eq.6) then
|
||||
apmask(1:58)=1
|
||||
llrd(1:58)=apmag*apsym
|
||||
apmask(75:77)=1
|
||||
llrd(75:76)=apmag*(-1)
|
||||
llrd(77)=apmag*(+1)
|
||||
else if(ncontest.eq.3) then ! Field Day
|
||||
apmask(1:56)=1
|
||||
llrd(1:28)=apmag*apsym(1:28)
|
||||
llrd(29:56)=apmag*apsym(30:57)
|
||||
apmask(72:74)=1
|
||||
apmask(75:77)=1
|
||||
llrd(75:77)=apmag*(-1)
|
||||
else if(ncontest.eq.4) then ! RTTY RU
|
||||
apmask(2:57)=1
|
||||
llrd(2:29)=apmag*apsym(1:28)
|
||||
llrd(30:57)=apmag*apsym(30:57)
|
||||
apmask(75:77)=1
|
||||
llrd(75)=apmag*(-1)
|
||||
llrd(76:77)=apmag*(+1)
|
||||
endif
|
||||
endif
|
||||
|
||||
if(iaptype.eq.5.and.ncontest.eq.6) cycle !Hound
|
||||
if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
|
||||
apmask=0
|
||||
apmask(1:77)=1 ! mycall, hiscall, RRR|73|RR73
|
||||
llrd(1:58)=apmag*apsym(1:58)
|
||||
if(iaptype.eq.4) llrd(59:77)=apmag*mrrr
|
||||
if(iaptype.eq.5) llrd(59:77)=apmag*m73
|
||||
if(iaptype.eq.6) llrd(59:77)=apmag*mrr73
|
||||
if(ncontest.le.4 .or. (ncontest.eq.6.and.iaptype.eq.6)) then
|
||||
apmask(1:77)=1 ! mycall, hiscall, RRR|73|RR73
|
||||
llrd(1:58)=apmag*apsym
|
||||
if(iaptype.eq.4) llrd(59:77)=apmag*mrrr
|
||||
if(iaptype.eq.5) llrd(59:77)=apmag*m73
|
||||
if(iaptype.eq.6) llrd(59:77)=apmag*mrr73
|
||||
else if(ncontest.eq.6.and.iaptype.eq.4) then ! Hound listens for MyCall RR73;...
|
||||
apmask(1:28)=1
|
||||
llrd(1:28)=apmag*apsym(1:28)
|
||||
apmask(72:77)=1
|
||||
llrd(72:73)=apmag*(-1)
|
||||
llrd(74)=apmag*(1)
|
||||
llrd(75:77)=apmag*(-1)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -299,11 +398,7 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
if(ndepth.eq.3 .and. nharderrors.lt.0) then
|
||||
ndeep=3
|
||||
if(abs(nfqso-f1).le.napwid .or. abs(nftx-f1).le.napwid) then
|
||||
if((ipass.eq.3 .or. ipass.eq.4) .and. .not.nagain) then
|
||||
ndeep=3
|
||||
else
|
||||
ndeep=4
|
||||
endif
|
||||
ndeep=4
|
||||
endif
|
||||
if(nagain) ndeep=5
|
||||
call timer('osd174_91 ',0)
|
||||
@ -312,7 +407,6 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
endif
|
||||
|
||||
msg37=' '
|
||||
xsnr=-99.0
|
||||
if(nharderrors.lt.0 .or. nharderrors.gt.36) cycle
|
||||
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
|
||||
write(c77,'(77i1)') message77
|
||||
@ -326,7 +420,7 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
cycle
|
||||
endif
|
||||
nbadcrc=0 ! If we get this far: valid codeword, valid (i3,n3), nonquirky message.
|
||||
call genft8_174_91(msg37,i3,n3,msgsent37,msgbits,itone)
|
||||
call get_tones_from_77bits(message77,itone)
|
||||
if(lsubtract) call subtractft8(dd0,itone,f1,xdt)
|
||||
xsig=0.0
|
||||
xnoi=0.0
|
||||
@ -336,13 +430,16 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
||||
xnoi=xnoi+s8(ios,i)**2
|
||||
enddo
|
||||
xsnr=0.001
|
||||
if(xnoi.gt.0 .and. xnoi.lt.xsig) xsnr=xsig/xnoi-1.0
|
||||
xsnr2=0.001
|
||||
arg=xsig/xnoi-1.0
|
||||
if(arg.gt.0.1) xsnr=arg
|
||||
arg=xsig/xbase/2.6e6-1.0
|
||||
if(arg.gt.0.1) xsnr2=arg
|
||||
xsnr=10.0*log10(xsnr)-27.0
|
||||
xbase=10**(xbase/10.0)
|
||||
! factor=xnoi/xbase
|
||||
factor=3.6e6
|
||||
xsnr2=10*log10(xsig/xbase/factor-1.0)-27.0
|
||||
! if(.not.nagain) xsnr=xsnr2
|
||||
xsnr2=10.0*log10(xsnr2)-27.0
|
||||
if(.not.nagain) then
|
||||
xsnr=xsnr2
|
||||
endif
|
||||
if(xsnr .lt. -24.0) xsnr=-24.0
|
||||
|
||||
return
|
||||
|
@ -18,10 +18,12 @@ subroutine genft8_174_91(msg,i3,n3,msgsent,msgbits,itone)
|
||||
n3=-1
|
||||
call pack77(msg,i3,n3,c77)
|
||||
call unpack77(c77,msgsent,unpk77_success)
|
||||
|
||||
read(c77,'(77i1)',err=1) msgbits
|
||||
go to 2
|
||||
1 write(81,*) msg,c77 ; flush(81)
|
||||
|
||||
entry get_tones_from_77bits(msgbits,itone)
|
||||
|
||||
2 call encode174_91(msgbits,codeword) !Encode the test message
|
||||
|
||||
! Message structure: S7 D29 S7 D29 S7
|
||||
|
@ -52,7 +52,7 @@ contains
|
||||
character*12 mycall12,hiscall12,mycall12_0
|
||||
character*6 hisgrid6
|
||||
integer*2 iwave(15*12000)
|
||||
integer apsym1(KK),apsym2(77)
|
||||
integer apsym1(KK),apsym2(58)
|
||||
character datetime*13,msg37*37
|
||||
! character message*22
|
||||
character*37 allmessages(100)
|
||||
@ -70,7 +70,7 @@ contains
|
||||
1001 format("000000_",i6.6)
|
||||
|
||||
call ft8apset(mycall12,hiscall12,apsym1)
|
||||
call ft8apset_174_91(mycall12,hiscall12,hisgrid6,ncontest,apsym2)
|
||||
call ft8apset_174_91(mycall12,hiscall12,apsym2)
|
||||
dd=iwave
|
||||
ndecodes=0
|
||||
allmessages=' '
|
||||
@ -121,7 +121,7 @@ contains
|
||||
nbadcrc,iappass,iera,msg37,xsnr)
|
||||
else
|
||||
call ft8b_2(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
|
||||
lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12, &
|
||||
lapcqonly,napwid,lsubtract,nagain,ncontest,iaptype,mycall12, &
|
||||
hiscall12,sync,f1,xdt,xbase,apsym2,nharderrors,dmin, &
|
||||
nbadcrc,iappass,iera,msg37,xsnr)
|
||||
endif
|
||||
@ -131,9 +131,6 @@ contains
|
||||
hd=nharderrors+dmin
|
||||
call timer('ft8b ',1)
|
||||
if(nbadcrc.eq.0) then
|
||||
! call jtmsg(message,iflag)
|
||||
! This probably needs to be re-visited for the new message type
|
||||
! if(iand(iflag,31).ne.0) message(22:22)='?'
|
||||
ldupe=.false.
|
||||
do id=1,ndecodes
|
||||
if(msg37.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
|
||||
@ -143,11 +140,11 @@ contains
|
||||
allmessages(ndecodes)=msg37
|
||||
allsnrs(ndecodes)=nsnr
|
||||
endif
|
||||
! write(81,1004) nutc,ncand,icand,ipass,iaptype,iappass, &
|
||||
! nharderrors,dmin,hd,min(sync,999.0),nint(xsnr), &
|
||||
! xdt,nint(f1),msg37,isync
|
||||
!1004 format(i6.6,2i4,3i2,i3,3f6.1,i4,f6.2,i5,2x,a37,i4)
|
||||
! flush(81)
|
||||
write(81,1004) nutc,ncand,icand,ipass,iaptype,iappass, &
|
||||
nharderrors,dmin,hd,min(sync,999.0),nint(xsnr), &
|
||||
xdt,nint(f1),msg37,isync
|
||||
1004 format(i6.6,2i4,3i2,i3,3f6.1,i4,f6.2,i5,2x,a37,i4)
|
||||
flush(81)
|
||||
if(.not.ldupe .and. associated(this%callback)) then
|
||||
qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]
|
||||
call this%callback(sync,nsnr,xdt,f1,msg37,iaptype,qual)
|
||||
|
@ -29,7 +29,7 @@ subroutine genmsk40(msg,msgsent,ichk,itone,itype)
|
||||
10 irpt=i !Report index, 0-15
|
||||
if(ichk.lt.10000) then
|
||||
hashmsg=msg(2:i1-1)
|
||||
call hash(hashmsg,22,ihash)
|
||||
call hash(hashmsg,37,ihash)
|
||||
ihash=iand(ihash,4095) !12-bit hash
|
||||
ig=16*ihash + irpt !4-bit report
|
||||
else
|
||||
|
@ -46,6 +46,7 @@ subroutine genmsk_128_90(msg0,ichk,msgsent,i4tone,itype)
|
||||
enddo
|
||||
endif
|
||||
|
||||
message(1:37)=' '
|
||||
itype=1
|
||||
if(msg0(1:1).eq.'@') then !Generate a fixed tone
|
||||
read(msg0(2:5),*,end=1,err=1) nfreq !at specified frequency
|
||||
@ -54,23 +55,28 @@ subroutine genmsk_128_90(msg0,ichk,msgsent,i4tone,itype)
|
||||
2 i4tone(1)=nfreq
|
||||
else
|
||||
message=msg0
|
||||
|
||||
do i=1, 37
|
||||
if(ichar(message(i:i)).eq.0) then
|
||||
message(i:)=' '
|
||||
message(i:37)=' '
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
|
||||
do i=1,37 !Strip leading blanks
|
||||
if(message(1:1).ne.' ') exit
|
||||
message=message(i+1:)
|
||||
enddo
|
||||
|
||||
if(message(1:1).eq.'<') then
|
||||
call genmsk40(message,msgsent,ichk,i4tone,itype)
|
||||
if(itype.lt.0) go to 999
|
||||
i4tone(41)=-40
|
||||
go to 999
|
||||
i2=index(message,'>')
|
||||
i1=0
|
||||
if(i2.gt.0) i1=index(message(1:i2),' ')
|
||||
if(i1.gt.0) then
|
||||
call genmsk40(message,msgsent,ichk,i4tone,itype)
|
||||
if(itype.lt.0) go to 999
|
||||
i4tone(41)=-40
|
||||
go to 999
|
||||
endif
|
||||
endif
|
||||
|
||||
i3=-1
|
||||
|
@ -5,8 +5,8 @@ subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, &
|
||||
|
||||
parameter (NSPM=240)
|
||||
character*4 rpt(0:15)
|
||||
character*6 mycall,hiscall,mycall0,hiscall0
|
||||
character*22 hashmsg,msgreceived
|
||||
character*12 mycall,hiscall,mycall0,hiscall0
|
||||
character*37 hashmsg,msgreceived
|
||||
complex cb(42)
|
||||
complex cfac,cca
|
||||
complex c(NSPM)
|
||||
@ -59,7 +59,7 @@ subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, &
|
||||
hashmsg=trim(mycall)//' '//trim(hiscall)
|
||||
if( hashmsg .ne. ' ' .and. hiscall .ne. '' ) then ! protect against blank mycall/hiscall
|
||||
call fmtmsg(hashmsg,iz)
|
||||
call hash(hashmsg,22,ihash)
|
||||
call hash(hashmsg,37,ihash)
|
||||
ihash=iand(ihash,4095)
|
||||
else
|
||||
ihash=9999 ! so that it can never match a received hash
|
||||
|
@ -6,8 +6,8 @@ subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray, &
|
||||
use timer_module, only: timer
|
||||
|
||||
parameter (NSPM=240, MAXSTEPS=150, NFFT=NSPM, MAXCAND=5, NPATTERNS=6)
|
||||
character*6 mycall,hiscall
|
||||
character*22 msgreceived
|
||||
character*12 mycall,hiscall
|
||||
character*37 msgreceived
|
||||
complex cbig(n)
|
||||
complex cdat(3*NSPM) !Analytic signal
|
||||
complex c(NSPM)
|
||||
|
@ -15,10 +15,10 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
|
||||
character*4 decsym !"&" for mskspd or "^" for long averages
|
||||
character*37 msgreceived !Decoded message
|
||||
character*22 msgrx22 !Sh messages are returned as 22chars
|
||||
character*37 msglast,msglastswl !Used for dupechecking
|
||||
character*37 msglast,msglastswl !Used for dupechecking
|
||||
character*80 line !Formatted line with UTC dB T Freq Msg
|
||||
character*12 mycall,hiscall
|
||||
character*13 mycall13
|
||||
character*6 mygrid
|
||||
character*37 recent_shmsgs(NSHMEM)
|
||||
character*512 datadir
|
||||
@ -55,7 +55,7 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
1,1,1,1,1,1,1,0/
|
||||
data xmc/2.0,4.5,2.5,3.5/ !Used to set time at center of averaging mask
|
||||
save first,tsec0,nutc00,pnoise,cdat,msglast,msglastswl, &
|
||||
nsnrlast,nsnrlastswl,nhasharray,recent_shmsgs
|
||||
nsnrlast,nsnrlastswl,nhasharray,recent_shmsgs,mycall13
|
||||
|
||||
if(first) then
|
||||
tsec0=tsec
|
||||
@ -71,11 +71,16 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
msglastswl=' '
|
||||
nsnrlast=-99
|
||||
nsnrlastswl=-99
|
||||
mycall13=mycall//" "
|
||||
call save_hash_call(mycall13,n10,n12,n22) ! Make sure that my callsign is in hashtable
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
fc=nrxfreq
|
||||
|
||||
! Reset if mycall changes
|
||||
if(mycall13(1:12).ne.mycall) first=.true.
|
||||
|
||||
! Dupe checking setup
|
||||
if(nutc00.ne.nutc0 .or. tsec.lt.tsec0) then ! reset dupe checker
|
||||
msglast=' '
|
||||
@ -119,9 +124,8 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
call msk144spd(cdat,np,ntol,ndecodesuccess,msgreceived,fc,fest,tdec,navg,ct, &
|
||||
softbits)
|
||||
if(ndecodesuccess.eq.0 .and. (bshmsg.or.bswl)) then
|
||||
call msk40spd(cdat,np,ntol,mycall(1:6),hiscall(1:6),bswl,nhasharray, &
|
||||
ndecodesuccess,msgrx22,fc,fest,tdec,navg)
|
||||
if( ndecodesuccess .ge. 1 ) msgreceived(1:22)=msgrx22
|
||||
call msk40spd(cdat,np,ntol,mycall,hiscall,bswl,nhasharray, &
|
||||
ndecodesuccess,msgreceived,fc,fest,tdec,navg)
|
||||
endif
|
||||
if( ndecodesuccess .ge. 1 ) then
|
||||
tdec=tsec+tdec
|
||||
@ -184,7 +188,12 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
nsnr=nint(snr0)
|
||||
|
||||
bshdecode=.false.
|
||||
if( msgreceived(1:1) .eq. '<' ) bshdecode=.true.
|
||||
if( msgreceived(1:1) .eq. '<' ) then
|
||||
i2=index(msgreceived,'>')
|
||||
i1=0
|
||||
if(i2.gt.0) i1=index(msgreceived(1:i2),' ')
|
||||
if(i1.gt.0) bshdecode=.true.
|
||||
endif
|
||||
|
||||
if(.not. bshdecode) then
|
||||
call msk144signalquality(ct,snr0,fest,tdec,softbits,msgreceived,hiscall, &
|
||||
@ -210,15 +219,17 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
if(.not. bshdecode) then
|
||||
call update_hasharray(nhasharray)
|
||||
endif
|
||||
if( .not.bshdecode ) then
|
||||
write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived(1:22), &
|
||||
navg,ncorrected,eyeopening,char(0)
|
||||
1020 format(i6.6,i4,f5.1,i5,a4,a22,i2,i3,f5.1,a1)
|
||||
else
|
||||
write(line,1022) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived(1:22), &
|
||||
navg,char(0)
|
||||
1022 format(i6.6,i4,f5.1,i5,a4,a22,i2,a1)
|
||||
endif
|
||||
write(line,1021) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived,char(0)
|
||||
1021 format(i6.6,i4,f5.1,i5,a4,a37,a1)
|
||||
! if( .not.bshdecode ) then
|
||||
! write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived(1:22), &
|
||||
! navg,ncorrected,eyeopening,char(0)
|
||||
!1020 format(i6.6,i4,f5.1,i5,a4,a22,i2,i3,f5.1,a1)
|
||||
! else
|
||||
! write(line,1022) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived(1:22), &
|
||||
! navg,char(0)
|
||||
!1022 format(i6.6,i4,f5.1,i5,a4,a22,i2,a1)
|
||||
! endif
|
||||
elseif(bswl .and. ndecodesuccess.ge.2) then
|
||||
seenb4=.false.
|
||||
do i=1,nshmem
|
||||
@ -233,8 +244,9 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
|
||||
if(bflag) then
|
||||
msglastswl=msgreceived
|
||||
nsnrlastswl=nsnr
|
||||
write(line,1022) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, &
|
||||
navg,char(0)
|
||||
write(line,1021) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived,char(0)
|
||||
! write(line,1022) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, &
|
||||
! navg,char(0)
|
||||
endif
|
||||
endif
|
||||
999 tsec0=tsec
|
||||
|
@ -29,7 +29,7 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
|
||||
df=0.5*11025.0/nfft
|
||||
ftop=nfqso + 7*mode4*df
|
||||
if(ftop.gt.11025.0/4.0) then
|
||||
print*,'*** Rx Freq is set too high for this sybmode ***'
|
||||
print*,'*** Rx Freq is set too high for this submode ***'
|
||||
go to 900
|
||||
endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
subroutine update_hasharray(nhasharray)
|
||||
|
||||
use packjt77
|
||||
character*22 hashmsg
|
||||
character*37 hashmsg
|
||||
integer nhasharray(MAXRECENT,MAXRECENT)
|
||||
|
||||
nhasharray=-1
|
||||
@ -10,12 +10,12 @@ subroutine update_hasharray(nhasharray)
|
||||
if( recent_calls(i)(1:1) .ne. ' ' .and. recent_calls(j)(1:1) .ne. ' ' ) then
|
||||
hashmsg=trim(recent_calls(i))//' '//trim(recent_calls(j))
|
||||
call fmtmsg(hashmsg,iz)
|
||||
call hash(hashmsg,22,ihash)
|
||||
call hash(hashmsg,37,ihash)
|
||||
ihash=iand(ihash,4095)
|
||||
nhasharray(i,j)=ihash
|
||||
hashmsg=trim(recent_calls(j))//' '//trim(recent_calls(i))
|
||||
call fmtmsg(hashmsg,iz)
|
||||
call hash(hashmsg,22,ihash)
|
||||
call hash(hashmsg,37,ihash)
|
||||
ihash=iand(ihash,4095)
|
||||
nhasharray(j,i)=ihash
|
||||
endif
|
||||
|
@ -115,7 +115,7 @@ void ADIF::add(QString const& call, QString const& grid, QString const& band,
|
||||
{
|
||||
QSO q;
|
||||
q.call = call;
|
||||
q.grid = grid;
|
||||
q.grid = grid.left(4); //We only want to test matches to 4-character grids.
|
||||
q.band = band;
|
||||
q.mode = mode;
|
||||
q.date = date;
|
||||
@ -180,11 +180,12 @@ int ADIF::getCount() const
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode
|
||||
, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn
|
||||
, QDateTime const& dateTimeOff, QString const& band, QString const& comments
|
||||
, QString const& name, QString const& strDialFreq, QString const& m_myCall
|
||||
, QString const& m_myGrid, QString const& m_txPower, QString const& operator_call)
|
||||
QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode,
|
||||
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
||||
QDateTime const& dateTimeOff, QString const& band, QString const& comments,
|
||||
QString const& name, QString const& strDialFreq, QString const& m_myCall,
|
||||
QString const& m_myGrid, QString const& m_txPower, QString const& operator_call,
|
||||
QString const& xSent, QString const& xRcvd)
|
||||
{
|
||||
QString t;
|
||||
t = "<call:" + QString::number(hisCall.length()) + ">" + hisCall;
|
||||
@ -198,26 +199,24 @@ QByteArray ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QStri
|
||||
t += " <time_off:6>" + dateTimeOff.time().toString("hhmmss");
|
||||
t += " <band:" + QString::number(band.length()) + ">" + band;
|
||||
t += " <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq;
|
||||
t += " <station_callsign:" + QString::number(m_myCall.length()) + ">" +
|
||||
m_myCall;
|
||||
t += " <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" +
|
||||
m_myGrid;
|
||||
if (m_txPower != "")
|
||||
t += " <tx_pwr:" + QString::number(m_txPower.length()) +
|
||||
">" + m_txPower;
|
||||
if (comments != "")
|
||||
t += " <comment:" + QString::number(comments.length()) +
|
||||
">" + comments;
|
||||
if (name != "")
|
||||
t += " <name:" + QString::number(name.length()) +
|
||||
">" + name;
|
||||
if (operator_call!="")
|
||||
t+=" <operator:" + QString::number(operator_call.length()) +
|
||||
">" + operator_call;
|
||||
return t.toLatin1 ();
|
||||
t += " <station_callsign:" + QString::number(m_myCall.length()) + ">" + m_myCall;
|
||||
t += " <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" + m_myGrid;
|
||||
if(m_txPower!="") t += " <tx_pwr:" + QString::number(m_txPower.length()) + ">" + m_txPower;
|
||||
if(comments!="") t += " <comment:" + QString::number(comments.length()) + ">" + comments;
|
||||
if(name!="") t += " <name:" + QString::number(name.length()) + ">" + name;
|
||||
if(operator_call!="") t+=" <operator:" + QString::number(operator_call.length()) + ">" + operator_call;
|
||||
if(xRcvd!="") {
|
||||
QString t1="";
|
||||
if(xRcvd.split(" ").size()==2) t1=xRcvd.split(" ").at(1);
|
||||
if(t1.toInt()>0) {
|
||||
t += " <SRX:" + QString::number(t1.length()) + ">" + t1;
|
||||
} else {
|
||||
t += " <STATE:" + QString::number(t1.length()) + ">" + t1;
|
||||
}
|
||||
}
|
||||
return t.toLatin1();
|
||||
}
|
||||
|
||||
|
||||
// open ADIF file and append the QSO details. Return true on success
|
||||
bool ADIF::addQSOToFile(QByteArray const& ADIF_record)
|
||||
{
|
||||
|
@ -33,11 +33,12 @@ class ADIF
|
||||
// open ADIF file and append the QSO details. Return true on success
|
||||
bool addQSOToFile(QByteArray const& ADIF_record);
|
||||
|
||||
QByteArray QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent
|
||||
, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff
|
||||
, QString const& band, QString const& comments, QString const& name
|
||||
, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid
|
||||
, QString const& m_txPower, QString const& operator_call);
|
||||
QByteArray QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode,
|
||||
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
||||
QDateTime const& dateTimeOff, QString const& band, QString const& comments,
|
||||
QString const& name, QString const& strDialFreq, QString const& m_myCall,
|
||||
QString const& m_myGrid, QString const& m_txPower, QString const& operator_call,
|
||||
QString const& xSent, QString const& xRcvd);
|
||||
|
||||
private:
|
||||
struct QSO
|
||||
|
18
logqso.cpp
18
logqso.cpp
@ -59,9 +59,14 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
|
||||
QString const& rptSent, QString const& rptRcvd,
|
||||
QDateTime const& dateTimeOn, QDateTime const& dateTimeOff,
|
||||
Radio::Frequency dialFreq, QString const& myCall, QString const& myGrid,
|
||||
bool noSuffix, bool toRTTY, bool dBtoComments, bool bFox, QString const& opCall)
|
||||
bool noSuffix, bool toRTTY, bool dBtoComments, bool bFox,
|
||||
bool bAutoLog, QString const& opCall, qint32 nContest,
|
||||
QString xSent, QString xRcvd)
|
||||
{
|
||||
if(!isHidden()) return;
|
||||
m_nContest=nContest;
|
||||
m_xSent=xSent;
|
||||
m_xRcvd=xRcvd;
|
||||
ui->call->setText(hisCall);
|
||||
ui->grid->setText(hisGrid);
|
||||
ui->name->setText("");
|
||||
@ -87,7 +92,9 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
|
||||
m_myGrid=myGrid;
|
||||
ui->band->setText (m_config->bands ()->find (dialFreq));
|
||||
ui->loggedOperator->setText(opCall);
|
||||
if(bFox) {
|
||||
ui->exchSent->setText(m_xSent);
|
||||
ui->exchRcvd->setText(m_xRcvd);
|
||||
if(bFox or bAutoLog) {
|
||||
accept();
|
||||
} else {
|
||||
show ();
|
||||
@ -114,13 +121,14 @@ void LogQSO::accept()
|
||||
QString strDialFreq(QString::number(m_dialFreq / 1.e6,'f',6));
|
||||
operator_call = ui->loggedOperator->text();
|
||||
//Log this QSO to ADIF file "wsjtx_log.adi"
|
||||
QString filename = "wsjtx_log.adi"; // TODO allow user to set
|
||||
QString filename = "wsjtx_log.adi"; // TODO allow user to set
|
||||
ADIF adifile;
|
||||
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx_log.adi");
|
||||
adifile.init(adifilePath);
|
||||
|
||||
QByteArray ADIF {adifile.QSOToADIF (hisCall, hisGrid, mode, rptSent, rptRcvd, m_dateTimeOn, m_dateTimeOff, band
|
||||
, comments, name, strDialFreq, m_myCall, m_myGrid, m_txPower, operator_call)};
|
||||
QByteArray ADIF {adifile.QSOToADIF (hisCall, hisGrid, mode, rptSent, rptRcvd,
|
||||
m_dateTimeOn, m_dateTimeOff, band, comments, name, strDialFreq, m_myCall,
|
||||
m_myGrid, m_txPower, operator_call, m_xSent, m_xRcvd)};
|
||||
if (!adifile.addQSOToFile (ADIF))
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("Log file error"),
|
||||
|
7
logqso.h
7
logqso.h
@ -33,7 +33,9 @@ public:
|
||||
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
||||
QDateTime const& dateTimeOff,
|
||||
Radio::Frequency dialFreq, QString const& myCall, QString const& myGrid,
|
||||
bool noSuffix, bool toRTTY, bool dBtoComments, bool bFox, QString const& opCall);
|
||||
bool noSuffix, bool toRTTY, bool dBtoComments, bool bFox,
|
||||
bool bAutoLog, QString const& opCall, qint32 nContest, QString xSent,
|
||||
QString xRcvd);
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
@ -61,6 +63,9 @@ private:
|
||||
Radio::Frequency m_dialFreq;
|
||||
QString m_myCall;
|
||||
QString m_myGrid;
|
||||
QString m_xSent;
|
||||
QString m_xRcvd;
|
||||
qint32 m_nContest;
|
||||
QDateTime m_dateTimeOn;
|
||||
QDateTime m_dateTimeOff;
|
||||
};
|
||||
|
57
logqso.ui
57
logqso.ui
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>377</width>
|
||||
<height>257</height>
|
||||
<height>287</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -16,7 +16,7 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
@ -390,6 +390,57 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Exch sent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="exchSent">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Rcvd</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="exchRcvd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@ -397,7 +448,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
|
34
main.cpp
34
main.cpp
@ -17,13 +17,10 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QStringList>
|
||||
#include <QLockFile>
|
||||
#include <QStack>
|
||||
#include <QSplashScreen>
|
||||
|
||||
#if QT_VERSION >= 0x050200
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
#endif
|
||||
|
||||
#include "revision_utils.hpp"
|
||||
#include "MetaDataRegistry.hpp"
|
||||
@ -54,38 +51,12 @@ namespace
|
||||
qsrand (seed); // this is good for rand() as well
|
||||
}
|
||||
} seeding;
|
||||
|
||||
class MessageTimestamper
|
||||
{
|
||||
public:
|
||||
MessageTimestamper ()
|
||||
{
|
||||
prior_handlers_.push (qInstallMessageHandler (message_handler));
|
||||
}
|
||||
~MessageTimestamper ()
|
||||
{
|
||||
if (prior_handlers_.size ()) qInstallMessageHandler (prior_handlers_.pop ());
|
||||
}
|
||||
|
||||
private:
|
||||
static void message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
|
||||
{
|
||||
QtMessageHandler handler {prior_handlers_.top ()};
|
||||
if (handler)
|
||||
{
|
||||
handler (type, context,
|
||||
QDateTime::currentDateTimeUtc ().toString ("yy-MM-ddTHH:mm:ss.zzzZ: ") + msg);
|
||||
}
|
||||
}
|
||||
static QStack<QtMessageHandler> prior_handlers_;
|
||||
};
|
||||
QStack<QtMessageHandler> MessageTimestamper::prior_handlers_;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Add timestamps to all debug messages
|
||||
MessageTimestamper message_timestamper;
|
||||
qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}");
|
||||
|
||||
init_random_seed ();
|
||||
|
||||
@ -108,7 +79,6 @@ int main(int argc, char *argv[])
|
||||
a.setApplicationName ("WSJT-X");
|
||||
a.setApplicationVersion (version ());
|
||||
|
||||
#if QT_VERSION >= 0x050200
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription ("\n" PROJECT_SUMMARY_DESCRIPTION);
|
||||
auto help_option = parser.addHelpOption ();
|
||||
@ -210,11 +180,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WSJT_QDEBUG_TO_FILE
|
||||
// Open a trace file
|
||||
TraceFile trace_file {temp_dir.absoluteFilePath (a.applicationName () + "_trace.log")};
|
||||
qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}");
|
||||
qDebug () << program_title (revision ()) + " - Program startup";
|
||||
#endif
|
||||
|
||||
|
458
mainwindow.cpp
458
mainwindow.cpp
@ -58,7 +58,9 @@
|
||||
#include "MultiSettings.hpp"
|
||||
#include "MaidenheadLocatorValidator.hpp"
|
||||
#include "CallsignValidator.hpp"
|
||||
#include "ExchangeValidator.hpp"
|
||||
#include "EqualizationToolsDialog.hpp"
|
||||
#include "LotWUsers.hpp"
|
||||
|
||||
#include "ui_mainwindow.h"
|
||||
#include "moc_mainwindow.cpp"
|
||||
@ -162,7 +164,6 @@ int fast_jhpeak {0};
|
||||
int fast_jh2 {0};
|
||||
int narg[15];
|
||||
QVector<QColor> g_ColorTbl;
|
||||
QHash<QString,int> m_LoTW;
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -203,7 +204,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_configurations_button {0},
|
||||
m_settings {multi_settings->settings ()},
|
||||
ui(new Ui::MainWindow),
|
||||
m_config {temp_directory, m_settings, this},
|
||||
m_config {&m_network_manager, temp_directory, m_settings, this},
|
||||
m_WSPR_band_hopping {m_settings, &m_config, this},
|
||||
m_WSPR_tx_next {false},
|
||||
m_rigErrorMessageBox {MessageBox::Critical, tr ("Rig Control Error")
|
||||
@ -386,6 +387,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this});
|
||||
ui->dxCallEntry->setValidator (new CallsignValidator {this});
|
||||
ui->sbTR->values ({5, 10, 15, 30});
|
||||
ui->decodedTextBrowser->set_configuration (&m_config);
|
||||
ui->decodedTextBrowser2->set_configuration (&m_config);
|
||||
|
||||
m_baseCall = Radio::base_callsign (m_config.my_callsign ());
|
||||
m_opCall = m_config.opCall();
|
||||
@ -555,6 +558,10 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_equalizationToolsDialog->show ();
|
||||
});
|
||||
|
||||
connect (&m_config.lotw_users (), &LotWUsers::LotW_users_error, this, [this] (QString const& reason) {
|
||||
MessageBox::warning_message (this, tr ("Error Loading LotW Users Data"), reason);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
QButtonGroup* txMsgButtonGroup = new QButtonGroup {this};
|
||||
txMsgButtonGroup->addButton(ui->txrb1,1);
|
||||
txMsgButtonGroup->addButton(ui->txrb2,2);
|
||||
@ -721,6 +728,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_msg[0][0]=0;
|
||||
ui->labDXped->setVisible(false);
|
||||
ui->labDXped->setStyleSheet("QLabel {background-color: red; color: white;}");
|
||||
ui->labNextCall->setText("");
|
||||
ui->labNextCall->setVisible(false);
|
||||
|
||||
for(int i=0; i<28; i++) { //Initialize dBm values
|
||||
float dbm=(10.0*i)/3.0 - 30.0;
|
||||
@ -740,7 +749,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
ui->decodedTextLabel->setText(t);
|
||||
ui->decodedTextLabel2->setText(t);
|
||||
readSettings(); //Restore user's setup parameters
|
||||
setColorHighlighting(); //Set the color highlighting scheme for decoded text.
|
||||
m_audioThread.start (m_audioThreadPriority);
|
||||
|
||||
#ifdef WIN32
|
||||
@ -919,31 +927,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
ui->cbMenus->setChecked(false);
|
||||
}
|
||||
|
||||
QFile f{m_config.data_dir().absoluteFilePath ("lotw-user-activity.csv")};
|
||||
if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream s(&f);
|
||||
QString line,call;
|
||||
int nLoTW=0;
|
||||
int i1;
|
||||
QDateTime now=QDateTime::currentDateTime();
|
||||
QDateTime callDateTime;
|
||||
// Read and process the file of LoTW-active stations
|
||||
while(!s.atEnd()) {
|
||||
line=s.readLine();
|
||||
i1=line.indexOf(",");
|
||||
call=line.left(i1);
|
||||
line=line.mid(i1+1);
|
||||
i1=line.indexOf(",");
|
||||
callDateTime=QDateTime::fromString(line.left(i1),"yyyy-MM-dd");
|
||||
int ndays=callDateTime.daysTo(now);
|
||||
if(ndays < 366) {
|
||||
nLoTW++;
|
||||
m_LoTW[call]=ndays;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
|
||||
// this must be the last statement of constructor
|
||||
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
|
||||
}
|
||||
@ -951,14 +934,14 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
void MainWindow::not_GA_warning_message ()
|
||||
{
|
||||
QDateTime now=QDateTime::currentDateTime();
|
||||
QDateTime timeout=QDateTime(QDate(2018,10,31));
|
||||
QDateTime timeout=QDateTime(QDate(2018,11,30));
|
||||
|
||||
MessageBox::critical_message (this,
|
||||
"This version of WSJT-X is a beta-level Release Candidate.\n\n"
|
||||
"On-the-air use carries an obligation to report problems\n"
|
||||
"to the WSJT Development group and to upgrade to a GA\n"
|
||||
"(General Availability) release when it becomes available.\n\n"
|
||||
"This version cannot be used after October 31, 2018\n\n");
|
||||
"This version cannot be used after November 30, 2018\n\n");
|
||||
|
||||
if(now.daysTo(timeout) < 0) Q_EMIT finished();
|
||||
}
|
||||
@ -1107,7 +1090,8 @@ void MainWindow::readSettings()
|
||||
ui->cbFirst->setChecked(m_settings->value("CallFirst",true).toBool());
|
||||
ui->comboBoxHoundSort->setCurrentIndex(m_settings->value("HoundSort",3).toInt());
|
||||
ui->sbNlist->setValue(m_settings->value("FoxNlist",12).toInt());
|
||||
ui->sbNslots->setValue(m_settings->value("FoxNslots",5).toInt());
|
||||
m_Nslots=m_settings->value("FoxNslots",5).toInt();
|
||||
ui->sbNslots->setValue(m_Nslots);
|
||||
ui->sbMax_dB->setValue(m_settings->value("FoxMaxDB",30).toInt());
|
||||
m_settings->endGroup();
|
||||
|
||||
@ -1187,8 +1171,8 @@ void MainWindow::readSettings()
|
||||
m_audioThreadPriority = static_cast<QThread::Priority> (m_settings->value ("Audio/ThreadPriority", QThread::HighPriority).toInt () % 8);
|
||||
m_settings->endGroup ();
|
||||
|
||||
if (displayMsgAvg) on_actionMessage_averaging_triggered();
|
||||
setContestType();
|
||||
if(displayMsgAvg) on_actionMessage_averaging_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::setContestType()
|
||||
@ -1198,6 +1182,8 @@ void MainWindow::setContestType()
|
||||
if(m_config.bEU_VHF_Contest()) m_nContest=EU_VHF;
|
||||
if(m_config.bFieldDay()) m_nContest=FIELD_DAY;
|
||||
if(m_config.bRTTYroundup()) m_nContest=RTTY;
|
||||
if(m_config.bFox()) m_nContest=FOX;
|
||||
if(m_config.bHound()) m_nContest=HOUND;
|
||||
}
|
||||
|
||||
void MainWindow::set_application_font (QFont const& font)
|
||||
@ -1217,7 +1203,7 @@ void MainWindow::setDecodedTextFont (QFont const& font)
|
||||
ui->decodedTextBrowser->setContentFont (font);
|
||||
ui->decodedTextBrowser2->setContentFont (font);
|
||||
ui->textBrowser4->setContentFont(font);
|
||||
ui->textBrowser4->displayFoxToBeCalled(" ","#ffffff");
|
||||
ui->textBrowser4->displayFoxToBeCalled(" ");
|
||||
ui->textBrowser4->setText("");
|
||||
auto style_sheet = "QLabel {" + font_as_stylesheet (font) + '}';
|
||||
ui->decodedTextLabel->setStyleSheet (ui->decodedTextLabel->styleSheet () + style_sheet);
|
||||
@ -1524,11 +1510,13 @@ void MainWindow::fastSink(qint64 frames)
|
||||
int RxFreq=ui->RxFreqSpinBox->value ();
|
||||
int nTRpDepth=m_TRperiod + 1000*(m_ndepth & 3);
|
||||
qint64 ms0 = QDateTime::currentMSecsSinceEpoch();
|
||||
strncpy(dec_data.params.mycall, (m_baseCall+" ").toLatin1(),12);
|
||||
// strncpy(dec_data.params.mycall, (m_baseCall+" ").toLatin1(),12);
|
||||
strncpy(dec_data.params.mycall,(m_config.my_callsign () + " ").toLatin1(),12);
|
||||
QString hisCall {ui->dxCallEntry->text ()};
|
||||
bool bshmsg=ui->cbShMsgs->isChecked();
|
||||
bool bswl=ui->cbSWL->isChecked();
|
||||
strncpy(dec_data.params.hiscall,(Radio::base_callsign (hisCall) + " ").toLatin1 ().constData (), 12);
|
||||
// strncpy(dec_data.params.hiscall,(Radio::base_callsign (hisCall) + " ").toLatin1 ().constData (), 12);
|
||||
strncpy(dec_data.params.hiscall,(hisCall + " ").toLatin1 ().constData (), 12);
|
||||
strncpy(dec_data.params.mygrid, (m_config.my_grid()+" ").toLatin1(),6);
|
||||
QString dataDir;
|
||||
dataDir = m_config.writeable_data_dir ().absolutePath ();
|
||||
@ -1702,23 +1690,8 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
|
||||
}
|
||||
m_opCall=m_config.opCall();
|
||||
}
|
||||
setColorHighlighting();
|
||||
}
|
||||
|
||||
void MainWindow::setColorHighlighting()
|
||||
{
|
||||
//Inform the decoded text windows about our color-highlighting scheme.
|
||||
ui->decodedTextBrowser->setDecodedTextColors(m_config.color_CQ(),m_config.color_MyCall(),
|
||||
m_config.color_DXCC(),m_config.color_DXCCband(),m_config.color_NewCall(),
|
||||
m_config.color_NewCallBand(),m_config.color_NewGrid(),m_config.color_NewGridBand(),
|
||||
m_config.color_TxMsg(),m_config.color_LoTW());
|
||||
ui->decodedTextBrowser2->setDecodedTextColors(m_config.color_CQ(),m_config.color_MyCall(),
|
||||
m_config.color_DXCC(),m_config.color_DXCCband(),m_config.color_NewCall(),
|
||||
m_config.color_NewCallBand(),m_config.color_NewGrid(),m_config.color_NewGridBand(),
|
||||
m_config.color_TxMsg(),m_config.color_LoTW());
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_monitorButton_clicked (bool checked)
|
||||
{
|
||||
if (!m_transmitting) {
|
||||
@ -1836,6 +1809,9 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
on_stopTxButton_clicked();
|
||||
return;
|
||||
case Qt::Key_F1:
|
||||
on_actionOnline_User_Guide_triggered();
|
||||
return;
|
||||
@ -1860,21 +1836,33 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
on_actionOpen_next_in_directory_triggered();
|
||||
return;
|
||||
case Qt::Key_F11:
|
||||
n=11;
|
||||
if(e->modifiers() & Qt::ControlModifier) n+=100;
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()-60);
|
||||
} else{
|
||||
bumpFqso(n);
|
||||
if((e->modifiers() & Qt::ControlModifier) and (e->modifiers() & Qt::ShiftModifier)) {
|
||||
m_bandEdited = true;
|
||||
band_changed(m_freqNominal-2000);
|
||||
// qDebug() << "Down" << m_freqNominal;
|
||||
} else {
|
||||
n=11;
|
||||
if(e->modifiers() & Qt::ControlModifier) n+=100;
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()-60);
|
||||
} else{
|
||||
bumpFqso(n);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case Qt::Key_F12:
|
||||
n=12;
|
||||
if(e->modifiers() & Qt::ControlModifier) n+=100;
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()+60);
|
||||
if((e->modifiers() & Qt::ControlModifier) and (e->modifiers() & Qt::ShiftModifier)) {
|
||||
m_bandEdited = true;
|
||||
band_changed(m_freqNominal+2000);
|
||||
// qDebug() << "Up " << m_freqNominal;
|
||||
} else {
|
||||
bumpFqso(n);
|
||||
n=12;
|
||||
if(e->modifiers() & Qt::ControlModifier) n+=100;
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()+60);
|
||||
} else {
|
||||
bumpFqso(n);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case Qt::Key_X:
|
||||
@ -1936,7 +1924,13 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_PageUp:
|
||||
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
band_changed(m_freqNominal-2000);
|
||||
qDebug() << "Down" << m_freqNominal;
|
||||
break; }
|
||||
|
||||
QMainWindow::keyPressEvent (e);
|
||||
}
|
||||
@ -2184,7 +2178,7 @@ void MainWindow::closeEvent(QCloseEvent * e)
|
||||
m_prefixes.reset ();
|
||||
m_shortcuts.reset ();
|
||||
m_mouseCmnds.reset ();
|
||||
m_colorHighlighting.reset();
|
||||
m_colorHighlighting.reset ();
|
||||
if(m_mode!="MSK144" and m_mode!="FT8") killFile();
|
||||
float sw=0.0;
|
||||
int nw=400;
|
||||
@ -2221,6 +2215,12 @@ void MainWindow::on_actionFT8_DXpedition_Mode_User_Guide_triggered()
|
||||
{
|
||||
QDesktopServices::openUrl (QUrl {"http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf"});
|
||||
}
|
||||
|
||||
void MainWindow::on_actionQuick_Start_Guide_v2_triggered()
|
||||
{
|
||||
QDesktopServices::openUrl (QUrl {"https://physics.princeton.edu/pulsar/k1jt/Quick_Start_WSJT-X_2.0.pdf"});
|
||||
}
|
||||
|
||||
void MainWindow::on_actionOnline_User_Guide_triggered() //Display manual
|
||||
{
|
||||
#if defined (CMAKE_BUILD)
|
||||
@ -2387,32 +2387,29 @@ void MainWindow::on_actionAstronomical_data_toggled (bool checked)
|
||||
void MainWindow::on_actionFox_Log_triggered()
|
||||
{
|
||||
on_actionMessage_averaging_triggered();
|
||||
m_msgAvgWidget->foxLogSetup();
|
||||
m_msgAvgWidget->foxLogSetup(m_nContest);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionColors_triggered()
|
||||
{
|
||||
if (!m_colorHighlighting) {
|
||||
m_colorHighlighting.reset (new ColorHighlighting {m_settings});
|
||||
}
|
||||
m_colorHighlighting->showNormal();
|
||||
if (!m_colorHighlighting)
|
||||
{
|
||||
m_colorHighlighting.reset (new ColorHighlighting {m_settings, m_config.decode_highlighting ()});
|
||||
connect (&m_config, &Configuration::decode_highlighting_changed, m_colorHighlighting.data (), &ColorHighlighting::set_items);
|
||||
}
|
||||
m_colorHighlighting->showNormal ();
|
||||
m_colorHighlighting->raise ();
|
||||
m_colorHighlighting->activateWindow ();
|
||||
m_colorHighlighting->colorHighlightlingSetup(m_config.color_CQ(),m_config.color_MyCall(),
|
||||
m_config.color_DXCC(),m_config.color_DXCCband(),m_config.color_NewCall(),
|
||||
m_config.color_NewCallBand(),m_config.color_NewGrid(),m_config.color_NewGridBand(),
|
||||
m_config.color_TxMsg(),m_config.color_LoTW());
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMessage_averaging_triggered()
|
||||
{
|
||||
if (!m_msgAvgWidget)
|
||||
{
|
||||
m_msgAvgWidget.reset (new MessageAveraging {m_settings, m_config.decoded_text_font ()});
|
||||
if(!m_msgAvgWidget) {
|
||||
m_msgAvgWidget.reset (new MessageAveraging {m_settings, m_config.decoded_text_font ()});
|
||||
|
||||
// Connect signals from Message Averaging window
|
||||
connect (this, &MainWindow::finished, m_msgAvgWidget.data (), &MessageAveraging::close);
|
||||
}
|
||||
// Connect signals from Message Averaging window
|
||||
connect (this, &MainWindow::finished, m_msgAvgWidget.data (), &MessageAveraging::close);
|
||||
}
|
||||
m_msgAvgWidget->showNormal();
|
||||
m_msgAvgWidget->raise ();
|
||||
m_msgAvgWidget->activateWindow ();
|
||||
@ -2943,12 +2940,17 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
m_blankLine = false;
|
||||
}
|
||||
|
||||
DecodedText decodedtext {QString::fromUtf8(t.constData()).remove(QRegularExpression {"\r|\n"})};
|
||||
DecodedText decodedtext0 {QString::fromUtf8(t.constData())
|
||||
.remove(QRegularExpression {"\r|\n"})};
|
||||
DecodedText decodedtext {QString::fromUtf8(t.constData())
|
||||
.remove(QRegularExpression {"\r|\n"}).remove("TU; ")};
|
||||
|
||||
if(m_mode=="FT8" and m_config.bFox() and
|
||||
(decodedtext.string().contains("R+") or decodedtext.string().contains("R-"))) {
|
||||
auto for_us = decodedtext.string().contains(" " + m_config.my_callsign() + " ") or
|
||||
decodedtext.string().contains(" "+m_baseCall) or
|
||||
decodedtext.string().contains(m_baseCall+" ");
|
||||
decodedtext.string().contains(m_baseCall+" ") or
|
||||
decodedtext.string().contains(" <" + m_config.my_callsign() + "> ");
|
||||
if(decodedtext.string().contains(" DE ")) for_us=true; //Hound with compound callsign
|
||||
if(for_us) {
|
||||
QString houndCall,houndGrid;
|
||||
@ -2956,7 +2958,8 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
foxRxSequencer(decodedtext.string(),houndCall,houndGrid);
|
||||
}
|
||||
}
|
||||
//Left (Band activity) window
|
||||
|
||||
//Left (Band activity) window
|
||||
if(!bAvgMsg) {
|
||||
if(m_mode=="FT8" and m_config.bFox()) {
|
||||
if(!m_bDisplayedOnce) {
|
||||
@ -2967,13 +2970,13 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
m_bDisplayedOnce=true;
|
||||
}
|
||||
} else {
|
||||
ui->decodedTextBrowser->displayDecodedText(decodedtext,m_baseCall,m_config.DXCC(),
|
||||
ui->decodedTextBrowser->displayDecodedText(decodedtext0,m_baseCall,m_config.DXCC(),
|
||||
m_logBook,m_currentBand,m_config.ppfx(),
|
||||
(ui->cbCQonly->isVisible() and ui->cbCQonly->isChecked()));
|
||||
}
|
||||
}
|
||||
|
||||
//Right (Rx Frequency) window
|
||||
//Right (Rx Frequency) window
|
||||
bool bDisplayRight=bAvgMsg;
|
||||
int audioFreq=decodedtext.frequencyOffset();
|
||||
|
||||
@ -3002,7 +3005,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
if (bDisplayRight) {
|
||||
// This msg is within 10 hertz of our tuned frequency, or a JT4 or JT65 avg,
|
||||
// or contains MyCall
|
||||
ui->decodedTextBrowser2->displayDecodedText(decodedtext,m_baseCall,m_config.DXCC(),
|
||||
ui->decodedTextBrowser2->displayDecodedText(decodedtext0,m_baseCall,m_config.DXCC(),
|
||||
m_logBook,m_currentBand,m_config.ppfx());
|
||||
|
||||
if(m_mode!="JT4") {
|
||||
@ -3056,8 +3059,9 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
|
||||
//### I think this is where we are preventing Hounds from spotting Fox ###
|
||||
if(m_mode!="FT8" or !m_config.bHound()) {
|
||||
if(m_mode=="FT8" or m_mode=="QRA64" or m_mode=="JT4" or m_mode=="JT65" or
|
||||
m_mode=="JT9") auto_sequence (decodedtext, 25, 50);
|
||||
if(m_mode=="FT8" or m_mode=="QRA64" or m_mode=="JT4" or m_mode=="JT65" or m_mode=="JT9") {
|
||||
auto_sequence (decodedtext, 25, 50);
|
||||
}
|
||||
postDecode (true, decodedtext.string ());
|
||||
|
||||
// find and extract any report for myCall, but save in m_rptRcvd only if it's from DXcall
|
||||
@ -3130,7 +3134,7 @@ void MainWindow::auto_sequence (DecodedText const& message, unsigned start_toler
|
||||
}
|
||||
}
|
||||
bool bEU_VHF_w2=(nrpt>=520001 and nrpt<=594000);
|
||||
if(bEU_VHF_w2) m_xRcvd=message.string().left(45).trimmed().right(13);
|
||||
if(bEU_VHF_w2) m_xRcvd=message.string().trimmed().right(13);
|
||||
if (m_auto
|
||||
&& (m_QSOProgress==REPLYING or (!ui->tx1->isEnabled () and m_QSOProgress==REPORT))
|
||||
&& qAbs (ui->TxFreqSpinBox->value () - df) <= int (stop_tolerance)
|
||||
@ -3333,13 +3337,9 @@ void MainWindow::guiUpdate()
|
||||
auto const& message = tr ("Please choose another Tx frequency."
|
||||
" WSJT-X will not knowingly transmit another"
|
||||
" mode in the WSPR sub-band on 30m.");
|
||||
#if QT_VERSION >= 0x050400
|
||||
QTimer::singleShot (0, [=] { // don't block guiUpdate
|
||||
MessageBox::warning_message (this, tr ("WSPR Guard Band"), message);
|
||||
});
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("WSPR Guard Band"), message);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -3354,13 +3354,9 @@ void MainWindow::guiUpdate()
|
||||
auto const& message = tr ("Please choose another dial frequency."
|
||||
" WSJT-X will not operate in Fox mode"
|
||||
" in the standard FT8 sub-bands.");
|
||||
#if QT_VERSION >= 0x050400
|
||||
QTimer::singleShot (0, [=] { // don't block guiUpdate
|
||||
MessageBox::warning_message (this, tr ("Fox Mode warning"), message);
|
||||
});
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("Fox Mode warning"), message);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3580,7 +3576,6 @@ void MainWindow::guiUpdate()
|
||||
m_xSent=t.at(n-2) + " " + t.at(n-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(m_isync==1) msgsent[22]=0;
|
||||
if(m_isync==2) msgsent[37]=0;
|
||||
@ -3629,18 +3624,20 @@ void MainWindow::guiUpdate()
|
||||
if(m_config.id_after_73 ()) {
|
||||
icw[0] = m_ncw;
|
||||
}
|
||||
if (m_config.prompt_to_log () && !m_tune) {
|
||||
logQSOTimer.start (0);
|
||||
}
|
||||
if((m_config.prompt_to_log() or m_config.autoLog()) && !m_tune) logQSOTimer.start(0);
|
||||
}
|
||||
|
||||
bool b=(m_mode=="FT8") and ui->cbAutoSeq->isChecked();
|
||||
if(is_73 and (m_config.disable_TX_on_73() or b)) {
|
||||
auto_tx_mode (false);
|
||||
if(b) {
|
||||
m_ntx=6;
|
||||
ui->txrb6->setChecked(true);
|
||||
m_QSOProgress = CALLING;
|
||||
if(m_nextCall!="") {
|
||||
useNextCall();
|
||||
} else {
|
||||
auto_tx_mode (false);
|
||||
if(b) {
|
||||
m_ntx=6;
|
||||
ui->txrb6->setChecked(true);
|
||||
m_QSOProgress = CALLING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3741,7 +3738,7 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
|
||||
if(m_mode=="FT8" or m_mode=="MSK144") {
|
||||
if(ui->txrb1->isEnabled() and m_nContest!=NONE and m_nContest!=EU_VHF) {
|
||||
if(ui->txrb1->isEnabled() and (m_nContest==NA_VHF or m_nContest==FIELD_DAY or m_nContest==RTTY)) {
|
||||
//We're in a contest-like mode other than EU_VHF: start QSO with Tx2.
|
||||
ui->tx1->setEnabled(false);
|
||||
}
|
||||
@ -3753,8 +3750,8 @@ void MainWindow::guiUpdate()
|
||||
|
||||
//Once per second:
|
||||
if(nsec != m_sec0) {
|
||||
// qDebug() << "OneSec:";
|
||||
|
||||
// qDebug() << "OneSec:" << m_nContest << m_Nslots;
|
||||
if(!m_msgAvgWidget and m_nContest>0 and m_nContest<6) on_actionFox_Log_triggered();
|
||||
if(m_freqNominal!=0 and m_freqNominal<50000000 and m_config.enable_VHF_features()) {
|
||||
if(!m_bVHFwarned) vhfWarning();
|
||||
} else {
|
||||
@ -3762,21 +3759,7 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
m_currentBand=m_config.bands()->find(m_freqNominal);
|
||||
|
||||
// if(m_config.bFox()) {
|
||||
// if(m_config.my_callsign()=="K1JT" or m_config.my_callsign()=="K9AN" or
|
||||
// m_config.my_callsign()=="G4WJS" or m_config.my_callsign().contains("KH7Z")) {
|
||||
// ui->sbNslots->setMaximum(5);
|
||||
// m_Nslots=ui->sbNslots->value();
|
||||
// ui->sbNslots->setEnabled(true);
|
||||
// } else {
|
||||
// ui->sbNslots->setMaximum(1);
|
||||
// m_Nslots=1;
|
||||
// ui->sbNslots->setEnabled(false);
|
||||
// }
|
||||
// }
|
||||
|
||||
if(m_config.bHound()) {
|
||||
// m_bWarnedHound=false;
|
||||
qint32 tHound=QDateTime::currentMSecsSinceEpoch()/1000 - m_tAutoOn;
|
||||
//To keep calling Fox, Hound must reactivate Enable Tx at least once every 2 minutes
|
||||
if(tHound >= 120 and m_ntx==1) auto_tx_mode(false);
|
||||
@ -3860,6 +3843,22 @@ void MainWindow::guiUpdate()
|
||||
m_btxok0=m_btxok;
|
||||
} //End of guiUpdate
|
||||
|
||||
void MainWindow::useNextCall()
|
||||
{
|
||||
ui->dxCallEntry->setText(m_nextCall);
|
||||
m_nextCall="";
|
||||
ui->labNextCall->setStyleSheet("");
|
||||
ui->labNextCall->setText("");
|
||||
if(m_nextGrid.contains(grid_regexp)) {
|
||||
ui->dxGridEntry->setText(m_nextGrid);
|
||||
m_ntx=2;
|
||||
ui->txrb2->setChecked(true);
|
||||
} else {
|
||||
m_ntx=3;
|
||||
ui->txrb3->setChecked(true);
|
||||
}
|
||||
genStdMsgs(m_nextRpt);
|
||||
}
|
||||
|
||||
void MainWindow::startTx2()
|
||||
{
|
||||
@ -4218,6 +4217,14 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
QString hiscall;
|
||||
QString hisgrid;
|
||||
message.deCallAndGrid(/*out*/hiscall,hisgrid);
|
||||
if(message.string().contains(hiscall+"/R")) {
|
||||
hiscall+="/R";
|
||||
ui->dxCallEntry->setText(hiscall);
|
||||
}
|
||||
if(message.string().contains(hiscall+"/P")) {
|
||||
hiscall+="/P";
|
||||
ui->dxCallEntry->setText(hiscall);
|
||||
}
|
||||
|
||||
bool is_73 = message_words.filter (QRegularExpression {"^(73|RR73)$"}).size ();
|
||||
if (!is_73 and !message.isStandardMessage() and !message.string().contains("<")) {
|
||||
@ -4264,7 +4271,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
}
|
||||
|
||||
// prior DX call (possible QSO partner)
|
||||
auto qso_partner_base_call = Radio::base_callsign (ui->dxCallEntry-> text ());
|
||||
auto qso_partner_base_call = Radio::base_callsign (ui->dxCallEntry->text ());
|
||||
auto base_call = Radio::base_callsign (hiscall);
|
||||
|
||||
// Determine appropriate response to received message
|
||||
@ -4277,7 +4284,8 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
|| dtext.contains ("/" + m_baseCall + " ")
|
||||
|| dtext.contains (" " + m_baseCall + "/")
|
||||
|| (firstcall == "DE")) {
|
||||
QString w2=message_words.at(2);
|
||||
QString w2="";
|
||||
if(message_words.size()>=3) w2=message_words.at(2);
|
||||
QString w34="";
|
||||
if(message_words.size()>=4) w34=message_words.at(3);
|
||||
int nrpt=w2.toInt();
|
||||
@ -4366,8 +4374,19 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
if (ui->rbGenMsg->isChecked ()) m_ntx=7;
|
||||
m_gen_message_is_cq = false;
|
||||
} else {
|
||||
m_ntx=5;
|
||||
ui->txrb5->setChecked(true);
|
||||
m_bTUmsg=false;
|
||||
if(m_nContest==RTTY and m_nextCall!="") {
|
||||
// We're in RTTY contest and have "nextCall" queued up: send a "TU; ..." message
|
||||
on_logQSOButton_clicked();
|
||||
ui->tx3->setText(ui->tx3->text().remove("TU; "));
|
||||
useNextCall();
|
||||
QString t="TU; " + ui->tx3->text();
|
||||
ui->tx3->setText(t);
|
||||
m_bTUmsg=true;
|
||||
} else {
|
||||
m_ntx=5;
|
||||
ui->txrb5->setChecked(true);
|
||||
}
|
||||
}
|
||||
m_QSOProgress = SIGNOFF;
|
||||
} else if((m_QSOProgress >= REPORT
|
||||
@ -4400,7 +4419,8 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
}
|
||||
}
|
||||
else if (m_QSOProgress >= ROGERS
|
||||
&& message_words.size () > 2 && message_words.at (1).contains (m_baseCall) && message_words.at (2) == "73") {
|
||||
&& message_words.size () > 2 && message_words.at (1).contains (m_baseCall)
|
||||
&& message_words.at (2) == "73") {
|
||||
// 73 back to compound call holder
|
||||
if(ui->tabWidget->currentIndex()==1) {
|
||||
gen_msg = 5;
|
||||
@ -4414,7 +4434,8 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
m_QSOProgress = SIGNOFF;
|
||||
}
|
||||
else if (!(m_bAutoReply && m_QSOProgress > CALLING)) {
|
||||
if ((message_words.size () > 4 && message_words.at (1).contains (m_baseCall) && message_words.at (4) == "OOO")) {
|
||||
if ((message_words.size () > 4 && message_words.at (1).contains (m_baseCall)
|
||||
&& message_words.at (4) == "OOO")) {
|
||||
// EME short code report or MSK144/FT8 contest mode reply, send back Tx3
|
||||
m_ntx=3;
|
||||
m_QSOProgress = ROGER_REPORT;
|
||||
@ -4445,6 +4466,17 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
}
|
||||
}
|
||||
else { // nothing for us
|
||||
if(message_words.size () > 3 // enough fields for a normal message
|
||||
&& m_nContest==RTTY
|
||||
&& (message_words.at(1).contains(m_baseCall) || "DE" == message_words.at(1))
|
||||
&& (!message_words.at(2).contains(qso_partner_base_call) and !bEU_VHF_w2)) {
|
||||
// Queue up the next QSO partner
|
||||
m_nextCall=message_words.at(2);
|
||||
m_nextGrid=message_words.at(3);
|
||||
m_nextRpt=message.report();
|
||||
ui->labNextCall->setText("Next: " + m_nextCall);
|
||||
ui->labNextCall->setStyleSheet("QLabel {background-color: #66ff66}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4488,7 +4520,8 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
ui->txrb5->setChecked(true);
|
||||
}
|
||||
m_QSOProgress = SIGNOFF;
|
||||
} else {// just work them
|
||||
} else {
|
||||
// just work them
|
||||
if (ui->tx1->isEnabled ()) {
|
||||
m_ntx = 1;
|
||||
m_QSOProgress = REPLYING;
|
||||
@ -4554,7 +4587,8 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
}
|
||||
|
||||
ui->rptSpinBox->setValue(n);
|
||||
if (!m_nTx73) { // Don't genStdMsgs if we're already sending 73.
|
||||
// Don't genStdMsgs if we're already sending 73, or a "TU; " msg is queued.
|
||||
if (!m_nTx73 and !m_bTUmsg) {
|
||||
genStdMsgs(rpt);
|
||||
if (gen_msg) {
|
||||
switch (gen_msg) {
|
||||
@ -4610,7 +4644,8 @@ void MainWindow::genCQMsg ()
|
||||
}
|
||||
} else {
|
||||
if(stdCall(m_config.my_callsign())) {
|
||||
msgtype (QString {"%1 %2 %3"}.arg(m_CQtype).arg(m_config.my_callsign()).arg(grid.left(4)),ui->tx6);
|
||||
msgtype (QString {"%1 %2 %3"}.arg(m_CQtype).arg(m_config.my_callsign())
|
||||
.arg(grid.left(4)),ui->tx6);
|
||||
} else {
|
||||
msgtype (QString {"%1 %2"}.arg(m_CQtype).arg(m_config.my_callsign()),ui->tx6);
|
||||
}
|
||||
@ -4623,11 +4658,14 @@ void MainWindow::genCQMsg ()
|
||||
}
|
||||
}
|
||||
|
||||
if((m_mode=="FT8" or m_mode=="MSK144") and m_nContest!=NONE) {
|
||||
QString t=ui->tx6->text();
|
||||
// if(m_nContest==NA_VHF) t="CQ QP" + t.mid(2,-1);
|
||||
QString t=ui->tx6->text();
|
||||
if((m_mode=="FT8" or m_mode=="MSK144") and m_nContest!=NONE and
|
||||
t.split(" ").at(1)==m_config.my_callsign() and stdCall(m_config.my_callsign())) {
|
||||
if(m_nContest==NA_VHF) t="CQ TEST" + t.mid(2,-1);
|
||||
if(m_nContest==EU_VHF) t="CQ TEST" + t.mid(2,-1);
|
||||
if(m_nContest==FIELD_DAY) t="CQ FD" + t.mid(2,-1);
|
||||
if(m_nContest==RTTY) t="CQ RU" + t.mid(2,-1);
|
||||
if(m_nContest==FOX) t="CQ HUND" + t.mid(2,-1);
|
||||
ui->tx6->setText(t);
|
||||
}
|
||||
} else {
|
||||
@ -4661,7 +4699,11 @@ bool MainWindow::stdCall(QString w)
|
||||
}
|
||||
|
||||
void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
{
|
||||
{
|
||||
if(ui->tx3->text().left(4)=="TU; ") {
|
||||
return;
|
||||
}
|
||||
|
||||
genCQMsg ();
|
||||
auto const& hisCall=ui->dxCallEntry->text();
|
||||
if(!hisCall.size ()) {
|
||||
@ -4686,19 +4728,22 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
|
||||
bool bMyCall=stdCall(my_callsign);
|
||||
bool bHisCall=stdCall(hisCall);
|
||||
bool b77=(m_mode=="MSK144" or m_mode=="FT8") and (!bMyCall or !bHisCall);
|
||||
bool b77=(m_mode=="MSK144" or m_mode=="FT8") and
|
||||
(!bMyCall or !bHisCall or m_config.bGenerate77());
|
||||
|
||||
QString t0=hisBase + " " + m_baseCall + " ";
|
||||
QString t0s=hisCall + " " + my_callsign + " ";
|
||||
QString t0a,t0b;
|
||||
if(b77) {
|
||||
// if(bHisCall and bMyCall) t0=hisCall + " " + my_callsign + " ";
|
||||
if(bHisCall and bMyCall) t0=hisCall + " " + my_callsign + " ";
|
||||
t0a="<"+hisCall + "> " + my_callsign + " ";
|
||||
t0b=hisCall + " <" + my_callsign + "> ";
|
||||
}
|
||||
|
||||
QString t00=t0;
|
||||
QString t {t0 + my_grid};
|
||||
if(b77 and (!bMyCall or !bHisCall)) t=t0a;
|
||||
// if(b77 and (!bMyCall or !bHisCall)) t=t0a;
|
||||
if(b77 and (!bMyCall)) t=t0a;
|
||||
msgtype(t, ui->tx1);
|
||||
if (eme_short_codes) {
|
||||
t=t+" OOO";
|
||||
@ -4744,8 +4789,8 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
}
|
||||
|
||||
if(m_mode=="MSK144" and m_bShMsgs) {
|
||||
int i=t0.length()-1;
|
||||
t0="<" + t0.mid(0,i) + "> ";
|
||||
int i=t0s.length()-1;
|
||||
t0="<" + t0s.mid(0,i) + "> ";
|
||||
if(!m_config.bNA_VHF_Contest()) {
|
||||
if(n<=-2) n=-3;
|
||||
if(n>=-1 and n<=1) n=0;
|
||||
@ -4764,14 +4809,14 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
t=t0 + "R" + rpt;
|
||||
msgtype(t, ui->tx3);
|
||||
}
|
||||
if(m_mode=="MSK144" and m_bShMsgs) {
|
||||
if(m_mode=="MSK144" and m_bShMsgs and m_nContest==NONE) {
|
||||
t=t0 + "R" + rpt;
|
||||
msgtype(t, ui->tx3);
|
||||
m_send_RR73=false;
|
||||
}
|
||||
|
||||
t=t0 + (m_send_RR73 ? "RR73" : "RRR");
|
||||
if(m_mode=="MSK144" or m_mode=="FT8") {
|
||||
if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8") {
|
||||
if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> " + (m_send_RR73 ? "RR73" : "RRR");
|
||||
if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " " + (m_send_RR73 ? "RR73" : "RRR");
|
||||
}
|
||||
@ -4779,7 +4824,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
msgtype(t, ui->tx4);
|
||||
|
||||
t=t0 + "73";
|
||||
if(m_mode=="MSK144" or m_mode=="FT8") {
|
||||
if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8") {
|
||||
if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> 73";
|
||||
if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " 73";
|
||||
}
|
||||
@ -4795,7 +4840,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
}
|
||||
}
|
||||
|
||||
if(m_config.bGenerate77()) return;
|
||||
if(m_config.bGenerate77() or "MSK144" == m_mode) return;
|
||||
|
||||
if (is_compound) {
|
||||
if (is_type_one) {
|
||||
@ -5180,22 +5225,38 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
|
||||
if (dateTimeQSOOff < m_dateTimeQSOOn) dateTimeQSOOff = m_dateTimeQSOOn;
|
||||
QString grid=m_hisGrid;
|
||||
if(grid=="....") grid="";
|
||||
m_logDlg->initLogQSO (m_hisCall, grid, m_modeTx, m_rptSent, m_rptRcvd,
|
||||
m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal + ui->TxFreqSpinBox->value(),
|
||||
m_config.my_callsign(), m_config.my_grid(), m_noSuffix,
|
||||
m_config.log_as_RTTY(), m_config.report_in_comments(),
|
||||
m_config.bFox(), m_opCall);
|
||||
if(m_nContest!=NONE) {
|
||||
if(m_nContest>NONE and m_nContest<FOX) {
|
||||
if(m_nContest==NA_VHF) {
|
||||
m_xSent=m_config.my_grid().left(4);
|
||||
m_xRcvd=m_hisGrid;
|
||||
}
|
||||
if(m_nContest!=NONE) {
|
||||
int n=ui->sbSerialNumber->value();
|
||||
ui->sbSerialNumber->setValue(n+1);
|
||||
cabLog(); //Call the Cabrillo contest logger
|
||||
if(m_nContest==EU_VHF) {
|
||||
m_rptSent=m_xSent.split(" ").at(0).left(2);
|
||||
m_rptRcvd=m_xRcvd.split(" ").at(0).left(2);
|
||||
m_hisGrid=m_xRcvd.split(" ").at(1);
|
||||
grid=m_hisGrid;
|
||||
ui->dxGridEntry->setText(grid);
|
||||
}
|
||||
if(m_nContest==FIELD_DAY) {
|
||||
m_rptSent=m_xSent.split(" ").at(0);
|
||||
m_rptRcvd=m_xRcvd.split(" ").at(0);
|
||||
}
|
||||
if(m_nContest==RTTY) {
|
||||
m_rptSent=m_xSent.split(" ").at(0);
|
||||
m_rptRcvd=m_xRcvd.split(" ").at(0);
|
||||
}
|
||||
int n=ui->sbSerialNumber->value();
|
||||
ui->sbSerialNumber->setValue(n+1);
|
||||
cabLog(); //Call the Cabrillo contest logger
|
||||
}
|
||||
|
||||
bool bAutoLog=m_config.autoLog() and m_nContest>0;
|
||||
m_logDlg->initLogQSO (m_hisCall, grid, m_modeTx, m_rptSent, m_rptRcvd,
|
||||
m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal +
|
||||
ui->TxFreqSpinBox->value(), m_config.my_callsign(),
|
||||
m_config.my_grid(), m_noSuffix, m_config.log_as_RTTY(),
|
||||
m_config.report_in_comments(), m_config.bFox(),
|
||||
bAutoLog, m_opCall, m_nContest, m_xSent, m_xRcvd);
|
||||
}
|
||||
|
||||
void MainWindow::cabLog()
|
||||
@ -5205,13 +5266,22 @@ void MainWindow::cabLog()
|
||||
int nfreq=m_freqNominal/1000;
|
||||
if(m_freqNominal>50000000) nfreq=m_freqNominal/1000000;
|
||||
QString t;
|
||||
t.sprintf("QSO: %5d RY ",nfreq);
|
||||
t.sprintf("QSO: %5d DG ",nfreq);
|
||||
t=t + QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd hhmm ") +
|
||||
m_config.my_callsign().leftJustified(13,' ') + m_xSent.leftJustified(14,' ') +
|
||||
m_hisCall.leftJustified(13,' ') + m_xRcvd;
|
||||
QTextStream out(&f);
|
||||
out << t << endl;
|
||||
f.close();
|
||||
if(m_msgAvgWidget != NULL and m_msgAvgWidget->isVisible()) {
|
||||
QString band;
|
||||
band.sprintf(" %5d ",nfreq);
|
||||
t=QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd hhmm ") + band +
|
||||
m_hisCall.leftJustified(13,' ') + m_xSent.leftJustified(14,' ') + m_xRcvd;
|
||||
m_msgAvgWidget->contestAddLog(m_nContest,t);
|
||||
}
|
||||
m_xSent="";
|
||||
m_xRcvd="";
|
||||
} else {
|
||||
MessageBox::warning_message (this, tr("File Open Error"),
|
||||
tr("Cannot open \"%1\" for append: %2").arg(f.fileName()).arg(f.errorString()));
|
||||
@ -5289,7 +5359,7 @@ void MainWindow::displayWidgets(qint64 n)
|
||||
if(i==25) ui->actionEnable_AP_JT65->setVisible (b);
|
||||
if(i==26) ui->actionEnable_AP_DXcall->setVisible (b);
|
||||
if(i==27) ui->cbFirst->setVisible(b);
|
||||
// if(i==28) ui->cbVHFcontest->setVisible(b);
|
||||
if(i==28) ui->labNextCall->setVisible(b);
|
||||
if(i==29) ui->measure_check_box->setVisible(b);
|
||||
if(i==30) ui->labDXped->setVisible(b);
|
||||
if(i==31) ui->cbRxAll->setVisible(b);
|
||||
@ -5338,7 +5408,7 @@ void MainWindow::on_actionFT8_triggered()
|
||||
ui->label_6->setText("Band Activity");
|
||||
ui->decodedTextLabel->setText( " UTC dB DT Freq Message");
|
||||
}
|
||||
displayWidgets(nWidgets("111010000100111000010000100100001"));
|
||||
displayWidgets(nWidgets("111010000100111000010000100110001"));
|
||||
ui->txrb2->setEnabled(true);
|
||||
ui->txrb4->setEnabled(true);
|
||||
ui->txrb5->setEnabled(true);
|
||||
@ -5357,7 +5427,7 @@ void MainWindow::on_actionFT8_triggered()
|
||||
ui->tabWidget->setCurrentIndex(2);
|
||||
ui->TxFreqSpinBox->setValue(300);
|
||||
displayWidgets(nWidgets("111010000100111000010000000000100"));
|
||||
ui->labDXped->setText("DXpedition: Fox");
|
||||
ui->labDXped->setText("Fox");
|
||||
on_actionFox_Log_triggered();
|
||||
}
|
||||
if(m_config.bHound()) {
|
||||
@ -5367,7 +5437,7 @@ void MainWindow::on_actionFT8_triggered()
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
ui->cbHoldTxFreq->setChecked(true);
|
||||
displayWidgets(nWidgets("111010000100110000010000000000110"));
|
||||
ui->labDXped->setText("DXpedition: Hound");
|
||||
ui->labDXped->setText("Hound");
|
||||
ui->txrb1->setChecked(true);
|
||||
ui->txrb2->setEnabled(false);
|
||||
ui->txrb4->setEnabled(false);
|
||||
@ -5964,6 +6034,17 @@ void MainWindow::on_actionErase_cabrillo_log_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExport_Cabrillo_log_triggered()
|
||||
{
|
||||
if(!m_exportCabrillo) {
|
||||
m_exportCabrillo.reset(new ExportCabrillo{m_settings});
|
||||
}
|
||||
QString CabLog=m_config.writeable_data_dir ().absoluteFilePath ("cabrillo.log");
|
||||
m_exportCabrillo->setFile(CabLog);
|
||||
m_exportCabrillo->exec();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionErase_wsjtx_log_adi_triggered()
|
||||
{
|
||||
int ret = MessageBox::query_message (this, tr ("Confirm Erase"),
|
||||
@ -6223,6 +6304,7 @@ void MainWindow::on_tuneButton_clicked (bool checked)
|
||||
}
|
||||
else { // we're turning off so remember our Tune pwr setting and reset to Tx pwr
|
||||
if (m_config.pwrBandTuneMemory() || m_config.pwrBandTxMemory()) {
|
||||
stopTx();
|
||||
m_pwrBandTuneMemory[curBand] = ui->outAttenuation->value(); // remember our Tune pwr
|
||||
m_PwrBandSetOK = false;
|
||||
ui->outAttenuation->setValue(m_pwrBandTxMemory[curBand].toInt()); // set to Tx pwr
|
||||
@ -6767,7 +6849,7 @@ void::MainWindow::VHF_features_enabled(bool b)
|
||||
ui->actionMessage_averaging->setEnabled(b);
|
||||
ui->actionEnable_AP_DXcall->setVisible (m_mode=="QRA64");
|
||||
ui->actionEnable_AP_JT65->setVisible (b && m_mode=="JT65");
|
||||
if(!b && m_msgAvgWidget and !m_config.bFox()) {
|
||||
if(!b && m_msgAvgWidget and !m_config.bFox() and !m_config.autoLog()) {
|
||||
if(m_msgAvgWidget->isVisible()) m_msgAvgWidget->close();
|
||||
}
|
||||
}
|
||||
@ -6898,27 +6980,28 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
|
||||
|
||||
QString format_string {"%1 %2 %3 %4 %5 %6"};
|
||||
auto const& time_string = time.toString ("~" == mode || "&" == mode ? "hhmmss" : "hhmm");
|
||||
auto cqtext = format_string
|
||||
auto message_line = format_string
|
||||
.arg (time_string)
|
||||
.arg (snr, 3)
|
||||
.arg (delta_time, 4, 'f', 1)
|
||||
.arg (delta_frequency, 4)
|
||||
.arg (mode, -2)
|
||||
.arg (message_text);
|
||||
auto messages = ui->decodedTextBrowser->toPlainText ();
|
||||
auto position = messages.lastIndexOf (cqtext);
|
||||
if (position < 0)
|
||||
QTextCursor start {ui->decodedTextBrowser->document ()};
|
||||
start.movePosition (QTextCursor::End);
|
||||
auto cursor = ui->decodedTextBrowser->document ()->find (message_line, start, QTextDocument::FindBackward);
|
||||
if (cursor.isNull ())
|
||||
{
|
||||
// try again with with -0.0 delta time
|
||||
position = messages.lastIndexOf (format_string
|
||||
.arg (time_string)
|
||||
.arg (snr, 3)
|
||||
.arg ('-' + QString::number (delta_time, 'f', 1), 4)
|
||||
.arg (delta_frequency, 4)
|
||||
.arg (mode, -2)
|
||||
.arg (message_text));
|
||||
cursor = ui->decodedTextBrowser->document ()->find (format_string
|
||||
.arg (time_string)
|
||||
.arg (snr, 3)
|
||||
.arg ('-' + QString::number (delta_time, 'f', 1), 4)
|
||||
.arg (delta_frequency, 4)
|
||||
.arg (mode, -2)
|
||||
.arg (message_text), start, QTextDocument::FindBackward);
|
||||
}
|
||||
if (position >= 0)
|
||||
if (!cursor.isNull ())
|
||||
{
|
||||
if (m_config.udpWindowToFront ())
|
||||
{
|
||||
@ -6931,14 +7014,11 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
|
||||
showNormal ();
|
||||
raise ();
|
||||
}
|
||||
// find the linefeed at the end of the line
|
||||
position = ui->decodedTextBrowser->toPlainText().indexOf(QChar::LineFeed,position);
|
||||
if (message_text.contains (QRegularExpression {R"(^(CQ |CQDX |QRZ ))"})) {
|
||||
// a message we are willing to accept and auto reply to
|
||||
m_bDoubleClicked = true;
|
||||
}
|
||||
auto start = messages.left (position).lastIndexOf (QChar::LineFeed) + 1;
|
||||
DecodedText message {messages.mid (start, position - start)};
|
||||
DecodedText message {message_line};
|
||||
Qt::KeyboardModifiers kbmod {modifiers << 24};
|
||||
processMessage (message, kbmod);
|
||||
tx_watchdog (false);
|
||||
@ -6946,7 +7026,7 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug () << "process reply message ignored, decode not found:" << cqtext;
|
||||
qDebug () << "process reply message ignored, decode not found:" << message_line;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6983,10 +7063,12 @@ void MainWindow::replayDecodes ()
|
||||
// is not checked
|
||||
|
||||
// attempt to parse the decoded text
|
||||
Q_FOREACH (auto const& message
|
||||
, ui->decodedTextBrowser->toPlainText ().split (QChar::LineFeed,
|
||||
QString::SkipEmptyParts))
|
||||
for (QTextBlock block = ui->decodedTextBrowser->document ()->firstBlock (); block.isValid (); block = block.next ())
|
||||
{
|
||||
auto message = block.text ();
|
||||
message = message.left (message.indexOf (QChar::Nbsp)); // discard
|
||||
// any
|
||||
// appended info
|
||||
if (message.size() >= 4 && message.left (4) != "----")
|
||||
{
|
||||
auto const& parts = message.split (' ', QString::SkipEmptyParts);
|
||||
@ -6996,14 +7078,8 @@ void MainWindow::replayDecodes ()
|
||||
}
|
||||
else
|
||||
{
|
||||
auto eom_pos = message.indexOf (' ', 35);
|
||||
// we always want at least the characters to position 35
|
||||
if (eom_pos < 35)
|
||||
{
|
||||
eom_pos = message.size () - 1;
|
||||
}
|
||||
// TODO - how to skip ISCAT decodes
|
||||
postDecode (false, message.left (eom_pos + 1));
|
||||
postDecode (false, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7607,13 +7683,9 @@ void MainWindow::write_transmit_entry (QString const& file_name)
|
||||
{
|
||||
auto const& message = tr ("Cannot open \"%1\" for append: %2")
|
||||
.arg (f.fileName ()).arg (f.errorString ());
|
||||
#if QT_VERSION >= 0x050400
|
||||
QTimer::singleShot (0, [=] { // don't block guiUpdate
|
||||
MessageBox::warning_message (this, tr ("Log File Error"), message);
|
||||
});
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("Log File Error"), message);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -7802,9 +7874,9 @@ void MainWindow::selectHound(QString line)
|
||||
if(rpt.mid(0,1) != "-" and rpt.mid(0,1) != "+") t2="+" + rpt;
|
||||
if(t2.length()==2) t2=t2.mid(0,1) + "0" + t2.mid(1,1);
|
||||
t1=t1.mid(0,12) + t2;
|
||||
ui->textBrowser4->displayFoxToBeCalled(t1,"#ffffff"); // Add hound call and rpt to tb4
|
||||
t1=t1 + " " + houndGrid; // Append the grid
|
||||
m_houndQueue.enqueue(t1); // Put this hound into the queue
|
||||
ui->textBrowser4->displayFoxToBeCalled(t1); // Add hound call and rpt to tb4
|
||||
t1=t1 + " " + houndGrid; // Append the grid
|
||||
m_houndQueue.enqueue(t1); // Put this hound into the queue
|
||||
writeFoxQSO(" Sel: " + t1);
|
||||
QTextCursor cursor = ui->textBrowser4->textCursor();
|
||||
cursor.setPosition(0); // Scroll to top of list
|
||||
|
14
mainwindow.h
14
mainwindow.h
@ -36,6 +36,7 @@
|
||||
#include "astro.h"
|
||||
#include "MessageBox.hpp"
|
||||
#include "NetworkAccessManager.hpp"
|
||||
#include "ExportCabrillo.h"
|
||||
|
||||
#define NUM_JT4_SYMBOLS 206 //(72+31)*2, embedded sync
|
||||
#define NUM_JT65_SYMBOLS 126 //63 data + 63 sync
|
||||
@ -139,6 +140,7 @@ private slots:
|
||||
void on_stopButton_clicked();
|
||||
void on_actionRelease_Notes_triggered ();
|
||||
void on_actionFT8_DXpedition_Mode_User_Guide_triggered();
|
||||
void on_actionQuick_Start_Guide_v2_triggered();
|
||||
void on_actionOnline_User_Guide_triggered();
|
||||
void on_actionLocal_User_Guide_triggered();
|
||||
void on_actionWide_Waterfall_triggered();
|
||||
@ -202,6 +204,7 @@ private slots:
|
||||
void on_actionErase_FoxQSO_txt_triggered();
|
||||
void on_actionErase_cabrillo_log_triggered();
|
||||
void on_actionErase_wsjtx_log_adi_triggered();
|
||||
void on_actionExport_Cabrillo_log_triggered();
|
||||
void startTx2();
|
||||
void startP1();
|
||||
void stopTx();
|
||||
@ -341,7 +344,6 @@ private:
|
||||
QSettings * m_settings;
|
||||
QScopedPointer<Ui::MainWindow> ui;
|
||||
|
||||
// other windows
|
||||
Configuration m_config;
|
||||
WSPRBandHopping m_WSPR_band_hopping;
|
||||
bool m_WSPR_tx_next;
|
||||
@ -359,6 +361,7 @@ private:
|
||||
QScopedPointer<HelpTextWindow> m_mouseCmnds;
|
||||
QScopedPointer<MessageAveraging> m_msgAvgWidget;
|
||||
QScopedPointer<ColorHighlighting> m_colorHighlighting;
|
||||
QScopedPointer<ExportCabrillo> m_exportCabrillo;
|
||||
Transceiver::TransceiverState m_rigState;
|
||||
Frequency m_lastDialFreq;
|
||||
QString m_lastBand;
|
||||
@ -501,6 +504,7 @@ private:
|
||||
bool m_bAutoReply;
|
||||
bool m_bCheckedContest;
|
||||
bool m_bWarnedSplit=false;
|
||||
bool m_bTUmsg;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -518,7 +522,9 @@ private:
|
||||
NA_VHF,
|
||||
EU_VHF,
|
||||
FIELD_DAY,
|
||||
RTTY
|
||||
RTTY,
|
||||
FOX,
|
||||
HOUND
|
||||
} m_nContest; //Contest type
|
||||
|
||||
enum {CALL, GRID, DXCC, MULT};
|
||||
@ -582,6 +588,7 @@ private:
|
||||
QString m_modeTx;
|
||||
QString m_fnameWE; // save path without extension
|
||||
QString m_rpt;
|
||||
QString m_nextRpt;
|
||||
QString m_rptSent;
|
||||
QString m_rptRcvd;
|
||||
QString m_qsoStart;
|
||||
@ -599,6 +606,8 @@ private:
|
||||
QString m_xSent; //Contest exchange sent
|
||||
QString m_xRcvd; //Contest exchange received
|
||||
QString m_currentBand;
|
||||
QString m_nextCall;
|
||||
QString m_nextGrid;
|
||||
|
||||
QSet<QString> m_pfx;
|
||||
QSet<QString> m_sfx;
|
||||
@ -694,6 +703,7 @@ private:
|
||||
void fast_config(bool b);
|
||||
void CQTxFreq();
|
||||
void cabLog();
|
||||
void useNextCall();
|
||||
bool isWorked(int itype, QString key, float fMHz=0, QString="");
|
||||
|
||||
QString save_wave_file (QString const& name
|
||||
|
@ -654,9 +654,15 @@ QLabel[oob="true"] {
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -698,9 +704,15 @@ QLabel[oob="true"] {
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1034,6 +1046,19 @@ QLabel[oob="true"] {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labNextCall">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Double-click on another caller to queue that call for your next QSO.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Next Call</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -2621,10 +2646,12 @@ QPushButton[state="ok"] {
|
||||
<addaction name="actionErase_FoxQSO_txt"/>
|
||||
<addaction name="actionErase_wsjtx_log_adi"/>
|
||||
<addaction name="actionErase_cabrillo_log"/>
|
||||
<addaction name="actionExport_Cabrillo_log"/>
|
||||
<addaction name="actionOpen_log_directory"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSettings"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
@ -2670,6 +2697,7 @@ QPushButton[state="ok"] {
|
||||
<addaction name="actionOnline_User_Guide"/>
|
||||
<addaction name="actionLocal_User_Guide"/>
|
||||
<addaction name="actionFT8_DXpedition_Mode_User_Guide"/>
|
||||
<addaction name="actionQuick_Start_Guide_v2"/>
|
||||
<addaction name="download_samples_action"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionKeyboard_shortcuts"/>
|
||||
@ -3275,13 +3303,13 @@ QPushButton[state="ok"] {
|
||||
</action>
|
||||
<action name="actionFox_Log">
|
||||
<property name="text">
|
||||
<string>Fox Log</string>
|
||||
<string>Fox or Contest Log</string>
|
||||
</property>
|
||||
<property name="iconText">
|
||||
<string>Fox Log</string>
|
||||
<string>Fox or Contest Log</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Fox Log</string>
|
||||
<string>Fox or Contest Log</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionErase_FoxQSO_txt">
|
||||
@ -3304,6 +3332,21 @@ QPushButton[state="ok"] {
|
||||
<string>Color highlighting scheme</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionContest_Log">
|
||||
<property name="text">
|
||||
<string>Contest Log</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExport_Cabrillo_log">
|
||||
<property name="text">
|
||||
<string>Export Cabrillo log</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQuick_Start_Guide_v2">
|
||||
<property name="text">
|
||||
<string>Quick-Start Guide to WSJT-X 2.0</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
@ -20,6 +20,12 @@ MessageAveraging::MessageAveraging(QSettings * settings, QFont const& font, QWid
|
||||
read_settings ();
|
||||
if(m_title_.contains("Fox")) {
|
||||
ui->header_label->setText(" Date Time Call Grid Sent Rcvd Band");
|
||||
} else if(m_title_.contains("Contest")) {
|
||||
ui->header_label->setText(" Date UTC Band Call Sent Rcvd");
|
||||
ui->lab1->setText("QSOs: 0");
|
||||
ui->lab2->setText("Mults: 0");
|
||||
ui->lab3->setText("Score: 0");
|
||||
ui->lab4->setText("Rate: 0");
|
||||
} else {
|
||||
ui->header_label->setText(" UTC Sync DT Freq ");
|
||||
ui->lab1->setVisible(false);
|
||||
@ -27,6 +33,7 @@ MessageAveraging::MessageAveraging(QSettings * settings, QFont const& font, QWid
|
||||
ui->lab3->setVisible(false);
|
||||
ui->lab4->setVisible(false);
|
||||
}
|
||||
|
||||
setWindowTitle(m_title_);
|
||||
m_nLogged_=0;
|
||||
}
|
||||
@ -74,6 +81,7 @@ void MessageAveraging::read_settings ()
|
||||
SettingsGroup group {settings_, "MessageAveraging"};
|
||||
restoreGeometry (settings_->value ("window/geometry").toByteArray ());
|
||||
m_title_=settings_->value("window/title","Message Averaging").toString();
|
||||
m_nContest_=settings_->value("nContest",0).toInt();
|
||||
}
|
||||
|
||||
void MessageAveraging::write_settings ()
|
||||
@ -81,6 +89,7 @@ void MessageAveraging::write_settings ()
|
||||
SettingsGroup group {settings_, "MessageAveraging"};
|
||||
settings_->setValue ("window/geometry", saveGeometry ());
|
||||
settings_->setValue("window/title",m_title_);
|
||||
settings_->setValue("nContest",m_nContest_);
|
||||
}
|
||||
|
||||
void MessageAveraging::displayAvg(QString const& t)
|
||||
@ -88,11 +97,19 @@ void MessageAveraging::displayAvg(QString const& t)
|
||||
ui->msgAvgPlainTextEdit->setPlainText(t);
|
||||
}
|
||||
|
||||
void MessageAveraging::foxLogSetup()
|
||||
void MessageAveraging::foxLogSetup(int nContest)
|
||||
{
|
||||
m_title_=QApplication::applicationName () + " - Fox Log";
|
||||
setWindowTitle(m_title_);
|
||||
ui->header_label->setText(" Date Time Call Grid Sent Rcvd Band");
|
||||
if(nContest==5) {
|
||||
m_title_=QApplication::applicationName () + " - Fox Log";
|
||||
setWindowTitle(m_title_);
|
||||
ui->header_label->setText(" Date Time Call Grid Sent Rcvd Band");
|
||||
}
|
||||
if(nContest>0 and nContest<5) {
|
||||
m_title_=QApplication::applicationName () + " - Contest Log";
|
||||
setWindowTitle(m_title_);
|
||||
ui->header_label->setText(" Date UTC Band Call Sent Rcvd");
|
||||
}
|
||||
m_nContest_=nContest;
|
||||
}
|
||||
|
||||
void MessageAveraging::foxLabCallers(int n)
|
||||
@ -124,3 +141,19 @@ void MessageAveraging::foxAddLog(QString logLine)
|
||||
t.sprintf("Logged: %d",m_nLogged_);
|
||||
ui->lab3->setText(t);
|
||||
}
|
||||
|
||||
void MessageAveraging::contestAddLog(qint32 nContest, QString logLine)
|
||||
{
|
||||
m_nContest_=nContest;
|
||||
ui->msgAvgPlainTextEdit->appendPlainText(logLine);
|
||||
m_nLogged_++;
|
||||
QString t;
|
||||
t.sprintf("QSOs: %d",m_nLogged_);
|
||||
ui->lab1->setText(t);
|
||||
if(m_mult_<1) m_mult_=1;
|
||||
t.sprintf("Mults: %d",m_mult_);
|
||||
ui->lab2->setText(t);
|
||||
int score=m_mult_*m_nLogged_;
|
||||
t.sprintf("Score: %d",score);
|
||||
ui->lab3->setText(t);
|
||||
}
|
||||
|
@ -17,11 +17,12 @@ public:
|
||||
~MessageAveraging();
|
||||
void displayAvg(QString const&);
|
||||
void changeFont (QFont const&);
|
||||
void foxLogSetup();
|
||||
void foxLogSetup(int nContest);
|
||||
void foxLabCallers(int n);
|
||||
void foxLabQueued(int n);
|
||||
void foxLabRate(int n);
|
||||
void foxAddLog(QString logLine);
|
||||
void contestAddLog(qint32 nContest, QString logLine);
|
||||
|
||||
protected:
|
||||
void closeEvent (QCloseEvent *) override;
|
||||
@ -32,7 +33,9 @@ private:
|
||||
void setContentFont (QFont const&);
|
||||
QSettings * settings_;
|
||||
QString m_title_;
|
||||
qint32 m_nLogged_;
|
||||
qint32 m_nLogged_=0;
|
||||
qint32 m_mult_=0;
|
||||
qint32 m_nContest_;
|
||||
|
||||
QScopedPointer<Ui::MessageAveraging> ui;
|
||||
};
|
||||
|
@ -18,7 +18,7 @@
|
||||
QDataStream& operator << (QDataStream& os, CLASS::ENUM const& v) \
|
||||
{ \
|
||||
auto const& mo = CLASS::staticMetaObject; \
|
||||
return os << mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (v); \
|
||||
return os << mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (static_cast<int> (v)); \
|
||||
} \
|
||||
\
|
||||
QDataStream& operator >> (QDataStream& is, CLASS::ENUM& v) \
|
||||
@ -47,35 +47,9 @@
|
||||
QString enum_to_qstring (CLASS::ENUM const& m) \
|
||||
{ \
|
||||
auto const& mo = CLASS::staticMetaObject; \
|
||||
return QString {mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (m)}; \
|
||||
return QString {mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (static_cast<int> (m))}; \
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x050500
|
||||
|
||||
// Qt 5.5 now has Q_ENUM which registers enumns better
|
||||
#define ENUM_QDEBUG_OPS_DECL(CLASS, ENUM)
|
||||
#define ENUM_QDEBUG_OPS_IMPL(CLASS, ENUM)
|
||||
|
||||
#else
|
||||
|
||||
#define Q_ENUM(E)
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
class QVariant;
|
||||
|
||||
#define ENUM_QDEBUG_OPS_DECL(CLASS, ENUM) \
|
||||
QDebug operator << (QDebug, CLASS::ENUM const&);
|
||||
|
||||
#define ENUM_QDEBUG_OPS_IMPL(CLASS, ENUM) \
|
||||
QDebug operator << (QDebug d, CLASS::ENUM const& m) \
|
||||
{ \
|
||||
auto const& mo = CLASS::staticMetaObject; \
|
||||
return d << mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (m); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline
|
||||
void throw_qstring (QString const& qs)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
<table cellspacing=1>
|
||||
<tr><td><b>Esc </b></td><td>Stop transmitting</td></tr>
|
||||
<tr><td><b>F1 </b></td><td>Online User's Guide</td></tr>
|
||||
<tr><td><b>Shift+F1 </b></td><td>Copyright Notice</td></tr>
|
||||
<tr><td><b>Ctrl+F1 </b></td><td>About WSJT-X</td></tr>
|
||||
@ -13,9 +14,11 @@
|
||||
<tr><td><b>F11 </b></td><td>Move Rx frequency down 1 Hz</td></tr>
|
||||
<tr><td><b>Ctrl+F11 </b></td><td>Move identical Rx and Tx frequencies down 1 Hz</td></tr>
|
||||
<tr><td><b>Shift+F11 </b></td><td>Move Tx frequency down 60 Hz</td></tr>
|
||||
<tr><td><b>Ctrl+Shift+F11 </b></td><td>Move dial frequency down 2000 Hz</td></tr>
|
||||
<tr><td><b>F12 </b></td><td>Move Rx frequency up 1 Hz</td></tr>
|
||||
<tr><td><b>Ctrl+F12 </b></td><td>Move identical Rx and Tx frequencies up 1 Hz</td></tr>
|
||||
<tr><td><b>Shift+F12 </b></td><td>Move Tx frequency up 60 Hz</td></tr>
|
||||
<tr><td><b>Ctrl+Shift+F12 </b></td><td>Move dial frequency up 2000 Hz</td></tr>
|
||||
<tr><td><b>Alt+1-6 </b></td><td>Set now transmission to this number on Tab 1</td></tr>
|
||||
<tr><td><b>Ctl+1-6 </b></td><td>Set next transmission to this number on Tab 1</td></tr>
|
||||
<tr><td><b>Alt+D </b></td><td>Decode again at QSO frequency</td></tr>
|
||||
|
11
wsjtx.pro
11
wsjtx.pro
@ -67,8 +67,8 @@ SOURCES += \
|
||||
echoplot.cpp echograph.cpp fastgraph.cpp fastplot.cpp Modes.cpp \
|
||||
WSPRBandHopping.cpp MessageAggregator.cpp SampleDownloader.cpp qt_helpers.cpp\
|
||||
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp MessageBox.cpp \
|
||||
EqualizationToolsDialog.cpp \
|
||||
colorhighlighting.cpp
|
||||
EqualizationToolsDialog.cpp CallsignValidator.cpp ExchangeValidator.cpp \
|
||||
colorhighlighting.cpp ExportCabrillo.cpp LotWUsers.cpp
|
||||
|
||||
HEADERS += qt_helpers.hpp \
|
||||
pimpl_h.hpp pimpl_impl.hpp \
|
||||
@ -84,8 +84,8 @@ HEADERS += qt_helpers.hpp \
|
||||
logbook/logbook.h logbook/countrydat.h logbook/countriesworked.h logbook/adif.h \
|
||||
messageaveraging.h echoplot.h echograph.h fastgraph.h fastplot.h Modes.hpp WSPRBandHopping.hpp \
|
||||
WsprTxScheduler.h SampleDownloader.hpp MultiSettings.hpp PhaseEqualizationDialog.hpp \
|
||||
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp \
|
||||
colorhighlighting.h
|
||||
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp CallsignValidator.hpp \
|
||||
ExchangeValidator.hpp colorhighlighting.h ExportCabrillo.h LotWUsers.h
|
||||
|
||||
|
||||
INCLUDEPATH += qmake_only
|
||||
@ -97,8 +97,7 @@ HEADERS += OmniRigTransceiver.hpp
|
||||
|
||||
FORMS += mainwindow.ui about.ui Configuration.ui widegraph.ui astro.ui \
|
||||
logqso.ui wf_palette_design_dialog.ui messageaveraging.ui echograph.ui \
|
||||
fastgraph.ui \
|
||||
colorhighlighting.ui
|
||||
fastgraph.ui colorhighlighting.ui ExportCabrillo.ui
|
||||
|
||||
RC_FILE = wsjtx.rc
|
||||
RESOURCES = wsjtx.qrc
|
||||
|
Loading…
Reference in New Issue
Block a user