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
DoubleClickableRadioButton.cpp
LotWUsers.cpp
DecodeHighlightingModel.cpp
DecodeHighlightingListView.cpp
)
set (wsjt_qtmm_CXXSRCS

View File

@ -157,7 +157,6 @@
#include <QStandardPaths>
#include <QFont>
#include <QFontDialog>
#include <QColorDialog>
#include <QSerialPortInfo>
#include <QScopedPointer>
#include <QDebug>
@ -182,6 +181,7 @@
#include "CallsignValidator.hpp"
#include "LotWUsers.hpp"
#include "ExchangeValidator.hpp"
#include "DecodeHighlightingModel.hpp"
#include "ui_Configuration.h"
#include "moc_Configuration.cpp"
@ -445,17 +445,8 @@ private:
Q_SLOT void on_calibration_slope_ppm_spin_box_valueChanged (double);
Q_SLOT void handle_transceiver_update (TransceiverState const&, unsigned sequence_number);
Q_SLOT void handle_transceiver_failure (QString const& reason);
Q_SLOT void on_pbCQmsg_clicked();
Q_SLOT void on_pbMyCall_clicked();
Q_SLOT void on_pbTxMsg_clicked();
Q_SLOT void on_pbNewDXCC_clicked();
Q_SLOT void on_pbNewDXCCband_clicked();
Q_SLOT void on_pbNewCall_clicked();
Q_SLOT void on_pbNewCallBand_clicked();
Q_SLOT void on_pbNewGrid_clicked();
Q_SLOT void on_pbNewGridBand_clicked();
Q_SLOT void on_pbLoTW_clicked();
Q_SLOT void on_pbResetDefaults_clicked();
Q_SLOT void on_reset_highlighting_to_defaults_push_button_clicked (bool);
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
Q_SLOT void on_cbFox_clicked (bool);
Q_SLOT void on_cbHound_clicked (bool);
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
@ -530,10 +521,14 @@ private:
QAction * reset_frequencies_action_;
FrequencyDialog * frequency_dialog_;
QAction * station_delete_action_;
QAction * station_insert_action_;
QAction station_delete_action_;
QAction station_insert_action_;
StationDialog * station_dialog_;
DecodeHighlightingModel decode_highlighing_model_;
DecodeHighlightingModel next_decode_highlighing_model_;
int LotW_days_since_upload_;
TransceiverFactory::ParameterPack rig_params_;
TransceiverFactory::ParameterPack saved_rig_params_;
TransceiverFactory::Capabilities::PortType last_port_type_;
@ -553,26 +548,6 @@ private:
QString my_grid_;
QString FD_exchange_;
QString RTTY_exchange_;
QColor color_CQ_;
QColor next_color_CQ_;
QColor color_MyCall_;
QColor next_color_MyCall_;
QColor color_TxMsg_;
QColor next_color_TxMsg_;
QColor color_DXCC_;
QColor next_color_DXCC_;
QColor color_DXCCband_;
QColor next_color_DXCCband_;
QColor color_NewCall_;
QColor next_color_NewCall_;
QColor color_NewCallBand_;
QColor next_color_NewCallBand_;
QColor color_NewGrid_;
QColor next_color_NewGrid_;
QColor color_NewGridBand_;
QColor next_color_NewGridBand_;
QColor color_LoTW_;
QColor next_color_LoTW_;
qint32 id_interval_;
qint32 ntrials_;
@ -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_;}
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
QString Configuration::my_callsign () const {return m_->my_callsign_;}
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
QColor Configuration::color_DXCC () const {return m_->color_DXCC_;}
QColor Configuration::color_DXCCband() const {return m_->color_DXCCband_;}
QColor Configuration::color_NewCall () const {return m_->color_NewCall_;}
QColor Configuration::color_NewCallBand () const {return m_->color_NewCallBand_;}
QColor Configuration::color_NewGrid () const {return m_->color_NewGrid_;}
QColor Configuration::color_NewGridBand () const {return m_->color_NewGridBand_;}
QColor Configuration::color_LoTW() const {return m_->color_LoTW_;}
QFont Configuration::text_font () const {return m_->font_;}
QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;}
qint32 Configuration::id_interval () const {return m_->id_interval_;}
@ -748,6 +713,7 @@ QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
bool Configuration::pwrBandTxMemory () const {return m_->pwrBandTxMemory_;}
bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;}
LotWUsers const& Configuration::lotw_users () const {return m_->lotw_users_;}
DecodeHighlightingModel const& Configuration::decode_highlighting () const {return m_->decode_highlighing_model_;}
void Configuration::set_calibration (CalibrationParams params)
{
@ -941,7 +907,10 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
, current_offset_ {0}
, current_tx_offset_ {0}
, 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}}
, LotW_days_since_upload_ {0}
, last_port_type_ {TransceiverFactory::Capabilities::none}
, rig_is_dummy_ {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
read_settings ();
// load LotW users data
lotw_users_.load (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv"));
// conditionally load LotW users data
ui_->LotW_CSV_fetch_push_button->setEnabled (false);
connect (&lotw_users_, &LotWUsers::load_finished, [this] () {
ui_->LotW_CSV_fetch_push_button->setEnabled (true);
});
lotw_users_.set_local_file_path (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv"));
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text ());
//
// validation
@ -1134,29 +1108,30 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
ui_->frequencies_table_view->insertAction (nullptr, reset_frequencies_action_);
connect (reset_frequencies_action_, &QAction::triggered, this, &Configuration::impl::reset_frequencies);
//
// setup stations table model & view
//
stations_.sort (StationList::band_column);
ui_->stations_table_view->setModel (&next_stations_);
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
// delegates
// stations delegates
auto stations_item_delegate = new QStyledItemDelegate {this};
stations_item_delegate->setItemEditorFactory (item_editor_factory ());
ui_->stations_table_view->setItemDelegate (stations_item_delegate);
ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this});
// actions
station_delete_action_ = new QAction {tr ("&Delete"), ui_->stations_table_view};
ui_->stations_table_view->insertAction (nullptr, station_delete_action_);
connect (station_delete_action_, &QAction::triggered, this, &Configuration::impl::delete_stations);
// stations actions
ui_->stations_table_view->addAction (&station_delete_action_);
connect (&station_delete_action_, &QAction::triggered, this, &Configuration::impl::delete_stations);
station_insert_action_ = new QAction {tr ("&Insert ..."), ui_->stations_table_view};
ui_->stations_table_view->insertAction (nullptr, station_insert_action_);
connect (station_insert_action_, &QAction::triggered, this, &Configuration::impl::insert_station);
ui_->stations_table_view->addAction (&station_insert_action_);
connect (&station_insert_action_, &QAction::triggered, this, &Configuration::impl::insert_station);
//
// colours and highlighting setup
//
ui_->highlighting_list_view->setModel (&next_decode_highlighing_model_);
//
// load combo boxes with audio setup choices
@ -1200,16 +1175,6 @@ void Configuration::impl::initialize_models ()
ui_->callsign_line_edit->setText (my_callsign_);
ui_->grid_line_edit->setText (my_grid_);
ui_->use_dynamic_grid->setChecked(use_dynamic_grid_);
ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name()));
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name()));
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name()));
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(color_DXCCband_.name()));
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name()));
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(color_NewCallBand_.name()));
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(color_NewGrid_.name()));
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(color_NewGridBand_.name()));
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(color_LoTW_.name()));
ui_->CW_id_interval_spin_box->setValue (id_interval_);
ui_->sbNtrials->setValue (ntrials_);
ui_->sbTxDelay->setValue (txDelay_);
@ -1311,6 +1276,9 @@ void Configuration::impl::initialize_models ()
next_frequencies_.frequency_list (frequencies_.frequency_list ());
next_stations_.station_list (stations_.station_list ());
next_decode_highlighing_model_.items (decode_highlighing_model_.items ());
ui_->LotW_days_since_upload_spin_box->setValue (LotW_days_since_upload_);
set_rig_invariants ();
}
@ -1334,16 +1302,6 @@ void Configuration::impl::read_settings ()
RTTY_exchange_ = settings_->value ("RTTYExchange",QString {}).toString ();
ui_->FieldDay_Exchange->setText(FD_exchange_);
ui_->RTTY_Exchange->setText(RTTY_exchange_);
next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString();
next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString();
next_color_TxMsg_ = color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString();
next_color_DXCC_ = color_DXCC_ = settings_->value("colorDXCC","#ff00ff").toString();
next_color_DXCCband_ = color_DXCCband_ = settings_->value("colorDXCCband","#ffaaff").toString();
next_color_NewCall_ = color_NewCall_ = settings_->value("colorNewCall","#66b2ff").toString();
next_color_NewCallBand_ = color_NewCallBand_ = settings_->value("colorNewCallBand","#99ffff").toString();
next_color_NewGrid_ = color_NewGrid_ = settings_->value("colorNewGrid","#ffaa00").toString();
next_color_NewGridBand_ = color_NewGridBand_ = settings_->value("colorNewGridBand","#ffcc99").toString();
next_color_LoTW_ = color_LoTW_ = settings_->value("colorLoTW","#990000").toString();
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
&& next_font_ != font_)
{
@ -1358,6 +1316,8 @@ void Configuration::impl::read_settings ()
&& next_decoded_text_font_ != decoded_text_font_)
{
decoded_text_font_ = next_decoded_text_font_;
next_decode_highlighing_model_.set_font (decoded_text_font_);
ui_->highlighting_list_view->reset ();
Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
}
else
@ -1461,6 +1421,10 @@ void Configuration::impl::read_settings ()
stations_.station_list (settings_->value ("stations").value<StationList::Stations> ());
decode_highlighing_model_.items (settings_->value ("DecodeHighlighting", QVariant::fromValue (DecodeHighlightingModel::default_items ())).value<DecodeHighlightingModel::HighlightItems> ());
LotW_days_since_upload_ = settings_->value ("LotWDaysSinceLastUpload", 365).toInt ();
lotw_users_.set_age_constraint (LotW_days_since_upload_);
log_as_RTTY_ = settings_->value ("toRTTY", false).toBool ();
report_in_comments_ = settings_->value("dBtoComments", false).toBool ();
rig_params_.rig_name = settings_->value ("Rig", TransceiverFactory::basic_transceiver_name_).toString ();
@ -1531,16 +1495,6 @@ void Configuration::impl::write_settings ()
settings_->setValue ("MyGrid", my_grid_);
settings_->setValue ("FieldDayExchange", FD_exchange_);
settings_->setValue ("RTTYExchange", RTTY_exchange_);
settings_->setValue("colorCQ",color_CQ_);
settings_->setValue("colorMyCall",color_MyCall_);
settings_->setValue("colorTxMsg",color_TxMsg_);
settings_->setValue("colorDXCC",color_DXCC_);
settings_->setValue("colorDXCCband",color_DXCCband_);
settings_->setValue("colorNewCall",color_NewCall_);
settings_->setValue("colorNewCallBand",color_NewCallBand_);
settings_->setValue("colorNewGrid",color_NewGrid_);
settings_->setValue("colorNewGridBand",color_NewGridBand_);
settings_->setValue("colorLoTW",color_LoTW_);
settings_->setValue ("Font", font_.toString ());
settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ());
settings_->setValue ("IDint", id_interval_);
@ -1582,6 +1536,8 @@ void Configuration::impl::write_settings ()
settings_->setValue ("Macros", macros_.stringList ());
settings_->setValue ("FrequenciesForRegionModes", QVariant::fromValue (frequencies_.frequency_list ()));
settings_->setValue ("stations", QVariant::fromValue (stations_.station_list ()));
settings_->setValue ("DecodeHighlighting", QVariant::fromValue (decode_highlighing_model_.items ()));
settings_->setValue ("LotWDaysSinceLastUpload", LotW_days_since_upload_);
settings_->setValue ("toRTTY", log_as_RTTY_);
settings_->setValue ("dBtoComments", report_in_comments_);
settings_->setValue ("Rig", rig_params_.rig_name);
@ -1905,20 +1861,11 @@ void Configuration::impl::accept ()
if (next_decoded_text_font_ != decoded_text_font_)
{
decoded_text_font_ = next_decoded_text_font_;
next_decode_highlighing_model_.set_font (decoded_text_font_);
ui_->highlighting_list_view->reset ();
Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
}
color_CQ_ = next_color_CQ_;
color_MyCall_ = next_color_MyCall_;
color_TxMsg_ = next_color_TxMsg_;
color_DXCC_ = next_color_DXCC_;
color_DXCCband_ = next_color_DXCCband_;
color_NewCall_ = next_color_NewCall_;
color_NewCallBand_ = next_color_NewCallBand_;
color_NewGrid_ = next_color_NewGrid_;
color_NewGridBand_ = next_color_NewGridBand_;
color_LoTW_ = next_color_LoTW_;
rig_params_ = temp_rig_params; // now we can go live with the rig
// related configuration parameters
rig_is_dummy_ = TransceiverFactory::basic_transceiver_name_ == rig_params_.rig_name;
@ -2065,10 +2012,8 @@ void Configuration::impl::accept ()
}
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text ();
n1mm_server_name_ = new_n1mm_server;
auto new_n1mm_port = ui_->n1mm_server_port_spin_box->value ();
n1mm_server_port_ = new_n1mm_port;
n1mm_server_name_ = ui_->n1mm_server_name_line_edit->text ();
n1mm_server_port_ = ui_->n1mm_server_port_spin_box->value ();
broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked ();
udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
@ -2089,10 +2034,18 @@ void Configuration::impl::accept ()
if (stations_.station_list () != next_stations_.station_list ())
{
stations_.station_list(next_stations_.station_list ());
stations_.station_list (next_stations_.station_list ());
stations_.sort (StationList::band_column);
}
if (decode_highlighing_model_.items () != next_decode_highlighing_model_.items ())
{
decode_highlighing_model_.items (next_decode_highlighing_model_.items ());
Q_EMIT self_->decode_highlighting_changed (decode_highlighing_model_);
}
LotW_days_since_upload_ = ui_->LotW_days_since_upload_spin_box->value ();
lotw_users_.set_age_constraint (LotW_days_since_upload_);
if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
{
// turning on so clear it so only the next location update gets used
@ -2131,136 +2084,27 @@ void Configuration::impl::on_font_push_button_clicked ()
next_font_ = QFontDialog::getFont (0, next_font_, this);
}
void Configuration::impl::on_pbCQmsg_clicked()
void Configuration::impl::on_reset_highlighting_to_defaults_push_button_clicked (bool /*checked*/)
{
auto new_color = QColorDialog::getColor(next_color_CQ_, this, "CQ Messages Color");
if (new_color.isValid ())
if (MessageBox::Yes == MessageBox::query_message (this
, tr ("Reset Decode Highlighting")
, tr ("Reset all decode highlighting and priorities to default values")))
{
next_color_CQ_ = new_color;
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
next_decode_highlighing_model_.items (DecodeHighlightingModel::default_items ());
}
}
void Configuration::impl::on_pbMyCall_clicked()
void Configuration::impl::on_LotW_CSV_fetch_push_button_clicked (bool /*checked*/)
{
auto new_color = QColorDialog::getColor(next_color_MyCall_, this, "My Call Messages Color");
if (new_color.isValid ())
{
next_color_MyCall_ = new_color;
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(next_color_MyCall_.name()));
}
}
void Configuration::impl::on_pbTxMsg_clicked()
{
auto new_color = QColorDialog::getColor(next_color_TxMsg_, this, "Tx Messages Color");
if (new_color.isValid ())
{
next_color_TxMsg_ = new_color;
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_TxMsg_.name()));
}
}
void Configuration::impl::on_pbNewDXCC_clicked()
{
auto new_color = QColorDialog::getColor(next_color_DXCC_, this, "New DXCC Messages Color");
if (new_color.isValid ())
{
next_color_DXCC_ = new_color;
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(next_color_DXCC_.name()));
}
}
void Configuration::impl::on_pbNewDXCCband_clicked()
{
auto new_color = QColorDialog::getColor(next_color_DXCCband_, this, "New DXCCband Color");
if (new_color.isValid ())
{
next_color_DXCCband_ = new_color;
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(next_color_DXCCband_.name()));
}
}
void Configuration::impl::on_pbNewCall_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewCall_, this, "New Call Messages Color");
if (new_color.isValid ())
{
next_color_NewCall_ = new_color;
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(next_color_NewCall_.name()));
}
}
void Configuration::impl::on_pbNewCallBand_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewCallBand_, this, "New CallBand Color");
if (new_color.isValid ())
{
next_color_NewCallBand_ = new_color;
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(next_color_NewCallBand_.name()));
}
}
void Configuration::impl::on_pbNewGrid_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewGrid_, this, "New Grid Messages Color");
if (new_color.isValid ())
{
next_color_NewGrid_ = new_color;
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(next_color_NewGrid_.name()));
}
}
void Configuration::impl::on_pbNewGridBand_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewGridBand_, this, "New GridBand Messages Color");
if (new_color.isValid ())
{
next_color_NewGridBand_ = new_color;
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(next_color_NewGridBand_.name()));
}
}
void Configuration::impl::on_pbLoTW_clicked()
{
auto new_color = QColorDialog::getColor(next_color_LoTW_, this, "Not in LoTW Color");
if (new_color.isValid ()) {
next_color_LoTW_ = new_color;
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(next_color_LoTW_.name()));
}
}
void Configuration::impl::on_pbResetDefaults_clicked()
{
next_color_CQ_ = color_CQ_ = "#66ff66";
next_color_MyCall_ = color_MyCall_ = "#ff6666";
next_color_TxMsg_ = color_TxMsg_ = "#ffff00";
next_color_DXCC_ = color_DXCC_ = "#ff00ff";
next_color_DXCCband_ = color_DXCCband_ = "#ffaaff";
next_color_NewCall_ = color_NewCall_ = "#66b2ff";
next_color_NewCallBand_ = color_NewCallBand_ = "#99ffff";
next_color_NewGrid_ = color_NewGrid_ = "#ffaa00";
next_color_NewGridBand_ = color_NewGridBand_ = "#ffcc99";
next_color_LoTW_ = color_LoTW_ = "#5500ff";
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(next_color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_TxMsg_.name()));
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(next_color_DXCC_.name()));
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(next_color_DXCCband_.name()));
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(next_color_NewCall_.name()));
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(next_color_NewCallBand_.name()));
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(next_color_NewGrid_.name()));
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(next_color_NewGridBand_.name()));
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(next_color_LoTW_.name()));
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), true);
ui_->LotW_CSV_fetch_push_button->setEnabled (false);
}
void Configuration::impl::on_decoded_text_font_push_button_clicked ()
{
next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this
, tr ("WSJT-X Decoded Text Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::MonospacedFonts
#endif
);
}
@ -3077,11 +2921,6 @@ auto Configuration::impl::remove_calibration (Frequency f) const -> Frequency
/ (1. + calibration_.slope_ppm / 1.e6));
}
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (Configuration, DataMode);
ENUM_QDEBUG_OPS_IMPL (Configuration, Type2MsgGen);
#endif
ENUM_QDATASTREAM_OPS_IMPL (Configuration, DataMode);
ENUM_QDATASTREAM_OPS_IMPL (Configuration, Type2MsgGen);

