Updated decode highlighting and LotW user's data file management

Includes a new settings facility  with the highlighting being contrled
by a new model class and a  modified QListView to display the data for
editing. Edits  include enable and  disable check boxes,  a contextual
pop-up menu to adjust backkground and foreground colours.

Still   to   be   implemented    are   priorities   for   highlighting
categories. This  will be adjustable  by drag  and drop in  the Colors
settings panel, it is already implemented by the priority order has no
effect on highlighting of decodes yet.

The LotW  users data file fetch  and time since user's  last upload is
now controled from the settings dialog.

This change also drops support for Qt versions before 5.5 so that many
workarounds for earlier versions can be removed.

Debug trace is slightly modified to make better use of the Qt built in
facilities to format and synchronize cross thread messaging.
This commit is contained in:
Bill Somerville 2018-10-17 00:26:04 +01:00
parent 851c0e3bc6
commit 873b1d1c43
32 changed files with 1232 additions and 1117 deletions

View File

@ -263,6 +263,8 @@ set (wsjt_qt_CXXSRCS
DoubleClickablePushButton.cpp DoubleClickablePushButton.cpp
DoubleClickableRadioButton.cpp DoubleClickableRadioButton.cpp
LotWUsers.cpp LotWUsers.cpp
DecodeHighlightingModel.cpp
DecodeHighlightingListView.cpp
) )
set (wsjt_qtmm_CXXSRCS set (wsjt_qtmm_CXXSRCS

View File

@ -157,7 +157,6 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QFont> #include <QFont>
#include <QFontDialog> #include <QFontDialog>
#include <QColorDialog>
#include <QSerialPortInfo> #include <QSerialPortInfo>
#include <QScopedPointer> #include <QScopedPointer>
#include <QDebug> #include <QDebug>
@ -182,6 +181,7 @@
#include "CallsignValidator.hpp" #include "CallsignValidator.hpp"
#include "LotWUsers.hpp" #include "LotWUsers.hpp"
#include "ExchangeValidator.hpp" #include "ExchangeValidator.hpp"
#include "DecodeHighlightingModel.hpp"
#include "ui_Configuration.h" #include "ui_Configuration.h"
#include "moc_Configuration.cpp" #include "moc_Configuration.cpp"
@ -445,17 +445,8 @@ private:
Q_SLOT void on_calibration_slope_ppm_spin_box_valueChanged (double); 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_update (TransceiverState const&, unsigned sequence_number);
Q_SLOT void handle_transceiver_failure (QString const& reason); Q_SLOT void handle_transceiver_failure (QString const& reason);
Q_SLOT void on_pbCQmsg_clicked(); Q_SLOT void on_reset_highlighting_to_defaults_push_button_clicked (bool);
Q_SLOT void on_pbMyCall_clicked(); Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
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_cbFox_clicked (bool); Q_SLOT void on_cbFox_clicked (bool);
Q_SLOT void on_cbHound_clicked (bool); Q_SLOT void on_cbHound_clicked (bool);
Q_SLOT void on_cbx2ToneSpacing_clicked(bool); Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
@ -530,10 +521,14 @@ private:
QAction * reset_frequencies_action_; QAction * reset_frequencies_action_;
FrequencyDialog * frequency_dialog_; FrequencyDialog * frequency_dialog_;
QAction * station_delete_action_; QAction station_delete_action_;
QAction * station_insert_action_; QAction station_insert_action_;
StationDialog * station_dialog_; StationDialog * station_dialog_;
DecodeHighlightingModel decode_highlighing_model_;
DecodeHighlightingModel next_decode_highlighing_model_;
int LotW_days_since_upload_;
TransceiverFactory::ParameterPack rig_params_; TransceiverFactory::ParameterPack rig_params_;
TransceiverFactory::ParameterPack saved_rig_params_; TransceiverFactory::ParameterPack saved_rig_params_;
TransceiverFactory::Capabilities::PortType last_port_type_; TransceiverFactory::Capabilities::PortType last_port_type_;
@ -553,26 +548,6 @@ private:
QString my_grid_; QString my_grid_;
QString FD_exchange_; QString FD_exchange_;
QString RTTY_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 id_interval_;
qint32 ntrials_; qint32 ntrials_;
@ -668,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_;} 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_;} auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
QString Configuration::my_callsign () const {return m_->my_callsign_;} 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::text_font () const {return m_->font_;}
QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;} QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;}
qint32 Configuration::id_interval () const {return m_->id_interval_;} qint32 Configuration::id_interval () const {return m_->id_interval_;}
@ -748,6 +713,7 @@ QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
bool Configuration::pwrBandTxMemory () const {return m_->pwrBandTxMemory_;} bool Configuration::pwrBandTxMemory () const {return m_->pwrBandTxMemory_;}
bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;} bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;}
LotWUsers const& Configuration::lotw_users () const {return m_->lotw_users_;} 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) void Configuration::set_calibration (CalibrationParams params)
{ {
@ -941,7 +907,10 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
, current_offset_ {0} , current_offset_ {0}
, current_tx_offset_ {0} , current_tx_offset_ {0}
, frequency_dialog_ {new FrequencyDialog {&regions_, &modes_, this}} , frequency_dialog_ {new FrequencyDialog {&regions_, &modes_, this}}
, station_delete_action_ {tr ("&Delete"), nullptr}
, station_insert_action_ {tr ("&Insert ..."), nullptr}
, station_dialog_ {new StationDialog {&next_stations_, &bands_, this}} , station_dialog_ {new StationDialog {&next_stations_, &bands_, this}}
, LotW_days_since_upload_ {0}
, last_port_type_ {TransceiverFactory::Capabilities::none} , last_port_type_ {TransceiverFactory::Capabilities::none}
, rig_is_dummy_ {false} , rig_is_dummy_ {false}
, rig_active_ {false} , rig_active_ {false}
@ -1012,8 +981,13 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
// this must be done after the default paths above are set // this must be done after the default paths above are set
read_settings (); read_settings ();
// load LotW users data // conditionally load LotW users data
lotw_users_.load (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv")); 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 // validation
@ -1134,29 +1108,30 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
ui_->frequencies_table_view->insertAction (nullptr, reset_frequencies_action_); ui_->frequencies_table_view->insertAction (nullptr, reset_frequencies_action_);
connect (reset_frequencies_action_, &QAction::triggered, this, &Configuration::impl::reset_frequencies); connect (reset_frequencies_action_, &QAction::triggered, this, &Configuration::impl::reset_frequencies);
// //
// setup stations table model & view // setup stations table model & view
// //
stations_.sort (StationList::band_column); stations_.sort (StationList::band_column);
ui_->stations_table_view->setModel (&next_stations_); ui_->stations_table_view->setModel (&next_stations_);
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder); ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
// delegates // stations delegates
auto stations_item_delegate = new QStyledItemDelegate {this}; auto stations_item_delegate = new QStyledItemDelegate {this};
stations_item_delegate->setItemEditorFactory (item_editor_factory ()); stations_item_delegate->setItemEditorFactory (item_editor_factory ());
ui_->stations_table_view->setItemDelegate (stations_item_delegate); 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}); ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this});
// actions // stations actions
station_delete_action_ = new QAction {tr ("&Delete"), ui_->stations_table_view}; ui_->stations_table_view->addAction (&station_delete_action_);
ui_->stations_table_view->insertAction (nullptr, station_delete_action_); connect (&station_delete_action_, &QAction::triggered, this, &Configuration::impl::delete_stations);
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->addAction (&station_insert_action_);
ui_->stations_table_view->insertAction (nullptr, station_insert_action_); connect (&station_insert_action_, &QAction::triggered, this, &Configuration::impl::insert_station);
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 // load combo boxes with audio setup choices
@ -1200,16 +1175,6 @@ void Configuration::impl::initialize_models ()
ui_->callsign_line_edit->setText (my_callsign_); ui_->callsign_line_edit->setText (my_callsign_);
ui_->grid_line_edit->setText (my_grid_); ui_->grid_line_edit->setText (my_grid_);
ui_->use_dynamic_grid->setChecked(use_dynamic_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_->CW_id_interval_spin_box->setValue (id_interval_);
ui_->sbNtrials->setValue (ntrials_); ui_->sbNtrials->setValue (ntrials_);
ui_->sbTxDelay->setValue (txDelay_); ui_->sbTxDelay->setValue (txDelay_);
@ -1311,6 +1276,9 @@ void Configuration::impl::initialize_models ()
next_frequencies_.frequency_list (frequencies_.frequency_list ()); next_frequencies_.frequency_list (frequencies_.frequency_list ());
next_stations_.station_list (stations_.station_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 (); set_rig_invariants ();
} }
@ -1334,16 +1302,6 @@ void Configuration::impl::read_settings ()
RTTY_exchange_ = settings_->value ("RTTYExchange",QString {}).toString (); RTTY_exchange_ = settings_->value ("RTTYExchange",QString {}).toString ();
ui_->FieldDay_Exchange->setText(FD_exchange_); ui_->FieldDay_Exchange->setText(FD_exchange_);
ui_->RTTY_Exchange->setText(RTTY_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 ()) if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
&& next_font_ != font_) && next_font_ != font_)
{ {
@ -1358,6 +1316,8 @@ void Configuration::impl::read_settings ()
&& next_decoded_text_font_ != decoded_text_font_) && next_decoded_text_font_ != decoded_text_font_)
{ {
decoded_text_font_ = next_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_); Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
} }
else else
@ -1461,6 +1421,10 @@ void Configuration::impl::read_settings ()
stations_.station_list (settings_->value ("stations").value<StationList::Stations> ()); 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 (); log_as_RTTY_ = settings_->value ("toRTTY", false).toBool ();
report_in_comments_ = settings_->value("dBtoComments", false).toBool (); report_in_comments_ = settings_->value("dBtoComments", false).toBool ();
rig_params_.rig_name = settings_->value ("Rig", TransceiverFactory::basic_transceiver_name_).toString (); rig_params_.rig_name = settings_->value ("Rig", TransceiverFactory::basic_transceiver_name_).toString ();
@ -1531,16 +1495,6 @@ void Configuration::impl::write_settings ()
settings_->setValue ("MyGrid", my_grid_); settings_->setValue ("MyGrid", my_grid_);
settings_->setValue ("FieldDayExchange", FD_exchange_); settings_->setValue ("FieldDayExchange", FD_exchange_);
settings_->setValue ("RTTYExchange", RTTY_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 ("Font", font_.toString ());
settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ()); settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ());
settings_->setValue ("IDint", id_interval_); settings_->setValue ("IDint", id_interval_);
@ -1582,6 +1536,8 @@ void Configuration::impl::write_settings ()
settings_->setValue ("Macros", macros_.stringList ()); settings_->setValue ("Macros", macros_.stringList ());
settings_->setValue ("FrequenciesForRegionModes", QVariant::fromValue (frequencies_.frequency_list ())); settings_->setValue ("FrequenciesForRegionModes", QVariant::fromValue (frequencies_.frequency_list ()));
settings_->setValue ("stations", QVariant::fromValue (stations_.station_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 ("toRTTY", log_as_RTTY_);
settings_->setValue ("dBtoComments", report_in_comments_); settings_->setValue ("dBtoComments", report_in_comments_);
settings_->setValue ("Rig", rig_params_.rig_name); settings_->setValue ("Rig", rig_params_.rig_name);
@ -1905,20 +1861,11 @@ void Configuration::impl::accept ()
if (next_decoded_text_font_ != decoded_text_font_) if (next_decoded_text_font_ != decoded_text_font_)
{ {
decoded_text_font_ = next_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_); 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 rig_params_ = temp_rig_params; // now we can go live with the rig
// related configuration parameters // related configuration parameters
rig_is_dummy_ = TransceiverFactory::basic_transceiver_name_ == rig_params_.rig_name; rig_is_dummy_ = TransceiverFactory::basic_transceiver_name_ == rig_params_.rig_name;
@ -2065,10 +2012,8 @@ void Configuration::impl::accept ()
} }
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked (); accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text (); n1mm_server_name_ = ui_->n1mm_server_name_line_edit->text ();
n1mm_server_name_ = new_n1mm_server; n1mm_server_port_ = ui_->n1mm_server_port_spin_box->value ();
auto new_n1mm_port = ui_->n1mm_server_port_spin_box->value ();
n1mm_server_port_ = new_n1mm_port;
broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked (); broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked ();
udpWindowToFront_ = ui_->udpWindowToFront->isChecked (); udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
@ -2089,10 +2034,18 @@ void Configuration::impl::accept ()
if (stations_.station_list () != next_stations_.station_list ()) 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); 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_ ) if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
{ {
// turning on so clear it so only the next location update gets used // turning on so clear it so only the next location update gets used
@ -2131,136 +2084,27 @@ void Configuration::impl::on_font_push_button_clicked ()
next_font_ = QFontDialog::getFont (0, next_font_, this); 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 (MessageBox::Yes == MessageBox::query_message (this
if (new_color.isValid ()) , tr ("Reset Decode Highlighting")
, tr ("Reset all decode highlighting and priorities to default values")))
{ {
next_color_CQ_ = new_color; next_decode_highlighing_model_.items (DecodeHighlightingModel::default_items ());
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
} }
} }
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"); lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), true);
if (new_color.isValid ()) ui_->LotW_CSV_fetch_push_button->setEnabled (false);
{
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()));
} }
void Configuration::impl::on_decoded_text_font_push_button_clicked () void Configuration::impl::on_decoded_text_font_push_button_clicked ()
{ {
next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this
, tr ("WSJT-X Decoded Text Font Chooser") , tr ("WSJT-X Decoded Text Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::MonospacedFonts , QFontDialog::MonospacedFonts
#endif
); );
} }
@ -3077,11 +2921,6 @@ auto Configuration::impl::remove_calibration (Frequency f) const -> Frequency
/ (1. + calibration_.slope_ppm / 1.e6)); / (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, DataMode);
ENUM_QDATASTREAM_OPS_IMPL (Configuration, Type2MsgGen); ENUM_QDATASTREAM_OPS_IMPL (Configuration, Type2MsgGen);

