Merge branch 'master' into develop

This commit is contained in:
Bill Somerville 2019-02-25 00:44:58 +00:00
commit a12e71f352
28 changed files with 269 additions and 93 deletions

View File

@ -10,10 +10,10 @@ if (APPLE)
# #
# otool -l <binary> | grep -A3 LC_VERSION_MIN_MACOSX # otool -l <binary> | grep -A3 LC_VERSION_MIN_MACOSX
# #
set (CMAKE_OSX_DEPLOYMENT_TARGET 10.9 set (CMAKE_OSX_DEPLOYMENT_TARGET 10.10
CACHE STRING "Earliest version of OS X supported CACHE STRING "Earliest version of OS X supported
Earliest version we can support with Qt 5.8, C++11 & libc++ is 10.9. Earliest version we can support with Qt 5.8, C++11 & libc++ is 10.10.
Do not override this if you intend to build an official deployable installer.") Do not override this if you intend to build an official deployable installer.")
set (CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk set (CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk
CACHE STRING "Mac OS X SDK to build with CACHE STRING "Mac OS X SDK to build with
@ -848,6 +848,7 @@ set (hamlib_STATIC 1)
find_package (hamlib 3 REQUIRED) find_package (hamlib 3 REQUIRED)
find_program (RIGCTL_EXE rigctl) find_program (RIGCTL_EXE rigctl)
find_program (RIGCTLD_EXE rigctld) find_program (RIGCTLD_EXE rigctld)
find_program (RIGCTLCOM_EXE rigctlcom)
message (STATUS "hamlib_INCLUDE_DIRS: ${hamlib_INCLUDE_DIRS}") message (STATUS "hamlib_INCLUDE_DIRS: ${hamlib_INCLUDE_DIRS}")
message (STATUS "hamlib_LIBRARIES: ${hamlib_LIBRARIES}") message (STATUS "hamlib_LIBRARIES: ${hamlib_LIBRARIES}")
@ -1417,6 +1418,13 @@ install (PROGRAMS
RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX} RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
) )
install (PROGRAMS
${RIGCTLCOM_EXE}
DESTINATION ${CMAKE_INSTALL_BINDIR}
#COMPONENT runtime
RENAME rigctlcom-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
)
install (FILES install (FILES
README README
COPYING COPYING

View File

@ -188,6 +188,18 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
} }
break; break;
case NetworkMessage::Clear:
{
quint8 window {0};
in >> window;
TRACE_UDP ("Clear window:" << window);
if (check_status (in) != Fail)
{
Q_EMIT self_->clear_decodes (window);
}
}
break;
case NetworkMessage::Replay: case NetworkMessage::Replay:
TRACE_UDP ("Replay"); TRACE_UDP ("Replay");
if (check_status (in) != Fail) if (check_status (in) != Fail)
@ -477,7 +489,7 @@ void MessageClient::WSPR_decode (bool is_new, QTime time, qint32 snr, float delt
} }
} }
void MessageClient::clear_decodes () void MessageClient::decodes_cleared ()
{ {
if (m_->server_port_ && !m_->server_string_.isEmpty ()) if (m_->server_port_ && !m_->server_string_.isEmpty ())
{ {

View File

@ -59,7 +59,7 @@ public:
Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency
, qint32 drift, QString const& callsign, QString const& grid, qint32 power , qint32 drift, QString const& callsign, QString const& grid, qint32 power
, bool off_air); , bool off_air);
Q_SLOT void clear_decodes (); Q_SLOT void decodes_cleared ();
Q_SLOT void qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid Q_SLOT void qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent , Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power, QString const& comments , QString const& report_received, QString const& tx_power, QString const& comments
@ -80,6 +80,10 @@ public:
// with send_raw_datagram() above) // with send_raw_datagram() above)
Q_SLOT void add_blocked_destination (QHostAddress const&); Q_SLOT void add_blocked_destination (QHostAddress const&);
// this signal is emitted if the server has requested a decode
// window clear action
Q_SIGNAL void clear_decodes (quint8 window);
// 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

View File

@ -224,7 +224,7 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
break; break;
case NetworkMessage::Clear: case NetworkMessage::Clear:
Q_EMIT self_->clear_decodes (id); Q_EMIT self_->decodes_cleared (id);
break; break;
case NetworkMessage::Status: case NetworkMessage::Status:
@ -455,6 +455,18 @@ void MessageServer::start (port_type port, QHostAddress const& multicast_group_a
} }
} }
void MessageServer::clear_decodes (QString const& id, quint8 window)
{
auto iter = m_->clients_.find (id);
if (iter != std::end (m_->clients_))
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::Clear, id, (*iter).negotiated_schema_number_};
out << window;
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
}
}
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode , quint32 delta_frequency, QString const& mode
, QString const& message_text, bool low_confidence, quint8 modifiers) , QString const& message_text, bool low_confidence, quint8 modifiers)

