New UDP message SwitchConfiguration(14) to switch to an existing configuration

The Status(1) message also acquires  the current configuration name as
a new  field. See  NetworkMessage.hpp for  details. The  UDP reference
example program message_aggregator acquires the ability to display and
change  the configuration  of a  WSJT-X client  to exercise  these new
features.
This commit is contained in:
Bill Somerville 2019-06-13 01:44:28 +01:00
parent fc07bd9287
commit 3f5a996842
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
12 changed files with 171 additions and 77 deletions

View File

@ -261,6 +261,18 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
}
break;
case NetworkMessage::SwitchConfiguration:
{
QByteArray configuration_name;
in >> configuration_name;
TRACE_UDP ("SwitchConfiguration name:" << configuration_name);
if (check_status (in) != Fail && configuration_name.size ())
{
Q_EMIT self_->switch_configuration (QString::fromUtf8 (configuration_name));
}
}
break;
default:
// Ignore
//
@ -444,7 +456,8 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
, qint32 rx_df, qint32 tx_df, QString const& de_call
, QString const& de_grid, QString const& dx_grid
, bool watchdog_timeout, QString const& sub_mode
, bool fast_mode, quint8 special_op_mode)
, bool fast_mode, quint8 special_op_mode
, QString const& configuration_name)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
@ -453,8 +466,8 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
out << f << mode.toUtf8 () << dx_call.toUtf8 () << report.toUtf8 () << tx_mode.toUtf8 ()
<< tx_enabled << transmitting << decoding << rx_df << tx_df << de_call.toUtf8 ()
<< de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 ()
<< fast_mode << special_op_mode;
TRACE_UDP ("frequency:" << f << "mode:" << mode << "DX:" << dx_call << "report:" << report << "Tx mode:" << tx_mode << "tx_enabled:" << tx_enabled << "Tx:" << transmitting << "decoding:" << decoding << "Rx df:" << rx_df << "Tx df:" << tx_df << "DE:" << de_call << "DE grid:" << de_grid << "DX grid:" << dx_grid << "w/d t/o:" << watchdog_timeout << "sub_mode:" << sub_mode << "fast mode:" << fast_mode << "spec op mode:" << special_op_mode);
<< fast_mode << special_op_mode << configuration_name.toUtf8 ();
TRACE_UDP ("frequency:" << f << "mode:" << mode << "DX:" << dx_call << "report:" << report << "Tx mode:" << tx_mode << "tx_enabled:" << tx_enabled << "Tx:" << transmitting << "decoding:" << decoding << "Rx df:" << rx_df << "Tx df:" << tx_df << "DE:" << de_call << "DE grid:" << de_grid << "DX grid:" << dx_grid << "w/d t/o:" << watchdog_timeout << "sub_mode:" << sub_mode << "fast mode:" << fast_mode << "spec op mode:" << special_op_mode << "configuration name:" << configuration_name);
m_->send_message (out, message);
}
}

View File

@ -52,7 +52,7 @@ public:
, QString const& tx_mode, bool tx_enabled, bool transmitting, bool decoding
, qint32 rx_df, qint32 tx_df, QString const& de_call, QString const& de_grid
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
, bool fast_mode, quint8 special_op_mode);
, bool fast_mode, quint8 special_op_mode, QString const& configuration_name);
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message, bool low_confidence
, bool off_air);
@ -105,6 +105,10 @@ public:
// callsign request for the specified call
Q_SIGNAL void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only);
// this signal is emitted if the server has requested a switch to a
// new configuration
Q_SIGNAL void switch_configuration (QString const& configuration_name);
// this signal is emitted when network errors occur or if a host
// lookup fails
Q_SIGNAL void error (QString const&) const;

View File

@ -247,9 +247,10 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
QByteArray sub_mode;
bool fast_mode {false};
quint8 special_op_mode {0};
QByteArray configuration_name;
in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting >> decoding
>> rx_df >> tx_df >> de_call >> de_grid >> dx_grid >> watchdog_timeout >> sub_mode
>> fast_mode >> special_op_mode;
>> fast_mode >> special_op_mode >> configuration_name;
if (check_status (in) != Fail)
{
Q_EMIT self_->status_update (id, f, QString::fromUtf8 (mode), QString::fromUtf8 (dx_call)
@ -258,7 +259,7 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
, QString::fromUtf8 (de_call), QString::fromUtf8 (de_grid)
, QString::fromUtf8 (dx_grid), watchdog_timeout
, QString::fromUtf8 (sub_mode), fast_mode
, special_op_mode);
, special_op_mode, QString::fromUtf8 (configuration_name));
}
}
break;
@ -541,3 +542,15 @@ void MessageServer::highlight_callsign (QString const& id, QString const& callsi
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
}
}
void MessageServer::switch_configuration (QString const& id, QString const& configuration_name)
{
auto iter = m_->clients_.find (id);
if (iter != std::end (m_->clients_))
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::SwitchConfiguration, id, (*iter).negotiated_schema_number_};
out << configuration_name.toUtf8 ();
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
}
}