View File

@ -23,6 +23,7 @@ class StationList;
class QStringListModel; class QStringListModel;
class QHostAddress; class QHostAddress;
class LotWUsers; class LotWUsers;
class DecodeHighlightingModel;
// //
// Class Configuration // Class Configuration
@ -58,7 +59,6 @@ class Configuration final
: public QObject : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS (DataMode Type2MsgGen)
public: public:
using MODE = Transceiver::MODE; using MODE = Transceiver::MODE;
@ -172,19 +172,10 @@ public:
QDir azel_directory () const; QDir azel_directory () const;
QString rig_name () const; QString rig_name () const;
Type2MsgGen type_2_msg_gen () 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 pwrBandTxMemory () const;
bool pwrBandTuneMemory () const; bool pwrBandTuneMemory () const;
LotWUsers const& lotw_users () const; LotWUsers const& lotw_users () const;
DecodeHighlightingModel const& decode_highlighting () const;
struct CalibrationParams struct CalibrationParams
{ {
@ -267,15 +258,17 @@ public:
// These signals indicate a font has been selected and accepted for // These signals indicate a font has been selected and accepted for
// the application text and decoded text respectively. // the application text and decoded text respectively.
// //
Q_SIGNAL void text_font_changed (QFont); Q_SIGNAL void text_font_changed (QFont) const;
Q_SIGNAL void decoded_text_font_changed (QFont); Q_SIGNAL void decoded_text_font_changed (QFont) const;
// //
// This signal is emitted when the UDP server changes // This signal is emitted when the UDP server changes
// //
Q_SIGNAL void udp_server_changed (QString const& udp_server); Q_SIGNAL void udp_server_changed (QString const& udp_server) const;
Q_SIGNAL void udp_server_port_changed (port_type server_port); 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 // These signals are emitted and reflect transceiver state changes
@ -297,16 +290,6 @@ private:
pimpl<impl> m_; 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, DataMode);
ENUM_QDATASTREAM_OPS_DECL (Configuration, Type2MsgGen); ENUM_QDATASTREAM_OPS_DECL (Configuration, Type2MsgGen);

View File

@ -1704,6 +1704,9 @@ QListView::item:hover {
<property name="text"> <property name="text">
<string>Op Call:</string> <string>Op Call:</string>
</property> </property>
<property name="buddy">
<cstring>opCallEntry</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
@ -1909,6 +1912,9 @@ for assessing propagation and system performance.</string>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;N1MM Server name or IP address:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;N1MM Server name or IP address:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="buddy">
<cstring>n1mm_server_name_line_edit</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -1923,6 +1929,9 @@ for assessing propagation and system performance.</string>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;N1MM Server port number:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;N1MM Server port number:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="buddy">
<cstring>n1mm_server_port_spin_box</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
@ -2166,8 +2175,158 @@ Right click for insert and delete options.</string>
<attribute name="title"> <attribute name="title">
<string>Colors</string> <string>Colors</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_5" rowstretch="1,0,0" columnstretch="1,0,0"> <layout class="QVBoxLayout" name="verticalLayout_7">
<item row="0" column="1"> <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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Push to reset all highlight items above to default values and priorities.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Controls for Logbook of the World user lookup.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Push this button to fetch the latest LotW user's upload date and time data file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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"> <spacer name="horizontalSpacer_8">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -2180,317 +2339,6 @@ Right click for insert and delete options.</string>
</property> </property>
</spacer> </spacer>
</item> </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>No 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> </layout>
</widget> </widget>
<widget class="QWidget" name="advanced_tab"> <widget class="QWidget" name="advanced_tab">
@ -2990,36 +2838,49 @@ Right click for insert and delete options.</string>
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>DecodeHighlightingListView</class>
<extends>QListView</extends>
<header>DecodehigHlightingListView.hpp</header>
</customwidget>
</customwidgets>
<tabstops> <tabstops>
<tabstop>configuration_tabs</tabstop> <tabstop>configuration_tabs</tabstop>
<tabstop>callsign_line_edit</tabstop> <tabstop>callsign_line_edit</tabstop>
<tabstop>grid_line_edit</tabstop> <tabstop>grid_line_edit</tabstop>
<tabstop>use_dynamic_grid</tabstop>
<tabstop>region_combo_box</tabstop> <tabstop>region_combo_box</tabstop>
<tabstop>type_2_msg_gen_combo_box</tabstop> <tabstop>type_2_msg_gen_combo_box</tabstop>
<tabstop>insert_blank_check_box</tabstop> <tabstop>insert_blank_check_box</tabstop>
<tabstop>miles_check_box</tabstop> <tabstop>miles_check_box</tabstop>
<tabstop>TX_messages_check_box</tabstop> <tabstop>TX_messages_check_box</tabstop>
<tabstop>DXCC_check_box</tabstop> <tabstop>DXCC_check_box</tabstop>
<tabstop>ppfx_check_box</tabstop>
<tabstop>font_push_button</tabstop> <tabstop>font_push_button</tabstop>
<tabstop>decoded_text_font_push_button</tabstop> <tabstop>decoded_text_font_push_button</tabstop>
<tabstop>monitor_off_check_box</tabstop> <tabstop>monitor_off_check_box</tabstop>
<tabstop>monitor_last_used_check_box</tabstop> <tabstop>monitor_last_used_check_box</tabstop>
<tabstop>quick_call_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>CW_id_after_73_check_box</tabstop>
<tabstop>enable_VHF_features_check_box</tabstop> <tabstop>enable_VHF_features_check_box</tabstop>
<tabstop>tx_QSY_check_box</tabstop> <tabstop>tx_QSY_check_box</tabstop>
<tabstop>single_decode_check_box</tabstop> <tabstop>single_decode_check_box</tabstop>
<tabstop>decode_at_52s_check_box</tabstop> <tabstop>decode_at_52s_check_box</tabstop>
<tabstop>tx_watchdog_spin_box</tabstop>
<tabstop>CW_id_interval_spin_box</tabstop> <tabstop>CW_id_interval_spin_box</tabstop>
<tabstop>rig_combo_box</tabstop> <tabstop>rig_combo_box</tabstop>
<tabstop>CAT_poll_interval_spin_box</tabstop> <tabstop>CAT_poll_interval_spin_box</tabstop>
<tabstop>CAT_port_combo_box</tabstop> <tabstop>CAT_port_combo_box</tabstop>
<tabstop>CAT_serial_baud_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_7_bit_radio_button</tabstop>
<tabstop>CAT_8_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_one_stop_bit_radio_button</tabstop>
<tabstop>CAT_two_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_none_radio_button</tabstop>
<tabstop>CAT_handshake_xon_radio_button</tabstop> <tabstop>CAT_handshake_xon_radio_button</tabstop>
<tabstop>CAT_handshake_hardware_radio_button</tabstop> <tabstop>CAT_handshake_hardware_radio_button</tabstop>
@ -3053,29 +2914,48 @@ Right click for insert and delete options.</string>
<tabstop>delete_macro_push_button</tabstop> <tabstop>delete_macro_push_button</tabstop>
<tabstop>macros_list_view</tabstop> <tabstop>macros_list_view</tabstop>
<tabstop>prompt_to_log_check_box</tabstop> <tabstop>prompt_to_log_check_box</tabstop>
<tabstop>cbAutoLog</tabstop>
<tabstop>log_as_RTTY_check_box</tabstop> <tabstop>log_as_RTTY_check_box</tabstop>
<tabstop>report_in_comments_check_box</tabstop> <tabstop>report_in_comments_check_box</tabstop>
<tabstop>clear_DX_check_box</tabstop> <tabstop>clear_DX_check_box</tabstop>
<tabstop>opCallEntry</tabstop>
<tabstop>psk_reporter_check_box</tabstop> <tabstop>psk_reporter_check_box</tabstop>
<tabstop>udp_server_line_edit</tabstop> <tabstop>udp_server_line_edit</tabstop>
<tabstop>udp_server_port_spin_box</tabstop> <tabstop>udp_server_port_spin_box</tabstop>
<tabstop>accept_udp_requests_check_box</tabstop> <tabstop>accept_udp_requests_check_box</tabstop>
<tabstop>udpWindowToFront</tabstop> <tabstop>udpWindowToFront</tabstop>
<tabstop>udpWindowRestore</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_slope_ppm_spin_box</tabstop>
<tabstop>calibration_intercept_spin_box</tabstop> <tabstop>calibration_intercept_spin_box</tabstop>
<tabstop>frequencies_table_view</tabstop> <tabstop>frequencies_table_view</tabstop>
<tabstop>stations_table_view</tabstop> <tabstop>stations_table_view</tabstop>
<tabstop>pbCQmsg</tabstop> <tabstop>highlighting_list_view</tabstop>
<tabstop>pbMyCall</tabstop> <tabstop>reset_highlighting_to_defaults_push_button</tabstop>
<tabstop>pbTxMsg</tabstop> <tabstop>LotW_CSV_URL_line_edit</tabstop>
<tabstop>pbNewDXCC</tabstop> <tabstop>LotW_CSV_fetch_push_button</tabstop>
<tabstop>LotW_days_since_upload_spin_box</tabstop>
<tabstop>sbNtrials</tabstop> <tabstop>sbNtrials</tabstop>
<tabstop>sbAggressive</tabstop> <tabstop>sbAggressive</tabstop>
<tabstop>cbTwoPass</tabstop> <tabstop>cbTwoPass</tabstop>
<tabstop>sbDegrade</tabstop> <tabstop>sbDegrade</tabstop>
<tabstop>sbBandwidth</tabstop> <tabstop>sbBandwidth</tabstop>
<tabstop>sbTxDelay</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> </tabstops>
<resources/> <resources/>
<connections> <connections>
@ -3145,12 +3025,12 @@ Right click for insert and delete options.</string>
</connection> </connection>
</connections> </connections>
<buttongroups> <buttongroups>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="CAT_handshake_button_group"/> <buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/> <buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="TX_mode_button_group"/> <buttongroup name="TX_mode_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="TX_audio_source_button_group"/> <buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="PTT_method_button_group"/> <buttongroup name="PTT_method_button_group"/>
</buttongroups> </buttongroups>
</ui> </ui>

View 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 ();
}

View 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
View 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;
}

