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
#
set (CMAKE_OSX_DEPLOYMENT_TARGET 10.9
set (CMAKE_OSX_DEPLOYMENT_TARGET 10.10
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.")
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
@ -848,6 +848,7 @@ set (hamlib_STATIC 1)
find_package (hamlib 3 REQUIRED)
find_program (RIGCTL_EXE rigctl)
find_program (RIGCTLD_EXE rigctld)
find_program (RIGCTLCOM_EXE rigctlcom)
message (STATUS "hamlib_INCLUDE_DIRS: ${hamlib_INCLUDE_DIRS}")
message (STATUS "hamlib_LIBRARIES: ${hamlib_LIBRARIES}")
@ -1417,6 +1418,13 @@ install (PROGRAMS
RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
)
install (PROGRAMS
${RIGCTLCOM_EXE}
DESTINATION ${CMAKE_INSTALL_BINDIR}
#COMPONENT runtime
RENAME rigctlcom-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
)
install (FILES
README
COPYING

View File

@ -188,6 +188,18 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
}
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:
TRACE_UDP ("Replay");
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 ())
{

View File

@ -59,7 +59,7 @@ public:
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
, 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
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power, QString const& comments
@ -80,6 +80,10 @@ public:
// with send_raw_datagram() above)
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
// 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

View File

@ -224,7 +224,7 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
break;
case NetworkMessage::Clear:
Q_EMIT self_->clear_decodes (id);
Q_EMIT self_->decodes_cleared (id);
break;
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
, quint32 delta_frequency, QString const& mode
, QString const& message_text, bool low_confidence, quint8 modifiers)

View File

@ -41,6 +41,9 @@ public:
Q_SLOT void start (port_type port,
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
// 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& my_call, QString const& my_grid
, 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);
// this signal is emitted when a network error occurs

View File

@ -186,16 +186,26 @@
* back a .WAV file.
*
*
* Clear Out 3 quint32
* Clear Out/In 3 quint32
* Id (unique key) utf8
* Window quint8 (In only)
*
* 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
* 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.
*
* 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
* 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));
}
void BeaconsModel::clear_decodes (QString const& client_id)
void BeaconsModel::decodes_cleared (QString const& client_id)
{
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
, Frequency frequency, qint32 drift, QString const& callsign, QString const& grid
, qint32 power, bool off_air);
Q_SLOT void clear_decodes (QString const& client_id);
Q_SLOT void decodes_cleared (QString const& client_id);
};
#endif

View File

@ -2,6 +2,7 @@
#include <QRegExp>
#include <QColor>
#include <QAction>
#include "validators/MaidenheadLocatorValidator.hpp"
@ -120,6 +121,9 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
, id_ {id}
, calls_of_interest_ {calls_of_interest}
, 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}
, beacons_table_view_ {new QTableView}
, message_line_edit_ {new QLineEdit}
@ -143,6 +147,10 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
decodes_table_view_->verticalHeader ()->hide ();
decodes_table_view_->hideColumn (0);
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;
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_->hideColumn (0);
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_layout = new QVBoxLayout {beacons_page};
@ -219,8 +229,19 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
setAllowedAreas (Qt::BottomDockWidgetArea);
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 (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);
});
@ -313,7 +334,7 @@ void ClientWidget::beacon_spot_added (bool /*is_new*/, QString const& client_id,
beacons_table_view_->scrollToBottom ();
}
void ClientWidget::clear_decodes (QString const& client_id)
void ClientWidget::decodes_cleared (QString const& client_id)
{
if (client_id == id_)
{

View File

@ -12,6 +12,7 @@
class QAbstractItemModel;
class QModelIndex;
class QColor;
class QAction;
using Frequency = MessageServer::Frequency;
@ -41,8 +42,9 @@ public:
, float delta_time, Frequency delta_frequency, qint32 drift
, QString const& callsign, QString const& grid, qint32 power
, 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_halt_tx (QString const& id, bool auto_only);
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
@ -74,6 +76,9 @@ private:
QRegularExpression base_call_re_;
int rx_df_;
} decodes_proxy_model_;
QAction * erase_action_;
QAction * erase_rx_frequency_action_;
QAction * erase_both_action_;
QTableView * decodes_table_view_;
QTableView * beacons_table_view_;
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));
}
void DecodesModel::clear_decodes (QString const& client_id)
void DecodesModel::decodes_cleared (QString const& client_id)
{
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
, quint32 delta_frequency, QString const& mode, QString const& message
, 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_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_closed, this, &MessageAggregatorMainWindow::remove_client);
connect (server_, &MessageServer::client_closed, decodes_model_, &DecodesModel::clear_decodes);
connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::clear_decodes);
connect (server_, &MessageServer::client_closed, decodes_model_, &DecodesModel::decodes_cleared);
connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::decodes_cleared);
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
, qint32 snr, float delta_time
, 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
, low_confidence, off_air, dock_widgets_[id]->fast_mode ());});
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes);
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes);
connect (server_, &MessageServer::decodes_cleared, decodes_model_, &DecodesModel::decodes_cleared);
connect (server_, &MessageServer::decodes_cleared, beacons_model_, &BeaconsModel::decodes_cleared);
connect (decodes_model_, &DecodesModel::reply, server_, &MessageServer::reply);
// 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::decode, dock, &ClientWidget::decode_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_halt_tx, server_, &MessageServer::halt_tx);
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);