View File

@ -23,6 +23,7 @@ class StationList;
class QStringListModel;
class QHostAddress;
class LotWUsers;
class DecodeHighlightingModel;
//
// Class Configuration
@ -58,7 +59,6 @@ class Configuration final
: public QObject
{
Q_OBJECT
Q_ENUMS (DataMode Type2MsgGen)
public:
using MODE = Transceiver::MODE;
@ -172,19 +172,10 @@ public:
QDir azel_directory () const;
QString rig_name () const;
Type2MsgGen type_2_msg_gen () const;
QColor color_CQ () const;
QColor color_MyCall () const;
QColor color_TxMsg () const;
QColor color_DXCC () const;
QColor color_DXCCband () const;
QColor color_NewCall () const;
QColor color_NewCallBand () const;
QColor color_NewGrid () const;
QColor color_NewGridBand () const;
QColor color_LoTW() const;
bool pwrBandTxMemory () const;
bool pwrBandTuneMemory () const;
LotWUsers const& lotw_users () const;
DecodeHighlightingModel const& decode_highlighting () const;
struct CalibrationParams
{
@ -267,15 +258,17 @@ public:
// These signals indicate a font has been selected and accepted for
// the application text and decoded text respectively.
//
Q_SIGNAL void text_font_changed (QFont);
Q_SIGNAL void decoded_text_font_changed (QFont);
Q_SIGNAL void text_font_changed (QFont) const;
Q_SIGNAL void decoded_text_font_changed (QFont) const;
//
// This signal is emitted when the UDP server changes
//
Q_SIGNAL void udp_server_changed (QString const& udp_server);
Q_SIGNAL void udp_server_port_changed (port_type server_port);
Q_SIGNAL void udp_server_changed (QString const& udp_server) const;
Q_SIGNAL void udp_server_port_changed (port_type server_port) const;
// signal updates to decode highlighting
Q_SIGNAL void decode_highlighting_changed (DecodeHighlightingModel const&) const;
//
// These signals are emitted and reflect transceiver state changes
@ -297,16 +290,6 @@ private:
pimpl<impl> m_;
};
#if QT_VERSION < 0x050500
Q_DECLARE_METATYPE (Configuration::DataMode);
Q_DECLARE_METATYPE (Configuration::Type2MsgGen);
#endif
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (Configuration, DataMode);
ENUM_QDEBUG_OPS_DECL (Configuration, Type2MsgGen);
#endif
ENUM_QDATASTREAM_OPS_DECL (Configuration, DataMode);
ENUM_QDATASTREAM_OPS_DECL (Configuration, Type2MsgGen);

View File

@ -1704,6 +1704,9 @@ QListView::item:hover {
<property name="text">
<string>Op Call:</string>
</property>
<property name="buddy">
<cstring>opCallEntry</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
@ -1909,6 +1912,9 @@ for assessing propagation and system performance.</string>
<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>
</property>
<property name="buddy">
<cstring>n1mm_server_name_line_edit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
@ -1923,6 +1929,9 @@ for assessing propagation and system performance.</string>
<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>
</property>
<property name="buddy">
<cstring>n1mm_server_port_spin_box</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
@ -2166,8 +2175,158 @@ Right click for insert and delete options.</string>
<attribute name="title">
<string>Colors</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5" rowstretch="1,0,0" columnstretch="1,0,0">
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QGroupBox" name="groupBox_12">
<property name="title">
<string>Decode Highlightling</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="DecodeHighlightingListView" name="highlighting_list_view">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&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">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -2180,317 +2339,6 @@ Right click for insert and delete options.</string>
</property>
</spacer>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_13">
<item row="9" column="1">
<widget class="QLabel" name="labLoTW">
<property name="styleSheet">
<string notr="true">QLabel{color: #990000}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pbMyCall">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>My Call in message</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="pbNewDXCCband">
<property name="text">
<string>New DXCC on Band</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="labDXCCband">
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ffaaff}
</string>
</property>
<property name="text">
<string notr="true">K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="pbCQmsg">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>CQ in message</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="labTx">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: yellow}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pbTxMsg">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Transmitted message</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labMyCall">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ff6666}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labCQ">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #66ff66}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labDXCC">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ff00ff}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QPushButton" name="pbResetDefaults">
<property name="text">
<string>Reset Defaults</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="pbNewDXCC">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>New DXCC</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="labNewGrid">
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ff8000}</string>
</property>
<property name="text">
<string notr="true">K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="labNewGridBand">
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ffcc99}</string>
</property>
<property name="text">
<string notr="true">K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="labNewCall">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #00ffff}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QPushButton" name="pbNewGrid">
<property name="text">
<string>New grid</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QPushButton" name="pbNewGridBand">
<property name="text">
<string>New Grid on Band</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="labNewCallBand">
<property name="styleSheet">
<string notr="true">QLabel{background-color: #99ffff}</string>
</property>
<property name="text">
<string notr="true">K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QPushButton" name="pbNewCall">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>New Call</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QPushButton" name="pbNewCallBand">
<property name="text">
<string>New Call on Band</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QPushButton" name="pbLoTW">
<property name="text">
<string>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>
</widget>
<widget class="QWidget" name="advanced_tab">
@ -2990,36 +2838,49 @@ Right click for insert and delete options.</string>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>DecodeHighlightingListView</class>
<extends>QListView</extends>
<header>DecodehigHlightingListView.hpp</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>configuration_tabs</tabstop>
<tabstop>callsign_line_edit</tabstop>
<tabstop>grid_line_edit</tabstop>
<tabstop>use_dynamic_grid</tabstop>
<tabstop>region_combo_box</tabstop>
<tabstop>type_2_msg_gen_combo_box</tabstop>
<tabstop>insert_blank_check_box</tabstop>
<tabstop>miles_check_box</tabstop>
<tabstop>TX_messages_check_box</tabstop>
<tabstop>DXCC_check_box</tabstop>
<tabstop>ppfx_check_box</tabstop>
<tabstop>font_push_button</tabstop>
<tabstop>decoded_text_font_push_button</tabstop>
<tabstop>monitor_off_check_box</tabstop>
<tabstop>monitor_last_used_check_box</tabstop>
<tabstop>quick_call_check_box</tabstop>
<tabstop>tx_watchdog_spin_box</tabstop>
<tabstop>disable_TX_on_73_check_box</tabstop>
<tabstop>CW_id_after_73_check_box</tabstop>
<tabstop>enable_VHF_features_check_box</tabstop>
<tabstop>tx_QSY_check_box</tabstop>
<tabstop>single_decode_check_box</tabstop>
<tabstop>decode_at_52s_check_box</tabstop>
<tabstop>tx_watchdog_spin_box</tabstop>
<tabstop>CW_id_interval_spin_box</tabstop>
<tabstop>rig_combo_box</tabstop>
<tabstop>CAT_poll_interval_spin_box</tabstop>
<tabstop>CAT_port_combo_box</tabstop>
<tabstop>CAT_serial_baud_combo_box</tabstop>
<tabstop>CAT_default_bit_radio_button</tabstop>
<tabstop>CAT_7_bit_radio_button</tabstop>
<tabstop>CAT_8_bit_radio_button</tabstop>
<tabstop>CAT_default_stop_bit_radio_button</tabstop>
<tabstop>CAT_one_stop_bit_radio_button</tabstop>
<tabstop>CAT_two_stop_bit_radio_button</tabstop>
<tabstop>CAT_handshake_default_radio_button</tabstop>
<tabstop>CAT_handshake_none_radio_button</tabstop>
<tabstop>CAT_handshake_xon_radio_button</tabstop>
<tabstop>CAT_handshake_hardware_radio_button</tabstop>
@ -3053,29 +2914,48 @@ Right click for insert and delete options.</string>
<tabstop>delete_macro_push_button</tabstop>
<tabstop>macros_list_view</tabstop>
<tabstop>prompt_to_log_check_box</tabstop>
<tabstop>cbAutoLog</tabstop>
<tabstop>log_as_RTTY_check_box</tabstop>
<tabstop>report_in_comments_check_box</tabstop>
<tabstop>clear_DX_check_box</tabstop>
<tabstop>opCallEntry</tabstop>
<tabstop>psk_reporter_check_box</tabstop>
<tabstop>udp_server_line_edit</tabstop>
<tabstop>udp_server_port_spin_box</tabstop>
<tabstop>accept_udp_requests_check_box</tabstop>
<tabstop>udpWindowToFront</tabstop>
<tabstop>udpWindowRestore</tabstop>
<tabstop>enable_n1mm_broadcast_check_box</tabstop>
<tabstop>n1mm_server_name_line_edit</tabstop>
<tabstop>n1mm_server_port_spin_box</tabstop>
<tabstop>calibration_slope_ppm_spin_box</tabstop>
<tabstop>calibration_intercept_spin_box</tabstop>
<tabstop>frequencies_table_view</tabstop>
<tabstop>stations_table_view</tabstop>
<tabstop>pbCQmsg</tabstop>
<tabstop>pbMyCall</tabstop>
<tabstop>pbTxMsg</tabstop>
<tabstop>pbNewDXCC</tabstop>
<tabstop>highlighting_list_view</tabstop>
<tabstop>reset_highlighting_to_defaults_push_button</tabstop>
<tabstop>LotW_CSV_URL_line_edit</tabstop>
<tabstop>LotW_CSV_fetch_push_button</tabstop>
<tabstop>LotW_days_since_upload_spin_box</tabstop>
<tabstop>sbNtrials</tabstop>
<tabstop>sbAggressive</tabstop>
<tabstop>cbTwoPass</tabstop>
<tabstop>sbDegrade</tabstop>
<tabstop>sbBandwidth</tabstop>
<tabstop>sbTxDelay</tabstop>
<tabstop>cbx2ToneSpacing</tabstop>
<tabstop>cbx4ToneSpacing</tabstop>
<tabstop>cbFox</tabstop>
<tabstop>cbHound</tabstop>
<tabstop>cbGenerate77</tabstop>
<tabstop>cbDecode77</tabstop>
<tabstop>rbNone</tabstop>
<tabstop>rbNA_VHF_Contest</tabstop>
<tabstop>rbEU_VHF_Contest</tabstop>
<tabstop>rbFieldDay</tabstop>
<tabstop>FieldDay_Exchange</tabstop>
<tabstop>rbRTTYroundup</tabstop>
<tabstop>RTTY_Exchange</tabstop>
</tabstops>
<resources/>
<connections>
@ -3145,12 +3025,12 @@ Right click for insert and delete options.</string>
</connection>
</connections>
<buttongroups>
<buttongroup name="CAT_data_bits_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="split_mode_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="PTT_method_button_group"/>
</buttongroups>
</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 "ui_ExportCabrillo.h"
#include "SettingsGroup.hpp"
#include "MessageBox.hpp"
@ -7,6 +6,9 @@
#include <QDebug>
#include <QFileDialog>
#include "ui_ExportCabrillo.h"
#include "moc_ExportCabrillo.cpp"
ExportCabrillo::ExportCabrillo(QSettings *settings, QWidget *parent) :
QDialog(parent),
settings_ {settings},

View File

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

View File

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

View File

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

View File

@ -29,8 +29,6 @@ class IARURegions final
: public QAbstractListModel
{
Q_OBJECT
Q_ENUMS (Region)
public:
//
// This enumeration contains the supported regions, to complement
@ -62,19 +60,6 @@ public:
QVariant headerData (int section, Qt::Orientation, int = Qt::DisplayRole) const override;
};
// Qt boilerplate to make the IARURegions::region enumeration a type
// that can be streamed and queued as a signal argument as well as
// showing the human readable string when output to debug streams.
#if QT_VERSION < 0x050500
// Qt 5.5 introduces the Q_ENUM macro which automatically registers
// the meta-type
Q_DECLARE_METATYPE (IARURegions::Region);
#endif
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (IARURegions, Region);
#endif
ENUM_QDATASTREAM_OPS_DECL (IARURegions, Region);
ENUM_CONVERSION_OPS_DECL (IARURegions, Region);

View File

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

View File

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

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)
, [this] (impl::SocketError e)
{
#if defined (Q_OS_WIN) && QT_VERSION >= 0x050500
#if defined (Q_OS_WIN)
if (e != impl::NetworkError // take this out when Qt 5.5
// stops doing this
// spuriously

View File

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

View File

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

View File

@ -29,7 +29,6 @@ class Modes final
: public QAbstractListModel
{
Q_OBJECT
Q_ENUMS (Mode)
public:
//
@ -69,19 +68,6 @@ public:
QVariant headerData (int section, Qt::Orientation, int = Qt::DisplayRole) const override;
};
// Qt boilerplate to make the Modes::Mode enumeration a type that can
// be streamed and queued as a signal argument as well as showing the
// human readable string when output to debug streams.
#if QT_VERSION < 0x050500
// Qt 5.5 introduces the Q_ENUM macro which automatically registers
// the meta-type
Q_DECLARE_METATYPE (Modes::Mode);
#endif
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (Modes, Mode);
#endif
ENUM_QDATASTREAM_OPS_DECL (Modes, Mode);
ENUM_CONVERSION_OPS_DECL (Modes, Mode);

View File

@ -6,18 +6,9 @@
#include <QString>
#include <QFile>
#include <QTextStream>
#include <QMessageLogContext>
#include <QDateTime>
#include <QMutex>
#include <QMutexLocker>
#include "pimpl_impl.hpp"
namespace
{
QMutex lock;
}
class TraceFile::impl
{
public:
@ -81,35 +72,8 @@ TraceFile::impl::~impl ()
// write Qt messages to the diagnostic log file
void TraceFile::impl::message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
{
char const * severity;
switch (type)
{
case QtDebugMsg:
severity = "Debug";
break;
case QtWarningMsg:
severity = "Warning";
break;
case QtFatalMsg:
severity = "Fatal";
break;
default:
severity = "Critical";
break;
}
{
// guard against multiple threads with overlapping messages
QMutexLocker guard (&lock);
Q_ASSERT_X (current_stream_, "TraceFile:message_handler", "no stream to write to");
*current_stream_
<< QDateTime::currentDateTimeUtc ().toString ("yyyy-MM-ddTHH:mm:ss.zzzZ")
<< '(' << context.file << ':' << context.line /* << ", " << context.function */ << ')'
<< severity << ": " << msg.trimmed () << endl;
}
Q_ASSERT_X (current_stream_, "TraceFile:message_handler", "no stream to write to");
*current_stream_ << qFormatLogMessage (type, context, msg) << endl;
if (QtFatalMsg == type)
{

View File

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

View File

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

View File

@ -197,15 +197,6 @@ std::unique_ptr<Transceiver> TransceiverFactory::create (ParameterPack const& pa
return result;
}
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, DataBits);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, StopBits);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, Handshake);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, PTTMethod);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, TXAudioSource);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, SplitMode);
#endif
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, DataBits);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, StopBits);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, Handshake);