View 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

View File

@ -1,5 +1,4 @@
#include "ExportCabrillo.h" #include "ExportCabrillo.h"
#include "ui_ExportCabrillo.h"
#include "SettingsGroup.hpp" #include "SettingsGroup.hpp"
#include "MessageBox.hpp" #include "MessageBox.hpp"
@ -7,6 +6,9 @@
#include <QDebug> #include <QDebug>
#include <QFileDialog> #include <QFileDialog>
#include "ui_ExportCabrillo.h"
#include "moc_ExportCabrillo.cpp"
ExportCabrillo::ExportCabrillo(QSettings *settings, QWidget *parent) : ExportCabrillo::ExportCabrillo(QSettings *settings, QWidget *parent) :
QDialog(parent), QDialog(parent),
settings_ {settings}, settings_ {settings},

View File

@ -261,12 +261,7 @@ HamlibTransceiver::HamlibTransceiver (int model_number, TransceiverFactory::Para
// //
// user defined Hamlib settings // user defined Hamlib settings
// //
auto settings_file_name = QStandardPaths::locate ( auto settings_file_name = QStandardPaths::locate (QStandardPaths::AppConfigLocation
#if QT_VERSION >= 0x050500
QStandardPaths::AppConfigLocation
#else
QStandardPaths::ConfigLocation
#endif
, "hamlib_settings.json"); , "hamlib_settings.json");
if (!settings_file_name.isEmpty ()) if (!settings_file_name.isEmpty ())
{ {

View File

@ -47,7 +47,7 @@ protected:
void stepBy (int steps) override; void stepBy (int steps) override;
private: private:
std::vector<int> values_; values_type values_;
}; };
#endif #endif

View File

@ -92,9 +92,5 @@ QVariant IARURegions::headerData (int section, Qt::Orientation orientation, int
return result; return result;
} }
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (IARURegions, Region);
#endif
ENUM_QDATASTREAM_OPS_IMPL (IARURegions, Region); ENUM_QDATASTREAM_OPS_IMPL (IARURegions, Region);
ENUM_CONVERSION_OPS_IMPL (IARURegions, Region); ENUM_CONVERSION_OPS_IMPL (IARURegions, Region);