View File

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

View File

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

View File

@ -17,7 +17,7 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
read(cbits,1002) ncrc12 !Received CRC12
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
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
itmp=0
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
i4Dec6BitWords(ibyte)=itmp
enddo

View File

@ -17,7 +17,7 @@ subroutine extractmessage174_91(decoded,msgreceived,ncrcflag)
read(cbits,1002) ncrc14 !Received CRC12
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
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
itmp=0
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
i4Dec6BitWords(ibyte)=itmp
enddo

View File

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

View File

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

View File

@ -6,7 +6,7 @@
== NAME
rigctl-wsjtx - Hamlib 3 rigctld server.
rigctl-wsjtx - Hamlib 4 rigctld server.
== SYNOPSIS
@ -15,7 +15,7 @@ rigctl-wsjtx - Hamlib 3 rigctld server.
== DESCRIPTION
*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
server *rigctld* to remotely control their transceiver; then this
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
rigctld-wsjtx - Hamlib 3 rigctld server.
rigctld-wsjtx - Hamlib 4 rigctld server.
== SYNOPSIS
@ -15,7 +15,7 @@ rigctld-wsjtx - Hamlib 3 rigctld server.
== DESCRIPTION
*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
server *rigctld* to remotely control their transceiver; then this
special version of *rigctld* should be used since that too has the

View File

@ -21,6 +21,8 @@ class CabrilloLog::impl final
public:
impl (Configuration const *);
QString cabrillo_frequency_string (Radio::Frequency frequency) const;
Configuration const * configuration_;
QSqlQuery mutable dupe_query_;
QSqlQuery mutable export_query_;
@ -46,10 +48,25 @@ CabrilloLog::impl::impl (Configuration const * configuration)
}
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,
"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);
setTable ("cabrillo_log");
@ -68,6 +85,32 @@ CabrilloLog::impl::impl (Configuration const * configuration)
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)
: m_ {configuration}
{
@ -138,6 +181,8 @@ bool CabrilloLog::dupe (Frequency frequency, QString const& call) const
void CabrilloLog::reset ()
{
// synchronize model
while (m_->canFetchMore ()) m_->fetchMore ();
if (m_->rowCount ())
{
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
@ -160,12 +205,10 @@ void CabrilloLog::export_qsos (QTextStream& stream) const
auto rcvd_index = record.indexOf ("exchange_rcvd");
while (m_->export_query_.next ())
{
auto frequency = m_->export_query_.value (frequency_index).value<Radio::Frequency> ();
auto my_call = m_->configuration_->my_callsign ();
frequency = frequency > 50000000ull ? frequency / 1000ull : frequency;
stream << QString {"QSO: %1 DG %2 %3 %4 %5 %6\n"}
.arg (frequency, 5)
.arg (QDateTime::fromMSecsSinceEpoch (m_->export_query_.value (when_index).toULongLong () * 1000ull, Qt::UTC).toString ("yyyy-MM-dd hhmm"))
.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 (my_call, -12)
.arg (m_->export_query_.value (sent_index).toString (), -13)
.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,
"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,
"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);
setTable ("fox_log");
@ -141,6 +157,8 @@ bool FoxLog::dupe (QString const& call, QString const& band) const
void FoxLog::reset ()
{
// synchronize model
while (m_->canFetchMore ()) m_->fetchMore ();
if (m_->rowCount ())
{
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);

View File

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

View File

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

View File

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

View File

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