View File

@ -21,7 +21,6 @@ class TransceiverFactory
: public QObject
{
Q_OBJECT
Q_ENUMS (DataBits StopBits Handshake PTTMethod TXAudioSource SplitMode)
public:
//
@ -161,28 +160,6 @@ bool operator != (TransceiverFactory::ParameterPack const& lhs, TransceiverFacto
return !(lhs == rhs);
}
//
// boilerplate routines to make enum types useable and debuggable in
// Qt
//
#if QT_VERSION < 0x050500
Q_DECLARE_METATYPE (TransceiverFactory::DataBits);
Q_DECLARE_METATYPE (TransceiverFactory::StopBits);
Q_DECLARE_METATYPE (TransceiverFactory::Handshake);
Q_DECLARE_METATYPE (TransceiverFactory::PTTMethod);
Q_DECLARE_METATYPE (TransceiverFactory::TXAudioSource);
Q_DECLARE_METATYPE (TransceiverFactory::SplitMode);
#endif
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, DataBits);
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, StopBits);
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, Handshake);
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, PTTMethod);
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, TXAudioSource);
ENUM_QDEBUG_OPS_DECL (TransceiverFactory, SplitMode);
#endif
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, DataBits);
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, StopBits);
ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, Handshake);

View File

@ -1,23 +1,28 @@
#include "colorhighlighting.h"
#include "ui_colorhighlighting.h"
#include "SettingsGroup.hpp"
#include <QApplication>
#include <QDebug>
ColorHighlighting::ColorHighlighting(QSettings *settings, QWidget *parent) :
QDialog(parent),
settings_ {settings},
ui(new Ui::ColorHighlighting)
#include "SettingsGroup.hpp"
#include "DecodeHighlightingModel.hpp"
#include "ui_colorhighlighting.h"
#include "moc_colorhighlighting.cpp"
ColorHighlighting::ColorHighlighting (QSettings * settings, DecodeHighlightingModel const& highlight_model, QWidget * parent)
: QDialog {parent}
, ui {new Ui::ColorHighlighting}
, settings_ {settings}
{
ui->setupUi(this);
setWindowTitle (QApplication::applicationName () + " - Colors");
read_settings ();
set_items (highlight_model);
}
ColorHighlighting::~ColorHighlighting()
{
if (isVisible ()) write_settings ();
delete ui;
}
void ColorHighlighting::read_settings ()
@ -32,21 +37,68 @@ void ColorHighlighting::write_settings ()
settings_->setValue ("window/geometry", saveGeometry ());
}
void ColorHighlighting::colorHighlightlingSetup(QColor color_CQ,QColor color_MyCall,
QColor color_DXCC,QColor color_DXCCband,QColor color_NewCall,
QColor color_NewCallBand,QColor color_NewGrid,QColor color_NewGridBand,
QColor color_TxMsg,QColor color_LoTW)
void ColorHighlighting::set_items (DecodeHighlightingModel const& highlighting_model)
{
setWindowTitle(QApplication::applicationName() + " - Colors");
ui->label->setStyleSheet(QString("background: %1").arg(color_CQ.name()));
ui->label_3->setStyleSheet(QString("background: %1").arg(color_MyCall.name()));
ui->label_5->setStyleSheet(QString("background: %1").arg(color_TxMsg.name()));
ui->label_7->setStyleSheet(QString("background: %1").arg(color_DXCC.name()));
ui->label_9->setStyleSheet(QString("background: %1").arg(color_DXCCband.name()));
ui->label_11->setStyleSheet(QString("background: %1").arg(color_NewCall.name()));
ui->label_13->setStyleSheet(QString("background: %1").arg(color_NewCallBand.name()));
ui->label_15->setStyleSheet(QString("background: %1").arg(color_NewGrid.name()));
ui->label_17->setStyleSheet(QString("background: %1").arg(color_NewGridBand.name()));
ui->label_19->setStyleSheet(QString("color: %1").arg(color_LoTW.name()));
int index {0};
for (auto const& item : highlighting_model.items ())
{
QLabel * example;
QLabel * label;
switch (index++)
{
case 0:
example = ui->example1_label;
label = ui->p1_label;
break;
case 1:
example = ui->example2_label;
label = ui->p2_label;
break;
case 2:
example = ui->example3_label;
label = ui->p3_label;
break;
case 3:
example = ui->example4_label;
label = ui->p4_label;
break;
case 4:
example = ui->example5_label;
label = ui->p5_label;
break;
case 5:
example = ui->example6_label;
label = ui->p6_label;
break;
case 6:
example = ui->example7_label;
label = ui->p7_label;
break;
case 7:
example = ui->example8_label;
label = ui->p8_label;
break;
case 8:
example = ui->example9_label;
label = ui->p9_label;
break;
case 9:
example = ui->example10_label;
label = ui->p10_label;
break;
}
auto palette = example->parentWidget ()->palette ();
if (Qt::NoBrush != item.background_.style ())
{
palette.setColor (QPalette::Window, item.background_.color ());
}
if (Qt::NoBrush != item.foreground_.style ())
{
palette.setColor (QPalette::WindowText, item.foreground_.color ());
}
example->setPalette (palette);
example->setEnabled (item.enabled_);
label->setText (DecodeHighlightingModel::highlight_name (item.type_));
label->setEnabled (item.enabled_);
}
}