View File

@ -29,8 +29,6 @@ class IARURegions final
: public QAbstractListModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS (Region)
public: public:
// //
// This enumeration contains the supported regions, to complement // This enumeration contains the supported regions, to complement
@ -62,19 +60,6 @@ public:
QVariant headerData (int section, Qt::Orientation, int = Qt::DisplayRole) const override; 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_QDATASTREAM_OPS_DECL (IARURegions, Region);
ENUM_CONVERSION_OPS_DECL (IARURegions, Region); ENUM_CONVERSION_OPS_DECL (IARURegions, Region);

View File

@ -37,16 +37,17 @@ public:
, network_manager_ {network_manager} , network_manager_ {network_manager}
, url_valid_ {false} , url_valid_ {false}
, redirect_count_ {0} , redirect_count_ {0}
, age_constraint_ {365}
{ {
} }
void load (bool forced_fetch) void load (QString const& url, bool forced_fetch)
{ {
auto csv_file_name = csv_file_.fileName (); auto csv_file_name = csv_file_.fileName ();
abort (); // abort any active download abort (); // abort any active download
if (!QFileInfo::exists (csv_file_name) || forced_fetch) if (!QFileInfo::exists (csv_file_name) || forced_fetch)
{ {
current_url_.setUrl ("https://lotw.arrl.org/lotw-user-activity.csv"); current_url_.setUrl (url);
redirect_count_ = 0; redirect_count_ = 0;
download (current_url_); download (current_url_);
} }
@ -59,10 +60,11 @@ public:
void download (QUrl url) void download (QUrl url)
{ {
if (QNetworkAccessManager::Accessible != network_manager_->networkAccessible ()) { if (QNetworkAccessManager::Accessible != network_manager_->networkAccessible ())
// try and recover network access for QNAM {
network_manager_->setNetworkAccessible (QNetworkAccessManager::Accessible); // try and recover network access for QNAM
} network_manager_->setNetworkAccessible (QNetworkAccessManager::Accessible);
}
if (url.isValid () && !QSslSocket::supportsSsl ()) if (url.isValid () && !QSslSocket::supportsSsl ())
{ {
@ -89,8 +91,11 @@ public:
void reply_finished () void reply_finished ()
{ {
if (!reply_) return; // we probably deleted it in an if (!reply_)
// earlier call {
Q_EMIT self_->load_finished ();
return; // we probably deleted it in an earlier call
}
QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()}; QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()};
if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ()) if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ())
{ {
@ -104,6 +109,7 @@ public:
Q_EMIT self_->LotW_users_error (tr ("Network Error - Too many redirects:\n\'%1\'") Q_EMIT self_->LotW_users_error (tr ("Network Error - Too many redirects:\n\'%1\'")
.arg (redirect_url.toDisplayString ())); .arg (redirect_url.toDisplayString ()));
url_valid_ = false; // reset url_valid_ = false; // reset
Q_EMIT self_->load_finished ();
} }
} }
else if (reply_->error () != QNetworkReply::NoError) else if (reply_->error () != QNetworkReply::NoError)
@ -117,6 +123,7 @@ public:
Q_EMIT self_->LotW_users_error (tr ("Network Error:\n%1") Q_EMIT self_->LotW_users_error (tr ("Network Error:\n%1")
.arg (reply_->errorString ())); .arg (reply_->errorString ()));
} }
Q_EMIT self_->load_finished ();
} }
else else
{ {
@ -125,6 +132,7 @@ public:
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot commit changes to:\n\"%1\"") Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot commit changes to:\n\"%1\"")
.arg (csv_file_.fileName ())); .arg (csv_file_.fileName ()));
url_valid_ = false; // reset url_valid_ = false; // reset
Q_EMIT self_->load_finished ();
} }
else else
{ {
@ -137,7 +145,6 @@ public:
else else
{ {
url_valid_ = false; // reset url_valid_ = false; // reset
// qDebug () << "LotW Users Data downloaded from" << reply_->url ().toDisplayString ();
// load the database asynchronously // load the database asynchronously
future_load_ = std::async (std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_.fileName ()); future_load_ = std::async (std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_.fileName ());
} }
@ -219,6 +226,7 @@ public:
QPointer<QNetworkReply> reply_; QPointer<QNetworkReply> reply_;
std::future<dictionary> future_load_; std::future<dictionary> future_load_;
dictionary last_uploaded_; dictionary last_uploaded_;
qint64 age_constraint_; // days
}; };
#include "LotWUsers.moc" #include "LotWUsers.moc"
@ -233,13 +241,22 @@ LotWUsers::~LotWUsers ()
{ {
} }
void LotWUsers::load (QString const& lotw_csv_file, bool force_download) void LotWUsers::set_local_file_path (QString const& path)
{ {
m_->csv_file_.setFileName (lotw_csv_file); m_->csv_file_.setFileName (path);
m_->load (force_download);
} }
bool LotWUsers::user (QString const& call, qint64 uploaded_since_days) const 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 ()) if (m_->future_load_.valid ())
{ {
@ -252,11 +269,12 @@ bool LotWUsers::user (QString const& call, qint64 uploaded_since_days) const
{ {
Q_EMIT LotW_users_error (e.what ()); Q_EMIT LotW_users_error (e.what ());
} }
Q_EMIT load_finished ();
} }
auto p = m_->last_uploaded_.constFind (call); auto p = m_->last_uploaded_.constFind (call);
if (p != m_->last_uploaded_.end ()) if (p != m_->last_uploaded_.end ())
{ {
return p.value ().daysTo (QDate::currentDate ()) <= uploaded_since_days; return p.value ().daysTo (QDate::currentDate ()) <= m_->age_constraint_;
} }
return false; return false;
} }

View File

@ -18,16 +18,20 @@ class LotWUsers final
Q_OBJECT Q_OBJECT
public: public:
LotWUsers (QNetworkAccessManager *, QObject * parent = 0); explicit LotWUsers (QNetworkAccessManager *, QObject * parent = 0);
~LotWUsers (); ~LotWUsers ();
void load (QString const& lotw_csv_file, bool force_download = false); 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 // returns true if the specified call sign 'call' has uploaded their
// log to LotW in the last 'uploaded_since_days' days // log to LotW in the last 'age_constraint_days' days
Q_SLOT bool user (QString const& call, qint64 uploaded_since_days) const; bool user (QString const& call) const;
Q_SIGNAL void LotW_users_error (QString const& reason) const; Q_SIGNAL void LotW_users_error (QString const& reason) const;
Q_SIGNAL void load_finished () const;
private: private:
class impl; class impl;

View File

