mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-18 10:01:57 -05:00
b8e4517718
This include inverting the order of table view rows so the newest is at the top, without that the Qt MVC interactions when using a database table based model is too slow and complex to manage. The table views now have sort by column capability in the normal way (click column header to reverse sort order) for timely logging and non-disruption of Tx starts the log view should be sorted in descending time order and scrolled to the last row added. Without that Fox and contest logging will work but serious delays may be invoked that disrupt operation.
145 lines
4.1 KiB
C++
145 lines
4.1 KiB
C++
#include "FoxLog.hpp"
|
|
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
#include <QString>
|
|
#include <QDateTime>
|
|
#include <QSqlDatabase>
|
|
#include <QSqlTableModel>
|
|
#include <QSqlRecord>
|
|
#include <QSqlError>
|
|
#include <QSqlQuery>
|
|
#include <QDebug>
|
|
#include "qt_db_helpers.hpp"
|
|
#include "pimpl_impl.hpp"
|
|
|
|
class FoxLog::impl final
|
|
: public QSqlTableModel
|
|
{
|
|
public:
|
|
impl ();
|
|
|
|
QSqlQuery mutable dupe_query_;
|
|
};
|
|
|
|
FoxLog::impl::impl ()
|
|
{
|
|
if (!database ().tables ().contains ("fox_log"))
|
|
{
|
|
QSqlQuery query;
|
|
SQL_error_check (query, static_cast<bool (QSqlQuery::*) (QString const&)> (&QSqlQuery::exec),
|
|
"CREATE TABLE fox_log ("
|
|
" id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
|
|
" \"when\" DATETIME NOT NULL,"
|
|
" call VARCHAR(20) NOT NULL,"
|
|
" grid VARCHAR(4),"
|
|
" report_sent VARCHAR(3),"
|
|
" report_rcvd VARCHAR(3),"
|
|
" band VARCHAR(6) NOT NULL,"
|
|
" CONSTRAINT no_dupes UNIQUE (call, band)"
|
|
")");
|
|
}
|
|
|
|
SQL_error_check (dupe_query_, &QSqlQuery::prepare,
|
|
"SELECT COUNT(*) FROM fox_log WHERE call = :call AND band = :band");
|
|
|
|
setEditStrategy (QSqlTableModel::OnFieldChange);
|
|
setTable ("fox_log");
|
|
setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
|
|
setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call"));
|
|
setHeaderData (fieldIndex ("grid"), Qt::Horizontal, tr ("Grid"));
|
|
setHeaderData (fieldIndex ("report_sent"), Qt::Horizontal, tr ("Sent"));
|
|
setHeaderData (fieldIndex ("report_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);
|
|
}
|
|
|
|
FoxLog::FoxLog ()
|
|
{
|
|
}
|
|
|
|
FoxLog::~FoxLog ()
|
|
{
|
|
}
|
|
|
|
QSqlTableModel * FoxLog::model ()
|
|
{
|
|
return &*m_;
|
|
}
|
|
|
|
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 FoxLog::add_QSO (QDateTime const& when, QString const& call, QString const& grid
|
|
, QString const& report_sent, QString const& report_received
|
|
, QString const& band)
|
|
{
|
|
auto record = m_->record ();
|
|
if (!when.isNull ())
|
|
{
|
|
record.setValue ("when", when.toMSecsSinceEpoch () / 1000);
|
|
}
|
|
else
|
|
{
|
|
record.setNull ("when");
|
|
}
|
|
set_value_maybe_null (record, "call", call);
|
|
set_value_maybe_null (record, "grid", grid);
|
|
set_value_maybe_null (record, "report_sent", report_sent);
|
|
set_value_maybe_null (record, "report_rcvd", report_received);
|
|
set_value_maybe_null (record, "band", band);
|
|
if (m_->isDirty ())
|
|
{
|
|
m_->revert (); // discard any uncommitted changes
|
|
}
|
|
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
|
|
ConditionalTransaction transaction {*m_};
|
|
auto ok = m_->insertRecord (-1, record);
|
|
if (ok)
|
|
{
|
|
ok = transaction.submit (false);
|
|
}
|
|
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
|
return ok;
|
|
}
|
|
|
|
bool FoxLog::dupe (QString const& call, QString const& band) const
|
|
{
|
|
m_->dupe_query_.bindValue (":call", call);
|
|
m_->dupe_query_.bindValue (":band", band);
|
|
SQL_error_check (m_->dupe_query_, static_cast<bool (QSqlQuery::*) ()> (&QSqlQuery::exec));
|
|
m_->dupe_query_.next ();
|
|
return m_->dupe_query_.value (0).toInt ();
|
|
}
|
|
|
|
void FoxLog::reset ()
|
|
{
|
|
if (m_->rowCount ())
|
|
{
|
|
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
|
|
ConditionalTransaction transaction {*m_};
|
|
SQL_error_check (*m_, &QSqlTableModel::removeRows, 0, m_->rowCount (), QModelIndex {});
|
|
transaction.submit ();
|
|
m_->select (); // to refresh views
|
|
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
|
}
|
|
}
|