Validate contest QSO details before allowing logging

Basic  validation, must  have  non-empty exchange  sent and  received.
Abstracted log view window widget  behaviour into a base class. Turned
on  auto  resize  to  row  height in  log  view  windows  and  enabled
alternating colours. Convert  empty fields to NULL  when inserting new
log table  rows to signify missing  data. Trap insert row  errors when
adding  to contest  log table  so  that logging  can be  held back  if
constraints are not met. Re-factored  log QSO processing to try insert
row into log table  first and pop up a message  box if constraints are
not met, this pops  up the Log QSO window in case  it was initiated by
an auto log event.
This commit is contained in:
Bill Somerville 2018-11-23 01:18:39 +00:00
parent a488c64e43
commit c81b3c8e65
16 changed files with 349 additions and 207 deletions

View File

@ -265,6 +265,7 @@ set (wsjt_qt_CXXSRCS
models/DecodeHighlightingModel.cpp models/DecodeHighlightingModel.cpp
widgets/DecodeHighlightingListView.cpp widgets/DecodeHighlightingListView.cpp
models/FoxLog.cpp models/FoxLog.cpp
widgets/AbstractLogWindow.cpp
widgets/FoxLogWindow.cpp widgets/FoxLogWindow.cpp
widgets/CabrilloLogWindow.cpp widgets/CabrilloLogWindow.cpp
item_delegates/CallsignDelegate.cpp item_delegates/CallsignDelegate.cpp

View File

@ -78,19 +78,46 @@ QAbstractItemModel * CabrilloLog::model ()
return &*m_; return &*m_;
} }
void CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString const& call namespace
{
void set_value_maybe_null (QSqlRecord& record, QString const& name, QString const& value)
{
if (value.size ())
{
record.setValue (name, value);
}
else
{
record.setNull (name);
}
}
}
bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString const& call
, QString const& exchange_sent, QString const& exchange_received) , QString const& exchange_sent, QString const& exchange_received)
{ {
ConditionalTransaction transaction {*m_}; ConditionalTransaction transaction {*m_};
auto record = m_->record (); auto record = m_->record ();
record.setValue ("frequency", frequency / 1000ull); // kHz record.setValue ("frequency", frequency / 1000ull); // kHz
if (!when.isNull ())
{
record.setValue ("when", when.toMSecsSinceEpoch () / 1000ull); record.setValue ("when", when.toMSecsSinceEpoch () / 1000ull);
record.setValue ("call", call); }
record.setValue ("exchange_sent", exchange_sent); else
record.setValue ("exchange_rcvd", exchange_received); {
record.setValue ("band", m_->configuration_->bands ()->find (frequency)); record.setNull ("when");
}
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));
SQL_error_check (*m_, &QSqlTableModel::insertRecord, -1, record); SQL_error_check (*m_, &QSqlTableModel::insertRecord, -1, record);
transaction.submit (); if (!transaction.submit (false))
{
transaction.revert ();
return false;
}
return true;
} }
bool CabrilloLog::dupe (Frequency frequency, QString const& call) const bool CabrilloLog::dupe (Frequency frequency, QString const& call) const

View File

@ -21,7 +21,7 @@ public:
~CabrilloLog (); ~CabrilloLog ();
// returns false if insert fails // returns false if insert fails
void add_QSO (Frequency, QDateTime const&, QString const& call bool add_QSO (Frequency, QDateTime const&, QString const& call
, QString const& report_sent, QString const& report_received); , QString const& report_sent, QString const& report_received);
bool dupe (Frequency, QString const& call) const; bool dupe (Frequency, QString const& call) const;

View File