@ -334,7 +334,7 @@ MessageClient::MessageClient (QString const& id, QString const& version, QString
connect (&*m_, static_cast<void (impl::*) (impl::SocketError)> (&impl::error) connect (&*m_, static_cast<void (impl::*) (impl::SocketError)> (&impl::error)
, [this] (impl::SocketError e) , [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 if (e != impl::NetworkError // take this out when Qt 5.5
// stops doing this // stops doing this
// spuriously // spuriously

View File

@ -13,7 +13,7 @@
#include "TransceiverFactory.hpp" #include "TransceiverFactory.hpp"
#include "WFPalette.hpp" #include "WFPalette.hpp"
#include "IARURegions.hpp" #include "IARURegions.hpp"
#include "DecodeHighlightingModel.hpp"
#include "FrequencyLineEdit.hpp" #include "FrequencyLineEdit.hpp"
QItemEditorFactory * item_editor_factory () QItemEditorFactory * item_editor_factory ()
@ -47,10 +47,6 @@ void register_types ()
qRegisterMetaType<AudioDevice::Channel> ("AudioDevice::Channel"); qRegisterMetaType<AudioDevice::Channel> ("AudioDevice::Channel");
// Configuration // Configuration
#if QT_VERSION < 0x050500
qRegisterMetaType<Configuration::DataMode> ("Configuration::DataMode");
qRegisterMetaType<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen");
#endif
qRegisterMetaTypeStreamOperators<Configuration::DataMode> ("Configuration::DataMode"); qRegisterMetaTypeStreamOperators<Configuration::DataMode> ("Configuration::DataMode");
qRegisterMetaTypeStreamOperators<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen"); qRegisterMetaTypeStreamOperators<Configuration::Type2MsgGen> ("Configuration::Type2MsgGen");
@ -62,17 +58,8 @@ void register_types ()
// Transceiver // Transceiver
qRegisterMetaType<Transceiver::TransceiverState> ("Transceiver::TransceiverState"); qRegisterMetaType<Transceiver::TransceiverState> ("Transceiver::TransceiverState");
qRegisterMetaType<Transceiver::MODE> ("Transceiver::MODE");
// Transceiver factory // 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::DataBits> ("TransceiverFactory::DataBits");
qRegisterMetaTypeStreamOperators<TransceiverFactory::StopBits> ("TransceiverFactory::StopBits"); qRegisterMetaTypeStreamOperators<TransceiverFactory::StopBits> ("TransceiverFactory::StopBits");
qRegisterMetaTypeStreamOperators<TransceiverFactory::Handshake> ("TransceiverFactory::Handshake"); qRegisterMetaTypeStreamOperators<TransceiverFactory::Handshake> ("TransceiverFactory::Handshake");
@ -84,8 +71,9 @@ void register_types ()
qRegisterMetaTypeStreamOperators<WFPalette::Colours> ("Colours"); qRegisterMetaTypeStreamOperators<WFPalette::Colours> ("Colours");
// IARURegions // IARURegions
#if QT_VERSION < 0x050500
qRegisterMetaType<IARURegions::Region> ("IARURegions::Region");
#endif
qRegisterMetaTypeStreamOperators<IARURegions::Region> ("IARURegions::Region"); qRegisterMetaTypeStreamOperators<IARURegions::Region> ("IARURegions::Region");
// DecodeHighlightingModel
qRegisterMetaTypeStreamOperators<DecodeHighlightingModel::HighlightInfo> ("HighlightInfo");
qRegisterMetaTypeStreamOperators<DecodeHighlightingModel::HighlightItems> ("HighlightItems");
} }

View File

@ -98,9 +98,5 @@ QVariant Modes::headerData (int section, Qt::Orientation orientation, int role)
return result; return result;
} }
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (Modes, Mode);
#endif
ENUM_QDATASTREAM_OPS_IMPL (Modes, Mode); ENUM_QDATASTREAM_OPS_IMPL (Modes, Mode);
ENUM_CONVERSION_OPS_IMPL (Modes, Mode); ENUM_CONVERSION_OPS_IMPL (Modes, Mode);

View File

@ -29,7 +29,6 @@ class Modes final
: public QAbstractListModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS (Mode)
public: public:
// //
@ -69,19 +68,6 @@ public:
QVariant headerData (int section, Qt::Orientation, int = Qt::DisplayRole) const override; 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_QDATASTREAM_OPS_DECL (Modes, Mode);
ENUM_CONVERSION_OPS_DECL (Modes, Mode); ENUM_CONVERSION_OPS_DECL (Modes, Mode);

View File

@ -6,18 +6,9 @@
#include <QString> #include <QString>
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <QMessageLogContext>
#include <QDateTime>
#include <QMutex>
#include <QMutexLocker>
#include "pimpl_impl.hpp" #include "pimpl_impl.hpp"
namespace
{
QMutex lock;
}
class TraceFile::impl class TraceFile::impl
{ {
public: public:
@ -81,35 +72,8 @@ TraceFile::impl::~impl ()
// write Qt messages to the diagnostic log file // write Qt messages to the diagnostic log file
void TraceFile::impl::message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg) void TraceFile::impl::message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
{ {
char const * severity; Q_ASSERT_X (current_stream_, "TraceFile:message_handler", "no stream to write to");
switch (type) *current_stream_ << qFormatLogMessage (type, context, msg) << endl;
{
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;
}
if (QtFatalMsg == type) if (QtFatalMsg == type)
{ {

View File

@ -3,9 +3,6 @@
#include "moc_Transceiver.cpp" #include "moc_Transceiver.cpp"
#if !defined (QT_NO_DEBUG_STREAM) #if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (Transceiver, MODE);
QDebug operator << (QDebug d, Transceiver::TransceiverState const& s) QDebug operator << (QDebug d, Transceiver::TransceiverState const& s)
{ {
d.nospace () d.nospace ()
@ -16,7 +13,6 @@ QDebug operator << (QDebug d, Transceiver::TransceiverState const& s)
<< ')'; << ')';
return d.space (); return d.space ();
} }
#endif #endif
ENUM_QDATASTREAM_OPS_IMPL (Transceiver, MODE); ENUM_QDATASTREAM_OPS_IMPL (Transceiver, MODE);

View File

@ -52,7 +52,6 @@ class Transceiver
: public QObject : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS (MODE)
public: public:
using Frequency = Radio::Frequency; using Frequency = Radio::Frequency;
@ -154,13 +153,8 @@ public:
}; };
Q_DECLARE_METATYPE (Transceiver::TransceiverState); Q_DECLARE_METATYPE (Transceiver::TransceiverState);
#if QT_VERSION < 0x050500
Q_DECLARE_METATYPE (Transceiver::MODE);
#endif
#if !defined (QT_NO_DEBUG_STREAM) #if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (Transceiver, MODE);
QDebug operator << (QDebug, Transceiver::TransceiverState const&); QDebug operator << (QDebug, Transceiver::TransceiverState const&);
#endif #endif

View File

@ -197,15 +197,6 @@ std::unique_ptr<Transceiver> TransceiverFactory::create (ParameterPack const& pa
return result; 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, DataBits);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, StopBits); ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, StopBits);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, Handshake); ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, Handshake);

View File

@ -21,7 +21,6 @@ class TransceiverFactory
: public QObject : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS (DataBits StopBits Handshake PTTMethod TXAudioSource SplitMode)
public: public:
// //
@ -161,28 +160,6 @@ bool operator != (TransceiverFactory::ParameterPack const& lhs, TransceiverFacto
return !(lhs == rhs); 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, DataBits);
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, StopBits); ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, StopBits);
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, Handshake); ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, Handshake);

View File

@ -1,23 +1,28 @@
#include "colorhighlighting.h" #include "colorhighlighting.h"
#include "ui_colorhighlighting.h"
#include "SettingsGroup.hpp"
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
ColorHighlighting::ColorHighlighting(QSettings *settings, QWidget *parent) : #include "SettingsGroup.hpp"
QDialog(parent), #include "DecodeHighlightingModel.hpp"
settings_ {settings},
ui(new Ui::ColorHighlighting) #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); ui->setupUi(this);
setWindowTitle (QApplication::applicationName () + " - Colors");
read_settings (); read_settings ();
set_items (highlight_model);
} }
ColorHighlighting::~ColorHighlighting() ColorHighlighting::~ColorHighlighting()
{ {
if (isVisible ()) write_settings (); if (isVisible ()) write_settings ();
delete ui;
} }
void ColorHighlighting::read_settings () void ColorHighlighting::read_settings ()
@ -32,21 +37,68 @@ void ColorHighlighting::write_settings ()
settings_->setValue ("window/geometry", saveGeometry ()); settings_->setValue ("window/geometry", saveGeometry ());
} }
void ColorHighlighting::set_items (DecodeHighlightingModel const& highlighting_model)
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)
{ {
setWindowTitle(QApplication::applicationName() + " - Colors"); int index {0};
ui->label->setStyleSheet(QString("background: %1").arg(color_CQ.name())); for (auto const& item : highlighting_model.items ())
ui->label_3->setStyleSheet(QString("background: %1").arg(color_MyCall.name())); {
ui->label_5->setStyleSheet(QString("background: %1").arg(color_TxMsg.name())); QLabel * example;
ui->label_7->setStyleSheet(QString("background: %1").arg(color_DXCC.name())); QLabel * label;
ui->label_9->setStyleSheet(QString("background: %1").arg(color_DXCCband.name())); switch (index++)
ui->label_11->setStyleSheet(QString("background: %1").arg(color_NewCall.name())); {
ui->label_13->setStyleSheet(QString("background: %1").arg(color_NewCallBand.name())); case 0:
ui->label_15->setStyleSheet(QString("background: %1").arg(color_NewGrid.name())); example = ui->example1_label;
ui->label_17->setStyleSheet(QString("background: %1").arg(color_NewGridBand.name())); label = ui->p1_label;
ui->label_19->setStyleSheet(QString("color: %1").arg(color_LoTW.name())); 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_);
}
} }

View File

@ -1,30 +1,33 @@
#ifndef COLORHIGHLIGHTING_H #ifndef COLORHIGHLIGHTING_H_
#define COLORHIGHLIGHTING_H #define COLORHIGHLIGHTING_H_
#include <QDialog> #include <QDialog>
#include <QSettings> #include <QScopedPointer>
class QSettings;
class DecodeHighlightingModel;
namespace Ui { namespace Ui {
class ColorHighlighting; class ColorHighlighting;
} }
class ColorHighlighting : public QDialog class ColorHighlighting final
: public QDialog
{ {
Q_OBJECT Q_OBJECT;
public: public:
explicit ColorHighlighting(QSettings *, QWidget *parent = 0); explicit ColorHighlighting(QSettings *, DecodeHighlightingModel const&, QWidget * parent = nullptr);
~ColorHighlighting(); ~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);
private: Q_SLOT void set_items (DecodeHighlightingModel const&);
QSettings * settings_;
private:
void read_settings (); void read_settings ();
void write_settings (); void write_settings ();
Ui::ColorHighlighting *ui;
QScopedPointer<Ui::ColorHighlighting> ui;
QSettings * settings_;
}; };
#endif // COLORHIGHLIGHTING_H #endif

