diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5d18467c..a2d6dd396 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -237,6 +237,7 @@ set (wsjt_qt_CXXSRCS
models/FrequencyList.cpp
models/StationList.cpp
widgets/FrequencyLineEdit.cpp
+ widgets/FrequencyDeltaLineEdit.cpp
item_delegates/CandidateKeyFilter.cpp
item_delegates/ForeignKeyDelegate.cpp
validators/LiveFrequencyValidator.cpp
@@ -279,9 +280,12 @@ set (wsjt_qt_CXXSRCS
widgets/CabrilloLogWindow.cpp
item_delegates/CallsignDelegate.cpp
item_delegates/MaidenheadLocatorDelegate.cpp
+ item_delegates/FrequencyDelegate.cpp
+ item_delegates/FrequencyDeltaDelegate.cpp
models/CabrilloLog.cpp
logbook/AD1CCty.cpp
logbook/WorkedBefore.cpp
+ logbook/Multiplier.cpp
)
set (wsjt_qtmm_CXXSRCS
diff --git a/Configuration.cpp b/Configuration.cpp
index d1cc8d172..b78739d11 100644
--- a/Configuration.cpp
+++ b/Configuration.cpp
@@ -167,8 +167,11 @@
#include "MetaDataRegistry.hpp"
#include "SettingsGroup.hpp"
#include "widgets/FrequencyLineEdit.hpp"
+#include "widgets/FrequencyDeltaLineEdit.hpp"
#include "item_delegates/CandidateKeyFilter.hpp"
#include "item_delegates/ForeignKeyDelegate.hpp"
+#include "item_delegates/FrequencyDelegate.hpp"
+#include "item_delegates/FrequencyDeltaDelegate.hpp"
#include "TransceiverFactory.hpp"
#include "Transceiver.hpp"
#include "models/Bands.hpp"
@@ -564,6 +567,7 @@ private:
DecodeHighlightingModel decode_highlighing_model_;
DecodeHighlightingModel next_decode_highlighing_model_;
bool highlight_by_mode_;
+ bool include_WAE_entities_;
int LotW_days_since_upload_;
TransceiverFactory::ParameterPack rig_params_;
@@ -745,6 +749,7 @@ 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_;}
bool Configuration::highlight_by_mode () const {return m_->highlight_by_mode_;}
+bool Configuration::include_WAE_entities () const {return m_->include_WAE_entities_;}
void Configuration::set_calibration (CalibrationParams params)
{
@@ -950,6 +955,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
, station_insert_action_ {tr ("&Insert ..."), nullptr}
, station_dialog_ {new StationDialog {&next_stations_, &bands_, this}}
, highlight_by_mode_ {false}
+ , include_WAE_entities_ {false}
, LotW_days_since_upload_ {0}
, last_port_type_ {TransceiverFactory::Capabilities::none}
, rig_is_dummy_ {false}
@@ -1119,9 +1125,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::frequency_mhz_column, true);
// delegates
- auto frequencies_item_delegate = new QStyledItemDelegate {this};
- frequencies_item_delegate->setItemEditorFactory (item_editor_factory ());
- ui_->frequencies_table_view->setItemDelegate (frequencies_item_delegate);
+ ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::frequency_column, new FrequencyDelegate {this});
ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::region_column, new ForeignKeyDelegate {®ions_, 0, this});
ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::mode_column, new ForeignKeyDelegate {&modes_, 0, this});
@@ -1160,9 +1164,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
// 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::offset_column, new FrequencyDeltaDelegate {this});
ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this});
// stations actions
@@ -1319,6 +1321,7 @@ void Configuration::impl::initialize_models ()
next_decode_highlighing_model_.items (decode_highlighing_model_.items ());
ui_->highlight_by_mode_check_box->setChecked (highlight_by_mode_);
+ ui_->include_WAE_check_box->setChecked (include_WAE_entities_);
ui_->LotW_days_since_upload_spin_box->setValue (LotW_days_since_upload_);
set_rig_invariants ();
@@ -1467,6 +1470,7 @@ void Configuration::impl::read_settings ()
if (!highlight_items.size ()) highlight_items = DecodeHighlightingModel::default_items ();
decode_highlighing_model_.items (highlight_items);
highlight_by_mode_ = settings_->value("HighlightByMode", false).toBool ();
+ include_WAE_entities_ = settings_->value("IncludeWAEEntities", false).toBool ();
LotW_days_since_upload_ = settings_->value ("LotWDaysSinceLastUpload", 365).toInt ();
lotw_users_.set_age_constraint (LotW_days_since_upload_);
@@ -1579,7 +1583,7 @@ void Configuration::impl::write_settings ()
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 ("HighlightByMode", highlight_by_mode_);
+ settings_->setValue ("IncludeWAEEntities", include_WAE_entities_);
settings_->setValue ("LotWDaysSinceLastUpload", LotW_days_since_upload_);
settings_->setValue ("toRTTY", log_as_RTTY_);
settings_->setValue ("dBtoComments", report_in_comments_);
@@ -2116,6 +2120,7 @@ void Configuration::impl::accept ()
Q_EMIT self_->decode_highlighting_changed (decode_highlighing_model_);
}
highlight_by_mode_ = ui_->highlight_by_mode_check_box->isChecked ();
+ include_WAE_entities_ = ui_->include_WAE_check_box->isChecked ();
LotW_days_since_upload_ = ui_->LotW_days_since_upload_spin_box->value ();
lotw_users_.set_age_constraint (LotW_days_since_upload_);
diff --git a/Configuration.hpp b/Configuration.hpp
index 9535605d9..80f5a5cd1 100644
--- a/Configuration.hpp
+++ b/Configuration.hpp
@@ -177,6 +177,7 @@ public:
LotWUsers const& lotw_users () const;
DecodeHighlightingModel const& decode_highlighting () const;
bool highlight_by_mode () const;
+ bool include_WAE_entities () const;
enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, FOX, HOUND};
SpecialOperatingActivity special_op_id () const;
diff --git a/Configuration.ui b/Configuration.ui
index e32f4a198..a9fe51d45 100644
--- a/Configuration.ui
+++ b/Configuration.ui
@@ -2294,6 +2294,23 @@ Right click for insert and delete options.
+ -
+
+
-
+
+
+ -
+
+
+ Include extra WAE entities
+
+
+ include_WAE_check_box
+
+
+
+
+
@@ -2306,35 +2323,6 @@ Right click for insert and delete options.
Logbook of the World User Validation
- -
-
-
- Age of last upload less than:
-
-
- LotW_days_since_upload_spin_box
-
-
-
- -
-
-
- <html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html>
-
-
- days
-
-
- 0
-
-
- 9999
-
-
- 365
-
-
-
-
@@ -2369,6 +2357,35 @@ Right click for insert and delete options.
+ -
+
+
+ Age of last upload less than:
+
+
+ LotW_days_since_upload_spin_box
+
+
+
+ -
+
+
+ <html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html>
+
+
+ days
+
+
+ 0
+
+
+ 9999
+
+
+ 365
+
+
+
@@ -3085,13 +3102,13 @@ Right click for insert and delete options.
-
+
-
-
+
-
+
+
diff --git a/DXLabSuiteCommanderTransceiver.cpp b/DXLabSuiteCommanderTransceiver.cpp
index 4e9270cfe..d745ec17f 100644
--- a/DXLabSuiteCommanderTransceiver.cpp
+++ b/DXLabSuiteCommanderTransceiver.cpp
@@ -127,7 +127,7 @@ int DXLabSuiteCommanderTransceiver::do_start ()
throw error {tr ("DX Lab Suite Commander didn't respond correctly reading frequency: ") + reply};
}
- poll ();
+ do_poll ();
return resolution;
}
@@ -247,7 +247,7 @@ void DXLabSuiteCommanderTransceiver::do_mode (MODE m)
update_mode (m);
}
-void DXLabSuiteCommanderTransceiver::poll ()
+void DXLabSuiteCommanderTransceiver::do_poll ()
{
#if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS
bool quiet {false};
diff --git a/DXLabSuiteCommanderTransceiver.hpp b/DXLabSuiteCommanderTransceiver.hpp
index b02fbef12..1196678b8 100644
--- a/DXLabSuiteCommanderTransceiver.hpp
+++ b/DXLabSuiteCommanderTransceiver.hpp
@@ -39,7 +39,7 @@ protected:
void do_mode (MODE) override;
void do_ptt (bool on) override;
- void poll () override;
+ void do_poll () override;
private:
MODE get_mode (bool no_debug = false);
diff --git a/HRDTransceiver.cpp b/HRDTransceiver.cpp
index 3b9f90e23..c44914145 100644
--- a/HRDTransceiver.cpp
+++ b/HRDTransceiver.cpp
@@ -885,7 +885,7 @@ bool HRDTransceiver::is_button_checked (int button_index, bool no_debug)
return "1" == reply;
}
-void HRDTransceiver::poll ()
+void HRDTransceiver::do_poll ()
{
#if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS
bool quiet {false};
diff --git a/HRDTransceiver.hpp b/HRDTransceiver.hpp
index e17134d53..6ccd72d52 100644
--- a/HRDTransceiver.hpp
+++ b/HRDTransceiver.hpp
@@ -48,7 +48,7 @@ protected:
void do_ptt (bool on) override;
// Implement the PollingTransceiver interface.
- void poll () override;
+ void do_poll () override;
private:
QString send_command (QString const&, bool no_debug = false, bool prepend_context = true, bool recurse = false);
diff --git a/HamlibTransceiver.cpp b/HamlibTransceiver.cpp
index f2e55bb4b..da0623e22 100644
--- a/HamlibTransceiver.cpp
+++ b/HamlibTransceiver.cpp
@@ -632,7 +632,7 @@ int HamlibTransceiver::do_start ()
resolution = -1; // best guess
}
- poll ();
+ do_poll ();
TRACE_CAT ("HamlibTransceiver", "exit" << state () << "reversed =" << reversed_ << "resolution = " << resolution);
return resolution;
@@ -898,7 +898,7 @@ void HamlibTransceiver::do_mode (MODE mode)
update_mode (mode);
}
-void HamlibTransceiver::poll ()
+void HamlibTransceiver::do_poll ()
{
#if !WSJT_TRACE_CAT_POLLS
#if defined (NDEBUG)
diff --git a/HamlibTransceiver.hpp b/HamlibTransceiver.hpp
index c8c0f74d7..17f1c28d3 100644
--- a/HamlibTransceiver.hpp
+++ b/HamlibTransceiver.hpp
@@ -40,7 +40,7 @@ class HamlibTransceiver final
void do_mode (MODE) override;
void do_ptt (bool) override;
- void poll () override;
+ void do_poll () override;
void error_check (int ret_code, QString const& doing) const;
void set_conf (char const * item, char const * value);
diff --git a/MetaDataRegistry.cpp b/MetaDataRegistry.cpp
index 6ce9a7f92..e66a43008 100644
--- a/MetaDataRegistry.cpp
+++ b/MetaDataRegistry.cpp
@@ -14,17 +14,35 @@
#include "WFPalette.hpp"
#include "models/IARURegions.hpp"
#include "models/DecodeHighlightingModel.hpp"
-#include "widgets/FrequencyLineEdit.hpp"
#include "widgets/DateTimeEdit.hpp"
-QItemEditorFactory * item_editor_factory ()
+namespace
{
- static QItemEditorFactory * our_item_editor_factory = new QItemEditorFactory;
- return our_item_editor_factory;
+ class ItemEditorFactory final
+ : public QItemEditorFactory
+ {
+ public:
+ ItemEditorFactory ()
+ : default_factory_ {QItemEditorFactory::defaultFactory ()}
+ {
+ }
+
+ QWidget * createEditor (int user_type, QWidget * parent) const override
+ {
+ auto editor = QItemEditorFactory::createEditor (user_type, parent);
+ return editor ? editor : default_factory_->createEditor (user_type, parent);
+ }
+
+ private:
+ QItemEditorFactory const * default_factory_;
+ };
}
void register_types ()
{
+ auto item_editor_factory = new ItemEditorFactory;
+ QItemEditorFactory::setDefaultFactory (item_editor_factory);
+
// types in Radio.hpp are registered in their own translation unit
// as they are needed in the wsjtx_udp shared library too
@@ -32,12 +50,7 @@ void register_types ()
// used as signal/slot connection arguments since the new Qt 5.5
// Q_ENUM macro only seems to register the unqualified name
- item_editor_factory ()->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ());
- //auto frequency_delta_type_id = qRegisterMetaType ("FrequencyDelta");
- item_editor_factory ()->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ());
- auto factory = new QItemEditorFactory;
- factory->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ());
- QItemEditorFactory::setDefaultFactory (factory);
+ item_editor_factory->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ());
// Frequency list model
qRegisterMetaTypeStreamOperators ("Item_v2");
diff --git a/MetaDataRegistry.hpp b/MetaDataRegistry.hpp
index 43000d201..8bf3c80dc 100644
--- a/MetaDataRegistry.hpp
+++ b/MetaDataRegistry.hpp
@@ -1,9 +1,6 @@
#ifndef META_DATA_REGISTRY_HPP__
#define META_DATA_REGISTRY_HPP__
-class QItemEditorFactory;
-
-QItemEditorFactory * item_editor_factory ();
void register_types ();
#endif
diff --git a/OmniRigTransceiver.cpp b/OmniRigTransceiver.cpp
index 09f1e5cfa..4d3bbf1f8 100644
--- a/OmniRigTransceiver.cpp
+++ b/OmniRigTransceiver.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include "qt_helpers.hpP"
@@ -109,6 +110,15 @@ OmniRigTransceiver::OmniRigTransceiver (std::unique_ptr wrapped
{
}
+// returns false on time out
+bool OmniRigTransceiver::await_notification_with_timeout (int timeout)
+{
+ QEventLoop el;
+ connect (this, &OmniRigTransceiver::notified, &el, [&el] () {el.exit (1);});
+ QTimer::singleShot (timeout, Qt::CoarseTimer, &el, [&el] () {el.exit (0);});
+ return 1 == el.exec (); // wait for notify or timer
+}
+
int OmniRigTransceiver::do_start ()
{
TRACE_CAT ("OmniRigTransceiver", "starting");
@@ -182,101 +192,97 @@ int OmniRigTransceiver::do_start ()
.arg (readable_params_, 8, 16, QChar ('0'))
.arg (writable_params_, 8, 16, QChar ('0'))
.arg (rig_number_).toLocal8Bit ());
-
- offline_timer_.reset (new QTimer);
- offline_timer_->setSingleShot (true);
- offline_timer_->setInterval (5 * 1000);
- connect (&*offline_timer_, &QTimer::timeout, this, &OmniRigTransceiver::timeout_check);
-
- for (unsigned tries {0}; tries < 10; ++tries)
+ if (OmniRig::ST_ONLINE != rig_->Status ())
{
- QThread::msleep (100); // wait until OmniRig polls the rig
- auto f = rig_->GetRxFrequency ();
- int resolution {0};
- if (f)
+ throw_qstring ("OmniRig: " + rig_->StatusStr ());
+ }
+ await_notification_with_timeout (1000);
+ update_rx_frequency (rig_->GetRxFrequency ());
+ qDebug () << "Initial state:" << state ();
+ int resolution {0};
+ if (OmniRig::PM_UNKNOWN == rig_->Vfo ()
+ && (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
+ == (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
+ {
+ // start with VFO A (probably MAIN) on rigs that we
+ // can't query VFO but can set explicitly
+ rig_->SetVfo (OmniRig::PM_VFOA);
+ }
+ auto f = state ().frequency ();
+ if (f % 10) return resolution; // 1Hz resolution
+ auto test_frequency = f - f % 100 + 55;
+ if (OmniRig::PM_FREQ & writable_params_)
+ {
+ rig_->SetFreq (test_frequency);
+ }
+ else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
+ {
+ rig_->SetFreqB (test_frequency);
+ }
+ else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
+ {
+ rig_->SetFreqA (test_frequency);
+ }
+ else
+ {
+ throw_qstring (tr ("OmniRig: don't know how to set rig frequency"));
+ }
+ if (!await_notification_with_timeout (1000))
+ {
+ TRACE_CAT ("OmniRigTransceiver", "do_start 1: wait timed out");
+ throw_qstring (tr ("OmniRig: timeout waiting for update from rig"));
+ }
+ switch (rig_->GetRxFrequency () - test_frequency)
+ {
+ case -5: resolution = -1; break; // 10Hz truncated
+ case 5: resolution = 1; break; // 10Hz rounded
+ case -15: resolution = -2; break; // 20Hz truncated
+ case -55: resolution = -2; break; // 100Hz truncated
+ case 45: resolution = 2; break; // 100Hz rounded
+ }
+ if (1 == resolution) // may be 20Hz rounded
+ {
+ test_frequency = f - f % 100 + 51;
+ if (OmniRig::PM_FREQ & writable_params_)
{
- if (OmniRig::PM_UNKNOWN == rig_->Vfo ()
- && (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
- == (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
- {
- // start with VFO A (probably MAIN) on rigs that we
- // can't query VFO but can set explicitly
- rig_->SetVfo (OmniRig::PM_VFOA);
- }
- if (f % 10) return resolution; // 1Hz resolution
- auto test_frequency = f - f % 100 + 55;
- if (OmniRig::PM_FREQ & writable_params_)
- {
- rig_->SetFreq (test_frequency);
- }
- else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
- {
- rig_->SetFreqB (test_frequency);
- }
- else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
- {
- rig_->SetFreqA (test_frequency);
- }
- else
- {
- throw_qstring (tr ("OmniRig: don't know how to set rig frequency"));
- }
- switch (rig_->GetRxFrequency () - test_frequency)
- {
- case -5: resolution = -1; break; // 10Hz truncated
- case 5: resolution = 1; break; // 10Hz rounded
- case -15: resolution = -2; break; // 20Hz truncated
- case -55: resolution = -2; break; // 100Hz truncated
- case 45: resolution = 2; break; // 100Hz rounded
- }
- if (1 == resolution) // may be 20Hz rounded
- {
- test_frequency = f - f % 100 + 51;
- if (OmniRig::PM_FREQ & writable_params_)
- {
- rig_->SetFreq (test_frequency);
- }
- else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
- {
- rig_->SetFreqB (test_frequency);
- }
- else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
- {
- rig_->SetFreqA (test_frequency);
- }
- if (9 == rig_->GetRxFrequency () - test_frequency)
- {
- resolution = 2; // 20Hz rounded
- }
- }
- if (OmniRig::PM_FREQ & writable_params_)
- {
- rig_->SetFreq (f);
- }
- else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
- {
- rig_->SetFreqB (f);
- }
- else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
- {
- rig_->SetFreqA (f);
- }
- update_rx_frequency (f);
- return resolution;
+ rig_->SetFreq (test_frequency);
+ }
+ else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
+ {
+ rig_->SetFreqB (test_frequency);
+ }
+ else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
+ {
+ rig_->SetFreqA (test_frequency);
+ }
+ if (!await_notification_with_timeout (2000))
+ {
+ TRACE_CAT ("OmniRigTransceiver", "do_start 2: wait timed out");
+ throw_qstring (tr ("OmniRig: timeout waiting for update from rig"));
+ }
+ if (9 == rig_->GetRxFrequency () - test_frequency)
+ {
+ resolution = 2; // 20Hz rounded
}
}
- throw_qstring (tr ("OmniRig: Initialization timed out"));
- return 0; // keep compiler happy
+ if (OmniRig::PM_FREQ & writable_params_)
+ {
+ rig_->SetFreq (f);
+ }
+ else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
+ {
+ rig_->SetFreqB (f);
+ }
+ else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
+ {
+ rig_->SetFreqA (f);
+ }
+ update_rx_frequency (f);
+ return resolution;
}
void OmniRigTransceiver::do_stop ()
{
- if (offline_timer_)
- {
- offline_timer_->stop ();
- offline_timer_.reset ();
- }
-
QThread::msleep (200); // leave some time for pending
// commands at the server end
if (port_)
@@ -300,17 +306,6 @@ void OmniRigTransceiver::do_stop ()
TRACE_CAT ("OmniRigTransceiver", "stopped");
}
-void OmniRigTransceiver::do_sync (bool force_signal, bool /*no_poll*/)
-{
- // nothing much we can do here, we just have to let OmniRig do its
- // stuff and its first poll should send us and update that will
- // trigger a update signal from us. Any attempt to query OmniRig
- // leads to a whole mess of trouble since its internal state is
- // garbage until it has done its first rig poll.
- send_update_signal_ = force_signal;
- update_complete ();
-}
-
void OmniRigTransceiver::handle_COM_exception (int code, QString source, QString desc, QString help)
{
TRACE_CAT ("OmniRigTransceiver", QString::number (code) + " at " + source + ": " + desc + " (" + help + ')');
@@ -319,16 +314,20 @@ void OmniRigTransceiver::handle_COM_exception (int code, QString source, QString
void OmniRigTransceiver::handle_visible_change ()
{
+ if (!omni_rig_ || omni_rig_->isNull ()) return;
TRACE_CAT ("OmniRigTransceiver", "visibility change: visibility =" << omni_rig_->DialogVisible ());
}
void OmniRigTransceiver::handle_rig_type_change (int rig_number)
{
+ if (!omni_rig_ || omni_rig_->isNull ()) return;
+ TRACE_CAT ("OmniRigTransceiver", "rig type change: rig =" << rig_number);
if (rig_number_ == rig_number)
{
+ if (!rig_ || rig_->isNull ()) return;
readable_params_ = rig_->ReadableParams ();
writable_params_ = rig_->WriteableParams ();
- TRACE_CAT ("OmniRigTransceiver", QString {"OmniRig rig type change to: %1 readable params = 0x%2 writable params = 0x%3 for rig %4"}
+ TRACE_CAT ("OmniRigTransceiver", QString {"rig type change to: %1 readable params = 0x%2 writable params = 0x%3 for rig %4"}
.arg (rig_->RigType ())
.arg (readable_params_, 8, 16, QChar ('0'))
.arg (writable_params_, 8, 16, QChar ('0'))
@@ -338,48 +337,43 @@ void OmniRigTransceiver::handle_rig_type_change (int rig_number)
void OmniRigTransceiver::handle_status_change (int rig_number)
{
+ if (!omni_rig_ || omni_rig_->isNull ()) return;
+ TRACE_CAT ("OmniRigTransceiver", QString {"status change for rig %1"}.arg (rig_number).toLocal8Bit ());
if (rig_number_ == rig_number)
{
+ if (!rig_ || rig_->isNull ()) return;
auto const& status = rig_->StatusStr ().toLocal8Bit ();
- TRACE_CAT ("OmniRigTransceiver", QString {"OmniRig status change: new status for rig %1 = "}.arg (rig_number).toLocal8Bit () << status);
+ TRACE_CAT ("OmniRigTransceiver", "OmniRig status change: new status = " << status);
if (OmniRig::ST_ONLINE != rig_->Status ())
{
- if (!offline_timer_->isActive ())
- {
- offline_timer_->start (); // give OmniRig time to recover
- }
- }
- else
- {
- offline_timer_->stop ();
- update_rx_frequency (rig_->GetRxFrequency ());
- update_complete ();
- TRACE_CAT ("OmniRigTransceiver", "OmniRig frequency:" << state ().frequency ());
+ offline ("Rig went offline");
}
+ // else
+ // {
+ // update_rx_frequency (rig_->GetRxFrequency ());
+ // update_complete ();
+ // TRACE_CAT ("OmniRigTransceiver", "frequency:" << state ().frequency ());
+ // }
}
}
-void OmniRigTransceiver::timeout_check ()
-{
- offline ("Rig went offline");
-}
-
void OmniRigTransceiver::handle_params_change (int rig_number, int params)
{
- if (rig_number_ == rig_number)
- {
- TRACE_CAT ("OmniRigTransceiver", QString {"OmniRig params change: params = 0x%1 for rig %2"}
+ if (!omni_rig_ || omni_rig_->isNull ()) return;
+ TRACE_CAT ("OmniRigTransceiver", QString {"params change: params = 0x%1 for rig %2"}
.arg (params, 8, 16, QChar ('0'))
.arg (rig_number).toLocal8Bit ()
<< "state before:" << state ());
+ if (rig_number_ == rig_number)
+ {
+ if (!rig_ || rig_->isNull ()) return;
// starting_ = false;
TransceiverState old_state {state ()};
auto need_frequency = false;
- // state_.online = true; // sometimes we don't get an initial
- // // OmniRig::ST_ONLINE status change
- // // event
+
if (params & OmniRig::PM_VFOAA)
{
+ TRACE_CAT ("OmniRigTransceiver", "VFOAA");
update_split (false);
reversed_ = false;
update_rx_frequency (rig_->FreqA ());
@@ -387,6 +381,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
}
if (params & OmniRig::PM_VFOAB)
{
+ TRACE_CAT ("OmniRigTransceiver", "VFOAB");
update_split (true);
reversed_ = false;
update_rx_frequency (rig_->FreqA ());
@@ -394,6 +389,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
}
if (params & OmniRig::PM_VFOBA)
{
+ TRACE_CAT ("OmniRigTransceiver", "VFOBA");
update_split (true);
reversed_ = true;
update_other_frequency (rig_->FreqA ());
@@ -401,6 +397,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
}
if (params & OmniRig::PM_VFOBB)
{
+ TRACE_CAT ("OmniRigTransceiver", "VFOBB");
update_split (false);
reversed_ = true;
update_other_frequency (rig_->FreqA ());
@@ -408,64 +405,75 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
}
if (params & OmniRig::PM_VFOA)
{
+ TRACE_CAT ("OmniRigTransceiver", "VFOA");
reversed_ = false;
need_frequency = true;
}
if (params & OmniRig::PM_VFOB)
{
+ TRACE_CAT ("OmniRigTransceiver", "VFOB");
reversed_ = true;
need_frequency = true;
}
if (params & OmniRig::PM_FREQ)
{
+ TRACE_CAT ("OmniRigTransceiver", "FREQ");
need_frequency = true;
}
if (params & OmniRig::PM_FREQA)
{
+ auto f = rig_->FreqA ();
+ TRACE_CAT ("OmniRigTransceiver", "FREQA = " << f);
if (reversed_)
{
- update_other_frequency (rig_->FreqA ());
+ update_other_frequency (f);
}
else
{
- update_rx_frequency (rig_->FreqA ());
+ update_rx_frequency (f);
}
}
if (params & OmniRig::PM_FREQB)
{
+ auto f = rig_->FreqB ();
+ TRACE_CAT ("OmniRigTransceiver", "FREQB = " << f);
if (reversed_)
{
- update_rx_frequency (rig_->FreqB ());
+ update_rx_frequency (f);
}
else
{
- update_other_frequency (rig_->FreqB ());
+ update_other_frequency (f);
}
}
if (need_frequency)
{
if (readable_params_ & OmniRig::PM_FREQA)
{
+ auto f = rig_->FreqA ();
+ TRACE_CAT ("OmniRigTransceiver", "FREQA = " << f);
if (reversed_)
{
- update_other_frequency (rig_->FreqA ());
+ update_other_frequency (f);
}
else
{
- update_rx_frequency (rig_->FreqA ());
+ update_rx_frequency (f);
}
need_frequency = false;
}
if (readable_params_ & OmniRig::PM_FREQB)
{
+ auto f = rig_->FreqB ();
+ TRACE_CAT ("OmniRigTransceiver", "FREQB = " << f);
if (reversed_)
{
- update_rx_frequency (rig_->FreqB ());
+ update_rx_frequency (f);
}
else
{
- update_other_frequency (rig_->FreqB ());
+ update_other_frequency (f);
}
need_frequency = false;
}
@@ -473,89 +481,113 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
if (need_frequency && (readable_params_ & OmniRig::PM_FREQ)
&& !state ().ptt ())
{
- update_rx_frequency (rig_->Freq ());
+ auto f = rig_->Freq ();
+ TRACE_CAT ("OmniRigTransceiver", "FREQ = " << f);
+ update_rx_frequency (f);
}
if (params & OmniRig::PM_PITCH)
{
+ TRACE_CAT ("OmniRigTransceiver", "PITCH");
}
if (params & OmniRig::PM_RITOFFSET)
{
+ TRACE_CAT ("OmniRigTransceiver", "RITOFFSET");
}
if (params & OmniRig::PM_RIT0)
{
+ TRACE_CAT ("OmniRigTransceiver", "RIT0");
}
if (params & OmniRig::PM_VFOEQUAL)
{
auto f = readable_params_ & OmniRig::PM_FREQA ? rig_->FreqA () : rig_->Freq ();
+ auto m = map_mode (rig_->Mode ());
+ TRACE_CAT ("OmniRigTransceiver", QString {"VFOEQUAL f=%1 m=%2"}.arg (f).arg (m));
update_rx_frequency (f);
update_other_frequency (f);
- update_mode (map_mode (rig_->Mode ()));
+ update_mode (m);
}
if (params & OmniRig::PM_VFOSWAP)
{
- auto temp = state ().tx_frequency ();
+ TRACE_CAT ("OmniRigTransceiver", "VFOSWAP");
+ auto f = state ().tx_frequency ();
update_other_frequency (state ().frequency ());
- update_rx_frequency (temp);
+ update_rx_frequency (f);
update_mode (map_mode (rig_->Mode ()));
}
if (params & OmniRig::PM_SPLITON)
{
+ TRACE_CAT ("OmniRigTransceiver", "SPLITON");
update_split (true);
}
if (params & OmniRig::PM_SPLITOFF)
{
+ TRACE_CAT ("OmniRigTransceiver", "SPLITOFF");
update_split (false);
}
if (params & OmniRig::PM_RITON)
{
+ TRACE_CAT ("OmniRigTransceiver", "RITON");
}
if (params & OmniRig::PM_RITOFF)
{
+ TRACE_CAT ("OmniRigTransceiver", "RITOFF");
}
if (params & OmniRig::PM_XITON)
{
+ TRACE_CAT ("OmniRigTransceiver", "XITON");
}
if (params & OmniRig::PM_XITOFF)
{
+ TRACE_CAT ("OmniRigTransceiver", "XITOFF");
}
if (params & OmniRig::PM_RX)
{
+ TRACE_CAT ("OmniRigTransceiver", "RX");
update_PTT (false);
}
if (params & OmniRig::PM_TX)
{
+ TRACE_CAT ("OmniRigTransceiver", "TX");
update_PTT ();
}
if (params & OmniRig::PM_CW_U)
{
+ TRACE_CAT ("OmniRigTransceiver", "CW-R");
update_mode (CW_R);
}
if (params & OmniRig::PM_CW_L)
{
+ TRACE_CAT ("OmniRigTransceiver", "CW");
update_mode (CW);
}
if (params & OmniRig::PM_SSB_U)
{
+ TRACE_CAT ("OmniRigTransceiver", "USB");
update_mode (USB);
}
if (params & OmniRig::PM_SSB_L)
{
+ TRACE_CAT ("OmniRigTransceiver", "LSB");
update_mode (LSB);
}
if (params & OmniRig::PM_DIG_U)
{
+ TRACE_CAT ("OmniRigTransceiver", "DATA-U");
update_mode (DIG_U);
}
if (params & OmniRig::PM_DIG_L)
{
+ TRACE_CAT ("OmniRigTransceiver", "DATA-L");
update_mode (DIG_L);
}
if (params & OmniRig::PM_AM)
{
+ TRACE_CAT ("OmniRigTransceiver", "AM");
update_mode (AM);
}
if (params & OmniRig::PM_FM)
{
+ TRACE_CAT ("OmniRigTransceiver", "FM");
update_mode (FM);
}
@@ -566,6 +598,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
}
TRACE_CAT ("OmniRigTransceiver", "OmniRig params change: state after:" << state ());
}
+ Q_EMIT notified ();
}
void OmniRigTransceiver::handle_custom_reply (int rig_number, QVariant const& command, QVariant const& reply)
@@ -573,8 +606,10 @@ void OmniRigTransceiver::handle_custom_reply (int rig_number, QVariant const& co
(void)command;
(void)reply;
+ if (!omni_rig_ || omni_rig_->isNull ()) return;
if (rig_number_ == rig_number)
{
+ if (!rig_ || rig_->isNull ()) return;
TRACE_CAT ("OmniRigTransceiver", "custom command" << command.toString ().toLocal8Bit ()
<< "with reply" << reply.toString ().toLocal8Bit ()
<< QString ("for rig %1").arg (rig_number).toLocal8Bit ());
diff --git a/OmniRigTransceiver.hpp b/OmniRigTransceiver.hpp
index c63266b69..2ba5fd4d3 100644
--- a/OmniRigTransceiver.hpp
+++ b/OmniRigTransceiver.hpp
@@ -38,10 +38,11 @@ public:
void do_tx_frequency (Frequency, MODE, bool no_ignore) override;
void do_mode (MODE) override;
void do_ptt (bool on) override;
- void do_sync (bool force_signal, bool no_poll) override;
private:
- Q_SLOT void timeout_check ();
+ bool await_notification_with_timeout (int timeout);
+ Q_SIGNAL void notified () const;
+ // Q_SLOT void timeout_check ();
Q_SLOT void handle_COM_exception (int, QString, QString, QString);
Q_SLOT void handle_visible_change ();
Q_SLOT void handle_rig_type_change (int rig_number);
@@ -62,7 +63,7 @@ private:
QString rig_type_;
int readable_params_;
int writable_params_;
- QScopedPointer offline_timer_;
+ // QScopedPointer offline_timer_;
bool send_update_signal_;
bool reversed_; // some rigs can reverse VFOs
};
diff --git a/PollingTransceiver.cpp b/PollingTransceiver.cpp
index b2bbab179..ed47144af 100644
--- a/PollingTransceiver.cpp
+++ b/PollingTransceiver.cpp
@@ -129,52 +129,46 @@ bool PollingTransceiver::do_pre_update ()
return true;
}
-void PollingTransceiver::do_sync (bool force_signal, bool no_poll)
-{
- if (!no_poll) poll (); // tell sub-classes to update our state
-
- // Signal new state if it is directly requested or, what we expected
- // or, hasn't become what we expected after polls_to_stabilize
- // polls. Unsolicited changes will be signalled immediately unless
- // they intervene in a expected sequence where they will be delayed.
- if (retries_)
- {
- --retries_;
- if (force_signal || state () == next_state_ || !retries_)
- {
- // our client wants a signal regardless
- // or the expected state has arrived
- // or there are no more retries
- force_signal = true;
- }
- }
- else if (force_signal || state () != last_signalled_state_)
- {
- // here is the normal passive polling path either our client has
- // requested a state update regardless of change or state has
- // changed asynchronously
- force_signal = true;
- }
-
- if (force_signal)
- {
- // reset everything, record and signal the current state
- retries_ = 0;
- next_state_ = state ();
- last_signalled_state_ = state ();
- update_complete (true);
- }
-}
-
void PollingTransceiver::handle_timeout ()
{
QString message;
+ bool force_signal {false};
// we must catch all exceptions here since we are called by Qt and
// inform our parent of the failure via the offline() message
try
{
- do_sync ();
+ do_poll (); // tell sub-classes to update our state
+
+ // Signal new state if it what we expected or, hasn't become
+ // what we expected after polls_to_stabilize polls. Unsolicited
+ // changes will be signalled immediately unless they intervene
+ // in a expected sequence where they will be delayed.
+ if (retries_)
+ {
+ --retries_;
+ if (state () == next_state_ || !retries_)
+ {
+ // the expected state has arrived or there are no more
+ // retries
+ force_signal = true;
+ }
+ }
+ else if (state () != last_signalled_state_)
+ {
+ // here is the normal passive polling path where state has
+ // changed asynchronously
+ force_signal = true;
+ }
+
+ if (force_signal)
+ {
+ // reset everything, record and signal the current state
+ retries_ = 0;
+ next_state_ = state ();
+ last_signalled_state_ = state ();
+ update_complete (true);
+ }
}
catch (std::exception const& e)
{
diff --git a/PollingTransceiver.hpp b/PollingTransceiver.hpp
index 0945c84ac..a9e639f9d 100644
--- a/PollingTransceiver.hpp
+++ b/PollingTransceiver.hpp
@@ -39,11 +39,9 @@ protected:
QObject * parent);
protected:
- void do_sync (bool force_signal = false, bool no_poll = false) override final;
-
// Sub-classes implement this and fetch what they can from the rig
// in a non-intrusive manner.
- virtual void poll () = 0;
+ virtual void do_poll () = 0;
void do_post_start () override final;
void do_post_stop () override final;
diff --git a/Radio.cpp b/Radio.cpp
index 3940815f4..e5b34c35d 100644
--- a/Radio.cpp
+++ b/Radio.cpp
@@ -74,14 +74,14 @@ namespace Radio
}
- QString frequency_MHz_string (Frequency f, QLocale const& locale)
+ QString frequency_MHz_string (Frequency f, int precision, QLocale const& locale)
{
- return locale.toString (f / MHz_factor, 'f', frequency_precsion);
+ return locale.toString (f / MHz_factor, 'f', precision);
}
- QString frequency_MHz_string (FrequencyDelta d, QLocale const& locale)
+ QString frequency_MHz_string (FrequencyDelta d, int precision, QLocale const& locale)
{
- return locale.toString (d / MHz_factor, 'f', frequency_precsion);
+ return locale.toString (d / MHz_factor, 'f', precision);
}
QString pretty_frequency_MHz_string (Frequency f, QLocale const& locale)
diff --git a/Radio.hpp b/Radio.hpp
index 7f8b0a0f4..e63abf4b8 100644
--- a/Radio.hpp
+++ b/Radio.hpp
@@ -42,8 +42,8 @@ namespace Radio
//
// Frequency type formatting
//
- QString UDP_EXPORT frequency_MHz_string (Frequency, QLocale const& = QLocale ());
- QString UDP_EXPORT frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
+ QString UDP_EXPORT frequency_MHz_string (Frequency, int precision = 6, QLocale const& = QLocale ());
+ QString UDP_EXPORT frequency_MHz_string (FrequencyDelta, int precision = 6, QLocale const& = QLocale ());
QString UDP_EXPORT pretty_frequency_MHz_string (Frequency, QLocale const& = QLocale ());
QString UDP_EXPORT pretty_frequency_MHz_string (double, int scale, QLocale const& = QLocale ());
QString UDP_EXPORT pretty_frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
diff --git a/Release_Notes.txt b/Release_Notes.txt
index 101e13d74..4dbad3454 100644
--- a/Release_Notes.txt
+++ b/Release_Notes.txt
@@ -40,6 +40,8 @@ OTHER IMPROVEMENTS
- N1MM Logger+ now uses the standard WSJT-X UDP messages
- OK/Cancel buttons on Log QSO window maintain fixed positions
- Put EU VHF contest serial numbers into the ADIF SRX and STX fields
+ - Enhancements to the Omni-Rig CAT interface
+ - New setting option to include or exclude WAE entities
BUG FIXES
- Fix generation of Tx5 message when one callsign is nonstandard
@@ -47,6 +49,7 @@ BUG FIXES
- Fix a bug that caused mode switch from FT4 to FT8
- Fix a bug that caused FT4 to do WSPR-style band hopping
- Fix a bug that caused a Fortran bounds error
+ - Repaired field editing in the Contest Log window
Release candidate WSJT-X 2.1.0-rc6 will be available for beta-testing
through July 21, 2019. It will be inoperable during the ARRL June VHF
diff --git a/TransceiverBase.cpp b/TransceiverBase.cpp
index ef77d51e4..43a88a4e1 100644
--- a/TransceiverBase.cpp
+++ b/TransceiverBase.cpp
@@ -19,10 +19,10 @@ void TransceiverBase::start (unsigned sequence_number) noexcept
QString message;
try
{
+ last_sequence_number_ = sequence_number;
may_update u {this, true};
shutdown ();
startup ();
- last_sequence_number_ = sequence_number;
}
catch (std::exception const& e)
{
@@ -46,6 +46,7 @@ void TransceiverBase::set (TransceiverState const& s,
QString message;
try
{
+ last_sequence_number_ = sequence_number;
may_update u {this, true};
bool was_online {requested_.online ()};
if (!s.online () && was_online)
@@ -115,7 +116,6 @@ void TransceiverBase::set (TransceiverState const& s,
// record what actually changed
requested_.ptt (actual_.ptt ());
}
- last_sequence_number_ = sequence_number;
}
catch (std::exception const& e)
{
@@ -133,10 +133,27 @@ void TransceiverBase::set (TransceiverState const& s,
void TransceiverBase::startup ()
{
- Q_EMIT resolution (do_start ());
- do_post_start ();
- actual_.online (true);
- requested_.online (true);
+ QString message;
+ try
+ {
+ actual_.online (true);
+ requested_.online (true);
+ auto res = do_start ();
+ do_post_start ();
+ Q_EMIT resolution (res);
+ }
+ catch (std::exception const& e)
+ {
+ message = e.what ();
+ }
+ catch (...)
+ {
+ message = unexpected;
+ }
+ if (!message.isEmpty ())
+ {
+ offline (message);
+ }
}
void TransceiverBase::shutdown ()
@@ -163,8 +180,8 @@ void TransceiverBase::shutdown ()
}
do_stop ();
do_post_stop ();
- actual_.online (false);
- requested_.online (false);
+ actual_ = TransceiverState {};
+ requested_ = TransceiverState {};
}
void TransceiverBase::stop () noexcept
diff --git a/TransceiverBase.hpp b/TransceiverBase.hpp
index ea981d44b..7d43cc32e 100644
--- a/TransceiverBase.hpp
+++ b/TransceiverBase.hpp
@@ -112,8 +112,6 @@ protected:
virtual void do_ptt (bool = true) = 0;
virtual void do_post_ptt (bool = true) {}
- virtual void do_sync (bool force_signal = false, bool no_poll = false) = 0;
-
virtual bool do_pre_update () {return true;}
// sub classes report rig state changes with these methods
diff --git a/Versions.cmake b/Versions.cmake
index f07339063..45cd79820 100644
--- a/Versions.cmake
+++ b/Versions.cmake
@@ -2,5 +2,5 @@
set (WSJTX_VERSION_MAJOR 2)
set (WSJTX_VERSION_MINOR 1)
set (WSJTX_VERSION_PATCH 0)
-set (WSJTX_RC 6) # release candidate number, comment out or zero for development versions
+set (WSJTX_RC 7) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
diff --git a/item_delegates/FrequencyDelegate.cpp b/item_delegates/FrequencyDelegate.cpp
new file mode 100644
index 000000000..b899c0563
--- /dev/null
+++ b/item_delegates/FrequencyDelegate.cpp
@@ -0,0 +1,27 @@
+#include "FrequencyDelegate.hpp"
+
+#include "widgets/FrequencyLineEdit.hpp"
+
+FrequencyDelegate::FrequencyDelegate (QObject * parent)
+ : QStyledItemDelegate {parent}
+{
+}
+
+QWidget * FrequencyDelegate::createEditor (QWidget * parent, QStyleOptionViewItem const&
+ , QModelIndex const&) const
+{
+ auto * editor = new FrequencyLineEdit {parent};
+ editor->setFrame (false);
+ return editor;
+}
+
+void FrequencyDelegate::setEditorData (QWidget * editor, QModelIndex const& index) const
+{
+ static_cast (editor)->frequency (index.model ()->data (index, Qt::EditRole).value ());
+}
+
+void FrequencyDelegate::setModelData (QWidget * editor, QAbstractItemModel * model, QModelIndex const& index) const
+{
+ model->setData (index, static_cast (editor)->frequency (), Qt::EditRole);
+}
+
diff --git a/item_delegates/FrequencyDelegate.hpp b/item_delegates/FrequencyDelegate.hpp
new file mode 100644
index 000000000..76fc5545d
--- /dev/null
+++ b/item_delegates/FrequencyDelegate.hpp
@@ -0,0 +1,21 @@
+#ifndef FREQUENCY_DELEGATE_HPP_
+#define FREQUENCY_DELEGATE_HPP_
+
+#include
+
+//
+// Class FrequencyDelegate
+//
+// Item delegate for editing a frequency in Hertz but displayed in MHz
+//
+class FrequencyDelegate final
+ : public QStyledItemDelegate
+{
+public:
+ explicit FrequencyDelegate (QObject * parent = nullptr);
+ QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const&, QModelIndex const&) const override;
+ void setEditorData (QWidget * editor, QModelIndex const&) const override;
+ void setModelData (QWidget * editor, QAbstractItemModel *, QModelIndex const&) const override;
+};
+
+#endif
diff --git a/item_delegates/FrequencyDeltaDelegate.cpp b/item_delegates/FrequencyDeltaDelegate.cpp
new file mode 100644
index 000000000..40d90dc58
--- /dev/null
+++ b/item_delegates/FrequencyDeltaDelegate.cpp
@@ -0,0 +1,26 @@
+#include "FrequencyDeltaDelegate.hpp"
+
+#include "widgets/FrequencyDeltaLineEdit.hpp"
+
+FrequencyDeltaDelegate::FrequencyDeltaDelegate (QObject * parent)
+ : QStyledItemDelegate {parent}
+{
+}
+
+QWidget * FrequencyDeltaDelegate::createEditor (QWidget * parent, QStyleOptionViewItem const&
+ , QModelIndex const&) const
+{
+ auto * editor = new FrequencyDeltaLineEdit {parent};
+ editor->setFrame (false);
+ return editor;
+}
+
+void FrequencyDeltaDelegate::setEditorData (QWidget * editor, QModelIndex const& index) const
+{
+ static_cast (editor)->frequency_delta (index.model ()->data (index, Qt::EditRole).value ());
+}
+
+void FrequencyDeltaDelegate::setModelData (QWidget * editor, QAbstractItemModel * model, QModelIndex const& index) const
+{
+ model->setData (index, static_cast (editor)->frequency_delta (), Qt::EditRole);
+}
diff --git a/item_delegates/FrequencyDeltaDelegate.hpp b/item_delegates/FrequencyDeltaDelegate.hpp
new file mode 100644
index 000000000..121bc3d94
--- /dev/null
+++ b/item_delegates/FrequencyDeltaDelegate.hpp
@@ -0,0 +1,21 @@
+#ifndef FREQUENCY_DELTA_DELEGATE_HPP_
+#define FREQUENCY_DELTA_DELEGATE_HPP_
+
+#include
+
+//
+// Class FrequencyDeltaDelegate
+//
+// Item delegate for editing a frequency delta in Hertz but displayed in MHz
+//
+class FrequencyDeltaDelegate final
+ : public QStyledItemDelegate
+{
+public:
+ explicit FrequencyDeltaDelegate (QObject * parent = nullptr);
+ QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const&, QModelIndex const&) const override;
+ void setEditorData (QWidget * editor, QModelIndex const&) const override;
+ void setModelData (QWidget * editor, QAbstractItemModel *, QModelIndex const&) const override;
+};
+
+#endif
diff --git a/item_delegates/item_delegates.pri b/item_delegates/item_delegates.pri
index 026e1ca57..819cb2e0c 100644
--- a/item_delegates/item_delegates.pri
+++ b/item_delegates/item_delegates.pri
@@ -1,11 +1,13 @@
SOURCES += \
item_delegates/ForeignKeyDelegate.cpp \
- item_delegates/FrequencyItemDelegate.cpp \
+ item_delegates/FrequencyDelegate.cpp \
+ item_delegates/FrequencyDeltaDelegate.cpp \
item_delegates/CallsignDelegate.cpp \
item_delegates/MaidenheadLocatorItemDelegate.cpp
HEADERS += \
item_delegates/ForeignKeyDelegate.hpp \
- item_delegates/FrequencyItemDelegate.hpp \
+ item_delegates/FrequencyDelegate.hpp \
+ item_delegates/FrequencyDeltaDelegate.hpp \
item_delegates/CallsignDelegate.hpp \
item_delegates/MaidenheadLocatorDelegate.hpp
diff --git a/logbook/AD1CCty.cpp b/logbook/AD1CCty.cpp
index 58ed375f6..23d34fb43 100644
--- a/logbook/AD1CCty.cpp
+++ b/logbook/AD1CCty.cpp
@@ -16,6 +16,7 @@
#include
#include
#include
+#include "Configuration.hpp"
#include "Radio.hpp"
#include "pimpl_impl.hpp"
@@ -155,14 +156,16 @@ typedef multi_index_container<
class AD1CCty::impl final
{
public:
- explicit impl ()
+ using entity_by_id = entities_type::index::type;
+
+ explicit impl (Configuration const * configuration)
+ : configuration_ {configuration}
{
}
- Record fixup (QString call, prefix const& p) const
+ entity_by_id::iterator lookup_entity (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
//
@@ -171,23 +174,26 @@ public:
if (call.startsWith ("KG4") && call.size () != 5 && call.size () != 3)
{
// KG4 2x1 and 2x3 calls that map to Gitmo are mainland US not Gitmo
- e = entities_.project (entities_.get ().find ("K"));
+ return entities_.project (entities_.get ().find ("K"));
}
else
{
- e = entities_.get ().find (p.entity_id_);
+ return entities_.get ().find (p.entity_id_);
}
-
+ }
+
+ Record fixup (prefix const& p, entity const& e) const
+ {
Record result;
- result.continent = e->continent_;
- result.CQ_zone = e->CQ_zone_;
- result.ITU_zone = e->ITU_zone_;
- result.entity_name = e->name_;
- result.WAE_only = e->WAE_only_;
- result.latitude = e->lat_;
- result.longtitude = e->long_;
- result.UTC_offset = e->UTC_offset_;
- result.primary_prefix = e->primary_prefix_;
+ result.continent = e.continent_;
+ result.CQ_zone = e.CQ_zone_;
+ result.ITU_zone = e.ITU_zone_;
+ result.entity_name = e.name_;
+ result.WAE_only = e.WAE_only_;
+ result.latitude = e.lat_;
+ result.longtitude = e.long_;
+ result.UTC_offset = e.UTC_offset_;
+ result.primary_prefix = e.primary_prefix_;
// check for overrides
bool ok1 {true}, ok2 {true}, ok3 {true}, ok4 {true}, ok5 {true};
@@ -220,6 +226,7 @@ public:
return false;
}
+ Configuration const * configuration_;
QString path_;
entities_type entities_;
prefixes_type prefixes_;
@@ -307,8 +314,13 @@ char const * AD1CCty::continent (Continent c)
}
}
-AD1CCty::AD1CCty ()
+AD1CCty::AD1CCty (Configuration const * configuration)
+ : m_ {configuration}
{
+ Q_ASSERT (configuration);
+ // TODO: G4WJS - consider doing the following asynchronously to
+ // speed up startup. Not urgent as it takes less than 1s on a Core
+ // i7 reading BIG CTY.DAT.
QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)};
m_->path_ = dataPath.exists (file_name)
? dataPath.absoluteFilePath (file_name) // user override
@@ -389,7 +401,7 @@ auto AD1CCty::lookup (QString const& call) const -> Record
auto p = m_->prefixes_.find (exact_search);
if (p != m_->prefixes_.end () && p->exact_)
{
- return m_->fixup (call, *p);
+ return m_->fixup (*p, *m_->lookup_entity (call, *p));
}
}
while (search_prefix.size ())
@@ -397,9 +409,11 @@ auto AD1CCty::lookup (QString const& call) const -> Record
auto p = m_->prefixes_.find (search_prefix);
if (p != m_->prefixes_.end ())
{
- if (!p->exact_ || call.size () == search_prefix.size ())
+ impl::entity_by_id::iterator e = m_->lookup_entity (call, *p);
+ if ((m_->configuration_->include_WAE_entities () || !e->WAE_only_)
+ && (!p->exact_ || call.size () == search_prefix.size ()))
{
- return m_->fixup (call, *p);
+ return m_->fixup (*p, *e);
}
}
search_prefix = search_prefix.left (search_prefix.size () - 1);
diff --git a/logbook/AD1CCty.hpp b/logbook/AD1CCty.hpp
index 37cada3e9..4a485afa9 100644
--- a/logbook/AD1CCty.hpp
+++ b/logbook/AD1CCty.hpp
@@ -1,17 +1,19 @@
#ifndef AD1C_CTY_HPP_
#define AD1C_CTY_HPP_
-#include
#include
+#include
#include "pimpl_h.hpp"
+class QString;
+class Configuration;
+
//
// AD1CCty - Fast access database of Jim Reisert, AD1C's, cty.dat
// entity and entity override information file.
//
class AD1CCty final
: public QObject
- , private boost::noncopyable
{
Q_OBJECT
@@ -39,7 +41,7 @@ public:
QString primary_prefix;
};
- explicit AD1CCty ();
+ explicit AD1CCty (Configuration const *);
~AD1CCty ();
Record lookup (QString const& call) const;
diff --git a/logbook/Multiplier.cpp b/logbook/Multiplier.cpp
new file mode 100644
index 000000000..6323e4feb
--- /dev/null
+++ b/logbook/Multiplier.cpp
@@ -0,0 +1,44 @@
+#include "Multiplier.hpp"
+
+#include
+#include
+#include
+#include "models/CabrilloLog.hpp"
+#include "pimpl_impl.hpp"
+
+class Multiplier::impl
+{
+public:
+ impl (AD1CCty const * countries)
+ : countries_ {countries}
+ {
+ }
+
+ AD1CCty const * countries_;
+ worked_set entities_worked_;
+ worked_set grids_worked_;
+};
+
+Multiplier::Multiplier (AD1CCty const * countries)
+ : m_ {countries}
+{
+}
+
+Multiplier::~Multiplier ()
+{
+}
+
+void Multiplier::reload (CabrilloLog const * log)
+{
+ m_->entities_worked_ = log->unique_DXCC_entities (m_->countries_);
+}
+
+auto Multiplier::entities_worked () const -> worked_set const&
+{
+ return m_->entities_worked_;
+}
+
+auto Multiplier::grids_worked () const -> worked_set const&
+{
+ return m_->grids_worked_;
+}
diff --git a/logbook/Multiplier.hpp b/logbook/Multiplier.hpp
new file mode 100644
index 000000000..2271dd775
--- /dev/null
+++ b/logbook/Multiplier.hpp
@@ -0,0 +1,30 @@
+#ifndef MULTIPLIER_HPP_
+#define MULTIPLIER_HPP_
+
+#include
+#include
+#include "pimpl_h.hpp"
+
+class QString;
+class AD1CCty;
+class CabrilloLog;
+
+class Multiplier final
+ : private boost::noncopyable
+{
+public:
+ using worked_item = QPair;
+ using worked_set = QSet;
+
+ explicit Multiplier (AD1CCty const *);
+ ~Multiplier ();
+ void reload (CabrilloLog const *);
+ worked_set const& entities_worked () const;
+ worked_set const& grids_worked () const;
+
+private:
+ class impl;
+ pimpl m_;
+};
+
+#endif
diff --git a/logbook/WorkedBefore.cpp b/logbook/WorkedBefore.cpp
index 31380b4c3..aa65ab651 100644
--- a/logbook/WorkedBefore.cpp
+++ b/logbook/WorkedBefore.cpp
@@ -18,7 +18,7 @@
#include
#include
#include
-
+#include "Configuration.hpp"
#include "qt_helpers.hpp"
#include "pimpl_impl.hpp"
@@ -361,8 +361,9 @@ namespace
class WorkedBefore::impl final
{
public:
- impl ()
+ impl (Configuration const * configuration)
: path_ {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath (logFileName)}
+ , prefixes_ {configuration}
{
}
@@ -379,8 +380,10 @@ public:
worked_before_database_type worked_;
};
-WorkedBefore::WorkedBefore ()
+WorkedBefore::WorkedBefore (Configuration const * configuration)
+ : m_ {configuration}
{
+ Q_ASSERT (configuration);
connect (&m_->loader_watcher_, &QFutureWatcher::finished, [this] () {
QString error;
size_t n {0};
@@ -412,9 +415,9 @@ QString const& WorkedBefore::path () const
return m_->path_;
}
-AD1CCty const& WorkedBefore::countries () const
+AD1CCty const * WorkedBefore::countries () const
{
- return m_->prefixes_;
+ return &m_->prefixes_;
}
bool WorkedBefore::add (QString const& call
diff --git a/logbook/WorkedBefore.hpp b/logbook/WorkedBefore.hpp
index 90a31813a..1aae1aca4 100644
--- a/logbook/WorkedBefore.hpp
+++ b/logbook/WorkedBefore.hpp
@@ -5,6 +5,7 @@
#include "AD1CCty.hpp"
#include "pimpl_h.hpp"
+class Configuration;
class CountryDat;
class QString;
class QByteArray;
@@ -17,7 +18,7 @@ class WorkedBefore final
public:
using Continent = AD1CCty::Continent;
- explicit WorkedBefore ();
+ explicit WorkedBefore (Configuration const *);
~WorkedBefore ();
Q_SLOT void reload ();
@@ -28,7 +29,7 @@ public:
, QByteArray const& ADIF_record);
QString const& path () const;
- AD1CCty const& countries () const;
+ AD1CCty const * countries () const;
bool country_worked (QString const& call, QString const& mode, QString const& band) const;
bool grid_worked (QString const& grid, QString const& mode, QString const& band) const;
bool call_worked (QString const& call, QString const& mode, QString const& band) const;
diff --git a/logbook/logbook.cpp b/logbook/logbook.cpp
index 0e855c88f..a154664d5 100644
--- a/logbook/logbook.cpp
+++ b/logbook/logbook.cpp
@@ -3,15 +3,25 @@
#include
#include "Configuration.hpp"
#include "AD1CCty.hpp"
+#include "Multiplier.hpp"
+#include "logbook/AD1CCty.hpp"
+#include "models/CabrilloLog.hpp"
+#include "models/FoxLog.hpp"
#include "moc_logbook.cpp"
LogBook::LogBook (Configuration const * configuration)
: config_ {configuration}
+ , worked_before_ {configuration}
{
+ Q_ASSERT (configuration);
connect (&worked_before_, &WorkedBefore::finished_loading, this, &LogBook::finished_loading);
}
+LogBook::~LogBook ()
+{
+}
+
void LogBook::match (QString const& call, QString const& mode, QString const& grid,
AD1CCty::Record const& looked_up,
bool& callB4,
@@ -136,3 +146,40 @@ QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, Q
}
return t.toLatin1();
}
+
+CabrilloLog * LogBook::contest_log ()
+{
+ // lazy create of Cabrillo log object instance
+ if (!contest_log_)
+ {
+ contest_log_.reset (new CabrilloLog {config_});
+ if (!multiplier_)
+ {
+ multiplier_.reset (new Multiplier {countries ()});
+ }
+ connect (contest_log_.data (), &CabrilloLog::data_changed, [this] () {
+ multiplier_->reload (contest_log_.data ());
+ });
+ }
+ return contest_log_.data ();
+}
+
+Multiplier const * LogBook::multiplier () const
+{
+ // lazy create of Multiplier object instance
+ if (!multiplier_)
+ {
+ multiplier_.reset (new Multiplier {countries ()});
+ }
+ return multiplier_.data ();
+}
+
+FoxLog * LogBook::fox_log ()
+{
+ // lazy create of Fox log object instance
+ if (!fox_log_)
+ {
+ fox_log_.reset (new FoxLog {config_});
+ }
+ return fox_log_.data ();
+}
diff --git a/logbook/logbook.h b/logbook/logbook.h
index 1850aa01f..c87009e48 100644
--- a/logbook/logbook.h
+++ b/logbook/logbook.h
@@ -8,12 +8,16 @@
#include
#include
+#include
#include "WorkedBefore.hpp"
class Configuration;
class QByteArray;
class QDateTime;
+class CabrilloLog;
+class Multiplier;
+class FoxLog;
class LogBook final
: public QObject
@@ -22,13 +26,14 @@ class LogBook final
public:
LogBook (Configuration const *);
+ ~LogBook ();
QString const& path () const {return worked_before_.path ();}
bool add (QString const& call
, QString const& grid
, QString const& band
, QString const& mode
, QByteArray const& ADIF_record);
- AD1CCty const& countries () const {return worked_before_.countries ();}
+ AD1CCty const * countries () const {return worked_before_.countries ();}
void rescan ();
void match (QString const& call, QString const& mode, QString const& grid,
AD1CCty::Record const&, bool& callB4, bool& countryB4,
@@ -43,9 +48,16 @@ public:
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const& error) const;
+ CabrilloLog * contest_log ();
+ Multiplier const * multiplier () const;
+ FoxLog * fox_log ();
+
private:
Configuration const * config_;
WorkedBefore worked_before_;
+ QScopedPointer contest_log_;
+ QScopedPointer mutable multiplier_;
+ QScopedPointer fox_log_;
};
#endif
diff --git a/logbook/logbook.pri b/logbook/logbook.pri
index fcac62524..e67cdebd3 100644
--- a/logbook/logbook.pri
+++ b/logbook/logbook.pri
@@ -2,10 +2,12 @@ SOURCES += \
logbook/countriesworked.cpp \
logbook/logbook.cpp \
logbook/AD1CCty.cpp \
- logbook/WorkedBefore.cpp
+ logbook/WorkedBefore.cpp \
+ logbook/Multiplier.cpp
HEADERS += \
logbook/WorkedBefore.hpp \
logbook/logbook.h \
logbook/countriesworked.h \
- logbook/AD1CCty.hpp
+ logbook/AD1CCty.hpp \
+ logbook/Multiplier.hpp
diff --git a/main.cpp b/main.cpp
index 1ea0c6a49..9070ce33f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -380,10 +380,12 @@ int main(int argc, char *argv[])
}
catch (std::exception const& e)
{
+ MessageBox::critical_message (nullptr, QApplication::translate ("main", "Fatal error"), e.what ());
std::cerr << "Error: " << e.what () << '\n';
}
catch (...)
{
+ MessageBox::critical_message (nullptr, QApplication::translate ("main", "Unexpected fatal error"));
std::cerr << "Unexpected fatal error\n";
throw; // hoping the runtime might tell us more about the exception
}
diff --git a/models/CabrilloLog.cpp b/models/CabrilloLog.cpp
index 6849cdd61..dfba3d439 100644
--- a/models/CabrilloLog.cpp
+++ b/models/CabrilloLog.cpp
@@ -12,6 +12,7 @@
#include
#include "Configuration.hpp"
#include "Bands.hpp"
+#include "logbook/AD1CCty.hpp"
#include "qt_db_helpers.hpp"
#include "pimpl_impl.hpp"
@@ -19,59 +20,109 @@ class CabrilloLog::impl final
: public QSqlTableModel
{
public:
- impl (Configuration const *);
+ impl (CabrilloLog *, Configuration const *);
- QVariant data (QModelIndex const& index, int role) const
+ int columnCount (QModelIndex const& /*index */) const override
{
- auto value = QSqlTableModel::data (index, role);
- if (index.column () == fieldIndex ("when")
- && (Qt::DisplayRole == role || Qt::EditRole == role))
+ return QSqlTableModel::columnCount () + 1;
+ }
+
+ Qt::ItemFlags flags (QModelIndex const& index) const override
+ {
+ auto flags = QSqlTableModel::flags (index);
+ if (index.isValid () && index.column () == columnCount (index) - 1)
{
- auto t = QDateTime::fromMSecsSinceEpoch (value.toULongLong () * 1000ull, Qt::UTC);
+ flags = Qt::ItemIsEnabled;
+ }
+ return flags;
+ }
+
+ QVariant data (QModelIndex const& model_index, int role) const override
+ {
+ QVariant value;
+ if (model_index.isValid () && model_index.column () == columnCount (model_index) - 1)
+ { // derive band column
if (Qt::DisplayRole == role)
{
- QLocale locale;
- return locale.toString (t, locale.dateFormat (QLocale::ShortFormat) + " hh:mm:ss");
+ value = configuration_->bands ()->find (QSqlTableModel::data (index (model_index.row (), fieldIndex ("frequency"))).toULongLong ());
+ }
+ }
+ else
+ {
+ value = QSqlTableModel::data (model_index, role);
+ if (model_index.column () == fieldIndex ("frequency") && Qt::DisplayRole == role)
+ {
+ value = Radio::frequency_MHz_string (value.value (), 3); // kHz precision
+ }
+ else if (model_index.column () == fieldIndex ("when")
+ && (Qt::DisplayRole == role || Qt::EditRole == role))
+ { // adjust date/time to Qt format
+ auto t = QDateTime::fromMSecsSinceEpoch (value.toULongLong () * 1000ull, Qt::UTC);
+ if (Qt::DisplayRole == role)
+ {
+ QLocale locale;
+ return locale.toString (t, locale.dateFormat (QLocale::ShortFormat) + " hh:mm:ss");
+ }
+ value = t;
}
- value = t;
}
return value;
}
QString cabrillo_frequency_string (Radio::Frequency frequency) const;
+ void create_table ();
+ CabrilloLog * self_;
Configuration const * configuration_;
QSqlQuery mutable dupe_query_;
QSqlQuery mutable export_query_;
+ bool adding_row_;
};
-CabrilloLog::impl::impl (Configuration const * configuration)
- : QSqlTableModel {}
+CabrilloLog::impl::impl (CabrilloLog * self, Configuration const * configuration)
+ : self_ {self}
, configuration_ {configuration}
+ , adding_row_ {false}
{
- if (!database ().tables ().contains ("cabrillo_log"))
+ if (!database ().tables ().contains ("cabrillo_log_v2"))
{
- QSqlQuery query;
- SQL_error_check (query, static_cast (&QSqlQuery::exec),
- "CREATE TABLE cabrillo_log ("
- " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
- " frequency INTEGER NOT NULL,"
- " \"when\" DATETIME NOT NULL,"
- " call VARCHAR(20) NOT NULL,"
- " exchange_sent VARCHAR(32) NOT NULL,"
- " exchange_rcvd VARCHAR(32) NOT NULL,"
- " band VARCHAR(6) NOT NULL"
- ")");
+ create_table ();
}
+ setEditStrategy (QSqlTableModel::OnFieldChange);
+ setTable ("cabrillo_log_v2");
+ setHeaderData (fieldIndex ("frequency"), Qt::Horizontal, tr ("Freq(MHz)"));
+ setHeaderData (fieldIndex ("mode"), Qt::Horizontal, tr ("Mode"));
+ setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
+ setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call"));
+ setHeaderData (fieldIndex ("exchange_sent"), Qt::Horizontal, tr ("Sent"));
+ setHeaderData (fieldIndex ("exchange_rcvd"), Qt::Horizontal, tr ("Rcvd"));
+ setHeaderData (columnCount (QModelIndex {}) - 1, Qt::Horizontal, tr ("Band"));
+
+ // This descending order by time is important, it makes the view
+ // place the latest row at the top, without this the model/view
+ // interactions are both sluggish and unhelpful.
+ setSort (fieldIndex ("when"), Qt::DescendingOrder);
+
+ connect (this, &CabrilloLog::impl::modelReset, self_, &CabrilloLog::data_changed);
+ connect (this, &CabrilloLog::impl::dataChanged, [this] (QModelIndex const& tl, QModelIndex const& br) {
+ if (!adding_row_ && !(tl == br)) // ignore single cell changes
+ // as a another change for the
+ // whole row will follow
+ {
+ Q_EMIT self_->data_changed ();
+ }
+ });
+
+ SQL_error_check (*this, &QSqlTableModel::select);
+
SQL_error_check (dupe_query_, &QSqlQuery::prepare,
"SELECT "
- " COUNT(*) "
+ " frequency "
" FROM "
- " cabrillo_log "
+ " cabrillo_log_v2 "
" WHERE "
- " call = :call "
- " AND band = :band");
+ " call = :call ");
SQL_error_check (export_query_, &QSqlQuery::prepare,
"SELECT "
@@ -81,32 +132,31 @@ CabrilloLog::impl::impl (Configuration const * configuration)
" , call"
" , exchange_rcvd"
" FROM "
- " cabrillo_log "
+ " cabrillo_log_v2 "
" ORDER BY "
" \"when\"");
-
- setEditStrategy (QSqlTableModel::OnFieldChange);
- setTable ("cabrillo_log");
- setHeaderData (fieldIndex ("frequency"), Qt::Horizontal, tr ("Freq(kHz)"));
- setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
- setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call"));
- setHeaderData (fieldIndex ("exchange_sent"), Qt::Horizontal, tr ("Sent"));
- setHeaderData (fieldIndex ("exchange_rcvd"), Qt::Horizontal, tr ("Rcvd"));
- setHeaderData (fieldIndex ("band"), Qt::Horizontal, tr ("Band"));
+}
- // This descending order by time is important, it makes the view
- // place the latest row at the top, without this the model/view
- // interactions are both sluggish and unhelpful.
- setSort (fieldIndex ("when"), Qt::DescendingOrder);
-
- SQL_error_check (*this, &QSqlTableModel::select);
+void CabrilloLog::impl::create_table ()
+{
+ QSqlQuery query;
+ SQL_error_check (query, static_cast (&QSqlQuery::exec),
+ "CREATE TABLE cabrillo_log_v2 ("
+ " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ " frequency INTEGER NOT NULL,"
+ " mode VARCHAR(6) NOT NULL,"
+ " \"when\" DATETIME NOT NULL,"
+ " call VARCHAR(20) NOT NULL,"
+ " exchange_sent VARCHAR(32) NOT NULL,"
+ " exchange_rcvd VARCHAR(32) NOT NULL"
+ ")");
}
// frequency here is in kHz
QString CabrilloLog::impl::cabrillo_frequency_string (Radio::Frequency frequency) const
{
QString result;
- auto band = configuration_->bands ()->find (frequency * 1000ull);
+ auto band = configuration_->bands ()->find (frequency);
if ("1mm" == band) result = "LIGHT";
else if ("2mm" == band) result = "241G";
else if ("2.5mm" == band) result = "134G";
@@ -124,12 +174,15 @@ QString CabrilloLog::impl::cabrillo_frequency_string (Radio::Frequency frequency
else if ("2m" == band) result = "144";
else if ("4m" == band) result = "70";
else if ("6m" == band) result = "50";
- else result = QString::number (frequency);
+ else result = QString::number (frequency / 1000ull);
return result;
}
-CabrilloLog::CabrilloLog (Configuration const * configuration)
- : m_ {configuration}
+#include "moc_CabrilloLog.cpp"
+
+CabrilloLog::CabrilloLog (Configuration const * configuration, QObject * parent)
+ : QObject {parent}
+ , m_ {this, configuration}
{
Q_ASSERT (configuration);
}
@@ -158,11 +211,12 @@ namespace
}
}
-bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString const& call
+bool CabrilloLog::add_QSO (Frequency frequency, QString const& mode, QDateTime const& when, QString const& call
, QString const& exchange_sent, QString const& exchange_received)
{
auto record = m_->record ();
- record.setValue ("frequency", frequency / 1000ull); // kHz
+ record.setValue ("frequency", frequency);
+ record.setValue ("mode", mode);
if (!when.isNull ())
{
record.setValue ("when", when.toMSecsSinceEpoch () / 1000ull);
@@ -174,15 +228,16 @@ bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString c
set_value_maybe_null (record, "call", call);
set_value_maybe_null (record, "exchange_sent", exchange_sent);
set_value_maybe_null (record, "exchange_rcvd", exchange_received);
- set_value_maybe_null (record, "band", m_->configuration_->bands ()->find (frequency));
if (m_->isDirty ())
{
m_->revert (); // discard any uncommitted changes
}
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
ConditionalTransaction transaction {*m_};
+ m_->adding_row_ = true;
auto ok = m_->insertRecord (-1, record);
transaction.submit ();
+ m_->adding_row_ = false;
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
return ok;
}
@@ -190,10 +245,18 @@ bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString c
bool CabrilloLog::dupe (Frequency frequency, QString const& call) const
{
m_->dupe_query_.bindValue (":call", call);
- m_->dupe_query_.bindValue (":band", m_->configuration_->bands ()->find (frequency));
SQL_error_check (m_->dupe_query_, static_cast (&QSqlQuery::exec));
- m_->dupe_query_.next ();
- return m_->dupe_query_.value (0).toInt ();
+ auto record = m_->dupe_query_.record ();
+ auto frequency_index = record.indexOf ("frequency");
+ while (m_->dupe_query_.next ())
+ {
+ if (m_->configuration_->bands ()->find (m_->dupe_query_.value (frequency_index).toULongLong ())
+ == m_->configuration_->bands ()->find (frequency))
+ {
+ return true;
+ }
+ }
+ return false;
}
void CabrilloLog::reset ()
@@ -208,6 +271,7 @@ void CabrilloLog::reset ()
transaction.submit ();
m_->select (); // to refresh views
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
+ Q_EMIT data_changed ();
}
}
@@ -216,6 +280,7 @@ void CabrilloLog::export_qsos (QTextStream& stream) const
SQL_error_check (m_->export_query_, static_cast (&QSqlQuery::exec));
auto record = m_->export_query_.record ();
auto frequency_index = record.indexOf ("frequency");
+ // auto mode_index = record.indexOf ("mode");
auto when_index = record.indexOf ("when");
auto call_index = record.indexOf ("call");
auto sent_index = record.indexOf ("exchange_sent");
@@ -232,3 +297,17 @@ void CabrilloLog::export_qsos (QTextStream& stream) const
.arg (m_->export_query_.value (rcvd_index).toString (), -13);
}
}
+
+auto CabrilloLog::unique_DXCC_entities (AD1CCty const * countries) const -> worked_set
+{
+ QSqlQuery q {"SELECT DISTINCT BAND, CALL FROM cabrillo_log_v2"};
+ auto band_index = q.record ().indexOf ("band");
+ auto call_index = q.record ().indexOf ("call");
+ worked_set entities;
+ while (q.next ())
+ {
+ entities << worked_item {q.value (band_index).toString ()
+ , countries->lookup (q.value (call_index).toString ()).primary_prefix};
+ }
+ return entities;
+}
diff --git a/models/CabrilloLog.hpp b/models/CabrilloLog.hpp
index 43b9e8f94..97d8f0d88 100644
--- a/models/CabrilloLog.hpp
+++ b/models/CabrilloLog.hpp
@@ -1,33 +1,43 @@
#ifndef CABRILLO_LOG_HPP_
#define CABRILLO_LOG_HPP_
-#include
+#include
+#include
+#include
+#include
#include "Radio.hpp"
#include "pimpl_h.hpp"
class Configuration;
class QDateTime;
-class QString;
class QSqlTableModel;
class QTextStream;
+class AD1CCty;
class CabrilloLog final
- : private boost::noncopyable
+ : public QObject
{
+ Q_OBJECT
+
public:
using Frequency = Radio::Frequency;
+ using worked_item = QPair;
+ using worked_set = QSet;
- explicit CabrilloLog (Configuration const *);
+ explicit CabrilloLog (Configuration const *, QObject * parent = nullptr);
~CabrilloLog ();
// returns false if insert fails
- bool add_QSO (Frequency, QDateTime const&, QString const& call
+ bool add_QSO (Frequency, QString const& mode, QDateTime const&, QString const& call
, QString const& report_sent, QString const& report_received);
bool dupe (Frequency, QString const& call) const;
QSqlTableModel * model ();
void reset ();
void export_qsos (QTextStream&) const;
+ worked_set unique_DXCC_entities (AD1CCty const *) const;
+
+ Q_SIGNAL void data_changed () const;
private:
class impl;
diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp
index b135a512a..c0170a499 100644
--- a/models/FrequencyList.cpp
+++ b/models/FrequencyList.cpp
@@ -127,7 +127,9 @@ namespace
{7074000, Modes::FT8, IARURegions::ALL},
{7076000, Modes::JT65, IARURegions::ALL},
{7078000, Modes::JT9, IARURegions::ALL},
- {7047000, Modes::FT4, IARURegions::ALL}, // provisional
+ {7047500, Modes::FT4, IARURegions::ALL}, // provisional - moved
+ // up 500Hz to clear
+ // W1AW code practice QRG
// Band plans (all USB dial unless stated otherwise)
//
diff --git a/qt_db_helpers.hpp b/qt_db_helpers.hpp
index 49a082f72..dcf9d0333 100644
--- a/qt_db_helpers.hpp
+++ b/qt_db_helpers.hpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include "boost/core/noncopyable.hpp"
template
void SQL_error_check (T&& object, Func func, Args&&... args)
diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt
index 6be6a6df2..271d2d3c4 100644
--- a/samples/CMakeLists.txt
+++ b/samples/CMakeLists.txt
@@ -1,5 +1,5 @@
set (SAMPLE_FILES
- FT4/190106_000112.wav
+ FT4/000000_000002.wav
FT8/181201_180245.wav
ISCAT/ISCAT-A/VK7MO_110401_235515.wav
ISCAT/ISCAT-B/K0AWU_100714_115000.wav
diff --git a/widgets/CabrilloLogWindow.cpp b/widgets/CabrilloLogWindow.cpp
index 2f7b44d4a..6fd753136 100644
--- a/widgets/CabrilloLogWindow.cpp
+++ b/widgets/CabrilloLogWindow.cpp
@@ -1,10 +1,12 @@
#include "CabrilloLogWindow.hpp"
+#include
#include
#include
#include
#include "Configuration.hpp"
#include "models/Bands.hpp"
+#include "item_delegates/FrequencyDelegate.hpp"
#include "item_delegates/ForeignKeyDelegate.hpp"
#include "item_delegates/CallsignDelegate.hpp"
#include "pimpl_impl.hpp"
@@ -29,7 +31,7 @@ namespace
switch (index.column ())
{
case 1:
- case 6:
+ case 7:
return Qt::AlignRight + Qt::AlignVCenter;
default:
break;
@@ -63,10 +65,10 @@ CabrilloLogWindow::CabrilloLogWindow (QSettings * settings, Configuration const
m_->format_model_.setSourceModel (m_->log_model_);
m_->ui_.log_table_view->setModel (&m_->format_model_);
set_log_view (m_->ui_.log_table_view);
- m_->ui_.log_table_view->setItemDelegateForColumn (3, new CallsignDelegate {this});
- m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), 0, this});
+ m_->ui_.log_table_view->setItemDelegateForColumn (1, new FrequencyDelegate {this});
+ m_->ui_.log_table_view->setItemDelegateForColumn (4, new CallsignDelegate {this});
auto h_header = m_->ui_.log_table_view->horizontalHeader ();
- h_header->moveSection (6, 1); // band to first column
+ h_header->moveSection (7, 1); // band to first column
}
CabrilloLogWindow::~CabrilloLogWindow ()
diff --git a/widgets/FrequencyDeltaLineEdit.cpp b/widgets/FrequencyDeltaLineEdit.cpp
new file mode 100644
index 000000000..b7ed144b6
--- /dev/null
+++ b/widgets/FrequencyDeltaLineEdit.cpp
@@ -0,0 +1,54 @@
+#include "FrequencyDeltaLineEdit.hpp"
+
+#include
+
+#include
+#include
+#include
+
+#include "moc_FrequencyDeltaLineEdit.cpp"
+
+namespace
+{
+ class MHzValidator
+ : public QDoubleValidator
+ {
+ public:
+ MHzValidator (double bottom, double top, QObject * parent = nullptr)
+ : QDoubleValidator {bottom, top, 6, parent}
+ {
+ }
+
+ State validate (QString& input, int& pos) const override
+ {
+ State result = QDoubleValidator::validate (input, pos);
+ if (Acceptable == result)
+ {
+ bool ok;
+ (void)QLocale {}.toDouble (input, &ok);
+ if (!ok)
+ {
+ result = Intermediate;
+ }
+ }
+ return result;
+ }
+ };
+}
+
+FrequencyDeltaLineEdit::FrequencyDeltaLineEdit (QWidget * parent)
+ : QLineEdit (parent)
+{
+ setValidator (new MHzValidator {-std::numeric_limits::max () / 10.e6,
+ std::numeric_limits::max () / 10.e6, this});
+}
+
+auto FrequencyDeltaLineEdit::frequency_delta () const -> FrequencyDelta
+{
+ return Radio::frequency_delta (text (), 6);
+}
+
+void FrequencyDeltaLineEdit::frequency_delta (FrequencyDelta d)
+{
+ setText (Radio::frequency_MHz_string (d));
+}
diff --git a/widgets/FrequencyDeltaLineEdit.hpp b/widgets/FrequencyDeltaLineEdit.hpp
new file mode 100644
index 000000000..caa00ecba
--- /dev/null
+++ b/widgets/FrequencyDeltaLineEdit.hpp
@@ -0,0 +1,29 @@
+#ifndef FREQUENCY_DELTA_LINE_EDIT_HPP_
+#define FREQUENCY_DELTA_LINE_EDIT_HPP_
+
+#include
+
+#include "Radio.hpp"
+
+class QWidget;
+
+//
+// MHz frequency delta line edit with validation
+//
+class FrequencyDeltaLineEdit final
+ : public QLineEdit
+{
+ Q_OBJECT;
+ Q_PROPERTY (FrequencyDelta frequency_delta READ frequency_delta WRITE frequency_delta USER true);
+
+public:
+ using FrequencyDelta = Radio::FrequencyDelta;
+
+ explicit FrequencyDeltaLineEdit (QWidget * parent = nullptr);
+
+ // Property frequency_delta implementation
+ FrequencyDelta frequency_delta () const;
+ void frequency_delta (FrequencyDelta);
+};
+
+#endif
diff --git a/widgets/FrequencyLineEdit.cpp b/widgets/FrequencyLineEdit.cpp
index 78f8b2e1f..1ca2ba20b 100644
--- a/widgets/FrequencyLineEdit.cpp
+++ b/widgets/FrequencyLineEdit.cpp
@@ -51,21 +51,3 @@ void FrequencyLineEdit::frequency (Frequency f)
{
setText (Radio::frequency_MHz_string (f));
}
-
-
-FrequencyDeltaLineEdit::FrequencyDeltaLineEdit (QWidget * parent)
- : QLineEdit (parent)
-{
- setValidator (new MHzValidator {-std::numeric_limits::max () / 10.e6,
- std::numeric_limits::max () / 10.e6, this});
-}
-
-auto FrequencyDeltaLineEdit::frequency_delta () const -> FrequencyDelta
-{
- return Radio::frequency_delta (text (), 6);
-}
-
-void FrequencyDeltaLineEdit::frequency_delta (FrequencyDelta d)
-{
- setText (Radio::frequency_MHz_string (d));
-}
diff --git a/widgets/FrequencyLineEdit.hpp b/widgets/FrequencyLineEdit.hpp
index dec0feb00..7e535f5a9 100644
--- a/widgets/FrequencyLineEdit.hpp
+++ b/widgets/FrequencyLineEdit.hpp
@@ -8,7 +8,7 @@
class QWidget;
//
-// MHz frequency line edits with validation
+// MHz frequency line edit with validation
//
class FrequencyLineEdit final
: public QLineEdit
@@ -26,20 +26,4 @@ public:
void frequency (Frequency);
};
-class FrequencyDeltaLineEdit final
- : public QLineEdit
-{
- Q_OBJECT;
- Q_PROPERTY (FrequencyDelta frequency_delta READ frequency_delta WRITE frequency_delta USER true);
-
-public:
- using FrequencyDelta = Radio::FrequencyDelta;
-
- explicit FrequencyDeltaLineEdit (QWidget * parent = nullptr);
-
- // Property frequency_delta implementation
- FrequencyDelta frequency_delta () const;
- void frequency_delta (FrequencyDelta);
-};
-
#endif
diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp
index c0bcd4129..53d7cd5cd 100644
--- a/widgets/displaytext.cpp
+++ b/widgets/displaytext.cpp
@@ -271,7 +271,7 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons
if(call.length()<3) return message;
if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message;
- auto const& looked_up = logBook.countries ().lookup (call);
+ auto const& looked_up = logBook.countries ()->lookup (call);
logBook.match (call, currentMode, grid, looked_up, callB4, countryB4, gridB4, continentB4, CQZoneB4, ITUZoneB4);
logBook.match (call, currentMode, grid, looked_up, callB4onBand, countryB4onBand, gridB4onBand,
continentB4onBand, CQZoneB4onBand, ITUZoneB4onBand, currentBand);
diff --git a/widgets/displaytext.h b/widgets/displaytext.h
index 7f308bef8..8b580b8a2 100644
--- a/widgets/displaytext.h
+++ b/widgets/displaytext.h
@@ -65,6 +65,4 @@ private:
int modified_vertical_scrollbar_max_;
};
- extern QHash m_LoTW;
-
#endif // DISPLAYTEXT_H
diff --git a/widgets/logqso.cpp b/widgets/logqso.cpp
index acbb340bc..2eaedf116 100644
--- a/widgets/logqso.cpp
+++ b/widgets/logqso.cpp
@@ -16,11 +16,12 @@
#include "moc_logqso.cpp"
LogQSO::LogQSO(QString const& programTitle, QSettings * settings
- , Configuration const * config, QWidget *parent)
+ , Configuration const * config, LogBook * log, QWidget *parent)
: QDialog {parent, Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint}
, ui(new Ui::LogQSO)
, m_settings (settings)
, m_config {config}
+ , m_log {log}
{
ui->setupUi(this);
setWindowTitle(programTitle + " - Log QSO");
@@ -57,8 +58,7 @@ void LogQSO::storeSettings () const
void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode,
QString const& rptSent, QString const& rptRcvd,
QDateTime const& dateTimeOn, QDateTime const& dateTimeOff,
- Radio::Frequency dialFreq, bool noSuffix, QString xSent, QString xRcvd,
- CabrilloLog * cabrillo_log)
+ Radio::Frequency dialFreq, bool noSuffix, QString xSent, QString xRcvd)
{
if(!isHidden()) return;
ui->call->setText (hisCall);
@@ -100,7 +100,6 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
ui->loggedOperator->setText(m_config->opCall());
ui->exchSent->setText (xSent);
ui->exchRcvd->setText (xRcvd);
- m_cabrilloLog = cabrillo_log;
using SpOp = Configuration::SpecialOperatingActivity;
auto special_op = m_config->special_op_id ();
@@ -158,7 +157,7 @@ void LogQSO::accept()
return; // without accepting
}
- if (!m_cabrilloLog->add_QSO (m_dialFreq, dateTimeOff, hisCall, xsent, xrcvd))
+ if (!m_log->contest_log ()->add_QSO (m_dialFreq, mode, dateTimeOff, hisCall, xsent, xrcvd))
{
show ();
MessageBox::warning_message (this, tr ("Invalid QSO Data"),
diff --git a/widgets/logqso.h b/widgets/logqso.h
index 82a75b7bd..739a601f7 100644
--- a/widgets/logqso.h
+++ b/widgets/logqso.h
@@ -17,19 +17,19 @@ namespace Ui {
class QSettings;
class Configuration;
class QByteArray;
-class CabrilloLog;
+class LogBook;
class LogQSO : public QDialog
{
Q_OBJECT
public:
- explicit LogQSO(QString const& programTitle, QSettings *, Configuration const *, QWidget *parent = 0);
+ explicit LogQSO(QString const& programTitle, QSettings *, Configuration const *, LogBook *, QWidget *parent = 0);
~LogQSO();
void initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode,
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
QDateTime const& dateTimeOff, Radio::Frequency dialFreq,
- bool noSuffix, QString xSent, QString xRcvd, CabrilloLog *);
+ bool noSuffix, QString xSent, QString xRcvd);
public slots:
void accept();
@@ -54,12 +54,12 @@ private:
QScopedPointer ui;
QSettings * m_settings;
Configuration const * m_config;
+ LogBook * m_log;
QString m_txPower;
QString m_comments;
Radio::Frequency m_dialFreq;
QString m_myCall;
QString m_myGrid;
- CabrilloLog * m_cabrilloLog;
};
#endif // LogQSO_H
diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp
index ef5dd616b..277dbfdd7 100644
--- a/widgets/mainwindow.cpp
+++ b/widgets/mainwindow.cpp
@@ -244,7 +244,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
m_echoGraph (new EchoGraph(m_settings)),
m_fastGraph (new FastGraph(m_settings)),
// no parent so that it has a taskbar icon
- m_logDlg (new LogQSO (program_title (), m_settings, &m_config, nullptr)),
+ m_logDlg (new LogQSO (program_title (), m_settings, &m_config, &m_logBook, nullptr)),
m_lastDialFreq {0},
m_dialFreqRxWSPR {0},
m_detector {new Detector {RX_SAMPLE_RATE, double(NTMAX), downSampleFactor}},
@@ -2544,16 +2544,14 @@ void MainWindow::on_actionAstronomical_data_toggled (bool checked)
void MainWindow::on_fox_log_action_triggered()
{
- if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config});
if (!m_foxLogWindow)
{
- m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_foxLog.data ()});
+ m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_logBook.fox_log ()});
// Connect signals from fox log window
connect (this, &MainWindow::finished, m_foxLogWindow.data (), &FoxLogWindow::close);
connect (m_foxLogWindow.data (), &FoxLogWindow::reset_log_model, [this] () {
- if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config});
- m_foxLog->reset ();
+ m_logBook.fox_log ()->reset ();
});
}
m_foxLogWindow->showNormal ();
@@ -2563,10 +2561,9 @@ void MainWindow::on_fox_log_action_triggered()
void MainWindow::on_contest_log_action_triggered()
{
- if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config});
if (!m_contestLogWindow)
{
- m_contestLogWindow.reset (new CabrilloLogWindow {m_settings, &m_config, m_cabrilloLog->model ()});
+ m_contestLogWindow.reset (new CabrilloLogWindow {m_settings, &m_config, m_logBook.contest_log ()->model ()});
// Connect signals from contest log window
connect (this, &MainWindow::finished, m_contestLogWindow.data (), &CabrilloLogWindow::close);
@@ -5521,15 +5518,9 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
default: break;
}
- auto special_op = m_config.special_op_id ();
- if (SpecOp::NONE < special_op && special_op < SpecOp::FOX)
- {
- if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config});
- }
m_logDlg->initLogQSO (m_hisCall, grid, m_modeTx, m_rptSent, m_rptRcvd,
m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal +
- ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd,
- m_cabrilloLog.data ());
+ ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd);
m_inQSOwith="";
}
@@ -6369,15 +6360,13 @@ void MainWindow::on_reset_cabrillo_log_action_triggered ()
"for export in your Cabrillo log.")))
{
if(m_config.RTTY_Exchange()!="SCC") ui->sbSerialNumber->setValue(1);
- if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config});
- m_cabrilloLog->reset ();
+ m_logBook.contest_log ()->reset ();
}
}
void MainWindow::on_actionExport_Cabrillo_log_triggered()
{
- if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config});
- if (QDialog::Accepted == ExportCabrillo {m_settings, &m_config, m_cabrilloLog.data ()}.exec())
+ if (QDialog::Accepted == ExportCabrillo {m_settings, &m_config, m_logBook.contest_log ()}.exec())
{
MessageBox::information_message (this, tr ("Cabrillo Log saved"));
}
@@ -8278,7 +8267,7 @@ void MainWindow::houndCallers()
if(!ui->textBrowser4->toPlainText().contains(paddedHoundCall)) {
if(m_loggedByFox[houndCall].contains(m_lastBand)) continue; //already logged on this band
if(m_foxQSO.contains(houndCall)) continue; //still in the QSO map
- auto const& entity = m_logBook.countries ().lookup (houndCall);
+ auto const& entity = m_logBook.countries ()->lookup (houndCall);
auto const& continent = AD1CCty::continent (entity.continent);
//If we are using a directed CQ, ignore Hound calls that do not comply.
@@ -8459,9 +8448,8 @@ list2Done:
m_hisGrid=m_foxQSO[hc1].grid;
m_rptSent=m_foxQSO[hc1].sent;
m_rptRcvd=m_foxQSO[hc1].rcvd;
- if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config});
if (!m_foxLogWindow) on_fox_log_action_triggered ();
- if (m_foxLog->add_QSO (QSO_time, m_hisCall, m_hisGrid, m_rptSent, m_rptRcvd, m_lastBand))
+ if (m_logBook.fox_log ()->add_QSO (QSO_time, m_hisCall, m_hisGrid, m_rptSent, m_rptRcvd, m_lastBand))
{
writeFoxQSO (QString {" Log: %1 %2 %3 %4 %5"}.arg (m_hisCall).arg (m_hisGrid)
.arg (m_rptSent).arg (m_rptRcvd).arg (m_lastBand));
diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h
index ffa71c1fe..03d009a76 100644
--- a/widgets/mainwindow.h
+++ b/widgets/mainwindow.h
@@ -72,9 +72,7 @@ class WideGraph;
class LogQSO;
class Transceiver;
class MessageAveraging;
-class FoxLog;
class FoxLogWindow;
-class CabrilloLog;
class CabrilloLogWindow;
class ColorHighlighting;
class MessageClient;
@@ -376,9 +374,7 @@ private:
QScopedPointer m_prefixes;
QScopedPointer m_mouseCmnds;
QScopedPointer m_msgAvgWidget;
- QScopedPointer m_foxLog;
QScopedPointer m_foxLogWindow;
- QScopedPointer m_cabrilloLog;
QScopedPointer m_contestLogWindow;
QScopedPointer m_colorHighlighting;
Transceiver::TransceiverState m_rigState;
diff --git a/widgets/widgets.pri b/widgets/widgets.pri
index eef0c7857..3c2cb2444 100644
--- a/widgets/widgets.pri
+++ b/widgets/widgets.pri
@@ -8,13 +8,14 @@ SOURCES += \
widgets/fastplot.cpp widgets/MessageBox.cpp \
widgets/colorhighlighting.cpp widgets/ExportCabrillo.cpp \
widgets/AbstractLogWindow.cpp \
+ widgets/FrequencyLineEdit.cpp widgets/FrequencyDeltaLineEdit.cpp \
widgets/FoxLogWindow.cpp widgets/CabrilloLogWindow.cpp
HEADERS += \
widgets/mainwindow.h widgets/plotter.h \
widgets/about.h widgets/widegraph.h \
widgets/displaytext.h widgets/logqso.h widgets/LettersSpinBox.hpp \
- widgets/FrequencyLineEdit.hpp widgets/signalmeter.h \
+ widgets/FrequencyLineEdit.hpp widgets/FrequencyDeltaLineEdit.hpp widgets/signalmeter.h \
widgets/meterwidget.h widgets/messageaveraging.h \
widgets/echoplot.h widgets/echograph.h widgets/fastgraph.h \
widgets/fastplot.h widgets/MessageBox.hpp widgets/colorhighlighting.h \