mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-02-03 09:44:24 -05:00
Extend UDP Reply message with keyboard modifiers
This allows UDP servers to emulate keyboard modified double-clicks on decoded messages, E.g. ALT+double-click for replying to a CQ or QRZ call without changing ones Tx frequency offset. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8103 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
e1da6f6e16
commit
567af321c0
@ -152,12 +152,14 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
|
|||||||
QByteArray mode;
|
QByteArray mode;
|
||||||
QByteArray message;
|
QByteArray message;
|
||||||
bool low_confidence {false};
|
bool low_confidence {false};
|
||||||
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message >> low_confidence;
|
quint8 modifiers {0};
|
||||||
|
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message
|
||||||
|
>> low_confidence >> modifiers;
|
||||||
if (check_status (in) != Fail)
|
if (check_status (in) != Fail)
|
||||||
{
|
{
|
||||||
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
|
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
|
||||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
||||||
, low_confidence);
|
, low_confidence, modifiers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -72,7 +72,7 @@ public:
|
|||||||
// this signal is emitted if the server sends us a reply, the only
|
// this signal is emitted if the server sends us a reply, the only
|
||||||
// reply supported is reply to a prior CQ or QRZ message
|
// reply supported is reply to a prior CQ or QRZ message
|
||||||
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
|
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
|
||||||
, QString const& message_text, bool low_confidence);
|
, QString const& message_text, bool low_confidence, quint8 modifiers);
|
||||||
|
|
||||||
// this signal is emitted if the server has requested a replay of
|
// this signal is emitted if the server has requested a replay of
|
||||||
// all decodes
|
// all decodes
|
||||||
|
@ -403,7 +403,9 @@ void MessageServer::start (port_type port, QHostAddress const& multicast_group_a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence)
|
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time
|
||||||
|
, quint32 delta_frequency, QString const& mode
|
||||||
|
, QString const& message_text, bool low_confidence, quint8 modifiers)
|
||||||
{
|
{
|
||||||
auto iter = m_->clients_.find (id);
|
auto iter = m_->clients_.find (id);
|
||||||
if (iter != std::end (m_->clients_))
|
if (iter != std::end (m_->clients_))
|
||||||
@ -411,7 +413,7 @@ void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delt
|
|||||||
QByteArray message;
|
QByteArray message;
|
||||||
NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_};
|
NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_};
|
||||||
out << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
out << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
||||||
<< message_text.toUtf8 () << low_confidence;
|
<< message_text.toUtf8 () << low_confidence << modifiers;
|
||||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
// note that the client is not obliged to take any action and only
|
// note that the client is not obliged to take any action and only
|
||||||
// takes any action if the decode is present and is a CQ or QRZ message
|
// takes any action if the decode is present and is a CQ or QRZ message
|
||||||
Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||||
, QString const& mode, QString const& message, bool low_confidence);
|
, QString const& mode, QString const& message, bool low_confidence, quint8 modifiers);
|
||||||
|
|
||||||
// ask the client with identification 'id' to replay all decodes
|
// ask the client with identification 'id' to replay all decodes
|
||||||
Q_SLOT void replay (QString const& id);
|
Q_SLOT void replay (QString const& id);
|
||||||
|
@ -157,7 +157,7 @@
|
|||||||
* Mode utf8
|
* Mode utf8
|
||||||
* Message utf8
|
* Message utf8
|
||||||
* Low confidence bool
|
* Low confidence bool
|
||||||
* Off air bool
|
* Off air bool
|
||||||
*
|
*
|
||||||
* The decode message is sent when a new decode is completed, in
|
* The decode message is sent when a new decode is completed, in
|
||||||
* this case the 'New' field is true. It is also used in response
|
* this case the 'New' field is true. It is also used in response
|
||||||
@ -193,6 +193,7 @@
|
|||||||
* Mode utf8
|
* Mode utf8
|
||||||
* Message utf8
|
* Message utf8
|
||||||
* Low confidence bool
|
* Low confidence bool
|
||||||
|
* Modifiers quint8
|
||||||
*
|
*
|
||||||
* In order for a server to provide a useful cooperative service
|
* 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
|
* to WSJT-X it is possible for it to initiate a QSO by sending
|
||||||
@ -209,6 +210,19 @@
|
|||||||
* initiation the rest of the QSO is carried out manually using
|
* initiation the rest of the QSO is carried out manually using
|
||||||
* the normal WSJT-X user interface.
|
* the normal WSJT-X user interface.
|
||||||
*
|
*
|
||||||
|
* The Modifiers field allows the equivalent of keyboard
|
||||||
|
* modifiers to be sent "as if" those modifier keys where pressed
|
||||||
|
* while double-clicking the specified decoded message. The
|
||||||
|
* modifier values (hexadecimal) are as follows:
|
||||||
|
*
|
||||||
|
* no modifier 0x00
|
||||||
|
* SHIFT 0x02
|
||||||
|
* CTRL 0x04 CMD on Mac
|
||||||
|
* ALT 0x08
|
||||||
|
* META 0x10 Windows key on MS Windows
|
||||||
|
* KEYPAD 0x20 Keypad or arrows
|
||||||
|
* Group switch 0x40 X11 only
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* QSO Logged Out 5 quint32
|
* QSO Logged Out 5 quint32
|
||||||
* Id (unique key) utf8
|
* Id (unique key) utf8
|
||||||
|
@ -208,7 +208,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
|||||||
|
|
||||||
// connect up table view signals
|
// connect up table view signals
|
||||||
connect (decodes_table_view_, &QTableView::doubleClicked, this, [this] (QModelIndex const& index) {
|
connect (decodes_table_view_, &QTableView::doubleClicked, this, [this] (QModelIndex const& index) {
|
||||||
Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index));
|
Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index), QApplication::keyboardModifiers () >> 24);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
, QString const& callsign, QString const& grid, qint32 power
|
, QString const& callsign, QString const& grid, qint32 power
|
||||||
, bool off_air);
|
, bool off_air);
|
||||||
|
|
||||||
Q_SIGNAL void do_reply (QModelIndex const&);
|
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier);
|
||||||
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
|
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
|
||||||
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
|
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ void DecodesModel::clear_decodes (QString const& client_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodesModel::do_reply (QModelIndex const& source)
|
void DecodesModel::do_reply (QModelIndex const& source, quint8 modifiers)
|
||||||
{
|
{
|
||||||
auto row = source.row ();
|
auto row = source.row ();
|
||||||
Q_EMIT reply (data (index (row, 0)).toString ()
|
Q_EMIT reply (data (index (row, 0)).toString ()
|
||||||
@ -146,7 +146,8 @@ void DecodesModel::do_reply (QModelIndex const& source)
|
|||||||
, item (row, 4)->data ().toInt ()
|
, item (row, 4)->data ().toInt ()
|
||||||
, data (index (row, 5)).toString ()
|
, data (index (row, 5)).toString ()
|
||||||
, data (index (row, 6)).toString ()
|
, data (index (row, 6)).toString ()
|
||||||
, confidence_string (true) == data (index (row, 7)).toString ());
|
, confidence_string (true) == data (index (row, 7)).toString ()
|
||||||
|
, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_DecodesModel.cpp"
|
#include "moc_DecodesModel.cpp"
|
||||||
|
@ -35,10 +35,10 @@ public:
|
|||||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||||
, bool low_confidence, bool off_air, bool is_fast);
|
, bool low_confidence, bool off_air, bool is_fast);
|
||||||
Q_SLOT void clear_decodes (QString const& client_id);
|
Q_SLOT void clear_decodes (QString const& client_id);
|
||||||
Q_SLOT void do_reply (QModelIndex const& source);
|
Q_SLOT void do_reply (QModelIndex const& source, quint8 modifiers);
|
||||||
|
|
||||||
Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||||
, QString const& mode, QString const& message, bool low_confidence);
|
, QString const& mode, QString const& message, bool low_confidence, quint8 modifiers);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6130,7 +6130,9 @@ void MainWindow::on_cbTx6_toggled(bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Takes a decoded CQ line and sets it up for reply
|
// Takes a decoded CQ line and sets it up for reply
|
||||||
void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text)
|
void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||||
|
, QString const& mode, QString const& message_text
|
||||||
|
, bool /*low_confidence*/, quint8 modifiers)
|
||||||
{
|
{
|
||||||
if (!m_config.accept_udp_requests ())
|
if (!m_config.accept_udp_requests ())
|
||||||
{
|
{
|
||||||
@ -6140,14 +6142,14 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
|
|||||||
if (message_text.contains (QRegularExpression {R"(^(CQ |CQDX |QRZ ))"}))
|
if (message_text.contains (QRegularExpression {R"(^(CQ |CQDX |QRZ ))"}))
|
||||||
{
|
{
|
||||||
// a message we are willing to accept
|
// a message we are willing to accept
|
||||||
QString format_string {"%1 %2 %3 %4 %5 %6"};
|
QString format_string {"%1 %2 %3 %4 %5 %6"};
|
||||||
auto const& time_string = time.toString ("~" == mode || "&" == mode ? "hhmmss" : "hhmm");
|
auto const& time_string = time.toString ("~" == mode || "&" == mode ? "hhmmss" : "hhmm");
|
||||||
auto cqtext = format_string
|
auto cqtext = format_string
|
||||||
.arg (time_string)
|
.arg (time_string)
|
||||||
.arg (snr, 3)
|
.arg (snr, 3)
|
||||||
.arg (delta_time, 4, 'f', 1)
|
.arg (delta_time, 4, 'f', 1)
|
||||||
.arg (delta_frequency, 4)
|
.arg (delta_frequency, 4)
|
||||||
.arg (mode)
|
.arg (mode, 2)
|
||||||
.arg (message_text);
|
.arg (message_text);
|
||||||
auto messages = ui->decodedTextBrowser->toPlainText ();
|
auto messages = ui->decodedTextBrowser->toPlainText ();
|
||||||
auto position = messages.lastIndexOf (cqtext);
|
auto position = messages.lastIndexOf (cqtext);
|
||||||
@ -6159,7 +6161,7 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
|
|||||||
.arg (snr, 3)
|
.arg (snr, 3)
|
||||||
.arg ('-' + QString::number (delta_time, 'f', 1), 4)
|
.arg ('-' + QString::number (delta_time, 'f', 1), 4)
|
||||||
.arg (delta_frequency, 4)
|
.arg (delta_frequency, 4)
|
||||||
.arg (mode)
|
.arg (mode, 2)
|
||||||
.arg (message_text));
|
.arg (message_text));
|
||||||
}
|
}
|
||||||
if (position >= 0)
|
if (position >= 0)
|
||||||
@ -6180,8 +6182,9 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de
|
|||||||
m_bDoubleClicked = true;
|
m_bDoubleClicked = true;
|
||||||
auto start = messages.left (position).lastIndexOf (QChar::LineFeed) + 1;
|
auto start = messages.left (position).lastIndexOf (QChar::LineFeed) + 1;
|
||||||
DecodedText message {messages.mid (start, position - start), ("MSK144" == m_mode || "FT8" == m_mode) &&
|
DecodedText message {messages.mid (start, position - start), ("MSK144" == m_mode || "FT8" == m_mode) &&
|
||||||
ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
|
ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
|
||||||
processMessage (message);
|
Qt::KeyboardModifiers kbmod {modifiers << 24};
|
||||||
|
processMessage (message, kbmod & Qt::ControlModifier,kbmod & Qt::AltModifier);
|
||||||
tx_watchdog (false);
|
tx_watchdog (false);
|
||||||
QApplication::alert (this);
|
QApplication::alert (this);
|
||||||
}
|
}
|
||||||
@ -6239,7 +6242,7 @@ void MainWindow::postDecode (bool is_new, QString const& message)
|
|||||||
m_messageClient->decode (is_new
|
m_messageClient->decode (is_new
|
||||||
, QTime::fromString (parts[0], has_seconds ? "hhmmss" : "hhmm")
|
, QTime::fromString (parts[0], has_seconds ? "hhmmss" : "hhmm")
|
||||||
, parts[1].toInt ()
|
, parts[1].toInt ()
|
||||||
, parts[2].toFloat (), parts[3].toUInt (), parts[4][0]
|
, parts[2].toFloat (), parts[3].toUInt (), parts[4]
|
||||||
, decode.mid (has_seconds ? 24 : 22, 21)
|
, decode.mid (has_seconds ? 24 : 22, 21)
|
||||||
, QChar {'?'} == decode.mid (has_seconds ? 24 + 21 : 22 + 21, 1)
|
, QChar {'?'} == decode.mid (has_seconds ? 24 + 21 : 22 + 21, 1)
|
||||||
, m_diskData);
|
, m_diskData);
|
||||||
|
@ -597,7 +597,7 @@ private:
|
|||||||
void displayDialFrequency ();
|
void displayDialFrequency ();
|
||||||
void transmitDisplay (bool);
|
void transmitDisplay (bool);
|
||||||
void processMessage(DecodedText const&, bool ctrl = false, bool alt = false);
|
void processMessage(DecodedText const&, bool ctrl = false, bool alt = false);
|
||||||
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
|
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence, quint8 modifiers);
|
||||||
void replayDecodes ();
|
void replayDecodes ();
|
||||||
void postDecode (bool is_new, QString const& message);
|
void postDecode (bool is_new, QString const& message);
|
||||||
void postWSPRDecode (bool is_new, QStringList message_parts);
|
void postWSPRDecode (bool is_new, QStringList message_parts);
|
||||||
|
Loading…
Reference in New Issue
Block a user