View File

@ -1,30 +1,33 @@
#ifndef COLORHIGHLIGHTING_H
#define COLORHIGHLIGHTING_H
#ifndef COLORHIGHLIGHTING_H_
#define COLORHIGHLIGHTING_H_
#include <QDialog>
#include <QSettings>
#include <QScopedPointer>
class QSettings;
class DecodeHighlightingModel;
namespace Ui {
class ColorHighlighting;
class ColorHighlighting;
}
class ColorHighlighting : public QDialog
class ColorHighlighting final
: public QDialog
{
Q_OBJECT
Q_OBJECT;
public:
explicit ColorHighlighting(QSettings *, QWidget *parent = 0);
~ColorHighlighting();
void colorHighlightlingSetup(QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_DXCCband, QColor color_NewCall,
QColor color_NewCallBand, QColor color_NewGrid, QColor color_NewGridBand,
QColor color_TxMsg, QColor color_LoTW);
public:
explicit ColorHighlighting(QSettings *, DecodeHighlightingModel const&, QWidget * parent = nullptr);
~ColorHighlighting ();
private:
QSettings * settings_;
Q_SLOT void set_items (DecodeHighlightingModel const&);
private:
void read_settings ();
void write_settings ();
Ui::ColorHighlighting *ui;
QScopedPointer<Ui::ColorHighlighting> ui;
QSettings * settings_;
};
#endif // COLORHIGHLIGHTING_H
#endif