View File

@ -10,183 +10,206 @@
<height>253</height> <height>253</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <layout class="QGridLayout" name="gridLayout">
<string>Dialog</string> <item row="0" column="0">
</property> <widget class="QLabel" name="example1_label">
<layout class="QVBoxLayout" name="verticalLayout"> <property name="autoFillBackground">
<item> <bool>true</bool>
<layout class="QGridLayout" name="gridLayout"> </property>
<item row="6" column="0"> <property name="text">
<widget class="QLabel" name="label_17"> <string>K1ABC</string>
<property name="text"> </property>
<string>K1ABC</string> <property name="alignment">
</property> <set>Qt::AlignCenter</set>
<property name="alignment"> </property>
<set>Qt::AlignCenter</set> </widget>
</property> </item>
</widget> <item row="0" column="1">
</item> <widget class="QLabel" name="p1_label">
<item row="8" column="0"> <property name="text">
<widget class="QLabel" name="label_13"> <string>CQ in message</string>
<property name="text"> </property>
<string>K1ABC</string> </widget>
</property> </item>
<property name="alignment"> <item row="1" column="0">
<set>Qt::AlignCenter</set> <widget class="QLabel" name="example2_label">
</property> <property name="autoFillBackground">
</widget> <bool>true</bool>
</item> </property>
<item row="7" column="0"> <property name="text">
<widget class="QLabel" name="label_11"> <string>K1ABC</string>
<property name="text"> </property>
<string>K1ABC</string> <property name="alignment">
</property> <set>Qt::AlignCenter</set>
<property name="alignment"> </property>
<set>Qt::AlignCenter</set> </widget>
</property> </item>
</widget> <item row="1" column="1">
</item> <widget class="QLabel" name="p2_label">
<item row="5" column="0"> <property name="text">
<widget class="QLabel" name="label_15"> <string>My Call in message</string>
<property name="text"> </property>
<string>K1ABC</string> </widget>
</property> </item>
<property name="alignment"> <item row="2" column="0">
<set>Qt::AlignCenter</set> <widget class="QLabel" name="example3_label">
</property> <property name="autoFillBackground">
</widget> <bool>true</bool>
</item> </property>
<item row="2" column="1"> <property name="text">
<widget class="QLabel" name="label_6"> <string>K1ABC</string>
<property name="text"> </property>
<string>Transmitted message</string> <property name="alignment">
</property> <set>Qt::AlignCenter</set>
</widget> </property>
</item> </widget>
<item row="8" column="1"> </item>
<widget class="QLabel" name="label_14"> <item row="2" column="1">
<property name="text"> <widget class="QLabel" name="p3_label">
<string>New Call on Band</string> <property name="text">
</property> <string>Transmitted message</string>
</widget> </property>
</item> </widget>
<item row="7" column="1"> </item>
<widget class="QLabel" name="label_12"> <item row="3" column="0">
<property name="text"> <widget class="QLabel" name="example4_label">
<string>New Call</string> <property name="autoFillBackground">
</property> <bool>true</bool>
</widget> </property>
</item> <property name="text">
<item row="5" column="1"> <string>K1ABC</string>
<widget class="QLabel" name="label_16"> </property>
<property name="text"> <property name="alignment">
<string>New Grid</string> <set>Qt::AlignCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="3" column="1">
<widget class="QLabel" name="label_18"> <widget class="QLabel" name="p4_label">
<property name="text"> <property name="text">
<string>New Grid on Band</string> <string>New DXCC</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="example5_label">
<property name="text"> <property name="autoFillBackground">
<string>K1ABC</string> <bool>true</bool>
</property> </property>
<property name="alignment"> <property name="text">
<set>Qt::AlignCenter</set> <string>K1ABC</string>
</property> </property>
</widget> <property name="alignment">
</item> <set>Qt::AlignCenter</set>
<item row="0" column="0"> </property>
<widget class="QLabel" name="label"> </widget>
<property name="text"> </item>
<string>K1ABC</string> <item row="4" column="1">
</property> <widget class="QLabel" name="p5_label">
<property name="alignment"> <property name="text">
<set>Qt::AlignCenter</set> <string>New DXCC on Band</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="example6_label">
<property name="text"> <property name="autoFillBackground">
<string>K1ABC</string> <bool>true</bool>
</property> </property>
<property name="alignment"> <property name="text">
<set>Qt::AlignCenter</set> <string>K1ABC</string>
</property> </property>
</widget> <property name="alignment">
</item> <set>Qt::AlignCenter</set>
<item row="4" column="0"> </property>
<widget class="QLabel" name="label_9"> </widget>
<property name="text"> </item>
<string>K1ABC</string> <item row="5" column="1">
</property> <widget class="QLabel" name="p6_label">
<property name="alignment"> <property name="text">
<set>Qt::AlignCenter</set> <string>New Grid</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="6" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="example7_label">
<property name="text"> <property name="autoFillBackground">
<string>CQ in message</string> <bool>true</bool>
</property> </property>
</widget> <property name="text">
</item> <string>K1ABC</string>
<item row="1" column="1"> </property>
<widget class="QLabel" name="label_4"> <property name="alignment">
<property name="text"> <set>Qt::AlignCenter</set>
<string>My Call in message</string> </property>
</property> </widget>
</widget> </item>
</item> <item row="6" column="1">
<item row="3" column="0"> <widget class="QLabel" name="p7_label">
<widget class="QLabel" name="label_7"> <property name="text">
<property name="text"> <string>New Grid on Band</string>
<string>K1ABC</string> </property>
</property> </widget>
<property name="alignment"> </item>
<set>Qt::AlignCenter</set> <item row="7" column="0">
</property> <widget class="QLabel" name="example8_label">
</widget> <property name="autoFillBackground">
</item> <bool>true</bool>
<item row="4" column="1"> </property>
<widget class="QLabel" name="label_10"> <property name="text">
<property name="text"> <string>K1ABC</string>
<string>New DXCC on Band</string> </property>
</property> <property name="alignment">
</widget> <set>Qt::AlignCenter</set>
</item> </property>
<item row="3" column="1"> </widget>
<widget class="QLabel" name="label_8"> </item>
<property name="text"> <item row="7" column="1">
<string>New DXCC</string> <widget class="QLabel" name="p8_label">
</property> <property name="text">
</widget> <string>New Call</string>
</item> </property>
<item row="9" column="0"> </widget>
<widget class="QLabel" name="label_19"> </item>
<property name="text"> <item row="8" column="0">
<string>K1ABC</string> <widget class="QLabel" name="example9_label">
</property> <property name="autoFillBackground">
<property name="alignment"> <bool>true</bool>
<set>Qt::AlignCenter</set> </property>
</property> <property name="text">
</widget> <string>K1ABC</string>
</item> </property>
<item row="9" column="1"> <property name="alignment">
<widget class="QLabel" name="label_20"> <set>Qt::AlignCenter</set>
<property name="text"> </property>
<string>Not in LoTW</string> </widget>
</property> </item>
</widget> <item row="8" column="1">
</item> <widget class="QLabel" name="p9_label">
</layout> <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> </item>
</layout> </layout>
</widget> </widget>

View File