View File

@ -41,6 +41,9 @@ public:
Q_SLOT void start (port_type port, Q_SLOT void start (port_type port,
QHostAddress const& multicast_group_address = QHostAddress {}); QHostAddress const& multicast_group_address = QHostAddress {});
// ask the client to clear one or both of the decode windows
Q_SLOT void clear_decodes (QString const& id, quint8 window = 0);
// ask the client with identification 'id' to make the same action // ask the client with identification 'id' to make the same action
// as a double click on the decode would // as a double click on the decode would
// //
@ -91,7 +94,7 @@ public:
, QString const& name, QDateTime time_on, QString const& operator_call , QString const& name, QDateTime time_on, QString const& operator_call
, QString const& my_call, QString const& my_grid , QString const& my_call, QString const& my_grid
, QString const& exchange_sent, QString const& exchange_rcvd); , QString const& exchange_sent, QString const& exchange_rcvd);
Q_SIGNAL void clear_decodes (QString const& id); Q_SIGNAL void decodes_cleared (QString const& id);
Q_SIGNAL void logged_ADIF (QString const& id, QByteArray const& ADIF); Q_SIGNAL void logged_ADIF (QString const& id, QByteArray const& ADIF);
// this signal is emitted when a network error occurs // this signal is emitted when a network error occurs

View File

@ -186,16 +186,26 @@
* back a .WAV file. * back a .WAV file.
* *
* *
* Clear Out 3 quint32 * Clear Out/In 3 quint32
* Id (unique key) utf8 * Id (unique key) utf8
* Window quint8 (In only)
* *
* This message is send when all prior "Decode" messages in the * This message is send when all prior "Decode" messages in the
* "Band activity" window have been discarded and therefore are * "Band Activity" window have been discarded and therefore are
* no long available for actioning with a "Reply" message. It is * no long available for actioning with a "Reply" message. It is
* sent when the user erases the "Band activity" window and when * sent when the user erases the "Band activity" window and when
* WSJT-X closes down normally. The server should discard all * WSJT-X closes down normally. The server should discard all
* decode messages upon receipt of this message. * decode messages upon receipt of this message.
* *
* It may also be sent to a WSJT-X instance in which case it
* clears one or both of the "Band Activity" and "Rx Frequency"
* windows. The Window argument can be one of the following
* values:
*
* 0 - clear the "Band Activity" window (default)
* 1 - clear the "Rx Frequency" window
* 2 - clear both "Band Activity" and "Rx Frequency" windows
*
* *
* Reply In 4 quint32 * Reply In 4 quint32
* Id (target unique key) utf8 * Id (target unique key) utf8

View File