View File

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

View File

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

View File

@ -12,7 +12,7 @@
#include "decodedtext.h"
class QAction;
class LotWUsers;
class Configuration;
class DisplayText
: public QTextEdit
@ -20,7 +20,7 @@ class DisplayText
Q_OBJECT
public:
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 insertLineSpacer(QString const&);
void displayDecodedText(DecodedText const& decodedText, QString const& myCall,
@ -28,16 +28,12 @@ public:
QString currentBand="", bool ppfx=false, bool bCQonly=false);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode);
void displayQSY(QString text);
void displayFoxToBeCalled(QString t, QColor bg);
void setDecodedTextColors(QColor color_CQ, QColor color_MyCall, QColor color_DXCC,
QColor color_DXCCband, QColor color_NewCall, QColor color_NewCallBand,
QColor color_NewGrid, QColor color_NewGridBand, QColor color_TxMsg,
QColor color_LoTW);
void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {});
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
Q_SIGNAL void erased ();
Q_SLOT void appendText (QString const& text, QColor bg = Qt::white
Q_SLOT void appendText (QString const& text, QColor bg = QColor {}, QColor fg = QColor {}
, QString const& call1 = QString {}, QString const& call2 = QString {});
Q_SLOT void erase ();
Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only);
@ -46,23 +42,14 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *e);
private:
LotWUsers const * m_lotw_users;
Configuration const * m_config;
bool m_bPrincipalPrefix;
QString appendWorkedB4(QString message, QString const& callsign, QString grid, QColor * bg,
LogBook const& logBook, QString currentBand);
QString appendWorkedB4(QString message, QString const& callsign
, QString grid, QColor * bg, QColor * fg
, LogBook const& logBook, QString currentBand);
QFont char_font_;
QAction * erase_action_;
QHash<QString, QPair<QColor, QColor>> highlighted_calls_;
QColor m_color_CQ;
QColor m_color_MyCall;
QColor m_color_DXCC;
QColor m_color_DXCCband;
QColor m_color_NewCall;
QColor m_color_NewCallBand;
QColor m_color_NewGrid;
QColor m_color_NewGridBand;
QColor m_color_LoTW;
QColor m_color_TxMsg;
};
extern QHash<QString,int> m_LoTW;