@ -88,12 +88,19 @@ bool FoxLog::add_QSO (QDateTime const& when, QString const& call, QString const&
{ {
ConditionalTransaction transaction {*m_}; ConditionalTransaction transaction {*m_};
auto record = m_->record (); auto record = m_->record ();
if (!when.isNull ())
{
record.setValue ("when", when.toMSecsSinceEpoch () / 1000); record.setValue ("when", when.toMSecsSinceEpoch () / 1000);
record.setValue ("call", call); }
else
{
record.setNull ("when");
}
set_value_maybe_null (record, "call", call);
set_value_maybe_null (record, "grid", grid); set_value_maybe_null (record, "grid", grid);
set_value_maybe_null (record, "report_sent", report_sent); set_value_maybe_null (record, "report_sent", report_sent);
set_value_maybe_null (record, "report_rcvd", report_received); set_value_maybe_null (record, "report_rcvd", report_received);
record.setValue ("band", band); set_value_maybe_null (record, "band", band);
SQL_error_check (*m_, &QSqlTableModel::insertRecord, -1, record); SQL_error_check (*m_, &QSqlTableModel::insertRecord, -1, record);
if (!transaction.submit (false)) if (!transaction.submit (false))
{ {

View File

@ -0,0 +1,76 @@
#include "AbstractLogWindow.hpp"
#include <QSettings>
#include <QString>
#include <QTableView>
#include <QHeaderView>
#include "Configuration.hpp"
#include "SettingsGroup.hpp"
#include "models/FontOverrideModel.hpp"
#include "pimpl_impl.hpp"
class AbstractLogWindow::impl final
{
public:
impl (QString const& settings_key, QSettings * settings, Configuration const * configuration)
: settings_key_ {settings_key}
, settings_ {settings}
, configuration_ {configuration}
, log_view_ {nullptr}
{
}
QString settings_key_;
QSettings * settings_;
Configuration const * configuration_;
QTableView * log_view_;
FontOverrideModel model_;
};
AbstractLogWindow::AbstractLogWindow (QString const& settings_key, QSettings * settings
, Configuration const * configuration
, QWidget * parent)
: QWidget {parent}
, m_ {settings_key, settings, configuration}
{
// ensure view scrolls to latest new row
connect (&m_->model_, &QAbstractItemModel::rowsInserted, [this] (QModelIndex const& /*parent*/, int /*first*/, int /*last*/) {
if (m_->log_view_) m_->log_view_->scrollToBottom ();
});
}
AbstractLogWindow::~AbstractLogWindow ()
{
SettingsGroup g {m_->settings_, m_->settings_key_};
m_->settings_->setValue ("window/geometry", saveGeometry ());
}
void AbstractLogWindow::set_log_model (QAbstractItemModel * log_model)
{
m_->model_.setSourceModel (log_model);
}
void AbstractLogWindow::set_log_view (QTableView * log_view)
{
// do this here because we know the UI must be setup before this
SettingsGroup g {m_->settings_, m_->settings_key_};
restoreGeometry (m_->settings_->value ("window/geometry").toByteArray ());
m_->log_view_ = log_view;
m_->log_view_->setModel (&m_->model_);
m_->log_view_->setColumnHidden (0, true);
auto horizontal_header = log_view->horizontalHeader ();
horizontal_header->setSectionResizeMode (QHeaderView::ResizeToContents);
horizontal_header->setSectionsMovable (true);
m_->log_view_->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
set_log_view_font (m_->configuration_->decoded_text_font ());
m_->log_view_->scrollToBottom ();
}
void AbstractLogWindow::set_log_view_font (QFont const& font)
{
// m_->log_view_->setFont (font);
// m_->log_view_->horizontalHeader ()->setFont (font);
// m_->log_view_->verticalHeader ()->setFont (font);
m_->model_.set_font (font);
}

View File

@ -0,0 +1,32 @@
#ifndef ABSTRACT_LOG_WINDOW_HPP_
#define ABSTRACT_LOG_WINDOW_HPP_
#include <QWidget>
#include "pimpl_h.hpp"
class QString;
class QSettings;
class Configuration;
class QAbstractItemModel;
class QTableView;
class QFont;
class AbstractLogWindow
: public QWidget
{
public:
AbstractLogWindow (QString const& settings_key, QSettings * settings
, Configuration const * configuration
, QWidget * parent = nullptr);
virtual ~AbstractLogWindow () = 0;
void set_log_model (QAbstractItemModel *);
void set_log_view (QTableView *);
void set_log_view_font (QFont const&);
private:
class impl;
pimpl<impl> m_;
};
#endif

View File

@ -1,77 +1,68 @@
#include "CabrilloLogWindow.hpp" #include "CabrilloLogWindow.hpp"
#include <QSettings>
#include <QApplication> #include <QApplication>
#include <QDateTime> #include <QIdentityProxyModel>
#include <QDir>
#include <QStyledItemDelegate>
#include <QDateTimeEdit>
#include <QPainter>
#include "SettingsGroup.hpp"
#include "Configuration.hpp" #include "Configuration.hpp"
#include "models/Bands.hpp" #include "models/Bands.hpp"
#include "item_delegates/ForeignKeyDelegate.hpp" #include "item_delegates/ForeignKeyDelegate.hpp"
#include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp" #include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp"
#include "item_delegates/CallsignDelegate.hpp" #include "item_delegates/CallsignDelegate.hpp"
#include "item_delegates/MaidenheadLocatorDelegate.hpp" #include "pimpl_impl.hpp"
#include "widgets/MessageBox.hpp"
#include "qt_helpers.hpp"
#include "ui_CabrilloLogWindow.h" #include "ui_CabrilloLogWindow.h"
namespace
{
class FormatProxyModel final
: public QIdentityProxyModel
{
public:
explicit FormatProxyModel (QObject * parent = nullptr)
: QIdentityProxyModel {parent}
{
}
QVariant data (QModelIndex const& index, int role) const override
{
if (Qt::TextAlignmentRole == role && index.isValid ())
{
switch (index.column ())
{
case 1:
case 6:
return Qt::AlignRight + Qt::AlignVCenter;
default:
break;
}
}
return QIdentityProxyModel::data (index, role);
}
};
}
class CabrilloLogWindow::impl final
{
public:
explicit impl () = default;
FormatProxyModel format_model_;
Ui::CabrilloLogWindow ui_;
};
CabrilloLogWindow::CabrilloLogWindow (QSettings * settings, Configuration const * configuration CabrilloLogWindow::CabrilloLogWindow (QSettings * settings, Configuration const * configuration
, QAbstractItemModel * cabrillo_log_model, QWidget * parent) , QAbstractItemModel * cabrillo_log_model, QWidget * parent)
: QWidget {parent} : AbstractLogWindow {"Cabrillo Log Window", settings, configuration, parent}
, settings_ {settings}
, configuration_ {configuration}
, ui_ {new Ui::CabrilloLogWindow}
{ {
cabrillo_log_model_.setSourceModel (cabrillo_log_model);
setWindowTitle (QApplication::applicationName () + " - Cabrillo Log"); setWindowTitle (QApplication::applicationName () + " - Cabrillo Log");
ui_->setupUi (this); m_->ui_.setupUi (this);
read_settings (); m_->format_model_.setSourceModel (cabrillo_log_model);
change_font (configuration_->decoded_text_font ()); set_log_model (&m_->format_model_);
ui_->log_table_view->setModel (&cabrillo_log_model_); set_log_view (m_->ui_.log_table_view);
ui_->log_table_view->setColumnHidden (0, true); m_->ui_.log_table_view->setItemDelegateForColumn (2, new DateTimeAsSecsSinceEpochDelegate {this});
ui_->log_table_view->setItemDelegateForColumn (2, new DateTimeAsSecsSinceEpochDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (3, new CallsignDelegate {this});
ui_->log_table_view->setItemDelegateForColumn (3, new CallsignDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), cabrillo_log_model, 0, 6, this});
ui_->log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration_->bands (), &cabrillo_log_model_, 0, 6, this}); m_->ui_.log_table_view->horizontalHeader ()->moveSection (6, 1); // band to first column
ui_->log_table_view->setSelectionMode (QTableView::SingleSelection);
auto horizontal_header = ui_->log_table_view->horizontalHeader ();
horizontal_header->setStretchLastSection (true);
horizontal_header->setSectionResizeMode (QHeaderView::ResizeToContents);
horizontal_header->setSectionsMovable (true);
horizontal_header->moveSection (6, 1); // band to first column
ui_->log_table_view->scrollToBottom ();
// ensure view scrolls to latest new row
connect (&cabrillo_log_model_, &QAbstractItemModel::rowsInserted, [this] (QModelIndex const& /*parent*/, int /*first*/, int /*last*/) {
ui_->log_table_view->scrollToBottom ();
});
} }
CabrilloLogWindow::~CabrilloLogWindow () CabrilloLogWindow::~CabrilloLogWindow ()
{ {
write_settings ();
}
void CabrilloLogWindow::read_settings ()
{
SettingsGroup g {settings_, "Cabrillo Log Window"};
restoreGeometry (settings_->value ("window/geometery").toByteArray ());
}
void CabrilloLogWindow::write_settings () const
{
SettingsGroup g {settings_, "Cabrillo Log Window"};
settings_->setValue ("window/geometery", saveGeometry ());
}
void CabrilloLogWindow::change_font (QFont const& font)
{
// ui_->log_table_view->setFont (font);
// ui_->log_table_view->horizontalHeader ()->setFont (font);
// ui_->log_table_view->verticalHeader ()->setFont (font);
cabrillo_log_model_.set_font (font);
} }

View File

@ -1,39 +1,25 @@
#ifndef CABRILLO_LOG_WINDOW_HPP_ #ifndef CABRILLO_LOG_WINDOW_HPP_
#define CABRILLO_LOG_WINDOW_HPP_ #define CABRILLO_LOG_WINDOW_HPP_
#include <QWidget> #include "AbstractLogWindow.hpp"
#include <QScopedPointer> #include "pimpl_h.hpp"
#include <QIdentityProxyModel>
#include "models/FontOverrideModel.hpp"
class QSettings; class QSettings;
class Configuration; class Configuration;
class QFont; class QFont;
class QDateTime;
class QAbstractItemModel; class QAbstractItemModel;
namespace Ui
{
class CabrilloLogWindow;
}
class CabrilloLogWindow final class CabrilloLogWindow final
: public QWidget : public AbstractLogWindow
{ {
public: public:
explicit CabrilloLogWindow (QSettings *, Configuration const *, QAbstractItemModel * cabrillo_log_model explicit CabrilloLogWindow (QSettings *, Configuration const *, QAbstractItemModel * cabrillo_log_model
, QWidget * parent = nullptr); , QWidget * parent = nullptr);
~CabrilloLogWindow (); ~CabrilloLogWindow ();
void change_font (QFont const&);
private: private:
void read_settings (); class impl;
void write_settings () const; pimpl<impl> m_;
QSettings * settings_;
Configuration const * configuration_;
FontOverrideModel cabrillo_log_model_;
QScopedPointer<Ui::CabrilloLogWindow> ui_;
}; };
#endif #endif

View File

@ -2,12 +2,30 @@
<ui version="4.0"> <ui version="4.0">
<class>CabrilloLogWindow</class> <class>CabrilloLogWindow</class>
<widget class="QWidget" name="CabrilloLogWindow"> <widget class="QWidget" name="CabrilloLogWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>274</width>
<height>210</height>
</rect>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Contest Log</string> <string>Contest Log</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QTableView" name="log_table_view"/> <widget class="QTableView" name="log_table_view">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

View File

@ -1,12 +1,6 @@
#include "FoxLogWindow.hpp" #include "FoxLogWindow.hpp"
#include <QSettings>
#include <QApplication> #include <QApplication>
#include <QDateTime>
#include <QDir>
#include <QStyledItemDelegate>
#include <QDateTimeEdit>
#include <QPainter>
#include "SettingsGroup.hpp" #include "SettingsGroup.hpp"
#include "Configuration.hpp" #include "Configuration.hpp"
@ -15,82 +9,50 @@
#include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp" #include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp"
#include "item_delegates/CallsignDelegate.hpp" #include "item_delegates/CallsignDelegate.hpp"
#include "item_delegates/MaidenheadLocatorDelegate.hpp" #include "item_delegates/MaidenheadLocatorDelegate.hpp"
#include "widgets/MessageBox.hpp" #include "pimpl_impl.hpp"
#include "qt_helpers.hpp"
#include "ui_FoxLogWindow.h" #include "ui_FoxLogWindow.h"
class FoxLogWindow::impl final
{
public:
explicit impl () = default;
Ui::FoxLogWindow ui_;
};
FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configuration FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configuration
, QAbstractItemModel * fox_log_model, QWidget * parent) , QAbstractItemModel * fox_log_model, QWidget * parent)
: QWidget {parent} : AbstractLogWindow {"Fox Log Window", settings, configuration, parent}
, settings_ {settings}
, configuration_ {configuration}
, ui_ {new Ui::FoxLogWindow}
{ {
fox_log_model_.setSourceModel (fox_log_model);
setWindowTitle (QApplication::applicationName () + " - Fox Log"); setWindowTitle (QApplication::applicationName () + " - Fox Log");
ui_->setupUi (this); m_->ui_.setupUi (this);
read_settings (); set_log_model (fox_log_model);
change_font (configuration_->decoded_text_font ()); set_log_view (m_->ui_.log_table_view);
ui_->log_table_view->setModel (&fox_log_model_); m_->ui_.log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this});
ui_->log_table_view->setColumnHidden (0, true); m_->ui_.log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this});
ui_->log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (3, new MaidenheadLocatorDelegate {this});
ui_->log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), fox_log_model, 0, 6, this});
ui_->log_table_view->setItemDelegateForColumn (3, new MaidenheadLocatorDelegate {this}); m_->ui_.log_table_view->horizontalHeader ()->moveSection (6, 1); // move band to first column
ui_->log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration_->bands (), &fox_log_model_, 0, 6, this}); m_->ui_.rate_label->setNum (0);
ui_->log_table_view->setSelectionMode (QTableView::SingleSelection); m_->ui_.queued_label->setNum (0);
auto horizontal_header = ui_->log_table_view->horizontalHeader (); m_->ui_.callers_label->setNum (0);
horizontal_header->setStretchLastSection (true);
horizontal_header->setSectionResizeMode (QHeaderView::ResizeToContents);
horizontal_header->setSectionsMovable (true);
horizontal_header->moveSection (6, 1); // move band to first column
ui_->rate_label->setNum (0);
ui_->queued_label->setNum (0);
ui_->callers_label->setNum (0);
ui_->log_table_view->scrollToBottom ();
// ensure view scrolls to latest new row
connect (&fox_log_model_, &QAbstractItemModel::rowsInserted, [this] (QModelIndex const& /*parent*/, int /*first*/, int /*last*/) {
ui_->log_table_view->scrollToBottom ();
});
} }
FoxLogWindow::~FoxLogWindow () FoxLogWindow::~FoxLogWindow ()
{ {
write_settings ();
}
void FoxLogWindow::read_settings ()
{
SettingsGroup g {settings_, "Fox Log Window"};
restoreGeometry (settings_->value ("window/geometery").toByteArray ());
}
void FoxLogWindow::write_settings () const
{
SettingsGroup g {settings_, "Fox Log Window"};
settings_->setValue ("window/geometery", saveGeometry ());
}
void FoxLogWindow::change_font (QFont const& font)
{
// ui_->log_table_view->setFont (font);
// ui_->log_table_view->horizontalHeader ()->setFont (font);
// ui_->log_table_view->verticalHeader ()->setFont (font);
fox_log_model_.set_font (font);
} }
void FoxLogWindow::callers (int n) void FoxLogWindow::callers (int n)
{ {
ui_->callers_label->setNum (n); m_->ui_.callers_label->setNum (n);
} }
void FoxLogWindow::queued (int n) void FoxLogWindow::queued (int n)
{ {
ui_->queued_label->setNum (n); m_->ui_.queued_label->setNum (n);
} }
void FoxLogWindow::rate (int n) void FoxLogWindow::rate (int n)
{ {
ui_->rate_label->setNum (n); m_->ui_.rate_label->setNum (n);
} }