@ -7,14 +7,16 @@
#include <QMenu> #include <QMenu>
#include <QAction> #include <QAction>
#include "Configuration.hpp"
#include "LotWUsers.hpp" #include "LotWUsers.hpp"
#include "DecodeHighlightingModel.hpp"
#include "qt_helpers.hpp" #include "qt_helpers.hpp"
#include "moc_displaytext.cpp" #include "moc_displaytext.cpp"
DisplayText::DisplayText(QWidget *parent) DisplayText::DisplayText(QWidget *parent)
: QTextEdit(parent) : QTextEdit(parent)
, m_lotw_users {0} , m_config {nullptr}
, erase_action_ {new QAction {tr ("&Erase"), this}} , erase_action_ {new QAction {tr ("&Erase"), this}}
{ {
setReadOnly (true); setReadOnly (true);
@ -74,13 +76,53 @@ void DisplayText::insertLineSpacer(QString const& line)
appendText (line, "#d3d3d3"); appendText (line, "#d3d3d3");
} }
void DisplayText::appendText(QString const& text, QColor bg, namespace
QString const& call1, QString const& call2) {
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 (); auto cursor = textCursor ();
cursor.movePosition (QTextCursor::End); cursor.movePosition (QTextCursor::End);
auto block_format = cursor.blockFormat (); 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 ()) if (0 == cursor.position ())
{ {
cursor.setBlockFormat (block_format); cursor.setBlockFormat (block_format);
@ -91,10 +133,13 @@ void DisplayText::appendText(QString const& text, QColor bg,
else else
{ {
cursor.insertBlock (block_format); cursor.insertBlock (block_format);
auto char_format = cursor.charFormat ();
char_format.clearBackground ();
char_format.clearForeground ();
cursor.setCharFormat (char_format);
} }
QTextCharFormat format = cursor.charFormat(); QTextCharFormat format = cursor.charFormat();
format.clearBackground();
int text_index {0}; int text_index {0};
if (call1.size ()) if (call1.size ())
{ {
@ -127,7 +172,7 @@ void DisplayText::appendText(QString const& text, QColor bg,
if (pos != highlighted_calls_.end ()) if (pos != highlighted_calls_.end ())
{ {
format.setBackground (bg); format.setBackground (bg);
format.clearForeground (); format.setForeground (fg);
cursor.insertText(text.mid (text_index, call_index - text_index), format); cursor.insertText(text.mid (text_index, call_index - text_index), format);
if (pos.value ().second.isValid ()) if (pos.value ().second.isValid ())
{ {
@ -142,11 +187,14 @@ void DisplayText::appendText(QString const& text, QColor bg,
} }
} }
} }
format.setBackground (bg); if (call2.size () && m_config && m_config->lotw_users ().user (call2))
format.clearForeground (); {
if(call2.size () && !m_lotw_users->user (call2, 365)) { QColor bg;
format.setForeground(m_color_LoTW); //Mark LoTW non-users 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); cursor.insertText(text.mid (text_index), format);
// position so viewport scrolled to left // position so viewport scrolled to left
@ -157,7 +205,7 @@ void DisplayText::appendText(QString const& text, QColor bg,
} }
QString DisplayText::appendWorkedB4(QString message, QString const& callsign, QString grid, 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 // allow for seconds
int padding {message.indexOf (" ") > 4 ? 2 : 0}; int padding {message.indexOf (" ") > 4 ? 2 : 0};
@ -192,29 +240,29 @@ QString DisplayText::appendWorkedB4(QString message, QString const& callsign, QS
if (!countryWorkedBefore) { if (!countryWorkedBefore) {
// therefore not worked call either // therefore not worked call either
// appendage += "!"; // appendage += "!";
*bg = m_color_DXCC; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::CQ);
} else { } else {
if(!countryB4onBand) { if(!countryB4onBand) {
*bg = m_color_DXCCband; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::DXCCBand);
} else { } else {
if(!gridB4) { if(!gridB4) {
*bg = m_color_NewGrid; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::Grid);
} else { } else {
if(!gridB4onBand) { if(!gridB4onBand) {
*bg = m_color_NewGridBand; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::GridBand);
} else { } else {
if (!callWorkedBefore) { if (!callWorkedBefore) {
// but have worked the country // but have worked the country
// appendage += "~"; // appendage += "~";
*bg = m_color_NewCall; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::Call);
} else { } else {
if(!callB4onBand) { if(!callB4onBand) {
// appendage += "~"; // appendage += "~";
*bg = m_color_NewCallBand; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::CallBand);
} else { } else {
// appendage += " "; // have worked this call before // appendage += " "; // have worked this call before
*bg = m_color_CQ; set_colours (m_config, bg, fg, DecodeHighlightingModel::Highlight::CQ);
} }
} }
} }
@ -267,14 +315,15 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
QString currentBand, bool ppfx, bool bCQonly) QString currentBand, bool ppfx, bool bCQonly)
{ {
m_bPrincipalPrefix=ppfx; m_bPrincipalPrefix=ppfx;
QColor bg {Qt::transparent}; QColor bg;
QColor fg;
bool CQcall = false; bool CQcall = false;
if (decodedText.string ().contains (" CQ ") if (decodedText.string ().contains (" CQ ")
|| decodedText.string ().contains (" CQDX ") || decodedText.string ().contains (" CQDX ")
|| decodedText.string ().contains (" QRZ ")) || decodedText.string ().contains (" QRZ "))
{ {
CQcall = true; CQcall = true;
bg = m_color_CQ; set_colours (m_config, &bg, &fg, DecodeHighlightingModel::Highlight::CQ);
} }
if(bCQonly and !CQcall) return; if(bCQonly and !CQcall) return;
if (myCall != "" and (decodedText.indexOf (" " + myCall + " ") >= 0 if (myCall != "" and (decodedText.indexOf (" " + myCall + " ") >= 0
@ -285,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 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(); auto message = decodedText.string();
QString dxCall; QString dxCall;
@ -297,8 +346,8 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
if (displayDXCCEntity && CQcall) if (displayDXCCEntity && CQcall)
// if enabled add the DXCC entity and B4 status to the end of the // if enabled add the DXCC entity and B4 status to the end of the
// preformated text line t1 // preformated text line t1
message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, logBook, currentBand); message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, &fg, logBook, currentBand);
appendText (message.trimmed (), bg, decodedText.call (), dxCall); appendText (message.trimmed (), bg, fg, decodedText.call (), dxCall);
} }
@ -322,7 +371,10 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \ t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
" Tx " + t2 + t1 + text; " 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) void DisplayText::displayQSY(QString text)
@ -331,9 +383,9 @@ void DisplayText::displayQSY(QString text)
appendText (t, "hotpink"); 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 namespace
@ -429,20 +481,3 @@ void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg,
} }
setCurrentCharFormat (old_format); 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;
}

View File

@ -12,7 +12,7 @@
#include "decodedtext.h" #include "decodedtext.h"
class QAction; class QAction;
class LotWUsers; class Configuration;
class DisplayText class DisplayText
: public QTextEdit : public QTextEdit
@ -20,7 +20,7 @@ class DisplayText
Q_OBJECT Q_OBJECT
public: public:
explicit DisplayText(QWidget *parent = 0); explicit DisplayText(QWidget *parent = 0);
void setLotWUsers (LotWUsers const * lotw_users) {m_lotw_users = lotw_users;} void set_configuration (Configuration const * configuration) {m_config = configuration;}
void setContentFont (QFont const&); void setContentFont (QFont const&);
void insertLineSpacer(QString const&); void insertLineSpacer(QString const&);
void displayDecodedText(DecodedText const& decodedText, QString const& myCall, void displayDecodedText(DecodedText const& decodedText, QString const& myCall,
@ -28,16 +28,12 @@ public:
QString currentBand="", bool ppfx=false, bool bCQonly=false); QString currentBand="", bool ppfx=false, bool bCQonly=false);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode); void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode);
void displayQSY(QString text); void displayQSY(QString text);
void displayFoxToBeCalled(QString t, QColor bg); void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {});
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);
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers); Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
Q_SIGNAL void erased (); 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 {}); , QString const& call1 = QString {}, QString const& call2 = QString {});
Q_SLOT void erase (); Q_SLOT void erase ();
Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only); Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only);
@ -46,23 +42,14 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e);
private: private:
LotWUsers const * m_lotw_users; Configuration const * m_config;
bool m_bPrincipalPrefix; bool m_bPrincipalPrefix;
QString appendWorkedB4(QString message, QString const& callsign, QString grid, QColor * bg, QString appendWorkedB4(QString message, QString const& callsign
LogBook const& logBook, QString currentBand); , QString grid, QColor * bg, QColor * fg
, LogBook const& logBook, QString currentBand);
QFont char_font_; QFont char_font_;
QAction * erase_action_; QAction * erase_action_;
QHash<QString, QPair<QColor, QColor>> highlighted_calls_; 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; extern QHash<QString,int> m_LoTW;

View File

@ -17,13 +17,10 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QStringList> #include <QStringList>
#include <QLockFile> #include <QLockFile>
#include <QStack>
#include <QSplashScreen> #include <QSplashScreen>
#if QT_VERSION >= 0x050200
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QCommandLineOption> #include <QCommandLineOption>
#endif
#include "revision_utils.hpp" #include "revision_utils.hpp"
#include "MetaDataRegistry.hpp" #include "MetaDataRegistry.hpp"
@ -54,38 +51,12 @@ namespace
qsrand (seed); // this is good for rand() as well qsrand (seed); // this is good for rand() as well
} }
} seeding; } 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[]) int main(int argc, char *argv[])
{ {
// Add timestamps to all debug messages // 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 (); init_random_seed ();
@ -108,7 +79,6 @@ int main(int argc, char *argv[])
a.setApplicationName ("WSJT-X"); a.setApplicationName ("WSJT-X");
a.setApplicationVersion (version ()); a.setApplicationVersion (version ());
#if QT_VERSION >= 0x050200
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription ("\n" PROJECT_SUMMARY_DESCRIPTION); parser.setApplicationDescription ("\n" PROJECT_SUMMARY_DESCRIPTION);
auto help_option = parser.addHelpOption (); auto help_option = parser.addHelpOption ();
@ -210,11 +180,11 @@ int main(int argc, char *argv[])
} }
} }
} }
#endif
#if WSJT_QDEBUG_TO_FILE #if WSJT_QDEBUG_TO_FILE
// Open a trace file // Open a trace file
TraceFile trace_file {temp_dir.absoluteFilePath (a.applicationName () + "_trace.log")}; 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"; qDebug () << program_title (revision ()) + " - Program startup";
#endif #endif