View File

@ -72,6 +72,9 @@ public:
, QColor const& bg = QColor {}, QColor const& fg = QColor {}
, bool last_only = false);
// ask the client with identification 'id' to switch configuration
Q_SLOT void switch_configuration (QString const& id, QString const& configuration_name);
// the following signals are emitted when a client broadcasts the
// matching message
Q_SIGNAL void client_opened (QString const& id, QString const& version, QString const& revision);
@ -80,7 +83,7 @@ public:
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
, QString const& de_call, QString const& de_grid, QString const& dx_grid
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode
, quint8 special_op_mode);
, quint8 special_op_mode, QString const& configuration_name);
Q_SIGNAL void client_closed (QString const& id);
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode, QString const& message

View File

@ -159,13 +159,16 @@ public:
bool exit ();
QSettings settings_;
QString current_;
// switch to this configuration
void select_configuration (QString const& target_name);
private:
using Dictionary = QMap<QString, QVariant>;
// create a configuration maintenance sub menu
QMenu * create_sub_menu (QMainWindow * main_window,
QMenu * parent,
QMenu * create_sub_menu (QMenu * parent,
QString const& menu_title,
QActionGroup * = nullptr);
@ -175,32 +178,32 @@ private:
// write the settings values from the dictionary to the current group
void load_from (Dictionary const&, bool add_placeholder = true);
// switch to this configuration
void select_configuration (QMainWindow *, QMenu const *);
// clone this configuration
void clone_configuration (QMainWindow * main_window, QMenu *, QMenu const *);
void clone_configuration (QMenu *, QMenu const *);
// update this configuration from another
void clone_into_configuration (QMainWindow *, QMenu const *);
void clone_into_configuration (QMenu const *);
// reset configuration to default values
void reset_configuration (QMainWindow *, QMenu const *);
void reset_configuration (QMenu const *);
// change configuration name
void rename_configuration (QMainWindow *, QMenu *);
void rename_configuration (QMenu *);
// remove a configuration
void delete_configuration (QMainWindow *, QMenu *);
void delete_configuration (QMenu *);
// action to take on restart
enum class RepositionType {unchanged, replace, save_and_replace};
void restart (RepositionType);
MultiSettings const * parent_; // required for emitting signals
QMainWindow * main_window_;
bool name_change_emit_pending_; // delayed until menu built
QFont original_font_;
QString current_;
// action to take on restart
enum class RepositionType {unchanged, replace, save_and_replace} reposition_type_;
RepositionType reposition_type_;
Dictionary new_settings_;
bool exit_flag_; // false means loop around with new
// configuration
@ -267,6 +270,16 @@ void MultiSettings::create_menu_actions (QMainWindow * main_window, QMenu * menu
m_->create_menu_actions (main_window, menu);
}
void MultiSettings::select_configuration (QString const& name)
{
m_->select_configuration (name);
}
QString MultiSettings::configuration_name () const
{
return m_->current_;
}
bool MultiSettings::exit ()
{
return m_->exit ();
@ -275,6 +288,7 @@ bool MultiSettings::exit ()
MultiSettings::impl::impl (MultiSettings const * parent, QString const& config_name)
: settings_ {settings_path (), QSettings::IniFormat}
, parent_ {parent}
, main_window_ {nullptr}
, name_change_emit_pending_ {true}
, reposition_type_ {RepositionType::unchanged}
, exit_flag_ {true}
@ -411,13 +425,14 @@ bool MultiSettings::impl::reposition ()
// and, reset
void MultiSettings::impl::create_menu_actions (QMainWindow * main_window, QMenu * menu)
{
main_window_ = main_window;
auto const& current_group = settings_.group ();
if (current_group.size ()) settings_.endGroup ();
SettingsGroup alternatives {&settings_, multi_settings_root_group};
// get the current configuration name
auto const& current_configuration_name = settings_.value (multi_settings_current_name_key, tr (default_string)).toString ();
// add the default configuration sub menu
QMenu * default_menu = create_sub_menu (main_window, menu, current_configuration_name, configurations_group_);
QMenu * default_menu = create_sub_menu (menu, current_configuration_name, configurations_group_);
// and set as the current configuration
default_menu->menuAction ()->setChecked (true);
@ -427,7 +442,7 @@ void MultiSettings::impl::create_menu_actions (QMainWindow * main_window, QMenu
// add all the other configurations
for (auto const& configuration_name: available_configurations)
{
create_sub_menu (main_window, menu, configuration_name, configurations_group_);
create_sub_menu (menu, configuration_name, configurations_group_);
}
if (current_group.size ()) settings_.beginGroup (current_group);
@ -450,8 +465,7 @@ bool MultiSettings::impl::exit ()
return reposition ();
}
QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window,
QMenu * parent_menu,
QMenu * MultiSettings::impl::create_sub_menu (QMenu * parent_menu,
QString const& menu_title,
QActionGroup * action_group)
{
@ -460,7 +474,7 @@ QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window,
sub_menu->menuAction ()->setCheckable (true);
// populate sub-menu actions before showing
connect (sub_menu, &QMenu::aboutToShow, [this, main_window, parent_menu, sub_menu] () {
connect (sub_menu, &QMenu::aboutToShow, [this, parent_menu, sub_menu] () {
// depopulate before populating and showing because on Mac OS X
// there is an issue with depopulating in QMenu::aboutToHide()
// with connections being disconnected before they are actioned
@ -474,16 +488,16 @@ QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window,
{
auto select_action = new QAction {tr ("&Switch To"), this};
sub_menu->addAction (select_action);
connect (select_action, &QAction::triggered, [this, main_window, sub_menu] (bool) {
select_configuration (main_window, sub_menu);
connect (select_action, &QAction::triggered, [this, sub_menu] (bool) {
select_configuration (sub_menu->title ());
});
sub_menu->addSeparator ();
}
auto clone_action = new QAction {tr ("&Clone"), this};
sub_menu->addAction (clone_action);
connect (clone_action, &QAction::triggered, [this, main_window, parent_menu, sub_menu] (bool) {
clone_configuration (main_window, parent_menu, sub_menu);
connect (clone_action, &QAction::triggered, [this, parent_menu, sub_menu] (bool) {
clone_configuration (parent_menu, sub_menu);
});
auto const& current_group = settings_.group ();
@ -493,29 +507,29 @@ QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window,
{
auto clone_into_action = new QAction {tr ("Clone &Into ..."), this};
sub_menu->addAction (clone_into_action);
connect (clone_into_action, &QAction::triggered, [this, main_window, sub_menu] (bool) {
clone_into_configuration (main_window, sub_menu);
connect (clone_into_action, &QAction::triggered, [this, sub_menu] (bool) {
clone_into_configuration (sub_menu);
});
}
if (current_group.size ()) settings_.beginGroup (current_group);
auto reset_action = new QAction {tr ("R&eset"), this};
sub_menu->addAction (reset_action);
connect (reset_action, &QAction::triggered, [this, main_window, sub_menu] (bool) {
reset_configuration (main_window, sub_menu);
connect (reset_action, &QAction::triggered, [this, sub_menu] (bool) {
reset_configuration (sub_menu);
});
auto rename_action = new QAction {tr ("&Rename ..."), this};
sub_menu->addAction (rename_action);
connect (rename_action, &QAction::triggered, [this, main_window, sub_menu] (bool) {
rename_configuration (main_window, sub_menu);
connect (rename_action, &QAction::triggered, [this, sub_menu] (bool) {
rename_configuration (sub_menu);
});
if (!is_current)
{
auto delete_action = new QAction {tr ("&Delete"), this};
sub_menu->addAction (delete_action);
connect (delete_action, &QAction::triggered, [this, main_window, sub_menu] (bool) {
delete_configuration (main_window, sub_menu);
connect (delete_action, &QAction::triggered, [this, sub_menu] (bool) {
delete_configuration (sub_menu);
});
}
});
@ -558,11 +572,9 @@ void MultiSettings::impl::load_from (Dictionary const& dictionary, bool add_plac
settings_.sync ();
}
void MultiSettings::impl::select_configuration (QMainWindow * main_window, QMenu const * menu)
void MultiSettings::impl::select_configuration (QString const& target_name)
{
auto const& target_name = menu->title ();
if (target_name != current_)
if (main_window_ && target_name != current_)
{
{
auto const& current_group = settings_.group ();
@ -577,13 +589,11 @@ void MultiSettings::impl::select_configuration (QMainWindow * main_window, QMenu
// and set up the restart
current_ = target_name;
Q_EMIT parent_->configurationNameChanged (unescape_ampersands (current_));
reposition_type_ = RepositionType::save_and_replace;
exit_flag_ = false;
main_window->close ();
restart (RepositionType::save_and_replace);
}
}
void MultiSettings::impl::clone_configuration (QMainWindow * main_window, QMenu * parent_menu, QMenu const * menu)
void MultiSettings::impl::clone_configuration (QMenu * parent_menu, QMenu const * menu)
{
auto const& current_group = settings_.group ();
if (current_group.size ()) settings_.endGroup ();
@ -616,12 +626,15 @@ void MultiSettings::impl::clone_configuration (QMainWindow * main_window, QMenu
load_from (source_settings);
// insert the new configuration sub menu in the parent menu
create_sub_menu (main_window, parent_menu, new_name, configurations_group_);
create_sub_menu (parent_menu, new_name, configurations_group_);
if (current_group.size ()) settings_.beginGroup (current_group);
}
void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, QMenu const * menu)
void MultiSettings::impl::clone_into_configuration (QMenu const * menu)
{
Q_ASSERT (main_window_);
if (!main_window_) return;
auto const& current_group = settings_.group ();
if (current_group.size ()) settings_.endGroup ();
auto const& target_name = menu->title ();
@ -642,15 +655,16 @@ void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, Q
}
// pick a source configuration
ExistingNameDialog dialog {sources, main_window};
ExistingNameDialog dialog {sources, main_window_};
if (sources.size () && (1 == sources.size () || QDialog::Accepted == dialog.exec ()))
{
QString source_name {1 == sources.size () ? sources.at (0) : dialog.name ()};
if (MessageBox::Yes == MessageBox::query_message (main_window,
tr ("Clone Into Configuration"),
tr ("Confirm overwrite of all values for configuration \"%1\" with values from \"%2\"?")
.arg (unescape_ampersands (target_name))
.arg (unescape_ampersands (source_name))))
if (main_window_
&& MessageBox::Yes == MessageBox::query_message (main_window_,
tr ("Clone Into Configuration"),
tr ("Confirm overwrite of all values for configuration \"%1\" with values from \"%2\"?")
.arg (unescape_ampersands (target_name))
.arg (unescape_ampersands (source_name))))
{
// grab the data to clone from
if (source_name == current_group_name)
@ -669,9 +683,7 @@ void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, Q
if (target_name == current_)
{
// restart with new settings
reposition_type_ = RepositionType::replace;
exit_flag_ = false;
main_window->close ();
restart (RepositionType::replace);
}
else
{
@ -686,14 +698,18 @@ void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, Q
if (current_group.size ()) settings_.beginGroup (current_group);
}
void MultiSettings::impl::reset_configuration (QMainWindow * main_window, QMenu const * menu)
void MultiSettings::impl::reset_configuration (QMenu const * menu)
{
Q_ASSERT (main_window_);
if (!main_window_) return;
auto const& target_name = menu->title ();
if (MessageBox::Yes != MessageBox::query_message (main_window,
tr ("Reset Configuration"),
tr ("Confirm reset to default values for configuration \"%1\"?")
.arg (unescape_ampersands (target_name))))
if (!main_window_
|| MessageBox::Yes != MessageBox::query_message (main_window_,
tr ("Reset Configuration"),
tr ("Confirm reset to default values for configuration \"%1\"?")
.arg (unescape_ampersands (target_name))))
{
return;
}
@ -701,10 +717,8 @@ void MultiSettings::impl::reset_configuration (QMainWindow * main_window, QMenu
if (target_name == current_)
{
// restart with default settings
reposition_type_ = RepositionType::replace;
new_settings_.clear ();
exit_flag_ = false;
main_window->close ();
restart (RepositionType::replace);
}
else
{
@ -721,8 +735,11 @@ void MultiSettings::impl::reset_configuration (QMainWindow * main_window, QMenu
}
}
void MultiSettings::impl::rename_configuration (QMainWindow * main_window, QMenu * menu)
void MultiSettings::impl::rename_configuration (QMenu * menu)
{
Q_ASSERT (main_window_);
if (!main_window_) return;
auto const& current_group = settings_.group ();
if (current_group.size ()) settings_.endGroup ();
auto const& target_name = menu->title ();
@ -733,7 +750,7 @@ void MultiSettings::impl::rename_configuration (QMainWindow * main_window, QMenu
invalid_names << settings_.value (multi_settings_current_name_key).toString ();
// get the new name
NameDialog dialog {target_name, invalid_names, main_window};
NameDialog dialog {target_name, invalid_names, main_window_};
if (QDialog::Accepted == dialog.exec ())
{
if (target_name == current_)
@ -764,8 +781,9 @@ void MultiSettings::impl::rename_configuration (QMainWindow * main_window, QMenu
if (current_group.size ()) settings_.beginGroup (current_group);
}
void MultiSettings::impl::delete_configuration (QMainWindow * main_window, QMenu * menu)
void MultiSettings::impl::delete_configuration (QMenu * menu)
{
Q_ASSERT (main_window_);
auto const& target_name = menu->title ();
if (target_name == current_)
@ -774,10 +792,11 @@ void MultiSettings::impl::delete_configuration (QMainWindow * main_window, QMenu
}
else
{
if (MessageBox::Yes != MessageBox::query_message (main_window,
tr ("Delete Configuration"),
tr ("Confirm deletion of configuration \"%1\"?")
.arg (unescape_ampersands (target_name))))
if (!main_window_
|| MessageBox::Yes != MessageBox::query_message (main_window_,
tr ("Delete Configuration"),
tr ("Confirm deletion of configuration \"%1\"?")
.arg (unescape_ampersands (target_name))))
{
return;
}
@ -793,3 +812,12 @@ void MultiSettings::impl::delete_configuration (QMainWindow * main_window, QMenu
// update the menu
menu->deleteLater ();
}
void MultiSettings::impl::restart (RepositionType type)
{
Q_ASSERT (main_window_);
reposition_type_ = type;
exit_flag_ = false;
main_window_->close ();
main_window_ = nullptr;
}

View File

@ -80,6 +80,10 @@ public:
// action is triggered.
void create_menu_actions (QMainWindow *, QMenu *);
// switch to this configuration if it exists
Q_SLOT void select_configuration (QString const& name);
QString configuration_name () const;
// Access to the QSettings object instance.
QSettings * settings ();

View File

@ -124,7 +124,8 @@
* Tx Watchdog bool
* Sub-mode utf8
* Fast mode bool
* Special operation mode quint8
* Special Operation Mode quint8
* Configuration Name utf8
*
* WSJT-X sends this status message when various internal state
* changes to allow the server to track the relevant state of each
@ -145,7 +146,8 @@
* When the Tx DF changes,
* When settings are exited,
* When the DX call or grid changes,
* When the Tx watchdog is set or reset.
* When the Tx watchdog is set or reset,
* When the configuration name changes.
*
* The Special operation mode is an enumeration that indicates the
* setting selected in the WSJT-X "Settings->Advanced->Special
@ -414,6 +416,15 @@
* the last instance only instead of all instances of the
* specified call be highlighted or have it's highlighting
* cleared.
*
*
* Switch Configuration In 14 quint32
* Id (unique key) utf8
* Configuration Name utf8
*
* The server may send this message at any time. The message
* specifies the name of the configuration to switch to. The new
* configuration must exist.
*/
#include <QDataStream>
@ -443,6 +454,7 @@ namespace NetworkMessage
Location,
LoggedADIF,
HighlightCallsign,
SwitchConfiguration,
maximum_message_type_ // ONLY add new message types
// immediately before here
};

View File

@ -139,6 +139,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
, rx_df_label_ {new QLabel}
, tx_df_label_ {new QLabel}
, report_label_ {new QLabel}
, configuration_line_edit_ {new QLineEdit}
, columns_resized_ {false}
{
// set up widgets
@ -155,6 +156,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
auto form_layout = new QFormLayout;
form_layout->addRow (tr ("Free text:"), message_line_edit_);
form_layout->addRow (tr ("Temporary grid:"), grid_line_edit_);
form_layout->addRow (tr ("Configuration name:"), configuration_line_edit_);
message_line_edit_->setValidator (new QRegExpValidator {message_alphabet, this});
grid_line_edit_->setValidator (new MaidenheadLocatorValidator {this});
connect (message_line_edit_, &QLineEdit::textEdited, [this] (QString const& text) {
@ -166,6 +168,9 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
connect (grid_line_edit_, &QLineEdit::editingFinished, [this] () {
Q_EMIT location (id_, grid_line_edit_->text ());
});
connect (configuration_line_edit_, &QLineEdit::editingFinished, [this] () {
Q_EMIT switch_configuration (id_, configuration_line_edit_->text ());
});
auto decodes_page = new QWidget;
auto decodes_layout = new QVBoxLayout {decodes_page};
@ -266,7 +271,7 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
, QString const& de_call, QString const& de_grid, QString const& dx_grid
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode
, quint8 special_op_mode)
, quint8 special_op_mode, QString const& configuration_name)
{
if (id == id_)
{
@ -304,6 +309,10 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
halt_tx_button_->setEnabled (transmitting);
update_dynamic_property (mode_label_, "decoding", decoding);
update_dynamic_property (tx_df_label_, "watchdog_timeout", watchdog_timeout);
if (!configuration_line_edit_->hasFocus ())
{
configuration_line_edit_->setText (configuration_name);
}
}
}

View File

@ -34,7 +34,7 @@ public:
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
, QString const& de_call, QString const& de_grid, QString const& dx_grid
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode
, quint8 special_op_mode);
, quint8 special_op_mode, QString const& configuration_name);
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
, float delta_time, quint32 delta_frequency, QString const& mode
, QString const& message, bool low_confidence, bool off_air);
@ -52,8 +52,10 @@ public:
Q_SIGNAL void highlight_callsign (QString const& id, QString const& call
, QColor const& bg = QColor {}, QColor const& fg = QColor {}
, bool last_only = false);
Q_SIGNAL void switch_configuration (QString const& id, QString const& configuration_name);
private:
QString id_;
QListWidget const * calls_of_interest_;
class IdFilterModel final
@ -94,6 +96,7 @@ private:
QLabel * rx_df_label_;
QLabel * tx_df_label_;
QLabel * report_label_;
QLineEdit * configuration_line_edit_;
bool columns_resized_;
};

View File

@ -256,6 +256,7 @@ void MessageAggregatorMainWindow::add_client (QString const& id, QString const&
connect (dock, &ClientWidget::location, server_, &MessageServer::location);
connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible);
connect (dock, &ClientWidget::highlight_callsign, server_, &MessageServer::highlight_callsign);
connect (dock, &ClientWidget::switch_configuration, server_, &MessageServer::switch_configuration);
dock_widgets_[id] = dock;
server_->replay (id); // request decodes and status
}

View File

@ -51,7 +51,7 @@ public:
, bool /*transmitting*/, bool /*decoding*/, qint32 /*rx_df*/, qint32 /*tx_df*/
, QString const& /*de_call*/, QString const& /*de_grid*/, QString const& /*dx_grid*/
, bool /* watchdog_timeout */, QString const& sub_mode, bool /*fast_mode*/
, quint8 /*special_op_mode*/)
, quint8 /*special_op_mode*/, QString const& /*configuration_name*/)
{
if (id == id_)
{

View File

@ -560,6 +560,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
connect (m_messageClient, &MessageClient::highlight_callsign, ui->decodedTextBrowser, &DisplayText::highlight_callsign);
connect (m_messageClient, &MessageClient::switch_configuration, m_multi_settings, &MultiSettings::select_configuration);
// Hook up WSPR band hopping
connect (ui->band_hopping_schedule_push_button, &QPushButton::clicked
, &m_WSPR_band_hopping, &WSPRBandHopping::show_dialog);
@ -719,6 +721,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
else {
config_label.hide ();
}
statusUpdate ();
});
m_multi_settings->create_menu_actions (this, ui->menuConfig);
m_configurations_button = m_rigErrorMessageBox.addButton (tr ("Configurations...")
@ -7908,7 +7911,8 @@ void MainWindow::statusUpdate () const
m_config.my_callsign (), m_config.my_grid (),
m_hisGrid, m_tx_watchdog,
submode != QChar::Null ? QString {submode} : QString {}, m_bFastMode,
static_cast<quint8> (m_config.special_op_id ()));
static_cast<quint8> (m_config.special_op_id ()),
m_multi_settings->configuration_name ());
}
void MainWindow::childEvent (QChildEvent * e)