mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-21 19:55:20 -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.
151 lines
5.4 KiB
C++
151 lines
5.4 KiB
C++
#include "AbstractLogWindow.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <QSettings>
|
|
#include <QString>
|
|
#include <QTableView>
|
|
#include <QHeaderView>
|
|
#include <QAction>
|
|
#include <QSqlTableModel>
|
|
#include <QItemSelectionModel>
|
|
#include <QItemSelection>
|
|
#include "Configuration.hpp"
|
|
#include "SettingsGroup.hpp"
|
|
#include "MessageBox.hpp"
|
|
#include "models/FontOverrideModel.hpp"
|
|
#include "pimpl_impl.hpp"
|
|
|
|
class AbstractLogWindow::impl final
|
|
{
|
|
public:
|
|
impl (AbstractLogWindow * self, QString const& settings_key, QSettings * settings
|
|
, Configuration const * configuration)
|
|
: self_ {self}
|
|
, settings_key_ {settings_key}
|
|
, settings_ {settings}
|
|
, configuration_ {configuration}
|
|
, log_view_ {nullptr}
|
|
{
|
|
}
|
|
|
|
void delete_QSOs ();
|
|
|
|
AbstractLogWindow * self_;
|
|
QString settings_key_;
|
|
QSettings * settings_;
|
|
Configuration const * configuration_;
|
|
QTableView * log_view_;
|
|
FontOverrideModel model_;
|
|
};
|
|
|
|
namespace
|
|
{
|
|
bool row_is_higher (QModelIndex const& lhs, QModelIndex const& rhs)
|
|
{
|
|
return lhs.row () > rhs.row ();
|
|
}
|
|
}
|
|
|
|
void AbstractLogWindow::impl::delete_QSOs ()
|
|
{
|
|
auto selection_model = log_view_->selectionModel ();
|
|
selection_model->select (selection_model->selection (), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
|
auto row_indexes = selection_model->selectedRows ();
|
|
|
|
if (row_indexes.size ()
|
|
&& MessageBox::Yes == MessageBox::query_message (self_
|
|
, tr ("Confirm Delete")
|
|
, tr ("Are you sure you want to delete the %n "
|
|
"selected QSO(s) from the log", ""
|
|
, row_indexes.size ())))
|
|
{
|
|
// We must work with source model indexes because we don't want row
|
|
// removes to invalidate model indexes we haven't yet processed. We
|
|
// achieve that by processing them in decending row order.
|
|
for (auto& row_index : row_indexes)
|
|
{
|
|
row_index = model_.mapToSource (row_index);
|
|
}
|
|
|
|
// reverse sort by row
|
|
std::sort (row_indexes.begin (), row_indexes.end (), row_is_higher);
|
|
for (auto index : row_indexes)
|
|
{
|
|
auto row = model_.mapFromSource (index).row ();
|
|
model_.removeRow (row);
|
|
self_->log_model_changed ();
|
|
}
|
|
}
|
|
}
|
|
|
|
AbstractLogWindow::AbstractLogWindow (QString const& settings_key, QSettings * settings
|
|
, Configuration const * configuration
|
|
, QWidget * parent)
|
|
: QWidget {parent}
|
|
, m_ {this, settings_key, settings, configuration}
|
|
{
|
|
// 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 ()
|
|
{
|
|
SettingsGroup g {m_->settings_, m_->settings_key_};
|
|
m_->settings_->setValue ("window/geometry", saveGeometry ());
|
|
}
|
|
|
|
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;
|
|
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);
|
|
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 ..."), log_view};
|
|
log_view->insertAction (nullptr, delete_action);
|
|
connect (delete_action, &QAction::triggered, [this] (bool /*checked*/) {
|
|
m_->delete_QSOs ();
|
|
});
|
|
}
|
|
|
|
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);
|
|
}
|