View File

@ -1,42 +1,29 @@
#ifndef FOX_LOG_WINDOW_HPP_ #ifndef FOX_LOG_WINDOW_HPP_
#define FOX_LOG_WINDOW_HPP_ #define FOX_LOG_WINDOW_HPP_
#include <QWidget> #include "AbstractLogWindow.hpp"
#include <QScopedPointer> #include "pimpl_h.hpp"
#include <QIdentityProxyModel>
#include "models/FontOverrideModel.hpp"
class QSettings; class QSettings;
class Configuration; class Configuration;
class QFont; class QFont;
class QDateTime;
class QAbstractItemModel; class QAbstractItemModel;
namespace Ui
{
class FoxLogWindow;
}
class FoxLogWindow final class FoxLogWindow final
: public QWidget : public AbstractLogWindow
{ {
public: public:
explicit FoxLogWindow (QSettings *, Configuration const *, QAbstractItemModel * fox_log_model explicit FoxLogWindow (QSettings *, Configuration const *, QAbstractItemModel * fox_log_model
, QWidget * parent = nullptr); , QWidget * parent = nullptr);
~FoxLogWindow (); ~FoxLogWindow ();
void change_font (QFont const&);
void callers (int); void callers (int);
void queued (int); void queued (int);
void rate (int); void rate (int);
private: private:
void read_settings (); class impl;
void write_settings () const; pimpl<impl> m_;
QSettings * settings_;
Configuration const * configuration_;
FontOverrideModel fox_log_model_;
QScopedPointer<Ui::FoxLogWindow> ui_;
}; };
#endif #endif

