Compare commits
4 Commits
v0.5.1
..
4f1fe4fc94
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f1fe4fc94 | |||
| 419c039d08 | |||
| 45cc6416c1 | |||
| 587950f372 |
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
@@ -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 {®ions_, &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
@@ -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
File diff suppressed because it is too large
Load Diff
+151
-11
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 ¶ms):
|
||||
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
@@ -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 ¶ms);
|
||||
|
||||
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_;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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()
|
||||
+30
-197
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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,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=' '
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
auto logFileName = "ft8call_log.adi";
|
||||
auto logFileName = "wsjtx_log.adi";
|
||||
auto countryFileName = "cty.dat";
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -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 ()),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+13
-263
@@ -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> ¶ms);
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
echo make
|
||||
echo cp wsjtx ft8call
|
||||
echo linuxdeployqt ./ft8call -appimage -bundle-non-qt-libs -no-strip -no-translations
|
||||
+4
-8
@@ -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
@@ -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 ()) {
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
-142
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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><html><head/><body><p>Select data for spectral display</p></body></html></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><html><head/><body><p>Frequency at left edge of waterfall</p></body></html></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><html><head/><body><p>Flatten spectral baseline over the full displayed interval.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flatten</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbRef">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Compute and save a reference spectrum. (Not yet fully implemented.)</p></body></html></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><html><head/><body><p>Enter definition for a new color palette.</p></body></html></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><html><head/><body><p>Set fractional size of spectrum in this window.</p></body></html></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><html><head/><body><p>Flatten spectral baseline over the full displayed interval.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flatten</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbRef">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Compute and save a reference spectrum. (Not yet fully implemented.)</p></body></html></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><html><head/><body><p>Select data for spectral display</p></body></html></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><html><head/><body><p>Frequency at left edge of waterfall</p></body></html></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><html><head/><body><p>Decode JT9 only above this frequency</p></body></html></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><html><head/><body><p>Set fractional size of spectrum in this window.</p></body></html></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><html><head/><body><p>Enter definition for a new color palette.</p></body></html></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><html><head/><body><p>Decode JT9 only above this frequency</p></body></html></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>
|
||||
|
||||
@@ -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
@@ -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>
|
||||
Reference in New Issue
Block a user