| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | #include "AbstractLogWindow.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | #include <QSettings>
 | 
					
						
							| 
									
										
										
										
											2019-06-06 12:56:25 +01:00
										 |  |  | #include <QObject>
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | #include <QString>
 | 
					
						
							|  |  |  | #include <QTableView>
 | 
					
						
							|  |  |  | #include <QHeaderView>
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | #include <QAction>
 | 
					
						
							|  |  |  | #include <QSqlTableModel>
 | 
					
						
							|  |  |  | #include <QItemSelectionModel>
 | 
					
						
							|  |  |  | #include <QItemSelection>
 | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  | #include <QTimer>
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | #include "Configuration.hpp"
 | 
					
						
							|  |  |  | #include "SettingsGroup.hpp"
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | #include "MessageBox.hpp"
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | #include "models/FontOverrideModel.hpp"
 | 
					
						
							|  |  |  | #include "pimpl_impl.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AbstractLogWindow::impl final | 
					
						
							| 
									
										
										
										
											2019-06-06 12:56:25 +01:00
										 |  |  |   : public QObject | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-06 12:56:25 +01:00
										 |  |  |   Q_OBJECT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |   impl (AbstractLogWindow * self, QString const& settings_key, QSettings * settings | 
					
						
							|  |  |  |         , Configuration const * configuration) | 
					
						
							|  |  |  |     : self_ {self} | 
					
						
							|  |  |  |     , settings_key_ {settings_key} | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  |     , settings_ {settings} | 
					
						
							|  |  |  |     , configuration_ {configuration} | 
					
						
							|  |  |  |     , log_view_ {nullptr} | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |   void delete_QSOs (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AbstractLogWindow * self_; | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  |   QString settings_key_; | 
					
						
							|  |  |  |   QSettings * settings_; | 
					
						
							|  |  |  |   Configuration const * configuration_; | 
					
						
							|  |  |  |   QTableView * log_view_; | 
					
						
							|  |  |  |   FontOverrideModel model_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 12:56:25 +01:00
										 |  |  | #include "moc_AbstractLogWindow.cpp"
 | 
					
						
							|  |  |  | #include "AbstractLogWindow.moc"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | 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 " | 
					
						
							| 
									
										
										
										
											2020-05-19 01:14:18 +01:00
										 |  |  |                                                              "selected QSO(s) from the log?", "" | 
					
						
							| 
									
										
										
										
											2021-03-01 22:19:08 +00:00
										 |  |  |                                                              , row_indexes.size ()) | 
					
						
							|  |  |  |                                                        , QString {} | 
					
						
							|  |  |  |                                                        , MessageBox::Yes | MessageBox::No | 
					
						
							|  |  |  |                                                        , MessageBox::No)) | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       // We must work with source model indexes because we don't want row
 | 
					
						
							|  |  |  |       // removes to invalidate model indexes we haven't yet processed. We
 | 
					
						
							| 
									
										
										
										
											2022-07-15 11:24:57 -07:00
										 |  |  |       // achieve that by processing them in descending row order.
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |       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); | 
					
						
							| 
									
										
										
										
											2022-07-15 11:24:57 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |       for (auto index : row_indexes) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-07-15 11:24:57 -07:00
										 |  |  |           auto row = model_.mapFromSource(index).row(); | 
					
						
							|  |  |  |           model_.removeRow(row); | 
					
						
							|  |  |  |           self_->log_model_changed(); | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | AbstractLogWindow::AbstractLogWindow (QString const& settings_key, QSettings * settings | 
					
						
							|  |  |  |                                       , Configuration const * configuration | 
					
						
							|  |  |  |                                       , QWidget * parent) | 
					
						
							|  |  |  |   : QWidget {parent} | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  |   , m_ {this, settings_key, settings, configuration} { | 
					
						
							|  |  |  |     // when we're viewing the log by contact ID (visually, up/down chevron in the column heading),
 | 
					
						
							|  |  |  |     // when we add a contact, scroll the list to the top or bottom, depending on the sort order.
 | 
					
						
							|  |  |  |     // If the table is sorted by some other criteria, don't change anything.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(&m_->model_, &QAbstractItemModel::rowsInserted, this, | 
					
						
							|  |  |  |             [this](QModelIndex const &parent, int first, int last) { | 
					
						
							|  |  |  |                 (void) (parent); // UNUSED
 | 
					
						
							|  |  |  |                 (void) (first);  // UNUSED
 | 
					
						
							|  |  |  |                 (void) (last);   // UNUSED
 | 
					
						
							|  |  |  |                 QTimer::singleShot(0, [=] { | 
					
						
							| 
									
										
										
										
											2022-07-13 21:36:07 -07:00
										 |  |  |                     // if we're sorting by the date, then show the most-recently logged contact.
 | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  |                     // Otherwise, leave the scroll alone
 | 
					
						
							|  |  |  |                     auto horizontal_header = m_->log_view_->horizontalHeader (); | 
					
						
							| 
									
										
										
										
											2022-07-13 21:36:07 -07:00
										 |  |  |                     if (horizontal_header->sortIndicatorSection() == 3) { // sorting on date?
 | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  |                         if (horizontal_header->sortIndicatorOrder() == Qt::AscendingOrder) { | 
					
						
							| 
									
										
										
										
											2022-07-13 21:36:07 -07:00
										 |  |  |                             // we're sorting oldes->newest, so go to bottom
 | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  |                             m_->log_view_->scrollToBottom(); | 
					
						
							|  |  |  |                         } else { | 
					
						
							|  |  |  |                             m_->log_view_->scrollToTop(); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							| 
									
										
										
										
											2018-12-06 05:41:16 +00:00
										 |  |  |   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_); | 
					
						
							| 
									
										
										
										
											2022-07-13 21:36:07 -07:00
										 |  |  |   log_view->setColumnHidden (0, true); // hide the ID column
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  |   auto horizontal_header = log_view->horizontalHeader (); | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 05:41:16 +00:00
										 |  |  |   horizontal_header->setResizeContentsPrecision (0); // visible region only
 | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  |   horizontal_header->setSectionResizeMode (QHeaderView::ResizeToContents); | 
					
						
							|  |  |  |   horizontal_header->setSectionsMovable (true); | 
					
						
							| 
									
										
										
										
											2022-07-13 21:36:07 -07:00
										 |  |  |   horizontal_header->setSortIndicator(3, Qt::AscendingOrder); // sort by the contact datetime oldest->newest
 | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 05:41:16 +00:00
										 |  |  |   auto vertical_header = log_view->horizontalHeader (); | 
					
						
							|  |  |  |   vertical_header->setResizeContentsPrecision (0); // visible region only
 | 
					
						
							|  |  |  |   vertical_header->setSectionResizeMode (QHeaderView::ResizeToContents); | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // actions
 | 
					
						
							| 
									
										
										
										
											2018-12-06 05:41:16 +00:00
										 |  |  |   auto delete_action = new QAction {tr ("&Delete ..."), log_view}; | 
					
						
							|  |  |  |   log_view->insertAction (nullptr, delete_action); | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |   connect (delete_action, &QAction::triggered, [this] (bool /*checked*/) { | 
					
						
							|  |  |  |       m_->delete_QSOs (); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-07-11 15:56:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // scroll to bottom, since we're showing 1-N
 | 
					
						
							|  |  |  |   log_view->scrollToBottom(); | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AbstractLogWindow::set_log_view_font (QFont const& font) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-06 05:41:16 +00:00
										 |  |  |   m_->log_view_->setFont (font); | 
					
						
							|  |  |  |   m_->log_view_->horizontalHeader ()->setFont (font); | 
					
						
							|  |  |  |   m_->log_view_->verticalHeader ()->setFont (font); | 
					
						
							| 
									
										
										
										
											2018-11-23 01:18:39 +00:00
										 |  |  |   m_->model_.set_font (font); | 
					
						
							|  |  |  | } |