View File

@ -2,12 +2,30 @@
<ui version="4.0"> <ui version="4.0">
<class>FoxLogWindow</class> <class>FoxLogWindow</class>
<widget class="QWidget" name="FoxLogWindow"> <widget class="QWidget" name="FoxLogWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>331</width>
<height>238</height>
</rect>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Fox Log</string> <string>Fox Log</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QTableView" name="log_table_view"/> <widget class="QTableView" name="log_table_view">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">

View File

@ -10,6 +10,7 @@
#include "MessageBox.hpp" #include "MessageBox.hpp"
#include "Configuration.hpp" #include "Configuration.hpp"
#include "models/Bands.hpp" #include "models/Bands.hpp"
#include "models/CabrilloLog.hpp"
#include "validators/MaidenheadLocatorValidator.hpp" #include "validators/MaidenheadLocatorValidator.hpp"
#include "ui_logqso.h" #include "ui_logqso.h"
@ -57,11 +58,10 @@ void LogQSO::storeSettings () const
void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode, void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode,
QString const& rptSent, QString const& rptRcvd, QString const& rptSent, QString const& rptRcvd,
QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff,
Radio::Frequency dialFreq, bool noSuffix, QString xSent, QString xRcvd) Radio::Frequency dialFreq, bool noSuffix, QString xSent, QString xRcvd,
CabrilloLog * cabrillo_log)
{ {
if(!isHidden()) return; if(!isHidden()) return;
m_xSent=xSent;
m_xRcvd=xRcvd;
ui->call->setText(hisCall); ui->call->setText(hisCall);
ui->grid->setText(hisGrid); ui->grid->setText(hisGrid);
ui->name->setText(""); ui->name->setText("");
@ -87,15 +87,21 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
m_myGrid=m_config->my_grid(); m_myGrid=m_config->my_grid();
ui->band->setText (m_config->bands ()->find (dialFreq)); ui->band->setText (m_config->bands ()->find (dialFreq));
ui->loggedOperator->setText(m_config->opCall()); ui->loggedOperator->setText(m_config->opCall());
ui->exchSent->setText(m_xSent); ui->exchSent->setText (xSent);
ui->exchRcvd->setText(m_xRcvd); ui->exchRcvd->setText (xRcvd);
m_cabrilloLog = cabrillo_log;
using SpOp = Configuration::SpecialOperatingActivity; using SpOp = Configuration::SpecialOperatingActivity;
if( SpOp::FOX == m_config->special_op_id() or auto special_op = m_config->special_op_id ();
(m_config->autoLog() and SpOp::NONE < m_config->special_op_id() and if (SpOp::FOX == special_op
m_xSent!="" and m_xRcvd!="")) { || (m_config->autoLog ()
&& SpOp::NONE < special_op && special_op < SpOp::FOX))
{
// allow auto logging in Fox mode and contests
accept(); accept();
} else { }
else
{
show(); show();
} }
} }
@ -120,6 +126,29 @@ void LogQSO::accept()
QString strDialFreq(QString::number(m_dialFreq / 1.e6,'f',6)); QString strDialFreq(QString::number(m_dialFreq / 1.e6,'f',6));
operator_call = ui->loggedOperator->text(); operator_call = ui->loggedOperator->text();
// validate
using SpOp = Configuration::SpecialOperatingActivity;
auto special_op = m_config->special_op_id ();
if (SpOp::NONE < special_op && special_op < SpOp::FOX)
{
if (ui->exchSent->text ().isEmpty () || ui->exchRcvd->text ().isEmpty ())
{
show ();
MessageBox::warning_message (this, tr ("Invalid QSO Data"),
tr ("Check exchange sent and received"));
return; // without accepting
}
if (!m_cabrilloLog->add_QSO (m_dialFreq, QDateTime::currentDateTimeUtc (), hisCall,
ui->exchSent->text (), ui->exchRcvd->text ()))
{
show ();
MessageBox::warning_message (this, tr ("Invalid QSO Data"),
tr ("Check all fields"));
return; // without accepting
}
}
//Log this QSO to file "wsjtx.log" //Log this QSO to file "wsjtx.log"
static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx.log")}; static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx.log")};
if(!f.open(QIODevice::Text | QIODevice::Append)) { if(!f.open(QIODevice::Text | QIODevice::Append)) {
@ -169,8 +198,8 @@ void LogQSO::accept()
, m_myGrid , m_myGrid
, m_txPower , m_txPower
, operator_call , operator_call
, m_xSent , ui->exchSent->text ()
, m_xRcvd)); , ui->exchRcvd->text ()));
QDialog::accept(); QDialog::accept();
} }

