From 4b4f65eb9f0aa4b21a6ec704553aa7377dda9abd Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 29 Nov 2018 00:56:53 +0000 Subject: [PATCH 1/3] More robust handling of imported ADIF records Some logging applications export the BAND ADIF field with uppercase characters. This change makes sure that the internal worked before lookup indexes use uppercase throughout when fields that can come from external sources are stored. --- Radio.cpp | 6 ++--- logbook/AD1CCty.cpp | 3 ++- logbook/WorkedBefore.cpp | 52 ++++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Radio.cpp b/Radio.cpp index c6175634e..3940815f4 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -136,12 +136,12 @@ namespace Radio // the full call if no valid prefix (or prefix as a suffix) is specified QString effective_prefix (QString callsign) { - auto prefix = callsign.toUpper (); + auto prefix = callsign; auto slash_pos = callsign.indexOf ('/'); if (slash_pos >= 0) { auto right_size = callsign.size () - slash_pos - 1; - if (right_size >= slash_pos) // naive call is longer than + if (right_size >= slash_pos) // native call is longer than // prefix/suffix algorithm { prefix = callsign.left (slash_pos); @@ -157,6 +157,6 @@ namespace Radio } } } - return prefix; + return prefix.toUpper (); } } diff --git a/logbook/AD1CCty.cpp b/logbook/AD1CCty.cpp index 42bacdd1c..58ed375f6 100644 --- a/logbook/AD1CCty.cpp +++ b/logbook/AD1CCty.cpp @@ -159,8 +159,9 @@ public: { } - Record fixup (QString const& call, prefix const& p) const + Record fixup (QString call, prefix const& p) const { + call = call.toUpper (); using entity_by_id = entities_type::index::type; entity_by_id::iterator e; // iterator into entity set diff --git a/logbook/WorkedBefore.cpp b/logbook/WorkedBefore.cpp index 41723e003..d6bac814a 100644 --- a/logbook/WorkedBefore.cpp +++ b/logbook/WorkedBefore.cpp @@ -307,10 +307,10 @@ WorkedBefore::WorkedBefore () if (call.size ()) { auto const& entity = m_->prefixes_.lookup (call); - m_->worked_.emplace (call - , extractField (record, "GRIDSQUARE").left (4) // not interested in 6-digit grids - , extractField (record, "BAND") - , extractField (record, "MODE") + m_->worked_.emplace (call.toUpper () + , extractField (record, "GRIDSQUARE").left (4).toUpper () // not interested in 6-digit grids + , extractField (record, "BAND").toUpper () + , extractField (record, "MODE").toUpper () , entity.entity_name , entity.continent , entity.CQ_zone @@ -357,8 +357,8 @@ bool WorkedBefore::add (QString const& call } out << ADIF_record << " " << endl; } - m_->worked_.emplace (call, grid, band, mode, entity.entity_name - , entity.continent, entity.CQ_zone, entity.ITU_zone); + m_->worked_.emplace (call.toUpper (), grid.left (4).toUpper (), band.toUpper (), mode.toUpper () + , entity.entity_name, entity.continent, entity.CQ_zone, entity.ITU_zone); } return true; } @@ -372,7 +372,7 @@ bool WorkedBefore::country_worked (QString const& country, QString const& mode, return country.size () && m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (country, mode, band)); + != m_->worked_.get ().find (std::make_tuple (country, mode.toUpper (), band.toUpper ())); } else { @@ -380,7 +380,7 @@ bool WorkedBefore::country_worked (QString const& country, QString const& mode, return country.size () && m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (country, mode)); + != m_->worked_.get ().find (std::make_tuple (country, mode.toUpper ())); } } else @@ -390,7 +390,7 @@ bool WorkedBefore::country_worked (QString const& country, QString const& mode, return country.size () && m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (country, band)); + != m_->worked_.get ().find (std::make_tuple (country, band.toUpper ())); } else { @@ -410,13 +410,13 @@ bool WorkedBefore::grid_worked (QString const& grid, QString const& mode, QStrin if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (grid, mode, band)); + != m_->worked_.get ().find (std::make_tuple (grid.left (4).toUpper (), mode.toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (grid, mode)); + != m_->worked_.get ().find (std::make_tuple (grid.left (4).toUpper (), mode.toUpper ())); } } else @@ -424,13 +424,13 @@ bool WorkedBefore::grid_worked (QString const& grid, QString const& mode, QStrin if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (grid, band)); + != m_->worked_.get ().find (std::make_tuple (grid.left (4).toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (grid); + != m_->worked_.get ().find (grid.left (4).toUpper ()); } } } @@ -442,13 +442,13 @@ bool WorkedBefore::call_worked (QString const& call, QString const& mode, QStrin if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (call, mode, band)); + != m_->worked_.get ().find (std::make_tuple (call.toUpper (), mode.toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (call, mode)); + != m_->worked_.get ().find (std::make_tuple (call.toUpper (), mode.toUpper ())); } } else @@ -456,13 +456,13 @@ bool WorkedBefore::call_worked (QString const& call, QString const& mode, QStrin if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (call, band)); + != m_->worked_.get ().find (std::make_tuple (call.toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (call)); + != m_->worked_.get ().find (std::make_tuple (call.toUpper ())); } } } @@ -474,13 +474,13 @@ bool WorkedBefore::continent_worked (Continent continent, QString const& mode, Q if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (continent, mode, band)); + != m_->worked_.get ().find (std::make_tuple (continent, mode.toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (continent, mode)); + != m_->worked_.get ().find (std::make_tuple (continent, mode.toUpper ())); } } else @@ -488,7 +488,7 @@ bool WorkedBefore::continent_worked (Continent continent, QString const& mode, Q if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (continent, band)); + != m_->worked_.get ().find (std::make_tuple (continent, band.toUpper ())); } else { @@ -506,13 +506,13 @@ bool WorkedBefore::CQ_zone_worked (int CQ_zone, QString const& mode, QString con if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (CQ_zone, mode, band)); + != m_->worked_.get ().find (std::make_tuple (CQ_zone, mode.toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (CQ_zone, mode)); + != m_->worked_.get ().find (std::make_tuple (CQ_zone, mode.toUpper ())); } } else @@ -520,7 +520,7 @@ bool WorkedBefore::CQ_zone_worked (int CQ_zone, QString const& mode, QString con if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (CQ_zone, band)); + != m_->worked_.get ().find (std::make_tuple (CQ_zone, band.toUpper ())); } else { @@ -538,13 +538,13 @@ bool WorkedBefore::ITU_zone_worked (int ITU_zone, QString const& mode, QString c if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (ITU_zone, mode, band)); + != m_->worked_.get ().find (std::make_tuple (ITU_zone, mode.toUpper (), band.toUpper ())); } else { // partial key lookup return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (ITU_zone, mode)); + != m_->worked_.get ().find (std::make_tuple (ITU_zone, mode.toUpper ())); } } else @@ -552,7 +552,7 @@ bool WorkedBefore::ITU_zone_worked (int ITU_zone, QString const& mode, QString c if (band.size ()) { return m_->worked_.get ().end () - != m_->worked_.get ().find (std::make_tuple (ITU_zone, band)); + != m_->worked_.get ().find (std::make_tuple (ITU_zone, band.toUpper ())); } else { From e5b17e270c771e6225d77d7268f3dfb3e1928bc1 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 29 Nov 2018 01:03:44 +0000 Subject: [PATCH 2/3] Improved decode highlighting Add "Settings->Colors->Decode Highlighting" context menu buttons to unset b/g and f/g colours. Add colour value as #rrggbb or unset in text to list items. Improved colour assignment to decodes giving better and more intuitive behaviour. --- Configuration.ui | 12 ++--- models/DecodeHighlightingModel.cpp | 8 ++- widgets/DecodeHighlightingListView.cpp | 55 +++++++++----------- widgets/DecodeHighlightingListView.hpp | 6 --- widgets/displaytext.cpp | 71 ++++++++++++++------------ widgets/displaytext.h | 2 +- 6 files changed, 75 insertions(+), 79 deletions(-) diff --git a/Configuration.ui b/Configuration.ui index 7a3ec96be..f82523e73 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -2197,7 +2197,7 @@ Right click for insert and delete options. true - <html><head/><body><p>Enable or disable using the check boxes and right-click an item to change the foreground color, background color, or reset the item to default values. Drag and drop the items to change their priority, higher in the list is higher in priority.</p></body></html> + <html><head/><body><p>Enable or disable using the check boxes and right-click an item to change or unset the foreground color, background color, or reset the item to default values. Drag and drop the items to change their priority, higher in the list is higher in priority.</p><p>Note that each foreground or background color may be either set or unset, unset means that it is not allocated for that item's type and lower priority items may apply.</p></body></html> QAbstractScrollArea::AdjustToContents @@ -3013,12 +3013,12 @@ Right click for insert and delete options. - - - - - + + + + + diff --git a/models/DecodeHighlightingModel.cpp b/models/DecodeHighlightingModel.cpp index 4f1ec3fbb..6425a1a5c 100644 --- a/models/DecodeHighlightingModel.cpp +++ b/models/DecodeHighlightingModel.cpp @@ -4,7 +4,8 @@ #include #include #include -#include +#include + #include #include #include #include @@ -160,7 +161,10 @@ QVariant DecodeHighlightingModel::data (const QModelIndex& index, int role) cons result = item.enabled_ ? Qt::Checked : Qt::Unchecked; break; case Qt::DisplayRole: - result = highlight_name (item.type_); + return QString {"%1 [f/g:%2, b/g:%3]"} + .arg (highlight_name (item.type_)) + .arg (item.foreground_.style () != Qt::NoBrush ? QString {"#%1"}.arg (item.foreground_.color ().rgb () & 0xffffff, 6, 16, QChar {'0'}) : QString {"unset"}) + .arg (item.background_.style () != Qt::NoBrush ? QString {"#%1"}.arg (item.background_.color ().rgb () & 0xffffff, 6, 16, QChar {'0'}) : QString {"unset"}); break; case Qt::ForegroundRole: if (Qt::NoBrush != item.foreground_.style ()) diff --git a/widgets/DecodeHighlightingListView.cpp b/widgets/DecodeHighlightingListView.cpp index 31115d1f7..cc5ea5d2e 100644 --- a/widgets/DecodeHighlightingListView.cpp +++ b/widgets/DecodeHighlightingListView.cpp @@ -6,31 +6,12 @@ #include "models/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 * fg_colour_action = new QAction {tr ("&Foreground color ..."), this}; + addAction (fg_colour_action); + connect (fg_colour_action, &QAction::triggered, [this] (bool /*checked*/) { auto const& index = currentIndex (); auto colour = QColorDialog::getColor (model ()->data (index, Qt::ForegroundRole).value ().color () , this @@ -38,10 +19,19 @@ DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent) .arg (model ()->data (index).toString ())); if (colour.isValid ()) { - model ()->setData (index, colour, Qt::ForegroundRole); + model ()->setData (index, QBrush {colour}, Qt::ForegroundRole); } }); - connect (&m_->bg_colour_action_, &QAction::triggered, [this] (bool /*checked*/) { + + auto * unset_fg_colour_action = new QAction {tr ("&Unset foreground color"), this}; + addAction (unset_fg_colour_action); + connect (unset_fg_colour_action, &QAction::triggered, [this] (bool /*checked*/) { + model ()->setData (currentIndex (), QBrush {}, Qt::ForegroundRole); + }); + + auto * bg_colour_action = new QAction {tr ("&Background color ..."), this}; + addAction (bg_colour_action); + connect (bg_colour_action, &QAction::triggered, [this] (bool /*checked*/) { auto const& index = currentIndex (); auto colour = QColorDialog::getColor (model ()->data (index, Qt::BackgroundRole).value ().color () , this @@ -49,10 +39,19 @@ DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent) .arg (model ()->data (index).toString ())); if (colour.isValid ()) { - model ()->setData (index, colour, Qt::BackgroundRole); + model ()->setData (index, QBrush {colour}, Qt::BackgroundRole); } }); - connect (&m_->defaults_action_, &QAction::triggered, [this] (bool /*checked*/) { + + auto * unset_bg_colour_action = new QAction {tr ("U&nset background color"), this}; + addAction (unset_bg_colour_action); + connect (unset_bg_colour_action, &QAction::triggered, [this] (bool /*checked*/) { + model ()->setData (currentIndex (), QBrush {}, Qt::BackgroundRole); + }); + + auto * defaults_action = new QAction {tr ("&Reset this item to defaults"), this}; + addAction (defaults_action); + connect (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); @@ -60,10 +59,6 @@ DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent) }); } -DecodeHighlightingListView::~DecodeHighlightingListView () -{ -} - QSize DecodeHighlightingListView::sizeHint () const { auto item_height = sizeHintForRow (0); diff --git a/widgets/DecodeHighlightingListView.hpp b/widgets/DecodeHighlightingListView.hpp index 731ecbb54..86aa86f4f 100644 --- a/widgets/DecodeHighlightingListView.hpp +++ b/widgets/DecodeHighlightingListView.hpp @@ -3,8 +3,6 @@ #include -#include "pimpl_h.hpp" - class QWidget; // Class Decode Highlighting List View @@ -20,13 +18,9 @@ class DecodeHighlightingListView final { public: explicit DecodeHighlightingListView (QWidget * parent = nullptr); - ~DecodeHighlightingListView (); private: QSize sizeHint () const override; - - class impl; - pimpl m_; }; #endif diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 7a00346cb..73df8af63 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -121,6 +121,7 @@ void DisplayText::appendText(QString const& text, QColor bg, QColor fg , QString const& call1, QString const& call2) { // qDebug () << "DisplayText::appendText: text:" << text << "Nbsp pos:" << text.indexOf (QChar::Nbsp); + auto cursor = textCursor (); cursor.movePosition (QTextCursor::End); auto block_format = cursor.blockFormat (); @@ -136,16 +137,6 @@ void DisplayText::appendText(QString const& text, QColor bg, QColor fg { format.setForeground (fg); } - if (call2.size () && m_config && m_config->lotw_users ().user (call2)) - { - QColor bg; - QColor fg; - highlight_types types {Highlight::LotW}; - set_colours (m_config, &bg, &fg, types); - if (bg.isValid ()) block_format.setBackground (bg); - if (fg.isValid ()) format.setForeground (fg); - } - if (cursor.position ()) { cursor.insertBlock (block_format, format); @@ -212,13 +203,12 @@ void DisplayText::appendText(QString const& text, QColor bg, QColor fg document ()->setMaximumBlockCount (document ()->maximumBlockCount ()); } -QString DisplayText::appendWorkedB4 (QString message, QString const& callsign, QString const& grid, +QString DisplayText::appendWorkedB4 (QString message, QString call, QString const& grid, QColor * bg, QColor * fg, LogBook const& logBook, QString const& currentBand, QString const& currentMode) { // allow for seconds int padding {message.indexOf (" ") > 4 ? 2 : 0}; - QString call = callsign; QString countryName; bool callB4; bool callB4onBand; @@ -292,6 +282,10 @@ QString DisplayText::appendWorkedB4 (QString message, QString const& callsign, Q if(!ITUZoneB4onBand) { types.push_back (Highlight::ITUZoneBand); } + if (m_config && m_config->lotw_users ().user (call)) + { + types.push_back (Highlight::LotW); + } types.push_back (Highlight::CQ); auto top_highlight = set_colours (m_config, bg, fg, types); @@ -367,21 +361,22 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con || decodedText.string ().contains (" QRZ ")) { CQcall = true; - highlight_types types {Highlight::CQ}; - set_colours (m_config, &bg, &fg, types); } - if(bCQonly and !CQcall) return; - if (myCall != "" and (decodedText.indexOf (" " + myCall + " ") >= 0 - or decodedText.indexOf (" " + myCall + "/") >= 0 - or decodedText.indexOf ("<" + myCall + "/") >= 0 - or decodedText.indexOf ("/" + myCall + " ") >= 0 - or decodedText.indexOf ("/" + myCall + ">") >= 0 - or decodedText.indexOf ("<" + myCall + " ") >= 0 - or decodedText.indexOf ("<" + myCall + ">") >= 0 - or decodedText.indexOf (" " + myCall + ">") >= 0)) { - highlight_types types {Highlight::MyCall}; - set_colours (m_config, &bg, &fg, types); - } + else + { + if (bCQonly) return; + if (myCall != "" && (decodedText.indexOf (" " + myCall + " ") >= 0 + or decodedText.indexOf (" " + myCall + "/") >= 0 + or decodedText.indexOf ("<" + myCall + "/") >= 0 + or decodedText.indexOf ("/" + myCall + " ") >= 0 + or decodedText.indexOf ("/" + myCall + ">") >= 0 + or decodedText.indexOf ("<" + myCall + " ") >= 0 + or decodedText.indexOf ("<" + myCall + ">") >= 0 + or decodedText.indexOf (" " + myCall + ">") >= 0)) { + highlight_types types {Highlight::MyCall}; + set_colours (m_config, &bg, &fg, types); + } + } auto message = decodedText.string(); QString dxCall; QString dxGrid; @@ -389,17 +384,25 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; if(!dxGrid.contains(grid_regexp)) dxGrid=""; message = message.left (message.indexOf (QChar::Nbsp)); // strip appended info - if (displayDXCCEntity && CQcall) + if (CQcall) { - // if enabled add the DXCC entity and B4 status to the end of the - // preformated text line t1 - auto currentMode = mode; - if ("JT9+JT65" == mode) + if (displayDXCCEntity) { - currentMode = decodedText.isJT65 () ? "JT65" : "JT9"; + // if enabled add the DXCC entity and B4 status to the end of the + // preformated text line t1 + auto currentMode = mode; + if ("JT9+JT65" == mode) + { + currentMode = decodedText.isJT65 () ? "JT65" : "JT9"; + } + message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, &fg + , logBook, currentBand, currentMode); + } + else + { + highlight_types types {Highlight::CQ, Highlight::LotW}; + set_colours (m_config, &bg, &fg, types); } - message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, &fg - , logBook, currentBand, currentMode); } appendText (message.trimmed (), bg, fg, decodedText.call (), dxCall); } diff --git a/widgets/displaytext.h b/widgets/displaytext.h index 2ccd8fe4c..1f20ac157 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -44,7 +44,7 @@ protected: private: Configuration const * m_config; bool m_bPrincipalPrefix; - QString appendWorkedB4(QString message, QString const& callsign + QString appendWorkedB4(QString message, QString callsign , QString const& grid, QColor * bg, QColor * fg , LogBook const& logBook, QString const& currentBand , QString const& currentMode); From 7113d58fb9f45e2ff370b5ec58add72c0f948942 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 29 Nov 2018 02:31:08 +0000 Subject: [PATCH 3/3] Use the QSO end time from the Log QSO dialog for the contest log records --- widgets/logqso.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/logqso.cpp b/widgets/logqso.cpp index b6412cb59..e5b8a2e56 100644 --- a/widgets/logqso.cpp +++ b/widgets/logqso.cpp @@ -139,7 +139,7 @@ void LogQSO::accept() return; // without accepting } - if (!m_cabrilloLog->add_QSO (m_dialFreq, QDateTime::currentDateTimeUtc (), hisCall, + if (!m_cabrilloLog->add_QSO (m_dialFreq, m_dateTimeOff, hisCall, ui->exchSent->text (), ui->exchRcvd->text ())) { show ();