@ -121,7 +121,7 @@ void BeaconsModel::add_beacon_spot (bool is_new, QString const& client_id, QTime
appendRow (make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power, off_air)); appendRow (make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power, off_air));
} }
void BeaconsModel::clear_decodes (QString const& client_id) void BeaconsModel::decodes_cleared (QString const& client_id)
{ {
for (auto row = rowCount () - 1; row >= 0; --row) for (auto row = rowCount () - 1; row >= 0; --row)
{ {

View File

@ -32,7 +32,7 @@ public:
Q_SLOT void add_beacon_spot (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time Q_SLOT void add_beacon_spot (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
, Frequency frequency, qint32 drift, QString const& callsign, QString const& grid , Frequency frequency, qint32 drift, QString const& callsign, QString const& grid
, qint32 power, bool off_air); , qint32 power, bool off_air);
Q_SLOT void clear_decodes (QString const& client_id); Q_SLOT void decodes_cleared (QString const& client_id);
}; };
#endif #endif

View File

@ -2,6 +2,7 @@
#include <QRegExp> #include <QRegExp>
#include <QColor> #include <QColor>
#include <QAction>
#include "validators/MaidenheadLocatorValidator.hpp" #include "validators/MaidenheadLocatorValidator.hpp"
@ -120,6 +121,9 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
, id_ {id} , id_ {id}
, calls_of_interest_ {calls_of_interest} , calls_of_interest_ {calls_of_interest}
, decodes_proxy_model_ {id_} , decodes_proxy_model_ {id_}
, erase_action_ {new QAction {tr ("&Erase Band Activity"), this}}
, erase_rx_frequency_action_ {new QAction {tr ("Erase &Rx Frequency"), this}}
, erase_both_action_ {new QAction {tr ("Erase &Both"), this}}
, decodes_table_view_ {new QTableView} , decodes_table_view_ {new QTableView}
, beacons_table_view_ {new QTableView} , beacons_table_view_ {new QTableView}
, message_line_edit_ {new QLineEdit} , message_line_edit_ {new QLineEdit}
@ -143,6 +147,10 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
decodes_table_view_->verticalHeader ()->hide (); decodes_table_view_->verticalHeader ()->hide ();
decodes_table_view_->hideColumn (0); decodes_table_view_->hideColumn (0);
decodes_table_view_->horizontalHeader ()->setStretchLastSection (true); decodes_table_view_->horizontalHeader ()->setStretchLastSection (true);
decodes_table_view_->setContextMenuPolicy (Qt::ActionsContextMenu);
decodes_table_view_->insertAction (nullptr, erase_action_);
decodes_table_view_->insertAction (nullptr, erase_rx_frequency_action_);
decodes_table_view_->insertAction (nullptr, erase_both_action_);
auto form_layout = new QFormLayout; auto form_layout = new QFormLayout;
form_layout->addRow (tr ("Free text:"), message_line_edit_); form_layout->addRow (tr ("Free text:"), message_line_edit_);
@ -171,6 +179,8 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
beacons_table_view_->verticalHeader ()->hide (); beacons_table_view_->verticalHeader ()->hide ();
beacons_table_view_->hideColumn (0); beacons_table_view_->hideColumn (0);
beacons_table_view_->horizontalHeader ()->setStretchLastSection (true); beacons_table_view_->horizontalHeader ()->setStretchLastSection (true);
beacons_table_view_->setContextMenuPolicy (Qt::ActionsContextMenu);
beacons_table_view_->insertAction (nullptr, erase_action_);
auto beacons_page = new QWidget; auto beacons_page = new QWidget;
auto beacons_layout = new QVBoxLayout {beacons_page}; auto beacons_layout = new QVBoxLayout {beacons_page};
@ -219,8 +229,19 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
setAllowedAreas (Qt::BottomDockWidgetArea); setAllowedAreas (Qt::BottomDockWidgetArea);
setFloating (true); setFloating (true);
// connect context menu actions
connect (erase_action_, &QAction::triggered, [this] (bool /*checked*/) {
Q_EMIT do_clear_decodes (id_);
});
connect (erase_rx_frequency_action_, &QAction::triggered, [this] (bool /*checked*/) {
Q_EMIT do_clear_decodes (id_, 1);
});
connect (erase_both_action_, &QAction::triggered, [this] (bool /*checked*/) {
Q_EMIT do_clear_decodes (id_, 2);
});
// 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] (QModelIndex const& index) {
Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index), QApplication::keyboardModifiers () >> 24); Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index), QApplication::keyboardModifiers () >> 24);
}); });
@ -313,7 +334,7 @@ void ClientWidget::beacon_spot_added (bool /*is_new*/, QString const& client_id,
beacons_table_view_->scrollToBottom (); beacons_table_view_->scrollToBottom ();
} }
void ClientWidget::clear_decodes (QString const& client_id) void ClientWidget::decodes_cleared (QString const& client_id)
{ {
if (client_id == id_) if (client_id == id_)
{ {

View File

@ -12,6 +12,7 @@
class QAbstractItemModel; class QAbstractItemModel;
class QModelIndex; class QModelIndex;
class QColor; class QColor;
class QAction;
using Frequency = MessageServer::Frequency; using Frequency = MessageServer::Frequency;
@ -41,8 +42,9 @@ public:
, float delta_time, Frequency delta_frequency, qint32 drift , float delta_time, Frequency delta_frequency, qint32 drift
, QString const& callsign, QString const& grid, qint32 power , QString const& callsign, QString const& grid, qint32 power
, bool off_air); , bool off_air);
Q_SLOT void clear_decodes (QString const& client_id); Q_SLOT void decodes_cleared (QString const& client_id);
Q_SIGNAL void do_clear_decodes (QString const& id, quint8 window = 0);
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier); 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);
@ -74,6 +76,9 @@ private:
QRegularExpression base_call_re_; QRegularExpression base_call_re_;
int rx_df_; int rx_df_;
} decodes_proxy_model_; } decodes_proxy_model_;
QAction * erase_action_;
QAction * erase_rx_frequency_action_;
QAction * erase_both_action_;
QTableView * decodes_table_view_; QTableView * decodes_table_view_;
QTableView * beacons_table_view_; QTableView * beacons_table_view_;
QLineEdit * message_line_edit_; QLineEdit * message_line_edit_;

View File

