mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-21 11:31:51 -05:00
Improve performance of Fox and contest log view windows
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.
This commit is contained in:
parent
1c48b39b58
commit
b8e4517718
@ -28,3 +28,4 @@ void CallsignDelegate::setModelData (QWidget * editor, QAbstractItemModel * mode
|
||||
{
|
||||
model->setData (index, static_cast<QLineEdit *> (editor)->text (), Qt::EditRole);
|
||||
}
|
||||
|
||||
|
9
main.cpp
9
main.cpp
@ -6,6 +6,8 @@
|
||||
#include <locale.h>
|
||||
#include <fftw3.h>
|
||||
|
||||
#include <QSharedMemory>
|
||||
#include <QTemporaryFile>
|
||||
#include <QDateTime>
|
||||
#include <QApplication>
|
||||
#include <QRegularExpression>
|
||||
@ -21,6 +23,7 @@
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlError>
|
||||
|
||||
#include "revision_utils.hpp"
|
||||
@ -288,6 +291,12 @@ int main(int argc, char *argv[])
|
||||
throw std::runtime_error {("Database Error: " + db.lastError ().text ()).toStdString ()};
|
||||
}
|
||||
|
||||
// better performance traded for a risk of d/b corruption
|
||||
// on system crash or application crash
|
||||
// db.exec ("PRAGMA synchronous=OFF"); // system crash risk
|
||||
// db.exec ("PRAGMA journal_mode=MEMORY"); // application crash risk
|
||||
db.exec ("PRAGMA locking_mode=EXCLUSIVE");
|
||||
|
||||
int result;
|
||||
do
|
||||
{
|
||||
|
@ -59,6 +59,12 @@ CabrilloLog::impl::impl (Configuration const * configuration)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -113,11 +119,11 @@ bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString c
|
||||
{
|
||||
m_->revert (); // discard any uncommitted changes
|
||||
}
|
||||
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
|
||||
ConditionalTransaction transaction {*m_};
|
||||
auto ok = m_->insertRecord (-1, record);
|
||||
if (ok)
|
||||
{
|
||||
m_->select (); // to refresh views
|
||||
}
|
||||
transaction.submit ();
|
||||
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,12 @@ FoxLog::impl::impl ()
|
||||
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);
|
||||
}
|
||||
|
||||
@ -104,11 +110,14 @@ bool FoxLog::add_QSO (QDateTime const& when, QString const& call, QString const&
|
||||
{
|
||||
m_->revert (); // discard any uncommitted changes
|
||||
}
|
||||
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
|
||||
ConditionalTransaction transaction {*m_};
|
||||
auto ok = m_->insertRecord (-1, record);
|
||||
if (ok)
|
||||
{
|
||||
m_->select (); // to refresh views
|
||||
ok = transaction.submit (false);
|
||||
}
|
||||
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -84,13 +84,23 @@ AbstractLogWindow::AbstractLogWindow (QString const& settings_key, QSettings * s
|
||||
: QWidget {parent}
|
||||
, m_ {this, settings_key, settings, configuration}
|
||||
{
|
||||
// ensure view scrolls to latest new row
|
||||
connect (&m_->model_, &QAbstractItemModel::rowsInserted, this, [this] (QModelIndex const& parent, int /*first*/, int last) {
|
||||
// note col 0 is hidden so use col 1
|
||||
// queued connection required otherwise row may not be available
|
||||
// in time
|
||||
if (m_->log_view_) m_->log_view_->scrollTo (m_->log_view_->model ()->index (last, 1, parent));
|
||||
}, Qt::QueuedConnection);
|
||||
// this attempt to scroll to the last new record doesn't work, some
|
||||
// sort of issue with model indexes and optimized DB fetches. For
|
||||
// now sorting by the same column and direction as the underlying DB
|
||||
// select and that DB select being in descending order so new rows
|
||||
// at the end appear at view row 0 gets the job done
|
||||
|
||||
// // ensure view scrolls to latest new row
|
||||
// connect (&m_->model_, &QAbstractItemModel::rowsInserted, this, [this] (QModelIndex const& parent, int first, int last) {
|
||||
// // note col 0 is hidden so use col 1
|
||||
// // queued connection required otherwise row may not be available
|
||||
// // in time
|
||||
// auto index = m_->model_.index (last, 1, parent);
|
||||
// if (m_->log_view_)
|
||||
// {
|
||||
// m_->log_view_->scrollTo (index);
|
||||
// }
|
||||
// }, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
AbstractLogWindow::~AbstractLogWindow ()
|
||||
@ -105,24 +115,27 @@ void AbstractLogWindow::set_log_view (QTableView * log_view)
|
||||
SettingsGroup g {m_->settings_, m_->settings_key_};
|
||||
restoreGeometry (m_->settings_->value ("window/geometry").toByteArray ());
|
||||
m_->log_view_ = log_view;
|
||||
m_->log_view_->setContextMenuPolicy (Qt::ActionsContextMenu);
|
||||
m_->log_view_->setAlternatingRowColors (true);
|
||||
m_->log_view_->setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||
m_->log_view_->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||
m_->log_view_->setVerticalScrollMode (QAbstractItemView::ScrollPerPixel);
|
||||
m_->model_.setSourceModel (m_->log_view_->model ());
|
||||
m_->log_view_->setModel (&m_->model_);
|
||||
m_->log_view_->setColumnHidden (0, true);
|
||||
set_log_view_font (m_->configuration_->decoded_text_font ());
|
||||
log_view->setSortingEnabled (true);
|
||||
log_view->setContextMenuPolicy (Qt::ActionsContextMenu);
|
||||
log_view->setAlternatingRowColors (true);
|
||||
log_view->setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||
log_view->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||
log_view->setVerticalScrollMode (QAbstractItemView::ScrollPerPixel);
|
||||
m_->model_.setSourceModel (log_view->model ());
|
||||
log_view->setModel (&m_->model_);
|
||||
log_view->setColumnHidden (0, true);
|
||||
auto horizontal_header = log_view->horizontalHeader ();
|
||||
horizontal_header->setResizeContentsPrecision (0); // visible region only
|
||||
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 ();
|
||||
auto vertical_header = log_view->horizontalHeader ();
|
||||
vertical_header->setResizeContentsPrecision (0); // visible region only
|
||||
vertical_header->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||
|
||||
// actions
|
||||
auto delete_action = new QAction {tr ("&Delete ..."), m_->log_view_};
|
||||
m_->log_view_->insertAction (nullptr, delete_action);
|
||||
auto delete_action = new QAction {tr ("&Delete ..."), log_view};
|
||||
log_view->insertAction (nullptr, delete_action);
|
||||
connect (delete_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||
m_->delete_QSOs ();
|
||||
});
|
||||
@ -130,8 +143,8 @@ void AbstractLogWindow::set_log_view (QTableView * log_view)
|
||||
|
||||
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_->log_view_->setFont (font);
|
||||
m_->log_view_->horizontalHeader ()->setFont (font);
|
||||
m_->log_view_->verticalHeader ()->setFont (font);
|
||||
m_->model_.set_font (font);
|
||||
}
|
||||
|
@ -67,7 +67,8 @@ CabrilloLogWindow::CabrilloLogWindow (QSettings * settings, Configuration const
|
||||
m_->ui_.log_table_view->setItemDelegateForColumn (2, new DateTimeAsSecsSinceEpochDelegate {this});
|
||||
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->horizontalHeader ()->moveSection (6, 1); // band to first column
|
||||
auto h_header = m_->ui_.log_table_view->horizontalHeader ();
|
||||
h_header->moveSection (6, 1); // band to first column
|
||||
}
|
||||
|
||||
CabrilloLogWindow::~CabrilloLogWindow ()
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "echoplot.h"
|
||||
#include "commons.h"
|
||||
#include <math.h>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QDebug>
|
||||
#include "moc_echoplot.cpp"
|
||||
|
||||
|
@ -4,17 +4,20 @@
|
||||
// For more details see the accompanying file LICENSE_WHEATLEY.TXT
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EPLOTTER_H
|
||||
#define EPLOTTER_H
|
||||
#ifndef EPLOTTER_H_
|
||||
#define EPLOTTER_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QFrame>
|
||||
#include <QSize>
|
||||
#include <QImage>
|
||||
#include <cstring>
|
||||
#include <QString>
|
||||
|
||||
#define VERT_DIVS 7 //specify grid screen divisions
|
||||
#define HORZ_DIVS 20
|
||||
|
||||
class QPaintEvent;
|
||||
class QResizeEvent;
|
||||
|
||||
class EPlotter : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "commons.h"
|
||||
#include <QSettings>
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
#include "fastplot.h"
|
||||
#include "SettingsGroup.hpp"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef FASTGRAPH_H
|
||||
#define FASTGRAPH_H
|
||||
#ifndef FASTGRAPH_H_
|
||||
#define FASTGRAPH_H_
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
@ -9,6 +9,8 @@ namespace Ui {
|
||||
}
|
||||
|
||||
class QSettings;
|
||||
class QCloseEvent;
|
||||
class QKeyEvent;
|
||||
|
||||
class FastGraph : public QDialog
|
||||
{
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include "fastplot.h"
|
||||
#include "commons.h"
|
||||
#include <math.h>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QMouseEvent>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include "moc_fastplot.cpp"
|
||||
|
||||
|
@ -4,13 +4,16 @@
|
||||
// For more details see the accompanying file LICENSE_WHEATLEY.TXT
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FPLOTTER_H
|
||||
#define FPLOTTER_H
|
||||
#ifndef FPLOTTER_H_
|
||||
#define FPLOTTER_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QFrame>
|
||||
#include <QImage>
|
||||
#include <cstring>
|
||||
#include <QString>
|
||||
#include <QPixmap>
|
||||
#include <QVector>
|
||||
#include <QColor>
|
||||
|
||||
class QMouseEvent;
|
||||
|
||||
class FPlotter : public QFrame
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef LogQSO_H
|
||||
#define LogQSO_H
|
||||
#ifndef LogQSO_H_
|
||||
#define LogQSO_H_
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
|
@ -1,12 +1,20 @@
|
||||
//---------------------------------------------------------- MainWindow
|
||||
#include "mainwindow.h"
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <fftw3.h>
|
||||
#include <QStringListModel>
|
||||
#include <QSettings>
|
||||
#include <QKeyEvent>
|
||||
#include <QSharedMemory>
|
||||
#include <QFileDialog>
|
||||
#include <QTextBlock>
|
||||
#include <QProgressBar>
|
||||
#include <QLineEdit>
|
||||
#include <QRegExpValidator>
|
||||
#include <QRegExp>
|
||||
@ -3100,7 +3108,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
if(w.at(0)==m_config.my_callsign() or w.at(0)==Radio::base_callsign(m_config.my_callsign())) {
|
||||
//### Check for ui->dxCallEntry->text()==foxCall before logging! ###
|
||||
ui->stopTxButton->click ();
|
||||
on_logQSOButton_clicked();
|
||||
logQSOTimer.start(0);
|
||||
}
|
||||
if((w.at(2)==m_config.my_callsign() or w.at(2)==Radio::base_callsign(m_config.my_callsign()))
|
||||
and ui->tx3->text().length()>0) {
|
||||
@ -3118,7 +3126,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
ui->tx3->text().length()>0) {
|
||||
if(w.at(2)=="RR73") {
|
||||
ui->stopTxButton->click ();
|
||||
on_logQSOButton_clicked();
|
||||
logQSOTimer.start(0);
|
||||
} else {
|
||||
if(w.at(1)==Radio::base_callsign(ui->dxCallEntry->text()) and
|
||||
(w.at(2).mid(0,1)=="+" or w.at(2).mid(0,1)=="-")) {
|
||||
@ -4453,7 +4461,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
m_nextCall=""; //### Temporary: disable use of "TU;" message
|
||||
if(SpecOp::RTTY == m_config.special_op_id() and m_nextCall!="") {
|
||||
// We're in RTTY contest and have "nextCall" queued up: send a "TU; ..." message
|
||||
on_logQSOButton_clicked();
|
||||
logQSOTimer.start(0);
|
||||
ui->tx3->setText(ui->tx3->text().remove("TU; "));
|
||||
useNextCall();
|
||||
QString t="TU; " + ui->tx3->text();
|
||||
@ -4462,7 +4470,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
} else {
|
||||
// if(SpecOp::RTTY == m_config.special_op_id()) {
|
||||
if(false) {
|
||||
on_logQSOButton_clicked();
|
||||
logQSOTimer.start(0);
|
||||
m_ntx=6;
|
||||
ui->txrb6->setChecked(true);
|
||||
} else {
|
||||
@ -8216,7 +8224,7 @@ list2Done:
|
||||
{
|
||||
writeFoxQSO (QString {" Log: %1 %2 %3 %4 %5"}.arg (m_hisCall).arg (m_hisGrid)
|
||||
.arg (m_rptSent).arg (m_rptRcvd).arg (m_lastBand));
|
||||
on_logQSOButton_clicked();
|
||||
logQSOTimer.start(0);
|
||||
m_foxRateQueue.enqueue (now); //Add present time in seconds
|
||||
//to Rate queue.
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
#ifdef QT5
|
||||
#include <QtWidgets>
|
||||
#else
|
||||
#include <QtGui>
|
||||
#endif
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QLabel>
|
||||
#include <QThread>
|
||||
#include <QProcess>
|
||||
#include <QProgressBar>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
@ -58,6 +58,8 @@ namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class QSharedMemory;
|
||||
class QSplashScreen;
|
||||
class QSettings;
|
||||
class QLineEdit;
|
||||
class QFont;
|
||||
@ -102,6 +104,8 @@ public:
|
||||
QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
int decoderBusy () const {return m_decoderBusy;}
|
||||
|
||||
public slots:
|
||||
void showSoundInError(const QString& errorMsg);
|
||||
void showSoundOutError(const QString& errorMsg);
|
||||
|
@ -1,5 +1,11 @@
|
||||
#include "plotter.h"
|
||||
#include <math.h>
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QDateTime>
|
||||
#include <QPen>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include "commons.h"
|
||||
#include "moc_plotter.cpp"
|
||||
|
@ -5,18 +5,14 @@
|
||||
// For more details see the accompanying file LICENSE_WHEATLEY.TXT
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLOTTER_H
|
||||
#define PLOTTER_H
|
||||
#ifndef PLOTTER_H_
|
||||
#define PLOTTER_H_
|
||||
|
||||
#ifdef QT5
|
||||
#include <QtWidgets>
|
||||
#else
|
||||
#include <QtGui>
|
||||
#endif
|
||||
#include <QFrame>
|
||||
#include <QSize>
|
||||
#include <QImage>
|
||||
#include <QVector>
|
||||
#include <cstring>
|
||||
#include <QColor>
|
||||
|
||||
#define VERT_DIVS 7 //specify grid screen divisions
|
||||
#define HORZ_DIVS 20
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <algorithm>
|
||||
#include <QApplication>
|
||||
#include <QSettings>
|
||||
#include <QDateTime>
|
||||
#include <QKeyEvent>
|
||||
#include "ui_widegraph.h"
|
||||
#include "commons.h"
|
||||
#include "Configuration.hpp"
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef WIDEGRAPH_H
|
||||
#define WIDEGRAPH_H
|
||||
#ifndef WIDEGRAPH_H_
|
||||
#define WIDEGRAPH_H_
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
|
@ -19,7 +19,7 @@ HEADERS += \
|
||||
widgets/echoplot.h widgets/echograph.h widgets/fastgraph.h \
|
||||
widgets/fastplot.h widgets/MessageBox.hpp widgets/colorhighlighting.h \
|
||||
widgets/ExportCabrillo.h widgets/AbstractLogWindow.hpp \
|
||||
widgets/FoxLogWindow.cpp widgets/CabrilloLogWindow.cpp
|
||||
widgets/FoxLogWindow.hpp widgets/CabrilloLogWindow.hpp
|
||||
|
||||
FORMS += \
|
||||
widgets/mainwindow.ui widgets/about.ui \
|
||||
|
Loading…
Reference in New Issue
Block a user