View File

@ -387,8 +387,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this});
ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this});
ui->sbTR->values ({5, 10, 15, 30}); ui->sbTR->values ({5, 10, 15, 30});
ui->decodedTextBrowser->setLotWUsers (&m_config.lotw_users ()); ui->decodedTextBrowser->set_configuration (&m_config);
ui->decodedTextBrowser2->setLotWUsers (&m_config.lotw_users ()); ui->decodedTextBrowser2->set_configuration (&m_config);
m_baseCall = Radio::base_callsign (m_config.my_callsign ()); m_baseCall = Radio::base_callsign (m_config.my_callsign ());
m_opCall = m_config.opCall(); m_opCall = m_config.opCall();
@ -749,7 +749,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->decodedTextLabel->setText(t); ui->decodedTextLabel->setText(t);
ui->decodedTextLabel2->setText(t); ui->decodedTextLabel2->setText(t);
readSettings(); //Restore user's setup parameters readSettings(); //Restore user's setup parameters
setColorHighlighting(); //Set the color highlighting scheme for decoded text.
m_audioThread.start (m_audioThreadPriority); m_audioThread.start (m_audioThreadPriority);
#ifdef WIN32 #ifdef WIN32
@ -1203,7 +1202,7 @@ void MainWindow::setDecodedTextFont (QFont const& font)
ui->decodedTextBrowser->setContentFont (font); ui->decodedTextBrowser->setContentFont (font);
ui->decodedTextBrowser2->setContentFont (font); ui->decodedTextBrowser2->setContentFont (font);
ui->textBrowser4->setContentFont(font); ui->textBrowser4->setContentFont(font);
ui->textBrowser4->displayFoxToBeCalled(" ","#ffffff"); ui->textBrowser4->displayFoxToBeCalled(" ");
ui->textBrowser4->setText(""); ui->textBrowser4->setText("");
auto style_sheet = "QLabel {" + font_as_stylesheet (font) + '}'; auto style_sheet = "QLabel {" + font_as_stylesheet (font) + '}';
ui->decodedTextLabel->setStyleSheet (ui->decodedTextLabel->styleSheet () + style_sheet); ui->decodedTextLabel->setStyleSheet (ui->decodedTextLabel->styleSheet () + style_sheet);
@ -1690,23 +1689,8 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
} }
m_opCall=m_config.opCall(); 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) void MainWindow::on_monitorButton_clicked (bool checked)
{ {
if (!m_transmitting) { if (!m_transmitting) {
@ -2175,7 +2159,7 @@ void MainWindow::closeEvent(QCloseEvent * e)
m_prefixes.reset (); m_prefixes.reset ();
m_shortcuts.reset (); m_shortcuts.reset ();
m_mouseCmnds.reset (); m_mouseCmnds.reset ();
m_colorHighlighting.reset(); m_colorHighlighting.reset ();
if(m_mode!="MSK144" and m_mode!="FT8") killFile(); if(m_mode!="MSK144" and m_mode!="FT8") killFile();
float sw=0.0; float sw=0.0;
int nw=400; int nw=400;
@ -2383,16 +2367,14 @@ void MainWindow::on_actionFox_Log_triggered()
void MainWindow::on_actionColors_triggered() void MainWindow::on_actionColors_triggered()
{ {
if (!m_colorHighlighting) { if (!m_colorHighlighting)
m_colorHighlighting.reset (new ColorHighlighting {m_settings}); {
} m_colorHighlighting.reset (new ColorHighlighting {m_settings, m_config.decode_highlighting ()});
m_colorHighlighting->showNormal(); connect (&m_config, &Configuration::decode_highlighting_changed, m_colorHighlighting.data (), &ColorHighlighting::set_items);
}
m_colorHighlighting->showNormal ();
m_colorHighlighting->raise (); m_colorHighlighting->raise ();
m_colorHighlighting->activateWindow (); 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() void MainWindow::on_actionMessage_averaging_triggered()
@ -3330,13 +3312,9 @@ void MainWindow::guiUpdate()
auto const& message = tr ("Please choose another Tx frequency." auto const& message = tr ("Please choose another Tx frequency."
" WSJT-X will not knowingly transmit another" " WSJT-X will not knowingly transmit another"
" mode in the WSPR sub-band on 30m."); " mode in the WSPR sub-band on 30m.");
#if QT_VERSION >= 0x050400
QTimer::singleShot (0, [=] { // don't block guiUpdate QTimer::singleShot (0, [=] { // don't block guiUpdate
MessageBox::warning_message (this, tr ("WSPR Guard Band"), message); MessageBox::warning_message (this, tr ("WSPR Guard Band"), message);
}); });
#else
MessageBox::warning_message (this, tr ("WSPR Guard Band"), message);
#endif
} }
} }
@ -3351,13 +3329,9 @@ void MainWindow::guiUpdate()
auto const& message = tr ("Please choose another dial frequency." auto const& message = tr ("Please choose another dial frequency."
" WSJT-X will not operate in Fox mode" " WSJT-X will not operate in Fox mode"
" in the standard FT8 sub-bands."); " in the standard FT8 sub-bands.");
#if QT_VERSION >= 0x050400
QTimer::singleShot (0, [=] { // don't block guiUpdate QTimer::singleShot (0, [=] { // don't block guiUpdate
MessageBox::warning_message (this, tr ("Fox Mode warning"), message); MessageBox::warning_message (this, tr ("Fox Mode warning"), message);
}); });
#else
MessageBox::warning_message (this, tr ("Fox Mode warning"), message);
#endif
break; break;
} }
} }
@ -7681,13 +7655,9 @@ void MainWindow::write_transmit_entry (QString const& file_name)
{ {
auto const& message = tr ("Cannot open \"%1\" for append: %2") auto const& message = tr ("Cannot open \"%1\" for append: %2")
.arg (f.fileName ()).arg (f.errorString ()); .arg (f.fileName ()).arg (f.errorString ());
#if QT_VERSION >= 0x050400
QTimer::singleShot (0, [=] { // don't block guiUpdate QTimer::singleShot (0, [=] { // don't block guiUpdate
MessageBox::warning_message (this, tr ("Log File Error"), message); MessageBox::warning_message (this, tr ("Log File Error"), message);
}); });
#else
MessageBox::warning_message (this, tr ("Log File Error"), message);
#endif
} }
} }
@ -7876,9 +7846,9 @@ void MainWindow::selectHound(QString line)
if(rpt.mid(0,1) != "-" and rpt.mid(0,1) != "+") t2="+" + rpt; 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); if(t2.length()==2) t2=t2.mid(0,1) + "0" + t2.mid(1,1);
t1=t1.mid(0,12) + t2; t1=t1.mid(0,12) + t2;
ui->textBrowser4->displayFoxToBeCalled(t1,"#ffffff"); // Add hound call and rpt to tb4 ui->textBrowser4->displayFoxToBeCalled(t1); // Add hound call and rpt to tb4
t1=t1 + " " + houndGrid; // Append the grid t1=t1 + " " + houndGrid; // Append the grid
m_houndQueue.enqueue(t1); // Put this hound into the queue m_houndQueue.enqueue(t1); // Put this hound into the queue
writeFoxQSO(" Sel: " + t1); writeFoxQSO(" Sel: " + t1);
QTextCursor cursor = ui->textBrowser4->textCursor(); QTextCursor cursor = ui->textBrowser4->textCursor();
cursor.setPosition(0); // Scroll to top of list cursor.setPosition(0); // Scroll to top of list

View File

@ -18,7 +18,7 @@
QDataStream& operator << (QDataStream& os, CLASS::ENUM const& v) \ QDataStream& operator << (QDataStream& os, CLASS::ENUM const& v) \
{ \ { \
auto const& mo = CLASS::staticMetaObject; \ 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) \ QDataStream& operator >> (QDataStream& is, CLASS::ENUM& v) \
@ -47,35 +47,9 @@
QString enum_to_qstring (CLASS::ENUM const& m) \ QString enum_to_qstring (CLASS::ENUM const& m) \
{ \ { \
auto const& mo = CLASS::staticMetaObject; \ 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 inline
void throw_qstring (QString const& qs) void throw_qstring (QString const& qs)
{ {