@ -125,7 +125,7 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
, off_air, is_fast)); , off_air, is_fast));
} }
void DecodesModel::clear_decodes (QString const& client_id) void DecodesModel::decodes_cleared (QString const& client_id)
{ {
for (auto row = rowCount () - 1; row >= 0; --row) for (auto row = rowCount () - 1; row >= 0; --row)
{ {

View File

@ -34,7 +34,7 @@ public:
Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
, 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 decodes_cleared (QString const& client_id);
Q_SLOT void do_reply (QModelIndex const& source, quint8 modifiers); 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

View File

@ -181,8 +181,8 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
}); });
connect (server_, &MessageServer::client_opened, this, &MessageAggregatorMainWindow::add_client); connect (server_, &MessageServer::client_opened, this, &MessageAggregatorMainWindow::add_client);
connect (server_, &MessageServer::client_closed, this, &MessageAggregatorMainWindow::remove_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, decodes_model_, &DecodesModel::decodes_cleared);
connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::clear_decodes); connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::decodes_cleared);
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
, qint32 snr, float delta_time , qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode , quint32 delta_frequency, QString const& mode
@ -191,8 +191,8 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message
, low_confidence, off_air, dock_widgets_[id]->fast_mode ());}); , low_confidence, off_air, dock_widgets_[id]->fast_mode ());});
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot); connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes); connect (server_, &MessageServer::decodes_cleared, decodes_model_, &DecodesModel::decodes_cleared);
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes); connect (server_, &MessageServer::decodes_cleared, beacons_model_, &BeaconsModel::decodes_cleared);
connect (decodes_model_, &DecodesModel::reply, server_, &MessageServer::reply); connect (decodes_model_, &DecodesModel::reply, server_, &MessageServer::reply);
// UI behaviour // UI behaviour
@ -248,7 +248,8 @@ void MessageAggregatorMainWindow::add_client (QString const& id, QString const&
connect (server_, &MessageServer::status_update, dock, &ClientWidget::update_status); connect (server_, &MessageServer::status_update, dock, &ClientWidget::update_status);
connect (server_, &MessageServer::decode, dock, &ClientWidget::decode_added); connect (server_, &MessageServer::decode, dock, &ClientWidget::decode_added);
connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added); connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added);
connect (server_, &MessageServer::clear_decodes, dock, &ClientWidget::clear_decodes); connect (server_, &MessageServer::decodes_cleared, dock, &ClientWidget::decodes_cleared);
connect (dock, &ClientWidget::do_clear_decodes, server_, &MessageServer::clear_decodes);
connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply); connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply);
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx); connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text); connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);

View File

@ -1,24 +1,24 @@
subroutine chkcrc13a(decoded,nbadcrc) subroutine chkcrc13a(decoded,nbadcrc)
use crc use crc
integer*1 decoded(90) integer*1 decoded(90)
integer*1, target:: i1Dec8BitBytes(12) integer*1, target:: i1Dec8BitBytes(12)
character*90 cbits character*90 cbits
! Write decoded bits into cbits: 77-bit message plus 13-bit CRC ! Write decoded bits into cbits: 77-bit message plus 13-bit CRC
write(cbits,1000) decoded write(cbits,1000) decoded
1000 format(90i1) 1000 format(90i1)
read(cbits,1001) i1Dec8BitBytes read(cbits,1001) i1Dec8BitBytes
1001 format(12b8) 1001 format(12b8)
read(cbits,1002) ncrc13 !Received CRC13 read(cbits,1002) ncrc13 !Received CRC13
1002 format(77x,b13) 1002 format(77x,b13)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32+16+8) i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),transfer(128+64+32+16+8,0_1))
i1Dec8BitBytes(11:12)=0 i1Dec8BitBytes(11:12)=0
icrc13=crc13(c_loc(i1Dec8BitBytes),12) !CRC13 computed from 77 msg bits icrc13=crc13(c_loc(i1Dec8BitBytes),12) !CRC13 computed from 77 msg bits
nbadcrc=1 nbadcrc=1
if(ncrc13.eq.icrc13) nbadcrc=0 if(ncrc13.eq.icrc13) nbadcrc=0
return return
end subroutine chkcrc13a end subroutine chkcrc13a

View File