View File

@ -17,13 +17,10 @@
#include <QStandardPaths>
#include <QStringList>
#include <QLockFile>
#include <QStack>
#include <QSplashScreen>
#if QT_VERSION >= 0x050200
#include <QCommandLineParser>
#include <QCommandLineOption>
#endif
#include "revision_utils.hpp"
#include "MetaDataRegistry.hpp"
@ -54,38 +51,12 @@ namespace
qsrand (seed); // this is good for rand() as well
}
} seeding;
class MessageTimestamper
{
public:
MessageTimestamper ()
{
prior_handlers_.push (qInstallMessageHandler (message_handler));
}
~MessageTimestamper ()
{
if (prior_handlers_.size ()) qInstallMessageHandler (prior_handlers_.pop ());
}
private:
static void message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
{
QtMessageHandler handler {prior_handlers_.top ()};
if (handler)
{
handler (type, context,
QDateTime::currentDateTimeUtc ().toString ("yy-MM-ddTHH:mm:ss.zzzZ: ") + msg);
}
}
static QStack<QtMessageHandler> prior_handlers_;
};
QStack<QtMessageHandler> MessageTimestamper::prior_handlers_;
}
int main(int argc, char *argv[])
{
// Add timestamps to all debug messages
MessageTimestamper message_timestamper;
qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}");
init_random_seed ();
@ -108,7 +79,6 @@ int main(int argc, char *argv[])
a.setApplicationName ("WSJT-X");
a.setApplicationVersion (version ());
#if QT_VERSION >= 0x050200
QCommandLineParser parser;
parser.setApplicationDescription ("\n" PROJECT_SUMMARY_DESCRIPTION);
auto help_option = parser.addHelpOption ();
@ -210,11 +180,11 @@ int main(int argc, char *argv[])
}
}
}
#endif
#if WSJT_QDEBUG_TO_FILE
// Open a trace file
TraceFile trace_file {temp_dir.absoluteFilePath (a.applicationName () + "_trace.log")};
qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}");
qDebug () << program_title (revision ()) + " - Program startup";
#endif

