diff --git a/item_delegates/CallsignDelegate.cpp b/item_delegates/CallsignDelegate.cpp index 017389458..d3b9864c1 100644 --- a/item_delegates/CallsignDelegate.cpp +++ b/item_delegates/CallsignDelegate.cpp @@ -28,3 +28,4 @@ void CallsignDelegate::setModelData (QWidget * editor, QAbstractItemModel * mode { model->setData (index, static_cast (editor)->text (), Qt::EditRole); } + diff --git a/main.cpp b/main.cpp index 601ae6a7e..fd510bffb 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include #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 { diff --git a/models/CabrilloLog.cpp b/models/CabrilloLog.cpp index d558e66e0..aaedd3bd1 100644 --- a/models/CabrilloLog.cpp +++ b/models/CabrilloLog.cpp @@ -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; } diff --git a/models/FoxLog.cpp b/models/FoxLog.cpp index 691647fdc..1f985f620 100644 --- a/models/FoxLog.cpp +++ b/models/FoxLog.cpp @@ -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; } diff --git a/widgets/AbstractLogWindow.cpp b/widgets/AbstractLogWindow.cpp index c1bfd35c2..efa1e60f1 100644 --- a/widgets/AbstractLogWindow.cpp +++ b/widgets/AbstractLogWindow.cpp @@ -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); } diff --git a/widgets/CabrilloLogWindow.cpp b/widgets/CabrilloLogWindow.cpp index 4bf70f805..44a52cc6b 100644 --- a/widgets/CabrilloLogWindow.cpp +++ b/widgets/CabrilloLogWindow.cpp @@ -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 () diff --git a/widgets/echoplot.cpp b/widgets/echoplot.cpp index 961173b06..0a93e889e 100644 --- a/widgets/echoplot.cpp +++ b/widgets/echoplot.cpp @@ -1,6 +1,8 @@ #include "echoplot.h" #include "commons.h" #include +#include +#include #include #include "moc_echoplot.cpp" diff --git a/widgets/echoplot.h b/widgets/echoplot.h index 23976b02e..a7492b974 100644 --- a/widgets/echoplot.h +++ b/widgets/echoplot.h @@ -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 #include +#include #include -#include +#include #define VERT_DIVS 7 //specify grid screen divisions #define HORZ_DIVS 20 +class QPaintEvent; +class QResizeEvent; + class EPlotter : public QFrame { Q_OBJECT diff --git a/widgets/fastgraph.cpp b/widgets/fastgraph.cpp index 2c86d5dcb..e599138f2 100644 --- a/widgets/fastgraph.cpp +++ b/widgets/fastgraph.cpp @@ -3,6 +3,7 @@ #include "commons.h" #include #include +#include #include "fastplot.h" #include "SettingsGroup.hpp" diff --git a/widgets/fastgraph.h b/widgets/fastgraph.h index 1832d84c4..7ed32671f 100644 --- a/widgets/fastgraph.h +++ b/widgets/fastgraph.h @@ -1,5 +1,5 @@ -#ifndef FASTGRAPH_H -#define FASTGRAPH_H +#ifndef FASTGRAPH_H_ +#define FASTGRAPH_H_ #include #include @@ -9,6 +9,8 @@ namespace Ui { } class QSettings; +class QCloseEvent; +class QKeyEvent; class FastGraph : public QDialog { diff --git a/widgets/fastplot.cpp b/widgets/fastplot.cpp index cd186c2c8..1437834d8 100644 --- a/widgets/fastplot.cpp +++ b/widgets/fastplot.cpp @@ -1,6 +1,10 @@ #include "fastplot.h" #include "commons.h" #include +#include +#include +#include +#include #include #include "moc_fastplot.cpp" diff --git a/widgets/fastplot.h b/widgets/fastplot.h index 57a4ea904..b13913388 100644 --- a/widgets/fastplot.h +++ b/widgets/fastplot.h @@ -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 #include -#include -#include +#include +#include +#include +#include + +class QMouseEvent; class FPlotter : public QFrame { diff --git a/widgets/logqso.h b/widgets/logqso.h index 346e3e5a2..3363d2eac 100644 --- a/widgets/logqso.h +++ b/widgets/logqso.h @@ -1,6 +1,6 @@ // -*- Mode: C++ -*- -#ifndef LogQSO_H -#define LogQSO_H +#ifndef LogQSO_H_ +#define LogQSO_H_ #include diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index d54b8f1c9..d7e883652 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1,12 +1,20 @@ //---------------------------------------------------------- MainWindow #include "mainwindow.h" #include +#include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -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. } diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 428ea6890..cfae42029 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -1,12 +1,12 @@ // -*- Mode: C++ -*- #ifndef MAINWINDOW_H #define MAINWINDOW_H -#ifdef QT5 -#include -#else -#include -#endif + +#include +#include #include +#include +#include #include #include #include @@ -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); diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index cf3166127..761dae08d 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -1,5 +1,11 @@ #include "plotter.h" #include +#include +#include +#include +#include +#include +#include #include #include "commons.h" #include "moc_plotter.cpp" diff --git a/widgets/plotter.h b/widgets/plotter.h index 20d1739ac..e243c1777 100644 --- a/widgets/plotter.h +++ b/widgets/plotter.h @@ -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 -#else -#include -#endif #include +#include #include #include -#include +#include #define VERT_DIVS 7 //specify grid screen divisions #define HORZ_DIVS 20 diff --git a/widgets/widegraph.cpp b/widgets/widegraph.cpp index 350eae9b0..b4601ba4c 100644 --- a/widgets/widegraph.cpp +++ b/widgets/widegraph.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "ui_widegraph.h" #include "commons.h" #include "Configuration.hpp" diff --git a/widgets/widegraph.h b/widgets/widegraph.h index f5e57f8dc..a809a6c8c 100644 --- a/widgets/widegraph.h +++ b/widgets/widegraph.h @@ -1,6 +1,6 @@ // -*- Mode: C++ -*- -#ifndef WIDEGRAPH_H -#define WIDEGRAPH_H +#ifndef WIDEGRAPH_H_ +#define WIDEGRAPH_H_ #include #include diff --git a/widgets/widgets.pri b/widgets/widgets.pri index e70c5cb9e..24ddd5a3c 100644 --- a/widgets/widgets.pri +++ b/widgets/widgets.pri @@ -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 \