Compare commits

..

4 Commits

Author SHA1 Message Date
Jordan Sherer 4f1fe4fc94 SVN r8748 2018-06-14 21:27:34 -04:00
Jordan Sherer 419c039d08 SVN r8577 2018-03-19 01:23:56 -04:00
Jordan Sherer 45cc6416c1 SVN r8568 2018-03-17 12:56:24 -04:00
Jordan Sherer 587950f372 SVN r8556 2018-03-12 20:20:52 -04:00
63 changed files with 4769 additions and 16002 deletions
-297
View File
@@ -1,297 +0,0 @@
#include "APRSISClient.h"
#include <cmath>
#include "Radio.hpp"
#include "varicode.h"
APRSISClient::APRSISClient(QString host, quint16 port, QObject *parent):
QTcpSocket(parent),
m_host(host),
m_port(port)
{
connect(&m_timer, &QTimer::timeout, this, &APRSISClient::sendReports);
m_timer.setInterval(30*1000); // every 30 seconds
m_timer.start();
}
quint32 APRSISClient::hashCallsign(QString callsign){
// based on: https://github.com/hessu/aprsc/blob/master/src/passcode.c
QByteArray rootCall = QString(callsign.split("-").first().toUpper()).toLocal8Bit() + '\0';
quint32 hash = 0x73E2;
int i = 0;
int len = rootCall.length();
while(i+1 < len){
hash ^= rootCall.at(i) << 8;
hash ^= rootCall.at(i+1);
i += 2;
}
return hash & 0x7FFF;
}
QString APRSISClient::loginFrame(QString callsign){
auto loginFrame = QString("user %1 pass %2 ver %3\n");
loginFrame = loginFrame.arg(callsign);
loginFrame = loginFrame.arg(hashCallsign(callsign));
loginFrame = loginFrame.arg("FT8Call");
return loginFrame;
}
QList<QStringList> findall(QRegularExpression re, QString content){
int pos = 0;
QList<QStringList> all;
while(pos < content.length()){
auto match = re.match(content, pos);
if(!match.hasMatch()){
break;
}
all.append(match.capturedTexts());
pos = match.capturedEnd();
}
return all;
}
inline long
floordiv (long num, long den)
{
if (0 < (num^den))
return num/den;
else
{
ldiv_t res = ldiv(num,den);
return (res.rem)? res.quot-1
: res.quot;
}
}
// convert an arbitrary length grid locator to a high precision lat/lon
QPair<float, float> APRSISClient::grid2deg(QString locator){
QString grid = locator.toUpper();
float lat = -90;
float lon = -90;
auto lats = findall(QRegularExpression("([A-X])([A-X])"), grid);
auto lons = findall(QRegularExpression("(\\d)(\\d)"), grid);
int valx[22];
int valy[22];
int i = 0;
int tot = 0;
char A = 'A';
foreach(QStringList matched, lats){
char x = matched.at(1).at(0).toLatin1();
char y = matched.at(2).at(0).toLatin1();
valx[i*2] = x-A;
valy[i*2] = y-A;
i++;
tot++;
}
i = 0;
foreach(QStringList matched, lons){
int x = matched.at(1).toInt();
int y = matched.at(2).toInt();
valx[i*2+1]=x;
valy[i*2+1]=y;
i++;
tot++;
}
for(int i = 0; i < tot; i++){
int x = valx[i];
int y = valy[i];
int z = i - 1;
float scale = pow(10, floordiv(-(z-1), 2)) * pow(24, floordiv(-z, 2));
lon += scale * x;
lat += scale * y;
}
lon *= 2;
return {lat, lon};
}
// convert an arbitrary length grid locator to a high precision lat/lon in aprs format
QPair<QString, QString> APRSISClient::grid2aprs(QString grid){
auto geo = APRSISClient::grid2deg(grid);
auto lat = geo.first;
auto lon = geo.second;
QString latDir = "N";
if(lat < 0){
lat *= -1;
latDir = "S";
}
QString lonDir = "E";
if(lon < 0){
lon *= -1;
lonDir = "W";
}
double iLat, fLat, iLon, fLon, iLatMin, fLatMin, iLonMin, fLonMin, iLatSec, iLonSec;
fLat = modf(lat, &iLat);
fLon = modf(lon, &iLon);
fLatMin = modf(fLat * 60, &iLatMin);
fLonMin = modf(fLon * 60, &iLonMin);
iLatSec = round(fLatMin * 60);
iLonSec = round(fLonMin * 60);
if(iLatSec == 60){
iLatMin += 1;
iLatSec = 0;
}
if(iLonSec == 60){
iLonMin += 1;
iLonSec = 0;
}
if(iLatMin == 60){
iLat += 1;
iLatMin = 0;
}
if(iLonMin == 60){
iLon += 1;
iLonMin = 0;
}
double aprsLat = iLat * 100 + iLatMin + (iLatSec / 60.0);
double aprsLon = iLon * 100 + iLonMin + (iLonSec / 60.0);
return {
QString().sprintf("%07.2f%%1", aprsLat).arg(latDir),
QString().sprintf("%08.2f%%1", aprsLon).arg(lonDir)
};
}
void APRSISClient::enqueueSpot(QString theircall, QString grid, QString comment){
if(m_localCall.isEmpty()) return;
auto geo = APRSISClient::grid2aprs(grid);
auto spotFrame = QString("%1>%2,APRS,TCPIP*:=%3/%4nFT8CALL %5\n");
spotFrame = spotFrame.arg(theircall);
spotFrame = spotFrame.arg(m_localCall);
spotFrame = spotFrame.arg(geo.first);
spotFrame = spotFrame.arg(geo.second);
spotFrame = spotFrame.arg(comment.left(43));
enqueueRaw(spotFrame);
}
void APRSISClient::enqueueMessage(QString tocall, QString message){
if(m_localCall.isEmpty()) return;
auto messageFrame = QString("%1>APRS,TCPIP*::%2:%3\n");
messageFrame = messageFrame.arg(m_localCall);
messageFrame = messageFrame.arg(tocall + QString(" ").repeated(9-tocall.length()));
messageFrame = messageFrame.arg(message);
enqueueRaw(messageFrame);
}
void APRSISClient::enqueueThirdParty(QString theircall, QString payload){
auto frame = QString("%1>%2,APRS,TCPIP*:%3\n");
frame = frame.arg(theircall);
frame = frame.arg(m_localCall);
frame = frame.arg(payload);
enqueueRaw(frame);
}
void APRSISClient::enqueueRaw(QString aprsFrame){
m_frameQueue.enqueue(aprsFrame);
}
void APRSISClient::processQueue(bool disconnect){
// don't process queue if we haven't set our local callsign
if(m_localCall.isEmpty()) return;
// don't process queue if there's nothing to process
if(m_frameQueue.isEmpty()) return;
// 1. connect (and read)
// 2. login (and read)
// 3. for each raw frame in queue, send
// 4. disconnect
if(state() != QTcpSocket::ConnectedState){
connectToHost(m_host, m_port);
if(!waitForConnected(5000)){
qDebug() << "APRSISClient Connection Error:" << errorString();
return;
}
}
auto re = QRegExp("(full|unavailable|busy)");
auto line = QString(readLine());
if(line.toLower().indexOf(re) >= 0){
qDebug() << "APRSISClient Connection Busy:" << line;
return;
}
if(write(loginFrame(m_localCall).toLocal8Bit()) == -1){
qDebug() << "APRSISClient Write Login Error:" << errorString();
return;
}
if(!waitForReadyRead(5000)){
qDebug() << "APRSISClient Login Error: Server Not Responding";
return;
}
line = QString(readAll());
if(line.toLower().indexOf(re) >= 0){
qDebug() << "APRSISClient Server Busy:" << line;
return;
}
while(!m_frameQueue.isEmpty()){
QByteArray data = m_frameQueue.head().toLocal8Bit();
if(write(data) == -1){
qDebug() << "APRSISClient Write Error:" << errorString();
return;
}
if(!waitForBytesWritten(5000)){
qDebug() << "APRSISClient Cannot Write Error: Write Timeout";
return;
}
qDebug() << "APRSISClient Write:" << data;
if(waitForReadyRead(5000)){
line = QString(readLine());
qDebug() << "APRSISClient Read:" << line;
if(line.toLower().indexOf(re) >= 0){
qDebug() << "APRSISClient Cannot Write Error:" << line;
return;
}
}
m_frameQueue.dequeue();
}
if(disconnect){
disconnectFromHost();
}
}
-44
View File
@@ -1,44 +0,0 @@
#ifndef APRSISCLIENT_H
#define APRSISCLIENT_H
#include <QTcpSocket>
#include <QQueue>
#include <QPair>
#include <QTimer>
class APRSISClient : public QTcpSocket
{
public:
APRSISClient(QString host, quint16 port, QObject *parent = nullptr);
static quint32 hashCallsign(QString callsign);
static QString loginFrame(QString callsign);
static QPair<float, float> grid2deg(QString grid);
static QPair<QString, QString> grid2aprs(QString grid);
void setLocalStation(QString mycall, QString mygrid){
m_localCall = mycall;
m_localGrid = mygrid;
}
void enqueueSpot(QString theircall, QString grid, QString comment);
void enqueueMessage(QString tocall, QString message);
void enqueueThirdParty(QString theircall, QString payload);
void enqueueRaw(QString aprsFrame);
void processQueue(bool disconnect=true);
public slots:
void sendReports(){ processQueue(true); }
private:
QString m_localCall;
QString m_localGrid;
QQueue<QString> m_frameQueue;
QString m_host;
quint16 m_port;
QTimer m_timer;
};
#endif // APRSISCLIENT_H
-13
View File
@@ -87,19 +87,6 @@ int Bands::find (QString const& band) const
return result;
}
bool Bands::findFreq(QString const& band, Radio::Frequency *pFreqLower, Radio::Frequency *pFreqHigher) const {
int row = find(band);
if(row == -1){
return false;
}
if(pFreqLower) *pFreqLower = ADIF_bands[row].lower_bound_;
if(pFreqHigher) *pFreqHigher = ADIF_bands[row].upper_bound_;
return true;
}
QString const& Bands::oob ()
{
return oob_name;
-2
View File
@@ -56,8 +56,6 @@ public:
//
QString find (Frequency) const; // find band Frequency is in
int find (QString const&) const; // find row of band (-1 if not valid)
bool findFreq(QString const& band, Radio::Frequency *pFreqLower, Radio::Frequency *pFreqHigher) const;
static QString const& oob ();
// Iterators
+7 -10
View File
@@ -2,15 +2,13 @@
# To pass variables to cpack from cmake, they must be configured
# in this file.
set (CPACK_SET_DESTDIR true)
set (CPACK_PACKAGE_VENDOR "@PROJECT_VENDOR@")
set (CPACK_PACKAGE_CONTACT "@PROJECT_CONTACT@")
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "@PROJECT_SUMMARY_DESCRIPTION@")
set (CPACK_RESOURCE_FILE_LICENSE "@PROJECT_SOURCE_DIR@/COPYING")
set (CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set (CPACK_PACKAGE_EXECUTABLES ft8call "@PROJECT_NAME@")
set (CPACK_CREATE_DESKTOP_LINKS ft8call)
set (CPACK_PACKAGE_EXECUTABLES wsjtx "@PROJECT_NAME@")
set (CPACK_CREATE_DESKTOP_LINKS wsjtx)
set (CPACK_STRIP_FILES TRUE)
#
@@ -21,10 +19,9 @@ set (CPACK_STRIP_FILES TRUE)
#set (CPACK_COMPONENT_RUNTIME_DESCRIPTION "@WSJTX_DESCRIPTION_SUMMARY@")
if (CPACK_GENERATOR MATCHES "NSIS")
set (CPACK_SET_DESTDIR FALSE)
set (CPACK_STRIP_FILES FALSE) # breaks Qt packaging on Windows
set (CPACK_NSIS_INSTALL_ROOT "C:\\FT8Call")
set (CPACK_NSIS_INSTALL_ROOT "C:\\WSJT")
# set the install/unistall icon used for the installer itself
# There is a bug in NSI that does not handle full unix paths properly.
@@ -38,13 +35,13 @@ if (CPACK_GENERATOR MATCHES "NSIS")
"@PROJECT_HOMEPAGE@" "@PROJECT_NAME@ Web Site"
)
# Use the icon from wsjtx for add-remove programs
set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\ft8call.exe")
set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\wsjtx.exe")
set (CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
set (CPACK_NSIS_HELP_LINK "@PROJECT_MANUAL_DIRECTORY_URL@/@PROJECT_MANUAL@")
set (CPACK_NSIS_URL_INFO_ABOUT "@PROJECT_HOMEPAGE@")
set (CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}")
set (CPACK_NSIS_MUI_FINISHPAGE_RUN "ft8call.exe")
set (CPACK_NSIS_MUI_FINISHPAGE_RUN "wsjtx.exe")
set (CPACK_NSIS_MODIFY_PATH ON)
endif ()
@@ -68,9 +65,9 @@ if ("${CPACK_GENERATOR}" STREQUAL "WIX")
# Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
# But the file names still use the full CMake_VERSION value:
set (CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-${CPACK_SYSTEM_NAME}")
"${CPACK_PACKAGE_NAME}-@wsjtx_VERSION@-${CPACK_SYSTEM_NAME}")
set (CPACK_SOURCE_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-Source")
"${CPACK_PACKAGE_NAME}-@wsjtx_VERSION@-Source")
if (NOT CPACK_WIX_SIZEOF_VOID_P)
set (CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
+28 -31
View File
@@ -22,7 +22,7 @@ Change this to the newest SDK available that you can install on your system (10.
Do not override this if you intend to build an official deployable installer.")
endif (APPLE)
project (ft8call C CXX Fortran)
project (wsjtx C CXX Fortran)
#
# CMake policies
@@ -45,10 +45,10 @@ message (STATUS "Building ${CMAKE_PROJECT_NAME}-${wsjtx_VERSION}")
#
# project information
#
set (PROJECT_NAME "FT8Call")
set (PROJECT_VENDOR "Jordan Sherer, KN4CRD")
set (PROJECT_CONTACT "Jordan Sherer <kn4crd@gmail.com>")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2018 by Joe Taylor, K1JT, (C) 2018 by Jordan Sherer, KN4CRD")
set (PROJECT_NAME "WSJT-X")
set (PROJECT_VENDOR "Joe Taylor, K1JT")
set (PROJECT_CONTACT "Joe Taylor <k1jt@arrl.net>")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2018 by Joe Taylor, K1JT")
set (PROJECT_HOMEPAGE http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html)
set (PROJECT_MANUAL wsjtx-main)
set (PROJECT_MANUAL_DIRECTORY_URL http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/)
@@ -303,9 +303,6 @@ set (wsjtx_CXXSRCS
astro.cpp
messageaveraging.cpp
WsprTxScheduler.cpp
varicode.cpp
SelfDestructMessageBox.cpp
APRSISClient.cpp
mainwindow.cpp
Configuration.cpp
main.cpp
@@ -1301,7 +1298,7 @@ else (${OPENMP_FOUND} OR APPLE)
endif (${OPENMP_FOUND} OR APPLE)
# build the main application
add_executable (ft8call MACOSX_BUNDLE
add_executable (wsjtx MACOSX_BUNDLE
${wsjtx_CXXSRCS}
${wsjtx_GENUISRCS}
wsjtx.rc
@@ -1310,10 +1307,10 @@ add_executable (ft8call MACOSX_BUNDLE
)
if (WSJT_CREATE_WINMAIN)
set_target_properties (ft8call PROPERTIES WIN32_EXECUTABLE ON)
set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON)
endif (WSJT_CREATE_WINMAIN)
set_target_properties (ft8call PROPERTIES
set_target_properties (wsjtx PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Darwin/Info.plist.in"
MACOSX_BUNDLE_INFO_STRING "${WSJTX_DESCRIPTION_SUMMARY}"
MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}"
@@ -1326,27 +1323,27 @@ set_target_properties (ft8call PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
)
target_include_directories (ft8call PRIVATE ${FFTW3_INCLUDE_DIRS})
target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS})
if (APPLE)
target_link_libraries (ft8call wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
target_link_libraries (wsjtx wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
else ()
target_link_libraries (ft8call wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
target_link_libraries (wsjtx wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
if (OpenMP_C_FLAGS)
set_target_properties (ft8call PROPERTIES
set_target_properties (wsjtx PROPERTIES
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
LINK_FLAGS "${OpenMP_C_FLAGS}"
)
endif ()
set_target_properties (ft8call PROPERTIES
set_target_properties (wsjtx PROPERTIES
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
)
if (WIN32)
set_target_properties (ft8call PROPERTIES
set_target_properties (wsjtx PROPERTIES
LINK_FLAGS -Wl,--stack,16777216
)
endif ()
endif ()
qt5_use_modules (ft8call SerialPort) # not sure why the interface link library syntax above doesn't work
qt5_use_modules (wsjtx SerialPort) # not sure why the interface link library syntax above doesn't work
# make a library for WSJT-X UDP servers
# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS})
@@ -1391,18 +1388,18 @@ endif (WSJT_CREATE_WINMAIN)
if (UNIX)
if (NOT WSJT_SKIP_MANPAGES)
add_subdirectory (manpages)
add_dependencies (ft8call manpages)
add_dependencies (wsjtx manpages)
endif (NOT WSJT_SKIP_MANPAGES)
if (NOT APPLE)
add_subdirectory (debian)
add_dependencies (ft8call debian)
add_dependencies (wsjtx debian)
endif (NOT APPLE)
endif (UNIX)
#
# installation
#
install (TARGETS ft8call
install (TARGETS wsjtx
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION . COMPONENT runtime
)
@@ -1492,15 +1489,15 @@ add_custom_target (uninstall
# creates or updates ${PROJECT_BINARY_DIR}/scs_version.h using cmake script
# add_custom_target (revisiontag
# COMMAND ${CMAKE_COMMAND}
# -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
# -D BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
# -D OUTPUT_DIR=${PROJECT_BINARY_DIR}
# -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
# COMMENT "Generating Subversion revision information"
# VERBATIM
# )
add_custom_target (revisiontag
COMMAND ${CMAKE_COMMAND}
-D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-D BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-D OUTPUT_DIR=${PROJECT_BINARY_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
COMMENT "Generating Subversion revision information"
VERBATIM
)
# explicitly say that the wsjt_qt depends on custom target, this is
# done indirectly so that the revisiontag target gets built exactly
# once per build
@@ -1520,7 +1517,7 @@ if (NOT WIN32 AND NOT APPLE)
# install a desktop file so wsjtx appears in the application start
# menu with an icon
install (
FILES ft8call.desktop message_aggregator.desktop
FILES wsjtx.desktop message_aggregator.desktop
DESTINATION share/applications
#COMPONENT runtime
)
-1
View File
@@ -10,7 +10,6 @@ auto CallsignValidator::validate (QString& input, int& pos) const -> State
{
auto match = re_.match (input, 0, QRegularExpression::PartialPreferCompleteMatch);
input = input.toUpper ();
if (input.count(QLatin1Char('/')) > 1) return Invalid;
if (match.hasMatch ()) return Acceptable;
if (!input.size () || match.hasPartialMatch ()) return Intermediate;
pos = input.size ();
+82 -275
View File
@@ -140,7 +140,6 @@
#include <QSettings>
#include <QAudioDeviceInfo>
#include <QAudioInput>
#include <QDebug>
#include <QDialog>
#include <QAction>
#include <QFileDialog>
@@ -161,7 +160,7 @@
#include <QColorDialog>
#include <QSerialPortInfo>
#include <QScopedPointer>
#include <QDateTimeEdit>
#include <QDebug>
#include "pimpl_impl.hpp"
#include "qt_helpers.hpp"
@@ -182,8 +181,6 @@
#include "MaidenheadLocatorValidator.hpp"
#include "CallsignValidator.hpp"
#include "varicode.h"
#include "ui_Configuration.h"
#include "moc_Configuration.cpp"
@@ -196,14 +193,11 @@ namespace
int const combo_box_item_disabled (0);
// QRegExp message_alphabet {"[- A-Za-z0-9+./?]*"};
QRegExp message_alphabet {"[^\\x00-\\x1F]*"};
QRegExp message_alphabet {"[- @A-Za-z0-9+./?#<>]*"};
// Magic numbers for file validation
constexpr quint32 qrg_magic {0xadbccbdb};
constexpr quint32 qrg_version {102}; // M.mm
// Bump this versioned key every time we need to "reset" our working frequencies...
const char * versionedFrequenciesSettingsKey = "FrequenciesForRegionModes_01";
constexpr quint32 qrg_version {100}; // M.mm
}
@@ -262,24 +256,16 @@ class StationDialog final
public:
explicit StationDialog (StationList const * stations, Bands * bands, QWidget * parent = nullptr)
: QDialog {parent}
, all_bands_ {bands}
, filtered_bands_ {new CandidateKeyFilter {bands, stations, 0, 0}}
{
setWindowTitle (QApplication::applicationName () + " - " + tr ("Add Schedule"));
setWindowTitle (QApplication::applicationName () + " - " + tr ("Add Station"));
band_.setModel (filtered_bands_.data ());
switch_at_.setTimeSpec(Qt::UTC);
switch_at_.setDisplayFormat("hh:mm");
switch_until_.setTimeSpec(Qt::UTC);
switch_until_.setDisplayFormat("hh:mm");
auto form_layout = new QFormLayout ();
form_layout->addRow (tr ("&Frequency (MHz):"), &freq_);
form_layout->addRow (tr ("&Switch at (UTC):"), &switch_at_);
form_layout->addRow (tr ("&Until (UTC):"), &switch_until_);
form_layout->addRow (tr ("&Description:"), &description_);
form_layout->addRow (tr ("&Band:"), &band_);
form_layout->addRow (tr ("&Offset (MHz):"), &delta_);
form_layout->addRow (tr ("&Antenna:"), &description_);
auto main_layout = new QVBoxLayout (this);
main_layout->addLayout (form_layout);
@@ -289,21 +275,16 @@ public:
connect (button_box, &QDialogButtonBox::accepted, this, &StationDialog::accept);
connect (button_box, &QDialogButtonBox::rejected, this, &StationDialog::reject);
if (delta_.text ().isEmpty ())
{
delta_.setText ("0");
}
}
StationList::Station station () const
{
auto band = all_bands_->find(freq_.frequency());
auto a = QDateTime(QDate(2000, 1, 1), switch_at_.time(), Qt::UTC);
auto b = QDateTime(QDate(2000, 1, 1), switch_until_.time(), Qt::UTC);
return {
band,
freq_.frequency(),
a,
b,
description_.text ()};
return {band_.currentText (), delta_.frequency_delta (), description_.text ()};
}
int exec () override
@@ -314,12 +295,9 @@ public:
private:
QScopedPointer<CandidateKeyFilter> filtered_bands_;
Bands * all_bands_;
QComboBox band_;
FrequencyLineEdit freq_;
QTimeEdit switch_at_;
QTimeEdit switch_until_;
FrequencyDeltaLineEdit delta_;
QLineEdit description_;
};
@@ -452,9 +430,6 @@ private:
Q_SLOT void on_add_macro_push_button_clicked (bool = false);
Q_SLOT void on_delete_macro_push_button_clicked (bool = false);
Q_SLOT void on_PTT_method_button_group_buttonClicked (int);
Q_SLOT void on_station_message_line_edit_textChanged(QString const&);
Q_SLOT void on_qth_message_line_edit_textChanged(QString const&);
Q_SLOT void on_reply_message_line_edit_textChanged(QString const&);
Q_SLOT void on_add_macro_line_edit_editingFinished ();
Q_SLOT void delete_macro ();
void delete_selected_macros (QModelIndexList);
@@ -522,6 +497,8 @@ private:
FrequencyList_v2 next_frequencies_;
StationList stations_;
StationList next_stations_;
FrequencyDelta current_offset_;
FrequencyDelta current_tx_offset_;
QAction * frequency_delete_action_;
QAction * frequency_insert_action_;
@@ -548,24 +525,16 @@ private:
bool frequency_calibration_disabled_; // not persistent
unsigned transceiver_command_number_;
QString dynamic_grid_;
QString dynamic_qtc_;
// configuration fields that we publish
bool auto_switch_bands_;
QString my_callsign_;
QString my_grid_;
QString my_station_;
QString aprs_ssid_;
QString my_qth_;
QString reply_;
int callsign_aging_;
int activity_aging_;
QColor color_CQ_;
QColor next_color_CQ_;
QColor color_MyCall_;
QColor next_color_MyCall_;
QColor color_ReceivedMsg_;
QColor next_color_ReceivedMsg_;
QColor color_TxMsg_;
QColor next_color_TxMsg_;
QColor color_DXCC_;
QColor next_color_DXCC_;
QColor color_NewCall_;
@@ -578,12 +547,10 @@ private:
double txDelay_;
bool id_after_73_;
bool tx_QSY_allowed_;
bool spot_to_reporting_networks_;
bool transmit_directed_;
bool autoreply_off_at_startup_;
bool spot_to_psk_reporter_;
bool monitor_off_at_startup_;
bool monitor_last_used_;
bool log_as_DATA_;
bool log_as_RTTY_;
bool report_in_comments_;
bool prompt_to_log_;
bool insert_blank_;
@@ -593,7 +560,6 @@ private:
bool miles_;
bool quick_call_;
bool disable_TX_on_73_;
int beacon_;
int watchdog_;
bool TX_messages_;
bool enable_VHF_features_;
@@ -604,7 +570,7 @@ private:
bool bHound_;
bool x2ToneSpacing_;
bool x4ToneSpacing_;
bool use_dynamic_info_;
bool use_dynamic_grid_;
QString opCall_;
QString udp_server_name_;
port_type udp_server_port_;
@@ -618,7 +584,6 @@ private:
bool accept_udp_requests_;
bool udpWindowToFront_;
bool udpWindowRestore_;
bool udpEnabled_;
DataMode data_mode_;
bool pwrBandTxMemory_;
bool pwrBandTuneMemory_;
@@ -663,11 +628,10 @@ AudioDevice::Channel Configuration::audio_output_channel () const {return m_->au
bool Configuration::restart_audio_input () const {return m_->restart_sound_input_device_;}
bool Configuration::restart_audio_output () const {return m_->restart_sound_output_device_;}
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
bool Configuration::use_dynamic_grid() const {return m_->use_dynamic_info_; }
QString Configuration::my_callsign () const {return m_->my_callsign_;}
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
QColor Configuration::color_ReceivedMsg () const {return m_->color_ReceivedMsg_;}
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
QColor Configuration::color_DXCC () const {return m_->color_DXCC_;}
QColor Configuration::color_NewCall () const {return m_->color_NewCall_;}
QFont Configuration::text_font () const {return m_->font_;}
@@ -680,24 +644,14 @@ double Configuration::txDelay() const {return m_->txDelay_;}
qint32 Configuration::RxBandwidth() const {return m_->RxBandwidth_;}
bool Configuration::id_after_73 () const {return m_->id_after_73_;}
bool Configuration::tx_QSY_allowed () const {return m_->tx_QSY_allowed_;}
bool Configuration::spot_to_reporting_networks () const
bool Configuration::spot_to_psk_reporter () const
{
// rig must be open and working to spot externally
return is_transceiver_online () && m_->spot_to_reporting_networks_;
return is_transceiver_online () && m_->spot_to_psk_reporter_;
}
void Configuration::set_spot_to_reporting_networks (bool spot)
{
if(m_->spot_to_reporting_networks_ != spot){
m_->spot_to_reporting_networks_ = spot;
m_->write_settings();
}
}
bool Configuration::transmit_directed() const { return m_->transmit_directed_; }
bool Configuration::autoreply_off_at_startup () const {return m_->autoreply_off_at_startup_;}
bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
bool Configuration::log_as_DATA () const {return m_->log_as_DATA_;}
bool Configuration::log_as_RTTY () const {return m_->log_as_RTTY_;}
bool Configuration::report_in_comments () const {return m_->report_in_comments_;}
bool Configuration::prompt_to_log () const {return m_->prompt_to_log_;}
bool Configuration::insert_blank () const {return m_->insert_blank_;}
@@ -707,7 +661,6 @@ bool Configuration::clear_DX () const {return m_->clear_DX_;}
bool Configuration::miles () const {return m_->miles_;}
bool Configuration::quick_call () const {return m_->quick_call_;}
bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;}
int Configuration::beacon () const {return m_->beacon_;}
int Configuration::watchdog () const {return m_->watchdog_;}
bool Configuration::TX_messages () const {return m_->TX_messages_;}
bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features_;}
@@ -728,12 +681,10 @@ auto Configuration::n1mm_server_port () const -> port_type {return m_->n1mm_serv
bool Configuration::broadcast_to_n1mm () const {return m_->broadcast_to_n1mm_;}
bool Configuration::udpWindowToFront () const {return m_->udpWindowToFront_;}
bool Configuration::udpWindowRestore () const {return m_->udpWindowRestore_;}
bool Configuration::udpEnabled () const {return m_->udpEnabled_;}
Bands * Configuration::bands () {return &m_->bands_;}
Bands const * Configuration::bands () const {return &m_->bands_;}
StationList * Configuration::stations () {return &m_->stations_;}
StationList const * Configuration::stations () const {return &m_->stations_;}
bool Configuration::auto_switch_bands() const { return m_->auto_switch_bands_; }
IARURegions::Region Configuration::region () const {return m_->region_;}
FrequencyList_v2 * Configuration::frequencies () {return &m_->frequencies_;}
FrequencyList_v2 const * Configuration::frequencies () const {return &m_->frequencies_;}
@@ -752,7 +703,7 @@ void Configuration::set_calibration (CalibrationParams params)
void Configuration::enable_calibration (bool on)
{
auto target_frequency = m_->remove_calibration (m_->cached_rig_state_.frequency ());
auto target_frequency = m_->remove_calibration (m_->cached_rig_state_.frequency ()) - m_->current_offset_;
m_->frequency_calibration_disabled_ = !on;
transceiver_frequency (target_frequency);
}
@@ -849,56 +800,20 @@ bool Configuration::valid_n1mm_info () const
QString Configuration::my_grid() const
{
auto grid = m_->my_grid_;
if (m_->use_dynamic_info_ && m_->dynamic_grid_.size () >= 4) {
grid = m_->dynamic_grid_;
auto the_grid = m_->my_grid_;
if (m_->use_dynamic_grid_ && m_->dynamic_grid_.size () >= 4) {
the_grid = m_->dynamic_grid_;
}
return grid;
return the_grid;
}
QString Configuration::my_station() const
{
auto station = m_->my_station_;
if(m_->use_dynamic_info_ && !m_->dynamic_qtc_.isEmpty()){
station = m_->dynamic_qtc_;
}
return station;
}
QString Configuration::aprs_ssid() const {
return m_->aprs_ssid_;
}
QString Configuration::my_qth() const
{
return m_->my_qth_;
}
QString Configuration::reply() const
{
return m_->reply_;
}
int Configuration::callsign_aging() const
{
return m_->callsign_aging_;
}
int Configuration::activity_aging() const
{
return m_->activity_aging_;
}
void Configuration::set_dynamic_location (QString const& grid_descriptor)
void Configuration::set_location (QString const& grid_descriptor)
{
// change the dynamic grid
qDebug () << "Configuration::set_location - location:" << grid_descriptor;
m_->dynamic_grid_ = grid_descriptor.trimmed ();
}
void Configuration::set_dynamic_station_message(QString const& qtc)
{
m_->dynamic_qtc_ = qtc.trimmed ();
}
namespace
{
#if defined (Q_OS_MAC)
@@ -950,6 +865,8 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
, next_frequencies_ {&bands_}
, stations_ {&bands_}
, next_stations_ {&bands_}
, current_offset_ {0}
, current_tx_offset_ {0}
, frequency_dialog_ {new FrequencyDialog {&regions_, &modes_, this}}
, station_dialog_ {new StationDialog {&next_stations_, &bands_, this}}
, last_port_type_ {TransceiverFactory::Capabilities::none}
@@ -1001,15 +918,6 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
throw std::runtime_error {"Failed to create samples directory"};
}
QString messages_dir {"messages"};
if (!default_save_directory_.mkpath (messages_dir))
{
MessageBox::critical_message (this, tr ("Failed to create messages directory"),
tr ("path: \"%1\"")
.arg (default_save_directory_.absoluteFilePath (messages_dir)));
throw std::runtime_error {"Failed to create messages directory"};
}
// copy in any new sample files to the sample directory
QDir dest_dir {default_save_directory_};
dest_dir.cd (samples_dir);
@@ -1035,11 +943,8 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
// validation
//
ui_->callsign_line_edit->setValidator (new CallsignValidator {this});
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this, MaidenheadLocatorValidator::Length::doubleextended});
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this});
ui_->add_macro_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->station_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->qth_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->reply_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->udp_server_port_spin_box->setMinimum (1);
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
@@ -1156,23 +1061,16 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
//
// setup stations table model & view
//
stations_.sort (StationList::switch_at_column);
stations_.sort (StationList::band_column);
ui_->stations_table_view->setModel (&next_stations_);
ui_->stations_table_view->sortByColumn (StationList::switch_at_column, Qt::AscendingOrder);
connect(ui_->auto_switch_bands_check_box, &QCheckBox::clicked, ui_->stations_table_view, &QTableView::setEnabled);
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
// delegates
auto stations_item_delegate = new QStyledItemDelegate {this};
stations_item_delegate->setItemEditorFactory (item_editor_factory ());
ui_->stations_table_view->setItemDelegate (stations_item_delegate);
//ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this});
ui_->stations_table_view->resizeColumnToContents (StationList::band_column);
ui_->stations_table_view->resizeColumnToContents (StationList::frequency_column);
ui_->stations_table_view->resizeColumnToContents (StationList::switch_at_column);
ui_->stations_table_view->resizeColumnToContents (StationList::switch_until_column);
ui_->stations_table_view->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this});
// actions
station_delete_action_ = new QAction {tr ("&Delete"), ui_->stations_table_view};
@@ -1220,21 +1118,14 @@ void Configuration::impl::initialize_models ()
{
pal.setColor (QPalette::Base, Qt::white);
}
ui_->callsign_line_edit->setPalette (pal);
ui_->grid_line_edit->setPalette (pal);
ui_->auto_switch_bands_check_box->setChecked(auto_switch_bands_);
ui_->callsign_line_edit->setText (my_callsign_);
ui_->grid_line_edit->setText (my_grid_.toUpper());
ui_->callsign_aging_spin_box->setValue(callsign_aging_);
ui_->activity_aging_spin_box->setValue(activity_aging_);
ui_->station_message_line_edit->setText (my_station_.toUpper());
ui_->qth_message_line_edit->setText (my_qth_.toUpper());
ui_->reply_message_line_edit->setText (reply_.toUpper());
ui_->use_dynamic_grid->setChecked(use_dynamic_info_);
ui_->grid_line_edit->setText (my_grid_);
ui_->use_dynamic_grid->setChecked(use_dynamic_grid_);
ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name()));
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_ReceivedMsg_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name()));
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name()));
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name()));
ui_->CW_id_interval_spin_box->setValue (id_interval_);
@@ -1248,13 +1139,10 @@ void Configuration::impl::initialize_models ()
ui_->azel_path_display_label->setText (azel_directory_.absolutePath ());
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
ui_->tx_QSY_check_box->setChecked (tx_QSY_allowed_);
ui_->psk_reporter_check_box->setChecked (spot_to_reporting_networks_);
ui_->transmit_directed_check_box->setChecked(transmit_directed_);
ui_->autoreply_off_check_box->setChecked (autoreply_off_at_startup_);
ui_->psk_reporter_check_box->setChecked (spot_to_psk_reporter_);
ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
ui_->log_as_RTTY_check_box->setChecked (log_as_DATA_);
ui_->stations_table_view->setEnabled(ui_->auto_switch_bands_check_box->isChecked());
ui_->log_as_RTTY_check_box->setChecked (log_as_RTTY_);
ui_->report_in_comments_check_box->setChecked (report_in_comments_);
ui_->prompt_to_log_check_box->setChecked (prompt_to_log_);
ui_->insert_blank_check_box->setChecked (insert_blank_);
@@ -1264,7 +1152,6 @@ void Configuration::impl::initialize_models ()
ui_->miles_check_box->setChecked (miles_);
ui_->quick_call_check_box->setChecked (quick_call_);
ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_);
ui_->beacon_spin_box->setValue (beacon_);
ui_->tx_watchdog_spin_box->setValue (watchdog_);
ui_->TX_messages_check_box->setChecked (TX_messages_);
ui_->enable_VHF_features_check_box->setChecked(enable_VHF_features_);
@@ -1311,7 +1198,6 @@ void Configuration::impl::initialize_models ()
ui_->n1mm_server_port_spin_box->setValue (n1mm_server_port_);
ui_->enable_n1mm_broadcast_check_box->setChecked (broadcast_to_n1mm_);
ui_->udpWindowToFront->setChecked(udpWindowToFront_);
ui_->udpEnable->setChecked(udpEnabled_);
ui_->udpWindowRestore->setChecked(udpWindowRestore_);
ui_->calibration_intercept_spin_box->setValue (calibration_.intercept);
ui_->calibration_slope_ppm_spin_box->setValue (calibration_.slope_ppm);
@@ -1334,7 +1220,6 @@ void Configuration::impl::initialize_models ()
next_frequencies_.frequency_list (frequencies_.frequency_list ());
next_stations_.station_list (stations_.station_list ());
set_rig_invariants ();
}
@@ -1352,18 +1237,11 @@ void Configuration::impl::read_settings ()
SettingsGroup g {settings_, "Configuration"};
restoreGeometry (settings_->value ("window/geometry").toByteArray ());
auto_switch_bands_ = settings_->value("AutoSwitchBands", false).toBool();
my_callsign_ = settings_->value ("MyCall", QString {}).toString ();
my_grid_ = settings_->value ("MyGrid", QString {}).toString ();
my_station_ = settings_->value("MyStation", QString {}).toString();
aprs_ssid_ = settings_->value("APRSSSID", "-0").toString();
callsign_aging_ = settings_->value ("CallsignAging", 0).toInt ();
activity_aging_ = settings_->value ("ActivityAging", 2).toInt ();
my_qth_ = settings_->value("MyQTH", QString {}).toString();
reply_ = settings_->value("Reply", QString {"HW CPY?"}).toString();
next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString();
next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString();
next_color_ReceivedMsg_ = color_ReceivedMsg_ = settings_->value("colorReceivedMsg","#ffeaa7").toString();
next_color_TxMsg_ = color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString();
next_color_DXCC_ = color_DXCC_ = settings_->value("colorDXCC","#ff00ff").toString();
next_color_NewCall_ = color_NewCall_ = settings_->value("colorNewCall","#ffaaff").toString();
@@ -1454,24 +1332,20 @@ void Configuration::impl::read_settings ()
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
transmit_directed_ = settings_->value ("TransmitDirected", true).toBool();
autoreply_off_at_startup_ = settings_->value ("AutoreplyOFF", false).toBool ();
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
spot_to_reporting_networks_ = settings_->value ("PSKReporter", true).toBool ();
spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
id_after_73_ = settings_->value ("After73", false).toBool ();
tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
use_dynamic_info_ = settings_->value ("AutoGrid", false).toBool ();
use_dynamic_grid_ = settings_->value ("AutoGrid", false).toBool ();
auto loadedMacros = settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList();
macros_.setStringList (loadedMacros);
macros_.setStringList (settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList ());
region_ = settings_->value ("Region", QVariant::fromValue (IARURegions::ALL)).value<IARURegions::Region> ();
if (settings_->contains (versionedFrequenciesSettingsKey))
if (settings_->contains ("FrequenciesForRegionModes"))
{
auto const& v = settings_->value (versionedFrequenciesSettingsKey);
auto const& v = settings_->value ("FrequenciesForRegionModes");
if (v.isValid ())
{
frequencies_.frequency_list (v.value<FrequencyList_v2::FrequencyItems> ());
@@ -1488,7 +1362,7 @@ void Configuration::impl::read_settings ()
stations_.station_list (settings_->value ("stations").value<StationList::Stations> ());
log_as_DATA_ = settings_->value ("toRTTY", false).toBool ();
log_as_RTTY_ = settings_->value ("toRTTY", false).toBool ();
report_in_comments_ = settings_->value("dBtoComments", false).toBool ();
rig_params_.rig_name = settings_->value ("Rig", TransceiverFactory::basic_transceiver_name_).toString ();
rig_is_dummy_ = TransceiverFactory::basic_transceiver_name_ == rig_params_.rig_name;
@@ -1515,8 +1389,7 @@ void Configuration::impl::read_settings ()
miles_ = settings_->value ("Miles", false).toBool ();
quick_call_ = settings_->value ("QuickCall", false).toBool ();
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
beacon_ = settings_->value ("TxBeacon", 30).toInt ();
watchdog_ = settings_->value ("TxWatchdog", 0).toInt ();
watchdog_ = settings_->value ("TxWatchdog", 6).toInt ();
TX_messages_ = settings_->value ("Tx2QSO", true).toBool ();
enable_VHF_features_ = settings_->value("VHFUHF",false).toBool ();
decode_at_52s_ = settings_->value("Decode52",false).toBool ();
@@ -1535,7 +1408,6 @@ void Configuration::impl::read_settings ()
n1mm_server_port_ = settings_->value ("N1MMServerPort", 2333).toUInt ();
broadcast_to_n1mm_ = settings_->value ("BroadcastToN1MM", false).toBool ();
accept_udp_requests_ = settings_->value ("AcceptUDPRequests", false).toBool ();
udpEnabled_ = settings_->value("UDPEnabled", false).toBool();
udpWindowToFront_ = settings_->value ("udpWindowToFront",false).toBool ();
udpWindowRestore_ = settings_->value ("udpWindowRestore",false).toBool ();
calibration_.intercept = settings_->value ("CalibrationIntercept", 0.).toDouble ();
@@ -1548,18 +1420,11 @@ void Configuration::impl::write_settings ()
{
SettingsGroup g {settings_, "Configuration"};
settings_->setValue ("AutoSwitchBands", auto_switch_bands_);
settings_->setValue ("MyCall", my_callsign_);
settings_->setValue ("MyGrid", my_grid_);
settings_->setValue ("MyStation", my_station_);
settings_->setValue ("APRSSSID", aprs_ssid_);
settings_->setValue ("MyQTH", my_qth_);
settings_->setValue ("Reply", reply_);
settings_->setValue ("CallsignAging", callsign_aging_);
settings_->setValue ("ActivityAging", activity_aging_);
settings_->setValue("colorCQ",color_CQ_);
settings_->setValue("colorMyCall",color_MyCall_);
settings_->setValue("colorReceivedMsg",color_ReceivedMsg_);
settings_->setValue("colorTxMsg",color_TxMsg_);
settings_->setValue("colorDXCC",color_DXCC_);
settings_->setValue("colorNewCall",color_NewCall_);
settings_->setValue ("Font", font_.toString ());
@@ -1595,17 +1460,15 @@ void Configuration::impl::write_settings ()
settings_->setValue ("AudioInputChannel", AudioDevice::toString (audio_input_channel_));
settings_->setValue ("AudioOutputChannel", AudioDevice::toString (audio_output_channel_));
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
settings_->setValue ("TransmitDirected", transmit_directed_);
settings_->setValue ("AutoreplyOFF", autoreply_off_at_startup_);
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
settings_->setValue ("PSKReporter", spot_to_reporting_networks_);
settings_->setValue ("PSKReporter", spot_to_psk_reporter_);
settings_->setValue ("After73", id_after_73_);
settings_->setValue ("TxQSYAllowed", tx_QSY_allowed_);
settings_->setValue ("Macros", macros_.stringList ());
settings_->setValue (versionedFrequenciesSettingsKey, QVariant::fromValue (frequencies_.frequency_list ()));
settings_->setValue ("FrequenciesForRegionModes", QVariant::fromValue (frequencies_.frequency_list ()));
settings_->setValue ("stations", QVariant::fromValue (stations_.station_list ()));
settings_->setValue ("toRTTY", log_as_DATA_);
settings_->setValue ("toRTTY", log_as_RTTY_);
settings_->setValue ("dBtoComments", report_in_comments_);
settings_->setValue ("Rig", rig_params_.rig_name);
settings_->setValue ("CATNetworkPort", rig_params_.network_port);
@@ -1624,7 +1487,6 @@ void Configuration::impl::write_settings ()
settings_->setValue ("Miles", miles_);
settings_->setValue ("QuickCall", quick_call_);
settings_->setValue ("73TxDisable", disable_TX_on_73_);
settings_->setValue ("TxBeacon", beacon_);
settings_->setValue ("TxWatchdog", watchdog_);
settings_->setValue ("Tx2QSO", TX_messages_);
settings_->setValue ("CATForceDTR", rig_params_.force_dtr);
@@ -1649,7 +1511,6 @@ void Configuration::impl::write_settings ()
settings_->setValue ("N1MMServerPort", n1mm_server_port_);
settings_->setValue ("BroadcastToN1MM", broadcast_to_n1mm_);
settings_->setValue ("AcceptUDPRequests", accept_udp_requests_);
settings_->setValue ("UDPEnabled", udpEnabled_);
settings_->setValue ("udpWindowToFront", udpWindowToFront_);
settings_->setValue ("udpWindowRestore", udpWindowRestore_);
settings_->setValue ("CalibrationIntercept", calibration_.intercept);
@@ -1657,7 +1518,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("pwrBandTxMemory", pwrBandTxMemory_);
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
settings_->setValue ("Region", QVariant::fromValue (region_));
settings_->setValue ("AutoGrid", use_dynamic_info_);
settings_->setValue ("AutoGrid", use_dynamic_grid_);
}
void Configuration::impl::set_rig_invariants ()
@@ -1927,12 +1788,10 @@ void Configuration::impl::accept ()
color_CQ_ = next_color_CQ_;
color_MyCall_ = next_color_MyCall_;
color_ReceivedMsg_ = next_color_ReceivedMsg_;
color_TxMsg_ = next_color_TxMsg_;
color_DXCC_ = next_color_DXCC_;
color_NewCall_ = next_color_NewCall_;
Q_EMIT self_->colors_changed();
rig_params_ = temp_rig_params; // now we can go live with the rig
// related configuration parameters
rig_is_dummy_ = TransceiverFactory::basic_transceiver_name_ == rig_params_.rig_name;
@@ -2011,16 +1870,9 @@ void Configuration::impl::accept ()
}
Q_ASSERT (audio_output_channel_ <= AudioDevice::Both);
auto_switch_bands_ = ui_->auto_switch_bands_check_box->isChecked();
my_callsign_ = ui_->callsign_line_edit->text ();
my_grid_ = ui_->grid_line_edit->text ();
my_station_ = ui_->station_message_line_edit->text().toUpper();
reply_ = ui_->reply_message_line_edit->text().toUpper();
aprs_ssid_ = ui_->aprs_ssid_line_edit->text().toUpper();
my_qth_ = ui_->qth_message_line_edit->text().toUpper();
callsign_aging_ = ui_->callsign_aging_spin_box->value();
activity_aging_ = ui_->activity_aging_spin_box->value();
spot_to_reporting_networks_ = ui_->psk_reporter_check_box->isChecked ();
spot_to_psk_reporter_ = ui_->psk_reporter_check_box->isChecked ();
id_interval_ = ui_->CW_id_interval_spin_box->value ();
ntrials_ = ui_->sbNtrials->value ();
txDelay_ = ui_->sbTxDelay->value ();
@@ -2029,12 +1881,10 @@ void Configuration::impl::accept ()
RxBandwidth_ = ui_->sbBandwidth->value ();
id_after_73_ = ui_->CW_id_after_73_check_box->isChecked ();
tx_QSY_allowed_ = ui_->tx_QSY_check_box->isChecked ();
transmit_directed_ = ui_->transmit_directed_check_box->isChecked();
autoreply_off_at_startup_ = ui_->autoreply_off_check_box->isChecked ();
monitor_off_at_startup_ = ui_->monitor_off_check_box->isChecked ();
monitor_last_used_ = ui_->monitor_last_used_check_box->isChecked ();
type_2_msg_gen_ = static_cast<Type2MsgGen> (ui_->type_2_msg_gen_combo_box->currentIndex ());
log_as_DATA_ = ui_->log_as_RTTY_check_box->isChecked ();
log_as_RTTY_ = ui_->log_as_RTTY_check_box->isChecked ();
report_in_comments_ = ui_->report_in_comments_check_box->isChecked ();
prompt_to_log_ = ui_->prompt_to_log_check_box->isChecked ();
insert_blank_ = ui_->insert_blank_check_box->isChecked ();
@@ -2044,7 +1894,6 @@ void Configuration::impl::accept ()
miles_ = ui_->miles_check_box->isChecked ();
quick_call_ = ui_->quick_call_check_box->isChecked ();
disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked ();
beacon_ = ui_->beacon_spin_box->value ();
watchdog_ = ui_->tx_watchdog_spin_box->value ();
TX_messages_ = ui_->TX_messages_check_box->isChecked ();
data_mode_ = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
@@ -2063,15 +1912,11 @@ void Configuration::impl::accept ()
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
opCall_=ui_->opCallEntry->text();
auto newUdpEnabled = ui_->udpEnable->isChecked();
auto new_server = ui_->udp_server_line_edit->text ();
if (new_server != udp_server_name_ || newUdpEnabled != udpEnabled_)
if (new_server != udp_server_name_)
{
udp_server_name_ = new_server;
udpEnabled_ = newUdpEnabled;
Q_EMIT self_->udp_server_changed (udpEnabled_ ? new_server : "");
Q_EMIT self_->udp_server_changed (new_server);
}
auto new_port = ui_->udp_server_port_spin_box->value ();
@@ -2080,7 +1925,7 @@ void Configuration::impl::accept ()
udp_server_port_ = new_port;
Q_EMIT self_->udp_server_port_changed (new_port);
}
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text ();
n1mm_server_name_ = new_n1mm_server;
@@ -2091,7 +1936,6 @@ void Configuration::impl::accept ()
udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
udpWindowRestore_ = ui_->udpWindowRestore->isChecked ();
if (macros_.stringList () != next_macros_.stringList ())
{
macros_.setStringList (next_macros_.stringList ());
@@ -2108,17 +1952,15 @@ void Configuration::impl::accept ()
if (stations_.station_list () != next_stations_.station_list ())
{
stations_.station_list(next_stations_.station_list ());
stations_.sort (StationList::switch_at_column);
Q_EMIT self_->band_schedule_changed(this->stations_);
stations_.sort (StationList::band_column);
}
if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_info_ )
if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
{
// turning on so clear it so only the next location update gets used
dynamic_grid_.clear ();
}
use_dynamic_info_ = ui_->use_dynamic_grid->isChecked();
use_dynamic_grid_ = ui_->use_dynamic_grid->isChecked();
write_settings (); // make visible to all
}
@@ -2153,7 +1995,7 @@ void Configuration::impl::on_font_push_button_clicked ()
void Configuration::impl::on_pbCQmsg_clicked()
{
auto new_color = QColorDialog::getColor(next_color_CQ_, this, "CQ and BEACON Messages Color");
auto new_color = QColorDialog::getColor(next_color_CQ_, this, "CQ Messages Color");
if (new_color.isValid ())
{
next_color_CQ_ = new_color;
@@ -2163,7 +2005,7 @@ void Configuration::impl::on_pbCQmsg_clicked()
void Configuration::impl::on_pbMyCall_clicked()
{
auto new_color = QColorDialog::getColor(next_color_MyCall_, this, "Directed Messages Color");
auto new_color = QColorDialog::getColor(next_color_MyCall_, this, "My Call Messages Color");
if (new_color.isValid ())
{
next_color_MyCall_ = new_color;
@@ -2173,11 +2015,11 @@ void Configuration::impl::on_pbMyCall_clicked()
void Configuration::impl::on_pbTxMsg_clicked()
{
auto new_color = QColorDialog::getColor(next_color_ReceivedMsg_, this, "Received Messages Textarea Color");
auto new_color = QColorDialog::getColor(next_color_TxMsg_, this, "Tx Messages Color");
if (new_color.isValid ())
{
next_color_ReceivedMsg_ = new_color;
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_ReceivedMsg_.name()));
next_color_TxMsg_ = new_color;
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_TxMsg_.name()));
}
}
@@ -2204,7 +2046,7 @@ void Configuration::impl::on_pbNewCall_clicked()
void Configuration::impl::on_decoded_text_font_push_button_clicked ()
{
next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this
, tr ("Font Chooser")
, tr ("WSJT-X Decoded Text Font Chooser")
#if QT_VERSION >= 0x050201
, QFontDialog::MonospacedFonts
#endif
@@ -2312,30 +2154,6 @@ void Configuration::impl::on_sound_output_combo_box_currentTextChanged (QString
default_audio_output_device_selected_ = QAudioDeviceInfo::defaultOutputDevice ().deviceName () == text;
}
void Configuration::impl::on_station_message_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
if(text != upper){
ui_->station_message_line_edit->setText (upper);
}
}
void Configuration::impl::on_qth_message_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
if(text != upper){
ui_->qth_message_line_edit->setText (upper);
}
}
void Configuration::impl::on_reply_message_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
if(text != upper){
ui_->reply_message_line_edit->setText (upper);
}
}
void Configuration::impl::on_add_macro_line_edit_editingFinished ()
{
ui_->add_macro_line_edit->setText (ui_->add_macro_line_edit->text ().toUpper ());
@@ -2522,29 +2340,16 @@ void Configuration::impl::delete_stations ()
selection_model->select (selection_model->selection (), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
next_stations_.removeDisjointRows (selection_model->selectedRows ());
ui_->stations_table_view->resizeColumnToContents (StationList::band_column);
ui_->stations_table_view->resizeColumnToContents (StationList::frequency_column);
ui_->stations_table_view->resizeColumnToContents (StationList::switch_at_column);
ui_->stations_table_view->resizeColumnToContents (StationList::switch_until_column);
ui_->stations_table_view->resizeColumnToContents (StationList::offset_column);
}
void Configuration::impl::insert_station ()
{
if (QDialog::Accepted == station_dialog_->exec ())
{
auto station = station_dialog_->station ();
if(station.frequency_ == 0){
Frequency l;
Frequency h;
if(bands_.findFreq(station.band_name_, &l, &h)){
station.frequency_ = l;
}
}
ui_->stations_table_view->setCurrentIndex (next_stations_.add (station));
ui_->stations_table_view->setCurrentIndex (next_stations_.add (station_dialog_->station ()));
ui_->stations_table_view->resizeColumnToContents (StationList::band_column);
ui_->stations_table_view->resizeColumnToContents (StationList::frequency_column);
ui_->stations_table_view->resizeColumnToContents (StationList::switch_at_column);
ui_->stations_table_view->resizeColumnToContents (StationList::switch_until_column);
ui_->stations_table_view->resizeColumnToContents (StationList::offset_column);
}
}
@@ -2708,7 +2513,8 @@ void Configuration::impl::transceiver_frequency (Frequency f)
// cannot absolutely determine if the offset should apply but by
// simply picking an offset when the Rx frequency is set and
// sticking to it we get sane behaviour
cached_rig_state_.frequency (apply_calibration (f));
current_offset_ = stations_.offset (f);
cached_rig_state_.frequency (apply_calibration (f + current_offset_));
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
}
@@ -2731,7 +2537,8 @@ void Configuration::impl::transceiver_tx_frequency (Frequency f)
// rig, we cannot absolutely determine if the offset should
// apply but by simply picking an offset when the Rx
// frequency is set and sticking to it we get sane behaviour
cached_rig_state_.tx_frequency (apply_calibration (f));
current_tx_offset_ = stations_.offset (f);
cached_rig_state_.tx_frequency (apply_calibration (f + current_tx_offset_));
}
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
@@ -2798,12 +2605,12 @@ void Configuration::impl::handle_transceiver_update (TransceiverState const& sta
{
TransceiverState reported_state {state};
// take off calibration & offset
reported_state.frequency (remove_calibration (reported_state.frequency ()));
reported_state.frequency (remove_calibration (reported_state.frequency ()) - current_offset_);
if (reported_state.tx_frequency ())
{
// take off calibration & offset
reported_state.tx_frequency (remove_calibration (reported_state.tx_frequency ()));
reported_state.tx_frequency (remove_calibration (reported_state.tx_frequency ()) - current_tx_offset_);
}
Q_EMIT self_->transceiver_update (reported_state);
+4 -24
View File
@@ -94,15 +94,8 @@ public:
bool restart_audio_input () const;
bool restart_audio_output () const;
bool use_dynamic_grid() const;
QString my_callsign () const;
QString my_grid () const;
QString my_station () const;
QString aprs_ssid() const;
int activity_aging() const;
int callsign_aging() const;
QString my_qth () const;
QString reply () const;
QFont text_font () const;
QFont decoded_text_font () const;
qint32 id_interval () const;
@@ -113,13 +106,10 @@ public:
double txDelay() const;
bool id_after_73 () const;
bool tx_QSY_allowed () const;
bool spot_to_reporting_networks () const;
void set_spot_to_reporting_networks (bool);
bool transmit_directed() const;
bool autoreply_off_at_startup () const;
bool spot_to_psk_reporter () const;
bool monitor_off_at_startup () const;
bool monitor_last_used () const;
bool log_as_DATA () const;
bool log_as_RTTY () const;
bool report_in_comments () const;
bool prompt_to_log () const;
bool insert_blank () const;
@@ -129,7 +119,6 @@ public:
bool miles () const;
bool quick_call () const;
bool disable_TX_on_73 () const;
int beacon () const;
int watchdog () const;
bool TX_messages () const;
bool split_mode () const;
@@ -158,7 +147,6 @@ public:
bool accept_udp_requests () const;
bool udpWindowToFront () const;
bool udpWindowRestore () const;
bool udpEnabled () const;
Bands * bands ();
Bands const * bands () const;
IARURegions::Region region () const;
@@ -166,7 +154,6 @@ public:
FrequencyList_v2 const * frequencies () const;
StationList * stations ();
StationList const * stations () const;
bool auto_switch_bands() const;
QStringListModel * macros ();
QStringListModel const * macros () const;
QDir save_directory () const;
@@ -175,7 +162,7 @@ public:
Type2MsgGen type_2_msg_gen () const;
QColor color_CQ () const;
QColor color_MyCall () const;
QColor color_ReceivedMsg () const;
QColor color_TxMsg () const;
QColor color_DXCC () const;
QColor color_NewCall () const;
bool pwrBandTxMemory () const;
@@ -206,11 +193,7 @@ public:
void set_calibration (CalibrationParams);
// Set the dynamic grid which is only used if configuration setting is enabled.
void set_dynamic_location (QString const&);
// Set the dynamic statios message which is only used if configuration setting is enabled.
void set_dynamic_station_message(QString const& qtc);
void set_location (QString const&);
// This method queries if a CAT and PTT connection is operational.
bool is_transceiver_online () const;
@@ -270,7 +253,6 @@ public:
//
Q_SIGNAL void text_font_changed (QFont);
Q_SIGNAL void decoded_text_font_changed (QFont);
Q_SIGNAL void colors_changed ();
//
// This signal is emitted when the UDP server changes
@@ -278,8 +260,6 @@ public:
Q_SIGNAL void udp_server_changed (QString const& udp_server);
Q_SIGNAL void udp_server_port_changed (port_type server_port);
// This signal is emitted when the band schedule changes
Q_SIGNAL void band_schedule_changed (StationList &stations);
//
// These signals are emitted and reflect transceiver state changes
+685 -1089
View File
File diff suppressed because it is too large Load Diff
+151 -11
View File
@@ -26,16 +26,154 @@ namespace
{
FrequencyList_v2::FrequencyItems const default_frequency_list =
{
{ 1842000, Modes::FT8CALL, IARURegions::ALL}, // 2 above
{ 3578000, Modes::FT8CALL, IARURegions::ALL}, // 5 above
{ 7078000, Modes::FT8CALL, IARURegions::ALL}, // 4 above
{10130000, Modes::FT8CALL, IARURegions::ALL}, // 6 below
{14078000, Modes::FT8CALL, IARURegions::ALL}, // 4 above
{18104000, Modes::FT8CALL, IARURegions::ALL}, // 4 above
{21078000, Modes::FT8CALL, IARURegions::ALL}, // 4 above
{24922000, Modes::FT8CALL, IARURegions::ALL}, // 9 above
{28078000, Modes::FT8CALL, IARURegions::ALL}, // 4 above
{50318000, Modes::FT8CALL, IARURegions::ALL}, // 5 above
{198000, Modes::FreqCal, IARURegions::R1}, // BBC Radio 4 Droitwich
{4996000, Modes::FreqCal, IARURegions::R1}, // RWM time signal
{9996000, Modes::FreqCal, IARURegions::R1}, // RWM time signal
{14996000, Modes::FreqCal, IARURegions::R1}, // RWM time signal
{660000, Modes::FreqCal, IARURegions::R2},
{880000, Modes::FreqCal, IARURegions::R2},
{1210000, Modes::FreqCal, IARURegions::R2},
{2500000, Modes::FreqCal, IARURegions::ALL},
{3330000, Modes::FreqCal, IARURegions::ALL},
{5000000, Modes::FreqCal, IARURegions::ALL},
{7850000, Modes::FreqCal, IARURegions::ALL},
{10000000, Modes::FreqCal, IARURegions::ALL},
{14670000, Modes::FreqCal, IARURegions::ALL},
{15000000, Modes::FreqCal, IARURegions::ALL},
{20000000, Modes::FreqCal, IARURegions::ALL},
{136000, Modes::WSPR, IARURegions::ALL},
{136130, Modes::JT65, IARURegions::ALL},
{136130, Modes::JT9, IARURegions::ALL},
{474200, Modes::JT65, IARURegions::ALL},
{474200, Modes::JT9, IARURegions::ALL},
{474200, Modes::WSPR, IARURegions::ALL},
{1836600, Modes::WSPR, IARURegions::ALL},
{1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations
{1839000, Modes::JT9, IARURegions::ALL},
{1840000, Modes::FT8, IARURegions::ALL},
{3570000, Modes::JT65, IARURegions::ALL}, // JA compatible
{3572000, Modes::JT9, IARURegions::ALL},
{3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65
// is out of DM allocation
{3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker
// and lock out
{7038600, Modes::WSPR, IARURegions::ALL},
{7074000, Modes::FT8, IARURegions::ALL},
{7076000, Modes::JT65, IARURegions::ALL},
{7078000, Modes::JT9, IARURegions::ALL},
{10136000, Modes::FT8, IARURegions::ALL},
{10138000, Modes::JT65, IARURegions::ALL},
{10138700, Modes::WSPR, IARURegions::ALL},
{10140000, Modes::JT9, IARURegions::ALL},
{14095600, Modes::WSPR, IARURegions::ALL},
{14074000, Modes::FT8, IARURegions::ALL},
{14076000, Modes::JT65, IARURegions::ALL},
{14078000, Modes::JT9, IARURegions::ALL},
{18100000, Modes::FT8, IARURegions::ALL},
{18102000, Modes::JT65, IARURegions::ALL},
{18104000, Modes::JT9, IARURegions::ALL},
{18104600, Modes::WSPR, IARURegions::ALL},
{21074000, Modes::FT8, IARURegions::ALL},
{21076000, Modes::JT65, IARURegions::ALL},
{21078000, Modes::JT9, IARURegions::ALL},
{21094600, Modes::WSPR, IARURegions::ALL},
{24915000, Modes::FT8, IARURegions::ALL},
{24917000, Modes::JT65, IARURegions::ALL},
{24919000, Modes::JT9, IARURegions::ALL},
{24924600, Modes::WSPR, IARURegions::ALL},
{28074000, Modes::FT8, IARURegions::ALL},
{28076000, Modes::JT65, IARURegions::ALL},
{28078000, Modes::JT9, IARURegions::ALL},
{28124600, Modes::WSPR, IARURegions::ALL},
{50200000, Modes::Echo, IARURegions::ALL},
{50276000, Modes::JT65, IARURegions::R2},
{50276000, Modes::JT65, IARURegions::R3},
{50260000, Modes::MSK144, IARURegions::R2},
{50260000, Modes::MSK144, IARURegions::R3},
{50293000, Modes::WSPR, IARURegions::R2},
{50293000, Modes::WSPR, IARURegions::R3},
{50310000, Modes::JT65, IARURegions::ALL},
{50312000, Modes::JT9, IARURegions::ALL},
{50313000, Modes::FT8, IARURegions::ALL},
{50360000, Modes::MSK144, IARURegions::R1},
{70100000, Modes::FT8, IARURegions::R1},
{70102000, Modes::JT65, IARURegions::R1},
{70104000, Modes::JT9, IARURegions::R1},
{70091000, Modes::WSPR, IARURegions::R1},
{70230000, Modes::MSK144, IARURegions::R1},
{144120000, Modes::JT65, IARURegions::ALL},
{144120000, Modes::Echo, IARURegions::ALL},
{144360000, Modes::MSK144, IARURegions::R1},
{144150000, Modes::MSK144, IARURegions::R2},
{144489000, Modes::WSPR, IARURegions::ALL},
{144120000, Modes::QRA64, IARURegions::ALL},
{222065000, Modes::Echo, IARURegions::R2},
{222065000, Modes::JT65, IARURegions::R2},
{222065000, Modes::QRA64, IARURegions::R2},
{432065000, Modes::Echo, IARURegions::ALL},
{432065000, Modes::JT65, IARURegions::ALL},
{432300000, Modes::WSPR, IARURegions::ALL},
{432360000, Modes::MSK144, IARURegions::ALL},
{432065000, Modes::QRA64, IARURegions::ALL},
{902065000, Modes::JT65, IARURegions::R2},
{902065000, Modes::QRA64, IARURegions::R2},
{1296065000, Modes::Echo, IARURegions::ALL},
{1296065000, Modes::JT65, IARURegions::ALL},
{1296500000, Modes::WSPR, IARURegions::ALL},
{1296065000, Modes::QRA64, IARURegions::ALL},
{2301000000, Modes::Echo, IARURegions::ALL},
{2301065000, Modes::JT4, IARURegions::ALL},
{2301065000, Modes::JT65, IARURegions::ALL},
{2301065000, Modes::QRA64, IARURegions::ALL},
{2304065000, Modes::Echo, IARURegions::ALL},
{2304065000, Modes::JT4, IARURegions::ALL},
{2304065000, Modes::JT65, IARURegions::ALL},
{2304065000, Modes::QRA64, IARURegions::ALL},
{2320065000, Modes::Echo, IARURegions::ALL},
{2320065000, Modes::JT4, IARURegions::ALL},
{2320065000, Modes::JT65, IARURegions::ALL},
{2320065000, Modes::QRA64, IARURegions::ALL},
{3400065000, Modes::Echo, IARURegions::ALL},
{3400065000, Modes::JT4, IARURegions::ALL},
{3400065000, Modes::JT65, IARURegions::ALL},
{3400065000, Modes::QRA64, IARURegions::ALL},
{5760065000, Modes::Echo, IARURegions::ALL},
{5760065000, Modes::JT4, IARURegions::ALL},
{5760065000, Modes::JT65, IARURegions::ALL},
{5760200000, Modes::QRA64, IARURegions::ALL},
{10368100000, Modes::Echo, IARURegions::ALL},
{10368200000, Modes::JT4, IARURegions::ALL},
{10368200000, Modes::QRA64, IARURegions::ALL},
{24048100000, Modes::Echo, IARURegions::ALL},
{24048200000, Modes::JT4, IARURegions::ALL},
{24048200000, Modes::QRA64, IARURegions::ALL},
};
}
@@ -257,7 +395,9 @@ bool FrequencyList_v2::filterAcceptsRow (int source_row, QModelIndex const& /* p
}
if (result && m_->mode_filter_ != Modes::ALL)
{
result = Modes::ALL == item.mode_ || m_->mode_filter_ == item.mode_;
// we pass ALL mode rows unless filtering for FreqCal mode
result = (Modes::ALL == item.mode_ && m_->mode_filter_ != Modes::FreqCal)
|| m_->mode_filter_ == item.mode_;
}
return result;
}
+1 -1
View File
@@ -11,7 +11,7 @@ class MaidenheadLocatorValidator final
: public QValidator
{
public:
enum class Length {field = 2, square = 4, subsquare = 6, extended = 8, doubleextended = 16};
enum class Length {field = 2, square = 4, subsquare = 6, extended = 8};
MaidenheadLocatorValidator (QObject * parent = nullptr
, Length length = Length::subsquare
, Length required = Length::square);
+210 -92
View File
@@ -4,7 +4,6 @@
#include <vector>
#include <algorithm>
#include <QApplication>
#include <QUdpSocket>
#include <QHostInfo>
#include <QTimer>
@@ -13,70 +12,16 @@
#include <QHostAddress>
#include <QColor>
#include "NetworkMessage.hpp"
#include "pimpl_impl.hpp"
#include "moc_MessageClient.cpp"
Message::Message()
{
}
Message::Message(QString const &type, QString const &value):
type_{ type },
value_{ value }
{
}
Message::Message(QString const &type, QString const &value, QMap<QString, QVariant> const &params):
type_{ type },
value_{ value },
params_{ params }
{
}
void Message::read(const QJsonObject &json){
if(json.contains("type") && json["type"].isString()){
type_ = json["type"].toString();
}
if(json.contains("value") && json["value"].isString()){
value_ = json["value"].toString();
}
if(json.contains("params") && json["params"].isObject()){
params_.clear();
QJsonObject params = json["params"].toObject();
foreach(auto key, params.keys()){
params_[key] = params[key].toVariant();
}
}
}
void Message::write(QJsonObject &json) const{
json["type"] = type_;
json["value"] = value_;
QJsonObject params;
foreach(auto key, params_.keys()){
params.insert(key, QJsonValue::fromVariant(params_[key]));
}
json["params"] = params;
}
QByteArray Message::toJson() const {
QJsonObject o;
write(o);
QJsonDocument d(o);
return d.toJson();
}
class MessageClient::impl
: public QUdpSocket
{
Q_OBJECT
Q_OBJECT;
public:
impl (QString const& id, QString const& version, QString const& revision,
@@ -92,7 +37,7 @@ public:
connect (heartbeat_timer_, &QTimer::timeout, this, &impl::heartbeat);
connect (this, &QIODevice::readyRead, this, &impl::pending_datagrams);
heartbeat_timer_->start (15 * 1000);
heartbeat_timer_->start (NetworkMessage::pulse * 1000);
// bind to an ephemeral port
bind ();
@@ -141,7 +86,6 @@ public:
QByteArray last_message_;
};
#include "MessageClient.moc"
void MessageClient::impl::host_info_results (QHostInfo host_info)
@@ -194,26 +138,111 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
{
try
{
if(msg.isEmpty()){
return;
//
// message format is described in NetworkMessage.hpp
//
NetworkMessage::Reader in {msg};
if (OK == check_status (in) && id_ == in.id ()) // OK and for us
{
if (schema_ < in.schema ()) // one time record of server's
// negotiated schema
{
schema_ = in.schema ();
}
//
// message format is described in NetworkMessage.hpp
//
switch (in.type ())
{
case NetworkMessage::Reply:
{
// unpack message
QTime time;
qint32 snr;
float delta_time;
quint32 delta_frequency;
QByteArray mode;
QByteArray message;
bool low_confidence {false};
quint8 modifiers {0};
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message
>> low_confidence >> modifiers;
if (check_status (in) != Fail)
{
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
, low_confidence, modifiers);
}
}
break;
case NetworkMessage::Replay:
if (check_status (in) != Fail)
{
last_message_.clear ();
Q_EMIT self_->replay ();
}
break;
case NetworkMessage::HaltTx:
{
bool auto_only {false};
in >> auto_only;
if (check_status (in) != Fail)
{
Q_EMIT self_->halt_tx (auto_only);
}
}
break;
case NetworkMessage::FreeText:
{
QByteArray message;
bool send {true};
in >> message >> send;
if (check_status (in) != Fail)
{
Q_EMIT self_->free_text (QString::fromUtf8 (message), send);
}
}
break;
case NetworkMessage::Location:
{
QByteArray location;
in >> location;
if (check_status (in) != Fail)
{
Q_EMIT self_->location (QString::fromUtf8 (location));
}
}
break;
case NetworkMessage::HighlightCallsign:
{
QByteArray call;
QColor bg; // default invalid color
QColor fg; // default invalid color
bool last_only {false};
in >> call >> bg >> fg >> last_only;
if (check_status (in) != Fail && call.size ())
{
Q_EMIT self_->highlight_callsign (QString::fromUtf8 (call), bg, fg, last_only);
}
}
break;
default:
// Ignore
//
// Note that although server heartbeat messages are not
// parsed here they are still partially parsed in the
// message reader class to negotiate the maximum schema
// number being used on the network.
break;
}
}
QJsonParseError e;
QJsonDocument d = QJsonDocument::fromJson(msg, &e);
if(e.error != QJsonParseError::NoError){
Q_EMIT self_->error(QString {"MessageClient json parse error: %1"}.arg(e.errorString()));
return;
}
if(!d.isObject()){
Q_EMIT self_->error(QString {"MessageClient json parse error: json is not an object"});
return;
}
Message m;
m.read(d.object());
Q_EMIT self_->message(m);
}
catch (std::exception const& e)
{
@@ -229,12 +258,14 @@ void MessageClient::impl::heartbeat ()
{
if (server_port_ && !server_.isNull ())
{
Message m("PING", "", QMap<QString, QVariant>{
{"NAME", QVariant(QApplication::applicationName())},
{"VERSION", QVariant(QApplication::applicationVersion())},
{"UTC", QVariant(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch())}
});
writeDatagram (m.toJson(), server_, server_port_);
QByteArray message;
NetworkMessage::Builder hb {&message, NetworkMessage::Heartbeat, id_, schema_};
hb << NetworkMessage::Builder::schema_number // maximum schema number accepted
<< version_.toUtf8 () << revision_.toUtf8 ();
if (OK == check_status (hb))
{
writeDatagram (message, server_, server_port_);
}
}
}
@@ -242,8 +273,12 @@ void MessageClient::impl::closedown ()
{
if (server_port_ && !server_.isNull ())
{
Message m("CLOSE");
writeDatagram (m.toJson(), server_, server_port_);
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::Close, id_, schema_};
if (OK == check_status (out))
{
writeDatagram (message, server_, server_port_);
}
}
}
@@ -329,7 +364,6 @@ auto MessageClient::server_port () const -> port_type
void MessageClient::set_server (QString const& server)
{
qDebug() << "server changed to" << server;
m_->server_.clear ();
m_->server_string_ = server;
if (!server.isEmpty ())
@@ -344,10 +378,6 @@ void MessageClient::set_server_port (port_type server_port)
m_->server_port_ = server_port;
}
void MessageClient::send(Message const &message){
m_->send_message(message.toJson());
}
void MessageClient::send_raw_datagram (QByteArray const& message, QHostAddress const& dest_address
, port_type dest_port)
{
@@ -367,3 +397,91 @@ void MessageClient::add_blocked_destination (QHostAddress const& a)
m_->pending_messages_.clear (); // discard
}
}
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 decoding
, qint32 rx_df, qint32 tx_df, QString const& de_call
, QString const& de_grid, QString const& dx_grid
, bool watchdog_timeout, QString const& sub_mode
, bool fast_mode)
{
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 << decoding << rx_df << tx_df << de_call.toUtf8 ()
<< de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 ()
<< fast_mode;
m_->send_message (out, message);
}
}
void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message_text, bool low_confidence
, bool off_air)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
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 () << low_confidence << off_air;
m_->send_message (out, message);
}
}
void MessageClient::WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency frequency
, qint32 drift, QString const& callsign, QString const& grid, qint32 power
, bool off_air)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::WSPRDecode, m_->id_, m_->schema_};
out << is_new << time << snr << delta_time << frequency << drift << callsign.toUtf8 ()
<< grid.toUtf8 () << power << off_air;
m_->send_message (out, message);
}
}
void MessageClient::clear_decodes ()
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::Clear, m_->id_, m_->schema_};
m_->send_message (out, message);
}
}
void MessageClient::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, QString const& name, QDateTime time_on
, QString const& operator_call, QString const& my_call
, QString const& my_grid)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
out << time_off << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 ()
<< name.toUtf8 () << time_on << operator_call.toUtf8 () << my_call.toUtf8 () << my_grid.toUtf8 ();
m_->send_message (out, message);
}
}
void MessageClient::logged_ADIF (QByteArray const& ADIF_record)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::LoggedADIF, m_->id_, m_->schema_};
QByteArray ADIF {"\n<adif_ver:5>3.0.7\n<programid:6>WSJT-X\n<EOH>\n" + ADIF_record + " <EOR>"};
out << ADIF;
m_->send_message (out, message);
}
}
+47 -32
View File
@@ -3,11 +3,8 @@
#include <QObject>
#include <QTime>
#include <QDataStream>
#include <QDateTime>
#include <QString>
#include <QJsonDocument>
#include <QJsonObject>
#include "Radio.hpp"
#include "pimpl_h.hpp"
@@ -16,29 +13,6 @@ class QByteArray;
class QHostAddress;
class QColor;
class Message {
public:
Message();
Message(QString const &type, QString const &value="");
Message(QString const &type, QString const &value, QMap<QString, QVariant> const &params);
void read(const QJsonObject &json);
void write(QJsonObject &json) const;
QByteArray toJson() const;
QString type() const { return type_; }
QString value() const { return value_; }
QMap<QString, QVariant> params() const { return params_; }
private:
QString type_;
QString value_;
QMap<QString, QVariant> params_;
};
//
// MessageClient - Manage messages sent and replies received from a
// matching server (MessageServer) at the other end of
@@ -50,7 +24,7 @@ private:
class MessageClient
: public QObject
{
Q_OBJECT
Q_OBJECT;
public:
using Frequency = Radio::Frequency;
@@ -73,8 +47,28 @@ public:
// change the server port messages are sent to
Q_SLOT void set_server_port (port_type server_port = 0u);
// this slot is used to send an arbitrary message
Q_SLOT void send(Message const &message);
// 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, bool decoding
, qint32 rx_df, qint32 tx_df, QString const& de_call, QString const& de_grid
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
, bool fast_mode);
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message, bool low_confidence
, bool off_air);
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 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
, QString const& name, QDateTime time_on, QString const& operator_call
, QString const& my_call, QString const& my_grid);
// ADIF_record argument should be valid ADIF excluding any <EOR> end
// of record marker
Q_SLOT void logged_ADIF (QByteArray const& ADIF_record);
// this slot may be used to send arbitrary UDP datagrams to and
// destination allowing the underlying socket to be used for general
@@ -85,15 +79,36 @@ public:
// with send_raw_datagram() above)
Q_SLOT void add_blocked_destination (QHostAddress const&);
Q_SIGNAL void message(Message const &message);
// 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
, QString const& message_text, bool low_confidence, quint8 modifiers);
// this signal is emitted when the a reply a message is received
Q_SIGNAL void message_received(QString const &type, QString const &message);
// this signal is emitted if the server has requested a replay of
// all decodes
Q_SIGNAL void replay ();
// this signal is emitted if the server has requested immediate (or
// auto Tx if auto_only is true) transmission to halt
Q_SIGNAL void halt_tx (bool auto_only);
// this signal is emitted if the server has requested a new free
// message text
Q_SIGNAL void free_text (QString const&, bool send);
// this signal is emitted if the server has sent a highlight
// callsign request for the specified call
Q_SIGNAL void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only);
// this signal is emitted when network errors occur or if a host
// lookup fails
Q_SIGNAL void error (QString const&) const;
// this signal is emitted if the message obtains a location from a
// server. (It doesn't have to be new, could be a periodic location
// update)
Q_SIGNAL void location (QString const&);
private:
class impl;
pimpl<impl> m_;
+10 -1
View File
@@ -14,7 +14,16 @@ namespace
char const * const mode_names[] =
{
"All",
"FT8CALL",
"JT65",
"JT9",
"JT4",
"WSPR",
"Echo",
"ISCAT",
"MSK144",
"QRA64",
"FreqCal",
"FT8"
};
std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]);
}
+10 -1
View File
@@ -40,7 +40,16 @@ public:
enum Mode
{
ALL, // matches with all modes
FT8CALL,
JT65,
JT9,
JT4,
WSPR,
Echo,
ISCAT,
MSK144,
QRA64,
FreqCal,
FT8,
MODES_END_SENTINAL_AND_COUNT // this must be last
};
Q_ENUM (Mode)
-40
View File
@@ -1,40 +0,0 @@
#include "SelfDestructMessageBox.h"
SelfDestructMessageBox::SelfDestructMessageBox(
int timeout,
const QString& title,
const QString& text,
QMessageBox::Icon icon,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton,
QWidget* parent,
Qt::WindowFlags flags)
: QMessageBox(icon, title, text, buttons, parent, flags),
m_timeout(timeout),
m_text(text)
{
connect(&m_timer, &QTimer::timeout, this, &SelfDestructMessageBox::tick);
m_timer.setInterval(1000);
setDefaultButton(defaultButton);
connect(this->defaultButton(), &QPushButton::clicked, this, &SelfDestructMessageBox::accept);
}
void SelfDestructMessageBox::showEvent(QShowEvent* event)
{
tick();
m_timer.start();
QMessageBox::showEvent(event);
}
void SelfDestructMessageBox::tick(){
m_timeout--;
if(m_timeout){
setText(m_text.arg(m_timeout));
return;
}
m_timer.stop();
accept();
}
-35
View File
@@ -1,35 +0,0 @@
#ifndef SELFDESTRUCTMESSAGEBOX_H
#define SELFDESTRUCTMESSAGEBOX_H
#include <QWidget>
#include <QMessageBox>
#include <QPushButton>
#include <QString>
#include <QTimer>
class SelfDestructMessageBox : public QMessageBox
{
Q_OBJECT
public:
SelfDestructMessageBox(int timeout,
const QString& title,
const QString& text,
QMessageBox::Icon icon,
QMessageBox::StandardButtons buttons = QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::StandardButton defaultButton = QMessageBox::Ok,
QWidget* parent = nullptr,
Qt::WindowFlags flags = 0);
void showEvent(QShowEvent* event) override;
private slots:
void tick();
private:
int m_timeout;
QString m_text;
QTimer m_timer;
};
#endif // SELFDESTRUCTMESSAGEBOX_H
+48 -152
View File
@@ -28,10 +28,8 @@ QDebug operator << (QDebug debug, StationList::Station const& station)
QDebugStateSaver saver {debug};
debug.nospace () << "Station("
<< station.band_name_ << ", "
<< station.frequency_ << ", "
<< station.switch_at_ << ", "
<< station.switch_until_ << ", "
<< station.description_ << ')';
<< station.offset_ << ", "
<< station.antenna_description_ << ')';
return debug;
}
#endif
@@ -39,19 +37,15 @@ QDebug operator << (QDebug debug, StationList::Station const& station)
QDataStream& operator << (QDataStream& os, StationList::Station const& station)
{
return os << station.band_name_
<< station.frequency_
<< station.switch_at_
<< station.switch_until_
<< station.description_;
<< station.offset_
<< station.antenna_description_;
}
QDataStream& operator >> (QDataStream& is, StationList::Station& station)
{
return is >> station.band_name_
>> station.frequency_
>> station.switch_at_
>> station.switch_until_
>> station.description_;
>> station.offset_
>> station.antenna_description_;
}
@@ -96,7 +90,7 @@ public:
return matches.isEmpty () ? QModelIndex {} : matches.first ();
}
static int constexpr num_columns {5};
static int constexpr num_columns {3};
static auto constexpr mime_type = "application/wsjt.antenna-descriptions";
Bands const * bands_;
@@ -178,6 +172,12 @@ bool StationList::removeDisjointRows (QModelIndexList rows)
return result;
}
auto StationList::offset (Frequency f) const -> FrequencyDelta
{
return m_->offset (f);
}
auto StationList::impl::station_list (Stations stations) -> Stations
{
beginResetModel ();
@@ -203,7 +203,6 @@ QModelIndex StationList::impl::add (Station s)
return QModelIndex {};
}
#if 0
auto StationList::impl::offset (Frequency f) const -> FrequencyDelta
{
// Lookup band for frequency
@@ -215,13 +214,12 @@ auto StationList::impl::offset (Frequency f) const -> FrequencyDelta
{
if (stations_[i].band_name_ == band)
{
return stations_[i].frequency_;
return stations_[i].offset_;
}
}
}
return 0; // no offset
}
#endif
int StationList::impl::rowCount (QModelIndex const& parent) const
{
@@ -244,10 +242,7 @@ Qt::ItemFlags StationList::impl::flags (QModelIndex const& index) const
&& row < stations_.size ()
&& column < num_columns)
{
if (band_column == column){
result |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
} else if (description_column == column)
if (description_column == column)
{
result |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
@@ -300,14 +295,14 @@ QVariant StationList::impl::data (QModelIndex const& index, int role) const
break;
case Qt::TextAlignmentRole:
item = (int)Qt::AlignHCenter | Qt::AlignVCenter;
item = Qt::AlignHCenter + Qt::AlignVCenter;
break;
}
break;
case frequency_column:
case offset_column:
{
auto frequency_offset = stations_.at (row).frequency_;
auto frequency_offset = stations_.at (row).offset_;
switch (role)
{
case SortRole:
@@ -322,79 +317,37 @@ QVariant StationList::impl::data (QModelIndex const& index, int role) const
case Qt::ToolTipRole:
case Qt::AccessibleDescriptionRole:
item = tr ("Frequency");
item = tr ("Frequency offset");
break;
case Qt::TextAlignmentRole:
item = (int)Qt::AlignRight | Qt::AlignVCenter;
item = Qt::AlignRight + Qt::AlignVCenter;
break;
}
}
break;
case switch_at_column:
switch (role)
{
case SortRole:
case Qt::EditRole:
case Qt::DisplayRole:
case Qt::AccessibleTextRole:
item = stations_.at (row).switch_at_.time().toString("hh:mm");
break;
case description_column:
switch (role)
{
case SortRole:
case Qt::EditRole:
case Qt::DisplayRole:
case Qt::AccessibleTextRole:
item = stations_.at (row).antenna_description_;
break;
case Qt::ToolTipRole:
case Qt::AccessibleDescriptionRole:
item = tr ("Switch at this time");
break;
case Qt::ToolTipRole:
case Qt::AccessibleDescriptionRole:
item = tr ("Antenna description");
break;
case Qt::TextAlignmentRole:
item = (int)Qt::AlignHCenter | Qt::AlignVCenter;
break;
}
break;
case switch_until_column:
switch (role)
{
case SortRole:
case Qt::EditRole:
case Qt::DisplayRole:
case Qt::AccessibleTextRole:
item = stations_.at (row).switch_until_.time().toString("hh:mm");
break;
case Qt::ToolTipRole:
case Qt::AccessibleDescriptionRole:
item = tr ("Switch until this time");
break;
case Qt::TextAlignmentRole:
item = (int)Qt::AlignHCenter | Qt::AlignVCenter;
break;
}
break;
case description_column:
switch (role)
{
case SortRole:
case Qt::EditRole:
case Qt::DisplayRole:
case Qt::AccessibleTextRole:
item = stations_.at (row).description_;
break;
case Qt::ToolTipRole:
case Qt::AccessibleDescriptionRole:
item = tr ("Antenna description");
break;
case Qt::TextAlignmentRole:
item = (int)Qt::AlignLeft | Qt::AlignVCenter;
break;
}
break;
}
case Qt::TextAlignmentRole:
item = Qt::AlignLeft + Qt::AlignVCenter;
break;
}
break;
}
}
return item;
@@ -409,10 +362,8 @@ QVariant StationList::impl::headerData (int section, Qt::Orientation orientation
switch (section)
{
case band_column: header = tr ("Band"); break;
case frequency_column: header = tr ("Freq. (MHz)"); break;
case switch_at_column: header = tr ("Switch at (UTC)"); break;
case switch_until_column: header = tr ("Until (UTC)"); break;
case description_column: header = tr ("Description"); break;
case offset_column: header = tr ("Offset"); break;
case description_column: header = tr ("Antenna Description"); break;
}
}
else
@@ -451,78 +402,23 @@ bool StationList::impl::setData (QModelIndex const& model_index, QVariant const&
}
break;
case frequency_column:
case offset_column:
{
if (value.canConvert<Frequency> ())
if (value.canConvert<FrequencyDelta> ())
{
Frequency offset {qvariant_cast<Radio::Frequency> (value)};
if(offset == 0){
Frequency l;
Frequency h;
if(bands_->findFreq(stations_[row].band_name_, &l, &h)){
offset = l;
}
}
if (offset != stations_[row].frequency_)
FrequencyDelta offset {qvariant_cast<Radio::FrequencyDelta> (value)};
if (offset != stations_[row].offset_)
{
stations_[row].frequency_ = offset;
stations_[row].offset_ = offset;
Q_EMIT dataChanged (model_index, model_index, roles);
auto band = bands_->find(offset);
if(band != stations_[row].band_name_){
stations_[row].band_name_ = band;
auto band_index = model_index.model()->index(row, band_column, model_index);
Q_EMIT dataChanged (band_index, band_index, roles);
}
changed = true;
}
}
}
break;
case switch_at_column:
{
QString s = value.toString();
if(s.length() < 5){
s = QString("0").repeated(5-s.length()) + s;
}
auto t = QTime::fromString(s);
auto at = QDateTime(QDate(2000,1,1), t, Qt::UTC);
auto until = stations_[row].switch_until_;
stations_[row].switch_at_ = at;
stations_[row].switch_until_ = until;
Q_EMIT dataChanged (model_index, model_index, roles);
auto switch_until_index = model_index.model()->index(row, switch_until_column, model_index);
Q_EMIT dataChanged (switch_until_index, switch_until_index, roles);
changed = true;
break;
}
case switch_until_column:
{
QString s = value.toString();
if(s.length() < 5){
s = QString("0").repeated(5-s.length()) + s;
}
auto t = QTime::fromString(s);
auto until = QDateTime(QDate(2000,1,1), t, Qt::UTC);
auto at = stations_[row].switch_at_;
stations_[row].switch_at_ = at;
stations_[row].switch_until_ = until;
Q_EMIT dataChanged (model_index, model_index, roles);
auto switch_at_index = model_index.model()->index(row, switch_at_column, model_index);
Q_EMIT dataChanged (switch_at_index, switch_at_index, roles);
changed = true;
break;
}
case description_column:
stations_[row].description_ = value.toString ();
stations_[row].antenna_description_ = value.toString ();
Q_EMIT dataChanged (model_index, model_index, roles);
changed = true;
break;
@@ -631,7 +527,7 @@ bool StationList::impl::dropMimeData (QMimeData const * data, Qt::DropAction act
, [&band] (Station const& s) {return s.band_name_ == band;}))
{
// not found so add it
add (Station {band, 0, QDateTime::currentDateTimeUtc(), QDateTime::currentDateTimeUtc(), QString {}});
add (Station {band, 0, QString {}});
}
}
return true;
+7 -11
View File
@@ -2,7 +2,6 @@
#define STATION_LIST_HPP__
#include <QSortFilterProxyModel>
#include <QDateTime>
#include <QString>
#include <QList>
@@ -53,15 +52,13 @@ public:
struct Station
{
QString band_name_;
Frequency frequency_;
QDateTime switch_at_;
QDateTime switch_until_;
QString description_;
FrequencyDelta offset_;
QString antenna_description_;
};
using Stations = QList<Station>;
enum Column {band_column, frequency_column, switch_at_column, switch_until_column, description_column};
enum Column {band_column, offset_column, description_column};
explicit StationList (Bands const * bands, QObject * parent = nullptr);
explicit StationList (Bands const * bands, Stations, QObject * parent = nullptr);
@@ -77,6 +74,7 @@ public:
QModelIndex add (Station); // Add a new Station
bool remove (Station); // Remove a Station
bool removeDisjointRows (QModelIndexList); // Remove one or more stations
FrequencyDelta offset (Frequency) const; // Return the offset to be used for a Frequency
// Custom sort role.
static int constexpr SortRole = Qt::UserRole;
@@ -90,11 +88,9 @@ private:
inline
bool operator == (StationList::Station const& lhs, StationList::Station const& rhs)
{
return lhs.band_name_ == rhs.band_name_ &&
lhs.description_ == rhs.description_ &&
lhs.frequency_ == rhs.frequency_ &&
lhs.switch_at_ == rhs.switch_at_ &&
lhs.switch_until_ == rhs.switch_until_;
return lhs.band_name_ == rhs.band_name_
&& lhs.offset_ == rhs.offset_
&& lhs.antenna_description_ == rhs.antenna_description_;
}
QDataStream& operator << (QDataStream&, StationList::Station const&);
+3 -3
View File
@@ -1,6 +1,6 @@
# Version number components
set (WSJTX_VERSION_MAJOR 0)
set (WSJTX_VERSION_MINOR 5)
set (WSJTX_VERSION_PATCH 1)
set (WSJTX_VERSION_MAJOR 1)
set (WSJTX_VERSION_MINOR 10)
set (WSJTX_VERSION_PATCH 0)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
-2
View File
@@ -269,14 +269,12 @@ bool WSPRBandHopping::impl::simple_scheduler ()
WSPRBandHopping::WSPRBandHopping (QSettings * settings, Configuration const * configuration, QWidget * parent_widget)
: m_ {settings, configuration, parent_widget}
{
#if INCLUDE_ALL_MODES
// detect changes to the working frequencies model
m_->WSPR_bands_ = m_->configuration_->frequencies ()->all_bands (m_->configuration_->region (), Modes::WSPR).toList ();
connect (m_->configuration_->frequencies (), &QAbstractItemModel::layoutChanged
, [this] () {
m_->WSPR_bands_ = m_->configuration_->frequencies ()->all_bands (m_->configuration_->region (), Modes::WSPR).toList ();
});
#endif
// load settings
SettingsGroup g {m_->settings_, title};
-69
View File
@@ -1,69 +0,0 @@
import socket
KKEY = 0x73e2
def do_hash(callsign):
rootCall = callsign.split("-")[0].upper() + '\0'
hash = KKEY
i = 0
length = len(rootCall)
while (i+1 < length):
hash ^= ord(rootCall[i])<<8
hash ^= ord(rootCall[i+1])
i += 2
return int(hash & 0x7fff)
HOST = 'rotate.aprs2.net'
PORT = 14580
print "Connecting..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print "Connected..."
data = s.recv(1024)
print data
call = 'KN4CRD'
pw = do_hash(call)
ver = "FT8Call"
login = "user {} pass {} ver {}\n".format(call, pw, ver)
s.send(login)
print "Login sent...", login
data = s.recv(1024)
print data
if 0:
message = "KN4CRD>OH8STN,APRS,TCPIP*::EMAIL-2 :KN4CRD@GMAIL.COM TESTING!{04}\n"
s.send(message)
if 0:
message = "{}>APRS,TCPIP*::EMAIL-2 :kn4crd@gmail.com testing456{{01}}\n".format(call)
message = "KN4CRD>APRS,TCPIP*::EMAIL-2 :KN4CRD@GMAIL.COM TESTING!{02}\n"
s.send(message)
if 0:
payload = ":This is a test message"
message = "{}>APRS,TCPIP*::{} {}\n".format(call, call, payload)
s.send(message)
if 1:
position = "=3352.45N/08422.71Wn"
status = "FT8CALL VIA XX9XXX/XXXX 14.082500MHz -20dB"
payload = "".join((position, status))
message = "{}>OH8STN,APRS,TCPIP*:{}\n".format(call, payload)
s.send(message)
print "Spot sent...", message
data = s.recv(1024)
print data
s.close()
-1699
View File
File diff suppressed because it is too large Load Diff
+30 -197
View File
@@ -4,8 +4,6 @@
#include <QRegularExpression>
#include <QDebug>
#include <varicode.h>
extern "C" {
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, fortran_charlen_t, fortran_charlen_t);
}
@@ -17,208 +15,43 @@ namespace
DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString const& my_grid)
: string_ {the_string.left (the_string.indexOf (QChar::Nbsp))} // discard appended info
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for seconds
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for
// seconds
, contest_mode_ {contest_mode}
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
, is_standard_ {false}
, frameType_(Varicode::FrameUnknown)
, isBeacon_(false)
, isAlt_(false)
{
if(message_.length() >= 1) {
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
int i1 = message_.indexOf ('\r');
if (i1 > 0) {
message_ = message_.left (i1 - 1);
if (message_.length() >= 1)
{
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
int i1 = message_.indexOf ('\r');
if (i1 > 0)
{
message_ = message_.left (i1 - 1);
}
if (message_.contains (QRegularExpression {"^(CQ|QRZ)\\s"})) {
// TODO this magic position 16 is guaranteed to be after the
// last space in a decoded CQ or QRZ message but before any
// appended DXCC entity name or worked before information
auto eom_pos = message_.indexOf (' ', 16);
// we always want at least the characters to position 16
if (eom_pos < 16) eom_pos = message_.size () - 1;
// remove DXCC entity and worked B4 status. TODO need a better way to do this
message_ = message_.left (eom_pos + 1);
}
// stdmsg is a fortran routine that packs the text, unpacks it
// and compares the result
auto message_c_string = message_.toLocal8Bit ();
message_c_string += QByteArray {22 - message_c_string.size (), ' '};
auto grid_c_string = my_grid.toLocal8Bit ();
grid_c_string += QByteArray {6 - grid_c_string.size (), ' '};
is_standard_ = stdmsg_ (message_c_string.constData (), contest_mode_, grid_c_string.constData (), 22, 6);
// We're only going to unpack standard messages for CQs && beacons...
// TODO: jsherer - this is a hack for now...
if(is_standard_){
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
if (message_.contains (QRegularExpression {"^(CQ|QRZ)\\s"}))
{
// TODO this magic position 16 is guaranteed to be after the
// last space in a decoded CQ or QRZ message but before any
// appended DXCC entity name or worked before information
auto eom_pos = message_.indexOf (' ', 16);
// we always want at least the characters to position 16
if (eom_pos < 16) eom_pos = message_.size () - 1;
// remove DXCC entity and worked B4 status. TODO need a better way to do this
message_ = message_.left (eom_pos + 1);
}
// stdmsg is a fortran routine that packs the text, unpacks it
// and compares the result
auto message_c_string = message_.toLocal8Bit ();
message_c_string += QByteArray {22 - message_c_string.size (), ' '};
auto grid_c_string = my_grid.toLocal8Bit ();
grid_c_string += QByteArray {6 - grid_c_string.size (), ' '};
is_standard_ = stdmsg_ (message_c_string.constData ()
, contest_mode_
, grid_c_string.constData ()
, 22, 6);
}
tryUnpack();
}
DecodedText::DecodedText (QString const& ft8callmessage):
frameType_(Varicode::FrameUnknown),
message_(ft8callmessage),
isBeacon_(false),
isAlt_(false)
{
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
tryUnpack();
}
bool DecodedText::tryUnpack(){
if(is_standard_){
message_ = message_.append(" ");
return false;
}
bool unpacked = false;
if(!unpacked){
unpacked = tryUnpackBeacon();
}
if(!unpacked){
unpacked = tryUnpackCompound();
}
if(!unpacked){
unpacked = tryUnpackDirected();
}
if(!unpacked){
unpacked = tryUnpackData();
}
return unpacked;
}
bool DecodedText::tryUnpackBeacon(){
QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
bool isAlt = false;
quint8 type = Varicode::FrameUnknown;
QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt);
if(parts.isEmpty() || parts.length() < 2){
return false;
}
// Beacon Alt Type
// ---------------
// 1 0 BCN
// 1 1 CQ
isBeacon_ = true;
isAlt_ = isAlt;
extra_ = parts.length() < 3 ? "" : parts.at(2);
QStringList cmp;
if(!parts.at(0).isEmpty()){
cmp.append(parts.at(0));
}
if(!parts.at(1).isEmpty()){
cmp.append(parts.at(1));
}
compound_ = cmp.join("/");
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? "CQCQCQ" : "BEACON").arg(extra_);
frameType_ = type;
return true;
}
bool DecodedText::tryUnpackCompound(){
auto m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
quint8 type = Varicode::FrameUnknown;
auto parts = Varicode::unpackCompoundMessage(m, &type);
if(parts.isEmpty() || parts.length() < 2){
return false;
}
QStringList cmp;
if(!parts.at(0).isEmpty()){
cmp.append(parts.at(0));
}
if(!parts.at(1).isEmpty()){
cmp.append(parts.at(1));
}
compound_ = cmp.join("/");
extra_ = parts.length() < 3 ? "" : parts.mid(2).join(" ");
if(type == Varicode::FrameCompound){
message_ = QString("%1: ").arg(compound_);
} else if(type == Varicode::FrameCompoundDirected){
message_ = QString("%1%2 ").arg(compound_).arg(extra_);
directed_ = QStringList{ "<....>", compound_ } + parts.mid(2);
}
frameType_ = type;
return true;
}
bool DecodedText::tryUnpackDirected(){
QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
quint8 type = Varicode::FrameUnknown;
QStringList parts = Varicode::unpackDirectedMessage(m, &type);
if(parts.isEmpty()){
return false;
}
if(parts.length() == 3){
// replace it with the correct unpacked (directed)
message_ = QString("%1: %2%3 ").arg(parts.at(0), parts.at(1), parts.at(2));
} else if(parts.length() == 4){
// replace it with the correct unpacked (directed numeric)
message_ = QString("%1: %2%3 %4 ").arg(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
} else {
// replace it with the correct unpacked (freetext)
message_ = QString(parts.join(""));
}
directed_ = parts;
frameType_ = type;
return true;
}
bool DecodedText::tryUnpackData(){
QString m = message().trimmed();
// data frames calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
quint8 type = Varicode::FrameUnknown;
QString data = Varicode::unpackDataMessage(m, &type);
if(data.isEmpty()){
return false;
}
message_ = data;
frameType_ = type;
return true;
}
};
QStringList DecodedText::messageWords () const
{
+6 -35
View File
@@ -10,7 +10,6 @@
#define DECODEDTEXT_H
#include <QString>
#include <QStringList>
@@ -31,35 +30,15 @@ class DecodedText
{
public:
explicit DecodedText (QString const& message, bool, QString const& my_grid);
explicit DecodedText (QString const& ft8callmessage);
bool tryUnpack();
bool tryUnpackBeacon();
bool tryUnpackCompound();
bool tryUnpackDirected();
bool tryUnpackData();
quint8 frameType() const { return frameType_; }
QString extra() const { return extra_; }
QString compoundCall() const { return compound_; }
bool isCompound() const { return !compound_.isEmpty(); }
bool isBeacon() const { return isBeacon_; }
bool isAlt() const { return isAlt_; }
QStringList directedMessage() const { return directed_; }
bool isDirectedMessage() const { return !directed_.isEmpty() && directed_.length() > 2; }
QString string() const { return string_; }
QString message() const { return message_; }
QString string() const { return string_; };
QStringList messageWords () const;
int indexOf(QString s) const { return string_.indexOf(s); }
int indexOf(QString s, int i) const { return string_.indexOf(s,i); }
QString mid(int f, int t) const { return string_.mid(f,t); }
QString left(int i) const { return string_.left(i); }
int indexOf(QString s) const { return string_.indexOf(s); };
int indexOf(QString s, int i) const { return string_.indexOf(s,i); };
QString mid(int f, int t) const { return string_.mid(f,t); };
QString left(int i) const { return string_.left(i); };
void clear() { string_.clear(); }
void clear() { string_.clear(); };
QString CQersCall() const;
@@ -70,8 +49,6 @@ public:
bool isLowConfidence () const;
int frequencyOffset() const; // hertz offset from the tuned dial or rx frequency, aka audio frequency
int snr() const;
bool hasBits() const { return !string_.right(5).trimmed().isEmpty(); }
int bits() const { return string_.right(5).trimmed().toShort(); }
float dt() const;
// find and extract any report. Returns true if this is a standard message
@@ -98,12 +75,6 @@ private:
column_mode = 19,
column_qsoText = 22 };
quint8 frameType_;
bool isBeacon_;
bool isAlt_;
QString compound_;
QString extra_;
QStringList directed_;
QString string_;
int padding_;
bool contest_mode_;
+2 -2
View File
@@ -277,7 +277,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
QColor color_ReceivedMsg, bool bFastMode)
QColor color_TxMsg, bool bFastMode)
{
QString t1=" @ ";
if(modeTx=="FT8") t1=" ~ ";
@@ -297,7 +297,7 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
" Tx " + t2 + t1 + text;
}
appendText (t, color_ReceivedMsg);
appendText (t, color_TxMsg);
}
void DisplayText::displayQSY(QString text)
+1 -1
View File
@@ -26,7 +26,7 @@ public:
LogBook const& logBook, QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall, bool ppfx, bool bCQonly=false);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
QColor color_ReceivedMsg, bool bFastMode);
QColor color_TxMsg, bool bFastMode);
void displayQSY(QString text);
void displayFoxToBeCalled(QString t, QColor bg);
-11
View File
@@ -1,11 +0,0 @@
[Desktop Entry]
Version=1.0
Name=ft8call
Comment=Amateur Radio Weak Signal Operating
Exec=ft8call
Icon=wsjtx_icon
Terminal=false
X-MultipleArgs=false
Type=Application
Categories=AudioVideo;Audio;HamRadio;
StartupNotify=true
-1
View File
@@ -16,7 +16,6 @@ subroutine chkcrc12a(decoded,nbadcrc)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32)
i1Dec8BitBytes(11)=0
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
icrc12=xor(icrc12, 42)
nbadcrc=1
if(ncrc12.eq.icrc12) nbadcrc=0
+2 -13
View File
@@ -2,15 +2,13 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
use iso_c_binding, only: c_loc,c_size_t
use crc
use packjt
character*68 alphabet
character*22 msgreceived
character*87 cbits
integer*1 decoded(87)
integer*1, target:: i1Dec8BitBytes(11)
integer*4 i4Dec6BitWords(12)
alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+/?.'
! Write decoded bits into cbits: 75-bit message plus 12-bit CRC
write(cbits,1000) decoded
1000 format(87i1)
@@ -22,7 +20,6 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32)
i1Dec8BitBytes(11)=0
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
icrc12=xor(icrc12, 42)
if(ncrc12.eq.icrc12 .or. sum(decoded(57:87)).eq.0) then !### Kludge ###
! CRC12 checks out --- unpack 72-bit message
@@ -33,15 +30,7 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
enddo
i4Dec6BitWords(ibyte)=itmp
enddo
!call unpackmsg(i4Dec6BitWords,msgreceived,.false.,' ')
msgreceived=' '
do ibyte=1,12
itmp=i4Dec6BitWords(ibyte)
msgreceived(ibyte:ibyte) = alphabet(itmp+1:itmp+1)
enddo
call unpackmsg(i4Dec6BitWords,msgreceived,.false.,' ')
ncrcflag=1
else
msgreceived=' '
-1
View File
@@ -73,7 +73,6 @@ subroutine foxgen()
read(cb88,1003) i1Msg8BitBytes(1:11)
1003 format(11b8)
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
icrc12=xor(icrc12, 42)
write(cbits,1001) msgbits(1:56),icrc10,nrpt,i3b,icrc12
read(cbits,1002) msgbits
+13 -13
View File
@@ -10,19 +10,19 @@ subroutine ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
integer*1 msgbits(KK)
integer itone(KK)
! mycall=mycall12(1:6)
! hiscall=hiscall12(1:6)
! hisgrid=hisgrid6(1:4)
! if(len_trim(hiscall).eq.0) then
! iaptype=1
! hiscall="K9AN"
! else
! iaptype=2
! endif
! hisgrid=hisgrid6(1:4)
!! if(len_trim(hisgrid).eq.0) hisgrid="EN50"
! if(index(hisgrid," ").eq.0) hisgrid="EN50"
msg='tZQpZP-slh4+' ! HELLO WORLD
mycall=mycall12(1:6)
hiscall=hiscall12(1:6)
hisgrid=hisgrid6(1:4)
if(len_trim(hiscall).eq.0) then
iaptype=1
hiscall="K9AN"
else
iaptype=2
endif
hisgrid=hisgrid6(1:4)
! if(len_trim(hisgrid).eq.0) hisgrid="EN50"
if(index(hisgrid," ").eq.0) hisgrid="EN50"
msg=mycall//' '//hiscall//' '//hisgrid
i3bit=0 ! ### TEMPORARY ??? ###
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
apsym=2*msgbits-1
+39 -7
View File
@@ -7,7 +7,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
include 'ft8_params.f90'
parameter(NP2=2812)
character*37 msg37
character message*22,msgsent*22,origmsg*22
character message*22,msgsent*22
character*12 mycall12,hiscall12
character*6 mycall6,mygrid6,hiscall6,c1,c2
character*87 cbits
@@ -374,12 +374,13 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
cycle
endif
i3bit=4*decoded(73) + 2*decoded(74) + decoded(75)
iFreeText=decoded(57)
if(nbadcrc.eq.0) then
decoded0=decoded
call extractmessage174(decoded,origmsg,ncrcflag)
if(i3bit.eq.1) decoded(57:)=0
call extractmessage174(decoded,message,ncrcflag)
decoded=decoded0
message(1:12)=origmsg(1:12)
! This needs fixing for messages with i3bit=1:
call genft8(message,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
if(lsubtract) call subtractft8(dd0,itone,f1,xdt2)
xsig=0.0
@@ -395,10 +396,41 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
xsnr2=db(xsig/xbase - 1.0) - 32.0
if(.not.nagain) xsnr=xsnr2
if(xsnr .lt. -24.0) xsnr=-24.0
if(i3bit.eq.1) then
do i=1,12
i1hiscall(i)=ichar(hiscall12(i:i))
enddo
icrc10=crc10(c_loc(i1hiscall),12)
write(cbits,1001) decoded
1001 format(87i1)
read(cbits,1002) ncrc10,nrpt
1002 format(56x,b10,b6)
irpt=nrpt-30
i1=index(message,' ')
i2=index(message(i1+1:),' ') + i1
c1=message(1:i1)//' '
c2=message(i1+1:i2)//' '
msg37=origmsg//' '
msg37(22:22) = char(48 + i3bit)
if(ncrc10.eq.icrc10) msg37=c1//' RR73; '//c2//' <'// &
trim(hiscall12)//'> '
if(ncrc10.ne.icrc10) msg37=c1//' RR73; '//c2//' <...> '
! msg37=c1//' RR73; '//c2//' <...> '
write(msg37(35:37),1010) irpt
1010 format(i3.2)
if(msg37(35:35).ne.'-') msg37(35:35)='+'
iz=len(trim(msg37))
do iter=1,10 !Collapse multiple blanks
ib2=index(msg37(1:iz),' ')
if(ib2.lt.1) exit
msg37=msg37(1:ib2)//msg37(ib2+2:)
iz=iz-1
enddo
else
msg37=message//' '
endif
return
endif
+48 -18
View File
@@ -62,17 +62,21 @@ program ft8code
msgchk=msg
! Generate msgsent, msgbits, and itone
call packmsg(msg(1:22),dgen,itype,bcontest)
msgtype=""
if(itype.eq.1) msgtype="Std Msg"
if(itype.eq.2) msgtype="Type 1 pfx"
if(itype.eq.3) msgtype="Type 1 sfx"
if(itype.eq.4) msgtype="Type 2 pfx"
if(itype.eq.5) msgtype="Type 2 sfx"
if(itype.eq.6) msgtype="Free text"
i3bit=0
call genft8(msg(1:22),mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
if(index(msg,';').le.0) then
call packmsg(msg(1:22),dgen,itype,bcontest)
msgtype=""
if(itype.eq.1) msgtype="Std Msg"
if(itype.eq.2) msgtype="Type 1 pfx"
if(itype.eq.3) msgtype="Type 1 sfx"
if(itype.eq.4) msgtype="Type 2 pfx"
if(itype.eq.5) msgtype="Type 2 sfx"
if(itype.eq.6) msgtype="Free text"
i3bit=0
call genft8(msg(1:22),mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
else
call foxgen_wrap(msg,msgbits,itone)
i3bit=1
endif
decoded=msgbits
i3bit=4*decoded(73) + 2*decoded(74) + decoded(75)
iFreeText=decoded(57)
@@ -81,14 +85,40 @@ program ft8code
call extractmessage174(decoded,message,ncrcflag)
decoded=decoded0
if(bcontest) call fix_contest_msg(mygrid6,message)
bad=" "
comment=' '
if(itype.ne.6 .and. message.ne.msgchk) bad="*"
if(itype.eq.6 .and. message(1:13).ne.msgchk(1:13)) bad="*"
if(itype.eq.6 .and. len(trim(msgchk)).gt.13) comment='truncated'
write(*,1020) imsg,msgchk,message,bad,i3bit,itype,msgtype,comment
if(i3bit.eq.0) then
if(bcontest) call fix_contest_msg(mygrid6,message)
bad=" "
comment=' '
if(itype.ne.6 .and. message.ne.msgchk) bad="*"
if(itype.eq.6 .and. message(1:13).ne.msgchk(1:13)) bad="*"
if(itype.eq.6 .and. len(trim(msgchk)).gt.13) comment='truncated'
write(*,1020) imsg,msgchk,message,bad,i3bit,itype,msgtype,comment
1020 format(i2,'.',1x,a22,1x,a22,1x,a1,2i2,1x,a10,1x,a9)
else
write(cbits,1001) decoded
1001 format(87i1)
read(cbits,1002) nrpt
1002 format(66x,b6)
irpt=nrpt-30
i1=index(message,' ')
i2=index(message(i1+1:),' ') + i1
c1=message(1:i1)//' '
c2=message(i1+1:i2)//' '
msg37=c1//' RR73; '//c2//' <...> '
write(msg37(35:37),1003) irpt
1003 format(i3.2)
if(msg37(35:35).ne.'-') msg37(35:35)='+'
iz=len(trim(msg37))
do iter=1,10 !Collapse multiple blanks into one
ib2=index(msg37(1:iz),' ')
if(ib2.lt.1) exit
msg37=msg37(1:ib2)//msg37(ib2+2:)
iz=iz-1
enddo
write(*,1021) imsg,msgchk,msg37
1021 format(i2,'.',1x,a40,1x,a37)
endif
enddo
+2 -15
View File
@@ -5,7 +5,6 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
use crc
use packjt
include 'ft8_params.f90'
character*68 alphabet
character*22 msg,msgsent
character*6 mygrid
character*87 cbits
@@ -17,19 +16,8 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
integer icos7(0:6)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+/?.'
itype=6
do i=1,12
v=index(alphabet, msg(i:i))
if(v.eq.0) exit
i4Msg6BitWords(i)=v - 1
enddo
msgsent=' '
msgsent(1:12)=msg(1:12)
! call packmsg(msg,i4Msg6BitWords,itype,bcontest) !Pack into 12 6-bit bytes
! call unpackmsg(i4Msg6BitWords,msgsent,bcontest,mygrid) !Unpack to get msgsent
call packmsg(msg,i4Msg6BitWords,itype,bcontest) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent,bcontest,mygrid) !Unpack to get msgsent
write(cbits,1000) i4Msg6BitWords,32*i3bit
1000 format(12b6.6,b8.8)
@@ -38,7 +26,6 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
i1Msg8BitBytes(10)=iand(i1Msg8BitBytes(10),128+64+32)
i1Msg8BitBytes(11)=0
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
icrc12=xor(icrc12, 42)
! For reference, here's how to check the CRC
! i1Msg8BitBytes(10)=icrc12/256
-1
View File
@@ -91,7 +91,6 @@ allocate ( rxdata(N), llr(N) )
i1Msg8BitBytes(10:11)=0
checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
checksum = xor(checksum, 42)
! For reference, the next 3 lines show how to check the CRC
i1Msg8BitBytes(10)=checksum/256
i1Msg8BitBytes(11)=iand (checksum,255)
-1
View File
@@ -63,7 +63,6 @@ contains
1001 format("000000_",i6.6)
call ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
dd=iwave
ndecodes=0
allmessages=' '
+1 -3
View File
@@ -423,9 +423,7 @@ subroutine packbits(dbits,nsymd,m0,sym)
itype=1
if(bcontest) then
!call to_contest_msg(msg0,msg)
! this causes problems with freetext ala, KN4CRD DE KN4CRD -13 R
msg=msg0
call to_contest_msg(msg0,msg)
else
msg=msg0
end if
+1 -1
View File
@@ -6,7 +6,7 @@
namespace
{
auto logFileName = "ft8call_log.adi";
auto logFileName = "wsjtx_log.adi";
auto countryFileName = "cty.dat";
}
+8 -7
View File
@@ -59,7 +59,7 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
QString const& rptSent, QString const& rptRcvd,
QDateTime const& dateTimeOn, QDateTime const& dateTimeOff,
Radio::Frequency dialFreq, QString const& myCall, QString const& myGrid,
bool toRTTY, bool dBtoComments, bool bFox, QString const& opCall)
bool noSuffix, bool toRTTY, bool dBtoComments, bool bFox, QString const& opCall)
{
if(!isHidden()) return;
ui->call->setText(hisCall);
@@ -75,7 +75,8 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
if(rptRcvd!="") t+=" Rcvd: " + rptRcvd;
ui->comments->setText(t);
}
if(toRTTY) mode="DATA";
if(noSuffix and mode.mid(0,3)=="JT9") mode="JT9";
if(toRTTY and mode.mid(0,3)=="JT9") mode="RTTY";
ui->mode->setText(mode);
ui->sent->setText(rptSent);
ui->rcvd->setText(rptRcvd);
@@ -112,10 +113,10 @@ void LogQSO::accept()
m_comments=comments;
QString strDialFreq(QString::number(m_dialFreq / 1.e6,'f',6));
operator_call = ui->loggedOperator->text();
//Log this QSO to ADIF file "ft8call_log.adi"
QString filename = "ft8call_log.adi"; // TODO allow user to set
//Log this QSO to ADIF file "wsjtx_log.adi"
QString filename = "wsjtx_log.adi"; // TODO allow user to set
ADIF adifile;
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("ft8call_log.adi");
auto adifilePath = QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx_log.adi");
adifile.init(adifilePath);
QByteArray ADIF {adifile.QSOToADIF (hisCall, hisGrid, mode, rptSent, rptRcvd, m_dateTimeOn, m_dateTimeOff, band
@@ -137,8 +138,8 @@ void LogQSO::accept()
}
}
//Log this QSO to file "ft8call.log"
static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("ft8call.log")};
//Log this QSO to file "wsjtx.log"
static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx.log")};
if(!f.open(QIODevice::Text | QIODevice::Append)) {
MessageBox::warning_message (this, tr ("Log file error"),
tr ("Cannot open \"%1\" for append").arg (f.fileName ()),
+1 -1
View File
@@ -33,7 +33,7 @@ public:
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
QDateTime const& dateTimeOff,
Radio::Frequency dialFreq, QString const& myCall, QString const& myGrid,
bool toRTTY, bool dBtoComments, bool bFox, QString const& opCall);
bool noSuffix, bool toRTTY, bool dBtoComments, bool bFox, QString const& opCall);
public slots:
void accept();
+2 -8
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>285</height>
<width>377</width>
<height>257</height>
</rect>
</property>
<property name="sizePolicy">
@@ -16,12 +16,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>600</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QLabel" name="label">
+3 -8
View File
@@ -105,8 +105,7 @@ int main(int argc, char *argv[])
// that GUI has correct l18n
// Override programs executable basename as application name.
//a.setApplicationName ("WSJT-X");
a.setApplicationName("FT8Call");
a.setApplicationName ("WSJT-X");
a.setApplicationVersion (version ());
#if QT_VERSION >= 0x050200
@@ -260,7 +259,7 @@ int main(int argc, char *argv[])
multi_settings.set_common_value (splash_flag_name, false);
splash.close ();
});
//splash.show ();
splash.show ();
a.processEvents ();
}
}
@@ -296,12 +295,8 @@ int main(int argc, char *argv[])
mem_jt9.setKey(a.applicationName ());
if(!mem_jt9.attach()) {
std::cerr << QString("memory attach error: %1").arg(mem_jt9.error()).toLocal8Bit ().data () << std::endl;
if (!mem_jt9.create(sizeof(struct dec_data))) {
splash.hide ();
std::cerr << QString("memory create error: %1").arg(mem_jt9.error()).toLocal8Bit ().data () << std::endl;
MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"),
a.translate ("main", "Unable to create shared memory segment"));
throw std::runtime_error {"Shared memory error"};
@@ -329,7 +324,7 @@ int main(int argc, char *argv[])
// run the application UI
MainWindow w(temp_dir, multiple, &multi_settings, &mem_jt9, downSampleFactor, &splash);
w.show();
//splash.raise ();
splash.raise ();
QObject::connect (&a, SIGNAL (lastWindowClosed()), &a, SLOT (quit()));
result = a.exec();
}
+725 -4016
View File
File diff suppressed because it is too large Load Diff
+13 -263
View File
@@ -16,15 +16,12 @@
#include <QProgressDialog>
#include <QAbstractSocket>
#include <QHostAddress>
#include <QPair>
#include <QPointer>
#include <QSet>
#include <QVector>
#include <QFuture>
#include <QFutureWatcher>
#include <functional>
#include "AudioDevice.hpp"
#include "commons.h"
#include "Radio.hpp"
@@ -40,11 +37,6 @@
#include "astro.h"
#include "MessageBox.hpp"
#include "NetworkAccessManager.hpp"
#include "qorderedmap.h"
#include "qpriorityqueue.h"
#include "varicode.h"
#include "MessageClient.hpp"
#include "APRSISClient.h"
#define NUM_JT4_SYMBOLS 206 //(72+31)*2, embedded sync
#define NUM_JT65_SYMBOLS 126 //63 data + 63 sync
@@ -91,14 +83,10 @@ class MultiSettings;
class EqualizationToolsDialog;
class DecodedText;
using namespace std;
typedef std::function<void()> Callback;
class MainWindow : public QMainWindow
{
Q_OBJECT;
struct CallDetail;
public:
using Frequency = Radio::Frequency;
using FrequencyDelta = Radio::FrequencyDelta;
@@ -125,31 +113,10 @@ public slots:
void readFromStdout();
void p1ReadFromStdout();
void setXIT(int n, Frequency base = 0u);
void setFreqOffsetForRestore(int freq, bool shouldRestore);
bool tryRestoreFreqOffset();
void setFreq4(int rxFreq, int txFreq);
void msgAvgDecode2();
void fastPick(int x0, int x1, int y);
void logCallActivity(CallDetail d, bool spot=true);
QString lookupCallInCompoundCache(QString const &call);
void cacheActivity(QString key);
void restoreActivity(QString key);
void clearActivity();
void displayTextForFreq(QString text, int freq, QDateTime date, bool isTx, bool isNewLine, bool isLast);
void writeNoticeTextToUI(QDateTime date, QString text);
int writeMessageTextToUI(QDateTime date, QString text, int freq, bool bold, int block=-1);
bool isMessageQueuedForTransmit();
void addMessageText(QString text, bool clear=false, bool selectFirstPlaceholder=false);
void enqueueMessage(int priority, QString message, int freq, Callback c);
void resetMessage();
void resetMessageUI();
void restoreMessage();
bool ensureCallsignSet(bool alert=true);
void createMessage(QString const& text);
void createMessageTransmitQueue(QString const& text);
void resetMessageTransmitQueue();
QString popMessageFrame();
protected:
void keyPressEvent (QKeyEvent *) override;
void closeEvent(QCloseEvent *) override;
@@ -164,19 +131,10 @@ private slots:
void on_tx4_editingFinished();
void on_tx5_currentTextChanged (QString const&);
void on_tx6_editingFinished();
void on_menuWindow_aboutToShow();
void on_actionShow_Band_Activity_triggered(bool checked);
void on_actionShow_Call_Activity_triggered(bool checked);
void on_actionShow_Waterfall_triggered(bool checked);
void on_actionReset_Window_Sizes_triggered();
void on_actionSettings_triggered();
void prepareSpotting();
void on_spotButton_clicked(bool checked);
void on_monitorButton_clicked (bool);
void on_actionAbout_triggered();
void on_autoButton_clicked (bool);
void on_labDialFreq_clicked();
void on_monitorTxButton_clicked();
void on_stopTxButton_clicked();
void on_stopButton_clicked();
void on_actionRelease_Notes_triggered ();
@@ -222,9 +180,6 @@ private slots:
void on_txb5_clicked();
void on_txb5_doubleClicked ();
void on_txb6_clicked();
void on_startTxButton_toggled(bool checked);
void toggleTx(bool start);
void on_rbNextFreeTextMsg_toggled (bool status);
void on_lookupButton_clicked();
void on_addButton_clicked();
void on_dxCallEntry_textChanged (QString const&);
@@ -232,6 +187,10 @@ private slots:
void on_dxCallEntry_returnPressed ();
void on_genStdMsgsPushButton_clicked();
void on_logQSOButton_clicked();
void on_actionJT9_triggered();
void on_actionJT65_triggered();
void on_actionJT9_JT65_triggered();
void on_actionJT4_triggered();
void on_actionFT8_triggered();
void on_TxFreqSpinBox_valueChanged(int arg1);
void on_actionSave_decoded_triggered();
@@ -241,11 +200,9 @@ private slots:
void bumpFqso(int n);
void on_actionErase_ALL_TXT_triggered();
void on_actionErase_FoxQSO_txt_triggered();
void on_actionErase_ft8call_log_adi_triggered();
void startTx();
void on_actionErase_wsjtx_log_adi_triggered();
void startTx2();
void startP1();
void continueTx();
void stopTx();
void stopTx2();
void on_pbCallCQ_clicked();
@@ -256,45 +213,12 @@ private slots:
void on_pbSend73_clicked();
void on_rbGenMsg_clicked(bool checked);
void on_rbFreeText_clicked(bool checked);
void on_clearAction_triggered(QObject * sender);
void on_cqMacroButton_clicked();
void on_replyMacroButton_clicked();
void on_qthMacroButton_clicked();
void setSortBy(QString key, QString value);
QString getSortBy(QString key, QString defaultValue);
void buildSortByMenu(QMenu * menu, QString key, QString defaultValue, QList<QPair<QString, QString> > values);
void buildBandActivitySortByMenu(QMenu * menu);
void buildCallActivitySortByMenu(QMenu * menu);
void buildQueryMenu(QMenu *, QString callsign);
void on_queryButton_pressed();
void on_macrosMacroButton_pressed();
void on_tableWidgetRXAll_cellClicked(int row, int col);
void on_tableWidgetRXAll_cellDoubleClicked(int row, int col);
void on_tableWidgetRXAll_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void on_tableWidgetCalls_cellClicked(int row, int col);
void on_tableWidgetCalls_cellDoubleClicked(int row, int col);
void on_tableWidgetCalls_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void on_freeTextMsg_currentTextChanged (QString const&);
void on_nextFreeTextMsg_currentTextChanged (QString const&);
void on_extFreeTextMsgEdit_currentTextChanged (QString const&);
int currentFreqOffset();
int countFT8MessageFrames(QString const& text);
QStringList buildFT8MessageFrames(QString const& text);
QString parseFT8Message(QString input, bool *isFree);
bool prepareNextMessageFrame();
bool isFreqOffsetFree(int f, int bw);
int findFreeFreqOffset(int fmin, int fmax, int bw);
void scheduleBacon(bool first=false);
void pauseBacon();
void checkBacon();
void prepareBacon();
QString calculateDistance(QString const& grid, int *pDistance=nullptr);
void on_rptSpinBox_valueChanged(int n);
void killFile();
void on_tuneButton_clicked (bool);
void on_pbR2T_clicked();
void on_pbT2R_clicked();
void on_beaconButton_clicked();
void acceptQSO (QDateTime const&, QString const& call, QString const& grid
, Frequency dial_freq, QString const& mode
, QString const& rpt_sent, QString const& rpt_received
@@ -331,11 +255,10 @@ private slots:
void on_cbCQonly_toggled(bool b);
void on_cbFirst_toggled(bool b);
void on_cbAutoSeq_toggled(bool b);
void networkMessage(Message const &message);
void sendNetworkMessage(QString const &type, QString const &message);
void sendNetworkMessage(QString const &type, QString const &message, const QMap<QString, QVariant> &params);
void networkError (QString const&);
void on_ClrAvgButton_clicked();
void on_actionWSPR_triggered();
void on_actionWSPR_LF_triggered();
void on_syncSpinBox_valueChanged(int n);
void on_TxPowerComboBox_currentIndexChanged(const QString &arg1);
void on_sbTxPercent_valueChanged(int n);
@@ -347,6 +270,8 @@ private slots:
void on_WSPRfreqSpinBox_valueChanged(int n);
void on_pbTxNext_clicked(bool b);
void on_actionEcho_Graph_triggered();
void on_actionEcho_triggered();
void on_actionISCAT_triggered();
void on_actionFast_Graph_triggered();
void fast_decode_done();
void on_actionMeasure_reference_spectrum_triggered();
@@ -357,14 +282,16 @@ private slots:
void on_cbFast9_clicked(bool b);
void on_sbCQTxFreq_valueChanged(int n);
void on_cbCQTx_toggled(bool b);
void splash_done ();
void on_actionMSK144_triggered();
void on_actionQRA64_triggered();
void on_actionFreqCal_triggered();
void splash_done ();
void on_measure_check_box_stateChanged (int);
void on_sbNlist_valueChanged(int n);
void on_sbNslots_valueChanged(int n);
void on_sbMax_dB_valueChanged(int n);
void on_pbFoxReset_clicked();
void on_comboBoxHoundSort_activated (int index);
void expiry_warning_message ();
void not_GA_warning_message ();
private:
@@ -580,7 +507,6 @@ private:
}
m_QSOProgress;
int m_extFreeTxtPos;
int m_ihsym;
int m_nzap;
int m_npts8;
@@ -628,7 +554,6 @@ private:
QTimer minuteTimer;
QTimer splashTimer;
QTimer p1Timer;
QTimer beaconTimer;
QString m_path;
QString m_baseCall;
@@ -659,112 +584,6 @@ private:
QSet<QString> m_pfx;
QSet<QString> m_sfx;
struct CallDetail
{
QString call;
QString through;
QString grid;
int freq;
QDateTime utcTimestamp;
int snr;
int bits;
};
struct CommandDetail
{
bool isCompound;
bool isBuffered;
QString from;
QString to;
QString cmd;
int freq;
QDateTime utcTimestamp;
int snr;
int bits;
QString grid;
QString text;
QString extra;
};
struct ActivityDetail
{
bool isFree;
bool isLowConfidence;
bool isCompound;
bool isDirected;
bool isBuffered;
int bits;
int freq;
QString text;
QDateTime utcTimestamp;
int snr;
};
struct MessageBuffer {
QQueue<CallDetail> compound;
CommandDetail cmd;
QList<ActivityDetail> msgs;
};
bool m_rxDirty;
bool m_rxDisplayDirty;
int m_txFrameCount;
QString m_lastTxMessage;
QDateTime m_lastTxTime;
enum Priority {
PriorityLow = 10,
PriorityNormal = 100,
PriorityHigh = 1000
};
struct PrioritizedMessage {
QDateTime date;
int priority;
QString message;
int freq;
Callback callback;
friend bool operator <(PrioritizedMessage const &a, PrioritizedMessage const &b){
if(a.priority < b.priority){
return true;
}
return a.date < b.date;
}
};
struct CachedDirectedType {
bool isAllcall;
QDateTime date;
};
QMap<QString, QVariant> m_sortCache; // table key -> sort by
QPriorityQueue<PrioritizedMessage> m_txMessageQueue; // messages to be sent
QQueue<QString> m_txFrameQueue; // frames to be sent
QQueue<ActivityDetail> m_rxActivityQueue; // all rx activity queue
QQueue<CommandDetail> m_rxCommandQueue; // command queue for processing commands
QQueue<CallDetail> m_rxCallQueue; // call detail queue for spots to pskreporter
QMap<QString, QString> m_compoundCallCache; // base callsign -> compound callsign
QCache<QString, QDateTime> m_txAllcallCommandCache; // callsign -> last tx
QCache<int, QDateTime> m_rxRecentCache; // freq -> last rx
QCache<int, CachedDirectedType> m_rxDirectedCache; // freq -> last directed rx
QCache<QString, int> m_rxCallCache; // call -> last freq seen
QMap<int, int> m_rxFrameBlockNumbers; // freq -> block
QMap<int, QList<ActivityDetail>> m_bandActivity; // freq -> [(text, last timestamp), ...]
QMap<int, MessageBuffer> m_messageBuffer; // freq -> (cmd, [frames, ...])
QMap<QString, CallDetail> m_callActivity; // call -> (last freq, last timestamp)
QMap<QString, QMap<QString, CallDetail>> m_callActivityCache; // band -> call activity
QMap<QString, QMap<int, QList<ActivityDetail>>> m_bandActivityCache; // band -> band activity
QMap<QString, QString> m_rxTextCache; // band -> rx text
QSet<QString> m_callSeenBeacon; // call
int m_previousFreq;
bool m_shouldRestoreFreq;
bool m_bandHopped;
Frequency m_bandHoppedFreq;
struct FoxQSO //Everything we need to know about QSOs in progress (or recently logged).
{
QString grid; //Hound's declared locator
@@ -783,9 +602,6 @@ private:
QQueue<QString> m_foxQSOinProgress; //QSOs in progress: Fox has sent a report
QQueue<qint64> m_foxRateQueue;
bool m_nextBeaconQueued = false;
bool m_nextBeaconPaused = false;
QDateTime m_nextBeacon;
QDateTime m_dateTimeQSOOn;
QDateTime m_dateTimeLastTX;
@@ -814,7 +630,6 @@ private:
QTimer m_heartbeat;
MessageClient * m_messageClient;
PSK_Reporter *psk_Reporter;
APRSISClient * m_aprsClient;
DisplayManual m_manual;
QHash<QString, QVariant> m_pwrBandTxMemory; // Remembers power level by band
QHash<QString, QVariant> m_pwrBandTuneMemory; // Remembers power level by band for tuning
@@ -841,11 +656,7 @@ private:
void transmit (double snr = 99.);
void rigFailure (QString const& reason);
void pskSetLocal ();
void aprsSetLocal ();
void pskPost(DecodedText const& decodedtext);
void pskLogReport(QString mode, int offset, int snr, QString callsign, QString grid);
void aprsLogReport(int offset, int snr, QString callsign, QString grid);
Radio::Frequency dialFrequency();
void displayDialFrequency ();
void transmitDisplay (bool);
void processMessage(DecodedText const&, Qt::KeyboardModifiers = 0);
@@ -853,25 +664,6 @@ private:
void locationChange(QString const& location);
void replayDecodes ();
void postDecode (bool is_new, QString const& message);
void displayTransmit();
void updateButtonDisplay();
bool isMyCallIncluded(QString const &text);
bool isAllCallIncluded(QString const &text);
QString callsignSelected();
bool isRecentOffset(int offset);
void markOffsetRecent(int offset);
bool isDirectedOffset(int offset, bool *pIsAllCall);
void markOffsetDirected(int offset, bool isAllCall);
void processActivity(bool force=false);
void processRxActivity();
void processCompoundActivity();
void processBufferedActivity();
void processCommandActivity();
void processSpots();
void processTxQueue();
void displayActivity(bool force=false);
void displayBandActivity();
void displayCallActivity();
void postWSPRDecode (bool is_new, QStringList message_parts);
void enable_DXCC_entity (bool on);
void switch_mode (Mode);
@@ -902,7 +694,6 @@ private:
void statusUpdate () const;
void update_watchdog_label ();
void on_the_minute ();
void tryBandHop();
void add_child_to_event_filter (QObject *);
void remove_child_from_event_filter (QObject *);
void setup_status_bar (bool vhf);
@@ -921,47 +712,6 @@ private:
void writeFoxQSO(QString msg);
};
class EscapeKeyPressEater : public QObject
{
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event){
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_Escape){
return true;
}
}
// standard event processing
return QObject::eventFilter(obj, event);
}
};
class EnterKeyPressEater : public QObject
{
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event){
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return){
bool processed = false;
emit this->enterKeyPressed(obj, keyEvent, &processed);
if(processed){
return true;
}
}
}
// standard event processing
return QObject::eventFilter(obj, event);
}
public:
Q_SIGNAL void enterKeyPressed(QObject *obj, QKeyEvent *evt, bool *pProcessed);
};
extern int killbyname(const char* progName);
extern void getDev(int* numDevices,char hostAPI_DeviceName[][50],
int minChan[], int maxChan[],
+2222 -4038
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -1,3 +0,0 @@
echo make
echo cp wsjtx ft8call
echo linuxdeployqt ./ft8call -appimage -bundle-non-qt-libs -no-strip -no-translations
+4 -8
View File
@@ -57,14 +57,12 @@ void MeterWidget::paintEvent (QPaintEvent * event)
auto const& target = contentsRect ();
QRect r {QPoint {target.left (), static_cast<int> (target.top () + target.height () - m_signal / (double)MAXDB * target.height ())}
, QPoint {target.right (), target.bottom ()}};
//p.setBrush (QColor(85,170,85));
p.setBrush (Qt::green);
p.setBrush (QColor(85,170,85));
if (m_sigPeak > 85) {
p.setBrush(Qt::red);
}
else if (m_noisePeak < 15) {
//p.setBrush(QColor(232,81,0));
p.setBrush(Qt::yellow);
p.setBrush(QColor(232,81,0));
}
p.drawRect (r);
@@ -72,11 +70,9 @@ void MeterWidget::paintEvent (QPaintEvent * event)
{
// Draw peak hold indicator
auto peak = static_cast<int> (target.top () + target.height () - m_noisePeak / (double)MAXDB * target.height ());
//p.setBrush (Qt::black);
p.setBrush (Qt::white);
p.setBrush (Qt::black);
p.translate (target.left (), peak);
//p.drawPolygon (QPolygon {{{0, -4}, {0, 4}, {target.width (), 0}}});
p.drawPolygon (QPolygon { { {target.width (), -4}, {target.width (), 4}, {0, 0} } });
p.drawPolygon (QPolygon {{{0, -4}, {0, 4}, {target.width (), 0}}});
}
}
+6 -101
View File
@@ -36,12 +36,11 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
m_line {0},
m_fSample {12000},
m_nsps {6912},
m_Percent2DScreen {0}, //percent of screen used for 2D display
m_Percent2DScreen {30}, //percent of screen used for 2D display
m_Percent2DScreen0 {0},
m_rxFreq {1020},
m_txFreq {0},
m_startFreq {0},
m_lastMouseX {-1}
m_startFreq {0}
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setFocusPolicy(Qt::StrongFocus);
@@ -51,8 +50,6 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
setAttribute(Qt::WA_NoSystemBackground, true);
m_bReplot=false;
setMouseTracking(true);
// contextual pop up menu
setContextMenuPolicy (Qt::CustomContextMenu);
connect (this, &QWidget::customContextMenuRequested, [this] (QPoint const& pos) {
@@ -93,11 +90,6 @@ void CPlotter::resizeEvent(QResizeEvent* ) //resizeEvent()
if(m_h2<1) m_h2=1;
m_h1=m_h-m_h2;
// m_line=0;
m_DialOverlayPixmap = QPixmap(m_Size.width(), m_h);
m_DialOverlayPixmap.fill(Qt::transparent);
m_HoverOverlayPixmap = QPixmap(m_Size.width(), m_h);
m_HoverOverlayPixmap.fill(Qt::transparent);
m_2DPixmap = QPixmap(m_Size.width(), m_h2);
m_2DPixmap.fill(Qt::black);
m_WaterfallPixmap = QPixmap(m_Size.width(), m_h1);
@@ -120,14 +112,6 @@ void CPlotter::paintEvent(QPaintEvent *) // paint
painter.drawPixmap(0,0,m_ScalePixmap);
painter.drawPixmap(0,30,m_WaterfallPixmap);
painter.drawPixmap(0,m_h1,m_2DPixmap);
int x = XfromFreq(m_rxFreq);
painter.drawPixmap(x,0,m_DialOverlayPixmap);
if(m_lastMouseX >= 0 && m_lastMouseX != x){
painter.drawPixmap(m_lastMouseX, 0, m_HoverOverlayPixmap);
}
m_paintEventBusy=false;
}
@@ -339,7 +323,6 @@ void CPlotter::DrawOverlay() //DrawOverlay()
QPen penOrange(QColor(255,165,0),3);
QPen penGreen(Qt::green, 3); //Mark Tol range with green line
QPen penRed(Qt::red, 3); //Mark Tx freq with red
QPen penYellow(QColor(243, 156, 18), 3); //Mark band block freq with this pen
QPainter painter(&m_OverlayPixmap);
painter.initFrom(this);
QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient
@@ -407,7 +390,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
if(m_freqPerDiv==200) minor=4;
for( int i=1; i<minor*m_hdivs; i++) { //minor ticks
x = i*pixperdiv/minor;
painter0.drawLine(x,22,x,30);
painter0.drawLine(x,24,x,30);
}
//draw frequency values
@@ -495,7 +478,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
painter0.drawLine(x1,24,x1,30);
}
if(false && (m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode=="QRA64" or m_mode=="FT8")) {
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode=="QRA64" or m_mode=="FT8") {
if(m_mode=="QRA64" or (m_mode=="JT65" and m_bVHF)) {
painter0.setPen(penGreen);
@@ -528,8 +511,8 @@ void CPlotter::DrawOverlay() //DrawOverlay()
}
}
if(false && (m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or
m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8")) {
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or
m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8") {
painter0.setPen(penRed);
x1=XfromFreq(m_txFreq);
x2=XfromFreq(m_txFreq+bw);
@@ -567,44 +550,6 @@ void CPlotter::DrawOverlay() //DrawOverlay()
painter0.drawLine(x1,9,x2,9);
}
}
x1=XfromFreq(0);
x2=XfromFreq(500);
if(x1<=m_w and x2>0) {
painter0.setPen(penYellow); //Mark bottom of sub-band
painter0.drawLine(x1+1,26,x2-2,26);
painter0.drawLine(x1+1,28,x2-2,28);
}
if(m_mode=="FT8"){
int fwidth=XfromFreq(m_rxFreq+bw)-XfromFreq(m_rxFreq);
QPainter overPainter(&m_DialOverlayPixmap);
overPainter.initFrom(this);
overPainter.setCompositionMode(QPainter::CompositionMode_Source);
overPainter.fillRect(0, 0, m_Size.width(), m_h, Qt::transparent);
QPen thinRed(Qt::red, 1);
overPainter.setPen(thinRed);
overPainter.drawLine(0, 30, 0, m_h);
overPainter.drawLine(fwidth+1, 30, fwidth+1, m_h);
overPainter.setPen(penRed);
overPainter.drawLine(0, 26, fwidth, 26);
overPainter.drawLine(0, 28, fwidth, 28);
QPainter hoverPainter(&m_HoverOverlayPixmap);
hoverPainter.initFrom(this);
hoverPainter.setCompositionMode(QPainter::CompositionMode_Source);
hoverPainter.fillRect(0, 0, m_Size.width(), m_h, Qt::transparent);
hoverPainter.setPen(QPen(Qt::white));
hoverPainter.drawLine(0, 30, 0, m_h);
hoverPainter.drawLine(fwidth+1, 30, fwidth+1, m_h);
#if DRAW_FREQ_OVERLAY
int f = FreqfromX(m_lastMouseX);
hoverPainter.setFont(Font);
hoverPainter.drawText(fwidth + 5, m_h, QString("%1").arg(f));
#endif
}
}
void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
@@ -725,46 +670,6 @@ void CPlotter::setRxFreq (int x) //setRxFreq
int CPlotter::rxFreq() {return m_rxFreq;} //rxFreq
void CPlotter::leaveEvent(QEvent *event)
{
m_lastMouseX = -1;
}
void CPlotter::wheelEvent(QWheelEvent *event){
auto delta = event->angleDelta();
if(delta.isNull()){
event->ignore();
return;
}
int newFreq = rxFreq();
int dir = delta.y() > 0 ? 1 : -1;
bool ctrl = (event->modifiers() & Qt::ControlModifier);
if(ctrl){
newFreq += dir;
} else {
newFreq = newFreq/10*10 + dir*10;
}
emit setFreq1 (newFreq, newFreq);
}
void CPlotter::mouseMoveEvent (QMouseEvent * event)
{
int x = event->x();
if(x < 0) x = 0;
if(x>m_Size.width()) x = m_Size.width();
m_lastMouseX = x;
#if DRAW_FREQ_OVERLAY
DrawOverlay();
#endif
update();
event->ignore();
}
void CPlotter::mouseReleaseEvent (QMouseEvent * event)
{
if (Qt::LeftButton == event->button ()) {
-6
View File
@@ -95,9 +95,6 @@ protected:
//re-implemented widget event handlers
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent* event) override;
void leaveEvent(QEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void mouseMoveEvent(QMouseEvent * event) override;
void mouseReleaseEvent (QMouseEvent * event) override;
void mouseDoubleClickEvent (QMouseEvent * event) override;
@@ -131,8 +128,6 @@ private:
qint32 m_ia;
qint32 m_ib;
QPixmap m_DialOverlayPixmap;
QPixmap m_HoverOverlayPixmap;
QPixmap m_WaterfallPixmap;
QPixmap m_2DPixmap;
QPixmap m_ScalePixmap;
@@ -178,7 +173,6 @@ private:
qint32 m_startFreq;
qint32 m_tol;
qint32 m_j;
qint32 m_lastMouseX;
char m_sutc[6];
};
-611
View File
@@ -1,611 +0,0 @@
#ifndef ORDEREDMAP_H
#define ORDEREDMAP_H
#include <QtGlobal>
#include <QHash>
#include <QLinkedList>
#include <QList>
#include <QPair>
template <typename Key> inline bool oMHashEqualToKey(const Key &key1, const Key &key2)
{
// Key type must provide '==' operator
return key1 == key2;
}
template <typename Ptr> inline bool oMHashEqualToKey(Ptr *key1, Ptr *key2)
{
Q_ASSERT(sizeof(quintptr) == sizeof(Ptr *));
return quintptr(key1) == quintptr(key2);
}
template <typename Ptr> inline bool oMHashEqualToKey(const Ptr *key1, const Ptr *key2)
{
Q_ASSERT(sizeof(quintptr) == sizeof(const Ptr *));
return quintptr(key1) == quintptr(key2);
}
template <typename Key, typename Value>
class OrderedMap
{
class OMHash;
typedef typename QLinkedList<Key>::iterator QllIterator;
typedef typename QLinkedList<Key>::const_iterator QllConstIterator;
typedef QPair<Value, QllIterator> OMHashValue;
typedef typename OMHash::iterator OMHashIterator;
typedef typename OMHash::const_iterator OMHashConstIterator;
public:
class iterator;
class const_iterator;
typedef typename OrderedMap<Key, Value>::iterator Iterator;
typedef typename OrderedMap<Key, Value>::const_iterator ConstIterator;
explicit OrderedMap();
OrderedMap(const OrderedMap<Key, Value>& other);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
OrderedMap(OrderedMap<Key, Value>&& other);
#endif
void clear();
bool contains(const Key &key) const;
int count() const;
bool empty() const;
iterator insert(const Key &key, const Value &value);
bool isEmpty() const;
QList<Key> keys() const;
int remove(const Key &key);
int size() const;
Value take(const Key &key);
Value value(const Key &key) const;
Value value(const Key &key, const Value &defaultValue) const;
QList<Value> values() const;
OrderedMap<Key, Value> & operator=(const OrderedMap<Key, Value>& other);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
OrderedMap<Key, Value> & operator=(OrderedMap<Key, Value>&& other);
#endif
bool operator==(const OrderedMap<Key, Value> &other) const;
bool operator!=(const OrderedMap<Key, Value> &other) const;
Value& operator[](const Key &key);
const Value operator[](const Key &key) const;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
iterator erase(iterator pos);
iterator find(const Key& key);
const_iterator find(const Key& key) const;
class const_iterator;
class iterator
{
QllIterator qllIter;
OMHash *data;
friend class const_iterator;
friend class OrderedMap;
public:
iterator() : data(NULL) {}
iterator(const QllIterator &qllIter, OMHash *data) :
qllIter(qllIter), data(data) {}
const Key & key() const
{
return *qllIter;
}
Value & value() const
{
OMHashIterator hit = data->find(*qllIter);
OMHashValue &pair = hit.value();
return pair.first;
}
Value & operator*() const
{
return value();
}
iterator operator+(int i) const
{
QllIterator q = qllIter;
q += i;
return iterator(q, data);
}
iterator operator-(int i) const
{
return operator +(- i);
}
iterator& operator+=(int i)
{
qllIter += i;
return *this;
}
iterator& operator-=(int i)
{
qllIter -= i;
return *this;
}
iterator& operator++()
{
++qllIter;
return *this;
}
iterator operator++(int)
{
iterator it = *this;
qllIter++;
return it;
}
iterator operator--()
{
--qllIter;
return *this;
}
iterator operator--(int)
{
iterator it = *this;
qllIter--;
return it;
}
bool operator ==(const iterator &other) const
{
return (qllIter == other.qllIter);
}
bool operator !=(const iterator &other) const
{
return (qllIter != other.qllIter);
}
};
class const_iterator
{
QllConstIterator qllConstIter;
const OMHash *data;
public:
const_iterator() : data(NULL) {}
const_iterator(const iterator &i) :
qllConstIter(i.qllIter), data(i.data) {}
const_iterator(const QllConstIterator &qllConstIter, const OMHash* data) :
qllConstIter(qllConstIter), data(data) {}
const Key & key() const
{
return *qllConstIter;
}
const Value & value() const
{
OMHashConstIterator hit = data->find(*qllConstIter);
const OMHashValue &pair = hit.value();
return pair.first;
}
const Value & operator*() const
{
return value();
}
const_iterator operator+(int i) const
{
QllConstIterator q = qllConstIter;
q += i;
return const_iterator(q, data);
}
const_iterator operator-(int i) const
{
return operator +(- i);
}
const_iterator& operator+=(int i)
{
qllConstIter += i;
return *this;
}
const_iterator& operator-=(int i)
{
qllConstIter -= i;
return *this;
}
const_iterator& operator++()
{
++qllConstIter;
return *this;
}
const_iterator operator++(int)
{
const_iterator it = *this;
qllConstIter++;
return it;
}
const_iterator operator--()
{
--qllConstIter;
return *this;
}
const_iterator operator--(int)
{
const_iterator it = *this;
qllConstIter--;
return it;
}
bool operator ==(const const_iterator &other) const
{
return (qllConstIter == other.qllConstIter);
}
bool operator !=(const const_iterator &other) const
{
return (qllConstIter != other.qllConstIter);
}
};
private:
class OMHash : public QHash<Key, OMHashValue >
{
public:
bool operator == (const OMHash &other) const
{
if (size() != other.size()) {
return false;
}
if (QHash<Key, OMHashValue >::operator ==(other)) {
return true;
}
typename QHash<Key, OMHashValue >::const_iterator it1 = this->constBegin();
typename QHash<Key, OMHashValue >::const_iterator it2 = other.constBegin();
while(it1 != this->end()) {
OMHashValue v1 = it1.value();
OMHashValue v2 = it2.value();
if ((v1.first != v2.first) || !oMHashEqualToKey<Key>(it1.key(), it2.key())) {
return false;
}
++it1;
++it2;
}
return true;
}
};
private:
void copy(const OrderedMap<Key, Value> &other);
OMHash data;
QLinkedList<Key> insertOrder;
};
template <typename Key, typename Value>
OrderedMap<Key, Value>::OrderedMap() {}
template <typename Key, typename Value>
OrderedMap<Key, Value>::OrderedMap(const OrderedMap<Key, Value>& other)
{
copy(other);
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
template <typename Key, typename Value>
OrderedMap<Key, Value>::OrderedMap(OrderedMap<Key, Value>&& other)
{
data = std::move(other.data);
insertOrder = std::move(other.insertOrder);
}
#endif
template <typename Key, typename Value>
void OrderedMap<Key, Value>::clear()
{
data.clear();
insertOrder.clear();
}
template <typename Key, typename Value>
bool OrderedMap<Key, Value>::contains(const Key &key) const
{
return data.contains(key);
}
template <typename Key, typename Value>
int OrderedMap<Key, Value>::count() const
{
return data.count();
}
template <typename Key, typename Value>
bool OrderedMap<Key, Value>::empty() const
{
return data.empty();
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::iterator OrderedMap<Key, Value>::insert(const Key &key, const Value &value)
{
OMHashIterator it = data.find(key);
if (it == data.end()) {
// New key
QllIterator ioIter = insertOrder.insert(insertOrder.end(), key);
OMHashValue pair(value, ioIter);
data.insert(key, pair);
return iterator(ioIter, &data);
}
OMHashValue pair = it.value();
// remove old reference
insertOrder.erase(pair.second);
// Add new reference
QllIterator ioIter = insertOrder.insert(insertOrder.end(), key);
pair.first = value;
pair.second = ioIter;
return iterator(ioIter, &data);
}
template <typename Key, typename Value>
bool OrderedMap<Key, Value>::isEmpty() const
{
return data.isEmpty();
}
template<typename Key, typename Value>
QList<Key> OrderedMap<Key, Value>::keys() const
{
return QList<Key>::fromStdList(insertOrder.toStdList());
}
template<typename Key, typename Value>
int OrderedMap<Key, Value>::remove(const Key &key)
{
OMHashIterator it = data.find(key);
if (it == data.end()) {
return 0;
}
OMHashValue pair = it.value();
insertOrder.erase(pair.second);
data.erase(it);
return 1;
}
template<typename Key, typename Value>
int OrderedMap<Key, Value>::size() const
{
return data.size();
}
template<typename Key, typename Value>
void OrderedMap<Key, Value>::copy(const OrderedMap<Key, Value> &other)
{
/* Since I'm storing iterators of QLinkedList, I simply cannot make
* a trivial copy of the linked list. This is a limitation due to implicit
* sharing used in Qt containers, due to which iterator active on one
* QLL can change the data of another QLL even after creating a copy.
*
* Because of this, the old iterators have to be invalidated and new ones
* have to be generated.
*/
insertOrder.clear();
// Copy hash
data = other.data;
QllConstIterator cit = other.insertOrder.begin();
for (; cit != other.insertOrder.end(); ++cit) {
Key key = *cit;
QllIterator ioIter = insertOrder.insert(insertOrder.end(), key);
OMHashIterator it = data.find(key);
(*it).second = ioIter;
}
}
template<typename Key, typename Value>
Value OrderedMap<Key, Value>::take(const Key &key)
{
OMHashIterator it = data.find(key);
if (it == data.end()) {
return Value();
}
OMHashValue pair = it.value();
insertOrder.erase(pair.second);
data.erase(it);
return pair.first;
}
template <typename Key, typename Value>
Value OrderedMap<Key, Value>::value(const Key &key) const
{
return data.value(key).first;
}
template <typename Key, typename Value>
Value OrderedMap<Key, Value>::value(const Key &key, const Value &defaultValue) const
{
OMHashConstIterator it = data.constFind(key);
if (it == data.end()) {
return defaultValue;
}
OMHashValue pair = it.value();
return pair.first;
}
template <typename Key, typename Value>
QList<Value> OrderedMap<Key, Value>::values() const
{
QList<Value> values;
foreach (const Key &key, insertOrder.toStdList()) {
OMHashValue v = data.value(key);
values.append(v.first);
}
return values;
}
template <typename Key, typename Value>
OrderedMap<Key, Value> & OrderedMap<Key, Value>::operator=(const OrderedMap<Key, Value>& other)
{
if (this != &other) {
copy(other);
}
return *this;
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
template <typename Key, typename Value>
OrderedMap<Key, Value> & OrderedMap<Key, Value>::operator=(OrderedMap<Key, Value>&& other)
{
if (this != &other) {
data = other.data;
insertOrder = other.insertOrder;
}
return *this;
}
#endif
template <typename Key, typename Value>
bool OrderedMap<Key, Value>::operator==(const OrderedMap<Key, Value> &other) const
{
// 2 Ordered maps are equal if they have the same contents in the same order
return ((data == other.data) && (insertOrder == other.insertOrder));
}
template <typename Key, typename Value>
bool OrderedMap<Key, Value>::operator!=(const OrderedMap<Key, Value> &other) const
{
return ((data != other.data) || (insertOrder != other.insertOrder));
}
template <typename Key, typename Value>
Value& OrderedMap<Key, Value>::operator[](const Key &key)
{
OMHashIterator it = data.find(key);
if (it == data.end()) {
insert(key, Value());
it = data.find(key);
}
OMHashValue &pair = it.value();
return pair.first;
}
template <typename Key, typename Value>
const Value OrderedMap<Key, Value>::operator[](const Key &key) const
{
return value(key);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::iterator OrderedMap<Key, Value>::begin()
{
return iterator(insertOrder.begin(), &data);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::const_iterator OrderedMap<Key, Value>::begin() const
{
return const_iterator(insertOrder.begin(), &data);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::iterator OrderedMap<Key, Value>::end()
{
return iterator(insertOrder.end(), &data);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::const_iterator OrderedMap<Key, Value>::end() const
{
return const_iterator(insertOrder.end(), &data);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::iterator OrderedMap<Key, Value>::erase(iterator pos)
{
OMHashIterator hit = data.find(*(pos.qllIter));
if (hit == data.end()) {
return pos;
}
data.erase(hit);
QllIterator ioIter = insertOrder.erase(pos.qllIter);
return iterator(ioIter, &data);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::iterator OrderedMap<Key, Value>::find(const Key& key)
{
OMHashIterator hit = data.find(key);
if (hit == data.end()) {
return end();
}
return iterator(hit.value().second, &data);
}
template <typename Key, typename Value>
typename OrderedMap<Key, Value>::const_iterator OrderedMap<Key, Value>::find(const Key& key) const
{
OMHashConstIterator hit = data.find(key);
if (hit == data.end()) {
return end();
}
return const_iterator(hit.value().second, &data);
}
#endif // ORDEREDMAP_H
-254
View File
@@ -1,254 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Corentin Chary <corentin.chary@gmail.cm>
**
** This file could be part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPRIORITY_QUEUE_H
#define QPRIORITY_QUEUE_H
#include <QtCore/qalgorithms.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Core)
template <class T> class QList;
#ifndef QT_NO_STL
#include <queue>
#include <vector>
#else
/* Fallback class used when stl is not available */
template <class T, typename LessThan = qLess < T > >
class QPriorityQueuePrivate {
public:
inline QPriorityQueuePrivate(LessThan l) : lessThan(l), d() {}
inline ~QPriorityQueuePrivate() {}
inline void clear() { return d.clear(); }
inline int size() const { return d.size(); }
inline bool empty() const { return d.empty(); }
inline T &top() { return d.front(); }
void pop();
void push(const T &value);
private:
inline int parent(int i) {
return (i - 1) / 2;
}
inline int leftChild(int i) {
return 2 * i + 1;
}
inline int rightChild(int i) {
return 2 * i + 2;
}
LessThan lessThan;
QList < T > d;
};
#endif
template <class T, typename LessThan = qLess < T > >
class Q_CORE_EXPORT QPriorityQueue
{
public:
inline QPriorityQueue(LessThan l = qLess < T >())
: lessThan(l), d(lessThan) { }
inline QPriorityQueue(const QPriorityQueue<T> &q)
: lessThan(q.lessThan), d(q.d) { }
inline ~QPriorityQueue() { }
QPriorityQueue<T> &operator=(const QPriorityQueue<T> &q) {
d = q.d; return *this;
}
inline int size() const { return d.size(); }
inline bool isEmpty() const { return empty(); }
// like qlist
void clear();
void append(const T &t) { return enqueue(t); }
void append(const QList<T> &t);
T takeFirst() { return dequeue(); }
inline int length() const { return size(); } // Same as count()
inline T& first() { return head(); }
inline const T& first() const { return head(); }
inline void removeFirst() { pop(); }
inline bool startsWith(const T &t) const
{ return !isEmpty() && first() == t; }
// like qqueue
inline void enqueue(const T &t) { push(t); }
inline T dequeue() { T t = d.top(); d.pop(); return t; }
inline T &head() { return const_cast<T&>(top()); }
inline const T &head() const { return top(); }
// stl compatibility
typedef int size_type;
typedef T value_type;
inline bool empty() const { return d.empty(); }
inline const value_type& top() { Q_ASSERT(!isEmpty()); return d.top(); }
inline void push(const value_type& x) { return d.push(x); }
inline void pop() { Q_ASSERT(!isEmpty()); d.pop(); }
// comfort
inline QPriorityQueue<T> &operator+=(const T &t) {
enqueue(t); return *this;
}
inline QPriorityQueue<T> &operator<< (const T &t) {
enqueue(t); return *this;
}
inline QPriorityQueue<T> &operator>> (T &t) {
t = d.top(); d.pop(); return *this;
}
#ifndef QT_NO_STL
static inline QPriorityQueue<T>fromStdPriorityQueue(
const std::priority_queue<T> &q) {
QPriorityQueue<T> tmp; tmp.d = q; return tmp;
}
inline std::priority_queue<T> toStdPriorityQueue() const {
return d;
}
#endif
private:
LessThan lessThan;
#ifndef QT_NO_STL
std::priority_queue <T, std::vector < T >, LessThan> d;
#else
QPriorityQueuePrivate <T> d;
#endif
};
#ifndef QT_NO_STL
template <typename T, typename LessThan>
Q_INLINE_TEMPLATE void QPriorityQueue<T, LessThan>::clear()
{
d = std::priority_queue <T, std::vector < T >, LessThan>(lessThan);
//d = std::priority_queue<T>(lessThan);
}
#else
template <typename T, typename LessThan>
Q_INLINE_TEMPLATE void QPriorityQueue<T, LessThan>::clear()
{
d.clear();
}
#endif
template <typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE void QPriorityQueue<T, LessThan>::append(const QList<T> &t)
{
foreach (T & e, t)
push(e);
}
// Re-implement std::priority_queue if STL not available, probably
// less efficient.
#ifdef QT_NO_STL
/*!
* Pop an element from the queue and reorder it using an
* inlined binary heap.
*
* \internal
*/
template <typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE void QPriorityQueuePrivate<T, LessThan>::pop()
{
int i = 0;
ssize_t size = d.size();;
if(!size)
return;
if(size == 1)
return d.clear();
d[0] = d.takeLast();
while(i < size - 1) {
int left = leftChild(i);
int right = rightChild(i);
bool validLeft = left < size;
bool validRight = right < size;
if(validLeft && lessThan(d.at(i), d.at(left)))
if(validRight && !lessThan(d.at(right), d.at(left))) {
d.swap(i, right);
i = right;
} else {
d.swap(i, left);
i = left;
}
else if(validRight && lessThan(d.at(i), d.at(right))) {
d.swap(i, right);
i = right;
}
else
break;
}
}
/*!
* Push an element with a given priority to the right place.
*
* \internal
*/
template <typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE void QPriorityQueuePrivate<T, LessThan>::push(const T &value)
{
int i = d.size();
d.append(value);
while(i != 0 && !lessThan(d.at(i), d.at(parent(i)))) {
d.swap(i, parent(i));
i = parent(i);
}
}
#endif
QT_END_NAMESPACE
QT_END_HEADER
#endif // QPRIORITY_QUEUE_H
+58 -8
View File
@@ -5,9 +5,62 @@
#include <QCoreApplication>
#include <QRegularExpression>
QString revision (QString const& svn_rev_string)
#include "scs_version.h"
namespace
{
return "";
QString revision_extract_number (QString const& s)
{
QString revision;
// try and match a number (hexadecimal allowed)
QRegularExpression re {R"(^[$:]\w+: (r?[\da-f]+[^$]*)\$$)"};
auto match = re.match (s);
if (match.hasMatch ())
{
revision = match.captured (1);
}
return revision;
}
}
QString revision (QString const& scs_rev_string)
{
QString result;
auto revision_from_scs = revision_extract_number (scs_rev_string);
#if defined (CMAKE_BUILD)
QString scs_info {":Rev: " WSJTX_STRINGIZE (SCS_VERSION) " $"};
auto revision_from_scs_info = revision_extract_number (scs_info);
if (!revision_from_scs_info.isEmpty ())
{
// we managed to get the revision number from svn info etc.
result = revision_from_scs_info;
}
else if (!revision_from_scs.isEmpty ())
{
// fall back to revision passed in if any
result = revision_from_scs;
}
else
{
// match anything
QRegularExpression re {R"(^[$:]\w+: ([^$]*)\$$)"};
auto match = re.match (scs_info);
if (match.hasMatch ())
{
result = match.captured (1);
}
}
#else
if (!revision_from_scs.isEmpty ())
{
// not CMake build so all we have is revision passed
result = revision_from_scs;
}
#endif
return result.trimmed ();
}
QString version (bool include_patch)
@@ -17,22 +70,19 @@ QString version (bool include_patch)
if (include_patch)
{
v += "." WSJTX_STRINGIZE (WSJTX_VERSION_PATCH)
#if 0
# if defined (WSJTX_RC)
+ "-rc" WSJTX_STRINGIZE (WSJTX_RC)
# endif
#endif
;
}
#else
QString v {"Not for Release"};
#endif
return v;
}
QString program_title (QString const& revision)
{
QString id {"FT8Call de KN4CRD (v%1) a derivative of WSJT-X by K1JT"};
return id.arg(QCoreApplication::applicationVersion ());
}
QString id {QCoreApplication::applicationName () + " v" + QCoreApplication::applicationVersion ()};
return id + " " + revision + " by K1JT";
}
+1 -8
View File
@@ -44,7 +44,6 @@ protected:
QWidget::paintEvent (event);
QPainter p {this};
p.setPen(Qt::white);
auto const& target = contentsRect ();
QFontMetrics font_metrics {p.font (), this};
auto font_offset = font_metrics.ascent () / 2;
@@ -83,18 +82,12 @@ SignalMeter::SignalMeter (QWidget * parent)
m_meter = new MeterWidget;
m_meter->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum);
//inner_layout->addWidget (m_meter);
inner_layout->addWidget (m_meter);
m_scale = new Scale;
inner_layout->addWidget (m_scale);
// add this second...
inner_layout->addWidget (m_meter);
m_reading = new QLabel(this);
auto p = m_reading->palette();
p.setColor(m_reading->foregroundRole(), Qt::white);
m_reading->setPalette(p);
outer_layout->addLayout (inner_layout);
outer_layout->addWidget (m_reading);
-105
View File
@@ -1,105 +0,0 @@
from __future__ import print_function
import json
from socket import socket, AF_INET, SOCK_DGRAM
import time
listen = ('127.0.0.1', 2237)
def from_message(content):
try:
return json.loads(content)
except ValueError:
return {}
def to_message(typ, value='', params=None):
if params is None:
params = {}
return json.dumps({'type': typ, 'value': value, 'params': params})
class Server(object):
first = True
def process(self, message):
typ = message.get('type', '')
value = message.get('value', '')
params = message.get('params', {})
if not typ:
return
print('->', typ)
if value:
print('-> value', value)
if params:
print('-> params: ', params)
#### if typ == 'PING':
#### if self.first:
#### self.send('RX.GET_BAND_ACTIVITY')
#### self.send('TX.SET_TEXT', 'HERE WE GO')
#### time.sleep(1)
#### self.send('WINDOW.RAISE')
#### self.first = False
#### if typ == 'PING':
#### self.send('STATION.GET_GRID')
#### self.send('RIG.GET_FREQ')
#### self.send('STATION.GET_CALLSIGN')
#### self.send('RX.GET_CALL_ACTIVITY')
#### elif typ == 'STATION.GRID':
#### if value != 'EM73TU49TQ':
#### self.send('STATION.SET_GRID', 'EM73TU49TQ')
#### elif typ == 'RIG.FREQ':
#### if params.get('DIAL', 0) != 14064000:
#### self.send('RIG.SET_FREQ', '', {"DIAL": 14064000, "OFFSET": 977})
#### self.send('TX.SEND_MESSAGE', 'HELLO WORLD')
elif typ == 'CLOSE':
self.close()
def send(self, *args, **kwargs):
message = to_message(*args, **kwargs)
print('outgoing message:', message)
self.sock.sendto(message, self.reply_to)
def listen(self):
print('listening on', ':'.join(map(str, listen)))
self.sock = socket(AF_INET, SOCK_DGRAM)
self.sock.bind(listen)
self.listening = True
try:
while self.listening:
content, addr = self.sock.recvfrom(65500)
print('incoming message:', ':'.join(map(str, addr)))
try:
message = json.loads(content)
except ValueError:
message = {}
if not message:
continue
self.reply_to = addr
self.process(message)
finally:
self.sock.close()
def close(self):
self.listening = False
def main():
s = Server()
s.listen()
if __name__ == '__main__':
main()
-1547
View File
File diff suppressed because it is too large Load Diff
-142
View File
@@ -1,142 +0,0 @@
#ifndef VARICODE_H
#define VARICODE_H
/**
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
**/
#include <QBitArray>
#include <QRegularExpression>
#include <QRegExp>
#include <QString>
#include <QVector>
class Varicode
{
public:
// frame type transmitted via itype and decoded by the ft8 decoded
enum TransmissionType {
FT8Call = 0, // [000] <- any other frame of the message
FT8CallFirst = 1, // [001] <- the first frame of a message
FT8CallLast = 2, // [010] <- the last frame of a message
FT8CallReserved = 4, // [100] <- a reserved flag for future use...
};
enum FrameType {
FrameUnknown = 255, // [11111111] <- only used as a sentinel
FrameBeacon = 0, // [000]
FrameCompound = 1, // [001]
FrameCompoundDirected = 2, // [010]
FrameDirected = 3, // [011]
FrameReservedA = 4, // [100] <- Reserved for future use, likely an extension of one of these formats.
FrameDataUnpadded = 5, // [101]
FrameDataPadded = 6, // [110]
FrameReservedB = 7, // [111] <- Reserved for future use, likely binary data / other formats.
};
static const quint8 FrameTypeMax = 7;
static QString frameTypeString(quint8 type) {
const char* FrameTypeStrings[] = {
"FrameBeacon",
"FrameCompound",
"FrameCompoundDirected",
"FrameDirected",
"FrameReservedA",
"FrameDataUnpadded",
"FrameDataPadded",
"FrameReservedB"
};
if(type > FrameTypeMax){
return "FrameUnknown";
}
return FrameTypeStrings[type];
}
//Varicode();
static QString formatSNR(int snr);
static QString formatPWR(int dbm);
static QString checksum16(QString const &input);
static bool checksum16Valid(QString const &checksum, QString const &input);
static QString checksum32(QString const &input);
static bool checksum32Valid(QString const &checksum, QString const &input);
static QStringList parseCallsigns(QString const &input);
static QStringList parseGrids(QString const &input);
static QList<QPair<int, QVector<bool>>> huffEncode(const QMap<QString, QString> &huff, QString const& text);
static QString huffDecode(const QMap<QString, QString> &huff, QVector<bool> const& bitvec);
static QString huffUnescape(QString const &input);
static QString huffEscape(QString const &input);
static QSet<QString> huffValidChars();
static bool huffShouldEscape(QString const &input);
static QVector<bool> bytesToBits(char * bitvec, int n);
static QVector<bool> strToBits(QString const& bitvec);
static QString bitsToStr(QVector<bool> const& bitvec);
static QVector<bool> intToBits(quint64 value, int expected=0);
static quint64 bitsToInt(QVector<bool> const value);
static quint64 bitsToInt(QVector<bool>::ConstIterator start, int n);
static QVector<bool> bitsListToBits(QList<QVector<bool>> &list);
static quint8 unpack5bits(QString const& value);
static QString pack5bits(quint8 packed);
static quint8 unpack6bits(QString const& value);
static QString pack6bits(quint8 packed);
static quint16 unpack16bits(QString const& value);
static QString pack16bits(quint16 packed);
static quint32 unpack32bits(QString const& value);
static QString pack32bits(quint32 packed);
static quint64 unpack64bits(QString const& value);
static QString pack64bits(quint64 packed);
static quint64 unpack72bits(QString const& value, quint8 *pRem);
static QString pack72bits(quint64 value, quint8 rem);
static quint32 packAlphaNumeric22(QString const& value, bool isFlag);
static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);
static quint32 packCallsign(QString const& value);
static QString unpackCallsign(quint32 value);
static QString deg2grid(float dlong, float dlat);
static QPair<float, float> grid2deg(QString const &grid);
static quint16 packGrid(QString const& value);
static QString unpackGrid(quint16 value);
static quint8 packNum(QString const &num, bool *ok);
static quint8 packPwr(QString const &pwr, bool *ok);
static quint8 packCmd(quint8 cmd, quint8 num, bool *pPackedNum);
static quint8 unpackCmd(quint8 value, quint8 *pNum);
static bool isCommandAllowed(const QString &cmd);
static bool isCommandBuffered(const QString &cmd);
static int isCommandChecksumed(const QString &cmd);
static QString packBeaconMessage(QString const &text, QString const&callsign, int *n);
static QStringList unpackBeaconMessage(const QString &text, quint8 *pType, bool *isAlt);
static QString packCompoundMessage(QString const &text, int *n);
static QStringList unpackCompoundMessage(const QString &text, quint8 *pType);
static QString packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint8 type, quint16 num);
static QStringList unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum);
static QString packDirectedMessage(QString const& text, QString const& callsign, QString *pTo, QString * pCmd, QString *pNum, int *n);
static QStringList unpackDirectedMessage(QString const& text, quint8 *pType);
static QString packDataMessage(QString const& text, int *n);
static QString unpackDataMessage(QString const& text, quint8 *pType);
};
#endif // VARICODE_H
+6 -21
View File
@@ -64,8 +64,8 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
ui->bppSpinBox->setValue(n);
m_nsmo=m_settings->value("SmoothYellow",1).toInt();
ui->smoSpinBox->setValue(m_nsmo);
m_Percent2DScreen=m_settings->value("Percent2D", 0).toInt();
m_waterfallAvg = m_settings->value("WaterfallAvg", 1).toInt();
m_Percent2DScreen=m_settings->value("Percent2D",30).toInt();
m_waterfallAvg = m_settings->value("WaterfallAvg",5).toInt();
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
ui->widePlot->setWaterfallAvg(m_waterfallAvg);
ui->widePlot->setCurrent(m_settings->value("Current",false).toBool());
@@ -76,18 +76,17 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
if(ui->widePlot->cumulative()) ui->spec2dComboBox->setCurrentIndex(1);
if(ui->widePlot->linearAvg()) ui->spec2dComboBox->setCurrentIndex(2);
if(ui->widePlot->Reference()) ui->spec2dComboBox->setCurrentIndex(3);
int nbpp=m_settings->value("BinsPerPixel", 4).toInt();
int nbpp=m_settings->value("BinsPerPixel",2).toInt();
ui->widePlot->setBinsPerPixel(nbpp);
ui->sbPercent2dPlot->setValue(m_Percent2DScreen);
ui->widePlot->SetPercent2DScreen(m_Percent2DScreen);
ui->widePlot->setStartFreq(m_settings->value("StartFreq", 500).toInt());
ui->widePlot->setStartFreq(m_settings->value("StartFreq",0).toInt());
ui->fStartSpinBox->setValue(ui->widePlot->startFreq());
m_waterfallPalette=m_settings->value("WaterfallPalette","Default").toString();
m_userPalette = WFPalette {m_settings->value("UserPalette").value<WFPalette::Colours> ()};
m_fMinPerBand = m_settings->value ("FminPerBand").toHash ();
setRxRange ();
ui->controls_widget->setVisible(!m_settings->value("HideControls", false).toBool());
ui->cbControls->setChecked(!m_settings->value("HideControls", false).toBool());
ui->controls_widget->setVisible(!m_settings->value("HideControls",false).toBool());
ui->cbControls->setChecked(!m_settings->value("HideControls",false).toBool());
}
int index=0;
@@ -207,18 +206,6 @@ void WideGraph::on_bppSpinBox_valueChanged(int n) //b
ui->widePlot->setBinsPerPixel(n);
}
void WideGraph::on_offsetSpinBox_valueChanged(int n){
if(n == rxFreq()){
return;
}
n = qMax(500, n);
setRxFreq(n);
setTxFreq(n);
setFreq2(n, n);
}
void WideGraph::on_waterfallAvgSpinBox_valueChanged(int n) //Navg
{
m_waterfallAvg = n;
@@ -249,7 +236,6 @@ void WideGraph::setRxFreq(int n) //set
{
ui->widePlot->setRxFreq(n);
ui->widePlot->draw(swide,false,false);
ui->offsetSpinBox->setValue(n);
}
int WideGraph::rxFreq() //rxFreq
@@ -300,7 +286,6 @@ void WideGraph::setTxFreq(int n) //setTxFreq
{
emit setXIT2(n);
ui->widePlot->setTxFreq(n);
ui->offsetSpinBox->setValue(n);
}
void WideGraph::setMode(QString mode) //setMode
-1
View File
@@ -66,7 +66,6 @@ protected:
void closeEvent (QCloseEvent *) override;
private slots:
void on_offsetSpinBox_valueChanged(int n);
void on_waterfallAvgSpinBox_valueChanged(int arg1);
void on_bppSpinBox_valueChanged(int arg1);
void on_spec2dComboBox_currentIndexChanged(const QString &arg1);
+280 -305
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>942</width>
<width>799</width>
<height>337</height>
</rect>
</property>
@@ -68,7 +68,7 @@
<string>Controls</string>
</property>
<property name="checked">
<bool>false</bool>
<bool>true</bool>
</property>
</widget>
</widget>
@@ -100,195 +100,7 @@
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="1" column="7">
<widget class="QComboBox" name="spec2dComboBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select data for spectral display&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Current</string>
</property>
</item>
<item>
<property name="text">
<string>Cumulative</string>
</property>
</item>
<item>
<property name="text">
<string>Linear Avg</string>
</property>
</item>
<item>
<property name="text">
<string>Reference</string>
</property>
</item>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
</widget>
</item>
<item row="0" column="6" rowspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="4" rowspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="fStartSpinBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Frequency at left edge of waterfall&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Start </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
<item row="1" column="12">
<widget class="QSpinBox" name="smoSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Smoothing of Linear Average spectrum</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Smooth </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
<item row="0" column="13" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="11">
<widget class="QSlider" name="zeroSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Waterfall zero</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QComboBox" name="paletteComboBox">
<property name="toolTip">
<string>Select waterfall palette</string>
</property>
</widget>
</item>
<item row="0" column="7">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="cbFlatten">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Flatten spectral baseline over the full displayed interval.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Flatten</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbRef">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Compute and save a reference spectrum. (Not yet fully implemented.)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Ref Spec</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="9">
<item row="1" column="8">
<widget class="QSlider" name="gain2dSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -325,7 +137,31 @@
</property>
</widget>
</item>
<item row="0" column="9">
<item row="0" column="4">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labPalette">
<property name="text">
<string> Palette </string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="adjust_palette_push_button">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enter definition for a new color palette.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Adjust...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="8">
<widget class="QSlider" name="gainSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -362,7 +198,240 @@
</property>
</widget>
</item>
<item row="0" column="11">
<widget class="QSpinBox" name="sbPercent2dPlot">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set fractional size of spectrum in this window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string> %</string>
</property>
<property name="prefix">
<string>Spec </string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
</item>
<item row="0" column="6">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="cbFlatten">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Flatten spectral baseline over the full displayed interval.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Flatten</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbRef">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Compute and save a reference spectrum. (Not yet fully implemented.)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Ref Spec</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="11">
<widget class="QSpinBox" name="smoSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Smoothing of Linear Average spectrum</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Smooth </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="bppSpinBox">
<property name="toolTip">
<string>Compression factor for frequency scale</string>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QComboBox" name="paletteComboBox">
<property name="toolTip">
<string>Select waterfall palette</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="spec2dComboBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select data for spectral display&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Current</string>
</property>
</item>
<item>
<property name="text">
<string>Cumulative</string>
</property>
</item>
<item>
<property name="text">
<string>Linear Avg</string>
</property>
</item>
<item>
<property name="text">
<string>Reference</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="fStartSpinBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Frequency at left edge of waterfall&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Start </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="fSplitSpinBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Decode JT9 only above this frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> JT9</string>
</property>
<property name="prefix">
<string>JT65 </string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>3000</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="QSlider" name="zeroSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Waterfall zero</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="1" column="10">
<widget class="QSlider" name="zero2dSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -412,124 +481,30 @@
</property>
</spacer>
</item>
<item row="0" column="12">
<widget class="QSpinBox" name="sbPercent2dPlot">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set fractional size of spectrum in this window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<item row="0" column="12" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<property name="suffix">
<string> %</string>
</property>
<property name="prefix">
<string>Spec </string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>0</number>
</spacer>
</item>
<item row="0" column="3" rowspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="5">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labPalette">
<property name="text">
<string> Palette </string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="adjust_palette_push_button">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enter definition for a new color palette.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Adjust...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="fSplitSpinBox">
<property name="visible">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Decode JT9 only above this frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> JT9</string>
</property>
<property name="prefix">
<string>JT65 </string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>3000</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="offsetSpinBox">
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Offset </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>1500</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="bppSpinBox">
<property name="toolTip">
<string>Compression factor for frequency scale</string>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
<item row="0" column="5" rowspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
+2 -15
View File
@@ -67,12 +67,7 @@ SOURCES += \
echoplot.cpp echograph.cpp fastgraph.cpp fastplot.cpp Modes.cpp \
WSPRBandHopping.cpp MessageAggregator.cpp SampleDownloader.cpp qt_helpers.cpp\
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp MessageBox.cpp \
EqualizationToolsDialog.cpp \
varicode.cpp \
NetworkMessage.cpp \
MessageClient.cpp \
SelfDestructMessageBox.cpp \
APRSISClient.cpp
EqualizationToolsDialog.cpp
HEADERS += qt_helpers.hpp \
pimpl_h.hpp pimpl_impl.hpp \
@@ -88,15 +83,7 @@ HEADERS += qt_helpers.hpp \
logbook/logbook.h logbook/countrydat.h logbook/countriesworked.h logbook/adif.h \
messageaveraging.h echoplot.h echograph.h fastgraph.h fastplot.h Modes.hpp WSPRBandHopping.hpp \
WsprTxScheduler.h SampleDownloader.hpp MultiSettings.hpp PhaseEqualizationDialog.hpp \
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp \
qorderedmap.h \
varicode.h \
qpriorityqueue.h \
crc.h \
NetworkMessage.hpp \
MessageClient.hpp \
SelfDestructMessageBox.h \
APRSISClient.h
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp
INCLUDEPATH += qmake_only
-271
View File
@@ -1,271 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2018-03-10T16:32:07. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{8aae28ee-a5c1-42be-b6ce-fec03bd16ac8}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{2070fb4e-8ad0-4fb1-a39c-093033bf1855}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jordan/Development/third-party/wsjtx-prefix/build-wsjtx-Desktop-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jordan/Development/third-party/wsjtx-prefix/build-wsjtx-Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">wsjtx</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/jordan/Development/third-party/wsjtx-prefix/src_wsjtx/wsjtx.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">wsjtx.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>