@ -1,24 +1,24 @@
subroutine chkcrc14a(decoded,nbadcrc) subroutine chkcrc14a(decoded,nbadcrc)
use crc use crc
integer*1 decoded(91) integer*1 decoded(91)
integer*1, target:: i1Dec8BitBytes(12) integer*1, target:: i1Dec8BitBytes(12)
character*91 cbits character*91 cbits
! Write decoded bits into cbits: 77-bit message plus 14-bit CRC ! Write decoded bits into cbits: 77-bit message plus 14-bit CRC
write(cbits,1000) decoded write(cbits,1000) decoded
1000 format(91i1) 1000 format(91i1)
read(cbits,1001) i1Dec8BitBytes read(cbits,1001) i1Dec8BitBytes
1001 format(12b8) 1001 format(12b8)
read(cbits,1002) ncrc14 !Received CRC14 read(cbits,1002) ncrc14 !Received CRC14
1002 format(77x,b14) 1002 format(77x,b14)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32+16+8) i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),transfer(128+64+32+16+8,0_1))
i1Dec8BitBytes(11:12)=0 i1Dec8BitBytes(11:12)=0
icrc14=crc14(c_loc(i1Dec8BitBytes),12) !CRC14 computed from 77 msg bits icrc14=crc14(c_loc(i1Dec8BitBytes),12) !CRC14 computed from 77 msg bits
nbadcrc=1 nbadcrc=1
if(ncrc14.eq.icrc14) nbadcrc=0 if(ncrc14.eq.icrc14) nbadcrc=0
return return
end subroutine chkcrc14a end subroutine chkcrc14a

View File

@ -17,7 +17,7 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
read(cbits,1002) ncrc12 !Received CRC12 read(cbits,1002) ncrc12 !Received CRC12
1002 format(75x,b12) 1002 format(75x,b12)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32) i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),transfer(128+64+32,0_1))
i1Dec8BitBytes(11)=0 i1Dec8BitBytes(11)=0
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
@ -26,7 +26,7 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
do ibyte=1,12 do ibyte=1,12
itmp=0 itmp=0
do ibit=1,6 do ibit=1,6
itmp=ishft(itmp,1)+iand(1,decoded((ibyte-1)*6+ibit)) itmp=ishft(itmp,1)+iand(1_1,decoded((ibyte-1)*6+ibit))
enddo enddo
i4Dec6BitWords(ibyte)=itmp i4Dec6BitWords(ibyte)=itmp
enddo enddo

View File

@ -17,7 +17,7 @@ subroutine extractmessage174_91(decoded,msgreceived,ncrcflag)
read(cbits,1002) ncrc14 !Received CRC12 read(cbits,1002) ncrc14 !Received CRC12
1002 format(77x,b14) 1002 format(77x,b14)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32+16+8) i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),transfer(128+64+32+16+8,0_1))
i1Dec8BitBytes(11:12)=0 i1Dec8BitBytes(11:12)=0
icrc14=crc14(c_loc(i1Dec8BitBytes),12) !CRC12 computed from 75 msg bits icrc14=crc14(c_loc(i1Dec8BitBytes),12) !CRC12 computed from 75 msg bits
@ -26,7 +26,7 @@ subroutine extractmessage174_91(decoded,msgreceived,ncrcflag)
do ibyte=1,12 do ibyte=1,12
itmp=0 itmp=0
do ibit=1,6 do ibit=1,6
itmp=ishft(itmp,1)+iand(1,decoded((ibyte-1)*6+ibit)) itmp=ishft(itmp,1)+iand(1_1,decoded((ibyte-1)*6+ibit))
enddo enddo
i4Dec6BitWords(ibyte)=itmp i4Dec6BitWords(ibyte)=itmp
enddo enddo

View File

@ -128,7 +128,7 @@ subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, &
imsg=0 imsg=0
do i=1,16 do i=1,16
imsg=ishft(imsg,1)+iand(1,decoded(17-i)) imsg=ishft(imsg,1)+iand(1_1,decoded(17-i))
enddo enddo
nrxrpt=iand(imsg,15) nrxrpt=iand(imsg,15)
nrxhash=(imsg-nrxrpt)/16 nrxhash=(imsg-nrxrpt)/16

View File

@ -4,6 +4,7 @@ set (ASCIIDOC_MANS
man1/jt65code.1.txt man1/jt65code.1.txt
man1/rigctl-wsjtx.1.txt man1/rigctl-wsjtx.1.txt
man1/rigctld-wsjtx.1.txt man1/rigctld-wsjtx.1.txt
man1/rigctlcom-wsjtx.1.txt
man1/message_aggregator.1.txt man1/message_aggregator.1.txt
man1/udp_daemon.1.txt man1/udp_daemon.1.txt
) )

View File

@ -6,7 +6,7 @@
== NAME == NAME
rigctl-wsjtx - Hamlib 3 rigctld server. rigctl-wsjtx - Hamlib 4 rigctld server.
== SYNOPSIS == SYNOPSIS
@ -15,7 +15,7 @@ rigctl-wsjtx - Hamlib 3 rigctld server.
== DESCRIPTION == DESCRIPTION
*wsjtx* uses a version of the *hamlib* CAT control library. This *wsjtx* uses a version of the *hamlib* CAT control library. This
library is heavily modified over the current release version of library is virtually identical to the the current release version of
*hamlib*. If a *wsjtx* user wishes to use the *hamlib* network rig *hamlib*. If a *wsjtx* user wishes to use the *hamlib* network rig
server *rigctld* to remotely control their transceiver; then this server *rigctld* to remotely control their transceiver; then this
special version of the *rigctl* client should be used since that too special version of the *rigctl* client should be used since that too