View File

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

View File

@ -18,7 +18,7 @@
QDataStream& operator << (QDataStream& os, CLASS::ENUM const& v) \
{ \
auto const& mo = CLASS::staticMetaObject; \
return os << mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (v); \
return os << mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (static_cast<int> (v)); \
} \
\
QDataStream& operator >> (QDataStream& is, CLASS::ENUM& v) \
@ -47,35 +47,9 @@
QString enum_to_qstring (CLASS::ENUM const& m) \
{ \
auto const& mo = CLASS::staticMetaObject; \
return QString {mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (m)}; \
return QString {mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (static_cast<int> (m))}; \
}
#if QT_VERSION >= 0x050500
// Qt 5.5 now has Q_ENUM which registers enumns better
#define ENUM_QDEBUG_OPS_DECL(CLASS, ENUM)
#define ENUM_QDEBUG_OPS_IMPL(CLASS, ENUM)
#else
#define Q_ENUM(E)
#include <QDebug>
class QVariant;
#define ENUM_QDEBUG_OPS_DECL(CLASS, ENUM) \
QDebug operator << (QDebug, CLASS::ENUM const&);
#define ENUM_QDEBUG_OPS_IMPL(CLASS, ENUM) \
QDebug operator << (QDebug d, CLASS::ENUM const& m) \
{ \
auto const& mo = CLASS::staticMetaObject; \
return d << mo.enumerator (mo.indexOfEnumerator (#ENUM)).valueToKey (m); \
}
#endif
inline
void throw_qstring (QString const& qs)
{