View File

@ -17,6 +17,7 @@ namespace Ui {
class QSettings; class QSettings;
class Configuration; class Configuration;
class QByteArray; class QByteArray;
class CabrilloLog;
class LogQSO : public QDialog class LogQSO : public QDialog
{ {
@ -28,7 +29,7 @@ public:
void initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode, void initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode,
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
QDateTime const& dateTimeOff, Radio::Frequency dialFreq, QDateTime const& dateTimeOff, Radio::Frequency dialFreq,
bool noSuffix, QString xSent, QString xRcvd); bool noSuffix, QString xSent, QString xRcvd, CabrilloLog *);
public slots: public slots:
void accept(); void accept();
@ -56,10 +57,9 @@ private:
Radio::Frequency m_dialFreq; Radio::Frequency m_dialFreq;
QString m_myCall; QString m_myCall;
QString m_myGrid; QString m_myGrid;
QString m_xSent;
QString m_xRcvd;
QDateTime m_dateTimeOn; QDateTime m_dateTimeOn;
QDateTime m_dateTimeOff; QDateTime m_dateTimeOff;
CabrilloLog * m_cabrilloLog;
}; };
#endif // LogQSO_H #endif // LogQSO_H

View File

@ -1228,10 +1228,10 @@ void MainWindow::setDecodedTextFont (QFont const& font)
m_msgAvgWidget->changeFont (font); m_msgAvgWidget->changeFont (font);
} }
if (m_foxLogWindow) { if (m_foxLogWindow) {
m_foxLogWindow->change_font (font); m_foxLogWindow->set_log_view_font (font);
} }
if (m_contestLogWindow) { if (m_contestLogWindow) {
m_contestLogWindow->change_font (font); m_contestLogWindow->set_log_view_font (font);
} }
updateGeometry (); updateGeometry ();
} }
@ -5331,9 +5331,16 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
default: break; default: break;
} }
using SpOp = Configuration::SpecialOperatingActivity;
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_logDlg->initLogQSO (m_hisCall, grid, m_modeTx, m_rptSent, m_rptRcvd,
m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal + m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal +
ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd); ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd,
m_cabrilloLog.data ());
} }
void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call, QString const& grid void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call, QString const& grid
@ -5350,15 +5357,6 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
tr ("Cannot open \"%1\"").arg (m_logBook.path ())); tr ("Cannot open \"%1\"").arg (m_logBook.path ()));
} }
if (SpecOp::NONE < m_config.special_op_id() && SpecOp::FOX > m_config.special_op_id()) {
if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config});
m_cabrilloLog->add_QSO (m_freqNominal, QDateTime::currentDateTimeUtc (), m_hisCall, m_xSent, m_xRcvd);
m_xSent="";
m_xRcvd="";
ui->sbSerialNumber->setValue (ui->sbSerialNumber->value () + 1);
}
m_messageClient->qso_logged (QSO_date_off, call, grid, dial_freq, mode, rpt_sent, rpt_received m_messageClient->qso_logged (QSO_date_off, call, grid, dial_freq, mode, rpt_sent, rpt_received
, tx_power, comments, name, QSO_date_on, operator_call, my_call, my_grid); , tx_power, comments, name, QSO_date_on, operator_call, my_call, my_grid);
m_messageClient->logged_ADIF (ADIF); m_messageClient->logged_ADIF (ADIF);
@ -5378,6 +5376,15 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call,
if (m_config.clear_DX () and SpecOp::HOUND != m_config.special_op_id()) clearDX (); if (m_config.clear_DX () and SpecOp::HOUND != m_config.special_op_id()) clearDX ();
m_dateTimeQSOOn = QDateTime {}; m_dateTimeQSOOn = QDateTime {};
using SpOp = Configuration::SpecialOperatingActivity;
auto special_op = m_config.special_op_id ();
if (SpecOp::NONE < special_op && special_op < SpecOp::FOX)
{
ui->sbSerialNumber->setValue (ui->sbSerialNumber->value () + 1);
}
m_xSent.clear ();
m_xRcvd.clear ();
} }
qint64 MainWindow::nWidgets(QString t) qint64 MainWindow::nWidgets(QString t)
@ -6125,11 +6132,12 @@ void MainWindow::on_reset_fox_log_action_triggered ()
void MainWindow::on_reset_cabrillo_log_action_triggered () void MainWindow::on_reset_cabrillo_log_action_triggered ()
{ {
if (MessageBox::Yes == MessageBox::query_message(this, tr("Confirm Erase"), if (MessageBox::Yes == MessageBox::query_message (this, tr ("Confirm Reset"),
tr("Are you sure you want to erase file cabrillo.log" tr ("Are you sure you want to erase your contest log?"),
" and start a new Cabrillo log?"))) tr ("Doing this will remove all QSO records for the current contest. "
"They will be kept in the ADIF log file but will not be available "
"for export in your Cabrillo log.")))
{ {
QFile {m_config.writeable_data_dir ().absoluteFilePath ("cabrillo.log")}.remove ();
ui->sbSerialNumber->setValue (1); ui->sbSerialNumber->setValue (1);
if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config}); if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config});
m_cabrilloLog->reset (); m_cabrilloLog->reset ();