View File

@ -0,0 +1,30 @@
:doctype: manpage
:man source: AsciiDoc
:man version: {revnumber}
:man manual: WSJT-X Manual
= rigctlcom-wsjtx(1)
== NAME
rigctlcom-wsjtx - Hamlib 4 rigctlcom Serial port passthru Kenwood TS-2000 emulator.
== SYNOPSIS
*rigctlcom-wsjtx* [OPTIONS]
== DESCRIPTION
*wsjtx* uses a version of the *hamlib* CAT control library. This
library is virtually identical to the current release version of
*hamlib*. If a *wsjtx* user wishes to use the *hamlib* TS-2000
emulator *rigctlcom* to allow CAT applications that do not talk to
*hamlib* to share CAT control control their transceiver; then this
special version of *rigctlcom* should be used since that too has the
modified *hamlib* code embedded with it.
WSJT-X home page:: http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html
WSJT-X User's Guide:: http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/wsjtx-main-toc2.html
== OPTIONS
Refer to the *hamlib* documentation.

View File

@ -6,7 +6,7 @@
== NAME == NAME
rigctld-wsjtx - Hamlib 3 rigctld server. rigctld-wsjtx - Hamlib 4 rigctld server.
== SYNOPSIS == SYNOPSIS
@ -15,7 +15,7 @@ rigctld-wsjtx - Hamlib 3 rigctld server.
== DESCRIPTION == DESCRIPTION
*wsjtx* uses a version of the *hamlib* CAT control library. This *wsjtx* uses a version of the *hamlib* CAT control library. This
library is heavily modified over the current release version of library is virtually identical to the current release version of
*hamlib*. If a *wsjtx* user wishes to use the *hamlib* network rig *hamlib*. If a *wsjtx* user wishes to use the *hamlib* network rig
server *rigctld* to remotely control their transceiver; then this server *rigctld* to remotely control their transceiver; then this
special version of *rigctld* should be used since that too has the special version of *rigctld* should be used since that too has the

View File

