| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  | #include "MessageAggregatorMainWindow.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QtWidgets>
 | 
					
						
							|  |  |  | #include <QDateTime>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DecodesModel.hpp"
 | 
					
						
							|  |  |  | #include "BeaconsModel.hpp"
 | 
					
						
							|  |  |  | #include "ClientWidget.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using port_type = MessageServer::port_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char const * const headings[] = { | 
					
						
							| 
									
										
										
										
											2017-01-18 17:24:08 +00:00
										 |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Time On"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Time Off"), | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Callsign"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Grid"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Name"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Frequency"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Mode"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Sent"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Rec'd"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Power"), | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"), | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MessageAggregatorMainWindow::MessageAggregatorMainWindow () | 
					
						
							| 
									
										
										
										
											2017-01-18 17:24:08 +00:00
										 |  |  |   : log_ {new QStandardItemModel {0, 11, this}} | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |   , decodes_model_ {new DecodesModel {this}} | 
					
						
							|  |  |  |   , beacons_model_ {new BeaconsModel {this}} | 
					
						
							|  |  |  |   , server_ {new MessageServer {this}} | 
					
						
							|  |  |  |   , multicast_group_line_edit_ {new QLineEdit} | 
					
						
							|  |  |  |   , log_table_view_ {new QTableView} | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // logbook
 | 
					
						
							|  |  |  |   int column {0}; | 
					
						
							|  |  |  |   for (auto const& heading : headings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       log_->setHeaderData (column++, Qt::Horizontal, tr (heading)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   connect (server_, &MessageServer::qso_logged, this, &MessageAggregatorMainWindow::log_qso); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // menu bar
 | 
					
						
							|  |  |  |   auto file_menu = menuBar ()->addMenu (tr ("&File")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   auto exit_action = new QAction {tr ("E&xit"), this}; | 
					
						
							|  |  |  |   exit_action->setShortcuts (QKeySequence::Quit); | 
					
						
							|  |  |  |   exit_action->setToolTip (tr ("Exit the application")); | 
					
						
							|  |  |  |   file_menu->addAction (exit_action); | 
					
						
							|  |  |  |   connect (exit_action, &QAction::triggered, this, &MessageAggregatorMainWindow::close); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   view_menu_ = menuBar ()->addMenu (tr ("&View")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // central layout
 | 
					
						
							|  |  |  |   auto central_layout = new QVBoxLayout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // server details
 | 
					
						
							|  |  |  |   auto port_spin_box = new QSpinBox; | 
					
						
							|  |  |  |   port_spin_box->setMinimum (1); | 
					
						
							|  |  |  |   port_spin_box->setMaximum (std::numeric_limits<port_type>::max ()); | 
					
						
							|  |  |  |   auto group_box_layout = new QFormLayout; | 
					
						
							|  |  |  |   group_box_layout->addRow (tr ("Port number:"), port_spin_box); | 
					
						
							|  |  |  |   group_box_layout->addRow (tr ("Multicast Group (blank for unicast server):"), multicast_group_line_edit_); | 
					
						
							|  |  |  |   auto group_box = new QGroupBox {tr ("Server Details")}; | 
					
						
							|  |  |  |   group_box->setLayout (group_box_layout); | 
					
						
							|  |  |  |   central_layout->addWidget (group_box); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   log_table_view_->setModel (log_); | 
					
						
							|  |  |  |   log_table_view_->verticalHeader ()->hide (); | 
					
						
							|  |  |  |   central_layout->addWidget (log_table_view_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // central widget
 | 
					
						
							|  |  |  |   auto central_widget = new QWidget; | 
					
						
							|  |  |  |   central_widget->setLayout (central_layout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // main window setup
 | 
					
						
							|  |  |  |   setCentralWidget (central_widget); | 
					
						
							|  |  |  |   setDockOptions (AnimatedDocks | AllowNestedDocks | AllowTabbedDocks); | 
					
						
							|  |  |  |   setTabPosition (Qt::BottomDockWidgetArea, QTabWidget::North); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // connect up server
 | 
					
						
							|  |  |  |   connect (server_, &MessageServer::error, [this] (QString const& message) { | 
					
						
							| 
									
										
										
										
											2016-07-03 20:31:19 +00:00
										 |  |  |       QMessageBox::warning (this, QApplication::applicationName (), tr ("Network Error"), message); | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |     }); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::client_opened, this, &MessageAggregatorMainWindow::add_client); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::client_closed, this, &MessageAggregatorMainWindow::remove_client); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::client_closed, decodes_model_, &DecodesModel::clear_decodes); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::clear_decodes); | 
					
						
							| 
									
										
										
										
											2016-12-16 19:36:21 +00:00
										 |  |  |   connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time | 
					
						
							|  |  |  |                                                     , qint32 snr, float delta_time | 
					
						
							|  |  |  |                                                     , quint32 delta_frequency, QString const& mode | 
					
						
							|  |  |  |                                                     , QString const& message) { | 
					
						
							|  |  |  |              decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message | 
					
						
							|  |  |  |                                          , dock_widgets_[id]->fast_mode ());}); | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |   connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes); | 
					
						
							|  |  |  |   connect (decodes_model_, &DecodesModel::reply, server_, &MessageServer::reply); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // UI behaviour
 | 
					
						
							|  |  |  |   connect (port_spin_box, static_cast<void (QSpinBox::*)(int)> (&QSpinBox::valueChanged) | 
					
						
							|  |  |  |            , [this] (port_type port) {server_->start (port);}); | 
					
						
							|  |  |  |   connect (multicast_group_line_edit_, &QLineEdit::editingFinished, [this, port_spin_box] () { | 
					
						
							|  |  |  |       server_->start (port_spin_box->value (), QHostAddress {multicast_group_line_edit_->text ()}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   port_spin_box->setValue (2237); // start up in unicast mode
 | 
					
						
							|  |  |  |   show (); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 17:24:08 +00:00
										 |  |  | void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime timeOff, QString const& dx_call, QString const& dx_grid | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |                                            , Frequency dial_frequency, QString const& mode, QString const& report_sent | 
					
						
							|  |  |  |                                            , QString const& report_received, QString const& tx_power, QString const& comments | 
					
						
							| 
									
										
										
										
											2017-01-18 17:24:08 +00:00
										 |  |  |                                            , QString const& name, QDateTime timeOn) | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   QList<QStandardItem *> row; | 
					
						
							| 
									
										
										
										
											2017-01-18 17:24:08 +00:00
										 |  |  |   row << new QStandardItem {timeOn.toString ("dd-MMM-yyyy hh:mm")} | 
					
						
							|  |  |  |   << new QStandardItem {timeOff.toString ("dd-MMM-yyyy hh:mm")} | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |   << new QStandardItem {dx_call} | 
					
						
							|  |  |  |   << new QStandardItem {dx_grid} | 
					
						
							|  |  |  |   << new QStandardItem {name} | 
					
						
							|  |  |  |   << new QStandardItem {Radio::frequency_MHz_string (dial_frequency)} | 
					
						
							|  |  |  |   << new QStandardItem {mode} | 
					
						
							|  |  |  |   << new QStandardItem {report_sent} | 
					
						
							|  |  |  |   << new QStandardItem {report_received} | 
					
						
							|  |  |  |   << new QStandardItem {tx_power} | 
					
						
							|  |  |  |   << new QStandardItem {comments}; | 
					
						
							|  |  |  |   log_->appendRow (row); | 
					
						
							|  |  |  |   log_table_view_->resizeColumnsToContents (); | 
					
						
							|  |  |  |   log_table_view_->horizontalHeader ()->setStretchLastSection (true); | 
					
						
							|  |  |  |   log_table_view_->scrollToBottom (); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 00:55:15 +00:00
										 |  |  | void MessageAggregatorMainWindow::add_client (QString const& id, QString const& version, QString const& revision) | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-12-04 00:55:15 +00:00
										 |  |  |   auto dock = new ClientWidget {decodes_model_, beacons_model_, id, version, revision, this}; | 
					
						
							| 
									
										
										
										
											2016-05-24 10:08:35 +00:00
										 |  |  |   dock->setAttribute (Qt::WA_DeleteOnClose); | 
					
						
							|  |  |  |   auto view_action = dock->toggleViewAction (); | 
					
						
							|  |  |  |   view_action->setEnabled (true); | 
					
						
							|  |  |  |   view_menu_->addAction (view_action); | 
					
						
							|  |  |  |   addDockWidget (Qt::BottomDockWidgetArea, dock); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::status_update, dock, &ClientWidget::update_status); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::decode, dock, &ClientWidget::decode_added); | 
					
						
							|  |  |  |   connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added); | 
					
						
							|  |  |  |   connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply); | 
					
						
							|  |  |  |   connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx); | 
					
						
							|  |  |  |   connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text); | 
					
						
							|  |  |  |   connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible); | 
					
						
							|  |  |  |   dock_widgets_[id] = dock; | 
					
						
							|  |  |  |   server_->replay (id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MessageAggregatorMainWindow::remove_client (QString const& id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   auto iter = dock_widgets_.find (id); | 
					
						
							|  |  |  |   if (iter != std::end (dock_widgets_)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       (*iter)->close (); | 
					
						
							|  |  |  |       dock_widgets_.erase (iter); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "moc_MessageAggregatorMainWindow.cpp"
 |