View File

@ -7,7 +7,8 @@ SOURCES += \
widgets/echoplot.cpp widgets/echograph.cpp widgets/fastgraph.cpp \ widgets/echoplot.cpp widgets/echograph.cpp widgets/fastgraph.cpp \
widgets/fastplot.cpp widgets/MessageBox.cpp \ widgets/fastplot.cpp widgets/MessageBox.cpp \
widgets/colorhighlighting.cpp widgets/ExportCabrillo.cpp \ widgets/colorhighlighting.cpp widgets/ExportCabrillo.cpp \
widgets/CabrilloLogWindow.cpp widgets/AbstractLogWindow.cpp \
widgets/FoxLogWindow.cpp widgets/CabrilloLogWindow.cpp
HEADERS += \ HEADERS += \
widgets/mainwindow.h widgets/plotter.h \ widgets/mainwindow.h widgets/plotter.h \
@ -17,8 +18,8 @@ HEADERS += \
widgets/meterwidget.h widgets/messageaveraging.h \ widgets/meterwidget.h widgets/messageaveraging.h \
widgets/echoplot.h widgets/echograph.h widgets/fastgraph.h \ widgets/echoplot.h widgets/echograph.h widgets/fastgraph.h \
widgets/fastplot.h widgets/MessageBox.hpp widgets/colorhighlighting.h \ widgets/fastplot.h widgets/MessageBox.hpp widgets/colorhighlighting.h \
widgets/ExportCabrillo.h \ widgets/ExportCabrillo.h widgets/AbstractLogWindow.hpp \
widgets/CabrilloLogWindow.cpp widgets/FoxLogWindow.cpp widgets/CabrilloLogWindow.cpp
FORMS += \ FORMS += \
widgets/mainwindow.ui widgets/about.ui \ widgets/mainwindow.ui widgets/about.ui \
@ -26,5 +27,4 @@ FORMS += \
widgets/logqso.ui widgets/messageaveraging.ui \ widgets/logqso.ui widgets/messageaveraging.ui \
widgets/echograph.ui widgets/fastgraph.ui \ widgets/echograph.ui widgets/fastgraph.ui \
widgets/colorhighlighting.ui widgets/ExportCabrillo.ui \ widgets/colorhighlighting.ui widgets/ExportCabrillo.ui \
widgets/FoxLogWindow.ui \ widgets/FoxLogWindow.ui widgets/CabrilloLogWindow.ui
widgets/CabrilloLogWindow.ui