@ -21,6 +21,8 @@ class CabrilloLog::impl final
public: public:
impl (Configuration const *); impl (Configuration const *);
QString cabrillo_frequency_string (Radio::Frequency frequency) const;
Configuration const * configuration_; Configuration const * configuration_;
QSqlQuery mutable dupe_query_; QSqlQuery mutable dupe_query_;
QSqlQuery mutable export_query_; QSqlQuery mutable export_query_;
@ -46,10 +48,25 @@ CabrilloLog::impl::impl (Configuration const * configuration)
} }
SQL_error_check (dupe_query_, &QSqlQuery::prepare, SQL_error_check (dupe_query_, &QSqlQuery::prepare,
"SELECT COUNT(*) FROM cabrillo_log WHERE call = :call AND band = :band"); "SELECT "
" COUNT(*) "
" FROM "
" cabrillo_log "
" WHERE "
" call = :call "
" AND band = :band");
SQL_error_check (export_query_, &QSqlQuery::prepare, SQL_error_check (export_query_, &QSqlQuery::prepare,
"SELECT frequency, \"when\", exchange_sent, call, exchange_rcvd FROM cabrillo_log ORDER BY \"when\""); "SELECT "
" frequency"
" , \"when\""
" , exchange_sent"
" , call"
" , exchange_rcvd"
" FROM "
" cabrillo_log "
" ORDER BY "
" \"when\"");
setEditStrategy (QSqlTableModel::OnFieldChange); setEditStrategy (QSqlTableModel::OnFieldChange);
setTable ("cabrillo_log"); setTable ("cabrillo_log");
@ -68,6 +85,32 @@ CabrilloLog::impl::impl (Configuration const * configuration)
SQL_error_check (*this, &QSqlTableModel::select); SQL_error_check (*this, &QSqlTableModel::select);
} }
// frequency here is in kHz
QString CabrilloLog::impl::cabrillo_frequency_string (Radio::Frequency frequency) const
{
QString result;
auto band = configuration_->bands ()->find (frequency * 1000ull);
if ("1mm" == band) result = "LIGHT";
else if ("2mm" == band) result = "241G";
else if ("2.5mm" == band) result = "134G";
else if ("4mm" == band) result = "75G";
else if ("6mm" == band) result = "47G";
else if ("1.25cm" == band) result = "24G";
else if ("3cm" == band) result = "10G";
else if ("6cm" == band) result = "5.7G";
else if ("9cm" == band) result = "3.4G";
else if ("13cm" == band) result = "2.3G";
else if ("23cm" == band) result = "1.2G";
else if ("33cm" == band) result = "902";
else if ("70cm" == band) result = "432";
else if ("1.25m" == band) result = "222";
else if ("2m" == band) result = "144";
else if ("4m" == band) result = "70";
else if ("6m" == band) result = "50";
else result = QString::number (frequency);
return result;
}
CabrilloLog::CabrilloLog (Configuration const * configuration) CabrilloLog::CabrilloLog (Configuration const * configuration)
: m_ {configuration} : m_ {configuration}
{ {
@ -138,6 +181,8 @@ bool CabrilloLog::dupe (Frequency frequency, QString const& call) const
void CabrilloLog::reset () void CabrilloLog::reset ()
{ {
// synchronize model
while (m_->canFetchMore ()) m_->fetchMore ();
if (m_->rowCount ()) if (m_->rowCount ())
{ {
m_->setEditStrategy (QSqlTableModel::OnManualSubmit); m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
@ -160,12 +205,10 @@ void CabrilloLog::export_qsos (QTextStream& stream) const
auto rcvd_index = record.indexOf ("exchange_rcvd"); auto rcvd_index = record.indexOf ("exchange_rcvd");
while (m_->export_query_.next ()) while (m_->export_query_.next ())
{ {
auto frequency = m_->export_query_.value (frequency_index).value<Radio::Frequency> ();
auto my_call = m_->configuration_->my_callsign (); auto my_call = m_->configuration_->my_callsign ();
frequency = frequency > 50000000ull ? frequency / 1000ull : frequency;
stream << QString {"QSO: %1 DG %2 %3 %4 %5 %6\n"} stream << QString {"QSO: %1 DG %2 %3 %4 %5 %6\n"}
.arg (frequency, 5) .arg (m_->cabrillo_frequency_string (m_->export_query_.value (frequency_index).value<Radio::Frequency> ()), 5)
.arg (QDateTime::fromMSecsSinceEpoch (m_->export_query_.value (when_index).toULongLong () * 1000ull, Qt::UTC).toString ("yyyy-MM-dd hhmm")) .arg (QDateTime::fromMSecsSinceEpoch (m_->export_query_.value (when_index).toULongLong () * 1000ull, Qt::UTC).toString ("yyyy-MM-dd hhmm"))
.arg (my_call, -12) .arg (my_call, -12)
.arg (m_->export_query_.value (sent_index).toString (), -13) .arg (m_->export_query_.value (sent_index).toString (), -13)
.arg (m_->export_query_.value (call_index).toString (), -12) .arg (m_->export_query_.value (call_index).toString (), -12)

View File

@ -46,10 +46,26 @@ FoxLog::impl::impl (Configuration const * configuration)
} }
SQL_error_check (dupe_query_, &QSqlQuery::prepare, SQL_error_check (dupe_query_, &QSqlQuery::prepare,
"SELECT COUNT(*) FROM fox_log WHERE call = :call AND band = :band"); "SELECT "
" COUNT(*) "
" FROM "
" fox_log "
" WHERE "
" call = :call "
" AND band = :band");
SQL_error_check (export_query_, &QSqlQuery::prepare, SQL_error_check (export_query_, &QSqlQuery::prepare,
"SELECT band, \"when\", call, grid, report_sent, report_rcvd FROM fox_log ORDER BY \"when\""); "SELECT "
" band"
" , \"when\""
" , call"
" , grid"
" , report_sent"
" , report_rcvd "
" FROM "
" fox_log "
" ORDER BY "
" \"when\"");
setEditStrategy (QSqlTableModel::OnFieldChange); setEditStrategy (QSqlTableModel::OnFieldChange);
setTable ("fox_log"); setTable ("fox_log");
@ -141,6 +157,8 @@ bool FoxLog::dupe (QString const& call, QString const& band) const
void FoxLog::reset () void FoxLog::reset ()
{ {
// synchronize model
while (m_->canFetchMore ()) m_->fetchMore ();
if (m_->rowCount ()) if (m_->rowCount ())
{ {
m_->setEditStrategy (QSqlTableModel::OnManualSubmit); m_->setEditStrategy (QSqlTableModel::OnManualSubmit);

View File

@ -68,7 +68,6 @@ namespace
{7038600, Modes::WSPR, IARURegions::ALL}, {7038600, Modes::WSPR, IARURegions::ALL},
{7074000, Modes::FT8, IARURegions::ALL}, {7074000, Modes::FT8, IARURegions::ALL},
{7076000, Modes::JT65, IARURegions::ALL}, {7076000, Modes::JT65, IARURegions::ALL},
{7078000, Modes::FT8, IARURegions::ALL},
{7078000, Modes::JT9, IARURegions::ALL}, {7078000, Modes::JT9, IARURegions::ALL},
{10136000, Modes::FT8, IARURegions::ALL}, {10136000, Modes::FT8, IARURegions::ALL},
@ -79,7 +78,6 @@ namespace
{14095600, Modes::WSPR, IARURegions::ALL}, {14095600, Modes::WSPR, IARURegions::ALL},
{14074000, Modes::FT8, IARURegions::ALL}, {14074000, Modes::FT8, IARURegions::ALL},
{14076000, Modes::JT65, IARURegions::ALL}, {14076000, Modes::JT65, IARURegions::ALL},
{14078000, Modes::FT8, IARURegions::ALL},
{14078000, Modes::JT9, IARURegions::ALL}, {14078000, Modes::JT9, IARURegions::ALL},
{18100000, Modes::FT8, IARURegions::ALL}, {18100000, Modes::FT8, IARURegions::ALL},

View File

@ -82,7 +82,6 @@ void DisplayText::setContentFont(QFont const& font)
void DisplayText::mouseDoubleClickEvent(QMouseEvent *e) void DisplayText::mouseDoubleClickEvent(QMouseEvent *e)
{ {
Q_EMIT selectCallsign(e->modifiers ()); Q_EMIT selectCallsign(e->modifiers ());
QTextEdit::mouseDoubleClickEvent(e);
} }
void DisplayText::insertLineSpacer(QString const& line) void DisplayText::insertLineSpacer(QString const& line)

View File

@ -44,10 +44,9 @@ public:
Q_SLOT void erase (); Q_SLOT void erase ();
Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only); Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only);
protected:
void mouseDoubleClickEvent(QMouseEvent *e);
private: private:
void mouseDoubleClickEvent (QMouseEvent *) override;
void extend_vertical_scrollbar (int min, int max); void extend_vertical_scrollbar (int min, int max);
Configuration const * m_config; Configuration const * m_config;

View File

@ -487,6 +487,17 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
}); });
// Network message handlers // Network message handlers
connect (m_messageClient, &MessageClient::clear_decodes, [this] (quint8 window) {
++window;
if (window & 1)
{
ui->decodedTextBrowser->erase ();
}
if (window & 2)
{
ui->decodedTextBrowser2->erase ();
}
});
connect (m_messageClient, &MessageClient::reply, this, &MainWindow::replyToCQ); connect (m_messageClient, &MessageClient::reply, this, &MainWindow::replyToCQ);
connect (m_messageClient, &MessageClient::replay, this, &MainWindow::replayDecodes); connect (m_messageClient, &MessageClient::replay, this, &MainWindow::replayDecodes);
connect (m_messageClient, &MessageClient::location, this, &MainWindow::locationChange); connect (m_messageClient, &MessageClient::location, this, &MainWindow::locationChange);
@ -3313,7 +3324,7 @@ void MainWindow::on_EraseButton_clicked ()
void MainWindow::band_activity_cleared () void MainWindow::band_activity_cleared ()
{ {
m_messageClient->clear_decodes (); m_messageClient->decodes_cleared ();
QFile f(m_config.temp_dir ().absoluteFilePath ("decoded.txt")); QFile f(m_config.temp_dir ().absoluteFilePath ("decoded.txt"));
if(f.exists()) f.remove(); if(f.exists()) f.remove();
} }
@ -5043,6 +5054,7 @@ void MainWindow::TxAgain()
void MainWindow::clearDX () void MainWindow::clearDX ()
{ {
set_dateTimeQSO (-1);
if (m_QSOProgress != CALLING) if (m_QSOProgress != CALLING)
{ {
auto_tx_mode (false); auto_tx_mode (false);
@ -8257,7 +8269,7 @@ list2Done:
{ {
writeFoxQSO (QString {" Log: %1 %2 %3 %4 %5"}.arg (m_hisCall).arg (m_hisGrid) writeFoxQSO (QString {" Log: %1 %2 %3 %4 %5"}.arg (m_hisCall).arg (m_hisGrid)
.arg (m_rptSent).arg (m_rptRcvd).arg (m_lastBand)); .arg (m_rptSent).arg (m_rptRcvd).arg (m_lastBand));
logQSOTimer.start(0); on_logQSOButton_clicked ();
m_foxRateQueue.enqueue (now); //Add present time in seconds m_foxRateQueue.enqueue (now); //Add present time in seconds
//to Rate queue. //to Rate queue.
} }