From 6bf83618509f95367841125497c73cb41d9c6f81 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 13 Nov 2015 15:44:11 +0000 Subject: [PATCH] Add decoding is busy flag to UDP Status message Updated message_aggregator reference application to show the mode label in the status bar with a cyan background colour when decoding is busy. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6089 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- MessageAggregator.cpp | 4 +- MessageClient.cpp | 51 ++++------- MessageClient.hpp | 2 +- MessageServer.cpp | 59 +++++-------- MessageServer.hpp | 3 +- NetworkMessage.hpp | 198 +++++++++++++++++++++--------------------- mainwindow.cpp | 13 ++- qss/default.qss | 4 + 8 files changed, 156 insertions(+), 178 deletions(-) diff --git a/MessageAggregator.cpp b/MessageAggregator.cpp index 2471ec2a5..6313afcb1 100644 --- a/MessageAggregator.cpp +++ b/MessageAggregator.cpp @@ -260,7 +260,8 @@ public: } Q_SLOT void update_status (QString const& id, Frequency f, QString const& mode, QString const& dx_call - , QString const& report, QString const& tx_mode, bool tx_enabled, bool transmitting) + , QString const& report, QString const& tx_mode, bool tx_enabled + , bool transmitting, bool decoding) { if (id == id_) { @@ -271,6 +272,7 @@ public: update_dynamic_property (frequency_label_, "transmitting", transmitting); auto_off_button_->setEnabled (tx_enabled); halt_tx_button_->setEnabled (transmitting); + update_dynamic_property (mode_label_, "decoding", decoding); } } diff --git a/MessageClient.cpp b/MessageClient.cpp index 47e60c45a..f29856a4f 100644 --- a/MessageClient.cpp +++ b/MessageClient.cpp @@ -50,6 +50,17 @@ public: void closedown (); StreamStatus check_status (QDataStream const&) const; void send_message (QByteArray const&); + void send_message (QDataStream const& out, QByteArray const& message) + { + if (OK == check_status (out)) + { + send_message (message); + } + else + { + Q_EMIT self_->error ("Error creating UDP message"); + } + } Q_SLOT void host_info_results (QHostInfo); @@ -305,22 +316,15 @@ void MessageClient::send_raw_datagram (QByteArray const& message, QHostAddress c void MessageClient::status_update (Frequency f, QString const& mode, QString const& dx_call , QString const& report, QString const& tx_mode - , bool tx_enabled, bool transmitting) + , bool tx_enabled, bool transmitting, bool decoding) { if (m_->server_port_ && !m_->server_string_.isEmpty ()) { QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::Status, m_->id_, m_->schema_}; out << f << mode.toUtf8 () << dx_call.toUtf8 () << report.toUtf8 () << tx_mode.toUtf8 () - << tx_enabled << transmitting; - if (impl::OK == m_->check_status (out)) - { - m_->send_message (message); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + << tx_enabled << transmitting << decoding; + m_->send_message (out, message); } } @@ -332,14 +336,7 @@ void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_tim QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_}; out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 (); - if (impl::OK == m_->check_status (out)) - { - m_->send_message (message); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message); } } @@ -349,14 +346,7 @@ void MessageClient::clear_decodes () { QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::Clear, m_->id_, m_->schema_}; - if (impl::OK == m_->check_status (out)) - { - m_->send_message (message); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message); } } @@ -371,13 +361,6 @@ void MessageClient::qso_logged (QDateTime time, QString const& dx_call, QString NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_}; out << time << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 () << report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 () << name.toUtf8 (); - if (impl::OK == m_->check_status (out)) - { - m_->send_message (message); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message); } } diff --git a/MessageClient.hpp b/MessageClient.hpp index 37f5e920d..f35b57d0e 100644 --- a/MessageClient.hpp +++ b/MessageClient.hpp @@ -47,7 +47,7 @@ public: // outgoing messages Q_SLOT void status_update (Frequency, QString const& mode, QString const& dx_call, QString const& report - , QString const& tx_mode, bool tx_enabled, bool transmitting); + , QString const& tx_mode, bool tx_enabled, bool transmitting, bool decoding); Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency , QString const& mode, QString const& message); Q_SLOT void clear_decodes (); diff --git a/MessageServer.cpp b/MessageServer.cpp index 0a97287fa..4feb0cc4f 100644 --- a/MessageServer.cpp +++ b/MessageServer.cpp @@ -43,6 +43,17 @@ public: void tick (); void pending_datagrams (); StreamStatus check_status (QDataStream const&) const; + void send_message (QDataStream const& out, QByteArray const& message, QHostAddress const& address, port_type port) + { + if (OK == check_status (out)) + { + writeDatagram (message, address, port); + } + else + { + Q_EMIT self_->error ("Error creating UDP message"); + } + } MessageServer * self_; port_type port_; @@ -182,12 +193,13 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s QByteArray tx_mode; bool tx_enabled {false}; bool transmitting {false}; - in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting; + bool decoding {false}; + in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting >> decoding; if (check_status (in) != Fail) { Q_EMIT self_->status_update (id, f, QString::fromUtf8 (mode), QString::fromUtf8 (dx_call) , QString::fromUtf8 (report), QString::fromUtf8 (tx_mode) - , tx_enabled, transmitting); + , tx_enabled, transmitting, decoding); } } break; @@ -236,11 +248,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s break; case NetworkMessage::Close: - if (check_status (in) != Fail) - { - Q_EMIT self_->client_closed (id); - clients_.remove (id); - } + Q_EMIT self_->client_closed (id); + clients_.remove (id); break; default: @@ -346,14 +355,7 @@ void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delt QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_}; out << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 (); - if (impl::OK == m_->check_status (out)) - { - m_->writeDatagram (message, iter.value ().sender_address_, (*iter).sender_port_); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); } } @@ -364,14 +366,7 @@ void MessageServer::replay (QString const& id) { QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::Replay, id, (*iter).negotiated_schema_number_}; - if (impl::OK == m_->check_status (out)) - { - m_->writeDatagram (message, iter.value ().sender_address_, (*iter).sender_port_); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); } } @@ -383,14 +378,7 @@ void MessageServer::halt_tx (QString const& id, bool auto_only) QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::HaltTx, id, (*iter).negotiated_schema_number_}; out << auto_only; - if (impl::OK == m_->check_status (out)) - { - m_->writeDatagram (message, iter.value ().sender_address_, (*iter).sender_port_); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); } } @@ -402,13 +390,6 @@ void MessageServer::free_text (QString const& id, QString const& text, bool send QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::FreeText, id, (*iter).negotiated_schema_number_}; out << text.toUtf8 () << send; - if (impl::OK == m_->check_status (out)) - { - m_->writeDatagram (message, iter.value ().sender_address_, (*iter).sender_port_); - } - else - { - Q_EMIT error ("Error creating UDP message"); - } + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); } } diff --git a/MessageServer.hpp b/MessageServer.hpp index b4fc7148d..da6a81683 100644 --- a/MessageServer.hpp +++ b/MessageServer.hpp @@ -60,7 +60,8 @@ public: // matching message Q_SIGNAL void client_opened (QString const& id); Q_SIGNAL void status_update (QString const& id, Frequency, QString const& mode, QString const& dx_call - , QString const& report, QString const& tx_mode, bool tx_enabled, bool transmitting); + , QString const& report, QString const& tx_mode, bool tx_enabled + , bool transmitting, bool decoding); 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); diff --git a/NetworkMessage.hpp b/NetworkMessage.hpp index 90bddb6e0..a96357166 100644 --- a/NetworkMessage.hpp +++ b/NetworkMessage.hpp @@ -65,7 +65,7 @@ * version can communicate with a client written to a later schema. * * Schema Version 1:- this schema used the QDataStream::Qt_5_0 version - * which is broken. + * which is broken. * * Schema Version 2:- this schema uses the QDataStream::Qt_5_2 version. * @@ -79,24 +79,24 @@ * Id (unique key) utf8 * Maximum schema number quint32 * - * The heartbeat message shall be sent on a periodic basis every - * NetworkMessage::pulse seconds (see below), the WSJT-X - * application does that using the MessageClient class. This - * message is intended to be used by servers to detect the presence - * of a client and also the unexpected disappearance of a client - * and by clients to learn the schema negotiated by the server - * after it receives the initial heartbeat message from a client. - * The message_aggregator reference server does just that using the - * MessageServer class. Upon initial startup a client must send a - * heartbeat message as soon as is practical, this message is used - * to negotiate the maximum schema number common to the client and - * server. Note that the server may not be able to support the - * client's requested maximum schema number, in which case the - * first message received from the server will specify a lower - * schema number (never a higher one as that is not allowed). If a - * server replies with a lower schema number then no higher than - * that number shall be used for all further outgoing messages from - * either clients or the server itself. + * The heartbeat message shall be sent on a periodic basis every + * NetworkMessage::pulse seconds (see below), the WSJT-X + * application does that using the MessageClient class. This + * message is intended to be used by servers to detect the presence + * of a client and also the unexpected disappearance of a client + * and by clients to learn the schema negotiated by the server + * after it receives the initial heartbeat message from a client. + * The message_aggregator reference server does just that using the + * MessageServer class. Upon initial startup a client must send a + * heartbeat message as soon as is practical, this message is used + * to negotiate the maximum schema number common to the client and + * server. Note that the server may not be able to support the + * client's requested maximum schema number, in which case the + * first message received from the server will specify a lower + * schema number (never a higher one as that is not allowed). If a + * server replies with a lower schema number then no higher than + * that number shall be used for all further outgoing messages from + * either clients or the server itself. * * * Status Out 1 quint32 @@ -108,21 +108,23 @@ * Tx Mode utf8 * Tx Enabled bool * Transmitting bool + * Decoding bool * - * WSJT-X sends this status message when various internal state - * changes to allow the server to track the relevant state of each - * client without the need for polling commands. The current state - * changes that generate status messages are: + * WSJT-X sends this status message when various internal state + * changes to allow the server to track the relevant state of each + * client without the need for polling commands. The current state + * changes that generate status messages are: * - * Application start up, - * "Enable Tx" button status changes, - * Dial frequency changes, - * Changes to the "DX Call" field, - * Operating mode changes, - * Transmit mode changed (in dual JT9+JT65 mode), - * Changes to the "Rpt" spinner, - * After an old decodes replay sequence (see Replay below), - * When switching between Tx and Rx mode. + * Application start up, + * "Enable Tx" button status changes, + * Dial frequency changes, + * Changes to the "DX Call" field, + * Operating mode changes, + * Transmit mode changed (in dual JT9+JT65 mode), + * Changes to the "Rpt" spinner, + * After an old decodes replay sequence (see Replay below), + * When switching between Tx and Rx mode, + * At the start and end of decoding. * * * Decode Out 2 quint32 @@ -135,23 +137,23 @@ * Mode utf8 * Message utf8 * - * The decode message is send when a new decode is completed, in - * this case the 'New' field is true. It is also used in response - * to a "Replay" message where each old decode in the "Band - * activity" window, that has not been erased, is sent in order - * as a one of these messages with the 'New' field set to - * false. See the "Replay" message below for details of usage. + * The decode message is send when a new decode is completed, in + * this case the 'New' field is true. It is also used in response + * to a "Replay" message where each old decode in the "Band + * activity" window, that has not been erased, is sent in order + * as a one of these messages with the 'New' field set to + * false. See the "Replay" message below for details of usage. * * * Clear Out 3 quint32 * Id (unique key) utf8 * - * This message is send when all prior "Decode" messages in the - * "Band activity" window have been discarded and therefore are - * no long available for actioning with a "Reply" message. It is - * sent when the user erases the "Band activity" window and when - * WSJT-X closes down normally. The server should discard all - * decode messages upon receipt of this message. + * This message is send when all prior "Decode" messages in the + * "Band activity" window have been discarded and therefore are + * no long available for actioning with a "Reply" message. It is + * sent when the user erases the "Band activity" window and when + * WSJT-X closes down normally. The server should discard all + * decode messages upon receipt of this message. * * * Reply In 4 quint32 @@ -163,20 +165,20 @@ * Mode utf8 * Message utf8 * - * In order for a server to provide a useful cooperative service - * to WSJT-X it is possible for it to initiate a QSO by sending - * this message to a client. WSJT-X filters this message and only - * acts upon it if the message exactly describes a prior decode - * and that decode is a CQ or QRZ message. The action taken is - * exactly equivalent to the user double clicking the message in - * the "Band activity" window. The intent of this message is for - * servers to be able to provide an advanced look up of potential - * QSO partners, for example determining if they have been worked - * before or if working them may advance some objective like - * award progress. The intention is not to provide a secondary - * user interface for WSJT-X, it is expected that after QSO - * initiation the rest of the QSO is carried out manually using - * the normal WSJT-X user interface. + * In order for a server to provide a useful cooperative service + * to WSJT-X it is possible for it to initiate a QSO by sending + * this message to a client. WSJT-X filters this message and only + * acts upon it if the message exactly describes a prior decode + * and that decode is a CQ or QRZ message. The action taken is + * exactly equivalent to the user double clicking the message in + * the "Band activity" window. The intent of this message is for + * servers to be able to provide an advanced look up of potential + * QSO partners, for example determining if they have been worked + * before or if working them may advance some objective like + * award progress. The intention is not to provide a secondary + * user interface for WSJT-X, it is expected that after QSO + * initiation the rest of the QSO is carried out manually using + * the normal WSJT-X user interface. * * * QSO Logged Out 5 quint32 @@ -192,40 +194,40 @@ * Comments utf8 * Name utf8 * - * The QSO logged message is sent to the server(s) when the - * WSJT-X user accepts the "Log QSO" dialog by clicking the "OK" - * button. + * The QSO logged message is sent to the server(s) when the + * WSJT-X user accepts the "Log QSO" dialog by clicking the "OK" + * button. * * * Close Out 6 quint32 * Id (unique key) utf8 * - * Close is sent by a client immediately prior to it shutting - * down gracefully. + * Close is sent by a client immediately prior to it shutting + * down gracefully. * * * Replay In 7 quint32 * Id (unique key) utf8 * - * When a server starts it may be useful for it to determine the - * state of preexisting clients. Sending this message to each - * client as it is discovered will cause that client (WSJT-X) to - * send a "Decode" message for each decode currently in its "Band - * activity" window. Each "Decode" message sent will have the - * "New" flag set to false so that they can be distinguished from - * new decodes. After all the old decodes have been broadcast a - * "Status" message is also broadcast. If the server wishes to - * determine the status of a newly discovered client; this - * message should be used. + * When a server starts it may be useful for it to determine the + * state of preexisting clients. Sending this message to each + * client as it is discovered will cause that client (WSJT-X) to + * send a "Decode" message for each decode currently in its "Band + * activity" window. Each "Decode" message sent will have the + * "New" flag set to false so that they can be distinguished from + * new decodes. After all the old decodes have been broadcast a + * "Status" message is also broadcast. If the server wishes to + * determine the status of a newly discovered client; this + * message should be used. * * * Halt Tx In 8 * Id (unique key) utf8 * Auto Tx Only bool * - * The server may stop a client from transmitting messages either - * immediately or at the end of the current transmission period - * using this message. + * The server may stop a client from transmitting messages either + * immediately or at the end of the current transmission period + * using this message. * * * Free Text In 9 @@ -233,30 +235,30 @@ * Text utf8 * Send bool * - * This message allows the server to set the current free text - * message content. Sending this message with a non-empty "Text" - * field is equivalent to typing a new message (old contents are - * discarded) in to the WSJT-X free text message field or "Tx5" - * field (both are updated) and if the "Send" flag is set then - * clicking the "Now" radio button for the "Tx5" field if tab one - * is current or clicking the "Free msg" radio button if tab two - * is current. + * This message allows the server to set the current free text + * message content. Sending this message with a non-empty "Text" + * field is equivalent to typing a new message (old contents are + * discarded) in to the WSJT-X free text message field or "Tx5" + * field (both are updated) and if the "Send" flag is set then + * clicking the "Now" radio button for the "Tx5" field if tab one + * is current or clicking the "Free msg" radio button if tab two + * is current. * - * It is the responsibility of the sender to limit the length of - * the message text and to limit it to legal message - * characters. Despite this, it may be difficult for the sender - * to determine the maximum message length without reimplementing - * the complete message encoding protocol. Because of this is may - * be better to allow any reasonable message length and to let - * the WSJT-X application encode and possibly truncate the actual - * on-air message. + * It is the responsibility of the sender to limit the length of + * the message text and to limit it to legal message + * characters. Despite this, it may be difficult for the sender + * to determine the maximum message length without reimplementing + * the complete message encoding protocol. Because of this is may + * be better to allow any reasonable message length and to let + * the WSJT-X application encode and possibly truncate the actual + * on-air message. * - * If the message text is empty the meaning of the message is - * refined to send the current free text unchanged when the - * "Send" flag is set or to clear the current free text when the - * "Send" flag is unset. Note that this API does not include a - * command to determine the contents of the current free text - * message. + * If the message text is empty the meaning of the message is + * refined to send the current free text unchanged when the + * "Send" flag is set or to clear the current free text when the + * "Send" flag is unset. Note that this API does not include a + * command to determine the contents of the current free text + * message. * */ diff --git a/mainwindow.cpp b/mainwindow.cpp index 5e85c4dfe..db34af0f3 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -983,7 +983,7 @@ void MainWindow::on_autoButton_clicked (bool checked) m_messageClient->status_update (m_dialFreq, m_mode, m_hisCall, QString::number (ui->rptSpinBox->value ()), m_modeTx, ui->autoButton->isChecked (), - m_transmitting); + m_transmitting, m_decoderBusy); m_bEchoTxOK=false; if(m_auto and (m_mode=="Echo")) { m_nclearave=1; @@ -1182,7 +1182,7 @@ void MainWindow::statusChanged() m_messageClient->status_update (m_dialFreq, m_mode, m_hisCall, QString::number (ui->rptSpinBox->value ()), m_modeTx, ui->autoButton->isChecked (), - m_transmitting); + m_transmitting, m_decoderBusy); QFile f {m_config.temp_dir ().absoluteFilePath ("wsjtx_status.txt")}; if(f.open(QFile::WriteOnly | QIODevice::Text)) { @@ -1755,6 +1755,11 @@ void MainWindow::decodeBusy(bool b) //decodeBusy() ui->actionOpen->setEnabled(!b); ui->actionOpen_next_in_directory->setEnabled(!b); ui->actionDecode_remaining_files_in_directory->setEnabled(!b); + + m_messageClient->status_update (m_dialFreq, m_mode, m_hisCall, + QString::number (ui->rptSpinBox->value ()), + m_modeTx, ui->autoButton->isChecked (), + m_transmitting, m_decoderBusy); } //------------------------------------------------------------- //guiUpdate() @@ -2064,7 +2069,7 @@ void MainWindow::guiUpdate() m_messageClient->status_update (m_dialFreq, m_mode, m_hisCall, QString::number (ui->rptSpinBox->value ()), m_modeTx, ui->autoButton->isChecked (), - m_transmitting); + m_transmitting, m_decoderBusy); } if(!m_btxok && btxok0 && g_iptt==1) stopTx(); @@ -2182,7 +2187,7 @@ void MainWindow::stopTx() m_messageClient->status_update (m_dialFreq, m_mode, m_hisCall, QString::number (ui->rptSpinBox->value ()), m_modeTx, ui->autoButton->isChecked (), - m_transmitting); + m_transmitting, m_decoderBusy); } void MainWindow::stopTx2() diff --git a/qss/default.qss b/qss/default.qss index f5571d5c4..bc4044d98 100644 --- a/qss/default.qss +++ b/qss/default.qss @@ -3,3 +3,7 @@ [transmitting="true"] { background-color: yellow } + +[decoding="true"] { + background-color: cyan +}